init repo
This commit is contained in:
commit
73fbf00bee
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
*.iml
|
||||
.idea/
|
||||
out/
|
||||
META-INF/
|
||||
target/
|
1
linux/.sync/modset.json
Normal file
1
linux/.sync/modset.json
Normal file
File diff suppressed because one or more lines are too long
26
linux/.sync/server.json
Normal file
26
linux/.sync/server.json
Normal file
@ -0,0 +1,26 @@
|
||||
{
|
||||
"servers": [
|
||||
{
|
||||
"name": "[The-Town] ACE Taktik",
|
||||
"password": "0815",
|
||||
"ipaddress": "148.251.216.100",
|
||||
"port": "2302",
|
||||
"preset": "Taktik"
|
||||
}
|
||||
],
|
||||
"modsets": [
|
||||
{
|
||||
"name": "Taktik",
|
||||
"mods": [
|
||||
"@ace",
|
||||
"@CBA_A3"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "ACE",
|
||||
"mods": [
|
||||
"@ace"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
122
linux/generateRepo.sh
Normal file
122
linux/generateRepo.sh
Normal file
@ -0,0 +1,122 @@
|
||||
#!/bin/bash
|
||||
###################################################################
|
||||
#Script Name :generateRepo.sh
|
||||
#Description :Generate meta data for ArmA 3 Launcher
|
||||
#Date :24.03.2020
|
||||
#Author :Niklas Schütrumpf
|
||||
#Email :niklas@mc8051.de
|
||||
###################################################################
|
||||
|
||||
if ! [ -x "$(command -v zsyncmake)" ]; then
|
||||
echo 'Error: zsync is not installed.' >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! [ -x "$(command -v jq)" ]; then
|
||||
echo 'Error: jq is not installed.' >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! [ -x "$(command -v strings)" ]; then
|
||||
echo 'Error: binutils is not installed.' >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "===== ===== ===== GENERATE .ZSYNC ===== ===== ====="
|
||||
FILELIST=$(find . -type f ! -path "*/.sync*" ! -path "*.zsync")
|
||||
while IFS= read -r line; do
|
||||
mustgenerate=false
|
||||
zsyncfile="${line}.zsync"
|
||||
|
||||
filebyte=$(wc -c < ${line})
|
||||
filedate=$(stat -c %Y ${line})
|
||||
|
||||
zsyncfiledate=$(strings ${zsyncfile} 2>/dev/null | grep -m 1 MTime | cut -d" " -f2-)
|
||||
|
||||
if [ ! -f "$zsyncfile" ]; then
|
||||
echo "$zsyncfile does not exist"
|
||||
mustgenerate=true
|
||||
elif [[ ! $(strings ${zsyncfile} | grep -m 1 Length | cut -d" " -f2) == $filebyte ]]; then # Check file length
|
||||
echo "$zsyncfile does not have corret length"
|
||||
mustgenerate=true
|
||||
elif [[ ! $filedate == $(date -d "${zsyncfiledate}" +"%s") ]]; then # Check date
|
||||
echo "$zsyncfile does not have corret date"
|
||||
mustgenerate=true
|
||||
fi
|
||||
|
||||
if [ "$mustgenerate" = true ]; then
|
||||
echo "Generate $zsyncfile"
|
||||
rm ${zsyncfile} 2> /dev/null
|
||||
dirfile=$(dirname ${line})
|
||||
filename=$(basename ${line})
|
||||
filenamezsync=$(basename ${zsyncfile})
|
||||
$(cd ${dirfile} && zsyncmake -o ${filenamezsync} ${filename})
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "Success: Generated ${zsyncfile}"
|
||||
else
|
||||
echo "Failure: Couldn't generate ${zsyncfile}" >&2
|
||||
fi
|
||||
else
|
||||
echo "Nothing changed for $line"
|
||||
fi
|
||||
|
||||
done <<< "$FILELIST"
|
||||
echo -e "===== ===== ===== ===== ===== =====\n"
|
||||
|
||||
|
||||
echo "===== ===== ===== DELETE SINGLE ZFILE WITHOUT FILE ===== ===== ====="
|
||||
ZSYNCLIST=$(find . -name "*.zsync")
|
||||
while IFS= read -r zfile; do
|
||||
ORIG=$(echo ${zfile} | rev | cut -c7- | rev)
|
||||
if [ ! -f "$ORIG" ]; then
|
||||
echo "$ORIG does not exist"
|
||||
rm ${zfile}
|
||||
fi
|
||||
done <<< "$ZSYNCLIST"
|
||||
echo -e "===== ===== ===== ===== ===== =====\n"
|
||||
|
||||
echo "===== ===== ===== GENERATE METADATA ===== ===== ====="
|
||||
FILELIST=$(find . -maxdepth 1 ! -path "*/.sync*" ! -path "*.zsync" ! -path "." | sed 's|^./||')
|
||||
declare -a JSONDATA
|
||||
while IFS= read -r folder; do
|
||||
echo "${folder}"
|
||||
|
||||
if [ -d "$folder" ]; then
|
||||
echo "is dir"
|
||||
x=""
|
||||
foldersize=0
|
||||
FILEFOLDER=$(find ${folder} -type f ! -path "*.zsync" | sed 's|^./||')
|
||||
while IFS= read -r folderfile; do
|
||||
filebyte=$(wc -c < ${folderfile})
|
||||
foldersize=$(expr $foldersize + $filebyte)
|
||||
name=$(echo ${folderfile} | cut -d"/" -f2-)
|
||||
x="\"${name}\":${filebyte},${x}"
|
||||
done <<< "$FILEFOLDER"
|
||||
x=$(echo ${x} | rev | cut -c2- | rev)
|
||||
JSONDATA+=( "\"${folder}\": {\"size\":${foldersize},\"content\":{${x}}}" )
|
||||
else
|
||||
echo "is file"
|
||||
filebyte=$(wc -c < ${folder})
|
||||
JSONDATA+=( "\"${folder}\": {\"size\":${filebyte}}" )
|
||||
fi
|
||||
done <<< "$FILELIST"
|
||||
|
||||
s=""
|
||||
for i in "${JSONDATA[@]}"
|
||||
do
|
||||
s="${s},${i}"
|
||||
done
|
||||
|
||||
s=$(echo ${s} | cut -c2-)
|
||||
s="{${s}}"
|
||||
|
||||
echo $s | jq . > /dev/null
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo $s > ./.sync/modset.json
|
||||
echo "Success: Generated metafile"
|
||||
else
|
||||
echo "Failure: invalid json generated" >&2
|
||||
fi
|
||||
|
||||
echo -e "===== ===== ===== ===== ===== =====\n"
|
101
pom.xml
Normal file
101
pom.xml
Normal file
@ -0,0 +1,101 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>de.mc8051</groupId>
|
||||
<artifactId>arma3launcher</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>jitpack.io</id>
|
||||
<url>https://jitpack.io</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.json</groupId>
|
||||
<artifactId>json</artifactId>
|
||||
<version>20190722</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.typesafe</groupId>
|
||||
<artifactId>config</artifactId>
|
||||
<version>1.4.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>2.6</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.formdev</groupId>
|
||||
<artifactId>flatlaf</artifactId>
|
||||
<version>0.28</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.RalleYTN</groupId>
|
||||
<artifactId>SimpleRegistry</artifactId>
|
||||
<version>java8-7949ac7f06-1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.ini4j</groupId>
|
||||
<artifactId>ini4j</artifactId>
|
||||
<version>0.5.4</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.takari.zsync</groupId>
|
||||
<artifactId>zsync-parent</artifactId>
|
||||
<version>0.1.0</version>
|
||||
<type>pom</type>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.bitshifted</groupId>
|
||||
<artifactId>zsyncer</artifactId>
|
||||
<version>-f69d844481-1</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.5.1</version>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<version>2.6</version>
|
||||
<configuration>
|
||||
<appendAssemblyId>false</appendAssemblyId>
|
||||
<finalName>${project.artifactId}</finalName>
|
||||
<descriptorRefs>
|
||||
<descriptorRef>
|
||||
jar-with-dependencies
|
||||
</descriptorRef>
|
||||
</descriptorRefs>
|
||||
<archive>
|
||||
<manifest>
|
||||
<mainClass>${project.groupId}.${project.artifactId}.ArmA3Launcher</mainClass>
|
||||
</manifest>
|
||||
</archive>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>assamble</id>
|
||||
<goals>
|
||||
<goal>single</goal>
|
||||
</goals>
|
||||
<phase>package</phase>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
119
src/main/java/de/mc8051/arma3launcher/ArmA3Launcher.java
Normal file
119
src/main/java/de/mc8051/arma3launcher/ArmA3Launcher.java
Normal file
@ -0,0 +1,119 @@
|
||||
package de.mc8051.arma3launcher;
|
||||
|
||||
import com.formdev.flatlaf.FlatDarkLaf;
|
||||
import com.typesafe.config.Config;
|
||||
import com.typesafe.config.ConfigFactory;
|
||||
import de.mc8051.arma3launcher.repo.RepositoryManger;
|
||||
import de.mc8051.arma3launcher.steam.SteamTimer;
|
||||
import org.ini4j.Ini;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Locale;
|
||||
import java.util.Timer;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* Created by gurkengewuerz.de on 23.03.2020.
|
||||
*/
|
||||
public class ArmA3Launcher {
|
||||
|
||||
public static final String[] SUPPORTED_LANGUAGES = {"en_US", "de_DE"};
|
||||
|
||||
public static String VERSION;
|
||||
public static String CLIENT_NAME;
|
||||
public static String APPLICATION_PATH;
|
||||
|
||||
public static Config config;
|
||||
public static Ini user_config;
|
||||
|
||||
public static void main(String... args) throws Exception {
|
||||
config = ConfigFactory.load("arma3launcher");
|
||||
|
||||
CLIENT_NAME = config.getString("name");
|
||||
VERSION = config.getString("version");
|
||||
|
||||
APPLICATION_PATH = getAppData() + CLIENT_NAME;
|
||||
|
||||
if (new File(APPLICATION_PATH).mkdirs()) {
|
||||
Logger.getLogger(ArmA3Launcher.class.getName()).log(Level.SEVERE, "Can not create " + APPLICATION_PATH);
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
File userConfigFile = new File(APPLICATION_PATH + File.separator + "config.ini");
|
||||
if(!userConfigFile.exists()) {
|
||||
if(!userConfigFile.createNewFile()) {
|
||||
Logger.getLogger(ArmA3Launcher.class.getName()).log(Level.SEVERE, "Can not create " + userConfigFile.getAbsolutePath());
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
user_config = new Ini(userConfigFile);
|
||||
|
||||
Timer steamTimer = new Timer();
|
||||
|
||||
setLanguage();
|
||||
|
||||
UIManager.setLookAndFeel(new FlatDarkLaf());
|
||||
|
||||
JFrame frame = new JFrame(CLIENT_NAME);
|
||||
LauncherGUI gui = new LauncherGUI();
|
||||
frame.setContentPane(gui.mainPanel);
|
||||
|
||||
frame.addWindowListener(new WindowAdapter() {
|
||||
@Override
|
||||
public void windowClosing(WindowEvent e) {
|
||||
steamTimer.cancel();
|
||||
steamTimer.purge();
|
||||
frame.dispose();
|
||||
}
|
||||
});
|
||||
|
||||
frame.setMinimumSize(new Dimension(1000, 500));
|
||||
|
||||
frame.pack();
|
||||
frame.setLocationRelativeTo(null);
|
||||
|
||||
steamTimer.scheduleAtFixedRate(
|
||||
new SteamTimer(gui),
|
||||
500, // run first occurrence immediately
|
||||
10000); // run every thirty seconds
|
||||
|
||||
frame.setVisible(true);
|
||||
}
|
||||
|
||||
public static String getAppData() {
|
||||
String path = "";
|
||||
String OS = System.getProperty("os.name").toUpperCase();
|
||||
if (OS.contains("WIN"))
|
||||
path = System.getenv("APPDATA");
|
||||
else if (OS.contains("MAC"))
|
||||
path = System.getProperty("user.home") + "/Library/";
|
||||
else if (OS.contains("NUX"))
|
||||
path = System.getProperty("user.home");
|
||||
else path = System.getProperty("user.dir");
|
||||
|
||||
path = path + File.separator;
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
private static void setLanguage() {
|
||||
String lang = Locale.getDefault().getLanguage() + "_" + Locale.getDefault().getCountry();
|
||||
|
||||
String clientSetting = ArmA3Launcher.user_config.get("client", "language");
|
||||
if(clientSetting != null && !clientSetting.equals("system") && Arrays.asList(SUPPORTED_LANGUAGES).contains(clientSetting)) {
|
||||
Locale.setDefault(new Locale(clientSetting.split("_")[0], clientSetting.split("_")[1]));
|
||||
return;
|
||||
}
|
||||
|
||||
if(!Arrays.asList(SUPPORTED_LANGUAGES).contains(lang))
|
||||
Locale.setDefault(new Locale("en", "US"));
|
||||
}
|
||||
}
|
1639
src/main/java/de/mc8051/arma3launcher/LauncherGUI.form
Normal file
1639
src/main/java/de/mc8051/arma3launcher/LauncherGUI.form
Normal file
File diff suppressed because it is too large
Load Diff
449
src/main/java/de/mc8051/arma3launcher/LauncherGUI.java
Normal file
449
src/main/java/de/mc8051/arma3launcher/LauncherGUI.java
Normal file
@ -0,0 +1,449 @@
|
||||
package de.mc8051.arma3launcher;
|
||||
|
||||
import de.mc8051.arma3launcher.interfaces.Observer;
|
||||
import de.mc8051.arma3launcher.model.ModListRenderer;
|
||||
import de.mc8051.arma3launcher.model.PresetListRenderer;
|
||||
import de.mc8051.arma3launcher.model.PresetTableModel;
|
||||
import de.mc8051.arma3launcher.model.ServerTableModel;
|
||||
import de.mc8051.arma3launcher.objects.Modset;
|
||||
import de.mc8051.arma3launcher.objects.Server;
|
||||
import de.mc8051.arma3launcher.repo.RepositoryManger;
|
||||
import de.mc8051.arma3launcher.utils.Callback;
|
||||
import de.mc8051.arma3launcher.utils.LangUtils;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.ListSelectionEvent;
|
||||
import javax.swing.event.ListSelectionListener;
|
||||
import javax.swing.plaf.basic.BasicTabbedPaneUI;
|
||||
import javax.swing.text.DefaultFormatter;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.ItemEvent;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.net.URLDecoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* Created by gurkengewuerz.de on 23.03.2020.
|
||||
*/
|
||||
public class LauncherGUI implements Observer {
|
||||
public JPanel mainPanel;
|
||||
private JButton settingsPanelButton;
|
||||
private JButton updatePanelButton;
|
||||
private JButton playPanelButton;
|
||||
private JLabel subtitle;
|
||||
private JLabel title;
|
||||
private JTabbedPane tabbedPane1;
|
||||
private JLabel steamStatus;
|
||||
private JLabel armaStatus;
|
||||
private JButton presetPanelButton;
|
||||
private JPanel logo;
|
||||
private JPanel presetsTab;
|
||||
private JButton playPresetButton;
|
||||
private JButton clonePresetButton;
|
||||
private JButton newPresetButtom;
|
||||
private JButton removePresetButtom;
|
||||
private JButton renamePresetButton;
|
||||
private JList presetList;
|
||||
private JList modList;
|
||||
private JPanel playTab;
|
||||
private JTable serverTable;
|
||||
private JButton playButton;
|
||||
private JPanel updateTab;
|
||||
private JPanel settingsTab;
|
||||
private JTextField settingsArmaPathText;
|
||||
private JButton settingsArmaPathBtn;
|
||||
private JComboBox settingsBehaviorStartCombo;
|
||||
private JComboBox settingsProfileCombo;
|
||||
private JComboBox settingsMallocCombo;
|
||||
private JSpinner settingsMaxMemSpinner;
|
||||
private JTextField parameterText;
|
||||
private JButton settingsModsPathBtn;
|
||||
private JTextField settingsModsPathText;
|
||||
private JCheckBox settingsShowParameterBox;
|
||||
private JCheckBox settingsCheckModsBox;
|
||||
private JComboBox settingsLanguageCombo;
|
||||
private JTextField settingsBackendText;
|
||||
private JComboBox settingsExThreadsCombo;
|
||||
private JTextField settingsWorldText;
|
||||
private JTextField settingsInitText;
|
||||
private JTextField settingsBetaText;
|
||||
private JCheckBox settingsUseSixtyFourBitBox;
|
||||
private JCheckBox settingsNoSplashBox;
|
||||
private JCheckBox settingsSkipIntroBox;
|
||||
private JCheckBox settingsNoCBBox;
|
||||
private JCheckBox settingsNoLogsBox;
|
||||
private JCheckBox settingsEnableHTBox;
|
||||
private JCheckBox settingsHugeoagesBox;
|
||||
private JCheckBox settingsNoPauseBox;
|
||||
private JCheckBox settingsShowScriptErrorsBox;
|
||||
private JCheckBox settingsFilePatchingBox;
|
||||
private JCheckBox settingsCrashDiagBox;
|
||||
private JCheckBox settingsWindowBox;
|
||||
private JSpinner settingsMaxVRamSpinner;
|
||||
private JSpinner settingsCpuCountSpinner;
|
||||
private JSpinner settingsPosXSpinner;
|
||||
private JSpinner settingsPosYSpinner;
|
||||
private JButton settingsResetDefault;
|
||||
private JScrollPane settingScrollPane;
|
||||
private JCheckBox settingsUseWorkshopBox;
|
||||
private JTree tree1;
|
||||
private JButton allesAuswählenButton;
|
||||
private JButton allesAusklappenButton;
|
||||
private JProgressBar progressBar1;
|
||||
private JButton abbrechenButton;
|
||||
private JButton überprüfenButton;
|
||||
private JProgressBar progressBar2;
|
||||
private JProgressBar progressBar3;
|
||||
private JButton downloadButton;
|
||||
private JButton abbrechenButton1;
|
||||
private JButton pauseButton;
|
||||
|
||||
// TODO: Updater
|
||||
/*
|
||||
Prüfung
|
||||
In eine Liste hinzufügen wenn Datei in modset.json (Neu runterladen), nicht in modset.json (zum Löschen) oder die Größe unterschiedlich ist (Geändert)
|
||||
*/
|
||||
|
||||
public LauncherGUI() {
|
||||
RepositoryManger.getInstance().addObserver(this);
|
||||
|
||||
tabbedPane1.setUI(new 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;
|
||||
}
|
||||
});
|
||||
|
||||
Insets x = new Insets(5, 5, 5, 5);
|
||||
settingsPanelButton.setMargin(x);
|
||||
updatePanelButton.setMargin(x);
|
||||
playPanelButton.setMargin(x);
|
||||
presetPanelButton.setMargin(x);
|
||||
|
||||
playPresetButton.setMargin(new Insets(10, 10, 10, 10));
|
||||
|
||||
playPanelButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
tabbedPane1.setSelectedIndex(0);
|
||||
}
|
||||
});
|
||||
|
||||
updatePanelButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
tabbedPane1.setSelectedIndex(1);
|
||||
}
|
||||
});
|
||||
|
||||
presetPanelButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
tabbedPane1.setSelectedIndex(2);
|
||||
}
|
||||
});
|
||||
|
||||
settingsPanelButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
tabbedPane1.setSelectedIndex(3);
|
||||
}
|
||||
});
|
||||
|
||||
serverTable.setModel(new ServerTableModel());
|
||||
|
||||
presetList.setModel(new PresetTableModel());
|
||||
presetList.setCellRenderer(new PresetListRenderer());
|
||||
presetList.addListSelectionListener(new ListSelectionListener() {
|
||||
|
||||
@Override
|
||||
public void valueChanged(ListSelectionEvent e) {
|
||||
if (!e.getValueIsAdjusting()) {
|
||||
PresetTableModel m = (PresetTableModel) presetList.getModel();
|
||||
Modset modset = (Modset) m.getElementAt(presetList.getSelectedIndex());
|
||||
System.out.println(modset.getName());
|
||||
|
||||
if(modset.getType() == Modset.Type.SERVER) {
|
||||
renamePresetButton.setEnabled(false);
|
||||
removePresetButtom.setEnabled(false);
|
||||
} else {
|
||||
renamePresetButton.setEnabled(true);
|
||||
removePresetButtom.setEnabled(true);
|
||||
}
|
||||
clonePresetButton.setEnabled(true);
|
||||
|
||||
updateModList(modset);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
modList.setCellRenderer(new ModListRenderer());
|
||||
|
||||
subtitle.setText(
|
||||
ArmA3Launcher.config.getString("subtitle")
|
||||
.replace("${name}", ArmA3Launcher.CLIENT_NAME)
|
||||
.replace("${version}", ArmA3Launcher.VERSION));
|
||||
|
||||
title.setText(
|
||||
ArmA3Launcher.config.getString("title")
|
||||
.replace("${name}", ArmA3Launcher.CLIENT_NAME)
|
||||
.replace("${version}", ArmA3Launcher.VERSION));
|
||||
|
||||
initSettings();
|
||||
|
||||
settingsResetDefault.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
try {
|
||||
ArmA3Launcher.user_config.remove("arma");
|
||||
ArmA3Launcher.user_config.store();
|
||||
initSettings();
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, e);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
settingScrollPane.getVerticalScrollBar().setUnitIncrement(16);
|
||||
|
||||
RepositoryManger.getInstance().refreshMeta();
|
||||
}
|
||||
|
||||
public static void infoBox(String infoMessage, String titleBar) {
|
||||
JOptionPane.showMessageDialog(null, infoMessage, "INFO: " + titleBar, JOptionPane.INFORMATION_MESSAGE);
|
||||
}
|
||||
|
||||
public static void warnBox(String infoMessage, String titleBar) {
|
||||
JOptionPane.showMessageDialog(null, infoMessage, titleBar, JOptionPane.WARNING_MESSAGE);
|
||||
}
|
||||
|
||||
public static void errorBox(String errorMessage, String titleBar) {
|
||||
JOptionPane.showMessageDialog(null, errorMessage, "ERROR: " + titleBar, JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
|
||||
public void updateLabels(boolean steamRunning, boolean armaRunning) {
|
||||
if (steamRunning) {
|
||||
steamStatus.setText(LangUtils.getInstance().getString("signed_in"));
|
||||
steamStatus.setForeground(new Color(82, 137, 74));
|
||||
} else {
|
||||
steamStatus.setText(LangUtils.getInstance().getString("closed"));
|
||||
steamStatus.setForeground(Color.RED);
|
||||
}
|
||||
|
||||
if (armaRunning) {
|
||||
armaStatus.setText(LangUtils.getInstance().getString("running"));
|
||||
armaStatus.setForeground(new Color(82, 137, 74));
|
||||
} else {
|
||||
armaStatus.setText(LangUtils.getInstance().getString("closed"));
|
||||
armaStatus.setForeground(Color.red);
|
||||
}
|
||||
}
|
||||
|
||||
public void techCheck() {
|
||||
// Arma Path set
|
||||
// Steam running
|
||||
// Arma not running
|
||||
}
|
||||
|
||||
public boolean checkArmaPath(String path) {
|
||||
if (settingsArmaPathText.getText().isEmpty()) return false;
|
||||
File dir = new File(settingsArmaPathText.getText());
|
||||
|
||||
ArrayList<String> search = new ArrayList<String>(Arrays.asList("arma3.exe", "steam.dll"));
|
||||
File[] listOfFiles = dir.listFiles();
|
||||
|
||||
try {
|
||||
for (File file : listOfFiles) {
|
||||
if (search.isEmpty()) return true;
|
||||
if (file.isFile()) {
|
||||
search.remove(file.getName().toLowerCase());
|
||||
}
|
||||
}
|
||||
} catch (NullPointerException ex) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void initSettings() {
|
||||
|
||||
settingsBackendText.setText(ArmA3Launcher.config.getString("sync.url"));
|
||||
|
||||
|
||||
// -------------------------------- PROFILE --------------------------------
|
||||
|
||||
File file = new File((new JFileChooser().getFileSystemView().getDefaultDirectory().toString()) + File.separator + "Arma 3 - Other Profiles");
|
||||
String[] directories = file.list((current, name) -> new File(current, name).isDirectory());
|
||||
|
||||
directories = Stream.concat(Arrays.stream(new String[]{""}), Arrays.stream(directories == null ? new String[]{} : directories)).toArray(String[]::new);
|
||||
|
||||
String[] readableDirectories = new String[directories.length];
|
||||
for (int i = 0; i < directories.length; i++) {
|
||||
try {
|
||||
readableDirectories[i] = URLDecoder.decode(directories[i], StandardCharsets.UTF_8.name());
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
readableDirectories[i] = directories[i];
|
||||
}
|
||||
}
|
||||
|
||||
((JComboBox<String>) settingsProfileCombo).setModel(new DefaultComboBoxModel<>(readableDirectories));
|
||||
|
||||
|
||||
initFolderChooser(settingsArmaPathText, settingsArmaPathBtn, "armaPath", Parameter.ParameterType.CLIENT, new Callback.JFileSelectCallback() {
|
||||
@Override
|
||||
public boolean allowSelection(File path) {
|
||||
String sPath = path.getAbsolutePath();
|
||||
if (!checkArmaPath(sPath)) {
|
||||
SwingUtilities.invokeLater(() -> warnBox(LangUtils.getInstance().getString("not_arma_dir_msg"), LangUtils.getInstance().getString("not_arma_dir")));
|
||||
return false;
|
||||
}
|
||||
settingsArmaPathText.setText(sPath);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
initFolderChooser(settingsModsPathText, settingsModsPathBtn, "modPath", Parameter.ParameterType.CLIENT, new Callback.JFileSelectCallback() {
|
||||
@Override
|
||||
public boolean allowSelection(File path) {
|
||||
settingsModsPathText.setText(path.getAbsolutePath());
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
// -------------------------------- COMBO BOXES --------------------------------
|
||||
|
||||
initComboBox(settingsLanguageCombo, "language", Parameter.ParameterType.CLIENT, new String[]{"system", "en_US", "de_DE"});
|
||||
initComboBox(settingsBehaviorStartCombo, "behaviourAfterStart", Parameter.ParameterType.CLIENT, new String[]{"nothing", "minimize", "exit"});
|
||||
|
||||
initComboBox(settingsProfileCombo, "Profile", Parameter.ParameterType.ARMA, directories);
|
||||
initComboBox(settingsExThreadsCombo, "ExThreads", Parameter.ParameterType.ARMA, new String[]{"", "3", "7"});
|
||||
initComboBox(settingsMallocCombo, "Malloc", Parameter.ParameterType.ARMA, new String[]{"", "tbb4malloc_bi", "jemalloc_bi", "system"});
|
||||
|
||||
|
||||
// -------------------------------- CHECK BOXES --------------------------------
|
||||
|
||||
initCheckBox(settingsShowParameterBox, "ShowStartParameter", Parameter.ParameterType.CLIENT);
|
||||
settingsShowParameterBox.addItemListener(e -> parameterText.setVisible(e.getStateChange() == ItemEvent.SELECTED));
|
||||
initCheckBox(settingsCheckModsBox, "CheckModset", Parameter.ParameterType.CLIENT);
|
||||
|
||||
initCheckBox(settingsUseWorkshopBox, "UseWorkshop", Parameter.ParameterType.CLIENT);
|
||||
settingsUseWorkshopBox.addItemListener(e -> {
|
||||
if (e.getStateChange() == ItemEvent.SELECTED) {
|
||||
SwingUtilities.invokeLater(() -> warnBox(LangUtils.getInstance().getString("warning_workshop"), LangUtils.getInstance().getString("warning")));
|
||||
}
|
||||
});
|
||||
|
||||
initCheckBox(settingsUseSixtyFourBitBox, "Use64BitClient", Parameter.ParameterType.ARMA);
|
||||
initCheckBox(settingsNoSplashBox, "NoSplash", Parameter.ParameterType.ARMA);
|
||||
initCheckBox(settingsSkipIntroBox, "SkipIntro", Parameter.ParameterType.ARMA);
|
||||
initCheckBox(settingsNoCBBox, "NoCB", Parameter.ParameterType.ARMA);
|
||||
initCheckBox(settingsNoLogsBox, "NoLogs", Parameter.ParameterType.ARMA);
|
||||
initCheckBox(settingsEnableHTBox, "EnableHT", Parameter.ParameterType.ARMA);
|
||||
initCheckBox(settingsHugeoagesBox, "Hugepages", Parameter.ParameterType.ARMA);
|
||||
initCheckBox(settingsNoPauseBox, "NoPause", Parameter.ParameterType.ARMA);
|
||||
initCheckBox(settingsShowScriptErrorsBox, "ShowScriptErrors", Parameter.ParameterType.ARMA);
|
||||
initCheckBox(settingsFilePatchingBox, "FilePatching", Parameter.ParameterType.ARMA);
|
||||
initCheckBox(settingsCrashDiagBox, "CrashDiag", Parameter.ParameterType.ARMA);
|
||||
initCheckBox(settingsWindowBox, "Window", Parameter.ParameterType.ARMA);
|
||||
|
||||
|
||||
// -------------------------------- SPINNER --------------------------------
|
||||
|
||||
com.sun.management.OperatingSystemMXBean mxbean = (com.sun.management.OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
|
||||
int memorySize = (int) (mxbean.getTotalPhysicalMemorySize() / 1024);
|
||||
|
||||
initSpinner(settingsMaxMemSpinner, "MaxMem", Parameter.ParameterType.ARMA, -1, memorySize);
|
||||
initSpinner(settingsMaxVRamSpinner, "MaxVRAM", Parameter.ParameterType.ARMA, -1, 99999);
|
||||
initSpinner(settingsCpuCountSpinner, "CpuCount", Parameter.ParameterType.ARMA, 0, Runtime.getRuntime().availableProcessors());
|
||||
initSpinner(settingsPosXSpinner, "PosX", Parameter.ParameterType.ARMA, -1, 99999);
|
||||
initSpinner(settingsPosYSpinner, "PosY", Parameter.ParameterType.ARMA, -1, 99999);
|
||||
|
||||
// -------------------------------- -------------------------------- --------------------------------
|
||||
}
|
||||
|
||||
private void initCheckBox(JCheckBox cb, String parameter, Parameter.ParameterType pType) {
|
||||
Parameter<Boolean> paraObj = new Parameter<>(parameter, pType, Boolean.class);
|
||||
cb.setSelected(paraObj.getValue());
|
||||
cb.addItemListener(new SettingsHandler.CheckBoxListener(paraObj));
|
||||
}
|
||||
|
||||
private void initComboBox(JComboBox<String> cb, String parameter, Parameter.ParameterType pType, String[] values) {
|
||||
Parameter<String> paraObj = new Parameter<>(parameter, pType, String.class, values);
|
||||
cb.setSelectedIndex(paraObj.getIndex());
|
||||
if (cb.getItemListeners().length == 0) cb.addItemListener(new SettingsHandler.ComboBoxListener(paraObj));
|
||||
}
|
||||
|
||||
private void initFolderChooser(JTextField showText, JButton actionButton, String parameter, Parameter.ParameterType pType, Callback.JFileSelectCallback check) {
|
||||
Parameter<String> paraObj = new Parameter<>(parameter, pType, String.class);
|
||||
showText.setText(paraObj.getValue());
|
||||
if (actionButton.getActionListeners().length == 0)
|
||||
actionButton.addActionListener(new SettingsHandler.Fileistener(mainPanel, paraObj, check));
|
||||
}
|
||||
|
||||
public void initSpinner(JSpinner spinner, String parameter, Parameter.ParameterType pType, int min, int max) {
|
||||
Parameter<String> paraObj = new Parameter<>(parameter, pType, String.class);
|
||||
|
||||
SpinnerNumberModel RAMModel = new SpinnerNumberModel(Integer.parseInt(paraObj.getValue()), min, max, 1);
|
||||
spinner.setModel(RAMModel);
|
||||
JComponent comp = spinner.getEditor();
|
||||
JFormattedTextField field = (JFormattedTextField) comp.getComponent(0);
|
||||
DefaultFormatter formatter = (DefaultFormatter) field.getFormatter();
|
||||
formatter.setCommitsOnValidEdit(false);
|
||||
spinner.addChangeListener(new SettingsHandler.SpinnerListener(paraObj));
|
||||
}
|
||||
|
||||
public void updateModList(Modset modset) {
|
||||
ListModel<String> model = (ListModel)modList.getModel();
|
||||
// TODO: RepositoryManger.downloadModlist
|
||||
// TODO: Show All Mods (keyname)
|
||||
// TODO: Show not installed Mods with red font
|
||||
// TODO: Select Mod if in modset.Mods
|
||||
// TODO: Custom Checkbox Render
|
||||
// TODO: Wenn modset.type == Server alle Checkboxen deaktivieren!
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(Object o) {
|
||||
String s = String.valueOf(o);
|
||||
|
||||
if (s.equals("refreshMeta")) {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
ServerTableModel model = (ServerTableModel) serverTable.getModel();
|
||||
|
||||
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);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
144
src/main/java/de/mc8051/arma3launcher/Parameter.java
Normal file
144
src/main/java/de/mc8051/arma3launcher/Parameter.java
Normal file
@ -0,0 +1,144 @@
|
||||
package de.mc8051.arma3launcher;
|
||||
|
||||
import org.ini4j.Ini;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* Created by gurkengewuerz.de on 24.03.2020.
|
||||
*/
|
||||
public class Parameter<T> {
|
||||
|
||||
private static Map<String, String> PARAMETERS = new HashMap<String, String>() {{
|
||||
put("profile", "name");
|
||||
put("nosplash", "noSplash");
|
||||
put("skipintro", "skipIntro");
|
||||
put("world", "world");
|
||||
put("maxmem", "maxMem");
|
||||
put("maxvram", "maxVRAM");
|
||||
put("nocb", "noCB");
|
||||
put("cpucount", "cpuCount");
|
||||
put("exthreads", "exThreads");
|
||||
put("malloc", "malloc");
|
||||
put("nologs", "noLogs");
|
||||
put("enableht", "enableHT");
|
||||
put("hugepages", "hugepages");
|
||||
put("nopause", "noPause");
|
||||
put("showscripterrors", "showScriptErrors");
|
||||
put("filepatching", "filePatching");
|
||||
put("init", "init");
|
||||
put("beta", "beta");
|
||||
put("crashdiag", "crashDiag");
|
||||
put("window", "window");
|
||||
put("posx", "posX");
|
||||
put("posy", "posY");
|
||||
|
||||
// use64bitclient -> arma3_x64.exe
|
||||
}};
|
||||
|
||||
private String name;
|
||||
private ParameterType pType;
|
||||
private Class<T> persistentClass;
|
||||
private String[] values = null;
|
||||
|
||||
public Parameter(String name, ParameterType pType, Class<T> persistentClass) {
|
||||
this(name, pType, persistentClass, null);
|
||||
}
|
||||
|
||||
public Parameter(String name, ParameterType pType, Class<T> persistentClass, String[] values) {
|
||||
this.name = name;
|
||||
this.pType = pType;
|
||||
this.persistentClass = persistentClass;
|
||||
this.values = values;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getUserConfigSectionName() {
|
||||
if (pType == ParameterType.CLIENT) return "client";
|
||||
if (pType == ParameterType.ARMA) return "arma";
|
||||
return "";
|
||||
}
|
||||
|
||||
public void save(T data) {
|
||||
T def = getDefault();
|
||||
|
||||
if (data == def || (persistentClass.getTypeName().equals("java.lang.String") && String.valueOf(data).equals(String.valueOf(def)))) {
|
||||
// remove entry from user config
|
||||
ArmA3Launcher.user_config.remove(getUserConfigSectionName(), name);
|
||||
} else {
|
||||
// save to user config
|
||||
Ini.Section section = ArmA3Launcher.user_config.get(getUserConfigSectionName());
|
||||
if (section == null) {
|
||||
section = ArmA3Launcher.user_config.add(getUserConfigSectionName());
|
||||
}
|
||||
if (section != null) {
|
||||
if (section.containsKey(name)) {
|
||||
ArmA3Launcher.user_config.remove(getUserConfigSectionName(), name);
|
||||
}
|
||||
section.add(name, data);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
ArmA3Launcher.user_config.store();
|
||||
} catch (IOException e) {
|
||||
Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, e);
|
||||
}
|
||||
}
|
||||
|
||||
public void save(int index) {
|
||||
if(values == null) throw new IllegalAccessError("call of save(int index) is only allowed for ComboBoxes");
|
||||
if(index > values.length - 1) throw new IndexOutOfBoundsException("index " + index + " is out of bound. Max: " + (values.length -1));
|
||||
save((T) values[index]);
|
||||
}
|
||||
|
||||
public String getParameter() {
|
||||
if(!PARAMETERS.containsKey(name.toLowerCase())) return null;
|
||||
return PARAMETERS.get(name.toLowerCase());
|
||||
}
|
||||
|
||||
public T getValue() {
|
||||
// Get User Value else Default else null
|
||||
Ini.Section section = ArmA3Launcher.user_config.get(getUserConfigSectionName());
|
||||
if (section != null) {
|
||||
if(section.containsKey(name)) {
|
||||
String val = section.get(name);
|
||||
|
||||
if (persistentClass.getTypeName().equals("java.lang.Boolean")) {
|
||||
return (T) (Boolean) Boolean.valueOf(val.toLowerCase());
|
||||
} else return (T) val;
|
||||
}
|
||||
}
|
||||
|
||||
return getDefault();
|
||||
}
|
||||
|
||||
public int getIndex() {
|
||||
if(values == null) throw new IllegalAccessError("call of save(int index) is only allowed for ComboBoxes");
|
||||
String value =String.valueOf(getValue());
|
||||
for(int i = 0; i < values.length; i++) {
|
||||
if(value.equalsIgnoreCase(values[i])) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public T getDefault() {
|
||||
if (persistentClass.getTypeName().equals("java.lang.Boolean")) {
|
||||
return (T) (Boolean) ArmA3Launcher.config.getBoolean( getUserConfigSectionName() + "." + name);
|
||||
} else if (persistentClass.getTypeName().equals("java.lang.String"))
|
||||
return (T) ArmA3Launcher.config.getString(getUserConfigSectionName()+ "." + name);
|
||||
else return null;
|
||||
}
|
||||
|
||||
enum ParameterType {
|
||||
ARMA,
|
||||
CLIENT
|
||||
}
|
||||
}
|
103
src/main/java/de/mc8051/arma3launcher/SettingsHandler.java
Normal file
103
src/main/java/de/mc8051/arma3launcher/SettingsHandler.java
Normal file
@ -0,0 +1,103 @@
|
||||
package de.mc8051.arma3launcher;
|
||||
|
||||
import de.mc8051.arma3launcher.utils.Callback;
|
||||
import de.mc8051.arma3launcher.utils.LangUtils;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.ItemEvent;
|
||||
import java.awt.event.ItemListener;
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* Created by gurkengewuerz.de on 24.03.2020.
|
||||
*/
|
||||
public class SettingsHandler {
|
||||
|
||||
public static class CheckBoxListener implements ItemListener {
|
||||
private Parameter<Boolean> parameter;
|
||||
|
||||
public CheckBoxListener(Parameter<Boolean> parameter) {
|
||||
this.parameter = parameter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void itemStateChanged(ItemEvent e) {
|
||||
parameter.save(e.getStateChange() == ItemEvent.SELECTED);
|
||||
}
|
||||
}
|
||||
|
||||
public static class ComboBoxListener implements ItemListener {
|
||||
|
||||
private Parameter<String> parameter;
|
||||
|
||||
public ComboBoxListener(Parameter<String> parameter) {
|
||||
this.parameter = parameter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void itemStateChanged(ItemEvent e) {
|
||||
if (e.getStateChange() == ItemEvent.SELECTED) {
|
||||
parameter.save(((JComboBox) e.getItemSelectable()).getSelectedIndex());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class Fileistener implements ActionListener {
|
||||
|
||||
private JPanel parent;
|
||||
private Parameter<String> parameter;
|
||||
private Callback.JFileSelectCallback check;
|
||||
|
||||
public Fileistener(JPanel parent, Parameter<String> parameter, Callback.JFileSelectCallback check) {
|
||||
this.parent = parent;
|
||||
this.parameter = parameter;
|
||||
this.check = check;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
JFileChooser chooser = new JFileChooser();
|
||||
|
||||
chooser.setCurrentDirectory(new File("."));
|
||||
chooser.setDialogTitle(LangUtils.getInstance().getString("select_folder"));
|
||||
chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
|
||||
chooser.setAcceptAllFileFilterUsed(false);
|
||||
|
||||
if (chooser.showOpenDialog(parent) == JFileChooser.APPROVE_OPTION) {
|
||||
File path = chooser.getSelectedFile();
|
||||
if(check.allowSelection(path)) {
|
||||
parameter.save(path.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public static class SpinnerListener implements ChangeListener {
|
||||
|
||||
private static long lastChange = -1;
|
||||
private Parameter<String> parameter;
|
||||
|
||||
public SpinnerListener(Parameter<String> parameter) {
|
||||
this.parameter = parameter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stateChanged(ChangeEvent e) {
|
||||
long time = System.currentTimeMillis();
|
||||
if(lastChange == -1 || time - lastChange > 500) {
|
||||
lastChange = time;
|
||||
parameter.save(String.valueOf(((JSpinner) e.getSource()).getValue()));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
29
src/main/java/de/mc8051/arma3launcher/SteamUtils.java
Normal file
29
src/main/java/de/mc8051/arma3launcher/SteamUtils.java
Normal file
@ -0,0 +1,29 @@
|
||||
package de.mc8051.arma3launcher;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Created by gurkengewuerz.de on 23.03.2020.
|
||||
*/
|
||||
public class SteamUtils {
|
||||
|
||||
public static boolean findProcess(String findProcess) throws IOException {
|
||||
String filenameFilter = "/nh /fi \"Imagename eq "+findProcess+"\"";
|
||||
String tasksCmd = System.getenv("windir") +"/system32/tasklist.exe "+filenameFilter;
|
||||
|
||||
Process p = Runtime.getRuntime().exec(tasksCmd);
|
||||
BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
|
||||
|
||||
ArrayList<String> procs = new ArrayList<String>();
|
||||
String line = null;
|
||||
while ((line = input.readLine()) != null)
|
||||
procs.add(line);
|
||||
|
||||
input.close();
|
||||
|
||||
return procs.stream().anyMatch(row -> row.contains(findProcess));
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
package de.mc8051.arma3launcher.interfaces;
|
||||
|
||||
/**
|
||||
* Created by gurkengewuerz.de on 25.03.2020.
|
||||
*/
|
||||
public interface Observable {
|
||||
|
||||
public void addObserver(Observer observer);
|
||||
public void removeObserver(Observer observer);
|
||||
public void notifyObservers(Object obj);
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
package de.mc8051.arma3launcher.interfaces;
|
||||
|
||||
/**
|
||||
* Created by gurkengewuerz.de on 25.03.2020.
|
||||
*/
|
||||
public interface Observer {
|
||||
|
||||
public void update(Object o);
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
package de.mc8051.arma3launcher.model;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* Created by gurkengewuerz.de on 25.03.2020.
|
||||
*/
|
||||
public class ModListRenderer extends JCheckBox implements ListCellRenderer {
|
||||
|
||||
public Component getListCellRendererComponent(JList list, Object value, int index,
|
||||
boolean isSelected, boolean cellHasFocus) {
|
||||
|
||||
setComponentOrientation(list.getComponentOrientation());
|
||||
setFont(list.getFont());
|
||||
setBackground(list.getBackground());
|
||||
setForeground(list.getForeground());
|
||||
setSelected(isSelected);
|
||||
setEnabled(list.isEnabled());
|
||||
|
||||
setText(value == null ? "" : value.toString());
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
package de.mc8051.arma3launcher.model;
|
||||
|
||||
import de.mc8051.arma3launcher.objects.Modset;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
import javax.swing.border.MatteBorder;
|
||||
import javax.swing.border.TitledBorder;
|
||||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* Created by gurkengewuerz.de on 25.03.2020.
|
||||
*/
|
||||
public class PresetListRenderer extends JLabel implements ListCellRenderer {
|
||||
JPanel separator;
|
||||
|
||||
public PresetListRenderer() {
|
||||
setOpaque(true);
|
||||
setBorder(new EmptyBorder(0, 0, 0, 0));
|
||||
|
||||
MatteBorder mb = new MatteBorder(1, 0, 0, 0, Color.BLACK);
|
||||
TitledBorder tb = new TitledBorder(mb, "", TitledBorder.CENTER, TitledBorder.DEFAULT_POSITION);
|
||||
separator = new JPanel();
|
||||
separator.setBorder(tb);
|
||||
separator.setPreferredSize(new Dimension(-1, 20));
|
||||
}
|
||||
|
||||
public Component getListCellRendererComponent(JList list, Object value,
|
||||
int index, boolean isSelected, boolean cellHasFocus) {
|
||||
Modset m = value == null ? new Modset("", Modset.Type.CLIENT,null, false) : (Modset) value;
|
||||
if (m.getName().startsWith("--")) {
|
||||
((TitledBorder)separator.getBorder()).setTitle(m.getName().substring(2));
|
||||
return separator;
|
||||
}
|
||||
if (isSelected) {
|
||||
setBackground(list.getSelectionBackground());
|
||||
} else {
|
||||
setBackground(list.getBackground());
|
||||
}
|
||||
setFont(list.getFont());
|
||||
setText(m.getName());
|
||||
return this;
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
package de.mc8051.arma3launcher.model;
|
||||
|
||||
import de.mc8051.arma3launcher.objects.Modset;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Created by gurkengewuerz.de on 25.03.2020.
|
||||
*/
|
||||
public class PresetTableModel extends AbstractListModel {
|
||||
|
||||
private ArrayList<Modset> data = new ArrayList<>();
|
||||
|
||||
public void add(Modset m){
|
||||
data.add(m);
|
||||
fireContentsChanged(this, 0, data.size());
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
data.clear();
|
||||
fireContentsChanged(this, 0, data.size());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSize() {
|
||||
return data.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getElementAt(int index) {
|
||||
return data.get(index);
|
||||
}
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
package de.mc8051.arma3launcher.model;
|
||||
|
||||
import de.mc8051.arma3launcher.objects.Server;
|
||||
import de.mc8051.arma3launcher.utils.LangUtils;
|
||||
|
||||
import javax.swing.table.AbstractTableModel;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by gurkengewuerz.de on 24.03.2020.
|
||||
*/
|
||||
public class ServerTableModel extends AbstractTableModel {
|
||||
|
||||
private String[] columnNames = {
|
||||
LangUtils.getInstance().getString("description"),
|
||||
LangUtils.getInstance().getString("ip_address"),
|
||||
LangUtils.getInstance().getString("port"),
|
||||
LangUtils.getInstance().getString("preset")
|
||||
};
|
||||
private List<Server> data = new ArrayList<>();
|
||||
|
||||
public String getColumnName(int col) {
|
||||
return columnNames[col];
|
||||
}
|
||||
|
||||
public void add(Server s) {
|
||||
data.add(s);
|
||||
fireTableDataChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRowCount() {
|
||||
return data.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getColumnCount() {
|
||||
return columnNames.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getValueAt(int rowIndex, int columnIndex) {
|
||||
if (columnIndex == 0) return data.get(rowIndex).getName();
|
||||
else if (columnIndex == 1) return data.get(rowIndex).getIp();
|
||||
else if (columnIndex == 2) return data.get(rowIndex).getPort();
|
||||
else if (columnIndex == 3) return data.get(rowIndex).getPreset().getName();
|
||||
return null;
|
||||
}
|
||||
}
|
17
src/main/java/de/mc8051/arma3launcher/objects/Mod.java
Normal file
17
src/main/java/de/mc8051/arma3launcher/objects/Mod.java
Normal file
@ -0,0 +1,17 @@
|
||||
package de.mc8051.arma3launcher.objects;
|
||||
|
||||
/**
|
||||
* Created by gurkengewuerz.de on 25.03.2020.
|
||||
*/
|
||||
public class Mod {
|
||||
|
||||
private String name;
|
||||
|
||||
public Mod(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
}
|
63
src/main/java/de/mc8051/arma3launcher/objects/Modset.java
Normal file
63
src/main/java/de/mc8051/arma3launcher/objects/Modset.java
Normal file
@ -0,0 +1,63 @@
|
||||
package de.mc8051.arma3launcher.objects;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by gurkengewuerz.de on 25.03.2020.
|
||||
*/
|
||||
public class Modset {
|
||||
|
||||
public static HashMap<String, Modset> MODSET_LIST = new HashMap<>();
|
||||
|
||||
private String name;
|
||||
private Type type;
|
||||
private List<Mod> mods = new ArrayList<>();
|
||||
|
||||
public Modset(String name, Type type, List<Mod> mods) {
|
||||
this(name, type, mods, true);
|
||||
}
|
||||
|
||||
public Modset(String name, Type type, List<Mod> mods, boolean add) {
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
this.mods = mods;
|
||||
|
||||
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++){
|
||||
mods.add(new Mod(modlist.getString(j)));
|
||||
}
|
||||
|
||||
this.type = type;
|
||||
|
||||
MODSET_LIST.put(name, this);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public List<Mod> getMods() {
|
||||
return mods;
|
||||
}
|
||||
|
||||
public Type getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public static enum Type {
|
||||
SERVER,
|
||||
CLIENT
|
||||
}
|
||||
}
|
62
src/main/java/de/mc8051/arma3launcher/objects/Server.java
Normal file
62
src/main/java/de/mc8051/arma3launcher/objects/Server.java
Normal file
@ -0,0 +1,62 @@
|
||||
package de.mc8051.arma3launcher.objects;
|
||||
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* Created by gurkengewuerz.de on 25.03.2020.
|
||||
*/
|
||||
public class Server {
|
||||
|
||||
public static HashMap<String, Server> SERVER_LIST = new HashMap<>();
|
||||
|
||||
private String name;
|
||||
private String password;
|
||||
private String ip;
|
||||
private int port;
|
||||
private Modset preset;
|
||||
|
||||
public Server(String name, String password, String ip, int port, Modset preset) {
|
||||
this.name = name;
|
||||
this.password = password;
|
||||
this.ip = ip;
|
||||
this.port = port;
|
||||
this.preset = preset;
|
||||
|
||||
SERVER_LIST.put(name, this);
|
||||
}
|
||||
|
||||
public Server(JSONObject o) {
|
||||
if(!o.has("name") || !o.has("password") || !o.has("ipaddress") || !o.has("port") || !o.has("preset")) return;
|
||||
name = o.getString("name");
|
||||
password = o.getString("password");
|
||||
ip = o.getString("ipaddress");
|
||||
port = o.getInt("port");
|
||||
|
||||
if(!Modset.MODSET_LIST.containsKey(o.getString("preset"))) return;
|
||||
preset = Modset.MODSET_LIST.get(o.getString("preset"));
|
||||
|
||||
SERVER_LIST.put(name, this);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public String getIp() {
|
||||
return ip;
|
||||
}
|
||||
|
||||
public int getPort() {
|
||||
return port;
|
||||
}
|
||||
|
||||
public Modset getPreset() {
|
||||
return preset;
|
||||
}
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
package de.mc8051.arma3launcher.repo;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* Created by gurkengewuerz.de on 24.03.2020.
|
||||
*/
|
||||
public class DownloadThread implements Runnable {
|
||||
|
||||
private ProcessBuilder processBuilder;
|
||||
private Process process;
|
||||
private Thread thread;
|
||||
|
||||
private Status status = Status.PENDING;
|
||||
|
||||
public DownloadThread(ProcessBuilder processBuilder) {
|
||||
this.processBuilder = processBuilder;
|
||||
this.processBuilder.redirectErrorStream(true);
|
||||
|
||||
thread = new Thread(this);
|
||||
thread.start();
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
process.destroy();
|
||||
thread.interrupt();
|
||||
}
|
||||
|
||||
public Status getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
process = processBuilder.start();
|
||||
status = Status.RUNNING;
|
||||
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
|
||||
String line;
|
||||
while ( (line = reader.readLine()) != null && !thread.isInterrupted()) {
|
||||
System.out.println(line);
|
||||
}
|
||||
|
||||
int exitVal = process.waitFor();
|
||||
if(exitVal == 0) status = Status.FINNISHED;
|
||||
else status = Status.ERROR;
|
||||
|
||||
System.out.println(exitVal);
|
||||
} catch (IOException | InterruptedException ex) {
|
||||
Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex);
|
||||
status = Status.ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
private enum Status {
|
||||
PENDING(0),
|
||||
RUNNING(1),
|
||||
FINNISHED(2),
|
||||
ERROR(3);
|
||||
|
||||
Status(int i) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
109
src/main/java/de/mc8051/arma3launcher/repo/RepositoryManger.java
Normal file
109
src/main/java/de/mc8051/arma3launcher/repo/RepositoryManger.java
Normal file
@ -0,0 +1,109 @@
|
||||
package de.mc8051.arma3launcher.repo;
|
||||
|
||||
import de.mc8051.arma3launcher.ArmA3Launcher;
|
||||
import de.mc8051.arma3launcher.interfaces.Observable;
|
||||
import de.mc8051.arma3launcher.interfaces.Observer;
|
||||
import de.mc8051.arma3launcher.objects.Modset;
|
||||
import de.mc8051.arma3launcher.objects.Server;
|
||||
import de.mc8051.arma3launcher.utils.Callback;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* Created by gurkengewuerz.de on 24.03.2020.
|
||||
*/
|
||||
public class RepositoryManger implements Observable {
|
||||
|
||||
private static RepositoryManger instance;
|
||||
private List<Observer> observerList = new ArrayList<>();
|
||||
private OkHttpClient client = new OkHttpClient();
|
||||
|
||||
private RepositoryManger() {
|
||||
}
|
||||
|
||||
public void refreshMeta() {
|
||||
downloadMeta(new Callback.HttpCallback() {
|
||||
@Override
|
||||
public void response(Response r) {
|
||||
if (!r.isSuccessful()) {
|
||||
Logger.getLogger(getClass().getName()).log(Level.SEVERE, "Cant open " + r.request().url().toString() + " code " + r.code());
|
||||
RepositoryManger.getInstance().notifyObservers("refreshMetaFailed");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
JSONObject jsonObject = new JSONObject(r.body().string());
|
||||
|
||||
if (jsonObject.has("modsets")) {
|
||||
JSONArray modsets = jsonObject.getJSONArray("modsets");
|
||||
if (modsets.length() > 0) {
|
||||
for (int i = 0; i < modsets.length(); i++) {
|
||||
JSONObject modset = modsets.getJSONObject(i);
|
||||
new Modset(modset, Modset.Type.SERVER);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Init servers after modsets because server search preset string in modsets
|
||||
if (jsonObject.has("servers")) {
|
||||
JSONArray servers = jsonObject.getJSONArray("servers");
|
||||
if (servers.length() > 0) {
|
||||
for (int i = 0; i < servers.length(); i++) {
|
||||
JSONObject server = servers.getJSONObject(i);
|
||||
new Server(server);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RepositoryManger.getInstance().notifyObservers("refreshMeta");
|
||||
} catch (IOException | NullPointerException e) {
|
||||
Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void downloadMeta(Callback.HttpCallback callback) {
|
||||
new Thread(() -> {
|
||||
try {
|
||||
Request request = new Request.Builder()
|
||||
.url(ArmA3Launcher.config.getString("sync.url") + "/.sync/server.json")
|
||||
.build();
|
||||
|
||||
callback.response(client.newCall(request).execute());
|
||||
} catch (IOException e) {
|
||||
Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, e);
|
||||
callback.response(null);
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
public static RepositoryManger getInstance() {
|
||||
if (instance == null) instance = new RepositoryManger();
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addObserver(Observer observer) {
|
||||
observerList.add(observer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeObserver(Observer observer) {
|
||||
observerList.remove(observer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyObservers(Object obj) {
|
||||
for (Observer obs : observerList) obs.update(obj);
|
||||
}
|
||||
}
|
60
src/main/java/de/mc8051/arma3launcher/steam/SteamTimer.java
Normal file
60
src/main/java/de/mc8051/arma3launcher/steam/SteamTimer.java
Normal file
@ -0,0 +1,60 @@
|
||||
package de.mc8051.arma3launcher.steam;
|
||||
|
||||
import de.mc8051.arma3launcher.LauncherGUI;
|
||||
import de.mc8051.arma3launcher.SteamUtils;
|
||||
import de.ralleytn.simple.registry.Key;
|
||||
import de.ralleytn.simple.registry.Registry;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.TimerTask;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* Created by gurkengewuerz.de on 23.03.2020.
|
||||
*/
|
||||
public class SteamTimer extends TimerTask {
|
||||
|
||||
public static boolean steam_running = false;
|
||||
public static boolean arma_running = false;
|
||||
|
||||
private LauncherGUI gui;
|
||||
|
||||
public SteamTimer(LauncherGUI gui) {
|
||||
this.gui = gui;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
String OS = System.getProperty("os.name").toUpperCase();
|
||||
if (!OS.contains("WIN")) return;
|
||||
|
||||
try {
|
||||
if(!SteamUtils.findProcess("steam.exe")) {
|
||||
steam_running = false;
|
||||
gui.updateLabels(steam_running, arma_running);
|
||||
return;
|
||||
}
|
||||
|
||||
Key activeSteamUserKey = Registry.getKey(Registry.HKEY_CURRENT_USER + "\\Software\\Valve\\Steam\\ActiveProcess");
|
||||
|
||||
String activeSteamUser = activeSteamUserKey.getValueByName("ActiveUser").getRawValue();
|
||||
|
||||
if(activeSteamUser.equals("0x0")) {
|
||||
steam_running = false;
|
||||
gui.updateLabels(steam_running, arma_running);
|
||||
return;
|
||||
}
|
||||
|
||||
steam_running = true;
|
||||
|
||||
arma_running = SteamUtils.findProcess("arma3.exe") || SteamUtils.findProcess("arma3_x64.exe") || SteamUtils.findProcess("arma3launcher.exe");
|
||||
} catch (IOException e) {
|
||||
steam_running = false;
|
||||
arma_running = false;
|
||||
Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, e);
|
||||
}
|
||||
|
||||
gui.updateLabels(steam_running, arma_running);
|
||||
}
|
||||
}
|
19
src/main/java/de/mc8051/arma3launcher/utils/Callback.java
Normal file
19
src/main/java/de/mc8051/arma3launcher/utils/Callback.java
Normal file
@ -0,0 +1,19 @@
|
||||
package de.mc8051.arma3launcher.utils;
|
||||
|
||||
import okhttp3.Response;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* Created by gurkengewuerz.de on 24.03.2020.
|
||||
*/
|
||||
public class Callback {
|
||||
|
||||
public static interface JFileSelectCallback { //declare an interface with the callback methods, so you can use on more than one class and just refer to the interface
|
||||
boolean allowSelection(File path);
|
||||
}
|
||||
|
||||
public static interface HttpCallback {
|
||||
void response(Response r);
|
||||
}
|
||||
}
|
26
src/main/java/de/mc8051/arma3launcher/utils/LangUtils.java
Normal file
26
src/main/java/de/mc8051/arma3launcher/utils/LangUtils.java
Normal file
@ -0,0 +1,26 @@
|
||||
package de.mc8051.arma3launcher.utils;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
/**
|
||||
* Created by gurkengewuerz.de on 24.03.2020.
|
||||
*/
|
||||
public class LangUtils {
|
||||
|
||||
private static LangUtils i;
|
||||
|
||||
private ResourceBundle r = ResourceBundle.getBundle("lang", Locale.getDefault());
|
||||
|
||||
private LangUtils() {
|
||||
}
|
||||
|
||||
public String getString(String key) {
|
||||
return r.getString(key);
|
||||
}
|
||||
|
||||
public static LangUtils getInstance() {
|
||||
if(i == null) i = new LangUtils();
|
||||
return i;
|
||||
}
|
||||
}
|
43
src/main/resources/arma3launcher.json
Normal file
43
src/main/resources/arma3launcher.json
Normal file
@ -0,0 +1,43 @@
|
||||
{
|
||||
"version": "0.1.1",
|
||||
"name": "TheTown Client",
|
||||
"title": "Welcome! :P",
|
||||
"subtitle": "${name} v${version}",
|
||||
"sync": {
|
||||
"url": "http://46.4.195.36"
|
||||
},
|
||||
"client": {
|
||||
"armaPath": "",
|
||||
"modPath": "",
|
||||
"ShowStartParameter": true,
|
||||
"CheckModset": false,
|
||||
"UseWorkshop": false,
|
||||
"behaviourAfterStart": "nothing",
|
||||
"language": "system"
|
||||
},
|
||||
"arma": {
|
||||
"Profile": "",
|
||||
"Use64BitClient": true,
|
||||
"NoSplash": true,
|
||||
"SkipIntro": true,
|
||||
"World": "",
|
||||
"MaxMem": -1,
|
||||
"MaxVRAM": -1,
|
||||
"NoCB": false,
|
||||
"CpuCount": 0,
|
||||
"ExThreads": "",
|
||||
"Malloc": "",
|
||||
"NoLogs": false,
|
||||
"EnableHT": false,
|
||||
"Hugepages": false,
|
||||
"NoPause": false,
|
||||
"ShowScriptErrors": true,
|
||||
"FilePatching": false,
|
||||
"Init": "",
|
||||
"Beta": "",
|
||||
"CrashDiag": false,
|
||||
"Window": false,
|
||||
"PosX": -1,
|
||||
"PosY": -1
|
||||
}
|
||||
}
|
82
src/main/resources/lang_de_DE.properties
Normal file
82
src/main/resources/lang_de_DE.properties
Normal file
@ -0,0 +1,82 @@
|
||||
abort=Abbrechen
|
||||
arm33_parameter=ArmA 3 Startparameter
|
||||
arma3_installpath=ArmA 3 Installationspfad
|
||||
backend_url=Backend-URL
|
||||
behaviour_aafter_start=Verhalten nach dem Start
|
||||
beta_desc=Es können Daten aus Unterverzeichnissen mitgestartet werden.
|
||||
check=Überprüfen
|
||||
check_modset=Modset automatisch überprüfen
|
||||
client_settings=Client Einstellungen
|
||||
clone=Klonen
|
||||
closed=geschlossen
|
||||
common=Allgemein
|
||||
cpucount_desc=Gibt an, wie viele Kerne der CPU von Arma 3 genutzt werden sollen.
|
||||
crashdiag_desc=Zusätzlich zur RPT wird beim Arma-Absturz ein Log vom Crash in einer binarisierten Datei abgelegt.
|
||||
description=Bezeichnung
|
||||
developer_settings=Entwicklereinstellungen
|
||||
display_settings=Anzeigeeinstellungen
|
||||
download=Download
|
||||
downloaded=Heruntergeladen
|
||||
enableht_desc=Sollte eure CPU das sog. „Hyper-Threading“ unterstützen, kann dies für Arma 3 mit dieser Option aktiviert werden (wird von CpuCount überschrieben).
|
||||
expand_all=Alles ausklappen
|
||||
exthreads_desc=Je nach eingegebenen Wert werden ein oder mehrere bestimmte Kerne der CPU für Arma 3 genutzt (3 für Dualcore, 7 für Quadcore).
|
||||
filepatching_desc=Ist die Option aktiv, können ungepackte Daten geladen werden (bpsw. Daten außerhalb von PBO’s).
|
||||
hugepages_desc=Die von der CPU markierten Bereiche des für Arma 3 genutzten RAM werden vergrößert. Kann unter Umständen die Fehleranfälligkeit verringern.
|
||||
init_desc=Führt einen Script-Befehl nach Spielstart im Hauptmenü aus.
|
||||
ip_address=IP-Adresse
|
||||
language=Sprache
|
||||
malloc_desc=Soll ein sog. „Memory Allucator“ zur Performance-Optimierung eingesetzt werden, wird dieser hier eingetragen.
|
||||
maxmem_desc=Hier kann die Limitierung des für Arma 3 zugewiesenen RAM verändert werden (je nach Betriebssystem und verwendeter .exe wird der Wert gekappt).
|
||||
maxvram_desc=Diese Option definiert die Zuweisung des Speichers der Grafikkarte für Arma 3, wird aber unter normalen Bedingungen ignoriert.
|
||||
modset_folder=Modset Installationspfad
|
||||
new=Neu
|
||||
nocb_desc=Ist diese Option aktiv, nutzt Arma 3 nur einen Kern der CPU.
|
||||
nologs_desc=Fehlermeldungen werden bei aktivierter Option nicht mehr in der sog. „RPT“ gespeichert, was die Fehlerbehebung bei Problemen mit Arma 3 erheblich erschwert.
|
||||
nopause_desc=Das Spiel läuft im Singleplayer-Modus auch dann im Hintergrund weiter, wenn es minimiert wird. Vergleichbar mit dem Multiplayer, da dort trotz minimiertem Spiel selbiges weitergeht.
|
||||
nosplash_desc=Ist diese Option aktiviert wird die Seite mit den Logos während des Spielstarts nicht mehr gezeigt.
|
||||
not_arma_dir=Das sieht irgendwie nicht nach deinem Arma-Verzeichnis aus...
|
||||
not_arma_dir_msg=Überprüfe ob sich in diesem Ordner auch eine arma3.exe befindet.\
|
||||
Der Ordner wurde jedoch trotzdem übernommen!
|
||||
pause=Pause
|
||||
performance=Performance
|
||||
play=Spielen
|
||||
play_now=Spiele Jetzt!
|
||||
port=Port
|
||||
posx_desc=Position (nicht Größe) des Fensters im Fenstermodus (X-Achse, horizontal).
|
||||
posy_desc=Das Pendant zu PosX, nur für die Y-Achse (die Vertikale oder „Rauf auf den Baum“).
|
||||
preset=Vorlage
|
||||
preset_settings=Vorlagen Einstellungen
|
||||
presets=Vorlagen
|
||||
profile_desc=Profil, welches beim Arma-Start geladen werden soll.
|
||||
progress=Fortschritt
|
||||
remaining_time=Verbleibende Zeit
|
||||
remove=Entfernen
|
||||
rename=Umbennen
|
||||
repository_content=Repository Inhalt
|
||||
reset_default=Auf Standard zurücksetzten
|
||||
running=gestartet
|
||||
select_all=Alles auswählen
|
||||
select_folder=Ordner auswählen
|
||||
select_mods=Mods auswählen
|
||||
select_server=Server-Auswahl
|
||||
settings=Einstellungen
|
||||
show_startparameter=Startparameter anzeigen
|
||||
showscripterrors_desc=Fehler in Scripten werden in einem Hinweistext signalisiert.
|
||||
signed_in=eingeloggt
|
||||
speed=Geschwindigkeit
|
||||
speed_up_game=Spielstart beschleunigen
|
||||
spikintro_desc=Die Intro-Sequenz wird übersprungen.
|
||||
total_file_size=Gesamtgröße
|
||||
update=Update
|
||||
use64bitclient_desc=Startet Arma3 mit der für 64-Bit Betriebssysteme optimierten .exe-Datei (kann die Performance von Arma 3 verbessern und Probleme beheben (bspw. 3-FPS-Bug).
|
||||
use_workshop=Versuche Workshop Inhalte zu nutzen
|
||||
use_workshop_desc=Bei großen Modspacks versucht der Client bereits heruntergeladene Workshop Inhalte, die gleich sind, zu kopieren um so den Download schneller zu gestalten
|
||||
warning=Warnung
|
||||
warning_workshop=Der Client versucht sein bestes die gleichen Dateien zu finden,\
|
||||
jedoch kann es vorkommen das es nicht die identischen Dateien sind.\
|
||||
Im Falle eines Fehlgeschlagenem Syncen mit dieser Option, solltest\
|
||||
du sie deaktivieren und ohne diese Option erneut syncen.\
|
||||
\
|
||||
Ebenfalls könnte es zu kurzen Performance einbußen kommen.
|
||||
window_desc=Ist diese Option aktiv, wird Arma 3 im Fenstermodus gestartet.
|
||||
world_desc=Hier kann eine Karte eingetragen werden, die geladen und in den Menüs als Hintergrund angezeigt werden soll (z.B. „altis“ oder „stratis“ – ohne Anführungszeichen!). Ist das Feld leer, wird keine Karte während des Startens geladen und der Start von Arma 3 ist entsprechend schneller.
|
81
src/main/resources/lang_en_US.properties
Normal file
81
src/main/resources/lang_en_US.properties
Normal file
@ -0,0 +1,81 @@
|
||||
abort=Abort
|
||||
arm33_parameter=ArmA 3 Start parameters
|
||||
arma3_installpath=ArmA 3 Installation path
|
||||
backend_url=Backend URL
|
||||
behaviour_aafter_start=Behaviour after start
|
||||
beta_desc=Data from subdirectories can be started as well.
|
||||
check=Check
|
||||
check_modset=Check Modset automatically
|
||||
client_settings=Client Settings
|
||||
clone=Clone
|
||||
closed=closed
|
||||
common=Common
|
||||
cpucount_desc=Specifies how many cores of the CPU should be used by Arma 3.
|
||||
crashdiag_desc=In addition to the RPT, a log of the crash is stored in a binarized file.
|
||||
description=Description
|
||||
developer_settings=Developer settings
|
||||
display_settings=Display settings
|
||||
download=Download
|
||||
downloaded=Downloaded
|
||||
enableht_desc=If your CPU supports the so-called "Hyper-Threading", this can be activated for Arma 3 with this option (will be overwritten by CpuCount)
|
||||
expand_all=Expand All
|
||||
exthreads_desc=Depending on the value entered, one or more specific cores of the CPU are used for Arma 3 (3 for dualcore, 7 for quadcore).
|
||||
filepatching_desc=If the option is active, unpacked data can be loaded (e.g. data outside PBOs).
|
||||
hugepages_desc=The areas of RAM used for Arma 3 marked by the CPU are increased. This may reduce error susceptibility under certain circumstances.
|
||||
init_desc=Executes a script command after game start in the main menu.
|
||||
ip_address=IP-Address
|
||||
language=Language
|
||||
malloc_desc=If a so-called "Memory Allucator" is to be used for performance optimization, it is entered here.
|
||||
maxmem_desc=Here you can change the limit of the RAM allocated for Arma 3 (depending on the operating system and the .exe used, the value is capped)
|
||||
maxvram_desc=This option defines the allocation of the graphics card memory for Arma 3, but is ignored under normal conditions.
|
||||
modset_folder=Modset Installation path
|
||||
new=New
|
||||
nocb_desc=If this option is enabled, Arma 3 uses only one core of the CPU.
|
||||
nologs_desc=Error messages are no longer stored in the so-called "RPT" when this option is activated, which makes troubleshooting problems with Arma 3 much more difficult.
|
||||
nopause_desc=The game continues to run in the background in single player mode even when minimized. Comparable to the multiplayer mode, as the game continues in the background even when minimized.
|
||||
nosplash_desc=If this option is activated, the page with the logos is no longer shown during the game start.
|
||||
not_arma_dir=This doesn't look like your ArmA directory...
|
||||
not_arma_dir_msg=The selected folder does not look like an ArmA directory. Check if there is also an arma3.exe in this folder.\
|
||||
But the folder was still saved!
|
||||
pause=Pause
|
||||
performance=Performance
|
||||
play=Play
|
||||
play_now=Play now on the server!
|
||||
port=Port
|
||||
posx_desc=Position (not size) of the window in window mode (X axis, horizontal).
|
||||
posy_desc=The counterpart to PosX, only for the Y-axis (the vertical or "Up the tree").
|
||||
preset=Preset
|
||||
preset_settings=Presets settings
|
||||
presets=Presets
|
||||
profile_desc=Profile to be loaded at Arma startup.
|
||||
progress=Progress
|
||||
remaining_time=Remaining time
|
||||
remove=Remove
|
||||
rename=Rename
|
||||
reset_default=Reset to default
|
||||
running=running
|
||||
select_all=Select All
|
||||
select_folder=Choose folder
|
||||
select_mods=Select mods
|
||||
select_server=Select Server
|
||||
settings=Settings
|
||||
show_startparameter=Show start parameters
|
||||
showscripterrors_desc=Errors in scripts are signaled in a message text.
|
||||
signed_in=signed in
|
||||
speed=Speed
|
||||
speed_up_game=Speed up game start
|
||||
spikintro_desc=The intro sequence is skipped.
|
||||
total_file_size=Total file size
|
||||
update=Update
|
||||
use64bitclient_desc=Starts Arma3 with the .exe file optimized for 64-bit operating systems (can improve the performance of Arma 3 and fix problems (e.g. 3-FPS bug)
|
||||
use_workshop=Try to use workshop content
|
||||
use_workshop_desc=For large modspacks, the client tries to copy already downloaded workshop content that is the same to make the download faster
|
||||
warning=Warning
|
||||
warning_workshop=The client tries its best to find the same files,\
|
||||
but it can happen that they are not the same files.\
|
||||
In case of a failed sync with this option, you should\
|
||||
you deactivate it and sync again without this option.\
|
||||
\
|
||||
This could also lead to short performance losses.
|
||||
window_desc=If this option is active, Arma 3 is started in windowed mode.
|
||||
world_desc=Here you can enter a card to be loaded and displayed as background in the menus (e.g. "altis" or "stratis" - without quotation marks!). If the field is empty, no map will be loaded during startup and the start of Arma 3 will be faster.
|
Loading…
Reference in New Issue
Block a user