/// <summary> /// /// </summary> /// <param name="mapFile"></param> private void LoadMapFile(string mapFile) { FileStream map; ushort low = 1; ushort medium = 1; ushort high = 1; // Load the protocol map file try { map = new FileStream(mapFile, FileMode.Open, FileAccess.Read); } catch (Exception e) { throw new Exception("Map file error", e); } try { StreamReader r = new StreamReader(map); r.BaseStream.Seek(0, SeekOrigin.Begin); string newline; string trimmedline; bool inPacket = false; bool inBlock = false; MapPacket currentPacket = null; MapBlock currentBlock = null; char[] trimArray = new char[] { ' ', '\t' }; // While not at the end of the file while (r.Peek() > -1) { #region ParseMap newline = r.ReadLine(); trimmedline = System.Text.RegularExpressions.Regex.Replace(newline, @"\s+", " "); trimmedline = trimmedline.Trim(trimArray); if (!inPacket) { // Outside of all packet blocks if (trimmedline == "{") { inPacket = true; } } else { // Inside of a packet block if (!inBlock) { // Inside a packet block, outside of the blocks if (trimmedline == "{") { inBlock = true; } else if (trimmedline == "}") { // Reached the end of the packet currentPacket.Blocks.Sort(); inPacket = false; } else { // The packet header #region ParsePacketHeader // Splice the string in to tokens string[] tokens = trimmedline.Split(new char[] { ' ', '\t' }); if (tokens.Length > 3) { //Hash packet name to insure correct keyword ordering KeywordPosition(tokens[0]); if (tokens[1] == "Fixed") { // Remove the leading "0x" if (tokens[2].Substring(0, 2) == "0x") { tokens[2] = tokens[2].Substring(2, tokens[2].Length - 2); } uint fixedID = UInt32.Parse(tokens[2], System.Globalization.NumberStyles.HexNumber); // Truncate the id to a short fixedID ^= 0xFFFF0000; LowMaps[fixedID] = new MapPacket(); LowMaps[fixedID].ID = (ushort)fixedID; LowMaps[fixedID].Frequency = PacketFrequency.Low; LowMaps[fixedID].Name = tokens[0]; LowMaps[fixedID].Trusted = (tokens[3] == "Trusted"); LowMaps[fixedID].Encoded = (tokens[4] == "Zerocoded"); LowMaps[fixedID].Blocks = new List <MapBlock>(); currentPacket = LowMaps[fixedID]; } else if (tokens[1] == "Low") { LowMaps[low] = new MapPacket(); LowMaps[low].ID = low; LowMaps[low].Frequency = PacketFrequency.Low; LowMaps[low].Name = tokens[0]; LowMaps[low].Trusted = (tokens[2] == "Trusted"); LowMaps[low].Encoded = (tokens[3] == "Zerocoded"); LowMaps[low].Blocks = new List <MapBlock>(); currentPacket = LowMaps[low]; low++; } else if (tokens[1] == "Medium") { MediumMaps[medium] = new MapPacket(); MediumMaps[medium].ID = medium; MediumMaps[medium].Frequency = PacketFrequency.Medium; MediumMaps[medium].Name = tokens[0]; MediumMaps[medium].Trusted = (tokens[2] == "Trusted"); MediumMaps[medium].Encoded = (tokens[3] == "Zerocoded"); MediumMaps[medium].Blocks = new List <MapBlock>(); currentPacket = MediumMaps[medium]; medium++; } else if (tokens[1] == "High") { HighMaps[high] = new MapPacket(); HighMaps[high].ID = high; HighMaps[high].Frequency = PacketFrequency.High; HighMaps[high].Name = tokens[0]; HighMaps[high].Trusted = (tokens[2] == "Trusted"); HighMaps[high].Encoded = (tokens[3] == "Zerocoded"); HighMaps[high].Blocks = new List <MapBlock>(); currentPacket = HighMaps[high]; high++; } else { Client.Log("Unknown packet frequency", Helpers.LogLevel.Error); } } #endregion } } else { if (trimmedline.Length > 0 && trimmedline.Substring(0, 1) == "{") { // A field #region ParseField MapField field = new MapField(); // Splice the string in to tokens string[] tokens = trimmedline.Split(new char[] { ' ', '\t' }); field.Name = tokens[1]; field.KeywordPosition = KeywordPosition(field.Name); field.Type = (FieldType)Enum.Parse(typeof(FieldType), tokens[2], true); if (tokens[3] != "}") { field.Count = Int32.Parse(tokens[3]); } else { field.Count = 1; } // Save this field to the current block currentBlock.Fields.Add(field); #endregion } else if (trimmedline == "}") { currentBlock.Fields.Sort(); inBlock = false; } else if (trimmedline.Length != 0 && trimmedline.Substring(0, 2) != "//") { // The block header #region ParseBlockHeader currentBlock = new MapBlock(); // Splice the string in to tokens string[] tokens = trimmedline.Split(new char[] { ' ', '\t' }); currentBlock.Name = tokens[0]; currentBlock.KeywordPosition = KeywordPosition(currentBlock.Name); currentBlock.Fields = new List <MapField>(); currentPacket.Blocks.Add(currentBlock); if (tokens[1] == "Single") { currentBlock.Count = 1; } else if (tokens[1] == "Multiple") { currentBlock.Count = Int32.Parse(tokens[2]); } else if (tokens[1] == "Variable") { currentBlock.Count = -1; } else { Client.Log("Unknown block frequency", Helpers.LogLevel.Error); } #endregion } } } #endregion } r.Close(); map.Close(); } catch (Exception e) { throw e; } }
public static bool PersistentLogin(SecondLife client, string firstName, string lastName, string password, string userAgent, string start, string author) { int unknownLogins = 0; Start: if (client.Network.Login(firstName, lastName, password, userAgent, start, author)) { client.Log("Logged in to " + client.Network.CurrentSim, Helpers.LogLevel.Info); return true; } else { if (client.Network.LoginErrorKey == "god") { client.Log("Grid is down, waiting 10 minutes", Helpers.LogLevel.Warning); LoginWait(10); goto Start; } else if (client.Network.LoginErrorKey == "key") { client.Log("Bad username or password, giving up on login", Helpers.LogLevel.Error); return false; } else if (client.Network.LoginErrorKey == "presence") { client.Log("Server is still logging us out, waiting 1 minute", Helpers.LogLevel.Warning); LoginWait(1); goto Start; } else if (client.Network.LoginErrorKey == "disabled") { client.Log("This account has been banned! Giving up on login", Helpers.LogLevel.Error); return false; } else if (client.Network.LoginErrorKey == "timed out") { client.Log("Login request timed out, waiting 1 minute", Helpers.LogLevel.Warning); LoginWait(1); goto Start; } else { ++unknownLogins; if (unknownLogins < 5) { client.Log("Unknown login error, waiting 2 minutes: " + client.Network.LoginErrorKey, Helpers.LogLevel.Warning); LoginWait(2); goto Start; } else { client.Log("Too many unknown login error codes, giving up", Helpers.LogLevel.Error); return false; } } } }
/// <summary> /// Process an incoming effect /// </summary> private void ViewerEffectHandler(Packet packet, Simulator simulator) { ViewerEffectPacket effect = (ViewerEffectPacket)packet; foreach (ViewerEffectPacket.EffectBlock block in effect.Effect) { EffectType type = (EffectType)block.Type; //LLColor color; //if (block.Color.Length == 4) //{ // color = new LLColor(block.Color, 0); //} //else //{ // Client.Log("Received a ViewerEffect.EffectBlock.Color array with " + block.Color.Length + // " bytes", Helpers.LogLevel.Warning); // color = LLColor.Black; //} // Each ViewerEffect type uses it's own custom binary format for additional data. Fun eh? switch (type) { case EffectType.Text: Client.Log("Received a ViewerEffect of type " + type.ToString() + ", implement me!", Helpers.LogLevel.Warning); break; case EffectType.Icon: Client.Log("Received a ViewerEffect of type " + type.ToString() + ", implement me!", Helpers.LogLevel.Warning); break; case EffectType.Connector: Client.Log("Received a ViewerEffect of type " + type.ToString() + ", implement me!", Helpers.LogLevel.Warning); break; case EffectType.FlexibleObject: Client.Log("Received a ViewerEffect of type " + type.ToString() + ", implement me!", Helpers.LogLevel.Warning); break; case EffectType.AnimalControls: Client.Log("Received a ViewerEffect of type " + type.ToString() + ", implement me!", Helpers.LogLevel.Warning); break; case EffectType.AnimationObject: Client.Log("Received a ViewerEffect of type " + type.ToString() + ", implement me!", Helpers.LogLevel.Warning); break; case EffectType.Cloth: Client.Log("Received a ViewerEffect of type " + type.ToString() + ", implement me!", Helpers.LogLevel.Warning); break; case EffectType.Glow: Client.Log("Received a Glow ViewerEffect which is not implemented yet", Helpers.LogLevel.Warning); break; case EffectType.Beam: case EffectType.Point: case EffectType.Trail: case EffectType.Sphere: case EffectType.Spiral: case EffectType.Edit: if (OnEffect != null) { if (block.TypeData.Length == 56) { LLUUID sourceAvatar = new LLUUID(block.TypeData, 0); LLUUID targetObject = new LLUUID(block.TypeData, 16); LLVector3d targetPos = new LLVector3d(block.TypeData, 32); try { OnEffect(type, sourceAvatar, targetObject, targetPos, block.Duration, block.ID); } catch (Exception e) { Client.Log(e.ToString(), Helpers.LogLevel.Error); } } else { Client.Log("Received a " + type.ToString() + " ViewerEffect with an incorrect TypeData size of " + block.TypeData.Length + " bytes", Helpers.LogLevel.Warning); } } break; case EffectType.LookAt: if (OnLookAt != null) { if (block.TypeData.Length == 57) { LLUUID sourceAvatar = new LLUUID(block.TypeData, 0); LLUUID targetObject = new LLUUID(block.TypeData, 16); LLVector3d targetPos = new LLVector3d(block.TypeData, 32); LookAtType lookAt = (LookAtType)block.TypeData[56]; try { OnLookAt(sourceAvatar, targetObject, targetPos, lookAt, block.Duration, block.ID); } catch (Exception e) { Client.Log(e.ToString(), Helpers.LogLevel.Error); } } else { Client.Log("Received a LookAt ViewerEffect with an incorrect TypeData size of " + block.TypeData.Length + " bytes", Helpers.LogLevel.Warning); } } break; case EffectType.PointAt: if (OnPointAt != null) { if (block.TypeData.Length == 57) { LLUUID sourceAvatar = new LLUUID(block.TypeData, 0); LLUUID targetObject = new LLUUID(block.TypeData, 16); LLVector3d targetPos = new LLVector3d(block.TypeData, 32); PointAtType pointAt = (PointAtType)block.TypeData[56]; try { OnPointAt(sourceAvatar, targetObject, targetPos, pointAt, block.Duration, block.ID); } catch (Exception e) { Client.Log(e.ToString(), Helpers.LogLevel.Error); } } else { Client.Log("Received a PointAt ViewerEffect with an incorrect TypeData size of " + block.TypeData.Length + " bytes", Helpers.LogLevel.Warning); } } break; default: Client.Log("Received a ViewerEffect with an unknown type " + type, Helpers.LogLevel.Warning); break; } } }
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(); }
/// <summary> /// Connect to a simulator /// </summary> /// <param name="ip">IP address to connect to</param> /// <param name="port">Port to connect to</param> /// <param name="handle">Handle for this simulator, to identify its /// location in the grid</param> /// <param name="setDefault">Whether to set CurrentSim to this new /// connection, use this if the avatar is moving in to this simulator</param> /// <param name="seedcaps">URL of the capabilities server to use for /// this sim connection</param> /// <returns>A Simulator object on success, otherwise null</returns> public Simulator Connect(IPAddress ip, ushort port, ulong handle, bool setDefault, string seedcaps) { IPEndPoint endPoint = new IPEndPoint(ip, (int)port); Simulator simulator = FindSimulator(endPoint); if (simulator == null) { // We're not tracking this sim, create a new Simulator object simulator = new Simulator(Client, endPoint, handle); // Immediately add this simulator to the list of current sims. It will be removed if the // connection fails lock (Simulators) Simulators.Add(simulator); } if (!simulator.Connected) { if (!connected) { // Mark that we are connecting/connected to the grid connected = true; // Start the packet decoding thread Thread decodeThread = new Thread(new ThreadStart(PacketHandler)); decodeThread.Start(); } // Fire the OnSimConnecting event if (OnSimConnecting != null) { try { if (!OnSimConnecting(simulator)) { // Callback is requesting that we abort this connection lock (Simulators) Simulators.Remove(simulator); return(null); } } catch (Exception e) { Client.Log(e.ToString(), Helpers.LogLevel.Error); } } // Attempt to establish a connection to the simulator if (simulator.Connect(setDefault)) { if (DisconnectTimer == null) { // Start a timer that checks if we've been disconnected DisconnectTimer = new Timer(new TimerCallback(DisconnectTimer_Elapsed), null, Client.Settings.SIMULATOR_TIMEOUT, Client.Settings.SIMULATOR_TIMEOUT); } if (setDefault) { SetCurrentSim(simulator, seedcaps); } // Fire the simulator connection callback if one is registered if (OnSimConnected != null) { try { OnSimConnected(simulator); } catch (Exception e) { Client.Log(e.ToString(), Helpers.LogLevel.Error); } } // If enabled, send an AgentThrottle packet to the server to increase our bandwidth if (Client.Settings.SEND_AGENT_THROTTLE) { Client.Throttle.Set(simulator); } return(simulator); } else { // Connection failed, remove this simulator from our list and destroy it lock (Simulators) Simulators.Remove(simulator); return(null); } } else if (setDefault) { // We're already connected to this server, but need to set it to the default SetCurrentSim(simulator, seedcaps); // Move in to this simulator Client.Self.CompleteAgentMovement(simulator); // Send an initial AgentUpdate to complete our movement in to the sim if (Client.Settings.SEND_AGENT_UPDATES) { Client.Self.Movement.SendUpdate(true, simulator); } return(simulator); } else { // Already connected to this simulator and wasn't asked to set it as the default, // just return a reference to the existing object return(simulator); } }
/// <summary> /// /// </summary> /// <param name="client"></param> /// <param name="callbacks"></param> /// <param name="circuit"></param> /// <param name="ip"></param> /// <param name="port"></param> public Simulator(SecondLife client, Dictionary<PacketType,List<PacketCallback>> callbacks, uint circuit, IPAddress ip, int port) { Client = client; Network = client.Network; Callbacks = callbacks; Region = new Region(client); circuitCode = circuit; Sequence = 0; RecvBuffer = new byte[2048]; Connection = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); connected = false; DisconnectCandidate = false; AckTimer = new System.Timers.Timer(500); AckTimer.Elapsed += new ElapsedEventHandler(AckTimer_Elapsed); // Initialize the dictionary for reliable packets waiting on ACKs from the server NeedAck = new Dictionary<int, Packet>(); // Initialize the lists of sequence numbers we've received so far Inbox = new Queue<ushort>(INBOX_SIZE); PendingAcks = new List<uint>(); Client.Log("Connecting to " + ip.ToString() + ":" + port, Helpers.LogLevel.Info); try { // Setup the callback ReceivedData = new AsyncCallback(OnReceivedData); // Create an endpoint that we will be communicating with (need it in two // types due to .NET weirdness) ipEndPoint = new IPEndPoint(ip, port); endPoint = (EndPoint)ipEndPoint; // Associate this simulator's socket with the given ip/port and start listening Connection.Connect(endPoint); Connection.BeginReceiveFrom(RecvBuffer, 0, RecvBuffer.Length, SocketFlags.None, ref endPoint, ReceivedData, null); // Send the UseCircuitCode packet to initiate the connection UseCircuitCodePacket use = new UseCircuitCodePacket(); use.CircuitCode.Code = circuitCode; use.CircuitCode.ID = Network.AgentID; use.CircuitCode.SessionID = Network.SessionID; // Start the ACK timer AckTimer.Start(); // Send the initial packet out SendPacket(use, true); // Track the current time for timeout purposes int start = Environment.TickCount; while (true) { if (connected || Environment.TickCount - start > 8000) { return; } System.Threading.Thread.Sleep(10); } } catch (Exception e) { Console.WriteLine(e.ToString()); Client.Log(e.ToString(), Helpers.LogLevel.Error); } }
private static bool ReadCategoryMember(SecondLife client, XmlReader reader, out int categoryID, out string categoryName) { categoryID = 0; categoryName = String.Empty; bool ret = false; if (reader.IsStartElement("value")) { reader.ReadStartElement("value"); if (reader.IsStartElement("struct")) { reader.ReadStartElement("struct"); string name; while (reader.IsStartElement("member")) { reader.ReadStartElement("member"); name = reader.ReadElementString("name"); switch (name) { case "category_id": categoryID = ReadIntegerValue(reader); break; case "category_name": categoryName = ReadStringValue(reader); break; default: client.Log("Unhandled element in login reply (CategoryMember)", Helpers.LogLevel.Error); reader.Skip(); break; } reader.ReadEndElement(); } reader.ReadEndElement(); ret = true; } reader.ReadEndElement(); } return ret; }
private static bool ReadBuddyMember(SecondLife client, XmlReader reader, out int buddyRightsGiven, out int buddyRightsHas, out LLUUID buddyID) { buddyRightsGiven = 0; buddyRightsHas = 0; buddyID = LLUUID.Zero; bool ret = false; if (reader.IsStartElement("value")) { reader.ReadStartElement("value"); if (reader.IsStartElement("struct")) { reader.ReadStartElement("struct"); string name; while (reader.IsStartElement("member")) { reader.ReadStartElement("member"); name = reader.ReadElementString("name"); switch (name) { case "buddy_rights_given": buddyRightsGiven = ReadIntegerValue(reader); break; case "buddy_id": string buddy = ReadStringValue(reader); LLUUID.TryParse(buddy, out buddyID); break; case "buddy_rights_has": buddyRightsHas = ReadIntegerValue(reader); break; default: client.Log("Unhandled element in login reply (BuddyMember)", Helpers.LogLevel.Error); reader.Skip(); break; } reader.ReadEndElement(); } reader.ReadEndElement(); ret = true; } reader.ReadEndElement(); } return ret; }
/// <summary> /// </summary> /// <param name="client"></param> /// <param name="ctype">The type of Cache system to use for images.</param> /// <param name="directory">The directory to use for disk based caching.</param> private void Init(SecondLife client, CacheTypes ctype, string directory) { slClient = client; // Setup Image Caching CacheType = ctype; if (ctype == CacheTypes.Disk) { if (directory != null) { CacheDirectory = directory; } try { if (!Directory.Exists(CacheDirectory)) { Directory.CreateDirectory(CacheDirectory); } } catch (Exception e) { slClient.Log("Disk Cache directory could not be established, defaulting to Memory Cache: " + Environment.NewLine + e.ToString(), Helpers.LogLevel.Warning); CacheType = CacheTypes.Memory; } } // Image Packet Helpers ImagePacketHelper = new ImagePacketHelpers(client); // Image Callbacks slClient.Network.RegisterCallback(PacketType.ImageData, new NetworkManager.PacketCallback(ImageDataCallbackHandler)); slClient.Network.RegisterCallback(PacketType.ImagePacket, new NetworkManager.PacketCallback(ImagePacketCallbackHandler)); slClient.Network.RegisterCallback(PacketType.ImageNotInDatabase, new NetworkManager.PacketCallback(ImageNotInDatabaseCallbackHandler)); }
/// <summary> /// Initiate an image download. This is an asynchronous function /// </summary> /// <param name="imageID">The image to download</param> /// <param name="type">Type of the image to download, either a baked /// avatar texture or a normal texture</param> /// <param name="priority">Priority level of the download. Default is /// <code>1,013,000.0f</code></param> /// <param name="discardLevel">Number of quality layers to discard</param> public void RequestImage(LLUUID imageID, ImageType type, float priority, int discardLevel) { if (!Transfers.ContainsKey(imageID)) { ImageDownload transfer = new ImageDownload(); //transfer.AssetType = AssetType.Texture // Handled in ImageDataHandler. transfer.ID = imageID; transfer.Simulator = Client.Network.CurrentSim; // Add this transfer to the dictionary lock (Transfers) Transfers[transfer.ID] = transfer; // Build and send the request packet RequestImagePacket request = new RequestImagePacket(); request.AgentData.AgentID = Client.Self.AgentID; request.AgentData.SessionID = Client.Self.SessionID; request.RequestImage = new RequestImagePacket.RequestImageBlock[1]; request.RequestImage[0] = new RequestImagePacket.RequestImageBlock(); request.RequestImage[0].DiscardLevel = (sbyte)discardLevel; request.RequestImage[0].DownloadPriority = priority; request.RequestImage[0].Packet = 0; request.RequestImage[0].Image = imageID; request.RequestImage[0].Type = (byte)type; Client.Network.SendPacket(request, transfer.Simulator); } else { Client.Log("RequestImage() called for an image we are already downloading, ignoring", Helpers.LogLevel.Info); } }
public Inventory(SecondLife client, InventoryManager manager, LLUUID owner) { Client = client; Manager = manager; _Owner = owner; if (owner == LLUUID.Zero) client.Log("Inventory owned by nobody!", Helpers.LogLevel.Warning); Items = new Dictionary<LLUUID, InventoryNode>(); }
/// <summary> /// Attempt to connect to this simulator /// </summary> /// <param name="moveToSim">Whether to move our agent in to this sim or not</param> /// <returns>True if the connection succeeded or connection status is /// unknown, false if there was a failure</returns> public bool Connect(bool moveToSim) { if (connected) { Client.Self.CompleteAgentMovement(this); return(true); } #region Start Timers // Destroy the timers if (AckTimer != null) { AckTimer.Dispose(); } if (StatsTimer != null) { StatsTimer.Dispose(); } if (PingTimer != null) { PingTimer.Dispose(); } // Timer for sending out queued packet acknowledgements AckTimer = new Timer(new TimerCallback(AckTimer_Elapsed), null, Settings.NETWORK_TICK_INTERVAL, Settings.NETWORK_TICK_INTERVAL); // Timer for recording simulator connection statistics StatsTimer = new Timer(new TimerCallback(StatsTimer_Elapsed), null, 1000, 1000); // Timer for periodically pinging the simulator if (Client.Settings.SEND_PINGS) { PingTimer = new Timer(new TimerCallback(PingTimer_Elapsed), null, Settings.PING_INTERVAL, Settings.PING_INTERVAL); } #endregion Start Timers Client.Log("Connecting to " + this.ToString(), Helpers.LogLevel.Info); try { // Create the UDP connection Start(); // Mark ourselves as connected before firing everything else up connected = true; // Send the UseCircuitCode packet to initiate the connection UseCircuitCodePacket use = new UseCircuitCodePacket(); use.CircuitCode.Code = Network.CircuitCode; use.CircuitCode.ID = Client.Self.AgentID; use.CircuitCode.SessionID = Client.Self.SessionID; // Send the initial packet out SendPacket(use, true); Stats.ConnectTime = Environment.TickCount; // Move our agent in to the sim to complete the connection if (moveToSim) { Client.Self.CompleteAgentMovement(this); } if (Client.Settings.SEND_AGENT_UPDATES) { Client.Self.Movement.SendUpdate(true, this); } if (!ConnectedEvent.WaitOne(Client.Settings.SIMULATOR_TIMEOUT, false)) { Client.Log("Giving up on waiting for RegionHandshake for " + this.ToString(), Helpers.LogLevel.Warning); } return(true); } catch (Exception e) { Client.Log(e.ToString(), Helpers.LogLevel.Error); } return(false); }
/// <summary> /// Constructor for Simulator /// </summary> /// <param name="client"></param> /// <param name="callbacks"></param> /// <param name="circuit"></param> /// <param name="ip"></param> /// <param name="port"></param> public Simulator(SecondLife client, Dictionary<PacketType, List<NetworkManager.PacketCallback>> callbacks, uint circuit, IPAddress ip, int port) { Client = client; Network = client.Network; Callbacks = callbacks; Region = new Region(client); circuitCode = circuit; Inbox = new Queue<uint>(Client.Settings.INBOX_SIZE); AckTimer = new System.Timers.Timer(Client.Settings.NETWORK_TICK_LENGTH); AckTimer.Elapsed += new ElapsedEventHandler(AckTimer_Elapsed); // Initialize the callback for receiving a new packet ReceivedData = new AsyncCallback(OnReceivedData); Client.Log("Connecting to " + ip.ToString() + ":" + port, Helpers.LogLevel.Info); try { // Create an endpoint that we will be communicating with (need it in two // types due to .NET weirdness) ipEndPoint = new IPEndPoint(ip, port); endPoint = (EndPoint)ipEndPoint; // Associate this simulator's socket with the given ip/port and start listening Connection.Connect(endPoint); Connection.BeginReceiveFrom(RecvBuffer, 0, RecvBuffer.Length, SocketFlags.None, ref endPoint, ReceivedData, null); // Send the UseCircuitCode packet to initiate the connection UseCircuitCodePacket use = new UseCircuitCodePacket(); use.CircuitCode.Code = circuitCode; use.CircuitCode.ID = Network.AgentID; use.CircuitCode.SessionID = Network.SessionID; // Start the ACK timer AckTimer.Start(); // Send the initial packet out SendPacket(use, true); // Track the current time for timeout purposes int start = Environment.TickCount; while (true) { if (connected || Environment.TickCount - start > Client.Settings.SIMULATOR_TIMEOUT) { return; } System.Threading.Thread.Sleep(10); } } catch (Exception e) { Client.Log(e.ToString(), Helpers.LogLevel.Error); } }
/// <summary> /// Enters mouselook, presses and releases the left mouse button, and leaves mouselook /// </summary> /// <returns></returns> public static bool Shoot(SecondLife client) { if (client.Settings.SEND_AGENT_UPDATES) { client.Self.Movement.Mouselook = true; client.Self.Movement.MLButtonDown = true; client.Self.Movement.SendUpdate(); client.Self.Movement.MLButtonUp = true; client.Self.Movement.MLButtonDown = false; client.Self.Movement.FinishAnim = true; client.Self.Movement.SendUpdate(); client.Self.Movement.Mouselook = false; client.Self.Movement.MLButtonUp = false; client.Self.Movement.FinishAnim = false; client.Self.Movement.SendUpdate(); return true; } else { client.Log("Attempted Shoot but agent updates are disabled", Helpers.LogLevel.Warning); return false; } }
/// <summary> /// Get grid region information using the region name, this function /// will block until it can find the region or gives up /// </summary> /// <param name="name">Name of sim you're looking for</param> /// <param name="layer">Layer that you are requesting</param> /// <param name="region">Will contain a GridRegion for the sim you're /// looking for if successful, otherwise an empty structure</param> /// <returns>True if the GridRegion was successfully fetched, otherwise /// false</returns> public bool GetGridRegion(string name, GridLayerType layer, out GridRegion region) { if (String.IsNullOrEmpty(name)) { Client.Log("GetGridRegion called with a null or empty region name", Helpers.LogLevel.Error); region = new GridRegion(); return(false); } // All lookups are done using lowercase sim names name = name.ToLower(); if (Regions.ContainsKey(name)) { // We already have this GridRegion structure region = Regions[name]; return(true); } else { AutoResetEvent regionEvent = new AutoResetEvent(false); GridRegionCallback callback = delegate(GridRegion gridRegion) { if (gridRegion.Name == name) { regionEvent.Set(); } }; OnGridRegion += callback; RequestMapRegion(name, layer); regionEvent.WaitOne(Client.Settings.MAP_REQUEST_TIMEOUT, false); OnGridRegion -= callback; if (Regions.ContainsKey(name)) { // The region was found after our request region = Regions[name]; return(true); } else { Client.Log("Couldn't find region " + name, Helpers.LogLevel.Warning); region = new GridRegion(); return(false); } } }