a web-based Rock Band 4 stats viewer and achievement tracker website
1using System.Security.Cryptography.X509Certificates;
2
3namespace davesave_web
4{
5 public class SongBinaryFormat
6 {
7#pragma warning disable CS8618
8 public int SongID;
9 public string Shortname;
10 public string Artist;
11 public string Title;
12 public string[] Sources;
13#pragma warning restore CS8618
14
15 public static SongBinaryFormat ReadFromStream(Stream stream)
16 {
17 SongBinaryFormat sbf = new();
18
19 sbf.SongID = stream.ReadInt32LE();
20 sbf.Shortname = stream.ReadLengthUTF8();
21 sbf.Artist = stream.ReadLengthUTF8();
22 sbf.Title = stream.ReadLengthUTF8();
23 int sourcesLen = stream.ReadInt32LE();
24 sbf.Sources = new string[sourcesLen];
25 for (int i = 0; i < sourcesLen; i++)
26 sbf.Sources[i] = stream.ReadLengthUTF8();
27
28 return sbf;
29 }
30
31 public void WriteToStream(Stream stream)
32 {
33 stream.WriteInt32LE(SongID);
34 stream.WriteLengthUTF8(Shortname);
35 stream.WriteLengthUTF8(Artist);
36 stream.WriteLengthUTF8(Title);
37 stream.WriteInt32LE(Sources.Length);
38 for (int i = 0; i < Sources.Length; i++)
39 stream.WriteLengthUTF8(Sources[i]);
40 }
41 }
42
43 public class SongCache
44 {
45 static public Dictionary<int, SongBinaryFormat>? database;
46 static public Dictionary<string, int>? shortnameLookup;
47 static public bool hasLoaded = false;
48
49 private readonly BrowserLocalStorage localStorage;
50 private readonly HttpClient http;
51
52 public SongCache(BrowserLocalStorage localStorage, HttpClient http)
53 {
54 this.localStorage = localStorage;
55 this.http = http;
56 }
57
58 public bool HasDatabase()
59 {
60 return hasLoaded;
61 }
62
63 public async Task ReadDatabase()
64 {
65 // don't bother reading if we already have a database
66 if (database != null)
67 return;
68 // fetch the response
69 HttpResponseMessage resp = await http.GetAsync("songCache.bin");
70 if (resp.IsSuccessStatusCode)
71 {
72 Stream str = resp.Content.ReadAsStream();
73 int version = str.ReadInt32LE();
74 if (version != 1)
75 {
76 Console.WriteLine("Invalid version, not loading a database...");
77 return;
78 }
79 int songCount = str.ReadInt32LE();
80 database = new Dictionary<int, SongBinaryFormat>();
81 shortnameLookup = new Dictionary<string, int>();
82 for (int i = 0; i < songCount; i++)
83 {
84 SongBinaryFormat sbf = SongBinaryFormat.ReadFromStream(str);
85 shortnameLookup.Add(sbf.Shortname, sbf.SongID);
86 database.Add(sbf.SongID, sbf);
87 }
88 Console.WriteLine("Loaded {0} songs", database.Count);
89 hasLoaded = true;
90 }
91 }
92
93 public SongBinaryFormat? GetSongInfo(int songID)
94 {
95 if (database == null)
96 return null;
97 if (!database.ContainsKey(songID))
98 return null;
99 return database[songID];
100 }
101
102 public SongBinaryFormat? GetSongInfo(string shortname)
103 {
104 if (database == null || shortnameLookup == null)
105 return null;
106 if (!shortnameLookup.ContainsKey(shortname))
107 return null;
108 int songID = shortnameLookup[shortname];
109 return database[songID];
110 }
111
112 public int[]? GetDiscSongs()
113 {
114 if (database == null)
115 return null;
116 var results = database.Values.Where((s) => { return s.Sources.Length == 1 && s.Sources[0] == "rb4"; });
117 List<int> list = new();
118 foreach(SongBinaryFormat sng in results)
119 {
120 list.Add(sng.SongID);
121 }
122 return list.ToArray();
123 }
124 }
125}