private void LoadMP3(string path, byte[] bytes)
        {
            string wavCacheFilename = this.Name + "_" + path.Replace('/', '_') + "_" + Version + ".wav";

            WAVCacheIO.DeleteIfOlder(File.path, wavCacheFilename);
            try
            {
                if (path.StartsWith("Sounds/Music/"))
                {
                    if (ModLoader.musicStreamMode != 1)
                    {                    //no cache
                        musics[path] = new MusicData(bytes, true);
                        return;
                    }

                    if (!WAVCacheIO.WAVCacheAvailable(wavCacheFilename))
                    {
                        WAVCacheIO.CacheMP3(wavCacheFilename, new MemoryStream(bytes));
                    }

                    musics[path] = new MusicData(Path.Combine(WAVCacheIO.ModCachePath, wavCacheFilename));
                    return;
                }

                sounds[path] = WAVCacheIO.WAVCacheAvailable(wavCacheFilename) ?
                               SoundEffect.FromStream(WAVCacheIO.GetWavStream(wavCacheFilename)) :
                               WAVCacheIO.CacheMP3(wavCacheFilename, new MemoryStream(bytes));
            }
            catch (Exception e)
            {
                throw new ResourceLoadException(Language.GetTextValue("tModLoader.LoadErrorMP3SoundFailedToLoad", path) + (Main.engine == null ? "\n" + Language.GetTextValue("tModLoader.LoadErrorSoundFailedToLoadAudioDeviceHint") : ""), e);
            }
        }
Beispiel #2
0
        private static bool Build(BuildingMod mod, IBuildStatus status)
        {
            byte[] winDLL  = null;
            byte[] monoDLL = null;
            byte[] winPDB  = null;
            if (mod.properties.noCompile)
            {
                winDLL = monoDLL = ReadIfExists(Path.Combine(mod.path, "All.dll"));
                winPDB = ReadIfExists(Path.Combine(mod.path, "All.pdb"));

                if (winDLL == null)
                {
                    winDLL  = ReadIfExists(Path.Combine(mod.path, "Windows.dll"));
                    monoDLL = ReadIfExists(Path.Combine(mod.path, "Mono.dll"));
                    winPDB  = ReadIfExists(Path.Combine(mod.path, "Windows.pdb"));
                }

                if (winDLL == null || monoDLL == null)
                {
                    ErrorLogger.LogDllBuildError(mod.path);
                    return(false);
                }
            }
            else
            {
                var refMods = FindReferencedMods(mod.properties);
                if (refMods == null)
                {
                    return(false);
                }

                if (Program.LaunchParameters.ContainsKey("-eac"))
                {
                    if (!windows)
                    {
                        ErrorLogger.LogBuildError("Edit and continue is only supported on windows");
                        return(false);
                    }

                    try {
                        status.SetStatus("Loading pre-compiled Windows.dll with edit and continue support");
                        var winPath = Program.LaunchParameters["-eac"];
                        var pdbPath = Path.ChangeExtension(winPath, "pdb");
                        winDLL = File.ReadAllBytes(winPath);
                        winPDB = File.ReadAllBytes(pdbPath);
                        mod.properties.editAndContinue = true;
                    }
                    catch (Exception e) {
                        ErrorLogger.LogBuildError("Failed to load pre-compiled edit and continue dll " + e);
                        return(false);
                    }
                }
                else
                {
                    status.SetStatus(Language.GetTextValue("tModLoader.MSCompilingWindows", mod));
                    status.SetProgress(0, 2);
                    CompileMod(mod, refMods, true, ref winDLL, ref winPDB);
                }
                if (winDLL == null)
                {
                    return(false);
                }

                status.SetStatus(Language.GetTextValue("tModLoader.MSCompilingMono", mod));
                status.SetProgress(1, 2);
                CompileMod(mod, refMods, false, ref monoDLL, ref winPDB);                //the pdb reference won't actually be written to
                if (monoDLL == null)
                {
                    return(false);
                }
            }

            if (!VerifyName(mod.Name, winDLL) || !VerifyName(mod.Name, monoDLL))
            {
                return(false);
            }

            status.SetStatus(Language.GetTextValue("tModLoader.MSBuilding") + mod + "...");
            status.SetProgress(0, 1);

            mod.modFile.AddFile("Info", mod.properties.ToBytes());

            if (Equal(winDLL, monoDLL))
            {
                mod.modFile.AddFile("All.dll", winDLL);
                if (winPDB != null)
                {
                    mod.modFile.AddFile("All.pdb", winPDB);
                }
            }
            else
            {
                mod.modFile.AddFile("Windows.dll", winDLL);
                mod.modFile.AddFile("Mono.dll", monoDLL);
                if (winPDB != null)
                {
                    mod.modFile.AddFile("Windows.pdb", winPDB);
                }
            }

            foreach (var resource in Directory.GetFiles(mod.path, "*", SearchOption.AllDirectories))
            {
                var relPath = resource.Substring(mod.path.Length + 1);
                if (mod.properties.ignoreFile(relPath) ||
                    relPath == "build.txt" ||
                    relPath == ".gitattributes" ||
                    relPath == ".gitignore" ||
                    relPath.StartsWith(".git" + Path.DirectorySeparatorChar) ||
                    relPath.StartsWith(".vs" + Path.DirectorySeparatorChar) ||
                    relPath.StartsWith("bin" + Path.DirectorySeparatorChar) ||
                    relPath.StartsWith("obj" + Path.DirectorySeparatorChar) ||
                    !mod.properties.includeSource && sourceExtensions.Contains(Path.GetExtension(resource)) ||
                    Path.GetFileName(resource) == "Thumbs.db")
                {
                    continue;
                }

                mod.modFile.AddFile(relPath, File.ReadAllBytes(resource));
            }

            WAVCacheIO.ClearCache(mod.Name);

            mod.modFile.Save();
            EnableMod(mod.modFile);
            ActivateExceptionReporting();
            ModLoader.isModder = true;
            return(true);
        }
