Compare commits
8 Commits
Developmen
...
master
Author | SHA1 | Date |
---|---|---|
yangzhi | 66e3d8b478 | |
yangzhi | 10f609ea4b | |
JoshuaNavarro | 5ded80f371 | |
JoshuaNavarro | ff612c1bb0 | |
Joshua Navarro | 81c0078b78 | |
Joshua Navarro | 82499561b9 | |
Joshua Navarro | 79c2965ae6 | |
Joshua Navarro | 18ad59258c |
|
@ -2,6 +2,7 @@ using System;
|
|||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Omegasis.SaveBackup.Framework;
|
||||
using StardewModdingAPI;
|
||||
using StardewModdingAPI.Events;
|
||||
|
@ -15,16 +16,16 @@ namespace Omegasis.SaveBackup
|
|||
** Fields
|
||||
*********/
|
||||
/// <summary>The folder path containing the game's app data.</summary>
|
||||
private static readonly string AppDataPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "StardewValley");
|
||||
private static string AppDataPath => Constants.TargetPlatform != GamePlatform.Android ? Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "StardewValley") : Constants.DataPath;
|
||||
|
||||
/// <summary>The folder path containing the game's saves.</summary>
|
||||
private static readonly string SavesPath = Path.Combine(SaveBackup.AppDataPath, "Saves");
|
||||
private static string SavesPath => Constants.TargetPlatform != GamePlatform.Android ? Path.Combine(SaveBackup.AppDataPath, "Saves") : Constants.CurrentSavePath;
|
||||
|
||||
/// <summary>The folder path containing backups of the save before the player starts playing.</summary>
|
||||
private static readonly string PrePlayBackupsPath = Path.Combine(SaveBackup.AppDataPath, "Backed_Up_Saves", "Pre_Play_Saves");
|
||||
|
||||
/// <summary>The folder path containing nightly backups of the save.</summary>
|
||||
private static readonly string NightlyBackupsPath = Path.Combine(SaveBackup.AppDataPath, "Backed_Up_Saves", "Nightly_InGame_Saves");
|
||||
private static string NightlyBackupsPath => Constants.TargetPlatform != GamePlatform.Android ? Path.Combine(SaveBackup.AppDataPath, "Backed_Up_Saves", "Nightly_InGame_Saves") : Path.Combine(SaveBackup.AppDataPath, "Backed_Up_Saves", Constants.SaveFolderName, "Nightly_InGame_Saves");
|
||||
|
||||
/// <summary>The mod configuration.</summary>
|
||||
private ModConfig Config;
|
||||
|
@ -39,7 +40,8 @@ namespace Omegasis.SaveBackup
|
|||
{
|
||||
this.Config = helper.ReadConfig<ModConfig>();
|
||||
|
||||
this.BackupSaves(SaveBackup.PrePlayBackupsPath);
|
||||
if(Constants.TargetPlatform != GamePlatform.Android)
|
||||
this.BackupSaves(SaveBackup.PrePlayBackupsPath);
|
||||
|
||||
helper.Events.GameLoop.Saving += this.OnSaving;
|
||||
}
|
||||
|
@ -56,21 +58,108 @@ namespace Omegasis.SaveBackup
|
|||
this.BackupSaves(SaveBackup.NightlyBackupsPath);
|
||||
}
|
||||
|
||||
/// <summary>Recursively copy a directory or file.</summary>
|
||||
/// <param name="source">The file or folder to copy.</param>
|
||||
/// <param name="targetFolder">The folder to copy into.</param>
|
||||
/// <param name="copyRoot">Whether to copy the root folder itself, or <c>false</c> to only copy its contents.</param>
|
||||
/// <param name="filter">A filter which matches the files or directories to copy, or <c>null</c> to copy everything.</param>
|
||||
/// <remarks>Derived from the SMAPI installer code.</remarks>
|
||||
/// <returns>Returns whether any files were copied.</returns>
|
||||
private bool RecursiveCopy(FileSystemInfo source, DirectoryInfo targetFolder, bool copyRoot = true)
|
||||
{
|
||||
if (!source.Exists)
|
||||
return false;
|
||||
|
||||
bool anyCopied = false;
|
||||
|
||||
switch (source)
|
||||
{
|
||||
case FileInfo sourceFile:
|
||||
targetFolder.Create();
|
||||
sourceFile.CopyTo(Path.Combine(targetFolder.FullName, sourceFile.Name));
|
||||
anyCopied = true;
|
||||
break;
|
||||
|
||||
case DirectoryInfo sourceDir:
|
||||
DirectoryInfo targetSubfolder = copyRoot ? new DirectoryInfo(Path.Combine(targetFolder.FullName, sourceDir.Name)) : targetFolder;
|
||||
foreach (var entry in sourceDir.EnumerateFileSystemInfos())
|
||||
anyCopied = this.RecursiveCopy(entry, targetSubfolder) || anyCopied;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new NotSupportedException($"Unknown filesystem info type '{source.GetType().FullName}'.");
|
||||
}
|
||||
|
||||
return anyCopied;
|
||||
}
|
||||
|
||||
/// <summary>Create a zip using the .NET compression library.</summary>
|
||||
/// <param name="sourcePath">The file or directory path to zip.</param>
|
||||
/// <param name="destination">The destination file to create.</param>
|
||||
/// <exception cref="NotSupportedException">The compression libraries aren't available on this system.</exception>
|
||||
private void CompressUsingNetFramework(string sourcePath, FileInfo destination)
|
||||
{
|
||||
// get compress method
|
||||
MethodInfo createFromDirectory;
|
||||
try
|
||||
{
|
||||
// create compressed backup
|
||||
Assembly coreAssembly = Assembly.Load("System.IO.Compression, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089") ?? throw new InvalidOperationException("Can't load System.IO.Compression assembly.");
|
||||
Assembly fsAssembly = Assembly.Load("System.IO.Compression.FileSystem, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089") ?? throw new InvalidOperationException("Can't load System.IO.Compression assembly.");
|
||||
Type compressionLevelType = coreAssembly.GetType("System.IO.Compression.CompressionLevel") ?? throw new InvalidOperationException("Can't load CompressionLevel type.");
|
||||
Type zipFileType = fsAssembly.GetType("System.IO.Compression.ZipFile") ?? throw new InvalidOperationException("Can't load ZipFile type.");
|
||||
createFromDirectory = zipFileType.GetMethod("CreateFromDirectory", new[] { typeof(string), typeof(string), compressionLevelType, typeof(bool) }) ?? throw new InvalidOperationException("Can't load ZipFile.CreateFromDirectory method.");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new NotSupportedException("Couldn't load the .NET compression libraries on this system.", ex);
|
||||
}
|
||||
|
||||
// compress file
|
||||
createFromDirectory.Invoke(null, new object[] { sourcePath, destination.FullName, CompressionLevel.Fastest, false });
|
||||
}
|
||||
|
||||
private void OriginCompressLogic(string folderPath)
|
||||
{
|
||||
ZipFile.CreateFromDirectory(SaveBackup.SavesPath, Path.Combine(folderPath, $"backup-{DateTime.Now:yyyyMMdd'-'HHmmss}.zip"));
|
||||
}
|
||||
|
||||
/// <summary>Back up saves to the specified folder.</summary>
|
||||
/// <param name="folderPath">The folder path in which to generate saves.</param>
|
||||
private void BackupSaves(string folderPath)
|
||||
{
|
||||
// back up saves
|
||||
Directory.CreateDirectory(folderPath);
|
||||
ZipFile.CreateFromDirectory(SaveBackup.SavesPath, Path.Combine(folderPath, $"backup-{DateTime.Now:yyyyMMdd'-'HHmmss}.zip"));
|
||||
if(Constants.TargetPlatform == GamePlatform.Android)
|
||||
{
|
||||
FileInfo targetFile = new FileInfo(Path.Combine(folderPath, $"backup-{DateTime.Now:yyyyMMdd'-'HHmmss}.zip"));
|
||||
try
|
||||
{
|
||||
this.CompressUsingNetFramework(folderPath, targetFile);
|
||||
}
|
||||
catch (NotSupportedException)
|
||||
{
|
||||
this.RecursiveCopy(new DirectoryInfo(SaveBackup.SavesPath), new DirectoryInfo(Path.Combine(folderPath, $"backup-{DateTime.Now:yyyyMMdd'-'HHmmss}")), false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this.OriginCompressLogic(folderPath);
|
||||
}
|
||||
|
||||
// delete old backups
|
||||
new DirectoryInfo(folderPath)
|
||||
.EnumerateFiles()
|
||||
.GetFileSystemInfos()
|
||||
.OrderByDescending(f => f.CreationTime)
|
||||
.Skip(this.Config.SaveCount)
|
||||
.ToList()
|
||||
.ForEach(file => file.Delete());
|
||||
.ForEach(file =>
|
||||
{
|
||||
if (file is DirectoryInfo folder)
|
||||
folder.Delete(recursive: true);
|
||||
else
|
||||
file.Delete();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace SimpleSoundManager.Framework.Music
|
||||
{
|
||||
/// <summary>
|
||||
/// Config class for the mod.
|
||||
/// </summary>
|
||||
public class Config
|
||||
{
|
||||
public bool EnableDebugLog;
|
||||
|
||||
/// <summary>
|
||||
/// Constructor.
|
||||
/// </summary>
|
||||
public Config()
|
||||
{
|
||||
EnableDebugLog = false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,111 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Timers;
|
||||
using Microsoft.Xna.Framework.Audio;
|
||||
using StardewValley;
|
||||
|
||||
namespace SimpleSoundManager.Framework
|
||||
{
|
||||
/// <summary>Manages all music for the mod.</summary>
|
||||
public class MusicManager
|
||||
{
|
||||
/*********
|
||||
** Fields
|
||||
*********/
|
||||
/// <summary>The RNG used to select music packs and songs.</summary>
|
||||
private readonly Random Random = new Random();
|
||||
|
||||
/// <summary>The delay timer between songs.</summary>
|
||||
private readonly Timer Timer = new Timer();
|
||||
|
||||
|
||||
/*********
|
||||
** Accessors
|
||||
*********/
|
||||
/// <summary>The loaded music packs.</summary>
|
||||
public IDictionary<string, MusicPack> MusicPacks { get; } = new Dictionary<string, MusicPack>();
|
||||
|
||||
|
||||
/*********
|
||||
** Public methods
|
||||
*********/
|
||||
/// <summary>Construct an instance.</summary>
|
||||
public MusicManager()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>Adds a valid xwb music pack to the list of music packs available.</summary>
|
||||
/// <param name="musicPack">The music pack to add.</param>
|
||||
/// <param name="displayLogInformation">Whether or not to display the process to the console. Will include information from the pack's metadata. Default:False</param>
|
||||
/// <param name="displaySongs">If displayLogInformation is also true this will display the name of all of the songs in the music pack when it is added in.</param>
|
||||
public void addMusicPack(MusicPack musicPack, bool displayLogInformation = false, bool displaySongs = false)
|
||||
{
|
||||
if (displayLogInformation)
|
||||
{
|
||||
if (ModCore.Config.EnableDebugLog)
|
||||
{
|
||||
ModCore.ModMonitor.Log("Adding music pack:");
|
||||
ModCore.ModMonitor.Log($" Name: {musicPack.Name}");
|
||||
ModCore.ModMonitor.Log($" Author: {musicPack.Manifest.Author}");
|
||||
ModCore.ModMonitor.Log($" Description: {musicPack.Manifest.Description}");
|
||||
ModCore.ModMonitor.Log($" Version Info: {musicPack.Manifest.Version}");
|
||||
}
|
||||
if (displaySongs && ModCore.Config.EnableDebugLog)
|
||||
{
|
||||
ModCore.ModMonitor.Log(" Song List:");
|
||||
foreach (string songName in musicPack.Sounds.Keys)
|
||||
ModCore.ModMonitor.Log($" {songName}");
|
||||
}
|
||||
}
|
||||
|
||||
this.MusicPacks.Add(musicPack.Name, musicPack);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Plays the specified sound from the music pack.
|
||||
/// </summary>
|
||||
/// <param name="packName"></param>
|
||||
/// <param name="soundName"></param>
|
||||
public void playSound(string packName, string soundName)
|
||||
{
|
||||
if (this.MusicPacks.ContainsKey(packName))
|
||||
{
|
||||
this.MusicPacks[packName].PlaySound(soundName);
|
||||
}
|
||||
else
|
||||
{
|
||||
ModCore.DebugLog("No pack with specified key/name: " + packName);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stops a said sound from the music pack.
|
||||
/// </summary>
|
||||
/// <param name="packName"></param>
|
||||
/// <param name="soundName"></param>
|
||||
public void stopSound(string packName,string soundName)
|
||||
{
|
||||
if (this.MusicPacks.ContainsKey(packName))
|
||||
{
|
||||
this.MusicPacks[packName].StopSound();
|
||||
}
|
||||
else
|
||||
{
|
||||
ModCore.DebugLog("No pack with specified key/name: " + packName);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates all music packs every so often.
|
||||
/// </summary>
|
||||
public void update()
|
||||
{
|
||||
foreach(MusicPack pack in this.MusicPacks.Values)
|
||||
{
|
||||
pack.update();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,224 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Microsoft.Xna.Framework.Audio;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using NAudio.Vorbis;
|
||||
using NAudio.Wave;
|
||||
using StardewModdingAPI;
|
||||
using StardewValley;
|
||||
|
||||
namespace SimpleSoundManager.Framework
|
||||
{
|
||||
/// <summary>A content pack which can provide music and sounds.</summary>
|
||||
public class MusicPack
|
||||
{
|
||||
/*********
|
||||
** Fields
|
||||
*********/
|
||||
/// <summary>The name of the folder which contains the saved player settings.</summary>
|
||||
private readonly string DataFolderName = "data";
|
||||
|
||||
/// <summary>The name of the folder which contains available music.</summary>
|
||||
private readonly string MusicFolderName = "music";
|
||||
|
||||
|
||||
/*********
|
||||
** Accessors
|
||||
*********/
|
||||
/// <summary>The underlying content pack.</summary>
|
||||
public IContentPack ContentPack { get; }
|
||||
|
||||
/// <summary>The current song name being played, if any.</summary>
|
||||
public string lastPlayedSoundName { get; private set; }
|
||||
|
||||
/// <summary>The currently sound being played, if any.</summary>
|
||||
public SoundEffectInstance lastPlayedSound { get; private set; }
|
||||
|
||||
public Dictionary<string, List<SoundEffectInstance>> playingSounds;
|
||||
|
||||
/// <summary>The manifest info.</summary>
|
||||
public IManifest Manifest => this.ContentPack.Manifest;
|
||||
|
||||
/// <summary>The name of the music pack.</summary>
|
||||
public string Name => this.ContentPack.Manifest.Name;
|
||||
|
||||
/// <summary>The available sounds.</summary>
|
||||
public Dictionary<string, SoundEffectInstance> Sounds { get; } = new Dictionary<string, SoundEffectInstance>();
|
||||
|
||||
|
||||
/*********
|
||||
** Public methods
|
||||
*********/
|
||||
/// <summary>Construct an instance.</summary>
|
||||
/// <param name="contentPack">The underlying content pack.</param>
|
||||
public MusicPack(IContentPack contentPack)
|
||||
{
|
||||
this.ContentPack = contentPack;
|
||||
this.playingSounds = new Dictionary<string, List<SoundEffectInstance>>();
|
||||
this.LoadMusicFiles();
|
||||
}
|
||||
|
||||
/// <summary>Play a song.</summary>
|
||||
/// <param name="name">The song name to play.</param>
|
||||
public void PlaySound(string name)
|
||||
{
|
||||
// get sound
|
||||
if (!this.Sounds.TryGetValue(name, out SoundEffectInstance sound))
|
||||
{
|
||||
ModCore.ModMonitor.Log("An error occured where we can't find the song anymore. Weird. Please contact Omegasis with a SMAPI Log and describe when/how the event occured.");
|
||||
return;
|
||||
}
|
||||
|
||||
// play sound
|
||||
this.lastPlayedSoundName = name;
|
||||
this.lastPlayedSound = sound;
|
||||
this.lastPlayedSound.Play();
|
||||
|
||||
if (this.playingSounds.ContainsKey(name))
|
||||
{
|
||||
this.playingSounds[name].Add(sound);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.playingSounds.Add(name,new List<SoundEffectInstance>());
|
||||
this.playingSounds[name].Add(sound);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>Stop the currently playing song.</summary>
|
||||
public void StopSound()
|
||||
{
|
||||
this.lastPlayedSound?.Stop(true);
|
||||
this.lastPlayedSoundName = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stops all of the currently playing sounds.
|
||||
/// </summary>
|
||||
public void stopAllSounds()
|
||||
{
|
||||
foreach (string soundName in playingSounds.Keys)
|
||||
{
|
||||
for (int i = 0; i < playingSounds[soundName].Count; i++)
|
||||
{
|
||||
if (playingSounds[soundName][i].State == SoundState.Stopped)
|
||||
{
|
||||
playingSounds[soundName][i].Stop(true);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the music pack to clean up all sounds that have been stopped.
|
||||
/// </summary>
|
||||
public void update()
|
||||
{
|
||||
///Clean up the list.
|
||||
foreach(string soundName in playingSounds.Keys)
|
||||
{
|
||||
for(int i = 0; i < playingSounds[soundName].Count; i++)
|
||||
{
|
||||
if(playingSounds[soundName][i].State== SoundState.Stopped)
|
||||
{
|
||||
playingSounds[soundName].RemoveAt(i);
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Get whether the content pack is currently playing a sound.</summary>
|
||||
public bool IsPlaying()
|
||||
{
|
||||
return this.lastPlayedSound?.State == SoundState.Playing;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if there is a sound with said name playing.
|
||||
/// </summary>
|
||||
/// <param name="SoundName"></param>
|
||||
/// <returns></returns>
|
||||
public bool IsPlaying(string SoundName)
|
||||
{
|
||||
return this.playingSounds[SoundName].FindAll(s => s.State== SoundState.Playing).Count>0;
|
||||
}
|
||||
|
||||
/*********
|
||||
** Private methods
|
||||
*********/
|
||||
|
||||
/// <summary>Load in the music files from the pack's respective Directory/Songs folder. Typically Content/Music/Wav/FolderName/Songs</summary>
|
||||
private void LoadMusicFiles()
|
||||
{
|
||||
DateTime startTime = DateTime.Now;
|
||||
|
||||
DirectoryInfo songFolder = new DirectoryInfo(Path.Combine(this.ContentPack.DirectoryPath, this.MusicFolderName));
|
||||
foreach (FileInfo file in songFolder.GetFiles())
|
||||
{
|
||||
// get name
|
||||
string name = Path.GetFileNameWithoutExtension(file.Name);
|
||||
if (this.Sounds.ContainsKey(name))
|
||||
continue;
|
||||
|
||||
// load data
|
||||
SoundEffect effect = null;
|
||||
using (Stream waveFileStream = File.OpenRead(file.FullName))
|
||||
{
|
||||
switch (file.Extension)
|
||||
{
|
||||
case ".wav":
|
||||
effect = SoundEffect.FromStream(waveFileStream);
|
||||
break;
|
||||
|
||||
case ".mp3":
|
||||
using (Mp3FileReader reader = new Mp3FileReader(waveFileStream))
|
||||
using (WaveStream pcmStream = WaveFormatConversionStream.CreatePcmStream(reader))
|
||||
{
|
||||
string tempPath = Path.Combine(songFolder.FullName, $"{name}.wav");
|
||||
ModCore.ModMonitor.Log($"Converting: {tempPath}");
|
||||
|
||||
WaveFileWriter.CreateWaveFile(tempPath, pcmStream);
|
||||
using (Stream tempStream = File.OpenRead(tempPath))
|
||||
effect = SoundEffect.FromStream(tempStream);
|
||||
File.Delete(tempPath);
|
||||
}
|
||||
break;
|
||||
|
||||
case ".ogg":
|
||||
// Credits: https://social.msdn.microsoft.com/Forums/vstudio/en-US/100a97af-2a1c-4b28-b464-d43611b9b5d6/converting-multichannel-ogg-to-stereo-wav-file?forum=csharpgeneral
|
||||
using (VorbisWaveReader vorbisStream = new VorbisWaveReader(file.FullName))
|
||||
{
|
||||
string tempPath = Path.Combine(songFolder.FullName, $"{name}.wav");
|
||||
ModCore.DebugLog($"Converting: {tempPath}");
|
||||
|
||||
WaveFileWriter.CreateWaveFile(tempPath, vorbisStream.ToWaveProvider16());
|
||||
using (Stream tempStream = File.OpenRead(tempPath))
|
||||
effect = SoundEffect.FromStream(tempStream);
|
||||
File.Delete(tempPath);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
ModCore.ModMonitor.Log($"Unsupported file extension {file.Extension}.", LogLevel.Warn);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (effect == null)
|
||||
continue;
|
||||
|
||||
// add sound
|
||||
SoundEffectInstance instance = effect.CreateInstance();
|
||||
this.Sounds.Add(name, instance);
|
||||
}
|
||||
|
||||
// log loading time
|
||||
if (ModCore.Config.EnableDebugLog)
|
||||
ModCore.ModMonitor.Log($"Time to load WAV music pack {this.Name}: {startTime.Subtract(DateTime.Now)}");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace SimpleSoundManager.Framework
|
||||
{
|
||||
/// <summary>A class that keeps track of the trigger and the list of songs associated with that trigger.</summary>
|
||||
internal class SongListNode
|
||||
{
|
||||
/*********
|
||||
** Accessors
|
||||
*********/
|
||||
/// <summary>The trigger name for the list of songs.</summary>
|
||||
public string Trigger { get; }
|
||||
|
||||
/// <summary>The list of songs associated with a trigger.</summary>
|
||||
public string[] SongList { get; }
|
||||
|
||||
|
||||
/*********
|
||||
** Public methods
|
||||
*********/
|
||||
/// <summary>Construct an instance.</summary>
|
||||
/// <param name="trigger">The trigger name for the list of songs.</param>
|
||||
/// <param name="songList">The list of songs associated with a trigger.</param>
|
||||
public SongListNode(string trigger, IEnumerable<string> songList)
|
||||
{
|
||||
this.Trigger = trigger;
|
||||
this.SongList = songList.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
namespace SimpleSoundManager.Framework
|
||||
{
|
||||
/// <summary>Interface used for common sound functionality;</summary>
|
||||
public interface Sound
|
||||
{
|
||||
/// <summary>Handles playing a sound.</summary>
|
||||
void play();
|
||||
|
||||
void play(float volume);
|
||||
|
||||
/// <summary>Handles pausing a song.</summary>
|
||||
void pause();
|
||||
|
||||
/// <summary>Handles stopping a song.</summary>
|
||||
void stop();
|
||||
|
||||
/// <summary>Handles restarting a song.</summary>
|
||||
void restart();
|
||||
|
||||
/// <summary>Handles getting a clone of the song.</summary>
|
||||
Sound clone();
|
||||
|
||||
string getSoundName();
|
||||
|
||||
bool isStopped();
|
||||
}
|
||||
}
|
|
@ -1,202 +0,0 @@
|
|||
using System.Collections.Generic;
|
||||
using Microsoft.Xna.Framework.Audio;
|
||||
using StardewModdingAPI;
|
||||
using StardewValley;
|
||||
|
||||
namespace SimpleSoundManager.Framework
|
||||
{
|
||||
public class SoundManager
|
||||
{
|
||||
public Dictionary<string, Sound> sounds;
|
||||
public Dictionary<string, XACTMusicPair> musicBanks;
|
||||
|
||||
public float volume;
|
||||
|
||||
public List<Sound> currentlyPlayingSounds = new List<Sound>();
|
||||
|
||||
/// <summary>Constructor for this class.</summary>
|
||||
public SoundManager()
|
||||
{
|
||||
this.sounds = new Dictionary<string, Sound>();
|
||||
this.musicBanks = new Dictionary<string, XACTMusicPair>();
|
||||
this.currentlyPlayingSounds = new List<Sound>();
|
||||
this.volume = 1.0f;
|
||||
}
|
||||
|
||||
/// <summary>Constructor for wav files.</summary>
|
||||
public void loadWavFile(string soundName, string pathToWav)
|
||||
{
|
||||
WavSound wav = new WavSound(soundName, pathToWav);
|
||||
SimpleSoundManagerMod.ModMonitor.Log("Getting sound file:" + soundName);
|
||||
try
|
||||
{
|
||||
this.sounds.Add(soundName, wav);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
/// <summary>Constructor for wav files.</summary>
|
||||
public void loadWavFile(IModHelper helper, string soundName, string relativePath)
|
||||
{
|
||||
WavSound wav = new WavSound(helper, soundName, relativePath);
|
||||
SimpleSoundManagerMod.ModMonitor.Log("Getting sound file:" + soundName);
|
||||
try
|
||||
{
|
||||
this.sounds.Add(soundName, wav);
|
||||
}
|
||||
catch
|
||||
{
|
||||
//Sound already added so no need to worry?
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Constructor for wav files.</summary>
|
||||
public void loadWavFile(IModHelper helper, string songName, List<string> pathToWav)
|
||||
{
|
||||
WavSound wav = new WavSound(helper, songName, pathToWav);
|
||||
SimpleSoundManagerMod.ModMonitor.Log("Getting sound file:" + songName);
|
||||
try
|
||||
{
|
||||
this.sounds.Add(songName, wav);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
/// <summary>Constructor for XACT files.</summary>
|
||||
public void loadXACTFile(WaveBank waveBank, ISoundBank soundBank, string songName)
|
||||
{
|
||||
XACTSound xactSound = new XACTSound(waveBank, soundBank, songName);
|
||||
this.sounds.Add(songName, xactSound);
|
||||
}
|
||||
|
||||
/// <summary>Constructor for XACT files based on already added music packs.</summary>
|
||||
public void loadXACTFile(string pairName, string songName)
|
||||
{
|
||||
XACTMusicPair musicPair = this.getMusicPack(pairName);
|
||||
if (pairName == null)
|
||||
return;
|
||||
this.loadXACTFile(musicPair.waveBank, musicPair.soundBank, songName);
|
||||
}
|
||||
|
||||
/// <summary>Creates a music pack pair that holds .xwb and .xsb music files.</summary>
|
||||
/// <param name="helper">The mod's helper that will handle the path of the files.</param>
|
||||
/// <param name="pairName">The name of this music pack pair.</param>
|
||||
/// <param name="wavName">The relative path to the .xwb file</param>
|
||||
/// <param name="soundName">The relative path to the .xsb file</param>
|
||||
public void loadXACTMusicBank(IModHelper helper, string pairName, string wavName, string soundName)
|
||||
{
|
||||
this.musicBanks.Add(pairName, new XACTMusicPair(helper, wavName, soundName));
|
||||
}
|
||||
|
||||
/// <summary>Gets the music pack pair from the sound pool.</summary>
|
||||
public XACTMusicPair getMusicPack(string name)
|
||||
{
|
||||
foreach (var pack in this.musicBanks)
|
||||
{
|
||||
if (name == pack.Key)
|
||||
return pack.Value;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>Gets a clone of the loaded sound.</summary>
|
||||
public Sound getSoundClone(string name)
|
||||
{
|
||||
foreach (var sound in this.sounds)
|
||||
{
|
||||
if (sound.Key == name)
|
||||
return sound.Value.clone();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>Play the sound with the given name.</summary>
|
||||
public void playSound(string soundName)
|
||||
{
|
||||
SimpleSoundManagerMod.ModMonitor.Log("Trying to play sound: " + soundName);
|
||||
foreach (var sound in this.sounds)
|
||||
{
|
||||
if (sound.Key == soundName)
|
||||
{
|
||||
SimpleSoundManagerMod.ModMonitor.Log("Time to play sound: " + soundName);
|
||||
var s = this.getSoundClone(soundName);
|
||||
s.play(this.volume);
|
||||
this.currentlyPlayingSounds.Add(s);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Play the sound with the given name and volume.</summary>
|
||||
public void playSound(string soundName, float volume = 1.0f)
|
||||
{
|
||||
SimpleSoundManagerMod.ModMonitor.Log("Trying to play sound: " + soundName);
|
||||
foreach (var sound in this.sounds)
|
||||
{
|
||||
if (sound.Key == soundName)
|
||||
{
|
||||
SimpleSoundManagerMod.ModMonitor.Log("Time to play sound: " + soundName);
|
||||
var s = this.getSoundClone(soundName);
|
||||
s.play(volume);
|
||||
this.currentlyPlayingSounds.Add(s);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Stop the sound that is playing.</summary>
|
||||
public void stopSound(string soundName)
|
||||
{
|
||||
List<Sound> removalList = new List<Sound>();
|
||||
foreach (var sound in this.currentlyPlayingSounds)
|
||||
{
|
||||
if (sound.getSoundName() == soundName)
|
||||
{
|
||||
sound.stop();
|
||||
removalList.Add(sound);
|
||||
}
|
||||
}
|
||||
foreach (var v in removalList)
|
||||
this.currentlyPlayingSounds.Remove(v);
|
||||
}
|
||||
|
||||
/// <summary>Pause the sound with this name?</summary>
|
||||
public void pauseSound(string soundName)
|
||||
{
|
||||
List<Sound> removalList = new List<Sound>();
|
||||
foreach (var sound in this.currentlyPlayingSounds)
|
||||
{
|
||||
if (sound.getSoundName() == soundName)
|
||||
{
|
||||
sound.pause();
|
||||
removalList.Add(sound);
|
||||
}
|
||||
}
|
||||
foreach (var v in removalList)
|
||||
this.currentlyPlayingSounds.Remove(v);
|
||||
}
|
||||
|
||||
public void swapSounds(string newSong)
|
||||
{
|
||||
this.playSound(newSong);
|
||||
}
|
||||
|
||||
public void update()
|
||||
{
|
||||
List<Sound> removalList = new List<Sound>();
|
||||
foreach (Sound song in this.currentlyPlayingSounds)
|
||||
{
|
||||
if (song.isStopped())
|
||||
removalList.Add(song);
|
||||
}
|
||||
foreach (var v in removalList)
|
||||
this.currentlyPlayingSounds.Remove(v);
|
||||
}
|
||||
|
||||
public void stopAllSounds()
|
||||
{
|
||||
foreach (var v in this.currentlyPlayingSounds)
|
||||
v.stop();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,211 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Microsoft.Xna.Framework.Audio;
|
||||
using SimpleSoundManager.Framework;
|
||||
using StardewModdingAPI;
|
||||
|
||||
namespace SimpleSoundManager
|
||||
{
|
||||
class WavSound : Sound
|
||||
{
|
||||
|
||||
/// <summary>Used to actually play the song.</summary>
|
||||
DynamicSoundEffectInstance dynamicSound;
|
||||
|
||||
/// <summary>Used to keep track of where in the song we are.</summary>
|
||||
int position;
|
||||
|
||||
int count;
|
||||
|
||||
/// <summary>Used to store the info for the song.</summary>
|
||||
byte[] byteArray;
|
||||
|
||||
public string path;
|
||||
|
||||
public string soundName;
|
||||
|
||||
public bool loop;
|
||||
|
||||
/// <summary>Get a raw disk path to the wav file.</summary>
|
||||
public WavSound(string name, string pathToWavFile, bool loop = false)
|
||||
{
|
||||
this.path = pathToWavFile;
|
||||
this.LoadWavFromFileToStream();
|
||||
this.soundName = name;
|
||||
this.loop = loop;
|
||||
}
|
||||
|
||||
/// <summary>A constructor that takes a mod helper and a relative path to a wav file.</summary>
|
||||
public WavSound(IModHelper modHelper, string name, string relativePath, bool loop = false)
|
||||
{
|
||||
string path = Path.Combine(modHelper.DirectoryPath, relativePath);
|
||||
this.path = path;
|
||||
this.soundName = name;
|
||||
this.loop = loop;
|
||||
}
|
||||
|
||||
/// <summary>Constructor that is more flexible than typing an absolute path.</summary>
|
||||
/// <param name="modHelper">The mod helper for the mod you wish to use to load the music files from.</param>
|
||||
/// <param name="pathPieces">The list of folders and files that make up a complete path.</param>
|
||||
public WavSound(IModHelper modHelper, string soundName, List<string> pathPieces, bool loop = false)
|
||||
{
|
||||
string dirPath = modHelper.DirectoryPath;
|
||||
foreach (string str in pathPieces)
|
||||
dirPath = Path.Combine(dirPath, str);
|
||||
this.path = dirPath;
|
||||
this.soundName = soundName;
|
||||
this.loop = loop;
|
||||
}
|
||||
|
||||
/// <summary>Loads the .wav file from disk and plays it.</summary>
|
||||
public void LoadWavFromFileToStream()
|
||||
{
|
||||
// Create a new SpriteBatch, which can be used to draw textures.
|
||||
|
||||
string file = this.path;
|
||||
Stream waveFileStream = File.OpenRead(file); //TitleContainer.OpenStream(file);
|
||||
|
||||
BinaryReader reader = new BinaryReader(waveFileStream);
|
||||
|
||||
int chunkID = reader.ReadInt32();
|
||||
int fileSize = reader.ReadInt32();
|
||||
int riffType = reader.ReadInt32();
|
||||
int fmtID = reader.ReadInt32();
|
||||
int fmtSize = reader.ReadInt32();
|
||||
int fmtCode = reader.ReadInt16();
|
||||
int channels = reader.ReadInt16();
|
||||
int sampleRate = reader.ReadInt32();
|
||||
int fmtAvgBPS = reader.ReadInt32();
|
||||
int fmtBlockAlign = reader.ReadInt16();
|
||||
int bitDepth = reader.ReadInt16();
|
||||
|
||||
if (fmtSize == 18)
|
||||
{
|
||||
// Read any extra values
|
||||
int fmtExtraSize = reader.ReadInt16();
|
||||
reader.ReadBytes(fmtExtraSize);
|
||||
}
|
||||
|
||||
int dataID = reader.ReadInt32();
|
||||
int dataSize = reader.ReadInt32();
|
||||
|
||||
this.byteArray = reader.ReadBytes(dataSize);
|
||||
|
||||
|
||||
this.dynamicSound = new DynamicSoundEffectInstance(sampleRate, (AudioChannels)channels);
|
||||
this.count = this.byteArray.Length;//dynamicSound.GetSampleSizeInBytes(TimeSpan.FromMilliseconds(1000));
|
||||
|
||||
this.dynamicSound.BufferNeeded += this.DynamicSound_BufferNeeded;
|
||||
}
|
||||
|
||||
void DynamicSound_BufferNeeded(object sender, EventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
this.dynamicSound.SubmitBuffer(this.byteArray, this.position, this.count);
|
||||
}
|
||||
catch { }
|
||||
|
||||
this.position += this.count;
|
||||
if (this.position + this.count > this.byteArray.Length)
|
||||
{
|
||||
|
||||
if (this.loop)
|
||||
this.position = 0;
|
||||
//else
|
||||
// this.stop();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Used to pause the current song.</summary>
|
||||
public void pause()
|
||||
{
|
||||
this.dynamicSound?.Pause();
|
||||
}
|
||||
|
||||
/// <summary>Used to play a song.</summary>
|
||||
public void play()
|
||||
{
|
||||
if (this.isPlaying())
|
||||
return;
|
||||
|
||||
this.LoadWavFromFileToStream();
|
||||
this.dynamicSound.Play();
|
||||
}
|
||||
|
||||
/// <summary>Used to play a song.</summary>
|
||||
/// <param name="volume">How lound the sound is when playing. 0~1.0f</param>
|
||||
public void play(float volume)
|
||||
{
|
||||
if (this.isPlaying())
|
||||
return;
|
||||
|
||||
this.LoadWavFromFileToStream();
|
||||
this.dynamicSound.Volume = volume;
|
||||
this.dynamicSound.Play();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>Used to resume the currently playing song.</summary>
|
||||
public void resume()
|
||||
{
|
||||
this.dynamicSound?.Resume();
|
||||
}
|
||||
|
||||
/// <summary>Used to stop the currently playing song.</summary>
|
||||
public void stop()
|
||||
{
|
||||
if (this.dynamicSound != null)
|
||||
{
|
||||
this.dynamicSound.Stop(true);
|
||||
this.dynamicSound.BufferNeeded -= this.DynamicSound_BufferNeeded;
|
||||
this.position = 0;
|
||||
this.count = 0;
|
||||
this.byteArray = new byte[0];
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Used to change from one playing song to another;</summary>
|
||||
public void swap(string pathToNewWavFile)
|
||||
{
|
||||
this.stop();
|
||||
this.path = pathToNewWavFile;
|
||||
this.play();
|
||||
}
|
||||
|
||||
/// <summary>Checks if the song is currently playing.</summary>
|
||||
public bool isPlaying()
|
||||
{
|
||||
return this.dynamicSound?.State == SoundState.Playing;
|
||||
}
|
||||
|
||||
/// <summary>Checks if the song is currently paused.</summary>
|
||||
public bool isPaused()
|
||||
{
|
||||
return this.dynamicSound?.State == SoundState.Paused;
|
||||
}
|
||||
|
||||
/// <summary>Checks if the song is currently stopped.</summary>
|
||||
public bool isStopped()
|
||||
{
|
||||
return this.dynamicSound?.State == SoundState.Stopped;
|
||||
}
|
||||
|
||||
public Sound clone()
|
||||
{
|
||||
return new WavSound(this.getSoundName(), this.path);
|
||||
}
|
||||
|
||||
public string getSoundName()
|
||||
{
|
||||
return this.soundName;
|
||||
}
|
||||
|
||||
public void restart()
|
||||
{
|
||||
this.stop();
|
||||
this.play();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,118 +0,0 @@
|
|||
using Microsoft.Xna.Framework.Audio;
|
||||
using StardewValley;
|
||||
|
||||
namespace SimpleSoundManager.Framework
|
||||
{
|
||||
public class XACTSound : Sound
|
||||
{
|
||||
public WaveBank waveBank;
|
||||
public ISoundBank soundBank;
|
||||
public string soundName;
|
||||
readonly WaveBank vanillaWaveBank;
|
||||
readonly ISoundBank vanillaSoundBank;
|
||||
readonly Cue song;
|
||||
|
||||
/// <summary>Make a new Sound Manager to play and manage sounds in a modded wave bank.</summary>
|
||||
/// <param name="newWaveBank">The reference to the wave bank in the mod's asset folder.</param>
|
||||
/// <param name="newSoundBank">The reference to the sound bank in the mod's asset folder.</param>
|
||||
public XACTSound(WaveBank newWaveBank, ISoundBank newSoundBank, string soundName)
|
||||
{
|
||||
this.waveBank = newWaveBank;
|
||||
this.soundBank = newSoundBank;
|
||||
|
||||
this.vanillaSoundBank = Game1.soundBank;
|
||||
this.vanillaWaveBank = Game1.waveBank;
|
||||
this.soundName = soundName;
|
||||
this.song = this.soundBank.GetCue(this.soundName);
|
||||
}
|
||||
|
||||
/// <summary>Play a sound from the mod's wave bank.</summary>
|
||||
/// <param name="soundName">The name of the sound in the mod's wave bank. This will fail if the sound doesn't exists. This is also case sensitive.</param>
|
||||
public void play(string soundName)
|
||||
{
|
||||
Game1.waveBank = this.waveBank;
|
||||
Game1.soundBank = this.soundBank;
|
||||
|
||||
if (this.song == null) return;
|
||||
|
||||
this.song.Play();
|
||||
|
||||
Game1.waveBank = this.vanillaWaveBank;
|
||||
Game1.soundBank = this.vanillaSoundBank;
|
||||
}
|
||||
|
||||
/// <summary>Pauses the first instance of this sound.</summary>
|
||||
/// <param name="soundName"></param>
|
||||
public void pause(string soundName)
|
||||
{
|
||||
this.song?.Pause();
|
||||
}
|
||||
|
||||
/// <summary>Resume the first instance of the sound that has this name.</summary>
|
||||
public void resume(string soundName)
|
||||
{
|
||||
this.song?.Resume();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>Stop the first instance of the sound that has this name.</summary>
|
||||
/// <param name="soundName"></param>
|
||||
public void stop(string soundName)
|
||||
{
|
||||
this.song?.Stop(AudioStopOptions.Immediate);
|
||||
}
|
||||
|
||||
/// <summary>Resumes a paused song.</summary>
|
||||
public void resume()
|
||||
{
|
||||
this.resume(this.soundName);
|
||||
}
|
||||
|
||||
/// <summary>Plays this song.</summary>
|
||||
public void play()
|
||||
{
|
||||
this.play(this.soundName);
|
||||
}
|
||||
|
||||
/// <summary>Plays this song.</summary>
|
||||
public void play(float volume)
|
||||
{
|
||||
this.play(this.soundName);
|
||||
}
|
||||
|
||||
/// <summary>Pauses this song.</summary>
|
||||
public void pause()
|
||||
{
|
||||
this.pause(this.soundName);
|
||||
}
|
||||
|
||||
/// <summary>Stops this somg.</summary>
|
||||
public void stop()
|
||||
{
|
||||
this.stop(this.soundName);
|
||||
}
|
||||
|
||||
/// <summary>Restarts this song.</summary>
|
||||
public void restart()
|
||||
{
|
||||
this.stop();
|
||||
this.play();
|
||||
}
|
||||
|
||||
/// <summary>Gets a clone of this song.</summary>
|
||||
public Sound clone()
|
||||
{
|
||||
return new XACTSound(this.waveBank, this.soundBank, this.soundName);
|
||||
}
|
||||
|
||||
public string getSoundName()
|
||||
{
|
||||
return this.soundName;
|
||||
}
|
||||
|
||||
public bool isStopped()
|
||||
{
|
||||
return this.song == null || this.song.IsStopped;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
using System.IO;
|
||||
using Microsoft.Xna.Framework.Audio;
|
||||
using StardewModdingAPI;
|
||||
using StardewValley;
|
||||
|
||||
namespace SimpleSoundManager
|
||||
{
|
||||
public class XACTMusicPair
|
||||
{
|
||||
public WaveBank waveBank;
|
||||
public ISoundBank soundBank;
|
||||
|
||||
/// <summary>Create a xwb and xsb music pack pair.</summary>
|
||||
/// <param name="helper">The mod helper from the mod that will handle loading in the file.</param>
|
||||
/// <param name="wavBankPath">A relative path to the .xwb file in the mod helper's mod directory.</param>
|
||||
/// <param name="soundBankPath">A relative path to the .xsb file in the mod helper's mod directory.</param>
|
||||
public XACTMusicPair(IModHelper helper, string wavBankPath, string soundBankPath)
|
||||
{
|
||||
wavBankPath = Path.Combine(helper.DirectoryPath, wavBankPath);
|
||||
soundBankPath = Path.Combine(helper.DirectoryPath, soundBankPath);
|
||||
|
||||
this.waveBank = new WaveBank(Game1.audioEngine, wavBankPath);
|
||||
this.soundBank = new SoundBankWrapper(new SoundBank(Game1.audioEngine, soundBankPath));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
using SimpleSoundManager.Framework;
|
||||
using SimpleSoundManager.Framework.Music;
|
||||
using StardewModdingAPI;
|
||||
|
||||
namespace SimpleSoundManager
|
||||
{
|
||||
/// <summary>
|
||||
/// Mod core.
|
||||
///
|
||||
/// Needs testing.
|
||||
///
|
||||
/// Seems like the current structure will require both content packs and a programmed mod to request when to play specific sounds. Interesting.
|
||||
/// </summary>
|
||||
public class ModCore : Mod
|
||||
{
|
||||
internal static IModHelper ModHelper;
|
||||
internal static IMonitor ModMonitor;
|
||||
internal static Config Config;
|
||||
public static MusicManager MusicManager;
|
||||
|
||||
/// <summary>The mod entry point, called after the mod is first loaded.</summary>
|
||||
/// <param name="helper">Provides simplified APIs for writing mods.</param>
|
||||
public override void Entry(IModHelper helper)
|
||||
{
|
||||
ModHelper = helper;
|
||||
ModMonitor = this.Monitor;
|
||||
Config = helper.ReadConfig<Config>();
|
||||
this.loadContentPacks();
|
||||
this.Helper.Events.GameLoop.OneSecondUpdateTicked += this.GameLoop_OneSecondUpdateTicked;
|
||||
|
||||
this.Helper.Events.GameLoop.SaveLoaded += this.GameLoop_SaveLoaded;
|
||||
}
|
||||
|
||||
private void GameLoop_SaveLoaded(object sender, StardewModdingAPI.Events.SaveLoadedEventArgs e)
|
||||
{
|
||||
|
||||
//MusicManager.MusicPacks["Your Project Name"].PlaySound("toby fox - UNDERTALE Soundtrack - 01 Once Upon a Time");
|
||||
//DebugLog("PLAY SOME SOUNDS");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update all music packs every second.
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void GameLoop_OneSecondUpdateTicked(object sender, StardewModdingAPI.Events.OneSecondUpdateTickedEventArgs e)
|
||||
{
|
||||
foreach(MusicPack pack in MusicManager.MusicPacks.Values)
|
||||
{
|
||||
pack.update();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads all content packs for SimpleSoundManager
|
||||
/// </summary>
|
||||
private void loadContentPacks()
|
||||
{
|
||||
MusicManager = new MusicManager();
|
||||
foreach (IContentPack contentPack in this.Helper.ContentPacks.GetOwned())
|
||||
{
|
||||
this.Monitor.Log($"Reading content pack: {contentPack.Manifest.Name} {contentPack.Manifest.Version} from {contentPack.DirectoryPath}");
|
||||
MusicPack musicPack = new MusicPack(contentPack);
|
||||
MusicManager.addMusicPack(musicPack, true, true);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Easy way to display debug logs when allowing for a check to see if they are enabled.
|
||||
/// </summary>
|
||||
/// <param name="s">The message to display.</param>
|
||||
public static void DebugLog(string s)
|
||||
{
|
||||
if (Config.EnableDebugLog)
|
||||
ModMonitor.Log(s);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -66,6 +66,12 @@
|
|||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="NAudio">
|
||||
<Version>1.8.5</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="NAudio.Vorbis">
|
||||
<Version>1.0.0</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Pathoschild.Stardew.ModBuildConfig" Version="2.2.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -73,12 +79,11 @@
|
|||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Framework\Sound.cs" />
|
||||
<Compile Include="Framework\SoundManager.cs" />
|
||||
<Compile Include="Framework\WavSound.cs" />
|
||||
<Compile Include="Framework\XactMusicPair.cs" />
|
||||
<Compile Include="Framework\XACTSound.cs" />
|
||||
<Compile Include="SimpleSoundManagerMod.cs" />
|
||||
<Compile Include="Framework\Music\Config.cs" />
|
||||
<Compile Include="Framework\Music\MusicManager.cs" />
|
||||
<Compile Include="Framework\Music\MusicPack.cs" />
|
||||
<Compile Include="Framework\Music\SongListNode.cs" />
|
||||
<Compile Include="ModCore.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
using StardewModdingAPI;
|
||||
|
||||
namespace SimpleSoundManager
|
||||
{
|
||||
public class SimpleSoundManagerMod : Mod
|
||||
{
|
||||
internal static IModHelper ModHelper;
|
||||
internal static IMonitor ModMonitor;
|
||||
|
||||
/// <summary>The mod entry point, called after the mod is first loaded.</summary>
|
||||
/// <param name="helper">Provides simplified APIs for writing mods.</param>
|
||||
public override void Entry(IModHelper helper)
|
||||
{
|
||||
ModHelper = helper;
|
||||
ModMonitor = this.Monitor;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,216 +0,0 @@
|
|||
0000-54e0: ff 1b 62 00-00 ff ff 25-62 00 00 ff-ff 2e 62 00 ..b....% b.....b.
|
||||
0000-54f0: 00 ff ff 33-62 00 00 ff-ff 41 62 00-00 ff ff 64 ...3b... .Ab....d
|
||||
0000-5500: 6f 6f 72 43-6c 6f 73 65-00 61 72 63-68 61 65 6f oorClose .archaeo
|
||||
0000-5510: 00 61 78 65-00 62 6f 75-6c 64 65 72-43 72 61 63 .axe.bou lderCrac
|
||||
0000-5520: 6b 00 63 6f-69 6e 00 63-75 74 00 64-69 61 6c 6f k.coin.c ut.dialo
|
||||
0000-5530: 67 75 65 43-68 61 72 61-63 74 65 72-00 64 69 61 gueChara cter.dia
|
||||
0000-5540: 6c 6f 67 75-65 43 68 61-72 61 63 74-65 72 43 6c logueCha racterCl
|
||||
0000-5550: 6f 73 65 00-64 72 6f 70-49 74 65 6d-49 6e 57 61 ose.drop ItemInWa
|
||||
0000-5560: 74 65 72 00-67 68 6f 73-74 00 67 72-75 6e 74 00 ter.ghos t.grunt.
|
||||
0000-5570: 68 61 6d 6d-65 72 00 68-6f 65 48 69-74 00 6f 70 hammer.h oeHit.op
|
||||
0000-5580: 65 6e 42 6f-78 00 70 69-63 6b 55 70-49 74 65 6d enBox.pi ckUpItem
|
||||
0000-5590: 00 73 61 6e-64 79 53 74-65 70 00 73-65 65 64 73 .sandySt ep.seeds
|
||||
0000-55a0: 00 73 68 61-64 6f 77 70-65 65 70 00-73 68 69 6e .shadowp eep.shin
|
||||
0000-55b0: 79 34 00 73-6d 61 6c 6c-53 65 6c 65-63 74 00 74 y4.small Select.t
|
||||
0000-55c0: 68 72 6f 77-44 6f 77 6e-49 54 65 6d-00 67 72 61 hrowDown ITem.gra
|
||||
0000-55d0: 73 73 79 53-74 65 70 00-73 74 6f 6e-65 53 74 65 ssyStep. stoneSte
|
||||
0000-55e0: 70 00 74 68-75 64 53 74-65 70 00 65-61 74 00 66 p.thudSt ep.eat.f
|
||||
0000-55f0: 69 73 68 42-69 74 65 00-74 6f 6f 6c-53 77 61 70 ishBite. toolSwap
|
||||
0000-5600: 00 70 75 6c-6c 49 74 65-6d 46 72 6f-6d 57 61 74 .pullIte mFromWat
|
||||
0000-5610: 65 72 00 77-6f 6f 64 79-53 74 65 70-00 62 6f 62 er.woody Step.bob
|
||||
0000-5620: 00 64 77 6f-6f 70 00 65-78 70 6c 6f-73 69 6f 6e .dwoop.e xplosion
|
||||
0000-5630: 00 63 72 61-66 74 69 6e-67 00 64 65-74 65 63 74 .craftin g.detect
|
||||
0000-5640: 6f 72 00 66-75 72 6e 61-63 65 00 70-6f 77 65 72 or.furna ce.power
|
||||
0000-5650: 75 70 00 64-65 73 6f 6c-61 74 65 00-6a 61 75 6e up.desol ate.jaun
|
||||
0000-5660: 74 79 00 73-74 61 72 73-68 6f 6f 74-00 73 61 70 ty.stars hoot.sap
|
||||
0000-5670: 70 79 70 69-61 6e 6f 00-6d 75 73 69-63 62 6f 78 pypiano. musicbox
|
||||
0000-5680: 73 6f 6e 67-00 35 30 73-00 72 61 67-74 69 6d 65 song.50s .ragtime
|
||||
0000-5690: 00 73 61 64-70 69 61 6e-6f 00 66 75-73 65 00 65 .sadpian o.fuse.e
|
||||
0000-56a0: 63 68 6f 73-00 73 61 6d-70 72 61 63-74 69 63 65 chos.sam practice
|
||||
0000-56b0: 00 68 65 61-76 79 00 68-6f 6e 6b 79-74 6f 6e 6b .heavy.h onkytonk
|
||||
0000-56c0: 79 00 70 6f-70 70 79 00-73 68 69 6d-6d 65 72 69 y.poppy. shimmeri
|
||||
0000-56d0: 6e 67 62 61-73 74 69 6f-6e 00 61 65-72 6f 62 69 ngbastio n.aerobi
|
||||
0000-56e0: 63 73 00 68-69 74 45 6e-65 6d 79 00-73 6c 69 6d cs.hitEn emy.slim
|
||||
0000-56f0: 65 00 44 75-67 67 79 00-6d 6f 6e 65-79 00 74 6f e.Duggy. money.to
|
||||
0000-5700: 6f 6c 43 68-61 72 67 65-00 6f 77 00-64 65 61 74 olCharge .ow.deat
|
||||
0000-5710: 68 00 66 69-72 65 62 61-6c 6c 00 72-61 62 62 69 h.fireba ll.rabbi
|
||||
0000-5720: 74 00 77 6f-6f 64 79 48-69 74 00 62-72 65 61 74 t.woodyH it.breat
|
||||
0000-5730: 68 6f 75 74-00 62 72 65-61 74 68 69-6e 00 77 69 hout.bre athin.wi
|
||||
0000-5740: 6e 64 00 73-70 72 69 6e-67 74 6f 77-6e 00 77 61 nd.sprin gtown.wa
|
||||
0000-5750: 76 79 00 63-6c 75 62 6c-6f 6f 70 00-61 63 68 69 vy.clubl oop.achi
|
||||
0000-5760: 65 76 65 6d-65 6e 74 00-77 65 64 64-69 6e 67 00 evement. wedding.
|
||||
0000-5770: 66 6c 75 74-65 00 64 72-75 6d 6b 69-74 30 00 64 flute.dr umkit0.d
|
||||
0000-5780: 72 75 6d 6b-69 74 31 00-64 72 75 6d-6b 69 74 32 rumkit1. drumkit2
|
||||
0000-5790: 00 64 72 75-6d 6b 69 74-33 00 64 72-75 6d 6b 69 .drumkit 3.drumki
|
||||
0000-57a0: 74 34 00 64-72 75 6d 6b-69 74 35 00-64 72 75 6d t4.drumk it5.drum
|
||||
0000-57b0: 6b 69 74 36-00 70 68 6f-6e 65 00 74-68 75 6e 64 kit6.pho ne.thund
|
||||
0000-57c0: 65 72 00 72-61 69 6e 00-63 72 69 63-6b 65 74 73 er.rain. crickets
|
||||
0000-57d0: 00 77 61 6e-64 00 74 69-74 6c 65 5f-6e 69 67 68 .wand.ti tle_nigh
|
||||
0000-57e0: 74 00 71 75-65 73 74 63-6f 6d 70 6c-65 74 65 00 t.questc omplete.
|
||||
0000-57f0: 63 61 76 65-64 72 69 70-00 6f 62 6a-65 63 74 69 cavedrip .objecti
|
||||
0000-5800: 76 65 43 6f-6d 70 6c 65-74 65 00 62-61 63 6b 70 veComple te.backp
|
||||
0000-5810: 61 63 6b 49-4e 00 43 72-79 73 74 61-6c 20 42 65 ackIN.Cr ystal.Be
|
||||
0000-5820: 6c 6c 73 00-43 61 76 65-72 6e 00 53-65 63 72 65 lls.Cave rn.Secre
|
||||
0000-5830: 74 20 47 6e-6f 6d 65 73-00 43 6c 6f-74 68 00 49 t.Gnomes .Cloth.I
|
||||
0000-5840: 63 69 63 6c-65 73 00 58-4f 52 00 4e-65 61 72 20 cicles.X OR.Near.
|
||||
0000-5850: 54 68 65 20-50 6c 61 6e-65 74 20 43-6f 72 65 00 The.Plan et.Core.
|
||||
0000-5860: 4f 66 20 44-77 61 72 76-65 73 00 73-70 72 69 6e Of.Dwarv es.sprin
|
||||
0000-5870: 67 32 00 73-70 72 69 6e-67 33 00 50-69 6e 6b 20 g2.sprin g3.Pink.
|
||||
0000-5880: 50 65 74 61-6c 73 00 54-72 6f 70 69-63 61 6c 20 Petals.T ropical.
|
||||
0000-5890: 4a 61 6d 00-47 68 6f 73-74 20 53 79-6e 74 68 00 Jam.Ghos t.Synth.
|
||||
0000-58a0: 50 6c 75 6d-73 00 4d 61-6a 65 73 74-69 63 00 4f Plums.Ma jestic.O
|
||||
0000-58b0: 72 61 6e 67-65 00 73 75-6d 6d 65 72-32 00 43 79 range.su mmer2.Cy
|
||||
0000-58c0: 63 6c 6f 70-73 00 77 69-6e 74 65 72-33 00 4e 65 clops.wi nter3.Ne
|
||||
0000-58d0: 77 20 53 6e-6f 77 00 63-72 6f 61 6b-00 74 72 65 w.Snow.c roak.tre
|
||||
0000-58e0: 65 74 68 75-64 00 74 72-65 65 63 72-61 63 6b 00 ethud.tr eecrack.
|
||||
0000-58f0: 61 78 63 68-6f 70 00 6c-65 61 66 72-75 73 74 6c axchop.l eafrustl
|
||||
0000-5900: 65 00 63 72-79 73 74 61-6c 00 73 77-65 65 74 00 e.crysta l.sweet.
|
||||
0000-5910: 70 6f 74 74-65 72 79 53-6d 61 73 68-00 73 65 6c potteryS mash.sel
|
||||
0000-5920: 65 63 74 00-66 6c 61 6d-65 53 70 65-6c 6c 48 69 ect.flam eSpellHi
|
||||
0000-5930: 74 00 66 6c-61 6d 65 53-70 65 6c 6c-00 64 65 62 t.flameS pell.deb
|
||||
0000-5940: 75 66 66 48-69 74 00 64-65 62 75 66-66 53 70 65 uffHit.d ebuffSpe
|
||||
0000-5950: 6c 6c 00 6d-6f 6e 73 74-65 72 64 65-61 64 00 63 ll.monst erdead.c
|
||||
0000-5960: 6c 75 62 68-69 74 00 63-6c 75 62 73-77 69 70 65 lubhit.c lubswipe
|
||||
0000-5970: 00 6f 70 65-6e 43 68 65-73 74 00 72-6f 63 6b 47 .openChe st.rockG
|
||||
0000-5980: 6f 6c 65 6d-53 70 61 77-6e 00 72 6f-63 6b 47 6f olemSpaw n.rockGo
|
||||
0000-5990: 6c 65 6d 44-69 65 00 64-61 72 6b 43-61 76 65 4c lemDie.d arkCaveL
|
||||
0000-59a0: 6f 6f 70 00-62 75 67 4c-65 76 65 6c-4c 6f 6f 70 oop.bugL evelLoop
|
||||
0000-59b0: 00 62 61 74-46 6c 61 70-00 62 61 74-53 63 72 65 .batFlap .batScre
|
||||
0000-59c0: 65 63 68 00-62 69 67 44-72 75 6d 73-00 63 6c 75 ech.bigD rums.clu
|
||||
0000-59d0: 62 53 6d 61-73 68 00 6f-63 65 61 6e-00 73 70 72 bSmash.o cean.spr
|
||||
0000-59e0: 69 6e 67 5f-64 61 79 5f-61 6d 62 69-65 6e 74 00 ing_day_ ambient.
|
||||
0000-59f0: 6d 61 72 6e-69 65 53 68-6f 70 00 74-6f 79 50 69 marnieSh op.toyPi
|
||||
0000-5a00: 61 6e 6f 00-73 6b 65 6c-65 74 6f 6e-53 74 65 70 ano.skel etonStep
|
||||
0000-5a10: 00 73 6b 65-6c 65 74 6f-6e 44 69 65-00 73 6b 65 .skeleto nDie.ske
|
||||
0000-5a20: 6c 65 74 6f-6e 48 69 74-00 73 6c 69-6d 65 48 69 letonHit .slimeHi
|
||||
0000-5a30: 74 00 64 75-73 74 4d 65-65 70 00 74-68 72 6f 77 t.dustMe ep.throw
|
||||
0000-5a40: 00 6d 69 6e-65 63 61 72-74 4c 6f 6f-70 00 43 6c .minecar tLoop.Cl
|
||||
0000-5a50: 6f 75 64 43-6f 75 6e 74-72 79 00 72-6f 61 64 6e oudCount ry.roadn
|
||||
0000-5a60: 6f 69 73 65-00 62 75 73-44 6f 6f 72-4f 70 65 6e oise.bus DoorOpen
|
||||
0000-5a70: 00 53 65 74-74 6c 69 6e-67 49 6e 00-73 69 70 54 .Settlin gIn.sipT
|
||||
0000-5a80: 65 61 00 73-68 61 64 6f-77 44 69 65-00 73 68 61 ea.shado wDie.sha
|
||||
0000-5a90: 64 6f 77 48-69 74 00 68-65 61 6c 53-6f 75 6e 64 dowHit.h ealSound
|
||||
0000-5aa0: 00 63 6f 6c-64 53 70 65-6c 6c 00 74-72 69 62 61 .coldSpe ll.triba
|
||||
0000-5ab0: 6c 00 55 70-70 65 72 5f-41 6d 62 69-65 6e 74 00 l.Upper_ Ambient.
|
||||
0000-5ac0: 46 72 6f 73-74 5f 41 6d-62 69 65 6e-74 00 4c 61 Frost_Am bient.La
|
||||
0000-5ad0: 76 61 5f 41-6d 62 69 65-6e 74 00 79-6f 62 61 00 va_Ambie nt.yoba.
|
||||
0000-5ae0: 77 61 72 72-69 6f 72 00-73 6c 69 6e-67 73 68 6f warrior. slingsho
|
||||
0000-5af0: 74 00 64 69-73 63 6f 76-65 72 4d 69-6e 65 72 61 t.discov erMinera
|
||||
0000-5b00: 6c 00 74 72-61 73 68 63-61 6e 00 6e-65 77 41 72 l.trashc an.newAr
|
||||
0000-5b10: 74 69 66 61-63 74 00 72-65 77 61 72-64 00 6e 65 tifact.r eward.ne
|
||||
0000-5b20: 77 52 65 63-6f 72 64 00-6e 65 77 52-65 63 69 70 wRecord. newRecip
|
||||
0000-5b30: 65 00 4f 76-65 72 63 61-73 74 00 77-6f 6f 64 73 e.Overca st.woods
|
||||
0000-5b40: 54 68 65 6d-65 00 73 74-75 6d 70 43-72 61 63 6b Theme.st umpCrack
|
||||
0000-5b50: 00 73 65 63-72 65 74 31-00 74 72 61-69 6e 57 68 .secret1 .trainWh
|
||||
0000-5b60: 69 73 74 6c-65 00 74 72-61 69 6e 4c-6f 6f 70 00 istle.tr ainLoop.
|
||||
0000-5b70: 67 65 74 4e-65 77 53 70-65 63 69 61-6c 49 74 65 getNewSp ecialIte
|
||||
0000-5b80: 6d 00 6e 69-67 68 74 54-69 6d 65 00-4d 65 74 65 m.nightT ime.Mete
|
||||
0000-5b90: 6f 72 69 74-65 00 55 46-4f 00 6f 77-6c 00 64 6f orite.UF O.owl.do
|
||||
0000-5ba0: 67 73 00 73-63 69 73 73-6f 72 73 00-4d 69 6c 6b gs.sciss ors.Milk
|
||||
0000-5bb0: 69 6e 67 00-44 75 63 6b-00 73 68 65-65 70 00 6b ing.Duck .sheep.k
|
||||
0000-5bc0: 69 6c 6c 41-6e 69 6d 61-6c 00 62 6f-75 6c 64 65 illAnima l.boulde
|
||||
0000-5bd0: 72 42 72 65-61 6b 00 73-65 6c 6c 00-70 75 72 63 rBreak.s ell.purc
|
||||
0000-5be0: 68 61 73 65-43 6c 69 63-6b 00 63 61-73 74 00 53 haseClic k.cast.S
|
||||
0000-5bf0: 69 6e 57 61-76 65 00 73-6c 6f 77 52-65 65 6c 00 inWave.s lowReel.
|
||||
0000-5c00: 66 61 73 74-52 65 65 6c-00 74 69 6e-79 57 68 69 fastReel .tinyWhi
|
||||
0000-5c10: 70 00 62 75-74 74 6f 6e-31 00 46 69-73 68 48 69 p.button 1.FishHi
|
||||
0000-5c20: 74 00 6a 69-6e 67 6c 65-31 00 66 69-73 68 45 73 t.jingle 1.fishEs
|
||||
0000-5c30: 63 61 70 65-00 66 69 73-68 53 6c 61-70 00 43 6f cape.fis hSlap.Co
|
||||
0000-5c40: 77 62 6f 79-5f 4f 56 45-52 57 4f 52-4c 44 00 43 wboy_OVE RWORLD.C
|
||||
0000-5c50: 6f 77 62 6f-79 5f 73 69-6e 67 69 6e-67 00 43 6f owboy_si nging.Co
|
||||
0000-5c60: 77 62 6f 79-5f 53 65 63-72 65 74 00-43 6f 77 62 wboy_Sec ret.Cowb
|
||||
0000-5c70: 6f 79 5f 67-75 6e 73 68-6f 74 00 63-6f 77 62 6f oy_gunsh ot.cowbo
|
||||
0000-5c80: 79 5f 62 6f-73 73 00 63-6f 77 62 6f-79 5f 64 65 y_boss.c owboy_de
|
||||
0000-5c90: 61 64 00 43-6f 77 62 6f-79 5f 46 6f-6f 74 73 74 ad.Cowbo y_Footst
|
||||
0000-5ca0: 65 70 00 43-6f 77 62 6f-79 5f 75 6e-64 65 61 64 ep.Cowbo y_undead
|
||||
0000-5cb0: 00 63 6f 77-62 6f 79 5f-70 6f 77 65-72 75 70 00 .cowboy_ powerup.
|
||||
0000-5cc0: 63 6f 77 62-6f 79 5f 67-75 6e 6c 6f-61 64 00 63 cowboy_g unload.c
|
||||
0000-5cd0: 6f 77 62 6f-79 5f 67 6f-70 68 65 72-00 63 6f 77 owboy_go pher.cow
|
||||
0000-5ce0: 62 6f 79 5f-65 78 70 6c-6f 73 69 6f-6e 00 63 6f boy_expl osion.co
|
||||
0000-5cf0: 77 62 6f 79-5f 6f 75 74-6c 61 77 73-6f 6e 67 00 wboy_out lawsong.
|
||||
0000-5d00: 70 6c 61 79-66 75 6c 00-41 62 69 67-61 69 6c 46 playful. AbigailF
|
||||
0000-5d10: 6c 75 74 65-00 41 62 69-67 61 69 6c-46 6c 75 74 lute.Abi gailFlut
|
||||
0000-5d20: 65 44 75 65-74 00 62 72-65 65 7a 79-00 6b 69 6e eDuet.br eezy.kin
|
||||
0000-5d30: 64 61 64 75-6d 62 61 75-74 75 6d 6e-00 48 6f 73 dadumbau tumn.Hos
|
||||
0000-5d40: 70 69 74 61-6c 5f 41 6d-62 69 65 6e-74 00 62 72 pital_Am bient.br
|
||||
0000-5d50: 65 61 6b 69-6e 67 47 6c-61 73 73 00-73 70 61 63 eakingGl ass.spac
|
||||
0000-5d60: 65 4d 75 73-69 63 00 72-6f 62 6f 74-53 6f 75 6e eMusic.r obotSoun
|
||||
0000-5d70: 64 45 66 66-65 63 74 73-00 72 6f 62-6f 74 42 4c dEffects .robotBL
|
||||
0000-5d80: 41 53 54 4f-46 46 00 70-6f 6f 6c 5f-61 6d 62 69 ASTOFF.p ool_ambi
|
||||
0000-5d90: 65 6e 74 00-63 61 6d 65-72 61 4e 6f-69 73 65 00 ent.came raNoise.
|
||||
0000-5da0: 6b 65 79 62-6f 61 72 64-54 79 70 69-6e 67 00 6d keyboard Typing.m
|
||||
0000-5db0: 6f 75 73 65-43 6c 69 63-6b 00 65 6c-6c 69 6f 74 ouseClic k.elliot
|
||||
0000-5dc0: 74 50 69 61-6e 6f 00 74-69 6e 79 6d-75 73 69 63 tPiano.t inymusic
|
||||
0000-5dd0: 62 6f 78 00-67 75 73 76-69 6f 6c 69-6e 00 77 68 box.gusv iolin.wh
|
||||
0000-5de0: 69 73 74 6c-65 00 65 76-65 6e 74 31-00 74 69 63 istle.ev ent1.tic
|
||||
0000-5df0: 6b 54 6f 63-6b 00 46 6c-6f 77 65 72-44 61 6e 63 kTock.Fl owerDanc
|
||||
0000-5e00: 65 00 65 76-65 6e 74 32-00 6d 6f 6f-6e 6c 69 67 e.event2 .moonlig
|
||||
0000-5e10: 68 74 4a 65-6c 6c 69 65-73 00 66 61-6c 6c 46 65 htJellie s.fallFe
|
||||
0000-5e20: 73 74 00 63-68 72 69 73-74 6d 61 73-54 68 65 6d st.chris tmasThem
|
||||
0000-5e30: 65 00 6a 75-6e 69 6d 6f-4d 65 65 70-31 00 63 6f e.junimo Meep1.co
|
||||
0000-5e40: 6d 6d 75 6e-69 74 79 43-65 6e 74 65-72 00 6a 75 mmunityC enter.ju
|
||||
0000-5e50: 6e 69 6d 6f-53 74 61 72-53 6f 6e 67-00 62 75 73 nimoStar Song.bus
|
||||
0000-5e60: 44 72 69 76-65 4f 66 66-00 73 74 61-69 72 73 64 DriveOff .stairsd
|
||||
0000-5e70: 6f 77 6e 00-73 65 72 70-65 6e 74 48-69 74 00 73 own.serp entHit.s
|
||||
0000-5e80: 65 72 70 65-6e 74 44 69-65 00 64 6f-67 57 68 69 erpentDi e.dogWhi
|
||||
0000-5e90: 6e 69 6e 67-00 73 68 77-69 70 00 66-61 6c 6c 44 ning.shw ip.fallD
|
||||
0000-5ea0: 6f 77 6e 00-57 69 7a 61-72 64 53 6f-6e 67 00 64 own.Wiza rdSong.d
|
||||
0000-5eb0: 6f 6f 72 43-72 65 61 6b-52 65 76 65-72 73 65 00 oorCreak Reverse.
|
||||
0000-5ec0: 63 61 63 6b-6c 69 6e 67-57 69 74 63-68 00 67 6c cackling Witch.gl
|
||||
0000-5ed0: 75 67 00 68-61 72 76 65-73 74 00 72-6f 6f 73 74 ug.harve st.roost
|
||||
0000-5ee0: 65 72 00 64-6f 67 5f 70-61 6e 74 00-64 6f 67 5f er.dog_p ant.dog_
|
||||
0000-5ef0: 62 61 72 6b-00 73 70 69-72 69 74 73-5f 65 76 65 bark.spi rits_eve
|
||||
0000-5f00: 00 4d 61 69-6e 54 68 65-6d 65 00 6a-6f 6a 61 4f .MainThe me.jojaO
|
||||
0000-5f10: 66 66 69 63-65 53 6f 75-6e 64 73 63-61 70 65 00 fficeSou ndscape.
|
||||
0000-5f20: 67 72 61 6e-64 70 61 73-5f 74 68 65-6d 65 00 66 grandpas _theme.f
|
||||
0000-5f30: 61 6c 6c 5f-64 61 79 5f-61 6d 62 69-65 6e 74 00 all_day_ ambient.
|
||||
0000-5f40: 73 75 6d 6d-65 72 5f 64-61 79 5f 61-6d 62 69 65 summer_d ay_ambie
|
||||
0000-5f50: 6e 74 00 73-6e 6f 77 79-53 74 65 70-00 73 70 72 nt.snowy Step.spr
|
||||
0000-5f60: 69 6e 67 31-00 73 75 6d-6d 65 72 31-00 73 75 6d ing1.sum mer1.sum
|
||||
0000-5f70: 6d 65 72 33-00 66 61 6c-6c 33 00 66-61 6c 6c 31 mer3.fal l3.fall1
|
||||
0000-5f80: 00 66 61 6c-6c 32 00 77-69 6e 74 65-72 32 00 77 .fall2.w inter2.w
|
||||
0000-5f90: 69 6e 74 65-72 31 00 6c-69 62 72 61-72 79 54 68 inter1.l ibraryTh
|
||||
0000-5fa0: 65 6d 65 00-63 72 61 63-6b 6c 69 6e-67 46 69 72 eme.crac klingFir
|
||||
0000-5fb0: 65 00 62 61-62 62 6c 69-6e 67 42 72-6f 6f 6b 00 e.babbli ngBrook.
|
||||
0000-5fc0: 68 65 61 76-79 45 6e 67-69 6e 65 00-73 70 72 69 heavyEng ine.spri
|
||||
0000-5fd0: 6e 67 5f 6e-69 67 68 74-5f 61 6d 62-69 65 6e 74 ng_night _ambient
|
||||
0000-5fe0: 00 63 72 69-63 6b 65 74-73 41 6d 62-69 65 6e 74 .cricket sAmbient
|
||||
0000-5ff0: 00 64 69 73-74 61 6e 74-42 61 6e 6a-6f 00 67 69 .distant Banjo.gi
|
||||
0000-6000: 76 65 5f 67-69 66 74 00-4d 61 72 6c-6f 6e 73 54 ve_gift. MarlonsT
|
||||
0000-6010: 68 65 6d 65-00 53 61 6c-6f 6f 6e 31-00 73 74 61 heme.Sal oon1.sta
|
||||
0000-6020: 72 64 72 6f-70 00 63 72-69 74 00 63-61 6e 63 65 rdrop.cr it.cance
|
||||
0000-6030: 6c 00 77 69-6e 74 65 72-5f 64 61 79-5f 61 6d 62 l.winter _day_amb
|
||||
0000-6040: 69 65 6e 74-00 53 74 61-64 69 75 6d-5f 63 68 65 ient.Sta dium_che
|
||||
0000-6050: 65 72 00 53-74 61 64 69-75 6d 5f 61-6d 62 69 65 er.Stadi um_ambie
|
||||
0000-6060: 6e 74 00 45-6d 69 6c 79-44 61 6e 63-65 00 45 6d nt.Emily Dance.Em
|
||||
0000-6070: 69 6c 79 44-72 65 61 6d-00 45 6d 69-6c 79 54 68 ilyDream .EmilyTh
|
||||
0000-6080: 65 6d 65 00-70 61 72 72-6f 74 00 73-68 61 6e 65 eme.parr ot.shane
|
||||
0000-6090: 54 68 65 6d-65 00 62 69-67 44 65 53-65 6c 65 63 Theme.bi gDeSelec
|
||||
0000-60a0: 74 00 62 69-67 53 65 6c-65 63 74 00-73 74 6f 6e t.bigSel ect.ston
|
||||
0000-60b0: 65 43 72 61-63 6b 00 77-61 74 65 72-69 6e 67 43 eCrack.w ateringC
|
||||
0000-60c0: 61 6e 00 63-6c 75 63 6b-00 73 77 6f-72 64 73 77 an.cluck .swordsw
|
||||
0000-60d0: 69 70 65 00-73 6c 69 6d-65 64 65 61-64 00 45 61 ipe.slim edead.Ea
|
||||
0000-60e0: 72 74 68 4d-69 6e 65 00-46 72 6f 73-74 4d 69 6e rthMine. FrostMin
|
||||
0000-60f0: 65 00 4c 61-76 61 4d 69-6e 65 00 67-6f 61 74 00 e.LavaMi ne.goat.
|
||||
0000-6100: 63 6f 77 00-53 70 72 69-6e 67 42 69-72 64 73 00 cow.Spri ngBirds.
|
||||
0000-6110: 73 70 72 69-6e 67 73 6f-6e 67 73 00-53 68 69 70 springso ngs.Ship
|
||||
0000-6120: 00 62 6f 6f-70 00 70 69-67 00 72 61-69 6e 73 6f .boop.pi g.rainso
|
||||
0000-6130: 75 6e 64 00-70 75 72 63-68 61 73 65-00 64 61 67 und.purc hase.dag
|
||||
0000-6140: 67 65 72 73-77 69 70 65-00 66 6c 79-62 75 7a 7a gerswipe .flybuzz
|
||||
0000-6150: 69 6e 67 00-72 6f 63 6b-47 6f 6c 65-6d 48 69 74 ing.rock GolemHit
|
||||
0000-6160: 00 70 61 72-72 79 00 73-65 61 67 75-6c 6c 73 00 .parry.s eagulls.
|
||||
0000-6170: 63 6c 61 6e-6b 00 74 72-61 73 68 63-61 6e 6c 69 clank.tr ashcanli
|
||||
0000-6180: 64 00 64 69-73 74 61 6e-74 54 72 61-69 6e 00 64 d.distan tTrain.d
|
||||
0000-6190: 77 6f 70 00-62 75 62 62-6c 65 73 00-6d 6f 6e 65 wop.bubb les.mone
|
||||
0000-61a0: 79 44 69 61-6c 00 67 75-6c 70 00 70-75 72 63 68 yDial.gu lp.purch
|
||||
0000-61b0: 61 73 65 52-65 70 65 61-74 00 64 69-72 74 79 48 aseRepea t.dirtyH
|
||||
0000-61c0: 69 74 00 66-69 73 68 69-6e 67 52 6f-64 42 65 6e it.fishi ngRodBen
|
||||
0000-61d0: 64 00 77 61-74 65 72 53-6c 6f 73 68-00 43 6f 77 d.waterS losh.Cow
|
||||
0000-61e0: 62 6f 79 5f-6d 6f 6e 73-74 65 72 44-69 65 00 50 boy_mons terDie.P
|
||||
0000-61f0: 69 63 6b 75-70 5f 43 6f-69 6e 31 35-00 63 6f 77 ickup_Co in15.cow
|
||||
0000-6200: 62 6f 79 5f-6d 6f 6e 73-74 65 72 68-69 74 00 73 boy_mons terhit.s
|
||||
0000-6210: 6c 6f 73 68-00 77 6f 6f-64 57 68 61-63 6b 00 62 losh.woo dWhack.b
|
||||
0000-6220: 61 72 72 65-6c 42 72 65-61 6b 00 64-6f 6f 72 43 arrelBre ak.doorC
|
||||
0000-6230: 72 65 61 6b-00 64 6f 6f-72 4f 70 65-6e 00 63 72 reak.doo rOpen.cr
|
||||
0000-6240: 6f 77 00 74-68 75 6e 64-65 72 5f 73-6d 61 6c 6c ow.thund er_small
|
||||
0000-6245: 00 63 61 74-00 .cat.
|
Loading…
Reference in New Issue