wörk wörk (day 5)
* added calculation for download speed * added calculation for the exact downloaded size * added first steps for autoupdater * fixed current sync status * removed file sync progress
This commit is contained in:
parent
112bc228d4
commit
beb80b8597
@ -52,7 +52,8 @@ while IFS= read -r line; do
|
|||||||
dirfile=$(dirname "${line}")
|
dirfile=$(dirname "${line}")
|
||||||
filename=$(basename "${line}")
|
filename=$(basename "${line}")
|
||||||
filenamezsync=$(basename "${zsyncfile}")
|
filenamezsync=$(basename "${zsyncfile}")
|
||||||
$(cd "${dirfile}" && zsyncmake -o "${filenamezsync}" "${filename}")
|
fileurl=$(python3 -c "import urllib.parse; print(urllib.parse.quote(input()))" <<< "${filename}")
|
||||||
|
$(cd "${dirfile}" && zsyncmake -u ${fileurl} -o "${filenamezsync}" "${filename}")
|
||||||
if [ $? -eq 0 ]; then
|
if [ $? -eq 0 ]; then
|
||||||
echo "Success: Generated ${zsyncfile}"
|
echo "Success: Generated ${zsyncfile}"
|
||||||
else
|
else
|
||||||
|
@ -701,11 +701,39 @@
|
|||||||
</component>
|
</component>
|
||||||
</children>
|
</children>
|
||||||
</grid>
|
</grid>
|
||||||
<grid id="c304c" layout-manager="GridLayoutManager" row-count="4" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
<grid id="c304c" layout-manager="FormLayout">
|
||||||
<margin top="0" left="0" bottom="0" right="0"/>
|
<rowspec value="center:d:grow"/>
|
||||||
|
<rowspec value="top:4dlu:noGrow"/>
|
||||||
|
<rowspec value="center:max(d;4px):noGrow"/>
|
||||||
|
<rowspec value="top:4dlu:noGrow"/>
|
||||||
|
<rowspec value="center:max(d;4px):noGrow"/>
|
||||||
|
<rowspec value="top:4dlu:noGrow"/>
|
||||||
|
<rowspec value="center:max(d;4px):noGrow"/>
|
||||||
|
<rowspec value="top:4dlu:noGrow"/>
|
||||||
|
<rowspec value="center:max(d;4px):noGrow"/>
|
||||||
|
<colspec value="fill:d:grow"/>
|
||||||
<constraints border-constraint="Center"/>
|
<constraints border-constraint="Center"/>
|
||||||
<properties/>
|
<properties/>
|
||||||
<border type="none"/>
|
<border type="none"/>
|
||||||
|
<children>
|
||||||
|
<grid id="e82d7" layout-manager="FormLayout">
|
||||||
|
<rowspec value="center:d:noGrow"/>
|
||||||
|
<colspec value="fill:d:grow"/>
|
||||||
|
<constraints>
|
||||||
|
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||||
|
<forms/>
|
||||||
|
</constraints>
|
||||||
|
<properties/>
|
||||||
|
<border type="none"/>
|
||||||
|
<children>
|
||||||
|
<grid id="5f038" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||||
|
<margin top="0" left="0" bottom="0" right="0"/>
|
||||||
|
<constraints>
|
||||||
|
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||||
|
<forms/>
|
||||||
|
</constraints>
|
||||||
|
<properties/>
|
||||||
|
<border type="none"/>
|
||||||
<children>
|
<children>
|
||||||
<component id="f39cc" class="javax.swing.JProgressBar" binding="syncDownloadProgress">
|
<component id="f39cc" class="javax.swing.JProgressBar" binding="syncDownloadProgress">
|
||||||
<constraints>
|
<constraints>
|
||||||
@ -718,21 +746,15 @@
|
|||||||
<value value="0"/>
|
<value value="0"/>
|
||||||
</properties>
|
</properties>
|
||||||
</component>
|
</component>
|
||||||
<component id="87392" class="javax.swing.JProgressBar" binding="syncFileProgress">
|
</children>
|
||||||
<constraints>
|
</grid>
|
||||||
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
</children>
|
||||||
</constraints>
|
</grid>
|
||||||
<properties>
|
|
||||||
<font size="14" style="1"/>
|
|
||||||
<string value=""/>
|
|
||||||
<stringPainted value="true"/>
|
|
||||||
<value value="0"/>
|
|
||||||
</properties>
|
|
||||||
</component>
|
|
||||||
<grid id="99173" layout-manager="GridLayoutManager" row-count="1" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
<grid id="99173" layout-manager="GridLayoutManager" row-count="1" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||||
<margin top="0" left="0" bottom="0" right="0"/>
|
<margin top="0" left="0" bottom="0" right="0"/>
|
||||||
<constraints>
|
<constraints>
|
||||||
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
<grid row="1" column="0" row-span="8" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||||
|
<forms/>
|
||||||
</constraints>
|
</constraints>
|
||||||
<properties/>
|
<properties/>
|
||||||
<border type="none"/>
|
<border type="none"/>
|
||||||
@ -2049,7 +2071,7 @@
|
|||||||
<text value="Client v1.0.1000"/>
|
<text value="Client v1.0.1000"/>
|
||||||
</properties>
|
</properties>
|
||||||
</component>
|
</component>
|
||||||
<component id="3c6b0" class="javax.swing.JLabel">
|
<component id="3c6b0" class="javax.swing.JLabel" binding="aboutUpdateLabel">
|
||||||
<constraints>
|
<constraints>
|
||||||
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="9" fill="0" indent="0" use-parent-layout="false"/>
|
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="9" fill="0" indent="0" use-parent-layout="false"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
|
@ -20,6 +20,8 @@ import de.mc8051.arma3launcher.repo.FileChecker;
|
|||||||
import de.mc8051.arma3launcher.repo.RepositoryManger;
|
import de.mc8051.arma3launcher.repo.RepositoryManger;
|
||||||
import de.mc8051.arma3launcher.repo.SyncList;
|
import de.mc8051.arma3launcher.repo.SyncList;
|
||||||
import de.mc8051.arma3launcher.repo.Syncer;
|
import de.mc8051.arma3launcher.repo.Syncer;
|
||||||
|
import de.mc8051.arma3launcher.repo.Updater;
|
||||||
|
import de.mc8051.arma3launcher.repo.Version;
|
||||||
import de.mc8051.arma3launcher.steam.SteamTimer;
|
import de.mc8051.arma3launcher.steam.SteamTimer;
|
||||||
import de.mc8051.arma3launcher.utils.Callback;
|
import de.mc8051.arma3launcher.utils.Callback;
|
||||||
import de.mc8051.arma3launcher.utils.Humanize;
|
import de.mc8051.arma3launcher.utils.Humanize;
|
||||||
@ -132,7 +134,6 @@ public class LauncherGUI implements Observer {
|
|||||||
private JButton syncCheckAbortButton;
|
private JButton syncCheckAbortButton;
|
||||||
private JButton syncIntensiveCheckButton;
|
private JButton syncIntensiveCheckButton;
|
||||||
public JProgressBar syncDownloadProgress;
|
public JProgressBar syncDownloadProgress;
|
||||||
public JProgressBar syncFileProgress;
|
|
||||||
private JButton syncDownloadButton;
|
private JButton syncDownloadButton;
|
||||||
private JButton syncDownloadAbortButton;
|
private JButton syncDownloadAbortButton;
|
||||||
private JButton syncPauseButton;
|
private JButton syncPauseButton;
|
||||||
@ -171,11 +172,13 @@ public class LauncherGUI implements Observer {
|
|||||||
private JTextPane presetNoteTextPane;
|
private JTextPane presetNoteTextPane;
|
||||||
private JPanel presetNotePaneWrapper;
|
private JPanel presetNotePaneWrapper;
|
||||||
private JPanel presetNotePane;
|
private JPanel presetNotePane;
|
||||||
|
private JLabel aboutUpdateLabel;
|
||||||
|
|
||||||
private JCheckBoxTree repoTree;
|
private JCheckBoxTree repoTree;
|
||||||
private FileChecker fileChecker;
|
private FileChecker fileChecker;
|
||||||
private Syncer syncer;
|
private Syncer syncer;
|
||||||
private SyncList lastSynclist = null;
|
private SyncList lastSynclist = null;
|
||||||
|
private Updater updater = new Updater();
|
||||||
|
|
||||||
public LauncherGUI() {
|
public LauncherGUI() {
|
||||||
fileChecker = new FileChecker(syncCheckProgress);
|
fileChecker = new FileChecker(syncCheckProgress);
|
||||||
@ -473,7 +476,7 @@ public class LauncherGUI implements Observer {
|
|||||||
|
|
||||||
Object newNameO = JOptionPane.showInputDialog(null, "",
|
Object newNameO = JOptionPane.showInputDialog(null, "",
|
||||||
LangUtils.getInstance().getString("new_modset_name"), JOptionPane.QUESTION_MESSAGE, null, null, selectedModset.getName());
|
LangUtils.getInstance().getString("new_modset_name"), JOptionPane.QUESTION_MESSAGE, null, null, selectedModset.getName());
|
||||||
if(newNameO == null) return;
|
if (newNameO == null) return;
|
||||||
String newName = (String) newNameO;
|
String newName = (String) newNameO;
|
||||||
if (newName.isEmpty()) return;
|
if (newName.isEmpty()) return;
|
||||||
if (Modset.MODSET_LIST.containsKey(newName)) {
|
if (Modset.MODSET_LIST.containsKey(newName)) {
|
||||||
@ -494,7 +497,7 @@ public class LauncherGUI implements Observer {
|
|||||||
DefaultComboBoxModel<Modset> model = (DefaultComboBoxModel<Modset>) syncPresetCombo.getModel();
|
DefaultComboBoxModel<Modset> model = (DefaultComboBoxModel<Modset>) syncPresetCombo.getModel();
|
||||||
Modset elementAt = model.getElementAt(((JComboBox) e.getItemSelectable()).getSelectedIndex());
|
Modset elementAt = model.getElementAt(((JComboBox) e.getItemSelectable()).getSelectedIndex());
|
||||||
repoTree.setCheckboxesChecked(false);
|
repoTree.setCheckboxesChecked(false);
|
||||||
if(elementAt.getType() == Modset.Type.PLACEHOLDER) return;
|
if (elementAt.getType() == Modset.Type.PLACEHOLDER) return;
|
||||||
|
|
||||||
List<String> collect = elementAt.getMods().stream().map(Mod::getName).collect(Collectors.toList());
|
List<String> collect = elementAt.getMods().stream().map(Mod::getName).collect(Collectors.toList());
|
||||||
|
|
||||||
@ -503,7 +506,7 @@ public class LauncherGUI implements Observer {
|
|||||||
|
|
||||||
for (int i = 0; i < root.getChildCount(); i++) {
|
for (int i = 0; i < root.getChildCount(); i++) {
|
||||||
TreeNode childAt = root.getChildAt(i);
|
TreeNode childAt = root.getChildAt(i);
|
||||||
if(!collect.contains(childAt.toString())) continue;
|
if (!collect.contains(childAt.toString())) continue;
|
||||||
final TreePath treePath = new TreePath(new TreeNode[]{root, childAt});
|
final TreePath treePath = new TreePath(new TreeNode[]{root, childAt});
|
||||||
repoTree.checkSubTree(treePath, true);
|
repoTree.checkSubTree(treePath, true);
|
||||||
repoTree.updatePredecessorsWithCheckMode(treePath, true);
|
repoTree.updatePredecessorsWithCheckMode(treePath, true);
|
||||||
@ -514,6 +517,12 @@ public class LauncherGUI implements Observer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
updater.needUpdate((needUpdate, newestVersion) -> {
|
||||||
|
if (needUpdate) {
|
||||||
|
SwingUtilities.invokeLater(() -> warnBox(LangUtils.getInstance().getString("client_outdated"), LangUtils.getInstance().getString("please_update")));
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void infoBox(String infoMessage, String titleBar) {
|
public static void infoBox(String infoMessage, String titleBar) {
|
||||||
@ -1104,7 +1113,6 @@ public class LauncherGUI implements Observer {
|
|||||||
syncPauseButton.setEnabled(false);
|
syncPauseButton.setEnabled(false);
|
||||||
|
|
||||||
syncStatusLabel.setText("Sync stopped");
|
syncStatusLabel.setText("Sync stopped");
|
||||||
syncFileProgress.setValue(0);
|
|
||||||
TaskBarUtils.getInstance().setValue(0);
|
TaskBarUtils.getInstance().setValue(0);
|
||||||
TaskBarUtils.getInstance().off();
|
TaskBarUtils.getInstance().off();
|
||||||
});
|
});
|
||||||
@ -1116,8 +1124,6 @@ public class LauncherGUI implements Observer {
|
|||||||
syncPauseButton.setEnabled(false);
|
syncPauseButton.setEnabled(false);
|
||||||
|
|
||||||
syncStatusLabel.setText("Sync finished");
|
syncStatusLabel.setText("Sync finished");
|
||||||
syncFileProgress.setValue(0);
|
|
||||||
syncFileProgress.setString("");
|
|
||||||
TaskBarUtils.getInstance().setValue(0);
|
TaskBarUtils.getInstance().setValue(0);
|
||||||
TaskBarUtils.getInstance().off();
|
TaskBarUtils.getInstance().off();
|
||||||
TaskBarUtils.getInstance().attention();
|
TaskBarUtils.getInstance().attention();
|
||||||
@ -1137,7 +1143,6 @@ public class LauncherGUI implements Observer {
|
|||||||
syncPauseButton.setEnabled(true);
|
syncPauseButton.setEnabled(true);
|
||||||
syncPauseButton.setText(LangUtils.getInstance().getString("resume"));
|
syncPauseButton.setText(LangUtils.getInstance().getString("resume"));
|
||||||
syncDownloadButton.setEnabled(false);
|
syncDownloadButton.setEnabled(false);
|
||||||
syncFileProgress.setValue(0);
|
|
||||||
TaskBarUtils.getInstance().paused();
|
TaskBarUtils.getInstance().paused();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -1145,7 +1150,7 @@ public class LauncherGUI implements Observer {
|
|||||||
|
|
||||||
private void updateModsetList() {
|
private void updateModsetList() {
|
||||||
SwingUtilities.invokeLater(() -> {
|
SwingUtilities.invokeLater(() -> {
|
||||||
if (((DefaultComboBoxModel<Modset>)syncPresetCombo.getModel()).getSize() > 0){
|
if (((DefaultComboBoxModel<Modset>) syncPresetCombo.getModel()).getSize() > 0) {
|
||||||
syncPresetCombo.setSelectedIndex(0);
|
syncPresetCombo.setSelectedIndex(0);
|
||||||
}
|
}
|
||||||
PresetTableModel model = (PresetTableModel) presetList.getModel();
|
PresetTableModel model = (PresetTableModel) presetList.getModel();
|
||||||
@ -1221,6 +1226,19 @@ public class LauncherGUI implements Observer {
|
|||||||
case SETTING:
|
case SETTING:
|
||||||
settingsPanelButton.setBackground(focusBackgroundColor);
|
settingsPanelButton.setBackground(focusBackgroundColor);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ABOUT:
|
||||||
|
updater.needUpdate(new Callback.NeedUpdateCallback() {
|
||||||
|
@Override
|
||||||
|
public void response(boolean needUpdate, Version newestVersion) {
|
||||||
|
if (needUpdate) {
|
||||||
|
SwingUtilities.invokeLater(() -> aboutUpdateLabel.setText(LangUtils.getInstance().getString("client_outdated") + ": v" + newestVersion.get()));
|
||||||
|
} else {
|
||||||
|
SwingUtilities.invokeLater(() -> aboutUpdateLabel.setText(LangUtils.getInstance().getString("client_up_to_date")));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
tabbedPane1.setSelectedIndex(tab.getIndex());
|
tabbedPane1.setSelectedIndex(tab.getIndex());
|
||||||
|
@ -51,7 +51,7 @@ public class RepositoryManger implements Observable {
|
|||||||
statusMap.put(Type.CHANGELOG, DownloadStatus.FINNISHED);
|
statusMap.put(Type.CHANGELOG, DownloadStatus.FINNISHED);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void getAsync(String urlS, Callback.HttpCallback callback) {
|
public void getAsync(String urlS, Callback.HttpCallback callback) {
|
||||||
new Thread(() -> {
|
new Thread(() -> {
|
||||||
try {
|
try {
|
||||||
URI url = new URI(urlS);
|
URI url = new URI(urlS);
|
||||||
|
29
src/main/java/de/mc8051/arma3launcher/repo/SyncListener.java
Normal file
29
src/main/java/de/mc8051/arma3launcher/repo/SyncListener.java
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
package de.mc8051.arma3launcher.repo;
|
||||||
|
|
||||||
|
import co.bitshfted.xapps.zsync.Zsync;
|
||||||
|
import co.bitshfted.xapps.zsync.http.ContentRange;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by gurkengewuerz.de on 29.03.2020.
|
||||||
|
*/
|
||||||
|
public interface SyncListener {
|
||||||
|
|
||||||
|
public void bytesDownloaded(long bytes);
|
||||||
|
public void remoteFileDownloadingInitiated(List<ContentRange> ranges);
|
||||||
|
public void remoteFileDownloadingStarted(long length);
|
||||||
|
public void remoteFileDownloadingComplete();
|
||||||
|
public void controlFileDownloadingComplete();
|
||||||
|
public void controlFileDownloadingStarted(Path path, long length);
|
||||||
|
public void controlFileReadingComplete();
|
||||||
|
public void outputFileWritingStarted(long length);
|
||||||
|
public void outputFileWritingCompleted();
|
||||||
|
public void inputFileReadingStarted(Path inputFile, long length);
|
||||||
|
public void inputFileReadingComplete();
|
||||||
|
public void zsyncComplete();
|
||||||
|
public void zsyncFailed(Exception exception);
|
||||||
|
public void zsyncStarted(Zsync.Options options);
|
||||||
|
}
|
107
src/main/java/de/mc8051/arma3launcher/repo/SyncObserver.java
Normal file
107
src/main/java/de/mc8051/arma3launcher/repo/SyncObserver.java
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
package de.mc8051.arma3launcher.repo;
|
||||||
|
|
||||||
|
import co.bitshfted.xapps.zsync.Zsync;
|
||||||
|
import co.bitshfted.xapps.zsync.ZsyncStatsObserver;
|
||||||
|
import co.bitshfted.xapps.zsync.http.ContentRange;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by gurkengewuerz.de on 29.03.2020.
|
||||||
|
*/
|
||||||
|
public class SyncObserver extends ZsyncStatsObserver {
|
||||||
|
|
||||||
|
private final SyncListener listener;
|
||||||
|
|
||||||
|
public SyncObserver(SyncListener listener) {
|
||||||
|
super();
|
||||||
|
this.listener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void zsyncStarted(URI requestedZsyncUri, Zsync.Options options) {
|
||||||
|
super.zsyncStarted(requestedZsyncUri, options);
|
||||||
|
listener.zsyncStarted(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void zsyncComplete() {
|
||||||
|
super.zsyncComplete();
|
||||||
|
listener.zsyncComplete();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void zsyncFailed(Exception exception) {
|
||||||
|
super.zsyncFailed(exception);
|
||||||
|
listener.zsyncFailed(exception);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void inputFileReadingStarted(Path inputFile, long length) {
|
||||||
|
super.inputFileReadingStarted(inputFile, length);
|
||||||
|
listener.inputFileReadingStarted(inputFile, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void inputFileReadingComplete() {
|
||||||
|
super.inputFileReadingComplete();
|
||||||
|
listener.inputFileReadingComplete();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void controlFileDownloadingComplete() {
|
||||||
|
super.controlFileDownloadingComplete();
|
||||||
|
listener.controlFileDownloadingComplete();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void controlFileReadingStarted(Path path, long length) {
|
||||||
|
super.controlFileReadingStarted(path, length);
|
||||||
|
listener.controlFileDownloadingStarted(path, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void controlFileReadingComplete() {
|
||||||
|
super.controlFileReadingComplete();
|
||||||
|
listener.controlFileReadingComplete();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void outputFileWritingStarted(Path outputFile, long length) {
|
||||||
|
super.outputFileWritingStarted(outputFile, length);
|
||||||
|
listener.outputFileWritingStarted(length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void outputFileWritingCompleted() {
|
||||||
|
super.outputFileWritingCompleted();
|
||||||
|
listener.outputFileWritingCompleted();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void remoteFileDownloadingInitiated(URI uri, List<ContentRange> ranges) {
|
||||||
|
super.remoteFileDownloadingInitiated(uri, ranges);
|
||||||
|
listener.remoteFileDownloadingInitiated(ranges);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void remoteFileDownloadingStarted(URI uri, long length) {
|
||||||
|
super.remoteFileDownloadingStarted(uri, length);
|
||||||
|
listener.remoteFileDownloadingStarted(length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void remoteFileDownloadingComplete() {
|
||||||
|
super.remoteFileDownloadingComplete();
|
||||||
|
listener.remoteFileDownloadingComplete();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void bytesDownloaded(long bytes) {
|
||||||
|
super.bytesDownloaded(bytes);
|
||||||
|
listener.bytesDownloaded(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -2,7 +2,8 @@ package de.mc8051.arma3launcher.repo;
|
|||||||
|
|
||||||
import co.bitshfted.xapps.zsync.Zsync;
|
import co.bitshfted.xapps.zsync.Zsync;
|
||||||
import co.bitshfted.xapps.zsync.ZsyncException;
|
import co.bitshfted.xapps.zsync.ZsyncException;
|
||||||
import co.bitshfted.xapps.zsync.ZsyncObserver;
|
import co.bitshfted.xapps.zsync.ZsyncStatsObserver;
|
||||||
|
import co.bitshfted.xapps.zsync.http.ContentRange;
|
||||||
import de.mc8051.arma3launcher.ArmA3Launcher;
|
import de.mc8051.arma3launcher.ArmA3Launcher;
|
||||||
import de.mc8051.arma3launcher.LauncherGUI;
|
import de.mc8051.arma3launcher.LauncherGUI;
|
||||||
import de.mc8051.arma3launcher.interfaces.Observable;
|
import de.mc8051.arma3launcher.interfaces.Observable;
|
||||||
@ -16,6 +17,7 @@ import javax.swing.*;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -25,7 +27,7 @@ import java.util.logging.Logger;
|
|||||||
/**
|
/**
|
||||||
* Created by gurkengewuerz.de on 25.03.2020.
|
* Created by gurkengewuerz.de on 25.03.2020.
|
||||||
*/
|
*/
|
||||||
public class Syncer extends ZsyncObserver implements Observable {
|
public class Syncer implements Observable, SyncListener {
|
||||||
|
|
||||||
private List<Observer> observerList = new ArrayList<>();
|
private List<Observer> observerList = new ArrayList<>();
|
||||||
|
|
||||||
@ -37,19 +39,22 @@ public class Syncer extends ZsyncObserver implements Observable {
|
|||||||
private SyncList modlist;
|
private SyncList modlist;
|
||||||
|
|
||||||
private boolean currentDownload_failed = false;
|
private boolean currentDownload_failed = false;
|
||||||
private String currentDownload_sizeS;
|
|
||||||
private boolean controlfile_downloaded = false;
|
|
||||||
private int failed = 0;
|
private int failed = 0;
|
||||||
private int success = 0;
|
private int success = 0;
|
||||||
|
|
||||||
private long syncSize;
|
private long syncSize;
|
||||||
private String syncSizeString;
|
|
||||||
private int syncCount;
|
private int syncCount;
|
||||||
|
|
||||||
private long downloadStarted;
|
private int syncRealCount;
|
||||||
private long downloadEnded;
|
|
||||||
private long downloadSize;
|
private SyncObserver syncObserver;
|
||||||
private long downloadDownloaded;
|
|
||||||
|
private long speedCalcSize = 0L;
|
||||||
|
private long speedCalcTime = 0L;
|
||||||
|
|
||||||
|
private long downloadDownloaded = 0L;
|
||||||
|
private long downloadStarted = 0L;
|
||||||
|
private long downloadSize = 0L;
|
||||||
|
|
||||||
private Zsync zsync;
|
private Zsync zsync;
|
||||||
private LauncherGUI gui;
|
private LauncherGUI gui;
|
||||||
@ -71,8 +76,12 @@ public class Syncer extends ZsyncObserver implements Observable {
|
|||||||
failed = 0;
|
failed = 0;
|
||||||
success = 0;
|
success = 0;
|
||||||
|
|
||||||
|
speedCalcSize = 0;
|
||||||
|
speedCalcTime = 0;
|
||||||
|
|
||||||
|
syncRealCount = 0;
|
||||||
|
|
||||||
syncSize = ml.getSize();
|
syncSize = ml.getSize();
|
||||||
syncSizeString = Humanize.binaryPrefix(syncSize);
|
|
||||||
syncCount = ml.getCount();
|
syncCount = ml.getCount();
|
||||||
SwingUtilities.invokeLater(() -> {
|
SwingUtilities.invokeLater(() -> {
|
||||||
gui.syncDownloadProgress.setMaximum(syncCount);
|
gui.syncDownloadProgress.setMaximum(syncCount);
|
||||||
@ -130,10 +139,9 @@ public class Syncer extends ZsyncObserver implements Observable {
|
|||||||
try {
|
try {
|
||||||
currentDownload = mf;
|
currentDownload = mf;
|
||||||
currentDownload_failed = false;
|
currentDownload_failed = false;
|
||||||
controlfile_downloaded = false;
|
|
||||||
currentDownload_sizeS = Humanize.binaryPrefix(currentDownload.getSize());
|
|
||||||
|
|
||||||
zsync.zsync(URI.create(mf.getRemoteFile() + ".zsync"), o, this);
|
syncObserver = new SyncObserver(this);
|
||||||
|
zsync.zsync(URI.create(mf.getRemoteFile() + ".zsync"), o, syncObserver);
|
||||||
} catch (ZsyncException | IllegalArgumentException e) {
|
} catch (ZsyncException | IllegalArgumentException e) {
|
||||||
Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, e);
|
Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, e);
|
||||||
}
|
}
|
||||||
@ -183,42 +191,40 @@ public class Syncer extends ZsyncObserver implements Observable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void zsyncStarted(URI requestedZsyncUri, Zsync.Options options) {
|
public void zsyncStarted(Zsync.Options options) {
|
||||||
super.zsyncStarted(requestedZsyncUri, options);
|
Logger.getLogger(getClass().getName()).log(Level.INFO, "ZSync started " + options.getOutputFile());
|
||||||
|
|
||||||
SwingUtilities.invokeLater(() -> {
|
|
||||||
gui.syncFileProgress.setValue(0);
|
|
||||||
gui.syncFileProgress.setString("0 %");
|
|
||||||
});
|
|
||||||
|
|
||||||
System.out.println("ZSync started " + options.getOutputFile());
|
|
||||||
SwingUtilities.invokeLater(() -> gui.syncStatusLabel.setText(currentDownload.getModPath() + ": Sync started"));
|
SwingUtilities.invokeLater(() -> gui.syncStatusLabel.setText(currentDownload.getModPath() + ": Sync started"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void zsyncFailed(Exception exception) {
|
public void zsyncFailed(Exception exception) {
|
||||||
super.zsyncFailed(exception);
|
|
||||||
currentDownload_failed = true;
|
currentDownload_failed = true;
|
||||||
System.out.println("Zsync failed " + exception.getMessage());
|
Logger.getLogger(getClass().getName()).log(Level.INFO, "Zsync failed " + exception.getMessage());
|
||||||
SwingUtilities.invokeLater(() -> gui.syncStatusLabel.setText(currentDownload.getModPath() + ": Sync failed"));
|
SwingUtilities.invokeLater(() -> gui.syncStatusLabel.setText(currentDownload.getModPath() + ": Sync failed"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void zsyncComplete() {
|
public void zsyncComplete() {
|
||||||
super.zsyncComplete();
|
speedCalcSize+=downloadDownloaded;
|
||||||
|
speedCalcTime+=System.currentTimeMillis()-downloadStarted;
|
||||||
|
|
||||||
downloadEnded = System.nanoTime();
|
if (speedCalcSize > 20 * 1024 * 1024) {
|
||||||
System.out.println(downloadSize);
|
|
||||||
System.out.println(downloadEnded - downloadStarted);
|
|
||||||
System.out.println((downloadSize / (downloadEnded - downloadStarted)) / 1000);
|
|
||||||
|
|
||||||
System.out.println("Zsync complete");
|
final double speedByte = ((double)speedCalcSize)/((double)speedCalcTime /1000);
|
||||||
|
SwingUtilities.invokeLater(() -> gui.syncDownloadSpeedLabel.setText(Humanize.binaryPrefix(Double.valueOf(speedByte).longValue()) + "/s"));
|
||||||
|
speedCalcSize = 0L;
|
||||||
|
speedCalcTime = 0L;
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger.getLogger(getClass().getName()).log(Level.INFO, "Zsync complete");
|
||||||
|
|
||||||
if (currentDownload_failed)
|
if (currentDownload_failed)
|
||||||
failed++;
|
failed++;
|
||||||
else success++;
|
else success++;
|
||||||
|
|
||||||
final long finalSize = syncSize - modlist.getSize();
|
syncRealCount+=downloadDownloaded;
|
||||||
|
|
||||||
|
final long finalSize = syncSize - ((syncSize - modlist.getSize() + currentDownload.getSize()) - syncRealCount);
|
||||||
final int i = success + failed;
|
final int i = success + failed;
|
||||||
final int percentage = (int) ((double) i / (double) Long.valueOf(syncCount).intValue() * 100);
|
final int percentage = (int) ((double) i / (double) Long.valueOf(syncCount).intValue() * 100);
|
||||||
final String modPath = currentDownload.getModPath();
|
final String modPath = currentDownload.getModPath();
|
||||||
@ -226,7 +232,7 @@ public class Syncer extends ZsyncObserver implements Observable {
|
|||||||
SwingUtilities.invokeLater(() -> {
|
SwingUtilities.invokeLater(() -> {
|
||||||
gui.syncDownloadProgress.setValue(i);
|
gui.syncDownloadProgress.setValue(i);
|
||||||
gui.syncFileCountLabel.setText(i + "/" + syncCount + " (" + failed + " failed)");
|
gui.syncFileCountLabel.setText(i + "/" + syncCount + " (" + failed + " failed)");
|
||||||
gui.syncSizeLabel.setText(Humanize.binaryPrefix(finalSize) + "/" + syncSizeString);
|
gui.syncSizeLabel.setText(Humanize.binaryPrefix(syncRealCount) + "/" + Humanize.binaryPrefix(finalSize));
|
||||||
|
|
||||||
if (currentDownload_failed)
|
if (currentDownload_failed)
|
||||||
gui.syncStatusLabel.setText(modPath + ": Sync failed");
|
gui.syncStatusLabel.setText(modPath + ": Sync failed");
|
||||||
@ -241,47 +247,65 @@ public class Syncer extends ZsyncObserver implements Observable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void controlFileDownloadingStarted(URI uri, long length) {
|
public void controlFileDownloadingStarted(Path path, long length) {
|
||||||
super.controlFileDownloadingStarted(uri, length);
|
Logger.getLogger(getClass().getName()).log(Level.INFO, "controlFileDownloadingStarted " + length);
|
||||||
System.out.println("controlFileDownloadingStarted " + length);
|
|
||||||
SwingUtilities.invokeLater(() -> gui.syncStatusLabel.setText(currentDownload.getModPath() + ": Get Header"));
|
SwingUtilities.invokeLater(() -> gui.syncStatusLabel.setText(currentDownload.getModPath() + ": Get Header"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void controlFileDownloadingComplete() {
|
public void controlFileReadingComplete() {
|
||||||
super.controlFileDownloadingComplete();
|
|
||||||
System.out.println("controlFileDownloadingComplete");
|
|
||||||
controlfile_downloaded = true;
|
|
||||||
|
|
||||||
SwingUtilities.invokeLater(() -> gui.syncStatusLabel.setText(currentDownload.getModPath() + ": Hashing"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void remoteFileDownloadingStarted(URI uri, long length) {
|
public void outputFileWritingStarted(long length) {
|
||||||
super.remoteFileDownloadingStarted(uri, length);
|
SwingUtilities.invokeLater(() -> gui.syncStatusLabel.setText(currentDownload.getModPath() + ": Writing File"));
|
||||||
System.out.println("remoteFileDownloadingStarted " + length);
|
}
|
||||||
|
|
||||||
downloadSize = length;
|
@Override
|
||||||
downloadDownloaded = 0;
|
public void outputFileWritingCompleted() {
|
||||||
downloadStarted = System.nanoTime();
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void inputFileReadingStarted(Path inputFile, long length) {
|
||||||
|
SwingUtilities.invokeLater(() -> gui.syncStatusLabel.setText(currentDownload.getModPath() + ": Reading File"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void inputFileReadingComplete() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void controlFileDownloadingComplete() {
|
||||||
|
Logger.getLogger(getClass().getName()).log(Level.INFO, "controlFileDownloadingComplete");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void remoteFileDownloadingInitiated(List<ContentRange> ranges) {
|
||||||
|
downloadStarted = System.currentTimeMillis();
|
||||||
|
Logger.getLogger(getClass().getName()).log(Level.INFO, "remoteFileDownloadingInitiated");
|
||||||
SwingUtilities.invokeLater(() -> gui.syncStatusLabel.setText(currentDownload.getModPath() + ": Downloading"));
|
SwingUtilities.invokeLater(() -> gui.syncStatusLabel.setText(currentDownload.getModPath() + ": Downloading"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void remoteFileDownloadingStarted(long length) {
|
||||||
|
downloadDownloaded = 0;
|
||||||
|
downloadSize = length;
|
||||||
|
|
||||||
|
Logger.getLogger(getClass().getName()).log(Level.INFO, "remoteFileDownloadingStarted " + length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void remoteFileDownloadingComplete() {
|
||||||
|
Logger.getLogger(getClass().getName()).log(Level.INFO, "remoteFileDownloadingStarted");
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void bytesDownloaded(long bytes) {
|
public void bytesDownloaded(long bytes) {
|
||||||
super.bytesDownloaded(bytes);
|
|
||||||
downloadDownloaded += bytes;
|
downloadDownloaded += bytes;
|
||||||
|
|
||||||
if (controlfile_downloaded) {
|
|
||||||
final int percentage = (int) (((double) downloadDownloaded / (double) downloadSize) * 100);
|
|
||||||
SwingUtilities.invokeLater(() -> {
|
|
||||||
gui.syncFileProgress.setValue(percentage);
|
|
||||||
gui.syncFileProgress.setString(percentage + " % " + Humanize.binaryPrefix(downloadDownloaded) + "/" + currentDownload_sizeS);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public boolean isStopped() {
|
public boolean isStopped() {
|
||||||
return stopped;
|
return stopped;
|
||||||
|
33
src/main/java/de/mc8051/arma3launcher/repo/Updater.java
Normal file
33
src/main/java/de/mc8051/arma3launcher/repo/Updater.java
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
package de.mc8051.arma3launcher.repo;
|
||||||
|
|
||||||
|
import de.mc8051.arma3launcher.ArmA3Launcher;
|
||||||
|
import de.mc8051.arma3launcher.utils.Callback;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by gurkengewuerz.de on 29.03.2020.
|
||||||
|
*/
|
||||||
|
public class Updater {
|
||||||
|
|
||||||
|
private boolean canPatch = false;
|
||||||
|
|
||||||
|
public void update() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void getNewestVersion(Callback.HttpCallback callback) {
|
||||||
|
RepositoryManger.getInstance().getAsync(ArmA3Launcher.config.getString("sync.url") + "/.sync/version.txt", callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void needUpdate(Callback.NeedUpdateCallback callback) {
|
||||||
|
final Version currentVersion = new Version(ArmA3Launcher.VERSION);
|
||||||
|
getNewestVersion(new Callback.HttpCallback() {
|
||||||
|
@Override
|
||||||
|
public void response(Response r) {
|
||||||
|
if (!r.isSuccessful()) callback.response(false, null);
|
||||||
|
final String[] split = r.getBody().split(":");
|
||||||
|
final Version newestVersion = new Version(r.getBody().split(":")[0]);
|
||||||
|
callback.response((currentVersion.compareTo(newestVersion) < 0), newestVersion);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
50
src/main/java/de/mc8051/arma3launcher/repo/Version.java
Normal file
50
src/main/java/de/mc8051/arma3launcher/repo/Version.java
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
package de.mc8051.arma3launcher.repo;
|
||||||
|
|
||||||
|
public class Version implements Comparable<Version> {
|
||||||
|
|
||||||
|
private String version;
|
||||||
|
|
||||||
|
public final String get() {
|
||||||
|
return this.version;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Version(String version) {
|
||||||
|
if (version == null)
|
||||||
|
throw new IllegalArgumentException("Version can not be null");
|
||||||
|
if (!version.matches("[0-9]+(\\.[0-9]+)*"))
|
||||||
|
throw new IllegalArgumentException("Invalid version format");
|
||||||
|
this.version = version;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(Version that) {
|
||||||
|
if (that == null)
|
||||||
|
return 1;
|
||||||
|
String[] thisParts = this.get().split("\\.");
|
||||||
|
String[] thatParts = that.get().split("\\.");
|
||||||
|
int length = Math.max(thisParts.length, thatParts.length);
|
||||||
|
for (int i = 0; i < length; i++) {
|
||||||
|
int thisPart = i < thisParts.length ?
|
||||||
|
Integer.parseInt(thisParts[i]) : 0;
|
||||||
|
int thatPart = i < thatParts.length ?
|
||||||
|
Integer.parseInt(thatParts[i]) : 0;
|
||||||
|
if (thisPart < thatPart)
|
||||||
|
return -1;
|
||||||
|
if (thisPart > thatPart)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object that) {
|
||||||
|
if (this == that)
|
||||||
|
return true;
|
||||||
|
if (that == null)
|
||||||
|
return false;
|
||||||
|
if (this.getClass() != that.getClass())
|
||||||
|
return false;
|
||||||
|
return this.compareTo((Version) that) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,6 +1,7 @@
|
|||||||
package de.mc8051.arma3launcher.utils;
|
package de.mc8051.arma3launcher.utils;
|
||||||
|
|
||||||
import de.mc8051.arma3launcher.repo.Response;
|
import de.mc8051.arma3launcher.repo.Response;
|
||||||
|
import de.mc8051.arma3launcher.repo.Version;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
||||||
@ -20,4 +21,9 @@ public class Callback {
|
|||||||
public interface ChangelogCallback {
|
public interface ChangelogCallback {
|
||||||
void response(String changelog);
|
void response(String changelog);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public interface NeedUpdateCallback {
|
||||||
|
void response(boolean needUpdate, Version newestVersion);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -100,6 +100,8 @@ about=
|
|||||||
follow_on_twitter=Folgt und auf Twitter
|
follow_on_twitter=Folgt und auf Twitter
|
||||||
star_on_github="Star us" auf GitHub
|
star_on_github="Star us" auf GitHub
|
||||||
client_up_to_date=Client ist aktuell
|
client_up_to_date=Client ist aktuell
|
||||||
|
client_outdated=Neue Client Version verfügbar
|
||||||
|
please_update=Bitte führe ein Update durch
|
||||||
developer_page=Entwickler-Seite
|
developer_page=Entwickler-Seite
|
||||||
project_page=Projektseite
|
project_page=Projektseite
|
||||||
fast_check=Schnelle Prüfung
|
fast_check=Schnelle Prüfung
|
||||||
|
@ -98,6 +98,8 @@ about=About
|
|||||||
follow_on_twitter=Follow us on Twitter
|
follow_on_twitter=Follow us on Twitter
|
||||||
star_on_github=Star us on GitHub
|
star_on_github=Star us on GitHub
|
||||||
client_up_to_date=Client is up to date
|
client_up_to_date=Client is up to date
|
||||||
|
client_outdated=New client version available
|
||||||
|
please_update=Please do an update
|
||||||
developer_page=Developer page
|
developer_page=Developer page
|
||||||
project_page=Project page
|
project_page=Project page
|
||||||
new_modset_name=Modsset name
|
new_modset_name=Modsset name
|
||||||
|
Loading…
Reference in New Issue
Block a user