Skip to content

Commit a6fa3bf

Browse files
Huge update, most of the boiler plate has come together, not fully tested but everything seems to work 98% of the time
1 parent 4956f9a commit a6fa3bf

File tree

12 files changed

+556
-153
lines changed

12 files changed

+556
-153
lines changed

BeatMapEvaluator/BeatMapEvaluator.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
<OutputType>WinExe</OutputType>
55
<TargetFramework>net6.0-windows</TargetFramework>
66
<Nullable>enable</Nullable>
7+
<UseWindowsForms>true</UseWindowsForms>
78
<UseWPF>true</UseWPF>
89
<BaseOutputPath>..\Builds\BeatMapEvaluator\</BaseOutputPath>
910
</PropertyGroup>

BeatMapEvaluator/MainWindow.xaml

Lines changed: 59 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -85,13 +85,23 @@
8585
<StackPanel Orientation="Vertical"
8686
Grid.Row="1"
8787
Margin="4">
88-
<TextBlock x:Name="evc_NPS" Text="Notes/Second:" Foreground="White"/>
89-
<TextBlock x:Name="evc_JD" Text="JD:" Foreground="White"/>
88+
<TextBlock x:Name="evc_NPS" Text="Notes/Second:" Foreground="White" Padding="2"/>
89+
<TextBlock x:Name="evc_JD" Text="JD:" Foreground="White" Padding="2"/>
90+
<TextBlock x:Name="evc_NJS" Text="NJS:" Foreground="White" Padding="2"/>
91+
<TextBlock x:Name="evc_RT" Text="Reaction time:" Foreground="White" Padding="2"/>
92+
<TextBlock x:Name="evc_OF" Text="Offset:" Foreground="White" Padding="2"/>
93+
<TextBlock x:Name="evc_BPM" Text="BPM:" Foreground="White" Padding="2"/>
94+
<TextBlock x:Name="evc_Mods" Text="Mods:" Foreground="White" Padding="2"/>
95+
<TextBlock x:Name="evc_HotStart" Text="Hot Starts:" Foreground="White" Padding="2"/>
96+
<TextBlock x:Name="evc_ColdEnd" Text="Cold Ends:" Foreground="White" Padding="2"/>
97+
<TextBlock x:Name="evc_Intersections" Text="Intersections:" Foreground="White" Padding="2"/>
98+
<TextBlock x:Name="evc_WallWidth" Text="Wall Widths:" Foreground="White" Padding="2"/>
99+
<TextBlock x:Name="evc_FailSwings" Text="Fail Swings:" Foreground="White" Padding="2"/>
100+
<TextBlock x:Name="evc_OOR" Text="Out-Of-Range:" Foreground="White" Padding="2"/>
90101
</StackPanel>
91-
92-
<custom:SwingPerSecondGraph x:Name="spsChartGraph" Grid.Row="2" Grid.Column="2"></custom:SwingPerSecondGraph>
102+
<custom:SwingPerSecondGraph x:Name="spsChartGraph" Grid.Row="2" Grid.Column="2"/>
93103
</Grid>
94-
104+
95105
</Border>
96106

97107
<!-- Console Log -->
@@ -117,19 +127,54 @@
117127
<!-- Button Panel -->
118128
<StackPanel Background="#303030"
119129
Margin="6,6,0,0">
130+
<Grid>
131+
<Grid.ColumnDefinitions>
132+
<ColumnDefinition Width="11*"/>
133+
<ColumnDefinition Width="3*"/>
134+
</Grid.ColumnDefinitions>
135+
<Grid.RowDefinitions>
136+
<RowDefinition Height="0.33*"/>
137+
<RowDefinition Height="0.33*"/>
138+
<RowDefinition Height="0.33*"/>
139+
</Grid.RowDefinitions>
120140

121-
<Button Grid.Column="0"
141+
<Button Grid.Column="0"
122142
Content="Evaluate !bsr"
123-
Height="50" Margin="0"
124143
Background="#404040"
125144
Foreground="#FAFAFA"
126-
FontSize="24" Click="evaluateCode_OnClick">
127-
</Button>
128-
<TextBox x:Name="bsrBox" TextWrapping="NoWrap"
129-
Text="1e6ff" Width="120"
130-
Margin="5"
131-
HorizontalAlignment="Left"/>
132-
145+
Margin="4,4,0,0"
146+
FontSize="24" Click="evaluateCode_OnClick"/>
147+
<TextBox x:Name="bsrBox" TextWrapping="NoWrap"
148+
Text="21703" Width="55"
149+
Margin="4,5,0,4" Grid.Column="1"
150+
HorizontalAlignment="Left"
151+
TextAlignment="Center"
152+
VerticalContentAlignment="Center"/>
153+
154+
<Button Grid.Column="0" Grid.Row="1"
155+
Content="Evaluate Folder"
156+
Background="#404040"
157+
Foreground="#FAFAFA"
158+
Margin="4,4,0,4"
159+
FontSize="24" Click="evaluateFolder_OnClick"/>
160+
161+
<Label x:Name="folderPerc" Grid.Column="1" Grid.Row="1"
162+
VerticalAlignment="Center"
163+
HorizontalAlignment="Center"
164+
Foreground="#FAFAFA"
165+
Content="" FontSize="10">
166+
</Label>
167+
168+
<!--
169+
<Button Grid.Column="0" Grid.Row="2"
170+
Content="Evaluate .bplist"
171+
Background="#404040"
172+
Foreground="#FAFAFA"
173+
Margin="4,4,0,4"
174+
FontSize="24"/>
175+
-->
176+
</Grid>
177+
133178
</StackPanel>
134179

135180
<!-- Queue List -->

BeatMapEvaluator/MainWindow.xaml.cs

Lines changed: 173 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616
using System.Collections.ObjectModel;
1717
using Newtonsoft.Json;
1818
using BeatMapEvaluator.Themes;
19+
using System.Security.Policy;
20+
using System.Runtime.Serialization;
21+
using System.Net.WebSockets;
1922

2023
namespace 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

Comments
 (0)