1616using System . Collections . ObjectModel ;
1717using Newtonsoft . Json ;
1818using BeatMapEvaluator . Themes ;
19+ using System . Security . Policy ;
20+ using System . Runtime . Serialization ;
21+ using System . Net . WebSockets ;
1922
2023namespace BeatMapEvaluator
2124{
@@ -27,29 +30,77 @@ public partial class MainWindow : Window
2730 private readonly char _ps = Path . DirectorySeparatorChar ;
2831 private string appTemp ;
2932
33+ private string appLogsFolder ;
34+ private string logFile ;
35+ private string logPath ;
36+
37+ private int Work_Numerator ; //Folder progress numerator
38+ private int Work_Denominator ; //Folder progress denominator
39+
3040 public MainWindow ( ) {
3141 InitializeComponent ( ) ;
3242 MapQueue = new ObservableCollection < MapQueueModel > ( ) ;
3343 evalStorage = new Dictionary < string , ( json_MapInfo , MapStorageLayout [ ] ) > ( ) ;
3444 QueueList . ItemsSource = MapQueue ;
35- UpdateDiffButtons ( MapDiffs . NONE ) ;
45+ UpdateDiffButtons ( MapDiffs . NONE , null ) ;
3646
37- appTemp = Path . Combine ( Directory . GetCurrentDirectory ( ) , "temp" ) + _ps ;
47+ string cd = Directory . GetCurrentDirectory ( ) ;
48+ appTemp = Path . Combine ( cd , "temp" ) + _ps ;
49+ appLogsFolder = Path . Combine ( cd , "logs" ) + _ps ;
3850 UserConsole . onConsoleUpdate = new UserConsole . updateStringGUI ( updateUserLog ) ;
51+ UserConsole . onLogUpdate = new UserConsole . updateStringGUI ( WriteToLogFile ) ;
3952
53+ if ( ! Directory . Exists ( appLogsFolder ) )
54+ Directory . CreateDirectory ( appLogsFolder ) ;
55+ logFile = "log_" + DateTime . Now . ToString ( "hh_mm_ss" ) + ".txt" ;
56+ logPath = Path . Combine ( appLogsFolder , logFile ) ;
57+
4058 if ( Directory . Exists ( appTemp ) )
4159 FileInterface . DeleteDir_Full ( appTemp ) ;
4260
4361 UserConsole . Log ( $ "tempDir: \" { appTemp } \" ") ;
62+ UserConsole . Log ( $ "logFile: \" { logFile } \" ") ;
4463 Directory . CreateDirectory ( appTemp ) ;
4564 }
4665
66+ private async Task evaluateMap ( string mapFolder , string bsr ) {
67+ json_MapInfo info = await FileInterface . ParseInfoFile ( mapFolder , bsr ) ;
68+
69+ int color = - 1 ;
70+ if ( ! evalStorage . ContainsKey ( info . mapBSR ) && info . mapDifficulties != MapDiffs . NONE ) {
71+ json_beatMapDifficulty [ ] diffRegistry = info . standardBeatmap . _diffMaps ;
72+ evalStorage . Add ( info . mapBSR , ( info , new MapStorageLayout [ 5 ] ) ) ;
73+
74+ for ( int i = 0 ; i < diffRegistry . Length ; i ++ ) {
75+ MapStorageLayout layout = await FileInterface . InterpretMapFile ( info , i ) ;
76+ if ( layout == null || layout . audioLength == - 1.0f )
77+ break ;
78+ try {
79+ await layout . ProcessDiffRegistery ( ) ;
80+ } catch ( Exception err ) {
81+ UserConsole . LogError ( $ "[{ bsr } ] Error: { err . Message } ") ;
82+ }
83+ int index = layout . mapDiff . _difficultyRank / 2 ;
84+ evalStorage [ info . mapBSR ] . Item2 [ index ] = layout ;
85+ if ( color == - 1 ) {
86+ if ( layout . reportColorIndex == 2 ) color = 2 ;
87+ if ( layout . reportColorIndex == 0 ) color = 0 ;
88+ }
89+ }
90+ }
91+ if ( color == - 1 ) color = 1 ;
92+ UserConsole . Log ( $ "[{ bsr } ]: Map loaded.") ;
93+ MapQueue . Add ( FileInterface . CreateMapListItem ( info , color ) ) ;
94+ Work_Numerator ++ ;
95+ folderPerc . Content = Work_Numerator . ToString ( ) + " / " + Work_Denominator . ToString ( ) ;
96+ }
97+
4798 //At the moment the user can press the button as many
4899 //times as they want... das bad
49100 private async void evaluateCode_OnClick ( object sender , RoutedEventArgs e ) {
50101 string bsr = bsrBox . Text ;
51102 if ( bsr == null || bsr . Equals ( "" ) ) {
52- UserConsole . Log ( "BSR code null." ) ;
103+ UserConsole . LogError ( "BSR code null." ) ;
53104 return ;
54105 }
55106 if ( Directory . Exists ( Path . Combine ( appTemp , bsr ) ) ) {
@@ -59,61 +110,124 @@ private async void evaluateCode_OnClick(object sender, RoutedEventArgs e) {
59110
60111 try {
61112 await FileInterface . DownloadBSR ( bsr , appTemp ) ;
62- string mapFolder = Path . Combine ( appTemp , bsr + '\\ ' ) ;
63-
64- json_MapInfo info = await FileInterface . ParseInfoFile ( mapFolder ) ;
65- info . mapBSR = bsr ;
66-
67- if ( ! evalStorage . ContainsKey ( info . mapBSR ) ) {
68- json_beatMapDifficulty [ ] diffRegistry = info . standardBeatmap . _diffMaps ;
69- evalStorage . Add ( info . mapBSR , ( info , new MapStorageLayout [ 5 ] ) ) ;
70- for ( int i = 0 ; i < diffRegistry . Length ; i ++ ) {
71- MapStorageLayout layout = await FileInterface . InterpretMapFile ( info , i ) ;
72- await layout . ProcessDiffRegistery ( ) ;
73- int index = layout . mapDiff . _difficultyRank / 2 ;
74- evalStorage [ info . mapBSR ] . Item2 [ index ] = layout ;
113+ } catch {
114+ UserConsole . LogError ( $ "Failed to download { bsr } ") ;
115+ return ;
116+ }
117+ string mapFolder = Path . Combine ( appTemp , bsr + _ps ) ;
118+ await evaluateMap ( mapFolder , bsr ) ;
119+ }
120+ private async void evaluateFolder_OnClick ( object sender , RoutedEventArgs e ) {
121+ //Request folder location
122+ var dialog = new System . Windows . Forms . FolderBrowserDialog {
123+ Description = "Select folder containing maps" ,
124+ UseDescriptionForTitle = true ,
125+ SelectedPath = Environment . GetFolderPath ( Environment . SpecialFolder . Desktop ) + _ps ,
126+ ShowNewFolderButton = true
127+ } ;
128+ if ( dialog . ShowDialog ( ) == System . Windows . Forms . DialogResult . OK ) {
129+ string folderPath = dialog . SelectedPath + _ps ;
130+ string [ ] maps = Directory . GetDirectories ( folderPath ) ;
131+ Work_Numerator = 0 ;
132+ Work_Denominator = maps . Length ;
133+ evalStorage . EnsureCapacity ( evalStorage . Count + Work_Denominator ) ;
134+
135+ //Evaluate all folders inside selected folder
136+ foreach ( var dir in maps ) {
137+ string mapFolder = dir + _ps ;
138+ int cut = dir . LastIndexOf ( _ps ) + 1 ;
139+ string name = dir . Substring ( cut , dir . Length - cut ) ;
140+ int end = name . IndexOf ( ' ' ) ;
141+ if ( end == - 1 ) {
142+ name = name . Substring ( 0 , Math . Min ( name . Length , 8 ) ) ;
143+ } else {
144+ name = name . Substring ( 0 , end ) ;
75145 }
146+ name += ( end == - 1 ) ? ".." : "" ;
147+ await evaluateMap ( mapFolder , name ) ;
76148 }
77149
78- //MapStorageLayout layout = await FileInterface.InterpretMapFile(info, 0);
79- //DiffCriteriaReport report = await layout.ProcessDiffRegistery();
80-
81- //spsChartGraph.spsData.Clear();
82- //spsChartGraph.spsData.AddRange(report.swingsPerSecond);
83-
84- UserConsole . Log ( "Map loaded." ) ;
85-
86- MapQueue . Add ( FileInterface . CreateMapListItem ( info ) ) ;
87- } catch ( Exception err ) {
88- UserConsole . Log ( $ "Error: { err . Message } ") ;
89- return ;
150+ Work_Numerator = 0 ;
151+ Work_Denominator = 0 ;
152+ folderPerc . Content = "" ;
90153 }
91154 }
92- private async void diffButton_OnClick ( object sender , RoutedEventArgs e ) {
155+
156+ private void diffButton_OnClick ( object sender , RoutedEventArgs e ) {
93157 Button button = sender as Button ;
94158 int diffValue = int . Parse ( button . Tag as string ) ;
95159 MapDiffs diff = ( MapDiffs ) ( 1 << ( diffValue / 2 ) ) ;
96- UserConsole . Log ( $ "Selected diff: { diff } ") ;
160+ // UserConsole.Log($"Selected diff: {diff}");
97161
98162 string bsr = MapQueue [ QueueList . SelectedIndex ] . mapID ;
99163 UpdateMainPage ( bsr , diffValue ) ;
100164 }
101165
102- private void UpdateDiffButtons ( MapDiffs avl ) {
166+ private void UpdateDiffButtons ( MapDiffs avl , MapStorageLayout [ ] ? layout ) {
103167 //Dont @ me
104168 diffButton_Easy . Visibility = ShowIfFound ( avl . HasFlag ( MapDiffs . Easy ) ) ;
105169 diffButton_Normal . Visibility = ShowIfFound ( avl . HasFlag ( MapDiffs . Normal ) ) ;
106170 diffButton_Hard . Visibility = ShowIfFound ( avl . HasFlag ( MapDiffs . Hard ) ) ;
107171 diffButton_Expert . Visibility = ShowIfFound ( avl . HasFlag ( MapDiffs . Expert ) ) ;
108172 diffButton_ExpertPlus . Visibility = ShowIfFound ( avl . HasFlag ( MapDiffs . ExpertPlus ) ) ;
173+
174+ if ( layout != null ) {
175+ var converter = new BrushConverter ( ) ;
176+ Brush [ ] colors = new Brush [ 5 ] ;
177+ for ( int i = 0 ; i < 5 ; i ++ ) {
178+ if ( layout [ i ] == null ) continue ;
179+ string hex = DiffCriteriaReport . diffColors [ layout [ i ] . reportColorIndex ] ;
180+ colors [ i ] = ( Brush ) converter . ConvertFromString ( hex ) ;
181+ }
182+ //Dont even think about it..
183+ if ( diffButton_Easy . IsVisible )
184+ diffButton_Easy . BorderBrush = colors [ 0 ] ;
185+
186+ if ( diffButton_Normal . IsVisible )
187+ diffButton_Normal . BorderBrush = colors [ 1 ] ;
188+
189+ if ( diffButton_Hard . IsVisible )
190+ diffButton_Hard . BorderBrush = colors [ 2 ] ;
191+
192+ if ( diffButton_Expert . IsVisible )
193+ diffButton_Expert . BorderBrush = colors [ 3 ] ;
194+
195+ if ( diffButton_ExpertPlus . IsVisible )
196+ diffButton_ExpertPlus . BorderBrush = colors [ 4 ] ;
197+ }
109198 }
199+ //Just fillin out some UI stuff
110200 private void UpdateMainPage ( string bsr , int dValue ) {
111201 json_MapInfo mapInfo = evalStorage [ bsr ] . Item1 ;
112202 MapStorageLayout [ ] layouts = evalStorage [ bsr ] . Item2 ;
113203
114204 int sel = dValue / 2 ;
205+ DiffCriteriaReport report = layouts [ sel ] . report ;
206+
115207 string _nps = layouts [ sel ] . nps . ToString ( "0.00" ) ;
116208 string _jd = layouts [ sel ] . jumpDistance . ToString ( "0.00" ) ;
209+ string _rt = layouts [ sel ] . reactionTime . ToString ( "000.0" ) ;
210+ string _off = layouts [ sel ] . noteOffset . ToString ( "0.00" ) ;
211+ string _njs = layouts [ sel ] . njs . ToString ( "00.00" ) ;
212+
213+ string _modsReq = "Mods: " ;
214+ for ( int i = 0 ; i < report . modsRequired . Count ; i ++ ) {
215+ _modsReq += report . modsRequired [ i ] ;
216+ if ( i != report . modsRequired . Count - 1 )
217+ _modsReq += ", " ;
218+ }
219+ if ( report . modsRequired . Count == 0 )
220+ _modsReq += "None :)" ;
221+
222+ int [ ] errorTable = report . errors ;
223+
224+ int _hotStartCount = errorTable [ 0 ] ;
225+ int _coldEndCount = errorTable [ 1 ] ;
226+ int _interCount = errorTable [ 2 ] ;
227+ int _wallWidth = errorTable [ 3 ] ;
228+ int _failSwings = errorTable [ 4 ] ;
229+ int _oorNote = errorTable [ 5 ] ;
230+ int _oorWall = errorTable [ 6 ] ;
117231
118232 spsChartGraph . spsData . Clear ( ) ;
119233 spsChartGraph . spsData . AddRange ( layouts [ sel ] . report . swingsPerSecond ) ;
@@ -123,12 +237,35 @@ private void UpdateMainPage(string bsr, int dValue) {
123237 evc_SongName . Content = mapInfo . _songName ;
124238 evc_SongDiff . Content = ( MapDiffs ) ( 1 << ( dValue / 2 ) ) ;
125239 evc_NPS . Text = $ "Notes/Second: { _nps } ";
240+ evc_NJS . Text = $ "NJS: { _njs } ";
126241 evc_JD . Text = $ "JD: { _jd } ";
242+ evc_RT . Text = $ "Reaction Time: { _rt } ms";
243+ evc_OF . Text = $ "Offset: { _off } ";
244+ evc_BPM . Text = $ "BPM: { mapInfo . _bpm } ";
245+
246+ evc_Mods . Text = _modsReq ;
247+ evc_HotStart . Text = $ "Hot Starts: { _hotStartCount } ";
248+ evc_ColdEnd . Text = $ "Cold Ends: { _coldEndCount } ";
249+ evc_Intersections . Text = $ "Intersections: { _interCount } ";
250+ evc_WallWidth . Text = $ "Wall Widths: { _wallWidth } ";
251+ evc_FailSwings . Text = $ "Fail Swings: { _failSwings } ";
252+ evc_OOR . Text = $ "Out-Of-Range: Notes:{ _oorNote } , Walls:{ _oorWall } ";
253+
254+ evc_Mods . Foreground = EvalColor ( report . modsRequired . Count == 0 ) ;
255+ evc_HotStart . Foreground = EvalColor ( _hotStartCount == 0 ) ;
256+ evc_ColdEnd . Foreground = EvalColor ( _coldEndCount == 0 ) ;
257+ evc_Intersections . Foreground = EvalColor ( _interCount == 0 ) ;
258+ evc_WallWidth . Foreground = EvalColor ( _wallWidth == 0 ) ;
259+ evc_FailSwings . Foreground = EvalColor ( _failSwings == 0 ) ;
260+ evc_OOR . Foreground = EvalColor ( ( _oorNote + _oorWall ) == 0 ) ;
127261
128262 }
129263
264+ private SolidColorBrush EvalColor ( bool exp ) => exp ? Brushes . Green : Brushes . Red ;
130265 private Visibility ShowIfFound ( bool Shown ) => Shown ? Visibility . Visible : Visibility . Collapsed ;
131266 private void updateUserLog ( string ctx ) => ConsoleText . Text = ctx ;
267+ private void WriteToLogFile ( string ctx ) => File . AppendAllText ( logPath , ctx + '\n ' ) ;
268+
132269 private void onAppQuit ( object sender , System . ComponentModel . CancelEventArgs e ) {
133270 MapQueue . Clear ( ) ;
134271 UserConsole . Log ( "Clearing temporary directory.." ) ;
@@ -140,7 +277,11 @@ private void QueueList_SelectionChanged(object sender, SelectionChangedEventArgs
140277 //Selection is changed when the app quits
141278 if ( ! model . HasItems )
142279 return ;
143- UpdateDiffButtons ( MapQueue [ model . SelectedIndex ] . diffsAvailable ) ;
280+ MapQueueModel mdl = MapQueue [ model . SelectedIndex ] ;
281+ UpdateDiffButtons ( mdl . diffsAvailable , evalStorage [ mdl . mapID ] . Item2 ) ;
282+ //Set the profile and song name on selection
283+ evc_Profile . Source = MapQueue [ QueueList . SelectedIndex ] . MapProfile ;
284+ evc_SongName . Content = mdl . MapSongName ;
144285 }
145286 }
146287}
0 commit comments