Repository navigation
Expand file tree
/
Copy pathreadme.dev
More file actions
300 lines (223 loc) · 9.13 KB
/
Copy pathreadme.dev
File metadata and controls
300 lines (223 loc) · 9.13 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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
# DuplicateHider - Developer Documentation
This document provides information for developers who want to contribute to or build DuplicateHider.
## Prerequisites
- **Visual Studio 2019 or later** (or any IDE that supports .NET Framework 4.6.2)
- **.NET Framework 4.6.2** or higher
- **Playnite** installed (for testing)
- **Git** for version control
## Project Structure
```
DuplicateHider/
├── source/ # Main source code
│ ├── Cache/ # Caching implementations
│ ├── Controls/ # Custom WPF controls
│ ├── Converters/ # WPF value converters
│ ├── Data/ # Data models
│ ├── Filters/ # Game filtering logic
│ ├── icons/ # Built-in source icons
│ ├── Localization/ # Translation files (XAML)
│ ├── Models/ # View models and data structures
│ ├── ViewModels/ # MVVM view models
│ ├── Views/ # XAML views
│ ├── Windows/ # Window implementations
│ ├── DuplicateHiderPlugin.cs # Main plugin class
│ ├── DuplicateHiderSettings.cs # Settings model
│ └── extension.yaml # Plugin manifest
├── UiIntegrationExamples/ # Theme integration examples
├── README.md # User documentation
├── CHANGELOG.md # Version history
└── LICENSE # MIT License
```
## Dependencies
The project uses the following NuGet packages:
- **PlayniteSDK** (v6.2.0) - Playnite API for plugin development
- **Newtonsoft.Json** (v10.0.3) - JSON serialization
- **gong-wpf-dragdrop** (v2.4.1) - Drag and drop functionality
Additional SDKs (referenced locally):
- **QuickSearchSDK** - Integration with QuickSearch extension
- **StartPage.SDK** - Integration with StartPage extension
## Building the Project
### Using Visual Studio
1. Clone the repository:
```bash
git clone https://github.com/ap0ught/DuplicateHider.git
cd DuplicateHider
```
2. Open `source/DuplicateHider.sln` in Visual Studio
3. Restore NuGet packages:
- Visual Studio will automatically restore packages on build
- Or manually: Right-click solution → "Restore NuGet Packages"
4. Build the solution:
- Press `Ctrl+Shift+B` or
- Menu: Build → Build Solution
5. Output will be in `source/bin/Debug/` or `source/bin/Release/`
### Using MSBuild (Command Line)
```bash
cd source
msbuild DuplicateHider.sln /p:Configuration=Release
```
### Post-Build Process
The project includes a post-build event that uses Playnite's Toolbox to package the extension:
```
%LOCALAPPDATA%\Playnite\Toolbox.exe pack $(ProjectDir)$(OutDir) $(ProjectDir)bin
```
This creates a `.pext` file that can be installed in Playnite.
## Installing for Development
1. Build the project in Debug or Release mode
2. Copy the output from `source/bin/Debug/` (or Release) to Playnite's extension folder:
```
%APPDATA%\Playnite\Extensions\felixkmh_DuplicateHider_Plugin\
```
3. Restart Playnite to load the extension
### Hot Reload During Development
For faster iteration:
1. Build the project
2. Use Playnite's extension reload feature (if available)
3. Or restart Playnite
## Debugging
1. In Visual Studio, set up debugging:
- Right-click the project → Properties
- Go to the Debug tab
- Set "Start external program" to your Playnite executable path
(typically `C:\Program Files\Playnite\Playnite.DesktopApp.exe`)
2. Set breakpoints in your code
3. Press `F5` to start debugging
- Playnite will launch and load your extension
- Your breakpoints will be hit when the code executes
## Code Structure
### Main Components
- **DuplicateHiderPlugin.cs**: Core plugin class implementing `GenericPlugin`
- Manages game indexing and duplicate detection
- Handles UI integration with themes
- Provides menu items and commands
- **DuplicateHiderSettings.cs**: Plugin settings model
- Priority lists for sources
- Game filters
- UI integration options
- **UiIntegration.cs**: Custom UI elements for theme integration
- SourceSelector controls
- ContentControl implementations
### Key Features
1. **Game Indexing**: Uses async/parallel processing to build duplicate indices
2. **Priority System**: Ranks game copies based on source priority and installation status
3. **UI Integration**: Provides custom WPF controls for theme developers
4. **Icon Management**: Caches and serves source icons (built-in, theme, or user-provided)
## Localization
Translation files are located in `source/Localization/` as XAML resource dictionaries.
To add a new language:
1. Copy an existing localization file (e.g., `en_US.xaml`)
2. Rename it with the appropriate language code
3. Translate the string values
4. The plugin will automatically detect and load it
Translations are managed via [Crowdin](https://crowdin.com/project/duplicatehider).
## Testing
Currently, the project does not have automated unit tests. Testing is done manually:
1. Build and install the extension
2. Launch Playnite
3. Test various scenarios:
- Adding duplicate games
- Changing priority settings
- Testing UI integration with different themes
- Verifying game hiding/revealing functionality
## Contributing
### Workflow
1. Fork the repository
2. Create a feature branch: `git checkout -b feature/your-feature-name`
3. Make your changes
4. Test thoroughly
5. Commit with meaningful messages (see Commit Guidelines below)
6. Push to your fork
7. Create a Pull Request
### Commit Guidelines
This project uses [Commitizen](https://github.com/commitizen/cz-cli) for consistent commit messages:
- `feat:` New feature
- `fix:` Bug fix
- `docs:` Documentation changes
- `refactor:` Code refactoring
- `perf:` Performance improvements
- `test:` Adding tests
- `chore:` Maintenance tasks
Version bumps are managed automatically using `commitizen`.
### Code Style
- Follow existing code patterns in the project
- Use meaningful variable and method names
- Add comments for complex logic
- Keep methods focused and concise
- Use async/await for I/O operations
## Versioning
Version information is stored in:
- `source/extension.yaml` (Version field)
- `pyproject.toml` (for commitizen)
To bump the version:
```bash
cz bump
```
This will:
1. Update version in `extension.yaml`
2. Create a git tag
3. Update `CHANGELOG.md`
### Version Compatibility and Playnite SDK
DuplicateHider's version compatibility is tightly coupled to the Playnite SDK version:
| DuplicateHider Version | Playnite Version | PlayniteSDK Version | Key Differences |
|------------------------|------------------|---------------------|-----------------|
| 2.x (≤ 2.5.4) | 8.x | 5.x | Core functionality only |
| 3.x | 9.x | 6.x | Adds UI integration via `GetGameViewControl` |
**Important SDK Differences:**
**Playnite 8 (SDK 5.x):**
- No `GetGameViewControl` method
- Limited custom UI integration
- Different event signatures in some cases
- Older dialog and notification APIs
**Playnite 9 (SDK 6.x):**
- Introduces `GetGameViewControl(GetGameViewControlArgs args)` for custom UI elements
- Enhanced theme integration capabilities
- Improved extension lifecycle management
- Better performance for extension UI components
**Code Example - Playnite 9 Specific Feature:**
```csharp
// This method only exists in Playnite 9 (SDK 6.x+)
public override Control GetGameViewControl(GetGameViewControlArgs args)
{
if (settings.EnableUiIntegration)
{
if (args.Name == "SourceSelector")
{
return new SourceSelector(0, Orientation.Horizontal);
}
// ... more UI integration code
}
return null;
}
```
If you need to support both versions, consider using conditional compilation:
```csharp
#if PLAYNITE9
public override Control GetGameViewControl(GetGameViewControlArgs args)
{
// Playnite 9 implementation
}
#endif
```
Then define the compilation symbol in your `.csproj`:
```xml
<PropertyGroup Condition="'$(PlayniteSDKVersion)' == '6'">
<DefineConstants>$(DefineConstants);PLAYNITE9</DefineConstants>
</PropertyGroup>
```
## Theme Integration
For theme developers, see the [Theme Integration](README.md#theme-integration) section in the main README.
Example files are available in the `UiIntegrationExamples/` directory:
- SourceSelector examples
- ContentControl examples
- Full theme integration examples
## Additional Resources
- [Playnite Extension Development](https://github.com/JosefNemec/Playnite/wiki/Extensions)
- [Playnite SDK Documentation](https://github.com/JosefNemec/Playnite/wiki)
- [Project Forum Thread](https://playnite.link/forum/thread-308.html)
- [GitHub Repository](https://github.com/felixkmh/DuplicateHider)
## License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
## Support
- Report issues on [GitHub Issues](https://github.com/felixkmh/DuplicateHider/issues)
- Discuss on [Playnite Forum](https://playnite.link/forum/thread-308.html)
- Contribute translations on [Crowdin](https://crowdin.com/project/duplicatehider)