1414
1515import de .scribble .lp .tasmod .CommonProxy ;
1616import de .scribble .lp .tasmod .TASmod ;
17- import de .scribble .lp .tasmod .savestates .client .InputSavestatesHandler ;
1817import de .scribble .lp .tasmod .savestates .client .InputSavestatesPacket ;
1918import de .scribble .lp .tasmod .savestates .server .chunkloading .SavestatesChunkControl ;
2019import de .scribble .lp .tasmod .savestates .server .exceptions .LoadstateException ;
4847 *
4948 */
5049public class SavestateHandler {
50+
5151 private MinecraftServer server ;
5252 private File savestateDirectory ;
5353
5454 public SavestateState state = SavestateState .NONE ;
5555
56+ private final List <Integer > indexList = new ArrayList <>();
57+
58+ private int latestIndex = 0 ;
59+ private int currentIndex ;
60+
61+ /**
62+ * Creates a savestate handler on the specified server
63+ *
64+ * @param The server that should store the savestates
65+ */
5666 public SavestateHandler (MinecraftServer server ) {
5767 this .server = server ;
5868 createSavestateDirectory ();
@@ -61,15 +71,28 @@ public SavestateHandler(MinecraftServer server) {
6171 }
6272
6373 /**
64- * Creates a copy of the currently played world and saves it in
65- * .minecraft/saves/savestates/worldname <br>
66- * Called in {@link SavestatePacketHandler}<br>
74+ * Creates a copy of the world that is currently being played and saves it in
75+ * .minecraft/saves/savestates/worldname-Savestate[{@linkplain #currentIndex}+1]
76+ * <br>
77+ * <br>
78+ * Side: Server
79+ *
80+ * @throws SavestateException
81+ * @throws IOException
82+ */
83+ public void saveState () throws SavestateException , IOException {
84+ saveState (-1 );
85+ }
86+
87+ /**
88+ * Creates a copy of the world that is currently being played and saves it in
89+ * .minecraft/saves/savestates/worldname-Savestate[savestateIndex] <br>
6790 * <br>
6891 * Side: Server
6992 *
7093 * @param savestateIndex The index where the mod will save the savestate.
71- * index<=0 if it should load the next from the
72- * currentindex
94+ * index<=0 if it should save it in the next index from
95+ * the currentindex
7396 * @throws SavestateException
7497 * @throws IOException
7598 */
@@ -100,16 +123,20 @@ public void saveState(int savestateIndex) throws SavestateException, IOException
100123 server .getPlayerList ().saveAllPlayerData ();
101124 server .saveAllWorlds (true );
102125
126+ // Refreshing the index list
127+ refresh ();
128+
129+ // Setting the current index depending on the savestateIndex.
103130 if (savestateIndex <= 0 ) {
104- setCurrentIndex (currentIndex + 1 );
131+ setCurrentIndex (currentIndex + 1 ); // If the savestateIndex <= 0, create a savestate at currentIndex+1
105132 } else {
106133 setCurrentIndex (savestateIndex );
107134 }
108135
109136 // Get the current and target directory for copying
110137 String worldname = server .getFolderName ();
111138 File currentfolder = new File (savestateDirectory , ".." + File .separator + worldname );
112- File targetfolder = get (currentIndex );
139+ File targetfolder = getSavestateFile (currentIndex );
113140
114141 if (targetfolder .exists ()) {
115142 TASmod .logger .warn ("WARNING! Overwriting the savestate with the index {}" , currentIndex );
@@ -118,7 +145,7 @@ public void saveState(int savestateIndex) throws SavestateException, IOException
118145
119146 // Send the name of the world to all players. This will make a savestate of the
120147 // recording on the client with that name
121- CommonProxy .NETWORK .sendToAll (new InputSavestatesPacket (true , getSavestateNameWithIndex (currentIndex )));
148+ CommonProxy .NETWORK .sendToAll (new InputSavestatesPacket (true , getSavestateName (currentIndex )));
122149
123150 // Wait for the chunkloader to save the game
124151 for (WorldServer world : server .worlds ) {
@@ -147,6 +174,19 @@ public void saveState(int savestateIndex) throws SavestateException, IOException
147174 state = SavestateState .NONE ;
148175 }
149176
177+ /**
178+ * Loads the latest savestate at {@linkplain #currentIndex}
179+ * .minecraft/saves/savestates/worldname-Savestate[{@linkplain #currentIndex}]
180+ *
181+ * Side: Server
182+ *
183+ * @throws LoadstateException
184+ * @throws IOException
185+ */
186+ public void loadState () throws LoadstateException , IOException {
187+ loadState (-1 );
188+ }
189+
150190 /**
151191 * Loads the latest savestate it can find in
152192 * .minecraft/saves/savestates/worldname-Savestate
@@ -176,19 +216,23 @@ public void loadState(int savestateIndex) throws LoadstateException, IOException
176216 // Update the server instance
177217 server = TASmod .getServerInstance ();
178218
179- if (!get (savestateIndex ).exists ()) {
180- throw new LoadstateException ("The savestate to load doesn't exist" );
219+ refresh ();
220+
221+ int indexToLoad = savestateIndex < 0 ? currentIndex : savestateIndex ;
222+
223+ if (!getSavestateFile (indexToLoad ).exists ()) {
224+ throw new LoadstateException ("Savestate " + indexToLoad + " doesn't exist" );
181225 } else {
182- setCurrentIndex (savestateIndex );
226+ setCurrentIndex (indexToLoad );
183227 }
184228
185229 // Get the current and target directory for copying
186230 String worldname = server .getFolderName ();
187231 File currentfolder = new File (savestateDirectory , ".." + File .separator + worldname );
188- File targetfolder = get (currentIndex );
232+ File targetfolder = getSavestateFile (currentIndex );
189233
190234 // Load savestate on the client
191- CommonProxy .NETWORK .sendToAll (new InputSavestatesPacket (false , getSavestateNameWithIndex (currentIndex )));
235+ CommonProxy .NETWORK .sendToAll (new InputSavestatesPacket (false , getSavestateName (currentIndex )));
192236
193237 // Disabeling level saving for all worlds in case the auto save kicks in during
194238 // world unload
@@ -255,12 +299,6 @@ private void createSavestateDirectory() {
255299 }
256300 }
257301
258- private final List <Integer > indexList = new ArrayList <>();
259-
260- private int latestIndex = 0 ;
261-
262- private int currentIndex ;
263-
264302 private void refresh () {
265303 indexList .clear ();
266304 File [] files = savestateDirectory .listFiles (new FileFilter () {
@@ -289,27 +327,52 @@ public boolean accept(File pathname) {
289327 indexList .add (index );
290328 }
291329 Collections .sort (indexList );
292- if (indexList .isEmpty ()) {
293- indexList .add (0 );
330+ if (!indexList .isEmpty ()) {
331+ latestIndex = indexList .get (indexList .size () - 1 );
332+ } else {
333+ latestIndex = 0 ;
294334 }
295- latestIndex = indexList .get (indexList .size () - 1 );
296- System .out .println ("LatestIndex: " + latestIndex );
297335 }
298336
299- public void deleteIndex (int index ) throws SavestateDeleteException {
337+ /**
338+ * @param index The index of the savestate file that we want to get
339+ * @return The file of the savestate from the specified index
340+ */
341+ private File getSavestateFile (int index ) {
342+ return new File (savestateDirectory , getSavestateName (index ));
343+ }
344+
345+ /**
346+ * @param index The index of the savestate file that we want to get
347+ * @return The savestate name without any paths
348+ */
349+ private String getSavestateName (int index ) {
350+ return server .getFolderName () + "-Savestate" + index ;
351+ }
352+
353+ /**
354+ * Deletes the specified savestate
355+ *
356+ * @param index The index of the savestate that should be deleted
357+ * @throws SavestateDeleteException
358+ */
359+ public void deleteSavestate (int index ) throws SavestateDeleteException {
360+ if (state != SavestateState .NONE ) {
361+ throw new SavestateDeleteException ("A savestate operation is currently being carried out" );
362+ }
300363 if (index <= 0 ) {
301- throw new SavestateDeleteException ("Cannot delete the indexes below or exactly 0: " + index );
364+ throw new SavestateDeleteException ("Cannot delete the indexes below or exactly zero" );
302365 }
303- File toDelete = get (index );
366+ File toDelete = getSavestateFile (index );
304367 if (toDelete .exists ()) {
305368 try {
306369 FileUtils .deleteDirectory (toDelete );
307370 } catch (IOException e ) {
308371 e .printStackTrace ();
372+ throw new SavestateDeleteException ("Something went wrong while trying to delete the savestate " + index );
309373 }
310374 } else {
311- server .getPlayerList ().sendMessage (new TextComponentString (TextFormatting .YELLOW + "Savestate " + index + " doesn't exist so it can't be deleted" ));
312- return ;
375+ throw new SavestateDeleteException (TextFormatting .YELLOW + "Savestate " + index + " doesn't exist, so it can't be deleted" );
313376 }
314377 refresh ();
315378 if (!indexList .contains (currentIndex )) {
@@ -319,6 +382,30 @@ public void deleteIndex(int index) throws SavestateDeleteException {
319382 server .getPlayerList ().sendMessage (new TextComponentString (TextFormatting .GREEN + "Savestate " + index + " deleted" ));
320383 }
321384
385+ /**
386+ * Deletes savestates in a range from "from" to "to"
387+ *
388+ * @param from
389+ * @param to (exclusive)
390+ * @throws SavestateDeleteException
391+ */
392+ public void deleteSavestate (int from , int to ) throws SavestateDeleteException {
393+ if (state != SavestateState .NONE ) {
394+ throw new SavestateDeleteException ("A savestate operation is currently being carried out" );
395+ }
396+ if (from >= to ) {
397+ throw new SavestateDeleteException ("The 'from-index' is smaller or equal to the 'to-index'" );
398+ }
399+ for (int i = from ; i < to ; i ++) {
400+ try {
401+ deleteSavestate (i );
402+ } catch (SavestateDeleteException e ) {
403+ server .getPlayerList ().sendMessage (new TextComponentString (TextFormatting .RED + e .getMessage ()));
404+ continue ;
405+ }
406+ }
407+ }
408+
322409 public String getIndexesAsString () {
323410 refresh ();
324411 String out = "" ;
@@ -328,10 +415,10 @@ public String getIndexesAsString() {
328415 return out ;
329416 }
330417
331- private File get ( int index ) {
332- return new File ( savestateDirectory , getSavestateNameWithIndex ( index ));
333- }
334-
418+ /**
419+ * Saves the current index to the current world-folder (not the savestate
420+ * folder)
421+ */
335422 private void saveCurrentIndexToFile () {
336423 File tasmodDir = new File (savestateDirectory , "../" + server .getFolderName () + "/tasmod/" );
337424 if (!tasmodDir .exists ()) {
@@ -347,6 +434,10 @@ private void saveCurrentIndexToFile() {
347434 }
348435 }
349436
437+ /**
438+ * Loads the current index to the current world-folder (not the savestate
439+ * folder)
440+ */
350441 public void loadCurrentIndexFromFile () {
351442 int index = -1 ;
352443 List <String > lines = new ArrayList <String >();
@@ -376,17 +467,13 @@ public void loadCurrentIndexFromFile() {
376467
377468 private void setCurrentIndex (int index ) {
378469 if (index < 0 ) {
379- currentIndex = latestIndex - 1 ;
470+ currentIndex = latestIndex ;
380471 } else {
381472 currentIndex = index ;
382473 }
383474 TASmod .logger .info ("Setting the savestate index to {}" , currentIndex );
384475 }
385476
386- private String getSavestateNameWithIndex (int index ) {
387- return server .getFolderName () + "-Savestate" + index ;
388- }
389-
390477 public int getCurrentIndex () {
391478 return currentIndex ;
392479 }
@@ -407,21 +494,4 @@ public static void playerLoadSavestateEventServer() {
407494 public static void playerLoadSavestateEventClient () {
408495 SavestatesChunkControl .addPlayerToChunk (Minecraft .getMinecraft ().player );
409496 }
410-
411- public void loadState () throws LoadstateException , IOException {
412- loadState (-1 );
413- }
414-
415- public void saveState () throws SavestateException , IOException {
416- saveState (-1 );
417- }
418-
419- public void deleteIndex (int from , int to ) throws SavestateDeleteException {
420- if (from >= to ) {
421- throw new SavestateDeleteException ("The 'from-index' is smaller or equal to the 'to-index'" );
422- }
423- for (int i = from ; i < to ; i ++) {
424- deleteIndex (i );
425- }
426- }
427497}
0 commit comments