Initial version. Basic functionality complete. Just needs touching up,

breaks added, bonus features.
master
sigonasr2 5 years ago
commit fd6642805a
  1. 8
      osuMapCombiner/.classpath
  2. 13
      osuMapCombiner/.externalToolBuilders/New_Builder (1).launch
  3. 1
      osuMapCombiner/.gitignore
  4. 27
      osuMapCombiner/.project
  5. 3
      osuMapCombiner/.settings/org.eclipse.core.resources.prefs
  6. 11
      osuMapCombiner/.settings/org.eclipse.jdt.core.prefs
  7. BIN
      osuMapCombiner/data.txt
  8. BIN
      osuMapCombiner/ffmpeg.exe
  9. 3
      osuMapCombiner/filecombine.txt
  10. 164
      osuMapCombiner/hs_err_pid24308.log
  11. BIN
      osuMapCombiner/lib/commons-exec-1.3.jar
  12. BIN
      osuMapCombiner/lib/jlayer-1.0.1.jar
  13. BIN
      osuMapCombiner/mp3val.exe
  14. BIN
      osuMapCombiner/osuMapCombiner.jar
  15. 19
      osuMapCombiner/projectBuilder.xml
  16. 26
      osuMapCombiner/src/osuMapCombiner/AddMap.java
  17. 340
      osuMapCombiner/src/osuMapCombiner/Convert.java
  18. 19
      osuMapCombiner/src/osuMapCombiner/DifficultyValues.java
  19. 143
      osuMapCombiner/src/osuMapCombiner/ListItem.java
  20. 126
      osuMapCombiner/src/osuMapCombiner/ListTransferHandler.java
  21. 38
      osuMapCombiner/src/osuMapCombiner/mp3utils.java
  22. 138
      osuMapCombiner/src/osuMapCombiner/osuMapCombiner.java
  23. 81
      osuMapCombiner/src/osuMapCombiner/utils.java
  24. 14
      osuMapCombiner/src/osuMapCombiner/window.java

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="lib" path="C:/Users/sigon/git/repository/Tagger/lib/commons-exec-1.3.jar"/>
<classpathentry kind="lib" path="C:/Users/sigon/Downloads/jlayer-1.0.1.jar/jlayer-1.0.1.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<launchConfiguration type="org.eclipse.ant.AntBuilderLaunchConfigurationType">
<booleanAttribute key="org.eclipse.ant.ui.ATTR_TARGETS_UPDATED" value="true"/>
<booleanAttribute key="org.eclipse.ant.ui.DEFAULT_VM_INSTALL" value="false"/>
<booleanAttribute key="org.eclipse.debug.ui.ATTR_LAUNCH_IN_BACKGROUND" value="false"/>
<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="org.eclipse.ant.ui.AntClasspathProvider"/>
<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="true"/>
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="osuMapCombiner"/>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${workspace_loc:/osuMapCombiner/projectBuilder.xml}"/>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_RUN_BUILD_KINDS" value="full,incremental,"/>
<booleanAttribute key="org.eclipse.ui.externaltools.ATTR_TRIGGERS_CONFIGURED" value="true"/>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_WORKING_DIRECTORY" value="${workspace_loc:/osuMapCombiner}"/>
</launchConfiguration>

@ -0,0 +1 @@
/bin/

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>osuMapCombiner</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.ui.externaltools.ExternalToolBuilder</name>
<triggers>full,incremental,</triggers>
<arguments>
<dictionary>
<key>LaunchConfigHandle</key>
<value>&lt;project&gt;/.externalToolBuilders/New_Builder (1).launch</value>
</dictionary>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

@ -0,0 +1,3 @@
eclipse.preferences.version=1
encoding//src/osuMapCombiner/Convert.java=UTF-8
encoding//src/osuMapCombiner/osuMapCombiner.java=UTF-8

@ -0,0 +1,11 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.8

Binary file not shown.

Binary file not shown.

@ -0,0 +1,3 @@
file 'E:/〇su/Songs/33911 Yousei Teikoku - Hades_ The Rise (1)/02.mp3'
file 'E:/〇su/Songs/13223 Demetori - Emotional Skyscraper ~ World'\''s End (1)/Demetori - Nada Upasana Pundarika - 06 - .mp3'
file 'E:/〇su/Songs/713989 FELT - Time and again (1)/audio.mp3'

