From a150ce2898641661400979a3db8734f35d9aa98d Mon Sep 17 00:00:00 2001 From: Chris Date: Mon, 4 Jan 2021 05:26:10 +0100 Subject: [PATCH] add files --- README.md | 2 - prebuild.xml | 44 ++++++++++ src/GetRegionTextures.cs | 167 ++++++++++++++++++++++++++++++++++++++ src/IDTools.cs | 168 +++++++++++++++++++++++++++++++++++++++ src/MySQLPrimObject.cs | 30 +++++++ src/SceneObjectGroup.cs | 85 ++++++++++++++++++++ 6 files changed, 494 insertions(+), 2 deletions(-) delete mode 100644 README.md create mode 100644 prebuild.xml create mode 100644 src/GetRegionTextures.cs create mode 100644 src/IDTools.cs create mode 100644 src/MySQLPrimObject.cs create mode 100644 src/SceneObjectGroup.cs diff --git a/README.md b/README.md deleted file mode 100644 index 11b6a19..0000000 --- a/README.md +++ /dev/null @@ -1,2 +0,0 @@ -# RegionImages - diff --git a/prebuild.xml b/prebuild.xml new file mode 100644 index 0000000..4b291a6 --- /dev/null +++ b/prebuild.xml @@ -0,0 +1,44 @@ + + + + + ../../bin/ + true + + + + + ../../bin/ + true + + + + ../../bin/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/GetRegionTextures.cs b/src/GetRegionTextures.cs new file mode 100644 index 0000000..afb6666 --- /dev/null +++ b/src/GetRegionTextures.cs @@ -0,0 +1,167 @@ +using MySql.Data.MySqlClient; +using Nini.Config; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Services.Connectors; +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://172.21.0.150:5738/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; + } + + + static void Main(string[] args) + { + if (!File.Exists("config-include/GridCommon.ini")) + return; + + IConfigSource source = new IniConfigSource("config-include/GridCommon.ini"); + + if (source.Configs["DatabaseService"] == null) + return; + + if (source.Configs["DatabaseService"].GetString("ConnectionString", null) == null) + return; + + 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); + } + } + } + } + } + } +} diff --git a/src/IDTools.cs b/src/IDTools.cs new file mode 100644 index 0000000..2a62152 --- /dev/null +++ b/src/IDTools.cs @@ -0,0 +1,168 @@ +using OpenMetaverse; +using OpenMetaverse.Assets; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading; +using System.Threading.Tasks; + +namespace GetRegionTextures +{ + class IDTools + { + public static void addToList(ref List _list, List _input) + { + foreach (String _entry in _input) + { + addToList(ref _list, _entry); + } + } + + public static void addToList(ref List _list, List _input) + { + foreach (TaskInventoryItemElement _entry in _input) + { + addToList(ref _list, _entry.AssetID.UUID); + } + } + + public static void addToList(ref List _list, String _input) + { + if (_input == "00000000-0000-0000-0000-000000000000") + return; + + if (_input == null) + return; + + if (!_list.Contains(_input)) + _list.Add(_input); + } + + public static List getUUIDListFromTexturEntry(String _base64) + { + List _ausgabe = new List(); + try + { + PrimObject obj = new PrimObject(); + + byte[] teData = Convert.FromBase64String(_base64); + obj.Textures = new Primitive.TextureEntry(teData, 0, teData.Length); + + foreach (Primitive.TextureEntryFace _face in obj.Textures.FaceTextures) + { + if (_face != null) + { + _ausgabe.Add(_face.TextureID.ToString()); + } + } + } + catch(Exception error) + { + Console.WriteLine("Cant decode textur data: " + error.Message); + } + return _ausgabe; + } + + public static List getUUIDListFromString(String _xml) + { + AppDomain.CurrentDomain.SetData("REGEX_DEFAULT_MATCH_TIMEOUT", TimeSpan.FromSeconds(10)); + List _ausgabe = new List(); + String _regex = @"[0-9A-Za-z]{8}-[0-9A-Za-z]{4}-[0-9A-Za-z]{4}-[0-9A-Za-z]{4}-[0-9A-Za-z]{12}"; + + try + { + Regex _suche = new Regex(_regex); + MatchCollection _funde = _suche.Matches(_xml); + + foreach (Match _f in _funde) + { + String _value = _f.Value.ToUpper().Trim(); + if (_value.Length < 75 && _value.Length > 10) + { + if (!_ausgabe.Contains(_value)) + { + _ausgabe.Add(_value); + } + } + } + } + catch (Exception _e) + { + Console.WriteLine(_e.ToString()); + Thread.Sleep(1000); + } + + return _ausgabe; + } + + + public static List getIDListFromSceneObjectGroup(SceneObjectGroup _group) + { + List _returnList = new List(); + + if (_group.RootPart.SceneObjectPart.CollisionSound != null) + { + if (_group.RootPart.SceneObjectPart.CollisionSound.UUID != null) + addToList(ref _returnList, _group.RootPart.SceneObjectPart.CollisionSound.UUID); + } + + if (_group.RootPart.SceneObjectPart.SoundID != null) + { + if (_group.RootPart.SceneObjectPart.SoundID.UUID != null) + addToList(ref _returnList, _group.RootPart.SceneObjectPart.SoundID.UUID); + } + + if (_group.RootPart.SceneObjectPart.Shape.SculptTexture != null) + { + if (_group.RootPart.SceneObjectPart.Shape.SculptTexture.UUID != null) + addToList(ref _returnList, _group.RootPart.SceneObjectPart.Shape.SculptTexture.UUID); + } + + if (_group.RootPart.SceneObjectPart.Shape != null) + { + if (_group.RootPart.SceneObjectPart.Shape.TextureEntry != null) + addToList(ref _returnList, getUUIDListFromTexturEntry(_group.RootPart.SceneObjectPart.Shape.TextureEntry)); + } + + if (_group.RootPart.SceneObjectPart.TaskInventory != null) + addToList(ref _returnList, _group.RootPart.SceneObjectPart.TaskInventory); + + if (_group.OtherParts != null) + { + foreach (PartElement _sope in _group.OtherParts) + { + if (_sope.SceneObjectPart.CollisionSound != null) + { + if (_sope.SceneObjectPart.CollisionSound.UUID != null) + addToList(ref _returnList, _sope.SceneObjectPart.CollisionSound.UUID); + } + + if (_sope.SceneObjectPart.SoundID != null) + { + if (_sope.SceneObjectPart.SoundID.UUID != null) + addToList(ref _returnList, _sope.SceneObjectPart.SoundID.UUID); + } + + if (_sope.SceneObjectPart.Shape.SculptTexture != null) + { + if (_sope.SceneObjectPart.Shape.SculptTexture.UUID != null) + addToList(ref _returnList, _sope.SceneObjectPart.Shape.SculptTexture.UUID); + } + + if (_sope.SceneObjectPart.Shape != null) + { + if (_sope.SceneObjectPart.Shape.TextureEntry != null) + addToList(ref _returnList, getUUIDListFromTexturEntry(_sope.SceneObjectPart.Shape.TextureEntry)); + } + + if (_sope.SceneObjectPart.TaskInventory != null) + addToList(ref _returnList, (_sope.SceneObjectPart.TaskInventory)); + } + } + + return _returnList; + } + } +} diff --git a/src/MySQLPrimObject.cs b/src/MySQLPrimObject.cs new file mode 100644 index 0000000..7980270 --- /dev/null +++ b/src/MySQLPrimObject.cs @@ -0,0 +1,30 @@ +using OpenMetaverse; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace GetRegionTextures +{ + class MySQLPrimObject + { + public String Name = null; + public String ID = null; + public byte[] RawTextueData = null; + public List Texture = new List(); + + public MySQLPrimObject(String name, String id) + { + Name = name; + ID = id; + } + + public MySQLPrimObject(String name, String id, byte[] texturedata) + { + Name = name; + ID = id; + RawTextueData = texturedata; + } + } +} diff --git a/src/SceneObjectGroup.cs b/src/SceneObjectGroup.cs new file mode 100644 index 0000000..215892a --- /dev/null +++ b/src/SceneObjectGroup.cs @@ -0,0 +1,85 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Xml.Serialization; + +namespace GetRegionTextures +{ + [Serializable()] + [XmlRoot] + public class SceneObjectGroup + { + [XmlElement("RootPart", typeof(RootPartElement))] + public RootPartElement RootPart { get; set; } + + [XmlArray("OtherParts")] + [XmlArrayItem("Part")] + public PartElement[] OtherParts { get; set; } + } + + [XmlRoot] + public class RootPartElement + { + [XmlElement("SceneObjectPart", typeof(SceneObjectPartElement))] + public SceneObjectPartElement SceneObjectPart { get; set; } + } + + [XmlRoot] + public class PartElement + { + [XmlElement("SceneObjectPart", typeof(SceneObjectPartElement))] + public SceneObjectPartElement SceneObjectPart { get; set; } + } + + [XmlRoot] + public class SceneObjectPartElement + { + [XmlElement("Name", typeof(String))] + public String Name { get; set; } + + [XmlElement("Shape", typeof(ShapeElement))] + public ShapeElement Shape { get; set; } + + [XmlElement("CollisionSound", typeof(UUIDEntry))] + public UUIDEntry CollisionSound { get; set; } + + [XmlElement("SoundID", typeof(UUIDEntry))] + public UUIDEntry SoundID { get; set; } + + [XmlArray("TaskInventory")] + [XmlArrayItem("TaskInventoryItem")] + public List TaskInventory { get; set; } + } + + [XmlRoot] + public class TaskInventoryItemElement + { + [XmlElement("Name", typeof(String))] + public String Name { get; set; } + + [XmlElement("AssetID", typeof(UUIDEntry))] + public UUIDEntry AssetID { get; set; } + } + + [XmlRoot] + public class ShapeElement + { + [XmlElement("TextureEntry", typeof(String))] + public String TextureEntry { get; set; } + + [XmlElement("ExtraParams", typeof(String))] + public String ExtraParams { get; set; } + + [XmlElement("SculptTexture", typeof(UUIDEntry))] + public UUIDEntry SculptTexture { get; set; } + } + + [XmlRoot] + public class UUIDEntry + { + [XmlElement("UUID", typeof(String))] + public String UUID { get; set; } + } +}