33import java .io .File ;
44import java .io .FileFilter ;
55import java .io .IOException ;
6+ import java .nio .charset .StandardCharsets ;
7+ import java .util .ArrayList ;
8+ import java .util .HashMap ;
9+ import java .util .List ;
10+ import java .util .Map ;
11+ import java .util .logging .Logger ;
612
713import org .apache .commons .io .FileUtils ;
814
1622import de .scribble .lp .tasmod .savestates .server .motion .ClientMotionServer ;
1723import de .scribble .lp .tasmod .savestates .server .playerloading .SavestatePlayerLoading ;
1824import de .scribble .lp .tasmod .tickratechanger .TickrateChangerServer ;
25+ import de .scribble .lp .tasmod .util .FileThread ;
1926import net .minecraft .client .Minecraft ;
2027import net .minecraft .entity .player .EntityPlayerMP ;
2128import net .minecraft .nbt .NBTTagCompound ;
2229import net .minecraft .server .MinecraftServer ;
30+ import net .minecraft .server .management .PlayerList ;
2331import net .minecraft .util .text .TextComponentString ;
2432import net .minecraft .util .text .TextFormatting ;
2533import net .minecraft .world .WorldServer ;
3745 *
3846 */
3947public class SavestateHandler {
40- private static MinecraftServer server = TASmod . getServerInstance () ;
41- private static File savestateDirectory ;
48+ private MinecraftServer server ;
49+ private File savestateDirectory ;
4250
4351 public static SavestateState state =SavestateState .NONE ;
4452
53+ public SavestateHandler (MinecraftServer server ) {
54+ this .server =server ;
55+ createSavestateDirectory ();
56+ refreshSavestateMap ();
57+ loadCurrentIndex ();
58+ }
59+
4560 /**
4661 * Creates a copy of the currently played world and saves it in .minecraft/saves/savestates/worldname <br>
4762 * Called in {@link SavestatePacketHandler}<br>
@@ -51,7 +66,7 @@ public class SavestateHandler {
5166 * @throws SavestateException
5267 * @throws IOException
5368 */
54- public static void saveState (int savestateIndex ) throws SavestateException , IOException {
69+ public void saveState (int savestateIndex ) throws SavestateException , IOException {
5570 if (state ==SavestateState .SAVING ) {
5671 throw new SavestateException ("A savestating operation is already being carried out" );
5772 }
@@ -64,6 +79,9 @@ public static void saveState(int savestateIndex) throws SavestateException, IOEx
6479 //Create a directory just in case
6580 createSavestateDirectory ();
6681
82+ increaseCurrentIndex ();
83+ saveCurrentIndex ();
84+
6785 //Enable tickrate 0
6886 TickrateChangerServer .changeServerTickrate (0 );
6987 TickrateChangerServer .changeClientTickrate (0 );
@@ -109,20 +127,6 @@ public static void saveState(int savestateIndex) throws SavestateException, IOEx
109127 state =SavestateState .NONE ;
110128 }
111129
112- private static String nextSaveName (String worldname , int index ) {
113- File [] listofFiles =savestateDirectory .listFiles (new FileFilter () {
114-
115- @ Override
116- public boolean accept (File pathname ) {
117- return pathname .getName ().startsWith (worldname );
118- }
119-
120- });
121- if (index <0 ) {
122- }
123- return "" ;
124- }
125-
126130 /**
127131 * Searches through the savestate folder to look for the next possible savestate foldername <br>
128132 * Savestate equivalent to {@link SavestateHandler#getLatestSavestateLocation(String)}
@@ -131,7 +135,7 @@ public boolean accept(File pathname) {
131135 * @throws SavestateException if the found savestates count is greater or equal than 300
132136 */
133137 @ Deprecated
134- private static File getNextSaveFolderLocation (String worldname ) throws SavestateException {
138+ private File getNextSaveFolderLocation (String worldname ) throws SavestateException {
135139 int i = 1 ;
136140 int limit =300 ;
137141 File targetsavefolder =null ;
@@ -156,7 +160,7 @@ private static File getNextSaveFolderLocation(String worldname) throws Savestate
156160 * @return The correct name of the next savestate
157161 */
158162 @ Deprecated
159- private static String nameWhenSaving (String worldname ) {
163+ private String nameWhenSaving (String worldname ) {
160164 int i = 1 ;
161165 int limit =300 ;
162166 File targetsavefolder =null ;
@@ -183,7 +187,7 @@ private static String nameWhenSaving(String worldname) {
183187 * @throws LoadstateException
184188 * @throws IOException
185189 */
186- public static void loadState () throws LoadstateException , IOException {
190+ public void loadState () throws LoadstateException , IOException {
187191 if (state ==SavestateState .SAVING ) {
188192 throw new LoadstateException ("A savestating operation is already being carried out" );
189193 }
@@ -269,7 +273,7 @@ public static void loadState() throws LoadstateException, IOException {
269273 * @return targetsavefolder
270274 * @throws LoadstateException if there is no savestate or more than 300 savestates
271275 */
272- private static File getLatestSavestateLocation (String worldname ) throws LoadstateException {
276+ private File getLatestSavestateLocation (String worldname ) throws LoadstateException {
273277 int i =1 ;
274278 int limit =300 ;
275279
@@ -297,13 +301,13 @@ private static File getLatestSavestateLocation(String worldname) throws Loadstat
297301 * @param worldname the name of the world currently on the server
298302 * @return The correct name of the next loadstate
299303 */
300- private static String nameWhenLoading (String worldname ) throws LoadstateException {
304+ private String nameWhenLoading (String worldname ) throws LoadstateException {
301305 int i =1 ;
302306 int limit =300 ;
303307 String name ="" ;
304308 File targetsavefolder =null ;
305309 while (i <=300 ) {
306- targetsavefolder = new File (savestateDirectory ,worldname +"-Savestate" +Integer .toString (i ));
310+ targetsavefolder = new File (savestateDirectory , worldname +"-Savestate" +Integer .toString (i ));
307311 if (!targetsavefolder .exists ()) {
308312 if (i -1 ==0 ) {
309313 throw new LoadstateException ("Couldn't find any savestates" );
@@ -323,7 +327,7 @@ private static String nameWhenLoading(String worldname) throws LoadstateExceptio
323327 /**
324328 * Creates the savestate directory in case the user deletes it between savestates
325329 */
326- private static void createSavestateDirectory () {
330+ private void createSavestateDirectory () {
327331 if (!server .isDedicatedServer ()) {
328332 savestateDirectory =new File (server .getDataDirectory ()+File .separator +"saves" +File .separator +"savestates" +File .separator );
329333 }else {
@@ -334,17 +338,106 @@ private static void createSavestateDirectory() {
334338 }
335339 }
336340
341+ private Map <Integer , File > savestateMap =new HashMap <Integer , File >();
342+
343+ private int nextFreeIndex =0 ;
344+
345+ private int currentIndex ;
346+
347+ public void refreshSavestateMap () {
348+ savestateMap .clear ();
349+ File [] files =savestateDirectory .listFiles (new FileFilter () {
350+
351+ @ Override
352+ public boolean accept (File pathname ) {
353+ return pathname .getName ().startsWith (server .getFolderName ()+"-Savestate" );
354+ }
355+ });
356+ int index =0 ;
357+ for (File file :files ) {
358+ try {
359+ index =Integer .parseInt (file .getName ().substring (file .getName ().length ()-1 ));
360+ } catch (NumberFormatException e ) {
361+ TASmod .logger .warn (String .format ("Could not process the savestate %s" , e .getMessage ()));
362+ }
363+ savestateMap .put (index , file );
364+ }
365+ nextFreeIndex =index +1 ;
366+ }
367+
368+ public void saveCurrentIndex () {
369+ File tasmodDir =new File (savestateDirectory , "../" +server .getFolderName ()+"/tasmod/" );
370+ if (!tasmodDir .exists ()) {
371+ tasmodDir .mkdir ();
372+ }
373+ File savestateDat =new File (tasmodDir , "savestate.data" );
374+ List <String > lines =new ArrayList <String >();
375+ lines .add ("currentIndex=" +currentIndex );
376+ try {
377+ FileUtils .writeLines (savestateDat , lines );
378+ } catch (IOException e ) {
379+ e .printStackTrace ();
380+ }
381+ }
382+
383+ public void loadCurrentIndex () {
384+ int index = -1 ;
385+ List <String > lines = new ArrayList <String >();
386+ File tasmodDir = new File (savestateDirectory , "../" + server .getFolderName () + "/tasmod/" );
387+ if (!tasmodDir .exists ()) {
388+ tasmodDir .mkdir ();
389+ }
390+ File savestateDat = new File (tasmodDir , "savestate.data" );
391+ try {
392+ lines = FileUtils .readLines (savestateDat , StandardCharsets .UTF_8 );
393+ } catch (IOException e ) {
394+ TASmod .logger .warn ("No savestate.data file found in current world folder, ignoring it" );
395+ }
396+ if (!lines .isEmpty ()) {
397+ for (String line : lines ) {
398+ if (line .startsWith ("currentIndex=" )) {
399+ try {
400+ index = Integer .parseInt (line .split ("=" )[1 ]);
401+ } catch (NumberFormatException e ) {
402+ e .printStackTrace ();
403+ }
404+ }
405+ }
406+ }
407+ setCurrentIndex (index );;
408+ }
409+
410+ private void setCurrentIndex (int index ) {
411+ if (index <0 ) {
412+ currentIndex =nextFreeIndex -1 ;
413+ }else {
414+ currentIndex =index ;
415+ }
416+ TASmod .logger .info ("Setting the savestate index to {}" , currentIndex );
417+ }
418+
419+ public void increaseCurrentIndex () {
420+ setCurrentIndex (currentIndex +1 );
421+ }
422+
423+ private String getSavestateNameWithIndex (int index ) {
424+ return server .getFolderName ()+File .separator +"Savestate" +index ;
425+ }
426+
337427 /**
338428 * Event, that gets executed after a loadstate operation was carried out, get's called on the server side
339429 */
340430 public static void playerLoadSavestateEventServer () {
341- EntityPlayerMP player =server .getPlayerList ().getPlayers ().get (0 );
342- NBTTagCompound nbttagcompound = server .getPlayerList ().getPlayerNBT (player );
431+ PlayerList playerList =TASmod .getServerInstance ().getPlayerList ();
432+ EntityPlayerMP player =playerList .getPlayers ().get (0 );
433+ NBTTagCompound nbttagcompound = playerList .getPlayerNBT (player );
434+ //TODO Make this multiplayer compatible ffs
343435 SavestatePlayerLoading .reattachEntityToPlayer (nbttagcompound , player .getServerWorld (), player );
344436 }
345437
346438 @ SideOnly (Side .CLIENT )
347439 public static void playerLoadSavestateEventClient () {
348440 SavestatesChunkControl .addPlayerToChunk (Minecraft .getMinecraft ().player );
349441 }
442+
350443}
0 commit comments