27 Commits
Author SHA1 Message Date
stijn ff4fb6c1ae Update to java 21, 1.21 with cosmso 2025-06-28 03:33:39 +02:00
auto ffd67eada8 Update file paths in quest configurations
The file paths previously pointed to the user home directory. This commit adjusts the paths to consistently use a mount point directory instead. The change affects the 'QuestsConfig', 'Config', 'MessagesConfig', and 'DatabaseConfig' classes.
2024-07-20 01:46:33 +02:00
auto 81ed73fbd1 Add new responses to handle quest reroll situations
This commit fixes a bug where the quest reroll feature could be used repeatedly without restrictions. Now, appropriate responses will be given in cases where the quest is still loading or if the daily quest has already been completed. This ensures that the player cannot misuse the reroll functionality.
2024-04-18 20:49:05 +02:00
auto 34c5252db4 Refactor quest saving, update Galaxy-API version
Quest saving logic was abstracted into a saveQuest method in the Quest class to avoid redundancy. This change was reflected in OtherQuest, MineQuest, BreedMobsQuest, KillMobsQuest and CollectDropsQuest classes. Additionally, the Galaxy-API version was updated in the build.gradle.kts file.
2024-04-13 20:50:56 +02:00
auto 3bb822b41c Optimize and cleanup various classes
Reformatted several classes for optimization purposes. This includes removing unnecessary try-catch blocks, redundant initializers and imports, and condensing confirmation checks. Additionally, updated the `Database` class's `createUserPointsTable` and `createQuestLogTable` methods to use try-with-resources to ensure proper resource management.
2024-04-13 20:43:37 +02:00
auto c6b186e2c6 Remove commented code and ensure async execution in specific methods
All code sections that were commented out are now completely removed, resulting in a cleaner and more efficient codebase. In addition, the method 'unloadUser' in the Quest class, which previously only included a comment suggesting it should be run as an async operation, is now forced to run in an asynchronous manner, potentially improving performance.
2024-04-13 20:32:56 +02:00
auto 46bfb4fd65 Replace printStackTrace with Logger.throwing in various classes
The changes made in these classes are intended to improve error handling and visibility. Instead of simply printing the StackTrace, the Logger.throwing method is now used to send error messages to the logger in a more controlled manner. This should facilitate better error tracking and resolution. The affected classes include database, configuration, and quest implementation classes.
2024-04-13 20:27:33 +02:00
auto 8a22f5188e Add reroll command and associated help messages
A new 'reroll' command has been added for players to get a new quest. This feature is now reflected in the help messages. Furthermore, messages have been introduced to inform the player about successful reroll, or if the rerolling option is on cooldown.
2024-04-13 20:16:21 +02:00
stijn 379ba6d624 Merge pull request 'OnceABranch' (#1) from OnceABranch into master
Reviewed-on: #1
2024-04-13 18:03:03 +00:00
once_a_fairy 410a825681 Fixed upper case quest names breaking bossbars. 2023-09-20 09:22:14 +02:00
once_a_fairy 2409103b3e Minor changes for OtherQuests and a progress bar was added. 2023-09-19 19:32:56 +02:00
auto e93a922cc8 Attempting to fix thread issues, temporarily disabled them 2023-08-06 20:57:59 +02:00
auto b8114ba0d3 Added auto hiding bossbar 2023-08-06 20:07:12 +02:00
once_a_fairy 2b9d6c0160 Minor changes. 2023-08-06 14:53:36 +02:00
once_a_fairy e258644a20 Fixed some dumb mistakes for the progress book. 2023-08-05 17:35:19 +02:00
once_a_fairy 0a0c4ffb98 Tried to add a progress book which only shows the quest progress upon using a command. 2023-08-05 13:49:12 +02:00
once_a_fairy e85e79c801 Added support for raid quests. 2023-08-04 23:41:13 +02:00
once_a_fairy 8eb28ea5f6 Added support for Shearing and Bucket quests and fixed some minor things. 2023-08-04 22:44:06 +02:00
OnceAFairyandGitHub e0d3251bc9 Delete .gradle directory 2023-07-16 16:28:42 +02:00
OnceAFairyandGitHub 75c9e71e00 Delete .idea directory 2023-07-16 16:28:33 +02:00
OnceAFairyandGitHub 48968e445f Delete build directory 2023-07-16 16:28:20 +02:00
once_a_fairy 244ac818a3 Merge remote-tracking branch 'origin/OnceABranch' into OnceABranch 2023-07-16 16:26:29 +02:00
once_a_fairy 3df774c2b6 Added ItemCaught.java which I previously forgot to push. 2023-07-16 16:15:10 +02:00
OnceAFairyandGitHub 5b0cb847c4 Delete build/classes/java/main/com/alttd/altitudequests/events directory 2023-07-16 16:13:10 +02:00
once_a_fairy 1aee415642 Added support for other quests.
Support for other quests of the fishing type was added.
2023-07-16 15:48:07 +02:00
once_a_fairy 5929582e71 Added support for other quests.
Support for other quests of the fishing type was added.
2023-07-13 13:38:29 +02:00
once_a_fairy 241dce0537 Added quest support for harvesting plants. 2023-07-10 17:33:48 +02:00
41 changed files with 1090 additions and 566 deletions
Vendored
+24
View File
@@ -0,0 +1,24 @@
pipeline {
agent any
stages {
stage('Gradle') {
steps {
sh '''
set +x
chmod +x gradlew
./gradlew build
'''
}
}
stage('Archive') {
steps {
archiveArtifacts artifacts: 'build/libs/', followSymlinks: false
}
}
stage('discord') {
steps {
discordSend description: "Build: ${BUILD_NUMBER}", showChangeset: true, result: currentBuild.currentResult, title: currentBuild.fullProjectName, webhookURL: env.discordwebhook
}
}
}
}
+4 -21
View File
@@ -1,8 +1,5 @@
import com.github.jengelman.gradle.plugins.shadow.tasks.ConfigureShadowRelocation
plugins {
id("java")
id("com.github.johnrengelman.shadow") version "7.1.0"
}
group = "com.alttd"
@@ -13,7 +10,7 @@ apply<JavaLibraryPlugin>()
java {
toolchain {
languageVersion.set(JavaLanguageVersion.of(17))
languageVersion.set(JavaLanguageVersion.of(21))
}
}
@@ -25,25 +22,11 @@ tasks {
withType<Javadoc> {
options.encoding = Charsets.UTF_8.name()
}
shadowJar {
dependsOn(getByName("relocateJars") as ConfigureShadowRelocation)
archiveFileName.set("${project.name}-${project.version}.jar")
minimize()
configurations = listOf(project.configurations.shadow.get())
}
build {
dependsOn(shadowJar)
}
create<ConfigureShadowRelocation>("relocateJars") {
target = shadowJar.get()
prefix = "${project.name}.lib"
}
}
dependencies {
compileOnly("com.alttd:Galaxy-API:1.19-R0.1-SNAPSHOT")
compileOnly("com.alttd.cosmos:cosmos-api:1.21.6-R0.1-SNAPSHOT") {
isChanging = true
}
compileOnly("com.alttd.datalock:api:1.1.0-SNAPSHOT")
}
Vendored
+179 -115
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env sh
#!/bin/sh
#
# Copyright 2015 the original author or authors.
# 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.
@@ -17,67 +17,99 @@
#
##############################################################################
##
## Gradle start up script for UN*X
##
#
# 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/HEAD/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
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
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
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='"-Xmx64m" "-Xms64m"'
# This is normally unused
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
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
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
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
@@ -87,9 +119,9 @@ CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
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"
JAVACMD=$JAVA_HOME/jre/sh/java
else
JAVACMD="$JAVA_HOME/bin/java"
JAVACMD=$JAVA_HOME/bin/java
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
@@ -98,88 +130,120 @@ 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.
JAVACMD=java
if ! command -v java >/dev/null 2>&1
then
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
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 or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; 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=`expr $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" ;;
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
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, 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.
# 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"
# 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
# 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"'
# Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain \
"$@"
# Stop when "xargs" is not available.
if ! command -v xargs >/dev/null 2>&1
then
die "xargs is not available"
fi
# 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
+19 -16
View File
@@ -14,7 +14,7 @@
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@@ -25,7 +25,8 @@
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
if "%DIRNAME%"=="" set DIRNAME=.
@rem This is normally unused
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@@ -40,13 +41,13 @@ if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto execute
if %ERRORLEVEL% equ 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.
echo. 1>&2
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail
@@ -56,11 +57,11 @@ 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.
echo. 1>&2
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail
@@ -75,13 +76,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
if %ERRORLEVEL% equ 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
set EXIT_CODE=%ERRORLEVEL%
if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%
:mainEnd
if "%OS%"=="Windows_NT" endlocal
+1 -2
View File
@@ -2,9 +2,8 @@ rootProject.name = "AQuest"
dependencyResolutionManagement {
repositories {
// mavenLocal()
mavenCentral()
maven("https://repo.destro.xyz/snapshots") // Altitude - Galaxy
maven("https://repo.destro.xyz/snapshots") // Altitude - Cosmos
maven("https://jitpack.io") { // Vault
content { includeGroup("com.github.milkbowl") }
}
@@ -4,6 +4,7 @@ import com.alttd.altitudequests.commands.CommandManager;
import com.alttd.altitudequests.config.*;
import com.alttd.altitudequests.events.*;
import com.alttd.altitudequests.objects.Quest;
import com.alttd.altitudequests.util.AutoHideBossBar;
import com.alttd.altitudequests.util.Logger;
import com.alttd.altitudequests.util.Utilities;
import com.alttd.datalock.DataLockAPI;
@@ -37,6 +38,7 @@ public final class AQuest extends JavaPlugin {
} else {
dataLockAPI.registerChannel("aquest:player-data");
}
AutoHideBossBar.initiate();
Logger.info("--------------------------------------------------");
Logger.info("AQuest started");
@@ -69,8 +71,8 @@ public final class AQuest extends JavaPlugin {
getServer().getPluginManager().registerEvents(new EntityBreed(), this);
getServer().getPluginManager().registerEvents(new DonNotMessWithNPC(), this);
getServer().getPluginManager().registerEvents(new DataLock(), this);
// getServer().getMessenger().registerOutgoingPluginChannel(this, "aquest:player-data");
// getServer().getMessenger().registerIncomingPluginChannel(this, "aquest:player-data", new PluginMessageListener());
getServer().getPluginManager().registerEvents(new ItemCaught(), this);
getServer().getPluginManager().registerEvents(new FinishedRaid(), this);
}
private static int yearDay = Utilities.getYearDay();
@@ -11,7 +11,6 @@ import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class CommandManager implements CommandExecutor, TabExecutor {
private final List<SubCommand> subCommands;
@@ -35,7 +34,10 @@ public class CommandManager implements CommandExecutor, TabExecutor {
new CommandChangeQuest(),
new CommandTurnIn(),
new CommandSetQuest(),
new CommandGetReward());
new CommandGetReward(),
new CommandProgress(),
new CommandReRoll()
);
}
@Override
@@ -47,7 +49,7 @@ public class CommandManager implements CommandExecutor, TabExecutor {
subCommand = getSubCommand(args[0]);
if (!commandSender.hasPermission(subCommand.getPermission())) {
commandSender.sendMiniMessage(MessagesConfig.NO_PERMISSION, null);
commandSender.sendRichMessage(MessagesConfig.NO_PERMISSION);
return true;
}
@@ -64,7 +66,7 @@ public class CommandManager implements CommandExecutor, TabExecutor {
.filter(subCommand -> commandSender.hasPermission(subCommand.getPermission()))
.map(SubCommand::getName)
.filter(name -> args.length == 0 || name.startsWith(args[0]))
.collect(Collectors.toList())
.toList()
);
} else {
SubCommand subCommand = getSubCommand(args[0]);
@@ -24,13 +24,13 @@ public class CommandCreateScruff extends SubCommand {
@Override
public boolean onCommand(CommandSender commandSender, String[] args) {
if (args.length != 7) {
commandSender.sendMiniMessage(getHelpMessage(), null);
commandSender.sendRichMessage(getHelpMessage());
return true;
}
World world = Bukkit.getServer().getWorld(args[6]);
if (world == null) {
commandSender.sendMiniMessage(getHelpMessage(), null);
commandSender.sendRichMessage(getHelpMessage());
return true;
}
Location location;
@@ -38,7 +38,7 @@ public class CommandCreateScruff extends SubCommand {
location = new Location(world, Double.parseDouble(args[1]), Double.parseDouble(args[2]), Double.parseDouble(args[3]),
Float.parseFloat(args[4]), Float.parseFloat(args[5]));
} catch (NumberFormatException exception) {
commandSender.sendMiniMessage("<red>Invalid arguments.</red>", null);
commandSender.sendRichMessage("<red>Invalid arguments.</red>");
return true;
}
Wolf wolf = (Wolf) world.spawnEntity(location, EntityType.WOLF, CreatureSpawnEvent.SpawnReason.CUSTOM);
@@ -55,7 +55,7 @@ public class CommandCreateScruff extends SubCommand {
UUID uuid = wolf.getUniqueId();
LocalConfig.setActiveNPC(uuid);
commandSender.sendMiniMessage("<green>Spawned Scruff</green>", null);
commandSender.sendRichMessage("<green>Spawned Scruff</green>");
return true;
}
@@ -21,34 +21,34 @@ public class CommandGetReward extends SubCommand {
if (args.length != 1)
return true;
if (!(commandSender instanceof Player player)) {
commandSender.sendMiniMessage(MessagesConfig.NO_CONSOLE, null);
commandSender.sendRichMessage(MessagesConfig.NO_CONSOLE);
return true;
}
Quest dailyQuest = Quest.getDailyQuest(player.getUniqueId());
if (dailyQuest == null) {
player.sendMiniMessage("<red>You have no active quests?</red>", null);
player.sendRichMessage("<red>You have no active quests?</red>");
return true;
}
if (player.getNearbyEntities(5, 5, 5).stream()
.noneMatch(entity -> entity.getUniqueId().equals(LocalConfig.activeNPC))) {
player.sendMiniMessage(MessagesConfig.TOO_FAR_FROM_NPC, Placeholder.component("npc", MiniMessage.miniMessage().deserialize(Config.NPC_NAME)));
player.sendRichMessage(MessagesConfig.TOO_FAR_FROM_NPC, Placeholder.component("npc", MiniMessage.miniMessage().deserialize(Config.NPC_NAME)));
return true;
}
if (!dailyQuest.isDone()) {
player.sendMiniMessage(MessagesConfig.NOT_FINISHED_QUEST, null);
player.sendRichMessage(MessagesConfig.NOT_FINISHED_QUEST);
return true;
}
if (dailyQuest.isRewardReceived()) {
player.sendMiniMessage(MessagesConfig.REWARD_ALREADY_RECEIVED, null);
player.sendRichMessage(MessagesConfig.REWARD_ALREADY_RECEIVED);
return true;
}
for (String command : dailyQuest.getRewardCommand())
Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(), command.replaceAll("<player>", commandSender.getName()));
dailyQuest.setRewardReceived(true);
player.sendMiniMessage(MessagesConfig.REWARD_SENT, null);
player.sendRichMessage(MessagesConfig.REWARD_SENT);
return true;
}
@@ -20,12 +20,12 @@ public class CommandHelp extends SubCommand {
@Override
public boolean onCommand(CommandSender commandSender, String[] args) {
commandSender.sendMiniMessage(MessagesConfig.HELP_MESSAGE_WRAPPER.replaceAll("<commands>", commandManager
commandSender.sendRichMessage(MessagesConfig.HELP_MESSAGE_WRAPPER.replaceAll("<commands>", commandManager
.getSubCommands().stream()
.filter(SubCommand::shouldTabComplete)
.filter(subCommand -> commandSender.hasPermission(subCommand.getPermission()))
.map(SubCommand::getHelpMessage)
.collect(Collectors.joining("\n"))), null);
.collect(Collectors.joining("\n"))));
return true;
}
@@ -1,15 +1,55 @@
package com.alttd.altitudequests.commands.subcommands;
import com.alttd.altitudequests.AQuest;
import com.alttd.altitudequests.commands.SubCommand;
import com.alttd.altitudequests.config.MessagesConfig;
import com.alttd.altitudequests.objects.Quest;
import com.alttd.altitudequests.util.ProgressBookOpener;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
public class CommandProgress extends SubCommand {
//TODO show player current quest progress
private static final Set<UUID> inProcess = new HashSet<>();
@Override
public boolean onCommand(CommandSender commandSender, String[] args) {
return false;
if (!(commandSender instanceof Player player)) {
commandSender.sendRichMessage(MessagesConfig.NO_CONSOLE);
return true;
}
if (!player.hasPlayedBefore()) {
commandSender.sendRichMessage(getHelpMessage());
return true;
}
Quest dailyQuest = Quest.getDailyQuest(player.getUniqueId());
if (dailyQuest == null) {
player.sendRichMessage("<red>You have no active quests.</red>");
return true;
}
if (dailyQuest.isDone()) {
player.sendRichMessage("<green>You already completed the daily quest.</green>");
return true;
}
final UUID uniqueId = player.getUniqueId();
if (inProcess.contains(uniqueId)) {
return true;
}
inProcess.add(uniqueId);
new BukkitRunnable() {
@Override
public void run() {
ProgressBookOpener.openProgressBook(player);
inProcess.remove(uniqueId);
}
}.runTaskAsynchronously(AQuest.getInstance());
return true;
}
@Override
@@ -0,0 +1,61 @@
package com.alttd.altitudequests.commands.subcommands;
import com.alttd.altitudequests.commands.SubCommand;
import com.alttd.altitudequests.config.MessagesConfig;
import com.alttd.altitudequests.objects.Quest;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.entity.Player;
import java.util.List;
public class CommandReRoll extends SubCommand {
@Override
public boolean onCommand(CommandSender commandSender, String[] args) {
if (!(commandSender instanceof Player player)) {
commandSender.sendRichMessage(MessagesConfig.NO_CONSOLE);
return true;
}
if (player.hasPermission("aquest.reroll.on-cooldown")) {
commandSender.sendRichMessage(MessagesConfig.NO_RE_ROLL_YET);
return true;
}
Quest dailyQuest = Quest.getDailyQuest(player.getUniqueId());
if (dailyQuest == null) {
commandSender.sendRichMessage(MessagesConfig.WAIT_FOR_QUEST);
return true;
}
if (dailyQuest.isDone()) {
commandSender.sendRichMessage(MessagesConfig.QUEST_ALREADY_FINISHED);
return true;
}
Quest.createDailyQuest(player);
commandSender.sendRichMessage(MessagesConfig.QUEST_RE_ROLLED);
ConsoleCommandSender consoleSender = Bukkit.getConsoleSender();
Bukkit.dispatchCommand(consoleSender, String.format("lp user %s permission settemp aquest.reroll.on-cooldown true 7d", player.getName()));
return true;
}
@Override
public String getName() {
return "reroll";
}
@Override
public List<String> getTabComplete(CommandSender commandSender, String[] args) {
return List.of();
}
@Override
public String getHelpMessage() {
return MessagesConfig.RE_ROLL_HELP;
}
@Override
public boolean shouldTabComplete() {
return true;
}
}
@@ -19,7 +19,7 @@ public class CommandReload extends SubCommand {
@Override
public boolean onCommand(CommandSender commandSender, String[] args) {
plugin.reloadConfigs();
commandSender.sendMiniMessage("<green>Reloaded AltitudeQuests config.</green>", null);
commandSender.sendRichMessage("<green>Reloaded AltitudeQuests config.</green>");
return true;
}
@@ -4,10 +4,7 @@ import com.alttd.altitudequests.AQuest;
import com.alttd.altitudequests.commands.SubCommand;
import com.alttd.altitudequests.config.MessagesConfig;
import com.alttd.altitudequests.objects.Quest;
import com.alttd.altitudequests.objects.quests.BreedMobsQuest;
import com.alttd.altitudequests.objects.quests.CollectDropsQuest;
import com.alttd.altitudequests.objects.quests.KillMobsQuest;
import com.alttd.altitudequests.objects.quests.MineQuest;
import com.alttd.altitudequests.objects.quests.*;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.bukkit.Bukkit;
@@ -17,8 +14,6 @@ import org.bukkit.scheduler.BukkitRunnable;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Optional;
import java.util.stream.Collectors;
public class CommandSetQuest extends SubCommand {
@@ -26,22 +21,22 @@ public class CommandSetQuest extends SubCommand {
@Override
public boolean onCommand(CommandSender commandSender, String[] args) {
if (args.length != 4) {
commandSender.sendMiniMessage(getHelpMessage(), null);
commandSender.sendRichMessage(getHelpMessage());
return true;
}
Player player = Bukkit.getServer().getPlayer(args[1]);
if (player == null || !player.hasPlayedBefore()) {
commandSender.sendMiniMessage(getHelpMessage(), null);
commandSender.sendRichMessage(getHelpMessage());
return true;
}
new BukkitRunnable() {
@Override
public void run() {
if (!Quest.loadDailyQuest(args[2], args[3], 0, 0, player.getUniqueId(), -1, false))
commandSender.sendMiniMessage("<red>Unable to create quest <quest> of variant <variant>.</red>",
commandSender.sendRichMessage("<red>Unable to create quest <quest> of variant <variant>.</red>",
TagResolver.resolver(Placeholder.parsed("quest", args[2]),
Placeholder.parsed("variant", args[3])));
commandSender.sendMiniMessage("<green>Created quest <quest> of variant <variant>.</green>",
commandSender.sendRichMessage("<green>Created quest <quest> of variant <variant>.</green>",
TagResolver.resolver(Placeholder.parsed("quest", args[2]),
Placeholder.parsed("variant", args[3])));
}
@@ -60,7 +55,7 @@ public class CommandSetQuest extends SubCommand {
switch (args.length) {
case 2 -> res.addAll(Bukkit.getServer().getOnlinePlayers().stream()
.map(Player::getName)
.collect(Collectors.toList()));
.toList());
case 3 -> res.addAll(Quest.getTypes());
case 4 -> {
switch (args[2].toLowerCase()) {
@@ -68,6 +63,7 @@ public class CommandSetQuest extends SubCommand {
case "collectdropsquest" -> res.addAll(CollectDropsQuest.getSubTypes());
case "killmobsquest" -> res.addAll(KillMobsQuest.getSubTypes());
case "minequest" -> res.addAll(MineQuest.getSubTypes());
case "otherquest" -> res.addAll(OtherQuest.getSubTypes());
default -> res.add("invalid quest type");
}
}
@@ -20,22 +20,22 @@ public class CommandTurnIn extends SubCommand {
if (args.length != 1)
return true;
if (!(commandSender instanceof Player player)) {
commandSender.sendMiniMessage(MessagesConfig.NO_CONSOLE, null);
commandSender.sendRichMessage(MessagesConfig.NO_CONSOLE);
return true;
}
Quest dailyQuest = Quest.getDailyQuest(player.getUniqueId());
if (dailyQuest == null || dailyQuest.isDone()) {
player.sendMiniMessage(MessagesConfig.DAILY_ALREADY_DONE, null);
player.sendRichMessage(MessagesConfig.DAILY_ALREADY_DONE);
return true;
}
if (player.getNearbyEntities(5, 5, 5).stream()
.noneMatch(entity -> entity.getUniqueId().equals(LocalConfig.activeNPC))) {
player.sendMiniMessage(MessagesConfig.TOO_FAR_FROM_NPC, Placeholder.component("npc", MiniMessage.miniMessage().deserialize(Config.NPC_NAME)));
player.sendRichMessage(MessagesConfig.TOO_FAR_FROM_NPC, Placeholder.component("npc", MiniMessage.miniMessage().deserialize(Config.NPC_NAME)));
return true;
}
dailyQuest.turnIn(player);
if (dailyQuest.isDone())
player.sendMiniMessage(MessagesConfig.FINISHED_QUEST, Placeholder.component("player", player.name()));
player.sendRichMessage(MessagesConfig.FINISHED_QUEST, Placeholder.component("player", player.name()));
BookOpener.openBook(player);
return true;
}
@@ -54,8 +54,7 @@ abstract class AbstractConfig {
} catch (InvocationTargetException ex) {
throw new RuntimeException(ex.getCause());
} catch (Exception ex) {
Logger.severe("Error invoking %.", method.toString());
ex.printStackTrace();
Logger.throwing(AbstractConfig.class.getName(), "readConfig", ex);
}
}
}
@@ -69,7 +68,7 @@ abstract class AbstractConfig {
yaml.save(file);
} catch (IOException ex) {
Logger.severe("Could not save %.", file.toString());
ex.printStackTrace();
Logger.throwing(AbstractConfig.class.getName(), "save", ex);
}
}
@@ -1,14 +1,14 @@
package com.alttd.altitudequests.config;
import java.io.File;
import java.time.Duration;
import java.util.List;
public final class Config extends AbstractConfig {
static Config config;
static int version;
public Config() {
super(new File(System.getProperty("user.home") + File.separator + "share" + File.separator + "configs" + File.separator + "AltitudeQuests"), "config.yml");
super(new File(File.separator + "mnt" + File.separator + "configs" + File.separator + "AltitudeQuests"), "config.yml");
}
public static void reload() {
config = new Config();
@@ -21,6 +21,8 @@ public final class Config extends AbstractConfig {
public static String QUEST_BOOK_AUTHOR = "<magenta>Scruff</magenta>";
public static String QUEST_BOOK_TITLE = "<green>Quest Title</green>";
public static String PROGRESS_BOOK_AUTHOR = "<magenta>Scruff</magenta>";
public static String PROGRESS_BOOK_TITLE = "<green>Quest Title</green>";
public static List<String> QUEST_PAGES = List.of("""
<bold><gold>Hey <player></gold></bold>
@@ -31,6 +33,16 @@ public final class Config extends AbstractConfig {
* <step_2>: <step_2_progress>/<step_2_total>
<click:run_command:/aquest turnin><turn_in_text></click>
""");
public static List<String> PROGRESS_PAGES = List.of("""
<bold><gold>Hey <player></gold></bold>
Your quest progress:
* Quest: <quest>
* Type: <variant>
* <step_1>: <step_1_progress>/<step_1_total>
* <step_2>: <step_2_progress>/<step_2_total>
""");
private static void loadBook() {
QUEST_BOOK_AUTHOR = config.getString("book.author", QUEST_BOOK_AUTHOR);
@@ -38,21 +50,31 @@ public final class Config extends AbstractConfig {
QUEST_PAGES = config.getStringList("book.pages", QUEST_PAGES);
}
private static void loadProgressBook() {
PROGRESS_BOOK_AUTHOR = config.getString("progressBook.author", PROGRESS_BOOK_AUTHOR);
PROGRESS_BOOK_TITLE = config.getString("progressBook.title", PROGRESS_BOOK_TITLE);
PROGRESS_PAGES = config.getStringList("progressBook.pages", PROGRESS_PAGES);
}
public static String NPC_NAME = "<light_purple>Scruff</light_purple>";
public static boolean DEBUG = false;
public static Duration BOSS_BAR_AUTO_HIDE;
private static void loadSettings() {
NPC_NAME = config.getString("settings.npc-name", NPC_NAME);
DEBUG = config.getBoolean("settings.debug", DEBUG);
BOSS_BAR_AUTO_HIDE = Duration.ofSeconds(config.getInt("settings.boss-bar-auto-hide-seconds", 10));
}
public static int MINE_QUEST_FREQ = 1;
public static int KILL_QUEST_FREQ = 1;
public static int COLLECT_QUEST_FREQ = 1;
public static int BREED_QUEST_FREQ = 1;
public static int OTHER_QUEST_FRQ = 1;
private static void loadQuestTypeFrequency() {
MINE_QUEST_FREQ = config.getInt("quest-type-frequency.mine", MINE_QUEST_FREQ);
KILL_QUEST_FREQ = config.getInt("quest-type-frequency.kill", KILL_QUEST_FREQ);
COLLECT_QUEST_FREQ = config.getInt("quest-type-frequency.collect", COLLECT_QUEST_FREQ);
BREED_QUEST_FREQ = config.getInt("quest-type-frequency.breed", BREED_QUEST_FREQ);
OTHER_QUEST_FRQ = config.getInt("quest-type-frequency.other", OTHER_QUEST_FRQ);
}
}
@@ -6,7 +6,7 @@ public class DatabaseConfig extends AbstractConfig {
static DatabaseConfig config;
public DatabaseConfig() {
super(new File(System.getProperty("user.home") + File.separator + "share" + File.separator + "configs"
super(new File(File.separator + "mnt" + File.separator + "configs"
+ File.separator + "AltitudeQuests"), "database.yml");
}
@@ -7,7 +7,7 @@ public class MessagesConfig extends AbstractConfig{
static MessagesConfig config;
public MessagesConfig() {
super(new File(System.getProperty("user.home") + File.separator + "share" + File.separator + "configs"
super(new File(File.separator + "mnt" + File.separator + "configs"
+ File.separator + "AltitudeQuests"), "messages.yml");
}
@@ -21,6 +21,7 @@ public class MessagesConfig extends AbstractConfig{
public static String RELOAD_HELP_MESSAGE = "<green>Reload configs: <gold>/aquest reload</gold></green>";
public static String CREATE_SCRUFF_MESSAGE = "<green>Create Scruff: <gold>/aquest createscruff <x> <y> <z> <yaw> <pitch> <world></gold></green>";
public static String SET_QUEST_HELP = "<green>Set quest: <gold>/aquest setquest <player> <quest> <variant></gold></green>";
public static String RE_ROLL_HELP = "<green>Get a new quest: <gold>/aquest reroll</gold></green>";
private static void loadHelp() {
HELP_MESSAGE_WRAPPER = config.getString("help.help-wrapper", HELP_MESSAGE_WRAPPER);
@@ -28,6 +29,7 @@ public class MessagesConfig extends AbstractConfig{
RELOAD_HELP_MESSAGE = config.getString("help.reload", RELOAD_HELP_MESSAGE);
SET_QUEST_HELP = config.getString("help.set-quest", SET_QUEST_HELP);
CREATE_SCRUFF_MESSAGE = config.getString("help.help-wrapper", CREATE_SCRUFF_MESSAGE);
RE_ROLL_HELP = config.getString("help.re-roll-help", RE_ROLL_HELP);
}
@@ -38,6 +40,11 @@ public class MessagesConfig extends AbstractConfig{
public static String REWARD_SENT = "<white>[<gold>Mascot</gold>] <light_purple>Scruff</light_purple><gray>:</gray> <green>Thank you for completing the quest! Your reward has been sent!</green></white>";
public static String FINISHED_QUEST = "<white>[<gold>Mascot</gold>] <light_purple>Scruff</light_purple><gray>:</gray> <green>You finished your quest! Don't forget to collect your reward at the end of the quest book!</green></white>";
public static String NOT_FINISHED_QUEST = "<red>You have not finished this quest yet.</red>";
public static String QUEST_RE_ROLLED = "<white>[<gold>Mascot</gold>] <light_purple>Scruff</light_purple><gray>:</gray> <green>I see, that last quest was too much for you, that's okay I have given you another one!</green></white>";
public static String NO_RE_ROLL_YET = "<white>[<gold>Mascot</gold>] <light_purple>Scruff</light_purple><gray>:</gray> <green>Sorry, you already rerolled your quest within the last 7 days. I can't give you a different quest quite yet.</green></white>";
public static String WAIT_FOR_QUEST = "<white>[<gold>Mascot</gold>] <light_purple>Scruff</light_purple><gray>:</gray> <green>You don't seem to have any quest, please wait for it to load!</green></white>";
public static String QUEST_ALREADY_FINISHED = "<white>[<gold>Mascot</gold>] <light_purple>Scruff</light_purple><gray>:</gray> <green>You already finished your quest today. You will get a new one tomorrow.</green></white>";
private static void loadMessages() {
TOO_FAR_FROM_NPC = config.getString("messages.too-far-from-npc", TOO_FAR_FROM_NPC);
DAILY_ALREADY_DONE = config.getString("messages.daily-already-done", DAILY_ALREADY_DONE);
@@ -46,6 +53,10 @@ public class MessagesConfig extends AbstractConfig{
FINISHED_QUEST = config.getString("messages.finished-quest", FINISHED_QUEST);
REWARD_SENT = config.getString("messages.reward-send", REWARD_SENT);
NOT_FINISHED_QUEST = config.getString("messages.not-finished-quest", NOT_FINISHED_QUEST);
QUEST_RE_ROLLED = config.getString("messages.re-rolled-quest", QUEST_RE_ROLLED);
NO_RE_ROLL_YET = config.getString("messages.no-re-rolled-yet", NO_RE_ROLL_YET);
WAIT_FOR_QUEST = config.getString("messages.wait-for-yet", WAIT_FOR_QUEST);
QUEST_ALREADY_FINISHED = config.getString("messages.quest-already-finished", QUEST_ALREADY_FINISHED);
}
public static String NO_PERMISSION = "<red>You do not have permission to do that.</red>";
@@ -1,9 +1,10 @@
package com.alttd.altitudequests.config;;
package com.alttd.altitudequests.config;
import com.alttd.altitudequests.objects.variants.BreedMobsQuestObject;
import com.alttd.altitudequests.objects.variants.CollectDropsQuestObject;
import com.alttd.altitudequests.objects.variants.KillMobsQuestObject;
import com.alttd.altitudequests.objects.variants.MineQuestObject;
import com.alttd.altitudequests.objects.variants.OtherQuestObject;
import com.alttd.altitudequests.util.Logger;
import org.bukkit.Material;
import org.bukkit.configuration.ConfigurationSection;
@@ -18,7 +19,7 @@ public class QuestsConfig extends AbstractConfig {
static QuestsConfig config;
public QuestsConfig() {
super(new File(System.getProperty("user.home") + File.separator + "share" + File.separator + "configs"
super(new File(File.separator + "mnt" + File.separator + "configs"
+ File.separator + "AltitudeQuests"), "quests.yml");
}
@@ -27,12 +28,14 @@ public class QuestsConfig extends AbstractConfig {
config.readConfig(QuestsConfig.class, null);
}
public static List<MineQuestObject> MINE_QUESTS = new ArrayList<>();
public static final List<MineQuestObject> MINE_QUESTS = new ArrayList<>();
public static String MINE_QUEST_NAME = "<green>Mining</green>";
public static String MINE_STEP_1 = "Mined";
public static String MINE_STEP_2 = "Turned in";
public static String MINE_TURN_IN = "<gold>Click here to turn in your <block></gold>";
public static List<String> MINE_COMMANDS = List.of("broadcast <player> Finished their daily quest!");
public static Material material;
public static Material turnInMaterial;
private static void loadMineQuests() {
MINE_QUESTS.clear();
@@ -44,10 +47,18 @@ public class QuestsConfig extends AbstractConfig {
Set<String> keys = configurationSection.getKeys(false);
for (String key : keys) {
try {
Material material = Material.valueOf(configurationSection.getString(key + ".material"));
material = Material.valueOf(configurationSection.getString(key + ".material"));
if (configurationSection.getString(key + ".turnInMaterial") == null) {
turnInMaterial = material;
}
else {
turnInMaterial = Material.valueOf(configurationSection.getString(key + ".turnInMaterial"));
}
MINE_QUESTS.add(new MineQuestObject(key,
configurationSection.getString(key + ".name"),
material,
turnInMaterial,
configurationSection.getStringList(key + ".quest-pages"),
configurationSection.getStringList(key + ".done-pages"),
configurationSection.getInt(key + ".amount-min"),
@@ -56,7 +67,7 @@ public class QuestsConfig extends AbstractConfig {
Logger.info("Loaded Mine quest " + key);
}
catch (Exception e) {
e.printStackTrace();
Logger.throwing(QuestsConfig.class.getName(), "loadMineQuest", e);
}
}
MINE_QUEST_NAME = config.getString("mining.name", MINE_QUEST_NAME);
@@ -66,7 +77,7 @@ public class QuestsConfig extends AbstractConfig {
MINE_COMMANDS = config.getStringList("mining.commands", MINE_COMMANDS);
}
public static List<KillMobsQuestObject> KILL_MOB_QUEST = new ArrayList<>();
public static final List<KillMobsQuestObject> KILL_MOB_QUEST = new ArrayList<>();
public static String KILL_MOB_QUEST_NAME = "<green>Kill mobs</green>";
public static String KILL_MOB_STEP_1 = "Killed";
public static String KILL_MOB_STEP_2 = "Confirmed";
@@ -95,7 +106,7 @@ public class QuestsConfig extends AbstractConfig {
Logger.info("Loaded Kill mob quest " + key);
}
catch (Exception e) {
e.printStackTrace();
Logger.throwing(QuestsConfig.class.getName(), "loadKillMobQuest", e);
}
}
KILL_MOB_QUEST_NAME = config.getString("kill_mobs.name", KILL_MOB_QUEST_NAME);
@@ -105,7 +116,7 @@ public class QuestsConfig extends AbstractConfig {
KILL_MOB_COMMANDS = config.getStringList("kill_mobs.commands", KILL_MOB_COMMANDS);
}
public static List<CollectDropsQuestObject> COLLECT_DROPS_QUEST = new ArrayList<>();
public static final List<CollectDropsQuestObject> COLLECT_DROPS_QUEST = new ArrayList<>();
public static String COLLECT_DROPS_QUEST_NAME = "<green>Collect drops quest</green>";
public static String COLLECT_DROPS_STEP_1 = "Obtained";
public static String COLLECT_DROPS_STEP_2 = "Turned in";
@@ -134,7 +145,7 @@ public class QuestsConfig extends AbstractConfig {
Logger.info("Loaded Collect drops quest " + key);
}
catch (Exception e) {
e.printStackTrace();
Logger.throwing(QuestsConfig.class.getName(), "loadCollectQuest", e);
}
}
COLLECT_DROPS_QUEST_NAME = config.getString("collect_drops.name", COLLECT_DROPS_QUEST_NAME);
@@ -144,7 +155,55 @@ public class QuestsConfig extends AbstractConfig {
COLLECT_DROPS_COMMANDS = config.getStringList("collect_drops.commands", COLLECT_DROPS_COMMANDS);
}
public static List<BreedMobsQuestObject> BREED_MOB_QUEST = new ArrayList<>();
public static final List<OtherQuestObject> OTHER_QUEST = new ArrayList<>();
public static String OTHER_QUEST_NAME = "<green>Other quest</green>";
public static String OTHER_TURN_IN = "<gold>Click here to turn in your <item></gold>";
public static List<String> OTHER_COMMANDS = List.of("broadcast <player> Finished their daily quest!");
public static Material item;
public static EntityType entityType;
private static void loadOtherQuests() {
OTHER_QUEST.clear();
ConfigurationSection configurationSection = config.getConfigurationSection("other.possible_tasks");
if (configurationSection == null) {
Logger.warning("No other quests in config");
return;
}
Set<String> keys = configurationSection.getKeys(false);
for (String key : keys) {
try {
item = Material.valueOf(configurationSection.getString(key + ".item"));
if (configurationSection.getString(key + ".mob") == null) {
entityType = null;
}
else {
entityType = EntityType.valueOf(configurationSection.getString(key + ".mob"));
}
OTHER_QUEST.add(new OtherQuestObject(key,
configurationSection.getString(key + ".name"),
configurationSection.getString(key + ".category"),
item,
entityType,
configurationSection.getStringList(key + ".quest-pages"),
configurationSection.getStringList(key + ".done-pages"),
configurationSection.getInt(key + ".amount-min"),
configurationSection.getInt(key + ".amount-max"),
configurationSection.getString(key + ".step-1"),
configurationSection.getString(key + ".step-2")));
if (Config.DEBUG)
Logger.info("Loaded Collect drops quest " + key);
}
catch (Exception e) {
Logger.throwing(QuestsConfig.class.getName(), "loadOtherQuests", e);
}
}
OTHER_QUEST_NAME = config.getString("other.name", OTHER_QUEST_NAME);
OTHER_TURN_IN = config.getString("other.turn-in", OTHER_TURN_IN);
OTHER_COMMANDS = config.getStringList("other.commands", OTHER_COMMANDS);
}
public static final List<BreedMobsQuestObject> BREED_MOB_QUEST = new ArrayList<>();
public static String BREED_MOB_QUEST_NAME = "<green>Breed mobs quest</green>";
public static String BREED_STEP_1 = "Bred";
public static String BREED_STEP_2 = "Confirmed";
@@ -173,7 +232,7 @@ public class QuestsConfig extends AbstractConfig {
Logger.info("Loaded Breed mob quest " + key);
}
catch (Exception e) {
e.printStackTrace();
Logger.throwing(QuestsConfig.class.getName(), "loadBreedMobQuest", e);
}
}
BREED_MOB_QUEST_NAME = config.getString("breed_mobs.name", BREED_MOB_QUEST_NAME);
@@ -10,6 +10,7 @@ import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class Database {
@@ -32,7 +33,7 @@ public class Database {
try {
openConnection();
} catch (SQLException e) {
e.printStackTrace();
Logger.throwing(Database.class.getName(), "init", e);
}
//Run all create table functions
@@ -45,8 +46,7 @@ public class Database {
} catch (InvocationTargetException ex) {
throw new RuntimeException(ex.getCause());
} catch (Exception ex) {
Logger.severe("Error invoking %.", method.toString());
ex.printStackTrace();
Logger.throwing(Database.class.getName(), "init", ex);
}
}
}
@@ -69,7 +69,7 @@ public class Database {
try {
Class.forName("com.mysql.cj.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
Logger.throwing(Database.class.getName(), "openConnection", e);
}
connection = DriverManager.getConnection(
@@ -83,27 +83,27 @@ public class Database {
try {
openConnection();
} catch (SQLException e) {
e.printStackTrace();
Logger.throwing(Database.class.getName(), "getConnection", e);
}
return connection;
}
private static void createUserPointsTable() {
try {
String sql = "CREATE TABLE IF NOT EXISTS generic_quest_progress(" +
"year_day INT NOT NULL, " +
"uuid VARCHAR(36) NOT NULL, " +
"quest VARCHAR(36) NOT NULL, " +
"quest_variant VARCHAR(36) NOT NULL, " +
"step_1_progress INT NOT NULL, " +
"step_2_progress INT NOT NULL, " +
"amount INT NOT NULL, " +
"reward_received BIT(1) NOT NULL, " +
"PRIMARY KEY (uuid)" +
")";
getDatabase().getConnection().prepareStatement(sql).executeUpdate();
String sql = "CREATE TABLE IF NOT EXISTS generic_quest_progress(" +
"year_day INT NOT NULL, " +
"uuid VARCHAR(36) NOT NULL, " +
"quest VARCHAR(36) NOT NULL, " +
"quest_variant VARCHAR(36) NOT NULL, " +
"step_1_progress INT NOT NULL, " +
"step_2_progress INT NOT NULL, " +
"amount INT NOT NULL, " +
"reward_received BIT(1) NOT NULL, " +
"PRIMARY KEY (uuid)" +
")";
try (PreparedStatement preparedStatement = getDatabase().getConnection().prepareStatement(sql)) {
preparedStatement.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
Logger.throwing(Database.class.getName(), "createUserPointsTable", e);
Logger.severe("Error while trying to create user point table");
Logger.severe("Shutting down AltitudeQuests");
Bukkit.getPluginManager().disablePlugin(AQuest.getInstance());
@@ -111,19 +111,18 @@ public class Database {
}
private static void createQuestLogTable() {
try {
String sql = "CREATE TABLE IF NOT EXISTS quest_log(" +
"uuid VARCHAR(36) NOT NULL, " +
"year INT NOT NULL, " +
"month INT NOT NULL, " +
"day INT NOT NULL, " +
"PRIMARY KEY (uuid, year, month, day)" +
")";
getDatabase().getConnection().prepareStatement(sql).executeUpdate();
String sql = "CREATE TABLE IF NOT EXISTS quest_log(" +
"uuid VARCHAR(36) NOT NULL, " +
"year INT NOT NULL, " +
"month INT NOT NULL, " +
"day INT NOT NULL, " +
"PRIMARY KEY (uuid, year, month, day)" +
")";
try (PreparedStatement preparedStatement = getDatabase().getConnection().prepareStatement(sql)) {
preparedStatement.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
Logger.severe("Error while trying to create quest log table");
Logger.severe("Shutting down AltitudeQuests");
Logger.throwing(Database.class.getName(), "createQuestLogTable", e);
Logger.severe("Error while trying to create quest log table\nShutting down AltitudeQuests");
Bukkit.getPluginManager().disablePlugin(AQuest.getInstance());
}
}
@@ -30,9 +30,7 @@ public class DataLock implements Listener {
return;
new LoadUser(uuid).runTaskAsynchronously(AQuest.getInstance());
}
case QUEUE_LOCK_FAILED -> {
Logger.warning("Unable to queue lock");
}
case QUEUE_LOCK_FAILED -> Logger.warning("Unable to queue lock");
case TRY_UNLOCK_RESULT -> {
if (event.getResult())
return;
@@ -1,28 +1,25 @@
package com.alttd.altitudequests.events;
import com.alttd.altitudequests.objects.Quest;
import com.alttd.altitudequests.objects.quests.CollectDropsQuest;
import com.alttd.altitudequests.objects.quests.OtherQuest;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerBucketFillEvent;
import org.bukkit.inventory.ItemStack;
import java.util.List;
import org.bukkit.event.player.PlayerBucketEntityEvent;
public class EntityBucketed implements Listener {
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onBucketFill(PlayerBucketFillEvent event) {
public void onBucketFill(PlayerBucketEntityEvent event) {
Player player = event.getPlayer();
Quest dailyQuest = Quest.getDailyQuest(player.getUniqueId());
if (dailyQuest == null || dailyQuest.isDone())
return;
if (dailyQuest instanceof CollectDropsQuest collectDropsQuest) {
ItemStack itemStack = event.getItemStack();
if (itemStack != null)
collectDropsQuest.collectDrops(List.of(itemStack));
if (dailyQuest instanceof OtherQuest otherQuest) {
Entity entity = event.getEntity();
otherQuest.bucket(entity);
}
}
@@ -1,15 +1,13 @@
package com.alttd.altitudequests.events;
import com.alttd.altitudequests.objects.Quest;
import com.alttd.altitudequests.objects.quests.CollectDropsQuest;
import com.alttd.altitudequests.objects.quests.OtherQuest;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerShearEntityEvent;
import java.util.List;
public class EntitySheared implements Listener {
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
@@ -18,8 +16,8 @@ public class EntitySheared implements Listener {
Quest dailyQuest = Quest.getDailyQuest(player.getUniqueId());
if (dailyQuest == null || dailyQuest.isDone())
return;
if (dailyQuest instanceof CollectDropsQuest collectDropsQuest) {
collectDropsQuest.collectDrops(List.of(event.getItem()));
if (dailyQuest instanceof OtherQuest otherQuest) {
otherQuest.shear(event.getEntity());
}
}
}
@@ -0,0 +1,30 @@
package com.alttd.altitudequests.events;
import com.alttd.altitudequests.objects.Quest;
import com.alttd.altitudequests.objects.quests.OtherQuest;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.raid.RaidFinishEvent;
import java.util.List;
import java.util.UUID;
public class FinishedRaid implements Listener {
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onRaidFinish(RaidFinishEvent event) {
List<Player> winners = event.getWinners();
for (Player player : winners) {
UUID uuid = player.getUniqueId();
Quest dailyQuest = Quest.getDailyQuest(uuid);
if (dailyQuest == null || dailyQuest.isDone()) {
return;
}
if (dailyQuest instanceof OtherQuest otherQuest) {
otherQuest.raid();
}
}
}
}
@@ -0,0 +1,31 @@
package com.alttd.altitudequests.events;
import com.alttd.altitudequests.objects.Quest;
import com.alttd.altitudequests.objects.quests.OtherQuest;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerFishEvent;
import org.bukkit.entity.Item;
import org.bukkit.inventory.ItemStack;
public class ItemCaught implements Listener {
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onItemCaught(PlayerFishEvent event) {
if (event.getCaught() == null) {
return;
}
Player player = event.getPlayer();
Quest dailyQuest = Quest.getDailyQuest(player.getUniqueId());
if (dailyQuest == null || dailyQuest.isDone()) {
return;
}
if (dailyQuest instanceof OtherQuest otherQuest) {
Item item = (Item) event.getCaught();
ItemStack caughtItem = item.getItemStack();
otherQuest.fish(caughtItem);
}
}
}
@@ -5,15 +5,14 @@ import com.alttd.altitudequests.config.Config;
import com.alttd.altitudequests.objects.Quest;
import com.alttd.altitudequests.util.Logger;
import com.alttd.datalock.DataLockAPI;
import com.google.common.io.ByteArrayDataOutput;
import com.google.common.io.ByteStreams;
import org.bukkit.Bukkit;
import org.bukkit.NamespacedKey;
import org.bukkit.boss.KeyedBossBar;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.scheduler.BukkitRunnable;
import java.util.ArrayList;
import javax.annotation.Nullable;
import java.util.UUID;
public class LogoutEvent implements Listener {
@@ -21,14 +20,22 @@ public class LogoutEvent implements Listener {
@EventHandler
public void onPlayerQuit(PlayerQuitEvent event) {
UUID uuid = event.getPlayer().getUniqueId();
new BukkitRunnable() {
@Override
public void run() {
if (Config.DEBUG)
Logger.info("Syncing %", event.getPlayer().getName());
Quest.unloadUser(uuid);
DataLockAPI.get().tryUnlock("aquest:player-data", uuid.toString());
}
}.runTaskAsynchronously(AQuest.getInstance());
if (Config.DEBUG)
Logger.info("Syncing %", event.getPlayer().getName());
removeBossBar(NamespacedKey.fromString(uuid + "-part-" + "1", AQuest.getInstance()));
removeBossBar(NamespacedKey.fromString(uuid + "-part-" + "2", AQuest.getInstance()));
Quest.unloadUser(uuid).thenAccept(result -> DataLockAPI.get().tryUnlock("aquest:player-data", uuid.toString()));
}
private void removeBossBar(@Nullable NamespacedKey namespacedKey) {
if (namespacedKey == null) {
return;
}
KeyedBossBar bossBar = Bukkit.getBossBar(namespacedKey);
if (bossBar == null) {
return;
}
Bukkit.removeBossBar(namespacedKey);
}
}
@@ -22,5 +22,4 @@ public class MineBlocks implements Listener {
if (quest instanceof MineQuest mineQuest)
mineQuest.mine(event.getBlock());
}
}
@@ -1,98 +0,0 @@
//package com.alttd.altitudequests.events;
//
//import com.alttd.altitudequests.AQuest;
//import com.alttd.altitudequests.config.Config;
//import com.alttd.altitudequests.database.Database;
//import com.alttd.altitudequests.objects.Quest;
//import com.alttd.altitudequests.util.Logger;
//import com.alttd.altitudequests.util.Utilities;
//import com.google.common.io.ByteArrayDataInput;
//import com.google.common.io.ByteStreams;
//import org.bukkit.Bukkit;
//import org.bukkit.entity.Player;
//import org.bukkit.scheduler.BukkitRunnable;
//import org.jetbrains.annotations.NotNull;
//
//import java.sql.PreparedStatement;
//import java.sql.ResultSet;
//import java.sql.SQLException;
//import java.util.UUID;
//
//public class PluginMessageListener implements org.bukkit.plugin.messaging.PluginMessageListener {
//
// @Override
// public void onPluginMessageReceived(@NotNull String channel, @NotNull Player player, @NotNull byte[] bytes) {
// if (!channel.equals("aquest:player-data")) {
// Logger.warning("Received plugin message on invalid channel");
// return;
// }
// ByteArrayDataInput in = ByteStreams.newDataInput(bytes);
// switch (in.readUTF()) {
// case "try-lock-result" -> {
// if (!in.readBoolean()) {
// Logger.warning("Unable to lock row");
// return;
// }
// UUID uuid = UUID.fromString(in.readUTF());
// if (Config.DEBUG)
// Logger.info("Received positive log result for %, loading user", uuid.toString());
// loadUser(uuid);
// }
// case "queue-lock-failed" -> Logger.warning("Encountered uuid that was locked and had a lock queued: %, lock is from %", in.readUTF(), in.readUTF());
// case "try-unlock-result" -> {
// if (in.readBoolean()) {
// // ignore?
// return;
// }
// Logger.severe("Unable to unlock %.", in.readUTF());
// }
// case "locked-queue-lock" -> {
// if (!in.readBoolean()) {
// Logger.warning("Got false back from locked queue lock");
// return;
// }
// UUID uuid = UUID.fromString(in.readUTF());
// if (Config.DEBUG)
// Logger.info("Received positive log result for %, loading user", uuid.toString());
// loadUser(uuid);
// }
// case "check-lock-result" -> {
//
// }
// }
// }
//
// private void loadUser(UUID uuid) {
// new BukkitRunnable() {
// @Override
// public void run() {
// String sql = "SELECT * FROM generic_quest_progress WHERE uuid = ?";
// try {
// PreparedStatement statement = Database.getDatabase().getConnection().prepareStatement(sql);
// statement.setString(1, uuid.toString());
// ResultSet resultSet = statement.executeQuery();
// if (resultSet.next() && resultSet.getInt("year_day") == Utilities.getYearDay()) {
// if (Quest.loadDailyQuest(
// resultSet.getString("quest"),
// resultSet.getString("quest_variant"),
// resultSet.getInt("step_1_progress"),
// resultSet.getInt("step_2_progress"),
// uuid,
// resultSet.getInt("amount"),
// resultSet.getInt("reward_received") == 1)) {
// if (Config.DEBUG)
// Logger.info("Loading daily quest for %", uuid.toString());
// return;
// } else
// Logger.warning("Unable to load quest for %, creating new quest...", uuid.toString());
// }
// } catch (SQLException exception) {
// exception.printStackTrace();
// }
// if (Config.DEBUG)
// Logger.info("Creating new daily quest for %", uuid.toString());
// Quest.createDailyQuest(Bukkit.getPlayer(uuid));
// }
// }.runTaskAsynchronously(AQuest.getInstance());
// }
//}
@@ -4,12 +4,11 @@ import com.alttd.altitudequests.AQuest;
import com.alttd.altitudequests.config.Config;
import com.alttd.altitudequests.config.MessagesConfig;
import com.alttd.altitudequests.database.Database;
import com.alttd.altitudequests.objects.quests.BreedMobsQuest;
import com.alttd.altitudequests.objects.quests.CollectDropsQuest;
import com.alttd.altitudequests.objects.quests.KillMobsQuest;
import com.alttd.altitudequests.objects.quests.MineQuest;
import com.alttd.altitudequests.objects.quests.*;
import com.alttd.altitudequests.util.Logger;
import com.alttd.altitudequests.util.Utilities;
import com.alttd.altitudequests.util.AutoHideBossBar;
import org.bukkit.boss.BarColor;
import com.alttd.datalock.DataLockAPI;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.MiniMessage;
@@ -17,19 +16,19 @@ import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
public abstract class Quest {
private static final HashMap<UUID, Quest> dailyQuests = new HashMap<>();
// private static Quest weeklyQuest = null;
// private static Quest weeklyQuest = null;
private static final List<Class<? extends Quest>> possibleQuests = new ArrayList<>();
static { // maybe make this make more sense idk
@@ -41,6 +40,8 @@ public abstract class Quest {
possibleQuests.add(CollectDropsQuest.class);
for (int i = 0; i < Config.BREED_QUEST_FREQ; i++)
possibleQuests.add(BreedMobsQuest.class);
for (int i = 0; i < Config.OTHER_QUEST_FRQ; i++)
possibleQuests.add(OtherQuest.class);
}
private final UUID uuid;
@@ -50,6 +51,8 @@ public abstract class Quest {
private boolean isDone;
private boolean rewardReceived;
private final int amount;
private final AutoHideBossBar barProgressOne;
private final AutoHideBossBar barProgressTwo;
public static synchronized void putDailyQuest(UUID uuid, Quest quest) {
dailyQuests.put(uuid, quest);
@@ -75,8 +78,8 @@ public abstract class Quest {
dailyQuests.clear();
}
public Quest(UUID uuid, int step1, int step2, Variant variant, int amount, boolean rewardReceived) {
this.uuid = uuid;
public Quest(Player player, int step1, int step2, Variant variant, int amount, boolean rewardReceived) throws Exception {
this.uuid = player.getUniqueId();
this.step1 = step1;
this.step2 = step2;
this.variant = variant;
@@ -84,17 +87,19 @@ public abstract class Quest {
this.rewardReceived = rewardReceived;
if (variant == null) {
Logger.warning("Created % quest without a variant for %", this.getClass().getName(), uuid.toString());
throw new Exception("Invalid variant");
}
if (variant != null && amount == -1)
if (amount == -1)
this.amount = variant.calculateAmount(loadQuestsDoneThisMonth(uuid));
else
this.amount = amount;
this.barProgressOne = new AutoHideBossBar(player, "1", "Step One Progress", BarColor.GREEN);
this.barProgressTwo = new AutoHideBossBar(player, "2", "Step Two Progress", BarColor.PURPLE);
}
private int loadQuestsDoneThisMonth(UUID uuid) {
String sql = "SELECT COUNT(uuid) AS total FROM quest_log WHERE uuid = ? AND year = ? AND month = ?";
try {
PreparedStatement statement = Database.getDatabase().getConnection().prepareStatement(sql);
try (PreparedStatement statement = Database.getDatabase().getConnection().prepareStatement(sql)) {
statement.setString(1, uuid.toString());
Calendar instance = Calendar.getInstance();
instance.setTime(new Date());
@@ -104,39 +109,38 @@ public abstract class Quest {
if (resultSet.next())
return resultSet.getInt("total");
} catch (SQLException exception) {
exception.printStackTrace();
Logger.throwing(Quest.class.getName(), "loadQuestsDoneThisMonth", exception);
}
return 0;
}
public static void createDailyQuest(Player player) {
if (possibleQuests.size() == 0) {
player.sendMiniMessage("<red>Unable to create quest, no quests in config</red>", null);
if (possibleQuests.isEmpty()) {
player.sendRichMessage("<red>Unable to create quest, no quests in config</red>");
return;
}
Class<? extends Quest> questClass = possibleQuests.get(Utilities.randomOr0(possibleQuests.size() - 1));
try {
Constructor<? extends Quest> constructor = questClass.getDeclaredConstructor(UUID.class);
putDailyQuest(player.getUniqueId(), constructor.newInstance(player.getUniqueId()));
} catch (InvocationTargetException | IllegalAccessException | InstantiationException | NoSuchMethodException e) {
player.sendMiniMessage("<red>Unable to create quest, contact an admin</red>", null);
e.printStackTrace();
Logger.severe("% does not have a constructor with a UUID input or has improper access.", questClass.getName());
Constructor<? extends Quest> constructor = questClass.getDeclaredConstructor(Player.class);
putDailyQuest(player.getUniqueId(), constructor.newInstance(player));
} catch (InvocationTargetException | IllegalAccessException | InstantiationException |
NoSuchMethodException e) {
player.sendRichMessage("<red>Unable to create quest, contact an admin</red>");
Logger.throwing(Quest.class.getName(), "createDailyQuest", e);
Logger.severe("% does not have a constructor with a Player input or has improper access.", questClass.getName());
} catch (Exception e) {
player.sendRichMessage("<red>Unable to create quest, contact an admin</red>");
Logger.throwing(Quest.class.getName(), "createDailyQuest", e);
Logger.severe("% could not be created due to invalid namespace key or variant.", questClass.getName());
}
}
// public static void setActiveWeeklyQuest(Quest newQuest) {
// Quest.weeklyQuest = newQuest;
// }
// private static final HashSet<UUID> queriedUsers = new HashSet<>();
public static void tryLoadDailyQuest(UUID uuid) {
// if (queriedUsers.contains(uuid))
// return;
if (dailyQuestContainsKey(uuid))
return;
// queriedUsers.add(uuid);
new BukkitRunnable() {
@Override
public void run() {
@@ -147,12 +151,14 @@ public abstract class Quest {
}.runTaskAsynchronously(AQuest.getInstance());
}
public static void unloadUser(UUID uuid) { //Pls only run async
// queriedUsers.remove(uuid);
Quest quest = removeDailyQuest(uuid);
if (quest == null)
return;
quest.save();
public static CompletableFuture<Boolean> unloadUser(UUID uuid) {
return CompletableFuture.supplyAsync(() ->{
Quest quest = removeDailyQuest(uuid);
if (quest == null)
return false;
quest.save();
return true;
});
}
public static void saveAll() {
@@ -172,6 +178,7 @@ public abstract class Quest {
Class<? extends Quest> aClass = any.get();
Constructor<? extends Quest> constructor;
try {
Player player = Bukkit.getPlayer(uuid);
if (Config.DEBUG) {
Logger.info("quest: %, uuid: %, step1: %, step2: %, variant: %, amount: %, turnedIn:%",
quest,
@@ -182,11 +189,12 @@ public abstract class Quest {
String.valueOf(amount),
String.valueOf(turnedIn));
}
constructor = aClass.getConstructor(UUID.class, int.class, int.class, String.class, int.class, boolean.class);
Quest quest1 = constructor.newInstance(uuid, step_1_progress, step_2_progress, quest_variant, amount, turnedIn);
constructor = aClass.getConstructor(Player.class, int.class, int.class, String.class, int.class, boolean.class);
Quest quest1 = constructor.newInstance(player, step_1_progress, step_2_progress, quest_variant, amount, turnedIn);
putDailyQuest(uuid, quest1);
} catch (NoSuchMethodException | IllegalAccessException | InstantiationException | InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException | IllegalAccessException | InstantiationException |
InvocationTargetException e) {
Logger.throwing(Quest.class.getName(), "loadDailyQuest", e);
return false;
}
return true;
@@ -213,7 +221,7 @@ public abstract class Quest {
public abstract TagResolver getTagResolvers();
public abstract int turnIn(Player player);
public abstract void turnIn(Player player);
public abstract Component getDisplayName();
@@ -251,12 +259,11 @@ public abstract class Quest {
}
private void saveDone() {
try {
String sql = "INSERT INTO quest_log " +
"(uuid, year, month, day) " +
"VALUES (?, ?, ?, ?) " +
"ON DUPLICATE KEY UPDATE uuid = ?";
PreparedStatement statement = Database.getDatabase().getConnection().prepareStatement(sql);
String sql = "INSERT INTO quest_log " +
"(uuid, year, month, day) " +
"VALUES (?, ?, ?, ?) " +
"ON DUPLICATE KEY UPDATE uuid = ?";
try (PreparedStatement statement = Database.getDatabase().getConnection().prepareStatement(sql)) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(new Date());
String uuidString = uuid.toString();
@@ -269,9 +276,8 @@ public abstract class Quest {
if (Config.DEBUG)
Logger.info("% finished their quest", uuidString);
} catch (SQLException e) {
e.printStackTrace();
Logger.severe("Error while trying to create quest log table");
Logger.severe("Shutting down AltitudeQuests");
Logger.throwing(Quest.class.getName(), "saveDone", e);
Logger.severe("Error while trying to create quest log table\nShutting down AltitudeQuests");
Bukkit.getPluginManager().disablePlugin(AQuest.getInstance());
}
}
@@ -290,6 +296,7 @@ public abstract class Quest {
public void addStep1(int step1) {
this.step1 += step1;
barProgressOne.show(((double) getStep1()) / getAmount());
}
public int getStep2() {
@@ -298,6 +305,7 @@ public abstract class Quest {
public void addStep2(int step2) {
this.step2 += step2;
barProgressTwo.show(((double) getStep2()) / getAmount());
}
public void setDone(boolean done) {
@@ -323,4 +331,26 @@ public abstract class Quest {
public int getAmount() {
return amount;
}
protected void saveQuest(PreparedStatement statement, Variant variant) throws SQLException {
int yearDay = Utilities.getYearDay();
if (Config.DEBUG)
Logger.info("Saving user for year day %.", String.valueOf(yearDay));
statement.setInt(1, yearDay);
statement.setString(2, getUuid().toString());
statement.setString(3, this.getClass().getSimpleName());
statement.setString(4, variant.getInternalName());
statement.setInt(5, getStep1());
statement.setInt(6, getStep2());
statement.setInt(7, getAmount());
statement.setInt(8, isRewardReceived() ? 1 : 0);
statement.setString(9, this.getClass().getSimpleName());
statement.setString(10, variant.getInternalName());
statement.setInt(11, getStep1());
statement.setInt(12, getStep2());
statement.setInt(13, yearDay);
statement.setInt(14, getAmount());
statement.setInt(15, isRewardReceived() ? 1 : 0);
statement.execute();
}
}
@@ -18,32 +18,30 @@ import org.bukkit.entity.Player;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
public class BreedMobsQuest extends Quest {
private final BreedMobsQuestObject breedMobsQuestObject;
public BreedMobsQuest(UUID uuid) {
super(uuid, 0, 0,
public BreedMobsQuest(Player player) throws Exception {
super(player, 0, 0,
QuestsConfig.BREED_MOB_QUEST.get(Utilities.randomOr0(QuestsConfig.BREED_MOB_QUEST.size() - 1)), -1, false);
if (getVariant() instanceof BreedMobsQuestObject breedMobsQuestObject)
this.breedMobsQuestObject = breedMobsQuestObject;
if (getVariant() instanceof BreedMobsQuestObject questObject)
this.breedMobsQuestObject = questObject;
else
this.breedMobsQuestObject = null;
if (breedMobsQuestObject == null) {
Logger.warning("Tried to create breedMobQuest but unable to find variant: %.", "unknown");
return;
if (this.breedMobsQuestObject == null) {
Logger.warning("Tried to create breedMobQuest but unable to find variant: %s.", "unknown");
}
}
public BreedMobsQuest(UUID uuid, int step1, int step2, String variant, int amount, boolean rewardReceived) {
super(uuid, step1, step2, QuestsConfig.BREED_MOB_QUEST.stream()
public BreedMobsQuest(Player player, int step1, int step2, String variant, int amount, boolean rewardReceived) throws Exception {
super(player, step1, step2, QuestsConfig.BREED_MOB_QUEST.stream()
.filter(object -> variant.equals(object.getInternalName()))
.findAny().orElse(null), amount, rewardReceived);
if (getVariant() instanceof BreedMobsQuestObject breedMobsQuestObject)
this.breedMobsQuestObject = breedMobsQuestObject;
if (getVariant() instanceof BreedMobsQuestObject questObject)
this.breedMobsQuestObject = questObject;
else
this.breedMobsQuestObject = null;
if (breedMobsQuestObject == null) {
@@ -61,29 +59,10 @@ public class BreedMobsQuest extends Quest {
"VALUES (?, ?, ?, ?, ?, ?, ?, ?) " +
"ON DUPLICATE KEY UPDATE " +
"quest = ?, quest_variant = ?, step_1_progress = ?, step_2_progress = ?, year_day = ?, amount = ?, reward_received = ?";
try {
PreparedStatement statement = Database.getDatabase().getConnection().prepareStatement(sql);
int yearDay = Utilities.getYearDay();
if (Config.DEBUG)
Logger.info("Saving user for year day %.", String.valueOf(yearDay));
statement.setInt(1, yearDay);
statement.setString(2, getUuid().toString());
statement.setString(3, this.getClass().getSimpleName());
statement.setString(4, breedMobsQuestObject.getInternalName());
statement.setInt(5, getStep1());
statement.setInt(6, getStep2());
statement.setInt(7, getAmount());
statement.setInt(8, isRewardReceived() ? 1 : 0);
statement.setString(9, this.getClass().getSimpleName());
statement.setString(10, breedMobsQuestObject.getInternalName());
statement.setInt(11, getStep1());
statement.setInt(12, getStep2());
statement.setInt(13, yearDay);
statement.setInt(14, getAmount());
statement.setInt(15, isRewardReceived() ? 1 : 0);
statement.execute();
try (PreparedStatement statement = Database.getDatabase().getConnection().prepareStatement(sql)) {
saveQuest(statement, getVariant());
} catch (SQLException exception) {
exception.printStackTrace();
Logger.throwing(BreedMobsQuest.class.getName(), "save", exception);
}
}
@@ -108,14 +87,13 @@ public class BreedMobsQuest extends Quest {
}
@Override
public int turnIn(Player player) {
public void turnIn(Player player) {
int maxToTurnIn = getMaxToTurnIn();
if (maxToTurnIn == 0)
return 0;
return;
addStep2(maxToTurnIn);
checkDone(player);
return maxToTurnIn;
}
@Override
@@ -21,32 +21,30 @@ import java.sql.SQLException;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
import java.util.stream.Collectors;
public class CollectDropsQuest extends Quest {
private final CollectDropsQuestObject collectDropsQuestObject;
public CollectDropsQuest(UUID uuid) {
super(uuid, 0, 0,
public CollectDropsQuest(Player player) throws Exception {
super(player, 0, 0,
QuestsConfig.COLLECT_DROPS_QUEST.get(Utilities.randomOr0(QuestsConfig.COLLECT_DROPS_QUEST.size() - 1)), -1, false);
if (getVariant() instanceof CollectDropsQuestObject collectDropsQuestObject)
this.collectDropsQuestObject = collectDropsQuestObject;
if (getVariant() instanceof CollectDropsQuestObject questObject)
this.collectDropsQuestObject = questObject;
else
this.collectDropsQuestObject = null;
if (collectDropsQuestObject == null) {
Logger.warning("Tried to create collectDropsQuest but unable to find variant: %.", "unknown");
return;
}
}
public CollectDropsQuest(UUID uuid, int step1, int step2, String variant, int amount, boolean rewardReceived) {
super(uuid, step1, step2, QuestsConfig.COLLECT_DROPS_QUEST.stream()
public CollectDropsQuest(Player player, int step1, int step2, String variant, int amount, boolean rewardReceived) throws Exception {
super(player, step1, step2, QuestsConfig.COLLECT_DROPS_QUEST.stream()
.filter(object -> variant.equals(object.getInternalName()))
.findAny().orElse(null), amount, rewardReceived);
if (getVariant() instanceof CollectDropsQuestObject collectDropsQuestObject)
this.collectDropsQuestObject = collectDropsQuestObject;
if (getVariant() instanceof CollectDropsQuestObject questObject)
this.collectDropsQuestObject = questObject;
else
this.collectDropsQuestObject = null;
if (collectDropsQuestObject == null) {
@@ -64,29 +62,10 @@ public class CollectDropsQuest extends Quest {
"VALUES (?, ?, ?, ?, ?, ?, ?, ?) " +
"ON DUPLICATE KEY UPDATE " +
"quest = ?, quest_variant = ?, step_1_progress = ?, step_2_progress = ?, year_day = ?, amount = ?, reward_received = ?";
try {
PreparedStatement statement = Database.getDatabase().getConnection().prepareStatement(sql);
int yearDay = Utilities.getYearDay();
if (Config.DEBUG)
Logger.info("Saving user for year day %.", String.valueOf(yearDay));
statement.setInt(1, yearDay);
statement.setString(2, getUuid().toString());
statement.setString(3, this.getClass().getSimpleName());
statement.setString(4, collectDropsQuestObject.getInternalName());
statement.setInt(5, getStep1());
statement.setInt(6, getStep2());
statement.setInt(7, getAmount());
statement.setInt(8, isRewardReceived() ? 1 : 0);
statement.setString(9, this.getClass().getSimpleName());
statement.setString(10, collectDropsQuestObject.getInternalName());
statement.setInt(11, getStep1());
statement.setInt(12, getStep2());
statement.setInt(13, yearDay);
statement.setInt(14, getAmount());
statement.setInt(15, isRewardReceived() ? 1 : 0);
statement.execute();
try (PreparedStatement statement = Database.getDatabase().getConnection().prepareStatement(sql)) {
saveQuest(statement, getVariant());
} catch (SQLException exception) {
exception.printStackTrace();
Logger.throwing(CollectDropsQuest.class.getName(), "save", exception);
}
}
@@ -112,12 +91,12 @@ public class CollectDropsQuest extends Quest {
}
@Override
public int turnIn(Player player) {
public void turnIn(Player player) {
PlayerInventory inventory = player.getInventory();
int maxToTurnIn = getMaxToTurnIn();
if (maxToTurnIn == 0)
return 0;
return;
var ref = new Object() {
int tmpAmount = maxToTurnIn;
};
@@ -139,7 +118,6 @@ public class CollectDropsQuest extends Quest {
int totalTurnedIn = maxToTurnIn - ref.tmpAmount;
addStep2(totalTurnedIn);
checkDone(player);
return totalTurnedIn;
}
@Override
@@ -18,32 +18,30 @@ import org.bukkit.entity.Player;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
public class KillMobsQuest extends Quest {
private final KillMobsQuestObject killMobsQuestObject;
public KillMobsQuest(UUID uuid) {
super(uuid, 0, 0,
public KillMobsQuest(Player player) throws Exception {
super(player, 0, 0,
QuestsConfig.KILL_MOB_QUEST.get(Utilities.randomOr0(QuestsConfig.KILL_MOB_QUEST.size() - 1)), -1, false);
if (getVariant() instanceof KillMobsQuestObject killMobsQuestObject)
this.killMobsQuestObject = killMobsQuestObject;
if (getVariant() instanceof KillMobsQuestObject questObject)
this.killMobsQuestObject = questObject;
else
this.killMobsQuestObject = null;
if (killMobsQuestObject == null) {
Logger.warning("Tried to create killMobsQuest but unable to find variant: %.", "unknown");
return;
}
}
public KillMobsQuest(UUID uuid, int step1, int step2, String variant, int amount, boolean rewardReceived) {
super(uuid, step1, step2, QuestsConfig.KILL_MOB_QUEST.stream()
public KillMobsQuest(Player player, int step1, int step2, String variant, int amount, boolean rewardReceived) throws Exception {
super(player, step1, step2, QuestsConfig.KILL_MOB_QUEST.stream()
.filter(object -> variant.equals(object.getInternalName()))
.findAny().orElse(null), amount, rewardReceived);
if (getVariant() instanceof KillMobsQuestObject killMobsQuestObject)
this.killMobsQuestObject = killMobsQuestObject;
if (getVariant() instanceof KillMobsQuestObject questObject)
this.killMobsQuestObject = questObject;
else
this.killMobsQuestObject = null;
if (killMobsQuestObject == null) {
@@ -61,29 +59,10 @@ public class KillMobsQuest extends Quest {
"VALUES (?, ?, ?, ?, ?, ?, ?, ?) " +
"ON DUPLICATE KEY UPDATE " +
"quest = ?, quest_variant = ?, step_1_progress = ?, step_2_progress = ?, year_day = ?, amount = ?, reward_received = ?";
try {
PreparedStatement statement = Database.getDatabase().getConnection().prepareStatement(sql);
int yearDay = Utilities.getYearDay();
if (Config.DEBUG)
Logger.info("Saving user for year day %.", String.valueOf(yearDay));
statement.setInt(1, yearDay);
statement.setString(2, getUuid().toString());
statement.setString(3, this.getClass().getSimpleName());
statement.setString(4, killMobsQuestObject.getInternalName());
statement.setInt(5, getStep1());
statement.setInt(6, getStep2());
statement.setInt(7, getAmount());
statement.setInt(8, isRewardReceived() ? 1 : 0);
statement.setString(9, this.getClass().getSimpleName());
statement.setString(10, killMobsQuestObject.getInternalName());
statement.setInt(11, getStep1());
statement.setInt(12, getStep2());
statement.setInt(13, yearDay);
statement.setInt(14, getAmount());
statement.setInt(15, isRewardReceived() ? 1 : 0);
statement.execute();
try (PreparedStatement statement = Database.getDatabase().getConnection().prepareStatement(sql)) {
saveQuest(statement, getVariant());
} catch (SQLException exception) {
exception.printStackTrace();
Logger.throwing(KillMobsQuest.class.getName(), "save", exception);
}
}
@@ -108,14 +87,13 @@ public class KillMobsQuest extends Quest {
}
@Override
public int turnIn(Player player) {
public void turnIn(Player player) {
int maxToTurnIn = getMaxToTurnIn();
if (maxToTurnIn == 0)
return 0;
return;
addStep2(maxToTurnIn);
checkDone(player);
return maxToTurnIn;
}
@Override
@@ -13,6 +13,8 @@ import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.bukkit.block.Block;
import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.Ageable;
import org.bukkit.entity.Player;
import org.bukkit.inventory.PlayerInventory;
@@ -25,26 +27,25 @@ public class MineQuest extends Quest {
private final MineQuestObject mineQuestObject;
public MineQuest(UUID uuid) {
super(uuid, 0, 0,
public MineQuest(Player player) throws Exception {
super(player, 0, 0,
QuestsConfig.MINE_QUESTS.get(Utilities.randomOr0(QuestsConfig.MINE_QUESTS.size() - 1)), -1, false);
if (getVariant() instanceof MineQuestObject mineQuestObject)
this.mineQuestObject = mineQuestObject;
if (getVariant() instanceof MineQuestObject questObject)
this.mineQuestObject = questObject;
else
mineQuestObject = null;
if (mineQuestObject == null) {
Logger.warning("Tried to create MineQuest but unable to find variant: %.", "unknown");
return;
}
}
public MineQuest(UUID uuid, int mined, int turnedIn, String variant, int amount, boolean rewardReceived) {
super(uuid, mined, turnedIn, QuestsConfig.MINE_QUESTS.stream()
public MineQuest(Player player, int mined, int turnedIn, String variant, int amount, boolean rewardReceived) throws Exception {
super(player, mined, turnedIn, QuestsConfig.MINE_QUESTS.stream()
.filter(object -> variant.equals(object.getInternalName()))
.findAny().orElse(null), amount,
rewardReceived);
if (getVariant() instanceof MineQuestObject mineQuestObject)
this.mineQuestObject = mineQuestObject;
if (getVariant() instanceof MineQuestObject questObject)
this.mineQuestObject = questObject;
else
this.mineQuestObject = null;
if (mineQuestObject == null) {
@@ -62,36 +63,17 @@ public class MineQuest extends Quest {
"VALUES (?, ?, ?, ?, ?, ?, ?, ?) " +
"ON DUPLICATE KEY UPDATE " +
"quest = ?, quest_variant = ?, step_1_progress = ?, step_2_progress = ?, year_day = ?, amount = ?, reward_received = ?";
try {
PreparedStatement statement = Database.getDatabase().getConnection().prepareStatement(sql);
int yearDay = Utilities.getYearDay();
if (Config.DEBUG)
Logger.info("Saving user for year day %.", String.valueOf(yearDay));
statement.setInt(1, yearDay);
statement.setString(2, getUuid().toString());
statement.setString(3, this.getClass().getSimpleName());
statement.setString(4, mineQuestObject.getInternalName());
statement.setInt(5, getStep1());
statement.setInt(6, getStep2());
statement.setInt(7, getAmount());
statement.setInt(8, isRewardReceived() ? 1 : 0);
statement.setString(9, this.getClass().getSimpleName());
statement.setString(10, mineQuestObject.getInternalName());
statement.setInt(11, getStep1());
statement.setInt(12, getStep2());
statement.setInt(13, yearDay);
statement.setInt(14, getAmount());
statement.setInt(15, isRewardReceived() ? 1 : 0);
statement.execute();
try (PreparedStatement statement = Database.getDatabase().getConnection().prepareStatement(sql)) {
saveQuest(statement, getVariant());
} catch (SQLException exception) {
exception.printStackTrace();
Logger.throwing(MineQuest.class.getName(), "save", exception);
}
}
@Override
public TagResolver getTagResolvers() {
TagResolver resolver = TagResolver.resolver(
Placeholder.unparsed("block", Utilities.formatName(mineQuestObject.getMaterial().name())),
Placeholder.unparsed("block", Utilities.formatName(mineQuestObject.getTurnInMaterial().name())),
Placeholder.parsed("step_1_progress", getStep1() == getAmount() ?
"<green>" + getStep1() + "</green>" : "<red>" + getStep1() + "</red>"),
Placeholder.parsed("step_1_total", String.valueOf(getAmount())),
@@ -109,19 +91,19 @@ public class MineQuest extends Quest {
}
@Override
public int turnIn(Player player) {
public void turnIn(Player player) {
PlayerInventory inventory = player.getInventory();
int maxToTurnIn = getMaxToTurnIn();
if (maxToTurnIn == 0)
return 0;
return;
var ref = new Object() {
int tmpAmount = maxToTurnIn;
};
Arrays.stream(inventory.getContents())
.filter(Objects::nonNull)
.filter(itemStack -> itemStack.getType().equals(mineQuestObject.getMaterial()))
.filter(itemStack -> itemStack.getType().equals(mineQuestObject.getTurnInMaterial()))
.forEach(itemStack -> {
if (ref.tmpAmount == 0)
return;
@@ -136,7 +118,6 @@ public class MineQuest extends Quest {
int totalTurnedIn = maxToTurnIn - ref.tmpAmount;
addStep2(totalTurnedIn);
checkDone(player);
return totalTurnedIn;
}
@Override
@@ -149,8 +130,20 @@ public class MineQuest extends Quest {
return QuestsConfig.MINE_COMMANDS;
}
public boolean checkBlock(Block block) {
BlockData blockData = block.getBlockData();
if (!block.getType().equals(mineQuestObject.getMaterial())) {
return true;
}
else if (blockData instanceof Ageable ageable) {
return ageable.getAge() != ageable.getMaximumAge();
}
return false;
}
public void mine(Block block) {
if (isDone() || !block.getType().equals(mineQuestObject.getMaterial()) || getAmount() == getStep1())
if (isDone() || checkBlock(block) || getAmount() == getStep1())
return;
addStep1(1);
checkDone();
@@ -0,0 +1,190 @@
package com.alttd.altitudequests.objects.quests;
import com.alttd.altitudequests.config.Config;
import com.alttd.altitudequests.config.QuestsConfig;
import com.alttd.altitudequests.database.Database;
import com.alttd.altitudequests.objects.Quest;
import com.alttd.altitudequests.objects.Variant;
import com.alttd.altitudequests.objects.variants.OtherQuestObject;
import com.alttd.altitudequests.util.Logger;
import com.alttd.altitudequests.util.Utilities;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.bukkit.DyeColor;
import org.bukkit.Material;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Sheep;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
public class OtherQuest extends Quest {
private final OtherQuestObject otherQuestObject;
public OtherQuest(Player player) throws Exception {
super(player, 0, 0,
QuestsConfig.OTHER_QUEST.get(Utilities.randomOr0(QuestsConfig.OTHER_QUEST.size() - 1)), -1, false);
if (getVariant() instanceof OtherQuestObject questObject)
this.otherQuestObject = questObject;
else
this.otherQuestObject = null;
if (otherQuestObject == null) {
Logger.warning("Tried to create OtherQuest but unable to find variant: %.", "unknown");
}
}
public OtherQuest(Player player, int step1, int step2, String variant, int amount, boolean rewardReceived) throws Exception {
super(player, step1, step2, QuestsConfig.OTHER_QUEST.stream()
.filter(object -> variant.equals(object.getInternalName()))
.findAny().orElse(null), amount, rewardReceived);
if (getVariant() instanceof OtherQuestObject questObject)
this.otherQuestObject = questObject;
else
this.otherQuestObject = null;
if (otherQuestObject == null) {
Logger.warning("Tried to create OtherQuest but unable to find variant: %.", variant);
Logger.warning("Possible variants: %", QuestsConfig.OTHER_QUEST.stream().map(Variant::getInternalName).collect(Collectors.joining(", ")));
return;
}
checkDone();
}
@Override
public void save() {
String sql = "INSERT INTO generic_quest_progress " +
"(year_day, uuid, quest, quest_variant, step_1_progress, step_2_progress, amount, reward_received) " +
"VALUES (?, ?, ?, ?, ?, ?, ?, ?) " +
"ON DUPLICATE KEY UPDATE " +
"quest = ?, quest_variant = ?, step_1_progress = ?, step_2_progress = ?, year_day = ?, amount = ?, reward_received = ?";
try (PreparedStatement statement = Database.getDatabase().getConnection().prepareStatement(sql)) {
saveQuest(statement, getVariant());
} catch (SQLException exception) {
Logger.throwing(OtherQuest.class.getName(), "save", exception);
}
}
@Override
public TagResolver getTagResolvers() {
TagResolver resolver = TagResolver.resolver(
Placeholder.unparsed("item", Utilities.formatName(otherQuestObject.getMaterial().name())),
Placeholder.parsed("step_1_progress", getStep1() == getAmount() ?
"<green>" + getStep1() + "</green>" : "<red>" + getStep1() + "</red>"),
Placeholder.parsed("step_1_total", String.valueOf(getAmount())),
Placeholder.parsed("step_2_progress", getStep2() == getAmount() ?
"<green>" + getStep2() + "</green>" : "<red>" + getStep2() + "</red>"),
Placeholder.parsed("step_2_total", String.valueOf(getAmount())),
Placeholder.unparsed("step_1", otherQuestObject.getStep1()),
Placeholder.unparsed("step_2", otherQuestObject.getStep2()),
Placeholder.unparsed("turn_in_text", QuestsConfig.OTHER_TURN_IN)
);
Component turnInText = MiniMessage.miniMessage().deserialize(QuestsConfig.OTHER_TURN_IN, resolver);
return TagResolver.resolver(
resolver,
Placeholder.component("turn_in_text", turnInText)
);
}
@Override
public void turnIn(Player player) {
PlayerInventory inventory = player.getInventory();
int maxToTurnIn = getMaxToTurnIn();
if (maxToTurnIn == 0)
return;
var ref = new Object() {
int tmpAmount = maxToTurnIn;
};
Arrays.stream(inventory.getContents())
.filter(Objects::nonNull)
.filter(itemStack -> itemStack.getType().equals(otherQuestObject.getMaterial()))
.forEach(itemStack -> {
if (ref.tmpAmount == 0)
return;
if (itemStack.getAmount() > ref.tmpAmount) {
itemStack.setAmount(itemStack.getAmount() - ref.tmpAmount);
ref.tmpAmount = 0;
} else {
ref.tmpAmount -= itemStack.getAmount();
itemStack.setAmount(0);
}
});
int totalTurnedIn = maxToTurnIn - ref.tmpAmount;
addStep2(totalTurnedIn);
checkDone(player);
}
@Override
public Component getDisplayName() {
return MiniMessage.miniMessage().deserialize("<green>%s</green>".formatted(otherQuestObject.getCategory()));
}
@Override
public List<String> getRewardCommand() {
return QuestsConfig.COLLECT_DROPS_COMMANDS;
}
public void fish(ItemStack caughtItem) {
if (isDone() || !caughtItem.getType().equals(otherQuestObject.getMaterial()) || getAmount() == getStep1()|| !otherQuestObject.getCategory().equalsIgnoreCase("FISHING")) {
return;
}
addStep1(1);
checkDone();
}
public void shear(Entity entity) {
if (isDone() || !entity.getType().equals(otherQuestObject.getEntity()) || getAmount() == getStep1()|| !otherQuestObject.getCategory().equalsIgnoreCase("SHEARING")) {
return;
}
DyeColor color = getDyeColorFromItemStack(otherQuestObject.getMaterial());
if (entity instanceof Sheep sheep) {
if (sheep.getColor() != color) {
return;
}
}
addStep1(1);
checkDone();
}
public void bucket(Entity entity) {
if (isDone() || !entity.getType().equals(otherQuestObject.getEntity()) || getAmount() == getStep1()|| !otherQuestObject.getCategory().equalsIgnoreCase("BUCKETING")) {
return;
}
addStep1(1);
checkDone();
}
public void raid() {
if (isDone() || getAmount() == getStep1() || !otherQuestObject.getCategory().equalsIgnoreCase("RAID")) { //without checking the category, other players who have otherQuests active will also have a step added
return;
}
addStep1(1);
checkDone();
}
public static List<String> getSubTypes() {
return QuestsConfig.OTHER_QUEST.stream().map(Variant::getInternalName).collect(Collectors.toList());
}
public static DyeColor getDyeColorFromItemStack(Material material) {
if (material != null && material.name().contains("_WOOL")) {
String colorName = material.name().replace("_WOOL", "");
try {
return DyeColor.valueOf(colorName);
} catch (IllegalArgumentException ignored) {
}
}
return null;
}
}
@@ -8,14 +8,19 @@ import java.util.List;
public class MineQuestObject extends Variant {
private final Material material;
private final Material turnInMaterial;
public MineQuestObject(String internalName, String name, Material material,
public MineQuestObject(String internalName, String name, Material material, Material turnInMaterial,
List<String> questPages, List<String> donePages, int min, int max) {
super(internalName, name, questPages, donePages, min, max);
this.material = material;
this.turnInMaterial = turnInMaterial;
}
public Material getMaterial() {
return material;
}
public Material getTurnInMaterial() {
return turnInMaterial;
}
}
@@ -0,0 +1,34 @@
package com.alttd.altitudequests.objects.variants;
import com.alttd.altitudequests.objects.Variant;
import org.bukkit.Material;
import org.bukkit.entity.EntityType;
import java.util.List;
public class OtherQuestObject extends Variant {
private final Material material;
private final EntityType entity;
private final String step1;
private final String step2;
private final String category;
public OtherQuestObject(String internalName, String name, String category, Material item, EntityType entity,
List<String> questPages, List<String> donePages, int min, int max, String step1, String step2) {
super(internalName, name, questPages, donePages, min, max);
this.material = item;
this.entity = entity;
this.step1 = step1;
this.step2 = step2;
this.category = category;
}
public Material getMaterial() {
return material;
}
public EntityType getEntity() {return entity;}
public String getStep1() {return step1;}
public String getStep2() {return step2;}
public String getCategory() {return category;}
}
@@ -0,0 +1,61 @@
package com.alttd.altitudequests.util;
import com.alttd.altitudequests.AQuest;
import com.alttd.altitudequests.config.Config;
import org.bukkit.Bukkit;
import org.bukkit.NamespacedKey;
import org.bukkit.boss.BarColor;
import org.bukkit.boss.BarStyle;
import org.bukkit.boss.BossBar;
import org.bukkit.boss.KeyedBossBar;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
import java.time.Instant;
import java.util.HashMap;
import java.util.Objects;
public class AutoHideBossBar {
private static final HashMap<BossBar, Instant> bossBars = new HashMap<>();
private final BossBar bossBar;
public AutoHideBossBar(Player player, String part, String title, BarColor barColor) throws Exception {
NamespacedKey namespacedKeyOne = NamespacedKey.fromString(player.getUniqueId() + "-part-" + part, AQuest.getInstance());
if (namespacedKeyOne == null) {
Logger.warning("Unable to create nameSpacedKey with suffix % for quest for %", part, player.getName());
throw new Exception("Failed to create namespace key");
}
KeyedBossBar retrievedBossBar = Bukkit.getBossBar(namespacedKeyOne);
this.bossBar = Objects.requireNonNullElseGet(retrievedBossBar, () -> Bukkit.createBossBar(
namespacedKeyOne,
title,
barColor,
BarStyle.SOLID));
bossBar.setVisible(false);
bossBar.addPlayer(player);
}
public void show(double progress) {
bossBar.setVisible(true);
bossBar.setProgress(progress);
bossBars.put(bossBar, Instant.now().plusSeconds(Config.BOSS_BAR_AUTO_HIDE.toSeconds()));
}
public static void initiate() {
new BukkitRunnable() {
@Override
public void run() {
for (HashMap.Entry<BossBar, Instant> entry : bossBars.entrySet()) {
if (Instant.now().isAfter(entry.getValue())) {
BossBar bossBar = entry.getKey();
bossBar.setVisible(false);
bossBars.remove(entry.getKey());
}
}
}
}.runTaskTimer(AQuest.getInstance(), 10, 10);
}
}
@@ -13,7 +13,7 @@ import java.util.UUID;
public class LoadUser extends BukkitRunnable {
UUID uuid;
private final UUID uuid;
public LoadUser(UUID uuid) {
this.uuid = uuid;
@@ -22,8 +22,7 @@ public class LoadUser extends BukkitRunnable {
@Override
public void run() {
String sql = "SELECT * FROM generic_quest_progress WHERE uuid = ?";
try {
PreparedStatement statement = Database.getDatabase().getConnection().prepareStatement(sql);
try (PreparedStatement statement = Database.getDatabase().getConnection().prepareStatement(sql)) {
statement.setString(1, uuid.toString());
ResultSet resultSet = statement.executeQuery();
if (resultSet.next() && resultSet.getInt("year_day") == Utilities.getYearDay()) {
@@ -42,7 +41,7 @@ public class LoadUser extends BukkitRunnable {
Logger.warning("Unable to load quest for %, creating new quest...", uuid.toString());
}
} catch (SQLException exception) {
exception.printStackTrace();
Logger.throwing(LoadUser.class.getName(), "run", exception);
}
if (Config.DEBUG)
Logger.info("Creating new daily quest for %", uuid.toString());
@@ -33,4 +33,8 @@ public class Logger {
}
logger.severe(severe);
}
public static void throwing(String sourceClass, String sourceMethod, Exception e) {
logger.throwing(sourceClass, sourceMethod, e);
}
}
@@ -0,0 +1,48 @@
package com.alttd.altitudequests.util;
import com.alttd.altitudequests.config.Config;
import com.alttd.altitudequests.objects.Quest;
import net.kyori.adventure.inventory.Book;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class ProgressBookOpener {
private static final MiniMessage miniMessage = MiniMessage.miniMessage();
public static void openProgressBook(Player player) {
player.openBook(getProgressBook(player));
}
private static Book getProgressBook (Player player) {
return Book.builder()
.author(miniMessage.deserialize(Config.PROGRESS_BOOK_AUTHOR))
.title(miniMessage.deserialize(Config.PROGRESS_BOOK_TITLE))
.pages(getPages(player))
.build();
}
private static final Component error = MiniMessage.miniMessage().deserialize("<red>Error retrieving quest data</red>");
private static List<Component> getPages(Player player) {
Quest dailyQuest = Quest.getDailyQuest(player.getUniqueId());
if (dailyQuest == null)
return List.of(error);
TagResolver tagResolver = TagResolver.resolver(
TagResolver.resolver(Placeholder.component("player", player.name())),
TagResolver.resolver(Placeholder.component("quest", dailyQuest.getDisplayName())),
TagResolver.resolver(Placeholder.component("variant", dailyQuest.getVariant().getName())),
dailyQuest.getTagResolvers()
);
List<String> pages = new ArrayList<>(Config.PROGRESS_PAGES);
return (pages.stream()
.map(page -> miniMessage.deserialize(page, tagResolver))
.collect(Collectors.toList()));
}
}