@ -0,0 +1,164 @@
#
# There is insufficient memory for the Java Runtime Environment to continue.
# Native memory allocation (malloc) failed to allocate 1048576 bytes for AllocateHeap
# Possible reasons:
# The system is out of physical RAM or swap space
# The process is running with CompressedOops enabled, and the Java Heap may be blocking the growth of the native heap
# Possible solutions:
# Reduce memory load on the system
# Increase physical memory or swap space
# Check if swap backing store is full
# Decrease Java heap size (-Xmx/-Xms)
# Decrease number of Java threads
# Decrease Java thread stack sizes (-Xss)
# Set larger code cache with -XX:ReservedCodeCacheSize=
# JVM is running with Zero Based Compressed Oops mode in which the Java heap is
# placed in the first 32GB address space. The Java Heap base address is the
# maximum limit for the native heap growth. Please use -XX:HeapBaseMinAddress
# to set the Java Heap base and to place the Java Heap above 32GB virtual address.
# This output file may be truncated or incomplete.
#
# Out of Memory Error (memory/allocation.inline.hpp:61), pid=24308, tid=0x00000000000021e0
#
# JRE version: (8.0_221-b11) (build )
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.221-b11 mixed mode windows-amd64 compressed oops)
# Failed to write core dump. Minidumps are not enabled by default on client versions of Windows
#
--------------- T H R E A D ---------------
Current thread (0x000000000316d800): JavaThread "Unknown thread" [_thread_in_vm, id=8672, stack(0x0000000002f10000,0x0000000003010000)]
Stack: [0x0000000002f10000,0x0000000003010000]
[error occurred during error reporting (printing stack bounds), id 0xc0000005]
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
--------------- P R O C E S S ---------------
Java Threads: ( => current thread )
Other Threads:
=>0x000000000316d800 (exited) JavaThread "Unknown thread" [_thread_in_vm, id=8672, stack(0x0000000002f10000,0x0000000003010000)]
VM state:not at safepoint (normal execution)
VM Mutex/Monitor currently owned by a thread: None
heap address: 0x00000006c0a00000, size: 4086 MB, Compressed Oops mode: Zero based, Oop shift amount: 3
Narrow klass base: 0x0000000000000000, Narrow klass shift: 3
Compressed class space size: 1073741824 Address: 0x00000007c0000000
Heap:
PSYoungGen total 76288K, used 1310K [0x000000076ae00000, 0x0000000770300000, 0x00000007c0000000)
eden space 65536K, 2% used [0x000000076ae00000,0x000000076af47af0,0x000000076ee00000)
from space 10752K, 0% used [0x000000076f880000,0x000000076f880000,0x0000000770300000)
to space 10752K, 0% used [0x000000076ee00000,0x000000076ee00000,0x000000076f880000)
ParOldGen total 175104K, used 0K [0x00000006c0a00000, 0x00000006cb500000, 0x000000076ae00000)
object space 175104K, 0% used [0x00000006c0a00000,0x00000006c0a00000,0x00000006cb500000)
Metaspace used 776K, capacity 4480K, committed 4480K, reserved 1056768K
class space used 76K, capacity 384K, committed 384K, reserved 1048576K
Card table byte_map: [0x0000000012530000,0x0000000012d30000] byte_map_base: 0x000000000ef2b000
Marking Bits: (ParMarkBitMap*) 0x000000005dbb5ce0
Begin Bits: [0x0000000013a90000, 0x0000000017a68000)
End Bits: [0x0000000017a68000, 0x000000001ba40000)
Polling page: 0x00000000011b0000
CodeCache: size=245760Kb used=328Kb max_used=328Kb free=245431Kb
bounds [0x0000000003170000, 0x00000000033e0000, 0x0000000012170000]
total_blobs=58 nmethods=0 adapters=38
compilation: enabled
Compilation events (0 events):
No events
GC Heap History (0 events):
No events
Deoptimization events (0 events):
No events
Classes redefined (0 events):
No events
Internal exceptions (0 events):
No events
Events (10 events):
Event: 0.020 loading class java/lang/Short
Event: 0.020 loading class java/lang/Short done
Event: 0.020 loading class java/lang/Integer
Event: 0.020 loading class java/lang/Integer done
Event: 0.020 loading class java/lang/Long
Event: 0.020 loading class java/lang/Long done
Event: 0.021 loading class java/lang/NullPointerException
Event: 0.021 loading class java/lang/NullPointerException done
Event: 0.021 loading class java/lang/ArithmeticException
Event: 0.021 loading class java/lang/ArithmeticException done
Dynamic libraries:
0x00007ff7eda60000 - 0x00007ff7eda97000 C:\Program Files\Java\jdk1.8.0_221\jre\bin\javaw.exe
0x00007fff50f60000 - 0x00007fff51150000 C:\Windows\SYSTEM32\ntdll.dll
0x00007fff50160000 - 0x00007fff50212000 C:\Windows\System32\KERNEL32.DLL
0x00007fff4e240000 - 0x00007fff4e4e3000 C:\Windows\System32\KERNELBASE.dll
0x00007fff4fab0000 - 0x00007fff4fb53000 C:\Windows\System32\ADVAPI32.dll
0x00007fff4f940000 - 0x00007fff4f9de000 C:\Windows\System32\msvcrt.dll
0x00007fff506b0000 - 0x00007fff50747000 C:\Windows\System32\sechost.dll
0x00007fff50040000 - 0x00007fff50160000 C:\Windows\System32\RPCRT4.dll
0x00007fff504d0000 - 0x00007fff50664000 C:\Windows\System32\USER32.dll
0x00007fff4ee30000 - 0x00007fff4ee51000 C:\Windows\System32\win32u.dll
0x00007fff50670000 - 0x00007fff50696000 C:\Windows\System32\GDI32.dll
0x00007fff4e4f0000 - 0x00007fff4e684000 C:\Windows\System32\gdi32full.dll
0x00007fff4dfc0000 - 0x00007fff4e05e000 C:\Windows\System32\msvcp_win.dll
0x00007fff4ef10000 - 0x00007fff4f00a000 C:\Windows\System32\ucrtbase.dll
0x00007fff45d70000 - 0x00007fff45ff5000 C:\Windows\WinSxS\amd64_microsoft.windows.common-controls_6595b64144ccf1df_6.0.18362.476_none_e6c4b11b130f2595\COMCTL32.dll
0x00007fff4fc30000 - 0x00007fff4ff66000 C:\Windows\System32\combase.dll
0x00007fff4def0000 - 0x00007fff4df70000 C:\Windows\System32\bcryptPrimitives.dll
0x00007fff504a0000 - 0x00007fff504ce000 C:\Windows\System32\IMM32.DLL
0x000000005e7b0000 - 0x000000005e882000 C:\Program Files\Java\jdk1.8.0_221\jre\bin\msvcr100.dll
0x000000005d390000 - 0x000000005dc35000 C:\Program Files\Java\jdk1.8.0_221\jre\bin\server\jvm.dll
0x00007fff506a0000 - 0x00007fff506a8000 C:\Windows\System32\PSAPI.DLL
0x00007fff41b60000 - 0x00007fff41b69000 C:\Windows\SYSTEM32\WSOCK32.dll
0x00007fff41b90000 - 0x00007fff41bb4000 C:\Windows\SYSTEM32\WINMM.dll
0x00007fff49250000 - 0x00007fff4925a000 C:\Windows\SYSTEM32\VERSION.dll
0x00007fff503a0000 - 0x00007fff5040f000 C:\Windows\System32\WS2_32.dll
0x00007fff405e0000 - 0x00007fff4060d000 C:\Windows\SYSTEM32\WINMMBASE.dll
0x00007fff4df70000 - 0x00007fff4dfba000 C:\Windows\System32\cfgmgr32.dll
0x00007fff400a0000 - 0x00007fff400af000 C:\Program Files\Java\jdk1.8.0_221\jre\bin\verify.dll
0x00007fff26db0000 - 0x00007fff26dd9000 C:\Program Files\Java\jdk1.8.0_221\jre\bin\java.dll
0x00007fff38cd0000 - 0x00007fff38ce6000 C:\Program Files\Java\jdk1.8.0_221\jre\bin\zip.dll
VM Arguments:
jvm_args: -Dfile.encoding=Cp1252
java_command: osuMapCombiner.osuMapCombiner
java_class_path (initial): C:\Users\sigon\eclipse-workspace\osuMapCombiner\bin;C:\Users\sigon\git\repository\Tagger\lib\commons-exec-1.3.jar
Launcher Type: SUN_STANDARD
Environment Variables:
PATH=C:/Program Files/Java/jdk-12.0.2/bin/server;C:/Program Files/Java/jdk-12.0.2/bin;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\Program Files (x86)\Common Files\Oracle\Java\javapath;C:\Program Files (x86)\Razer Chroma SDK\bin;C:\Program Files\Razer Chroma SDK\bin;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Users\sigon\AppData\Local\Microsoft\WindowsApps;C:\Program Files\PuTTY\;C:\Users\sigon\AppData\Local\Microsoft\WindowsApps;;C:\Windows\system32;
USERNAME=sigon
OS=Windows_NT
PROCESSOR_IDENTIFIER=Intel64 Family 6 Model 158 Stepping 9, GenuineIntel
--------------- S Y S T E M ---------------
OS: Windows 10.0 , 64 bit Build 18362 (10.0.18362.329)
CPU:total 8 (initial active 8) (4 cores per cpu, 2 threads per core) family 6 model 158 stepping 9, cmov, cx8, fxsr, mmx, sse, sse2, sse3, ssse3, sse4.1, sse4.2, popcnt, avx, avx2, aes, clmul, erms, rtm, 3dnowpref, lzcnt, ht, tsc, tscinvbit, bmi1, bmi2, adx
Memory: 4k page, physical 16729332k(3845212k free), swap 23440508k(5132k free)
vm_info: Java HotSpot(TM) 64-Bit Server VM (25.221-b11) for windows-amd64 JRE (1.8.0_221-b11), built on Jul 4 2019 04:39:29 by "java_re" with MS VC++ 10.0 (VS2010)
time: Sat Dec 14 15:44:18 2019
timezone: Korea Standard Time
elapsed time: 0 seconds (0d 0h 0m 0s)

Binary file not shown.

Binary file not shown.

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project default="create_run_jar" name="Create Runnable Jar for Project osuMapCombiner">
<!--this file was created by Eclipse Runnable JAR Export Wizard-->
<!--ANT 1.7 is required -->
<!--define folder properties-->
<property name="dir.buildfile" value="."/>
<property name="dir.workspace" value="${dir.buildfile}/.."/>
<property name="dir.jarfile" value="${dir.buildfile}"/>
<target name="create_run_jar">
<jar destfile="${dir.jarfile}/osuMapCombiner.jar" filesetmanifest="mergewithoutmain">
<manifest>
<attribute name="Main-Class" value="osuMapCombiner"/>
<attribute name="Class-Path" value="."/>
</manifest>
<fileset dir="${dir.jarfile}/bin"/>
<zipfileset excludes="META-INF/*.SF" src="lib/commons-exec-1.3.jar"/>
</jar>
</target>
</project>

@ -0,0 +1,26 @@
package osuMapCombiner;
import java.io.File;
import java.io.FileFilter;
import javax.swing.JFileChooser;
import javax.swing.filechooser.FileNameExtensionFilter;
public class AddMap {
JFileChooser chooser = new JFileChooser();
public AddMap() {
chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
chooser.setAcceptAllFileFilterUsed(false);
FileNameExtensionFilter filter = new FileNameExtensionFilter("osu! Beatmaps", "osu");
chooser.addChoosableFileFilter(filter);
}
public void openDialog() {
int val = chooser.showOpenDialog(null);
if (val==JFileChooser.APPROVE_OPTION) {
osuMapCombiner.model.addElement(new ListItem(chooser.getSelectedFile()));
}
}
}

