wörk wörk (day 4)
* added checkbox JList for preset mod list * added multiselect of JList without pressing CTRL * added compareable for Mod object * added user modsets * added functions to add/save/remove/clone Modset to user config * added fast check (only detect byte size changes) * added load user modsets * added "focusing" correct button corresponding to the tab * added JComboBox to select a preset in updater * changed button alignment * fixed synclist for single ModFile #coronatime
This commit is contained in:
parent
5eeffde3c3
commit
112bc228d4
5
pom.xml
5
pom.xml
@ -46,6 +46,11 @@
|
||||
<artifactId>zsyncer</artifactId>
|
||||
<version>1de0d3f651</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.jgoodies</groupId>
|
||||
<artifactId>jgoodies-forms</artifactId>
|
||||
<version>1.9.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
@ -42,10 +42,14 @@
|
||||
<properties>
|
||||
<alignmentY value="0.0"/>
|
||||
<borderPainted value="true"/>
|
||||
<focusCycleRoot value="false"/>
|
||||
<focusPainted value="false"/>
|
||||
<focusable value="true"/>
|
||||
<focusable value="false"/>
|
||||
<font size="16"/>
|
||||
<horizontalAlignment value="2"/>
|
||||
<icon value="icons/settings_16.png"/>
|
||||
<iconTextGap value="10"/>
|
||||
<inheritsPopupMenu value="true"/>
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<text resource-bundle="lang" key="settings"/>
|
||||
</properties>
|
||||
@ -64,8 +68,11 @@
|
||||
</constraints>
|
||||
<properties>
|
||||
<focusPainted value="false"/>
|
||||
<focusable value="false"/>
|
||||
<font size="16"/>
|
||||
<horizontalAlignment value="2"/>
|
||||
<icon value="icons/download_16.png"/>
|
||||
<iconTextGap value="10"/>
|
||||
<text resource-bundle="lang" key="update"/>
|
||||
</properties>
|
||||
</component>
|
||||
@ -75,8 +82,11 @@
|
||||
</constraints>
|
||||
<properties>
|
||||
<focusPainted value="false"/>
|
||||
<focusable value="false"/>
|
||||
<font size="16"/>
|
||||
<horizontalAlignment value="2"/>
|
||||
<icon value="icons/play_16.png"/>
|
||||
<iconTextGap value="10"/>
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<text resource-bundle="lang" key="play"/>
|
||||
</properties>
|
||||
@ -168,8 +178,11 @@
|
||||
</constraints>
|
||||
<properties>
|
||||
<focusPainted value="false"/>
|
||||
<focusable value="false"/>
|
||||
<font size="16"/>
|
||||
<horizontalAlignment value="2"/>
|
||||
<icon value="icons/preset_16.png"/>
|
||||
<iconTextGap value="10"/>
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<text resource-bundle="lang" key="presets"/>
|
||||
</properties>
|
||||
@ -180,8 +193,11 @@
|
||||
</constraints>
|
||||
<properties>
|
||||
<focusPainted value="false"/>
|
||||
<focusable value="false"/>
|
||||
<font size="16"/>
|
||||
<horizontalAlignment value="2"/>
|
||||
<icon value="icons/changelog_16.png"/>
|
||||
<iconTextGap value="10"/>
|
||||
<text resource-bundle="lang" key="changelog"/>
|
||||
</properties>
|
||||
</component>
|
||||
@ -445,20 +461,24 @@
|
||||
<text resource-bundle="lang" key="abort"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="d7e4b" class="javax.swing.JButton" binding="syncCheckButton">
|
||||
<component id="d7e4b" class="javax.swing.JButton" binding="syncIntensiveCheckButton">
|
||||
<constraints>
|
||||
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<enabled value="false"/>
|
||||
<text resource-bundle="lang" key="check"/>
|
||||
<text resource-bundle="lang" key="intensive_check"/>
|
||||
</properties>
|
||||
</component>
|
||||
<hspacer id="a2208">
|
||||
<component id="df55f" class="javax.swing.JButton" binding="syncFastCheckButton">
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
</hspacer>
|
||||
<properties>
|
||||
<enabled value="false"/>
|
||||
<text resource-bundle="lang" key="fast_check"/>
|
||||
</properties>
|
||||
</component>
|
||||
</children>
|
||||
</grid>
|
||||
<component id="c97ef" class="javax.swing.JLabel">
|
||||
@ -561,23 +581,25 @@
|
||||
</component>
|
||||
</children>
|
||||
</grid>
|
||||
<grid id="b8ac" layout-manager="GridLayoutManager" row-count="4" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<grid id="b8ac" layout-manager="FormLayout">
|
||||
<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"/>
|
||||
<colspec value="left:4dlu:noGrow"/>
|
||||
<colspec value="fill:d:grow"/>
|
||||
<constraints border-constraint="Center"/>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<component id="e74aa" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text resource-bundle="lang" key="total_file_size"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="f5997" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
<grid row="4" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
<forms/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text resource-bundle="lang" key="speed"/>
|
||||
@ -585,31 +607,17 @@
|
||||
</component>
|
||||
<component id="25551" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
<grid row="6" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
<forms/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text resource-bundle="lang" key="remaining_time"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="b28b6" class="javax.swing.JLabel" binding="syncSizeLabel">
|
||||
<component id="9148" class="javax.swing.JLabel" binding="syncFileCountLabel">
|
||||
<constraints>
|
||||
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="0.0 B"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="617c7" class="javax.swing.JLabel" binding="syncDownloadSpeedLabel">
|
||||
<constraints>
|
||||
<grid row="2" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value=""/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="b64ac" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="3" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
<grid row="2" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
<forms/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value=""/>
|
||||
@ -617,15 +625,44 @@
|
||||
</component>
|
||||
<component id="28be3" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
<forms/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text resource-bundle="lang" key="file_count"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="9148" class="javax.swing.JLabel" binding="syncFileCountLabel">
|
||||
<component id="e74aa" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
<forms/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text resource-bundle="lang" key="total_file_size"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="b28b6" class="javax.swing.JLabel" binding="syncSizeLabel">
|
||||
<constraints>
|
||||
<grid row="0" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
<forms/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="0.0 B/0.0 B"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="617c7" class="javax.swing.JLabel" binding="syncDownloadSpeedLabel">
|
||||
<constraints>
|
||||
<grid row="4" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
<forms/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value=""/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="63dca" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="6" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
<forms/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value=""/>
|
||||
@ -793,7 +830,7 @@
|
||||
<text resource-bundle="lang" key="expand_all"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="43543" class="javax.swing.JComboBox" binding="comboBox1" default-binding="true">
|
||||
<component id="43543" class="javax.swing.JComboBox" binding="syncPresetCombo">
|
||||
<constraints>
|
||||
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
@ -945,10 +982,78 @@
|
||||
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="7" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<verticalScrollBarPolicy value="22"/>
|
||||
<horizontalScrollBarPolicy value="31"/>
|
||||
<verticalScrollBarPolicy value="20"/>
|
||||
</properties>
|
||||
<border type="empty"/>
|
||||
<children>
|
||||
<grid id="87071" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="100" left="70" bottom="100" right="70"/>
|
||||
<constraints/>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<grid id="1679e" binding="presetNotePane" layout-manager="FormLayout">
|
||||
<rowspec value="center:d: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>
|
||||
<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"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<visible value="false"/>
|
||||
</properties>
|
||||
<border type="none"/>
|
||||
<children/>
|
||||
<children>
|
||||
<component id="7b832" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
<forms/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<font size="14" style="1"/>
|
||||
<text resource-bundle="lang" key="note"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="d466d" class="javax.swing.JButton" binding="presetNoteButton">
|
||||
<constraints>
|
||||
<grid row="4" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||
<forms/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text resource-bundle="lang" key="clone_preset"/>
|
||||
</properties>
|
||||
</component>
|
||||
<grid id="8f1ff" binding="presetNotePaneWrapper" 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="2" 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>
|
||||
<component id="862fc" class="javax.swing.JTextPane" binding="presetNoteTextPane">
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="6" anchor="0" fill="3" indent="0" use-parent-layout="false">
|
||||
<preferred-size width="200" height="50"/>
|
||||
</grid>
|
||||
</constraints>
|
||||
<properties>
|
||||
<enabled value="true"/>
|
||||
<text resource-bundle="lang" key="presets_note"/>
|
||||
</properties>
|
||||
</component>
|
||||
</children>
|
||||
</grid>
|
||||
</children>
|
||||
</grid>
|
||||
</children>
|
||||
</grid>
|
||||
</children>
|
||||
</scrollpane>
|
||||
<component id="3960a" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
@ -1033,7 +1138,9 @@
|
||||
<preferred-size width="150" height="50"/>
|
||||
</grid>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<properties>
|
||||
<selectionMode value="1"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="4fbf3" class="javax.swing.JList" binding="modList">
|
||||
<constraints>
|
||||
|
@ -3,10 +3,12 @@ package de.mc8051.arma3launcher;
|
||||
import de.mc8051.arma3launcher.interfaces.Observer;
|
||||
import de.mc8051.arma3launcher.model.JCheckBoxTree;
|
||||
import de.mc8051.arma3launcher.model.ModListRenderer;
|
||||
import de.mc8051.arma3launcher.model.MultiSelectModel;
|
||||
import de.mc8051.arma3launcher.model.PresetListRenderer;
|
||||
import de.mc8051.arma3launcher.model.PresetTableModel;
|
||||
import de.mc8051.arma3launcher.model.RepositoryTreeNode;
|
||||
import de.mc8051.arma3launcher.model.ServerTableModel;
|
||||
import de.mc8051.arma3launcher.model.TabbedPaneUI;
|
||||
import de.mc8051.arma3launcher.objects.AbstractMod;
|
||||
import de.mc8051.arma3launcher.objects.Changelog;
|
||||
import de.mc8051.arma3launcher.objects.Mod;
|
||||
@ -24,10 +26,12 @@ import de.mc8051.arma3launcher.utils.Humanize;
|
||||
import de.mc8051.arma3launcher.utils.ImageUtils;
|
||||
import de.mc8051.arma3launcher.utils.LangUtils;
|
||||
import de.mc8051.arma3launcher.utils.TaskBarUtils;
|
||||
import org.json.JSONArray;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
import javax.swing.plaf.basic.BasicTabbedPaneUI;
|
||||
import javax.swing.event.ListSelectionEvent;
|
||||
import javax.swing.event.ListSelectionListener;
|
||||
import javax.swing.text.DefaultFormatter;
|
||||
import javax.swing.tree.DefaultMutableTreeNode;
|
||||
import javax.swing.tree.DefaultTreeModel;
|
||||
@ -37,12 +41,12 @@ import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.ItemEvent;
|
||||
import java.awt.event.ItemListener;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.StringWriter;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.net.URL;
|
||||
@ -51,11 +55,12 @@ import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.Properties;
|
||||
import java.util.List;
|
||||
import java.util.Scanner;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
@ -125,13 +130,13 @@ public class LauncherGUI implements Observer {
|
||||
private JButton expandAllButton;
|
||||
private JProgressBar syncCheckProgress;
|
||||
private JButton syncCheckAbortButton;
|
||||
private JButton syncCheckButton;
|
||||
private JButton syncIntensiveCheckButton;
|
||||
public JProgressBar syncDownloadProgress;
|
||||
public JProgressBar syncFileProgress;
|
||||
private JButton syncDownloadButton;
|
||||
private JButton syncDownloadAbortButton;
|
||||
private JButton syncPauseButton;
|
||||
private JComboBox comboBox1;
|
||||
private JComboBox syncPresetCombo;
|
||||
private JButton refreshRepoButton;
|
||||
private JPanel updateTreePanel;
|
||||
private JScrollPane updateTreeScrolPane;
|
||||
@ -161,6 +166,11 @@ public class LauncherGUI implements Observer {
|
||||
private JLabel aboutProjectLabel;
|
||||
private JLabel aboutDeveloperLabel;
|
||||
private JLabel aboutCopyrightLabel;
|
||||
private JButton syncFastCheckButton;
|
||||
private JButton presetNoteButton;
|
||||
private JTextPane presetNoteTextPane;
|
||||
private JPanel presetNotePaneWrapper;
|
||||
private JPanel presetNotePane;
|
||||
|
||||
private JCheckBoxTree repoTree;
|
||||
private FileChecker fileChecker;
|
||||
@ -186,7 +196,9 @@ public class LauncherGUI implements Observer {
|
||||
RepositoryManger.getInstance().refreshModset();
|
||||
}).start();
|
||||
|
||||
updateTreePanel.remove(tree1);
|
||||
switchTab(Tab.PLAY);
|
||||
|
||||
updateTreePanel.removeAll();
|
||||
|
||||
repoTree = new JCheckBoxTree();
|
||||
updateTreePanel.add(repoTree, BorderLayout.CENTER);
|
||||
@ -197,25 +209,9 @@ public class LauncherGUI implements Observer {
|
||||
updateTreePanel.revalidate();
|
||||
updateTreePanel.repaint();
|
||||
|
||||
tabbedPane1.setUI(new BasicTabbedPaneUI() {
|
||||
private final Insets borderInsets = new Insets(0, 0, 0, 0);
|
||||
tabbedPane1.setUI(new TabbedPaneUI());
|
||||
|
||||
@Override
|
||||
protected void paintContentBorder(Graphics g, int tabPlacement, int selectedIndex) {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Insets getContentBorderInsets(int tabPlacement) {
|
||||
return borderInsets;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int calculateTabAreaHeight(int tab_placement, int run_count, int max_tab_height) {
|
||||
return -5;
|
||||
}
|
||||
});
|
||||
|
||||
Insets x = new Insets(5, 5, 5, 5);
|
||||
Insets x = new Insets(5, 15, 5, 0);
|
||||
settingsPanelButton.setMargin(x);
|
||||
updatePanelButton.setMargin(x);
|
||||
playPanelButton.setMargin(x);
|
||||
@ -228,7 +224,9 @@ public class LauncherGUI implements Observer {
|
||||
presetList.setModel(new PresetTableModel());
|
||||
|
||||
presetList.setCellRenderer(new PresetListRenderer());
|
||||
modList.setCellRenderer(new ModListRenderer());
|
||||
modList.setCellRenderer(new ModListRenderer<String>());
|
||||
|
||||
modList.setSelectionModel(new MultiSelectModel());
|
||||
|
||||
subtitle.setText(
|
||||
ArmA3Launcher.config.getString("subtitle")
|
||||
@ -248,20 +246,26 @@ public class LauncherGUI implements Observer {
|
||||
aboutClient.setText(ArmA3Launcher.config.getString("name") + " v" + ArmA3Launcher.VERSION);
|
||||
|
||||
aboutDeveloperLabel.setText("<html><a href=''>https://gurkengewuerz.de</a></html>");
|
||||
aboutProjectLabel.setText("<html><a href=''>"+ArmA3Launcher.config.getString("social.github")+"</a></html>");
|
||||
aboutProjectLabel.setText("<html><a href=''>" + ArmA3Launcher.config.getString("social.github") + "</a></html>");
|
||||
|
||||
InputStream resourceAsStream = getClass().getClassLoader().getResourceAsStream("disclaimer.html");
|
||||
if(resourceAsStream != null) {
|
||||
if (resourceAsStream != null) {
|
||||
Scanner s = new Scanner(resourceAsStream).useDelimiter("\\A");
|
||||
String result = s.hasNext() ? s.next() : "";
|
||||
disclaimer.setText(result);
|
||||
}
|
||||
|
||||
presetNoteTextPane.setHighlighter(null);
|
||||
presetNoteTextPane.getCaret().setVisible(false);
|
||||
presetNoteTextPane.setBackground(presetNotePaneWrapper.getBackground());
|
||||
presetNoteTextPane.setCaretColor(presetNoteTextPane.getBackground());
|
||||
|
||||
presetNoteTextPane.setPreferredSize(new Dimension(-1, -1));
|
||||
|
||||
aboutCopyrightLabel.setText(aboutCopyrightLabel.getText().replace("{year}", "" + Calendar.getInstance().get(Calendar.YEAR)));
|
||||
|
||||
twitterIcon.setBorder(new EmptyBorder(2,2,2,2));
|
||||
githubIcon.setBorder(new EmptyBorder(2,2,2,2));
|
||||
twitterIcon.setBorder(new EmptyBorder(2, 2, 2, 2));
|
||||
githubIcon.setBorder(new EmptyBorder(2, 2, 2, 2));
|
||||
|
||||
settingScrollPane.getVerticalScrollBar().setUnitIncrement(16);
|
||||
updateTreeScrolPane.getVerticalScrollBar().setUnitIncrement(16);
|
||||
@ -270,16 +274,17 @@ public class LauncherGUI implements Observer {
|
||||
presetList.addListSelectionListener(e -> {
|
||||
if (!e.getValueIsAdjusting()) {
|
||||
PresetTableModel m = (PresetTableModel) presetList.getModel();
|
||||
Modset modset = (Modset) m.getElementAt(presetList.getSelectedIndex());
|
||||
Object elementAt = m.getElementAt(presetList.getSelectedIndex());
|
||||
Modset modset = (Modset) elementAt;
|
||||
|
||||
if (modset.getType() == Modset.Type.SERVER) {
|
||||
if (modset.getType() == Modset.Type.SERVER || modset.getType() == Modset.Type.PLACEHOLDER) {
|
||||
renamePresetButton.setEnabled(false);
|
||||
removePresetButtom.setEnabled(false);
|
||||
} else {
|
||||
renamePresetButton.setEnabled(true);
|
||||
removePresetButtom.setEnabled(true);
|
||||
}
|
||||
clonePresetButton.setEnabled(true);
|
||||
clonePresetButton.setEnabled(modset.getType() != Modset.Type.PLACEHOLDER);
|
||||
|
||||
updateModList(modset);
|
||||
}
|
||||
@ -300,14 +305,11 @@ public class LauncherGUI implements Observer {
|
||||
|
||||
|
||||
collapseAllButton.addActionListener(e -> repoTree.collapseAllNodes());
|
||||
playPanelButton.addActionListener(e -> tabbedPane1.setSelectedIndex(0));
|
||||
updatePanelButton.addActionListener(e -> tabbedPane1.setSelectedIndex(1));
|
||||
changelogButton.addActionListener(e -> {
|
||||
tabbedPane1.setSelectedIndex(2);
|
||||
Changelog.refresh();
|
||||
});
|
||||
presetPanelButton.addActionListener(e -> tabbedPane1.setSelectedIndex(3));
|
||||
settingsPanelButton.addActionListener(e -> tabbedPane1.setSelectedIndex(4));
|
||||
playPanelButton.addActionListener(e -> switchTab(Tab.PLAY));
|
||||
updatePanelButton.addActionListener(e -> switchTab(Tab.UPDATE));
|
||||
changelogButton.addActionListener(e -> switchTab(Tab.CHANGELOG));
|
||||
presetPanelButton.addActionListener(e -> switchTab(Tab.PRESET));
|
||||
settingsPanelButton.addActionListener(e -> switchTab(Tab.SETTING));
|
||||
|
||||
refreshRepoButton.addActionListener(e -> RepositoryManger.getInstance().refreshModset());
|
||||
expandAllButton.addActionListener(e -> repoTree.expandAllNodes());
|
||||
@ -315,24 +317,17 @@ public class LauncherGUI implements Observer {
|
||||
syncCheckAbortButton.addActionListener(e -> fileChecker.stop());
|
||||
|
||||
|
||||
syncCheckButton.addActionListener(e -> {
|
||||
syncCheckButton.setEnabled(false);
|
||||
syncCheckAbortButton.setEnabled(true);
|
||||
syncCheckStatusLabel.setText("Running!");
|
||||
new Thread(() -> fileChecker.check()).start();
|
||||
|
||||
refreshRepoButton.setEnabled(false);
|
||||
|
||||
repoTree.setCheckboxesEnabled(false);
|
||||
repoTree.setCheckboxesChecked(false);
|
||||
});
|
||||
syncIntensiveCheckButton.addActionListener(e -> fileCheck(false));
|
||||
syncFastCheckButton.addActionListener(e -> fileCheck(true));
|
||||
|
||||
syncDownloadButton.addActionListener(e -> {
|
||||
if (!fileChecker.isChecked()) return;
|
||||
if (lastSynclist == null) return;
|
||||
syncDownloadButton.setEnabled(false);
|
||||
syncDownloadAbortButton.setEnabled(true);
|
||||
syncPauseButton.setEnabled(true);
|
||||
syncCheckButton.setEnabled(false);
|
||||
syncIntensiveCheckButton.setEnabled(false);
|
||||
syncFastCheckButton.setEnabled(false);
|
||||
refreshRepoButton.setEnabled(false);
|
||||
new Thread(() -> syncer.sync(lastSynclist.clone())).start();
|
||||
});
|
||||
@ -350,7 +345,7 @@ public class LauncherGUI implements Observer {
|
||||
|
||||
@Override
|
||||
public void mouseExited(MouseEvent e) {
|
||||
twitterIcon.setBorder(new EmptyBorder(2,2,2,2));
|
||||
twitterIcon.setBorder(new EmptyBorder(2, 2, 2, 2));
|
||||
}
|
||||
});
|
||||
|
||||
@ -362,14 +357,14 @@ public class LauncherGUI implements Observer {
|
||||
|
||||
@Override
|
||||
public void mouseExited(MouseEvent e) {
|
||||
githubIcon.setBorder(new EmptyBorder(2,2,2,2));
|
||||
githubIcon.setBorder(new EmptyBorder(2, 2, 2, 2));
|
||||
}
|
||||
});
|
||||
|
||||
aboutLabel.addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
tabbedPane1.setSelectedIndex(5);
|
||||
switchTab(Tab.ABOUT);
|
||||
}
|
||||
});
|
||||
|
||||
@ -400,6 +395,125 @@ public class LauncherGUI implements Observer {
|
||||
openURL(ArmA3Launcher.config.getString("social.github"));
|
||||
}
|
||||
});
|
||||
|
||||
modList.addListSelectionListener(new ListSelectionListener() {
|
||||
@Override
|
||||
public void valueChanged(ListSelectionEvent e) {
|
||||
if (presetList.getSelectedIndex() == -1) return;
|
||||
JList<?> list = (JList<?>) e.getSource();
|
||||
ListModel<?> model = list.getModel();
|
||||
|
||||
ListSelectionModel listSelectionModel = list.getSelectionModel();
|
||||
|
||||
int minSelectionIndex = listSelectionModel.getMinSelectionIndex();
|
||||
int maxSelectionIndex = listSelectionModel.getMaxSelectionIndex();
|
||||
|
||||
List<String> selectedMods = new ArrayList<>();
|
||||
|
||||
for (int i = minSelectionIndex; i <= maxSelectionIndex; i++) {
|
||||
if (listSelectionModel.isSelectedIndex(i)) {
|
||||
selectedMods.add(String.valueOf(model.getElementAt(i)));
|
||||
}
|
||||
}
|
||||
|
||||
PresetTableModel model1 = (PresetTableModel) presetList.getModel();
|
||||
if (presetList.getSelectedIndex() == -1) return;
|
||||
Object elementAt = model1.getElementAt(presetList.getSelectedIndex());
|
||||
Modset selectedModset = (Modset) elementAt;
|
||||
if (selectedModset.getType() == Modset.Type.PLACEHOLDER) return;
|
||||
selectedModset.getMods().clear();
|
||||
selectedModset.setMods(selectedMods);
|
||||
updateModsetList();
|
||||
selectedModset.save();
|
||||
}
|
||||
});
|
||||
|
||||
newPresetButtom.addActionListener(e -> {
|
||||
String modname = JOptionPane.showInputDialog(null, "", LangUtils.getInstance().getString("new_modset_name"));
|
||||
if (modname.isEmpty()) return;
|
||||
if (Modset.MODSET_LIST.containsKey(modname)) {
|
||||
infoBox(LangUtils.getInstance().getString("modset_exists_msg"), LangUtils.getInstance().getString("modset_exists"));
|
||||
return;
|
||||
}
|
||||
|
||||
Modset ms = new Modset(modname, new JSONArray(), Modset.Type.CLIENT);
|
||||
updateModsetList();
|
||||
ms.save();
|
||||
});
|
||||
|
||||
presetNoteButton.addActionListener(e -> clonePresetButton.doClick());
|
||||
clonePresetButton.addActionListener(e -> {
|
||||
if (presetList.getSelectedIndex() == -1) return;
|
||||
String newName = JOptionPane.showInputDialog(null, "", LangUtils.getInstance().getString("new_modset_name"));
|
||||
if (newName.isEmpty()) return;
|
||||
if (Modset.MODSET_LIST.containsKey(newName)) {
|
||||
infoBox(LangUtils.getInstance().getString("modset_exists_msg"), LangUtils.getInstance().getString("modset_exists"));
|
||||
return;
|
||||
}
|
||||
|
||||
PresetTableModel model1 = (PresetTableModel) presetList.getModel();
|
||||
Modset selectedModset = ((Modset) model1.getElementAt(presetList.getSelectedIndex()));
|
||||
Modset newModset = selectedModset.clone(newName, Modset.Type.CLIENT);
|
||||
updateModsetList();
|
||||
newModset.save();
|
||||
});
|
||||
|
||||
removePresetButtom.addActionListener(e -> {
|
||||
if (presetList.getSelectedIndex() == -1) return;
|
||||
modList.setModel(new DefaultListModel<>());
|
||||
PresetTableModel model1 = (PresetTableModel) presetList.getModel();
|
||||
((Modset) model1.getElementAt(presetList.getSelectedIndex())).removeFromConfig();
|
||||
updateModsetList();
|
||||
});
|
||||
|
||||
renamePresetButton.addActionListener(e -> {
|
||||
if (presetList.getSelectedIndex() == -1) return;
|
||||
PresetTableModel model1 = (PresetTableModel) presetList.getModel();
|
||||
Modset selectedModset = ((Modset) model1.getElementAt(presetList.getSelectedIndex()));
|
||||
|
||||
Object newNameO = JOptionPane.showInputDialog(null, "",
|
||||
LangUtils.getInstance().getString("new_modset_name"), JOptionPane.QUESTION_MESSAGE, null, null, selectedModset.getName());
|
||||
if(newNameO == null) return;
|
||||
String newName = (String) newNameO;
|
||||
if (newName.isEmpty()) return;
|
||||
if (Modset.MODSET_LIST.containsKey(newName)) {
|
||||
infoBox(LangUtils.getInstance().getString("modset_exists_msg"), LangUtils.getInstance().getString("modset_exists"));
|
||||
return;
|
||||
}
|
||||
|
||||
Modset newModset = selectedModset.clone(newName, Modset.Type.CLIENT);
|
||||
updateModsetList();
|
||||
selectedModset.removeFromConfig();
|
||||
newModset.save();
|
||||
});
|
||||
|
||||
syncPresetCombo.addItemListener(new ItemListener() {
|
||||
@Override
|
||||
public void itemStateChanged(ItemEvent e) {
|
||||
if (e.getStateChange() == ItemEvent.SELECTED) {
|
||||
DefaultComboBoxModel<Modset> model = (DefaultComboBoxModel<Modset>) syncPresetCombo.getModel();
|
||||
Modset elementAt = model.getElementAt(((JComboBox) e.getItemSelectable()).getSelectedIndex());
|
||||
repoTree.setCheckboxesChecked(false);
|
||||
if(elementAt.getType() == Modset.Type.PLACEHOLDER) return;
|
||||
|
||||
List<String> collect = elementAt.getMods().stream().map(Mod::getName).collect(Collectors.toList());
|
||||
|
||||
DefaultTreeModel repoModel = (DefaultTreeModel) repoTree.getModel();
|
||||
RepositoryTreeNode root = (RepositoryTreeNode) repoModel.getRoot();
|
||||
|
||||
for (int i = 0; i < root.getChildCount(); i++) {
|
||||
TreeNode childAt = root.getChildAt(i);
|
||||
if(!collect.contains(childAt.toString())) continue;
|
||||
final TreePath treePath = new TreePath(new TreeNode[]{root, childAt});
|
||||
repoTree.checkSubTree(treePath, true);
|
||||
repoTree.updatePredecessorsWithCheckMode(treePath, true);
|
||||
}
|
||||
repoTree.revalidate();
|
||||
repoTree.repaint();
|
||||
updateDownloadLabel();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void infoBox(String infoMessage, String titleBar) {
|
||||
@ -438,13 +552,15 @@ public class LauncherGUI implements Observer {
|
||||
if (SteamTimer.arma_running) {
|
||||
playButton.setEnabled(false);
|
||||
playPresetButton.setEnabled(false);
|
||||
syncCheckButton.setEnabled(false);
|
||||
syncIntensiveCheckButton.setEnabled(false);
|
||||
syncFastCheckButton.setEnabled(false);
|
||||
refreshRepoButton.setEnabled(false);
|
||||
syncDownloadButton.setEnabled(false);
|
||||
|
||||
playButton.setToolTipText(LangUtils.getInstance().getString("arma_running"));
|
||||
playPresetButton.setToolTipText(LangUtils.getInstance().getString("arma_running"));
|
||||
syncCheckButton.setToolTipText(LangUtils.getInstance().getString("arma_running"));
|
||||
syncIntensiveCheckButton.setToolTipText(LangUtils.getInstance().getString("arma_running"));
|
||||
syncFastCheckButton.setToolTipText(LangUtils.getInstance().getString("arma_running"));
|
||||
} else {
|
||||
if (SteamTimer.steam_running) {
|
||||
if (pathSet) {
|
||||
@ -469,20 +585,23 @@ public class LauncherGUI implements Observer {
|
||||
}
|
||||
|
||||
if (pathSet) {
|
||||
syncCheckButton.setEnabled(true);
|
||||
syncIntensiveCheckButton.setEnabled(true);
|
||||
syncFastCheckButton.setEnabled(true);
|
||||
refreshRepoButton.setEnabled(true);
|
||||
|
||||
syncDownloadButton.setEnabled(fileChecker.isChecked());
|
||||
|
||||
syncCheckButton.setToolTipText(null);
|
||||
syncIntensiveCheckButton.setToolTipText(null);
|
||||
refreshRepoButton.setToolTipText(null);
|
||||
} else {
|
||||
syncCheckButton.setEnabled(false);
|
||||
syncIntensiveCheckButton.setEnabled(false);
|
||||
syncFastCheckButton.setEnabled(false);
|
||||
refreshRepoButton.setEnabled(false);
|
||||
|
||||
syncDownloadButton.setEnabled(false);
|
||||
|
||||
syncCheckButton.setToolTipText(LangUtils.getInstance().getString("path_not_set"));
|
||||
syncIntensiveCheckButton.setToolTipText(LangUtils.getInstance().getString("path_not_set"));
|
||||
syncFastCheckButton.setToolTipText(LangUtils.getInstance().getString("path_not_set"));
|
||||
refreshRepoButton.setToolTipText(LangUtils.getInstance().getString("path_not_set"));
|
||||
}
|
||||
}
|
||||
@ -664,7 +783,7 @@ public class LauncherGUI implements Observer {
|
||||
if (!isSelected) continue;
|
||||
|
||||
ArrayList<String> treePathList = new ArrayList<>();
|
||||
for (int i = 2; i < path.length; i++) {
|
||||
for (int i = (path.length > 2 ? 2 : 1); i < path.length; i++) {
|
||||
treePathList.add(String.valueOf(((DefaultMutableTreeNode) path[i]).getUserObject()));
|
||||
}
|
||||
String treePath = String.join("/", treePathList);
|
||||
@ -693,14 +812,33 @@ public class LauncherGUI implements Observer {
|
||||
return synclist;
|
||||
}
|
||||
|
||||
public void updateModList(Modset modset) {
|
||||
ListModel<String> model = (ListModel) modList.getModel();
|
||||
// TODO: Show All Mods (keyname)
|
||||
// Show not installed Mods with red font
|
||||
// Select Mod if in modset.Mods
|
||||
// Custom Checkbox Render
|
||||
// Wenn modset.type == Server alle Checkboxen deaktivieren!
|
||||
// Show hint that server modsets cant be edited
|
||||
public void updateModList(final Modset modset) {
|
||||
if (modset == null) return;
|
||||
DefaultListModel<String> listModel = new DefaultListModel<>();
|
||||
|
||||
if (modset.getType() == Modset.Type.PLACEHOLDER) return;
|
||||
int[] select = new int[modset.getMods().size()];
|
||||
|
||||
AtomicInteger selectCounter = new AtomicInteger(0);
|
||||
RepositoryManger.MOD_LIST.stream()
|
||||
.filter((am) -> am instanceof Mod)
|
||||
.sorted()
|
||||
.forEach((abstractMod) -> {
|
||||
final int i = listModel.getSize();
|
||||
listModel.add(i, abstractMod.getName());
|
||||
for (Mod mod : modset.getMods()) {
|
||||
if (mod.getName().equals(abstractMod.getName())) {
|
||||
select[selectCounter.getAndIncrement()] = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
modList.setModel(listModel);
|
||||
modList.setSelectedIndices(select);
|
||||
modList.setEnabled(modset.getType() != Modset.Type.SERVER);
|
||||
presetNotePane.setVisible(modset.getType() == Modset.Type.SERVER);
|
||||
modList.revalidate();
|
||||
}
|
||||
|
||||
public void updateRepoTree() {
|
||||
@ -769,6 +907,17 @@ public class LauncherGUI implements Observer {
|
||||
repoTree.addCheckChangeEventListener(new JCheckBoxTree.CheckChangeEventListener() {
|
||||
@Override
|
||||
public void checkStateChanged(JCheckBoxTree.CheckChangeEvent event) {
|
||||
syncPresetCombo.setSelectedIndex(0);
|
||||
|
||||
updateDownloadLabel();
|
||||
}
|
||||
});
|
||||
|
||||
expandAllButton.setEnabled(true);
|
||||
collapseAllButton.setEnabled(true);
|
||||
}
|
||||
|
||||
public void updateDownloadLabel() {
|
||||
lastSynclist = getSyncList();
|
||||
if (lastSynclist.getSize() != 0)
|
||||
syncSizeLabel.setText("0.0 B/" + Humanize.binaryPrefix(lastSynclist.getSize()));
|
||||
@ -781,11 +930,6 @@ public class LauncherGUI implements Observer {
|
||||
syncFileCountLabel.setText("");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
expandAllButton.setEnabled(true);
|
||||
collapseAllButton.setEnabled(true);
|
||||
}
|
||||
|
||||
public Color getNodeColor(String mod, ModFile mf) {
|
||||
if (fileChecker.getAdded().containsKey(mod)) {
|
||||
@ -863,7 +1007,7 @@ public class LauncherGUI implements Observer {
|
||||
|
||||
@Override
|
||||
public void update(String s) {
|
||||
System.out.println(s);
|
||||
Logger.getLogger(getClass().getName()).log(Level.INFO, "Observer received: " + s);
|
||||
if (s.equals(RepositoryManger.Type.METADATA.toString())) {
|
||||
switch (RepositoryManger.getInstance().getStatus(RepositoryManger.Type.METADATA)) {
|
||||
case ERROR:
|
||||
@ -878,16 +1022,7 @@ public class LauncherGUI implements Observer {
|
||||
Server.SERVER_LIST.forEach((name, server) -> model.add(server));
|
||||
});
|
||||
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
PresetTableModel model = (PresetTableModel) presetList.getModel();
|
||||
model.clear();
|
||||
|
||||
model.add(new Modset("--Server", Modset.Type.CLIENT, null, false));
|
||||
|
||||
Modset.MODSET_LIST.forEach((name, set) -> {
|
||||
model.add(set);
|
||||
});
|
||||
});
|
||||
updateModsetList();
|
||||
break;
|
||||
}
|
||||
} else if (s.equals("steamtimer")) {
|
||||
@ -918,7 +1053,8 @@ public class LauncherGUI implements Observer {
|
||||
});
|
||||
}
|
||||
} else if (s.equals("fileChecker")) {
|
||||
syncCheckButton.setEnabled(true);
|
||||
syncIntensiveCheckButton.setEnabled(true);
|
||||
syncFastCheckButton.setEnabled(true);
|
||||
syncCheckAbortButton.setEnabled(false);
|
||||
syncCheckStatusLabel.setText("Finished!");
|
||||
updateRepoTree();
|
||||
@ -933,9 +1069,14 @@ public class LauncherGUI implements Observer {
|
||||
syncDownloadButton.setEnabled(true);
|
||||
syncPauseButton.setEnabled(false);
|
||||
|
||||
refreshRepoButton.setEnabled(true);
|
||||
|
||||
syncChangedFileSizeLabel.setText(Humanize.binaryPrefix(fileChecker.getSize()));
|
||||
|
||||
lastSynclist = null;
|
||||
} else if (s.equals("fileCheckerStopped")) {
|
||||
syncCheckButton.setEnabled(true);
|
||||
syncIntensiveCheckButton.setEnabled(true);
|
||||
syncFastCheckButton.setEnabled(true);
|
||||
syncCheckAbortButton.setEnabled(false);
|
||||
syncCheckProgress.setValue(0);
|
||||
syncCheckStatusLabel.setText("Failed!");
|
||||
@ -954,8 +1095,9 @@ public class LauncherGUI implements Observer {
|
||||
|
||||
syncChangedFileSizeLabel.setText("0.0 B");
|
||||
|
||||
lastSynclist = null;
|
||||
} else if (s.equals("syncStopped")) {
|
||||
new Thread(() -> fileChecker.check()).start();
|
||||
new Thread(() -> fileChecker.check(true)).start();
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
syncDownloadButton.setEnabled(false);
|
||||
syncDownloadAbortButton.setEnabled(false);
|
||||
@ -967,7 +1109,7 @@ public class LauncherGUI implements Observer {
|
||||
TaskBarUtils.getInstance().off();
|
||||
});
|
||||
} else if (s.equals("syncComplete")) {
|
||||
new Thread(() -> fileChecker.check()).start();
|
||||
new Thread(() -> fileChecker.check(true)).start();
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
syncDownloadButton.setEnabled(false);
|
||||
syncDownloadAbortButton.setEnabled(false);
|
||||
@ -1001,6 +1143,41 @@ public class LauncherGUI implements Observer {
|
||||
}
|
||||
}
|
||||
|
||||
private void updateModsetList() {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
if (((DefaultComboBoxModel<Modset>)syncPresetCombo.getModel()).getSize() > 0){
|
||||
syncPresetCombo.setSelectedIndex(0);
|
||||
}
|
||||
PresetTableModel model = (PresetTableModel) presetList.getModel();
|
||||
model.clear();
|
||||
|
||||
model.add(new Modset("--Server", Modset.Type.PLACEHOLDER, null, false));
|
||||
Modset.MODSET_LIST.values().stream().filter((ms) -> ms.getType() == Modset.Type.SERVER).sorted().forEach(model::add);
|
||||
|
||||
model.add(new Modset("--User", Modset.Type.PLACEHOLDER, null, false));
|
||||
Modset.MODSET_LIST.values().stream().filter((ms) -> ms.getType() == Modset.Type.CLIENT).sorted().forEach(model::add);
|
||||
|
||||
DefaultComboBoxModel<Modset> presetModel = new DefaultComboBoxModel<>();
|
||||
presetModel.addElement(new Modset("", Modset.Type.PLACEHOLDER, null, false));
|
||||
Modset.MODSET_LIST.values().stream().filter((ms) -> ms.getType() != Modset.Type.PLACEHOLDER).sorted().forEach(presetModel::addElement);
|
||||
|
||||
syncPresetCombo.setModel(presetModel);
|
||||
});
|
||||
}
|
||||
|
||||
public void fileCheck(boolean fastscan) {
|
||||
syncIntensiveCheckButton.setEnabled(false);
|
||||
syncFastCheckButton.setEnabled(false);
|
||||
syncCheckAbortButton.setEnabled(true);
|
||||
syncCheckStatusLabel.setText("Running!");
|
||||
new Thread(() -> fileChecker.check(fastscan)).start();
|
||||
|
||||
refreshRepoButton.setEnabled(false);
|
||||
|
||||
repoTree.setCheckboxesEnabled(false);
|
||||
repoTree.setCheckboxesChecked(false);
|
||||
}
|
||||
|
||||
public void exit() {
|
||||
fileChecker.stop();
|
||||
syncer.stop();
|
||||
@ -1012,4 +1189,59 @@ public class LauncherGUI implements Observer {
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
public void switchTab(Tab tab) {
|
||||
Color focusBackgroundColor = UIManager.getColor("Button.default.focusColor");
|
||||
Color backgroundColor = UIManager.getColor("Button.background");
|
||||
|
||||
playPanelButton.setBackground(backgroundColor);
|
||||
updatePanelButton.setBackground(backgroundColor);
|
||||
changelogButton.setBackground(backgroundColor);
|
||||
presetPanelButton.setBackground(backgroundColor);
|
||||
settingsPanelButton.setBackground(backgroundColor);
|
||||
|
||||
switch (tab) {
|
||||
case PLAY:
|
||||
playPanelButton.setBackground(focusBackgroundColor);
|
||||
break;
|
||||
|
||||
case UPDATE:
|
||||
updatePanelButton.setBackground(focusBackgroundColor);
|
||||
break;
|
||||
|
||||
case CHANGELOG:
|
||||
changelogButton.setBackground(focusBackgroundColor);
|
||||
Changelog.refresh();
|
||||
break;
|
||||
|
||||
case PRESET:
|
||||
presetPanelButton.setBackground(focusBackgroundColor);
|
||||
break;
|
||||
|
||||
case SETTING:
|
||||
settingsPanelButton.setBackground(focusBackgroundColor);
|
||||
break;
|
||||
}
|
||||
|
||||
tabbedPane1.setSelectedIndex(tab.getIndex());
|
||||
}
|
||||
|
||||
private enum Tab {
|
||||
PLAY(0),
|
||||
UPDATE(1),
|
||||
CHANGELOG(2),
|
||||
PRESET(3),
|
||||
SETTING(4),
|
||||
ABOUT(5);
|
||||
|
||||
private int index;
|
||||
|
||||
Tab(int index) {
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
public int getIndex() {
|
||||
return index;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -233,7 +233,7 @@ public class JCheckBoxTree extends JTree {
|
||||
}
|
||||
|
||||
// When a node is checked/unchecked, updating the states of the predecessors
|
||||
protected void updatePredecessorsWithCheckMode(TreePath tp, boolean check) {
|
||||
public void updatePredecessorsWithCheckMode(TreePath tp, boolean check) {
|
||||
TreePath parentPath = tp.getParentPath();
|
||||
// If it is the root, stop the recursive calls and return
|
||||
if (parentPath == null) {
|
||||
@ -266,7 +266,7 @@ public class JCheckBoxTree extends JTree {
|
||||
}
|
||||
|
||||
// Recursively checks/unchecks a subtree
|
||||
protected void checkSubTree(TreePath tp, boolean check) {
|
||||
public void checkSubTree(TreePath tp, boolean check) {
|
||||
CheckedNode cn = nodesCheckingState.get(tp);
|
||||
cn.isSelected = check;
|
||||
DefaultMutableTreeNode node = (DefaultMutableTreeNode) tp.getLastPathComponent();
|
||||
|
@ -4,22 +4,28 @@ import javax.swing.*;
|
||||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* Created by gurkengewuerz.de on 25.03.2020.
|
||||
* Created by gurkengewuerz.de on 28.03.2020.
|
||||
*/
|
||||
public class ModListRenderer extends JCheckBox implements ListCellRenderer {
|
||||
public class ModListRenderer<E> extends JCheckBox implements
|
||||
ListCellRenderer<E> {
|
||||
|
||||
public Component getListCellRendererComponent(JList list, Object value, int index,
|
||||
boolean isSelected, boolean cellHasFocus) {
|
||||
private static final long serialVersionUID = 3734536442230283966L;
|
||||
|
||||
@Override
|
||||
public Component getListCellRendererComponent(JList<? extends E> list,
|
||||
E value, int index, boolean isSelected, boolean cellHasFocus) {
|
||||
setComponentOrientation(list.getComponentOrientation());
|
||||
|
||||
setFont(list.getFont());
|
||||
setText(String.valueOf(value));
|
||||
|
||||
setBackground(list.getBackground());
|
||||
setForeground(list.getForeground());
|
||||
|
||||
setSelected(isSelected);
|
||||
setEnabled(list.isEnabled());
|
||||
|
||||
setText(value == null ? "" : value.toString());
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
package de.mc8051.arma3launcher.model;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
/**
|
||||
* Created by gurkengewuerz.de on 28.03.2020.
|
||||
*/
|
||||
public class MultiSelectModel extends DefaultListSelectionModel {
|
||||
|
||||
private int i0 = -1;
|
||||
private int i1 = -1;
|
||||
|
||||
public void setSelectionInterval(int index0, int index1) {
|
||||
if (i0 == index0 && i1 == index1) {
|
||||
if (getValueIsAdjusting()) {
|
||||
setValueIsAdjusting(false);
|
||||
setSelection(index0, index1);
|
||||
}
|
||||
} else {
|
||||
i0 = index0;
|
||||
i1 = index1;
|
||||
setValueIsAdjusting(false);
|
||||
setSelection(index0, index1);
|
||||
}
|
||||
}
|
||||
|
||||
private void setSelection(int index0, int index1) {
|
||||
if (super.isSelectedIndex(index0)) {
|
||||
super.removeSelectionInterval(index0, index1);
|
||||
} else {
|
||||
super.addSelectionInterval(index0, index1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package de.mc8051.arma3launcher.model;
|
||||
|
||||
import javax.swing.plaf.basic.BasicTabbedPaneUI;
|
||||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* Created by gurkengewuerz.de on 28.03.2020.
|
||||
*/
|
||||
public class TabbedPaneUI extends BasicTabbedPaneUI {
|
||||
|
||||
private final Insets borderInsets = new Insets(0, 0, 0, 0);
|
||||
|
||||
@Override
|
||||
protected void paintContentBorder(Graphics g, int tabPlacement, int selectedIndex) {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Insets getContentBorderInsets(int tabPlacement) {
|
||||
return borderInsets;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int calculateTabAreaHeight(int tab_placement, int run_count, int max_tab_height) {
|
||||
return -5;
|
||||
}
|
||||
}
|
@ -5,7 +5,7 @@ import java.util.ArrayList;
|
||||
/**
|
||||
* Created by gurkengewuerz.de on 25.03.2020.
|
||||
*/
|
||||
public class Mod implements AbstractMod {
|
||||
public class Mod implements AbstractMod, Comparable {
|
||||
|
||||
private String name;
|
||||
private long size;
|
||||
@ -37,4 +37,9 @@ public class Mod implements AbstractMod {
|
||||
public Mod clone() {
|
||||
return new Mod(name, size, new ArrayList<>(files));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(Object o) {
|
||||
return getName().compareToIgnoreCase(((Mod) o).getName());
|
||||
}
|
||||
}
|
||||
|
@ -1,16 +1,22 @@
|
||||
package de.mc8051.arma3launcher.objects;
|
||||
|
||||
import de.mc8051.arma3launcher.ArmA3Launcher;
|
||||
import org.ini4j.Ini;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Created by gurkengewuerz.de on 25.03.2020.
|
||||
*/
|
||||
public class Modset {
|
||||
public class Modset implements Comparable {
|
||||
|
||||
public static HashMap<String, Modset> MODSET_LIST = new HashMap<>();
|
||||
|
||||
@ -27,23 +33,69 @@ public class Modset {
|
||||
this.type = type;
|
||||
this.mods = mods;
|
||||
|
||||
if(add) MODSET_LIST.put(name, this);
|
||||
if (add) MODSET_LIST.put(name, this);
|
||||
}
|
||||
|
||||
public Modset(JSONObject o, Type type) {
|
||||
if(!o.has("name") || !o.has("mods")) return;
|
||||
name = o.getString("name");
|
||||
|
||||
JSONArray modlist = o.getJSONArray("mods");
|
||||
for(int j = 0; j < modlist.length(); j++){
|
||||
public Modset(String name, JSONArray modlist, Type type) {
|
||||
for (int j = 0; j < modlist.length(); j++) {
|
||||
mods.add(new Mod(modlist.getString(j)));
|
||||
}
|
||||
|
||||
this.type = type;
|
||||
this.name = name;
|
||||
|
||||
MODSET_LIST.put(name, this);
|
||||
}
|
||||
|
||||
public Modset(JSONObject o, Type type) {
|
||||
this(o.getString("name"), o.getJSONArray("mods"), type);
|
||||
}
|
||||
|
||||
public void save() {
|
||||
if (type != Type.CLIENT) return;
|
||||
|
||||
Ini.Section section = ArmA3Launcher.user_config.get("presets");
|
||||
if (section == null) {
|
||||
section = ArmA3Launcher.user_config.add("presets");
|
||||
}
|
||||
if (section != null) {
|
||||
|
||||
List<String> list = mods.stream()
|
||||
.map(Mod::getName)
|
||||
.collect(Collectors.toList());
|
||||
JSONArray ja = new JSONArray(list);
|
||||
if (section.containsKey(name))
|
||||
section.replace(name, ja.toString());
|
||||
else
|
||||
section.add(name, ja.toString());
|
||||
|
||||
try {
|
||||
ArmA3Launcher.user_config.store();
|
||||
} catch (IOException e) {
|
||||
Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void removeFromConfig() {
|
||||
MODSET_LIST.remove(name);
|
||||
if (type != Type.CLIENT) return;
|
||||
|
||||
Ini.Section section = ArmA3Launcher.user_config.get("presets");
|
||||
if (section != null) {
|
||||
if (section.containsKey(name)) {
|
||||
section.remove(name);
|
||||
|
||||
try {
|
||||
ArmA3Launcher.user_config.store();
|
||||
} catch (IOException e) {
|
||||
Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
@ -60,8 +112,31 @@ public class Modset {
|
||||
// TODO: Implement play with this Modset
|
||||
}
|
||||
|
||||
public Modset clone(String newName, Type newType) {
|
||||
return new Modset(newName, newType, new ArrayList<>(mods));
|
||||
}
|
||||
|
||||
public Modset clone() {
|
||||
return new Modset(name, type, mods, false);
|
||||
}
|
||||
|
||||
public void setMods(List<String> selectedMods) {
|
||||
mods.addAll(selectedMods.stream().map(Mod::new).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(Object o) {
|
||||
return getName().compareToIgnoreCase(((Modset) o).getName());
|
||||
}
|
||||
|
||||
public static enum Type {
|
||||
SERVER,
|
||||
CLIENT
|
||||
CLIENT,
|
||||
PLACEHOLDER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getName();
|
||||
}
|
||||
}
|
||||
|
@ -8,9 +8,7 @@ import de.mc8051.arma3launcher.objects.Mod;
|
||||
import de.mc8051.arma3launcher.objects.ModFile;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Array;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
@ -45,6 +43,10 @@ public class FileChecker implements Observable {
|
||||
}
|
||||
|
||||
public void check() {
|
||||
check(false);
|
||||
}
|
||||
|
||||
public void check(boolean fastscan) {
|
||||
deleted.clear();
|
||||
changed.clear();
|
||||
changedCount = 0;
|
||||
@ -59,16 +61,16 @@ public class FileChecker implements Observable {
|
||||
});
|
||||
|
||||
for (AbstractMod abstractMod : RepositoryManger.MOD_LIST) {
|
||||
if(stop) {
|
||||
if (stop) {
|
||||
stop = false;
|
||||
notifyObservers("fileCheckerStopped");
|
||||
return;
|
||||
}
|
||||
if(abstractMod instanceof Mod) {
|
||||
if (abstractMod instanceof Mod) {
|
||||
Mod m = (Mod) abstractMod;
|
||||
|
||||
for (ModFile mf : m.getFiles()) {
|
||||
checkFile(m.getName(), mf);
|
||||
checkFile(m.getName(), mf, fastscan);
|
||||
|
||||
i++;
|
||||
int finalI = i;
|
||||
@ -76,7 +78,7 @@ public class FileChecker implements Observable {
|
||||
pb.setValue(finalI);
|
||||
});
|
||||
|
||||
if(stop) {
|
||||
if (stop) {
|
||||
stop = false;
|
||||
notifyObservers("fileCheckerStopped");
|
||||
return;
|
||||
@ -84,7 +86,7 @@ public class FileChecker implements Observable {
|
||||
}
|
||||
} else if (abstractMod instanceof ModFile) {
|
||||
ModFile mf = (ModFile) abstractMod;
|
||||
checkFile(mf.getName(), mf);
|
||||
checkFile(mf.getName(), mf, fastscan);
|
||||
i++;
|
||||
int finalI1 = i;
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
@ -106,11 +108,11 @@ public class FileChecker implements Observable {
|
||||
stop = true;
|
||||
}
|
||||
|
||||
private void checkFile(String mod, ModFile mf) {
|
||||
private void checkFile(String mod, ModFile mf, boolean fastscan) {
|
||||
ArrayList<ModFile> temp = new ArrayList<>();
|
||||
|
||||
if(!mf.exists()) {
|
||||
if(added.containsKey(mod)) temp =added.get(mod);
|
||||
if (!mf.exists()) {
|
||||
if (added.containsKey(mod)) temp = added.get(mod);
|
||||
temp.add(mf);
|
||||
added.put(mod, temp);
|
||||
addedCount++;
|
||||
@ -118,8 +120,10 @@ public class FileChecker implements Observable {
|
||||
return;
|
||||
}
|
||||
|
||||
if(mf.getLocalSize() != mf.getSize() || !mf.getSHA1Sum().equalsIgnoreCase(mf.getLocalGeneratedSHA1Sum())) {
|
||||
if(changed.containsKey(mod)) temp =changed.get(mod);
|
||||
|
||||
if (fastscan || !mf.getSHA1Sum().equalsIgnoreCase(mf.getLocalGeneratedSHA1Sum())) {
|
||||
if (mf.getLocalSize() != mf.getSize()) {
|
||||
if (changed.containsKey(mod)) temp = changed.get(mod);
|
||||
temp.add(mf);
|
||||
changed.put(mod, temp);
|
||||
changedCount++;
|
||||
@ -127,10 +131,11 @@ public class FileChecker implements Observable {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void checkDeleted() {
|
||||
String modPath = ArmA3Launcher.user_config.get("client", "modPath");
|
||||
if(modPath == null) modPath = "";
|
||||
if (modPath == null) modPath = "";
|
||||
|
||||
try {
|
||||
List<Path> filePathList = Files.find(Paths.get(modPath),
|
||||
@ -144,7 +149,7 @@ public class FileChecker implements Observable {
|
||||
|
||||
outerloop:
|
||||
for (AbstractMod abstractMod : RepositoryManger.MOD_LIST) {
|
||||
if(abstractMod instanceof Mod) {
|
||||
if (abstractMod instanceof Mod) {
|
||||
Mod m = (Mod) abstractMod;
|
||||
|
||||
for (ModFile mf : m.getFiles()) {
|
||||
|
@ -10,6 +10,7 @@ import de.mc8051.arma3launcher.objects.ModFile;
|
||||
import de.mc8051.arma3launcher.objects.Modset;
|
||||
import de.mc8051.arma3launcher.objects.Server;
|
||||
import de.mc8051.arma3launcher.utils.Callback;
|
||||
import org.ini4j.Ini;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
|
||||
@ -27,6 +28,7 @@ import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static java.time.temporal.ChronoUnit.SECONDS;
|
||||
|
||||
@ -93,10 +95,19 @@ public class RepositoryManger implements Observable {
|
||||
}
|
||||
|
||||
try {
|
||||
Modset.MODSET_LIST.clear();
|
||||
Ini.Section section = ArmA3Launcher.user_config.get("presets");
|
||||
if (section != null) {
|
||||
for (String key : section.keySet()) {
|
||||
String jsonString = section.get(key);
|
||||
JSONArray ja = new JSONArray(jsonString);
|
||||
new Modset(key, ja, Modset.Type.CLIENT);
|
||||
}
|
||||
}
|
||||
|
||||
JSONObject jsonObject = new JSONObject(r.getBody());
|
||||
|
||||
if (jsonObject.has("modsets")) {
|
||||
Modset.MODSET_LIST.clear();
|
||||
JSONArray modsets = jsonObject.getJSONArray("modsets");
|
||||
if (modsets.length() > 0) {
|
||||
for (int i = 0; i < modsets.length(); i++) {
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "TheTown Client",
|
||||
"title": "Welcome! :P",
|
||||
"title": "Willkommen!",
|
||||
"subtitle": "${name} v${version}",
|
||||
"sync": {
|
||||
"useragent": "TheTownSyncer",
|
||||
|
@ -29,7 +29,7 @@ nicht jeder Fehler unsererseits behoben werden kann.
|
||||
<br/>
|
||||
<br/>
|
||||
<h1>Licenses</h1>
|
||||
<h3>de.mc8051.arma3launcher</h3>
|
||||
<h2>de.mc8051.arma3launcher</h2>
|
||||
<tt>
|
||||
MIT License<br/>
|
||||
<br/>
|
||||
@ -54,7 +54,7 @@ nicht jeder Fehler unsererseits behoben werden kann.
|
||||
SOFTWARE.<br/>
|
||||
</tt>
|
||||
<br/>
|
||||
<h3>com.formdev.flatlaf</h3>
|
||||
<h2>com.formdev.flatlaf</h2>
|
||||
<a href="">https://github.com/JFormDesigner/FlatLaf</a><br/>
|
||||
<tt>
|
||||
Copyright 2019 FormDev Software GmbH<br/>
|
||||
@ -72,7 +72,7 @@ nicht jeder Fehler unsererseits behoben werden kann.
|
||||
limitations under the License.<br/>
|
||||
</tt>
|
||||
<br/>
|
||||
<h3>co.bitshfted.xapps.zsync</h3>
|
||||
<h2>co.bitshfted.xapps.zsync</h2>
|
||||
<a href="">https://github.com/bitshifted/zsyncer</a><br/>
|
||||
<tt>
|
||||
Copyright (c) 2015, Salesforce.com, Inc. All rights reserved.<br/>
|
||||
@ -99,7 +99,7 @@ nicht jeder Fehler unsererseits behoben werden kann.
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.<br/>
|
||||
</tt>
|
||||
<br/>
|
||||
<h3>com.github.RalleYTN.SimpleRegistry</h3>
|
||||
<h2>com.github.RalleYTN.SimpleRegistry</h2>
|
||||
<a href="">https://github.com/RalleYTN/SimpleRegistry</a><br/>
|
||||
<tt>
|
||||
MIT License<br/>
|
||||
@ -125,7 +125,7 @@ nicht jeder Fehler unsererseits behoben werden kann.
|
||||
SOFTWARE.<br/>
|
||||
</tt>
|
||||
<br/>
|
||||
<h3>com.typesafe.config</h3>
|
||||
<h2>com.typesafe.config</h2>
|
||||
<a href="">https://github.com/lightbend/config</a><br/>
|
||||
<tt>
|
||||
Copyright (C) 2011-2012 Typesafe Inc. http://typesafe.com<br/>
|
||||
@ -143,7 +143,7 @@ nicht jeder Fehler unsererseits behoben werden kann.
|
||||
limitations under the License.<br/>
|
||||
</tt>
|
||||
<br/>
|
||||
<h3>org.ini4j.ini4j</h3>
|
||||
<h2>org.ini4j.ini4j</h2>
|
||||
<a href="">https://github.com/facebookarchive/ini4j</a><br/>
|
||||
<tt>
|
||||
Copyright 2005,2009 Ivan SZKIBA<br/>
|
||||
@ -160,7 +160,7 @@ nicht jeder Fehler unsererseits behoben werden kann.
|
||||
See the License for the specific language governing permissions and<br/>
|
||||
limitations under the License.<br/>
|
||||
</tt>
|
||||
<h3>org.json.json</h3>
|
||||
<h2>org.json.json</h2>
|
||||
<a href="">https://json.org</a><br/>
|
||||
<tt>
|
||||
Copyright (c) 2018 JSON.org<br/>
|
||||
@ -185,5 +185,35 @@ nicht jeder Fehler unsererseits behoben werden kann.
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE<br/>
|
||||
SOFTWARE.<br/>
|
||||
</tt>
|
||||
<h2>com.jgoodies.forms</h2>
|
||||
<tt>
|
||||
Copyright (c) 2002-2015 JGoodies Software GmbH. All Rights Reserved.<br/>
|
||||
<br/>
|
||||
Redistribution and use in source and binary forms, with or without<br/>
|
||||
modification, are permitted provided that the following conditions are met:<br/>
|
||||
<br/>
|
||||
o Redistributions of source code must retain the above copyright notice,<br/>
|
||||
this list of conditions and the following disclaimer.<br/>
|
||||
<br/>
|
||||
o Redistributions in binary form must reproduce the above copyright notice,<br/>
|
||||
this list of conditions and the following disclaimer in the documentation<br/>
|
||||
and/or other materials provided with the distribution.<br/>
|
||||
<br/>
|
||||
o Neither the name of JGoodies Software GmbH nor the names of<br/>
|
||||
its contributors may be used to endorse or promote products derived<br/>
|
||||
from this software without specific prior written permission.<br/>
|
||||
<br/>
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"<br/>
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,<br/>
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR<br/>
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR<br/>
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,<br/>
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,<br/>
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;<br/>
|
||||
OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,<br/>
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE<br/>
|
||||
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,<br/>
|
||||
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.<br/>
|
||||
</tt>
|
||||
</body>
|
||||
</html>
|
@ -102,3 +102,11 @@ star_on_github="Star us" auf GitHub
|
||||
client_up_to_date=Client ist aktuell
|
||||
developer_page=Entwickler-Seite
|
||||
project_page=Projektseite
|
||||
fast_check=Schnelle Prüfung
|
||||
intensive_check=Intensive Prüfung
|
||||
note=Hinweis
|
||||
presets_note=Vorlagen können nur als Vorlage für neue User-Vorlagen verwendet werden. Du kannst eine eigene Vorlage auf Bases dieser Server Vorlage erstellen. Dabei wird die Liste aler Mods übernommen.
|
||||
clone_preset=Vorlage klonen
|
||||
new_modset_name=Modsset Name
|
||||
modset_exists_msg=Bitte wähle ein anderen Namen für deine Vorlage.
|
||||
modset_exists=Preset mit diesen Namen existiert bereits
|
@ -100,3 +100,11 @@ star_on_github=Star us on GitHub
|
||||
client_up_to_date=Client is up to date
|
||||
developer_page=Developer page
|
||||
project_page=Project page
|
||||
new_modset_name=Modsset name
|
||||
intensive_check=Intensive check
|
||||
fast_check=Fast check
|
||||
note=Note
|
||||
presets_note=Presets can only be used as preset for new user presents. You can create your own custom preset based on this server preset. The list of all mods will be used.
|
||||
clone_preset=Clone preset
|
||||
modset_exists_msg=Please choose another name for your preset.
|
||||
modset_exists=Preset with these names already exists
|
Loading…
Reference in New Issue
Block a user