mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/PCK-Studio.git
synced 2026-05-31 19:54:44 +00:00
this also fixes the "Include Overworld songs in Creative" feature. The code for that functionality was already perfect, so that hasn't been touched at all. Just needed to adjust the class a little. (:
114 lines
3.7 KiB
C#
114 lines
3.7 KiB
C#
using PckStudio.Classes.FileTypes;
|
|
using PckStudio.Classes.Utils;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace PckStudio.Classes.IO.PCK
|
|
{
|
|
|
|
public class InvalidAudioPckException : Exception
|
|
{
|
|
public InvalidAudioPckException(string message) : base(message)
|
|
{ }
|
|
}
|
|
|
|
internal class PCKAudioFileReader : StreamDataReader
|
|
{
|
|
private PCKAudioFile _file;
|
|
private List<string> LUT = new List<string>();
|
|
|
|
|
|
public static PCKAudioFile Read(Stream stream, bool isLittleEndian)
|
|
{
|
|
return new PCKAudioFileReader(isLittleEndian).ReadFromStream(stream);
|
|
}
|
|
|
|
private PCKAudioFileReader(bool isLittleEndian) : base(isLittleEndian)
|
|
{
|
|
}
|
|
|
|
private PCKAudioFile ReadFromStream(Stream stream)
|
|
{
|
|
int pck_type = ReadInt(stream);
|
|
if (pck_type > 0xf00000) // 03 00 00 00 == true
|
|
throw new OverflowException(nameof(pck_type));
|
|
if (pck_type > 1)
|
|
throw new InvalidAudioPckException(nameof(pck_type));
|
|
_file = new PCKAudioFile();
|
|
ReadLookUpTabel(stream);
|
|
ReadCategories(stream);
|
|
ReadCategorySongs(stream);
|
|
return _file;
|
|
}
|
|
|
|
private void ReadLookUpTabel(Stream stream)
|
|
{
|
|
int count = ReadInt(stream);
|
|
LUT = new List<string>(count);
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
int index = ReadInt(stream);
|
|
LUT.Insert(index, ReadString(stream));
|
|
}
|
|
}
|
|
|
|
private void ReadCategories(Stream stream)
|
|
{
|
|
int categoryEntryCount = ReadInt(stream);
|
|
for (; 0 < categoryEntryCount; categoryEntryCount--)
|
|
{
|
|
var parameterType = (PCKAudioFile.AudioCategory.EAudioParameterType)ReadInt(stream);
|
|
var audioType = (PCKAudioFile.AudioCategory.EAudioType)ReadInt(stream);
|
|
string name = ReadString(stream);
|
|
_file.AddCategory(parameterType, audioType, name);
|
|
}
|
|
}
|
|
|
|
private void ReadCategorySongs(Stream stream)
|
|
{
|
|
List<string> credits = new List<string>();
|
|
List<string> creditIds = new List<string>();
|
|
foreach (var c in _file.Categories)
|
|
{
|
|
int audioCount = ReadInt(stream);
|
|
for (; 0 < audioCount; audioCount--)
|
|
{
|
|
string key = LUT[ReadInt(stream)];
|
|
string value = ReadString(stream);
|
|
switch (key)
|
|
{
|
|
case "CUENAME":
|
|
c.SongNames.Add(value);
|
|
break;
|
|
case "CREDIT":
|
|
credits.Add(value);
|
|
break;
|
|
case "CREDITID":
|
|
creditIds.Add(value);
|
|
_file.AddCreditId(value);
|
|
break;
|
|
default:
|
|
throw new InvalidDataException(nameof(key));
|
|
}
|
|
}
|
|
};
|
|
foreach (var credit in credits.Zip(creditIds, (str, id) => (str, id)))
|
|
{
|
|
_file.SetCredit(credit.id, credit.str);
|
|
}
|
|
}
|
|
|
|
private string ReadString(Stream stream)
|
|
{
|
|
int len = ReadInt(stream);
|
|
string s = ReadString(stream, len, IsUsingLittleEndian ? Encoding.Unicode : Encoding.BigEndianUnicode);
|
|
ReadInt(stream); // padding
|
|
return s;
|
|
}
|
|
}
|
|
}
|