From e6239936d2b1a41213d44d4e3d556c17e427b64e Mon Sep 17 00:00:00 2001 From: nossr50 Date: Tue, 13 Apr 2021 13:40:24 -0700 Subject: [PATCH] Add lastlogin tests --- .../gmail/nossr50/database/ExpectedType.java | 1 + .../nossr50/database/FlatFileDataFlag.java | 1 + .../database/FlatFileDataProcessor.java | 18 ++- .../database/FlatFileDatabaseManager.java | 19 ++- ...taProcessor.java => FlatFileDataUtil.java} | 7 +- .../datatypes/player/PlayerProfile.java | 2 +- .../database/FlatFileDatabaseManagerTest.java | 124 +++++++++++++----- ...sorTest.java => FlatFileDataUtilTest.java} | 4 +- src/test/resources/healthydb.users | 6 +- src/test/resources/missinglastlogin.users | 4 + 10 files changed, 130 insertions(+), 56 deletions(-) rename src/main/java/com/gmail/nossr50/database/flatfile/{FlatFileSaveDataProcessor.java => FlatFileDataUtil.java} (96%) rename src/test/java/com/gmail/nossr50/database/flatfile/{FlatFileSaveDataProcessorTest.java => FlatFileDataUtilTest.java} (82%) create mode 100644 src/test/resources/missinglastlogin.users diff --git a/src/main/java/com/gmail/nossr50/database/ExpectedType.java b/src/main/java/com/gmail/nossr50/database/ExpectedType.java index 57da078fb..ab3ad7c9c 100644 --- a/src/main/java/com/gmail/nossr50/database/ExpectedType.java +++ b/src/main/java/com/gmail/nossr50/database/ExpectedType.java @@ -3,6 +3,7 @@ package com.gmail.nossr50.database; public enum ExpectedType { STRING, INTEGER, + LONG, BOOLEAN, FLOAT, DOUBLE, diff --git a/src/main/java/com/gmail/nossr50/database/FlatFileDataFlag.java b/src/main/java/com/gmail/nossr50/database/FlatFileDataFlag.java index b67fe2806..b80c39e15 100644 --- a/src/main/java/com/gmail/nossr50/database/FlatFileDataFlag.java +++ b/src/main/java/com/gmail/nossr50/database/FlatFileDataFlag.java @@ -3,6 +3,7 @@ package com.gmail.nossr50.database; public enum FlatFileDataFlag { INCOMPLETE, BAD_VALUES, + LAST_LOGIN_SCHEMA_UPGRADE, MISSING_NAME, DUPLICATE_NAME, DUPLICATE_UUID, diff --git a/src/main/java/com/gmail/nossr50/database/FlatFileDataProcessor.java b/src/main/java/com/gmail/nossr50/database/FlatFileDataProcessor.java index ddda18143..1b9651089 100644 --- a/src/main/java/com/gmail/nossr50/database/FlatFileDataProcessor.java +++ b/src/main/java/com/gmail/nossr50/database/FlatFileDataProcessor.java @@ -2,8 +2,9 @@ package com.gmail.nossr50.database; import com.gmail.nossr50.database.flatfile.FlatFileDataBuilder; import com.gmail.nossr50.database.flatfile.FlatFileDataContainer; -import com.gmail.nossr50.database.flatfile.FlatFileSaveDataProcessor; +import com.gmail.nossr50.database.flatfile.FlatFileDataUtil; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.*; import java.util.logging.Logger; @@ -134,16 +135,19 @@ public class FlatFileDataProcessor { //Check each data for bad values for(int i = 0; i < DATA_ENTRY_COUNT; i++) { if(shouldNotBeEmpty(splitDataLine[i], i)) { + + if(i == OVERHAUL_LAST_LOGIN) { + builder.appendFlag(FlatFileDataFlag.LAST_LOGIN_SCHEMA_UPGRADE); + } + badDataValues[i] = true; anyBadData = true; - reportBadDataLine("Data is empty when it should not be at index", "[index=" + i + "]", lineData); continue; } boolean isCorrectType = isOfExpectedType(splitDataLine[i], getExpectedValueType(i)); if(!isCorrectType) { - reportBadDataLine("Data is not of correct type", splitDataLine[i], lineData); anyBadData = true; badDataValues[i] = true; } @@ -177,7 +181,7 @@ public class FlatFileDataProcessor { } - public boolean shouldNotBeEmpty(String data, int index) { + public boolean shouldNotBeEmpty(@Nullable String data, int index) { if(getExpectedValueType(index) == ExpectedType.IGNORED) { return false; } else { @@ -255,6 +259,7 @@ public class FlatFileDataProcessor { case 23: //Assumption: Used to be used for something, no longer used case 33: //Assumption: Used to be used for something, no longer used case HEALTHBAR: + case LEGACY_LAST_LOGIN: return ExpectedType.IGNORED; case SKILLS_MINING: case SKILLS_REPAIR: @@ -269,7 +274,6 @@ public class FlatFileDataProcessor { case SKILLS_TAMING: case SKILLS_FISHING: case SKILLS_ALCHEMY: - case LAST_LOGIN: case COOLDOWN_BERSERK: case COOLDOWN_GIGA_DRILL_BREAKER: case COOLDOWN_TREE_FELLER: @@ -297,6 +301,8 @@ public class FlatFileDataProcessor { return ExpectedType.FLOAT; case UUID_INDEX: return ExpectedType.UUID; + case OVERHAUL_LAST_LOGIN: + return ExpectedType.LONG; } throw new IndexOutOfBoundsException(); @@ -320,7 +326,7 @@ public class FlatFileDataProcessor { //Fix our data if needed and prepare it to be saved for(FlatFileDataContainer dataContainer : flatFileDataContainers) { - String[] splitData = FlatFileSaveDataProcessor.getPreparedSaveDataLine(dataContainer); + String[] splitData = FlatFileDataUtil.getPreparedSaveDataLine(dataContainer); if(splitData == null) continue; diff --git a/src/main/java/com/gmail/nossr50/database/FlatFileDatabaseManager.java b/src/main/java/com/gmail/nossr50/database/FlatFileDatabaseManager.java index 42a65c868..97c77aeb5 100644 --- a/src/main/java/com/gmail/nossr50/database/FlatFileDatabaseManager.java +++ b/src/main/java/com/gmail/nossr50/database/FlatFileDatabaseManager.java @@ -70,15 +70,16 @@ public final class FlatFileDatabaseManager implements DatabaseManager { public static final int SKILLS_FISHING = 34; public static final int EXP_FISHING = 35; public static final int COOLDOWN_BLAST_MINING = 36; - public static final int LAST_LOGIN = 37; + public static final int LEGACY_LAST_LOGIN = 37; public static final int HEALTHBAR = 38; public static final int SKILLS_ALCHEMY = 39; public static final int EXP_ALCHEMY = 40; public static final int UUID_INDEX = 41; public static final int SCOREBOARD_TIPS = 42; public static final int COOLDOWN_CHIMAERA_WING = 43; + public static final int OVERHAUL_LAST_LOGIN = 44; - public static final int DATA_ENTRY_COUNT = COOLDOWN_CHIMAERA_WING + 1; //Update this everytime new data is added + public static final int DATA_ENTRY_COUNT = OVERHAUL_LAST_LOGIN + 1; //Update this everytime new data is added protected FlatFileDatabaseManager(@NotNull File usersFile, @NotNull Logger logger, long purgeTime, int startingLevel, boolean testing) { this.usersFile = usersFile; @@ -666,6 +667,10 @@ public final class FlatFileDatabaseManager implements DatabaseManager { String line; while ((line = in.readLine()) != null) { + if(line.startsWith("#")) { + continue; + } + // Find if the line contains the player we want. String[] rawSplitData = line.split(":"); @@ -718,6 +723,10 @@ public final class FlatFileDatabaseManager implements DatabaseManager { String line; while ((line = in.readLine()) != null) { + if(line.startsWith("#")) { + continue; + } + String[] character = line.split(":"); try { @@ -1071,7 +1080,7 @@ public final class FlatFileDatabaseManager implements DatabaseManager { fileWriter = new FileWriter(usersFilePath); //Write data to file if(dbCommentDate != null) - fileWriter.write(dbCommentDate); + fileWriter.write(dbCommentDate + "\r\n"); fileWriter.write(dataProcessor.processDataForSave().toString()); } @@ -1200,9 +1209,9 @@ public final class FlatFileDatabaseManager implements DatabaseManager { } try { - lastLogin = Long.parseLong(character[LAST_LOGIN]); + lastLogin = Long.parseLong(character[OVERHAUL_LAST_LOGIN]); } catch (Exception e) { - lastLogin = System.currentTimeMillis(); + lastLogin = -1; } return new PlayerProfile(character[USERNAME_INDEX], uuid, skills, skillsXp, skillsDATS, scoreboardTipsShown, uniquePlayerDataMap, lastLogin); diff --git a/src/main/java/com/gmail/nossr50/database/flatfile/FlatFileSaveDataProcessor.java b/src/main/java/com/gmail/nossr50/database/flatfile/FlatFileDataUtil.java similarity index 96% rename from src/main/java/com/gmail/nossr50/database/flatfile/FlatFileSaveDataProcessor.java rename to src/main/java/com/gmail/nossr50/database/flatfile/FlatFileDataUtil.java index eb06d1dab..e4048cdf0 100644 --- a/src/main/java/com/gmail/nossr50/database/flatfile/FlatFileSaveDataProcessor.java +++ b/src/main/java/com/gmail/nossr50/database/flatfile/FlatFileDataUtil.java @@ -7,7 +7,7 @@ import org.jetbrains.annotations.Nullable; import static com.gmail.nossr50.database.FlatFileDatabaseManager.*; -public class FlatFileSaveDataProcessor { +public class FlatFileDataUtil { public static @Nullable String[] getPreparedSaveDataLine(@NotNull FlatFileDataContainer dataContainer) { if(dataContainer.getDataFlags() == null) { @@ -64,6 +64,7 @@ public class FlatFileSaveDataProcessor { case 3: //Assumption: Used to be for something, no longer used case 23: //Assumption: Used to be used for something, no longer used case 33: //Assumption: Used to be used for something, no longer used + case LEGACY_LAST_LOGIN: case HEALTHBAR: return "IGNORED"; case SKILLS_MINING: @@ -80,8 +81,8 @@ public class FlatFileSaveDataProcessor { case SKILLS_FISHING: case SKILLS_ALCHEMY: return String.valueOf(startingLevel); - case LAST_LOGIN: - return String.valueOf(System.currentTimeMillis() / 1000); //This is just to shorten the value + case OVERHAUL_LAST_LOGIN: + return String.valueOf(-1L); case COOLDOWN_BERSERK: case COOLDOWN_GIGA_DRILL_BREAKER: case COOLDOWN_TREE_FELLER: diff --git a/src/main/java/com/gmail/nossr50/datatypes/player/PlayerProfile.java b/src/main/java/com/gmail/nossr50/datatypes/player/PlayerProfile.java index f2e4306fe..1295a6d05 100644 --- a/src/main/java/com/gmail/nossr50/datatypes/player/PlayerProfile.java +++ b/src/main/java/com/gmail/nossr50/datatypes/player/PlayerProfile.java @@ -162,7 +162,7 @@ public class PlayerProfile { @Deprecated public @NotNull Long getLastLogin() { if(lastLogin == null) - return System.currentTimeMillis(); + return -1L; else return lastLogin; } diff --git a/src/test/java/com/gmail/nossr50/database/FlatFileDatabaseManagerTest.java b/src/test/java/com/gmail/nossr50/database/FlatFileDatabaseManagerTest.java index 30314b1fb..48a1481b7 100644 --- a/src/test/java/com/gmail/nossr50/database/FlatFileDatabaseManagerTest.java +++ b/src/test/java/com/gmail/nossr50/database/FlatFileDatabaseManagerTest.java @@ -19,14 +19,13 @@ import org.powermock.modules.junit4.PowerMockRunner; import java.io.*; import java.net.URI; import java.net.URISyntaxException; -import java.nio.file.Path; -import java.nio.file.Paths; import java.util.*; import java.util.logging.Logger; import static org.junit.Assert.*; +//TODO: Test update leaderboards @RunWith(PowerMockRunner.class) public class FlatFileDatabaseManagerTest { @@ -35,8 +34,10 @@ public class FlatFileDatabaseManagerTest { public static final @NotNull String BAD_DATA_FILE_LINE_TWENTY_THREE = "nossr51:baddata:::baddata:baddata:640:baddata:1000:1000:1000:baddata:baddata:baddata:baddata:16:0:500:20273:0:0:0:0::1000:0:0:baddata:1593543012:0:0:0:0::1000:0:0:baddata:IGNORED:1000:0:588fe472-1c82-4c4e-9aa1-7eefccb277e3:1:0:"; public static final @NotNull String DB_BADDATA = "baddatadb.users"; public static final @NotNull String DB_HEALTHY = "healthydb.users"; - public static final @NotNull String HEALTHY_DB_LINE_1 = "nossr50:1:IGNORED:IGNORED:10:2:20:3:4:5:6:7:8:9:10:30:40:50:60:70:80:90:100:IGNORED:11:110:111:222:333:444:555:666:777:IGNORED:12:120:888:2020:HEARTS:13:130:588fe472-1c82-4c4e-9aa1-7eefccb277e3:1111:999:"; + public static final @NotNull String HEALTHY_DB_LINE_1 = "nossr50:1:IGNORED:IGNORED:10:2:20:3:4:5:6:7:8:9:10:30:40:50:60:70:80:90:100:IGNORED:11:110:111:222:333:444:555:666:777:IGNORED:12:120:888:IGNORED:HEARTS:13:130:588fe472-1c82-4c4e-9aa1-7eefccb277e3:1111:999:2020:"; public static final @NotNull String HEALTHY_DB_LINE_ONE_UUID_STR = "588fe472-1c82-4c4e-9aa1-7eefccb277e3"; + public static final String DB_MISSING_LAST_LOGIN = "missinglastlogin.users"; + public static final String LINE_TWO_FROM_MISSING_DB = "nossr50:1:IGNORED:IGNORED:10:2:20:3:4:5:6:7:8:9:10:30:40:50:60:70:80:90:100:IGNORED:11:110:111:222:333:444:555:666:777:IGNORED:12:120:888:0:HEARTS:13:130:588fe472-1c82-4c4e-9aa1-7eefccb277e3:1111:999:"; private static File tempDir; private final static @NotNull Logger logger = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME); private final long PURGE_TIME = 2630000000L; @@ -157,21 +158,99 @@ public class FlatFileDatabaseManagerTest { } @Test - public void testLoadByName() { + public void testAddedMissingLastLoginValues() { + File dbFile = prepareDatabaseTestResource(DB_MISSING_LAST_LOGIN); + //This makes sure our private method is working before the tests run afterwards + ArrayList dataFromFile = getSplitDataFromFile(dbFile); + System.out.println("File Path: "+ dbFile.getAbsolutePath()); + assertArrayEquals(LINE_TWO_FROM_MISSING_DB.split(":"), dataFromFile.get(1)); + assertEquals(dataFromFile.get(1)[FlatFileDatabaseManager.UUID_INDEX], HEALTHY_DB_LINE_ONE_UUID_STR); + + db = new FlatFileDatabaseManager(dbFile, logger, PURGE_TIME, 0, true); + List flagsFound = db.checkFileHealthAndStructure(); + assertNotNull(flagsFound); + assertTrue(flagsFound.contains(FlatFileDataFlag.LAST_LOGIN_SCHEMA_UPGRADE)); + + //Check for the fixed value + PlayerProfile profile = db.loadPlayerProfile("nossr50"); + assertEquals(-1, (long) profile.getLastLogin()); + } + + + @Test + public void testLoadByName() { + File healthyDB = prepareDatabaseTestResource(DB_HEALTHY); + + /* + * We have established the files are in good order, so now for the actual testing + */ + + //This makes sure our private method is working before the tests run afterwards + ArrayList dataFromFile = getSplitDataFromFile(healthyDB); + System.out.println("File Path: "+healthyDB.getAbsolutePath()); + assertArrayEquals(HEALTHY_DB_LINE_1.split(":"), dataFromFile.get(0)); + assertEquals(dataFromFile.get(0)[FlatFileDatabaseManager.UUID_INDEX], HEALTHY_DB_LINE_ONE_UUID_STR); + UUID healthDBEntryOneUUID = UUID.fromString(HEALTHY_DB_LINE_ONE_UUID_STR); + + db = new FlatFileDatabaseManager(healthyDB, logger, PURGE_TIME, 0, true); + List flagsFound = db.checkFileHealthAndStructure(); + assertNull(flagsFound); //No flags should be found + + /* + * Once the DB looks fine load the profile + */ + + String playerName = "nossr50"; + UUID uuid = UUID.fromString("588fe472-1c82-4c4e-9aa1-7eefccb277e3"); + + PlayerProfile profile = db.loadPlayerProfile(playerName); + testHealthyDataProfileValues(playerName, uuid, profile); } @Test public void testLoadByUUID() { + File dbFile = prepareDatabaseTestResource(DB_HEALTHY); + /* - * This test uses a file provided in test resources + * We have established the files are in good order, so now for the actual testing */ + //This makes sure our private method is working before the tests run afterwards + ArrayList dataFromFile = getSplitDataFromFile(dbFile); + System.out.println("File Path: " + dbFile.getAbsolutePath()); + assertArrayEquals(HEALTHY_DB_LINE_1.split(":"), dataFromFile.get(0)); + assertEquals(dataFromFile.get(0)[FlatFileDatabaseManager.UUID_INDEX], HEALTHY_DB_LINE_ONE_UUID_STR); + + db = new FlatFileDatabaseManager(dbFile, logger, PURGE_TIME, 0, true); + List flagsFound = db.checkFileHealthAndStructure(); + assertNull(flagsFound); //No flags should be found + + /* + * Once the DB looks fine load the profile + */ + + String playerName = "nossr50"; + UUID uuid = UUID.fromString("588fe472-1c82-4c4e-9aa1-7eefccb277e3"); + + PlayerProfile profile1 = db.loadPlayerProfile(uuid, null); + PlayerProfile profile2 = db.loadPlayerProfile(uuid, playerName); + PlayerProfile profile3 = db.loadPlayerProfile(uuid, "incorrectName"); + PlayerProfile profile4 = db.loadPlayerProfile(new UUID(0, 1), "shouldBeUnloaded"); + assertFalse(profile4.isLoaded()); + + //Three possible ways to load the thing + testHealthyDataProfileValues(playerName, uuid, profile1); + testHealthyDataProfileValues(playerName, uuid, profile2); + testHealthyDataProfileValues(playerName, uuid, profile3); + } + + private File prepareDatabaseTestResource(@NotNull String dbFileName) { ClassLoader classLoader = getClass().getClassLoader(); URI resourceFileURI = null; try { - resourceFileURI = classLoader.getResource(DB_HEALTHY).toURI(); + resourceFileURI = classLoader.getResource(dbFileName).toURI(); } catch (URISyntaxException e) { e.printStackTrace(); } @@ -179,7 +258,7 @@ public class FlatFileDatabaseManagerTest { assertNotNull(resourceFileURI); File fromResourcesFile = new File(resourceFileURI); assertNotNull(resourceFileURI); - File copyOfFile = new File(tempDir.getPath() + File.separator + DB_HEALTHY); + File copyOfFile = new File(tempDir.getPath() + File.separator + dbFileName); if(copyOfFile.exists()) { //noinspection ResultOfMethodCallIgnored @@ -196,37 +275,10 @@ public class FlatFileDatabaseManagerTest { } assertNotNull(copyOfFile); - - - - /* - * We have established the files are in good order, so now for the actual testing - */ - - //This makes sure our private method is working before the tests run afterwards - ArrayList dataFromFile = getSplitDataFromFile(copyOfFile); - System.out.println("File Path: "+copyOfFile.getAbsolutePath()); - assertArrayEquals(HEALTHY_DB_LINE_1.split(":"), dataFromFile.get(0)); - assertEquals(dataFromFile.get(0)[FlatFileDatabaseManager.UUID_INDEX], HEALTHY_DB_LINE_ONE_UUID_STR); - UUID healthDBEntryOneUUID = UUID.fromString(HEALTHY_DB_LINE_ONE_UUID_STR); - - FlatFileDatabaseManager db_a = new FlatFileDatabaseManager(copyOfFile, logger, PURGE_TIME, 0, true); - List flagsFound = db_a.checkFileHealthAndStructure(); - assertNull(flagsFound); //No flags should be found - - /* - * Once the DB looks fine load the profile - */ - - String playerName = "nossr50"; - UUID uuid = UUID.fromString("588fe472-1c82-4c4e-9aa1-7eefccb277e3"); - - PlayerProfile profile = db_a.loadPlayerProfile(uuid, null); - testHealthyDataProfileValues(db_a, playerName, uuid, profile); + return copyOfFile; } - private void testHealthyDataProfileValues(FlatFileDatabaseManager flatFileDatabaseManager, String playerName, UUID uuid, PlayerProfile playerProfile) { - PlayerProfile profile = flatFileDatabaseManager.loadPlayerProfile(uuid, null); + private void testHealthyDataProfileValues(@NotNull String playerName, @NotNull UUID uuid, @NotNull PlayerProfile profile) { assertTrue(profile.isLoaded()); //PlayerProfile::isLoaded returns true if the data was created from the file, false if it wasn't found and a dummy profile was returned assertEquals(uuid, profile.getUniqueId()); assertEquals(playerName, profile.getPlayerName()); diff --git a/src/test/java/com/gmail/nossr50/database/flatfile/FlatFileSaveDataProcessorTest.java b/src/test/java/com/gmail/nossr50/database/flatfile/FlatFileDataUtilTest.java similarity index 82% rename from src/test/java/com/gmail/nossr50/database/flatfile/FlatFileSaveDataProcessorTest.java rename to src/test/java/com/gmail/nossr50/database/flatfile/FlatFileDataUtilTest.java index 8b10772fa..ee6e71ffb 100644 --- a/src/test/java/com/gmail/nossr50/database/flatfile/FlatFileSaveDataProcessorTest.java +++ b/src/test/java/com/gmail/nossr50/database/flatfile/FlatFileDataUtilTest.java @@ -5,7 +5,7 @@ import org.junit.Test; import java.util.HashSet; -public class FlatFileSaveDataProcessorTest { +public class FlatFileDataUtilTest { @Test public void getPreparedSaveDataLine() { @@ -22,6 +22,6 @@ public class FlatFileSaveDataProcessorTest { @Test(expected = AssertionError.class) public void testTooManyDataEntriesSplitString() { FlatFileDataContainer dataContainer = new CategorizedFlatFileData(0, new HashSet<>(), new String[FlatFileDatabaseManager.DATA_ENTRY_COUNT + 1]); - FlatFileSaveDataProcessor.getPreparedSaveDataLine(dataContainer); + FlatFileDataUtil.getPreparedSaveDataLine(dataContainer); } } \ No newline at end of file diff --git a/src/test/resources/healthydb.users b/src/test/resources/healthydb.users index 38c671177..7ce5ccbad 100644 --- a/src/test/resources/healthydb.users +++ b/src/test/resources/healthydb.users @@ -1,3 +1,3 @@ -nossr50:1:IGNORED:IGNORED:10:2:20:3:4:5:6:7:8:9:10:30:40:50:60:70:80:90:100:IGNORED:11:110:111:222:333:444:555:666:777:IGNORED:12:120:888:2020:HEARTS:13:130:588fe472-1c82-4c4e-9aa1-7eefccb277e3:1111:999: -mrfloris:2420:::0:2452:0:1983:1937:1790:3042:1138:3102:2408:3411:0:0:0:0:0:0:0:0::642:0:1617583171:0:1617165043:0:1617583004:1617563189:1616785408::2184:0:0:1617852413:HEARTS:415:0:631e3896-da2a-4077-974b-d047859d76bc:5:1600906906: -powerless:0:::0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0::0:0:0:0:0:0:0:0:0::0:0:0:0:HEARTS:0:0:e0d07db8-f7e8-43c7-9ded-864dfc6f3b7c:5:1600906906: \ No newline at end of file +nossr50:1:IGNORED:IGNORED:10:2:20:3:4:5:6:7:8:9:10:30:40:50:60:70:80:90:100:IGNORED:11:110:111:222:333:444:555:666:777:IGNORED:12:120:888:IGNORED:HEARTS:13:130:588fe472-1c82-4c4e-9aa1-7eefccb277e3:1111:999:2020: +mrfloris:2420:::0:2452:0:1983:1937:1790:3042:1138:3102:2408:3411:0:0:0:0:0:0:0:0::642:0:1617583171:0:1617165043:0:1617583004:1617563189:1616785408::2184:0:0:1617852413:HEARTS:415:0:631e3896-da2a-4077-974b-d047859d76bc:5:1600906906:3030: +powerless:0:::0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0::0:0:0:0:0:0:0:0:0::0:0:0:1337:HEARTS:0:0:e0d07db8-f7e8-43c7-9ded-864dfc6f3b7c:5:1600906906:4040: \ No newline at end of file diff --git a/src/test/resources/missinglastlogin.users b/src/test/resources/missinglastlogin.users new file mode 100644 index 000000000..54378e194 --- /dev/null +++ b/src/test/resources/missinglastlogin.users @@ -0,0 +1,4 @@ +# A single comment line is sometimes at the top of the DB +nossr50:1:IGNORED:IGNORED:10:2:20:3:4:5:6:7:8:9:10:30:40:50:60:70:80:90:100:IGNORED:11:110:111:222:333:444:555:666:777:IGNORED:12:120:888:0:HEARTS:13:130:588fe472-1c82-4c4e-9aa1-7eefccb277e3:1111:999: +mrfloris:2420:::0:2452:0:1983:1937:1790:3042:1138:3102:2408:3411:0:0:0:0:0:0:0:0::642:0:1617583171:0:1617165043:0:1617583004:1617563189:1616785408::2184:0:0:1617852413:HEARTS:415:0:631e3896-da2a-4077-974b-d047859d76bc:5:1600906906: +powerless:0:::0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0::0:0:0:0:0:0:0:0:0::0:0:0:1337:HEARTS:0:0:e0d07db8-f7e8-43c7-9ded-864dfc6f3b7c:5:1600906906: \ No newline at end of file