├── .gitattributes
├── .gitignore
├── LICENSE
├── README.md
├── docs
├── README.md
├── _config.yml
└── img
│ ├── GameBoxView Formatted Text.png
│ └── GameBoxView.PNG
└── src
├── .editorconfig
├── ManiaPlanetSharp.CustomParserGenerationTest
├── App.config
├── ManiaPlanetSharp.CustomParserGenerationTest.csproj
├── Program.cs
└── Properties
│ └── AssemblyInfo.cs
├── ManiaPlanetSharp.GameBox.AutoGenerated
├── ChunkParsers.tt
├── Classes.tt
├── GlobalSuppressions.cs
├── ManiaPlanetSharp.GameBox.AutoGenerated.csproj
└── StructParsers.tt
├── ManiaPlanetSharp.GameBox.Parsing.Benchmark
├── ManiaPlanetSharp.GameBox.Parsing.Benchmark.csproj
├── ParserBenchmark.cs
├── PreGeneratedParserBenchmark.cs
├── Program.cs
├── RuntimeGeneratedParserBenchmark.cs
└── TestMap.Gbx
├── ManiaPlanetSharp.GameBox.Parsing.ParserGenerationIntegrityTest
├── ManiaPlanetSharp.GameBox.Parsing.ParserGenerationIntegrityTest.csproj
├── Program.cs
└── TestMap.Gbx
├── ManiaPlanetSharp.GameBoxView
├── App.xaml
├── App.xaml.cs
├── AssemblyInfo.cs
├── GameBoxMetadataViewModel.cs
├── MainWindow.xaml
├── MainWindow.xaml.cs
├── ManiaPlanetSharp.GameBoxView.csproj
├── RelayCommand.cs
├── TreeNodes
│ ├── Advanced
│ │ ├── ChunkTreeNode.cs
│ │ ├── DecorationTreeNode.cs
│ │ ├── DependencyTreeNode.cs
│ │ ├── EmbeddedItemTreeNode.cs
│ │ ├── FileReferenceTreeNode.cs
│ │ ├── PlayerTreeNode.cs
│ │ ├── ReferenceTableFolderTreeNode.cs
│ │ ├── ReferenceTableTreeNode.cs
│ │ ├── TimeTreeNode.cs
│ │ ├── TimesTreeNode.cs
│ │ └── VehicleTreeNode.cs
│ ├── ButtonTreeNode.cs
│ ├── FormattedTextTreeNode.cs
│ ├── HyperlinkTreeNode.cs
│ ├── ImageTreeNode.cs
│ ├── Metadata
│ │ ├── EmbeddedMapTreeNode.cs
│ │ ├── FileMetadataTreeNode.cs
│ │ ├── ItemMetadataTreeNode.cs
│ │ ├── MacroblockMetadataTreeNode.cs
│ │ ├── MapMetadataTreeNode.cs
│ │ └── MetadataTreeNode.cs
│ └── TextTreeNode.cs
├── TreeViewItemHelper.cs
└── Utils.cs
├── ManiaPlanetSharp.ParserTest
├── ManiaPlanetSharp.ParserTest.csproj
└── Program.cs
├── ManiaPlanetSharp.sln
└── ManiaPlanetSharp
├── GameBox
├── Chunk.cs
├── ClassId.cs
├── GameBoxFile.cs
├── MetadataProviders
│ ├── CollectorMetadataProvider.cs
│ ├── ItemMetadataProvider.cs
│ ├── MacroBlockMetadataProvider.cs
│ ├── MapMetadataProvider.cs
│ ├── MetadataProvider.cs
│ └── ReplayMetadataProvider.cs
├── Node.cs
├── ParseException.cs
├── Parsing
│ ├── Chunks
│ │ ├── Collector
│ │ │ ├── CollectorBasicMetadataChunk.cs
│ │ │ ├── CollectorBrowserMetadataChunk.cs
│ │ │ ├── CollectorCatalogChunk.cs
│ │ │ ├── CollectorDefaultSkinChunk.cs
│ │ │ ├── CollectorDescriptionChunk.cs
│ │ │ ├── CollectorIconChunk.cs
│ │ │ ├── CollectorIconMetadataChunk.cs
│ │ │ ├── CollectorLightmapCacheIdChunk.cs
│ │ │ ├── CollectorListChunk.cs
│ │ │ ├── CollectorMetadataChunk.cs
│ │ │ └── CollectorNameChunk.cs
│ │ ├── Ghost
│ │ │ ├── GhostCheckpointEntriesChunk.cs
│ │ │ ├── GhostChunk.cs
│ │ │ ├── GhostDataChunk.cs
│ │ │ ├── GhostDisplayChunk.cs
│ │ │ ├── GhostLightTrailColorChunk.cs
│ │ │ ├── GhostLoginChunk.cs
│ │ │ ├── GhostPlayerMobilIdChunk.cs
│ │ │ ├── GhostRaceTimeChunk.cs
│ │ │ ├── GhostRespawnCountChunk.cs
│ │ │ ├── GhostStuntScoreChunk.cs
│ │ │ ├── GhostUidChunk.cs
│ │ │ ├── GhostUnknown2Chunk.cs
│ │ │ ├── GhostUnknown3Chunk.cs
│ │ │ ├── GhostUnknown4Chunk.cs
│ │ │ ├── GhostUnknown5Chunk.cs
│ │ │ ├── GhostUnknown6Chunk.cs
│ │ │ └── GhostUnknown7Chunk.cs
│ │ ├── Map
│ │ │ ├── MapAuthorChunk.cs
│ │ │ ├── MapChallengeParameterChunk.cs
│ │ │ ├── MapCheckpointsChunk.cs
│ │ │ ├── MapChunk.cs
│ │ │ ├── MapCommonChunk.cs
│ │ │ ├── MapCommunityChunk.cs
│ │ │ ├── MapCoordinateChunk.cs
│ │ │ ├── MapCustomMusicChunk.cs
│ │ │ ├── MapDescriptionChunk.cs
│ │ │ ├── MapEmbeddedItemsChunk.cs
│ │ │ ├── MapGlobalClipChunk.cs
│ │ │ ├── MapGmCamArchiveChunk.cs
│ │ │ ├── MapLapCountChunk.cs
│ │ │ ├── MapLightmapChunk.cs
│ │ │ ├── MapMediaTrackerChunk.cs
│ │ │ ├── MapModpackChunk.cs
│ │ │ ├── MapPasswordChunk.cs
│ │ │ ├── MapPasswordChunkOld.cs
│ │ │ ├── MapPlaymodeChunk.cs
│ │ │ ├── MapThumbnailChunk.cs
│ │ │ ├── MapTimeChunk.cs
│ │ │ ├── MapTimelimitChunk.cs
│ │ │ ├── MapTimelimitTimeChunk.cs
│ │ │ ├── MapTipChunk.cs
│ │ │ ├── MapVehicleChunk.cs
│ │ │ └── MapVersionChunk.cs
│ │ ├── MediaTracker
│ │ │ └── MediaTrackerTrianglesChunk.cs
│ │ ├── Object
│ │ │ ├── ObjectAnchorChunk.cs
│ │ │ ├── ObjectAudioEnvironmentChunk.cs
│ │ │ ├── ObjectBannerProfileChunk.cs
│ │ │ ├── ObjectBaseAttributesChunk.cs
│ │ │ ├── ObjectCameraIndexChunk.cs
│ │ │ ├── ObjectCamerasChunk.cs
│ │ │ ├── ObjectDecoratorSolidChunk.cs
│ │ │ ├── ObjectDefaultSkinChunk.cs
│ │ │ ├── ObjectGroundPointChunk.cs
│ │ │ ├── ObjectItemTypeChunk.cs
│ │ │ ├── ObjectMaterialChunk.cs
│ │ │ ├── ObjectModelChunk.cs
│ │ │ ├── ObjectNadeoSkinFileChunk.cs
│ │ │ ├── ObjectRaceInterfaceChunk.cs
│ │ │ ├── ObjectTypeChunk.cs
│ │ │ ├── ObjectUnknownChunk.cs
│ │ │ └── ObjectUsabilityChunk.cs
│ │ ├── Other
│ │ │ ├── GameSkinChunk.cs
│ │ │ ├── PackDescriptionChunk.cs
│ │ │ ├── PhysicalModelChunk.cs
│ │ │ ├── VisualModelChunk.cs
│ │ │ └── WaypointSpecialPropertyChunk.cs
│ │ ├── Replay
│ │ │ ├── ReplayCommunityChunk.cs
│ │ │ ├── ReplayGhostsChunk.cs
│ │ │ ├── ReplayMainChunk.cs
│ │ │ ├── ReplayUnknown2Chunk.cs
│ │ │ ├── ReplayUnknownChunk.cs
│ │ │ └── ReplayVersionChunk.cs
│ │ └── TMUnlimiter
│ │ │ ├── ChallengeBackendChunk.cs
│ │ │ ├── LegacyParameterSetChunk.cs
│ │ │ └── LegacyScriptChunk.cs
│ ├── GameBoxReader.cs
│ ├── GlobalParserSettings.cs
│ ├── Parser.cs
│ ├── ParserFactory.cs
│ ├── ParserGeneration
│ │ ├── Attributes
│ │ │ ├── ArrayAttribute.cs
│ │ │ ├── ChunkAttribute.cs
│ │ │ ├── ConditionAttribute.cs
│ │ │ ├── CustomParserMethodAttribute.cs
│ │ │ ├── CustomStructAttribute.cs
│ │ │ └── PropertyAttribute.cs
│ │ ├── Field.cs
│ │ ├── ParserCodeGenerator.cs
│ │ ├── ParserGenerator.cs
│ │ └── ParserGeneratorException.cs
│ ├── ParsingErrorLogger.cs
│ └── Utils
│ │ └── ParsedValueMappings.cs
└── Types
│ ├── FileFormat.cs
│ ├── FileReference.cs
│ ├── GameCtnBlockSkin.cs
│ ├── Size2D.cs
│ ├── Size3D.cs
│ ├── Vector2D.cs
│ └── Vector3D.cs
├── GlobalSuppressions.cs
├── ManiaPlanetSharp.csproj
├── Properties
├── Resources.Designer.cs
├── Resources.resx
└── launchSettings.json
├── TMUnlimiter
├── BlockData.cs
├── ChallengeBackend.cs
├── DecorationVisibility.cs
├── LegacyMediaClipResource.cs
├── LegacyScript.cs
├── LegacyScriptExecutionType.cs
├── Parameter.cs
├── ParameterFunction.cs
├── ParameterSet.cs
├── ParameterValueType.cs
├── SpawnPointAlterMethod.cs
├── TrackVersion.cs
├── Vanilla
│ └── VersionBackend.cs
├── Version04
│ └── VersionBackend.cs
├── Version06
│ ├── BlockData.cs
│ └── VersionBackend.cs
├── Version07
│ ├── BlockData.cs
│ └── VersionBackend.cs
├── Version11
│ ├── BlockData.cs
│ └── VersionBackend.cs
├── Version12
│ ├── BlockData.cs
│ └── VersionBackend.cs
├── Version13
│ ├── BlockData.cs
│ ├── BlockFlags.cs
│ ├── ChallengeFlags.cs
│ └── VersionBackend.cs
├── Version20
│ └── VersionBackend.cs
└── VersionBackend.cs
└── Utilities
├── IndentingStringBuilder.cs
├── MiniLZO.cs
└── Utils.cs
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
4 | # Custom for Visual Studio
5 | *.cs diff=csharp
6 |
7 | # Standard to msysgit
8 | *.doc diff=astextplain
9 | *.DOC diff=astextplain
10 | *.docx diff=astextplain
11 | *.DOCX diff=astextplain
12 | *.dot diff=astextplain
13 | *.DOT diff=astextplain
14 | *.pdf diff=astextplain
15 | *.PDF diff=astextplain
16 | *.rtf diff=astextplain
17 | *.RTF diff=astextplain
18 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | #################
2 | ## Eclipse
3 | #################
4 |
5 | *.pydevproject
6 | .project
7 | .metadata
8 | bin/
9 | tmp/
10 | *.tmp
11 | *.bak
12 | *.swp
13 | *~.nib
14 | local.properties
15 | .classpath
16 | .settings/
17 | .loadpath
18 |
19 | # External tool builders
20 | .externalToolBuilders/
21 |
22 | # Locally stored "Eclipse launch configurations"
23 | *.launch
24 |
25 | # CDT-specific
26 | .cproject
27 |
28 | # PDT-specific
29 | .buildpath
30 |
31 |
32 | #################
33 | ## Visual Studio
34 | #################
35 |
36 | ## Ignore Visual Studio temporary files, build results, and
37 | ## files generated by popular Visual Studio add-ons.
38 |
39 | # User-specific files
40 | *.suo
41 | *.user
42 | *.sln.docstates
43 |
44 | # Build results
45 |
46 | [Dd]ebug/
47 | [Rr]elease/
48 | x64/
49 | build/
50 | [Bb]in/
51 | [Oo]bj/
52 |
53 | # MSTest test Results
54 | [Tt]est[Rr]esult*/
55 | [Bb]uild[Ll]og.*
56 |
57 | *_i.c
58 | *_p.c
59 | *.ilk
60 | *.meta
61 | *.obj
62 | *.pch
63 | *.pdb
64 | *.pgc
65 | *.pgd
66 | *.rsp
67 | *.sbr
68 | *.tlb
69 | *.tli
70 | *.tlh
71 | *.tmp
72 | *.tmp_proj
73 | *.log
74 | *.vspscc
75 | *.vssscc
76 | .builds
77 | *.pidb
78 | *.log
79 | *.scc
80 |
81 | # Visual C++ cache files
82 | ipch/
83 | *.aps
84 | *.ncb
85 | *.opensdf
86 | *.sdf
87 | *.cachefile
88 |
89 | # Visual Studio profiler
90 | *.psess
91 | *.vsp
92 | *.vspx
93 |
94 | # Guidance Automation Toolkit
95 | *.gpState
96 |
97 | # ReSharper is a .NET coding add-in
98 | _ReSharper*/
99 | *.[Rr]e[Ss]harper
100 |
101 | # TeamCity is a build add-in
102 | _TeamCity*
103 |
104 | # DotCover is a Code Coverage Tool
105 | *.dotCover
106 |
107 | # NCrunch
108 | *.ncrunch*
109 | .*crunch*.local.xml
110 |
111 | # Installshield output folder
112 | [Ee]xpress/
113 |
114 | # DocProject is a documentation generator add-in
115 | DocProject/buildhelp/
116 | DocProject/Help/*.HxT
117 | DocProject/Help/*.HxC
118 | DocProject/Help/*.hhc
119 | DocProject/Help/*.hhk
120 | DocProject/Help/*.hhp
121 | DocProject/Help/Html2
122 | DocProject/Help/html
123 |
124 | # Click-Once directory
125 | publish/
126 |
127 | # Publish Web Output
128 | *.Publish.xml
129 | *.pubxml
130 | *.publishproj
131 |
132 | # NuGet Packages Directory
133 | ## TODO: If you have NuGet Package Restore enabled, uncomment the next line
134 | #packages/
135 |
136 | # Windows Azure Build Output
137 | csx
138 | *.build.csdef
139 |
140 | # Windows Store app package directory
141 | AppPackages/
142 |
143 | # Others
144 | sql/
145 | *.Cache
146 | ClientBin/
147 | [Ss]tyle[Cc]op.*
148 | ~$*
149 | *~
150 | *.dbmdl
151 | *.[Pp]ublish.xml
152 | *.pfx
153 | *.publishsettings
154 |
155 | # RIA/Silverlight projects
156 | Generated_Code/
157 |
158 | # Backup & report files from converting an old project file to a newer
159 | # Visual Studio version. Backup files are not needed, because we have git ;-)
160 | _UpgradeReport_Files/
161 | Backup*/
162 | UpgradeLog*.XML
163 | UpgradeLog*.htm
164 |
165 | # SQL Server files
166 | App_Data/*.mdf
167 | App_Data/*.ldf
168 |
169 | #############
170 | ## Windows detritus
171 | #############
172 |
173 | # Windows image file caches
174 | Thumbs.db
175 | ehthumbs.db
176 |
177 | # Folder config file
178 | Desktop.ini
179 |
180 | # Recycle Bin used on file shares
181 | $RECYCLE.BIN/
182 |
183 | # Mac crap
184 | .DS_Store
185 |
186 |
187 | #############
188 | ## Python
189 | #############
190 |
191 | *.py[cod]
192 |
193 | # Packages
194 | *.egg
195 | *.egg-info
196 | dist/
197 | build/
198 | eggs/
199 | parts/
200 | var/
201 | sdist/
202 | develop-eggs/
203 | .installed.cfg
204 |
205 | # Installer logs
206 | pip-log.txt
207 |
208 | # Unit test / coverage reports
209 | .coverage
210 | .tox
211 |
212 | #Translations
213 | *.mo
214 |
215 | #Mr Developer
216 | .mr.developer.cfg
217 | *.jrs
218 | *.ide
219 |
220 |
221 | AeroSuite.sln.GhostDoc.xml
222 | old/ManiaPlanetSharp/.vs
223 | /ManiaPlanetSharp.zip
224 | src/.vs/**
225 | src/ManiaPlanetSharp.GameBox.AutoGenerated/ManiaPlanetSharp.dll
226 | src/ManiaPlanetSharp.dll
227 | src/ManiaPlanetSharp.GameBox.AutoGenerated/ChunkParsers.cs
228 | src/ManiaPlanetSharp.GameBox.AutoGenerated/Classes.cs
229 | src/ManiaPlanetSharp.GameBox.AutoGenerated/StructParsers.cs
230 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017-2020 Stefan Baumann
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/docs/_config.yml:
--------------------------------------------------------------------------------
1 | theme: jekyll-theme-cayman
--------------------------------------------------------------------------------
/docs/img/GameBoxView Formatted Text.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stefan-baumann/ManiaPlanetSharp/e5b95bcd806bf2ebb0ea8776576861ccb6e4cd83/docs/img/GameBoxView Formatted Text.png
--------------------------------------------------------------------------------
/docs/img/GameBoxView.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stefan-baumann/ManiaPlanetSharp/e5b95bcd806bf2ebb0ea8776576861ccb6e4cd83/docs/img/GameBoxView.PNG
--------------------------------------------------------------------------------
/src/.editorconfig:
--------------------------------------------------------------------------------
1 | [*.cs]
2 |
3 | # CS0618: Type or member is obsolete
4 | dotnet_diagnostic.CS0618.severity = none
5 |
--------------------------------------------------------------------------------
/src/ManiaPlanetSharp.CustomParserGenerationTest/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/src/ManiaPlanetSharp.CustomParserGenerationTest/ManiaPlanetSharp.CustomParserGenerationTest.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {F3949E03-50D8-4C0F-A723-2C23F69D51EA}
8 | Exe
9 | ManiaPlanetSharp.CustomParserGenerationTest
10 | ManiaPlanetSharp.CustomParserGenerationTest
11 | v4.6.1
12 | 512
13 | true
14 |
15 |
16 | AnyCPU
17 | true
18 | full
19 | false
20 | bin\Debug\
21 | DEBUG;TRACE
22 | prompt
23 | 4
24 |
25 |
26 | AnyCPU
27 | pdbonly
28 | true
29 | bin\Release\
30 | TRACE
31 | prompt
32 | 4
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 | .editorconfig
51 |
52 |
53 |
54 |
55 |
56 | {2461a29a-da40-4a58-b4f4-9c1f3762c5b2}
57 | ManiaPlanetSharp.GameBox.AutoGenerated
58 |
59 |
60 | {ae645ff0-e68e-4c6f-b17d-6758f4596164}
61 | ManiaPlanetSharp
62 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/src/ManiaPlanetSharp.CustomParserGenerationTest/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("ManiaPlanetSharp.CustomParserGenerationTest")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("ManiaPlanetSharp.CustomParserGenerationTest")]
13 | [assembly: AssemblyCopyright("Copyright © 2019")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("f3949e03-50d8-4c0f-a723-2c23f69d51ea")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/src/ManiaPlanetSharp.GameBox.AutoGenerated/ChunkParsers.tt:
--------------------------------------------------------------------------------
1 | <#@ template debug="true" hostspecific="false" language="C#" #>
2 | <#@ assembly name="System" #>
3 | <#@ assembly name="System.Console, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" #>
4 | <#@ assembly name="System.Core" #>
5 | <#@ assembly name="System.Reflection" #>
6 | <#@ assembly name="System.Linq" #>
7 | <#@ assembly name="System.Runtime, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" #>
8 | <#@ assembly name="netstandard" #>
9 | <#@ assembly name="mscorlib" #>
10 | <#@ assembly name="ManiaPlanetSharp.dll" #>
11 | <#@ import namespace="System" #>
12 | <#@ import namespace="System.Collections" #>
13 | <#@ import namespace="System.Collections.Generic" #>
14 | <#@ import namespace="System.Diagnostics" #>
15 | <#@ import namespace="System.Reflection" #>
16 | <#@ import namespace="System.Runtime" #>
17 | <#@ import namespace="System.Runtime.CompilerServices" #>
18 | <#@ import namespace="System.Runtime.InteropServices" #>
19 | <#@ import namespace="System.Linq" #>
20 | <#@ import namespace="System.Text" #>
21 | <#@ import namespace="System.Text.RegularExpressions" #>
22 | <#@ import namespace="ManiaPlanetSharp.GameBox" #>
23 | <#@ import namespace="ManiaPlanetSharp.GameBox.Parsing" #>
24 | <#@ import namespace="ManiaPlanetSharp.GameBox.Parsing.ParserGeneration" #>
25 | <#@ output extension=".cs" #>
26 | using System;
27 | using System.Collections;
28 | using System.Collections.Generic;
29 | using ManiaPlanetSharp.GameBox.Parsing.Chunks;
30 |
31 | namespace ManiaPlanetSharp.GameBox.Parsing.ParserGeneration.AutoGenerated
32 | {
33 | public static partial class AutoGeneratedParsers
34 | {
35 | public static Dictionary> ChunkParsers { get; } = new Dictionary> {
36 | <#
37 | var assemblies = AppDomain.CurrentDomain.GetAssemblies().Where(p => !p.IsDynamic);
38 | var chunkTypes = assemblies.SelectMany(a => a.GetExportedTypes().Where(t => t != typeof(Chunk) && typeof(Chunk).IsAssignableFrom(t) && t.CustomAttributes.Where(x => x.AttributeType == typeof(ChunkAttribute)).Any()));
39 | foreach (var chunkType in chunkTypes)
40 | {
41 | #> { typeof(<#= chunkType #>), new <#= chunkType.Name #>Parser() },
42 | <#
43 | }
44 | #>
45 | };
46 | }
47 | <#
48 | foreach (var chunkType in chunkTypes)
49 | {
50 | Console.WriteLine($"Generating parser for type {chunkType.Name}");
51 | string code = (string)typeof(ParserCodeGenerator).GetMethod(nameof(ParserCodeGenerator.GenerateChunkParserString), BindingFlags.Static | BindingFlags.Public).MakeGenericMethod(chunkType).Invoke(null, null);
52 | List> ids = (List>)typeof(ParserCodeGenerator).GetMethod(nameof(ParserCodeGenerator.GetParserChunkIds), BindingFlags.Static | BindingFlags.Public).MakeGenericMethod(chunkType).Invoke(null, null);
53 | #>
54 |
55 | public class <#= chunkType.Name #>Parser
56 | : PregeneratedChunkParser<<#= chunkType #>>
57 | {
58 | public override List> ParseableIds => new List>() { <#= string.Join(", ", ids.Select(i => $"Tuple.Create(0x{i.Item1:X8}U, {(i.Item2 ? "true" : "false")})")) #> };
59 |
60 | public override <#= chunkType #> Parse(GameBoxReader reader, uint chunkId)
61 | {
62 | <#= string.Join(Environment.NewLine, code/*.Replace(chunkType.Name, chunkType.FullName)*/.Split(new[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries).Select(line => $"\t\t\t{line}")) #>
63 | }
64 | }
65 | <#
66 | }
67 | #>
68 | }
69 |
--------------------------------------------------------------------------------
/src/ManiaPlanetSharp.GameBox.AutoGenerated/Classes.tt:
--------------------------------------------------------------------------------
1 | <#@ template debug="false" hostspecific="false" language="C#" #>
2 | <#@ assembly name="System.Core" #>
3 | <#@ assembly name="netstandard" #>
4 | <#@ assembly name="ManiaPlanetSharp.dll" #>
5 | <#@ import namespace="System.Linq" #>
6 | <#@ import namespace="System.Text" #>
7 | <#@ import namespace="System.Collections.Generic" #>
8 | <#@ import namespace="System.Reflection" #>
9 | <#@ import namespace="ManiaPlanetSharp.GameBox" #>
10 | <#@ import namespace="ManiaPlanetSharp.GameBox.Parsing" #>
11 | <#@ import namespace="ManiaPlanetSharp.GameBox.Parsing.ParserGeneration" #>
12 | <#@ output extension=".cs" #>
13 | <#
14 | Assembly mpSharp = Assembly.GetAssembly(typeof(Chunk));
15 | var chunks = mpSharp.GetExportedTypes().Where(t => typeof(Chunk).IsAssignableFrom(t) && t != typeof(Chunk) && t.GetCustomAttributes().Any());
16 | var classes = chunks.SelectMany(c => c.GetCustomAttributes().Select(ca => Tuple.Create(ca.Id, c))).GroupBy(c => c.Item1 & ~0xFFFU);
17 | foreach (var @class in classes)
18 | {
19 | var classId = @class.Key;
20 | #>//<#= KnownClassIds.GetClassName(classId) #>
21 | <#
22 | foreach (var chunk in @class)
23 | {
24 | #>
25 | // - Chunk <#= chunk.Item2.Name #> (<#= $"0x{chunk.Item1:X8}" #>)
26 | <#
27 | }
28 | #>
29 |
30 | <#
31 | }
32 | #>
--------------------------------------------------------------------------------
/src/ManiaPlanetSharp.GameBox.AutoGenerated/GlobalSuppressions.cs:
--------------------------------------------------------------------------------
1 |
2 | // This file is used by Code Analysis to maintain SuppressMessage
3 | // attributes that are applied to this project.
4 | // Project-level suppressions either have no target or are given
5 | // a specific target and scoped to a namespace, type, member, etc.
6 |
7 | [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE0017:Simplify object initialization", Justification = "")]
--------------------------------------------------------------------------------
/src/ManiaPlanetSharp.GameBox.AutoGenerated/StructParsers.tt:
--------------------------------------------------------------------------------
1 | <#@ template debug="true" hostspecific="false" language="C#" #>
2 | <#@ assembly name="System" #>
3 | <#@ assembly name="System.Runtime, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" #>
4 | <#@ assembly name="System.Console, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" #>
5 | <#@ assembly name="System.Core" #>
6 | <#@ assembly name="System.Linq" #>
7 | <#@ assembly name="System.Reflection" #>
8 | <#@ assembly name="netstandard" #>
9 | <#@ assembly name="mscorlib" #>
10 | <#@ assembly name="ManiaPlanetSharp.dll" #>
11 | <#@ import namespace="System" #>
12 | <#@ import namespace="System.Collections" #>
13 | <#@ import namespace="System.Collections.Generic" #>
14 | <#@ import namespace="System.Diagnostics" #>
15 | <#@ import namespace="System.Reflection" #>
16 | <#@ import namespace="System.Runtime" #>
17 | <#@ import namespace="System.Runtime.InteropServices" #>
18 | <#@ import namespace="System.Linq" #>
19 | <#@ import namespace="System.Text" #>
20 | <#@ import namespace="System.Text.RegularExpressions" #>
21 | <#@ import namespace="ManiaPlanetSharp.GameBox" #>
22 | <#@ import namespace="ManiaPlanetSharp.GameBox.Parsing" #>
23 | <#@ import namespace="ManiaPlanetSharp.GameBox.Parsing.ParserGeneration" #>
24 | <#@ output extension=".cs" #>
25 | using System;
26 | using System.Diagnostics;
27 | using System.Collections;
28 | using System.Collections.Generic;
29 | using System.Linq;
30 | using ManiaPlanetSharp.GameBox.Parsing.Chunks;
31 |
32 | namespace ManiaPlanetSharp.GameBox.Parsing.ParserGeneration.AutoGenerated
33 | {
34 | public static partial class AutoGeneratedParsers
35 | {
36 | public static Dictionary> StructParsers { get; } = new Dictionary> {
37 | <#
38 | var assemblies = AppDomain.CurrentDomain.GetAssemblies().Where(p => !p.IsDynamic);
39 | var structTypes = assemblies.SelectMany(a => a.GetExportedTypes().Where(t => t.CustomAttributes.Where(x => x.AttributeType == typeof(CustomStructAttribute)).Any()));
40 | foreach (var structType in structTypes)
41 | {
42 | #> { typeof(<#= structType #>), new <#= structType.Name #>Parser() },
43 | <#
44 | }
45 | #>
46 | };
47 | }
48 |
49 |
50 | <#
51 | foreach (var structType in structTypes)
52 | {
53 | System.Console.WriteLine($"Generating parser for type {structType.Name}");
54 | string code = (string)typeof(ParserCodeGenerator).GetMethod(nameof(ParserCodeGenerator.GenerateStructParserString), BindingFlags.Static | BindingFlags.Public).MakeGenericMethod(structType).Invoke(null, null);
55 | #>
56 |
57 | public class <#= structType.Name #>Parser
58 | : PregeneratedCustomStructParser<<#= structType #>>
59 | {
60 | public override <#= structType #> Parse(GameBoxReader reader)
61 | {
62 | <#= string.Join(Environment.NewLine, code/*.Replace(structType.Name, structType.FullName)*/.Split(new[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries).Select(line => $"\t\t\t{line}")) #>
63 | }
64 | }
65 | <#
66 | }
67 | #>
68 | }
69 |
--------------------------------------------------------------------------------
/src/ManiaPlanetSharp.GameBox.Parsing.Benchmark/ManiaPlanetSharp.GameBox.Parsing.Benchmark.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | netcoreapp3.1
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | PreserveNewest
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/src/ManiaPlanetSharp.GameBox.Parsing.Benchmark/ParserBenchmark.cs:
--------------------------------------------------------------------------------
1 | using BenchmarkDotNet.Attributes;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.IO;
5 | using System.Linq;
6 | using System.Text;
7 |
8 | namespace ManiaPlanetSharp.GameBox.Parsing.Benchmark
9 | {
10 | public abstract class ParserBenchmark
11 | {
12 | protected string gbxPath;
13 | protected byte[] file;
14 | protected GameBoxFile parsedFile;
15 |
16 | [GlobalSetup]
17 | public virtual void Setup()
18 | {
19 | this.gbxPath = Directory.EnumerateFiles(Directory.GetCurrentDirectory(), "*.Gbx").FirstOrDefault();
20 | if (!File.Exists(this.gbxPath))
21 | {
22 | throw new FileNotFoundException("Could not find test gbx file.");
23 | }
24 | Console.WriteLine($"Test file: {gbxPath}");
25 | this.file = File.ReadAllBytes(this.gbxPath);
26 | Console.WriteLine($"File length: {this.file.Length} bytes");
27 | this.parsedFile = GameBoxFile.Parse(new MemoryStream(this.file));
28 | Console.WriteLine($"Uncompressed body length: {this.parsedFile.GetUncompressedBodyData().Length} bytes");
29 | }
30 |
31 | [Benchmark]
32 | public void ParseHeader()
33 | {
34 | GameBoxFile.Parse(new MemoryStream(file));
35 | }
36 |
37 | [Benchmark]
38 | public void ParseBody()
39 | {
40 | this.parsedFile.ParseBody();
41 | }
42 |
43 | [Benchmark]
44 | public void ParseFullFile()
45 | {
46 | GameBoxFile.Parse(new MemoryStream(file)).ParseBody();
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/ManiaPlanetSharp.GameBox.Parsing.Benchmark/PreGeneratedParserBenchmark.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Text;
5 |
6 | namespace ManiaPlanetSharp.GameBox.Parsing.Benchmark
7 | {
8 | public class PreGeneratedParserBenchmark
9 | : ParserBenchmark
10 | {
11 | public override void Setup()
12 | {
13 | base.Setup();
14 |
15 | GlobalParserSettings.UseDynamicallyCompiledChunkParsers = false;
16 | GlobalParserSettings.UsePrecompiledParsersIfPresent = true;
17 | ParserFactory.ClearParsers();
18 | ParserFactory.InitializePrecompiledParsers();
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/ManiaPlanetSharp.GameBox.Parsing.Benchmark/Program.cs:
--------------------------------------------------------------------------------
1 | using BenchmarkDotNet.Running;
2 | using System;
3 |
4 | namespace ManiaPlanetSharp.GameBox.Parsing.Benchmark
5 | {
6 | public static class Program
7 | {
8 | public static void Main(string[] args)
9 | {
10 | BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args);
11 | Console.ReadKey(true);
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/ManiaPlanetSharp.GameBox.Parsing.Benchmark/RuntimeGeneratedParserBenchmark.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace ManiaPlanetSharp.GameBox.Parsing.Benchmark
6 | {
7 | public class RuntimeGeneratedParserBenchmark
8 | : ParserBenchmark
9 | {
10 | public override void Setup()
11 | {
12 | base.Setup();
13 |
14 | ParserFactory.ClearParsers();
15 | GlobalParserSettings.UseDynamicallyCompiledChunkParsers = true;
16 | GlobalParserSettings.UsePrecompiledParsersIfPresent = false;
17 | ParserFactory.ClearParsers();
18 | ParserFactory.ScanForParseableChunks();
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/ManiaPlanetSharp.GameBox.Parsing.Benchmark/TestMap.Gbx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stefan-baumann/ManiaPlanetSharp/e5b95bcd806bf2ebb0ea8776576861ccb6e4cd83/src/ManiaPlanetSharp.GameBox.Parsing.Benchmark/TestMap.Gbx
--------------------------------------------------------------------------------
/src/ManiaPlanetSharp.GameBox.Parsing.ParserGenerationIntegrityTest/ManiaPlanetSharp.GameBox.Parsing.ParserGenerationIntegrityTest.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | netcoreapp3.1
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | PreserveNewest
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/src/ManiaPlanetSharp.GameBox.Parsing.ParserGenerationIntegrityTest/Program.cs:
--------------------------------------------------------------------------------
1 | using KellermanSoftware.CompareNetObjects;
2 | using System;
3 | using System.IO;
4 | using System.Linq;
5 |
6 | namespace ManiaPlanetSharp.GameBox.Parsing.ParserGenerationIntegrityTest
7 | {
8 | class Program
9 | {
10 | static void Main(string[] args)
11 | {
12 | var gbxPath = Directory.EnumerateFiles(Directory.GetCurrentDirectory(), "*.Gbx").FirstOrDefault();
13 | if (!File.Exists(gbxPath))
14 | {
15 | throw new FileNotFoundException("Could not find test gbx file.");
16 | }
17 | Console.WriteLine($"Test file: {gbxPath}");
18 |
19 | var compareLogic = new CompareLogic(new ComparisonConfig() { MaxDifferences = 10 });
20 |
21 | //Runtime
22 | ParserFactory.ClearParsers();
23 | GlobalParserSettings.UseDynamicallyCompiledChunkParsers = true;
24 | GlobalParserSettings.UsePrecompiledParsersIfPresent = false;
25 | ParserFactory.ClearParsers();
26 | ParserFactory.ScanForParseableChunks();
27 |
28 | var runtimeFile = GameBoxFile.Parse(gbxPath);
29 | var runtimeBody = runtimeFile.ParseBody().ToList();
30 |
31 | //Pregenerated
32 | GlobalParserSettings.UseDynamicallyCompiledChunkParsers = false;
33 | GlobalParserSettings.UsePrecompiledParsersIfPresent = true;
34 | ParserFactory.ClearParsers();
35 | ParserFactory.InitializePrecompiledParsers();
36 |
37 | var pregeneratedFile = GameBoxFile.Parse(gbxPath);
38 | var pregeneratedBody = runtimeFile.ParseBody().ToList();
39 |
40 | Console.WriteLine("\n\n# Header and general file metadata");
41 | var fileResult = compareLogic.Compare(pregeneratedFile, runtimeFile);
42 | if (fileResult.AreEqual)
43 | {
44 | Console.WriteLine("Same data. OK.");
45 | }
46 | else
47 | {
48 | Console.WriteLine(fileResult.DifferencesString);
49 | }
50 |
51 | Console.WriteLine("\n\n# Body");
52 | var bodyResult = compareLogic.Compare(pregeneratedBody, runtimeBody);
53 | if (bodyResult.AreEqual)
54 | {
55 | Console.WriteLine("Same data. OK.");
56 | }
57 | else
58 | {
59 | Console.WriteLine(bodyResult.DifferencesString);
60 | }
61 |
62 |
63 | Console.ReadKey(true);
64 | }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/src/ManiaPlanetSharp.GameBox.Parsing.ParserGenerationIntegrityTest/TestMap.Gbx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stefan-baumann/ManiaPlanetSharp/e5b95bcd806bf2ebb0ea8776576861ccb6e4cd83/src/ManiaPlanetSharp.GameBox.Parsing.ParserGenerationIntegrityTest/TestMap.Gbx
--------------------------------------------------------------------------------
/src/ManiaPlanetSharp.GameBoxView/App.xaml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/src/ManiaPlanetSharp.GameBoxView/App.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Configuration;
4 | using System.Data;
5 | using System.IO;
6 | using System.Linq;
7 | using System.Threading.Tasks;
8 | using System.Windows;
9 |
10 | namespace ManiaPlanetSharp.GameBoxView
11 | {
12 | ///
13 | /// Interaction logic for App.xaml
14 | ///
15 | public partial class App : Application
16 | {
17 | private void Application_Startup(object sender, StartupEventArgs e)
18 | {
19 | if (e.Args?.Length == 1)
20 | {
21 | string path = e.Args[0];
22 | if (File.Exists(path) && path.ToLowerInvariant().EndsWith(".gbx"))
23 | {
24 | this.MainWindow = new MainWindow(new GameBoxMetadataViewModel(path));
25 | }
26 | }
27 |
28 | this.MainWindow = this.MainWindow ?? new MainWindow();
29 | this.MainWindow.Show();
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/ManiaPlanetSharp.GameBoxView/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Windows;
2 |
3 | [assembly: ThemeInfo(
4 | ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
5 | //(used if a resource is not found in the page,
6 | // or application resource dictionaries)
7 | ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
8 | //(used if a resource is not found in the page,
9 | // app, or any theme specific resource dictionaries)
10 | )]
11 |
--------------------------------------------------------------------------------
/src/ManiaPlanetSharp.GameBoxView/GameBoxMetadataViewModel.cs:
--------------------------------------------------------------------------------
1 | using ManiaPlanetSharp.GameBox;
2 | using ManiaPlanetSharp.GameBox.MetadataProviders;
3 | using ManiaPlanetSharp.GameBox.Parsing;
4 | using ManiaPlanetSharp.GameBox.Parsing.Chunks;
5 | using System;
6 | using System.Collections.Generic;
7 | using System.Collections.ObjectModel;
8 | using System.ComponentModel;
9 | using System.IO;
10 | using System.Linq;
11 | using System.Runtime.CompilerServices;
12 | using System.Text;
13 | using System.Windows;
14 | using System.Windows.Controls;
15 | using System.Windows.Documents;
16 | using System.Windows.Media;
17 | using System.Windows.Media.Imaging;
18 |
19 | namespace ManiaPlanetSharp.GameBoxView
20 | {
21 | public class GameBoxMetadataViewModel
22 | : INotifyPropertyChanged
23 | {
24 | public GameBoxMetadataViewModel()
25 | { }
26 |
27 | public GameBoxMetadataViewModel(string path)
28 | : this()
29 | {
30 | this.Path = path;
31 | this.File = GameBoxFile.Parse(this.Path);
32 |
33 | this.MetadataTreeItems.Add(new FileMetadataTreeNode(this.File));
34 |
35 | if (this.File.MainClass == ClassId.CGameCtnChallenge)
36 | {
37 | this.FileType = "Map";
38 | var map = new MapMetadataProvider(this.File);
39 | this.MetadataProvider = map;
40 | this.MetadataTreeItems.Add(new MapMetadataTreeNode(map) { IsExpanded = true });
41 | }
42 | else if (this.File.MainClass == ClassId.CGameItemModel)
43 | {
44 | this.FileType = "Item/Block";
45 | var item = new ItemMetadataProvider(this.File);
46 | this.MetadataProvider = item;
47 | this.MetadataTreeItems.Add(new ItemMetadataTreeNode(item) { IsExpanded = true });
48 | }
49 | else if (this.File.MainClass == ClassId.CGameCtnMacroBlockInfo)
50 | {
51 | this.FileType = "Macroblock";
52 | var macroblock = new MacroblockMetadataProvider(this.File);
53 | this.MetadataProvider = macroblock;
54 | this.MetadataTreeItems.Add(new MacroblockMetadataTreeNode(macroblock) { IsExpanded = true });
55 | }
56 | }
57 |
58 |
59 |
60 | public string Path { get; private set; }
61 |
62 | public string FileType { get; private set; }
63 |
64 | public GameBoxFile File { get; private set; }
65 |
66 | public MetadataProvider MetadataProvider { get; private set; }
67 |
68 |
69 |
70 | public string TitleText => $"MP# GameBoxView - {(string.IsNullOrWhiteSpace(this.Path) ? "drag and drop file to open" : this.Path)}";
71 |
72 | public ObservableCollection MetadataTreeItems { get; private set; } = new ObservableCollection();
73 |
74 |
75 |
76 | public event PropertyChangedEventHandler PropertyChanged;
77 |
78 | [MethodImpl(MethodImplOptions.NoInlining)]
79 | protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
80 | {
81 | this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
82 | }
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/src/ManiaPlanetSharp.GameBoxView/MainWindow.xaml.cs:
--------------------------------------------------------------------------------
1 | using ManiaPlanetSharp.GameBox;
2 | using ManiaPlanetSharp.GameBox.MetadataProviders;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Diagnostics;
6 | using System.Linq;
7 | using System.Text;
8 | using System.Threading.Tasks;
9 | using System.Windows;
10 | using System.Windows.Controls;
11 | using System.Windows.Data;
12 | using System.Windows.Documents;
13 | using System.Windows.Input;
14 | using System.Windows.Media;
15 | using System.Windows.Media.Imaging;
16 | using System.Windows.Navigation;
17 | using System.Windows.Shapes;
18 |
19 | namespace ManiaPlanetSharp.GameBoxView
20 | {
21 | ///
22 | /// Interaction logic for MainWindow.xaml
23 | ///
24 | public partial class MainWindow : Window
25 | {
26 | public MainWindow()
27 | : this(new GameBoxMetadataViewModel())
28 | { }
29 |
30 | public MainWindow(GameBoxMetadataViewModel viewModel)
31 | {
32 | InitializeComponent();
33 | this.DataContext = viewModel;
34 | }
35 |
36 | private void Grid_Drop(object sender, DragEventArgs e)
37 | {
38 | if (e.Data.GetDataPresent(DataFormats.FileDrop))
39 | {
40 | string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
41 | if (files?.Length == 1 && files[0].ToLowerInvariant().EndsWith(".gbx"))
42 | {
43 | e.Handled = true;
44 | this.DataContext = new GameBoxMetadataViewModel(files[0]);
45 | GC.Collect();
46 | }
47 | }
48 | }
49 |
50 | private void Grid_Drag(object sender, DragEventArgs e)
51 | {
52 | e.Effects = DragDropEffects.None;
53 | if (e.Data.GetDataPresent(DataFormats.FileDrop))
54 | {
55 | string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
56 | if (files?.Length == 1 && files[0].ToLowerInvariant().EndsWith(".gbx"))
57 | {
58 | e.Effects = DragDropEffects.Copy;
59 | }
60 | }
61 | }
62 |
63 | private void Hyperlink_RequestNavigate(object sender, RequestNavigateEventArgs e)
64 | {
65 | try
66 | {
67 | Process.Start(new ProcessStartInfo(e.Uri.AbsoluteUri) { UseShellExecute = true, Verb = "open" });
68 | }
69 | catch
70 | {
71 | #if DEBUG
72 | throw;
73 | #endif
74 | }
75 | e.Handled = true;
76 | }
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/src/ManiaPlanetSharp.GameBoxView/ManiaPlanetSharp.GameBoxView.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | WinExe
5 | net8.0-windows
6 | true
7 | Stefan Baumann
8 | Stefan Baumann
9 | Application for viewing metadata from files created with the GameBox engine by Ubisoft Nadeo.
10 | Copyright © 2020 Stefan Baumann
11 | https://github.com/stefan-baumann/ManiaPlanetSharp
12 | https://github.com/stefan-baumann/ManiaPlanetSharp
13 | 1.0.0
14 | 1.0.0
15 | ManiaPlanetSharp.GameBoxView.App
16 | LICENSE
17 |
18 |
19 |
20 | DEBUG;TRACE
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 | True
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/src/ManiaPlanetSharp.GameBoxView/RelayCommand.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Diagnostics;
4 | using System.Text;
5 | using System.Windows.Input;
6 |
7 | namespace ManiaPlanetSharp.GameBoxView
8 | {
9 | ///
10 | /// A command whose sole purpose is to
11 | /// relay its functionality to other
12 | /// objects by invoking delegates. The
13 | /// default return value for the CanExecute
14 | /// method is 'true'.
15 | ///
16 | public class RelayCommand : ICommand
17 | {
18 | #region Fields
19 |
20 | readonly Action