mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-12 18:27:24 +01:00
Use compiled regex.
This commit is contained in:
parent
b0370139ec
commit
fe0e01b8fe
1 changed files with 49 additions and 69 deletions
|
|
@ -1,7 +1,5 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using Dalamud.Logging;
|
||||
|
|
@ -80,62 +78,6 @@ internal class GamePathParser : IGamePathParser
|
|||
private const string WorldFolder1 = "bgcommon";
|
||||
private const string WorldFolder2 = "bg";
|
||||
|
||||
// @formatter:off
|
||||
// language=regex
|
||||
private readonly IReadOnlyDictionary<FileType, IReadOnlyDictionary<ObjectType, IReadOnlyList<Regex>>> _regexes = new Dictionary<FileType, IReadOnlyDictionary<ObjectType, IReadOnlyList<Regex>>>()
|
||||
{
|
||||
[FileType.Font] = new Dictionary<ObjectType, IReadOnlyList<Regex>>
|
||||
{
|
||||
[ObjectType.Font] = CreateRegexes(@"common/font/(?'fontname'.*)_(?'id'\d\d)(_lobby)?\.fdt"),
|
||||
},
|
||||
[FileType.Texture] = new Dictionary<ObjectType, IReadOnlyList<Regex>>
|
||||
{
|
||||
[ObjectType.Icon] = CreateRegexes(@"ui/icon/(?'group'\d*)(/(?'lang'[a-z]{2}))?(/(?'hq'hq))?/(?'id'\d*)(?'hr'_hr1)?\.tex"),
|
||||
[ObjectType.Map] = CreateRegexes(@"ui/map/(?'id'[a-z0-9]{4})/(?'variant'\d{2})/\k'id'\k'variant'(?'suffix'[a-z])?(_[a-z])?\.tex"),
|
||||
[ObjectType.Weapon] = CreateRegexes(@"chara/weapon/w(?'id'\d{4})/obj/body/b(?'weapon'\d{4})/texture/v(?'variant'\d{2})_w\k'id'b\k'weapon'(_[a-z])?_[a-z]\.tex"),
|
||||
[ObjectType.Monster] = CreateRegexes(@"chara/monster/m(?'monster'\d{4})/obj/body/b(?'id'\d{4})/texture/v(?'variant'\d{2})_m\k'monster'b\k'id'(_[a-z])?_[a-z]\.tex"),
|
||||
[ObjectType.Equipment] = CreateRegexes(@"chara/equipment/e(?'id'\d{4})/texture/v(?'variant'\d{2})_c(?'race'\d{4})e\k'id'_(?'slot'[a-z]{3})(_[a-z])?_[a-z]\.tex"),
|
||||
[ObjectType.DemiHuman] = CreateRegexes(@"chara/demihuman/d(?'id'\d{4})/obj/equipment/e(?'equip'\d{4})/texture/v(?'variant'\d{2})_d\k'id'e\k'equip'_(?'slot'[a-z]{3})(_[a-z])?_[a-z]\.tex"),
|
||||
[ObjectType.Accessory] = CreateRegexes(@"chara/accessory/a(?'id'\d{4})/texture/v(?'variant'\d{2})_c(?'race'\d{4})a\k'id'_(?'slot'[a-z]{3})_[a-z]\.tex"),
|
||||
[ObjectType.Character] = CreateRegexes( @"chara/human/c(?'race'\d{4})/obj/(?'type'[a-z]+)/(?'typeabr'[a-z])(?'id'\d{4})/texture/(?'minus'(--)?)(v(?'variant'\d{2})_)?c\k'race'\k'typeabr'\k'id'(_(?'slot'[a-z]{3}))?(_[a-z])?_[a-z]\.tex"
|
||||
, @"chara/human/c(?'race'\d{4})/obj/(?'type'[a-z]+)/(?'typeabr'[a-z])(?'id'\d{4})/texture"
|
||||
, @"chara/common/texture/skin(?'skin'.*)\.tex"
|
||||
, @"chara/common/texture/(?'catchlight'catchlight)(.*)\.tex"
|
||||
, @"chara/common/texture/decal_(?'location'[a-z]+)/[-_]?decal_(?'id'\d+).tex"),
|
||||
},
|
||||
[FileType.Model] = new Dictionary<ObjectType, IReadOnlyList<Regex>>
|
||||
{
|
||||
[ObjectType.Weapon] = CreateRegexes(@"chara/weapon/w(?'id'\d{4})/obj/body/b(?'weapon'\d{4})/model/w\k'id'b\k'weapon'\.mdl"),
|
||||
[ObjectType.Monster] = CreateRegexes(@"chara/monster/m(?'monster'\d{4})/obj/body/b(?'id'\d{4})/model/m\k'monster'b\k'id'\.mdl"),
|
||||
[ObjectType.Equipment] = CreateRegexes(@"chara/equipment/e(?'id'\d{4})/model/c(?'race'\d{4})e\k'id'_(?'slot'[a-z]{3})\.mdl"),
|
||||
[ObjectType.DemiHuman] = CreateRegexes(@"chara/demihuman/d(?'id'\d{4})/obj/equipment/e(?'equip'\d{4})/model/d\k'id'e\k'equip'_(?'slot'[a-z]{3})\.mdl"),
|
||||
[ObjectType.Accessory] = CreateRegexes(@"chara/accessory/a(?'id'\d{4})/model/c(?'race'\d{4})a\k'id'_(?'slot'[a-z]{3})\.mdl"),
|
||||
[ObjectType.Character] = CreateRegexes(@"chara/human/c(?'race'\d{4})/obj/(?'type'[a-z]+)/(?'typeabr'[a-z])(?'id'\d{4})/model/c\k'race'\k'typeabr'\k'id'_(?'slot'[a-z]{3})\.mdl"),
|
||||
},
|
||||
[FileType.Material] = new Dictionary<ObjectType, IReadOnlyList<Regex>>
|
||||
{
|
||||
[ObjectType.Weapon] = CreateRegexes(@"chara/weapon/w(?'id'\d{4})/obj/body/b(?'weapon'\d{4})/material/v(?'variant'\d{4})/mt_w\k'id'b\k'weapon'_[a-z]+\.mtrl"),
|
||||
[ObjectType.Monster] = CreateRegexes(@"chara/monster/m(?'monster'\d{4})/obj/body/b(?'id'\d{4})/material/v(?'variant'\d{4})/mt_m\k'monster'b\k'id'_[a-z]+\.mtrl"),
|
||||
[ObjectType.Equipment] = CreateRegexes(@"chara/equipment/e(?'id'\d{4})/material/v(?'variant'\d{4})/mt_c(?'race'\d{4})e\k'id'_(?'slot'[a-z]{3})_[a-z]+\.mtrl"),
|
||||
[ObjectType.DemiHuman] = CreateRegexes(@"chara/demihuman/d(?'id'\d{4})/obj/equipment/e(?'equip'\d{4})/material/v(?'variant'\d{4})/mt_d\k'id'e\k'equip'_(?'slot'[a-z]{3})_[a-z]+\.mtrl"),
|
||||
[ObjectType.Accessory] = CreateRegexes(@"chara/accessory/a(?'id'\d{4})/material/v(?'variant'\d{4})/mt_c(?'race'\d{4})a\k'id'_(?'slot'[a-z]{3})_[a-z]+\.mtrl"),
|
||||
[ObjectType.Character] = CreateRegexes(@"chara/human/c(?'race'\d{4})/obj/(?'type'[a-z]+)/(?'typeabr'[a-z])(?'id'\d{4})/material(/v(?'variant'\d{4}))?/mt_c\k'race'\k'typeabr'\k'id'(_(?'slot'[a-z]{3}))?_[a-z]+\.mtrl"),
|
||||
},
|
||||
[FileType.Imc] = new Dictionary<ObjectType, IReadOnlyList<Regex>>
|
||||
{
|
||||
[ObjectType.Weapon] = CreateRegexes(@"chara/weapon/w(?'id'\d{4})/obj/body/b(?'weapon'\d{4})/b\k'weapon'\.imc"),
|
||||
[ObjectType.Monster] = CreateRegexes(@"chara/monster/m(?'monster'\d{4})/obj/body/b(?'id'\d{4})/b\k'id'\.imc"),
|
||||
[ObjectType.Equipment] = CreateRegexes(@"chara/equipment/e(?'id'\d{4})/e\k'id'\.imc"),
|
||||
[ObjectType.DemiHuman] = CreateRegexes(@"chara/demihuman/d(?'id'\d{4})/obj/equipment/e(?'equip'\d{4})/e\k'equip'\.imc"),
|
||||
[ObjectType.Accessory] = CreateRegexes(@"chara/accessory/a(?'id'\d{4})/a\k'id'\.imc"),
|
||||
},
|
||||
};
|
||||
|
||||
private static IReadOnlyList<Regex> CreateRegexes(params string[] regexes)
|
||||
=> regexes.Select(s => new Regex(s, RegexOptions.Compiled)).ToArray();
|
||||
// @formatter:on
|
||||
|
||||
|
||||
public ObjectType PathToObjectType(string path)
|
||||
{
|
||||
if (path.Length == 0)
|
||||
|
|
@ -190,20 +132,58 @@ internal class GamePathParser : IGamePathParser
|
|||
|
||||
var objectType = PathToObjectType(path);
|
||||
|
||||
if (!_regexes.TryGetValue(fileType, out var objectDict))
|
||||
return (fileType, objectType, null);
|
||||
|
||||
if (!objectDict.TryGetValue(objectType, out var regexes))
|
||||
return (fileType, objectType, null);
|
||||
|
||||
foreach (var regex in regexes)
|
||||
static Match TestCharacterTextures(string path)
|
||||
{
|
||||
var match = regex.Match(path);
|
||||
if (match.Success)
|
||||
return (fileType, objectType, match);
|
||||
var regexes = new Regex[]
|
||||
{
|
||||
GamePathManager.Character.Tex.Regex(),
|
||||
GamePathManager.Character.Tex.FolderRegex(),
|
||||
GamePathManager.Character.Tex.SkinRegex(),
|
||||
GamePathManager.Character.Tex.CatchlightRegex(),
|
||||
GamePathManager.Character.Tex.DecalRegex(),
|
||||
};
|
||||
foreach (var regex in regexes)
|
||||
{
|
||||
var match = regex.Match(path);
|
||||
if (match.Success)
|
||||
return match;
|
||||
}
|
||||
|
||||
return Match.Empty;
|
||||
}
|
||||
|
||||
return (fileType, objectType, null);
|
||||
var match = (fileType, objectType) switch
|
||||
{
|
||||
(FileType.Font, ObjectType.Font) => GamePathManager.Font.Regex().Match(path),
|
||||
(FileType.Imc, ObjectType.Weapon) => GamePathManager.Weapon.Imc.Regex().Match(path),
|
||||
(FileType.Imc, ObjectType.Monster) => GamePathManager.Monster.Imc.Regex().Match(path),
|
||||
(FileType.Imc, ObjectType.DemiHuman) => GamePathManager.DemiHuman.Imc.Regex().Match(path),
|
||||
(FileType.Imc, ObjectType.Equipment) => GamePathManager.Equipment.Imc.Regex().Match(path),
|
||||
(FileType.Imc, ObjectType.Accessory) => GamePathManager.Accessory.Imc.Regex().Match(path),
|
||||
(FileType.Model, ObjectType.Weapon) => GamePathManager.Weapon.Mdl.Regex().Match(path),
|
||||
(FileType.Model, ObjectType.Monster) => GamePathManager.Monster.Mdl.Regex().Match(path),
|
||||
(FileType.Model, ObjectType.DemiHuman) => GamePathManager.DemiHuman.Mdl.Regex().Match(path),
|
||||
(FileType.Model, ObjectType.Equipment) => GamePathManager.Equipment.Mdl.Regex().Match(path),
|
||||
(FileType.Model, ObjectType.Accessory) => GamePathManager.Accessory.Mdl.Regex().Match(path),
|
||||
(FileType.Model, ObjectType.Character) => GamePathManager.Character.Mdl.Regex().Match(path),
|
||||
(FileType.Material, ObjectType.Weapon) => GamePathManager.Weapon.Mtrl.Regex().Match(path),
|
||||
(FileType.Material, ObjectType.Monster) => GamePathManager.Monster.Mtrl.Regex().Match(path),
|
||||
(FileType.Material, ObjectType.DemiHuman) => GamePathManager.DemiHuman.Mtrl.Regex().Match(path),
|
||||
(FileType.Material, ObjectType.Equipment) => GamePathManager.Equipment.Mtrl.Regex().Match(path),
|
||||
(FileType.Material, ObjectType.Accessory) => GamePathManager.Accessory.Mtrl.Regex().Match(path),
|
||||
(FileType.Material, ObjectType.Character) => GamePathManager.Character.Mtrl.Regex().Match(path),
|
||||
(FileType.Texture, ObjectType.Weapon) => GamePathManager.Weapon.Tex.Regex().Match(path),
|
||||
(FileType.Texture, ObjectType.Monster) => GamePathManager.Monster.Tex.Regex().Match(path),
|
||||
(FileType.Texture, ObjectType.DemiHuman) => GamePathManager.DemiHuman.Tex.Regex().Match(path),
|
||||
(FileType.Texture, ObjectType.Equipment) => GamePathManager.Equipment.Tex.Regex().Match(path),
|
||||
(FileType.Texture, ObjectType.Accessory) => GamePathManager.Accessory.Tex.Regex().Match(path),
|
||||
(FileType.Texture, ObjectType.Character) => TestCharacterTextures(path),
|
||||
(FileType.Texture, ObjectType.Icon) => GamePathManager.Icon.Regex().Match(path),
|
||||
(FileType.Texture, ObjectType.Map) => GamePathManager.Map.Regex().Match(path),
|
||||
_ => Match.Empty,
|
||||
};
|
||||
|
||||
return (fileType, objectType, match.Success ? match : null);
|
||||
}
|
||||
|
||||
private static GameObjectInfo HandleEquipment(FileType fileType, GroupCollection groups)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue