@@ -76,7 +76,9 @@ public final class CraftEnginePackGatePlugin {
7676 private final Logger logger ;
7777 private final Path dataDirectory ;
7878 private final Path configFile ;
79+ private final Path appliedHashesFile ;
7980 private final Properties config = new Properties ();
81+ private final Map <UUID , String > appliedHashes = new ConcurrentHashMap <>();
8082 private final Map <UUID , PackDefinition > pendingPlayers = new ConcurrentHashMap <>();
8183 private final Set <String > appliedThisSession = ConcurrentHashMap .newKeySet ();
8284 private final Set <UUID > notifiedEaglerPlayers = ConcurrentHashMap .newKeySet ();
@@ -109,11 +111,13 @@ public CraftEnginePackGatePlugin(ProxyServer proxy, Logger logger, @DataDirector
109111 this .logger = logger ;
110112 this .dataDirectory = dataDirectory ;
111113 this .configFile = dataDirectory .resolve ("config.properties" );
114+ this .appliedHashesFile = dataDirectory .resolve ("applied-hashes.properties" );
112115 }
113116
114117 @ Subscribe
115118 public void onProxyInitialize (ProxyInitializeEvent event ) {
116119 loadConfig ();
120+ loadAppliedHashes ();
117121 buildPackConfigs ();
118122 proxy .getChannelRegistrar ().register (EAGLER_STATUS_CHANNEL );
119123 logger .info ("CraftEnginePackGate enabled: force={}, sendDelayMillis={}, skipEaglerPlayers={}, forwardEaglerStatus={}, hideEaglerTabFooter={}, server assignments={}" , force , sendDelayMillis , skipEaglerPlayers , forwardEaglerStatus , hideEaglerTabFooter , packsByServer .keySet ());
@@ -163,6 +167,8 @@ public void onResourcePackStatus(PlayerResourcePackStatusEvent event) {
163167 PlayerResourcePackStatusEvent .Status status = event .getStatus ();
164168 if (status == PlayerResourcePackStatusEvent .Status .SUCCESSFUL ) {
165169 appliedThisSession .add (key (player , pack ));
170+ appliedHashes .put (player .getUniqueId (), pack .sha1 ());
171+ saveAppliedHashes ();
166172 pendingPlayers .remove (player .getUniqueId ());
167173 logger .info ("{} applied mandatory CraftEngine resource pack {} ({})" , player .getUsername (), pack .name (), pack .sha1 ());
168174 return ;
@@ -234,7 +240,7 @@ private void sendPackIfStillNeeded(UUID playerId, String serverName, PackConfig
234240 }
235241
236242 PackDefinition pack = resolvedPack .get ();
237- if (appliedThisSession .contains (key (player , pack ))) {
243+ if (appliedThisSession .contains (key (player , pack )) || pack . sha1 (). equals ( appliedHashes . get ( player . getUniqueId ())) ) {
238244 return ;
239245 }
240246
@@ -505,6 +511,34 @@ private String requireConfig(String key) {
505511 return value ;
506512 }
507513
514+ private void loadAppliedHashes () {
515+ if (!Files .isRegularFile (appliedHashesFile )) {
516+ return ;
517+ }
518+ Properties hashes = new Properties ();
519+ try (var reader = Files .newBufferedReader (appliedHashesFile , StandardCharsets .UTF_8 )) {
520+ hashes .load (reader );
521+ for (String playerId : hashes .stringPropertyNames ()) {
522+ String sha1 = hashes .getProperty (playerId , "" ).toLowerCase (Locale .ROOT );
523+ if (isSha1 (sha1 )) {
524+ appliedHashes .put (UUID .fromString (playerId ), sha1 );
525+ }
526+ }
527+ } catch (IOException | IllegalArgumentException exception ) {
528+ logger .warn ("Failed to load applied resource-pack hashes: {}" , exception .getMessage ());
529+ }
530+ }
531+
532+ private void saveAppliedHashes () {
533+ Properties hashes = new Properties ();
534+ appliedHashes .forEach ((playerId , sha1 ) -> hashes .setProperty (playerId .toString (), sha1 ));
535+ try (var writer = Files .newBufferedWriter (appliedHashesFile , StandardCharsets .UTF_8 )) {
536+ hashes .store (writer , "Resource packs successfully applied by player UUID" );
537+ } catch (IOException exception ) {
538+ logger .warn ("Failed to save applied resource-pack hashes: {}" , exception .getMessage ());
539+ }
540+ }
541+
508542 private void loadConfig () {
509543 try {
510544 Files .createDirectories (dataDirectory );
0 commit comments