-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
405 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
|
||
Microsoft Visual Studio Solution File, Format Version 12.00 | ||
# Visual Studio Version 16 | ||
VisualStudioVersion = 16.0.30907.101 | ||
MinimumVisualStudioVersion = 10.0.40219.1 | ||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Song Beater Map Mixer", "Song Beater Map Mixer\Song Beater Map Mixer.csproj", "{3CAD55CC-609C-42ED-80AE-AF9BCBACF408}" | ||
EndProject | ||
Global | ||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||
Debug|Any CPU = Debug|Any CPU | ||
Release|Any CPU = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(ProjectConfigurationPlatforms) = postSolution | ||
{3CAD55CC-609C-42ED-80AE-AF9BCBACF408}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
{3CAD55CC-609C-42ED-80AE-AF9BCBACF408}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
{3CAD55CC-609C-42ED-80AE-AF9BCBACF408}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
{3CAD55CC-609C-42ED-80AE-AF9BCBACF408}.Release|Any CPU.Build.0 = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(SolutionProperties) = preSolution | ||
HideSolutionNode = FALSE | ||
EndGlobalSection | ||
GlobalSection(ExtensibilityGlobals) = postSolution | ||
SolutionGuid = {D3852CAE-313F-4792-86E6-0AF767F7BFB8} | ||
EndGlobalSection | ||
EndGlobal |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
<Application x:Class="Song_Beater_Map_Mixer.App" | ||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | ||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | ||
xmlns:local="clr-namespace:Song_Beater_Map_Mixer" | ||
StartupUri="MainWindow.xaml"> | ||
<Application.Resources> | ||
|
||
</Application.Resources> | ||
</Application> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Configuration; | ||
using System.Data; | ||
using System.Linq; | ||
using System.Threading.Tasks; | ||
using System.Windows; | ||
|
||
namespace Song_Beater_Map_Mixer | ||
{ | ||
/// <summary> | ||
/// Interaction logic for App.xaml | ||
/// </summary> | ||
public partial class App : Application | ||
{ | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
using System.Windows; | ||
|
||
[assembly: ThemeInfo( | ||
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located | ||
//(used if a resource is not found in the page, | ||
// or application resource dictionaries) | ||
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located | ||
//(used if a resource is not found in the page, | ||
// app, or any theme specific resource dictionaries) | ||
)] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
<Window x:Class="Song_Beater_Map_Mixer.MainWindow" | ||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | ||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | ||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" | ||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" | ||
xmlns:local="clr-namespace:Song_Beater_Map_Mixer" | ||
Closing="Window_Closing" | ||
mc:Ignorable="d" | ||
Title="Song Beater Map Mixer" Height="310" Width="499"> | ||
<Grid Margin="0,0,0,0"> | ||
<TextBox x:Name="dir" HorizontalAlignment="Left" Height="30" Margin="17,36,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="453" | ||
TextChanged="dirChanged" | ||
/> | ||
<Label Content="Song folder to watch for saved levels" HorizontalAlignment="Left" Margin="17,10,0,0" VerticalAlignment="Top"/> | ||
<Button Content="Merge" x:Name="button" IsEnabled="False" HorizontalAlignment="Left" Height="28" Margin="17,108,0,0" VerticalAlignment="Top" Width="83" | ||
Click="merge" | ||
/> | ||
<Label x:Name="message" Content="Save level from SongBeaterEditor with different settings" HorizontalAlignment="Left" Height="28" Margin="121,108,0,0" VerticalAlignment="Top" Width="349"/> | ||
<TextBlock HorizontalAlignment="Left" Height="128" Margin="17,146,0,0" Text="How to use:
1. Copy path of Song Beater folder
2. While this app runs saved levels in that folder will be renamed to level variants
3. When you have at least 2 variants of the same level you can merge the variants into a mixed level (where chuncks of min..max orbs are taken randomly from the variants)
4. Note counts in main jb.json file are updated, and video if found is also added." TextWrapping="Wrap" VerticalAlignment="Top" Width="453"/> | ||
<TextBox HorizontalAlignment="Left" x:Name="min" Margin="95,71,0,0" Text="6" TextWrapping="Wrap" VerticalAlignment="Top" Width="45"/> | ||
<TextBox HorizontalAlignment="Left" x:Name="max" | ||
Margin="175,71,0,0" Text="18" TextWrapping="Wrap" VerticalAlignment="Top" Width="47"/> | ||
<Label Content="Chunck size" HorizontalAlignment="Left" Margin="17,67,0,0" VerticalAlignment="Top"/> | ||
<Label Content="..." HorizontalAlignment="Left" Margin="152,67,0,0" VerticalAlignment="Top"/> | ||
<CheckBox Checked="same_Checked" Unchecked="same_Checked" x:Name="same" Content="Merge only same orb count" HorizontalAlignment="Left" Height="18" Margin="244,71,0,0" VerticalAlignment="Top" Width="226"/> | ||
|
||
</Grid> | ||
</Window> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,301 @@ | ||
using Newtonsoft.Json; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Diagnostics; | ||
using System.IO; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Text.Json; | ||
using System.Threading.Tasks; | ||
using System.Windows; | ||
using System.Windows.Controls; | ||
using System.Windows.Data; | ||
using System.Windows.Documents; | ||
using System.Windows.Input; | ||
using System.Windows.Media; | ||
using System.Windows.Media.Imaging; | ||
using System.Windows.Navigation; | ||
using System.Windows.Shapes; | ||
using System.Windows.Threading; | ||
using Path = System.IO.Path; | ||
|
||
namespace Song_Beater_Map_Mixer | ||
{ | ||
/// <summary> | ||
/// Interaction logic for MainWindow.xaml | ||
/// </summary> | ||
public partial class MainWindow : Window | ||
{ | ||
|
||
DispatcherTimer timer = null; | ||
private FileSystemWatcher watcher=null; | ||
private readonly int SAMPLE=20; | ||
|
||
public MainWindow() | ||
{ | ||
InitializeComponent(); | ||
|
||
} | ||
|
||
|
||
|
||
private void dirChanged(object sender, TextChangedEventArgs e) | ||
{ | ||
try | ||
{ | ||
DisposeWatcher(); | ||
if (Directory.GetFiles(dir.Text, "*.ogg").Length > 0) | ||
{ | ||
/* timer = new DispatcherTimer(); | ||
timer.Interval = TimeSpan.FromSeconds(5); | ||
timer.Tick += rescan; | ||
timer.Start(); | ||
*/ | ||
|
||
watcher = new FileSystemWatcher(); | ||
watcher.Path = dir.Text; | ||
watcher.IncludeSubdirectories = false; | ||
watcher.NotifyFilter = NotifyFilters.LastWrite; | ||
for (int i = 1; i < 6; i++) | ||
watcher.Filters.Add(i + ".json"); | ||
|
||
watcher.Changed += OnChanged; | ||
|
||
watcher.EnableRaisingEvents = true; | ||
|
||
same_Checked(null, null); | ||
|
||
message.Content = "Save level from SongBeaterEditor with different settings"; | ||
} | ||
} catch { | ||
messager("Invalid folder"); | ||
} | ||
|
||
} | ||
|
||
private void same_Checked(object sender, RoutedEventArgs e) | ||
{ | ||
button.IsEnabled = false; | ||
for (int i = 1; i < 6; i++) enableButton(i.ToString()); | ||
} | ||
|
||
private void enableButton(string i) | ||
{ | ||
string[] list = Directory.GetFiles(dir.Text, i + "-*.json"); | ||
if (same.IsChecked == true) | ||
{ | ||
foreach (string path in list) | ||
{ | ||
string fn = Path.GetFileName(path); | ||
if (Directory.GetFiles(dir.Text, i + "-" + fn.Split("-")[1] + "-*.json").Length > 1) | ||
{ | ||
button.IsEnabled = true; | ||
return; | ||
} | ||
} | ||
} | ||
else if (list.Length > 1) | ||
{ | ||
button.IsEnabled = true; | ||
return; | ||
} | ||
|
||
} | ||
|
||
private void DisposeWatcher() | ||
{ | ||
if (watcher == null) return; | ||
watcher.Changed -= OnChanged; | ||
watcher.Dispose(); | ||
watcher = null; | ||
} | ||
|
||
private void OnChanged(object sender, FileSystemEventArgs e) | ||
{ | ||
|
||
string i= Path.GetFileName(e.FullPath).Substring(0,1); | ||
|
||
if (!File.Exists(e.FullPath)) return; | ||
|
||
string json = File.ReadAllText(e.FullPath); | ||
Level level = JsonConvert.DeserializeObject<Level>(json); | ||
|
||
if (level.spheres.Length > SAMPLE - 1) | ||
{ | ||
String newname = "-" + level.spheres.Length + "-"; | ||
|
||
for (int s = 0; s < SAMPLE; s++) | ||
if (s < SAMPLE - 1 && level.spheres[s].time == level.spheres[s + 1].time) { newname += level.spheres[s].y.ToString()+ level.spheres[s+1].y; s++; } | ||
else newname += (level.spheres[s].type == 1 ? "L" : "R")+level.spheres[s].y; | ||
|
||
messager("Renamed " + i + newname + ".json"); | ||
|
||
newname = e.FullPath.Substring(0, e.FullPath.Length - 5) + newname + ".json"; | ||
File.Delete(newname); | ||
File.Move(e.FullPath, newname); | ||
} | ||
|
||
Dispatcher.Invoke(() => { | ||
enableButton(i); | ||
}); | ||
} | ||
|
||
private void messager(string v) | ||
{ | ||
Dispatcher.Invoke(() => { | ||
message.Content = v; | ||
message.Foreground = Brushes.Red; | ||
}); | ||
|
||
} | ||
|
||
public class Level | ||
{ | ||
public string version; | ||
public Sphere[] spheres; | ||
} | ||
|
||
public class Sphere | ||
{ | ||
public float time; | ||
public int x, y, type; | ||
} | ||
|
||
private void merge(object sender, RoutedEventArgs e) | ||
{ | ||
// check for problems | ||
|
||
int cmin, cmax; | ||
|
||
try | ||
{ | ||
cmin = int.Parse(min.Text); | ||
cmax = int.Parse(max.Text); | ||
if (cmin > cmax || cmin < 1 || cmax<1) cmin = cmax / 0; | ||
} catch | ||
{ | ||
message.Content = "Incorrect chuck size"; | ||
return; | ||
} | ||
|
||
if(same.IsChecked==true) for (int i = 1; i < 6; i++) { | ||
string[] list = Directory.GetFiles(dir.Text, i + "-*.json"); | ||
string lastCount = null; | ||
foreach (string path in list) | ||
{ | ||
string count = Path.GetFileName(path).Split("-")[1]; | ||
if (lastCount != null && !count.Equals(lastCount)) | ||
{ | ||
message.Content = "Remove unmatching orb count for level " + i; | ||
return; | ||
} | ||
lastCount = count; | ||
} | ||
} | ||
|
||
string mergedir = dir.Text + (dir.Text.EndsWith("\\") ? "" : "\\") + "merged"; | ||
Directory.CreateDirectory(mergedir); | ||
|
||
// add mp4 | ||
|
||
string sb = "",fn=""; | ||
if (Directory.GetFiles(dir.Text, "sb.json").Length == 1) | ||
{ | ||
fn = Directory.GetFiles(dir.Text, "sb.json")[0]; | ||
sb = File.ReadAllText(fn); | ||
} | ||
string[] sbsplit = sb.Split(","); | ||
|
||
// mix | ||
|
||
string mixed = "", notmixed = ""; | ||
|
||
for (int i = 1; i < 6; i++) | ||
{ | ||
string[] list = Directory.GetFiles(dir.Text, i + "-*.json"); | ||
|
||
if (list.Length > 1) | ||
{ | ||
// read inputs | ||
|
||
Level[] level = new Level[list.Length]; | ||
|
||
int part = 0; | ||
float maxorb = 0; | ||
foreach (string path in list) | ||
{ | ||
string json = File.ReadAllText(path); | ||
level[part++] = JsonConvert.DeserializeObject<Level>(json); | ||
maxorb = Math.Max(maxorb, level[part - 1].spheres.Last<Sphere>().time); | ||
} | ||
|
||
// prepare output | ||
|
||
Level output = new Level(); | ||
output.version = level[0].version; | ||
List<Sphere> spheres = new List<Sphere>(); | ||
|
||
// merge | ||
|
||
Random random = new Random(); | ||
float lastorb = 0; | ||
do | ||
{ | ||
int next = random.Next(cmax - cmin) + cmin; | ||
int copy = random.Next(level.Length); | ||
|
||
int sphere = 0, len = level[copy].spheres.Length; | ||
while (sphere < len && level[copy].spheres[sphere].time <= lastorb) sphere++; | ||
|
||
while (sphere < len && (next > 0 || sphere>0 && level[copy].spheres[sphere].time == level[copy].spheres[sphere - 1].time)) | ||
{ | ||
//Debug.WriteLine("sphere="+sphere+" len="+len+" next="+next+" copy="+copy+" time="+ level[copy].spheres[sphere].time); | ||
spheres.Add(level[copy].spheres[sphere++]); | ||
next--; | ||
} | ||
lastorb = spheres.Last<Sphere>().time; | ||
} while (lastorb < maxorb); | ||
|
||
output.spheres = spheres.ToArray(); | ||
|
||
if (File.Exists(mergedir + "\\" + i + ".json")) | ||
notmixed += " " + i; | ||
else | ||
{ | ||
mixed += " " + i; | ||
File.WriteAllText(mergedir + "\\" + i + ".json", JsonConvert.SerializeObject(output)); | ||
|
||
// update note counts in sb | ||
|
||
if (sb.Length>0) | ||
{ | ||
for(int c=0;c<sbsplit.Length;c++) if(sbsplit[c].TrimStart().StartsWith("\"notes"+i+"\"")) | ||
{ | ||
sbsplit[c] = "\"notes" + i + "\":" + spheres.Count; | ||
break; | ||
} | ||
} | ||
} | ||
} | ||
} | ||
message.Content = (mixed.Length > 0 ? "Merged" + mixed + " into subfolder 'merged'. " : "") | ||
+ (notmixed.Length>0 ? "Did not overwrite existing"+notmixed+(mixed.Length>0 ? "":" in 'subfolder 'merged'"):""); | ||
|
||
if (sb.Length > 0) { | ||
sb = String.Join(",", sbsplit); | ||
if(Directory.GetFiles(dir.Text, "*.mp4").Length == 1) { | ||
string song = Path.GetFileName(Directory.GetFiles(dir.Text, "*.mp4")[0]); | ||
sb = sb.Replace("\"video\":\"\"", "\"video\":\"" + song + "\""); | ||
} | ||
File.WriteAllText(Path.GetDirectoryName(fn) + "\\merged\\sb.json", sb); | ||
} | ||
|
||
} | ||
|
||
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) | ||
{ | ||
DisposeWatcher(); | ||
} | ||
|
||
} | ||
} |
Oops, something went wrong.