init repo

This commit is contained in:
Niklas 2020-03-25 05:32:38 +01:00
commit 73fbf00bee
28 changed files with 3543 additions and 0 deletions

5
.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
*.iml
.idea/
out/
META-INF/
target/

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
View 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
View 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
View 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>

View 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"));
}
}

File diff suppressed because it is too large Load Diff

View 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);
});
});
}
}
}

View 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
}
}

View 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()));
}
}
}
}

View 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));
}
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View 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;
}
}

View 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
}
}

View 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;
}
}

View File

@ -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) {
}
}
}

View 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);
}
}

View 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);
}
}

View 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);
}
}

View 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;
}
}

View 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
}
}

View 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 PBOs).
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.

View 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.