11package parallelmc .parallelutils .modules .parallelquests ;
22
3+ import net .kyori .adventure .key .Key ;
4+ import net .kyori .adventure .sound .Sound ;
5+ import net .kyori .adventure .text .Component ;
6+ import net .kyori .adventure .text .format .NamedTextColor ;
37import org .bukkit .Bukkit ;
8+ import org .bukkit .entity .Player ;
49import org .bukkit .plugin .Plugin ;
510import org .bukkit .plugin .PluginManager ;
611import org .jetbrains .annotations .NotNull ;
@@ -92,7 +97,13 @@ PRIMARY KEY (Id)
9297 }
9398
9499 Bukkit .getScheduler ().runTaskTimer (puPlugin , () -> {
95- PlayerQuestStatuses .keySet ().forEach (u -> savePlayerQuestStatus (u , false ));
100+ PlayerQuestStatuses .keySet ().forEach (u -> {
101+ Player p = Bukkit .getPlayer (u );
102+ // the quest cache should only contain online players since players are removed when they log off
103+ // regardless, make sure the players we're saving actually exist
104+ if (p == null ) return ;
105+ savePlayerQuestStatus (p , false );
106+ });
96107 }, 6000L , 6000L ); // 5 minutes
97108
98109 Instance = this ;
@@ -120,23 +131,36 @@ public Quest getQuest(String questId) {
120131 return RegisteredQuests .get (questId );
121132 }
122133
123- public Optional <QuestStatus > getQuestStatus (UUID uuid , String questId ) {
124- return getAllQuestStatuses (uuid ).stream ()
134+ public Optional <QuestStatus > getQuestStatus (Player player , String questId ) {
135+ return getAllQuestStatuses (player ).stream ()
125136 .filter (x -> x .getQuestId ().equals (questId ))
126137 .findFirst ();
127138 }
128139
129140 /**
130141 * Returns a list of quests a player currently has active, as well as if they are completed.
131142 * If a quest ID is not in this list, the player has not accepted it yet.
132- * @param uuid The player UUID to search
143+ * @param player The Player to search
133144 */
134- public List <QuestStatus > getAllQuestStatuses (UUID uuid ) {
135- return PlayerQuestStatuses .getOrDefault (uuid , new ArrayList <>());
145+ public List <QuestStatus > getAllQuestStatuses (Player player ) {
146+ return PlayerQuestStatuses .getOrDefault (player . getUniqueId () , new ArrayList <>());
136147 }
137148
138- public void startQuest (UUID uuid , String questId , String initialStage ) {
139- List <QuestStatus > statuses = getAllQuestStatuses (uuid );
149+ public boolean hasCompletedQuest (Player player , String questId ) {
150+ Optional <QuestStatus > status = getQuestStatus (player , questId );
151+ return status .isPresent () && status .get ().isCompleted ();
152+ }
153+
154+ public void startQuest (Player player , String questId , String initialStage ) {
155+ Quest quest = getQuest (questId );
156+ if (quest == null ) {
157+ ParallelUtils .log (Level .SEVERE , "Tried to start-nonexistent quest: " + questId );
158+ return ;
159+ }
160+ player .sendMessage (Component .text ("Quest Accepted: " + quest .getQuestName (), NamedTextColor .GOLD ));
161+ player .playSound (Sound .sound (Key .key (Key .MINECRAFT_NAMESPACE , "block.note_block.chime" ), Sound .Source .MASTER , 1f , 1f ));
162+ UUID uuid = player .getUniqueId ();
163+ List <QuestStatus > statuses = getAllQuestStatuses (player );
140164 if (statuses .isEmpty ()) {
141165 statuses .add (new QuestStatus (questId , initialStage ));
142166 PlayerQuestStatuses .put (uuid , statuses );
@@ -149,10 +173,10 @@ public void startQuest(UUID uuid, String questId, String initialStage) {
149173 statuses .add (new QuestStatus (questId , initialStage ));
150174 }
151175
152- public void setQuestStage (UUID uuid , String questId , String newStage ) {
153- var status = getQuestStatus (uuid , questId );
176+ public void setQuestStage (Player player , String questId , String newStage ) {
177+ var status = getQuestStatus (player , questId );
154178 if (status .isEmpty ()) {
155- ParallelUtils .log (Level .WARNING , "Tried to update status of quest " + questId + " for UUID " + uuid + " that has not accepted said quest!" );
179+ ParallelUtils .log (Level .WARNING , "Tried to update status of quest " + questId + " for " + player . getName () + " that has not accepted said quest!" );
156180 return ;
157181 }
158182 status .get ().setQuestStage (newStage );
@@ -161,16 +185,16 @@ public void setQuestStage(UUID uuid, String questId, String newStage) {
161185 /**
162186 * Asynchronously loads a player's quest data into the cache.
163187 * If a player's data already exists in the cache, the load will be ignored.
164- * @param uuid The Player UUID to load
188+ * @param player The Player to load
165189 */
166- public void loadPlayerQuestStatus (UUID uuid ) {
190+ public void loadPlayerQuestStatus (Player player ) {
167191 Bukkit .getScheduler ().runTaskAsynchronously (puPlugin , () -> {
168192 List <QuestStatus > result = new ArrayList <>();
169193 try (Connection conn = puPlugin .getDbConn ()) {
170194 if (conn == null ) throw new SQLException ("Unable to establish connection!" );
171195 Statement statement = conn .createStatement ();
172196 statement .setQueryTimeout (10 );
173- ResultSet results = statement .executeQuery ("select * from Quests where UUID = '" + uuid + "'" );
197+ ResultSet results = statement .executeQuery ("select * from Quests where UUID = '" + player . getUniqueId () + "'" );
174198 while (results .next ()) {
175199 String questId = results .getString ("QuestId" );
176200 String questStage = results .getString ("QuestStage" );
@@ -182,30 +206,30 @@ public void loadPlayerQuestStatus(UUID uuid) {
182206 e .printStackTrace ();
183207 }
184208
185- if (PlayerQuestStatuses .putIfAbsent (uuid , result ) != null ) {
186- ParallelUtils .log (Level .WARNING , "UUID " + uuid + " already has an entry in PlayerQuestStatuses, ignoring!" );
209+ if (PlayerQuestStatuses .putIfAbsent (player . getUniqueId () , result ) != null ) {
210+ ParallelUtils .log (Level .WARNING , "UUID " + player . getUniqueId () + " already has an entry in PlayerQuestStatuses, ignoring!" );
187211 }
188212 });
189213 }
190214
191215 /**
192216 * Asynchronously saves a player's quest data to the database.
193- * @param uuid The Player UUID to save
217+ * @param player The Player to save
194218 * @param removeFromCache If true, the data will also be removed from the local cache
195219 */
196- public void savePlayerQuestStatus (UUID uuid , boolean removeFromCache ) {
220+ public void savePlayerQuestStatus (Player player , boolean removeFromCache ) {
197221 Bukkit .getScheduler ().runTaskAsynchronously (puPlugin , () -> {
198- List <QuestStatus > status = getAllQuestStatuses (uuid );
222+ List <QuestStatus > status = getAllQuestStatuses (player );
199223 try (Connection conn = puPlugin .getDbConn ()) {
200224 if (conn == null ) throw new SQLException ("Unable to establish connection!" );
201225 Statement statement = conn .createStatement ();
202226 statement .setQueryTimeout (10 );
203- statement .execute ("delete from Quests where UUID = '" + uuid + "'" );
227+ statement .execute ("delete from Quests where UUID = '" + player . getUniqueId () + "'" );
204228 PreparedStatement prepared = conn .prepareStatement ("insert into Quests (UUID, QuestId, QuestStage) values (?, ?, ?)" );
205229 prepared .setQueryTimeout (30 );
206230 status .forEach (s -> {
207231 try {
208- prepared .setString (1 , uuid .toString ());
232+ prepared .setString (1 , player . getUniqueId () .toString ());
209233 prepared .setString (2 , s .getQuestId ());
210234 prepared .setString (3 , s .getQuestStage ());
211235 prepared .addBatch ();
@@ -222,7 +246,7 @@ public void savePlayerQuestStatus(UUID uuid, boolean removeFromCache) {
222246 e .printStackTrace ();
223247 } finally {
224248 if (removeFromCache )
225- PlayerQuestStatuses .remove (uuid );
249+ PlayerQuestStatuses .remove (player . getUniqueId () );
226250 }
227251 });
228252 }
0 commit comments