Beispiel #3
0
        private bool Build(BuildingMod mod)
        {
            status.SetMod(mod.Name);
            status.SetStatus(Language.GetTextValue("tModLoader.Building", mod.Name));
            byte[] winDLL  = null;
            byte[] monoDLL = null;
            byte[] winPDB  = null;
            if (mod.properties.noCompile)
            {
                winDLL = monoDLL = ReadIfExists(Path.Combine(mod.path, "All.dll"));
                winPDB = ReadIfExists(Path.Combine(mod.path, "All.pdb"));

                if (winDLL == null)
                {
                    winDLL  = ReadIfExists(Path.Combine(mod.path, "Windows.dll"));
                    monoDLL = ReadIfExists(Path.Combine(mod.path, "Mono.dll"));
                    winPDB  = ReadIfExists(Path.Combine(mod.path, "Windows.pdb"));
                }

                if (winDLL == null || monoDLL == null)
                {
                    var missing = new List <string> {
                        "All.dll"
                    };
                    if (winDLL == null)
                    {
                        missing.Add("Windows.dll");
                    }
                    if (monoDLL == null)
                    {
                        missing.Add("Mono.dll");
                    }
                    status.LogError(Language.GetTextValue("tModLoader.BuildErrorMissingDllFiles", string.Join(", ", missing)));
                    return(false);
                }
            }
            else
            {
                List <LocalMod> refMods;
                try {
                    refMods = FindReferencedMods(mod.properties);
                }
                catch (Exception e) {
                    status.LogError(e.Message, e.InnerException);
                    return(false);
                }

                if (Program.LaunchParameters.ContainsKey("-eac"))
                {
                    if (!windows)
                    {
                        status.LogError(Language.GetTextValue("tModLoader.BuildErrorEACWindowsOnly"));
                        return(false);
                    }

                    var winPath = Program.LaunchParameters["-eac"];
                    try {
                        status.SetStatus(Language.GetTextValue("tModLoader.LoadingEAC"));
                        var pdbPath = Path.ChangeExtension(winPath, "pdb");
                        winDLL = File.ReadAllBytes(winPath);
                        winPDB = File.ReadAllBytes(pdbPath);
                        mod.properties.editAndContinue = true;
                    }
                    catch (Exception e) {
                        status.LogError(Language.GetTextValue("tModLoader.BuildErrorEACLoadFailed", winPath + "/.pdb"), e);
                        return(false);
                    }
                }
                else
                {
                    status.SetStatus(Language.GetTextValue("tModLoader.CompilingWindows", mod));
                    status.SetProgress(0, 2);
                    CompileMod(mod, refMods, true, ref winDLL, ref winPDB);
                }
                if (winDLL == null)
                {
                    return(false);
                }

                status.SetStatus(Language.GetTextValue("tModLoader.CompilingMono", mod));
                status.SetProgress(1, 2);
                CompileMod(mod, refMods, false, ref monoDLL, ref winPDB);                //the pdb reference won't actually be written to
                if (monoDLL == null)
                {
                    return(false);
                }
            }

            if (!VerifyName(mod.Name, winDLL) || !VerifyName(mod.Name, monoDLL))
            {
                return(false);
            }

            status.SetStatus(Language.GetTextValue("tModLoader.Packaging", mod));
            status.SetProgress(0, 1);

            mod.modFile.AddFile("Info", mod.properties.ToBytes());

            if (Equal(winDLL, monoDLL))
            {
                mod.modFile.AddFile("All.dll", winDLL);
                if (winPDB != null)
                {
                    mod.modFile.AddFile("All.pdb", winPDB);
                }
            }
            else
            {
                mod.modFile.AddFile("Windows.dll", winDLL);
                mod.modFile.AddFile("Mono.dll", monoDLL);
                if (winPDB != null)
                {
                    mod.modFile.AddFile("Windows.pdb", winPDB);
                }
            }

            foreach (var resource in Directory.GetFiles(mod.path, "*", SearchOption.AllDirectories))
            {
                var relPath = resource.Substring(mod.path.Length + 1);
                if (mod.properties.ignoreFile(relPath) ||
                    relPath == "build.txt" ||
                    relPath == ".gitattributes" ||
                    relPath == ".gitignore" ||
                    relPath.StartsWith(".git" + Path.DirectorySeparatorChar) ||
                    relPath.StartsWith(".vs" + Path.DirectorySeparatorChar) ||
                    relPath.StartsWith(".idea" + Path.DirectorySeparatorChar) ||
                    relPath.StartsWith("bin" + Path.DirectorySeparatorChar) ||
                    relPath.StartsWith("obj" + Path.DirectorySeparatorChar) ||
                    !mod.properties.includeSource && sourceExtensions.Contains(Path.GetExtension(resource)) ||
                    Path.GetFileName(resource) == "Thumbs.db")
                {
                    continue;
                }

                AddResource(mod.modFile, relPath, resource);
            }

            WAVCacheIO.ClearCache(mod.Name);

            GetMod(mod.Name)?.File?.Close();             // if the mod is currently loaded, the file-handle needs to be released
            mod.modFile.Save();
            mod.modFile.Close();
            EnableMod(mod.Name);
            return(true);
        }
