Skip to content

Commit 1555021

Browse files
committed
NoIssue: Factor out client worker phases
1 parent 1ec44e4 commit 1555021

File tree

1 file changed

+138
-136
lines changed

1 file changed

+138
-136
lines changed

src/main/java/com/superzanti/serversync/client/ClientWorker.java

+138-136
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,10 @@ public class ClientWorker implements Runnable {
3131

3232
private Server server;
3333

34-
private List<SyncFile> clientFiles;
3534
private List<SyncFile> ignoredClientSideFiles;
3635
private FileManager fileManager = new FileManager();
3736

3837
public ClientWorker() {
39-
clientFiles = new ArrayList<>();
4038
ignoredClientSideFiles = new ArrayList<>(20);
4139
errorInUpdates = false;
4240
updateHappened = false;
@@ -78,14 +76,10 @@ private void closeWorker() {
7876

7977
Main.clientGUI.enableSyncButton();
8078
}
81-
82-
private void populateClientFiles(ArrayList<String> directories) {
83-
populateClientFiles(directories, false);
84-
}
85-
86-
private void populateClientFiles(ArrayList<String> directories, boolean ignoreRules) {
79+
80+
private List<SyncFile> getClientFiles(ArrayList<String> directories) {
8781
boolean addConfigFiles = true;
88-
82+
8983
for (String directory : directories) {
9084
// Currently servers can add the config directory to the included dirs list
9185
// this essentially switches the included configs from whitelist to blacklist
@@ -94,21 +88,136 @@ private void populateClientFiles(ArrayList<String> directories, boolean ignoreRu
9488
addConfigFiles = false;
9589
}
9690
}
97-
98-
clientFiles = fileManager.getModFiles(directories, Main.CONFIG.FILE_IGNORE_LIST, EFileMatchingMode.INGORE);
99-
91+
92+
List<SyncFile> clientFiles = fileManager.getModFiles(directories, Main.CONFIG.FILE_IGNORE_LIST,
93+
EFileMatchingMode.INGORE);
94+
10095
if (addConfigFiles) {
101-
clientFiles.addAll(fileManager.getConfigurationFiles(Main.CONFIG.CONFIG_INCLUDE_LIST, EFileMatchingMode.INCLUDE));
96+
clientFiles.addAll(
97+
fileManager.getConfigurationFiles(Main.CONFIG.CONFIG_INCLUDE_LIST, EFileMatchingMode.INCLUDE));
98+
}
99+
return clientFiles;
100+
}
101+
102+
private void updateFiles(List<SyncFile> clientFiles, List<SyncFile> serverFiles) {
103+
Logger.log("<------> " + Main.strings.getString("update_start") + " <------>");
104+
Logger.debug(Main.strings.getString("ignoring") + " " + Main.CONFIG.FILE_IGNORE_LIST);
105+
106+
int currentProgress = 0;
107+
int maxProgress = serverFiles.size();
108+
109+
for (SyncFile serverFile : serverFiles) {
110+
SyncFile clientFile;
111+
if (serverFile.isClientSideOnlyFile) {
112+
// TODO link this to a config value
113+
clientFile = SyncFile.ClientOnlySyncFile(serverFile.getClientSidePath());
114+
ignoredClientSideFiles.add(clientFile);
115+
Logger.log(Main.strings.getString("mods_clientmod_added") + ": " + clientFile.getFileName());
116+
} else {
117+
clientFile = SyncFile.StandardSyncFile(serverFile.getFileAsPath());
118+
}
119+
120+
boolean exists = Files.exists(clientFile.getFileAsPath());
121+
122+
if (exists) {
123+
try {
124+
if (!clientFile.equals(serverFile)) {
125+
server.updateFile(serverFile, clientFile);
126+
} else {
127+
Logger.log(clientFile.getFileName() + " " + Main.strings.getString("up_to_date"));
128+
}
129+
} catch (InvalidSyncFileException e) {
130+
// TODO stub invalid file handling
131+
Logger.debug(e);
132+
}
133+
} else {
134+
// Ignore support for client only files, users may wish to not allow some mods
135+
// out of personal preference
136+
if (serverFile.isClientSideOnlyFile && serverFile.matchesIgnoreListPattern()) {
137+
Logger.log("<>" + Main.strings.getString("ignoring") + " " + serverFile.getFileName());
138+
} else {
139+
Logger.debug(serverFile.getFileName() + " " + Main.strings.getString("does_not_exist"));
140+
server.updateFile(serverFile, clientFile);
141+
}
142+
}
143+
144+
Main.clientGUI.updateProgress((int) (++currentProgress / maxProgress));
145+
}
146+
}
147+
148+
private void deleteFiles(List<SyncFile> clientFiles, List<SyncFile> serverFiles) {
149+
Logger.log("<------> " + Main.strings.getString("delete_start") + " <------>");
150+
Logger.log(String.format("Ignore patterns: %s", String.join(", ", Main.CONFIG.FILE_IGNORE_LIST)));
151+
int currentProgress = 0;
152+
int maxProgress = clientFiles.size();
153+
154+
for (SyncFile clientFile : clientFiles) {
155+
if (clientFile.matchesIgnoreListPattern()) {
156+
// User created ignore rules
157+
Logger.debug(Main.strings.getString("ignoring") + " " + clientFile.getFileName());
158+
} else {
159+
Logger.debug(Main.strings.getString("client_check") + " " + clientFile.getFileName());
160+
161+
if (!serverFiles.contains(clientFile)) {
162+
if (clientFile.delete()) {
163+
Logger.log("<>" + clientFile.getFileName() + " " + Main.strings.getString("delete_success"));
164+
Path parentDirectory = clientFile.getClientSidePath().getParent();
165+
166+
if (parentDirectory != null && Files.isDirectory(parentDirectory)
167+
&& !parentDirectory.getFileName().toString().matches("mods|minecraft")) {
168+
try {
169+
Files.delete(parentDirectory);
170+
} catch (IOException e) {
171+
// Don't actually care if this fails, this either means there are files
172+
// left in the directory so we don't want to delete it
173+
// or some other failure to delete has happened, eg permissions
174+
}
175+
}
176+
} else {
177+
Logger.log("!!! failed to delete: " + clientFile.getFileName() + " !!!");
178+
}
179+
updateHappened = true;
180+
}
181+
182+
Main.clientGUI.updateProgress((int) (++currentProgress / maxProgress));
183+
}
184+
}
185+
}
186+
187+
private void duplicateCheck(List<SyncFile> clientFiles) {
188+
// ENHANCE: User dialog to pick a file to keep?
189+
ArrayList<String> modNames = new ArrayList<>(200);
190+
ArrayList<String> modHashes = new ArrayList<>(200);
191+
ArrayList<SyncFile> dupes = new ArrayList<>(10);
192+
193+
for (SyncFile clientFile : clientFiles) {
194+
MinecraftModInformation modInfo = clientFile.getModInformation();
195+
if (modInfo != null) {
196+
if (modNames.contains(modInfo.name)) {
197+
Logger.log("<!> Potential duplicate: " + clientFile.getFileName() + " - " + modInfo.name);
198+
dupes.add(clientFile);
199+
} else {
200+
modNames.add(modInfo.name);
201+
}
202+
} else {
203+
String hash = clientFile.getFileHash();
204+
if (modHashes.contains(hash)) {
205+
Logger.log("<!> Potential duplicate: " + clientFile.getFileName() + " - " + hash);
206+
dupes.add(clientFile);
207+
} else {
208+
modHashes.add(hash);
209+
}
210+
}
102211
}
103212
}
104213

105214
@Override
106215
public void run() {
107216
updateHappened = false;
108-
217+
109218
Main.clientGUI.disableSyncButton();
110219
Logger.getLog().clearUserFacingLog();
111-
220+
112221
server = new Server(this, Main.CONFIG.SERVER_IP, Main.CONFIG.SERVER_PORT);
113222

114223
if (!server.connect()) {
@@ -130,8 +239,8 @@ public void run() {
130239
closeWorker();
131240
return;
132241
}
133-
134-
populateClientFiles(syncableDirectories);
242+
243+
List<SyncFile> clientFiles = getClientFiles(syncableDirectories);
135244

136245
Logger.debug("Checking Server.isUpdateNeeded()");
137246
Logger.debug(clientFiles.toString());
@@ -144,27 +253,26 @@ public void run() {
144253
Logger.log(Main.strings.getString("mods_incompatable"));
145254
Logger.log("<------> " + "Getting files" + " <------>");
146255

147-
// get all files on server
148256
Logger.log(Main.strings.getString("mods_get"));
149257
ArrayList<SyncFile> serverFiles = server.getFiles();
150258

151259
if (serverFiles == null) {
152-
// TODO add to TDB
153260
Logger.log("Failed to get files from server, check detailed log in minecraft/logs");
154261
errorInUpdates = true;
155262
closeWorker();
156263
return;
157264
}
158265

159266
if (serverFiles.isEmpty()) {
160-
// TODO add to TDB
161267
Logger.log("Server has no syncable files");
162268
finished = true;
163269
closeWorker();
164270
return;
165271
}
166-
167-
/* CLIENT MODS */
272+
273+
/* CLIENT SPECIFIC MODS */
274+
// These are files that do not need to be present on the server to connect and play
275+
// These are only added if the user wanting to connect to the server has ServerSync configured to accept them
168276
if (!Main.CONFIG.REFUSE_CLIENT_MODS) {
169277
Logger.log(Main.strings.getString("mods_accepting_clientmods"));
170278

@@ -181,124 +289,18 @@ public void run() {
181289
Logger.log(Main.strings.getString("mods_refusing_clientmods"));
182290
}
183291

184-
Logger.debug(Main.strings.getString("ignoring") + " " + Main.CONFIG.FILE_IGNORE_LIST);
185-
186-
// figure out how big the progress bar is
187-
// TODO check this logic
188-
float numberOfFiles = clientFiles.size() + serverFiles.size();
189-
float percentScale = numberOfFiles / 100;
190-
float currentPercent = 0;
191-
192-
/* UPDATING */
193-
Logger.log("<------> " + Main.strings.getString("update_start") + " <------>");
194-
195-
/* COMMON MODS */
196-
for (SyncFile serverFile : serverFiles) {
197-
SyncFile clientFile;
198-
if (serverFile.isClientSideOnlyFile) {
199-
// TODO link this to a config value
200-
clientFile = SyncFile.ClientOnlySyncFile(serverFile.getClientSidePath());
201-
ignoredClientSideFiles.add(clientFile);
202-
Logger.log(Main.strings.getString("mods_clientmod_added") + ": " + clientFile.getFileName());
203-
} else {
204-
clientFile = SyncFile.StandardSyncFile(serverFile.getFileAsPath());
205-
}
206-
207-
boolean exists = Files.exists(clientFile.getFileAsPath());
208-
209-
if (exists) {
210-
try {
211-
if (!clientFile.equals(serverFile)) {
212-
server.updateFile(serverFile, clientFile);
213-
} else {
214-
Logger.log(clientFile.getFileName() + " " + Main.strings.getString("up_to_date"));
215-
}
216-
} catch (InvalidSyncFileException e) {
217-
//TODO stub invalid file handling
218-
Logger.debug(e);
219-
}
220-
} else {
221-
// Ignore support for client only files, users may wish to not allow some mods out of personal preference
222-
if (serverFile.isClientSideOnlyFile && serverFile.matchesIgnoreListPattern()) {
223-
Logger.log("<>" + Main.strings.getString("ignoring") + " " + serverFile.getFileName());
224-
} else {
225-
Logger.debug(serverFile.getFileName() + " " + Main.strings.getString("does_not_exist"));
226-
server.updateFile(serverFile, clientFile);
227-
}
228-
}
229-
currentPercent++;
230-
Main.clientGUI.updateProgress((int) (currentPercent / percentScale));
231-
}
292+
updateFiles(clientFiles, serverFiles);
293+
294+
deleteFiles(clientFiles, serverFiles);
232295

233-
/* DELETION */
234-
Logger.log("<------> " + Main.strings.getString("delete_start") + " <------>");
235-
for (SyncFile clientFile : clientFiles) {
236-
currentPercent++;
296+
// Get a new list of client files as we will have modified them during the
297+
// previous phases
298+
duplicateCheck(getClientFiles(syncableDirectories));
237299

238-
Logger.log(String.format("Ignore patterns: %s", String.join(", ", Main.CONFIG.FILE_IGNORE_LIST)));
239-
if (clientFile.matchesIgnoreListPattern()) {
240-
// User created ignore rules
241-
Logger.debug(Main.strings.getString("ignoring") + " " + clientFile.getFileName());
242-
} else {
243-
Logger.debug(Main.strings.getString("client_check") + " " + clientFile.getFileName());
244-
245-
if (!serverFiles.contains(clientFile)) {
246-
if (clientFile.delete()) {
247-
Logger.log("<>" + clientFile.getFileName()
248-
+ " " + Main.strings.getString("delete_success"));
249-
Path parentDirectory = clientFile.getClientSidePath().getParent();
250-
// TODO check this logic well, don't want to have potential for deleting random folders
251-
if (parentDirectory != null && Files.isDirectory(parentDirectory) &&
252-
!parentDirectory.getFileName().toString().matches("mods|minecraft")) {
253-
try {
254-
Files.delete(parentDirectory);
255-
} catch (IOException e) {
256-
// Don't actually care if this fails, this either means there are files
257-
// left in the directory so we don't want to delete it
258-
// or some other failure to delete has happened, eg permissions
259-
}
260-
}
261-
} else {
262-
Logger.log("!!! failed to delete: " + clientFile.getFileName() + " !!!");
263-
}
264-
updateHappened = true;
265-
}
266-
267-
Main.clientGUI.updateProgress((int) (currentPercent / percentScale));
268-
}
269-
}
270-
271-
// TODO complete this with user prompt to pick which duplicate to keep
272-
/* DUPLICATE CHECK */
273-
populateClientFiles(syncableDirectories, true);
274-
ArrayList<String> modNames = new ArrayList<>(200);
275-
ArrayList<String> modHashes = new ArrayList<>(200);
276-
ArrayList<SyncFile> dupes = new ArrayList<>(10);
277-
for (SyncFile clientFile : clientFiles) {
278-
MinecraftModInformation modInfo = clientFile.getModInformation();
279-
if (modInfo != null) {
280-
if (modNames.contains(modInfo.name)) {
281-
Logger.log("<!> Potential duplicate: " + clientFile.getFileName() + " - " + modInfo.name);
282-
dupes.add(clientFile);
283-
} else {
284-
modNames.add(modInfo.name);
285-
}
286-
} else {
287-
String hash = clientFile.getFileHash();
288-
if (modHashes.contains(hash)) {
289-
Logger.log("<!> Potential duplicate: " + clientFile.getFileName() + " - " + hash);
290-
dupes.add(clientFile);
291-
} else {
292-
modHashes.add(hash);
293-
}
294-
}
295-
}
296300
}
297-
Logger.log(Main.strings.getString("update_complete"));
298-
299-
// Teardown
301+
300302
closeWorker();
301-
303+
Logger.log(Main.strings.getString("update_complete"));
302304
}
303305

304306
}

0 commit comments

Comments
 (0)