初始提交
This commit is contained in:
@@ -0,0 +1,4 @@
|
|||||||
|
.gradle
|
||||||
|
.idea
|
||||||
|
build
|
||||||
|
bin
|
||||||
@@ -0,0 +1,121 @@
|
|||||||
|
Creative Commons Legal Code
|
||||||
|
|
||||||
|
CC0 1.0 Universal
|
||||||
|
|
||||||
|
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
|
||||||
|
LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
|
||||||
|
ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
|
||||||
|
INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
|
||||||
|
REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
|
||||||
|
PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
|
||||||
|
THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
|
||||||
|
HEREUNDER.
|
||||||
|
|
||||||
|
Statement of Purpose
|
||||||
|
|
||||||
|
The laws of most jurisdictions throughout the world automatically confer
|
||||||
|
exclusive Copyright and Related Rights (defined below) upon the creator
|
||||||
|
and subsequent owner(s) (each and all, an "owner") of an original work of
|
||||||
|
authorship and/or a database (each, a "Work").
|
||||||
|
|
||||||
|
Certain owners wish to permanently relinquish those rights to a Work for
|
||||||
|
the purpose of contributing to a commons of creative, cultural and
|
||||||
|
scientific works ("Commons") that the public can reliably and without fear
|
||||||
|
of later claims of infringement build upon, modify, incorporate in other
|
||||||
|
works, reuse and redistribute as freely as possible in any form whatsoever
|
||||||
|
and for any purposes, including without limitation commercial purposes.
|
||||||
|
These owners may contribute to the Commons to promote the ideal of a free
|
||||||
|
culture and the further production of creative, cultural and scientific
|
||||||
|
works, or to gain reputation or greater distribution for their Work in
|
||||||
|
part through the use and efforts of others.
|
||||||
|
|
||||||
|
For these and/or other purposes and motivations, and without any
|
||||||
|
expectation of additional consideration or compensation, the person
|
||||||
|
associating CC0 with a Work (the "Affirmer"), to the extent that he or she
|
||||||
|
is an owner of Copyright and Related Rights in the Work, voluntarily
|
||||||
|
elects to apply CC0 to the Work and publicly distribute the Work under its
|
||||||
|
terms, with knowledge of his or her Copyright and Related Rights in the
|
||||||
|
Work and the meaning and intended legal effect of CC0 on those rights.
|
||||||
|
|
||||||
|
1. Copyright and Related Rights. A Work made available under CC0 may be
|
||||||
|
protected by copyright and related or neighboring rights ("Copyright and
|
||||||
|
Related Rights"). Copyright and Related Rights include, but are not
|
||||||
|
limited to, the following:
|
||||||
|
|
||||||
|
i. the right to reproduce, adapt, distribute, perform, display,
|
||||||
|
communicate, and translate a Work;
|
||||||
|
ii. moral rights retained by the original author(s) and/or performer(s);
|
||||||
|
iii. publicity and privacy rights pertaining to a person's image or
|
||||||
|
likeness depicted in a Work;
|
||||||
|
iv. rights protecting against unfair competition in regards to a Work,
|
||||||
|
subject to the limitations in paragraph 4(a), below;
|
||||||
|
v. rights protecting the extraction, dissemination, use and reuse of data
|
||||||
|
in a Work;
|
||||||
|
vi. database rights (such as those arising under Directive 96/9/EC of the
|
||||||
|
European Parliament and of the Council of 11 March 1996 on the legal
|
||||||
|
protection of databases, and under any national implementation
|
||||||
|
thereof, including any amended or successor version of such
|
||||||
|
directive); and
|
||||||
|
vii. other similar, equivalent or corresponding rights throughout the
|
||||||
|
world based on applicable law or treaty, and any national
|
||||||
|
implementations thereof.
|
||||||
|
|
||||||
|
2. Waiver. To the greatest extent permitted by, but not in contravention
|
||||||
|
of, applicable law, Affirmer hereby overtly, fully, permanently,
|
||||||
|
irrevocably and unconditionally waives, abandons, and surrenders all of
|
||||||
|
Affirmer's Copyright and Related Rights and associated claims and causes
|
||||||
|
of action, whether now known or unknown (including existing as well as
|
||||||
|
future claims and causes of action), in the Work (i) in all territories
|
||||||
|
worldwide, (ii) for the maximum duration provided by applicable law or
|
||||||
|
treaty (including future time extensions), (iii) in any current or future
|
||||||
|
medium and for any number of copies, and (iv) for any purpose whatsoever,
|
||||||
|
including without limitation commercial, advertising or promotional
|
||||||
|
purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
|
||||||
|
member of the public at large and to the detriment of Affirmer's heirs and
|
||||||
|
successors, fully intending that such Waiver shall not be subject to
|
||||||
|
revocation, rescission, cancellation, termination, or any other legal or
|
||||||
|
equitable action to disrupt the quiet enjoyment of the Work by the public
|
||||||
|
as contemplated by Affirmer's express Statement of Purpose.
|
||||||
|
|
||||||
|
3. Public License Fallback. Should any part of the Waiver for any reason
|
||||||
|
be judged legally invalid or ineffective under applicable law, then the
|
||||||
|
Waiver shall be preserved to the maximum extent permitted taking into
|
||||||
|
account Affirmer's express Statement of Purpose. In addition, to the
|
||||||
|
extent the Waiver is so judged Affirmer hereby grants to each affected
|
||||||
|
person a royalty-free, non transferable, non sublicensable, non exclusive,
|
||||||
|
irrevocable and unconditional license to exercise Affirmer's Copyright and
|
||||||
|
Related Rights in the Work (i) in all territories worldwide, (ii) for the
|
||||||
|
maximum duration provided by applicable law or treaty (including future
|
||||||
|
time extensions), (iii) in any current or future medium and for any number
|
||||||
|
of copies, and (iv) for any purpose whatsoever, including without
|
||||||
|
limitation commercial, advertising or promotional purposes (the
|
||||||
|
"License"). The License shall be deemed effective as of the date CC0 was
|
||||||
|
applied by Affirmer to the Work. Should any part of the License for any
|
||||||
|
reason be judged legally invalid or ineffective under applicable law, such
|
||||||
|
partial invalidity or ineffectiveness shall not invalidate the remainder
|
||||||
|
of the License, and in such case Affirmer hereby affirms that he or she
|
||||||
|
will not (i) exercise any of his or her remaining Copyright and Related
|
||||||
|
Rights in the Work or (ii) assert any associated claims and causes of
|
||||||
|
action with respect to the Work, in either case contrary to Affirmer's
|
||||||
|
express Statement of Purpose.
|
||||||
|
|
||||||
|
4. Limitations and Disclaimers.
|
||||||
|
|
||||||
|
a. No trademark or patent rights held by Affirmer are waived, abandoned,
|
||||||
|
surrendered, licensed or otherwise affected by this document.
|
||||||
|
b. Affirmer offers the Work as-is and makes no representations or
|
||||||
|
warranties of any kind concerning the Work, express, implied,
|
||||||
|
statutory or otherwise, including without limitation warranties of
|
||||||
|
title, merchantability, fitness for a particular purpose, non
|
||||||
|
infringement, or the absence of latent or other defects, accuracy, or
|
||||||
|
the present or absence of errors, whether or not discoverable, all to
|
||||||
|
the greatest extent permissible under applicable law.
|
||||||
|
c. Affirmer disclaims responsibility for clearing rights of other persons
|
||||||
|
that may apply to the Work or any use thereof, including without
|
||||||
|
limitation any person's Copyright and Related Rights in the Work.
|
||||||
|
Further, Affirmer disclaims responsibility for obtaining any necessary
|
||||||
|
consents, permissions or other rights required for any use of the
|
||||||
|
Work.
|
||||||
|
d. Affirmer understands and acknowledges that Creative Commons is not a
|
||||||
|
party to this document and has no duty or obligation with respect to
|
||||||
|
this CC0 or use of the Work.
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
# Building
|
||||||
|
|
||||||
|
* [Gradle](https://gradle.org/) - Dependency Management
|
||||||
|
|
||||||
|
The GradleWrapper in included in this project.
|
||||||
|
|
||||||
|
**Windows:**
|
||||||
|
|
||||||
|
```
|
||||||
|
gradlew.bat clean build
|
||||||
|
```
|
||||||
|
|
||||||
|
**macOS/Linux:**
|
||||||
|
|
||||||
|
```
|
||||||
|
./gradlew clean build
|
||||||
|
```
|
||||||
|
|
||||||
|
Build artifacts should be found in `./build/libs` folder.
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
plugins {
|
||||||
|
`java-library`
|
||||||
|
`maven-publish`
|
||||||
|
id("io.izzel.taboolib") version "1.42"
|
||||||
|
id("org.jetbrains.kotlin.jvm") version "1.5.10"
|
||||||
|
}
|
||||||
|
|
||||||
|
taboolib {
|
||||||
|
description {
|
||||||
|
dependencies {
|
||||||
|
name("PlaceholderAPI").optional(true)
|
||||||
|
name("Vault").optional(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
install("common")
|
||||||
|
install("common-5")
|
||||||
|
install("module-chat")
|
||||||
|
install("module-configuration")
|
||||||
|
install("module-database")
|
||||||
|
install("module-lang")
|
||||||
|
install("module-ui")
|
||||||
|
install("module-nms-util")
|
||||||
|
install("module-nms")
|
||||||
|
install("platform-bukkit")
|
||||||
|
install("expansion-command-helper")
|
||||||
|
classifier = null
|
||||||
|
version = "6.0.9-84"
|
||||||
|
}
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
maven("https://repo.xbaimiao.com/nexus/content/repositories/releases/")
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
compileOnly("ink.ptms:nms-all:1.0.0")
|
||||||
|
compileOnly("public:papi:1.0.0")
|
||||||
|
compileOnly("public:vault:1.0.0")
|
||||||
|
compileOnly("ink.ptms.core:v11902:11902-minimize:mapped")
|
||||||
|
compileOnly("ink.ptms.core:v11902:11902-minimize:universal")
|
||||||
|
compileOnly(kotlin("stdlib"))
|
||||||
|
compileOnly(fileTree("libs"))
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.withType<JavaCompile> {
|
||||||
|
options.encoding = "UTF-8"
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
|
||||||
|
kotlinOptions {
|
||||||
|
jvmTarget = "1.8"
|
||||||
|
freeCompilerArgs = listOf("-Xjvm-default=all")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
configure<JavaPluginConvention> {
|
||||||
|
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||||
|
targetCompatibility = JavaVersion.VERSION_1_8
|
||||||
|
}
|
||||||
|
|
||||||
|
publishing {
|
||||||
|
repositories {
|
||||||
|
maven {
|
||||||
|
url = uri("https://repo.tabooproject.org/repository/releases")
|
||||||
|
credentials {
|
||||||
|
username = project.findProperty("taboolibUsername").toString()
|
||||||
|
password = project.findProperty("taboolibPassword").toString()
|
||||||
|
}
|
||||||
|
authentication {
|
||||||
|
create<BasicAuthentication>("basic")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
publications {
|
||||||
|
create<MavenPublication>("library") {
|
||||||
|
from(components["java"])
|
||||||
|
groupId = project.group.toString()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
group=com.github.xbaimiao.shoppro
|
||||||
|
version=1.0.0
|
||||||
Vendored
BIN
Binary file not shown.
+5
@@ -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
|
||||||
@@ -0,0 +1,172 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
##
|
||||||
|
## Gradle start up script for UN*X
|
||||||
|
##
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
# Attempt to set APP_HOME
|
||||||
|
# Resolve links: $0 may be a link
|
||||||
|
PRG="$0"
|
||||||
|
# Need this for relative symlinks.
|
||||||
|
while [ -h "$PRG" ] ; do
|
||||||
|
ls=`ls -ld "$PRG"`
|
||||||
|
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||||
|
if expr "$link" : '/.*' > /dev/null; then
|
||||||
|
PRG="$link"
|
||||||
|
else
|
||||||
|
PRG=`dirname "$PRG"`"/$link"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
SAVED="`pwd`"
|
||||||
|
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||||
|
APP_HOME="`pwd -P`"
|
||||||
|
cd "$SAVED" >/dev/null
|
||||||
|
|
||||||
|
APP_NAME="Gradle"
|
||||||
|
APP_BASE_NAME=`basename "$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=""
|
||||||
|
|
||||||
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
|
MAX_FD="maximum"
|
||||||
|
|
||||||
|
warn () {
|
||||||
|
echo "$*"
|
||||||
|
}
|
||||||
|
|
||||||
|
die () {
|
||||||
|
echo
|
||||||
|
echo "$*"
|
||||||
|
echo
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# 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
|
||||||
|
;;
|
||||||
|
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" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||||
|
MAX_FD_LIMIT=`ulimit -H -n`
|
||||||
|
if [ $? -eq 0 ] ; then
|
||||||
|
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||||
|
MAX_FD="$MAX_FD_LIMIT"
|
||||||
|
fi
|
||||||
|
ulimit -n $MAX_FD
|
||||||
|
if [ $? -ne 0 ] ; then
|
||||||
|
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Darwin, add options to specify how the application appears in the dock
|
||||||
|
if $darwin; then
|
||||||
|
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Cygwin, switch paths to Windows format before running java
|
||||||
|
if $cygwin ; then
|
||||||
|
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||||
|
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||||
|
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||||
|
|
||||||
|
# We build the pattern for arguments to be converted via cygpath
|
||||||
|
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||||
|
SEP=""
|
||||||
|
for dir in $ROOTDIRSRAW ; do
|
||||||
|
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||||
|
SEP="|"
|
||||||
|
done
|
||||||
|
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||||
|
# Add a user-defined pattern to the cygpath arguments
|
||||||
|
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||||
|
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||||
|
fi
|
||||||
|
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||||
|
i=0
|
||||||
|
for arg in "$@" ; do
|
||||||
|
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||||
|
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||||
|
|
||||||
|
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||||
|
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||||
|
else
|
||||||
|
eval `echo args$i`="\"$arg\""
|
||||||
|
fi
|
||||||
|
i=$((i+1))
|
||||||
|
done
|
||||||
|
case $i in
|
||||||
|
(0) set -- ;;
|
||||||
|
(1) set -- "$args0" ;;
|
||||||
|
(2) set -- "$args0" "$args1" ;;
|
||||||
|
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||||
|
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||||
|
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||||
|
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||||
|
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||||
|
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||||
|
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Escape application args
|
||||||
|
save () {
|
||||||
|
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||||
|
echo " "
|
||||||
|
}
|
||||||
|
APP_ARGS=$(save "$@")
|
||||||
|
|
||||||
|
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||||
|
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||||
|
|
||||||
|
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
|
||||||
|
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
||||||
|
cd "$(dirname "$0")"
|
||||||
|
fi
|
||||||
|
|
||||||
|
exec "$JAVACMD" "$@"
|
||||||
Vendored
+84
@@ -0,0 +1,84 @@
|
|||||||
|
@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 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=
|
||||||
|
|
||||||
|
@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 init
|
||||||
|
|
||||||
|
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 init
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
:init
|
||||||
|
@rem Get command-line arguments, handling Windows variants
|
||||||
|
|
||||||
|
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||||
|
|
||||||
|
:win9xME_args
|
||||||
|
@rem Slurp the command line arguments.
|
||||||
|
set CMD_LINE_ARGS=
|
||||||
|
set _SKIP=2
|
||||||
|
|
||||||
|
:win9xME_args_slurp
|
||||||
|
if "x%~1" == "x" goto execute
|
||||||
|
|
||||||
|
set CMD_LINE_ARGS=%*
|
||||||
|
|
||||||
|
: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 %CMD_LINE_ARGS%
|
||||||
|
|
||||||
|
: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
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
rootProject.name="ShopPro"
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package com.github.xbaimiao.shoppro
|
||||||
|
|
||||||
|
import com.github.xbaimiao.shoppro.core.database.Database
|
||||||
|
import com.github.xbaimiao.shoppro.core.shop.ShopManager
|
||||||
|
import taboolib.common.platform.Plugin
|
||||||
|
import taboolib.module.configuration.Config
|
||||||
|
import taboolib.module.configuration.Configuration
|
||||||
|
|
||||||
|
object ShopPro : Plugin() {
|
||||||
|
|
||||||
|
@Config(value = "config.yml")
|
||||||
|
lateinit var config: Configuration
|
||||||
|
private set
|
||||||
|
|
||||||
|
lateinit var database: Database
|
||||||
|
|
||||||
|
override fun onEnable() {
|
||||||
|
ShopManager.load()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun reload() {
|
||||||
|
ShopManager.shops.clear()
|
||||||
|
ShopManager.load()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package com.github.xbaimiao.shoppro
|
||||||
|
|
||||||
|
import java.text.DecimalFormat
|
||||||
|
|
||||||
|
|
||||||
|
object Util {
|
||||||
|
|
||||||
|
fun Double.format(): Double {
|
||||||
|
val df = DecimalFormat("#0.00")
|
||||||
|
return df.format(this).toDouble()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package com.github.xbaimiao.shoppro.api
|
||||||
|
|
||||||
|
import com.github.xbaimiao.shoppro.core.item.ShopItem
|
||||||
|
import org.bukkit.entity.Player
|
||||||
|
import org.bukkit.event.Event
|
||||||
|
import org.bukkit.event.HandlerList
|
||||||
|
|
||||||
|
class ShopProBuyEvent(
|
||||||
|
val item: ShopItem,
|
||||||
|
val amount: Int,
|
||||||
|
val player: Player
|
||||||
|
) : Event() {
|
||||||
|
|
||||||
|
override fun getHandlers(): HandlerList {
|
||||||
|
return handlerList
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val handlerList = HandlerList()
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun getHandlerList(): HandlerList {
|
||||||
|
return handlerList
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package com.github.xbaimiao.shoppro.api
|
||||||
|
|
||||||
|
import com.github.xbaimiao.shoppro.core.item.ShopItem
|
||||||
|
import org.bukkit.entity.Player
|
||||||
|
import org.bukkit.event.Event
|
||||||
|
import org.bukkit.event.HandlerList
|
||||||
|
import org.bukkit.event.inventory.ClickType
|
||||||
|
import org.bukkit.inventory.Inventory
|
||||||
|
|
||||||
|
class ShopProSellEvent(
|
||||||
|
val item: ShopItem,
|
||||||
|
val amount: Int,
|
||||||
|
val player: Player
|
||||||
|
) : Event() {
|
||||||
|
|
||||||
|
override fun getHandlers(): HandlerList {
|
||||||
|
return handlerList
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val handlerList = HandlerList()
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun getHandlerList(): HandlerList? {
|
||||||
|
return handlerList
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
package com.github.xbaimiao.shoppro.core
|
||||||
|
|
||||||
|
import com.github.xbaimiao.shoppro.core.shop.ShopManager
|
||||||
|
import org.bukkit.Bukkit
|
||||||
|
import org.bukkit.command.CommandSender
|
||||||
|
import org.bukkit.entity.Player
|
||||||
|
import taboolib.common.platform.command.*
|
||||||
|
import taboolib.expansion.createHelper
|
||||||
|
import taboolib.platform.util.onlinePlayers
|
||||||
|
|
||||||
|
@CommandHeader("shoppro", aliases = ["sp"], permissionDefault = PermissionDefault.TRUE)
|
||||||
|
object Commands {
|
||||||
|
|
||||||
|
@CommandBody
|
||||||
|
val main = mainCommand {
|
||||||
|
createHelper()
|
||||||
|
}
|
||||||
|
|
||||||
|
@CommandBody
|
||||||
|
val open = subCommand {
|
||||||
|
dynamic("name") {
|
||||||
|
suggestion<CommandSender> { _, _ ->
|
||||||
|
ShopManager.shops.map { it.getName() }
|
||||||
|
}
|
||||||
|
execute<Player> { sender, _, argument ->
|
||||||
|
val shop = ShopManager.shops.first { it.getName() == argument }
|
||||||
|
shop.open(sender)
|
||||||
|
}
|
||||||
|
dynamic("玩家", permission = "admin") {
|
||||||
|
suggestion<CommandSender> { _, _ ->
|
||||||
|
onlinePlayers.map { it.name }
|
||||||
|
}
|
||||||
|
execute<CommandSender> { _, context, argument ->
|
||||||
|
val player = Bukkit.getPlayerExact(argument)!!
|
||||||
|
val shop = ShopManager.shops.first { it.getName() == context.argument(-1) }
|
||||||
|
shop.open(player)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package com.github.xbaimiao.shoppro.core.database
|
||||||
|
|
||||||
|
import com.github.xbaimiao.shoppro.core.item.Item
|
||||||
|
import org.bukkit.entity.Player
|
||||||
|
|
||||||
|
interface Database {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取该物品该玩家今日已购买多少次了
|
||||||
|
*/
|
||||||
|
fun getPlayerLimit(player: Player, item: Item): Long
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置该物品该玩家今日已购买多少次了
|
||||||
|
*/
|
||||||
|
fun setPlayerLimit(player: Player, item: Item, amount: Long)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取该物品今日已购买多少次了
|
||||||
|
*/
|
||||||
|
fun getServerLimit(item: Item)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置该物品今日已购买多少次了
|
||||||
|
*/
|
||||||
|
fun setServerLimit(item: Item, amount: Long)
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
package com.github.xbaimiao.shoppro.core.item
|
||||||
|
|
||||||
|
import com.github.xbaimiao.shoppro.core.shop.ShopManager
|
||||||
|
import com.github.xbaimiao.shoppro.core.vault.Vault
|
||||||
|
import com.github.xbaimiao.shoppro.core.vault.VaultImpl
|
||||||
|
import org.bukkit.Bukkit
|
||||||
|
import org.bukkit.Material
|
||||||
|
import org.bukkit.entity.Player
|
||||||
|
import org.bukkit.inventory.ItemStack
|
||||||
|
import org.bukkit.permissions.Permission
|
||||||
|
import taboolib.module.chat.colored
|
||||||
|
|
||||||
|
interface Item {
|
||||||
|
|
||||||
|
val key: Char
|
||||||
|
val material: Material
|
||||||
|
val lore: List<String>
|
||||||
|
val name: String
|
||||||
|
val vanilla: Boolean
|
||||||
|
val commands: List<String>
|
||||||
|
|
||||||
|
val vault: Vault
|
||||||
|
get() = VaultImpl
|
||||||
|
|
||||||
|
fun isCommodity(): Boolean
|
||||||
|
fun buildItem(): ItemStack
|
||||||
|
fun update(player: Player, itemStack: ItemStack)
|
||||||
|
|
||||||
|
fun exeCommands(player: Player) {
|
||||||
|
commands.map { it.replace("%player%", player.name) }.forEach { command ->
|
||||||
|
if (command.startsWith("[tell] ")) {
|
||||||
|
player.sendMessage(command.substring(7).colored())
|
||||||
|
} else if (command.startsWith("[console] ")) {
|
||||||
|
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), command.substring(10))
|
||||||
|
} else if (command.startsWith("[player] ")) {
|
||||||
|
Bukkit.dispatchCommand(player, command.substring(9))
|
||||||
|
} else if (command.startsWith("[open] ")) {
|
||||||
|
val shop = ShopManager.shops.firstOrNull { it.getName() == command.substring(7) }
|
||||||
|
shop?.open(player)
|
||||||
|
} else if (command.startsWith("[op] ")) {
|
||||||
|
Bukkit.dispatchCommand(object : Player by player {
|
||||||
|
override fun isOp() = true
|
||||||
|
override fun hasPermission(p0: Permission) = true
|
||||||
|
override fun hasPermission(p0: String) = true
|
||||||
|
}, command.substring(5))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
package com.github.xbaimiao.shoppro.core.item
|
||||||
|
|
||||||
|
import me.clip.placeholderapi.PlaceholderAPI
|
||||||
|
import org.bukkit.Material
|
||||||
|
import org.bukkit.entity.Player
|
||||||
|
import org.bukkit.inventory.ItemStack
|
||||||
|
import taboolib.platform.util.modifyLore
|
||||||
|
|
||||||
|
open class ItemImpl(
|
||||||
|
override val material: Material, override val lore: List<String>, override val name: String,
|
||||||
|
override val key: Char, override val vanilla: Boolean, override val commands: List<String>
|
||||||
|
) : Item {
|
||||||
|
|
||||||
|
override fun isCommodity(): Boolean {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun buildItem(): ItemStack {
|
||||||
|
return taboolib.platform.util.buildItem(material) {
|
||||||
|
this.name = this@ItemImpl.name
|
||||||
|
this.lore.addAll(this@ItemImpl.lore)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun update(player: Player, itemStack: ItemStack) {
|
||||||
|
itemStack.modifyLore {
|
||||||
|
val newLore = ArrayList<String>()
|
||||||
|
for (line in this) {
|
||||||
|
newLore.add(PlaceholderAPI.setPlaceholders(player, line))
|
||||||
|
}
|
||||||
|
this.clear()
|
||||||
|
this.addAll(newLore)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
package com.github.xbaimiao.shoppro.core.item
|
||||||
|
|
||||||
|
import org.bukkit.Material
|
||||||
|
import org.bukkit.inventory.ItemStack
|
||||||
|
import taboolib.library.xseries.XMaterial
|
||||||
|
import taboolib.module.nms.getItemTag
|
||||||
|
|
||||||
|
class ItemsAdderShopItem(
|
||||||
|
override val key: Char,
|
||||||
|
override val price: Double,
|
||||||
|
iaMaterial: String,
|
||||||
|
override val limitServer: Long,
|
||||||
|
override val limitPlayer: Long,
|
||||||
|
override val name: String,
|
||||||
|
override val lore: List<String>,
|
||||||
|
override val vanilla: Boolean,
|
||||||
|
override val commands: List<String>
|
||||||
|
) : ShopItem() {
|
||||||
|
|
||||||
|
override val material: Material
|
||||||
|
|
||||||
|
private val custom: Int
|
||||||
|
|
||||||
|
private var customPotionColor: Int? = null
|
||||||
|
|
||||||
|
init {
|
||||||
|
iaMaterial.split(":").let { strings ->
|
||||||
|
material = XMaterial.matchXMaterial(strings[1]).get().parseMaterial()!!
|
||||||
|
custom = strings[2].toInt()
|
||||||
|
strings.getOrNull(3)?.let { customPotionColor = it.toInt() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun equal(itemStack: ItemStack): Boolean {
|
||||||
|
return itemStack.type == material && itemStack.itemMeta?.customModelData == custom
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun vanillaItem(): ItemStack {
|
||||||
|
return taboolib.platform.util.buildItem(material) {
|
||||||
|
this.customModelData = custom
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun buildItem(): ItemStack {
|
||||||
|
return taboolib.platform.util.buildItem(material) {
|
||||||
|
this.name = this@ItemsAdderShopItem.name
|
||||||
|
this.lore.addAll(this@ItemsAdderShopItem.lore)
|
||||||
|
this.customModelData = custom
|
||||||
|
}.also { item ->
|
||||||
|
customPotionColor?.let {
|
||||||
|
val tag = item.getItemTag()
|
||||||
|
tag.putDeep("meta.CustomPotionColor.data", it)
|
||||||
|
tag.putDeep("meta.CustomPotionColor.type", "INT")
|
||||||
|
tag.saveTo(item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
package com.github.xbaimiao.shoppro.core.item
|
||||||
|
|
||||||
|
import me.clip.placeholderapi.PlaceholderAPI
|
||||||
|
import org.bukkit.entity.Player
|
||||||
|
import org.bukkit.inventory.ItemStack
|
||||||
|
import taboolib.platform.util.modifyLore
|
||||||
|
|
||||||
|
abstract class ShopItem : Item {
|
||||||
|
|
||||||
|
abstract val price: Double
|
||||||
|
abstract val limitServer: Long
|
||||||
|
abstract val limitPlayer: Long
|
||||||
|
|
||||||
|
override fun isCommodity(): Boolean {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract fun vanillaItem(): ItemStack
|
||||||
|
|
||||||
|
abstract fun equal(itemStack: ItemStack): Boolean
|
||||||
|
|
||||||
|
fun isLimit(): Boolean {
|
||||||
|
return limitPlayer != 0L && limitServer != 0L
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun update(player: Player, itemStack: ItemStack) {
|
||||||
|
val playerLimit = "1"
|
||||||
|
val serverLimit = "1"
|
||||||
|
val priceAll = "1"
|
||||||
|
itemStack.modifyLore {
|
||||||
|
val newLore = ArrayList<String>()
|
||||||
|
for (line in this) {
|
||||||
|
val newLine = line.replace("\${name}", name)
|
||||||
|
.replace("\${price}", price.toString())
|
||||||
|
.replace("\${money}", vault.getMoney(player).toString())
|
||||||
|
.replace("\${price64}", (price * 64).toString())
|
||||||
|
.replace("\${limit}", limitPlayer.toString())
|
||||||
|
.replace("\${priceAll}", priceAll)
|
||||||
|
.replace("\${allLimit}", limitServer.toString())
|
||||||
|
.replace("\${limit-player}", playerLimit)
|
||||||
|
.replace("\${limit-server}", serverLimit)
|
||||||
|
newLore.add(PlaceholderAPI.setPlaceholders(player, newLine))
|
||||||
|
}
|
||||||
|
this.clear()
|
||||||
|
this.addAll(newLore)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package com.github.xbaimiao.shoppro.core.item
|
||||||
|
|
||||||
|
import org.bukkit.Material
|
||||||
|
import org.bukkit.inventory.ItemStack
|
||||||
|
|
||||||
|
class VanillaShopItem(
|
||||||
|
override val key: Char,
|
||||||
|
override val material: Material,
|
||||||
|
override val price: Double,
|
||||||
|
override val limitServer: Long,
|
||||||
|
override val limitPlayer: Long,
|
||||||
|
override val name: String,
|
||||||
|
override val lore: List<String>,
|
||||||
|
override val vanilla: Boolean,
|
||||||
|
override val commands: List<String>
|
||||||
|
) : ShopItem() {
|
||||||
|
|
||||||
|
override fun vanillaItem(): ItemStack {
|
||||||
|
return taboolib.platform.util.buildItem(material)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun equal(itemStack: ItemStack): Boolean {
|
||||||
|
return itemStack.itemMeta?.hasLore() == false && itemStack.type == material
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun buildItem(): ItemStack {
|
||||||
|
return taboolib.platform.util.buildItem(material) {
|
||||||
|
this.name = this@VanillaShopItem.name
|
||||||
|
this.lore.addAll(this@VanillaShopItem.lore)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package com.github.xbaimiao.shoppro.core.shop
|
||||||
|
|
||||||
|
import org.bukkit.entity.Player
|
||||||
|
|
||||||
|
abstract class Shop {
|
||||||
|
|
||||||
|
enum class ShopType(val string: String) {
|
||||||
|
BUY("buy"), SELL("sell");
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun formString(string: String): ShopType {
|
||||||
|
return ShopType.values().first { it.string == string }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract fun getTitle(): String
|
||||||
|
|
||||||
|
abstract fun getType(): ShopType
|
||||||
|
|
||||||
|
abstract fun getName(): String
|
||||||
|
|
||||||
|
abstract fun open(player: Player)
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,167 @@
|
|||||||
|
package com.github.xbaimiao.shoppro.core.shop
|
||||||
|
|
||||||
|
import com.github.xbaimiao.shoppro.api.ShopProBuyEvent
|
||||||
|
import com.github.xbaimiao.shoppro.api.ShopProSellEvent
|
||||||
|
import com.github.xbaimiao.shoppro.core.item.*
|
||||||
|
import org.bukkit.Bukkit
|
||||||
|
import org.bukkit.configuration.Configuration
|
||||||
|
import org.bukkit.entity.Player
|
||||||
|
import taboolib.library.xseries.parseToMaterial
|
||||||
|
import taboolib.module.chat.colored
|
||||||
|
import taboolib.module.ui.ClickType
|
||||||
|
import taboolib.module.ui.openMenu
|
||||||
|
import taboolib.module.ui.type.Basic
|
||||||
|
import taboolib.platform.util.giveItem
|
||||||
|
import taboolib.platform.util.hasItem
|
||||||
|
import taboolib.platform.util.sendLang
|
||||||
|
import taboolib.platform.util.takeItem
|
||||||
|
|
||||||
|
class ShopImpl(private val configuration: Configuration) : Shop() {
|
||||||
|
|
||||||
|
private val slots = configuration.getStringList("slots").map { it.toCharArray().toList() }
|
||||||
|
|
||||||
|
private val items = ArrayList<Item>()
|
||||||
|
|
||||||
|
init {
|
||||||
|
val section = configuration.getConfigurationSection("items")!!
|
||||||
|
for (key in section.getKeys(false)) {
|
||||||
|
if (section.getBoolean("$key.is-commodity", true)) {
|
||||||
|
val materialString = section.getString("$key.material")!!
|
||||||
|
if (materialString.startsWith("IA")) {
|
||||||
|
items.add(
|
||||||
|
ItemsAdderShopItem(
|
||||||
|
key[0],
|
||||||
|
section.getDouble("$key.price"),
|
||||||
|
materialString,
|
||||||
|
section.getLong("$key.limit"),
|
||||||
|
section.getLong("$key.limit-player"),
|
||||||
|
section.getString("$key.name")!!.colored(),
|
||||||
|
section.getStringList("$key.lore").colored(),
|
||||||
|
section.getBoolean("$key.vanilla", true),
|
||||||
|
section.getStringList("$key.commands")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
items.add(
|
||||||
|
VanillaShopItem(
|
||||||
|
key[0],
|
||||||
|
section.getString("$key.material")!!.parseToMaterial(),
|
||||||
|
section.getDouble("$key.price"),
|
||||||
|
section.getLong("$key.limit"),
|
||||||
|
section.getLong("$key.limit-player"),
|
||||||
|
section.getString("$key.name")!!.colored(),
|
||||||
|
section.getStringList("$key.lore").colored(),
|
||||||
|
section.getBoolean("$key.vanilla", true),
|
||||||
|
section.getStringList("$key.commands")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
items.add(
|
||||||
|
ItemImpl(
|
||||||
|
section.getString("$key.material")!!.parseToMaterial(),
|
||||||
|
section.getStringList("$key.lore").colored(),
|
||||||
|
section.getString("$key.name")!!.colored(),
|
||||||
|
key[0],
|
||||||
|
section.getBoolean("$key.vanilla", true),
|
||||||
|
section.getStringList("$key.commands")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getTitle(): String {
|
||||||
|
return configuration.getString("title")!!.colored()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getType(): ShopType {
|
||||||
|
return ShopType.formString(configuration.getString("type")!!)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getName(): String {
|
||||||
|
return configuration.getString("name")!!.colored()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun open(player: Player) {
|
||||||
|
player.openMenu<Basic>(getTitle()) {
|
||||||
|
rows(slots.size)
|
||||||
|
slots = ArrayList<List<Char>>().also { it.addAll(this@ShopImpl.slots) }
|
||||||
|
onClick {
|
||||||
|
it.isCancelled = true
|
||||||
|
}
|
||||||
|
for (item in this@ShopImpl.items) {
|
||||||
|
val itemStack = item.buildItem()
|
||||||
|
item.update(player, itemStack)
|
||||||
|
set(item.key, itemStack)
|
||||||
|
if (item is ShopItem) {
|
||||||
|
if (getType() == ShopType.BUY) {
|
||||||
|
onClick(item.key) { event ->
|
||||||
|
if (event.clickType != ClickType.CLICK) {
|
||||||
|
return@onClick
|
||||||
|
}
|
||||||
|
val amount = when (event.clickEvent().click) {
|
||||||
|
org.bukkit.event.inventory.ClickType.LEFT -> 1
|
||||||
|
org.bukkit.event.inventory.ClickType.RIGHT -> 64
|
||||||
|
else -> 1
|
||||||
|
}
|
||||||
|
buy(amount, item, player)
|
||||||
|
event.currentItem?.let { item.update(player, it) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (getType() == ShopType.SELL) {
|
||||||
|
onClick(item.key) { event ->
|
||||||
|
if (event.clickType != ClickType.CLICK) {
|
||||||
|
return@onClick
|
||||||
|
}
|
||||||
|
val amount = when (event.clickEvent().click) {
|
||||||
|
org.bukkit.event.inventory.ClickType.LEFT -> 1
|
||||||
|
org.bukkit.event.inventory.ClickType.RIGHT -> 64
|
||||||
|
else -> 1
|
||||||
|
}
|
||||||
|
sell(amount, item, player)
|
||||||
|
event.currentItem?.let { item.update(player, it) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
onClick(item.key) {
|
||||||
|
item.exeCommands(player)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun buy(amount: Int, item: ShopItem, player: Player) {
|
||||||
|
if (item.isLimit()){
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
if (item.vault.takeMoney(player, item.price * amount)) {
|
||||||
|
if (item.vanilla) {
|
||||||
|
val vanilla = item.vanillaItem()
|
||||||
|
vanilla.amount = amount
|
||||||
|
player.giveItem(vanilla)
|
||||||
|
}
|
||||||
|
Bukkit.getPluginManager().callEvent(ShopProBuyEvent(item, amount, player))
|
||||||
|
item.exeCommands(player)
|
||||||
|
player.sendLang("buy-item", amount, item.name, item.price * amount)
|
||||||
|
} else {
|
||||||
|
player.sendLang("not-money")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun sell(amount: Int, item: ShopItem, player: Player) {
|
||||||
|
if (item.isLimit()){
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
if (player.inventory.hasItem(amount) { item.equal(it) }) {
|
||||||
|
player.inventory.takeItem(amount) { item.equal(it) }
|
||||||
|
item.vault.giveMoney(player, item.price * amount)
|
||||||
|
Bukkit.getPluginManager().callEvent(ShopProSellEvent(item, amount, player))
|
||||||
|
player.sendLang("sell-item", amount, item.name, item.price * amount)
|
||||||
|
} else {
|
||||||
|
player.sendLang("not-item")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package com.github.xbaimiao.shoppro.core.shop
|
||||||
|
|
||||||
|
import org.bukkit.configuration.file.YamlConfiguration
|
||||||
|
import taboolib.common.platform.function.info
|
||||||
|
import taboolib.platform.BukkitPlugin
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
object ShopManager {
|
||||||
|
|
||||||
|
val shops = ArrayList<Shop>()
|
||||||
|
|
||||||
|
fun load() {
|
||||||
|
val fileDirectory = File(BukkitPlugin.getInstance().dataFolder, "shops")
|
||||||
|
|
||||||
|
var files = fileDirectory.listFiles()
|
||||||
|
if (files == null || files.isEmpty()) {
|
||||||
|
BukkitPlugin.getInstance().saveResource("shops${File.separator}limit-buy.yml", false)
|
||||||
|
BukkitPlugin.getInstance().saveResource("shops${File.separator}limit-sell.yml", false)
|
||||||
|
BukkitPlugin.getInstance().saveResource("shops${File.separator}sell.yml", false)
|
||||||
|
files = fileDirectory.listFiles()
|
||||||
|
}
|
||||||
|
files?.forEach { file ->
|
||||||
|
shops.add(ShopImpl(YamlConfiguration.loadConfiguration(file)))
|
||||||
|
}
|
||||||
|
info("加载了 ${shops.size} 个商店配置")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package com.github.xbaimiao.shoppro.core.vault
|
||||||
|
|
||||||
|
import org.bukkit.entity.Player
|
||||||
|
|
||||||
|
interface Vault {
|
||||||
|
|
||||||
|
fun hasMoney(player: Player, double: Double): Boolean
|
||||||
|
|
||||||
|
fun giveMoney(player: Player, double: Double)
|
||||||
|
|
||||||
|
fun takeMoney(player: Player, double: Double): Boolean
|
||||||
|
|
||||||
|
fun getMoney(player: Player): Double
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package com.github.xbaimiao.shoppro.core.vault
|
||||||
|
|
||||||
|
import com.github.xbaimiao.shoppro.Util.format
|
||||||
|
import org.bukkit.entity.Player
|
||||||
|
import taboolib.platform.compat.VaultService
|
||||||
|
|
||||||
|
object VaultImpl : Vault {
|
||||||
|
|
||||||
|
override fun hasMoney(player: Player, double: Double): Boolean {
|
||||||
|
return getMoney(player) >= double.format()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun giveMoney(player: Player, double: Double) {
|
||||||
|
VaultService.economy!!.depositPlayer(player, double.format())
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun takeMoney(player: Player, double: Double): Boolean {
|
||||||
|
if (!hasMoney(player, double.format())) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
VaultService.economy!!.withdrawPlayer(player, double.format())
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getMoney(player: Player): Double {
|
||||||
|
return VaultService.economy!!.getBalance(player)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
shop-not-found: "&7[&e&l!&7] 你需要打开什么商店呢"
|
||||||
|
not-item: "&7[&e&l!&7] 你没有足够的可以出售的物品"
|
||||||
|
sell-item: "&7[&e&l!&7] 你出售了§6 {0}个 §7{1}§7获得了§6 {2}"
|
||||||
|
sell-limit: "&7[&e&l!&7] 此物品已达到今日收购限制"
|
||||||
|
buy-item: "&7[&e&l!&7] 你购买了§6 {0}个 §7{1} §7花费了§6 {2}"
|
||||||
|
not-money: "&7[&e&l!&7] 你没有足够的钱"
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
# 商店类型
|
||||||
|
# buy 为购买商店
|
||||||
|
# sell 为收购商店
|
||||||
|
type: buy
|
||||||
|
name: "默认出售商店"
|
||||||
|
title: "系统出售商店"
|
||||||
|
# 物品摆放顺序
|
||||||
|
slots:
|
||||||
|
- 'NNNNNNNNN'
|
||||||
|
- 'NAB N'
|
||||||
|
- 'NNNNNNNNN'
|
||||||
|
items:
|
||||||
|
N:
|
||||||
|
material: GLASS_PANE
|
||||||
|
name: ' '
|
||||||
|
lore:
|
||||||
|
- ' '
|
||||||
|
# 是否为商品
|
||||||
|
is-commodity: false
|
||||||
|
# 普通物品收购示例
|
||||||
|
A:
|
||||||
|
material: STONE
|
||||||
|
name: '石头'
|
||||||
|
# 每日限购买
|
||||||
|
limit: 5000
|
||||||
|
# 每个玩家限购买
|
||||||
|
limit-player: 500
|
||||||
|
# 物品金额
|
||||||
|
price: 2
|
||||||
|
lore:
|
||||||
|
- '&e| &7这里可以购买&6 ${name}'
|
||||||
|
- '&e| &7购买单价 &6${price}'
|
||||||
|
- '&e| &7你的余额 &6${money}'
|
||||||
|
- ''
|
||||||
|
- '&e|&6 左击 &7购买 &6单个'
|
||||||
|
- '&e|&6 右击 &7购买 &6一组 &7需要 &6${price64}'
|
||||||
|
- ''
|
||||||
|
- '&e| &7限买公示:'
|
||||||
|
- '&e| &7每人限制购买: ${limit}'
|
||||||
|
- '&e| &7全服限制购买: ${allLimit}'
|
||||||
|
- '&e| &7您已购买: ${limit-player}'
|
||||||
|
- '&e| &7全服剩余: ${limit-server}'
|
||||||
|
# itemsadder 物品购买示例
|
||||||
|
# 需要使用IA:前缀 中间为物品材质 后面为物品customData
|
||||||
|
B:
|
||||||
|
material: 'IA:PAPER:10001'
|
||||||
|
name: 'IA物品名'
|
||||||
|
# 每日限购买
|
||||||
|
limit: 5000
|
||||||
|
# 每个玩家限购买
|
||||||
|
limit-player: 500
|
||||||
|
# 物品金额
|
||||||
|
price: 2
|
||||||
|
lore:
|
||||||
|
- '&e| &7这里可以购买&6 ${name}'
|
||||||
|
- '&e| &7购买单价 &6${price}'
|
||||||
|
- '&e| &7你的余额 &6${money}'
|
||||||
|
- ''
|
||||||
|
- '&e|&6 左击 &7购买 &6单个'
|
||||||
|
- '&e|&6 右击 &7购买 &6一组 &7需要 &6${price64}'
|
||||||
|
- ''
|
||||||
|
- '&e| &7限买公示:'
|
||||||
|
- '&e| &7每人限制购买: ${limit}'
|
||||||
|
- '&e| &7全服限制购买: ${allLimit}'
|
||||||
|
- '&e| &7您已购买: ${limit-player}'
|
||||||
|
- '&e| &7全服剩余: ${limit-server}'
|
||||||
|
# 关闭此选项 可只执行命令 不给原版物品
|
||||||
|
vanilla: false
|
||||||
|
commands:
|
||||||
|
- '[console] ia give %player% 物品'
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
# 商店类型
|
||||||
|
# buy 为出售商店
|
||||||
|
# sell 为收购商店
|
||||||
|
type: sell
|
||||||
|
name: "默认收购商店"
|
||||||
|
title: "系统收购商店"
|
||||||
|
# 物品摆放顺序
|
||||||
|
slots:
|
||||||
|
- 'NNNNNNNNN'
|
||||||
|
- 'NAB N'
|
||||||
|
- 'NNNNNNNNN'
|
||||||
|
items:
|
||||||
|
N:
|
||||||
|
material: GLASS_PANE
|
||||||
|
name: ' '
|
||||||
|
lore:
|
||||||
|
- ' '
|
||||||
|
# 是否为商品
|
||||||
|
is-commodity: false
|
||||||
|
# 普通物品收购示例
|
||||||
|
A:
|
||||||
|
material: STONE
|
||||||
|
name: '石头'
|
||||||
|
# 每日限出售
|
||||||
|
limit: 5000
|
||||||
|
# 每个玩家限出售
|
||||||
|
limit-player: 500
|
||||||
|
# 物品金额
|
||||||
|
price: 1
|
||||||
|
lore:
|
||||||
|
- '&e| &7这里可以出售你背包里面的&6 ${name}'
|
||||||
|
- '&e| &7收购单价 &6${price}'
|
||||||
|
- '&e| &7你的余额 &6${money}'
|
||||||
|
- ''
|
||||||
|
- '&e|&6 左击 &7出售 &6单个'
|
||||||
|
- '&e|&6 右击 &7出售 &6一组 &7获得 &6${price64}'
|
||||||
|
- '&e|&6 Shift + 右击 &7出售 &6背包所有 &7获得${priceAll}'
|
||||||
|
- ''
|
||||||
|
- '&e| &7限售公示:'
|
||||||
|
- '&e| &7每人限制出售: ${limit}'
|
||||||
|
- '&e| &7全服限制出售: ${allLimit}'
|
||||||
|
- '&e| &7您已出售: ${limit-player}'
|
||||||
|
- '&e| &7全服剩余: ${limit-server}'
|
||||||
|
# itemsadder 物品收购示例
|
||||||
|
# 需要使用IA:前缀 中间为物品材质 后面为物品customData,如果是药水需要在添加一个 CustomPotionColor
|
||||||
|
B:
|
||||||
|
material: 'IA:PAPER:10001'
|
||||||
|
name: 'IA物品名'
|
||||||
|
# 每日限出售
|
||||||
|
limit: 5000
|
||||||
|
# 每个玩家限出售
|
||||||
|
limit-player: 500
|
||||||
|
# 物品金额
|
||||||
|
price: 1
|
||||||
|
lore:
|
||||||
|
- '&e| &7这里可以出售你背包里面的&6 ${name}'
|
||||||
|
- '&e| &7收购单价 &6${price}'
|
||||||
|
- '&e| &7你的余额 &6${money}'
|
||||||
|
- ''
|
||||||
|
- '&e|&6 左击 &7出售 &6单个'
|
||||||
|
- '&e|&6 右击 &7出售 &6一组 &7获得 &6${price64}'
|
||||||
|
- '&e|&6 Shift + 右击 &7出售 &6背包所有 &7获得${priceAll}'
|
||||||
|
- ''
|
||||||
|
- '&e| &7限售公示:'
|
||||||
|
- '&e| &7每人限制出售: ${limit}'
|
||||||
|
- '&e| &7全服限制出售: ${allLimit}'
|
||||||
|
- '&e| &7您已出售: ${limit-player}'
|
||||||
|
- '&e| &7全服剩余: ${limit-server}'
|
||||||
@@ -0,0 +1,131 @@
|
|||||||
|
type: sell
|
||||||
|
name: "自带收购商店"
|
||||||
|
title: "系统收购商店"
|
||||||
|
|
||||||
|
slots:
|
||||||
|
- 'NNNNNNNNN'
|
||||||
|
- 'NQWERTYUN'
|
||||||
|
- 'NIOP N'
|
||||||
|
- 'NNNNNNNNX'
|
||||||
|
|
||||||
|
items:
|
||||||
|
N:
|
||||||
|
material: GLASS_PANE
|
||||||
|
name: ' '
|
||||||
|
lore:
|
||||||
|
- ' '
|
||||||
|
is-commodity: false
|
||||||
|
X:
|
||||||
|
material: ARROW
|
||||||
|
name: '&f下一页'
|
||||||
|
lore:
|
||||||
|
- '&f点击前往下一页'
|
||||||
|
is-commodity: false
|
||||||
|
commands:
|
||||||
|
- '[open] 默认收购商店'
|
||||||
|
Q:
|
||||||
|
material: COAL
|
||||||
|
name: '&f&l煤炭'
|
||||||
|
price: 0.5
|
||||||
|
lore:
|
||||||
|
- '&a&l左键 &f&l出售单个'
|
||||||
|
- '&a&l右键 &f&l出售一组'
|
||||||
|
- '&a&lShift + 右键 &f&l出售背包所有可出售物品'
|
||||||
|
- ''
|
||||||
|
- '&a&l收购价格 &c&l${price}'
|
||||||
|
# 关闭此选项 可只执行命令 不给原版物品
|
||||||
|
vanilla: false
|
||||||
|
commands:
|
||||||
|
- '[console] give %player% COAL'
|
||||||
|
W:
|
||||||
|
material: IRON_INGOT
|
||||||
|
name: '&f&l铁锭'
|
||||||
|
price: 10
|
||||||
|
lore:
|
||||||
|
- '&a&l左键 &f&l出售单个'
|
||||||
|
- '&a&l右键 &f&l出售一组'
|
||||||
|
- '&a&lShift + 右键 &f&l出售背包所有可出售物品'
|
||||||
|
- ''
|
||||||
|
- '&a&l收购价格 &c&l${price}'
|
||||||
|
E:
|
||||||
|
material: GOLD_INGOT
|
||||||
|
name: '&f&l金锭'
|
||||||
|
price: 13
|
||||||
|
lore:
|
||||||
|
- '&a&l左键 &f&l出售单个'
|
||||||
|
- '&a&l右键 &f&l出售一组'
|
||||||
|
- '&a&lShift + 右键 &f&l出售背包所有可出售物品'
|
||||||
|
- ''
|
||||||
|
- '&a&l收购价格 &c&l${price}'
|
||||||
|
R:
|
||||||
|
material: COPPER_INGOT
|
||||||
|
name: '&f&l铜锭'
|
||||||
|
price: 12
|
||||||
|
lore:
|
||||||
|
- '&a&l左键 &f&l出售单个'
|
||||||
|
- '&a&l右键 &f&l出售一组'
|
||||||
|
- '&a&lShift + 右键 &f&l出售背包所有可出售物品'
|
||||||
|
- ''
|
||||||
|
- '&a&l收购价格 &c&l${price}'
|
||||||
|
T:
|
||||||
|
material: DIAMOND
|
||||||
|
name: '&f&l钻石'
|
||||||
|
price: 20
|
||||||
|
lore:
|
||||||
|
- '&a&l左键 &f&l出售单个'
|
||||||
|
- '&a&l右键 &f&l出售一组'
|
||||||
|
- '&a&lShift + 右键 &f&l出售背包所有可出售物品'
|
||||||
|
- ''
|
||||||
|
- '&a&l收购价格 &c&l${price}'
|
||||||
|
Y:
|
||||||
|
material: BREAD
|
||||||
|
name: '&f&l面包'
|
||||||
|
price: 3
|
||||||
|
lore:
|
||||||
|
- '&a&l左键 &f&l出售单个'
|
||||||
|
- '&a&l右键 &f&l出售一组'
|
||||||
|
- '&a&lShift + 右键 &f&l出售背包所有可出售物品'
|
||||||
|
- ''
|
||||||
|
- '&a&l收购价格 &c&l${price}'
|
||||||
|
U:
|
||||||
|
material: CAKE
|
||||||
|
name: '&f&l蛋糕'
|
||||||
|
price: 30
|
||||||
|
lore:
|
||||||
|
- '&a&l左键 &f&l出售单个'
|
||||||
|
- '&a&l右键 &f&l出售一组'
|
||||||
|
- '&a&lShift + 右键 &f&l出售背包所有可出售物品'
|
||||||
|
- ''
|
||||||
|
- '&a&l收购价格 &c&l${price}'
|
||||||
|
I:
|
||||||
|
material: PUMPKIN_PIE
|
||||||
|
name: '&f&l南瓜派'
|
||||||
|
price: 4
|
||||||
|
lore:
|
||||||
|
- '&a&l左键 &f&l出售单个'
|
||||||
|
- '&a&l右键 &f&l出售一组'
|
||||||
|
- '&a&lShift + 右键 &f&l出售背包所有可出售物品'
|
||||||
|
- ''
|
||||||
|
- '&a&l收购价格 &c&l${price}'
|
||||||
|
O:
|
||||||
|
material: MUSHROOM_STEW
|
||||||
|
name: '&f&l蘑菇煲'
|
||||||
|
price: 2
|
||||||
|
lore:
|
||||||
|
- '&a&l左键 &f&l出售单个'
|
||||||
|
- '&a&l右键 &f&l出售一组'
|
||||||
|
- '&a&lShift + 右键 &f&l出售背包所有可出售物品'
|
||||||
|
- ''
|
||||||
|
- '&a&l收购价格 &c&l${price}'
|
||||||
|
|
||||||
|
# itemsadder 物品
|
||||||
|
P:
|
||||||
|
material: 'IA:PAPER:10007'
|
||||||
|
name: 'itemsadder'
|
||||||
|
price: 20
|
||||||
|
lore:
|
||||||
|
- '&a&l左键 &f&l出售单个'
|
||||||
|
- '&a&l右键 &f&l出售一组'
|
||||||
|
- '&a&lShift + 右键 &f&l出售背包所有可出售物品'
|
||||||
|
- ''
|
||||||
|
- '&a&l收购价格 &c&l${price}'
|
||||||
Reference in New Issue
Block a user