Beispiel #4
0
        private static void LoadMod(TmodFile modFile, BuildProperties properties)
        {
            AddAssemblyResolver();
            string fileName = Path.GetFileNameWithoutExtension(modFile.Name);

            Interface.loadMods.SetProgressReading(fileName, 0, 2);
            Assembly modCode;
            string   rootDirectory;

            if (modFile.HasFile("All"))
            {
                modCode = Assembly.Load(modFile.GetFile("All"));
            }
            else
            {
                modCode = Assembly.Load(modFile.GetFile(windows ? "Windows" : "Other"));
            }
            Interface.loadMods.SetProgressReading(fileName, 1, 2);
            using (MemoryStream memoryStream = new MemoryStream(modFile.GetFile("Resources")))
            {
                using (BinaryReader reader = new BinaryReader(memoryStream))
                {
                    rootDirectory = reader.ReadString();
                    for (string path = reader.ReadString(); path != "end"; path = reader.ReadString())
                    {
                        byte[] data = reader.ReadBytes(reader.ReadInt32());
                        files[path] = data;
                        if (Main.dedServ)
                        {
                            continue;
                        }
                        string extension = Path.GetExtension(path);
                        switch (extension)
                        {
                        case ".png":
                            string texturePath = Path.ChangeExtension(path, null);
                            using (MemoryStream buffer = new MemoryStream(data))
                            {
                                textures[texturePath] = Texture2D.FromStream(Main.instance.GraphicsDevice, buffer);
                            }
                            break;

                        case ".wav":
                            string soundPath = Path.ChangeExtension(path, null);
                            using (MemoryStream buffer = new MemoryStream(data))
                            {
                                sounds[soundPath] = SoundEffect.FromStream(buffer);
                            }
                            break;

                        case ".mp3":
                            string mp3Path          = Path.ChangeExtension(path, null);
                            string wavCacheFilename = mp3Path.Replace('/', '_') + "_" + properties.version + ".wav";
                            if (WAVCacheIO.WAVCacheAvailable(wavCacheFilename))
                            {
                                sounds[mp3Path] = SoundEffect.FromStream(WAVCacheIO.GetWavStream(wavCacheFilename));
                                break;
                            }
                            ushort       wFormatTag = 1;
                            ushort       nChannels;
                            uint         nSamplesPerSec;
                            uint         nAvgBytesPerSec;
                            ushort       nBlockAlign;
                            ushort       wBitsPerSample = 16;
                            const int    headerSize     = 44;
                            MemoryStream output         = new MemoryStream(headerSize + data.Length);
                            using (MemoryStream yourMp3FileStream = new MemoryStream(data))
                            {
                                using (MP3Sharp.MP3Stream input = new MP3Sharp.MP3Stream(yourMp3FileStream))
                                {
                                    using (BinaryWriter writer = new BinaryWriter(output, Encoding.UTF8))
                                    {
                                        output.Position = headerSize;
                                        input.CopyTo(output);
                                        UInt32 wavDataLength = (UInt32)output.Length - headerSize;
                                        output.Position = 0;
                                        nChannels       = (ushort)input.ChannelCount;
                                        nSamplesPerSec  = (uint)input.Frequency;
                                        nBlockAlign     = (ushort)(nChannels * (wBitsPerSample / 8));
                                        nAvgBytesPerSec = (uint)(nSamplesPerSec * nChannels * (wBitsPerSample / 8));
                                        //write the header
                                        writer.Write("RIFF".ToCharArray());                               //4
                                        writer.Write((UInt32)(wavDataLength + 36));                       // 4
                                        writer.Write("WAVE".ToCharArray());                               //4
                                        writer.Write("fmt ".ToCharArray());                               //4
                                        writer.Write(16);                                                 //4
                                        writer.Write(wFormatTag);                                         //
                                        writer.Write((ushort)nChannels);
                                        writer.Write(nSamplesPerSec);
                                        writer.Write(nAvgBytesPerSec);
                                        writer.Write(nBlockAlign);
                                        writer.Write(wBitsPerSample);
                                        writer.Write("data".ToCharArray());
                                        writer.Write((UInt32)(wavDataLength));
                                        output.Position = 0;
                                        WAVCacheIO.SaveWavStream(output, wavCacheFilename);
                                        sounds[mp3Path] = SoundEffect.FromStream(output);
                                    }
                                }
                            }
                            break;
                        }
                    }
                }
            }
            Type[] classes = modCode.GetTypes();
            foreach (Type type in classes)
            {
                if (type.IsSubclassOf(typeof(Mod)))
                {
                    Mod mod = (Mod)Activator.CreateInstance(type);
                    mod.file         = modFile.Name;
                    mod.buildVersion = properties.modBuildVersion;
                    mod.code         = modCode;
                    mod.Init();
                    if (mod.Name == "Terraria")
                    {
                        throw new DuplicateNameException("Mods cannot be named Terraria");
                    }
                    if (mods.ContainsKey(mod.Name))
                    {
                        throw new DuplicateNameException("Two mods share the internal name " + mod.Name);
                    }
                    if (rootDirectory != mod.Name)
                    {
                        throw new MissingResourceException("Mod name " + mod.Name + " does not match source directory name " + rootDirectory);
                    }
                    mods[mod.Name] = mod;
                    loadOrder.Push(mod.Name);
                }
            }
        }
