Skip to content

Commit 04e87b8

Browse files
ScribbleScribble
authored andcommitted
Make SavestateHandler not static anymore
-Added a way to map savestate folders to an index, although that is not fully implemented -Added a current index that stores the number of which savestate to load/create next -Added serialization for that currentIndex in .minecraft/saves/<worldfolder>/tasmod/savestate.data (Maybe with more information to store in the future?) -Fixed a crash when opening the SavestateSavingScreen
1 parent b0a4782 commit 04e87b8

File tree

5 files changed

+134
-29
lines changed

5 files changed

+134
-29
lines changed

src/main/java/de/scribble/lp/tasmod/TASmod.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import de.scribble.lp.tasmod.commands.recording.CommandRecord;
1616
import de.scribble.lp.tasmod.commands.savetas.CommandSaveTAS;
1717
import de.scribble.lp.tasmod.commands.tutorial.CommandPlaybacktutorial;
18+
import de.scribble.lp.tasmod.savestates.server.SavestateHandler;
1819
import de.scribble.lp.tasmod.savestates.server.SavestateTrackerFile;
1920
import de.scribble.lp.tasmod.tickratechanger.CommandTickrate;
2021
import de.scribble.lp.tasmod.util.ModIncompatibleException;
@@ -53,6 +54,8 @@ public class TASmod {
5354
public static final Logger logger = LogManager.getLogger("TASMod");
5455

5556
public static ContainerStateServer containerStateServer;
57+
58+
public static SavestateHandler savestateHandler;
5659

5760
@EventHandler
5861
public void preInit(FMLPreInitializationEvent ev) throws Exception {
@@ -107,6 +110,8 @@ public void serverStart(FMLServerStartingEvent ev) {
107110
} catch (IOException e) {
108111
e.printStackTrace();
109112
}
113+
114+
savestateHandler=new SavestateHandler(ev.getServer());
110115
}
111116

112117
public static TASmod getInstance() {

src/main/java/de/scribble/lp/tasmod/savestates/server/GuiSavestateSavingScreen.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,12 @@
77

88
public class GuiSavestateSavingScreen extends GuiScreen{
99

10-
10+
@Override
11+
public void initGui() {
12+
this.mc=Minecraft.getMinecraft();
13+
super.initGui();
14+
}
15+
1116
@Override
1217
public void drawScreen(int mouseX, int mouseY, float partialTicks) {
1318
this.drawDefaultBackground();

src/main/java/de/scribble/lp/tasmod/savestates/server/LoadstatePacketHandler.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package de.scribble.lp.tasmod.savestates.server;
22

3+
import de.scribble.lp.tasmod.TASmod;
34
import de.scribble.lp.tasmod.savestates.server.chunkloading.SavestatesChunkControl;
45
import de.scribble.lp.tasmod.savestates.server.exceptions.LoadstateException;
56
import net.minecraft.client.Minecraft;
@@ -22,7 +23,7 @@ public IMessage onMessage(LoadstatePacket message, MessageContext ctx) {
2223
return;
2324
}
2425
try {
25-
SavestateHandler.loadState();
26+
TASmod.savestateHandler.loadState();
2627
} catch (LoadstateException e) {
2728
player.sendMessage(new TextComponentString(TextFormatting.RED+"Failed to load a savestate: "+e.getMessage()));
2829

src/main/java/de/scribble/lp/tasmod/savestates/server/SavestateHandler.java

Lines changed: 119 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@
33
import java.io.File;
44
import java.io.FileFilter;
55
import 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

713
import org.apache.commons.io.FileUtils;
814

@@ -16,10 +22,12 @@
1622
import de.scribble.lp.tasmod.savestates.server.motion.ClientMotionServer;
1723
import de.scribble.lp.tasmod.savestates.server.playerloading.SavestatePlayerLoading;
1824
import de.scribble.lp.tasmod.tickratechanger.TickrateChangerServer;
25+
import de.scribble.lp.tasmod.util.FileThread;
1926
import net.minecraft.client.Minecraft;
2027
import net.minecraft.entity.player.EntityPlayerMP;
2128
import net.minecraft.nbt.NBTTagCompound;
2229
import net.minecraft.server.MinecraftServer;
30+
import net.minecraft.server.management.PlayerList;
2331
import net.minecraft.util.text.TextComponentString;
2432
import net.minecraft.util.text.TextFormatting;
2533
import net.minecraft.world.WorldServer;
@@ -37,11 +45,18 @@
3745
*
3846
*/
3947
public 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
}

src/main/java/de/scribble/lp/tasmod/savestates/server/SavestatePacketHandler.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package de.scribble.lp.tasmod.savestates.server;
22

3+
import de.scribble.lp.tasmod.TASmod;
34
import de.scribble.lp.tasmod.savestates.server.exceptions.SavestateException;
45
import net.minecraft.entity.player.EntityPlayerMP;
56
import net.minecraft.util.text.TextComponentString;
@@ -30,7 +31,7 @@ public IMessage onMessage(SavestatePacket message, MessageContext ctx) {
3031
return;
3132
}
3233
try {
33-
SavestateHandler.saveState(-1);
34+
TASmod.savestateHandler.saveState(-1);
3435
} catch (SavestateException e) {
3536
player.sendMessage(new TextComponentString(TextFormatting.RED+"Failed to create a savestate: "+ e.getMessage()));
3637

0 commit comments

Comments
 (0)