@ -0,0 +1,340 @@
package osuMapCombiner;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.SequenceInputStream;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import org.apache.commons.exec.CommandLine;
import org.apache.commons.exec.DefaultExecutor;
public class Convert {
public final static boolean debugOutput=true;
public static void Convert() {
String marathonName = "";
List<ListItem> maps = new ArrayList<ListItem>();
List<String> points = new ArrayList<String>();
double timePoint=0;
double remainder=0;
for (int i=0;i<osuMapCombiner.model.getSize();i++) {
ListItem l = (ListItem)osuMapCombiner.model.get(i);
maps.add(l);
/*
* Remove any remainder times due to decimals, since timings like to be integers, and we could be 1ms off.
*/
remainder = timePoint-Math.floor(timePoint);
while (remainder>=1) {
timePoint++;
remainder--;
}
if (timePoint!=0) {
for (int j=0;j<l.timingPoints.size();j++) {
String timingPoint = l.timingPoints.get(j);
String[] split = timingPoint.split(",");
Double timing = Double.parseDouble(split[0]);
/*if (j==0) {
timing=(int)timePoint;
} else {*/
timing+=timePoint;
//}
StringBuilder newString = new StringBuilder(Double.toString(timing));
for (int k=1;k<split.length;k++) {
newString.append(",");
newString.append(split[k]);
}
points.add(newString.toString());
}
} else {
points.addAll(l.timingPoints);
}
timePoint+=l.songDuration;
}
if (debugOutput) {
System.out.println(points.size()+" timing points added: ");
for (int i=0;i<points.size();i++) {
System.out.println(points.get(i));
}
}
do {
marathonName = JOptionPane.showInputDialog("Enter a name for the marathon map:");
} while (marathonName.length()==0);
List<String> marathonMap = new ArrayList<String>();
System.out.println("Beginning marathon map conversion process...");
marathonMap.add("osu file format v14");
marathonMap.add("");
marathonMap.add("[General]");
marathonMap.add("AudioFilename: marathon.mp3");
marathonMap.add("AudioLeadIn: 0");
marathonMap.add("PreviewTime: "+(int)Math.floor(osuMapCombiner.duration/2));
marathonMap.add("Countdown: 1");
marathonMap.add("SampleSet: Soft");
marathonMap.add("StackLeniency: 0.5");
marathonMap.add("Mode: 0");
marathonMap.add("LetterboxInBreaks: 0");
marathonMap.add("WidescreenStoryboard: 0");
marathonMap.add("");
/*
* Artist:FELT
ArtistUnicode:FELT
Creator:MokouSmoke
Version:Lunatic
Source:東方星蓮船  Undefined Fantastic Object.
Tags:Maika 舞花 Mika 美歌 NAGIFlying Fantastica touhou ZUN Byakuren Hijiri 感情の摩天楼 Emotional Skyscraper Cosmic Mind C93
DistanceSpacing: 1.2
BeatDivisor: 4
GridSize: 4
TimelineZoom: 1
BeatmapID:0
BeatmapSetID:-1
*/
marathonMap.add("[Editor]");
marathonMap.add("DistanceSpacing: 1.2");
marathonMap.add("BeatDivisor: 4");
marathonMap.add("GridSize: 4");
marathonMap.add("TimelineZoom: 1");
marathonMap.add("");
marathonMap.add("[Metadata]");
marathonMap.add("Title:"+marathonName);
marathonMap.add("TitleUnicode:"+marathonName);
marathonMap.add("Artist:"+marathonName);
marathonMap.add("Creator:"+marathonName);
marathonMap.add("Version:Marathon");
marathonMap.add("Source:"+marathonName);
marathonMap.add("Tags:"+marathonName);
marathonMap.add("BeatmapID:0");
marathonMap.add("BeatmapSetID:-1");
marathonMap.add("");
double averageHPDrain = AverageValues(DifficultyValues.HPDrainRate,maps);
double averageCircleSize = AverageValues(DifficultyValues.CircleSize,maps);
double averageOverallDifficulty = AverageValues(DifficultyValues.OverallDifficulty,maps);
double averageApproachRate = AverageValues(DifficultyValues.ApproachRate,maps);
double averageSliderMultiplier = AverageValues(DifficultyValues.SliderMultiplier,maps);
double averageSliderTickRate = AverageValues(DifficultyValues.SliderTickRate,maps);
System.out.println("Averages: "+averageHPDrain+"/"+averageCircleSize+"/"+averageOverallDifficulty+"/"+averageOverallDifficulty+"/"+averageApproachRate+"/"+averageSliderMultiplier+"/"+averageSliderTickRate);
marathonMap.add("[Difficulty]");
marathonMap.add("HPDrainRate:"+(int)averageHPDrain);
marathonMap.add("CircleSize:"+(int)averageCircleSize);
marathonMap.add("OverallDifficulty:"+(int)averageOverallDifficulty);
marathonMap.add("ApproachRate:"+(int)averageApproachRate);
marathonMap.add("SliderMultiplier:1.0");
marathonMap.add("SliderTickRate:"+(int)averageSliderTickRate);
marathonMap.add("");
/*[Events]
//Background and Video events
//Break Periods
//Storyboard Layer 0 (Background)
//Storyboard Layer 1 (Fail)
//Storyboard Layer 2 (Pass)
//Storyboard Layer 3 (Foreground)
//Storyboard Layer 4 (Overlay)
//Storyboard Sound Samples
*
*/
marathonMap.add("[Events]");
marathonMap.add("//Background and Video events\r\n" +
"//Break Periods\r\n" +
"//Storyboard Layer 0 (Background)\r\n" +
"//Storyboard Layer 1 (Fail)\r\n" +
"//Storyboard Layer 2 (Pass)\r\n" +
"//Storyboard Layer 3 (Foreground)\r\n" +
"//Storyboard Layer 4 (Overlay)\r\n" +
"//Storyboard Sound Samples");
marathonMap.add("");
marathonMap.add("[TimingPoints]");
for(int i=0;i<points.size();i++) {
marathonMap.add(points.get(i));
}
marathonMap.add("");
marathonMap.add("[HitObjects]");
timePoint=0;
remainder=0;
for (int i=0;i<maps.size();i++) {
ListItem map = maps.get(i);
remainder = timePoint-Math.floor(timePoint);
while (remainder>=1) {
timePoint++;
remainder--;
}
double sliderMultiplierRatio = 1.0d/map.sliderMultiplier;
for (int j=0;j<map.hitObjects.size();j++) {
String hitobject = map.hitObjects.get(j);
String[] split = hitobject.split(",");
split[2] = Integer.toString(Integer.parseInt(split[2])+(int)timePoint);
if (split.length>=6) {
//Might be a spinner.
if (!split[5].contains("|")) {
//This is a spinner.
split[5] = Integer.toString(Integer.parseInt(split[5])+(int)timePoint);
} else {
//This is a slider.
if (split.length>=8) {
//Verified.
double sliderlength = Double.parseDouble(split[7]);
split[7] = Double.toString(sliderlength * sliderMultiplierRatio);
}
}
}
//Re-write the hit object.
StringBuilder hitObj = new StringBuilder(split[0]);
for (int k=1;k<split.length;k++) {
hitObj.append(",");
hitObj.append(split[k]);
}
marathonMap.add(hitObj.toString());
}
timePoint += map.songDuration;
}
marathonMap.add("");
JFileChooser chooser = new JFileChooser();
chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
chooser.setDialogTitle("Choose your osu! Songs folder to save the marathon map");
int val = chooser.showOpenDialog(null);
while (val!=JFileChooser.APPROVE_OPTION) {
val = chooser.showOpenDialog(null);
}
File saveDir = chooser.getSelectedFile();
File targetDir = new File(saveDir.getAbsolutePath(),marathonName);
targetDir.mkdirs();
String songCombiners = "";
for (int i=0;i<maps.size();i++) {
try {
File filer = new File(maps.get(i).songLoc.getName());
utils.copyFile(maps.get(i).songLoc, filer);
filer.deleteOnExit();
} catch (IOException e) {
e.printStackTrace();
}
songCombiners+=" \""+maps.get(i).songLoc.getName()+"\"";
}
File checkForDeletion = new File("marathon.mp3");
checkForDeletion.delete();
/*for (int i=0;i<maps.size();i++) {
File filer = new File(maps.get(i).songLoc.getName().replace(".mp3", "_A.mp3"));
String command = "ffmpeg -i \""+maps.get(i).songLoc.getName()+"\" -f mp3 -b:a 128k -ar 44100 -ac 2 \""+maps.get(i).songLoc.getName().replace(".mp3", "_A.mp3")+"\"";
CommandLine cmdLine = CommandLine.parse(command);
DefaultExecutor exec = new DefaultExecutor();
try {
exec.execute(cmdLine);
System.out.println(filer.getName()+": "+mp3utils.GetSongDuration(filer.getAbsolutePath()));
} catch (IOException e) {
e.printStackTrace();
}
filer.deleteOnExit();
}*/
//Next, concatenate all files together.
File f = new File("list.txt");
FileWriter fw2;
try {
fw2 = new FileWriter(f);
BufferedWriter bw2 = new BufferedWriter(fw2);
for (int i=0;i<maps.size();i++) {
File filer = new File(maps.get(i).songLoc.getName().replace(".mp3", "_A.mp3"));
bw2.write("file '"+filer.getAbsolutePath().replace("'", "'\\''")+"'\n");
}
bw2.close();
fw2.close();
} catch (IOException e1) {
e1.printStackTrace();
}
f.deleteOnExit();
String command = "ffmpeg -f concat -safe 0 -i list.txt -c copy marathon.mp3";
CommandLine cmdLine = CommandLine.parse(command);
DefaultExecutor exec = new DefaultExecutor();
try {
exec.execute(cmdLine);
} catch (IOException e) {
e.printStackTrace();
}
command = "mp3val marathon.mp3 -f -nb";
cmdLine = CommandLine.parse(command);
exec = new DefaultExecutor();
try {
exec.execute(cmdLine);
} catch (IOException e) {
e.printStackTrace();
}
File finalFile2 = new File("marathon.mp3");
try {
utils.copyFile(finalFile2, new File(targetDir,"marathon.mp3"));
} catch (IOException e) {
e.printStackTrace();
}
finalFile2.deleteOnExit();
File beatmapLoc = new File(targetDir,marathonName+" [Marathon].osu");
FileWriter fw;
try {
fw = new FileWriter(beatmapLoc);
BufferedWriter bw = new BufferedWriter(fw);
for (int i=0;i<marathonMap.size();i++) {
bw.write(marathonMap.get(i));
bw.write("\n");
}
bw.close();
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public static double AverageValues(DifficultyValues val,List<ListItem> maps) {
double total = 0;
for (int i=0;i<maps.size();i++) {
switch (val) {
case HPDrainRate:{
total += maps.get(i).hpDrainRate;
}break;
case CircleSize:{
total += maps.get(i).circleSize;
}break;
case OverallDifficulty:{
total += maps.get(i).overallDifficulty;
}break;
case ApproachRate:{
total += maps.get(i).approachRate;
}break;
case SliderMultiplier:{
total += maps.get(i).sliderMultiplier;
}break;
case SliderTickRate:{
total += maps.get(i).sliderTickRate;
}break;
}
}
return total/maps.size();
}
}

@ -0,0 +1,19 @@
package osuMapCombiner;
public enum DifficultyValues{
HPDrainRate(1),
CircleSize(2),
OverallDifficulty(3),
ApproachRate(4),
SliderMultiplier(5),
SliderTickRate(6),
;
int i=0;
DifficultyValues(int i) {
this.i=i;
}
}

@ -0,0 +1,143 @@
package osuMapCombiner;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.exec.CommandLine;
import org.apache.commons.exec.DefaultExecutor;
import org.apache.commons.exec.PumpStreamHandler;
public class ListItem{
String songTitle;
File file;
File songLoc;
double songDuration=0;
double hpDrainRate=7;
double circleSize=7;
double overallDifficulty=7;
double approachRate=7;
double sliderMultiplier=1;
double sliderTickRate=1;
double beatDuration=0;
String[] data;
List<String> timingPoints;
List<String> hitObjects;
public ListItem(File f) {
//this.songTitle=s;
timingPoints = new ArrayList<String>();
hitObjects = new ArrayList<String>();
songTitle = f.getName();
System.out.println("Song Title: "+songTitle);
data = utils.readFromFile(f.getAbsolutePath());
String line = "";
int i =0 ;
String targetString = "AudioFilename: ";
do {
line = data[i++];
} while (!line.contains(targetString));
songLoc = new File(f.getParent()+File.separatorChar+line.replace(targetString, ""));
System.out.println("SongLoc: "+songLoc);
File filer = new File(songLoc.getName().replace(".mp3", "_A.mp3"));
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
PumpStreamHandler streamHandler = new PumpStreamHandler(outputStream);
String command = "ffmpeg -i \""+songLoc.getAbsolutePath()+"\" -f mp3 -b:a 128k -ar 44100 -ac 2 \""+songLoc.getName().replace(".mp3", "_A.mp3")+"\"";
CommandLine cmdLine = CommandLine.parse(command);
DefaultExecutor exec = new DefaultExecutor();
exec.setStreamHandler(streamHandler);
try {
exec.execute(cmdLine);
//System.out.println(filer.getName()+": "+mp3utils.GetSongDuration(filer.getAbsolutePath()));
} catch (IOException e) {
e.printStackTrace();
}
filer.deleteOnExit();
String[] data2 = outputStream.toString().split("\n");
for (int h=0;h<data2.length;h++) {
if (data2[h].contains("Duration:")) {
String[] s = data2[h].split(",");
String timestamp = s[0].replace("Duration: ", "").trim();
String[] timestamp_s = timestamp.split(":");
int hrs = Integer.parseInt(timestamp_s[0]);
int min = Integer.parseInt(timestamp_s[1]);
double sec = Double.parseDouble(timestamp_s[2]);
songDuration += hrs*60*60*1000;
songDuration += min*60*1000;
songDuration += sec*1000;
}
}
//osuMapCombiner.duration += songDuration = mp3utils.GetSongDuration(songLoc.getAbsolutePath());
System.out.println("Song duration of "+songTitle+" : "+songDuration+"ms");
targetString="[Difficulty]";
do {
line = data[i++];
} while (!line.contains(targetString));
for (int j=0;j<6;j++) {
line = data[i++];
switch (line.split(":")[0]) {
case "HPDrainRate": {
hpDrainRate = Double.parseDouble(line.split(":")[1]);
}break;
case "CircleSize": {
circleSize = Double.parseDouble(line.split(":")[1]);
}break;
case "OverallDifficulty": {
overallDifficulty = Double.parseDouble(line.split(":")[1]);
}break;
case "ApproachRate": {
approachRate = Double.parseDouble(line.split(":")[1]);
}break;
case "SliderMultiplier": {
sliderMultiplier = Double.parseDouble(line.split(":")[1]);
}break;
case "SliderTickRate": {
sliderTickRate = Double.parseDouble(line.split(":")[1]);
}break;
}
}
targetString="[TimingPoints]";
do {
line = data[i++];
} while (!line.contains(targetString));
do {
line=data[i++];
if (line.trim().length()>3) {
timingPoints.add(line);
}
} while (line.trim().length()>3);
targetString="[HitObjects]";
do {
line = data[i++];
} while (!line.contains(targetString));
do {
if (i<data.length) {
line=data[i++];
if (Convert.debugOutput) {
System.out.println(line);
}
if (line.trim().length()>3) {
hitObjects.add(line);
}
}
} while (i<data.length && line.trim().length()>3);
}
public String getData() {
return songTitle;
}
public String toString() {
return songTitle;
}
}

@ -0,0 +1,126 @@
package osuMapCombiner;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
import java.util.Arrays;
import javax.swing.DefaultListModel;
import javax.swing.JComponent;
import javax.swing.JList;
import javax.swing.TransferHandler;
public class ListTransferHandler extends TransferHandler {
private int[] indices = null;
private int addIndex = -1; //Location where items were added
private int addCount = 0; //Number of items added.
private ListItem item = null;
/**
* We only support importing strings.
*/
public boolean canImport(TransferHandler.TransferSupport info) {
// Check for String flavor
if (!info.isDataFlavorSupported(DataFlavor.stringFlavor)) {
return false;
}
return true;
}
/**
* Bundle up the selected items in a single list for export.
* Each line is separated by a newline.
*/
protected Transferable createTransferable(JComponent c) {
JList list = (JList)c;
indices = list.getSelectedIndices();
System.out.println("Selected indexes: "+Arrays.toString(indices));
Object[] values = list.getSelectedValues();
StringBuffer buff = new StringBuffer();
for (int i = 0; i < values.length; i++) {
Object val = values[i];
buff.append(val == null ? "" : val.toString());
if (i != values.length - 1) {
buff.append("\n");
}
}
System.out.println(buff.toString());
return new StringSelection(buff.toString());
}
/**
* We support both copy and move actions.
*/
public int getSourceActions(JComponent c) {
return TransferHandler.MOVE;
}
/**
* Perform the actual import. This demo only supports drag and drop.
*/
@SuppressWarnings("unchecked")
public boolean importData(TransferHandler.TransferSupport info) {
if (!info.isDrop()) {
return false;
}
JList list = (JList)info.getComponent();
DefaultListModel listModel = (DefaultListModel)list.getModel();
JList.DropLocation dl = (JList.DropLocation)info.getDropLocation();
int index = dl.getIndex();
boolean insert = dl.isInsert();
// Get the string that is being dropped.
Transferable t = info.getTransferable();
String data;
try {
data = (String)t.getTransferData(DataFlavor.stringFlavor);
}
catch (Exception e) { return false; }
// Wherever there is a newline in the incoming data,
// break it into a separate item in the list.
String[] values = data.split("\n");
addIndex = index;
addCount = values.length;
System.out.println(addIndex+","+addCount);
System.out.println("Selected indexes: "+Arrays.toString(indices));
for (int i=0;i<indices.length;i++) {
if (addIndex<indices[i]) {
listModel.add(addIndex, listModel.get(indices[i]));
//list.setSelectedValue(listModel.get(indices[i]), true);
listModel.remove(indices[i]+1);
} else {
//list.setSelectedIndex(addIndex-1);
listModel.add(addIndex, listModel.get(indices[i]));
//list.setSelectedValue(listModel.get(indices[i]), true);
listModel.remove(indices[i]);
}
}
return true;
}
/**
* Remove the items moved from the list.
*/
protected void exportDone(JComponent c, Transferable data, int action) {
JList source = (JList)c;
DefaultListModel listModel = (DefaultListModel)(source.getModel());
if (action == TransferHandler.MOVE) {
for (int i = indices.length - 1; i >= 0; i--) {
//listModel.remove(indices[i]);
}
}
indices = null;
addCount = 0;
addIndex = -1;
}
}

@ -0,0 +1,38 @@
package osuMapCombiner;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import javazoom.jl.decoder.Bitstream;
import javazoom.jl.decoder.BitstreamException;
import javazoom.jl.decoder.Header;
public class mp3utils {
/***
* @deprecated
* Returns song duration in milliseconds (mp3).
*/
/*public static double GetSongDuration(String filename) {
Header h = null;
FileInputStream file = null;
try {
file = new FileInputStream(filename);
} catch (FileNotFoundException ex) {
}
Bitstream bitstream = new Bitstream(file);
try {
h = bitstream.readFrame();
} catch (BitstreamException ex) {
}
long tn = 0;
try {
tn = file.getChannel().size();
} catch (IOException e) {
e.printStackTrace();
}
double duration = h.total_ms((int) tn);
return duration;
}*/
}

@ -0,0 +1,138 @@
package osuMapCombiner;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.logging.Logger;
import javax.swing.Box;
import javax.swing.DefaultListModel;
import javax.swing.DropMode;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ListSelectionModel;
import javax.swing.ScrollPaneConstants;
import org.apache.commons.exec.CommandLine;
import org.apache.commons.exec.DefaultExecutor;
import javazoom.jl.decoder.Bitstream;
import javazoom.jl.decoder.BitstreamException;
import javazoom.jl.decoder.Header;
public class osuMapCombiner extends JPanel implements ActionListener{
AddMap mapdialog = new AddMap();
public static DefaultListModel model = new DefaultListModel();
public static JList l = new JList(model);
public static double duration = 0;
public static JFrame f = new JFrame();
public static osuMapCombiner main;
osuMapCombiner() {
osuMapCombiner.main = this;
l.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
JScrollPane pane = new JScrollPane(l);
pane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
l.setDragEnabled(true);
l.setDropMode(DropMode.INSERT);
l.setTransferHandler(new ListTransferHandler());
l.setPreferredSize(new Dimension(280,400));
Component c = Box.createRigidArea(new Dimension(240,32));
JButton button = new JButton("+");
button.setActionCommand("Add");
button.setPreferredSize(new Dimension(42,42));
button.addActionListener(this);
JButton button2 = new JButton("Combine");
button2.setActionCommand("Combine");
button2.setPreferredSize(new Dimension(360,24));
button2.addActionListener(this);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
FlowLayout layout = new FlowLayout();
f.setLayout(layout);
f.add(l);
f.add(c);
f.add(button);
f.add(button2);
f.pack();
f.setSize(360, 520);
f.setVisible(true);
}
public static void main(String[] args) {
osuMapCombiner program = new osuMapCombiner();
/*
* DETECT SONG DURATION
Header h = null;
FileInputStream file = null;
String filename="E:/〇su/Songs/713989 FELT - Time and again (1)/audio.mp3";
try {
file = new FileInputStream(filename);
} catch (FileNotFoundException ex) {
}
Bitstream bitstream = new Bitstream(file);
try {
h = bitstream.readFrame();
} catch (BitstreamException ex) {
}
long tn = 0;
try {
tn = file.getChannel().size();
} catch (IOException e) {
e.printStackTrace();
}
double duration = h.total_ms((int) tn);
System.out.println(duration);
String command = "mp3wrap.exe output.mp3 \"E:/〇su/Songs/33911 Yousei Teikoku - Hades_ The Rise (1)/02.mp3\" \"E:/〇su/Songs/13223 Demetori - Emotional Skyscraper ~ World'\\''s End (1)/Demetori - Nada Upasana Pundarika - 06 - .mp3\" \"E:/〇su/Songs/713989 FELT - Time and again (1)/audio.mp3\"";
CommandLine cmdLine = CommandLine.parse(command);
DefaultExecutor exec = new DefaultExecutor();
try {
exec.execute(cmdLine);
} catch (IOException e) {
e.printStackTrace();
}*/
}
@Override
public void actionPerformed(ActionEvent e) {
switch (e.getActionCommand()) {
case "Add": {
mapdialog.openDialog();
}break;
case "Combine":{
int pane = JOptionPane.showConfirmDialog(f,"A marathon map with all "+model.getSize()+" maps will be created. The total duration of the marathon map will be "+
Math.floor(duration/1000)+"s long. Proceed?"
);
if (pane == JOptionPane.YES_OPTION) {
Convert.Convert();
}
}break;
}
}
}

@ -0,0 +1,81 @@
package osuMapCombiner;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.List;
public class utils {
public static String[] readFromFile(String filename) {
File file = new File(filename);
//System.out.println(file.getAbsolutePath());
List<String> contents= new ArrayList<String>();
if (file.exists()) {
try(
FileReader fw = new FileReader(filename);
BufferedReader bw = new BufferedReader(fw);)
{
String readline = bw.readLine();
do {
if (readline!=null) {
//System.out.println(readline);
contents.add(readline);
readline = bw.readLine();
}} while (readline!=null);
fw.close();
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return contents.toArray(new String[contents.size()]);
}
public static void writetoFile(String[] data, String filename) {
File file = new File(filename);
try {
if (!file.exists()) {
file.createNewFile();
}
FileWriter fw = new FileWriter(file,false);
PrintWriter pw = new PrintWriter(fw);
for (String s : data) {
pw.println(s);
}
pw.flush();
pw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void copyFile(File source, File dest) throws IOException {
FileChannel sourceChannel = null;
FileChannel destChannel = null;
try {
sourceChannel = new FileInputStream(source).getChannel();
destChannel = new FileOutputStream(dest).getChannel();
destChannel.transferFrom(sourceChannel, 0, sourceChannel.size());
}finally{
sourceChannel.close();
destChannel.close();
}
}
public static void deleteFile(String filename) {
File file = new File(filename);
if (file.exists()) {
file.delete();
}
}
}

@ -0,0 +1,14 @@
package osuMapCombiner;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JPanel;
public class window extends JPanel implements ActionListener{
@Override
public void actionPerformed(ActionEvent e) {
}
}
Loading…
Cancel
Save