-
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathResolver.cs
More file actions
146 lines (119 loc) · 4.44 KB
/
Resolver.cs
File metadata and controls
146 lines (119 loc) · 4.44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Playnite.SDK;
using Playnite.SDK.Models;
using Playnite.SDK.Plugins;
namespace Plugin
{
namespace Resolver
{
public interface IResolver
{
/*
* Name of the resolver
*/
string Name { get; }
/*
* Example input patterns the resolver can match, used only to inform the user
*/
string[] ExamplePatterns { get; }
/*
* Returns true if the resolver can match the given values.
*/
bool Match(MatchOptions options);
/*
* Return a metadata provider for the given game. This follows the same pattern as Metadata plugins.
* See https://api.playnite.link/docs/tutorials/extensions/metadataPlugins.html#ondemandmetadataprovider
* You can return null if you don't want to provide metadata for the given game.
*/
OnDemandMetadataProvider Resolve(Game game, ResolveOptions options);
/*
* Return a string that will be used as the game id for the given game.
*/
string ResolveGameId(Game game, ResolveOptions options);
/*
* Return a string that will be used as the game source for the given game.
*/
string ResolveGameSource(Game game, ResolveOptions options);
}
public class MatchOptions
{
public Uri Url { get; set; } = null;
public string Name { get; set; } = null;
public virtual MatchOptions Clone()
{
var o = new MatchOptions();
o.Url = Url;
o.Name = Name;
return o;
}
public override string ToString()
{
return $"<Name: {Name} Url: {Url}>";
}
}
public class ResolveOptions : MatchOptions
{
public MetadataRequestOptions MetadataRequestOptions { get; private set; } = null;
public Uri OriginalUrl { get; private set; } = null;
public bool IsBackgroundDownload { get { return MetadataRequestOptions.IsBackgroundDownload; } }
public ResolveOptions(Uri url, MetadataRequestOptions options, MatchOptions opts = null)
{
OriginalUrl = url;
MetadataRequestOptions = options;
if (opts != null)
{
Url = opts.Url;
Name = opts.Name;
}
}
public override MatchOptions Clone()
{
throw new Exception("ResolveOptions cannot be cloned");
}
}
static public class ResolverBuilder
{
public static readonly ILogger log = LogManager.GetLogger();
private static readonly Dictionary<string, IResolver> resolvers = new Dictionary<string, IResolver>();
static public T Create<T>() where T : IResolver
{
return (T)Create(typeof(T));
}
static public IResolver Create(Type resolver)
{
if (resolver.GetType().IsAssignableFrom(typeof(IResolver)))
{
throw new Exception("Given object is not a Resolver");
}
return (IResolver)Activator.CreateInstance(resolver);
}
static public IResolver[] GetResolvers()
{
var ass = Meta.AssemblyUtils.GetAssembly();
foreach (var t in Meta.AssemblyUtils.GetTypesWithInterface<IResolver>(ass))
{
if (!resolvers.ContainsKey(t.FullName))
{
try
{
resolvers.Add(t.FullName, Create(t));
}
catch (Exception)
{
log.Error($"Failed to create resolver {t.FullName}");
}
}
}
var res = resolvers.Values.ToList();
log.Debug($"Found {resolvers.Count} resolvers");
#if DEV
log.Trace($"{String.Join("\n", resolvers.Select(x => x.Value.Name))}");
#endif
return res.ToArray();
}
}
}
}