Skip to content

Commit 3ccf8d4

Browse files
committed
One scene for each player, add LoopSceneManager
Replaced direct player and scene management with a new `LoopSceneManager` class to centralize logic and improve maintainability. Updated related methods and removed redundant code for managing recordings and scenes. Enhanced clarity and flexibility in handling player-specific scenes.
1 parent 9802833 commit 3ccf8d4

3 files changed

Lines changed: 108 additions & 53 deletions

File tree

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package com.vltno.timeloop;
2+
3+
import java.util.ArrayList;
4+
import java.util.List;
5+
import java.util.function.Consumer;
6+
7+
public class LoopSceneManager {
8+
private TimeLoopConfig config;
9+
private String sceneName;
10+
private List<String> recordingPlayers;
11+
12+
// Constructor to initialize recordingPlayers
13+
public LoopSceneManager(TimeLoopConfig _config) {
14+
this.config = _config;
15+
this.sceneName = config.sceneName;
16+
this.recordingPlayers = new ArrayList<>();
17+
}
18+
19+
// Method to add a player to the recordingPlayers list
20+
public void addPlayer(String playerName) {
21+
if (playerName != null && !playerName.isEmpty()) {
22+
recordingPlayers.add(playerName.toLowerCase());
23+
} else {
24+
System.out.println("Invalid player name. Player not added.");
25+
}
26+
}
27+
28+
// Method to remove a specific player from the recordingPlayers list
29+
public void removePlayer(String playerName) {
30+
if (playerName != null && !playerName.isEmpty()) {
31+
boolean removed = recordingPlayers.remove(playerName);
32+
if (removed) {
33+
System.out.println("Player '" + playerName + "' removed successfully.");
34+
} else {
35+
System.out.println("Player '" + playerName + "' not found in the list.");
36+
}
37+
} else {
38+
System.out.println("Invalid player name. Player not removed.");
39+
}
40+
}
41+
42+
// Method to generate playerSceneName for a given player
43+
public String getPlayerSceneName(String playerName) {
44+
return (sceneName + "_" + playerName).toLowerCase();
45+
}
46+
47+
// Method to get all playerSceneNames for recordingPlayers
48+
public List<String> getAllPlayerSceneNames() {
49+
List<String> playerSceneNames = new ArrayList<>();
50+
for (String player : recordingPlayers) {
51+
playerSceneNames.add(getPlayerSceneName(player));
52+
}
53+
return playerSceneNames;
54+
}
55+
56+
public void forEachPlayerSceneName(Consumer<String> action) {
57+
getAllPlayerSceneNames().forEach(action);
58+
}
59+
60+
public void forEachRecordingPlayer(Consumer<String> action) {
61+
recordingPlayers.forEach(action);
62+
}
63+
}

src/main/java/com/vltno/timeloop/TimeLoop.java

