public static bool GenerateOJNList(ClientCheck Client) { if (!Directory.Exists(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Client.Music))) { _ = Directory.CreateDirectory(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Client.Music)); } DirectoryInfo Folder = new( Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Client.Music) ); FileInfo[] Files = Folder.GetFiles("o2ma*.ojn"); if (Files.Length < 1) { _ = MessageBox.Show($"There no known files \"o2ma*.ojn\" in folder \"{Client.Music}\", check your folder if there any songs!", "Error", MessageBoxButton.OK, MessageBoxImage.Error); return(false); } int MAX_SONG_FILES_COUNT = 620; if (Files.Length > MAX_SONG_FILES_COUNT) { _ = MessageBox.Show($"Maximum client song count reached! ({Files.Length}/{MAX_SONG_FILES_COUNT})", "Error", MessageBoxButton.OK, MessageBoxImage.Error); return(false); } Dictionary <string, OJN> ojnList = new(); foreach (FileInfo file in Files) { Log.Write($"OJNRead -> {file.Name}"); byte[] rawData = File.ReadAllBytes(file.FullName); OJN ojn = OJNDecoder.Decode(rawData); ojnList.Add(file.Name, ojn); } List <KeyValuePair <string, OJN> > list = ojnList.ToList(); list.Sort((KeyValuePair <string, OJN> pair1, KeyValuePair <string, OJN> pair2) => { return(pair1.Value.Id.CompareTo(pair2.Value.Id)); }); using MemoryStream ms = new(); using BinaryWriter br = new(ms); br.Write(ojnList.Count); foreach (KeyValuePair <string, OJN> itr in ojnList) { Log.Write($"OJNParse -> {itr.Key}"); br.Write(OJNEncoder.Encode(itr.Value, true)); } File.WriteAllBytes(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Image", Client.OJNList), ms.ToArray()); return(true); }
public static OJN Decode(byte[] inputData, Encoding encoding = default) { if (encoding == default(Encoding)) { encoding = Encoding.UTF8; } using (var mstream = new MemoryStream(inputData)) using (var reader = new BinaryReader(mstream)) { var header = new OJN(); header.Id = reader.ReadInt32(); header.Signature = reader.ReadBytes(4); header.EncodingVersion = reader.ReadSingle(); header.Genre = (Genre)reader.ReadInt32(); header.BPM = reader.ReadSingle(); header.LevelEx = reader.ReadInt16(); header.LevelNx = reader.ReadInt16(); header.LevelHx = reader.ReadInt16(); header.Padding = reader.ReadInt16(); header.EventCountEx = reader.ReadInt32(); header.EventCountNx = reader.ReadInt32(); header.EventCountHx = reader.ReadInt32(); header.NoteCountEx = reader.ReadInt32(); header.NoteCountNx = reader.ReadInt32(); header.NoteCountHx = reader.ReadInt32(); header.MeasureCountEx = reader.ReadInt32(); header.MeasureCountNx = reader.ReadInt32(); header.MeasureCountHx = reader.ReadInt32(); header.BlockCountEx = reader.ReadInt32(); header.BlockCountNx = reader.ReadInt32(); header.BlockCountHx = reader.ReadInt32(); header.OldEncodingVersion = reader.ReadInt16(); header.OldSongId = reader.ReadInt16(); header.OldGenre = reader.ReadBytes(20); header.ThumbnailSize = reader.ReadInt32(); header.FileVersion = reader.ReadInt32(); header.Title = reader.ReadBytes(64); header.Artist = reader.ReadBytes(32); header.Pattern = reader.ReadBytes(32); header.OJM = reader.ReadBytes(32); header.CoverSize = reader.ReadInt32(); header.DurationEx = reader.ReadInt32(); header.DurationNx = reader.ReadInt32(); header.DurationHx = reader.ReadInt32(); header.BlockOffsetEx = reader.ReadInt32(); header.BlockOffsetNx = reader.ReadInt32(); header.BlockOffsetHx = reader.ReadInt32(); header.CoverOffset = reader.ReadInt32(); header.CharacterEncoding = encoding; if (mstream.Length > 300 && header.ThumbnailSize > 0) { mstream.Seek(header.CoverOffset + header.CoverSize, SeekOrigin.Begin); using (var bitmapStream = new MemoryStream(reader.ReadBytes(header.ThumbnailSize))) { header.Thumbnail = new System.Drawing.Bitmap(bitmapStream); } } return(header); } }
public static byte[] Encode(OJN ojn) { byte[] header = EncodeHeader(ojn); using (var stream = new BufferStream(header)) { foreach (var difficulty in Enum.GetValues(typeof(OJN.Difficulty)) as OJN.Difficulty[]) { if (difficulty == OJN.Difficulty.MX) { continue; } var events = new List <Event>(); long offset = ojn.BlockOffset[difficulty]; int count = ojn.BlockCount[difficulty]; stream.Seek(offset, SeekOrigin.Begin); var blocks = ojn.Events[difficulty].GroupBy((ev) => new { ev.Measure, ev.Tempo, ev.LaneIndex }); foreach (var block in blocks) { stream.Write(block.Key.Measure); stream.Write((short)block.Key.LaneIndex); stream.Write((short)block.Key.Tempo); for (int i = 0; i < block.Key.Tempo; i++) { var ev = block.FirstOrDefault((e) => e.Cell == i); if (ev != null) { if (ev.Channel == Event.ChannelType.Measurement || ev.Channel == Event.ChannelType.BPM) { var time = ev as Event.Time; stream.Write(time.Value); } else { var sound = ev as Event.Sound; int id = sound.Id; int vol = sound.Volume == 100 ? 0 : (int)((sound.Volume / 100f) * 16f); int pan = (int)sound.Pan; id = (id >= 1000 ? id - 1000 : id) + 1; pan = pan == 0 ? pan : ((pan / 100) * 8) + 8; stream.Write((short)id); stream.Write((byte)((vol << 8) | pan & 0x00FF)); stream.Write((byte)((int)sound.Signature)); } } else { stream.Write(0); } } } } stream.Seek(ojn.CoverArtOffset, SeekOrigin.Begin); stream.Write(ojn.CoverArt); stream.Write(ojn.Thumbnail); return(stream.ToArray()); } }
public static byte[] EncodeHeader(OJN ojn) { using (var stream = new BufferStream()) { stream.Seek(0, SeekOrigin.Begin); stream.Write(ojn.Id); stream.Write(ojn.Sign.PadNull(4)); stream.Write(ojn.EncodingVersion); stream.Write((int)ojn.Genre); stream.Write(ojn.BPM); foreach (var diff in Enum.GetValues(typeof(OJN.Difficulty)) as OJN.Difficulty[]) { if (diff != OJN.Difficulty.MX) { stream.Write(ojn.Level[diff]); } else { stream.Write((short)0); } } foreach (var diff in Enum.GetValues(typeof(OJN.Difficulty)) as OJN.Difficulty[]) { if (diff != OJN.Difficulty.MX) { stream.Write(ojn.EventCount[diff]); } } foreach (var diff in Enum.GetValues(typeof(OJN.Difficulty)) as OJN.Difficulty[]) { if (diff != OJN.Difficulty.MX) { stream.Write(ojn.NoteCount[diff]); } } foreach (var diff in Enum.GetValues(typeof(OJN.Difficulty)) as OJN.Difficulty[]) { if (diff != OJN.Difficulty.MX) { stream.Write(ojn.MeasureCount[diff]); } } foreach (var diff in Enum.GetValues(typeof(OJN.Difficulty)) as OJN.Difficulty[]) { if (diff != OJN.Difficulty.MX) { stream.Write(ojn.BlockCount[diff]); } } stream.Write(ojn.OldEncodingVersion); stream.Write(ojn.OldId); stream.Write(ojn.OldGenre.PadNull(20)); stream.Write(ojn.ThumbnailSize); stream.Write(ojn.Version); stream.Write(ojn.Title.PadNull(64)); stream.Write(ojn.Artist.PadNull(32)); stream.Write(ojn.Pattern.PadNull(32)); stream.Write(ojn.OJMFileName.PadNull(32)); stream.Write(ojn.CoverArtSize); foreach (var diff in Enum.GetValues(typeof(OJN.Difficulty)) as OJN.Difficulty[]) { if (diff != OJN.Difficulty.MX) { stream.Write(ojn.Duration[diff]); } } foreach (var diff in Enum.GetValues(typeof(OJN.Difficulty)) as OJN.Difficulty[]) { if (diff != OJN.Difficulty.MX) { stream.Write(ojn.BlockOffset[diff]); } } stream.Write(ojn.CoverArtOffset); //stream.Seek(ojn.CoverArtOffset, SeekOrigin.Begin); //stream.Write(ojn.CoverArt); //stream.Write(ojn.Thumbnail); return(stream.ToArray()); } }
public static OJN DecodeHeader(string filename) { var ojn = new OJN(); using (var stream = new BufferStream(filename)) { stream.Seek(0, SeekOrigin.Begin); ojn.Id = stream.ReadInt32(); ojn.Sign = stream.ReadString(4); ojn.EncodingVersion = stream.ReadSingle(); ojn.Genre = (OJN.Genres)stream.ReadInt32(); ojn.BPM = stream.ReadSingle(); ojn.Level = new Dictionary <OJN.Difficulty, short> { [OJN.Difficulty.EX] = stream.ReadInt16(), [OJN.Difficulty.NX] = stream.ReadInt16(), [OJN.Difficulty.HX] = stream.ReadInt16(), [OJN.Difficulty.MX] = stream.ReadInt16() }; ojn.EventCount = new Dictionary <OJN.Difficulty, int> { [OJN.Difficulty.EX] = stream.ReadInt32(), [OJN.Difficulty.NX] = stream.ReadInt32(), [OJN.Difficulty.HX] = stream.ReadInt32() }; ojn.NoteCount = new Dictionary <OJN.Difficulty, int> { [OJN.Difficulty.EX] = stream.ReadInt32(), [OJN.Difficulty.NX] = stream.ReadInt32(), [OJN.Difficulty.HX] = stream.ReadInt32() }; ojn.MeasureCount = new Dictionary <OJN.Difficulty, int> { [OJN.Difficulty.EX] = stream.ReadInt32(), [OJN.Difficulty.NX] = stream.ReadInt32(), [OJN.Difficulty.HX] = stream.ReadInt32() }; ojn.BlockCount = new Dictionary <OJN.Difficulty, int> { [OJN.Difficulty.EX] = stream.ReadInt32(), [OJN.Difficulty.NX] = stream.ReadInt32(), [OJN.Difficulty.HX] = stream.ReadInt32() }; ojn.OldEncodingVersion = stream.ReadInt16(); ojn.OldId = stream.ReadInt16(); ojn.OldGenre = stream.ReadString(20); int thumbnailSize = stream.ReadInt32(); ojn.Version = stream.ReadInt32(); ojn.Title = stream.ReadString(64); ojn.Artist = stream.ReadString(32); ojn.Pattern = stream.ReadString(32); ojn.OJMFileName = stream.ReadString(32); int coverArtSize = stream.ReadInt32(); ojn.Duration = new Dictionary <OJN.Difficulty, int> { [OJN.Difficulty.EX] = stream.ReadInt32(), [OJN.Difficulty.NX] = stream.ReadInt32(), [OJN.Difficulty.HX] = stream.ReadInt32() }; ojn.BlockOffset = new Dictionary <OJN.Difficulty, int> { [OJN.Difficulty.EX] = stream.ReadInt32(), [OJN.Difficulty.NX] = stream.ReadInt32(), [OJN.Difficulty.HX] = stream.ReadInt32() }; ojn.CoverArtOffset = stream.ReadInt32(); stream.Seek(ojn.CoverArtOffset, SeekOrigin.Begin); ojn.CoverArt = stream.ReadBytes(coverArtSize); ojn.Thumbnail = stream.ReadBytes(thumbnailSize); return(ojn); } }