Beispiel #5
0
        internal static bool do_BuildMod(object threadContext)
        {
            Interface.buildMod.SetReading();
            BuildProperties properties = BuildProperties.ReadBuildFile(modToBuild);

            if (!CreateModReferenceDlls(properties))
            {
                if (!buildAll)
                {
                    Main.menuMode = Interface.errorMessageID;
                }
                return(false);
            }
            LoadReferences();
            byte[] windowsData;
            byte[] otherData;
            if (properties.noCompile)
            {
                string modDir = modToBuild + Path.DirectorySeparatorChar;
                if (File.Exists(modDir + "All.dll"))
                {
                    windowsData = File.ReadAllBytes(modDir + "All.dll");
                    otherData   = File.ReadAllBytes(modDir + "All.dll");
                }
                else if (File.Exists(modDir + "Windows.dll") && File.Exists(modDir + "Other.dll"))
                {
                    windowsData = File.ReadAllBytes(modDir + "Windows.dll");
                    otherData   = File.ReadAllBytes(modDir + "Other.dll");
                }
                else
                {
                    ErrorLogger.LogDllBuildError(modToBuild);
                    if (!buildAll)
                    {
                        Main.menuMode = Interface.errorMessageID;
                    }
                    return(false);
                }
            }
            else
            {
                Interface.buildMod.SetCompiling(0);
                windowsData = CompileMod(modToBuild, properties, true);
                Interface.buildMod.SetCompiling(1);
                otherData = CompileMod(modToBuild, properties, false);
                if (windowsData == null || otherData == null)
                {
                    if (!buildAll)
                    {
                        Main.menuMode = Interface.errorMessageID;
                    }
                    return(false);
                }
            }
            Interface.buildMod.SetBuildText();
            string file = ModPath + Path.DirectorySeparatorChar + Path.GetFileName(modToBuild) + ".tmod";

            byte[]   propertiesData = properties.ToBytes();
            TmodFile modFile        = new TmodFile(file);

            using (MemoryStream memoryStream = new MemoryStream())
            {
                using (BinaryWriter writer = new BinaryWriter(memoryStream))
                {
                    writer.Write(version);
                    writer.Write(propertiesData.Length);
                    writer.Write(propertiesData);
                    writer.Flush();
                    modFile.AddFile("Info", memoryStream.ToArray());
                }
            }
            using (MemoryStream memoryStream = new MemoryStream())
            {
                using (BinaryWriter writer = new BinaryWriter(memoryStream))
                {
                    writer.Write(Path.GetFileName(modToBuild));
                    string[] resources = Directory.GetFiles(modToBuild, "*", SearchOption.AllDirectories);
                    foreach (string resource in resources)
                    {
                        if (properties.ignoreFile(resource.Replace(modToBuild + Path.DirectorySeparatorChar, null)))
                        {
                            continue;
                        }
                        if (Path.GetExtension(resource) == ".cs" && !properties.includeSource)
                        {
                            continue;
                        }
                        if (Path.GetFileName(resource) == "Thumbs.db")
                        {
                            continue;
                        }
                        if (resource.Substring(modToBuild.Length + 1) == "build.txt")
                        {
                            continue;
                        }
                        string resourcePath = resource.Replace(ModSourcePath + Path.DirectorySeparatorChar, null);
                        resourcePath = resourcePath.Replace(Path.DirectorySeparatorChar, '/');
                        byte[] buffer = File.ReadAllBytes(resource);
                        writer.Write(resourcePath);
                        writer.Write(buffer.Length);
                        writer.Write(buffer);
                    }
                    writer.Write("end");
                    writer.Flush();
                    modFile.AddFile("Resources", memoryStream.ToArray());
                }
            }
            bool same = windowsData.Length == otherData.Length;

            if (same)
            {
                for (int k = 0; k < windowsData.Length; k++)
                {
                    if (windowsData[k] != otherData[k])
                    {
                        same = false;
                        break;
                    }
                }
            }
            if (same)
            {
                modFile.AddFile("All", windowsData);
            }
            else
            {
                modFile.AddFile("Windows", windowsData);
                modFile.AddFile("Other", otherData);
            }
            modFile.Save();
            WAVCacheIO.ClearCache(modFile.Name);
            EnableMod(file);
            if (!buildAll)
            {
                Main.menuMode = reloadAfterBuild ? Interface.reloadModsID : 0;
            }
            return(true);
        }