void UseCircuitCodeHandler(Packet packet, Agent agent) { RegionHandshakePacket handshake = new RegionHandshakePacket(); handshake.RegionInfo.BillableFactor = 0f; handshake.RegionInfo.CacheID = UUID.Random(); handshake.RegionInfo.IsEstateManager = false; handshake.RegionInfo.RegionFlags = 1; handshake.RegionInfo.SimOwner = UUID.Random(); handshake.RegionInfo.SimAccess = 1; handshake.RegionInfo.SimName = Utils.StringToBytes("Simian"); handshake.RegionInfo.WaterHeight = 20.0f; handshake.RegionInfo.TerrainBase0 = UUID.Zero; handshake.RegionInfo.TerrainBase1 = UUID.Zero; handshake.RegionInfo.TerrainBase2 = UUID.Zero; handshake.RegionInfo.TerrainBase3 = UUID.Zero; handshake.RegionInfo.TerrainDetail0 = UUID.Zero; handshake.RegionInfo.TerrainDetail1 = UUID.Zero; handshake.RegionInfo.TerrainDetail2 = UUID.Zero; handshake.RegionInfo.TerrainDetail3 = UUID.Zero; handshake.RegionInfo.TerrainHeightRange00 = 0f; handshake.RegionInfo.TerrainHeightRange01 = 20f; handshake.RegionInfo.TerrainHeightRange10 = 0f; handshake.RegionInfo.TerrainHeightRange11 = 20f; handshake.RegionInfo.TerrainStartHeight00 = 0f; handshake.RegionInfo.TerrainStartHeight01 = 40f; handshake.RegionInfo.TerrainStartHeight10 = 0f; handshake.RegionInfo.TerrainStartHeight11 = 40f; handshake.RegionInfo2.RegionID = UUID.Random(); agent.SendPacket(handshake); }
void LogoutRequestHandler(Packet packet, Agent agent) { LogoutRequestPacket request = (LogoutRequestPacket)packet; LogoutReplyPacket reply = new LogoutReplyPacket(); reply.AgentData.AgentID = agent.AgentID; reply.AgentData.SessionID = agent.SessionID; reply.InventoryData = new LogoutReplyPacket.InventoryDataBlock[1]; reply.InventoryData[0] = new LogoutReplyPacket.InventoryDataBlock(); reply.InventoryData[0].ItemID = UUID.Zero; lock (server.Agents) { if (server.Agents.ContainsKey(agent.Address)) { KillObjectPacket kill = new KillObjectPacket(); kill.ObjectData = new KillObjectPacket.ObjectDataBlock[1]; kill.ObjectData[0] = new KillObjectPacket.ObjectDataBlock(); kill.ObjectData[0].ID = agent.Avatar.LocalID; server.Agents.Remove(agent.Address); foreach (Agent recipient in server.Agents.Values) recipient.SendPacket(kill); } } }
void AssetUploadRequestHandler(Packet packet, Agent agent) { AssetUploadRequestPacket request = (AssetUploadRequestPacket)packet; UUID assetID = UUID.Combine(request.AssetBlock.TransactionID, agent.SecureSessionID); // Check if the asset is small enough to fit in a single packet if (request.AssetBlock.AssetData.Length != 0) { // Create a new asset from the completed upload Asset asset = CreateAsset((AssetType)request.AssetBlock.Type, assetID, request.AssetBlock.AssetData); if (asset == null) { Logger.Log("Failed to create asset from uploaded data", Helpers.LogLevel.Warning); return; } Logger.DebugLog(String.Format("Storing uploaded asset {0} ({1})", assetID, asset.AssetType)); asset.Temporary = (request.AssetBlock.Tempfile | request.AssetBlock.StoreLocal); // Store the asset scene.Server.Assets.StoreAsset(asset); // Send a success response AssetUploadCompletePacket complete = new AssetUploadCompletePacket(); complete.AssetBlock.Success = true; complete.AssetBlock.Type = request.AssetBlock.Type; complete.AssetBlock.UUID = assetID; scene.UDP.SendPacket(agent.ID, complete, PacketCategory.Inventory); } else { // Create a new (empty) asset for the upload Asset asset = CreateAsset((AssetType)request.AssetBlock.Type, assetID, null); if (asset == null) { Logger.Log("Failed to create asset from uploaded data", Helpers.LogLevel.Warning); return; } Logger.DebugLog(String.Format("Starting upload for {0} ({1})", assetID, asset.AssetType)); asset.Temporary = (request.AssetBlock.Tempfile | request.AssetBlock.StoreLocal); RequestXferPacket xfer = new RequestXferPacket(); xfer.XferID.DeleteOnCompletion = request.AssetBlock.Tempfile; xfer.XferID.FilePath = 0; xfer.XferID.Filename = Utils.EmptyBytes; xfer.XferID.ID = request.AssetBlock.TransactionID.GetULong(); xfer.XferID.UseBigPackets = false; xfer.XferID.VFileID = asset.AssetID; xfer.XferID.VFileType = request.AssetBlock.Type; // Add this asset to the current upload list lock (CurrentUploads) CurrentUploads[xfer.XferID.ID] = asset; scene.UDP.SendPacket(agent.ID, xfer, PacketCategory.Inventory); } }
/// <summary> /// Fire the events registered for this packet type asynchronously /// </summary> /// <param name="packetType">Incoming packet type</param> /// <param name="packet">Incoming packet</param> /// <param name="agent">Agent this packet was received from</param> internal void BeginRaiseEvent(PacketType packetType, Packet packet, Agent agent) { UDPServer.PacketCallback callback; PacketCallbackWrapper wrapper; // Default handler first, if one exists if (_EventTable.TryGetValue(PacketType.Default, out callback)) { if (callback != null) { wrapper.Callback = callback; wrapper.Packet = packet; wrapper.Agent = agent; ThreadPool.QueueUserWorkItem(_ThreadPoolCallback, wrapper); } } if (_EventTable.TryGetValue(packetType, out callback)) { if (callback != null) { wrapper.Callback = callback; wrapper.Packet = packet; wrapper.Agent = agent; ThreadPool.QueueUserWorkItem(_ThreadPoolCallback, wrapper); return; } } if (packetType != PacketType.Default && packetType != PacketType.PacketAck) { Logger.DebugLog("No handler registered for packet event " + packetType); } }
void StartPingCheckHandler(Packet packet, Agent agent) { StartPingCheckPacket start = (StartPingCheckPacket)packet; CompletePingCheckPacket complete = new CompletePingCheckPacket(); complete.Header.Reliable = false; complete.PingID.PingID = start.PingID.PingID; agent.SendPacket(complete); }
public bool TryGetUnassociatedAgent(uint circuitCode, out Agent agent) { if (unassociatedAgents.TryGetValue(circuitCode, out agent)) { lock (unassociatedAgents) unassociatedAgents.Remove(circuitCode); return true; } else { return false; } }
void RequestImageHandler(Packet packet, Agent agent) { RequestImagePacket request = (RequestImagePacket)packet; for (int i = 0; i < request.RequestImage.Length; i++) { RequestImagePacket.RequestImageBlock block = request.RequestImage[i]; ImageDownload download; bool downloadFound = currentDownloads.TryGetValue(block.Image, out download); if (downloadFound) { lock (download) { if (block.DiscardLevel == -1 && block.DownloadPriority == 0.0f) Logger.DebugLog(String.Format("Image download {0} is aborting", block.Image)); // Update download download.Update(block.DiscardLevel, block.DownloadPriority, (int)block.Packet); } } else if (block.DiscardLevel == -1 && block.DownloadPriority == 0.0f) { // Aborting a download we are not tracking, this may be in the pipeline Pipeline.AbortDownload(block.Image); } else { //bool bake = ((ImageType)block.Type == ImageType.Baked); // New download, check if we have this image Asset asset; if (scene.Server.Assets.TryGetAsset(block.Image, out asset) && asset is AssetTexture) { SendTexture(agent, (AssetTexture)asset, block.DiscardLevel, (int)block.Packet, block.DownloadPriority); } else { // We don't have this texture, add it to the download queue and see if the bot can get it for us download = new ImageDownload(null, agent, block.DiscardLevel, block.DownloadPriority, (int)block.Packet); lock (currentDownloads) currentDownloads[block.Image] = download; Pipeline.RequestTexture(block.Image, (ImageType)block.Type); } } } }
public void DisconnectClient(Agent agent) { // Remove the avatar from the scene SimulationObject obj; if (Scene.TryGetObject(agent.AgentID, out obj)) Scene.ObjectRemove(this, obj); else Logger.Log("Disconnecting an agent that is not in the scene", Helpers.LogLevel.Warning); // Remove the UDP client UDP.RemoveClient(agent); // HACK: Notify everyone when someone disconnects OfflineNotificationPacket offline = new OfflineNotificationPacket(); offline.AgentBlock = new OfflineNotificationPacket.AgentBlockBlock[1]; offline.AgentBlock[0] = new OfflineNotificationPacket.AgentBlockBlock(); offline.AgentBlock[0].AgentID = agent.AgentID; UDP.BroadcastPacket(offline, PacketCategory.State); }
void AgentWearablesRequestHandler(Packet packet, Agent agent) { AgentWearablesUpdatePacket update = new AgentWearablesUpdatePacket(); update.AgentData.AgentID = agent.AgentID; update.AgentData.SessionID = agent.SessionID; // Technically this should be per-agent, but if the only requirement is that it // increments this is easier update.AgentData.SerialNum = (uint)Interlocked.Increment(ref currentWearablesSerialNum); update.WearableData = new AgentWearablesUpdatePacket.WearableDataBlock[4]; for (int i = 0; i < 4; i++) { update.WearableData[i] = new AgentWearablesUpdatePacket.WearableDataBlock(); update.WearableData[i].AssetID = UUID.Zero; update.WearableData[i].ItemID = UUID.Zero; update.WearableData[i].WearableType = 42; // HACK } agent.SendPacket(update); }
void CompleteAgentMovementHandler(Packet packet, Agent agent) { CompleteAgentMovementPacket request = (CompleteAgentMovementPacket)packet; // Create a representation for this agent Avatar avatar = new Avatar(); avatar.ID = agent.AgentID; avatar.LocalID = (uint)Interlocked.Increment(ref currentLocalID); avatar.Position = new Vector3(128f, 128f, 25f); avatar.Rotation = Quaternion.Identity; avatar.Scale = new Vector3(1f, 1f, 3f); // Set the avatar name NameValue[] name = new NameValue[2]; name[0] = new NameValue("FirstName", NameValue.ValueType.String, NameValue.ClassType.ReadWrite, NameValue.SendtoType.SimViewer, agent.FirstName); name[1] = new NameValue("LastName", NameValue.ValueType.String, NameValue.ClassType.ReadWrite, NameValue.SendtoType.SimViewer, agent.LastName); avatar.NameValues = name; // Link this avatar up with the corresponding agent agent.Avatar = avatar; // Give testers a provisionary balance of 1000L agent.Balance = 1000; AgentMovementCompletePacket complete = new AgentMovementCompletePacket(); complete.AgentData.AgentID = agent.AgentID; complete.AgentData.SessionID = agent.SessionID; complete.Data.LookAt = Vector3.UnitX; complete.Data.Position = avatar.Position; complete.Data.RegionHandle = server.RegionHandle; complete.Data.Timestamp = Utils.DateTimeToUnixTime(DateTime.Now); complete.SimData.ChannelVersion = Utils.StringToBytes("Simian"); agent.SendPacket(complete); SendLayerData(agent); }
void AgentUpdateHandler(Packet packet, Agent agent) { AgentUpdatePacket update = (AgentUpdatePacket)packet; // Don't use the local physics to update the master agent if (agent != periscope.MasterAgent) { agent.Avatar.Prim.Rotation = update.AgentData.BodyRotation; agent.ControlFlags = (AgentManager.ControlFlags)update.AgentData.ControlFlags; agent.State = (AgentState)update.AgentData.State; agent.HideTitle = update.AgentData.Flags != 0; } SimulationObject obj; if (scene.TryGetObject(update.AgentData.AgentID, out obj)) { obj.Prim.Rotation = update.AgentData.BodyRotation; scene.ObjectAddOrUpdate(this, obj, obj.Prim.OwnerID, 0, PrimFlags.None, UpdateFlags.Rotation); } }
public bool EnableClientCapHandler(IHttpClientContext context, IHttpRequest request, IHttpResponse response, object state) { OSDMap map = OSDParser.DeserializeLLSDXml(request.Body) as OSDMap; OSDMap osdResponse = new OSDMap(); if (map != null) { UUID agentID = map["agent_id"].AsUUID(); UUID sessionID = map["session_id"].AsUUID(); UUID secureSessionID = map["secure_session_id"].AsUUID(); uint circuitCode = (uint)map["circuit_code"].AsInteger(); // TODO: Send an identity url and token instead so we can pull down all of the information string firstName = map["first_name"].AsString(); string lastName = map["last_name"].AsString(); Uri callbackUri = map["callback_uri"].AsUri(); Logger.Log(String.Format( "enable_client request. agent_id: {0}, session_id: {1}, secureSessionID: {2}, " + "first_name: {3}, last_name: {4}, callback_uri: {5}", agentID, sessionID, secureSessionID, firstName, lastName, callbackUri), Helpers.LogLevel.Info); if (agentID != UUID.Zero && sessionID != UUID.Zero && secureSessionID != UUID.Zero && !String.IsNullOrEmpty(firstName) && !String.IsNullOrEmpty(lastName)) { AgentInfo info = new AgentInfo(); info.AccessLevel = "M"; info.FirstName = firstName; info.Height = 1.9f; info.HomeLookAt = Vector3.UnitZ; info.HomePosition = new Vector3(128f, 128f, 25f); info.HomeRegionHandle = regionHandle; info.ID = agentID; info.LastName = lastName; info.PasswordHash = String.Empty; Agent agent = new Agent(new SimulationObject(new Avatar(), this), info); // Set the avatar ID agent.Avatar.Prim.ID = agentID; // Random session IDs agent.SessionID = sessionID; agent.SecureSessionID = secureSessionID; // Create a seed capability for this agent agent.SeedCapability = server.Capabilities.CreateCapability(SeedCapabilityHandler, false, agentID); agent.TickLastPacketReceived = Environment.TickCount; agent.Info.LastLoginTime = Utils.DateTimeToUnixTime(DateTime.Now); // Add the callback URI to the list of pending enable_client_complete callbacks lock (enableClientCompleteCallbacks) enableClientCompleteCallbacks[agentID] = callbackUri; // Assign a circuit code and track the agent as an unassociated agent (no UDP connection yet) udp.CreateCircuit(agent, circuitCode); agent.CircuitCode = circuitCode; osdResponse["success"] = OSD.FromBoolean(true); } else { osdResponse["success"] = OSD.FromBoolean(false); osdResponse["message"] = OSD.FromString("missing required fields for enable_client"); } } else { osdResponse["success"] = OSD.FromBoolean(false); osdResponse["message"] = OSD.FromString("failed to parse enable_client message"); } byte[] responseData = OSDParser.SerializeLLSDXmlBytes(osdResponse); response.ContentLength = responseData.Length; response.Body.Write(responseData, 0, responseData.Length); response.Body.Flush(); return true; }
public void AgentAppearance(object sender, Agent agent, Primitive.TextureEntry textures, byte[] visualParams) { if (OnAgentAppearance != null) { OnAgentAppearance(sender, agent, textures, visualParams); } // Broadcast an object update for this avatar // TODO: Is this necessary here? //ObjectUpdatePacket update = SimulationObject.BuildFullUpdate(agent.Avatar, // regionHandle, agent.Flags); //scene.UDP.BroadcastPacket(update, PacketCategory.State); // Update the avatar agent.Avatar.Prim.Textures = textures; if (visualParams != null && visualParams.Length > 1) agent.Info.VisualParams = visualParams; if (agent.Info.VisualParams != null) { // Send the appearance packet to all other clients AvatarAppearancePacket appearance = agent.BuildAppearancePacket(); ForEachAgent( delegate(Agent recipient) { if (recipient != agent) udp.SendPacket(recipient.ID, appearance, PacketCategory.State); } ); } }
void TransferRequestHandler(Packet packet, Agent agent) { TransferRequestPacket request = (TransferRequestPacket)packet; ChannelType channel = (ChannelType)request.TransferInfo.ChannelType; SourceType source = (SourceType)request.TransferInfo.SourceType; if (channel == ChannelType.Asset) { if (source == SourceType.Asset) { // Parse the request UUID assetID = new UUID(request.TransferInfo.Params, 0); AssetType type = (AssetType)(sbyte)Utils.BytesToInt(request.TransferInfo.Params, 16); // Check if we have this asset Asset asset; if (scene.Server.Assets.TryGetAsset(assetID, out asset)) { if (asset.AssetType == type) { TransferToClient(asset, agent, request.TransferInfo.TransferID); } else { Logger.Log(String.Format( "Request for asset {0} with type {1} does not match actual asset type {2}", assetID, type, asset.AssetType), Helpers.LogLevel.Warning); } } else { // Use the bot to try and request this asset lock (currentDownloads) { currentDownloads.Add(client.Assets.RequestAsset(assetID, type, false), new KeyValuePair<UUID, UUID>(agent.ID, request.TransferInfo.TransferID)); } } } else if (source == SourceType.SimEstate) { //UUID agentID = new UUID(request.TransferInfo.Params, 0); //UUID sessionID = new UUID(request.TransferInfo.Params, 16); //EstateAssetType type = (EstateAssetType)Utils.BytesToInt(request.TransferInfo.Params, 32); Logger.Log("Please implement estate asset transfers", Helpers.LogLevel.Warning); } else if (source == SourceType.SimInventoryItem) { //UUID agentID = new UUID(request.TransferInfo.Params, 0); //UUID sessionID = new UUID(request.TransferInfo.Params, 16); //UUID ownerID = new UUID(request.TransferInfo.Params, 32); UUID taskID = new UUID(request.TransferInfo.Params, 48); //UUID itemID = new UUID(request.TransferInfo.Params, 64); //UUID assetID = new UUID(request.TransferInfo.Params, 80); //AssetType type = (AssetType)(sbyte)Utils.BytesToInt(request.TransferInfo.Params, 96); if (taskID != UUID.Zero) { // Task (prim) inventory request Logger.Log("Please implement task inventory transfers", Helpers.LogLevel.Warning); } else { // Agent inventory request Logger.Log("Please implement agent inventory transfer", Helpers.LogLevel.Warning); } } else { Logger.Log(String.Format( "Received a TransferRequest that we don't know how to handle. Channel: {0}, Source: {1}", channel, source), Helpers.LogLevel.Warning); } } else { Logger.Log(String.Format( "Received a TransferRequest that we don't know how to handle. Channel: {0}, Source: {1}", channel, source), Helpers.LogLevel.Warning); } }
public void Start() { simian = new Simian.Simian(); simian.UDP = new UDPManager(); (simian.UDP as IExtension<Simian.Simian>).Start(simian); sceneManager = new SceneManager(); sceneManager.Start(simian); agent = CreateDummyAgent(); simian.Agents.Add(agent.Avatar.ID, agent); observer = CreateDummyAgent(); simian.Agents.Add(observer.Avatar.ID, observer); }
uint CreateAgentCircuit(Agent agent) { uint circuitCode = (uint)Interlocked.Increment(ref currentCircuitCode); // Put this client in the list of clients that have not been associated with an IPEndPoint yet lock (unassociatedAgents) unassociatedAgents[circuitCode] = agent; Logger.Log("Created a circuit for " + agent.FirstName, Helpers.LogLevel.Info); return circuitCode; }
LoginResponseData HandleLogin(string firstName, string lastName, string password, string start, string version, string channel) { uint regionX = 256000; uint regionY = 256000; Agent agent = new Agent(UDPServer); agent.AgentID = UUID.Random(); agent.FirstName = firstName; agent.LastName = lastName; agent.SessionID = UUID.Random(); agent.SecureSessionID = UUID.Random(); agent.CircuitCode = CreateAgentCircuit(agent); IPHostEntry addresses = Dns.GetHostByName(Dns.GetHostName()); IPAddress simIP = addresses.AddressList.Length > 0 ? addresses.AddressList[0] : IPAddress.Loopback; // Setup default login response values LoginResponseData response; response.AgentID = agent.AgentID; response.SecureSessionID = agent.SecureSessionID; response.SessionID = agent.SessionID; response.CircuitCode = agent.CircuitCode; response.AgentAccess = "M"; response.BuddyList = null; response.FirstName = agent.FirstName; response.HomeLookAt = Vector3.UnitX; response.HomePosition = new Vector3(128f, 128f, 25f); response.HomeRegion = Helpers.UIntsToLong(regionX, regionY); response.InventoryFolders = null; response.InventoryRoot = UUID.Random(); response.LastName = agent.LastName; response.LibraryFolders = null; response.LibraryOwner = response.AgentID; response.LibraryRoot = UUID.Random(); response.LookAt = Vector3.UnitX; response.Message = "Welcome to Simian"; response.Reason = String.Empty; response.RegionX = regionX; response.RegionY = regionY; response.SecondsSinceEpoch = DateTime.Now; // FIXME: Actually generate a seed capability response.SeedCapability = String.Format("http://{0}:{1}/seed_caps", simIP, tcpPort); response.SimIP = simIP; response.SimPort = (ushort)udpPort; response.StartLocation = "last"; response.Success = true; return response; }
public void InformClientOfNeighbors(Agent agent) { for (int i = 0; i < 8; i++) { if (!agent.NeighborConnections[i] && neighbors[i].Online) { Logger.Log("Sending enable_client for " + agent.FullName + " to neighbor " + neighbors[i].Name, Helpers.LogLevel.Info); // Create a callback for enable_client_complete Uri callbackUri = server.Capabilities.CreateCapability(EnableClientCompleteCapHandler, false, null); OSDMap enableClient = CapsMessages.EnableClient(agent.ID, agent.SessionID, agent.SecureSessionID, (int)agent.CircuitCode, agent.Info.FirstName, agent.Info.LastName, callbackUri); AutoResetEvent waitEvent = new AutoResetEvent(false); CapsClient request = new CapsClient(neighbors[i].EnableClientCap); request.OnComplete += delegate(CapsClient client, OSD result, Exception error) { OSDMap response = result as OSDMap; if (response != null) { bool success = response["success"].AsBoolean(); Logger.Log("enable_client response: " + success, Helpers.LogLevel.Info); if (success) { // Send the EnableSimulator capability to clients RegionInfo neighbor = neighbors[i]; OSDMap enableSimulator = CapsMessages.EnableSimulator(neighbor.Handle, neighbor.IPAndPort.Address, neighbor.IPAndPort.Port); SendEvent(agent, "EnableSimulator", enableSimulator); } } waitEvent.Set(); }; request.StartRequest(enableClient); if (!waitEvent.WaitOne(30 * 1000, false)) Logger.Log("enable_client request timed out", Helpers.LogLevel.Warning); } } }
public void SendEvent(Agent agent, string name, OSDMap body) { EventQueueServerCap eventQueue; if (eventQueues.TryGetValue(agent.ID, out eventQueue)) { eventQueue.Server.SendEvent(name, body); } else { Logger.Log(String.Format("Cannot send the event {0} to agent {1}, no event queue for that avatar", name, agent.FullName), Helpers.LogLevel.Warning); } }
public bool HasRunningEventQueue(Agent agent) { return eventQueues.ContainsKey(agent.ID); }
public bool TryGetAgent(UUID id, out Agent agent) { return sceneAgents.TryGetValue(id, out agent); }
void SetAlwaysRunHandler(Packet packet, Agent agent) { SetAlwaysRunPacket run = (SetAlwaysRunPacket)packet; agent.Running = run.AgentData.AlwaysRun; }
static Agent CreateDummyAgent() { Agent agent = new Agent(); agent.Avatar.ID = UUID.Random(); agent.SessionID = UUID.Random(); agent.Avatar.Position = new Vector3(128f, 128f, 40f); agent.Avatar.Rotation = Quaternion.Identity; return agent; }
public bool AgentAdd(object sender, Agent agent, PrimFlags creatorFlags) { // Sanity check, since this should have already been done agent.Avatar.Prim.ID = agent.Info.ID; // Check if the agent already exists in the scene lock (sceneAgents) { if (sceneAgents.ContainsKey(agent.ID)) sceneAgents.Remove(agent.ID); } // Update the current region handle agent.Avatar.Prim.RegionHandle = regionHandle; // Avatars always have physics agent.Avatar.Prim.Flags |= PrimFlags.Physics; // Default avatar values agent.Avatar.Prim.Position = new Vector3(128f, 128f, 25f); agent.Avatar.Prim.Rotation = Quaternion.Identity; agent.Avatar.Prim.Scale = new Vector3(0.45f, 0.6f, 1.9f); agent.Avatar.Prim.PrimData.Material = Material.Flesh; agent.Avatar.Prim.PrimData.PCode = PCode.Avatar; agent.Avatar.Prim.Textures = new Primitive.TextureEntry(new UUID("c228d1cf-4b5d-4ba8-84f4-899a0796aa97")); // Set the avatar name NameValue[] name = new NameValue[2]; name[0] = new NameValue("FirstName", NameValue.ValueType.String, NameValue.ClassType.ReadWrite, NameValue.SendtoType.SimViewer, agent.Info.FirstName); name[1] = new NameValue("LastName", NameValue.ValueType.String, NameValue.ClassType.ReadWrite, NameValue.SendtoType.SimViewer, agent.Info.LastName); agent.Avatar.Prim.NameValues = name; // Give testers a provisionary balance of 1000L agent.Info.Balance = 1000; // Some default avatar prim properties agent.Avatar.Prim.Properties = new Primitive.ObjectProperties(); agent.Avatar.Prim.Properties.CreationDate = Utils.UnixTimeToDateTime(agent.Info.CreationTime); agent.Avatar.Prim.Properties.Name = agent.FullName; agent.Avatar.Prim.Properties.ObjectID = agent.ID; if (agent.Avatar.Prim.LocalID == 0) { // Assign a unique LocalID to this agent agent.Avatar.Prim.LocalID = (uint)Interlocked.Increment(ref currentLocalID); } if (OnAgentAdd != null) OnAgentAdd(sender, agent, creatorFlags); // Add the agent to the scene dictionary lock (sceneAgents) sceneAgents[agent.ID] = agent; Logger.Log("Added agent " + agent.FullName + " to the scene", Helpers.LogLevel.Info); return true; }
void AbortXferHandler(Packet packet, Agent agent) { AbortXferPacket abort = (AbortXferPacket)packet; lock (CurrentUploads) { if (CurrentUploads.ContainsKey(abort.XferID.ID)) { Logger.DebugLog(String.Format("Aborting Xfer {0}, result: {1}", abort.XferID.ID, (TransferError)abort.XferID.Result)); CurrentUploads.Remove(abort.XferID.ID); } else { Logger.DebugLog(String.Format("Received an AbortXfer for an unknown xfer {0}", abort.XferID.ID)); } } }
void CompleteAgentMovementHandler(Packet packet, Agent agent) { // Add this avatar as an object in the scene ObjectAddOrUpdate(this, agent.Avatar, agent.Avatar.Prim.OwnerID, 0, PrimFlags.None, UpdateFlags.FullUpdate); // Send a response back to the client AgentMovementCompletePacket complete = new AgentMovementCompletePacket(); complete.AgentData.AgentID = agent.ID; complete.AgentData.SessionID = agent.SessionID; complete.Data.LookAt = Vector3.UnitZ; // TODO: Properly implement LookAt someday complete.Data.Position = agent.Avatar.Prim.Position; complete.Data.RegionHandle = regionHandle; complete.Data.Timestamp = Utils.DateTimeToUnixTime(DateTime.Now); complete.SimData.ChannelVersion = Utils.StringToBytes("Simian"); udp.SendPacket(agent.ID, complete, PacketCategory.Transaction); //HACK: Notify everyone when someone logs on to the simulator OnlineNotificationPacket online = new OnlineNotificationPacket(); online.AgentBlock = new OnlineNotificationPacket.AgentBlockBlock[1]; online.AgentBlock[0] = new OnlineNotificationPacket.AgentBlockBlock(); online.AgentBlock[0].AgentID = agent.ID; udp.BroadcastPacket(online, PacketCategory.State); }
void TransferToClient(Asset asset, Agent agent, UUID transferID) { Logger.Log(String.Format("Transferring asset {0} ({1})", asset.AssetID, asset.AssetType), Helpers.LogLevel.Info); TransferInfoPacket response = new TransferInfoPacket(); response.TransferInfo = new TransferInfoPacket.TransferInfoBlock(); response.TransferInfo.TransferID = transferID; response.TransferInfo.Params = new byte[20]; Buffer.BlockCopy(asset.AssetID.GetBytes(), 0, response.TransferInfo.Params, 0, 16); Buffer.BlockCopy(Utils.IntToBytes((int)asset.AssetType), 0, response.TransferInfo.Params, 16, 4); response.TransferInfo.ChannelType = (int)ChannelType.Asset; response.TransferInfo.Size = asset.AssetData.Length; response.TransferInfo.Status = (int)StatusCode.OK; response.TransferInfo.TargetType = (int)TargetType.Unknown; // Doesn't seem to be used by the client scene.UDP.SendPacket(agent.ID, response, PacketCategory.Asset); // Transfer system does not wait for ACKs, just sends all of the // packets for this transfer out const int MAX_CHUNK_SIZE = Settings.MAX_PACKET_SIZE - 100; int processedLength = 0; int packetNum = 0; while (processedLength < asset.AssetData.Length) { TransferPacketPacket transfer = new TransferPacketPacket(); transfer.TransferData.ChannelType = (int)ChannelType.Asset; transfer.TransferData.TransferID = transferID; transfer.TransferData.Packet = packetNum++; int chunkSize = Math.Min(asset.AssetData.Length - processedLength, MAX_CHUNK_SIZE); transfer.TransferData.Data = new byte[chunkSize]; Buffer.BlockCopy(asset.AssetData, processedLength, transfer.TransferData.Data, 0, chunkSize); processedLength += chunkSize; if (processedLength >= asset.AssetData.Length) transfer.TransferData.Status = (int)StatusCode.Done; else transfer.TransferData.Status = (int)StatusCode.OK; scene.UDP.SendPacket(agent.ID, transfer, PacketCategory.Asset); } }
void udp_OnAgentConnection(Agent agent, uint circuitCode) { Uri callbackUri; if (enableClientCompleteCallbacks.TryGetValue(agent.ID, out callbackUri)) { lock (enableClientCompleteCallbacks) enableClientCompleteCallbacks.Remove(agent.ID); Logger.Log("Sending enable_client_complete callback to " + callbackUri.ToString(), Helpers.LogLevel.Info); OSDMap enableClientComplete = CapsMessages.EnableClientComplete(agent.ID); AutoResetEvent waitEvent = new AutoResetEvent(false); CapsClient request = new CapsClient(callbackUri); request.OnComplete += delegate(CapsClient client, OSD result, Exception error) { OSDMap response = result as OSDMap; if (response != null) { bool success = response["success"].AsBoolean(); Logger.Log("enable_client_complete response: " + success, Helpers.LogLevel.Info); if (success) { Uri seedCapability = response["seed_capability"].AsUri(); } } waitEvent.Set(); }; request.StartRequest(enableClientComplete); if (!waitEvent.WaitOne(30 * 1000, false)) Logger.Log("enable_client_complete request timed out", Helpers.LogLevel.Warning); } }
void SendXferPacketHandler(Packet packet, Agent agent) { SendXferPacketPacket xfer = (SendXferPacketPacket)packet; Asset asset; if (CurrentUploads.TryGetValue(xfer.XferID.ID, out asset)) { if (asset.AssetData == null) { if (xfer.XferID.Packet != 0) { Logger.Log(String.Format("Received Xfer packet {0} before the first packet!", xfer.XferID.Packet), Helpers.LogLevel.Error); return; } uint size = Utils.BytesToUInt(xfer.DataPacket.Data); asset.AssetData = new byte[size]; Buffer.BlockCopy(xfer.DataPacket.Data, 4, asset.AssetData, 0, xfer.DataPacket.Data.Length - 4); // Confirm the first upload packet ConfirmXferPacketPacket confirm = new ConfirmXferPacketPacket(); confirm.XferID.ID = xfer.XferID.ID; confirm.XferID.Packet = xfer.XferID.Packet; scene.UDP.SendPacket(agent.ID, confirm, PacketCategory.Asset); } else { Buffer.BlockCopy(xfer.DataPacket.Data, 0, asset.AssetData, (int)xfer.XferID.Packet * 1000, xfer.DataPacket.Data.Length); // Confirm this upload packet ConfirmXferPacketPacket confirm = new ConfirmXferPacketPacket(); confirm.XferID.ID = xfer.XferID.ID; confirm.XferID.Packet = xfer.XferID.Packet; scene.UDP.SendPacket(agent.ID, confirm, PacketCategory.Asset); if ((xfer.XferID.Packet & (uint)0x80000000) != 0) { // Asset upload finished Logger.DebugLog(String.Format("Completed Xfer upload of asset {0} ({1}", asset.AssetID, asset.AssetType)); lock (CurrentUploads) CurrentUploads.Remove(xfer.XferID.ID); scene.Server.Assets.StoreAsset(asset); AssetUploadCompletePacket complete = new AssetUploadCompletePacket(); complete.AssetBlock.Success = true; complete.AssetBlock.Type = (sbyte)asset.AssetType; complete.AssetBlock.UUID = asset.AssetID; scene.UDP.SendPacket(agent.ID, complete, PacketCategory.Asset); } } } else { Logger.DebugLog("Received a SendXferPacket for an unknown upload"); } }
void AgentRemove(object sender, Agent agent) { if (OnAgentRemove != null) OnAgentRemove(sender, agent); Logger.Log("Removing agent " + agent.FullName + " from the scene", Helpers.LogLevel.Info); lock (sceneAgents) sceneAgents.Remove(agent.ID); // Kill the EventQueue RemoveEventQueue(agent.ID); // Remove the UDP client udp.RemoveClient(agent); // Notify everyone in the scene that this agent has gone offline OfflineNotificationPacket offline = new OfflineNotificationPacket(); offline.AgentBlock = new OfflineNotificationPacket.AgentBlockBlock[1]; offline.AgentBlock[0] = new OfflineNotificationPacket.AgentBlockBlock(); offline.AgentBlock[0].AgentID = agent.ID; udp.BroadcastPacket(offline, PacketCategory.State); }