Lines changed: 43 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ public class TimeLoop implements ModInitializer {
4646
public String sceneName;
4747
private int tickCounter = 0; // Tracks elapsed ticks
4848
public int ticksLeft;
49-
private List<String> recordingPlayers; // Add this field
5049

5150
public boolean showLoopInfo;
5251
public boolean displayTimeInTicks;
@@ -55,6 +54,9 @@ public class TimeLoop implements ModInitializer {
5554

5655
// The configuration object loaded from disk
5756
public TimeLoopConfig config;
57+
58+
// The loop scene manager object
59+
private LoopSceneManager loopSceneManager;
5860

5961
// Get the world folder path for config/recording loading
6062
private Path worldFolder;
@@ -63,7 +65,7 @@ public class TimeLoop implements ModInitializer {
6365
@Override
6466
public void onInitialize() {
6567
LOOP_LOGGER.info("Initializing TimeLoop mod");
66-
recordingPlayers = new ArrayList<>(); // Initialize the list
68+
loopSceneManager = new LoopSceneManager(config);
6769

6870
// Register the custom ArgumentType
6971
ArgumentTypeRegistry.registerArgumentType(Identifier.of("timeloop",""), LoopTypesArgumentType.class, ConstantArgumentSerializer.of(LoopTypesArgumentType::new));
@@ -119,15 +121,6 @@ public void onInitialize() {
119121
executeCommand("mocap settings recording entity_tracking_distance 1");
120122

121123
updateEntitiesToTrack(trackItems);
122-
123-
executeCommand(String.format("mocap scenes add %s", sceneName));
124-
if (config.isLooping) {
125-
LOOP_LOGGER.info("Loop was active in config, automatically restarting loop.");
126-
// Reset the in-memory flag so that startLoop() does not return early.
127-
isLooping = false;
128-
executeCommand(String.format("mocap playback start .%s", sceneName));
129-
startLoop();
130-
}
131124
});
132125

133126
ServerLifecycleEvents.SERVER_STOPPING.register(server -> {
@@ -141,11 +134,14 @@ public void onInitialize() {
141134
ServerPlayerEntity player = handler.getPlayer();
142135
String playerName = player.getName().getString();
143136

137+
loopSceneManager.addPlayer(playerName);
138+
loopBossBar.addPlayer(player);
139+
140+
executeCommand(String.format("mocap scenes add %s", loopSceneManager.getPlayerSceneName(playerName)));
141+
144142
if (config.firstStart) {
145143
config.firstStart = false;
146144
config.save();
147-
148-
executeCommand(String.format("mocap scenes add %s", sceneName)); // Stupid patch because for some reason the first time fails, but when i add this, IT DOESNT FAIL. idk. if its fixed, remove this.
149145

150146
LOOP_LOGGER.info("First start detected, sending message to ops.");
151147

@@ -154,8 +150,6 @@ public void onInitialize() {
154150
}
155151
}
156152

157-
recordingPlayers.add(playerName); // Add to recording list
158-
loopBossBar.addPlayer(player);
159153
if (isLooping) {
160154
LOOP_LOGGER.info("Starting recording for newly joined player: {}", playerName);
161155
executeCommand(String.format("mocap recording start %s", playerName));
@@ -165,16 +159,11 @@ public void onInitialize() {
165159
ServerPlayConnectionEvents.DISCONNECT.register((handler, server) -> {
166160
ServerPlayerEntity player = handler.getPlayer();
167161
String playerName = player.getName().getString();
168-
recordingPlayers.remove(playerName); // Remove from recording list
162+
163+
loopSceneManager.removePlayer(playerName);
169164
loopBossBar.removePlayer(player);
170165
if (isLooping) {
171-
LOOP_LOGGER.info("Saving recording for Disconnected player: {}", playerName);
172-
String recordingName = playerName + "_" + System.currentTimeMillis();
173-
executeCommand(String.format("mocap recording stop -+mc.%s.1", playerName));
174-
executeCommand(String.format("mocap recording save %s -+mc.%s.1", recordingName.toLowerCase(), playerName));
175-
if (recordingFileExists(recordingName)) {
176-
executeCommand(String.format("mocap scenes add_to %s %s", sceneName, recordingName.toLowerCase()));
177-
}
166+
saveRecordings();
178167
}
179168
});
180169

@@ -193,11 +182,6 @@ public void onInitialize() {
193182
config.startTimeOfDay = 0;}
194183

195184
long time = (serverWorld.getTimeOfDay() > 24000 ? serverWorld.getTimeOfDay() % 24000 : serverWorld.getTimeOfDay());
196-
//
197-
// long timeLeft = (timeFixed > timeSetting) ? Math.abs(timeFixed - (2 * timeSetting)) : Math.abs(timeFixed - timeSetting);
198-
// LOOP_LOGGER.info("Time Fixed: " + timeFixed);
199-
// LOOP_LOGGER.info("Time Setting: " + timeSetting);
200-
// LOOP_LOGGER.info("Time Left: " + timeLeft);
201185

202186
long timeLeft = (time > timeSetting) ? Math.abs(serverWorld.getTimeOfDay() - (2 * timeSetting)) : Math.abs(time - timeSetting);
203187

@@ -251,7 +235,11 @@ private void runLoopIteration() {
251235
startRecordings();
252236
if (trackTimeOfDay) { serverWorld.setTimeOfDay(startTimeOfDay); }
253237
executeCommand("mocap playback stop_all including_others");
254-
executeCommand(String.format("mocap playback start .%s", sceneName));
238+
239+
loopSceneManager.forEachPlayerSceneName(playerSceneName -> {
240+
executeCommand(String.format("mocap playback start .%s", loopSceneManager.getPlayerSceneName(playerSceneName)));
241+
});
242+
255243
loopIteration++;
256244
config.loopIteration = loopIteration;
257245
config.save();
@@ -263,26 +251,28 @@ private void runLoopIteration() {
263251
*/
264252
private void startRecordings() {
265253
// Start recording for every player
266-
for (String playerName : recordingPlayers) {
254+
loopSceneManager.forEachRecordingPlayer(playerName -> {
267255
executeCommand(String.format("mocap recording start %s", playerName));
268-
}
256+
});
269257
}
270258

271259
/**
272260
* Saves the recordings.
273261
*/
274262
public void saveRecordings() {
275263
// Stop and save recordings for each player
276-
for (String playerName : recordingPlayers) {
264+
loopSceneManager.forEachRecordingPlayer(playerName -> {
277265
String recordingName = playerName + "_" + System.currentTimeMillis();
278266

267+
String playerSceneName = loopSceneManager.getPlayerSceneName(playerName);
268+
279269
LOOP_LOGGER.info("Processing recording for player: {}", playerName);
280270
executeCommand(String.format("mocap recording stop -+mc.%s.1", playerName));
281271
executeCommand(String.format("mocap recording save %s -+mc.%s.1", recordingName.toLowerCase(), playerName));
282272
if (recordingFileExists(recordingName)) {
283-
executeCommand(String.format("mocap scenes add_to %s %s", sceneName, recordingName.toLowerCase()));
273+
executeCommand(String.format("mocap scenes add_to %s %s", playerSceneName, recordingName.toLowerCase()));
284274
}
285-
}
275+
});
286276
}
287277

288278
/**
@@ -353,39 +343,40 @@ private boolean recordingFileExists(String recordingName) {
353343
*
354344
*/
355345
private void removeOldSceneEntries() {
356-
if (isLooping) {
357-
if (maxLoops > 1) {
358-
Path sceneDir = worldFolder.resolve("mocap_files").resolve("scenes");
359-
Path sceneFile = sceneDir.resolve(sceneName+".mcmocap_scene");
346+
if (isLooping && maxLoops > 1) {
347+
Path sceneDir = worldFolder.resolve("mocap_files").resolve("scenes");
360348

361-
// Check if the scene file exists
349+
List<Path> sceneFiles = new ArrayList<>();
350+
loopSceneManager.forEachRecordingPlayer(playerSceneName -> {
351+
if (playerSceneName != null && !playerSceneName.isBlank()) {
352+
sceneFiles.add(sceneDir.resolve(playerSceneName + ".mcmocap_scene"));
353+
} else {
354+
LOOP_LOGGER.warn("Invalid playerSceneName encountered: {}", playerSceneName);
355+
}
356+
});
357+
358+
if (sceneFiles.isEmpty()) {
359+
LOOP_LOGGER.warn("No scene files found to process.");
360+
}
361+
362+
for (Path sceneFile : sceneFiles) {
362363
if (sceneFile.toFile().exists()) {
363364
try {
364-
// Load the scene data from the file
365365
String jsonContent = new String(Files.readAllBytes(sceneFile));
366-
367-
// Parse the content
368366
JsonObject jsonObject = JsonParser.parseString(jsonContent).getAsJsonObject();
369367
JsonArray subScenes = jsonObject.getAsJsonArray("subscenes");
370368

371-
// Check if we have more scenes than maxLoops
372369
if (subScenes.size() > maxLoops) {
373-
// Calculate the number of scenes to remove
374370
int entriesToRemove = subScenes.size() - maxLoops;
375-
// Remove the excess entries (removing from the start of the array)
376371
for (int i = 0; i < entriesToRemove; i++) {
377-
subScenes.remove(0); // Remove the first (oldest) entry
372+
subScenes.remove(0); // Remove the oldest
378373
}
379-
380-
// Update the JSON object with the modified subScenes array
381374
jsonObject.add("subScenes", subScenes);
382-
383-
// Write the updated JSON back to the file
384375
Files.write(sceneFile, jsonObject.toString().getBytes());
385-
LOOP_LOGGER.info("Removed old scene entries to maintain maxLoops: {}", maxLoops);
376+
LOOP_LOGGER.info("Removed old scene entries for file: {}", sceneFile);
386377
}
387378
} catch (IOException e) {
388-
LOOP_LOGGER.error("Failed to read or write scene file: {}", sceneFile, e);
379+
LOOP_LOGGER.error("Failed to process scene file: {}", sceneFile, e);
389380
}
390381
} else {
391382
LOOP_LOGGER.error("Scene file does not exist: {}", sceneFile);

src/main/java/com/vltno/timeloop/TimeLoopConfig.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,12 @@
1111

1212
public class TimeLoopConfig {
1313
// These values will be loaded/saved from/to the JSON config file.bossbar set minecraft:loop_info
14+
public String sceneName = "loop_scene";
1415
public boolean firstStart = true;
1516
public int loopIteration = 1;
1617
public boolean isLooping = false;
1718
public int loopLengthTicks = 6000; // Default: 6000 ticks (i.e. 5 minutes)
18-
public int maxLoops = 0; //No limit by default
19+
public int maxLoops = 0; // No limit by default
1920
public long timeSetting = 13000;
2021
public long startTimeOfDay = 0;
2122
public boolean trackTimeOfDay = true;

0 commit comments

Comments
 (0)