11package parallelmc .parallelutils .modules .parallelquests ;
22
33import org .bukkit .Bukkit ;
4- import org .bukkit .entity .Player ;
54import org .bukkit .plugin .Plugin ;
65import org .bukkit .plugin .PluginManager ;
7- import org .checkerframework .checker .units .qual .C ;
86import org .jetbrains .annotations .NotNull ;
97import org .jetbrains .annotations .Nullable ;
108import parallelmc .parallelutils .Constants ;
119import parallelmc .parallelutils .ParallelClassLoader ;
1210import parallelmc .parallelutils .ParallelModule ;
1311import parallelmc .parallelutils .ParallelUtils ;
14- import parallelmc .parallelutils .modules .parallelquests .commands .ExampleConversation ;
1512import parallelmc .parallelutils .modules .parallelquests .commands .QuestTracker ;
16- import parallelmc .parallelutils .modules .parallelquests .dialogue .Conversation ;
17- import parallelmc .parallelutils .modules .parallelquests .dialogue . Dialogue ;
13+ import parallelmc .parallelutils .modules .parallelquests .dialogue .ConversationManager ;
14+ import parallelmc .parallelutils .modules .parallelquests .events . OnCommand ;
1815import parallelmc .parallelutils .modules .parallelquests .events .OnJoinLeave ;
19- import parallelmc .parallelutils .modules .parallelquests .events .OnSlotUpdated ;
16+ import parallelmc .parallelutils .modules .parallelquests .quests .Quest ;
17+ import parallelmc .parallelutils .modules .parallelquests .quests .TheBakersBeastQuest ;
2018
2119import java .sql .*;
2220import java .util .*;
@@ -28,11 +26,11 @@ public class ParallelQuests extends ParallelModule {
2826
2927 public ParallelQuests (ParallelClassLoader classLoader , List <String > dependents ) { super (classLoader , dependents ); }
3028
31- // TODO: populate
32- private final HashSet <String > ValidQuests = new HashSet <>();
29+ private final HashMap <String , Quest > RegisteredQuests = new HashMap <>();
3330
3431 private final ConcurrentHashMap <UUID , List <QuestStatus >> PlayerQuestStatuses = new ConcurrentHashMap <>();
35- private final HashMap <UUID , Conversation > ActiveConversations = new HashMap <>();
32+
33+ private static final ConversationManager ConversationManager = new ConversationManager ();
3634
3735 private static ParallelQuests Instance ;
3836
@@ -59,10 +57,17 @@ public void onEnable() {
5957 }
6058
6159 manager .registerEvents (new OnJoinLeave (), puPlugin );
62- manager .registerEvents (new OnSlotUpdated (), puPlugin );
60+ manager .registerEvents (new OnCommand (), puPlugin );
6361
6462 puPlugin .getCommand ("questtracker" ).setExecutor (new QuestTracker ());
65- puPlugin .getCommand ("exampleconversation" ).setExecutor (new ExampleConversation ());
63+
64+ RegisteredQuests .put ("thebakersbeast" , new TheBakersBeastQuest ());
65+
66+ for (Quest quest : RegisteredQuests .values ()) {
67+ quest .init ();
68+ }
69+
70+ ParallelUtils .log (Level .WARNING , "Initialized " + RegisteredQuests .size () + " quests." );
6671
6772 try (Connection conn = puPlugin .getDbConn ()) {
6873 if (conn == null ) throw new SQLException ("Unable to establish connection!" );
@@ -74,7 +79,7 @@ public void onEnable() {
7479 Id int not null auto_increment,
7580 UUID varchar(36) not null,
7681 QuestId varchar(128) not null,
77- Completed tinyint not null,
82+ QuestStage varchar(128) not null,
7883 constraint Quests_Id_uindex
7984 unique (Id),
8085 PRIMARY KEY (Id)
@@ -87,7 +92,7 @@ PRIMARY KEY (Id)
8792 }
8893
8994 Bukkit .getScheduler ().runTaskTimer (puPlugin , () -> {
90- PlayerQuestStatuses .keySet ().forEach (this :: savePlayerQuestStatus );
95+ PlayerQuestStatuses .keySet ().forEach (u -> savePlayerQuestStatus ( u , false ) );
9196 }, 6000L , 6000L ); // 5 minutes
9297
9398 Instance = this ;
@@ -108,46 +113,49 @@ public static ParallelQuests get() {
108113 return Instance ;
109114 }
110115
111- public void startConversation (Player player , Dialogue dialogue ) {
112- if (ActiveConversations .containsKey (player .getUniqueId ())) {
113- ParallelUtils .log (Level .WARNING , "Tried to add " + player .getName () + " to a conversation when they are already in one!" );
114- return ;
115- }
116- Conversation c = new Conversation (dialogue );
117- c .enter (player );
118- ActiveConversations .put (player .getUniqueId (), c );
119- }
116+ public static ConversationManager getConversationManager () { return ConversationManager ; }
120117
121- public void endConversation (UUID uuid ) {
122- ActiveConversations .remove (uuid );
118+ @ Nullable
119+ public Quest getQuest (String questId ) {
120+ return RegisteredQuests .get (questId );
123121 }
124122
125- public @ Nullable Conversation getActiveConversation (UUID uuid ) {
126- return ActiveConversations .getOrDefault (uuid , null );
123+ public Optional <QuestStatus > getQuestStatus (UUID uuid , String questId ) {
124+ return getAllQuestStatuses (uuid ).stream ()
125+ .filter (x -> x .getQuestId ().equals (questId ))
126+ .findFirst ();
127127 }
128128
129129 /**
130130 * Returns a list of quests a player currently has active, as well as if they are completed.
131131 * If a quest ID is not in this list, the player has not accepted it yet.
132132 * @param uuid The player UUID to search
133133 */
134- public List <QuestStatus > getQuestStatus (UUID uuid ) {
135- return PlayerQuestStatuses .getOrDefault (uuid , List . of ());
134+ public List <QuestStatus > getAllQuestStatuses (UUID uuid ) {
135+ return PlayerQuestStatuses .getOrDefault (uuid , new ArrayList <> ());
136136 }
137137
138- public boolean markQuestCompleted (UUID uuid , String questId ) {
139- if (!ValidQuests .contains (questId )) {
140- ParallelUtils .log (Level .SEVERE , "Invalid Quest ID " + questId + " provided for quest completion!" );
141- return false ;
138+ public void startQuest (UUID uuid , String questId , String initialStage ) {
139+ List <QuestStatus > statuses = getAllQuestStatuses (uuid );
140+ if (statuses .isEmpty ()) {
141+ statuses .add (new QuestStatus (questId , initialStage ));
142+ PlayerQuestStatuses .put (uuid , statuses );
143+ return ;
144+ }
145+ if (statuses .stream ().anyMatch (x -> x .getQuestId ().equals (questId ))) {
146+ ParallelUtils .log (Level .WARNING , "Tried to start already active quest " + questId + " for UUID " + uuid );
147+ return ;
142148 }
149+ statuses .add (new QuestStatus (questId , initialStage ));
150+ }
143151
144- Optional <QuestStatus > status = getQuestStatus (uuid ).stream ().filter (x -> x .getQuestId ().equals (questId )).findFirst ();
152+ public void setQuestStage (UUID uuid , String questId , String newStage ) {
153+ var status = getQuestStatus (uuid , questId );
145154 if (status .isEmpty ()) {
146- return false ;
155+ ParallelUtils .log (Level .WARNING , "Tried to update status of quest " + questId + " for UUID " + uuid + " that has not accepted said quest!" );
156+ return ;
147157 }
148-
149- status .get ().markCompleted ();
150- return false ;
158+ status .get ().setQuestStage (newStage );
151159 }
152160
153161 /**
@@ -165,8 +173,8 @@ public void loadPlayerQuestStatus(UUID uuid) {
165173 ResultSet results = statement .executeQuery ("select * from Quests where UUID = '" + uuid + "'" );
166174 while (results .next ()) {
167175 String questId = results .getString ("QuestId" );
168- boolean completed = results .getBoolean ( "Completed " );
169- result .add (new QuestStatus (questId , completed ));
176+ String questStage = results .getString ( "QuestStage " );
177+ result .add (new QuestStatus (questId , questStage ));
170178 }
171179 conn .commit ();
172180 statement .close ();
@@ -182,34 +190,24 @@ public void loadPlayerQuestStatus(UUID uuid) {
182190
183191 /**
184192 * Asynchronously saves a player's quest data to the database.
185- * The player's data WILL be removed from the cache, see savePlayerQuestStatus to avoid this.
186- * @param uuid The Player UUID to save
187- */
188- public void saveAndRemovePlayerQuestStatus (UUID uuid ) {
189- savePlayerQuestStatus (uuid );
190- PlayerQuestStatuses .remove (uuid );
191- }
192-
193- /**
194- * Asynchronously saves a player's quest data to the database.
195- * The player's data will NOT be removed from the cache, see saveAndRemovePlayerQuestStatus
196193 * @param uuid The Player UUID to save
194+ * @param removeFromCache If true, the data will also be removed from the local cache
197195 */
198- public void savePlayerQuestStatus (UUID uuid ) {
196+ public void savePlayerQuestStatus (UUID uuid , boolean removeFromCache ) {
199197 Bukkit .getScheduler ().runTaskAsynchronously (puPlugin , () -> {
200- List <QuestStatus > status = getQuestStatus (uuid );
198+ List <QuestStatus > status = getAllQuestStatuses (uuid );
201199 try (Connection conn = puPlugin .getDbConn ()) {
202200 if (conn == null ) throw new SQLException ("Unable to establish connection!" );
203201 Statement statement = conn .createStatement ();
204202 statement .setQueryTimeout (10 );
205203 statement .execute ("delete from Quests where UUID = '" + uuid + "'" );
206- PreparedStatement prepared = conn .prepareStatement ("insert into Quests (UUID, QuestId, Completed ) values (?, ?, ?)" );
204+ PreparedStatement prepared = conn .prepareStatement ("insert into Quests (UUID, QuestId, QuestStage ) values (?, ?, ?)" );
207205 prepared .setQueryTimeout (30 );
208206 status .forEach (s -> {
209207 try {
210208 prepared .setString (1 , uuid .toString ());
211209 prepared .setString (2 , s .getQuestId ());
212- prepared .setBoolean (3 , s .isCompleted ());
210+ prepared .setString (3 , s .getQuestStage ());
213211 prepared .addBatch ();
214212 }
215213 catch (SQLException e ){
@@ -222,6 +220,9 @@ public void savePlayerQuestStatus(UUID uuid) {
222220 prepared .close ();
223221 } catch (SQLException e ) {
224222 e .printStackTrace ();
223+ } finally {
224+ if (removeFromCache )
225+ PlayerQuestStatuses .remove (uuid );
225226 }
226227 });
227228 }
0 commit comments