Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ public class LocalSignatureCipherManager implements CipherManager {
Pattern.DOTALL);

private final ConcurrentMap<String, SignatureCipher> cipherCache;
private final ConcurrentMap<String, String> stsCache;
private final Set<String> dumpedScriptUrls;
private final ScriptEngine scriptEngine;

Expand All @@ -100,6 +101,7 @@ public class LocalSignatureCipherManager implements CipherManager {
*/
public LocalSignatureCipherManager() {
this.cipherCache = new ConcurrentHashMap<>();
this.stsCache = new ConcurrentHashMap<>();
this.dumpedScriptUrls = new HashSet<>();
this.scriptEngine = new RhinoScriptEngineFactory().getScriptEngine();
}
Expand Down Expand Up @@ -255,8 +257,22 @@ private void dumpProblematicScript(@NotNull String script, @NotNull String sourc
}

public String getTimestamp(HttpInterface httpInterface, String sourceUrl) throws IOException {
// Check cache first
String cachedSts = stsCache.get(sourceUrl);
if (cachedSts != null) {
log.debug("STS cache hit for script URL: {}", sourceUrl);
return cachedSts;
}

synchronized (this) {
log.debug("Timestamp from script {}", sourceUrl);
// Double-check after acquiring lock
cachedSts = stsCache.get(sourceUrl);
if (cachedSts != null) {
log.debug("STS cache hit (after lock) for script URL: {}", sourceUrl);
return cachedSts;
}

log.debug("STS cache miss - fetching timestamp from script {}", sourceUrl);

try (CloseableHttpResponse response = httpInterface.execute(new HttpGet(CipherUtils.parseTokenScriptUrl(sourceUrl)))) {
int statusCode = response.getStatusLine().getStatusCode();
Expand All @@ -266,7 +282,10 @@ public String getTimestamp(HttpInterface httpInterface, String sourceUrl) throws
sourceUrl + " ( " + CipherUtils.parseTokenScriptUrl(sourceUrl) + " )");
}

return getScriptTimestamp(httpInterface, EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8), sourceUrl);
String sts = getScriptTimestamp(httpInterface, EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8), sourceUrl);
stsCache.put(sourceUrl, sts);
log.debug("Cached STS {} for script URL: {}", sts, sourceUrl);
return sts;
}
}
}
Expand Down Expand Up @@ -323,4 +342,31 @@ private void scriptExtractionFailed(String script, String sourceUrl, ExtractionF
dumpProblematicScript(script, sourceUrl, "must find " + failureType.friendlyName);
throw new ScriptExtractionException("Must find " + failureType.friendlyName + " from script: " + sourceUrl, failureType);
}

/**
* Clears the STS cache. Useful for testing and when player script updates are detected.
*/
public void clearStsCache() {
stsCache.clear();
log.debug("STS cache cleared");
}

/**
* Removes a specific STS entry from the cache.
* @param scriptUrl The player script URL whose STS should be removed from cache
*/
public void evictStsFromCache(@NotNull String scriptUrl) {
String removed = stsCache.remove(scriptUrl);
if (removed != null) {
log.debug("Evicted STS {} for script URL: {}", removed, scriptUrl);
}
}

/**
* Returns the current size of the STS cache.
* @return The number of cached STS entries
*/
public int getStsCacheSize() {
return stsCache.size();
}
}
Loading