From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Dreeam <61569423+Dreeam-qwq@users.noreply.github.com> Date: Mon, 11 Nov 2024 02:46:39 -0500 Subject: [PATCH] Use faster and thread-safe ban list date format parsing Use DateTimeFormatter since the original java SimpleDateFormat is not thread-safe If store StoredUserList asynchronously, one data format may pollute another Some performance test only for reference Single thread, 10,000,000 times loop, java 21 (graalvm / zulu) SimpleDateFormat: ~29,446ms DateTimeFormatter: ~13,128ms apache commons-lang's FastDateFormat: ~23,514ms diff --git a/src/main/java/net/minecraft/server/players/BanListEntry.java b/src/main/java/net/minecraft/server/players/BanListEntry.java index 8b1da1fb5ca27432a39aff6dbc452b793268dab5..46188a8b8598c36ccb0f5e037a80eb1741c68491 100644 --- a/src/main/java/net/minecraft/server/players/BanListEntry.java +++ b/src/main/java/net/minecraft/server/players/BanListEntry.java @@ -10,7 +10,9 @@ import net.minecraft.network.chat.Component; public abstract class BanListEntry extends StoredUserEntry { - public static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z", Locale.ROOT); + //public static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z", Locale.ROOT); // Leaf - I assume no one will use this, if yes, why? + private static final java.time.ZoneId ZONE_ID = java.time.ZoneId.systemDefault(); + public static final java.time.format.DateTimeFormatter DATE_TIME_FORMATTER = java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss Z"); // Leaf - Use faster and thread-safe ban list date format parsing public static final String EXPIRES_NEVER = "forever"; protected final Date created; protected final String source; @@ -32,8 +34,10 @@ public abstract class BanListEntry extends StoredUserEntry { Date date; try { - date = json.has("created") ? BanListEntry.DATE_FORMAT.parse(json.get("created").getAsString()) : new Date(); - } catch (ParseException parseexception) { + // Leaf start - Use faster and thread-safe ban list date format parsing + date = json.has("created") ? parseToDate(json.get("created").getAsString()) : new Date(); + } catch (java.time.format.DateTimeParseException e) { + // Leaf end - Use faster and thread-safe ban list date format parsing date = new Date(); } @@ -43,8 +47,10 @@ public abstract class BanListEntry extends StoredUserEntry { Date date1; try { - date1 = json.has("expires") ? BanListEntry.DATE_FORMAT.parse(json.get("expires").getAsString()) : null; - } catch (ParseException parseexception1) { + // Leaf start - Use faster and thread-safe ban list date format parsing + date1 = json.has("expires") ? parseToDate(json.get("expires").getAsString()) : null; + } catch (java.time.format.DateTimeParseException e) { + // Leaf end - Use faster and thread-safe ban list date format parsing date1 = null; } @@ -78,9 +84,9 @@ public abstract class BanListEntry extends StoredUserEntry { @Override protected void serialize(JsonObject json) { - json.addProperty("created", BanListEntry.DATE_FORMAT.format(this.created)); + json.addProperty("created", formateToString(this.created)); // Leaf - Use faster and thread-safe ban list date format parsing json.addProperty("source", this.source); - json.addProperty("expires", this.expires == null ? "forever" : BanListEntry.DATE_FORMAT.format(this.expires)); + json.addProperty("expires", this.expires == null ? "forever" : formateToString(this.expires)); // Leaf - Use faster and thread-safe ban list date format parsing json.addProperty("reason", this.reason); } @@ -89,9 +95,11 @@ public abstract class BanListEntry extends StoredUserEntry { Date expires = null; try { - expires = jsonobject.has("expires") ? BanListEntry.DATE_FORMAT.parse(jsonobject.get("expires").getAsString()) : null; - } catch (ParseException ex) { + // Leaf start - Use faster and thread-safe ban list date format parsing + expires = jsonobject.has("expires") ? parseToDate(jsonobject.get("expires").getAsString()) : null; + } catch (java.time.format.DateTimeParseException ignored) { // Guess we don't have a date + // Leaf end - Use faster and thread-safe ban list date format parsing } if (expires == null || expires.after(new Date())) { @@ -101,4 +109,15 @@ public abstract class BanListEntry extends StoredUserEntry { } } // CraftBukkit end + + // Leaf start - Use faster and thread-safe ban list date format parsing + public static Date parseToDate(String string) { + java.time.ZonedDateTime parsedDateTime = java.time.ZonedDateTime.parse(string, DATE_TIME_FORMATTER); + return Date.from(parsedDateTime.toInstant()); + } + + public static String formateToString(Date date) { + return DATE_TIME_FORMATTER.format(date.toInstant().atZone(ZONE_ID)); + } + // Leaf end - Use faster and thread-safe ban list date format parsing } diff --git a/src/main/java/net/minecraft/server/players/OldUsersConverter.java b/src/main/java/net/minecraft/server/players/OldUsersConverter.java index 653856d0b8dcf2baf4cc77a276f17c8cc1fa717e..6416bc12f3d7733a4bd89d208a320f1b68983788 100644 --- a/src/main/java/net/minecraft/server/players/OldUsersConverter.java +++ b/src/main/java/net/minecraft/server/players/OldUsersConverter.java @@ -516,8 +516,10 @@ public class OldUsersConverter { Date date1; try { - date1 = BanListEntry.DATE_FORMAT.parse(dateString); - } catch (ParseException parseexception) { + // Leaf start - Use faster and thread-safe ban list date format parsing + date1 = BanListEntry.parseToDate(dateString); + } catch (java.time.format.DateTimeParseException e) { + // Leaf end - Use faster and thread-safe ban list date format parsing date1 = fallback; }