59 Commits
Author SHA1 Message Date
CodedRed 8d5a815f22 fixed update checker bug 2023-07-10 19:56:23 -05:00
CodedRed 93a8dd97cc plugin.yml changes 2023-07-10 19:53:58 -05:00
CodedRed 2a497041f8 updated bstats metrics 2023-07-10 19:49:35 -05:00
CodedRed 0d5167bf53 refactored papi 2023-07-10 19:26:46 -05:00
CodedRed 9dec539ab9 added tab completer 2023-07-10 19:07:10 -05:00
CodedRed 106ce705a3 fixed block permission 2023-07-10 18:55:16 -05:00
CodedRed 961cd9c5a5 added help & debug subcommands for admins 2023-07-10 18:51:12 -05:00
CodedRed d739c329ff small color change 2023-07-10 18:29:13 -05:00
CodedRed 5fcc916cce updated license 2023-07-10 18:24:12 -05:00
CodedRed 1f21dd5046 updated readme 2023-07-10 18:23:20 -05:00
CodedRed c2ec5303f2 config update 2023-07-10 18:12:46 -05:00
CodedRed d06ef50677 refactored time registry 2023-07-10 18:10:38 -05:00
CodedRed 9cef097cf7 added spaces to config file 2023-07-10 17:49:57 -05:00
CodedRed d79acc4641 removed extra space between format 2023-07-10 17:49:15 -05:00
CodedRed 3ea405947e optimized time formats 2023-07-10 17:41:50 -05:00
CodedRed 24c4438dcf fixed reload cmd 2023-07-10 17:41:38 -05:00
CodedRed b787f8db6f reverted to old custom time formatter 2023-07-10 17:22:31 -05:00
CodedRed 4d92c2c9ad fixed join bug 2023-07-10 16:41:50 -05:00
CodedRed 155a08207e fixed reload command 2023-07-10 16:36:09 -05:00
CodedRed 0b9301a400 improved time formatter 2023-07-10 16:25:50 -05:00
CodedRed 6aa59e4cb7 quick change 2023-07-10 15:56:03 -05:00
CodedRed 9a8cdda6b8 setup to use craftengine 2023-07-10 14:01:13 -05:00
CodedRed 899f04967f Added timezone to TimeFormatter 2023-02-21 13:31:22 -06:00
CodedRed ad05be5f5c Timeformatter Fixes 2023-02-21 13:11:13 -06:00
CodedRed 252e454224 bug fixes 2023-02-19 14:17:20 -06:00
CodedRed a01b4db91d Stat update 2023-02-19 14:15:55 -06:00
CodedRed aaca127457 Added papermake 2023-02-19 12:22:06 -06:00
CodedRed cdc53fbe6c Fixed Leaderboard & DateFormatter 2023-02-19 12:02:47 -06:00
CodedRed c628acd809 removed api. Will handle that later 2023-02-18 21:39:52 -06:00
CodedRed 725389ff02 updated with new time format 2023-02-18 21:39:32 -06:00
CodedRed c20806f0bc Simplifying how time get formatted, wip 2023-02-18 21:37:01 -06:00
CodedRed 60b079e6d0 Remove built-in holograms 2023-02-18 21:31:40 -06:00
CodedRed 19587e44ff Quick data fix 2023-02-18 21:31:05 -06:00
CodedRed 02297b8cfa Removed debugger, don't think I need it? 2023-02-18 20:44:59 -06:00
CodedRed 834455344b refactoring cooldowns, still needs more work 2023-02-18 20:43:07 -06:00
CodedRed 22d0c25161 removed useless try/catch block 2023-02-18 20:39:16 -06:00
CodedRed 9f367a5194 some refactoring 2023-02-18 20:37:10 -06:00
CodedRed 5f0bcb5cd1 major command refactoring. Reduced complexity by a loooooooooot 2023-02-18 20:24:28 -06:00
CodedRed c575ed7f74 performance changes to Stats 2023-02-18 20:07:49 -06:00
CodedRed 94afb36d5a small Off/On Player changes 2023-02-18 20:06:41 -06:00
CodedRed 38001557be small server changes 2023-02-18 19:27:40 -06:00
CodedRed b2a1cfa247 new optimized leaderboard that hopefully works 2023-02-18 19:23:25 -06:00
CodedRed a98e1e2bb0 improved listener performance 2023-02-18 19:06:02 -06:00
CodedRed 94267e64e1 needs more changes later 2023-02-18 19:03:04 -06:00
CodedRed febfc7d378 Merge pull request #29 from CodedRed-Spigot/add-license-1
Create LICENSE
2023-02-18 18:52:26 -06:00
CodedRed b185d1364a Create LICENSE 2023-02-18 18:52:15 -06:00
CodedRed 4a1d5c7deb Add files via upload 2023-02-18 18:51:39 -06:00
CodedRed 6a5238d8dd Create README.md 2023-02-18 18:50:52 -06:00
CodedRed ac40ac17dd improved performance 2023-02-18 17:40:26 -06:00
CodedRed 51bfaf656d improved performance and reduced the number of unnecessary reflection checks 2023-02-18 17:38:54 -06:00
CodedRed 6db539fb88 no more regular expression when doing Hex 2023-02-18 17:29:49 -06:00
CodedRed 7a8fdbedc4 improved update checker 2023-02-18 17:24:28 -06:00
CodedRed 24e35e01e2 change to using logger 2023-02-18 17:20:04 -06:00
CodedRed ee28c37637 oh hi gradle pt2 2023-02-18 17:14:11 -06:00
CodedRed 5bbe1a1018 oh hi gradle 2023-02-18 17:11:22 -06:00
CodedRed 6d5cad3607 bye bye 2023-02-18 17:07:25 -06:00
CodedRed deb512dfd0 wow ummm a lot to do... changes coming 2023-02-18 17:00:59 -06:00
CodedRed 550338b799 1.19 Support. 2022-07-19 13:21:59 -05:00
CodedRed 46f5435684 Added 1.18 Support 2021-12-15 20:27:18 -06:00
73 changed files with 2302 additions and 2106 deletions

No files matched your search

