mirror of
https://github.com/chylex/TweetDuck.git
synced 2025-04-09 06:15:49 +02:00
Rewrite plugin cache to use tokens and local paths as multikeys
This commit is contained in:
parent
4bb35295ca
commit
f7ed7703b4
@ -1,24 +1,35 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using TweetDck.Core.Utils;
|
||||
using TweetDck.Plugins.Enums;
|
||||
using TweetDck.Plugins.Events;
|
||||
|
||||
namespace TweetDck.Plugins{
|
||||
class PluginBridge{
|
||||
private static string SanitizeCacheKey(string key){
|
||||
return key.Replace('\\', '/').Trim();
|
||||
}
|
||||
|
||||
private readonly PluginManager manager;
|
||||
private readonly Dictionary<string, string> fileCache = new Dictionary<string, string>(2);
|
||||
private readonly TwoKeyDictionary<int, string, string> fileCache = new TwoKeyDictionary<int, string, string>(4, 2);
|
||||
|
||||
public PluginBridge(PluginManager manager){
|
||||
this.manager = manager;
|
||||
this.manager.Reloaded += manager_Reloaded;
|
||||
this.manager.PluginChangedState += manager_PluginChangedState;
|
||||
}
|
||||
|
||||
private void manager_Reloaded(object sender, PluginLoadEventArgs e){
|
||||
fileCache.Clear();
|
||||
}
|
||||
|
||||
private void manager_PluginChangedState(object sender, PluginChangedStateEventArgs e){
|
||||
if (!e.IsEnabled){
|
||||
fileCache.Remove(manager.GetTokenFromPlugin(e.Plugin));
|
||||
}
|
||||
}
|
||||
|
||||
private string GetFullPathOrThrow(int token, PluginFolder folder, string path){
|
||||
Plugin plugin = manager.GetPluginFromToken(token);
|
||||
string fullPath = plugin == null ? string.Empty : plugin.GetFullPathIfSafe(folder, path);
|
||||
@ -35,15 +46,17 @@ private string GetFullPathOrThrow(int token, PluginFolder folder, string path){
|
||||
}
|
||||
}
|
||||
|
||||
private string ReadFileUnsafe(string fullPath, bool readCached){
|
||||
private string ReadFileUnsafe(int token, string cacheKey, string fullPath, bool readCached){
|
||||
cacheKey = SanitizeCacheKey(cacheKey);
|
||||
|
||||
string cachedContents;
|
||||
|
||||
if (readCached && fileCache.TryGetValue(fullPath, out cachedContents)){
|
||||
if (readCached && fileCache.TryGetValue(token, cacheKey, out cachedContents)){
|
||||
return cachedContents;
|
||||
}
|
||||
|
||||
try{
|
||||
return fileCache[fullPath] = File.ReadAllText(fullPath, Encoding.UTF8);
|
||||
return fileCache[token, cacheKey] = File.ReadAllText(fullPath, Encoding.UTF8);
|
||||
}catch(FileNotFoundException){
|
||||
throw new Exception("File not found.");
|
||||
}catch(DirectoryNotFoundException){
|
||||
@ -60,17 +73,17 @@ public void WriteFile(int token, string path, string contents){
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(fullPath));
|
||||
|
||||
File.WriteAllText(fullPath, contents, Encoding.UTF8);
|
||||
fileCache[fullPath] = contents;
|
||||
fileCache[token, SanitizeCacheKey(path)] = contents;
|
||||
}
|
||||
|
||||
public string ReadFile(int token, string path, bool cache){
|
||||
return ReadFileUnsafe(GetFullPathOrThrow(token, PluginFolder.Data, path), cache);
|
||||
return ReadFileUnsafe(token, path, GetFullPathOrThrow(token, PluginFolder.Data, path), cache);
|
||||
}
|
||||
|
||||
public void DeleteFile(int token, string path){
|
||||
string fullPath = GetFullPathOrThrow(token, PluginFolder.Data, path);
|
||||
|
||||
fileCache.Remove(fullPath);
|
||||
fileCache.Remove(token, SanitizeCacheKey(path));
|
||||
File.Delete(fullPath);
|
||||
}
|
||||
|
||||
@ -79,7 +92,7 @@ public bool CheckFileExists(int token, string path){
|
||||
}
|
||||
|
||||
public string ReadFileRoot(int token, string path){
|
||||
return ReadFileUnsafe(GetFullPathOrThrow(token, PluginFolder.Root, path), true);
|
||||
return ReadFileUnsafe(token, "root*"+path, GetFullPathOrThrow(token, PluginFolder.Root, path), true);
|
||||
}
|
||||
|
||||
public bool CheckFileExistsRoot(int token, string path){
|
||||
|
@ -13,6 +13,8 @@ class PluginManager{
|
||||
public const string PluginNotificationScriptFile = "plugins.notification.js";
|
||||
public const string PluginGlobalScriptFile = "plugins.js";
|
||||
|
||||
private const int InvalidToken = 0;
|
||||
|
||||
public string PathOfficialPlugins { get { return Path.Combine(rootPath, "official"); } }
|
||||
public string PathCustomPlugins { get { return Path.Combine(rootPath, "user"); } }
|
||||
|
||||
@ -63,6 +65,16 @@ public bool HasAnyPlugin(PluginEnvironment environment){
|
||||
return plugins.Any(plugin => plugin.Environments.HasFlag(environment));
|
||||
}
|
||||
|
||||
public int GetTokenFromPlugin(Plugin plugin){
|
||||
foreach(KeyValuePair<int, Plugin> kvp in tokens){
|
||||
if (kvp.Value.Equals(plugin)){
|
||||
return kvp.Key;
|
||||
}
|
||||
}
|
||||
|
||||
return InvalidToken;
|
||||
}
|
||||
|
||||
public Plugin GetPluginFromToken(int token){
|
||||
Plugin plugin;
|
||||
return tokens.TryGetValue(token, out plugin) ? plugin : null;
|
||||
@ -108,7 +120,7 @@ public void ExecutePlugins(IFrame frame, PluginEnvironment environment, bool inc
|
||||
int token;
|
||||
|
||||
if (tokens.ContainsValue(plugin)){
|
||||
token = tokens.First(kvp => kvp.Value.Equals(plugin)).Key;
|
||||
token = GetTokenFromPlugin(plugin);
|
||||
}
|
||||
else{
|
||||
token = GenerateToken();
|
||||
@ -141,7 +153,7 @@ private int GenerateToken(){
|
||||
for(int attempt = 0; attempt < 1000; attempt++){
|
||||
int token = rand.Next();
|
||||
|
||||
if (!tokens.ContainsKey(token)){
|
||||
if (!tokens.ContainsKey(token) && token != InvalidToken){
|
||||
return token;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user