diff --git a/libsecondlife/AgentManager.cs b/libsecondlife/AgentManager.cs index 13153a41..e7da9bd9 100644 --- a/libsecondlife/AgentManager.cs +++ b/libsecondlife/AgentManager.cs @@ -2387,7 +2387,7 @@ namespace libsecondlife } private void Network_OnLoginResponse(bool loginSuccess, bool redirect, string message, string reason, - NetworkManager.LoginResponseData reply) + LoginResponseData reply) { id = reply.AgentID; sessionID = reply.SessionID; diff --git a/libsecondlife/FriendsManager.cs b/libsecondlife/FriendsManager.cs index 30bd94c1..5a3f7754 100644 --- a/libsecondlife/FriendsManager.cs +++ b/libsecondlife/FriendsManager.cs @@ -31,217 +31,222 @@ using libsecondlife.Packets; namespace libsecondlife { /// - /// This class is used to add and remove avatars from your friends list and to manage their permission. + /// /// - - public class FriendsManager + [Flags] + public enum FriendRights : int { - [Flags] - public enum RightsFlags : int + /// The avatar has no rights + None = 0, + /// The avatar can see the online status of the target avatar + CanSeeOnline = 1, + /// The avatar can see the location of the target avatar on the map + CanSeeOnMap = 2, + /// The avatar can modify the ojects of the target avatar + CanModifyObjects = 4 + } + + /// + /// This class holds information about an avatar in the friends list. There are two ways + /// to interface to this class. The first is through the set of boolean properties. This is the typical + /// way clients of this class will use it. The second interface is through two bitmap properties. While + /// the bitmap interface is public, it is intended for use the libsecondlife framework. + /// + public class FriendInfo + { + private LLUUID m_id; + private string m_name; + private bool m_isOnline; + private bool m_canSeeMeOnline; + private bool m_canSeeMeOnMap; + private bool m_canModifyMyObjects; + private bool m_canSeeThemOnline; + private bool m_canSeeThemOnMap; + private bool m_canModifyTheirObjects; + + /// + /// Used by the libsecondlife framework when building the initial list of friends + /// at login time. This constructor should not be called by consummer of this class. + /// + /// System ID of the avatar being prepesented + /// Rights the friend has to see you online and to modify your objects + /// Rights you have to see your friend online and to modify their objects + public FriendInfo(LLUUID id, FriendRights theirRights, FriendRights myRights) { - /// The avatar has no rights - None = 0, - /// The avatar can see the online status of the target avatar - CanSeeOnline = 1, - /// The avatar can see the location of the target avatar on the map - CanSeeOnMap = 2, - /// The avatar can modify the ojects of the target avatar - CanModifyObjects = 4 + m_id = id; + m_canSeeMeOnline = (theirRights & FriendRights.CanSeeOnline) != 0; + m_canSeeMeOnMap = (theirRights & FriendRights.CanSeeOnMap) != 0; + m_canModifyMyObjects = (theirRights & FriendRights.CanModifyObjects) != 0; + + m_canSeeThemOnline = (myRights & FriendRights.CanSeeOnline) != 0; + m_canSeeThemOnMap = (myRights & FriendRights.CanSeeOnMap) != 0; + m_canModifyTheirObjects = (myRights & FriendRights.CanModifyObjects) != 0; } /// - /// This class holds information about an avatar in the friends list. There are two ways - /// to interface to this class. The first is through the set of boolean properties. This is the typical - /// way clients of this class will use it. The second interface is through two bitmap properties. While - /// the bitmap interface is public, it is intended for use the libsecondlife framework. + /// System ID of the avatar /// - public class FriendInfo + public LLUUID UUID { get { return m_id; } } + + /// + /// full name of the avatar + /// + public string Name { - private LLUUID m_id; - private string m_name; - private bool m_isOnline; - private bool m_canSeeMeOnline; - private bool m_canSeeMeOnMap; - private bool m_canModifyMyObjects; - private bool m_canSeeThemOnline; - private bool m_canSeeThemOnMap; - private bool m_canModifyTheirObjects; + get { return m_name; } + set { m_name = value; } + } - /// - /// Used by the libsecondlife framework when building the initial list of friends - /// at login time. This constructor should not be called by consummer of this class. - /// - /// System ID of the avatar being prepesented - /// Rights the friend has to see you online and to modify your objects - /// Rights you have to see your friend online and to modify their objects - public FriendInfo(LLUUID id, RightsFlags theirRights, RightsFlags myRights) + /// + /// True if the avatar is online + /// + public bool IsOnline + { + get { return m_isOnline; } + set { m_isOnline = value; } + } + + /// + /// True if the friend can see if I am online + /// + public bool CanSeeMeOnline + { + get { return m_canSeeMeOnline; } + set { - m_id = id; - m_canSeeMeOnline = (theirRights & RightsFlags.CanSeeOnline) != 0; - m_canSeeMeOnMap = (theirRights & RightsFlags.CanSeeOnMap) != 0; - m_canModifyMyObjects = (theirRights & RightsFlags.CanModifyObjects) != 0; + m_canSeeMeOnline = value; - m_canSeeThemOnline = (myRights & RightsFlags.CanSeeOnline) != 0; - m_canSeeThemOnMap = (myRights & RightsFlags.CanSeeOnMap) != 0; - m_canModifyTheirObjects = (myRights & RightsFlags.CanModifyObjects) != 0; - } - - /// - /// System ID of the avatar - /// - public LLUUID UUID { get { return m_id; } } - - /// - /// full name of the avatar - /// - public string Name - { - get { return m_name; } - set { m_name = value; } - } - - /// - /// True if the avatar is online - /// - public bool IsOnline - { - get { return m_isOnline; } - set { m_isOnline = value; } - } - - /// - /// True if the friend can see if I am online - /// - public bool CanSeeMeOnline - { - get { return m_canSeeMeOnline; } - set - { - m_canSeeMeOnline = value; - - // if I can't see them online, then I can't see them on the map - if (!m_canSeeMeOnline) - m_canSeeMeOnMap = false; - } - } - - /// - /// True if the friend can see me on the map - /// - public bool CanSeeMeOnMap - { - get { return m_canSeeMeOnMap; } - set - { - // if I can't see them online, then I can't see them on the map - if (m_canSeeMeOnline) - m_canSeeMeOnMap = value; - } - } - - /// - /// True if the freind can modify my objects - /// - public bool CanModifyMyObjects - { - get { return m_canModifyMyObjects; } - set { m_canModifyMyObjects = value; } - } - - /// - /// True if I can see if my friend is online - /// - public bool CanSeeThemOnline { get { return m_canSeeThemOnline; } } - - /// - /// True if I can see if my friend is on the map - /// - public bool CanSeeThemOnMap { get { return m_canSeeThemOnMap; } } - - /// - /// True if I can modify my friend's objects - /// - public bool CanModifyTheirObjects { get { return m_canModifyTheirObjects; } } - - /// - /// My friend's rights represented as bitmapped flags - /// - public RightsFlags TheirRightsFlags - { - get - { - RightsFlags results = RightsFlags.None; - if (m_canSeeMeOnline) - results |= RightsFlags.CanSeeOnline; - if (m_canSeeMeOnMap) - results |= RightsFlags.CanSeeOnMap; - if (m_canModifyMyObjects) - results |= RightsFlags.CanModifyObjects; - - return results; - } - set - { - m_canSeeMeOnline = (value & RightsFlags.CanSeeOnline) != 0; - m_canSeeMeOnMap = (value & RightsFlags.CanSeeOnMap) != 0; - m_canModifyMyObjects = (value & RightsFlags.CanModifyObjects) != 0; - } - } - - /// - /// My rights represented as bitmapped flags - /// - public RightsFlags MyRightsFlags - { - get - { - RightsFlags results = RightsFlags.None; - if (m_canSeeThemOnline) - results |= RightsFlags.CanSeeOnline; - if (m_canSeeThemOnMap) - results |= RightsFlags.CanSeeOnMap; - if (m_canModifyTheirObjects) - results |= RightsFlags.CanModifyObjects; - - return results; - } - set - { - m_canSeeThemOnline = (value & RightsFlags.CanSeeOnline) != 0; - m_canSeeThemOnMap = (value & RightsFlags.CanSeeOnMap) != 0; - m_canModifyTheirObjects = (value & RightsFlags.CanModifyObjects) != 0; - } - } - - /// - /// This class represented as a string. - /// - /// A string reprentation of both my rights and my friend's righs - public override string ToString() - { - return String.Format("{0} (Their Rights: {1}, My Rights: {2})", m_name, TheirRightsFlags, - MyRightsFlags); + // if I can't see them online, then I can't see them on the map + if (!m_canSeeMeOnline) + m_canSeeMeOnMap = false; } } + /// + /// True if the friend can see me on the map + /// + public bool CanSeeMeOnMap + { + get { return m_canSeeMeOnMap; } + set + { + // if I can't see them online, then I can't see them on the map + if (m_canSeeMeOnline) + m_canSeeMeOnMap = value; + } + } + + /// + /// True if the freind can modify my objects + /// + public bool CanModifyMyObjects + { + get { return m_canModifyMyObjects; } + set { m_canModifyMyObjects = value; } + } + + /// + /// True if I can see if my friend is online + /// + public bool CanSeeThemOnline { get { return m_canSeeThemOnline; } } + + /// + /// True if I can see if my friend is on the map + /// + public bool CanSeeThemOnMap { get { return m_canSeeThemOnMap; } } + + /// + /// True if I can modify my friend's objects + /// + public bool CanModifyTheirObjects { get { return m_canModifyTheirObjects; } } + + /// + /// My friend's rights represented as bitmapped flags + /// + public FriendRights TheirFriendRights + { + get + { + FriendRights results = FriendRights.None; + if (m_canSeeMeOnline) + results |= FriendRights.CanSeeOnline; + if (m_canSeeMeOnMap) + results |= FriendRights.CanSeeOnMap; + if (m_canModifyMyObjects) + results |= FriendRights.CanModifyObjects; + + return results; + } + set + { + m_canSeeMeOnline = (value & FriendRights.CanSeeOnline) != 0; + m_canSeeMeOnMap = (value & FriendRights.CanSeeOnMap) != 0; + m_canModifyMyObjects = (value & FriendRights.CanModifyObjects) != 0; + } + } + + /// + /// My rights represented as bitmapped flags + /// + public FriendRights MyFriendRights + { + get + { + FriendRights results = FriendRights.None; + if (m_canSeeThemOnline) + results |= FriendRights.CanSeeOnline; + if (m_canSeeThemOnMap) + results |= FriendRights.CanSeeOnMap; + if (m_canModifyTheirObjects) + results |= FriendRights.CanModifyObjects; + + return results; + } + set + { + m_canSeeThemOnline = (value & FriendRights.CanSeeOnline) != 0; + m_canSeeThemOnMap = (value & FriendRights.CanSeeOnMap) != 0; + m_canModifyTheirObjects = (value & FriendRights.CanModifyObjects) != 0; + } + } + + /// + /// FriendInfo represented as a string + /// + /// A string reprentation of both my rights and my friends rights + public override string ToString() + { + if (!String.IsNullOrEmpty(m_name)) + return String.Format("{0} (Their Rights: {1}, My Rights: {2})", m_name, TheirFriendRights, + MyFriendRights); + else + return String.Format("{0} (Their Rights: {1}, My Rights: {2})", m_id, TheirFriendRights, + MyFriendRights); + } + } + + /// + /// This class is used to add and remove avatars from your friends list and to manage their permission. + /// + public class FriendsManager + { + #region Delegates + /// /// Triggered when an avatar in your friends list comes online /// /// System ID of the avatar public delegate void FriendOnlineEvent(FriendInfo friend); - /// /// Triggered when an avatar in your friends list goes offline /// /// System ID of the avatar public delegate void FriendOfflineEvent(FriendInfo friend); - /// /// Triggered in response to a call to the GrantRighs() method, or when a friend changes your rights /// /// System ID of the avatar you changed the right of public delegate void FriendRightsEvent(FriendInfo friend); - /// /// Triggered when someone offers you friendship /// @@ -250,7 +255,6 @@ namespace libsecondlife /// session ID need when accepting/declining the offer /// Return true to accept the friendship, false to deny it public delegate void FriendshipOfferedEvent(LLUUID agentID, string agentName, LLUUID imSessionID); - /// /// Trigger when your friendship offer has been accepted or declined /// @@ -258,7 +262,6 @@ namespace libsecondlife /// Full name of the avatar who accepted your friendship offer /// Whether the friendship request was accepted or declined public delegate void FriendshipResponseEvent(LLUUID agentID, string agentName, bool accepted); - /// /// Trigger when someone terminates your friendship. /// @@ -266,6 +269,10 @@ namespace libsecondlife /// Full name of the avatar who terminated your friendship public delegate void FriendshipTerminatedEvent(LLUUID agentID, string agentName); + #endregion Delegates + + #region Events + public event FriendOnlineEvent OnFriendOnline; public event FriendOfflineEvent OnFriendOffline; public event FriendRightsEvent OnFriendRights; @@ -273,6 +280,8 @@ namespace libsecondlife public event FriendshipResponseEvent OnFriendshipResponse; public event FriendshipTerminatedEvent OnFriendshipTerminated; + #endregion Events + private SecondLife Client; private Dictionary _Friends = new Dictionary(); private Dictionary _Requests = new Dictionary(); @@ -293,8 +302,10 @@ namespace libsecondlife Client.Network.RegisterCallback(PacketType.OfflineNotification, OfflineNotificationHandler); Client.Network.RegisterCallback(PacketType.ChangeUserRights, ChangeUserRightsHandler); Client.Network.RegisterCallback(PacketType.TerminateFriendship, TerminateFriendshipHandler); - } + Client.Network.RegisterLoginResponseCallback(new NetworkManager.LoginResponseCallback(Network_OnLoginResponse), + new string[] { "buddy-list" }); + } /// /// Get a list of all the friends we are currently aware of @@ -351,8 +362,8 @@ namespace libsecondlife Client.Network.SendPacket(request); - FriendInfo friend = new FriendInfo(fromAgentID, RightsFlags.CanSeeOnline, - RightsFlags.CanSeeOnline); + FriendInfo friend = new FriendInfo(fromAgentID, FriendRights.CanSeeOnline, + FriendRights.CanSeeOnline); lock (_Friends) { if(!_Friends.ContainsKey(fromAgentID)) _Friends.Add(friend.UUID, friend); @@ -455,32 +466,11 @@ namespace libsecondlife request.Rights = new GrantUserRightsPacket.RightsBlock[1]; request.Rights[0] = new GrantUserRightsPacket.RightsBlock(); request.Rights[0].AgentRelated = agentID; - request.Rights[0].RelatedRights = (int)(_Friends[agentID].TheirRightsFlags); + request.Rights[0].RelatedRights = (int)(_Friends[agentID].TheirFriendRights); Client.Network.SendPacket(request); } - - /// - /// Adds a friend. Intended for use by the libsecondlife framework to build the - /// initial list of friends from the buddy-list in the login reply XML - /// - /// ID of the agent being added to the list of friends - /// rights the friend has - /// rights you have - internal void AddFriend(LLUUID agentID, RightsFlags theirRights, RightsFlags myRights) - { - lock (_Friends) - { - if (!_Friends.ContainsKey(agentID)) - { - FriendInfo friend = new FriendInfo(agentID, theirRights, myRights); - _Friends[agentID] = friend; - } - } - } - - /// /// Called when a connection to the SL server is established. The list of friend avatars /// is populated from XML returned by the login server. That list contains the avatar's id @@ -543,8 +533,8 @@ namespace libsecondlife { if (!_Friends.ContainsKey(block.AgentID)) { - friend = new FriendInfo(block.AgentID, RightsFlags.CanSeeOnline, - RightsFlags.CanSeeOnline); + friend = new FriendInfo(block.AgentID, FriendRights.CanSeeOnline, + FriendRights.CanSeeOnline); _Friends.Add(block.AgentID, friend); } else @@ -584,7 +574,7 @@ namespace libsecondlife lock (_Friends) { if (!_Friends.ContainsKey(block.AgentID)) - _Friends.Add(block.AgentID, new FriendInfo(block.AgentID, RightsFlags.CanSeeOnline, RightsFlags.CanSeeOnline)); + _Friends.Add(block.AgentID, new FriendInfo(block.AgentID, FriendRights.CanSeeOnline, FriendRights.CanSeeOnline)); friend = _Friends[block.AgentID]; friend.IsOnline = false; @@ -615,10 +605,10 @@ namespace libsecondlife foreach (ChangeUserRightsPacket.RightsBlock block in rights.Rights) { - RightsFlags newRights = (RightsFlags)block.RelatedRights; + FriendRights newRights = (FriendRights)block.RelatedRights; if (_Friends.TryGetValue(block.AgentRelated, out friend)) { - friend.TheirRightsFlags = newRights; + friend.TheirFriendRights = newRights; if (OnFriendRights != null) { try { OnFriendRights(friend); } @@ -629,7 +619,7 @@ namespace libsecondlife { if (_Friends.TryGetValue(rights.AgentData.AgentID, out friend)) { - friend.MyRightsFlags = newRights; + friend.MyFriendRights = newRights; if (OnFriendRights != null) { try { OnFriendRights(friend); } @@ -678,7 +668,8 @@ namespace libsecondlife } else if (im.Dialog == InstantMessageDialog.FriendshipAccepted) { - FriendInfo friend = new FriendInfo(im.FromAgentID, RightsFlags.CanSeeOnline, RightsFlags.CanSeeOnline); + FriendInfo friend = new FriendInfo(im.FromAgentID, FriendRights.CanSeeOnline, + FriendRights.CanSeeOnline); friend.Name = im.FromAgentName; lock (_Friends) _Friends[friend.UUID] = friend; @@ -697,5 +688,21 @@ namespace libsecondlife } } } + + private void Network_OnLoginResponse(bool loginSuccess, bool redirect, string message, string reason, + LoginResponseData replyData) + { + if (loginSuccess) + { + lock (_Friends) + { + for (int i = 0; i < replyData.BuddyList.Length; i++) + { + FriendInfo friend = replyData.BuddyList[i]; + _Friends[friend.UUID] = friend; + } + } + } + } } } diff --git a/libsecondlife/InventoryManager.cs b/libsecondlife/InventoryManager.cs index 4a54f659..7132bdcd 100644 --- a/libsecondlife/InventoryManager.cs +++ b/libsecondlife/InventoryManager.cs @@ -224,6 +224,11 @@ namespace libsecondlife public InventoryFolder(LLUUID itemID) : base(itemID) { } + public override string ToString() + { + return Name; + } + public override int GetHashCode() { return PreferredType.GetHashCode() ^ Version.GetHashCode() ^ DescendentCount.GetHashCode(); @@ -262,6 +267,8 @@ namespace libsecondlife public int Level; } + #region Delegates + /// /// Callback for inventory item creation finishing /// @@ -336,6 +343,10 @@ namespace libsecondlife /// Filename of the task inventory asset public delegate void TaskInventoryReplyCallback(LLUUID itemID, short serial, string assetFilename); + #endregion Delegates + + #region Events + public event ItemReceivedCallback OnItemReceived; public event FolderUpdatedCallback OnFolderUpdated; public event ObjectOfferedCallback OnObjectOffered; @@ -343,6 +354,8 @@ namespace libsecondlife public event FindObjectByPathCallback OnFindObjectByPath; public event TaskInventoryReplyCallback OnTaskInventoryReply; + #endregion Events + private SecondLife _Client; private Inventory _Store; private Random _RandNumbers = new Random(); @@ -465,10 +478,16 @@ namespace libsecondlife _Client.Network.RegisterCallback(PacketType.InventoryDescendents, new NetworkManager.PacketCallback(InventoryDescendentsHandler)); _Client.Network.RegisterCallback(PacketType.FetchInventoryReply, new NetworkManager.PacketCallback(FetchInventoryReplyHandler)); _Client.Network.RegisterCallback(PacketType.ReplyTaskInventory, new NetworkManager.PacketCallback(ReplyTaskInventoryHandler)); + // Watch for inventory given to us through instant message _Client.Self.OnInstantMessage += new AgentManager.InstantMessageCallback(Self_OnInstantMessage); + // Register extra parameters with login and parse the inventory data that comes back - _Client.Network.RegisterLoginResponseCallback(new NetworkManager.LoginResponseCallback(Network_OnLoginResponse), new string[] {"inventory-root", "inventory-skeleton", "inventory-lib-root", "inventory-lib-owner", "inventory-skel-lib"} ); + _Client.Network.RegisterLoginResponseCallback( + new NetworkManager.LoginResponseCallback(Network_OnLoginResponse), + new string[] { + "inventory-root", "inventory-skeleton", "inventory-lib-root", + "inventory-lib-owner", "inventory-skel-lib"}); } @@ -2563,7 +2582,7 @@ namespace libsecondlife } } - private void Network_OnLoginResponse(bool loginSuccess, bool redirect, string message, string reason, NetworkManager.LoginResponseData replyData) + private void Network_OnLoginResponse(bool loginSuccess, bool redirect, string message, string reason, LoginResponseData replyData) { if (loginSuccess) { @@ -2573,8 +2592,8 @@ namespace libsecondlife rootFolder.ParentUUID = LLUUID.Zero; _Store.RootFolder = rootFolder; - foreach (InventoryFolder folder in replyData.InventorySkeleton) - _Store.UpdateNodeFor(folder); + for (int i = 0; i < replyData.InventorySkeleton.Length; i++) + _Store.UpdateNodeFor(replyData.InventorySkeleton[i]); } } diff --git a/libsecondlife/LLSD/LLSD.cs b/libsecondlife/LLSD/LLSD.cs index 7f8c04b2..70b6f2f3 100644 --- a/libsecondlife/LLSD/LLSD.cs +++ b/libsecondlife/LLSD/LLSD.cs @@ -141,7 +141,11 @@ namespace libsecondlife.StructuredData public LLSDString(string value) { - this.value = value; + // Refuse to hold null pointers + if (value != null) + this.value = value; + else + this.value = String.Empty; } public override bool AsBoolean() { return !String.IsNullOrEmpty(value); } diff --git a/libsecondlife/Login.cs b/libsecondlife/Login.cs index 046045de..f0850e4e 100644 --- a/libsecondlife/Login.cs +++ b/libsecondlife/Login.cs @@ -36,6 +36,60 @@ using CookComputing.XmlRpc; namespace libsecondlife { + /// + /// + /// + public enum LoginStatus + { + /// + Failed = -1, + /// + None = 0, + /// + ConnectingToLogin, + /// + ReadingResponse, + /// + ConnectingToSim, + /// + Redirecting, + /// + Success + } + + /// + /// + /// + public struct LoginParams + { + /// + public string URI; + /// + public int Timeout; + /// + public string MethodName; + /// + public string FirstName; + /// + public string LastName; + /// + public string Password; + /// + public string Start; + /// + public string Channel; + /// + public string Version; + /// + public string Platform; + /// + public string MAC; + /// + public string ViewerDigest; + /// + public List Options; + } + // TODO: Remove me when MONO can handle ServerCertificateValidationCallback internal class AcceptAllCertificatePolicy : ICertificatePolicy { @@ -52,25 +106,147 @@ namespace libsecondlife } } + public struct LoginResponseData + { + public LLUUID AgentID; + public LLUUID SessionID; + public LLUUID SecureSessionID; + public string FirstName; + public string LastName; + public string StartLocation; + public string AgentAccess; + public LLVector3 LookAt; + public LLVector3 HomePosition; + public LLVector3 HomeLookAt; + public uint CircuitCode; + public uint RegionX; + public uint RegionY; + public ushort SimPort; + public IPAddress SimIP; + public string SeedCapability; + public FriendInfo[] BuddyList; + public DateTime SecondsSinceEpoch; + public LLUUID InventoryRoot; + public LLUUID LibraryRoot; + public InventoryFolder[] InventorySkeleton; + public InventoryFolder[] LibrarySkeleton; + public LLUUID LibraryOwner; + + public void Parse(NetworkManager.LoginMethodResponse reply) + { + AgentID = LLUUID.Parse(reply.agent_id); + SessionID = LLUUID.Parse(reply.session_id); + SecureSessionID = LLUUID.Parse(reply.secure_session_id); + FirstName = reply.first_name; + LastName = reply.last_name; + StartLocation = reply.start_location; + AgentAccess = reply.agent_access; + + LLSDArray look_at = (LLSDArray)LLSDParser.DeserializeNotation(reply.look_at); + LookAt = new LLVector3( + (float)look_at[0].AsReal(), + (float)look_at[1].AsReal(), + (float)look_at[2].AsReal()); + + if (reply.home != null) + { + LLSDMap home = (LLSDMap)LLSDParser.DeserializeNotation(reply.home); + LLSDArray array = (LLSDArray)home["position"]; + HomePosition = new LLVector3( + (float)array[0].AsReal(), + (float)array[1].AsReal(), + (float)array[2].AsReal()); + + array = (LLSDArray)home["look_at"]; + HomeLookAt = new LLVector3( + (float)array[0].AsReal(), + (float)array[1].AsReal(), + (float)array[2].AsReal()); + } + + CircuitCode = (uint)reply.circuit_code; + RegionX = (uint)reply.region_x; + RegionY = (uint)reply.region_y; + SimPort = (ushort)reply.sim_port; + SimIP = IPAddress.Parse(reply.sim_ip); + SeedCapability = reply.seed_capability; + + if (reply.buddy_list != null) + { + BuddyList = new FriendInfo[reply.buddy_list.Length]; + for (int i = 0; i < BuddyList.Length; ++i) + { + NetworkManager.BuddyListEntry buddy = reply.buddy_list[i]; + BuddyList[i] = new FriendInfo(buddy.buddy_id, (FriendRights)buddy.buddy_rights_given, + (FriendRights)buddy.buddy_rights_has); + } + } + else + { + BuddyList = new FriendInfo[0]; + } + + InventoryRoot = LLUUID.Parse(reply.inventory_root[0].folder_id); + LibraryRoot = LLUUID.Parse(reply.inventory_lib_root[0].folder_id); + LibraryOwner = LLUUID.Parse(reply.inventory_lib_owner[0].agent_id); + InventorySkeleton = ParseSkeleton(reply.inventory_skeleton, AgentID); + LibrarySkeleton = ParseSkeleton(reply.inventory_skel_lib, LibraryOwner); + } + + public InventoryFolder[] ParseSkeleton(NetworkManager.InventorySkeletonEntry[] skeleton, LLUUID owner) + { + Dictionary Folders = new Dictionary(); + Dictionary> FoldersChildren = new Dictionary>(skeleton.Length); + + foreach (NetworkManager.InventorySkeletonEntry entry in skeleton) + { + InventoryFolder folder = new InventoryFolder(entry.folder_id); + if (entry.type_default != -1) + folder.PreferredType = (AssetType)entry.type_default; + folder.Version = entry.version; + folder.OwnerID = owner; + folder.ParentUUID = LLUUID.Parse(entry.parent_id); + folder.Name = entry.name; + Folders.Add(entry.folder_id, folder); + + if (entry.parent_id != LLUUID.Zero) + { + List parentChildren; + if (!FoldersChildren.TryGetValue(entry.parent_id, out parentChildren)) + { + parentChildren = new List(); + FoldersChildren.Add(entry.parent_id, parentChildren); + } + parentChildren.Add(folder); + } + } + + foreach (KeyValuePair> pair in FoldersChildren) + { + if (Folders.ContainsKey(pair.Key)) + { + InventoryFolder parentFolder = Folders[pair.Key]; + parentFolder.DescendentCount = pair.Value.Count; // Should we set this here? it's just the folders, not the items! + } + } + + // Should we do this or just return an IEnumerable? + InventoryFolder[] ret = new InventoryFolder[Folders.Count]; + int index = 0; + foreach (InventoryFolder folder in Folders.Values) + { + ret[index] = folder; + ++index; + } + return ret; + } + } + public partial class NetworkManager { /// /// /// - /// - /// - /// - /// - /// - /// - /// - /// - [Obsolete("Use LoginResponseCallback instead.")] - public delegate void LoginReplyCallback(bool loginSuccess, bool redirect, IPAddress simIP, int simPort, - uint regionX, uint regionY, string reason, string message); - /// - /// - /// /// /// public delegate void LoginCallback(LoginStatus login, string message); @@ -83,201 +259,6 @@ namespace libsecondlife /// public delegate void LoginResponseCallback(bool loginSuccess, bool redirect, string message, string reason, LoginResponseData replyData); - /// - /// - /// - public struct LoginParams - { - /// - public string URI; - /// - public int Timeout; - /// - public string MethodName; - /// - public string FirstName; - /// - public string LastName; - /// - public string Password; - /// - public string Start; - /// - public string Channel; - /// - public string Version; - /// - public string Platform; - /// - public string MAC; - /// - public string ViewerDigest; - /// - public List Options; - } - - public struct LoginResponseData - { - public LLUUID AgentID; - public LLUUID SessionID; - public LLUUID SecureSessionID; - public string FirstName; - public string LastName; - public string StartLocation; - public string AgentAccess; - public LLVector3 LookAt; - public LLVector3 HomePosition; - public LLVector3 HomeLookAt; - public uint CircuitCode; - public uint RegionX; - public uint RegionY; - public ushort SimPort; - public IPAddress SimIP; - public string SeedCapability; - public FriendsManager.FriendInfo[] BuddyList; - public DateTime SecondsSinceEpoch; - public LLUUID InventoryRoot; - public LLUUID LibraryRoot; - public InventoryFolder[] InventorySkeleton; - public InventoryFolder[] LibrarySkeleton; - public LLUUID LibraryOwner; - - public void Parse(LoginMethodResponse reply) - { - AgentID = LLUUID.Parse(reply.agent_id); - SessionID = LLUUID.Parse(reply.session_id); - SecureSessionID = LLUUID.Parse(reply.secure_session_id); - FirstName = reply.first_name; - LastName = reply.last_name; - StartLocation = reply.start_location; - AgentAccess = reply.agent_access; - - LLSDArray look_at = (LLSDArray)LLSDParser.DeserializeNotation(reply.look_at); - LookAt = new LLVector3( - (float)look_at[0].AsReal(), - (float)look_at[1].AsReal(), - (float)look_at[2].AsReal()); - - if (reply.home != null) - { - LLSDMap home = (LLSDMap)LLSDParser.DeserializeNotation(reply.home); - LLSDArray array = (LLSDArray)home["position"]; - HomePosition = new LLVector3( - (float)array[0].AsReal(), - (float)array[1].AsReal(), - (float)array[2].AsReal()); - - array = (LLSDArray)home["look_at"]; - HomeLookAt = new LLVector3( - (float)array[0].AsReal(), - (float)array[1].AsReal(), - (float)array[2].AsReal()); - } - - CircuitCode = (uint)reply.circuit_code; - RegionX = (uint)reply.region_x; - RegionY = (uint)reply.region_y; - SimPort = (ushort)reply.sim_port; - SimIP = IPAddress.Parse(reply.sim_ip); - SeedCapability = reply.seed_capability; - - if (reply.buddy_list != null) - { - BuddyList = new FriendsManager.FriendInfo[reply.buddy_list.Length]; - for (int i = 0; i < BuddyList.Length; ++i) - { - BuddyListEntry buddy = reply.buddy_list[i]; - BuddyList[i] = new FriendsManager.FriendInfo(buddy.buddy_id, (FriendsManager.RightsFlags)buddy.buddy_rights_given, - (FriendsManager.RightsFlags)buddy.buddy_rights_has); - } - } - else - { - BuddyList = new FriendsManager.FriendInfo[0]; - } - - InventoryRoot = LLUUID.Parse(reply.inventory_root[0].folder_id); - LibraryRoot = LLUUID.Parse(reply.inventory_lib_root[0].folder_id); - LibraryOwner = LLUUID.Parse(reply.inventory_lib_owner[0].agent_id); - InventorySkeleton = ParseSkeleton(reply.inventory_skeleton, AgentID); - LibrarySkeleton = ParseSkeleton(reply.inventory_skel_lib, LibraryOwner); - } - - public InventoryFolder[] ParseSkeleton(InventorySkeletonEntry[] skeleton, LLUUID owner) - { - Dictionary Folders = new Dictionary(); - Dictionary> FoldersChildren = new Dictionary>(skeleton.Length); - - foreach (InventorySkeletonEntry entry in skeleton) - { - InventoryFolder folder = new InventoryFolder(entry.folder_id); - if (entry.type_default != -1) - folder.PreferredType = (AssetType)entry.type_default; - folder.Version = entry.version; - folder.OwnerID = owner; - folder.ParentUUID = LLUUID.Parse(entry.parent_id); - folder.Name = entry.name; - Folders.Add(entry.folder_id, folder); - - if (entry.parent_id != LLUUID.Zero) - { - List parentChildren; - if (!FoldersChildren.TryGetValue(entry.parent_id, out parentChildren)) - { - parentChildren = new List(); - FoldersChildren.Add(entry.parent_id, parentChildren); - } - parentChildren.Add(folder); - } - } - - foreach (KeyValuePair> pair in FoldersChildren) - { - if (Folders.ContainsKey(pair.Key)) - { - InventoryFolder parentFolder = Folders[pair.Key]; - parentFolder.DescendentCount = pair.Value.Count; // Should we set this here? it's just the folders, not the items! - } - } - - // Should we do this or just return an IEnumerable? - InventoryFolder[] ret = new InventoryFolder[Folders.Count]; - int index = 0; - foreach (InventoryFolder folder in Folders.Values) - { - ret[index] = folder; - ++index; - } - return ret; - } - } - - /// - /// - /// - public enum LoginStatus - { - /// - Failed = -1, - /// - None = 0, - /// - ConnectingToLogin, - /// - ReadingResponse, - /// - ConnectingToSim, - /// - Redirecting, - /// - Success - } - - /// Called when a reply is received from the login server, the - /// login sequence will block until this event returns - [Obsolete("Use RegisterLoginResponse instead.")] - public event LoginReplyCallback OnLoginReply; - /// Called any time the login status changes, will eventually /// return LoginStatus.Success or LoginStatus.Failure public event LoginCallback OnLogin; @@ -631,45 +612,10 @@ namespace libsecondlife } #endregion Critical Information - - // Buddies: - if (reply.buddy_list != null) - { - foreach (BuddyListEntry buddy in reply.buddy_list) - { - Client.Friends.AddFriend(buddy.buddy_id, (FriendsManager.RightsFlags)buddy.buddy_rights_given, - (FriendsManager.RightsFlags)buddy.buddy_rights_has); - } - } - - // Misc: - //uint timestamp = (uint)reply.seconds_since_epoch; - //DateTime time = Helpers.UnixTimeToDateTime(timestamp); // TODO: Do something with this? - - // Unhandled: - // reply.gestures - // reply.event_categories - // reply.classified_categories - // reply.event_notifications - // reply.ui_config - // reply.login_flags - // reply.global_textures - // reply.inventory_lib_root - // reply.inventory_lib_owner - // reply.inventory_skeleton - // reply.inventory_skel_lib - // reply.initial_outfit } bool redirect = (reply.login == "indeterminate"); - // Fire the client handler - if (OnLoginReply != null) - { - try { OnLoginReply(loginSuccess, redirect, simIP, simPort, regionX, regionY, reason, message); } - catch (Exception ex) { Client.Log(ex.ToString(), Helpers.LogLevel.Error); } - } - try { if (OnLoginResponse != null) diff --git a/libsecondlife/Prims.cs b/libsecondlife/Prims.cs index 723c2bcb..a6b58e7a 100644 --- a/libsecondlife/Prims.cs +++ b/libsecondlife/Prims.cs @@ -257,6 +257,24 @@ namespace libsecondlife return data; } + + /// + /// + /// + /// + public LLSD ToLLSD() + { + LLSDMap map = new LLSDMap(); + + map["softness"] = LLSD.FromInteger(Softness); + map["gravity"] = LLSD.FromReal(Gravity); + map["drag"] = LLSD.FromReal(Drag); + map["wind"] = LLSD.FromReal(Wind); + map["tension"] = LLSD.FromReal(Tension); + map["force"] = Force.ToLLSD(); + + return map; + } } /// @@ -322,6 +340,19 @@ namespace libsecondlife return data; } + public LLSD ToLLSD() + { + LLSDMap map = new LLSDMap(); + + map["color"] = Color.ToLLSD(); + map["intensity"] = LLSD.FromReal(Intensity); + map["radius"] = LLSD.FromReal(Radius); + map["cutoff"] = LLSD.FromReal(Cutoff); + map["falloff"] = LLSD.FromReal(Falloff); + + return map; + } + /// /// /// @@ -364,6 +395,16 @@ namespace libsecondlife return data; } + + public LLSD ToLLSD() + { + LLSDMap map = new LLSDMap(); + + map["texture"] = LLSD.FromUUID(SculptTexture); + map["type"] = LLSD.FromInteger((int)Type); + + return map; + } } #endregion Subclasses @@ -462,6 +503,10 @@ namespace libsecondlife if (ParentID != 0) prim["parentid"] = LLSD.FromInteger(ParentID); + prim["light"] = Light.ToLLSD(); + prim["flex"] = Flexible.ToLLSD(); + prim["sculpt"] = Sculpt.ToLLSD(); + return prim; } diff --git a/libsecondlife/_Packets_.cs b/libsecondlife/_Packets_.cs index d663a5f6..5ba65089 100644 --- a/libsecondlife/_Packets_.cs +++ b/libsecondlife/_Packets_.cs @@ -1196,35 +1196,6 @@ namespace libsecondlife.Packets return PacketType.Default; } - public static PacketType GetType(byte[] bytes, int packetEnd, byte[] zeroBuffer) - { - ushort id; PacketFrequency freq; - int i = 0, end = packetEnd; - Header header = Header.BuildHeader(bytes, ref i, ref end); - if (header.Zerocoded) - { - end = Helpers.ZeroDecode(bytes, end + 1, zeroBuffer) - 1; - bytes = zeroBuffer; - } - - if (bytes[6] == 0xFF) - { - if (bytes[7] == 0xFF) - { - id = (ushort)((bytes[8] << 8) + bytes[9]); freq = PacketFrequency.Low; - } - else - { - id = (ushort)bytes[7]; freq = PacketFrequency.Medium; - } - } - else - { - id = (ushort)bytes[6]; freq = PacketFrequency.High; - } - return GetType(id, freq); - } - public static Packet BuildPacket(PacketType type) { if(type == PacketType.StartPingCheck) return new StartPingCheckPacket(); diff --git a/libsecondlife/examples/TestClient/ClientManager.cs b/libsecondlife/examples/TestClient/ClientManager.cs index 07cea828..6415bfa5 100644 --- a/libsecondlife/examples/TestClient/ClientManager.cs +++ b/libsecondlife/examples/TestClient/ClientManager.cs @@ -42,7 +42,7 @@ namespace libsecondlife.TestClient public bool Running = true; - string contactPerson = String.Empty; + string version = "1.0.0"; private LLUUID resolvedMasterKey = LLUUID.Zero; private ManualResetEvent keyResolution = new ManualResetEvent(false); @@ -50,16 +50,14 @@ namespace libsecondlife.TestClient /// /// /// - public ClientManager(List accounts, string c) + public ClientManager(List accounts) { - this.contactPerson = c; foreach (LoginDetails account in accounts) Login(account); } - public ClientManager(List accounts, string c, string s) + public ClientManager(List accounts, string s) { - this.contactPerson = c; char sep = '/'; string[] startbits = s.Split(sep); @@ -98,8 +96,8 @@ namespace libsecondlife.TestClient client.MasterName = account.MasterName; client.MasterKey = account.MasterKey; - NetworkManager.LoginParams loginParams = client.Network.DefaultLoginParams( - account.FirstName, account.LastName, account.Password, "TestClient", contactPerson); + LoginParams loginParams = client.Network.DefaultLoginParams( + account.FirstName, account.LastName, account.Password, "TestClient", version); if (!String.IsNullOrEmpty(account.StartLocation)) loginParams.Start = account.StartLocation; diff --git a/libsecondlife/examples/TestClient/Commands/Friends/FriendsCommand.cs b/libsecondlife/examples/TestClient/Commands/Friends/FriendsCommand.cs index 2f7d24a5..1f9463bc 100644 --- a/libsecondlife/examples/TestClient/Commands/Friends/FriendsCommand.cs +++ b/libsecondlife/examples/TestClient/Commands/Friends/FriendsCommand.cs @@ -18,11 +18,11 @@ namespace libsecondlife.TestClient } public override string Execute(string[] args, LLUUID fromAgentID) { - List friends = Client.Friends.FriendsList(); + List friends = Client.Friends.FriendsList(); if (friends.Count > 0) { StringBuilder sb = new StringBuilder(); - foreach (FriendsManager.FriendInfo friend in friends) + foreach (FriendInfo friend in friends) { sb.AppendLine(friend.Name); } diff --git a/libsecondlife/examples/TestClient/Commands/Inventory/ImportOutfitCommand.cs b/libsecondlife/examples/TestClient/Commands/Inventory/ImportOutfitCommand.cs index 9e8c80c4..f36682d7 100644 --- a/libsecondlife/examples/TestClient/Commands/Inventory/ImportOutfitCommand.cs +++ b/libsecondlife/examples/TestClient/Commands/Inventory/ImportOutfitCommand.cs @@ -8,7 +8,7 @@ namespace libsecondlife.TestClient { public class ImportOutfitCommand : Command { - private uint SerialNum = 1; + //private uint SerialNum = 1; public ImportOutfitCommand(TestClient testClient) { @@ -23,45 +23,45 @@ namespace libsecondlife.TestClient return "LLSD packet import is under construction"; - try - { - Packet packet = Packet.FromXmlString((File.ReadAllText(args[0]))); - if (packet.Type != PacketType.AvatarAppearance) - return "Deserialized a " + packet.Type + " packet instead of an AvatarAppearance packet"; - AvatarAppearancePacket appearance = (AvatarAppearancePacket)packet; + //try + //{ + // Packet packet = Packet.FromXmlString((File.ReadAllText(args[0]))); + // if (packet.Type != PacketType.AvatarAppearance) + // return "Deserialized a " + packet.Type + " packet instead of an AvatarAppearance packet"; + // AvatarAppearancePacket appearance = (AvatarAppearancePacket)packet; - AgentSetAppearancePacket set = new AgentSetAppearancePacket(); + // AgentSetAppearancePacket set = new AgentSetAppearancePacket(); - set.AgentData.AgentID = Client.Self.AgentID; - set.AgentData.SessionID = Client.Self.SessionID; - set.AgentData.SerialNum = SerialNum++; + // set.AgentData.AgentID = Client.Self.AgentID; + // set.AgentData.SessionID = Client.Self.SessionID; + // set.AgentData.SerialNum = SerialNum++; - // HACK: Weak hack to calculate size - float AV_Height_Range = 2.025506f - 1.50856f; - float AV_Height = 1.50856f + (((float)appearance.VisualParam[25].ParamValue / 255.0f) * AV_Height_Range); - set.AgentData.Size = new LLVector3(0.45f, 0.6f, AV_Height); + // // HACK: Weak hack to calculate size + // float AV_Height_Range = 2.025506f - 1.50856f; + // float AV_Height = 1.50856f + (((float)appearance.VisualParam[25].ParamValue / 255.0f) * AV_Height_Range); + // set.AgentData.Size = new LLVector3(0.45f, 0.6f, AV_Height); - set.ObjectData.TextureEntry = appearance.ObjectData.TextureEntry; - set.VisualParam = new AgentSetAppearancePacket.VisualParamBlock[appearance.VisualParam.Length]; + // set.ObjectData.TextureEntry = appearance.ObjectData.TextureEntry; + // set.VisualParam = new AgentSetAppearancePacket.VisualParamBlock[appearance.VisualParam.Length]; - int i = 0; - foreach (AvatarAppearancePacket.VisualParamBlock block in appearance.VisualParam) - { - set.VisualParam[i] = new AgentSetAppearancePacket.VisualParamBlock(); - set.VisualParam[i].ParamValue = block.ParamValue; - i++; - } + // int i = 0; + // foreach (AvatarAppearancePacket.VisualParamBlock block in appearance.VisualParam) + // { + // set.VisualParam[i] = new AgentSetAppearancePacket.VisualParamBlock(); + // set.VisualParam[i].ParamValue = block.ParamValue; + // i++; + // } - set.WearableData = new AgentSetAppearancePacket.WearableDataBlock[0]; + // set.WearableData = new AgentSetAppearancePacket.WearableDataBlock[0]; - Client.Network.SendPacket(set); - } - catch (Exception) - { - return "Failed to import the appearance XML file, maybe it doesn't exist or is in the wrong format?"; - } + // Client.Network.SendPacket(set); + //} + //catch (Exception) + //{ + // return "Failed to import the appearance XML file, maybe it doesn't exist or is in the wrong format?"; + //} - return "Imported " + args[0] + " and sent an AgentSetAppearance packet"; + //return "Imported " + args[0] + " and sent an AgentSetAppearance packet"; } } } diff --git a/libsecondlife/examples/TestClient/Commands/System/PacketLogCommand.cs b/libsecondlife/examples/TestClient/Commands/System/PacketLogCommand.cs index a3f2aed0..9c9bd2e0 100644 --- a/libsecondlife/examples/TestClient/Commands/System/PacketLogCommand.cs +++ b/libsecondlife/examples/TestClient/Commands/System/PacketLogCommand.cs @@ -1,18 +1,10 @@ using System; -using System.Collections.Generic; -using System.Xml; using libsecondlife; -using libsecondlife.Packets; namespace libsecondlife.TestClient { public class PacketLogCommand : Command { - List Packets = new List(); - bool Done = false; - int Count = 0; - int Total = 0; - public PacketLogCommand(TestClient testClient) { Name = "packetlog"; @@ -24,61 +16,7 @@ namespace libsecondlife.TestClient if (args.Length != 2) return "Usage: packetlog 10 tenpackets.xml"; - XmlWriter writer; - NetworkManager.PacketCallback callback = new NetworkManager.PacketCallback(OnPacket); - - Packets.Clear(); - Done = false; - Count = 0; - - try - { - Total = Int32.Parse(args[0]); - writer = XmlWriter.Create(args[1]); - - Client.Network.RegisterCallback(PacketType.Default, callback); - } - catch (Exception e) - { - return "Usage: packetlog 10 tenpackets.xml (" + e + ")"; - } - - while (!Done) - { - System.Threading.Thread.Sleep(100); - } - - Client.Network.UnregisterCallback(PacketType.Default, callback); - - try - { - return "This command is currently under construction"; - } - catch (Exception e) - { - return "Serialization failed: " + e.ToString(); - } - - writer.Close(); - Packets.Clear(); - - return "Exported " + Count + " packets to " + args[1]; - } - - private void OnPacket(Packet packet, Simulator simulator) - { - lock (Packets) - { - if (Count >= Total) - { - Done = true; - } - else - { - Packets.Add(packet); - Count++; - } - } + return "This function is currently unimplemented"; } } } diff --git a/libsecondlife/examples/TestClient/Program.cs b/libsecondlife/examples/TestClient/Program.cs index d057555f..6c672409 100644 --- a/libsecondlife/examples/TestClient/Program.cs +++ b/libsecondlife/examples/TestClient/Program.cs @@ -27,7 +27,6 @@ namespace libsecondlife.TestClient string masterName = String.Empty; LLUUID masterKey = LLUUID.Zero; string file = String.Empty; - string contact = String.Empty; string loginuri = String.Empty; try @@ -42,15 +41,6 @@ namespace libsecondlife.TestClient masterName = arguments["master"]; } - if (arguments["contact"] != null) - { - contact = arguments["contact"]; - } - else - { - contact = "anonymous"; - } - if (arguments["loginuri"] != null) { loginuri = arguments["loginuri"]; @@ -139,11 +129,11 @@ namespace libsecondlife.TestClient // Login the accounts and run the input loop if (arguments["startpos"] != null) { - manager = new ClientManager(accounts, contact, arguments["startpos"]); + manager = new ClientManager(accounts, arguments["startpos"]); } else { - manager = new ClientManager(accounts, contact); + manager = new ClientManager(accounts); } manager.Run(); diff --git a/libsecondlife/examples/sldump/sldump.cs b/libsecondlife/examples/sldump/sldump.cs index b94d9966..b4efb0c9 100644 --- a/libsecondlife/examples/sldump/sldump.cs +++ b/libsecondlife/examples/sldump/sldump.cs @@ -147,16 +147,16 @@ namespace sldump client.Network.Logout(); } - static void Network_OnLogin(NetworkManager.LoginStatus login, string message) + static void Network_OnLogin(LoginStatus login, string message) { Console.WriteLine("Login: " + login.ToString() + " (" + message + ")"); switch (login) { - case NetworkManager.LoginStatus.Failed: + case LoginStatus.Failed: LoginEvent.Set(); break; - case NetworkManager.LoginStatus.Success: + case LoginStatus.Success: LoginSuccess = true; LoginEvent.Set(); break; diff --git a/libsecondlife/mapgenerator/mapgenerator.cs b/libsecondlife/mapgenerator/mapgenerator.cs index 3168ff60..adc23465 100644 --- a/libsecondlife/mapgenerator/mapgenerator.cs +++ b/libsecondlife/mapgenerator/mapgenerator.cs @@ -876,27 +876,31 @@ namespace mapgenerator " break;" + Environment.NewLine + " }" + Environment.NewLine + Environment.NewLine + " return PacketType.Default;" + Environment.NewLine + " }" + Environment.NewLine); + // TODO: Not sure if this function is useful to anyone, but if it is it needs to be + // rewritten to not overwrite passed in pointers and decode the entire packet just + // to read the header + // Write the Packet.GetType() function - writer.WriteLine( - " public static PacketType GetType(byte[] bytes, int packetEnd, byte[] zeroBuffer)" + Environment.NewLine + - " {" + Environment.NewLine + " ushort id; PacketFrequency freq;" + Environment.NewLine + - " int i = 0, end = packetEnd;" + Environment.NewLine + - " Header header = Header.BuildHeader(bytes, ref i, ref end);" + Environment.NewLine + - " if (header.Zerocoded)" + Environment.NewLine + " {" + Environment.NewLine + - " end = Helpers.ZeroDecode(bytes, end + 1, zeroBuffer) - 1;" + Environment.NewLine + - " bytes = zeroBuffer;" + Environment.NewLine + " }" + Environment.NewLine + Environment.NewLine + - " if (bytes[6] == 0xFF)" + Environment.NewLine + " {" + Environment.NewLine + - " if (bytes[7] == 0xFF)" + Environment.NewLine + " {" + Environment.NewLine + - " id = (ushort)((bytes[8] << 8) + bytes[9]); freq = PacketFrequency.Low;" + Environment.NewLine + - " }" + Environment.NewLine + - " else" + Environment.NewLine + - " {" + Environment.NewLine + " id = (ushort)bytes[7]; freq = PacketFrequency.Medium;" + - Environment.NewLine + " }" + Environment.NewLine + " }" + Environment.NewLine + - " else" + Environment.NewLine + " {" + Environment.NewLine + - " id = (ushort)bytes[6]; freq = PacketFrequency.High;" + Environment.NewLine + - " }" + Environment.NewLine + - " return GetType(id, freq);" + Environment.NewLine + - " }" + Environment.NewLine); + //writer.WriteLine( + // " public static PacketType GetType(byte[] bytes, int packetEnd, byte[] zeroBuffer)" + Environment.NewLine + + // " {" + Environment.NewLine + " ushort id; PacketFrequency freq;" + Environment.NewLine + + // " int i = 0, end = packetEnd;" + Environment.NewLine + + // " Header header = Header.BuildHeader(bytes, ref i, ref end);" + Environment.NewLine + + // " if (header.Zerocoded)" + Environment.NewLine + " {" + Environment.NewLine + + // " end = Helpers.ZeroDecode(bytes, end + 1, zeroBuffer) - 1;" + Environment.NewLine + + // " bytes = zeroBuffer;" + Environment.NewLine + " }" + Environment.NewLine + Environment.NewLine + + // " if (bytes[6] == 0xFF)" + Environment.NewLine + " {" + Environment.NewLine + + // " if (bytes[7] == 0xFF)" + Environment.NewLine + " {" + Environment.NewLine + + // " id = (ushort)((bytes[8] << 8) + bytes[9]); freq = PacketFrequency.Low;" + Environment.NewLine + + // " }" + Environment.NewLine + + // " else" + Environment.NewLine + + // " {" + Environment.NewLine + " id = (ushort)bytes[7]; freq = PacketFrequency.Medium;" + + // Environment.NewLine + " }" + Environment.NewLine + " }" + Environment.NewLine + + // " else" + Environment.NewLine + " {" + Environment.NewLine + + // " id = (ushort)bytes[6]; freq = PacketFrequency.High;" + Environment.NewLine + + // " }" + Environment.NewLine + + // " return GetType(id, freq);" + Environment.NewLine + + // " }" + Environment.NewLine); // Write the Packet.BuildPacket(PacketType) function writer.WriteLine(" public static Packet BuildPacket(PacketType type)");