RegionImages/src/GetRegionTextures.cs

200 lines
7.8 KiB
C#

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<UUID> m_assets = new List<UUID>();
private static List<MySQLPrimObject> getAllScenePrims(String regionID)
{
List<MySQLPrimObject> returnData = new List<MySQLPrimObject>();
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<String> getAllRegionIDsFromStorage()
{
List<String> returnData = new List<String>();
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<String> 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<MySQLPrimObject> 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<String> entrys = new List<String>();
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);
}
}
}
}
}
}
}