diff --git a/Programs/Simian/Extensions/AvatarManager.cs b/Programs/Simian/Extensions/AvatarManager.cs index 55c7fbc3..e8c68b82 100644 --- a/Programs/Simian/Extensions/AvatarManager.cs +++ b/Programs/Simian/Extensions/AvatarManager.cs @@ -268,6 +268,7 @@ namespace Simian.Extensions reply.UUIDNameBlock[i].ID = kvp.Key; reply.UUIDNameBlock[i].FirstName = Utils.StringToBytes(kvp.Value.FirstName); reply.UUIDNameBlock[i].LastName = Utils.StringToBytes(kvp.Value.LastName); + i++; } Server.UDP.SendPacket(agent.AgentID, reply, PacketCategory.Transaction); diff --git a/Programs/Simian/Extensions/FriendManager.cs b/Programs/Simian/Extensions/FriendManager.cs new file mode 100644 index 00000000..61b5a145 --- /dev/null +++ b/Programs/Simian/Extensions/FriendManager.cs @@ -0,0 +1,113 @@ +using OpenMetaverse; +using OpenMetaverse.Packets; +using System; +using System.Collections.Generic; +using System.Text; + +namespace Simian.Extensions +{ + public class FriendManager : ISimianExtension + { + Simian Server; + + public FriendManager(Simian server) + { + Server = server; + } + + public void Start() + { + Server.UDP.RegisterPacketCallback(PacketType.ImprovedInstantMessage, new PacketCallback(ImprovedInstantMessageHandler)); + } + + public void Stop() + { + } + + void ImprovedInstantMessageHandler(Packet packet, Agent agent) + { + ImprovedInstantMessagePacket im = (ImprovedInstantMessagePacket)packet; + InstantMessageDialog dialog = (InstantMessageDialog)im.MessageBlock.Dialog; + + if (dialog == InstantMessageDialog.FriendshipOffered || dialog == InstantMessageDialog.FriendshipAccepted || dialog == InstantMessageDialog.FriendshipDeclined) + { + lock (Server.Agents) + { + foreach (Agent recipient in Server.Agents.Values) + { + if (recipient.AgentID == im.MessageBlock.ToAgentID) + { + ImprovedInstantMessagePacket sendIM = new ImprovedInstantMessagePacket(); + sendIM.MessageBlock.RegionID = UUID.Random(); //FIXME + sendIM.MessageBlock.ParentEstateID = 1; + sendIM.MessageBlock.FromGroup = false; + sendIM.MessageBlock.FromAgentName = Utils.StringToBytes(agent.Avatar.Name); + sendIM.MessageBlock.ToAgentID = im.MessageBlock.ToAgentID; + sendIM.MessageBlock.Dialog = im.MessageBlock.Dialog; + sendIM.MessageBlock.Offline = (byte)InstantMessageOnline.Online; + sendIM.MessageBlock.ID = agent.AgentID; + sendIM.MessageBlock.Message = im.MessageBlock.Message; + sendIM.MessageBlock.BinaryBucket = new byte[0]; + sendIM.MessageBlock.Timestamp = 0; + sendIM.MessageBlock.Position = agent.Avatar.Position; + + sendIM.AgentData.AgentID = agent.AgentID; + + Server.UDP.SendPacket(recipient.AgentID, sendIM, PacketCategory.Transaction); + + if (dialog == InstantMessageDialog.FriendshipAccepted) + { + bool receiverOnline = Server.Agents.ContainsKey(agent.AgentID); + bool senderOnline = Server.Agents.ContainsKey(recipient.AgentID); + + if (receiverOnline) + { + if (senderOnline) + { + OnlineNotificationPacket notify = new OnlineNotificationPacket(); + notify.AgentBlock = new OnlineNotificationPacket.AgentBlockBlock[0]; + notify.AgentBlock[0] = new OnlineNotificationPacket.AgentBlockBlock(); + notify.AgentBlock[0].AgentID = agent.AgentID; + Server.UDP.SendPacket(recipient.AgentID, notify, PacketCategory.State); + } + else + { + OfflineNotificationPacket notify = new OfflineNotificationPacket(); + notify.AgentBlock = new OfflineNotificationPacket.AgentBlockBlock[0]; + notify.AgentBlock[0] = new OfflineNotificationPacket.AgentBlockBlock(); + notify.AgentBlock[0].AgentID = agent.AgentID; + Server.UDP.SendPacket(recipient.AgentID, notify, PacketCategory.State); + } + } + + if (senderOnline) + { + if (receiverOnline) + { + OnlineNotificationPacket notify = new OnlineNotificationPacket(); + notify.AgentBlock = new OnlineNotificationPacket.AgentBlockBlock[0]; + notify.AgentBlock[0] = new OnlineNotificationPacket.AgentBlockBlock(); + notify.AgentBlock[0].AgentID = recipient.AgentID; + Server.UDP.SendPacket(agent.AgentID, notify, PacketCategory.State); + } + else + { + OfflineNotificationPacket notify = new OfflineNotificationPacket(); + notify.AgentBlock = new OfflineNotificationPacket.AgentBlockBlock[0]; + notify.AgentBlock[0] = new OfflineNotificationPacket.AgentBlockBlock(); + notify.AgentBlock[0].AgentID = recipient.AgentID; + Server.UDP.SendPacket(agent.AgentID, notify, PacketCategory.State); + } + } + + } + + break; + } + } + } + } + } + + } +} diff --git a/Programs/Simian/Extensions/Messaging.cs b/Programs/Simian/Extensions/Messaging.cs index 8f0b8683..46fd3206 100644 --- a/Programs/Simian/Extensions/Messaging.cs +++ b/Programs/Simian/Extensions/Messaging.cs @@ -3,7 +3,6 @@ using OpenMetaverse.Packets; using System; using System.Collections.Generic; using System.Text; -using System.Threading; namespace Simian.Extensions { @@ -67,7 +66,7 @@ namespace Simian.Extensions sendIM.MessageBlock.FromGroup = false; sendIM.MessageBlock.FromAgentName = Utils.StringToBytes(agent.Avatar.Name); sendIM.MessageBlock.ToAgentID = im.MessageBlock.ToAgentID; - sendIM.MessageBlock.Dialog = (byte)InstantMessageDialog.MessageFromAgent; + sendIM.MessageBlock.Dialog = im.MessageBlock.Dialog; sendIM.MessageBlock.Offline = (byte)InstantMessageOnline.Online; sendIM.MessageBlock.ID = agent.AgentID; sendIM.MessageBlock.Message = im.MessageBlock.Message; diff --git a/Programs/Simian/Extensions/UDPServer.cs b/Programs/Simian/Extensions/UDPServer.cs index f9ac4e5b..d0ab374f 100644 --- a/Programs/Simian/Extensions/UDPServer.cs +++ b/Programs/Simian/Extensions/UDPServer.cs @@ -418,8 +418,8 @@ namespace Simian dropAck.Add(outgoing.Packet.Header.Sequence); //Disconnect an agent if no packets are received for some time - //TODO: Send logout packet? Also, 10000 should be a setting somewhere. - if (Environment.TickCount - client.Agent.TickLastPacketReceived > 10000) + //TODO: Send logout packet? Also, 60000 should be a setting somewhere. + if (Environment.TickCount - client.Agent.TickLastPacketReceived > 60000) { Logger.Log(String.Format("Ack timeout for {0}, disconnecting", client.Agent.Avatar.Name), Helpers.LogLevel.Warning); server.UDP.RemoveClient(client.Agent);