using MySql.Data.MySqlClient; using Nini.Config; using OpenMetaverse; using OpenSim.Framework; using OpenSim.Services.Interfaces; using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Net; using System.Text; using System.Threading.Tasks; using static OpenMetaverse.Primitive; namespace GetRegionTextures { class GetRegionTextures { private static MySqlConnection m_mySQLConnection = null; private static String m_assetURL = "http://127.0.0.1:8002/assets/"; private static List m_assets = new List(); private static List getAllScenePrims(String regionID) { List returnData = new List(); MySqlCommand _mysqlCommand = m_mySQLConnection.CreateCommand(); _mysqlCommand.CommandTimeout = int.MaxValue; _mysqlCommand.CommandText = "SELECT prims.Name,prims.UUID,primshapes.Texture FROM prims LEFT JOIN primshapes ON prims.UUID = primshapes.UUID WHERE RegionUUID = ?RegionUUID"; _mysqlCommand.Parameters.AddWithValue("RegionUUID", regionID); MySqlDataReader _commandReader = _mysqlCommand.ExecuteReader(); while (_commandReader.Read()) returnData.Add(new MySQLPrimObject(_commandReader.GetString(0), _commandReader.GetString(1), (byte[])_commandReader["Texture"])); _commandReader.Close(); return returnData; } private static List getAllRegionIDsFromStorage() { List returnData = new List(); MySqlCommand _mysqlCommand = m_mySQLConnection.CreateCommand(); _mysqlCommand.CommandTimeout = int.MaxValue; _mysqlCommand.CommandText = "SELECT RegionUUID FROM terrain"; MySqlDataReader _commandReader = _mysqlCommand.ExecuteReader(); while (_commandReader.Read()) returnData.Add(_commandReader.GetString(0)); _commandReader.Close(); return returnData; } public static Stream GenerateStreamFromString(string s) { var stream = new MemoryStream(); var writer = new StreamWriter(stream); writer.Write(s); writer.Flush(); stream.Position = 0; return stream; } static void Main(string[] args) { if(File.Exists("ffmpeg.exe")) { Console.WriteLine("Cant find ffmpeg.exe"); Console.ReadLine(); return; } String config = ""; if (File.Exists("OpenSim.ini")) config += File.ReadAllText("OpenSim.ini") + "\n"; if (File.Exists("config-include/GridCommon.ini")) config += File.ReadAllText("config-include/GridCommon.ini") + "\n"; IConfigSource source = new IniConfigSource(GenerateStreamFromString(config)); source.ExpandKeyValues(); if (source.Configs["DatabaseService"] == null) return; if (source.Configs["HGAssetService"] == null) return; if (source.Configs["DatabaseService"].GetString("ConnectionString", null) == null) return; if (source.Configs["HGAssetService"].GetString("HomeURI", "http://127.0.0.1:8002") == null) return; m_assetURL = source.Configs["HGAssetService"].GetString("HomeURI", "http://127.0.0.1:8002") + "/assets/"; Console.WriteLine("AssetServer URL: " + m_assetURL); m_mySQLConnection = new MySqlConnection(source.Configs["DatabaseService"].GetString("ConnectionString", null)); m_mySQLConnection.Open(); if (!Directory.Exists("RegionData")) Directory.CreateDirectory("RegionData"); List allRegionIDs = getAllRegionIDsFromStorage(); foreach(String regionID in allRegionIDs) { Console.WriteLine("Start with region '" + regionID + "'"); if (!Directory.Exists("RegionData/" + regionID)) Directory.CreateDirectory("RegionData/" + regionID); if (!Directory.Exists("RegionData/assets")) Directory.CreateDirectory("RegionData/assets"); if (!Directory.Exists("RegionData/" + regionID + "/images")) Directory.CreateDirectory("RegionData/" + regionID + "/images"); List prims = getAllScenePrims(regionID); int primCounter = 0; foreach(MySQLPrimObject prim in prims) { Console.WriteLine(" ["+ ++primCounter + " / "+ prims .Count+ "]Start with scene object '" + prim.Name + "'"); Primitive.TextureEntry textureEntry = new Primitive.TextureEntry(prim.RawTextueData, 0, prim.RawTextueData.Length); foreach (TextureEntryFace faceEntry in textureEntry.FaceTextures) { if (faceEntry != null) { if (faceEntry.TextureID != UUID.Zero) { prim.Texture.Add(faceEntry.TextureID); Console.WriteLine(" Found texture '" + faceEntry.TextureID + "'"); if (!m_assets.Contains(faceEntry.TextureID)) m_assets.Add(faceEntry.TextureID); } } } } //Create CSV List entrys = new List(); foreach (MySQLPrimObject prim in prims) { String newEntry = prim.Name + ";" + prim.ID.ToString() + ";"; foreach (UUID texturID in prim.Texture) newEntry += texturID.ToString() + ";"; entrys.Add(newEntry); } File.WriteAllLines("RegionData/" + regionID + "/result.csv", entrys.ToArray()); //Start Asset Download using (WebClient assetHTTPClient = new WebClient()) { int downloadCounter = 0; foreach(UUID assetID in m_assets) { try { Console.WriteLine("[" + ++downloadCounter + " / " + m_assets.Count + "] Download asset " + assetID.ToString()); if(!File.Exists("RegionData/assets/" + assetID.ToString() + ".jpeg2000")) assetHTTPClient.DownloadFile(m_assetURL + assetID.ToString() + "/data", "RegionData/assets/" + assetID.ToString() + ".jpeg2000"); if (!File.Exists("RegionData/" + regionID + "/images/" + assetID.ToString() + ".png")) { Process process = new Process(); process.StartInfo.FileName = "ffmpeg.exe"; process.StartInfo.Arguments = "-i RegionData/assets/" + assetID.ToString() + ".jpeg2000 RegionData/" + regionID + "/images/" + assetID.ToString() + ".png"; process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; process.Start(); process.WaitForExit(); } }catch(Exception error) { Console.WriteLine("[" + downloadCounter + " / " + m_assets.Count + "] Download failed for asset " + assetID.ToString() + ": " + error.Message); } } } } } } }