+118
View File
@@ -0,0 +1,118 @@
# User-specific stuff
.idea/
*.iml
*.ipr
*.iws
# IntelliJ
out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Compiled class file
*.class
# Log file
*.log
# BlueJ files
*.ctxt
# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
*~
# 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-*
# .nfs files are created when an open file is removed but is still being accessed
.nfs*
# General
.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
# Windows thumbnail cache files
Thumbs.db
Thumbs.db:encryptable
ehthumbs.db
ehthumbs_vista.db
# Dump file
*.stackdump
# Folder config file
[Dd]esktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msix
*.msm
*.msp
# Windows shortcuts
*.lnk
.gradle
build/
# Ignore Gradle GUI config
gradle-app.setting
# Cache of project
.gradletasknamecache
**/build/
# Common working directory
run/
# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
!gradle-wrapper.jar
-5
View File
@@ -1,5 +0,0 @@
# Default ignored files
/shelf/
/workspace.xml
# CodeStream ignored files
/../../PlayTimes\.idea/codestream.xml
-6
View File
@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CodeStream">
<option name="webViewContext" value="{&quot;chatProviderAccess&quot;:&quot;strict&quot;,&quot;currentTeamId&quot;:&quot;&quot;,&quot;currentStreamId&quot;:&quot;&quot;,&quot;pullRequestCheckoutBranch&quot;:false,&quot;isRepositioning&quot;:false,&quot;onboardStep&quot;:0,&quot;panelStack&quot;:[&quot;landing-redirect&quot;],&quot;hasFocus&quot;:false,&quot;channelFilter&quot;:&quot;all&quot;,&quot;channelsMuteAll&quot;:false,&quot;codemarkFileFilter&quot;:&quot;all&quot;,&quot;codemarkTypeFilter&quot;:&quot;all&quot;,&quot;codemarkTagFilter&quot;:&quot;all&quot;,&quot;codemarkBranchFilter&quot;:&quot;all&quot;,&quot;codemarkAuthorFilter&quot;:&quot;all&quot;,&quot;codemarksFileViewStyle&quot;:&quot;inline&quot;,&quot;codemarksShowArchived&quot;:false,&quot;codemarksShowResolved&quot;:false,&quot;codemarksWrapComments&quot;:false,&quot;showFeedbackSmiley&quot;:true,&quot;route&quot;:{&quot;name&quot;:&quot;newUserEntry&quot;,&quot;params&quot;:{}},&quot;spatialViewShowPRComments&quot;:false}" />
</component>
</project>
-16
View File
@@ -1,16 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<annotationProcessing>
<profile name="Maven default annotation processors profile" enabled="true">
<sourceOutputDir name="target/generated-sources/annotations" />
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
<outputRelativeToContentRoot value="true" />
<module name="PlayTimes" />
</profile>
</annotationProcessing>
<bytecodeTargetLevel>
<module name="PlayTimes" target="1.8" />
</bytecodeTargetLevel>
</component>
</project>
-6
View File
@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DiscordProjectSettings">
<option name="show" value="PROJECT_FILES" />
</component>
</project>
-7
View File
@@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
</component>
</project>
-99
View File
@@ -1,99 +0,0 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="AccessToNonThreadSafeStaticFieldFromInstance" enabled="true" level="WARNING" enabled_by_default="true">
<option name="nonThreadSafeClasses">
<value />
</option>
<option name="nonThreadSafeTypes" value="" />
</inspection_tool>
<inspection_tool class="ArrayEquality" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="BooleanExpressionMayBeConditional" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="CallToSimpleGetterInClass" enabled="false" level="WEAK WARNING" enabled_by_default="false">
<option name="ignoreGetterCallsOnOtherObjects" value="false" />
<option name="onlyReportPrivateGetter" value="false" />
</inspection_tool>
<inspection_tool class="CallToSimpleSetterInClass" enabled="false" level="WEAK WARNING" enabled_by_default="false">
<option name="ignoreSetterCallsOnOtherObjects" value="false" />
<option name="onlyReportPrivateSetter" value="false" />
</inspection_tool>
<inspection_tool class="CallToStringConcatCanBeReplacedByOperator" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="ClassName" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="CodotaLocalLearning" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
<inspection_tool class="ConditionalExpressionWithIdenticalBranches" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="ConnectionResource" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="ConstPropertyName" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="ConstantConditions" enabled="false" level="WARNING" enabled_by_default="false">
<option name="SUGGEST_NULLABLE_ANNOTATIONS" value="false" />
<option name="DONT_REPORT_TRUE_ASSERT_STATEMENTS" value="false" />
</inspection_tool>
<inspection_tool class="DeprecatedIsStillUsed" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
<inspection_tool class="Deprecation" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
<inspection_tool class="EnumEntryName" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="FunctionName" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="IOResource" enabled="true" level="WARNING" enabled_by_default="true">
<option name="ignoredTypesString" value="java.io.ByteArrayOutputStream,java.io.ByteArrayInputStream,java.io.StringBufferInputStream,java.io.CharArrayWriter,java.io.CharArrayReader,java.io.StringWriter,java.io.StringReader" />
<option name="insideTryAllowed" value="false" />
</inspection_tool>
<inspection_tool class="IgnoreResultOfCall" enabled="false" level="WARNING" enabled_by_default="false">
<option name="m_reportAllNonLibraryCalls" value="false" />
<option name="callCheckString" value="java.io.File,.*,java.io.InputStream,read|skip|available|markSupported,java.io.Reader,read|skip|ready|markSupported,java.lang.Boolean,.*,java.lang.Byte,.*,java.lang.Character,.*,java.lang.Double,.*,java.lang.Float,.*,java.lang.Integer,.*,java.lang.Long,.*,java.lang.Math,.*,java.lang.Object,equals|hashCode|toString,java.lang.Short,.*,java.lang.StrictMath,.*,java.lang.String,.*,java.lang.Thread,interrupted,java.math.BigInteger,.*,java.math.BigDecimal,.*,java.net.InetAddress,.*,java.net.URI,.*,java.util.Arrays,.*,java.util.List,of,java.util.Set,of,java.util.Map,of|ofEntries|entry,java.util.Collections,(?!addAll).*,java.util.UUID,.*,java.util.regex.Matcher,pattern|toMatchResult|start|end|group|groupCount|matches|find|lookingAt|quoteReplacement|replaceAll|replaceFirst|regionStart|regionEnd|hasTransparentBounds|hasAnchoringBounds|hitEnd|requireEnd,java.util.regex.Pattern,.*,java.util.stream.BaseStream,.*" />
</inspection_tool>
<inspection_tool class="InconsistentLineSeparators" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="KeySetIterationMayUseEntrySet" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="LengthOneStringInIndexOf" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="LocalVariableName" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="MapReplaceableByEnumMap" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="MultiplyOrDivideByPowerOfTwo" enabled="true" level="WEAK WARNING" enabled_by_default="true">
<option name="checkDivision" value="false" />
</inspection_tool>
<inspection_tool class="NegatedConditionalExpression" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="NotNullFieldNotInitialized" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
<inspection_tool class="NullableProblems" enabled="true" level="WEAK WARNING" enabled_by_default="true">
<option name="REPORT_NULLABLE_METHOD_OVERRIDES_NOTNULL" value="true" />
<option name="REPORT_NOT_ANNOTATED_METHOD_OVERRIDES_NOTNULL" value="true" />
<option name="REPORT_NOTNULL_PARAMETER_OVERRIDES_NULLABLE" value="true" />
<option name="REPORT_NOT_ANNOTATED_PARAMETER_OVERRIDES_NOTNULL" value="true" />
<option name="REPORT_NOT_ANNOTATED_GETTER" value="true" />
<option name="REPORT_NOT_ANNOTATED_SETTER_PARAMETER" value="true" />
<option name="REPORT_ANNOTATION_NOT_PROPAGATED_TO_OVERRIDERS" value="true" />
<option name="REPORT_NULLS_PASSED_TO_NON_ANNOTATED_METHOD" value="true" />
</inspection_tool>
<inspection_tool class="ObjectAllocationInLoop" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
<inspection_tool class="ObjectPropertyName" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="PackageName" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="PointlessIndexOfComparison" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="PrivatePropertyName" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="PropertyName" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="RandomDoubleForRandomInteger" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="RecordStoreResource" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="RedundantInnerClassModifier" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
<inspection_tool class="SetReplaceableByEnumSet" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="SimplifiableAnnotation" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="SimplifiableEqualsExpression" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="SizeReplaceableByIsEmpty" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="SleepWhileHoldingLock" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="SocketResource" enabled="true" level="WARNING" enabled_by_default="true">
<option name="insideTryAllowed" value="false" />
</inspection_tool>
<inspection_tool class="StringBufferToStringInConcatenation" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="StringEqualsEmptyString" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="StringReplaceableByStringBuffer" enabled="true" level="WARNING" enabled_by_default="true">
<option name="onlyWarnOnLoop" value="true" />
</inspection_tool>
<inspection_tool class="TestFunctionName" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="ThreadStopSuspendResume" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="TodoComment" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="UnnecessaryConstantArrayCreationExpression" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="UnnecessaryConstructor" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="UnnecessaryFinalOnLocalVariableOrParameter" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="UnnecessarySuperConstructor" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="UnnecessarySuperQualifier" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="UnnecessaryThis" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="UnqualifiedInnerClassAccess" enabled="true" level="WARNING" enabled_by_default="true">
<option name="ignoreReferencesToLocalInnerClasses" value="true" />
</inspection_tool>
<inspection_tool class="UnsecureRandomNumberGeneration" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
<inspection_tool class="ZeroLengthArrayInitialization" enabled="true" level="WARNING" enabled_by_default="true" />
</profile>
</component>
-30
View File
@@ -1,30 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RemoteRepositoriesConfiguration">
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Central Repository" />
<option name="url" value="https://repo.maven.apache.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="spigot-repo" />
<option name="name" value="spigot-repo" />
<option name="url" value="https://hub.spigotmc.org/nexus/content/repositories/snapshots/" />
</remote-repository>
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Maven Central repository" />
<option name="url" value="https://repo1.maven.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="placeholderapi" />
<option name="name" value="placeholderapi" />
<option name="url" value="https://repo.extendedclip.com/content/repositories/placeholderapi/" />
</remote-repository>
<remote-repository>
<option name="id" value="jboss.community" />
<option name="name" value="JBoss Community repository" />
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
</remote-repository>
</component>
</project>
@@ -1,13 +0,0 @@
<component name="libraryTable">
<library name="Maven: com.google.code.gson:gson:2.8.7">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/com/google/code/gson/gson/2.8.7/gson-2.8.7.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/com/google/code/gson/gson/2.8.7/gson-2.8.7-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/com/google/code/gson/gson/2.8.7/gson-2.8.7-sources.jar!/" />
</SOURCES>
</library>
</component>
-13
View File
@@ -1,13 +0,0 @@
<component name="libraryTable">
<library name="Maven: com.google.guava:guava:21.0">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/com/google/guava/guava/21.0/guava-21.0.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/com/google/guava/guava/21.0/guava-21.0-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/com/google/guava/guava/21.0/guava-21.0-sources.jar!/" />
</SOURCES>
</library>
</component>
-13
View File
@@ -1,13 +0,0 @@
<component name="libraryTable">
<library name="Maven: commons-lang:commons-lang:2.6">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/commons-lang/commons-lang/2.6/commons-lang-2.6.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/commons-lang/commons-lang/2.6/commons-lang-2.6-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/commons-lang/commons-lang/2.6/commons-lang-2.6-sources.jar!/" />
</SOURCES>
</library>
</component>
-13
View File
@@ -1,13 +0,0 @@
<component name="libraryTable">
<library name="Maven: me.clip:placeholderapi:2.10.9">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/me/clip/placeholderapi/2.10.9/placeholderapi-2.10.9.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/me/clip/placeholderapi/2.10.9/placeholderapi-2.10.9-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/me/clip/placeholderapi/2.10.9/placeholderapi-2.10.9-sources.jar!/" />
</SOURCES>
</library>
</component>
@@ -1,13 +0,0 @@
<component name="libraryTable">
<library name="Maven: net.md-5:bungeecord-chat:1.16-R0.4">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/net/md-5/bungeecord-chat/1.16-R0.4/bungeecord-chat-1.16-R0.4.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/net/md-5/bungeecord-chat/1.16-R0.4/bungeecord-chat-1.16-R0.4-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/net/md-5/bungeecord-chat/1.16-R0.4/bungeecord-chat-1.16-R0.4-sources.jar!/" />
</SOURCES>
</library>
</component>
@@ -1,13 +0,0 @@
<component name="libraryTable">
<library name="Maven: org.jetbrains:annotations:19.0.0">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/annotations/19.0.0/annotations-19.0.0.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/annotations/19.0.0/annotations-19.0.0-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/annotations/19.0.0/annotations-19.0.0-sources.jar!/" />
</SOURCES>
</library>
</component>
@@ -1,13 +0,0 @@
<component name="libraryTable">
<library name="Maven: org.spigotmc:spigot-api:1.17-R0.1-SNAPSHOT">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/org/spigotmc/spigot-api/1.17-R0.1-SNAPSHOT/spigot-api-1.17-R0.1-20210616.003322-46.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/org/spigotmc/spigot-api/1.17-R0.1-SNAPSHOT/spigot-api-1.17-R0.1-20210616.003322-46-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/org/spigotmc/spigot-api/1.17-R0.1-SNAPSHOT/spigot-api-1.17-R0.1-20210616.003322-46-sources.jar!/" />
</SOURCES>
</library>
</component>
-13
View File
@@ -1,13 +0,0 @@
<component name="libraryTable">
<library name="Maven: org.yaml:snakeyaml:1.28">
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/org/yaml/snakeyaml/1.28/snakeyaml-1.28.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://$MAVEN_REPOSITORY$/org/yaml/snakeyaml/1.28/snakeyaml-1.28-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/org/yaml/snakeyaml/1.28/snakeyaml-1.28-sources.jar!/" />
</SOURCES>
</library>
</component>
-18
View File
@@ -1,18 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="EntryPointsManager">
<list size="1">
<item index="0" class="java.lang.String" itemvalue="org.bukkit.event.EventHandler" />
</list>
</component>
<component name="MavenProjectsManager">
<option name="originalFiles">
<list>
<option value="$PROJECT_DIR$/pom.xml" />
</list>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>
-8
View File
@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/PlayTimes.iml" filepath="$PROJECT_DIR$/PlayTimes.iml" />
</modules>
</component>
</project>
-124
View File
@@ -1,124 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Palette2">
<group name="Swing">
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
</item>
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
</item>
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.png" removable="false" auto-create-binding="false" can-attach-label="true">
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
</item>
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
<initial-values>
<property name="text" value="Button" />
</initial-values>
</item>
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="RadioButton" />
</initial-values>
</item>
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="CheckBox" />
</initial-values>
</item>
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
<initial-values>
<property name="text" value="Label" />
</initial-values>
</item>
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
</item>
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
</item>
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
<preferred-size width="-1" height="20" />
</default-constraints>
</item>
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
</item>
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
</item>
</group>
</component>
</project>
Generated
-6
View File
@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>
+1 -1
View File
@@ -652,7 +652,7 @@ Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
PlayTimes Copyright (C) 2021 CodedRed
PlayTimes Copyright (C) 2023 CodedRed
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
-31
View File
@@ -1,31 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="minecraft" name="Minecraft">
<configuration>
<autoDetectTypes>
<platformType>SPIGOT</platformType>
</autoDetectTypes>
</configuration>
</facet>
</component>
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
<output url="file://$MODULE_DIR$/target/classes" />
<output-test url="file://$MODULE_DIR$/target/test-classes" />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.spigotmc:spigot-api:1.17-R0.1-SNAPSHOT" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: commons-lang:commons-lang:2.6" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: com.google.guava:guava:21.0" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: net.md-5:bungeecord-chat:1.16-R0.4" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.yaml:snakeyaml:1.28" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: me.clip:placeholderapi:2.10.9" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Maven: org.jetbrains:annotations:19.0.0" level="project" />
<orderEntry type="library" name="Maven: com.google.code.gson:gson:2.8.8" level="project" />
</component>
</module>
+27 -103
View File
@@ -1,97 +1,40 @@
# PlayTimes
> The best /playtime plugin! PAPI support, offline checks, API & more!
[![Downloads][downloads-shield]][downloads-url]
[![Bstatsp][bstatsp-shield]][bstatsp-url]
[![Bstatss][bstatss-shield]][bstatss-url]
[![Bstats Players][bstatsp-shield]][bstatsp-url]
[![Bstats Servers][bstatss-shield]][bstatss-url]
[![Issues][issues-shield]][issues-url]
[![GNU License][license-shield]][license-url]
<!-- PROJECT LOGO -->
<br />
<p align="center">
<a href="https://github.com/CodedRed-Spigot/PlayTimes">
<img src="logo.png" alt="Logo" width="750" height="500">
<img src="logo.png" alt="PlayTimes logo" width="750" height="500">
</a>
<h3 align="center">PlayTimes</h3>
<p align="center">
The best /playtime plugin! PAPI support, offline checks, API & more!
<br />
<a href="https://github.com/CodedRed-Spigot/PlayTimes/wiki"><strong>Explore the docs »</strong></a>
<br />
<br />
<a href="https://www.spigotmc.org/resources/playtimes-check-players-playtime-server-uptime.58858/">View Demo</a>
·
<a href="https://github.com/CodedRed-Spigot/PlayTimes/issues">Report Bug</a>
·
<a href="https://github.com/CodedRed-Spigot/PlayTimes/issues">Request Feature</a>
</p>
</p>
## Table of Contents
- [About The Project](#about-the-project)
- [Usage](#usage)
- [Roadmap](#roadmap)
- [Contributing](#contributing)
- [License](#license)
- [Contact](#contact)
<!-- TABLE OF CONTENTS -->
<details open="open">
<summary><h2 style="display: inline-block">Table of Contents</h2></summary>
<ol>
<li>
<a href="#about-the-project">About The Project</a>
</li>
<!-- <li>
<a href="#getting-started">Getting Started</a>
<ul>
<li><a href="#prerequisites">Prerequisites</a></li>
<li><a href="#installation">Installation</a></li>
</ul>
</li> -->
<li><a href="#usage">Usage</a></li>
<li><a href="#roadmap">Roadmap</a></li>
<li><a href="#contributing">Contributing</a></li>
<li><a href="#license">License</a></li>
<li><a href="#contact">Contact</a></li>
</ol>
</details>
<!-- ABOUT THE PROJECT -->
## About The Project
PlayTimes is the perfect plugin for your server! Have players show off and compete for more time played with playtime's leaderboards! Not only can you check online/offline players playtime you can also check the uptime of the server! There is a lot coming to playtime such as PlayTime Rewards, PlayTime Ranks & PlayTime Shop!
PlayTimes is your ideal plugin for gamified competition! It enables players to compete for the most time played, with leaderboards for showing off achievements. Beyond player time, you can also monitor server uptime. Future plans include introducing PlayTime Rewards, Ranks, and Shop! Start using PlayTimes today to add an exciting dimension to your server.
<!-- GETTING STARTED
## Getting Started -->
<!-- To get a local copy up and running follow these simple steps. -->
<!-- USAGE EXAMPLES -->
## Usage
Check out the Wiki!
[Documentation](https://github.com/CodedRed-Spigot/PlayTimes/wiki)
For detailed instructions and examples on how to use the plugin, refer to our comprehensive [Documentation](https://github.com/CodedRed-Spigot/PlayTimes/wiki).
<!-- ROADMAP -->
## Roadmap
See the [open issues](https://github.com/CodedRed-Spigot/PlayTimes/issues) for a list of proposed features (and known issues).
Check out the [open issues](https://github.com/CodedRed-Spigot/PlayTimes/issues) for a list of proposed features and known bugs.
<!-- CONTRIBUTING -->
## Contributing
Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are **greatly appreciated**.
Contributions are the lifeblood of the open source community. We appreciate and welcome any contributions you can make. Here's how you can contribute:
1. Fork the Project
2. Create your Feature Branch (`git checkout -b feature/AwesomeFeature`)
@@ -99,47 +42,28 @@ Contributions are what make the open source community such an amazing place to b
4. Push to the Branch (`git push origin feature/AwesomeFeature`)
5. Open a Pull Request
<!-- LICENSE -->
## License
Distributed under the GNU General Public License v3.0. See `LICENSE` for more information.
PlayTimes is distributed under the GNU General Public License v3.0. See `LICENSE` for more information.
<!-- CONTACT -->
## Contact
CodedRed - [@twitter](https://twitter.com/devcodedred) - devcodedred@gmail.com
[@spigotmc](https://www.spigotmc.org/resources/authors/codedred.421005/)
Discord: CodedRed#0900
Project Link: [https://github.com/CodedRed-Spigot/PlayTimes](https://github.com/CodedRed-Spigot/PlayTimes)
You can reach out to us using the following platforms:
- Twitter: [@twitter](https://twitter.com/devcodedred)
- Email: devcodedred@gmail.com
- SpigotMC: [@spigotmc](https://www.spigotmc.org/resources/authors/codedred.421005/)
- Discord: .CodedRed
Find the project on GitHub: [https://github.com/CodedRed-Spigot/PlayTimes](https://github.com/CodedRed-Spigot/PlayTimes)
<!-- MARKDOWN LINKS & IMAGES -->
<!-- https://www.markdownguide.org/basic-syntax/#reference-style-links -->
[contributors-shield]: https://img.shields.io/github/contributors/CodedRed-Spigot/PlayTimes.svg?style=for-the-badge
[contributors-url]: https://github.com/CodedRed-Spigot/PlayTimes/graphs/contributors
[downloads-shield]: https://img.shields.io/spiget/downloads/58858?style=for-the-badge
[downloads-url]: https://www.spigotmc.org/resources/playtimes-check-players-playtime-server-uptime.58858/
[bstatsp-shield]: https://img.shields.io/bstats/players/5289?style=for-the-badge
[bstatsp-url]: https://bstats.org/plugin/bukkit/PlayTimes/5289
[bstatss-shield]: https://img.shields.io/bstats/servers/5289?color=orange&style=for-the-badge
[bstatss-url]: https://bstats.org/plugin/bukkit/PlayTimes/5289
[stars-shield]: https://img.shields.io/github/stars/CodedRed-Spigot/PlayTimes.svg?style=for-the-badge
[stars-url]: https://github.com/CodedRed-Spigot/PlayTimes/stargazers
[downloads-shield]: https://img.shields.io/spiget/downloads/58858?style=for-the-badge
[downloads-url]: https://www.spigotmc.org/resources/playtimes-check-players-playtime-server-uptime.58858/
[issues-shield]: https://img.shields.io/github/issues/CodedRed-Spigot/PlayTimes.svg?style=for-the-badge
[issues-url]: https://github.com/CodedRed-Spigot/PlayTimes/issues
[license-shield]: https://img.shields.io/github/license/CodedRed-Spigot/PlayTimes.svg?style=for-the-badge
[license-url]: https://github.com/CodedRed-Spigot/PlayTimes/blob/main/LICENSE
[site-url]: https://www.spigotmc.org/resources/playtimes-check-players-playtime-server-uptime.58858/
[license-shield]: https://img.shields.io/github/license/CodedRed-Spigot/PlayTimes.svg?
+58
View File
@@ -0,0 +1,58 @@
plugins {
id 'java'
id 'dev.codedred.craftengine' version '1.0.0'
}
group = 'dev.codedred'
version = '1.5'
repositories {
mavenLocal()
gradlePluginPortal()
maven {
name = 'spigotmc-repo'
url = 'https://hub.spigotmc.org/nexus/content/repositories/snapshots/'
}
maven {
name = 'sonatype'
url = 'https://oss.sonatype.org/content/groups/public/'
}
maven {
url = 'https://repo.extendedclip.com/content/repositories/placeholderapi/'
}
}
dependencies {
implementation 'org.jetbrains:annotations:23.0.0'
compileOnly 'org.spigotmc:spigot-api:1.19.3-R0.1-SNAPSHOT'
compileOnly 'me.clip:placeholderapi:2.10.9'
}
def targetJavaVersion = 17
java {
def javaVersion = JavaVersion.toVersion(targetJavaVersion)
sourceCompatibility = javaVersion
targetCompatibility = javaVersion
if (JavaVersion.current() < javaVersion) {
toolchain.languageVersion = JavaLanguageVersion.of(targetJavaVersion)
}
}
tasks.withType(JavaCompile).configureEach {
if (targetJavaVersion >= 10 || JavaVersion.current().isJava10Compatible()) {
options.release = targetJavaVersion
}
}
processResources {
def props = [version: version]
inputs.properties props
filteringCharset 'UTF-8'
filesMatching('plugin.yml') {
expand props
}
}
View File
Whitespace-only changes.
Binary file not shown.
+5
View File
@@ -0,0 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Vendored
+234
View File
@@ -0,0 +1,234 @@
#!/bin/sh
#
# Copyright © 2015-2021 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
#
# Gradle start up script for POSIX generated by Gradle.
#
# Important for running:
#
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
# noncompliant, but you have some other compliant shell such as ksh or
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
# ksh Gradle
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#
# (2) This script targets any POSIX shell, so it avoids extensions provided
# by Bash, Ksh, etc; in particular arrays are avoided.
#
# The "traditional" practice of packing multiple parameters into a
# space-separated string is a well documented source of bugs and security
# problems, so this is (mostly) avoided, by progressively accumulating
# options in "$@", and eventually passing that to Java.
#
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
# see the in-line comments for details.
#
# There are tweaks for specific operating systems such as AIX, CygWin,
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
#
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
app_path=$0
# Need this for daisy-chained symlinks.
while
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
[ -h "$app_path" ]
do
ls=$( ls -ld "$app_path" )
link=${ls#*' -> '}
case $link in #(
/*) app_path=$link ;; #(
*) app_path=$APP_HOME$link ;;
esac
done
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
APP_NAME="Gradle"
APP_BASE_NAME=${0##*/}
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
warn () {
echo "$*"
} >&2
die () {
echo
echo "$*"
echo
exit 1
} >&2
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "$( uname )" in #(
CYGWIN* ) cygwin=true ;; #(
Darwin* ) darwin=true ;; #(
MSYS* | MINGW* ) msys=true ;; #(
NONSTOP* ) nonstop=true ;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD=$JAVA_HOME/jre/sh/java
else
JAVACMD=$JAVA_HOME/bin/java
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD=java
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
fi
# Collect all arguments for the java command, stacking in reverse order:
# * args from the command line
# * the main class name
# * -classpath
# * -D...appname settings
# * --module-path (only if needed)
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
# For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
JAVACMD=$( cygpath --unix "$JAVACMD" )
# Now convert the arguments - kludge to limit ourselves to /bin/sh
for arg do
if
case $arg in #(
-*) false ;; # don't mess with options #(
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
[ -e "$t" ] ;; #(
*) false ;;
esac
then
arg=$( cygpath --path --ignore --mixed "$arg" )
fi
# Roll the args list around exactly as many times as the number of
# args, so each arg winds up back in the position where it started, but
# possibly modified.
#
# NB: a `for` loop captures its iteration list before it begins, so
# changing the positional parameters here affects neither the number of
# iterations, nor the values presented in `arg`.
shift # remove old arg
set -- "$@" "$arg" # push replacement arg
done
fi
# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# shell script including quotes and variable substitutions, so put them in
# double quotes to make sure that they get re-expanded; and
# * put everything else in single quotes, so that it's not re-expanded.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain \
"$@"
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
#
# In Bash we could simply go:
#
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
# set -- "${ARGS[@]}" "$@"
#
# but POSIX shell has neither arrays nor command substitution, so instead we
# post-process each arg (as a line of input to sed) to backslash-escape any
# character that might be a shell metacharacter, then use eval to reverse
# that process (while maintaining the separation between arguments), and wrap
# the whole thing up as a single "set" statement.
#
# This will of course break if any of these variables contains a newline or
# an unmatched quote.
#
eval "set -- $(
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
xargs -n1 |
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
tr '\n' ' '
)" '"$@"'
exec "$JAVACMD" "$@"
Vendored
+89
View File
@@ -0,0 +1,89 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
-88
View File
@@ -1,88 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>groupId</groupId>
<artifactId>PlayTimes</artifactId>
<version>1.4.5</version>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<outputFile>C:\Users\chris\OneDrive\Desktop\Spigot\Servers\Spigot 1.17\plugins\PlayTimes.jar</outputFile>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
<repositories>
<!-- This adds the Spigot Maven repository to the build -->
<repository>
<id>spigot-repo</id>
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
</repository>
<repository>
<id>placeholderapi</id>
<url>https://repo.extendedclip.com/content/repositories/placeholderapi/</url>
</repository>
</repositories>
<dependencies>
<!--This adds the Spigot API artifact to the build -->
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.17-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>me.clip</groupId>
<artifactId>placeholderapi</artifactId>
<version>2.10.9</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.8</version>
</dependency>
</dependencies>
</project>
+8
View File
@@ -0,0 +1,8 @@
pluginManagement {
repositories {
mavenLocal()
gradlePluginPortal()
}
}
rootProject.name = 'PlayTimes'
@@ -10,150 +10,117 @@ import org.bukkit.ChatColor;
import org.bukkit.OfflinePlayer;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.*;
/**
* This class will automatically register as a placeholder expansion
* when a jar including this class is added to the directory
* {@code /plugins/PlaceholderAPI/expansions} on your server.
* <br>
* <br>If you create such a class inside your own plugin, you have to
* register it manually in your plugins {@code onEnable()} by using
* {@code new YourExpansionClass().register();}
*/
public class Expansions extends PlaceholderExpansion {
/**
* This method should always return true unless we
* have a dependency we need to make sure is on the server
* for our placeholders to work!
*
* @return always true since we do not have any dependencies.
*/
@Override
public boolean canRegister(){
return true;
}
@Override
public boolean canRegister() {
return true;
}
/**
* The name of the person who created this expansion should go here.
*
* @return The name of the author as a String.
*/
@Override
public @NotNull String getAuthor(){
return "Cmaaxx"; // CodedRed
}
@Override
public @NotNull String getAuthor() {
return "CodedRed";
}
/**
* The placeholder identifier should go here.
* <br>This is what tells PlaceholderAPI to call our onRequest
* method to obtain a value if a placeholder starts with our
* identifier.
* <br>This must be unique and can not contain % or _
*
* @return The identifier in {@code %<identifier>_<value>%} as String.
*/
@Override
public @NotNull String getIdentifier(){
return "PlayTimes";
}
@Override
public @NotNull String getIdentifier() {
return "PlayTimes";
}
/**
* This is the version of this expansion.
* <br>You don't have to use numbers, since it is set as a String.
*
* @return The version as a String.
*/
@Override
public @NotNull String getVersion(){
return "1.4.6";
}
@Override
public boolean persist(){
return true;
}
/**
* This is the method called when a placeholder with our identifier
* is found and needs a value.
* <br>We specify the value identifier in this method.
* <br>Since version 2.9.1 can you use OfflinePlayers in your requests.
*
* @param player
* A {@link OfflinePlayer OfflinePlayer}.
* @param identifier
* A String containing the identifier/value.
*
* @return Possibly-null String of the requested identifier.
*/
@Override
@Override
public @NotNull String getVersion() {
return "1.5";
}
@Override
public boolean persist() {
return true;
}
@Override
public String onRequest(OfflinePlayer player, @NotNull String identifier) {
identifier = identifier.toLowerCase();
StatManager stats = StatManager.getInstance();
TimeManager timings = TimeManager.getInstance();
switch (identifier) {
case "playtime":
return timings.buildFormat(stats.getPlayerStat(player.getUniqueId(), StatisticType.PLAYTIME)/20);
return getPlayerPlayTime(player);
case "uptime":
return stats.getUptime();
return StatManager.getInstance().getUptime();
case "joindate":
return stats.getJoinDate(player.getUniqueId());
return StatManager.getInstance().getJoinDate(player.getUniqueId());
default:
return handleLeaderboardIdentifier(identifier);
}
}
// %PlayTimes_topname#%
private String getPlayerPlayTime(OfflinePlayer player) {
StatManager stats = StatManager.getInstance();
TimeManager timeManager = TimeManager.getInstance();
return timeManager.buildFormat(stats.getPlayerStat(player.getUniqueId(), StatisticType.PLAYTIME) / 20);
}
private String handleLeaderboardIdentifier(String identifier) {
if (identifier.contains("topname")) {
Leaderboard board = new Leaderboard();
List<UUID> players = new ArrayList<>();
for (Map.Entry<String, Integer> entry : board.getTopTen().entrySet())
players.add(UUID.fromString(entry.getKey()));
String num = identifier.substring(7);
int val;
if (isInteger(num))
val = (Integer.parseInt(num) < 1) ? 0 : Integer.parseInt(num) - 1;
else
return ChatColor.RED + "Invalid leaderboard position!";
if (players.size() < val + 1)
return "N/A";
OfflinePlayer targetPlayer = Bukkit.getOfflinePlayer(players.get(val));
String name = targetPlayer.getName();
return (players.isEmpty() ? "N/A" : name);
return getLeaderboardPlayerName(identifier);
} else if (identifier.contains("toptime")) {
return getLeaderboardPlayTime(identifier);
}
// %PlayTimes_toptime#%
else if (identifier.contains("toptime")) {
Leaderboard board = new Leaderboard();
List<Integer> players = new ArrayList<>();
for (Map.Entry<String, Integer> entry : board.getTopTen().entrySet())
players.add(entry.getValue());
String num = identifier.substring(7);
int val;
if (isInteger(num))
val = (Integer.parseInt(num) < 1) ? 0 : Integer.parseInt(num) - 1;
else
return ChatColor.RED + "Invalid leaderboard position!";
if (players.size() < val + 1)
return "N/A";
return (players.isEmpty() ? "N/A" : timings.buildFormat(players.get(val)/20));
}
// We return null if an invalid placeholder (f.e. %example_placeholder3%)
// was provided
return null;
}
boolean isInteger(String str) {
private String getLeaderboardPlayerName(String identifier) {
Leaderboard board = new Leaderboard();
int val = parseLeaderboardPosition(identifier);
if (val == -1) {
return ChatColor.RED + "Invalid leaderboard position!";
}
List<UUID> players = getTopPlayersUUID(board);
if (players.size() < val + 1)
return "N/A";
OfflinePlayer targetPlayer = Bukkit.getOfflinePlayer(players.get(val));
return targetPlayer.getName();
}
private String getLeaderboardPlayTime(String identifier) {
Leaderboard board = new Leaderboard();
int val = parseLeaderboardPosition(identifier);
if (val == -1) {
return ChatColor.RED + "Invalid leaderboard position!";
}
List<Integer> players = getTopPlayersPlayTime(board);
if (players.size() < val + 1)
return "N/A";
return TimeManager.getInstance().buildFormat(players.get(val) / 20);
}
private List<UUID> getTopPlayersUUID(Leaderboard board) {
List<UUID> players = new ArrayList<>();
for (Map.Entry<String, Integer> entry : board.getTopTen().entrySet())
players.add(UUID.fromString(entry.getKey()));
return players;
}
private List<Integer> getTopPlayersPlayTime(Leaderboard board) {
List<Integer> players = new ArrayList<>();
for (Map.Entry<String, Integer> entry : board.getTopTen().entrySet())
players.add(entry.getValue());
return players;
}
private int parseLeaderboardPosition(String identifier) {
String num = identifier.substring(7);
if (isInteger(num)) {
return (Integer.parseInt(num) < 1) ? 0 : Integer.parseInt(num) - 1;
}
return -1;
}
private boolean isInteger(String str) {
try {
Integer.parseInt(str);
return true;
@@ -161,25 +128,4 @@ public class Expansions extends PlaceholderExpansion {
return false;
}
}
}
File diff suppressed because it is too large. Load diff
@@ -3,25 +3,24 @@ package me.codedred.playtimes;
import me.codedred.playtimes.commands.Time;
import me.codedred.playtimes.commands.TopTime;
import me.codedred.playtimes.commands.Uptime;
import me.codedred.playtimes.data.Debugger;
import me.codedred.playtimes.commands.completer.TimeTabCompleter;
import me.codedred.playtimes.listeners.Join;
import me.codedred.playtimes.listeners.Quit;
import me.codedred.playtimes.server.ServerManager;
import me.codedred.playtimes.statistics.StatManager;
import me.codedred.playtimes.time.TimeManager;
import me.codedred.playtimes.utils.ChatUtil;
import net.md_5.bungee.api.ChatColor;
import org.bukkit.Bukkit;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin;
import java.io.IOException;
import java.util.Objects;
public class PlayTimes extends JavaPlugin {
@Override
public void onEnable() {
Debugger debug = new Debugger();
debug.execute();
checkForUpdate();
@@ -32,20 +31,20 @@ public class PlayTimes extends JavaPlugin {
if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null) {
Expansions exp = new Expansions();
exp.register();
getServer().getConsoleSender().sendMessage(ChatColor.DARK_PURPLE + "[PlayTimes] " + ChatColor.WHITE + "PlaceholdersAPI Hooked!");
getLogger().info("[PlayTimes] PlaceholdersAPI Hooked!");
}
registerEvents();
registerCommands();
@SuppressWarnings("unused")
Metrics metrics = new Metrics(this);
getServer().getConsoleSender().sendMessage(ChatColor.DARK_PURPLE + "[PlayTimes] " + ChatColor.WHITE + "Successfully loaded.");
Metrics metrics = new Metrics(this, 5289);
getLogger().info("[PlayTimes] Successfully loaded.");
}
@Override
public void onDisable() {
getLogger().info("PlayTimes shutting down");
}
private void registerEvents() {
@@ -55,28 +54,31 @@ public class PlayTimes extends JavaPlugin {
}
private void registerCommands() {
getCommand("playtime").setExecutor(
Objects.requireNonNull(getCommand("playtime")).setExecutor(
new Time());
getCommand("uptime").setExecutor(
Objects.requireNonNull(getCommand("uptime")).setExecutor(
new Uptime());
getCommand("topplaytime").setExecutor(
Objects.requireNonNull(getCommand("topplaytime")).setExecutor(
new TopTime());
Objects.requireNonNull(this.getCommand("pt")).setTabCompleter(new TimeTabCompleter());
}
private void checkForUpdate() {
UpdateChecker updater = new UpdateChecker(this, 58858);
try {
if (updater.checkForUpdates()) {
getServer().getConsoleSender().sendMessage(ChatUtil.format("&eYou are using an older version of PlayTimes!"));
getServer().getConsoleSender().sendMessage(ChatUtil.format("&eDownload the newest version here:"));
getServer().getConsoleSender().sendMessage(ChatUtil.format("&bhttps://www.spigotmc.org/resources/58858/"));
} else {
getServer().getConsoleSender().sendMessage("[PlayTimes] Plugin is up to date! - "
+ getDescription().getVersion());
}
} catch (Exception e) {
getServer().getConsoleSender().sendMessage("[PlayTimes] Could not check for updates!");
}
Bukkit.getScheduler().runTaskAsynchronously(this, () -> {
UpdateChecker updater = new UpdateChecker(this, 58858);
try {
if (!updater.checkForUpdates()) {
getLogger().warning(ChatUtil.format("&eYou are using an older version of PlayTimes!"));
getLogger().info(ChatUtil.format("&eDownload the newest version here:"));
getLogger().info(ChatUtil.format("&bhttps://www.spigotmc.org/resources/58858/"));
} else {
getLogger().info("[PlayTimes] Plugin is up to date! - " + getDescription().getVersion());
}
} catch (IOException e) {
getLogger().warning("[PlayTimes] Could not check for updates!");
}
});
}
@@ -2,50 +2,53 @@ package me.codedred.playtimes;
import org.bukkit.plugin.java.JavaPlugin;
import javax.net.ssl.HttpsURLConnection;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.Objects;
public class UpdateChecker {
private URL checkURL;
private String newVersion;
private static final String UPDATE_URL = "https://api.spigotmc.org/legacy/update.php?resource=%d";
private final JavaPlugin plugin;
private final int projectId;
private String cachedVersion;
public UpdateChecker(JavaPlugin plugin, int projectID) {
this.plugin = plugin;
newVersion = plugin.getDescription().getVersion();
try {
checkURL = new URL(
"https://api.spigotmc.org/legacy/update.php?resource=" + projectID);
} catch (MalformedURLException e) {
//e.printStackTrace();
public UpdateChecker(JavaPlugin plugin, int projectId) {
this.plugin = Objects.requireNonNull(plugin, "Plugin cannot be null.");
this.projectId = projectId;
this.cachedVersion = plugin.getDescription().getVersion();
}
public boolean checkForUpdates() throws IOException {
String latestVersion = getCachedVersion();
if (latestVersion == null) {
URL url = new URL(String.format(UPDATE_URL, projectId));
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(5000);
connection.setReadTimeout(5000);
connection.setUseCaches(true);
latestVersion = new BufferedReader(new InputStreamReader(connection.getInputStream()))
.readLine();
if (latestVersion == null || latestVersion.isEmpty()) {
throw new IOException("Failed to retrieve latest version.");
}
cachedVersion = latestVersion;
}
return !plugin.getDescription().getVersion().equals(cachedVersion);
}
/*public int getProjectID() {
return project;
public String getCachedVersion() {
return cachedVersion;
}
public JavaPlugin getPlugin() {
return plugin;
}
public String getLatestVersion() {
return newVersion;
}
public String getResourceURL() {
return "https://www.spigotmc.org/resources/" + project;
}*/
public boolean checkForUpdates() throws Exception {
URLConnection con = checkURL.openConnection();
newVersion = new BufferedReader(new InputStreamReader(con.getInputStream()))
.readLine();
return !plugin.getDescription().getVersion().equals(newVersion);
}
}
}
@@ -1,42 +0,0 @@
package me.codedred.playtimes.api;
import me.codedred.playtimes.statistics.StatManager;
import me.codedred.playtimes.statistics.StatisticType;
import me.codedred.playtimes.time.TimeManager;
import org.bukkit.entity.Player;
import java.util.UUID;
public class TimelessPlayer {
private final Player player;
private final UUID uuid;
private final StatManager stats;
private final TimeManager timings;
public TimelessPlayer(Player player) {
this.player = player;
this.uuid = player.getUniqueId();
stats = StatManager.getInstance();
timings = TimeManager.getInstance();
}
public TimelessPlayer(UUID player) {
this.uuid = player;
this.player = null;
stats = StatManager.getInstance();
timings = TimeManager.getInstance();
}
public String getPlayTime() {
return timings.buildFormat(stats.getPlayerStat(uuid, StatisticType.PLAYTIME)/20);
}
public long getRawPlayTimeInSeconds() {
return stats.getPlayerStat(uuid, StatisticType.PLAYTIME)/20;
}
}
@@ -1,87 +0,0 @@
package me.codedred.playtimes.api;
import me.codedred.playtimes.models.Leaderboard;
import me.codedred.playtimes.statistics.StatManager;
import java.lang.management.ManagementFactory;
import java.util.*;
import java.util.concurrent.TimeUnit;
public class TimelessServer {
public List<UUID> getTop10Players() {
List<UUID> players = new ArrayList<>();
Leaderboard board = new Leaderboard();
Map<String, Integer> map = board.getTopTen();
Object[] array = map.keySet().toArray();
for (int i = 0; i < map.size(); i++)
players.add(UUID.fromString(array[i].toString()));
return players;
}
public List<Integer> getTop10Times() {
List<Integer> players = new ArrayList<>();
Leaderboard board = new Leaderboard();
Map<String, Integer> map = board.getTopTen();
Object[] array = map.values().toArray();
for (int i = 0; i < map.size(); i++)
players.add(Integer.parseInt(array[i].toString())/20);
return players;
}
public Map<String, Integer> getTopMap() {
Leaderboard board = new Leaderboard();
return board.getTopTen();
}
public UUID getNumberOne() {
return getTop10Players().get(0);
}
public UUID getNumberTwo() {
return getTop10Players().get(1);
}
public UUID getNumberThree() {
return getTop10Players().get(2);
}
public UUID getNumberFour() {
return getTop10Players().get(3);
}
public UUID getNumberFive() {
return getTop10Players().get(4);
}
public UUID getNumberSix() {
return getTop10Players().get(5);
}
public UUID getNumberSeven() {
return getTop10Players().get(6);
}
public UUID getNumberEight() {
return getTop10Players().get(7);
}
public UUID getNumberNine() {
return getTop10Players().get(8);
}
public UUID getNumberTen() {
return getTop10Players().get(9);
}
public String getUptime() {
return StatManager.getInstance().getUptime();
}
public long getUptimeInSeconds() {
return TimeUnit.MILLISECONDS.toSeconds(ManagementFactory.getRuntimeMXBean().getUptime());
}
}
@@ -2,197 +2,178 @@ package me.codedred.playtimes.commands;
import me.codedred.playtimes.PlayTimes;
import me.codedred.playtimes.data.DataManager;
import me.codedred.playtimes.data.Debugger;
import me.codedred.playtimes.player.OfflinePlayer;
import me.codedred.playtimes.player.OnlinePlayer;
import me.codedred.playtimes.server.ServerManager;
import me.codedred.playtimes.statistics.StatManager;
import me.codedred.playtimes.time.TimeConstants;
import me.codedred.playtimes.time.TimeManager;
import me.codedred.playtimes.utils.ChatUtil;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import me.codedred.playtimes.player.OnlinePlayer;
import me.codedred.playtimes.player.OfflinePlayer;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitRunnable;
import org.jetbrains.annotations.NotNull;
import java.util.Objects;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Time implements CommandExecutor {
public boolean onCommand(CommandSender sender, @NotNull Command cmd, @NotNull String label, String[] args) {
DataManager data = DataManager.getInstance();
if (!sender.hasPermission("pt.use")) {
ChatUtil.errno(sender, ChatUtil.ChatTypes.NO_PERMISSION);
return true;
}
// command -> /playtimes [0 arguments]
if (args.length == 0) {
if (!(sender instanceof Player)) {
StatManager stats = StatManager.getInstance();
sender.sendMessage(ChatUtil.format("&cThe console has been up for " + stats.getUptime()));
return true;
}
OnlinePlayer player = new OnlinePlayer((Player) sender);
player.sendMessageToTarget();
return true;
}
private final DataManager data = DataManager.getInstance();
public boolean onCommand(CommandSender sender, @NotNull Command cmd, @NotNull String label, String[] args) {
if (!sender.hasPermission("pt.use")) {
ChatUtil.errno(sender, ChatUtil.ChatTypes.NO_PERMISSION);
return true;
}
switch (args.length > 0 ? args[0].toLowerCase() : "") {
case "" -> handlePlayerCommand(sender);
case "reload" -> handleReloadCommand(sender);
case "top" -> handleTopCommand(sender);
case "block" -> handleBlockCommand(sender, args, true);
case "unblock" -> handleBlockCommand(sender, args, false);
case "debug" -> handleDebugCommand(sender);
case "help" -> handleHelpCommand(sender);
default -> handleOtherPlayerCommand(sender, args);
}
return true;
}
private void handleHelpCommand(CommandSender sender) {
if (!sender.hasPermission("pt.reload")) {
ChatUtil.errno(sender, ChatUtil.ChatTypes.NO_PERMISSION);
return;
}
// assuming the main command is "pt"
sender.sendMessage(ChatUtil.format("&6&l*** PlayTimes Help ***"));
sender.sendMessage(ChatUtil.format("&e/pt: &7Displays your play time"));
sender.sendMessage(ChatUtil.format("&e/pt reload: &7Reloads the PlayTimes plugin configurations"));
sender.sendMessage(ChatUtil.format("&e/pt top: &7Shows the top players by play time"));
sender.sendMessage(ChatUtil.format("&e/pt block <player>: &7Blocks a player from leaderboards"));
sender.sendMessage(ChatUtil.format("&e/pt unblock <player>: &7Unblocks a player from leaderboards"));
sender.sendMessage(ChatUtil.format("&e/pt debug: &7Displays the debug info"));
sender.sendMessage(ChatUtil.format("&e/pt <player>: &7Displays the play time of <player>"));
}
// command -> /playtimes reload
if (args[0].equalsIgnoreCase("reload")) {
if (!sender.hasPermission("pt.reload")) {
ChatUtil.errno(sender, ChatUtil.ChatTypes.NO_PERMISSION);
return true;
}
Debugger debug = new Debugger();
debug.execute();
data.reloadAll();
TimeManager.getInstance().registerTimings();
sender.sendMessage(ChatUtil.format("&9&lPlayTime Configurations Reloaded!"));
return true;
}
private void handleDebugCommand(CommandSender sender) {
if (!sender.hasPermission("pt.reload")) {
ChatUtil.errno(sender, ChatUtil.ChatTypes.NO_PERMISSION);
return;
}
boolean isOnline = ServerManager.getInstance().isOnline();
String serverStatus = isOnline ? "Online" : "Offline";
sender.sendMessage(ChatUtil.format("&6&l*** PlayTimes Debug ***"));
sender.sendMessage(ChatColor.GOLD + "Server version: " + ChatColor.WHITE + Bukkit.getServer().getVersion() +
ChatColor.GOLD + "\nPlayTimes version: " + ChatColor.WHITE + JavaPlugin.getPlugin(PlayTimes.class).getDescription().getVersion() +
ChatColor.GOLD + "\nStatManager: " + ChatColor.WHITE + StatManager.getInstance().name +
ChatColor.GOLD + "\nServerStatus: " + ChatColor.WHITE + serverStatus);
}
private void handlePlayerCommand(CommandSender sender) {
if (!(sender instanceof Player)) {
StatManager stats = StatManager.getInstance();
sender.sendMessage(ChatUtil.format("&cThe console has been up for " + stats.getUptime()));
return;
}
OnlinePlayer player = new OnlinePlayer((Player) sender);
player.sendMessageToTarget();
}
private void handleReloadCommand(CommandSender sender) {
if (!sender.hasPermission("pt.reload")) {
ChatUtil.errno(sender, ChatUtil.ChatTypes.NO_PERMISSION);
return;
}
data.reloadAll();
TimeConstants.reload();
TimeManager.getInstance().registerTimings();
sender.sendMessage(ChatUtil.format("&aPlayTimes Configurations Reloaded!"));
}
// command -> /playtimes top
else if (args[0].equalsIgnoreCase("top")) {
Bukkit.dispatchCommand(sender, "toppt");
return true;
}
private void handleTopCommand(CommandSender sender) {
Bukkit.dispatchCommand(sender, "toppt");
}
private void handleBlockCommand(CommandSender sender, String[] args, boolean block) {
String blockAction = block ? "block" : "unblock";
if (!sender.hasPermission("pt.block")) {
ChatUtil.errno(sender, ChatUtil.ChatTypes.NO_PERMISSION);
return;
}
if (args.length < 2) {
sender.sendMessage(ChatUtil.formatWithPrefix("&c&lIncorrect Usage&c, try &7/pt " + blockAction + " <player>"));
return;
}
String playerName = args[1];
String blockedKey = "blocked." + playerName.toLowerCase();
if (block == data.getData().contains(blockedKey)) {
sender.sendMessage(ChatUtil.formatWithPrefix("&cUser is already " + blockAction + "ed!"));
sender.sendMessage(ChatUtil.formatWithPrefix("&c&oMaybe try, &7/pt " + (block ? "unblock" : "block") + " <player>"));
return;
}
UUID uuid;
if (Bukkit.getPlayer(playerName) == null) {
try {
uuid = ServerManager.getInstance().getUUID(playerName.toLowerCase());
} catch (NullPointerException e) {
ChatUtil.errno(sender, ChatUtil.ChatTypes.PLAYER_NOT_FOUND);
return;
}
} else {
uuid = Objects.requireNonNull(Bukkit.getPlayer(playerName)).getUniqueId();
}
if (block) {
data.getData().set(blockedKey, uuid.toString());
if (data.getData().contains("leaderboard." + uuid)) {
data.getData().set("leaderboard." + uuid, null);
}
sender.sendMessage(ChatUtil.formatWithPrefix("&aUser &c&lBLOCKED &afrom leaderboards!"));
} else {
data.getData().set(blockedKey, null);
sender.sendMessage(ChatUtil.formatWithPrefix("&aUser &b&lUNBLOCKED &afrom leaderboards!"));
}
data.saveData();
}
private void handleOtherPlayerCommand(CommandSender sender, String[] args) {
new BukkitRunnable() {
@Override
public void run() {
Pattern p = Pattern.compile("[^a-z0-9_]", Pattern.CASE_INSENSITIVE);
Matcher m = p.matcher(args[0]);
boolean b = m.find();
// command -> /playtimes block <player>
else if (args[0].equalsIgnoreCase("block")) {
if (!sender.hasPermission("pt.block")) {
ChatUtil.errno(sender, ChatUtil.ChatTypes.NO_PERMISSION);
return true;
}
if (args.length < 2) {
sender.sendMessage(ChatUtil.formatWithPrefix("&c&lIncorrect Usage&c, try &7/pt block <player>"));
return true;
}
if (data.getData().contains("blocked." + args[1].toLowerCase())) {
sender.sendMessage(ChatUtil.formatWithPrefix("&cUser is already blocked!"));
sender.sendMessage(ChatUtil.formatWithPrefix("&c&oMaybe try, &7/pt unblock <player>"));
return true;
}
UUID uuid;
if (Bukkit.getPlayer(args[1]) == null) {
try {
uuid = ServerManager.getInstance().getUUID(args[1].toLowerCase());
} catch (NullPointerException e) {
ChatUtil.errno(sender, ChatUtil.ChatTypes.PLAYER_NOT_FOUND);
return true;
}
}
else
uuid = Bukkit.getPlayer(args[1]).getUniqueId();
if (b) {
ChatUtil.errno(sender, ChatUtil.ChatTypes.PLAYER_NOT_FOUND);
return;
}
data.getData().set("blocked." + args[1].toLowerCase(), uuid.toString());
UUID target;
if (Bukkit.getPlayer(args[0]) == null) {
target = ServerManager.getInstance().getUUID(args[0]);
if (target == null) {
ChatUtil.errno(sender, ChatUtil.ChatTypes.PLAYER_NOT_FOUND);
return;
}
} else {
target = Objects.requireNonNull(Bukkit.getPlayer(args[0])).getUniqueId();
}
if (data.getData().contains("leaderboard." + uuid))
data.getData().set("leaderboard." + uuid, null);
data.saveData();
sender.sendMessage(ChatUtil.formatWithPrefix("&aUser &c&lBLOCKED &afrom leaderboards!"));
return true;
}
// command -> /playtimes block <player>
else if (args[0].equalsIgnoreCase("unblock")) {
if (!sender.hasPermission("pt.block")) {
ChatUtil.errno(sender, ChatUtil.ChatTypes.NO_PERMISSION);
return true;
}
if (args.length < 2) {
sender.sendMessage(ChatUtil.formatWithPrefix("&c&lIncorrect Usage&c, try &7/pt unblock <player>"));
return true;
}
if (!data.getData().contains("blocked." + args[1].toLowerCase())) {
sender.sendMessage(ChatUtil.formatWithPrefix("&cUser is not blocked!"));
sender.sendMessage(ChatUtil.formatWithPrefix("&c&oMaybe try, &7/pt block <player>"));
return true;
}
data.getData().set("blocked." + args[1].toLowerCase(), null);
data.saveData();
sender.sendMessage(ChatUtil.formatWithPrefix("&aUser &b&lUNBLOCKED &afrom leaderboards!"));
return true;
}
// command -/playtimes holo
/*else if (args[0].equalsIgnoreCase("holo")) {
if (args.length != 3) {
switch(args[2].toUpperCase()) {
case "CUSTOM":
return true;
case "TOP10":
return true;
case "TOP5":
return true;
case "TOP3":
return true;
}
}
}*/
// command -> /playtimes <player>
if (!sender.hasPermission("pt.others")) {
ChatUtil.errno(sender, ChatUtil.ChatTypes.NO_PERMISSION);
return true;
}
new BukkitRunnable() {
@Override
public void run() {
Pattern p = Pattern.compile("[^a-z0-9_]", Pattern.CASE_INSENSITIVE);
Matcher m = p.matcher(args[0]);
boolean b = m.find();
if (b) {
ChatUtil.errno(sender, ChatUtil.ChatTypes.PLAYER_NOT_FOUND);
return;
}
UUID target;
if (Bukkit.getPlayer(args[0]) == null) {
target = ServerManager.getInstance().getUUID(args[0]);
if (target == null) {
ChatUtil.errno(sender, ChatUtil.ChatTypes.PLAYER_NOT_FOUND);
return;
}
}
else
target = Bukkit.getPlayer(args[0]).getUniqueId();
org.bukkit.OfflinePlayer offlinePlayer = Bukkit.getServer().getOfflinePlayer(target);
OfflinePlayer player = new OfflinePlayer(sender, target, offlinePlayer.getName());
player.sendMessageToTarget();
}
}.runTaskAsynchronously(PlayTimes.getPlugin(PlayTimes.class));
return true;
}
org.bukkit.OfflinePlayer offlinePlayer = Bukkit.getServer().getOfflinePlayer(target);
OfflinePlayer player = new OfflinePlayer(sender, target, offlinePlayer.getName());
player.sendMessageToTarget();
}
}.runTaskAsynchronously(JavaPlugin.getPlugin(PlayTimes.class));
}
}
@@ -3,90 +3,96 @@ package me.codedred.playtimes.commands;
import me.codedred.playtimes.data.DataManager;
import me.codedred.playtimes.statistics.StatManager;
import me.codedred.playtimes.time.TimeManager;
import me.codedred.playtimes.utils.ChatUtil;
import me.codedred.playtimes.utils.CoolDownUtil;
import me.codedred.playtimes.utils.ServerUtils;
import org.apache.commons.lang.StringUtils;
import me.codedred.playtimes.utils.*;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import me.codedred.playtimes.models.Leaderboard;
import me.codedred.playtimes.utils.PAPIHolders;
import org.jetbrains.annotations.NotNull;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;
public class TopTime implements CommandExecutor {
@Override
public boolean onCommand(CommandSender sender, @NotNull Command cmd, @NotNull String label, String[] args) {
if (!sender.hasPermission("pt.top")) {
ChatUtil.errno(sender, ChatUtil.ChatTypes.NO_PERMISSION);
if (!sender.hasPermission("pt.top")) {
ChatUtil.errno(sender, ChatUtil.ChatTypes.NO_PERMISSION);
return true;
}
if (!(sender instanceof Player player)) {
sender.sendMessage("Must be a player to run this command.");
return true;
}
DataManager data = DataManager.getInstance();
if (data.getConfig().getBoolean("top-playtime.enable-cooldown") && !player.hasPermission("pt.block-cooldown")) {
if (CoolDownUtil.contains(player.getUniqueId())) {
String cooldownMessage = Objects.requireNonNull(data.getConfig().getString("messages.cooldown"))
.replace("%timeleft%", Integer.toString(CoolDownUtil.left(player.getUniqueId())));
sender.sendMessage(ChatUtil.formatWithPrefix(cooldownMessage));
return true;
}
DataManager data = DataManager.getInstance();
if (data.getConfig().getBoolean("top-playtime.enable-cooldown") && !sender.hasPermission("pt.block-cooldown")) {
if (sender instanceof Player) {
Player player = (Player) sender;
if (CoolDownUtil.contains(player.getUniqueId())) {
sender.sendMessage(ChatUtil.formatWithPrefix(data.getConfig().getString("messages.cooldown")
.replace("%timeleft%", Integer.toString(CoolDownUtil.left(player.getUniqueId())))));
return true;
}
CoolDownUtil.add(player.getUniqueId(), System.currentTimeMillis() +
(data.getConfig().getInt("top-playtime.cooldown-seconds") * 1000L));
}
}
Leaderboard board = new Leaderboard();
Map<String, Integer> map = board.getTopTen();
if (map.isEmpty()) {
sender.sendMessage(ChatUtil.format("&cRejoin the server to fill the leaderboard!"));
return true;
}
CoolDownUtil.add(player.getUniqueId(), System.currentTimeMillis() + (data.getConfig().getInt("top-playtime.cooldown-seconds") * 1000L));
}
String header = ChatUtil.format(data.getConfig().getString("top-playtime.header"));
String footer = ChatUtil.format(data.getConfig().getString("top-playtime.footer"));
String content = data.getConfig().getString("top-playtime.content");
Leaderboard board = new Leaderboard();
Map<String, Integer> map = board.getTopTen();
StatManager statManager = StatManager.getInstance();
TimeManager timeManager = TimeManager.getInstance();
if (map.isEmpty()) {
sender.sendMessage(ChatUtil.format("&cRejoin the server to fill the leaderboard!"));
return true;
}
if (ServerUtils.hasPAPI() && sender instanceof Player) {
Player player = (Player) sender;
StatManager statManager = StatManager.getInstance();
TimeManager timeManager = TimeManager.getInstance();
String header = ChatUtil.format(data.getConfig().getString("top-playtime.header"));
String footer = ChatUtil.format(data.getConfig().getString("top-playtime.footer"));
String content = data.getConfig().getString("top-playtime.content");
if (ServerUtils.hasPAPI()) {
header = PAPIHolders.getHolders(player, header);
footer = PAPIHolders.getHolders(player, footer);
}
String original = content;
sender.sendMessage(header);
for (int i = 0; i < map.size(); i++) {
UUID uuid = UUID.fromString(map.keySet().toArray()[i].toString());
if (ServerUtils.hasPAPI()) {
org.bukkit.OfflinePlayer player = Bukkit.getPlayer(uuid);
if (player != null)
content = PAPIHolders.getHolders(player, content);
else {
org.bukkit.OfflinePlayer oplayer = Bukkit.getOfflinePlayer(uuid);
content = PAPIHolders.getHolders(oplayer, content);
}
sender.sendMessage(header);
}
for (int i = 0; i < map.size(); i++) {
UUID uuid = UUID.fromString(map.keySet().toArray()[i].toString());
org.bukkit.OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(uuid);
String[][] replacements = {{"%player%", Bukkit.getServer().getOfflinePlayer(uuid).getName()},
{"%place%",String.valueOf(i + 1)},
{"%time%", timeManager.buildFormat(Integer.parseInt(map.values().toArray()[i].toString())/20) }};
for (String[] r : replacements)
content = StringUtils.replace(content, r[0], r[1]);
content = StringUtils.replace(content,"%joindate%", statManager.getJoinDate(uuid));
sender.sendMessage(ChatUtil.format(content));
content = original;
}
sender.sendMessage(footer);
if (ServerUtils.hasPAPI()) {
content = PAPIHolders.getHolders(offlinePlayer, content);
}
return true;
String offlinePlayerName = offlinePlayer.getName();
String place = String.valueOf(i + 1);
String time = timeManager.buildFormat(map.get(offlinePlayer.getUniqueId().toString()) / 20);
String joinDate = statManager.getJoinDate(uuid);
if (time == null) {
continue;
}
sender.sendMessage(ChatUtil.format(content
.replace("%player%", offlinePlayerName)
.replace("%place%", place)
.replace("%time%", time)
.replace("%joindate%", joinDate)));
content = data.getConfig().getString("top-playtime.content");
}
sender.sendMessage(footer);
return true;
}
}
@@ -12,35 +12,37 @@ import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.List;
public class Uptime implements CommandExecutor {
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command cmd, String cmdL, String[] args) {
if (cmdL.equalsIgnoreCase("uptime") || cmdL.equalsIgnoreCase("serveruptime") || cmdL.equalsIgnoreCase("serverupt")) {
if (sender.hasPermission("pt.uptime")) {
if (args.length >= 0) {
if (sender instanceof Player ) {
Player player = (Player) sender;
for (String msg : DataManager.getInstance().getConfig().getStringList("uptime.message")) {
if (ServerUtils.hasPAPI())
msg = PlaceholderAPI.setPlaceholders(player, msg);
if (msg.contains("{\"text\":")) {
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), ("tellraw " + player + " " + msg.replace("%serveruptime%",
StatManager.getInstance().getUptime())));
} else
player.sendMessage(ChatUtil.format(msg.replace("%serveruptime%", StatManager.getInstance().getUptime())));
}
return true;
} else {
for (String msg : DataManager.getInstance().getConfig().getStringList("uptime.message")) {
sender.sendMessage(ChatUtil.format(msg.replace("%serveruptime%", StatManager.getInstance().getUptime())));
}
}
}
} else
ChatUtil.errno(sender, ChatUtil.ChatTypes.NO_PERMISSION);
return true;
}
return false;
if (!cmdL.equalsIgnoreCase("uptime") && !cmdL.equalsIgnoreCase("serveruptime") && !cmdL.equalsIgnoreCase("serverupt")) {
return false;
}
if (!sender.hasPermission("pt.uptime")) {
ChatUtil.errno(sender, ChatUtil.ChatTypes.NO_PERMISSION);
return true;
}
String uptime = StatManager.getInstance().getUptime();
List<String> messages = DataManager.getInstance().getConfig().getStringList("uptime.message");
for (String message : messages) {
if (ServerUtils.hasPAPI() && sender instanceof Player player) {
message = PlaceholderAPI.setPlaceholders(player, message);
}
if (message.contains("{\"text\":")) {
String consoleCommand = "tellraw " + sender.getName() + " " + message.replace("%serveruptime%", uptime);
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), consoleCommand);
} else {
sender.sendMessage(ChatUtil.format(message.replace("%serveruptime%", uptime)));
}
}
return true;
}
}
@@ -0,0 +1,46 @@
package me.codedred.playtimes.commands.completer;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabCompleter;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
public class TimeTabCompleter implements TabCompleter {
@Override
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, String[] args) {
List<String> completions = new ArrayList<>();
if (args.length == 1) {
if (sender.hasPermission("pt.use")) {
completions.add("top");
completions.addAll(getOnlinePlayerNames());
}
if (sender.hasPermission("pt.block")) {
completions.add("block");
completions.add("unblock");
}
if (sender.hasPermission("pt.reload")) {
completions.add("reload");
completions.add("debug");
completions.add("help");
}
}
return completions;
}
private List<String> getOnlinePlayerNames() {
List<String> playerNames = new ArrayList<>();
for (Player player : Bukkit.getOnlinePlayers()) {
playerNames.add(player.getName());
}
return playerNames;
}
}
@@ -1,8 +1,8 @@
package me.codedred.playtimes.data;
import me.codedred.playtimes.PlayTimes;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import me.codedred.playtimes.PlayTimes;
import java.io.File;
import java.io.IOException;
@@ -11,61 +11,51 @@ import java.io.InputStreamReader;
import java.util.logging.Level;
public class CustomConfig {
private final String name;
private final PlayTimes plugin;
private FileConfiguration dataConfig = null;
private File dataConfigFile = null;
private final String name;
public CustomConfig(PlayTimes plugin, String name) {
public CustomConfig(PlayTimes plugin, String fileName) {
this.plugin = plugin;
this.name = name;
this.name = fileName;
saveDefaultConfig();
}
public void reloadConfig() {
if (dataConfigFile == null) {
dataConfigFile = new File(plugin.getDataFolder(),
name);
}
dataConfig = YamlConfiguration
.loadConfiguration(dataConfigFile);
if (this.dataConfigFile == null)
this.dataConfigFile = new File(this.plugin.getDataFolder(), name);
InputStream defConfigStream = plugin.getResource(name);
this.dataConfig = YamlConfiguration.loadConfiguration(this.dataConfigFile);
InputStream defConfigStream = this.plugin.getResource(name);
if (defConfigStream != null) {
YamlConfiguration defConfig = YamlConfiguration
.loadConfiguration(new InputStreamReader(defConfigStream));
dataConfig.setDefaults(defConfig);
this.dataConfig.setDefaults(defConfig);
}
}
public FileConfiguration getConfig() {
if (dataConfig == null) {
if (this.dataConfig == null)
reloadConfig();
}
return dataConfig;
return this.dataConfig;
}
public void saveConfig() {
if ((dataConfig == null) || (dataConfigFile == null)) {
if ((this.dataConfig == null) || (this.dataConfigFile == null))
return;
}
try {
getConfig().save(dataConfigFile);
getConfig().save(this.dataConfigFile);
} catch (IOException ex) {
plugin.getLogger().log(Level.SEVERE, "Could not save config to "
+ dataConfigFile, ex);
}
}
this.plugin.getLogger().log(Level.SEVERE, ex, () -> "Could not save config to " + this.dataConfigFile); }
}
public void saveDefaultConfig() {
if (dataConfigFile == null) {
dataConfigFile = new File(plugin.getDataFolder(),
name);
}
if (!dataConfigFile.exists()) {
plugin.saveResource(name, false);
}
if (this.dataConfigFile == null)
this.dataConfigFile = new File(this.plugin.getDataFolder(), name);
if (!this.dataConfigFile.exists())
this.plugin.saveResource(name, false);
}
}
@@ -2,47 +2,34 @@ package me.codedred.playtimes.data;
import me.codedred.playtimes.PlayTimes;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.plugin.java.JavaPlugin;
public class DataManager {
private final static DataManager instance = new DataManager();
public static DataManager getInstance() {
return instance;
}
private final CustomConfig data = new CustomConfig(PlayTimes.getPlugin(PlayTimes.class), "data.yml");
private final CustomConfig cfg = new CustomConfig(PlayTimes.getPlugin(PlayTimes.class), "config.yml");
//private final CustomConfig holo = new CustomConfig(PlayTimes.getPlugin(PlayTimes.class), "hologram.yml");
public FileConfiguration getConfig() {
return cfg.getConfig();
}
private static final DataManager instance = new DataManager();
private final CustomConfig data = new CustomConfig(JavaPlugin.getPlugin(PlayTimes.class), "data.yml");
private final CustomConfig cfg = new CustomConfig(JavaPlugin.getPlugin(PlayTimes.class), "config.yml");
public FileConfiguration getData() {
return data.getConfig();
}
public static DataManager getInstance() {
return instance;
}
//public FileConfiguration getHolo() {
// return holo.getConfig();
//}
public void reloadAll() {
data.reloadConfig();
cfg.reloadConfig();
//holo.reloadConfig();
}
public void saveData() {
data.saveConfig();
}
//public void saveHolo() {
// holo.saveConfig();
//}
public FileConfiguration getConfig() {
return cfg.getConfig();
}
public FileConfiguration getData() {
return data.getConfig();
}
public void reloadAll() {
data.reloadConfig();
cfg.reloadConfig();
}
public void saveData() {
data.saveConfig();
}
}
@@ -1,26 +0,0 @@
package me.codedred.playtimes.data;
import java.util.HashMap;
import java.util.Map;
public class Debugger {
public void execute() {
DataManager data = DataManager.getInstance();
//Data file update
if (!data.getData().contains("leaderboard")) {
//Bukkit.getServer().getConsoleSender().sendMessage(ChatColor.DARK_PURPLE + "[PlayTime] " + ChatColor.WHITE + "Updating data file...");
Map<String, Long> boardData = new HashMap<>();
for (String uuid : data.getData().getKeys(false))
boardData.put(uuid, data.getData().getLong(uuid));
for (String uuid : data.getData().getKeys(false))
data.getData().set(uuid, null);
for (Map.Entry<String, Long> d : boardData.entrySet())
data.getData().set("leaderboard." + d.getKey(), d.getValue());
// Bukkit.getServer().getConsoleSender().sendMessage(ChatColor.DARK_PURPLE + "[PlayTime] " + ChatColor.WHITE + "Data file updated!");
data.saveData();
}
}
}
@@ -1,9 +0,0 @@
package me.codedred.playtimes.holograms;
public enum HoloType {
CUSTOM,
TOP10,
TOP5,
TOP3
}
@@ -1,51 +0,0 @@
package me.codedred.playtimes.holograms;
import org.bukkit.Location;
import java.util.ArrayList;
import java.util.List;
public class Hologram {
private List<String> lines;
private HoloType type;
private Location location;
public Hologram() {
lines = new ArrayList<>();
type = HoloType.CUSTOM;
location = null;
}
private void setLocation(Location location) {
this.location = location;
}
public Location getLocation(Location location) {
return location;
}
public void addLine(String line) {
lines.add(line);
}
public void setLines(List<String> lines) {
this.lines = lines;
}
public List<String> getLines() {
return lines;
}
public void setType(HoloType type) {
this.type = type;
}
public HoloType getType() {
return type;
}
}
@@ -3,6 +3,7 @@ package me.codedred.playtimes.listeners;
import me.codedred.playtimes.data.DataManager;
import me.codedred.playtimes.statistics.StatManager;
import me.codedred.playtimes.statistics.StatisticType;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
@@ -14,18 +15,23 @@ public class Join implements Listener {
@EventHandler
public void onJoin(PlayerJoinEvent event) {
DataManager data = DataManager.getInstance();
if (data.getData().contains("blocked." + event.getPlayer().getName().toLowerCase()))
if (data.getData().contains("blocked." + event.getPlayer().getName().toLowerCase())) {
return;
UUID uuid = event.getPlayer().getUniqueId();
if (!data.getData().contains("leaderboard." + uuid)) {
long time = StatManager.getInstance().getPlayerStat(uuid, StatisticType.PLAYTIME);
data.getData().set("leaderboard." + uuid, time);
data.saveData();
}
}
UUID uuid = event.getPlayer().getUniqueId();
ConfigurationSection leaderboardSection = data.getData().getConfigurationSection("leaderboard");
if (leaderboardSection == null) {
leaderboardSection = data.getData().createSection("leaderboard");
}
if (leaderboardSection.contains(uuid.toString())) {
return;
}
long time = StatManager.getInstance().getPlayerStat(uuid, StatisticType.PLAYTIME);
leaderboardSection.set(uuid.toString(), time);
data.saveData();
}
}
@@ -14,12 +14,15 @@ public class Quit implements Listener {
@EventHandler
public void onQuit(PlayerQuitEvent event) {
DataManager data = DataManager.getInstance();
if (data.getData().contains("blocked." + event.getPlayer().getName().toLowerCase()))
String playerName = event.getPlayer().getName().toLowerCase();
if (data.getData().contains("blocked." + playerName)) {
return;
}
StatManager statManager = StatManager.getInstance();
UUID uuid = event.getPlayer().getUniqueId();
long time = StatManager.getInstance().getPlayerStat(uuid, StatisticType.PLAYTIME);
data.getData().set("leaderboard." + uuid, time);
long playtime = statManager.getPlayerStat(uuid, StatisticType.PLAYTIME);
data.getData().set("leaderboard." + uuid, playtime);
data.saveData();
}
}
@@ -8,63 +8,72 @@ import java.util.*;
public class Leaderboard {
/***
final String LEADERBOARD = "leaderboard";
/**
* Grabs the uuids from the data file, sorts them, then removes redundant uuids and updates the top 10
*
* @return listing of top 10 players
*/
public Map<String, Integer> getTopTen() {
Map<String, Integer> topTen = new LinkedHashMap<>();
Map<String, Integer> topTen = new LinkedHashMap<>();
DataManager data = DataManager.getInstance();
if (!data.getData().contains("leaderboard"))
if (!data.getData().contains("leaderboard")) {
return topTen;
for (String key : data.getData().getConfigurationSection("leaderboard").getKeys(false))
topTen.put(key, Integer.valueOf(data.getData().getString("leaderboard." + key)));
List<Map.Entry<String, Integer>> list = new LinkedList<>(topTen.entrySet());
list.sort((o1, o2) -> o2.getValue() - o1.getValue());
if (list.size() > 20) {
List<Map.Entry<String, Integer>> delList = list.subList(20, list.size());
for (Map.Entry<String, Integer> key : delList)
data.getData().set("leaderboard." + key.getKey(), null);
data.saveData();
}
for (String key : data.getData().getConfigurationSection(LEADERBOARD).getKeys(false)) {
topTen.put(key, Integer.valueOf(data.getData().getString(LEADERBOARD + "." + key)));
}
if (list.size() > 9)
list = list.subList(0, 10);
topTen.clear();
for (Map.Entry<String, Integer> aList : list)
topTen.put(aList.getKey(), aList.getValue());
topTen = updateTimes(topTen);
return topTen;
}
/***
* Updates the top ten times.
* Need to find better solution eventually.
* @param topTen - Map of top ten uuids and times
* @return updated map
*/
private Map<String, Integer> updateTimes(Map<String, Integer> topTen) {
StatManager stats = StatManager.getInstance();
topTen.replaceAll((u, v) -> (int) stats.getPlayerStat(UUID.fromString(u), StatisticType.PLAYTIME));
List<Map.Entry<String, Integer>> list = new LinkedList<>(topTen.entrySet());
list.sort((o1, o2) -> o2.getValue() - o1.getValue());
list.sort((o1, o2) -> o2.getValue() - o1.getValue());
topTen.clear();
if (list.size() > 20) {
List<Map.Entry<String, Integer>> delList = list.subList(20, list.size());
for (Map.Entry<String, Integer> aList : list)
topTen.put(aList.getKey(), aList.getValue());
return topTen;
for (Map.Entry<String, Integer> key : delList) {
data.getData().set(LEADERBOARD + "." + key.getKey(), null);
}
data.saveData();
}
if (list.size() > 9) {
list = list.subList(0, 10);
}
topTen.clear();
for (Map.Entry<String, Integer> entry : list) {
topTen.put(entry.getKey(), entry.getValue());
}
updateTimes(topTen);
return topTen;
}
/**
* Updates the top ten times by querying the latest times from the StatManager and sorting the list.
*
* @param topTen the current leaderboard, with UUIDs and their corresponding time
*/
private void updateTimes(Map<String, Integer> topTen) {
StatManager statManager = StatManager.getInstance();
List<Map.Entry<String, Integer>> list = new ArrayList<>(topTen.entrySet());
for (Map.Entry<String, Integer> entry : list) {
String uuid = entry.getKey();
int latestTime = (int) statManager.getPlayerStat(UUID.fromString(uuid), StatisticType.PLAYTIME);
topTen.put(uuid, latestTime);
}
list = new ArrayList<>(topTen.entrySet());
list.sort(Map.Entry.<String, Integer>comparingByValue().reversed());
topTen.clear();
for (int i = 0; i < Math.min(list.size(), 10); i++) {
Map.Entry<String, Integer> entry = list.get(i);
topTen.put(entry.getKey(), entry.getValue());
}
}
}
@@ -7,7 +7,6 @@ import me.codedred.playtimes.time.TimeManager;
import me.codedred.playtimes.utils.ChatUtil;
import me.codedred.playtimes.utils.PAPIHolders;
import me.codedred.playtimes.utils.ServerUtils;
import org.apache.commons.lang.StringUtils;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
@@ -32,29 +31,28 @@ public class OfflinePlayer {
private void buildMessage() {
DataManager dataManager = DataManager.getInstance();
TimeManager timeManager = TimeManager.getInstance();
StatManager statManager = StatManager.getInstance();
TimeManager timeManager = TimeManager.getInstance();
message = dataManager.getConfig().getStringList("playtime.message");
long rawTime = statManager.getPlayerStat(target, StatisticType.PLAYTIME);
if (ServerUtils.hasPAPI()) {
org.bukkit.OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(target);
List<String> papiMessage = new ArrayList<>();
if (offlinePlayer != null) {
for (String msg : message)
papiMessage.add(PAPIHolders.getHolders(offlinePlayer, msg));
message = papiMessage;
for (String msg : message) {
papiMessage.add(PAPIHolders.getHolders(Bukkit.getOfflinePlayer(target), msg));
}
message = papiMessage;
}
String timeFormat = timeManager.buildFormat(rawTime/20);
String timeFormat = timeManager.buildFormat(rawTime / 20);
List<String> newMessage = new ArrayList<>();
for (String msg : message) {
msg = StringUtils.replace(msg,"%time%", timeFormat);
msg = StringUtils.replace(msg, "%player%", name);
msg = StringUtils.replace(msg, "%timesjoined%", Long.toString(statManager.getPlayerStat(target, StatisticType.LEAVE)));
msg = StringUtils.replace(msg, "%joindate%", statManager.getJoinDate(target));
msg = msg.replace("%time%", timeFormat);
msg = msg.replace("%player%", name);
msg = msg.replace("%timesjoined%", Long.toString(statManager.getPlayerStat(target, StatisticType.LEAVE)));
msg = msg.replace("%joindate%", statManager.getJoinDate(target));
newMessage.add(msg);
}
message = newMessage;
@@ -62,11 +60,11 @@ public class OfflinePlayer {
public void sendMessageToTarget() {
for (String msg : message) {
if (msg.contains("{\"text\":"))
if (msg.contains("{\"text\":")) {
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "tellraw " + sender + " " + ChatUtil.format(msg));
else
} else {
sender.sendMessage(ChatUtil.format(msg));
}
}
}
}
@@ -7,61 +7,93 @@ import me.codedred.playtimes.time.TimeManager;
import me.codedred.playtimes.utils.ChatUtil;
import me.codedred.playtimes.utils.PAPIHolders;
import me.codedred.playtimes.utils.ServerUtils;
import org.apache.commons.lang.StringUtils;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.List;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class OnlinePlayer {
private final Player target;
private List<String> message = new ArrayList<>();
private final List<String> message;
private final DataManager dataManager;
private final StatManager statManager;
private final TimeManager timeManager;
public OnlinePlayer(Player target) {
this.target = target;
this.message = new ArrayList<>();
this.dataManager = DataManager.getInstance();
this.statManager = StatManager.getInstance();
this.timeManager = TimeManager.getInstance();
buildMessage();
}
private void buildMessage() {
DataManager dataManager = DataManager.getInstance();
TimeManager timeManager = TimeManager.getInstance();
StatManager statManager = StatManager.getInstance();
message = dataManager.getConfig().getStringList("playtime.message");
long rawTime;
if (statManager.isLegacy())
if (statManager.isLegacy()) {
rawTime = statManager.getPlayerStat(target.getUniqueId(), StatisticType.PLAYTIME);
else
} else {
rawTime = statManager.getStats().getOnlineStatistic(target, StatisticType.PLAYTIME);
}
message.addAll(dataManager.getConfig().getStringList("playtime.message"));
if (ServerUtils.hasPAPI()) {
List<String> papiMessage = new ArrayList<>();
for (String msg : message)
for (String msg : message) {
papiMessage.add(PAPIHolders.getHolders(target, msg));
message = papiMessage;
}
message.clear();
message.addAll(papiMessage);
}
String timeFormat = timeManager.buildFormat(rawTime/20);
if (message.isEmpty()) {
return;
}
Map<String, String> replacements = new HashMap<>();
String timeFormat = timeManager.buildFormat(rawTime / 20);
replacements.put("%time%", timeFormat);
replacements.put("%player%", target.getName());
replacements.put("%timesjoined%", Long.toString(statManager.getPlayerStat(target.getUniqueId(), StatisticType.LEAVE)));
replacements.put("%joindate%", statManager.getJoinDate(target.getUniqueId()));
Pattern pattern = Pattern.compile("%(\\w+)%");
List<String> newMessage = new ArrayList<>();
for (String msg : message) {
msg = StringUtils.replace(msg,"%time%", timeFormat);
msg = StringUtils.replace(msg, "%player%", target.getName());
msg = StringUtils.replace(msg, "%timesjoined%", Long.toString(statManager.getPlayerStat(target.getUniqueId(), StatisticType.LEAVE)));
msg = StringUtils.replace(msg, "%joindate%", statManager.getJoinDate(target.getUniqueId()));
newMessage.add(msg);
Matcher matcher = pattern.matcher(msg);
StringBuilder sb = new StringBuilder();
while (matcher.find()) {
String replacement = replacements.get(matcher.group(1));
if (replacement != null) {
matcher.appendReplacement(sb, replacement);
}
}
matcher.appendTail(sb);
newMessage.add(sb.toString());
}
message = newMessage;
message.clear();
message.addAll(newMessage);
}
public void sendMessageToTarget() {
String playerName = target.getName();
for (String msg : message) {
if (msg.contains("{\"text\":"))
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "tellraw " + target + " " + ChatUtil.format(msg));
else
target.sendMessage(ChatUtil.format(msg));
String formattedMsg = ChatUtil.format(msg)
.replace("%time%", timeManager.buildFormat(StatManager.getInstance().getStats().getOnlineStatistic(target, StatisticType.PLAYTIME) / 20))
.replace("%player%", playerName)
.replace("%timesjoined%", Long.toString(StatManager.getInstance().getPlayerStat(target.getUniqueId(), StatisticType.LEAVE)))
.replace("%joindate%", StatManager.getInstance().getJoinDate(target.getUniqueId()));
if (formattedMsg.contains("{\"text\":")) {
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "tellraw " + target + " " + formattedMsg);
} else {
target.sendMessage(formattedMsg);
}
}
}
}
}
@@ -7,7 +7,7 @@ import java.io.IOException;
import java.util.UUID;
public class ServerManager {
private final static ServerManager instance = new ServerManager();
private static final ServerManager instance = new ServerManager();
public static ServerManager getInstance() {
return instance;
@@ -1,6 +1,7 @@
package me.codedred.playtimes.server;
import com.google.gson.*;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import me.codedred.playtimes.statistics.StatManager;
import java.io.BufferedReader;
@@ -15,17 +16,16 @@ public class ServerOffline implements ServerStatus {
@Override
public UUID getUUID(String name) {
try {
InputStream is = new URL("https://api.mojang.com/users/profiles/minecraft/" + name).openStream();
try (InputStream is = new URL("https://api.mojang.com/users/profiles/minecraft/" + name).openStream()) {
BufferedReader rd = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8));
JsonObject rootobj = new Gson().fromJson(rd, JsonObject.class);
String fixedName = rootobj.get("name").getAsString();
is.close();
UUID uuid = UUID.nameUUIDFromBytes(("OfflinePlayer:" + fixedName).getBytes(StandardCharsets.UTF_8));
if (!StatManager.getInstance().hasJoinedBefore(uuid))
if (StatManager.getInstance().hasJoinedBefore(uuid)) {
return null;
}
return uuid;
} catch (Exception e) {
} catch (IOException e) {
return null;
}
}
@@ -36,11 +36,10 @@ public class ServerOffline implements ServerStatus {
}
@Override
public String getName(UUID uuid) throws JsonSyntaxException, IOException {
try (InputStream is = new URL("https://mcapi.ca/player/profile/" + uuid).openStream()) {
BufferedReader rd = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8));
public String getName(UUID uuid) throws IOException {
try (InputStream is = new URL("https://mcapi.ca/player/profile/" + uuid).openStream();
BufferedReader rd = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8))) {
JsonObject rootobj = new Gson().fromJson(rd, JsonObject.class);
return rootobj.get("name").getAsString();
} catch (IOException e) {
e.printStackTrace();
@@ -1,10 +1,9 @@
package me.codedred.playtimes.server;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.JsonSyntaxException;
import com.google.gson.*;
import me.codedred.playtimes.statistics.StatManager;
import org.bukkit.Bukkit;
import org.jetbrains.annotations.NotNull;
import java.io.BufferedReader;
import java.io.IOException;
@@ -17,31 +16,12 @@ import java.util.UUID;
public class ServerOnline implements ServerStatus {
@Override
public UUID getUUID(String name) {
public UUID getUUID(@NotNull String name) {
UUID uuid = Bukkit.getOfflinePlayer(name).getUniqueId();
if (!StatManager.getInstance().hasJoinedBefore(uuid))
return null;
return uuid;
}
private UUID getMainThreadMojangUUID(String name) {
try {
InputStream is = new URL("https://api.mojang.com/users/profiles/minecraft/" + name).openStream();
BufferedReader rd = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8));
JsonObject rootobj = new Gson().fromJson(rd, JsonObject.class);
String u = rootobj.get("id").getAsString();
StringBuilder uuid = new StringBuilder();
for (int i = 0; i <= 31; i++) {
uuid.append(u.charAt(i));
if (i == 7 || i == 11 || i == 15 || i == 19) {
uuid.append("-");
}
}
is.close();
return UUID.fromString(uuid.toString());
} catch (JsonSyntaxException | IOException e) {
if (StatManager.getInstance().hasJoinedBefore(uuid)) {
return null;
}
return uuid;
}
@Override
@@ -50,15 +30,17 @@ public class ServerOnline implements ServerStatus {
}
@Override
public String getName(UUID uuid) throws JsonSyntaxException, IOException {
public String getName(UUID uuid) throws IOException {
try (InputStream is = new URL("https://mcapi.ca/player/profile/" + uuid).openStream()) {
BufferedReader rd = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8));
JsonObject rootobj = new Gson().fromJson(rd, JsonObject.class);
JsonElement root = JsonParser.parseReader(rd);
return rootobj.get("name").getAsString();
JsonObject rootObj = root.getAsJsonObject();
return rootObj.get("name").getAsString();
} catch (IOException e) {
e.printStackTrace();
return "User Not Found";
}
}
}
}
@@ -21,14 +21,11 @@ public class LegacyStats implements Stats {
try {
JsonObject jsonObject = new Gson().fromJson(new FileReader(playerStatistics), JsonObject.class);
switch(type) {
case PLAYTIME:
return jsonObject.get("stat.playOneMinute").getAsLong();
case LEAVE:
return jsonObject.get("stat.leaveGame").getAsLong();
case REST:
return jsonObject.get("stat.timeSinceDeath").getAsLong();
}
return switch (type) {
case PLAYTIME -> jsonObject.get("stat.playOneMinute").getAsLong();
case LEAVE -> jsonObject.get("stat.leaveGame").getAsLong();
case REST -> jsonObject.get("stat.timeSinceDeath").getAsLong();
};
} catch (Exception e) {
//e.printStackTrace();
@@ -29,15 +29,18 @@ public class RisenStats implements Stats {
JsonObject pilot = (JsonObject) jsonObject.get("stats");
JsonObject passenger = (JsonObject) pilot.get("minecraft:custom");
switch(type) {
case PLAYTIME:
switch (type) {
case PLAYTIME -> {
if (passenger.get("minecraft:play_time") == null)
return passenger.get("minecraft:play_one_minute").getAsLong();
return passenger.get("minecraft:play_time").getAsLong();
case LEAVE:
}
case LEAVE -> {
return passenger.get("minecraft:leave_game").getAsLong();
case REST:
}
case REST -> {
return passenger.get("minecraft:time_since_rest").getAsLong();
}
}
} catch (Exception e) {
//e.printStackTrace();
@@ -48,15 +51,11 @@ public class RisenStats implements Stats {
@Override
public long getOnlineStatistic(Player player, StatisticType type) {
switch(type) {
case PLAYTIME:
return player.getStatistic(Statistic.PLAY_ONE_MINUTE);
case REST:
return player.getStatistic(Statistic.TIME_SINCE_REST);
case LEAVE:
return player.getStatistic(Statistic.LEAVE_GAME) + 1;
}
return 0;
return switch (type) {
case PLAYTIME -> player.getStatistic(Statistic.PLAY_ONE_MINUTE);
case REST -> player.getStatistic(Statistic.TIME_SINCE_REST);
case LEAVE -> player.getStatistic(Statistic.LEAVE_GAME) + 1;
};
}
@Override
@@ -28,14 +28,11 @@ public class RisingStats implements Stats {
JsonObject pilot = (JsonObject) jsonObject.get("stats");
JsonObject passenger = (JsonObject) pilot.get("minecraft:custom");
switch(type) {
case PLAYTIME:
return passenger.get("minecraft:play_one_minute").getAsLong();
case LEAVE:
return passenger.get("minecraft:leave_game").getAsLong();
case REST:
return passenger.get("minecraft:time_since_rest").getAsLong();
}
return switch (type) {
case PLAYTIME -> passenger.get("minecraft:play_one_minute").getAsLong();
case LEAVE -> passenger.get("minecraft:leave_game").getAsLong();
case REST -> passenger.get("minecraft:time_since_rest").getAsLong();
};
} catch (Exception e) {
//e.printStackTrace();
}
@@ -45,15 +42,11 @@ public class RisingStats implements Stats {
@Override
public long getOnlineStatistic(Player player, StatisticType type) {
switch(type) {
case PLAYTIME:
return player.getStatistic(Statistic.PLAY_ONE_MINUTE);
case REST:
return player.getStatistic(Statistic.TIME_SINCE_REST);
case LEAVE:
return player.getStatistic(Statistic.LEAVE_GAME) + 1;
}
return 0;
return switch (type) {
case PLAYTIME -> player.getStatistic(Statistic.PLAY_ONE_MINUTE);
case REST -> player.getStatistic(Statistic.TIME_SINCE_REST);
case LEAVE -> player.getStatistic(Statistic.LEAVE_GAME) + 1;
};
}
@Override
@@ -9,7 +9,7 @@ import java.util.concurrent.TimeUnit;
public class StatManager {
private final static StatManager instance = new StatManager();
private static final StatManager instance = new StatManager();
public static StatManager getInstance() {
return instance;
@@ -18,14 +18,21 @@ public class StatManager {
private Stats stats;
private boolean legacy = false;
public String name;
public void registerStatistics() {
if (ServerUtils.isRisenVersion())
if (ServerUtils.isRisenVersion()) {
stats = new RisenStats();
else if (ServerUtils.isNewerVersion())
name = "Risen";
}
else if (ServerUtils.isNewerVersion()) {
stats = new RisingStats();
name = "Rising";
}
else {
stats = new LegacyStats();
setLegacy();
name = "Legacy";
}
}
@@ -38,7 +45,7 @@ public class StatManager {
}
public boolean hasJoinedBefore(UUID uuid) {
return getStats().hasJoinedBefore(uuid);
return !getStats().hasJoinedBefore(uuid);
}
public String getJoinDate(UUID uuid) {
@@ -0,0 +1,31 @@
package me.codedred.playtimes.time;
import me.codedred.playtimes.data.DataManager;
public class TimeConstants {
private static String second, seconds, minute, minutes, hour, hours, day, days;
static {
reload();
}
public static void reload() {
second = DataManager.getInstance().getConfig().getString("playtime.name.second");
seconds = DataManager.getInstance().getConfig().getString("playtime.name.seconds");
minute = DataManager.getInstance().getConfig().getString("playtime.name.minute");
minutes = DataManager.getInstance().getConfig().getString("playtime.name.minutes");
hour = DataManager.getInstance().getConfig().getString("playtime.name.hour");
hours = DataManager.getInstance().getConfig().getString("playtime.name.hours");
day = DataManager.getInstance().getConfig().getString("playtime.name.day");
days = DataManager.getInstance().getConfig().getString("playtime.name.days");
}
public static String getSecond() { return second; }
public static String getSeconds() { return seconds; }
public static String getMinute() { return minute; }
public static String getMinutes() { return minutes; }
public static String getHour() { return hour; }
public static String getHours() { return hours; }
public static String getDay() { return day; }
public static String getDays() { return days; }
}
@@ -1,16 +0,0 @@
package me.codedred.playtimes.time;
import me.codedred.playtimes.data.DataManager;
public interface TimeRegistry {
String SECOND = DataManager.getInstance().getConfig().getString("playtime.name.second");
String SECONDS = DataManager.getInstance().getConfig().getString("playtime.name.seconds");
String MINUTE = DataManager.getInstance().getConfig().getString("playtime.name.minute");
String MINUTES = DataManager.getInstance().getConfig().getString("playtime.name.minutes");
String HOUR = DataManager.getInstance().getConfig().getString("playtime.name.hour");
String HOURS = DataManager.getInstance().getConfig().getString("playtime.name.hours");
String DAY = DataManager.getInstance().getConfig().getString("playtime.name.day");
String DAYS = DataManager.getInstance().getConfig().getString("playtime.name.days");
}
@@ -1,40 +1,6 @@
package me.codedred.playtimes.time;
public interface Timings extends TimeRegistry {
public interface Timings {
String buildFormat(long time);
/*public static int getDays(long l) {
if (l < 60) {
return 0;
}
int minutes = (int) (l / 60);
if (minutes < 1440)
return 0;
return minutes / 1440;
}
public static int getHours(long l) {
if (l < 60) {
return 0;
}
int minutes = (int) (l / 60);
if (minutes < 60)
return 0;
return minutes / 60;
}
public static int getMins(long l) {
if (l < 60) {
return 0;
}
return (int) (l / 60);
}
public static int getSecs(long l) {
if (l <= 0) {
return 0;
}
return (int) (l);
}*/
}
@@ -1,65 +1,66 @@
package me.codedred.playtimes.time.formats;
import me.codedred.playtimes.time.TimeConstants;
import me.codedred.playtimes.time.Timings;
public class NativeFormat implements Timings {
@Override
public String buildFormat(long time) {
if (time < 60)
return time + ( time == 1 ? SECONDS : SECOND);
if (time < 60)
return formatSeconds(time);
int minutes = (int) (time / 60);
int seconds = 60 * minutes;
int secondsLeft = (int) (time - seconds);
int secondsLeft = (int) (time % 60);
// Time less than 1 hour
if (minutes < 60) {
if (secondsLeft > 0)
return minutes + (minutes == 1 ? MINUTE : MINUTES) + " " + secondsLeft + (secondsLeft == 1 ? SECOND : SECONDS);
return minutes + (minutes == 1 ? MINUTE : MINUTES);
}
String format;
if (minutes < 60)
return formatMinutes(minutes, secondsLeft);
// Time less than 1 Day
if (minutes < 1440) {
int hours = minutes / 60;
format = hours + (hours == 1 ? HOUR : HOURS);
int inMins = 60 * hours;
int left = minutes - inMins;
if (left >= 1)
format = format + " " + left + (left == 1 ? MINUTE : MINUTES);
if (secondsLeft > 0)
format = format + " " + secondsLeft + (secondsLeft == 1 ? SECOND : SECONDS);
return format;
int minutesLeft = minutes % 60;
return formatHours(hours, minutesLeft, secondsLeft);
}
// Time greater than 1 day
int days = minutes / 1440;
format = days + (days == 1 ? DAY : DAYS);
int inMins = 1440 * days;
int leftOver = minutes - inMins;
if (leftOver >= 1) {
if (leftOver < 60) {
format = format + " " + leftOver + (leftOver == 1 ? MINUTE : MINUTES);
}
else {
int hours = leftOver / 60;
format = format + " " + hours + (hours == 1 ? HOUR : HOURS);
int hoursInMins = 60 * hours;
int minsLeft = leftOver - hoursInMins;
if (leftOver >= 1) {
format = format + " " + minsLeft + (minsLeft == 1 ? MINUTE : MINUTES);
}
}
}
int minutesLeft = minutes % 1440;
return formatDays(days, minutesLeft, secondsLeft);
}
private String formatSeconds(long seconds) {
return seconds + (seconds == 1 ? TimeConstants.getSeconds() : TimeConstants.getSecond());
}
private String formatMinutes(int minutes, int secondsLeft) {
String format = minutes + (minutes == 1 ? TimeConstants.getMinute() : TimeConstants.getMinutes());
if (secondsLeft > 0)
format = format + " " + secondsLeft + (secondsLeft == 1 ? SECOND : SECONDS);
format += formatSeconds(secondsLeft);
return format;
}
private String formatHours(int hours, int minutesLeft, int secondsLeft) {
String format = hours + (hours == 1 ? TimeConstants.getHour() : TimeConstants.getHours());
if (minutesLeft >= 1)
format += formatMinutes(minutesLeft, secondsLeft);
else if (secondsLeft > 0)
format += formatSeconds(secondsLeft);
return format;
}
private String formatDays(int days, int minutesLeft, int secondsLeft) {
String format = days + (days == 1 ? TimeConstants.getDay() : TimeConstants.getDays());
if (minutesLeft >= 60) {
int hours = minutesLeft / 60;
int minutesAfterHours = minutesLeft % 60;
format += formatHours(hours, minutesAfterHours, secondsLeft);
} else if (minutesLeft >= 1) {
format += formatMinutes(minutesLeft, secondsLeft);
} else if (secondsLeft > 0) {
format += formatSeconds(secondsLeft);
}
return format;
}
}
@@ -1,5 +1,6 @@
package me.codedred.playtimes.time.formats;
import me.codedred.playtimes.time.TimeConstants;
import me.codedred.playtimes.time.Timings;
public class NoDays implements Timings {
@@ -7,33 +8,39 @@ public class NoDays implements Timings {
@Override
public String buildFormat(long time) {
if (time < 60)
return time + ( time == 1 ? SECONDS : SECOND);
return formatSeconds(time);
int minutes = (int) (time / 60);
int seconds = 60 * minutes;
int secondsLeft = (int) (time - seconds);
int secondsLeft = (int) (time % 60);
// Time less than 1 hour
if (minutes < 60) {
if (secondsLeft > 0)
return minutes + (minutes == 1 ? MINUTE : MINUTES) + " " + secondsLeft + (secondsLeft == 1 ? SECOND : SECONDS);
return minutes + (minutes == 1 ? MINUTE : MINUTES);
}
String format;
if (minutes < 60)
return formatMinutes(minutes, secondsLeft);
// Greater than 1 hour, only in hours
int hours = minutes / 60;
format = hours + (hours == 1 ? HOUR : HOURS);
int inMins = 60 * hours;
int left = minutes - inMins;
int minutesLeft = minutes % 60;
if (left >= 1)
format = format + " " + left + (left == 1 ? MINUTE : MINUTES);
return formatHours(hours, minutesLeft, secondsLeft);
}
private String formatSeconds(long seconds) {
return seconds + (seconds == 1 ? TimeConstants.getSeconds() : TimeConstants.getSecond());
}
private String formatMinutes(int minutes, int secondsLeft) {
String format = minutes + (minutes == 1 ? TimeConstants.getMinute() : TimeConstants.getMinutes());
if (secondsLeft > 0)
format = format + " " + secondsLeft + (secondsLeft == 1 ? SECOND : SECONDS);
format += formatSeconds(secondsLeft);
return format;
}
private String formatHours(int hours, int minutesLeft, int secondsLeft) {
String format = hours + (hours == 1 ? TimeConstants.getHour() : TimeConstants.getHours());
if (minutesLeft >= 1)
format += formatMinutes(minutesLeft, secondsLeft);
else if (secondsLeft > 0)
format += formatSeconds(secondsLeft);
return format;
}
}
@@ -1,5 +1,6 @@
package me.codedred.playtimes.time.formats;
import me.codedred.playtimes.time.TimeConstants;
import me.codedred.playtimes.time.Timings;
public class NoDaysNoSeconds implements Timings {
@@ -7,23 +8,23 @@ public class NoDaysNoSeconds implements Timings {
@Override
public String buildFormat(long time) {
if (time < 60)
return time + ( time == 1 ? SECONDS : SECOND);
return time + ( time == 1 ? TimeConstants.getSeconds() : TimeConstants.getSecond());
int minutes = (int) (time / 60);
// Time less than 1 hour
if (minutes < 60)
return minutes + (minutes == 1 ? MINUTE : MINUTES);
return minutes + (minutes == 1 ? TimeConstants.getMinute() : TimeConstants.getMinutes());
String format;
int hours = minutes / 60;
format = hours + (hours == 1 ? HOUR : HOURS);
format = hours + (hours == 1 ? TimeConstants.getHour() : TimeConstants.getHours());
int inMins = 60 * hours;
int left = minutes - inMins;
if (left >= 1)
format = format + " " + left + (left == 1 ? MINUTE : MINUTES);
format = format + left + (left == 1 ? TimeConstants.getMinute() : TimeConstants.getMinutes());
return format;
@@ -1,5 +1,6 @@
package me.codedred.playtimes.time.formats;
import me.codedred.playtimes.time.TimeConstants;
import me.codedred.playtimes.time.Timings;
public class NoSeconds implements Timings {
@@ -7,49 +8,51 @@ public class NoSeconds implements Timings {
@Override
public String buildFormat(long time) {
if (time < 60)
return time + ( time == 1 ? SECONDS : SECOND);
return formatSeconds(time);
int minutes = (int) (time / 60);
// Time less than 1 hour
if (minutes < 60)
return minutes + (minutes == 1 ? MINUTE : MINUTES);
String format;
return formatMinutes(minutes);
// Time less than 1 Day
if (minutes < 1440) {
int hours = minutes / 60;
format = hours + (hours == 1 ? HOUR : HOURS);
int inMins = 60 * hours;
int left = minutes - inMins;
if (left >= 1)
format = format + " " + left + (left == 1 ? MINUTE : MINUTES);
return format;
int minutesLeft = minutes % 60;
return formatHours(hours, minutesLeft);
}
// Time greater than 1 day
int days = minutes / 1440;
format = days + (days == 1 ? DAY : DAYS);
int inMins = 1440 * days;
int leftOver = minutes - inMins;
if (leftOver >= 1) {
if (leftOver < 60) {
format = format + " " + leftOver + (leftOver == 1 ? MINUTE : MINUTES);
}
else {
int hours = leftOver / 60;
format = format + " " + hours + (hours == 1 ? HOUR : HOURS);
int hoursInMins = 60 * hours;
int minsLeft = leftOver - hoursInMins;
if (leftOver >= 1) {
format = format + " " + minsLeft + (minsLeft == 1 ? MINUTE : MINUTES);
}
}
}
int minutesLeft = minutes % 1440;
return formatDays(days, minutesLeft);
}
private String formatSeconds(long seconds) {
return seconds + (seconds == 1 ? TimeConstants.getSeconds() : TimeConstants.getSecond());
}
private String formatMinutes(int minutes) {
return minutes + (minutes == 1 ? TimeConstants.getMinute() : TimeConstants.getMinutes());
}
private String formatHours(int hours, int minutesLeft) {
String format = hours + (hours == 1 ? TimeConstants.getHour() : TimeConstants.getHours());
if (minutesLeft >= 1)
format += formatMinutes(minutesLeft);
return format;
}
private String formatDays(int days, int minutesLeft) {
String format = days + (days == 1 ? TimeConstants.getDay() : TimeConstants.getDays());
if (minutesLeft >= 60) {
int hours = minutesLeft / 60;
int minutesAfterHours = minutesLeft % 60;
format += formatHours(hours, minutesAfterHours);
} else if (minutesLeft >= 1) {
format += formatMinutes(minutesLeft);
}
return format;
}
}
@@ -1,12 +1,13 @@
package me.codedred.playtimes.time.formats;
import me.codedred.playtimes.time.TimeConstants;
import me.codedred.playtimes.time.Timings;
public class OnlyHours implements Timings {
@Override
public String buildFormat(long time) {
return ((double)Math.round((time/3600.0)*100d))/100d + HOURS;
return (Math.round((time/3600.0)*100d))/100d + TimeConstants.getHours();
}
}
@@ -6,39 +6,36 @@ import org.bukkit.command.CommandSender;
public class ChatUtil {
public enum ChatTypes {
private static final DataManager DATA_MANAGER = DataManager.getInstance();
private static final boolean IS_NEWER_VERSION = ServerUtils.isNewerVersion();
public enum ChatTypes {
NO_PERMISSION,
PLAYER_NOT_FOUND,
PLAYER_NEVER_PLAYED
}
public static void errno(CommandSender sender, ChatTypes type) {
DataManager data = DataManager.getInstance();
switch (type) {
case NO_PERMISSION:
sender.sendMessage(format(data.getConfig().getString("messages.noPermission")));
break;
case PLAYER_NOT_FOUND:
sender.sendMessage(formatWithPrefix(data.getConfig().getString("messages.player-not-found")));
break;
case PLAYER_NEVER_PLAYED:
sender.sendMessage(formatWithPrefix(data.getConfig().getString("messages.player-never-joined")));
break;
case NO_PERMISSION ->
sender.sendMessage(format(DATA_MANAGER.getConfig().getString("messages.noPermission")));
case PLAYER_NOT_FOUND ->
sender.sendMessage(formatWithPrefix(DATA_MANAGER.getConfig().getString("messages.player-not-found")));
case PLAYER_NEVER_PLAYED ->
sender.sendMessage(formatWithPrefix(DATA_MANAGER.getConfig().getString("messages.player-never-joined")));
}
}
public static String format(String msg) {
msg = ChatColor.translateAlternateColorCodes('&', msg);
if (ServerUtils.isNewerVersion())
if (IS_NEWER_VERSION)
msg = HexUtil.hex(msg);
return msg;
}
public static String formatWithPrefix(String msg) {
msg = ChatColor.translateAlternateColorCodes('&', DataManager.getInstance().getConfig().getString("prefix") + " " + msg);
if (ServerUtils.isNewerVersion())
msg = ChatColor.translateAlternateColorCodes('&', DATA_MANAGER.getConfig().getString("prefix") + " " + msg);
if (IS_NEWER_VERSION)
msg = HexUtil.hex(msg);
return msg;
}
@@ -1,13 +1,15 @@
package me.codedred.playtimes.utils;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
import java.util.UUID;
public class CoolDownUtil {
private static Hashtable<UUID, Long> cooldowns = new Hashtable<>();
private CoolDownUtil() {
throw new IllegalStateException("Utility Class");
}
private static final HashMap<UUID, Long> cooldowns = new HashMap<>();
public static void remove(UUID uuid) {
cooldowns.remove(uuid);
@@ -2,21 +2,33 @@ package me.codedred.playtimes.utils;
import net.md_5.bungee.api.ChatColor;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class HexUtil {
private static final Pattern hexPattern = Pattern.compile("<#([A-Fa-f0-9]){6}>");
public static String hex(String message){
Matcher matcher = hexPattern.matcher(message);
while (matcher.find()) {
ChatColor hexColor = ChatColor.of(matcher.group().substring(1, matcher.group().length() - 1));
String before = message.substring(0, matcher.start());
String after = message.substring(matcher.end());
message = before + hexColor + after;
matcher = hexPattern.matcher(message);
}
return ChatColor.translateAlternateColorCodes('&', message);
private HexUtil() {
throw new IllegalStateException("Utility Class");
}
}
public static String hex(String message) {
StringBuilder builder = new StringBuilder();
int index = 0;
while (index < message.length()) {
int colorCodeStart = message.indexOf("<#", index);
if (colorCodeStart != -1) {
int colorCodeEnd = message.indexOf(">", colorCodeStart + 2);
if (colorCodeEnd != -1) {
builder.append(message, index, colorCodeStart);
String hexCode = message.substring(colorCodeStart + 2, colorCodeEnd);
ChatColor hexColor = ChatColor.of('#' + hexCode);
builder.append(hexColor);
index = colorCodeEnd + 1;
continue;
}
}
builder.append(message.substring(index));
break;
}
return ChatColor.translateAlternateColorCodes('&', builder.toString());
}
}
@@ -6,33 +6,29 @@ import org.bukkit.entity.Player;
public class PAPIHolders {
/***
private PAPIHolders() {
throw new IllegalStateException("Utility class");
}
/**
* Translates PAPI holders
*
* @param player - receiver
* @param msg - message that is being checked/translated
* @return fixed message with updated PAPI holders
*
* @param player the receiver of the message
* @param msg the message that is being checked/translated
* @return the fixed message with updated PAPI holders
*/
public static String getHolders(Player player, String msg) {
try {
return PlaceholderAPI.setPlaceholders(player, msg);
} catch (Exception e) {
return msg;
}
return PlaceholderAPI.setPlaceholders(player, msg);
}
/***
* Translates PAPI holders for offline player
*
* @param player - receiver
* @param msg - message that is being checked/translated
* @return fixed message with updated PAPI holders
/**
* Translates PAPI holders for offline players
*
* @param player the receiver of the message
* @param msg the message that is being checked/translated
* @return the fixed message with updated PAPI holders
*/
public static String getHolders(OfflinePlayer player, String msg) {
try {
return PlaceholderAPI.setPlaceholders(player, msg);
} catch (Exception e) {
return msg;
}
return PlaceholderAPI.setPlaceholders(player, msg);
}
}
@@ -8,20 +8,38 @@ import java.lang.reflect.Method;
public class ServerUtils {
public static boolean isNewerVersion() {
try {
Class<?> class_Material = Material.class;
Method method = class_Material.getDeclaredMethod("matchMaterial", String.class, Boolean.TYPE);
return (method != null);
} catch(ReflectiveOperationException ex) {
return false;
}
private static Boolean isNewerVersion = null;
private ServerUtils() {
throw new IllegalStateException("Utility Class");
}
public static boolean isRisenVersion() {
return Bukkit.getServer().getVersion().contains("1.17");
public static boolean isNewerVersion() {
if (isNewerVersion == null) {
try {
Class<?> classMaterial = Material.class;
Method method = classMaterial.getDeclaredMethod("matchMaterial", String.class, boolean.class);
isNewerVersion = (method != null);
} catch (ReflectiveOperationException ex) {
isNewerVersion = false;
}
}
return isNewerVersion;
}
/**
* Checks if the server version is 1.17+
*
* @return true if so
*/
public static boolean isRisenVersion() {
String[] versionParts = Bukkit.getServer().getVersion().split("\\.");
int majorVersion = Integer.parseInt(versionParts[1]);
int minorVersion = Integer.parseInt(versionParts[2].replaceAll("[^0-9]", ""));
return majorVersion >= 17 && minorVersion >= 0;
}
public static boolean hasPAPI() {
if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null)
return DataManager.getInstance().getConfig().getBoolean("use-papi-placeholders");
+29 -29
View File
@@ -4,38 +4,16 @@
# Prefix will show before 'player-not-found' & 'player-never-joined' messages
prefix: "&7[&b&lPlayTimes&7]"
# date-format can be changed to your liking.
# For more placeholders look here: https://docs.oracle.com/javase/8/docs/api/java/text/SimpleDateFormat.html
# This is the join date format.
date-format: MM/dd/yyyy
# Placeholders API info
# Placeholders API info
# Only enable this if you are using PAPI holders in PlayTimes
# If you want to use PlayTimes placeholders in other plugins...
# Just download PAPI and it will *automatically* register
use-papi-placeholders: false
# Main Playtimes info.
# The name refers to the format. Example if you have minute = " min" then it will display "x min"
# PlayTimes format & message settings
# The name refers to the format. See spigot plugin page for format examples
playtime:
name:
second: "s"
minute: "min"
hour: "hr"
day: "day"
seconds: "s"
minutes: "mins"
hours: "hrs"
days: "days"
## only-hours - when true it will display playtime in hours (When true this will also disable show-seconds/days setting)
## show-seconds - when true it will display seconds
## show-days - when true it will display days
only-hours: false
show-seconds: true
show-days: true
## Built-in Placeholders:
## %player% %time% %timesjoined% %joindate%
## You may also use PAPI Placeholders
@@ -45,6 +23,22 @@ playtime:
- "&aTimes joined:&f %timesjoined%"
- "&aJoined Date:&f %joindate%"
- "&b&m============================"
name:
second: "s"
minute: "min "
hour: "hr "
day: "day "
seconds: "s"
minutes: "mins "
hours: "hrs "
days: "days "
## only-hours - when true it will display playtime in hours (When true this will also disable show-seconds/days setting)
## show-seconds - when true it will display seconds
## show-days - when true it will display days
only-hours: false
show-seconds: true
show-days: true
# /Uptime command info - only placeholder is %serveruptime%
uptime:
@@ -53,10 +47,10 @@ uptime:
- "&aServer Uptime:&f %serveruptime%"
- "&b&m============================"
# /toppt command info
## Built-in Placeholders:
## %player% %place% %time% %joindate%
## You may also use PAPI placeholders
# /toppt command info
## Built-in Placeholders:
## %player% %place% %time% %joindate%
## You may also use PAPI placeholders
top-playtime:
header: "&b******&9[&3&lPlayTime Leaderboards&9]&b*****"
content: "&5%place%) &9&l%player% &9&o- %time%"
@@ -64,6 +58,12 @@ top-playtime:
enable-cooldown: true
cooldown-seconds: 60
# date-format can be changed to your liking.
# For more placeholders look here: https://docs.oracle.com/javase/8/docs/api/java/text/SimpleDateFormat.html
# This is the join date format.
date-format: "MM/dd/yyyy"
# Built in messages, may change to your liking :D
messages:
noPermission: "&cYou cannot run this command."
+3 -3
View File
@@ -3,8 +3,8 @@ main: me.codedred.playtimes.PlayTimes
# Keeping 'Cmaaxx' as author for Metric purposes.
author: Cmaaxx
authors: [CodedRed]
version: 1.4.5
softdepend: [PlaceholdersAPI, PlaceholderAPI]
version: 1.5
softdepend: [PlaceholderAPI]
commands:
playtime:
@@ -21,4 +21,4 @@ commands:
description: Check your servers uptime!
usage: /topplaytime
permission: pt.top
aliases: [toppt, topplayt]
aliases: [topplayt, toppt]