From 611adf512f6e89d6f425cbea0cc805b023027cb9 Mon Sep 17 00:00:00 2001 From: Scoppio Date: Sun, 23 Feb 2025 03:04:39 -0300 Subject: [PATCH 1/3] fix: fix a parsing error and turns it into a singleton using enum --- .../generator/RandomCallsignGenerator.java | 89 +++++-------------- 1 file changed, 21 insertions(+), 68 deletions(-) diff --git a/megamek/src/megamek/client/generator/RandomCallsignGenerator.java b/megamek/src/megamek/client/generator/RandomCallsignGenerator.java index 4a7087aa7a4..79b6a93bf92 100644 --- a/megamek/src/megamek/client/generator/RandomCallsignGenerator.java +++ b/megamek/src/megamek/client/generator/RandomCallsignGenerator.java @@ -37,86 +37,39 @@ * Callsign is a String that does not include a ',' * Weight is an integer weight that is used during generation */ -public class RandomCallsignGenerator implements Serializable { - private final static MMLogger logger = MMLogger.create(RandomCallsignGenerator.class); - - // region Variable Declarations - private static final long serialVersionUID = 4721410214327210288L; +public enum RandomCallsignGenerator { + INSTANCE; - private static WeightedIntMap weightedCallsigns; + private final static MMLogger logger = MMLogger.create(RandomCallsignGenerator.class); - private static RandomCallsignGenerator rcg; + private final WeightedIntMap weightedCallsigns = new WeightedIntMap<>(); - private static volatile boolean initialized = false; // volatile to ensure readers get the current version - // endregion Variable Declarations + RandomCallsignGenerator() { + final Map callsigns = new HashMap<>(); + loadCallsignsFromFile(new File(MMConstants.CALLSIGN_FILE_PATH), callsigns); + loadCallsignsFromFile(new File(MMConstants.USER_CALLSIGN_FILE_PATH), callsigns); - // region Constructors - protected RandomCallsignGenerator() { + for (final Map.Entry entry : callsigns.entrySet()) { + getWeightedCallsigns().add(entry.getValue(), entry.getKey()); + } + } + public static RandomCallsignGenerator getInstance() { + return INSTANCE; } - // endregion Constructors // region Getters/Setters - public static WeightedIntMap getWeightedCallsigns() { + public WeightedIntMap getWeightedCallsigns() { return weightedCallsigns; } - public static void setWeightedCallsigns(final WeightedIntMap weightedCallsigns) { - RandomCallsignGenerator.weightedCallsigns = weightedCallsigns; - } - // endregion Getters/Setters - - // region Synchronization - /** - * @return the instance of the RandomCallsignGenerator to use - */ - public static synchronized RandomCallsignGenerator getInstance() { - // only this code reads and writes 'rcg' - if (rcg == null) { - // synchronized ensures this will only be entered exactly once - rcg = new RandomCallsignGenerator(); - rcg.runThreadLoader(); - } - // when getInstance returns, rcg will always be non-null - return rcg; - } - // endregion Synchronization - // region Generation public String generate() { - String callsign = ""; - - if (initialized) { - callsign = getWeightedCallsigns().randomItem(); - } else { - logger.warn("Attempted to generate a callsign before the list was initialized."); - } - - return callsign; + return getWeightedCallsigns().randomItem(); } // endregion Generation - // region Initialization - private void runThreadLoader() { - Thread loader = new Thread(() -> rcg.populateCallsigns(), "Random Callsign Generator initializer"); - loader.setPriority(Thread.NORM_PRIORITY - 1); - loader.start(); - } - - private void populateCallsigns() { - setWeightedCallsigns(new WeightedIntMap<>()); - final Map callsigns = new HashMap<>(); - loadCallsignsFromFile(new File(MMConstants.CALLSIGN_FILE_PATH), callsigns); - loadCallsignsFromFile(new File(MMConstants.USER_CALLSIGN_FILE_PATH), callsigns); - - for (final Map.Entry entry : callsigns.entrySet()) { - getWeightedCallsigns().add(entry.getValue(), entry.getKey()); - } - - initialized = true; - } - - private void loadCallsignsFromFile(final File file, final Map callsigns) { + private void loadCallsignsFromFile(File file, Map callsigns) { if (!file.exists()) { return; } @@ -124,7 +77,7 @@ private void loadCallsignsFromFile(final File file, final Map c int lineNumber = 0; try (InputStream is = new FileInputStream(file); - Scanner input = new Scanner(is, StandardCharsets.UTF_8.name())) { + Scanner input = new Scanner(is, StandardCharsets.UTF_8)) { // skip the first line, as that's the header lineNumber++; input.nextLine(); @@ -133,11 +86,11 @@ private void loadCallsignsFromFile(final File file, final Map c lineNumber++; String[] values = input.nextLine().split(","); if (values.length == 2) { - callsigns.put(values[0], Integer.parseInt(values[1])); + callsigns.put(values[0], Integer.parseInt(values[1].trim())); } else if (values.length < 2) { - logger.error("Not enough fields in " + file + " on " + lineNumber); + logger.warn("Not enough fields in {} on {}",file, lineNumber); } else { - logger.error("Too many fields in " + file + " on " + lineNumber); + logger.warn("Too many fields in {} on {}", file, lineNumber); } } } catch (Exception e) { From 7e9657cb2d58ba72d09861eed934bc8dffdda96f Mon Sep 17 00:00:00 2001 From: Scoppio Date: Sun, 23 Feb 2025 03:04:39 -0300 Subject: [PATCH 2/3] fix: fix a parsing error and turns it into a singleton using enum --- .../generator/RandomCallsignGenerator.java | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/megamek/src/megamek/client/generator/RandomCallsignGenerator.java b/megamek/src/megamek/client/generator/RandomCallsignGenerator.java index 79b6a93bf92..41c8ad402ac 100644 --- a/megamek/src/megamek/client/generator/RandomCallsignGenerator.java +++ b/megamek/src/megamek/client/generator/RandomCallsignGenerator.java @@ -84,13 +84,19 @@ private void loadCallsignsFromFile(File file, Map callsigns) { while (input.hasNextLine()) { lineNumber++; - String[] values = input.nextLine().split(","); - if (values.length == 2) { + String line = input.nextLine(); + int lastCommaIndex = line.lastIndexOf(","); + if (lastCommaIndex == -1 || line.length() == lastCommaIndex + 1) { + logger.debug("Not enough fields in {} on {}",file, lineNumber); + continue; + } + + String[] values = {line.substring(0, lastCommaIndex), line.substring(lastCommaIndex + 1)}; + + try { callsigns.put(values[0], Integer.parseInt(values[1].trim())); - } else if (values.length < 2) { - logger.warn("Not enough fields in {} on {}",file, lineNumber); - } else { - logger.warn("Too many fields in {} on {}", file, lineNumber); + } catch (NumberFormatException e) { + logger.warn("Invalid weight in {} on {}", file, lineNumber); } } } catch (Exception e) { From 75e7787250798053ddb36e065bf80a492a5ef72b Mon Sep 17 00:00:00 2001 From: Scoppio Date: Sun, 23 Feb 2025 13:08:00 -0300 Subject: [PATCH 3/3] chore: changing from enum to class --- .../client/generator/RandomCallsignGenerator.java | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/megamek/src/megamek/client/generator/RandomCallsignGenerator.java b/megamek/src/megamek/client/generator/RandomCallsignGenerator.java index 41c8ad402ac..9b9f86e9b02 100644 --- a/megamek/src/megamek/client/generator/RandomCallsignGenerator.java +++ b/megamek/src/megamek/client/generator/RandomCallsignGenerator.java @@ -18,28 +18,26 @@ */ package megamek.client.generator; +import megamek.MMConstants; +import megamek.common.util.weightedMaps.WeightedIntMap; +import megamek.logging.MMLogger; + import java.io.File; import java.io.FileInputStream; import java.io.InputStream; -import java.io.Serializable; import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.Map; import java.util.Scanner; -import megamek.MMConstants; -import megamek.common.util.weightedMaps.WeightedIntMap; -import megamek.logging.MMLogger; - /** * Save File Formatting: * callsign, weight * Callsign is a String that does not include a ',' * Weight is an integer weight that is used during generation */ -public enum RandomCallsignGenerator { - INSTANCE; - +public class RandomCallsignGenerator { + private final static RandomCallsignGenerator INSTANCE = new RandomCallsignGenerator(); private final static MMLogger logger = MMLogger.create(RandomCallsignGenerator.class); private final WeightedIntMap weightedCallsigns = new WeightedIntMap<>();