static void Main(string[] args) { if (args.Length != 8 && args.Length != 9) { Console.WriteLine("Usage: importprimscript.exe [firstname] [lastname] [password] " + "[loginuri] [Simulator] [x] [y] [z] [input.primscript]" + Environment.NewLine + "Example: importprimscript.exe My Bot password " + "Hooper 128 128 40 maya-export" + Path.DirectorySeparatorChar + "ant.primscript" + Environment.NewLine + "(the loginuri is optional and only used for logging in to another grid)"); Environment.Exit(-1); } // Strip quotes from any arguments for (int i = 0; i < args.Length; i++) { args[i] = args[i].Trim(new char[] { '"' }); } // Parse the primscript file string scriptfilename = args[args.Length - 1]; string error; List <Sculpt> sculpties = ParsePrimscript(scriptfilename, out error); scriptfilename = Path.GetFileNameWithoutExtension(scriptfilename); // Check for parsing errors if (error != String.Empty) { Console.WriteLine("An error was encountered reading the input file: " + error); Environment.Exit(-2); } else if (sculpties.Count == 0) { Console.WriteLine("No primitives were read from the input file"); Environment.Exit(-3); } // Add callback handlers for asset uploads finishing. new prims spotted, and logging Client.Objects.ObjectUpdate += new EventHandler <PrimEventArgs>(Objects_OnNewPrim); Logger.OnLogMessage += new Logger.LogCallback(Client_OnLogMessage); // Optimize the connection for our purposes Client.Self.Movement.Camera.Far = 64f; Client.Settings.MULTIPLE_SIMS = false; Client.Settings.SEND_AGENT_UPDATES = true; Settings.LOG_LEVEL = Helpers.LogLevel.None; Client.Settings.ALWAYS_REQUEST_OBJECTS = true; Client.Settings.ALWAYS_DECODE_OBJECTS = true; Client.Settings.THROTTLE_OUTGOING_PACKETS = false; Client.Throttle.Land = 0; Client.Throttle.Wind = 0; Client.Throttle.Cloud = 0; // Not sure if Asset or Texture will help with uploads, but it won't hurt Client.Throttle.Asset = 220000.0f; Client.Throttle.Texture = 446000.0f; Client.Throttle.Task = 446000.0f; // Create a handler for the event queue connecting, so we know when // it is safe to start uploading AutoResetEvent eventQueueEvent = new AutoResetEvent(false); EventHandler <EventQueueRunningEventArgs> eventQueueCallback = delegate(object sender, EventQueueRunningEventArgs e) { if (e.Simulator == Client.Network.CurrentSim) { eventQueueEvent.Set(); } }; Client.Network.EventQueueRunning += eventQueueCallback; int x = Int32.Parse(args[args.Length - 4]); int y = Int32.Parse(args[args.Length - 3]); int z = Int32.Parse(args[args.Length - 2]); string start = NetworkManager.StartLocation(args[args.Length - 5], x, y, z); LoginParams loginParams = Client.Network.DefaultLoginParams(args[0], args[1], args[2], "importprimscript", "1.4.0"); loginParams.Start = start; if (args.Length == 9) { loginParams.URI = args[3]; } // Attempt to login if (!Client.Network.Login(loginParams)) { Console.WriteLine("Login failed: " + Client.Network.LoginMessage); Environment.Exit(-4); } // Need to be connected to the event queue before we can upload Console.WriteLine("Login succeeded, waiting for the event handler to connect..."); if (!eventQueueEvent.WaitOne(1000 * 90, false)) { Console.WriteLine("Event queue connection timed out, disconnecting..."); Client.Network.Logout(); Environment.Exit(-5); } // Don't need this anymore Client.Network.EventQueueRunning -= eventQueueCallback; // Set the root position for the import RootPosition = Client.Self.SimPosition; RootPosition.Z += 3.0f; // TODO: Check if our account balance is high enough to upload everything // // Create a folder to hold all of our texture uploads UploadFolderID = Client.Inventory.CreateFolder(Client.Inventory.Store.RootFolder.UUID, scriptfilename); // Loop through each sculpty and do what we need to do for (int i = 0; i < sculpties.Count; i++) { // Upload the sculpt map and texture sculpties[i].SculptID = UploadImage(sculpties[i].SculptFile, true); sculpties[i].TextureID = UploadImage(sculpties[i].TextureFile, false); // Check for failed uploads if (sculpties[i].SculptID == UUID.Zero) { Console.WriteLine("Sculpt map " + sculpties[i].SculptFile + " failed to upload, skipping " + sculpties[i].Name); continue; } else if (sculpties[i].TextureID == UUID.Zero) { Console.WriteLine("Texture " + sculpties[i].TextureFile + " failed to upload, skipping " + sculpties[i].Name); continue; } // Create basic spherical volume parameters. It will be set to // a scultpy in the callback for new objects being created Primitive.ConstructionData volume = new Primitive.ConstructionData(); volume.PCode = PCode.Prim; volume.Material = Material.Wood; volume.PathScaleY = 0.5f; volume.PathCurve = PathCurve.Circle; volume.ProfileCurve = ProfileCurve.Circle; // Rez this prim CurrentSculpt = sculpties[i]; Client.Objects.AddPrim(Client.Network.CurrentSim, volume, UUID.Zero, RootPosition + CurrentSculpt.Offset, CurrentSculpt.Scale, Quaternion.Identity); // Wait for the prim to rez and the properties be set for it if (!RezzedEvent.WaitOne(1000 * 10, false)) { Console.WriteLine("Timed out waiting for prim " + CurrentSculpt.Name + " to rez, skipping"); continue; } } CurrentSculpt = null; lock (RezzedPrims) { // Set full permissions for all of the objects Client.Objects.SetPermissions(Client.Network.CurrentSim, RezzedPrims, PermissionWho.All, PermissionMask.All, true); // Link the entire object together Client.Objects.LinkPrims(Client.Network.CurrentSim, RezzedPrims); } Console.WriteLine("Rezzed, textured, and linked " + RezzedPrims.Count + " sculpted prims, logging out..."); Client.Network.Logout(); }
static List <Sculpt> ParsePrimscript(string primscriptfile, out string error) { string line; Sculpt current = null; List <Sculpt> sculpties = new List <Sculpt>(); error = String.Empty; StreamReader primscript = null; // Parse a directory out of the primscriptfile string, if one exists string path = Path.GetDirectoryName(primscriptfile); if (!String.IsNullOrEmpty(path)) { path += Path.DirectorySeparatorChar; } else { path = String.Empty; } try { primscript = File.OpenText(primscriptfile); while ((line = primscript.ReadLine()) != null) { string[] words = line.Split(new char[] { ' ' }); if (words.Length > 0) { if (current != null) { switch (words[0]) { case "newPrim": if (current.Scale != Vector3.Zero && !String.IsNullOrEmpty(current.SculptFile) && !String.IsNullOrEmpty(current.TextureFile)) { // Add the previous prim to the list as it is now finalized sculpties.Add(current); } // Start a new prim current = new Sculpt(); break; case "prim": // The only useful bit of information here is the prim name if (words.Length >= 3) { current.Name = words[2]; } break; case "shape": // This line has the name of the sculpt texture if (words.Length >= 3) { current.SculptFile = path + words[2] + ".bmp"; } break; case "texture": // This line has the name of the actual texture if (words.Length >= 3) { current.TextureFile = path + words[2] + ".bmp"; } break; case "transform": // Get some primitive params if (words.Length >= 9) { float x, y, z; x = Single.Parse(words[2], CultureInfo.InvariantCulture); y = Single.Parse(words[3], CultureInfo.InvariantCulture); z = Single.Parse(words[4], CultureInfo.InvariantCulture); current.Scale = new Vector3(x, y, z); x = Single.Parse(words[6], CultureInfo.InvariantCulture); y = Single.Parse(words[7], CultureInfo.InvariantCulture); z = Single.Parse(words[8], CultureInfo.InvariantCulture); current.Offset = new Vector3(x, y, z); } break; } } else if (words[0] == "newPrim") { // Start a new prim current = new Sculpt(); } } } // Add the final prim if (current != null && current.Scale != Vector3.Zero && !String.IsNullOrEmpty(current.SculptFile) && !String.IsNullOrEmpty(current.TextureFile)) { // Add the previous prim to the list as it is now finalized sculpties.Add(current); } } catch (Exception ex) { error = ex.ToString(); } finally { if (primscript != null) { primscript.Close(); } } return(sculpties); }
static List<Sculpt> ParsePrimscript(string primscriptfile, out string error) { string line; Sculpt current = null; List<Sculpt> sculpties = new List<Sculpt>(); error = String.Empty; StreamReader primscript = null; // Parse a directory out of the primscriptfile string, if one exists string path = Path.GetDirectoryName(primscriptfile); if (!String.IsNullOrEmpty(path)) path += Path.DirectorySeparatorChar; else path = String.Empty; try { primscript = File.OpenText(primscriptfile); while ((line = primscript.ReadLine()) != null) { string[] words = line.Split(new char[] { ' ' }); if (words.Length > 0) { if (current != null) { switch (words[0]) { case "newPrim": if (current.Scale != LLVector3.Zero && !String.IsNullOrEmpty(current.SculptFile) && !String.IsNullOrEmpty(current.TextureFile)) { // Add the previous prim to the list as it is now finalized sculpties.Add(current); } // Start a new prim current = new Sculpt(); break; case "prim": // The only useful bit of information here is the prim name if (words.Length >= 3) current.Name = words[2]; break; case "shape": // This line has the name of the sculpt texture if (words.Length >= 3) current.SculptFile = path + words[2] + ".bmp"; break; case "texture": // This line has the name of the actual texture if (words.Length >= 3) current.TextureFile = path + words[2] + ".bmp"; break; case "transform": // Get some primitive params if (words.Length >= 9) { float x, y, z; x = Single.Parse(words[2]); y = Single.Parse(words[3]); z = Single.Parse(words[4]); current.Scale = new LLVector3(x, y, z); x = Single.Parse(words[6]); y = Single.Parse(words[7]); z = Single.Parse(words[8]); current.Offset = new LLVector3(x, y, z); } break; } } else if (words[0] == "newPrim") { // Start a new prim current = new Sculpt(); } } } // Add the final prim if (current != null && current.Scale != LLVector3.Zero && !String.IsNullOrEmpty(current.SculptFile) && !String.IsNullOrEmpty(current.TextureFile)) { // Add the previous prim to the list as it is now finalized sculpties.Add(current); } } catch (Exception ex) { error = ex.ToString(); } finally { if (primscript != null) primscript.Close(); } return sculpties; }
static void Main(string[] args) { if (args.Length != 8 && args.Length != 9) { Console.WriteLine("Usage: importprimscript.exe [firstname] [lastname] [password] " + "[loginuri] [Simulator] [x] [y] [z] [input.primscript]" + Environment.NewLine + "Example: importprimscript.exe My Bot password " + "Hooper 128 128 40 maya-export" + Path.DirectorySeparatorChar + "ant.primscript" + Environment.NewLine + "(the loginuri is optional and only used for logging in to another grid)"); Environment.Exit(-1); } // Strip quotes from any arguments for (int i = 0; i < args.Length; i++) args[i] = args[i].Trim(new char[] { '"' }); // Parse the primscript file string scriptfilename = args[args.Length - 1]; string error; List<Sculpt> sculpties = ParsePrimscript(scriptfilename, out error); scriptfilename = Path.GetFileNameWithoutExtension(scriptfilename); // Check for parsing errors if (error != String.Empty) { Console.WriteLine("An error was encountered reading the input file: " + error); Environment.Exit(-2); } else if (sculpties.Count == 0) { Console.WriteLine("No primitives were read from the input file"); Environment.Exit(-3); } // Add callback handlers for asset uploads finishing. new prims spotted, and logging Client.Objects.OnNewPrim += new ObjectManager.NewPrimCallback(Objects_OnNewPrim); Client.OnLogMessage += new SecondLife.LogCallback(Client_OnLogMessage); // Optimize the connection for our purposes Client.Self.Movement.Camera.Far = 64f; Client.Settings.MULTIPLE_SIMS = false; Client.Settings.SEND_AGENT_UPDATES = true; Client.Settings.CONTINUOUS_AGENT_UPDATES = true; Client.Settings.DEBUG = false; Client.Settings.ALWAYS_REQUEST_OBJECTS = true; Client.Settings.ALWAYS_DECODE_OBJECTS = true; Client.Throttle.Land = 0; Client.Throttle.Wind = 0; Client.Throttle.Cloud = 0; // Not sure if Asset or Texture will help with uploads, but it won't hurt Client.Throttle.Asset = 220000.0f; Client.Throttle.Texture = 446000.0f; Client.Throttle.Task = 446000.0f; // Create a handler for the event queue connecting, so we know when // it is safe to start uploading AutoResetEvent eventQueueEvent = new AutoResetEvent(false); NetworkManager.EventQueueRunningCallback eventQueueCallback = delegate(Simulator simulator) { if (simulator == Client.Network.CurrentSim) eventQueueEvent.Set(); }; Client.Network.OnEventQueueRunning += eventQueueCallback; int x = Int32.Parse(args[args.Length - 4]); int y = Int32.Parse(args[args.Length - 3]); int z = Int32.Parse(args[args.Length - 2]); string start = NetworkManager.StartLocation(args[args.Length - 5], x, y, z); LoginParams loginParams = Client.Network.DefaultLoginParams(args[0], args[1], args[2], "importprimscript", "1.4.0"); loginParams.Start = start; if (args.Length == 9) loginParams.URI = args[3]; // Attempt to login if (!Client.Network.Login(loginParams)) { Console.WriteLine("Login failed: " + Client.Network.LoginMessage); Environment.Exit(-4); } // Need to be connected to the event queue before we can upload Console.WriteLine("Login succeeded, waiting for the event handler to connect..."); if (!eventQueueEvent.WaitOne(1000 * 90, false)) { Console.WriteLine("Event queue connection timed out, disconnecting..."); Client.Network.Logout(); Environment.Exit(-5); } // Don't need this anymore Client.Network.OnEventQueueRunning -= eventQueueCallback; // Set the root position for the import RootPosition = Client.Self.SimPosition; RootPosition.Z += 3.0f; // TODO: Check if our account balance is high enough to upload everything // // Create a folder to hold all of our texture uploads UploadFolderID = Client.Inventory.CreateFolder(Client.Inventory.Store.RootFolder.UUID, scriptfilename); // Loop through each sculpty and do what we need to do for (int i = 0; i < sculpties.Count; i++) { // Upload the sculpt map and texture sculpties[i].SculptID = UploadImage(sculpties[i].SculptFile, true); sculpties[i].TextureID = UploadImage(sculpties[i].TextureFile, false); // Check for failed uploads if (sculpties[i].SculptID == LLUUID.Zero) { Console.WriteLine("Sculpt map " + sculpties[i].SculptFile + " failed to upload, skipping " + sculpties[i].Name); continue; } else if (sculpties[i].TextureID == LLUUID.Zero) { Console.WriteLine("Texture " + sculpties[i].TextureFile + " failed to upload, skipping " + sculpties[i].Name); continue; } // Create basic spherical volume parameters. It will be set to // a scultpy in the callback for new objects being created LLObject.ObjectData volume = new LLObject.ObjectData(); volume.PCode = PCode.Prim; volume.Material = LLObject.MaterialType.Wood; volume.PathScaleY = 0.5f; volume.PathCurve = LLObject.PathCurve.Circle; volume.ProfileCurve = LLObject.ProfileCurve.Circle; // Rez this prim CurrentSculpt = sculpties[i]; Client.Objects.AddPrim(Client.Network.CurrentSim, volume, LLUUID.Zero, RootPosition + CurrentSculpt.Offset, CurrentSculpt.Scale, LLQuaternion.Identity); // Wait for the prim to rez and the properties be set for it if (!RezzedEvent.WaitOne(1000 * 10, false)) { Console.WriteLine("Timed out waiting for prim " + CurrentSculpt.Name + " to rez, skipping"); continue; } } CurrentSculpt = null; lock (RezzedPrims) { // Set full permissions for all of the objects Client.Objects.SetPermissions(Client.Network.CurrentSim, RezzedPrims, PermissionWho.All, PermissionMask.All, true); // Link the entire object together Client.Objects.LinkPrims(Client.Network.CurrentSim, RezzedPrims); } Console.WriteLine("Rezzed, textured, and linked " + RezzedPrims.Count + " sculpted prims, logging out..."); Client.Network.Logout(); }
static void Main(string[] args) { if (args.Length != 8) { Console.WriteLine("Usage: importprimscript.exe [firstname] [lastname] [password] " + "[Simulator] [x] [y] [z] [input.primscript]" + Environment.NewLine + "Example: importprimscript.exe My Bot password " + "Hooper 128 128 40 maya-export" + Path.DirectorySeparatorChar + "ant.primscript"); Environment.Exit(-1); } // Strip quotes from any arguments for (int i = 0; i < args.Length; i++) args[i] = args[i].Trim(new char[] { '"' }); // Parse the primscript file string error; List<Sculpt> sculpties = ParsePrimscript(args[7], out error); // Check for parsing errors if (error != String.Empty) { Console.WriteLine("An error was encountered reading the input file: " + error); Environment.Exit(-2); } else if (sculpties.Count == 0) { Console.WriteLine("No primitives were read from the input file"); Environment.Exit(-3); } // Initialize libsecondlife Client = new SecondLife(); Assets = new AssetManager(Client); // Add callback handlers for asset uploads finishing. new prims spotted, and logging Assets.OnAssetUploaded += new AssetManager.AssetUploadedCallback(Assets_OnAssetUploaded); Client.Objects.OnNewPrim += new ObjectManager.NewPrimCallback(Objects_OnNewPrim); Client.OnLogMessage += new SecondLife.LogCallback(Client_OnLogMessage); // Optimize the connection for our purposes Client.Self.Status.Camera.Far = 32.0f; Client.Settings.MULTIPLE_SIMS = false; Client.Settings.SEND_AGENT_UPDATES = true; Client.Settings.ENABLE_CAPS = false; Client.Settings.DEBUG = false; Client.Settings.ENABLE_SIMSTATS = false; Client.Settings.ALWAYS_REQUEST_OBJECTS = true; Client.Settings.ALWAYS_DECODE_OBJECTS = true; Client.Throttle.Land = 0; Client.Throttle.Wind = 0; Client.Throttle.Cloud = 0; // Not sure if Asset or Texture will help with uploads, but it won't hurt Client.Throttle.Asset = 220000.0f; Client.Throttle.Texture = 446000.0f; Client.Throttle.Task = 446000.0f; int x = Int32.Parse(args[4]); int y = Int32.Parse(args[5]); int z = Int32.Parse(args[6]); string start = NetworkManager.StartLocation(args[3], x, y, z); // Attempt to login if (!Client.Network.Login(args[0], args[1], args[2], "importprimscript 1.0.0", start, "John Hurliman <*****@*****.**>")) { Console.WriteLine("Login failed: " + Client.Network.LoginMessage); Environment.Exit(-4); } // Wait a moment for the initial flood of packets to die down Console.WriteLine("Login succeeded, pausing for a moment..."); System.Threading.Thread.Sleep(1000 * 10); // Set the root position for the import RootPosition = Client.Self.Position; RootPosition.Z += 3.0f; for (int i = 0; i < sculpties.Count; i++) { // Upload the sculpt map and texture sculpties[i].SculptID = UploadImage(sculpties[i].SculptFile, true); sculpties[i].TextureID = UploadImage(sculpties[i].TextureFile, false); // Check for failed uploads if (sculpties[i].SculptID == LLUUID.Zero) { Client.Log("Sculpt map " + sculpties[i].SculptFile + " failed to upload, skipping " + sculpties[i].Name, Helpers.LogLevel.Warning); continue; } else if (sculpties[i].TextureID == LLUUID.Zero) { Client.Log("Texture " + sculpties[i].TextureFile + " failed to upload, skipping " + sculpties[i].Name, Helpers.LogLevel.Warning); continue; } LLObject.ObjectData prim = new LLObject.ObjectData(); prim.PCode = ObjectManager.PCode.Prim; prim.Material = LLObject.MaterialType.Wood; prim.PathScaleY = 0.5f; prim.PathCurve = 32; // Rez this prim CurrentSculpt = sculpties[i]; Client.Objects.AddPrim(Client.Network.CurrentSim, prim, LLUUID.Zero, RootPosition + CurrentSculpt.Offset, CurrentSculpt.Scale, LLQuaternion.Identity); // Wait for the prim to rez and the properties be set for it if (!RezzedEvent.WaitOne(1000 * 10, false)) { Console.WriteLine("Timed out waiting for prim " + CurrentSculpt.Name + " to rez, skipping"); continue; } } CurrentSculpt = null; lock (RezzedPrims) { // Set the permissions Client.Objects.SetPermissions(Client.Network.CurrentSim, RezzedPrims, PermissionWho.All, PermissionMask.All, true); // Link the object together Client.Objects.LinkPrims(Client.Network.CurrentSim, RezzedPrims); } Console.WriteLine("Rezzed, textured, and linked " + RezzedPrims.Count + " sculpted prims, logging out..."); Client.Network.Logout(); }