-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathProgram.cs
More file actions
137 lines (121 loc) · 4.42 KB
/
Copy pathProgram.cs
File metadata and controls
137 lines (121 loc) · 4.42 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
using ProtoBuf;
using System.Globalization;
using System.IO.Compression;
namespace ModData;
public class Program
{
[ProtoContract]
public class CompDatabaseEntry
{
[ProtoMember(1)]
public int WikiId { get; set; }
[ProtoMember(2)]
public required string ChineseName { get; set; }
[ProtoMember(3)]
public string? CurseForgeSlug { get; set; }
[ProtoMember(4)]
public string? ModrinthSlug { get; set; }
}
public class RawEntry
{
public required string ChineseName { get; set; }
public string? CurseForgeSlug { get; set; }
public string? ModrinthSlug { get; set; }
}
public static async Task Main()
{
Console.WriteLine("Please enter a file name");
var fileName = Console.ReadLine()?.Trim().Trim('"');
ArgumentNullException.ThrowIfNullOrWhiteSpace(fileName, nameof(fileName));
fileName = Path.GetFullPath(fileName);
if (!File.Exists(fileName)) throw new FileNotFoundException();
var workFolder = Directory.GetParent(fileName);
ArgumentNullException.ThrowIfNull(workFolder, nameof(workFolder));
await using var fileStream = File.OpenRead(fileName);
using var reader = new StreamReader(fileStream);
var buffer = new List<CompDatabaseEntry>();
var wikiId = 0;
while (await reader
.ReadLineAsync()
.ConfigureAwait(false) is { } line)
{
wikiId++;
if (string.IsNullOrWhiteSpace(line)) continue;
foreach (var entry in Parser(line))
{
buffer.Add(new CompDatabaseEntry
{
WikiId = wikiId,
ChineseName = entry.ChineseName,
CurseForgeSlug = entry.CurseForgeSlug,
ModrinthSlug = entry.ModrinthSlug
});
}
}
var output = Path.Combine(workFolder.FullName, "mcmod.buf");
await using var fs = File.OpenWrite(output);
fs.SetLength(0);
fs.Seek(0, SeekOrigin.Begin);
await using var compress = new GZipStream(fs, CompressionLevel.SmallestSize);
Serializer.Serialize(compress, buffer);
}
public static List<RawEntry> Parser(string line)
{
var textInfo = CultureInfo.CurrentCulture.TextInfo;
var result = new List<RawEntry>();
if (string.IsNullOrEmpty(line)) return result;
var parts = line.Split('¨');
foreach (var part in parts)
{
var subparts = part.Split('|');
if (subparts.Length < 1) continue;
string idPart = subparts[0].Trim();
string chineseName = subparts.Length >= 2 ? subparts[1].Trim() : "";
string? curseForgeSlug;
string? modrinthSlug;
// Match VB logic exactly
if (idPart.StartsWith('@'))
{
// @modrinth
modrinthSlug = idPart.Substring(1);
curseForgeSlug = null;
}
else if (idPart.EndsWith('@'))
{
// curseforge@
var slug = idPart.TrimEnd('@');
curseForgeSlug = slug;
modrinthSlug = slug;
}
else if (idPart.Contains('@'))
{
// cf@mr
var split = idPart.Split('@', 2); // max 2 parts
curseForgeSlug = string.IsNullOrWhiteSpace(split[0]) ? null : split[0];
modrinthSlug = string.IsNullOrWhiteSpace(split[1]) ? null : split[1];
}
else
{
// only curseforge
curseForgeSlug = idPart;
modrinthSlug = null;
}
// Handle * replacement
if (chineseName.Contains('*'))
{
var baseName = chineseName.Replace("*", "").Trim();
var displayId = curseForgeSlug ?? modrinthSlug ?? "Unknown";
// Mimic VB: replace '-' with space, then title case
var displayName = textInfo.ToTitleCase(displayId.Replace('-', ' '));
chineseName = $"{baseName} ({displayName})";
}
result.Add(new RawEntry
{
ChineseName = chineseName,
CurseForgeSlug = curseForgeSlug,
ModrinthSlug = modrinthSlug
});
}
return result;
}
}