a web-based Rock Band 4 stats viewer and achievement tracker website
at master 125 lines 4.2 kB view raw
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}