diff --git a/.nant/local.include b/.nant/local.include index 5ff96446c5..be79d1cfce 100644 --- a/.nant/local.include +++ b/.nant/local.include @@ -145,7 +145,12 @@ - + + + + + + @@ -260,6 +265,11 @@ + + + + + @@ -271,6 +281,7 @@ + diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index d540c07d76..30bf0140db 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -4,14 +4,10 @@ The following people have contributed to OpenSim (Thank you for your effort!) These folks represent the current core team for OpenSim, and are the people that make the day to day of OpenSim happen. -* justincc (OSVW Consulting, justincc.org) * Melanie Thielker * Diva (Crista Lopes, University of California, Irvine) -* BlueWall (James Hughes) * Nebadon Izumi (Michael Cerquoni, OSgrid) -* Snoopy Pfeffer * Robert Adams (MisterBlue) -* Oren Hurvitz (Kitely) * Kevin Cozens * Leal Duarte (Ubit Umarov) @@ -20,11 +16,14 @@ Core developers who have temporarily (we hope) gone chasing the white rabbit. They are in all similar to the active core developers, except that they haven't been that active lately, so their voting rights are awaiting their come back. -* Teravus (w3z) * Arthur Rodrigo S Valadares (IBM) +* BlueWall (James Hughes) * Dan Lake -* Marck + * Marck * Mic Bowman +* Oren Hurvitz (Kitely) +* Snoopy Pfeffer +* Teravus (w3z) = Past Open Sim Developers = These folks are alumns of the OpenSim core group, but are now @@ -57,7 +56,7 @@ where we are today. * John Hurliman * chi11ken (Genkii) * dahlia - +* justincc (OSVW Consulting, justincc.org) = Additional OpenSim Contributors = These folks have contributed code patches or content to OpenSimulator to help make it @@ -149,6 +148,7 @@ what it is today. * Micheil Merlin * Mike Osias (IBM) * Mike Pitman (IBM) +* Mike Rieker (Dreamnation) * mikemig * mikkopa/_someone - RealXtend * Misterblue diff --git a/OpenSim/Addons/Groups/GroupsModule.cs b/OpenSim/Addons/Groups/GroupsModule.cs index 0e3a1729b5..5b76e0a5b8 100644 --- a/OpenSim/Addons/Groups/GroupsModule.cs +++ b/OpenSim/Addons/Groups/GroupsModule.cs @@ -787,7 +787,7 @@ namespace OpenSim.Groups remoteClient.SendCreateGroupReply(groupID, true, "Group created successfully"); // Update the founder with new group information. - SendAgentGroupDataUpdate(remoteClient, false); + SendAgentGroupDataUpdate(remoteClient, true); } else remoteClient.SendCreateGroupReply(groupID, false, reason); diff --git a/OpenSim/Addons/Groups/Hypergrid/HGGroupsServiceRobustConnector.cs b/OpenSim/Addons/Groups/Hypergrid/HGGroupsServiceRobustConnector.cs index af007709be..51f3ec15e0 100644 --- a/OpenSim/Addons/Groups/Hypergrid/HGGroupsServiceRobustConnector.cs +++ b/OpenSim/Addons/Groups/Hypergrid/HGGroupsServiceRobustConnector.cs @@ -115,9 +115,10 @@ namespace OpenSim.Groups protected override byte[] ProcessRequest(string path, Stream requestData, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { - StreamReader sr = new StreamReader(requestData); - string body = sr.ReadToEnd(); - sr.Close(); + string body; + using(StreamReader sr = new StreamReader(requestData)) + body = sr.ReadToEnd(); + body = body.Trim(); //m_log.DebugFormat("[XXX]: query String: {0}", body); diff --git a/OpenSim/Addons/Groups/Remote/GroupsServiceRobustConnector.cs b/OpenSim/Addons/Groups/Remote/GroupsServiceRobustConnector.cs index 598e7a5a9d..8502bb5bda 100644 --- a/OpenSim/Addons/Groups/Remote/GroupsServiceRobustConnector.cs +++ b/OpenSim/Addons/Groups/Remote/GroupsServiceRobustConnector.cs @@ -91,9 +91,10 @@ namespace OpenSim.Groups protected override byte[] ProcessRequest(string path, Stream requestData, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { - StreamReader sr = new StreamReader(requestData); - string body = sr.ReadToEnd(); - sr.Close(); + string body; + using(StreamReader sr = new StreamReader(requestData)) + body = sr.ReadToEnd(); + body = body.Trim(); //m_log.DebugFormat("[XXX]: query String: {0}", body); diff --git a/OpenSim/Addons/Groups/Service/GroupsService.cs b/OpenSim/Addons/Groups/Service/GroupsService.cs index ea0fedd9de..bed91d9666 100644 --- a/OpenSim/Addons/Groups/Service/GroupsService.cs +++ b/OpenSim/Addons/Groups/Service/GroupsService.cs @@ -43,60 +43,62 @@ namespace OpenSim.Groups { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - public const GroupPowers DefaultEveryonePowers = GroupPowers.AllowSetHome | - GroupPowers.Accountable | - GroupPowers.JoinChat | - GroupPowers.AllowVoiceChat | - GroupPowers.ReceiveNotices | - GroupPowers.StartProposal | - GroupPowers.VoteOnProposal; + public const GroupPowers DefaultEveryonePowers = + GroupPowers.AllowSetHome | + GroupPowers.Accountable | + GroupPowers.JoinChat | + GroupPowers.AllowVoiceChat | + GroupPowers.ReceiveNotices | + GroupPowers.StartProposal | + GroupPowers.VoteOnProposal; - public const GroupPowers OwnerPowers = GroupPowers.Accountable | - GroupPowers.AllowEditLand | - GroupPowers.AllowFly | - GroupPowers.AllowLandmark | - GroupPowers.AllowRez | - GroupPowers.AllowSetHome | - GroupPowers.AllowVoiceChat | - GroupPowers.AssignMember | - GroupPowers.AssignMemberLimited | - GroupPowers.ChangeActions | - GroupPowers.ChangeIdentity | - GroupPowers.ChangeMedia | - GroupPowers.ChangeOptions | - GroupPowers.CreateRole | - GroupPowers.DeedObject | - GroupPowers.DeleteRole | - GroupPowers.Eject | - GroupPowers.FindPlaces | - GroupPowers.HostEvent | - GroupPowers.Invite | - GroupPowers.JoinChat | - GroupPowers.LandChangeIdentity | - GroupPowers.LandDeed | - GroupPowers.LandDivideJoin | - GroupPowers.LandEdit | - GroupPowers.LandEjectAndFreeze | - GroupPowers.LandGardening | - GroupPowers.LandManageAllowed | - GroupPowers.LandManageBanned | - GroupPowers.LandManagePasses | - GroupPowers.LandOptions | - GroupPowers.LandRelease | - GroupPowers.LandSetSale | - GroupPowers.ModerateChat | - GroupPowers.ObjectManipulate | - GroupPowers.ObjectSetForSale | - GroupPowers.ReceiveNotices | - GroupPowers.RemoveMember | - GroupPowers.ReturnGroupOwned | - GroupPowers.ReturnGroupSet | - GroupPowers.ReturnNonGroup | - GroupPowers.RoleProperties | - GroupPowers.SendNotices | - GroupPowers.SetLandingPoint | - GroupPowers.StartProposal | - GroupPowers.VoteOnProposal; + public const GroupPowers OfficersPowers = DefaultEveryonePowers | + GroupPowers.AllowFly | + GroupPowers.AllowLandmark | + GroupPowers.AllowRez | + GroupPowers.AssignMemberLimited | + GroupPowers.ChangeIdentity | + GroupPowers.ChangeMedia | + GroupPowers.ChangeOptions | + GroupPowers.DeedObject | + GroupPowers.Eject | + GroupPowers.FindPlaces | + GroupPowers.Invite | + GroupPowers.LandChangeIdentity | + GroupPowers.LandDeed | + GroupPowers.LandDivideJoin | + GroupPowers.LandEdit | + GroupPowers.LandEjectAndFreeze | + GroupPowers.LandGardening | + GroupPowers.LandManageAllowed | + GroupPowers.LandManageBanned | + GroupPowers.LandManagePasses | + GroupPowers.LandOptions | + GroupPowers.LandRelease | + GroupPowers.LandSetSale | + GroupPowers.MemberVisible | + GroupPowers.ModerateChat | + GroupPowers.ObjectManipulate | + GroupPowers.ObjectSetForSale | + GroupPowers.ReturnGroupOwned | + GroupPowers.ReturnGroupSet | + GroupPowers.ReturnNonGroup | + GroupPowers.RoleProperties | + GroupPowers.SendNotices | + GroupPowers.SetLandingPoint; + + public const GroupPowers OwnerPowers = OfficersPowers | + GroupPowers.Accountable | + GroupPowers.AllowEditLand | + GroupPowers.AssignMember | + GroupPowers.ChangeActions | + GroupPowers.CreateRole | + GroupPowers.DeleteRole | + GroupPowers.ExperienceAdmin | + GroupPowers.ExperienceCreator | + GroupPowers.GroupBanAccess | + GroupPowers.HostEvent | + GroupPowers.RemoveMember; #region Daily Cleanup @@ -151,20 +153,25 @@ namespace OpenSim.Groups data.Data["ShowInList"] = showInList ? "1" : "0"; data.Data["AllowPublish"] = allowPublish ? "1" : "0"; data.Data["MaturePublish"] = maturePublish ? "1" : "0"; - UUID roleID = UUID.Random(); - data.Data["OwnerRoleID"] = roleID.ToString(); + UUID ownerRoleID = UUID.Random(); + data.Data["OwnerRoleID"] = ownerRoleID.ToString(); if (!m_Database.StoreGroup(data)) return UUID.Zero; // Create Everyone role - _AddOrUpdateGroupRole(RequestingAgentID, data.GroupID, UUID.Zero, "Everyone", "Everyone in the group", "Member of " + name, (ulong)DefaultEveryonePowers, true); + _AddOrUpdateGroupRole(RequestingAgentID, data.GroupID, UUID.Zero, "Everyone", "Everyone in the group is in the everyone role.", "Member of " + name, (ulong)DefaultEveryonePowers, true); + + // Create Officers role + UUID officersRoleID = UUID.Random(); + _AddOrUpdateGroupRole(RequestingAgentID, data.GroupID, officersRoleID, "Officers", "The officers of the group, with more powers than regular members.", "Officer of " + name, (ulong)OfficersPowers, true); // Create Owner role - _AddOrUpdateGroupRole(RequestingAgentID, data.GroupID, roleID, "Owners", "Owners of the group", "Owner of " + name, (ulong)OwnerPowers, true); + _AddOrUpdateGroupRole(RequestingAgentID, data.GroupID, ownerRoleID, "Owners", "Owners of the group", "Owner of " + name, (ulong)OwnerPowers, true); // Add founder to group - _AddAgentToGroup(RequestingAgentID, founderID.ToString(), data.GroupID, roleID); + _AddAgentToGroup(RequestingAgentID, founderID.ToString(), data.GroupID, ownerRoleID); + _AddAgentToGroup(RequestingAgentID, founderID.ToString(), data.GroupID, officersRoleID); return data.GroupID; } @@ -843,7 +850,7 @@ namespace OpenSim.Groups return false; } - if (!add && data == null) // it deosn't exist, can't update + if (!add && data == null) // it doesn't exist, can't update { m_log.DebugFormat("[Groups]: Group {0} doesn't exist. Can't update it", groupID); return false; diff --git a/OpenSim/Addons/OfflineIM/OfflineIMRegionModule.cs b/OpenSim/Addons/OfflineIM/OfflineIMRegionModule.cs index 5340bcd094..d8164e718a 100644 --- a/OpenSim/Addons/OfflineIM/OfflineIMRegionModule.cs +++ b/OpenSim/Addons/OfflineIM/OfflineIMRegionModule.cs @@ -114,7 +114,6 @@ namespace OpenSim.OfflineIM scene.ForEachClient(delegate(IClientAPI client) { client.OnRetrieveInstantMessages -= RetrieveInstantMessages; - client.OnMuteListRequest -= OnMuteListRequest; }); } @@ -162,7 +161,6 @@ namespace OpenSim.OfflineIM private void OnNewClient(IClientAPI client) { client.OnRetrieveInstantMessages += RetrieveInstantMessages; - client.OnMuteListRequest += OnMuteListRequest; } private void RetrieveInstantMessages(IClientAPI client) @@ -194,20 +192,6 @@ namespace OpenSim.OfflineIM } } - // Apparently this is needed in order for the viewer to request the IMs. - private void OnMuteListRequest(IClientAPI client, uint crc) - { - m_log.DebugFormat("[OfflineIM.V2] Got mute list request for crc {0}", crc); - string filename = "mutes" + client.AgentId.ToString(); - - IXfer xfer = client.Scene.RequestModuleInterface(); - if (xfer != null) - { - xfer.AddNewFile(filename, new Byte[0]); - client.SendMuteListUpdate(filename); - } - } - private void UndeliveredMessage(GridInstantMessage im) { if (im.dialog != (byte)InstantMessageDialog.MessageFromObject && diff --git a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs index 1ee24689dc..468e7be92e 100644 --- a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs +++ b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs @@ -1934,7 +1934,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController GetSceneFromRegionParams(requestData, responseData, out scene); health = scene.GetHealth(out flags, out text); } - catch (Exception e) + catch { responseData["error"] = null; } @@ -3087,15 +3087,13 @@ namespace OpenSim.ApplicationPlugins.RemoteController /// private void ApplyNextOwnerPermissions(InventoryItemBase item) { - if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0) + if (item.InvType == (int)InventoryType.Object) { - if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) - item.CurrentPermissions &= ~(uint)PermissionMask.Copy; - if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) - item.CurrentPermissions &= ~(uint)PermissionMask.Transfer; - if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0) - item.CurrentPermissions &= ~(uint)PermissionMask.Modify; + uint perms = item.CurrentPermissions; + PermissionsUtil.ApplyFoldedPermissions(item.CurrentPermissions, ref perms); + item.CurrentPermissions = perms; } + item.CurrentPermissions &= item.NextPermissions; item.BasePermissions &= item.NextPermissions; item.EveryOnePermissions &= item.NextPermissions; diff --git a/OpenSim/Capabilities/Handlers/FetchInventory/FetchInvDescHandler.cs b/OpenSim/Capabilities/Handlers/FetchInventory/FetchInvDescHandler.cs index 53ed1152fd..427a310233 100644 --- a/OpenSim/Capabilities/Handlers/FetchInventory/FetchInvDescHandler.cs +++ b/OpenSim/Capabilities/Handlers/FetchInventory/FetchInvDescHandler.cs @@ -30,6 +30,7 @@ using System.Collections; using System.Collections.Generic; using System.Linq; using System.Reflection; +using System.Text; using log4net; using Nini.Config; using OpenMetaverse; @@ -60,26 +61,10 @@ namespace OpenSim.Capabilities.Handlers m_Scene = s; } - public string FetchInventoryDescendentsRequest(string request, string path, string param, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { //m_log.DebugFormat("[XXX]: FetchInventoryDescendentsRequest in {0}, {1}", (m_Scene == null) ? "none" : m_Scene.Name, request); - - // nasty temporary hack here, the linden client falsely - // identifies the uuid 00000000-0000-0000-0000-000000000000 - // as a string which breaks us - // - // correctly mark it as a uuid - // - request = request.Replace("00000000-0000-0000-0000-000000000000", "00000000-0000-0000-0000-000000000000"); - - // another hack 1 results in a - // System.ArgumentException: Object type System.Int32 cannot - // be converted to target type: System.Boolean - // - request = request.Replace("fetch_folders0", "fetch_folders0"); - request = request.Replace("fetch_folders1", "fetch_folders1"); - + Hashtable hash = new Hashtable(); try { @@ -92,10 +77,7 @@ namespace OpenSim.Capabilities.Handlers } ArrayList foldersrequested = (ArrayList)hash["folders"]; - - string response = ""; - string bad_folders_response = ""; - + List folders = new List(); for (int i = 0; i < foldersrequested.Count; i++) { @@ -113,72 +95,56 @@ namespace OpenSim.Capabilities.Handlers continue; } - // Filter duplicate folder ids that bad viewers may send - if (folders.Find(f => f.folder_id == llsdRequest.folder_id) == null) - folders.Add(llsdRequest); - + folders.Add(llsdRequest); } - if (folders.Count > 0) + if(folders.Count == 0) + return "folders"; + + List bad_folders = new List(); + + List invcollSet = Fetch(folders, bad_folders); + //m_log.DebugFormat("[XXX]: Got {0} folders from a request of {1}", invcollSet.Count, folders.Count); + + if (invcollSet == null) { - List bad_folders = new List(); - List invcollSet = Fetch(folders, bad_folders); - //m_log.DebugFormat("[XXX]: Got {0} folders from a request of {1}", invcollSet.Count, folders.Count); - - if (invcollSet == null) - { - m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Multiple folder fetch failed. Trying old protocol."); + m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Multiple folder fetch failed. Trying old protocol."); #pragma warning disable 0612 - return FetchInventoryDescendentsRequest(foldersrequested, httpRequest, httpResponse); + return FetchInventoryDescendentsRequest(foldersrequested, httpRequest, httpResponse); #pragma warning restore 0612 - } + } - string inventoryitemstr = string.Empty; + StringBuilder lastresponse = new StringBuilder(1024); + lastresponse.Append(""); + + if(invcollSet.Count > 0) + { + lastresponse.Append("folders"); foreach (InventoryCollectionWithDescendents icoll in invcollSet) { - LLSDInventoryDescendents reply = ToLLSD(icoll.Collection, icoll.Descendents); - - inventoryitemstr = LLSDHelpers.SerialiseLLSDReply(reply); - inventoryitemstr = inventoryitemstr.Replace("folders", ""); - inventoryitemstr = inventoryitemstr.Replace("", ""); - - response += inventoryitemstr; - } - - //m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Bad folders {0}", string.Join(", ", bad_folders)); - foreach (UUID bad in bad_folders) - bad_folders_response += "" + bad + ""; - } - - if (response.Length == 0) - { - /* Viewers expect a bad_folders array when not available */ - if (bad_folders_response.Length != 0) - { - response = "bad_folders" + bad_folders_response + ""; - } - else - { - response = "folders"; + LLSDInventoryFolderContents thiscontents = contentsToLLSD(icoll.Collection, icoll.Descendents); + lastresponse.Append(LLSDHelpers.SerialiseLLSDReplyNoHeader(thiscontents)); } + lastresponse.Append(""); } else + lastresponse.Append("folders"); + + //m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Bad folders {0}", string.Join(", ", bad_folders)); + if(bad_folders.Count > 0) { - if (bad_folders_response.Length != 0) + lastresponse.Append("bad_folders"); + foreach (UUID bad in bad_folders) { - response = "folders" + response + "bad_folders" + bad_folders_response + ""; - } - else - { - response = "folders" + response + ""; + lastresponse.Append("folder_id"); + lastresponse.Append(bad.ToString()); + lastresponse.Append("errorUnknown"); } + lastresponse.Append(""); } + lastresponse.Append(""); - //m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Replying to CAPS fetch inventory request for {0} folders. Item count {1}", folders.Count, item_count); - //m_log.Debug("[WEB FETCH INV DESC HANDLER] " + response); - - return response; - + return lastresponse.ToString();; } /// @@ -240,24 +206,19 @@ namespace OpenSim.Capabilities.Handlers return reply; } - private LLSDInventoryDescendents ToLLSD(InventoryCollection inv, int descendents) + private LLSDInventoryFolderContents contentsToLLSD(InventoryCollection inv, int descendents) { - LLSDInventoryDescendents reply = new LLSDInventoryDescendents(); LLSDInventoryFolderContents contents = new LLSDInventoryFolderContents(); contents.agent_id = inv.OwnerID; contents.owner_id = inv.OwnerID; contents.folder_id = inv.FolderID; - reply.folders.Array.Add(contents); - if (inv.Folders != null) { foreach (InventoryFolderBase invFolder in inv.Folders) { contents.categories.Array.Add(ConvertInventoryFolder(invFolder)); } - - descendents += inv.Folders.Count; } if (inv.Items != null) @@ -271,7 +232,7 @@ namespace OpenSim.Capabilities.Handlers contents.descendents = descendents; contents.version = inv.Version; - return reply; + return contents; } /// /// Old style. Soon to be deprecated. @@ -285,8 +246,8 @@ namespace OpenSim.Capabilities.Handlers { //m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Received request for {0} folders", foldersrequested.Count); - string response = ""; - string bad_folders_response = ""; + StringBuilder tmpresponse = new StringBuilder(1024); + StringBuilder tmpbadfolders = new StringBuilder(1024); for (int i = 0; i < foldersrequested.Count; i++) { @@ -308,7 +269,9 @@ namespace OpenSim.Capabilities.Handlers if (null == reply) { - bad_folders_response += "" + llsdRequest.folder_id.ToString() + ""; + tmpbadfolders.Append("folder_id"); + tmpbadfolders.Append(llsdRequest.folder_id.ToString()); + tmpbadfolders.Append("errorUnknown"); } else { @@ -317,39 +280,29 @@ namespace OpenSim.Capabilities.Handlers inventoryitemstr = inventoryitemstr.Replace("", ""); } - response += inventoryitemstr; + tmpresponse.Append(inventoryitemstr); } - if (response.Length == 0) + StringBuilder lastresponse = new StringBuilder(1024); + lastresponse.Append(""); + if(tmpresponse.Length > 0) { - /* Viewers expect a bad_folders array when not available */ - if (bad_folders_response.Length != 0) - { - response = "bad_folders" + bad_folders_response + ""; - } - else - { - response = "folders"; - } + lastresponse.Append("folders"); + lastresponse.Append(tmpresponse.ToString()); + lastresponse.Append(""); } else + lastresponse.Append("folders"); + + if(tmpbadfolders.Length > 0) { - if (bad_folders_response.Length != 0) - { - response = "folders" + response + "bad_folders" + bad_folders_response + ""; - } - else - { - response = "folders" + response + ""; - } + lastresponse.Append("bad_folders"); + lastresponse.Append(tmpbadfolders.ToString()); + lastresponse.Append(""); } + lastresponse.Append(""); - // m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Replying to CAPS fetch inventory request"); - //m_log.Debug("[WEB FETCH INV DESC HANDLER] "+response); - - return response; - - // } + return lastresponse.ToString(); } /// @@ -436,108 +389,7 @@ namespace OpenSim.Capabilities.Handlers itemsToReturn.Insert(0, linkedItem); } } - - // Now scan for folder links and insert the items they target and those links at the head of the return data - -/* dont send contents of LinkFolders. -from docs seems this was never a spec - - foreach (InventoryItemBase item in originalItems) - { - if (item.AssetType == (int)AssetType.LinkFolder) - { - InventoryCollection linkedFolderContents = m_InventoryService.GetFolderContent(ownerID, item.AssetID); - List links = linkedFolderContents.Items; - - itemsToReturn.InsertRange(0, links); - - foreach (InventoryItemBase link in linkedFolderContents.Items) - { - // Take care of genuinely broken links where the target doesn't exist - // HACK: Also, don't follow up links that just point to other links. In theory this is legitimate, - // but no viewer has been observed to set these up and this is the lazy way of avoiding cycles - // rather than having to keep track of every folder requested in the recursion. - if (link != null) - { -// m_log.DebugFormat( -// "[WEB FETCH INV DESC HANDLER]: Adding item {0} {1} from folder {2} linked from {3}", -// link.Name, (AssetType)link.AssetType, item.AssetID, containingFolder.Name); - - InventoryItemBase linkedItem - = m_InventoryService.GetItem(new InventoryItemBase(link.AssetID)); - - if (linkedItem != null) - itemsToReturn.Insert(0, linkedItem); - } - } - } - } -*/ } - -// foreach (InventoryItemBase item in contents.Items) -// { -// m_log.DebugFormat( -// "[WEB FETCH INV DESC HANDLER]: Returning item {0}, type {1}, parent {2} in {3} {4}", -// item.Name, (AssetType)item.AssetType, item.Folder, containingFolder.Name, containingFolder.ID); -// } - - // ===== - -// -// foreach (InventoryItemBase linkedItem in linkedItemsToAdd) -// { -// m_log.DebugFormat( -// "[WEB FETCH INV DESC HANDLER]: Inserted linked item {0} for link in folder {1} for agent {2}", -// linkedItem.Name, folderID, agentID); -// -// contents.Items.Add(linkedItem); -// } -// -// // If the folder requested contains links, then we need to send those folders first, otherwise the links -// // will be broken in the viewer. -// HashSet linkedItemFolderIdsToSend = new HashSet(); -// foreach (InventoryItemBase item in contents.Items) -// { -// if (item.AssetType == (int)AssetType.Link) -// { -// InventoryItemBase linkedItem = m_InventoryService.GetItem(new InventoryItemBase(item.AssetID)); -// -// // Take care of genuinely broken links where the target doesn't exist -// // HACK: Also, don't follow up links that just point to other links. In theory this is legitimate, -// // but no viewer has been observed to set these up and this is the lazy way of avoiding cycles -// // rather than having to keep track of every folder requested in the recursion. -// if (linkedItem != null && linkedItem.AssetType != (int)AssetType.Link) -// { -// // We don't need to send the folder if source and destination of the link are in the same -// // folder. -// if (linkedItem.Folder != containingFolder.ID) -// linkedItemFolderIdsToSend.Add(linkedItem.Folder); -// } -// } -// } -// -// foreach (UUID linkedItemFolderId in linkedItemFolderIdsToSend) -// { -// m_log.DebugFormat( -// "[WEB FETCH INV DESC HANDLER]: Recursively fetching folder {0} linked by item in folder {1} for agent {2}", -// linkedItemFolderId, folderID, agentID); -// -// int dummyVersion; -// InventoryCollection linkedCollection -// = Fetch( -// agentID, linkedItemFolderId, ownerID, fetchFolders, fetchItems, sortOrder, out dummyVersion); -// -// InventoryFolderBase linkedFolder = new InventoryFolderBase(linkedItemFolderId); -// linkedFolder.Owner = agentID; -// linkedFolder = m_InventoryService.GetFolder(linkedFolder); -// -//// contents.Folders.AddRange(linkedCollection.Folders); -// -// contents.Folders.Add(linkedFolder); -// contents.Items.AddRange(linkedCollection.Items); -// } -// } } } else @@ -550,33 +402,26 @@ from docs seems this was never a spec } - private void AddLibraryFolders(List fetchFolders, List result) + private void AddLibraryFolders(List libFolders, List result) { InventoryFolderImpl fold; - if (m_LibraryService != null && m_LibraryService.LibraryRootFolder != null) + foreach (LLSDFetchInventoryDescendents f in libFolders) { - List libfolders = fetchFolders.FindAll(f => f.owner_id == m_LibraryService.LibraryRootFolder.Owner); - fetchFolders.RemoveAll(f => libfolders.Contains(f)); - - //m_log.DebugFormat("[XXX]: Found {0} library folders in request", libfolders.Count); - - foreach (LLSDFetchInventoryDescendents f in libfolders) + if ((fold = m_LibraryService.LibraryRootFolder.FindFolder(f.folder_id)) != null) { - if ((fold = m_LibraryService.LibraryRootFolder.FindFolder(f.folder_id)) != null) - { - InventoryCollectionWithDescendents ret = new InventoryCollectionWithDescendents(); - ret.Collection = new InventoryCollection(); - ret.Collection.Folders = new List(); - ret.Collection.Items = fold.RequestListOfItems(); - ret.Collection.OwnerID = m_LibraryService.LibraryRootFolder.Owner; - ret.Collection.FolderID = f.folder_id; - ret.Collection.Version = fold.Version; + InventoryCollectionWithDescendents ret = new InventoryCollectionWithDescendents(); + ret.Collection = new InventoryCollection(); +// ret.Collection.Folders = new List(); + ret.Collection.Folders = fold.RequestListOfFolders(); + ret.Collection.Items = fold.RequestListOfItems(); + ret.Collection.OwnerID = m_LibraryService.LibraryRootFolder.Owner; + ret.Collection.FolderID = f.folder_id; + ret.Collection.Version = fold.Version; - ret.Descendents = ret.Collection.Items.Count; - result.Add(ret); + ret.Descendents = ret.Collection.Items.Count + ret.Collection.Folders.Count; + result.Add(ret); - //m_log.DebugFormat("[XXX]: Added libfolder {0} ({1}) {2}", ret.Collection.FolderID, ret.Collection.OwnerID); - } + //m_log.DebugFormat("[XXX]: Added libfolder {0} ({1}) {2}", ret.Collection.FolderID, ret.Collection.OwnerID); } } } @@ -589,117 +434,122 @@ from docs seems this was never a spec // FIXME MAYBE: We're not handling sortOrder! List result = new List(); + List libFolders = new List(); + List otherFolders = new List(); + HashSet libIDs = new HashSet(); + HashSet otherIDs = new HashSet(); - AddLibraryFolders(fetchFolders, result); + bool dolib = (m_LibraryService != null && m_LibraryService.LibraryRootFolder != null); + UUID libOwner = UUID.Zero; + if(dolib) + libOwner = m_LibraryService.LibraryRootFolder.Owner; // Filter folder Zero right here. Some viewers (Firestorm) send request for folder Zero, which doesn't make sense // and can kill the sim (all root folders have parent_id Zero) - LLSDFetchInventoryDescendents zero = fetchFolders.Find(f => f.folder_id == UUID.Zero); - if (zero != null) + // send something. + bool doneZeroID = false; + foreach(LLSDFetchInventoryDescendents f in fetchFolders) { - fetchFolders.Remove(zero); - BadFolder(zero, null, bad_folders); + if (f.folder_id == UUID.Zero) + { + if(doneZeroID) + continue; + doneZeroID = true; + InventoryCollectionWithDescendents zeroColl = new InventoryCollectionWithDescendents(); + zeroColl.Collection = new InventoryCollection(); + zeroColl.Collection.OwnerID = f.owner_id; + zeroColl.Collection.Version = 0; + zeroColl.Collection.FolderID = f.folder_id; + zeroColl.Descendents = 0; + result.Add(zeroColl); + continue; + } + if(dolib && f.owner_id == libOwner) + { + if(libIDs.Contains(f.folder_id)) + continue; + libIDs.Add(f.folder_id); + libFolders.Add(f); + continue; + } + if(otherIDs.Contains(f.folder_id)) + continue; + otherIDs.Add(f.folder_id); + otherFolders.Add(f); } - if (fetchFolders.Count > 0) - { - UUID[] fids = new UUID[fetchFolders.Count]; + if(otherFolders.Count > 0) + { int i = 0; - foreach (LLSDFetchInventoryDescendents f in fetchFolders) - fids[i++] = f.folder_id; //m_log.DebugFormat("[XXX]: {0}", string.Join(",", fids)); - InventoryCollection[] fetchedContents = m_InventoryService.GetMultipleFoldersContent(fetchFolders[0].owner_id, fids); + InventoryCollection[] fetchedContents = m_InventoryService.GetMultipleFoldersContent(otherFolders[0].owner_id, otherIDs.ToArray()); - if (fetchedContents == null || (fetchedContents != null && fetchedContents.Length == 0)) + if (fetchedContents == null) + return null; + + if (fetchedContents.Length == 0) { - m_log.WarnFormat("[WEB FETCH INV DESC HANDLER]: Could not get contents of multiple folders for user {0}", fetchFolders[0].owner_id); - foreach (LLSDFetchInventoryDescendents freq in fetchFolders) + foreach (LLSDFetchInventoryDescendents freq in otherFolders) BadFolder(freq, null, bad_folders); - return null; } - - i = 0; - // Do some post-processing. May need to fetch more from inv server for links - foreach (InventoryCollection contents in fetchedContents) + else { - // Find the original request - LLSDFetchInventoryDescendents freq = fetchFolders[i++]; + i = 0; + // Do some post-processing. May need to fetch more from inv server for links + foreach (InventoryCollection contents in fetchedContents) + { + // Find the original request + LLSDFetchInventoryDescendents freq = otherFolders[i++]; - InventoryCollectionWithDescendents coll = new InventoryCollectionWithDescendents(); - coll.Collection = contents; + InventoryCollectionWithDescendents coll = new InventoryCollectionWithDescendents(); + coll.Collection = contents; - if (BadFolder(freq, contents, bad_folders)) - continue; + if (BadFolder(freq, contents, bad_folders)) + continue; - // Next: link management - ProcessLinks(freq, coll); + // Next: link management + ProcessLinks(freq, coll); - result.Add(coll); + result.Add(coll); + } } } + if(dolib && libFolders.Count > 0) + { + AddLibraryFolders(libFolders, result); + } + return result; } private bool BadFolder(LLSDFetchInventoryDescendents freq, InventoryCollection contents, List bad_folders) { - bool bad = false; if (contents == null) { bad_folders.Add(freq.folder_id); - bad = true; + return true; } // The inventory server isn't sending FolderID in the collection... // Must fetch it individually - else if (contents.FolderID == UUID.Zero) + if (contents.FolderID == UUID.Zero) { InventoryFolderBase containingFolder = m_InventoryService.GetFolder(freq.owner_id, freq.folder_id); - - if (containingFolder != null) + if (containingFolder == null) { - contents.FolderID = containingFolder.ID; - contents.OwnerID = containingFolder.Owner; - contents.Version = containingFolder.Version; - } - else - { - // Was it really a request for folder Zero? - // This is an overkill, but Firestorm really asks for folder Zero. - // I'm leaving the code here for the time being, but commented. - if (freq.folder_id == UUID.Zero) - { - //coll.Collection.OwnerID = freq.owner_id; - //coll.Collection.FolderID = contents.FolderID; - //containingFolder = m_InventoryService.GetRootFolder(freq.owner_id); - //if (containingFolder != null) - //{ - // m_log.WarnFormat("[WEB FETCH INV DESC HANDLER]: Request for parent of folder {0}", containingFolder.ID); - // coll.Collection.Folders.Clear(); - // coll.Collection.Folders.Add(containingFolder); - // if (m_LibraryService != null && m_LibraryService.LibraryRootFolder != null) - // { - // InventoryFolderBase lib = new InventoryFolderBase(m_LibraryService.LibraryRootFolder.ID, m_LibraryService.LibraryRootFolder.Owner); - // lib.Name = m_LibraryService.LibraryRootFolder.Name; - // lib.Type = m_LibraryService.LibraryRootFolder.Type; - // lib.Version = m_LibraryService.LibraryRootFolder.Version; - // coll.Collection.Folders.Add(lib); - // } - // coll.Collection.Items.Clear(); - //} - } - else - { - m_log.WarnFormat("[WEB FETCH INV DESC HANDLER]: Unable to fetch folder {0}", freq.folder_id); - bad_folders.Add(freq.folder_id); - } - bad = true; + m_log.WarnFormat("[WEB FETCH INV DESC HANDLER]: Unable to fetch folder {0}", freq.folder_id); + bad_folders.Add(freq.folder_id); + return true; } + contents.FolderID = containingFolder.ID; + contents.OwnerID = containingFolder.Owner; + contents.Version = containingFolder.Version; } - return bad; + return false; } private void ProcessLinks(LLSDFetchInventoryDescendents freq, InventoryCollectionWithDescendents coll) @@ -708,42 +558,21 @@ from docs seems this was never a spec if (freq.fetch_items && contents.Items != null) { - List itemsToReturn = contents.Items; - + // viewers are lasy and want a copy of the linked item sent before the link to it + // descendents must only include the links, not the linked items we add - coll.Descendents = itemsToReturn.Count; + coll.Descendents = contents.Items.Count + contents.Folders.Count; - // Add target items for links in this folder before the links themselves. + // look for item links List itemIDs = new List(); - List folderIDs = new List(); - foreach (InventoryItemBase item in itemsToReturn) + foreach (InventoryItemBase item in contents.Items) { //m_log.DebugFormat("[XXX]: {0} {1}", item.Name, item.AssetType); if (item.AssetType == (int)AssetType.Link) itemIDs.Add(item.AssetID); - -// else if (item.AssetType == (int)AssetType.LinkFolder) -// folderIDs.Add(item.AssetID); - } - - //m_log.DebugFormat("[XXX]: folder {0} has {1} links and {2} linkfolders", contents.FolderID, itemIDs.Count, folderIDs.Count); - - // Scan for folder links and insert the items they target and those links at the head of the return data - if (folderIDs.Count > 0) - { - InventoryCollection[] linkedFolders = m_InventoryService.GetMultipleFoldersContent(coll.Collection.OwnerID, folderIDs.ToArray()); - foreach (InventoryCollection linkedFolderContents in linkedFolders) - { - if (linkedFolderContents == null) - continue; - - List links = linkedFolderContents.Items; - - itemsToReturn.InsertRange(0, links); - - } } + // get the linked if any if (itemIDs.Count > 0) { InventoryItemBase[] linked = m_InventoryService.GetMultipleItems(freq.owner_id, itemIDs.ToArray()); @@ -758,13 +587,11 @@ from docs seems this was never a spec linked[i++] = m_InventoryService.GetItem(freq.owner_id, id); } } - - //m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Processing folder {0}. Existing items:", freq.folder_id); - //foreach (InventoryItemBase item in itemsToReturn) - // m_log.DebugFormat("[XXX]: {0} {1} {2}", item.Name, item.AssetType, item.Folder); - + if (linked != null) { + List linkedItems = new List(); + // check for broken foreach (InventoryItemBase linkedItem in linked) { // Take care of genuinely broken links where the target doesn't exist @@ -773,14 +600,16 @@ from docs seems this was never a spec // rather than having to keep track of every folder requested in the recursion. if (linkedItem != null && linkedItem.AssetType != (int)AssetType.Link) { - itemsToReturn.Insert(0, linkedItem); + linkedItems.Add(linkedItem); //m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Added {0} {1} {2}", linkedItem.Name, linkedItem.AssetType, linkedItem.Folder); } } + // insert them + if(linkedItems.Count > 0) + contents.Items.InsertRange(0,linkedItems); } } } - } /// @@ -795,6 +624,7 @@ from docs seems this was never a spec llsdFolder.parent_id = invFolder.ParentID; llsdFolder.name = invFolder.Name; llsdFolder.type = invFolder.Type; + llsdFolder.version = invFolder.Version; llsdFolder.preferred_type = -1; return llsdFolder; diff --git a/OpenSim/Capabilities/Handlers/FetchInventory/FetchInventory2Handler.cs b/OpenSim/Capabilities/Handlers/FetchInventory/FetchInventory2Handler.cs index e239a90dbf..bae4cf60c8 100644 --- a/OpenSim/Capabilities/Handlers/FetchInventory/FetchInventory2Handler.cs +++ b/OpenSim/Capabilities/Handlers/FetchInventory/FetchInventory2Handler.cs @@ -26,6 +26,7 @@ */ using System.Reflection; +using System.Text; using OpenMetaverse; using OpenMetaverse.StructuredData; using OpenSim.Framework; @@ -59,9 +60,6 @@ namespace OpenSim.Capabilities.Handlers OSDMap requestmap = (OSDMap)OSDParser.DeserializeLLSDXml(Utils.StringToBytes(request)); OSDArray itemsRequested = (OSDArray)requestmap["items"]; - string reply; - LLSDFetchInventory llsdReply = new LLSDFetchInventory(); - UUID[] itemIDs = new UUID[itemsRequested.Count]; int i = 0; @@ -75,15 +73,6 @@ namespace OpenSim.Capabilities.Handlers if (m_agentID != UUID.Zero) { items = m_inventoryService.GetMultipleItems(m_agentID, itemIDs); - - if (items == null) - { - // OMG!!! One by one!!! This is fallback code, in case the backend isn't updated - m_log.WarnFormat("[FETCH INVENTORY HANDLER]: GetMultipleItems failed. Falling back to fetching inventory items one by one."); - items = new InventoryItemBase[itemsRequested.Count]; - foreach (UUID id in itemIDs) - items[i++] = m_inventoryService.GetItem(m_agentID, id); - } } else { @@ -92,55 +81,31 @@ namespace OpenSim.Capabilities.Handlers items[i++] = m_inventoryService.GetItem(UUID.Zero, id); } - foreach (InventoryItemBase item in items) + StringBuilder lsl = LLSDxmlEncode.Start(4096); + LLSDxmlEncode.AddMap(lsl); + + if(m_agentID == UUID.Zero && items.Length > 0) + LLSDxmlEncode.AddElem("agent_id", items[0].Owner, lsl); + else + LLSDxmlEncode.AddElem("agent_id", m_agentID, lsl); + + if(items == null || items.Length == 0) { - if (item != null) - { - // We don't know the agent that this request belongs to so we'll use the agent id of the item - // which will be the same for all items. - llsdReply.agent_id = item.Owner; - llsdReply.items.Array.Add(ConvertInventoryItem(item)); - } + LLSDxmlEncode.AddEmptyArray("items", lsl); } + else + { + LLSDxmlEncode.AddArray("items", lsl); + foreach (InventoryItemBase item in items) + { + if (item != null) + item.ToLLSDxml(lsl); + } + LLSDxmlEncode.AddEndArray(lsl); + } - reply = LLSDHelpers.SerialiseLLSDReply(llsdReply); - - return reply; - } - - /// - /// Convert an internal inventory item object into an LLSD object. - /// - /// - /// - private LLSDInventoryItem ConvertInventoryItem(InventoryItemBase invItem) - { - LLSDInventoryItem llsdItem = new LLSDInventoryItem(); - llsdItem.asset_id = invItem.AssetID; - llsdItem.created_at = invItem.CreationDate; - llsdItem.desc = invItem.Description; - llsdItem.flags = ((int)invItem.Flags) & 0xff; - llsdItem.item_id = invItem.ID; - llsdItem.name = invItem.Name; - llsdItem.parent_id = invItem.Folder; - llsdItem.type = invItem.AssetType; - llsdItem.inv_type = invItem.InvType; - - llsdItem.permissions = new LLSDPermissions(); - llsdItem.permissions.creator_id = invItem.CreatorIdAsUuid; - llsdItem.permissions.base_mask = (int)invItem.CurrentPermissions; - llsdItem.permissions.everyone_mask = (int)invItem.EveryOnePermissions; - llsdItem.permissions.group_id = invItem.GroupID; - llsdItem.permissions.group_mask = (int)invItem.GroupPermissions; - llsdItem.permissions.is_owner_group = invItem.GroupOwned; - llsdItem.permissions.next_owner_mask = (int)invItem.NextPermissions; - llsdItem.permissions.owner_id = invItem.Owner; - llsdItem.permissions.owner_mask = (int)invItem.CurrentPermissions; - llsdItem.sale_info = new LLSDSaleInfo(); - llsdItem.sale_info.sale_price = invItem.SalePrice; - llsdItem.sale_info.sale_type = invItem.SaleType; - - return llsdItem; + LLSDxmlEncode.AddEndMap(lsl); + return LLSDxmlEncode.End(lsl);; } } } diff --git a/OpenSim/Capabilities/Handlers/FetchInventory/Tests/FetchInventoryDescendents2HandlerTests.cs b/OpenSim/Capabilities/Handlers/FetchInventory/Tests/FetchInventoryDescendents2HandlerTests.cs index 4143aa33af..1e9a993494 100644 --- a/OpenSim/Capabilities/Handlers/FetchInventory/Tests/FetchInventoryDescendents2HandlerTests.cs +++ b/OpenSim/Capabilities/Handlers/FetchInventory/Tests/FetchInventoryDescendents2HandlerTests.cs @@ -267,6 +267,7 @@ namespace OpenSim.Capabilities.Handlers.FetchInventory.Tests [Test] public void Test_005_FolderZero() { + TestHelpers.InMethod(); Init(); @@ -283,11 +284,11 @@ namespace OpenSim.Capabilities.Handlers.FetchInventory.Tests Assert.That(llsdresponse != null, Is.True, "Incorrect null response"); Assert.That(llsdresponse != string.Empty, Is.True, "Incorrect empty response"); - Assert.That(llsdresponse.Contains("bad_folders00000000-0000-0000-0000-000000000000"), Is.True, "Folder Zero should be a bad folder"); + // we do return a answer now + //Assert.That(llsdresponse.Contains("bad_folders00000000-0000-0000-0000-000000000000"), Is.True, "Folder Zero should be a bad folder"); Console.WriteLine(llsdresponse); } - } } \ No newline at end of file diff --git a/OpenSim/Capabilities/Handlers/GetMesh/GetMeshHandler.cs b/OpenSim/Capabilities/Handlers/GetMesh/GetMeshHandler.cs index a9b81f3138..a0471bb0c4 100644 --- a/OpenSim/Capabilities/Handlers/GetMesh/GetMeshHandler.cs +++ b/OpenSim/Capabilities/Handlers/GetMesh/GetMeshHandler.cs @@ -64,10 +64,7 @@ namespace OpenSim.Capabilities.Handlers Hashtable ret = new Hashtable(); ret["int_response_code"] = (int)System.Net.HttpStatusCode.NotFound; ret["content_type"] = "text/plain"; - ret["keepalive"] = false; - ret["reusecontext"] = false; ret["int_bytes"] = 0; - ret["int_lod"] = 0; string MeshStr = (string)request["mesh_id"]; @@ -76,6 +73,8 @@ namespace OpenSim.Capabilities.Handlers if (m_assetService == null) { m_log.Error("[GETMESH]: Cannot fetch mesh " + MeshStr + " without an asset service"); + ret["keepalive"] = false; + return ret; } UUID meshID; @@ -101,10 +100,7 @@ namespace OpenSim.Capabilities.Handlers Hashtable responsedata = new Hashtable(); responsedata["int_response_code"] = 400; //501; //410; //404; responsedata["content_type"] = "text/plain"; - responsedata["keepalive"] = false; responsedata["str_response_string"] = "Request wasn't what was expected"; - responsedata["reusecontext"] = false; - responsedata["int_lod"] = 0; responsedata["int_bytes"] = 0; string meshStr = string.Empty; @@ -118,10 +114,8 @@ namespace OpenSim.Capabilities.Handlers if (m_assetService == null) { responsedata["int_response_code"] = 404; //501; //410; //404; - responsedata["content_type"] = "text/plain"; responsedata["keepalive"] = false; responsedata["str_response_string"] = "The asset service is unavailable. So is your mesh."; - responsedata["reusecontext"] = false; return responsedata; } @@ -155,10 +149,7 @@ namespace OpenSim.Capabilities.Handlers { responsedata["int_response_code"] = 404; //501; //410; //404; responsedata["content_type"] = "text/plain"; - responsedata["keepalive"] = false; responsedata["str_response_string"] = "This range doesnt exist."; - responsedata["reusecontext"] = false; - responsedata["int_lod"] = 3; return responsedata; } else @@ -169,28 +160,11 @@ namespace OpenSim.Capabilities.Handlers //m_log.Debug("Serving " + start + " to " + end + " of " + texture.Data.Length + " bytes for texture " + texture.ID); - if (start > 20000) - { - responsedata["int_lod"] = 3; - } - else if (start < 4097) - { - responsedata["int_lod"] = 1; - } - else - { - responsedata["int_lod"] = 2; - } - - if (start == 0 && len == mesh.Data.Length) // well redudante maybe { responsedata["int_response_code"] = (int)System.Net.HttpStatusCode.OK; responsedata["bin_response_data"] = mesh.Data; responsedata["int_bytes"] = mesh.Data.Length; - responsedata["reusecontext"] = false; - responsedata["int_lod"] = 3; - } else { @@ -203,7 +177,6 @@ namespace OpenSim.Capabilities.Handlers Array.Copy(mesh.Data, start, d, 0, len); responsedata["bin_response_data"] = d; responsedata["int_bytes"] = len; - responsedata["reusecontext"] = false; } } } @@ -213,8 +186,6 @@ namespace OpenSim.Capabilities.Handlers responsedata["str_response_string"] = Convert.ToBase64String(mesh.Data); responsedata["content_type"] = "application/vnd.ll.mesh"; responsedata["int_response_code"] = 200; - responsedata["reusecontext"] = false; - responsedata["int_lod"] = 3; } } else @@ -222,8 +193,6 @@ namespace OpenSim.Capabilities.Handlers responsedata["str_response_string"] = Convert.ToBase64String(mesh.Data); responsedata["content_type"] = "application/vnd.ll.mesh"; responsedata["int_response_code"] = 200; - responsedata["reusecontext"] = false; - responsedata["int_lod"] = 3; } } // Optionally add additional mesh types here @@ -231,10 +200,7 @@ namespace OpenSim.Capabilities.Handlers { responsedata["int_response_code"] = 404; //501; //410; //404; responsedata["content_type"] = "text/plain"; - responsedata["keepalive"] = false; responsedata["str_response_string"] = "Unfortunately, this asset isn't a mesh."; - responsedata["reusecontext"] = false; - responsedata["int_lod"] = 1; return responsedata; } } @@ -242,10 +208,7 @@ namespace OpenSim.Capabilities.Handlers { responsedata["int_response_code"] = 404; //501; //410; //404; responsedata["content_type"] = "text/plain"; - responsedata["keepalive"] = false; responsedata["str_response_string"] = "Your Mesh wasn't found. Sorry!"; - responsedata["reusecontext"] = false; - responsedata["int_lod"] = 0; return responsedata; } } diff --git a/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs index 062a842748..2499ce4023 100644 --- a/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs +++ b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs @@ -66,8 +66,6 @@ namespace OpenSim.Capabilities.Handlers Hashtable ret = new Hashtable(); ret["int_response_code"] = (int)System.Net.HttpStatusCode.NotFound; ret["content_type"] = "text/plain"; - ret["keepalive"] = false; - ret["reusecontext"] = false; ret["int_bytes"] = 0; string textureStr = (string)request["texture_id"]; string format = (string)request["format"]; @@ -112,8 +110,6 @@ namespace OpenSim.Capabilities.Handlers ret["error_status_text"] = "not found"; ret["str_response_string"] = "not found"; ret["content_type"] = "text/plain"; - ret["keepalive"] = false; - ret["reusecontext"] = false; ret["int_bytes"] = 0; } } @@ -362,8 +358,6 @@ namespace OpenSim.Capabilities.Handlers { // Taking our jpeg2000 data, decoding it, then saving it to a byte array with regular data - imgstream = new MemoryStream(); - // Decode image to System.Drawing.Image if (OpenJPEG.DecodeToImage(texture.Data, out managedImage, out image) && image != null) { @@ -404,10 +398,7 @@ namespace OpenSim.Capabilities.Handlers if(managedImage != null) managedImage.Clear(); if (imgstream != null) - { - imgstream.Close(); imgstream.Dispose(); - } } return data; diff --git a/OpenSim/Capabilities/Handlers/GetTexture/GetTextureRobustHandler.cs b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureRobustHandler.cs index d5df7a29bd..a9b3d48694 100644 --- a/OpenSim/Capabilities/Handlers/GetTexture/GetTextureRobustHandler.cs +++ b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureRobustHandler.cs @@ -131,87 +131,46 @@ namespace OpenSim.Capabilities.Handlers /// False for "caller try another codec"; true otherwise private bool FetchTexture(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse, UUID textureID, string format) { -// m_log.DebugFormat("[GETTEXTURE]: {0} with requested format {1}", textureID, format); - AssetBase texture; - - string fullID = textureID.ToString(); - if (format != DefaultFormat) - fullID = fullID + "-" + format; - - if (!String.IsNullOrEmpty(m_RedirectURL)) + // m_log.DebugFormat("[GETTEXTURE]: {0} with requested format {1}", textureID, format); + if(!String.IsNullOrEmpty(m_RedirectURL)) { - // Only try to fetch locally cached textures. Misses are redirected - texture = m_assetService.GetCached(fullID); + string textureUrl = m_RedirectURL + "?texture_id=" + textureID.ToString(); + m_log.Debug("[GETTEXTURE]: Redirecting texture request to " + textureUrl); + httpResponse.StatusCode = (int)OSHttpStatusCode.RedirectMovedPermanently; + httpResponse.RedirectLocation = textureUrl; + return true; + } - if (texture != null) + // Fetch, Misses or invalid return a 404 + AssetBase texture = m_assetService.Get(textureID.ToString()); + if (texture != null) + { + if (texture.Type != (sbyte)AssetType.Texture) + { + httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound; + return true; + } + if (format == DefaultFormat) { - if (texture.Type != (sbyte)AssetType.Texture) - { - httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound; - return true; - } WriteTextureData(httpRequest, httpResponse, texture, format); return true; } - else - { - string textureUrl = m_RedirectURL + "?texture_id="+ textureID.ToString(); - m_log.Debug("[GETTEXTURE]: Redirecting texture request to " + textureUrl); - httpResponse.StatusCode = (int)OSHttpStatusCode.RedirectMovedPermanently; - httpResponse.RedirectLocation = textureUrl; - return true; - } - } - else // no redirect - { - // try the cache - texture = m_assetService.GetCached(fullID); - if (texture == null) - { -// m_log.DebugFormat("[GETTEXTURE]: texture was not in the cache"); + // need to convert format + AssetBase newTexture = new AssetBase(texture.ID + "-" + format, texture.Name, (sbyte)AssetType.Texture, texture.Metadata.CreatorID); + newTexture.Data = ConvertTextureData(texture, format); + if (newTexture.Data.Length == 0) + return false; // !!! Caller try another codec, please! - // Fetch locally or remotely. Misses return a 404 - texture = m_assetService.Get(textureID.ToString()); - - if (texture != null) - { - if (texture.Type != (sbyte)AssetType.Texture) - { - httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound; - return true; - } - if (format == DefaultFormat) - { - WriteTextureData(httpRequest, httpResponse, texture, format); - return true; - } - else - { - AssetBase newTexture = new AssetBase(texture.ID + "-" + format, texture.Name, (sbyte)AssetType.Texture, texture.Metadata.CreatorID); - newTexture.Data = ConvertTextureData(texture, format); - if (newTexture.Data.Length == 0) - return false; // !!! Caller try another codec, please! - - newTexture.Flags = AssetFlags.Collectable; - newTexture.Temporary = true; - newTexture.Local = true; - m_assetService.Store(newTexture); - WriteTextureData(httpRequest, httpResponse, newTexture, format); - return true; - } - } - } - else // it was on the cache - { -// m_log.DebugFormat("[GETTEXTURE]: texture was in the cache"); - WriteTextureData(httpRequest, httpResponse, texture, format); - return true; - } + newTexture.Flags = AssetFlags.Collectable; + newTexture.Temporary = true; + newTexture.Local = true; + WriteTextureData(httpRequest, httpResponse, newTexture, format); + return true; } // not found -// m_log.Warn("[GETTEXTURE]: Texture " + textureID + " not found"); + // m_log.Warn("[GETTEXTURE]: Texture " + textureID + " not found"); httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound; return true; } @@ -368,9 +327,6 @@ namespace OpenSim.Capabilities.Handlers try { // Taking our jpeg2000 data, decoding it, then saving it to a byte array with regular data - - imgstream = new MemoryStream(); - // Decode image to System.Drawing.Image if (OpenJPEG.DecodeToImage(texture.Data, out managedImage, out image) && image != null) { @@ -412,10 +368,7 @@ namespace OpenSim.Capabilities.Handlers managedImage.Clear(); if (imgstream != null) - { - imgstream.Close(); imgstream.Dispose(); - } } return data; diff --git a/OpenSim/Capabilities/Handlers/UploadBakedTexture/UploadBakedTextureHandler.cs b/OpenSim/Capabilities/Handlers/UploadBakedTexture/UploadBakedTextureHandler.cs index 80b83069e2..48274c1ae5 100644 --- a/OpenSim/Capabilities/Handlers/UploadBakedTexture/UploadBakedTextureHandler.cs +++ b/OpenSim/Capabilities/Handlers/UploadBakedTexture/UploadBakedTextureHandler.cs @@ -26,24 +26,12 @@ */ using System; -using System.Collections; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Drawing; -using System.Drawing.Imaging; using System.Reflection; -using System.IO; -using System.Web; using log4net; -using Nini.Config; using OpenMetaverse; -using OpenMetaverse.StructuredData; -using OpenMetaverse.Imaging; using OpenSim.Framework; using OpenSim.Framework.Capabilities; -using OpenSim.Framework.Servers; using OpenSim.Framework.Servers.HttpServer; -using OpenSim.Region.Framework.Interfaces; using OpenSim.Services.Interfaces; using Caps = OpenSim.Framework.Capabilities.Caps; @@ -56,13 +44,11 @@ namespace OpenSim.Capabilities.Handlers private Caps m_HostCapsObj; private IAssetService m_assetService; - private bool m_persistBakedTextures; - public UploadBakedTextureHandler(Caps caps, IAssetService assetService, bool persistBakedTextures) + public UploadBakedTextureHandler(Caps caps, IAssetService assetService) { m_HostCapsObj = caps; m_assetService = assetService; - m_persistBakedTextures = persistBakedTextures; } /// @@ -125,9 +111,8 @@ namespace OpenSim.Capabilities.Handlers asset = new AssetBase(assetID, "Baked Texture", (sbyte)AssetType.Texture, m_HostCapsObj.AgentID.ToString()); asset.Data = data; asset.Temporary = true; - asset.Local = !m_persistBakedTextures; // Local assets aren't persisted, non-local are + asset.Local = true; m_assetService.Store(asset); - } } @@ -151,8 +136,6 @@ namespace OpenSim.Capabilities.Handlers // m_log.InfoFormat("[CAPS] baked texture upload starting for {0}",newAssetID); } - - /// /// Handle raw uploaded baked texture data. /// diff --git a/OpenSim/Capabilities/Handlers/UploadBakedTexture/UploadBakedTextureServerConnector.cs b/OpenSim/Capabilities/Handlers/UploadBakedTexture/UploadBakedTextureServerConnector.cs index 10ea8eefe6..fd484bad8e 100644 --- a/OpenSim/Capabilities/Handlers/UploadBakedTexture/UploadBakedTextureServerConnector.cs +++ b/OpenSim/Capabilities/Handlers/UploadBakedTexture/UploadBakedTextureServerConnector.cs @@ -67,7 +67,7 @@ namespace OpenSim.Capabilities.Handlers server.AddStreamHandler(new RestStreamHandler( "POST", "/CAPS/UploadBakedTexture/", - new UploadBakedTextureHandler(caps, m_AssetService, true).UploadBakedTexture, + new UploadBakedTextureHandler(caps, m_AssetService).UploadBakedTexture, "UploadBakedTexture", "Upload Baked Texture Capability")); diff --git a/OpenSim/Capabilities/LLSD.cs b/OpenSim/Capabilities/LLSD.cs index c59cede3f4..342164d9af 100644 --- a/OpenSim/Capabilities/LLSD.cs +++ b/OpenSim/Capabilities/LLSD.cs @@ -107,17 +107,17 @@ namespace OpenSim.Framework.Capabilities /// public static byte[] LLSDSerialize(object obj) { - StringWriter sw = new StringWriter(); - XmlTextWriter writer = new XmlTextWriter(sw); - writer.Formatting = Formatting.None; + using(StringWriter sw = new StringWriter()) + using(XmlTextWriter writer = new XmlTextWriter(sw)) + { + writer.Formatting = Formatting.None; - writer.WriteStartElement(String.Empty, "llsd", String.Empty); - LLSDWriteOne(writer, obj); - writer.WriteEndElement(); - - writer.Close(); - - return Util.UTF8.GetBytes(sw.ToString()); + writer.WriteStartElement(String.Empty, "llsd", String.Empty); + LLSDWriteOne(writer, obj); + writer.WriteEndElement(); + writer.Flush(); + return Util.UTF8.GetBytes(sw.ToString()); + } } /// @@ -566,7 +566,7 @@ namespace OpenSim.Framework.Capabilities endPos = FindEnd(llsd, 1); if (Double.TryParse(llsd.Substring(1, endPos - 1), NumberStyles.Float, - Utils.EnUsCulture.NumberFormat, out value)) + Culture.NumberFormatInfo, out value)) return value; else throw new LLSDParseException("Failed to parse double value type"); diff --git a/OpenSim/Capabilities/LLSDHelpers.cs b/OpenSim/Capabilities/LLSDHelpers.cs index 8f1a40e632..e54618d3b5 100644 --- a/OpenSim/Capabilities/LLSDHelpers.cs +++ b/OpenSim/Capabilities/LLSDHelpers.cs @@ -30,6 +30,7 @@ using System.Collections; using System.IO; using System.Reflection; using System.Xml; +using OpenMetaverse; namespace OpenSim.Framework.Capabilities { @@ -40,17 +41,32 @@ namespace OpenSim.Framework.Capabilities public static string SerialiseLLSDReply(object obj) { - StringWriter sw = new StringWriter(); - XmlTextWriter writer = new XmlTextWriter(sw); - writer.Formatting = Formatting.None; - writer.WriteStartElement(String.Empty, "llsd", String.Empty); - SerializeOSDType(writer, obj); - writer.WriteEndElement(); - writer.Close(); - + using(StringWriter sw = new StringWriter()) + using(XmlTextWriter writer = new XmlTextWriter(sw)) + { + writer.Formatting = Formatting.None; + writer.WriteStartElement(String.Empty, "llsd", String.Empty); + SerializeOSDType(writer, obj); + writer.WriteEndElement(); + writer.Flush(); //m_log.DebugFormat("[LLSD Helpers]: Generated serialized LLSD reply {0}", sw.ToString()); - return sw.ToString(); + return sw.ToString(); + } + } + + public static string SerialiseLLSDReplyNoHeader(object obj) + { + using(StringWriter sw = new StringWriter()) + using(XmlTextWriter writer = new XmlTextWriter(sw)) + { + writer.Formatting = Formatting.None; + SerializeOSDType(writer, obj); + writer.Flush(); + //m_log.DebugFormat("[LLSD Helpers]: Generated serialized LLSD reply {0}", sw.ToString()); + + return sw.ToString(); + } } private static void SerializeOSDType(XmlTextWriter writer, object obj) @@ -157,6 +173,22 @@ namespace OpenSim.Framework.Capabilities // the LLSD map/array types in the array need to be deserialised // but first we need to know the right class to deserialise them into. } + else if(enumerator.Value is Boolean && field.FieldType == typeof(int) ) + { + int i = (bool)enumerator.Value ? 1 : 0; + field.SetValue(obj, i); + } + else if(field.FieldType == typeof(bool) && enumerator.Value is int) + { + bool b = (int)enumerator.Value != 0; + field.SetValue(obj, b); + } + else if(field.FieldType == typeof(UUID) && enumerator.Value is string) + { + UUID u; + UUID.TryParse((string)enumerator.Value, out u); + field.SetValue(obj, u); + } else { field.SetValue(obj, enumerator.Value); diff --git a/OpenSim/Capabilities/LLSDInventoryFolder.cs b/OpenSim/Capabilities/LLSDInventoryFolder.cs index d085430e8a..76b3f4135d 100644 --- a/OpenSim/Capabilities/LLSDInventoryFolder.cs +++ b/OpenSim/Capabilities/LLSDInventoryFolder.cs @@ -37,5 +37,6 @@ namespace OpenSim.Framework.Capabilities public string name; public int type; public int preferred_type; + public int version; } } diff --git a/OpenSim/Framework/GcNotify.cs b/OpenSim/Data/IMuteListData.cs similarity index 69% rename from OpenSim/Framework/GcNotify.cs rename to OpenSim/Data/IMuteListData.cs index 14a22a6104..b0235b2fa8 100644 --- a/OpenSim/Framework/GcNotify.cs +++ b/OpenSim/Data/IMuteListData.cs @@ -26,37 +26,19 @@ */ using System; -using System.Reflection; -using log4net; +using System.Collections.Generic; +using OpenMetaverse; +using OpenSim.Framework; -public class GcNotify +namespace OpenSim.Data { - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - - public static bool Enabled + /// + /// An interface for connecting to the Mute List datastore + /// + public interface IMuteListData { - get { return s_initialized; } - set - { - if (!s_initialized && value) - new GcNotify(); - - s_initialized = value; - } + bool Store(MuteData data); + MuteData[] Get(UUID agentID); + bool Delete(UUID agentID, UUID muteID, string muteName); } - - private static bool s_initialized = false; - - private GcNotify() {} - - ~GcNotify() - { - if (!Environment.HasShutdownStarted && !AppDomain.CurrentDomain.IsFinalizingForUnload()) - { - m_log.DebugFormat("[GC NOTIFY]: Garbage collection triggered."); - - if (Enabled) - new GcNotify(); - } - } -} \ No newline at end of file +} diff --git a/OpenSim/Data/MySQL/MySQLAssetData.cs b/OpenSim/Data/MySQL/MySQLAssetData.cs index f16cd913e7..8569c903a6 100644 --- a/OpenSim/Data/MySQL/MySQLAssetData.cs +++ b/OpenSim/Data/MySQL/MySQLAssetData.cs @@ -75,6 +75,7 @@ namespace OpenSim.Data.MySQL dbcon.Open(); Migration m = new Migration(dbcon, Assembly, "AssetStore"); m.Update(); + dbcon.Close(); } } @@ -144,6 +145,7 @@ namespace OpenSim.Data.MySQL string.Format("[ASSETS DB]: MySql failure fetching asset {0}. Exception ", assetID), e); } } + dbcon.Close(); } return asset; @@ -156,28 +158,27 @@ namespace OpenSim.Data.MySQL /// On failure : Throw an exception and attempt to reconnect to database override public bool StoreAsset(AssetBase asset) { + string assetName = asset.Name; + if (asset.Name.Length > AssetBase.MAX_ASSET_NAME) + { + assetName = asset.Name.Substring(0, AssetBase.MAX_ASSET_NAME); + m_log.WarnFormat( + "[ASSET DB]: Name '{0}' for asset {1} truncated from {2} to {3} characters on add", + asset.Name, asset.ID, asset.Name.Length, assetName.Length); + } + + string assetDescription = asset.Description; + if (asset.Description.Length > AssetBase.MAX_ASSET_DESC) + { + assetDescription = asset.Description.Substring(0, AssetBase.MAX_ASSET_DESC); + m_log.WarnFormat( + "[ASSET DB]: Description '{0}' for asset {1} truncated from {2} to {3} characters on add", + asset.Description, asset.ID, asset.Description.Length, assetDescription.Length); + } + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { dbcon.Open(); - - string assetName = asset.Name; - if (asset.Name.Length > AssetBase.MAX_ASSET_NAME) - { - assetName = asset.Name.Substring(0, AssetBase.MAX_ASSET_NAME); - m_log.WarnFormat( - "[ASSET DB]: Name '{0}' for asset {1} truncated from {2} to {3} characters on add", - asset.Name, asset.ID, asset.Name.Length, assetName.Length); - } - - string assetDescription = asset.Description; - if (asset.Description.Length > AssetBase.MAX_ASSET_DESC) - { - assetDescription = asset.Description.Substring(0, AssetBase.MAX_ASSET_DESC); - m_log.WarnFormat( - "[ASSET DB]: Description '{0}' for asset {1} truncated from {2} to {3} characters on add", - asset.Description, asset.ID, asset.Description.Length, assetDescription.Length); - } - using (MySqlCommand cmd = new MySqlCommand( "replace INTO assets(id, name, description, assetType, local, temporary, create_time, access_time, asset_flags, CreatorID, data)" + @@ -200,15 +201,17 @@ namespace OpenSim.Data.MySQL cmd.Parameters.AddWithValue("?asset_flags", (int)asset.Flags); cmd.Parameters.AddWithValue("?data", asset.Data); cmd.ExecuteNonQuery(); + dbcon.Close(); return true; } catch (Exception e) { m_log.ErrorFormat("[ASSET DB]: MySQL failure creating asset {0} with name \"{1}\". Error: {2}", asset.FullID, asset.Name, e.Message); + dbcon.Close(); return false; } - } + } } } @@ -238,6 +241,7 @@ namespace OpenSim.Data.MySQL e); } } + dbcon.Close(); } } @@ -270,6 +274,7 @@ namespace OpenSim.Data.MySQL } } } + dbcon.Close(); } bool[] results = new bool[uuids.Length]; @@ -334,6 +339,7 @@ namespace OpenSim.Data.MySQL e); } } + dbcon.Close(); } return retList; @@ -350,6 +356,7 @@ namespace OpenSim.Data.MySQL cmd.Parameters.AddWithValue("?id", id); cmd.ExecuteNonQuery(); } + dbcon.Close(); } return true; diff --git a/OpenSim/Data/MySQL/MySQLAuthenticationData.cs b/OpenSim/Data/MySQL/MySQLAuthenticationData.cs index af6be75bf7..fef582e809 100644 --- a/OpenSim/Data/MySQL/MySQLAuthenticationData.cs +++ b/OpenSim/Data/MySQL/MySQLAuthenticationData.cs @@ -59,6 +59,7 @@ namespace OpenSim.Data.MySQL dbcon.Open(); Migration m = new Migration(dbcon, Assembly, "AuthStore"); m.Update(); + dbcon.Close(); } } @@ -76,27 +77,30 @@ namespace OpenSim.Data.MySQL { cmd.Parameters.AddWithValue("?principalID", principalID.ToString()); - IDataReader result = cmd.ExecuteReader(); - - if (result.Read()) + using(IDataReader result = cmd.ExecuteReader()) { - ret.PrincipalID = principalID; - - CheckColumnNames(result); - - foreach (string s in m_ColumnNames) + if(result.Read()) { - if (s == "UUID") - continue; + ret.PrincipalID = principalID; - ret.Data[s] = result[s].ToString(); + CheckColumnNames(result); + + foreach(string s in m_ColumnNames) + { + if(s == "UUID") + continue; + + ret.Data[s] = result[s].ToString(); + } + + dbcon.Close(); + return ret; + } + else + { + dbcon.Close(); + return null; } - - return ret; - } - else - { - return null; } } } diff --git a/OpenSim/Data/MySQL/MySQLEstateData.cs b/OpenSim/Data/MySQL/MySQLEstateData.cs index a5c8d24de5..eeedf02b29 100644 --- a/OpenSim/Data/MySQL/MySQLEstateData.cs +++ b/OpenSim/Data/MySQL/MySQLEstateData.cs @@ -82,6 +82,7 @@ namespace OpenSim.Data.MySQL Migration m = new Migration(dbcon, Assembly, "EstateStore"); m.Update(); + dbcon.Close(); Type t = typeof(EstateSettings); m_Fields = t.GetFields(BindingFlags.NonPublic | @@ -143,7 +144,6 @@ namespace OpenSim.Data.MySQL using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { dbcon.Open(); - cmd.Connection = dbcon; bool found = false; @@ -171,6 +171,8 @@ namespace OpenSim.Data.MySQL } } } + dbcon.Close(); + cmd.Connection = null; if (!found && create) { @@ -231,6 +233,7 @@ namespace OpenSim.Data.MySQL es.Save(); } + dbcon.Close(); } } @@ -263,6 +266,7 @@ namespace OpenSim.Data.MySQL cmd.ExecuteNonQuery(); } + dbcon.Close(); } SaveBanList(es); @@ -300,6 +304,7 @@ namespace OpenSim.Data.MySQL } } } + dbcon.Close(); } } @@ -329,6 +334,7 @@ namespace OpenSim.Data.MySQL cmd.Parameters.Clear(); } } + dbcon.Close(); } } @@ -358,6 +364,7 @@ namespace OpenSim.Data.MySQL cmd.Parameters.Clear(); } } + dbcon.Close(); } } @@ -383,6 +390,7 @@ namespace OpenSim.Data.MySQL } } } + dbcon.Close(); } return uuids.ToArray(); @@ -437,7 +445,6 @@ namespace OpenSim.Data.MySQL reader.Close(); } } - dbcon.Close(); } @@ -466,7 +473,6 @@ namespace OpenSim.Data.MySQL reader.Close(); } } - dbcon.Close(); } diff --git a/OpenSim/Data/MySQL/MySQLFSAssetData.cs b/OpenSim/Data/MySQL/MySQLFSAssetData.cs index 2837ce31be..6c486077d3 100644 --- a/OpenSim/Data/MySQL/MySQLFSAssetData.cs +++ b/OpenSim/Data/MySQL/MySQLFSAssetData.cs @@ -78,6 +78,7 @@ namespace OpenSim.Data.MySQL conn.Open(); Migration m = new Migration(conn, Assembly, "FSAssetStore"); m.Update(); + conn.Close(); } } catch (MySqlException e) @@ -121,9 +122,13 @@ namespace OpenSim.Data.MySQL } catch (MySqlException e) { + cmd.Connection = null; + conn.Close(); m_log.ErrorFormat("[FSASSETS]: Query {0} failed with {1}", cmd.CommandText, e.ToString()); return false; } + conn.Close(); + cmd.Connection = null; } return true; @@ -175,7 +180,7 @@ namespace OpenSim.Data.MySQL UpdateAccessTime(id, AccessTime); } } - + conn.Close(); } return meta; @@ -206,6 +211,7 @@ namespace OpenSim.Data.MySQL cmd.Parameters.AddWithValue("?id", AssetID); cmd.ExecuteNonQuery(); } + conn.Close(); } } @@ -299,6 +305,7 @@ namespace OpenSim.Data.MySQL } } } + conn.Close(); } for (int i = 0; i < uuids.Length; i++) @@ -333,6 +340,7 @@ namespace OpenSim.Data.MySQL count = Convert.ToInt32(reader["count"]); } } + conn.Close(); } return count; @@ -413,8 +421,8 @@ namespace OpenSim.Data.MySQL imported++; } } - } + importConn.Close(); } MainConsole.Instance.Output(String.Format("Import done, {0} assets imported", imported)); diff --git a/OpenSim/Data/MySQL/MySQLFramework.cs b/OpenSim/Data/MySQL/MySQLFramework.cs index 93662db875..98106f0057 100644 --- a/OpenSim/Data/MySQL/MySQLFramework.cs +++ b/OpenSim/Data/MySQL/MySQLFramework.cs @@ -74,7 +74,9 @@ namespace OpenSim.Data.MySQL using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { dbcon.Open(); - return ExecuteNonQueryWithConnection(cmd, dbcon); + int ret = ExecuteNonQueryWithConnection(cmd, dbcon); + dbcon.Close(); + return ret; } } else @@ -97,12 +99,15 @@ namespace OpenSim.Data.MySQL try { - return cmd.ExecuteNonQuery(); + int ret = cmd.ExecuteNonQuery(); + cmd.Connection = null; + return ret; } catch (Exception e) { m_log.Error(e.Message, e); m_log.Error(Environment.StackTrace.ToString()); + cmd.Connection = null; return 0; } } diff --git a/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs b/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs index bd8bbd5920..1564140785 100644 --- a/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs +++ b/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs @@ -29,11 +29,9 @@ using System; using System.Collections.Generic; using System.Data; using System.Reflection; -using log4net; +using System.Text; using MySql.Data.MySqlClient; using OpenMetaverse; -using OpenSim.Framework; -using OpenSim.Region.Framework.Interfaces; namespace OpenSim.Data.MySQL { @@ -129,25 +127,27 @@ namespace OpenSim.Data.MySQL public virtual T[] Get(string[] fields, string[] keys, string options) { - if (fields.Length != keys.Length) + int flen = fields.Length; + if (flen == 0 || flen != keys.Length) return new T[0]; - List terms = new List(); + int flast = flen - 1; + StringBuilder sb = new StringBuilder(1024); + sb.AppendFormat("select * from {0} where ", m_Realm); using (MySqlCommand cmd = new MySqlCommand()) { - for (int i = 0 ; i < fields.Length ; i++) + for (int i = 0 ; i < flen ; i++) { cmd.Parameters.AddWithValue(fields[i], keys[i]); - terms.Add("`" + fields[i] + "` = ?" + fields[i]); + if(i< flast) + sb.AppendFormat("`{0}` = ?{0} and ", fields[i]); + else + sb.AppendFormat("`{0}` = ?{0} ", fields[i]); } - string where = String.Join(" and ", terms.ToArray()); - - string query = String.Format("select * from {0} where {1} {2}", - m_Realm, where, options); - - cmd.CommandText = query; + sb.Append(options); + cmd.CommandText = sb.ToString(); return DoQuery(cmd); } @@ -160,8 +160,9 @@ namespace OpenSim.Data.MySQL using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { dbcon.Open(); - - return DoQueryWithConnection(cmd, dbcon); + T[] ret = DoQueryWithConnection(cmd, dbcon); + dbcon.Close(); + return ret; } } else @@ -203,7 +204,7 @@ namespace OpenSim.Data.MySQL if (m_Fields[name].FieldType == typeof(bool)) { int v = Convert.ToInt32(reader[name]); - m_Fields[name].SetValue(row, v != 0 ? true : false); + m_Fields[name].SetValue(row, v != 0); } else if (m_Fields[name].FieldType == typeof(UUID)) { @@ -243,7 +244,7 @@ namespace OpenSim.Data.MySQL result.Add(row); } } - + cmd.Connection = null; return result.ToArray(); } @@ -402,7 +403,10 @@ namespace OpenSim.Data.MySQL dbcon.Open(); cmd.Connection = dbcon; - return cmd.ExecuteScalar(); + Object ret = cmd.ExecuteScalar(); + cmd.Connection = null; + dbcon.Close(); + return ret; } } else diff --git a/OpenSim/Data/MySQL/MySQLInventoryData.cs b/OpenSim/Data/MySQL/MySQLInventoryData.cs index 382d4a5c33..cc787ccde8 100644 --- a/OpenSim/Data/MySQL/MySQLInventoryData.cs +++ b/OpenSim/Data/MySQL/MySQLInventoryData.cs @@ -78,6 +78,7 @@ namespace OpenSim.Data.MySQL dbcon.Open(); Migration m = new Migration(dbcon, assem, "InventoryStore"); m.Update(); + dbcon.Close(); } } @@ -130,6 +131,7 @@ namespace OpenSim.Data.MySQL items.Add(item); } + dbcon.Close(); return items; } } @@ -170,6 +172,7 @@ namespace OpenSim.Data.MySQL while (reader.Read()) items.Add(readInventoryFolder(reader)); + dbcon.Close(); return items; } } @@ -221,6 +224,7 @@ namespace OpenSim.Data.MySQL if (items.Count > 0) rootFolder = items[0]; + dbcon.Close(); return rootFolder; } } @@ -261,6 +265,7 @@ namespace OpenSim.Data.MySQL while (reader.Read()) items.Add(readInventoryFolder(reader)); + dbcon.Close(); return items; } } @@ -352,6 +357,7 @@ namespace OpenSim.Data.MySQL if (reader.Read()) item = readInventoryItem(reader); + dbcon.Close(); return item; } } @@ -417,6 +423,7 @@ namespace OpenSim.Data.MySQL if (reader.Read()) folder = readInventoryFolder(reader); + dbcon.Close(); return folder; } } @@ -504,6 +511,7 @@ namespace OpenSim.Data.MySQL lock (m_dbLock) result.ExecuteNonQuery(); } + dbcon.Close(); } } catch (MySqlException e) @@ -540,6 +548,7 @@ namespace OpenSim.Data.MySQL lock (m_dbLock) cmd.ExecuteNonQuery(); } + dbcon.Close(); } } catch (MySqlException e) @@ -600,6 +609,7 @@ namespace OpenSim.Data.MySQL m_log.Error(e.ToString()); } } + dbcon.Close(); } } @@ -643,6 +653,7 @@ namespace OpenSim.Data.MySQL m_log.Error(e.ToString()); } } + dbcon.Close(); } } @@ -806,6 +817,7 @@ namespace OpenSim.Data.MySQL lock (m_dbLock) cmd.ExecuteNonQuery(); } + dbcon.Close(); } } catch (MySqlException e) @@ -833,6 +845,7 @@ namespace OpenSim.Data.MySQL lock (m_dbLock) cmd.ExecuteNonQuery(); } + dbcon.Close(); } } catch (MySqlException e) @@ -886,6 +899,7 @@ namespace OpenSim.Data.MySQL if (item != null) list.Add(item); } + dbcon.Close(); return list; } } diff --git a/OpenSim/Data/MySQL/MySQLMuteListData.cs b/OpenSim/Data/MySQL/MySQLMuteListData.cs new file mode 100644 index 0000000000..a5935a32fa --- /dev/null +++ b/OpenSim/Data/MySQL/MySQLMuteListData.cs @@ -0,0 +1,67 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Data; +using OpenMetaverse; +using OpenSim.Framework; +using MySql.Data.MySqlClient; + +namespace OpenSim.Data.MySQL +{ + public class MySqlMuteListData : MySQLGenericTableHandler, IMuteListData + { + public MySqlMuteListData(string connectionString) + : base(connectionString, "MuteList", "MuteListStore") + { + } + + public MuteData[] Get(UUID agentID) + { + MuteData[] data = base.Get("AgentID", agentID.ToString()); + return data; + } + + public bool Delete(UUID agentID, UUID muteID, string muteName) + { + string cmnd ="delete from MuteList where AgentID = ?AgentID and MuteID = ?MuteID and MuteName = ?MuteName"; + + using (MySqlCommand cmd = new MySqlCommand(cmnd)) + { + cmd.Parameters.AddWithValue("?AgentID", agentID.ToString()); + cmd.Parameters.AddWithValue("?MuteID", muteID.ToString()); + cmd.Parameters.AddWithValue("?MuteName", muteName); + + if (ExecuteNonQuery(cmd) > 0) + return true; + return false; + } + } + } +} \ No newline at end of file diff --git a/OpenSim/Data/MySQL/MySQLRegionData.cs b/OpenSim/Data/MySQL/MySQLRegionData.cs index 0e55285451..46df421352 100644 --- a/OpenSim/Data/MySQL/MySQLRegionData.cs +++ b/OpenSim/Data/MySQL/MySQLRegionData.cs @@ -60,6 +60,7 @@ namespace OpenSim.Data.MySQL dbcon.Open(); Migration m = new Migration(dbcon, Assembly, "GridStore"); m.Update(); + dbcon.Close(); } } @@ -260,6 +261,8 @@ namespace OpenSim.Data.MySQL retList.Add(ret); } } + cmd.Connection = null; + dbcon.Close(); } return retList; diff --git a/OpenSim/Data/MySQL/MySQLSimulationData.cs b/OpenSim/Data/MySQL/MySQLSimulationData.cs index 8278c0ec20..e754522f44 100644 --- a/OpenSim/Data/MySQL/MySQLSimulationData.cs +++ b/OpenSim/Data/MySQL/MySQLSimulationData.cs @@ -88,6 +88,7 @@ namespace OpenSim.Data.MySQL // Migration m = new Migration(dbcon, Assembly, "RegionStore"); m.Update(); + dbcon.Close(); } } @@ -187,7 +188,7 @@ namespace OpenSim.Data.MySQL "LinkNumber, MediaURL, KeyframeMotion, AttachedPosX, " + "AttachedPosY, AttachedPosZ, " + "PhysicsShapeType, Density, GravityModifier, " + - "Friction, Restitution, Vehicle, DynAttrs, " + + "Friction, Restitution, Vehicle, PhysInertia, DynAttrs, " + "RotationAxisLocks" + ") values (" + "?UUID, " + "?CreationDate, ?Name, ?Text, " + @@ -224,7 +225,7 @@ namespace OpenSim.Data.MySQL "?LinkNumber, ?MediaURL, ?KeyframeMotion, ?AttachedPosX, " + "?AttachedPosY, ?AttachedPosZ, " + "?PhysicsShapeType, ?Density, ?GravityModifier, " + - "?Friction, ?Restitution, ?Vehicle, ?DynAttrs," + + "?Friction, ?Restitution, ?Vehicle, ?PhysInertia, ?DynAttrs," + "?RotationAxisLocks)"; FillPrimCommand(cmd, prim, obj.UUID, regionUUID); @@ -261,6 +262,7 @@ namespace OpenSim.Data.MySQL ExecuteNonQuery(cmd); } } + dbcon.Close(); } } } @@ -300,6 +302,7 @@ namespace OpenSim.Data.MySQL cmd.CommandText = "delete from prims where SceneGroupID= ?UUID"; ExecuteNonQuery(cmd); } + dbcon.Close(); } } @@ -334,6 +337,7 @@ namespace OpenSim.Data.MySQL ExecuteNonQuery(cmd); } + dbcon.Close(); } } } @@ -372,6 +376,7 @@ namespace OpenSim.Data.MySQL ExecuteNonQuery(cmd); } + dbcon.Close(); } } } @@ -411,6 +416,7 @@ namespace OpenSim.Data.MySQL ExecuteNonQuery(cmd); } + dbcon.Close(); } } } @@ -460,6 +466,7 @@ namespace OpenSim.Data.MySQL } } } + dbcon.Close(); } } @@ -535,6 +542,7 @@ namespace OpenSim.Data.MySQL } } } + dbcon.Close(); } } @@ -580,6 +588,7 @@ namespace OpenSim.Data.MySQL } } } + dbcon.Close(); } prim.Inventory.RestoreInventoryItems(inventory); @@ -598,6 +607,10 @@ namespace OpenSim.Data.MySQL { m_log.Info("[REGION DB]: Storing terrain"); + int terrainDBRevision; + Array terrainDBblob; + terrData.GetDatabaseBlob(out terrainDBRevision, out terrainDBblob); + lock (m_dbLock) { using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) @@ -617,10 +630,6 @@ namespace OpenSim.Data.MySQL "Revision, Heightfield) values (?RegionUUID, " + "?Revision, ?Heightfield)"; - int terrainDBRevision; - Array terrainDBblob; - terrData.GetDatabaseBlob(out terrainDBRevision, out terrainDBblob); - cmd2.Parameters.AddWithValue("RegionUUID", regionID.ToString()); cmd2.Parameters.AddWithValue("Revision", terrainDBRevision); cmd2.Parameters.AddWithValue("Heightfield", terrainDBblob); @@ -634,6 +643,7 @@ namespace OpenSim.Data.MySQL } } } + dbcon.Close(); } } }); @@ -645,6 +655,10 @@ namespace OpenSim.Data.MySQL { m_log.Info("[REGION DB]: Storing Baked terrain"); + int terrainDBRevision; + Array terrainDBblob; + terrData.GetDatabaseBlob(out terrainDBRevision, out terrainDBblob); + lock (m_dbLock) { using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) @@ -664,10 +678,6 @@ namespace OpenSim.Data.MySQL "Revision, Heightfield) values (?RegionUUID, " + "?Revision, ?Heightfield)"; - int terrainDBRevision; - Array terrainDBblob; - terrData.GetDatabaseBlob(out terrainDBRevision, out terrainDBblob); - cmd2.Parameters.AddWithValue("RegionUUID", regionID.ToString()); cmd2.Parameters.AddWithValue("Revision", terrainDBRevision); cmd2.Parameters.AddWithValue("Heightfield", terrainDBblob); @@ -681,6 +691,7 @@ namespace OpenSim.Data.MySQL } } } + dbcon.Close(); } } }); @@ -700,9 +711,12 @@ namespace OpenSim.Data.MySQL public TerrainData LoadTerrain(UUID regionID, int pSizeX, int pSizeY, int pSizeZ) { TerrainData terrData = null; + byte[] blob = null; + int rev = 0; lock (m_dbLock) { + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { dbcon.Open(); @@ -718,24 +732,29 @@ namespace OpenSim.Data.MySQL { while (reader.Read()) { - int rev = Convert.ToInt32(reader["Revision"]); + rev = Convert.ToInt32(reader["Revision"]); if ((reader["Heightfield"] != DBNull.Value)) { - byte[] blob = (byte[])reader["Heightfield"]; - terrData = TerrainData.CreateFromDatabaseBlobFactory(pSizeX, pSizeY, pSizeZ, rev, blob); + blob = (byte[])reader["Heightfield"]; } } } } + dbcon.Close(); } } + if(blob != null) + terrData = TerrainData.CreateFromDatabaseBlobFactory(pSizeX, pSizeY, pSizeZ, rev, blob); + return terrData; } public TerrainData LoadBakedTerrain(UUID regionID, int pSizeX, int pSizeY, int pSizeZ) { TerrainData terrData = null; + byte[] blob = null; + int rev = 0; lock (m_dbLock) { @@ -753,17 +772,19 @@ namespace OpenSim.Data.MySQL { while (reader.Read()) { - int rev = Convert.ToInt32(reader["Revision"]); + rev = Convert.ToInt32(reader["Revision"]); if ((reader["Heightfield"] != DBNull.Value)) { - byte[] blob = (byte[])reader["Heightfield"]; - terrData = TerrainData.CreateFromDatabaseBlobFactory(pSizeX, pSizeY, pSizeZ, rev, blob); + blob = (byte[])reader["Heightfield"]; } } } } + dbcon.Close(); } } + if(blob != null) + terrData = TerrainData.CreateFromDatabaseBlobFactory(pSizeX, pSizeY, pSizeZ, rev, blob); return terrData; } @@ -783,6 +804,7 @@ namespace OpenSim.Data.MySQL ExecuteNonQuery(cmd); } + dbcon.Close(); } } } @@ -842,6 +864,7 @@ namespace OpenSim.Data.MySQL cmd.Parameters.Clear(); } } + dbcon.Close(); } } } @@ -863,82 +886,85 @@ namespace OpenSim.Data.MySQL cmd.Parameters.AddWithValue("?regionID", regionUUID.ToString()); - IDataReader result = ExecuteReader(cmd); - if (!result.Read()) + using(IDataReader result = ExecuteReader(cmd)) { - //No result, so store our default windlight profile and return it - nWP.regionID = regionUUID; -// StoreRegionWindlightSettings(nWP); - return nWP; - } - else - { - nWP.regionID = DBGuid.FromDB(result["region_id"]); - nWP.waterColor.X = Convert.ToSingle(result["water_color_r"]); - nWP.waterColor.Y = Convert.ToSingle(result["water_color_g"]); - nWP.waterColor.Z = Convert.ToSingle(result["water_color_b"]); - nWP.waterFogDensityExponent = Convert.ToSingle(result["water_fog_density_exponent"]); - nWP.underwaterFogModifier = Convert.ToSingle(result["underwater_fog_modifier"]); - nWP.reflectionWaveletScale.X = Convert.ToSingle(result["reflection_wavelet_scale_1"]); - nWP.reflectionWaveletScale.Y = Convert.ToSingle(result["reflection_wavelet_scale_2"]); - nWP.reflectionWaveletScale.Z = Convert.ToSingle(result["reflection_wavelet_scale_3"]); - nWP.fresnelScale = Convert.ToSingle(result["fresnel_scale"]); - nWP.fresnelOffset = Convert.ToSingle(result["fresnel_offset"]); - nWP.refractScaleAbove = Convert.ToSingle(result["refract_scale_above"]); - nWP.refractScaleBelow = Convert.ToSingle(result["refract_scale_below"]); - nWP.blurMultiplier = Convert.ToSingle(result["blur_multiplier"]); - nWP.bigWaveDirection.X = Convert.ToSingle(result["big_wave_direction_x"]); - nWP.bigWaveDirection.Y = Convert.ToSingle(result["big_wave_direction_y"]); - nWP.littleWaveDirection.X = Convert.ToSingle(result["little_wave_direction_x"]); - nWP.littleWaveDirection.Y = Convert.ToSingle(result["little_wave_direction_y"]); - UUID.TryParse(result["normal_map_texture"].ToString(), out nWP.normalMapTexture); - nWP.horizon.X = Convert.ToSingle(result["horizon_r"]); - nWP.horizon.Y = Convert.ToSingle(result["horizon_g"]); - nWP.horizon.Z = Convert.ToSingle(result["horizon_b"]); - nWP.horizon.W = Convert.ToSingle(result["horizon_i"]); - nWP.hazeHorizon = Convert.ToSingle(result["haze_horizon"]); - nWP.blueDensity.X = Convert.ToSingle(result["blue_density_r"]); - nWP.blueDensity.Y = Convert.ToSingle(result["blue_density_g"]); - nWP.blueDensity.Z = Convert.ToSingle(result["blue_density_b"]); - nWP.blueDensity.W = Convert.ToSingle(result["blue_density_i"]); - nWP.hazeDensity = Convert.ToSingle(result["haze_density"]); - nWP.densityMultiplier = Convert.ToSingle(result["density_multiplier"]); - nWP.distanceMultiplier = Convert.ToSingle(result["distance_multiplier"]); - nWP.maxAltitude = Convert.ToUInt16(result["max_altitude"]); - nWP.sunMoonColor.X = Convert.ToSingle(result["sun_moon_color_r"]); - nWP.sunMoonColor.Y = Convert.ToSingle(result["sun_moon_color_g"]); - nWP.sunMoonColor.Z = Convert.ToSingle(result["sun_moon_color_b"]); - nWP.sunMoonColor.W = Convert.ToSingle(result["sun_moon_color_i"]); - nWP.sunMoonPosition = Convert.ToSingle(result["sun_moon_position"]); - nWP.ambient.X = Convert.ToSingle(result["ambient_r"]); - nWP.ambient.Y = Convert.ToSingle(result["ambient_g"]); - nWP.ambient.Z = Convert.ToSingle(result["ambient_b"]); - nWP.ambient.W = Convert.ToSingle(result["ambient_i"]); - nWP.eastAngle = Convert.ToSingle(result["east_angle"]); - nWP.sunGlowFocus = Convert.ToSingle(result["sun_glow_focus"]); - nWP.sunGlowSize = Convert.ToSingle(result["sun_glow_size"]); - nWP.sceneGamma = Convert.ToSingle(result["scene_gamma"]); - nWP.starBrightness = Convert.ToSingle(result["star_brightness"]); - nWP.cloudColor.X = Convert.ToSingle(result["cloud_color_r"]); - nWP.cloudColor.Y = Convert.ToSingle(result["cloud_color_g"]); - nWP.cloudColor.Z = Convert.ToSingle(result["cloud_color_b"]); - nWP.cloudColor.W = Convert.ToSingle(result["cloud_color_i"]); - nWP.cloudXYDensity.X = Convert.ToSingle(result["cloud_x"]); - nWP.cloudXYDensity.Y = Convert.ToSingle(result["cloud_y"]); - nWP.cloudXYDensity.Z = Convert.ToSingle(result["cloud_density"]); - nWP.cloudCoverage = Convert.ToSingle(result["cloud_coverage"]); - nWP.cloudScale = Convert.ToSingle(result["cloud_scale"]); - nWP.cloudDetailXYDensity.X = Convert.ToSingle(result["cloud_detail_x"]); - nWP.cloudDetailXYDensity.Y = Convert.ToSingle(result["cloud_detail_y"]); - nWP.cloudDetailXYDensity.Z = Convert.ToSingle(result["cloud_detail_density"]); - nWP.cloudScrollX = Convert.ToSingle(result["cloud_scroll_x"]); - nWP.cloudScrollXLock = Convert.ToBoolean(result["cloud_scroll_x_lock"]); - nWP.cloudScrollY = Convert.ToSingle(result["cloud_scroll_y"]); - nWP.cloudScrollYLock = Convert.ToBoolean(result["cloud_scroll_y_lock"]); - nWP.drawClassicClouds = Convert.ToBoolean(result["draw_classic_clouds"]); - nWP.valid = true; + if(!result.Read()) + { + //No result, so store our default windlight profile and return it + nWP.regionID = regionUUID; + // StoreRegionWindlightSettings(nWP); + return nWP; + } + else + { + nWP.regionID = DBGuid.FromDB(result["region_id"]); + nWP.waterColor.X = Convert.ToSingle(result["water_color_r"]); + nWP.waterColor.Y = Convert.ToSingle(result["water_color_g"]); + nWP.waterColor.Z = Convert.ToSingle(result["water_color_b"]); + nWP.waterFogDensityExponent = Convert.ToSingle(result["water_fog_density_exponent"]); + nWP.underwaterFogModifier = Convert.ToSingle(result["underwater_fog_modifier"]); + nWP.reflectionWaveletScale.X = Convert.ToSingle(result["reflection_wavelet_scale_1"]); + nWP.reflectionWaveletScale.Y = Convert.ToSingle(result["reflection_wavelet_scale_2"]); + nWP.reflectionWaveletScale.Z = Convert.ToSingle(result["reflection_wavelet_scale_3"]); + nWP.fresnelScale = Convert.ToSingle(result["fresnel_scale"]); + nWP.fresnelOffset = Convert.ToSingle(result["fresnel_offset"]); + nWP.refractScaleAbove = Convert.ToSingle(result["refract_scale_above"]); + nWP.refractScaleBelow = Convert.ToSingle(result["refract_scale_below"]); + nWP.blurMultiplier = Convert.ToSingle(result["blur_multiplier"]); + nWP.bigWaveDirection.X = Convert.ToSingle(result["big_wave_direction_x"]); + nWP.bigWaveDirection.Y = Convert.ToSingle(result["big_wave_direction_y"]); + nWP.littleWaveDirection.X = Convert.ToSingle(result["little_wave_direction_x"]); + nWP.littleWaveDirection.Y = Convert.ToSingle(result["little_wave_direction_y"]); + UUID.TryParse(result["normal_map_texture"].ToString(),out nWP.normalMapTexture); + nWP.horizon.X = Convert.ToSingle(result["horizon_r"]); + nWP.horizon.Y = Convert.ToSingle(result["horizon_g"]); + nWP.horizon.Z = Convert.ToSingle(result["horizon_b"]); + nWP.horizon.W = Convert.ToSingle(result["horizon_i"]); + nWP.hazeHorizon = Convert.ToSingle(result["haze_horizon"]); + nWP.blueDensity.X = Convert.ToSingle(result["blue_density_r"]); + nWP.blueDensity.Y = Convert.ToSingle(result["blue_density_g"]); + nWP.blueDensity.Z = Convert.ToSingle(result["blue_density_b"]); + nWP.blueDensity.W = Convert.ToSingle(result["blue_density_i"]); + nWP.hazeDensity = Convert.ToSingle(result["haze_density"]); + nWP.densityMultiplier = Convert.ToSingle(result["density_multiplier"]); + nWP.distanceMultiplier = Convert.ToSingle(result["distance_multiplier"]); + nWP.maxAltitude = Convert.ToUInt16(result["max_altitude"]); + nWP.sunMoonColor.X = Convert.ToSingle(result["sun_moon_color_r"]); + nWP.sunMoonColor.Y = Convert.ToSingle(result["sun_moon_color_g"]); + nWP.sunMoonColor.Z = Convert.ToSingle(result["sun_moon_color_b"]); + nWP.sunMoonColor.W = Convert.ToSingle(result["sun_moon_color_i"]); + nWP.sunMoonPosition = Convert.ToSingle(result["sun_moon_position"]); + nWP.ambient.X = Convert.ToSingle(result["ambient_r"]); + nWP.ambient.Y = Convert.ToSingle(result["ambient_g"]); + nWP.ambient.Z = Convert.ToSingle(result["ambient_b"]); + nWP.ambient.W = Convert.ToSingle(result["ambient_i"]); + nWP.eastAngle = Convert.ToSingle(result["east_angle"]); + nWP.sunGlowFocus = Convert.ToSingle(result["sun_glow_focus"]); + nWP.sunGlowSize = Convert.ToSingle(result["sun_glow_size"]); + nWP.sceneGamma = Convert.ToSingle(result["scene_gamma"]); + nWP.starBrightness = Convert.ToSingle(result["star_brightness"]); + nWP.cloudColor.X = Convert.ToSingle(result["cloud_color_r"]); + nWP.cloudColor.Y = Convert.ToSingle(result["cloud_color_g"]); + nWP.cloudColor.Z = Convert.ToSingle(result["cloud_color_b"]); + nWP.cloudColor.W = Convert.ToSingle(result["cloud_color_i"]); + nWP.cloudXYDensity.X = Convert.ToSingle(result["cloud_x"]); + nWP.cloudXYDensity.Y = Convert.ToSingle(result["cloud_y"]); + nWP.cloudXYDensity.Z = Convert.ToSingle(result["cloud_density"]); + nWP.cloudCoverage = Convert.ToSingle(result["cloud_coverage"]); + nWP.cloudScale = Convert.ToSingle(result["cloud_scale"]); + nWP.cloudDetailXYDensity.X = Convert.ToSingle(result["cloud_detail_x"]); + nWP.cloudDetailXYDensity.Y = Convert.ToSingle(result["cloud_detail_y"]); + nWP.cloudDetailXYDensity.Z = Convert.ToSingle(result["cloud_detail_density"]); + nWP.cloudScrollX = Convert.ToSingle(result["cloud_scroll_x"]); + nWP.cloudScrollXLock = Convert.ToBoolean(result["cloud_scroll_x_lock"]); + nWP.cloudScrollY = Convert.ToSingle(result["cloud_scroll_y"]); + nWP.cloudScrollYLock = Convert.ToBoolean(result["cloud_scroll_y_lock"]); + nWP.drawClassicClouds = Convert.ToBoolean(result["draw_classic_clouds"]); + nWP.valid = true; + } } } + dbcon.Close(); } return nWP; @@ -947,6 +973,7 @@ namespace OpenSim.Data.MySQL public virtual RegionSettings LoadRegionSettings(UUID regionUUID) { RegionSettings rs = null; + bool needStore = false; lock (m_dbLock) { @@ -972,13 +999,17 @@ namespace OpenSim.Data.MySQL rs.RegionUUID = regionUUID; rs.OnSave += StoreRegionSettings; - StoreRegionSettings(rs); + needStore = true; } } } + dbcon.Close(); } } + if(needStore) + StoreRegionSettings(rs); + LoadSpawnPoints(rs); return rs; @@ -992,31 +1023,32 @@ namespace OpenSim.Data.MySQL using (MySqlCommand cmd = dbcon.CreateCommand()) { - cmd.CommandText = "REPLACE INTO `regionwindlight` (`region_id`, `water_color_r`, `water_color_g`, "; - cmd.CommandText += "`water_color_b`, `water_fog_density_exponent`, `underwater_fog_modifier`, "; - cmd.CommandText += "`reflection_wavelet_scale_1`, `reflection_wavelet_scale_2`, `reflection_wavelet_scale_3`, "; - cmd.CommandText += "`fresnel_scale`, `fresnel_offset`, `refract_scale_above`, `refract_scale_below`, "; - cmd.CommandText += "`blur_multiplier`, `big_wave_direction_x`, `big_wave_direction_y`, `little_wave_direction_x`, "; - cmd.CommandText += "`little_wave_direction_y`, `normal_map_texture`, `horizon_r`, `horizon_g`, `horizon_b`, "; - cmd.CommandText += "`horizon_i`, `haze_horizon`, `blue_density_r`, `blue_density_g`, `blue_density_b`, "; - cmd.CommandText += "`blue_density_i`, `haze_density`, `density_multiplier`, `distance_multiplier`, `max_altitude`, "; - cmd.CommandText += "`sun_moon_color_r`, `sun_moon_color_g`, `sun_moon_color_b`, `sun_moon_color_i`, `sun_moon_position`, "; - cmd.CommandText += "`ambient_r`, `ambient_g`, `ambient_b`, `ambient_i`, `east_angle`, `sun_glow_focus`, `sun_glow_size`, "; - cmd.CommandText += "`scene_gamma`, `star_brightness`, `cloud_color_r`, `cloud_color_g`, `cloud_color_b`, `cloud_color_i`, "; - cmd.CommandText += "`cloud_x`, `cloud_y`, `cloud_density`, `cloud_coverage`, `cloud_scale`, `cloud_detail_x`, "; - cmd.CommandText += "`cloud_detail_y`, `cloud_detail_density`, `cloud_scroll_x`, `cloud_scroll_x_lock`, `cloud_scroll_y`, "; - cmd.CommandText += "`cloud_scroll_y_lock`, `draw_classic_clouds`) VALUES (?region_id, ?water_color_r, "; - cmd.CommandText += "?water_color_g, ?water_color_b, ?water_fog_density_exponent, ?underwater_fog_modifier, ?reflection_wavelet_scale_1, "; - cmd.CommandText += "?reflection_wavelet_scale_2, ?reflection_wavelet_scale_3, ?fresnel_scale, ?fresnel_offset, ?refract_scale_above, "; - cmd.CommandText += "?refract_scale_below, ?blur_multiplier, ?big_wave_direction_x, ?big_wave_direction_y, ?little_wave_direction_x, "; - cmd.CommandText += "?little_wave_direction_y, ?normal_map_texture, ?horizon_r, ?horizon_g, ?horizon_b, ?horizon_i, ?haze_horizon, "; - cmd.CommandText += "?blue_density_r, ?blue_density_g, ?blue_density_b, ?blue_density_i, ?haze_density, ?density_multiplier, "; - cmd.CommandText += "?distance_multiplier, ?max_altitude, ?sun_moon_color_r, ?sun_moon_color_g, ?sun_moon_color_b, "; - cmd.CommandText += "?sun_moon_color_i, ?sun_moon_position, ?ambient_r, ?ambient_g, ?ambient_b, ?ambient_i, ?east_angle, "; - cmd.CommandText += "?sun_glow_focus, ?sun_glow_size, ?scene_gamma, ?star_brightness, ?cloud_color_r, ?cloud_color_g, "; - cmd.CommandText += "?cloud_color_b, ?cloud_color_i, ?cloud_x, ?cloud_y, ?cloud_density, ?cloud_coverage, ?cloud_scale, "; - cmd.CommandText += "?cloud_detail_x, ?cloud_detail_y, ?cloud_detail_density, ?cloud_scroll_x, ?cloud_scroll_x_lock, "; - cmd.CommandText += "?cloud_scroll_y, ?cloud_scroll_y_lock, ?draw_classic_clouds)"; + cmd.CommandText = "REPLACE INTO `regionwindlight` (`region_id`, `water_color_r`, `water_color_g`, " + + "`water_color_b`, `water_fog_density_exponent`, `underwater_fog_modifier`, " + + "`reflection_wavelet_scale_1`, `reflection_wavelet_scale_2`, `reflection_wavelet_scale_3`, " + + "`fresnel_scale`, `fresnel_offset`, `refract_scale_above`, `refract_scale_below`, " + + "`blur_multiplier`, `big_wave_direction_x`, `big_wave_direction_y`, `little_wave_direction_x`, " + + "`little_wave_direction_y`, `normal_map_texture`, `horizon_r`, `horizon_g`, `horizon_b`, " + + "`horizon_i`, `haze_horizon`, `blue_density_r`, `blue_density_g`, `blue_density_b`, " + + "`blue_density_i`, `haze_density`, `density_multiplier`, `distance_multiplier`, `max_altitude`, " + + "`sun_moon_color_r`, `sun_moon_color_g`, `sun_moon_color_b`, `sun_moon_color_i`, `sun_moon_position`, " + + "`ambient_r`, `ambient_g`, `ambient_b`, `ambient_i`, `east_angle`, `sun_glow_focus`, `sun_glow_size`, " + + "`scene_gamma`, `star_brightness`, `cloud_color_r`, `cloud_color_g`, `cloud_color_b`, `cloud_color_i`, " + + "`cloud_x`, `cloud_y`, `cloud_density`, `cloud_coverage`, `cloud_scale`, `cloud_detail_x`, " + + "`cloud_detail_y`, `cloud_detail_density`, `cloud_scroll_x`, `cloud_scroll_x_lock`, `cloud_scroll_y`, " + + "`cloud_scroll_y_lock`, `draw_classic_clouds`) VALUES (?region_id, ?water_color_r, " + + "?water_color_g, ?water_color_b, ?water_fog_density_exponent, ?underwater_fog_modifier, ?reflection_wavelet_scale_1, " + + "?reflection_wavelet_scale_2, ?reflection_wavelet_scale_3, ?fresnel_scale, ?fresnel_offset, ?refract_scale_above, " + + "?refract_scale_below, ?blur_multiplier, ?big_wave_direction_x, ?big_wave_direction_y, ?little_wave_direction_x, " + + "?little_wave_direction_y, ?normal_map_texture, ?horizon_r, ?horizon_g, ?horizon_b, ?horizon_i, ?haze_horizon, " + + "?blue_density_r, ?blue_density_g, ?blue_density_b, ?blue_density_i, ?haze_density, ?density_multiplier, " + + "?distance_multiplier, ?max_altitude, ?sun_moon_color_r, ?sun_moon_color_g, ?sun_moon_color_b, " + + "?sun_moon_color_i, ?sun_moon_position, ?ambient_r, ?ambient_g, ?ambient_b, ?ambient_i, ?east_angle, " + + "?sun_glow_focus, ?sun_glow_size, ?scene_gamma, ?star_brightness, ?cloud_color_r, ?cloud_color_g, " + + "?cloud_color_b, ?cloud_color_i, ?cloud_x, ?cloud_y, ?cloud_density, ?cloud_coverage, ?cloud_scale, " + + "?cloud_detail_x, ?cloud_detail_y, ?cloud_detail_density, ?cloud_scroll_x, ?cloud_scroll_x_lock, " + + "?cloud_scroll_y, ?cloud_scroll_y_lock, ?draw_classic_clouds)" + ; cmd.Parameters.AddWithValue("region_id", wl.regionID); cmd.Parameters.AddWithValue("water_color_r", wl.waterColor.X); @@ -1084,6 +1116,7 @@ namespace OpenSim.Data.MySQL ExecuteNonQuery(cmd); } + dbcon.Close(); } } @@ -1099,6 +1132,7 @@ namespace OpenSim.Data.MySQL cmd.Parameters.AddWithValue("?regionID", regionID.ToString()); ExecuteNonQuery(cmd); } + dbcon.Close(); } } @@ -1117,14 +1151,19 @@ namespace OpenSim.Data.MySQL cmd.Parameters.AddWithValue("?region_id", regionUUID.ToString()); - IDataReader result = ExecuteReader(cmd); - if (!result.Read()) + using(IDataReader result = ExecuteReader(cmd)) { - return String.Empty; - } - else - { - return Convert.ToString(result["llsd_settings"]); + if(!result.Read()) + { + dbcon.Close(); + return String.Empty; + } + else + { + string ret = Convert.ToString(result["llsd_settings"]); + dbcon.Close(); + return ret; + } } } } @@ -1145,6 +1184,7 @@ namespace OpenSim.Data.MySQL ExecuteNonQuery(cmd); } + dbcon.Close(); } } @@ -1160,6 +1200,7 @@ namespace OpenSim.Data.MySQL cmd.Parameters.AddWithValue("?region_id", regionUUID.ToString()); ExecuteNonQuery(cmd); } + dbcon.Close(); } } #endregion @@ -1212,7 +1253,7 @@ namespace OpenSim.Data.MySQL FillRegionSettingsCommand(cmd, rs); ExecuteNonQuery(cmd); } - + dbcon.Close(); SaveSpawnPoints(rs); } } @@ -1259,6 +1300,7 @@ namespace OpenSim.Data.MySQL } } } + dbcon.Close(); } } @@ -1452,6 +1494,11 @@ namespace OpenSim.Data.MySQL prim.VehicleParams = vehicle; } + PhysicsInertiaData pdata = null; + if (row["PhysInertia"].ToString() != String.Empty) + pdata = PhysicsInertiaData.FromXml2(row["PhysInertia"].ToString()); + prim.PhysicsInertia = pdata; + return prim; } @@ -1810,6 +1857,11 @@ namespace OpenSim.Data.MySQL else cmd.Parameters.AddWithValue("KeyframeMotion", new Byte[0]); + if (prim.PhysicsInertia != null) + cmd.Parameters.AddWithValue("PhysInertia", prim.PhysicsInertia.ToXml2()); + else + cmd.Parameters.AddWithValue("PhysInertia", String.Empty); + if (prim.VehicleParams != null) cmd.Parameters.AddWithValue("Vehicle", prim.VehicleParams.ToXml2()); else @@ -2113,6 +2165,7 @@ namespace OpenSim.Data.MySQL ExecuteNonQuery(cmd); } } + dbcon.Close(); } } } @@ -2142,6 +2195,7 @@ namespace OpenSim.Data.MySQL } } } + dbcon.Close(); } } @@ -2177,6 +2231,7 @@ namespace OpenSim.Data.MySQL } } } + dbcon.Close(); } } } @@ -2211,6 +2266,7 @@ namespace OpenSim.Data.MySQL cmd.Parameters.Clear(); } } + dbcon.Close(); } } } @@ -2230,6 +2286,7 @@ namespace OpenSim.Data.MySQL cmd.ExecuteNonQuery(); } + dbcon.Close(); } } @@ -2247,6 +2304,7 @@ namespace OpenSim.Data.MySQL cmd.ExecuteNonQuery(); } + dbcon.Close(); } } @@ -2270,6 +2328,7 @@ namespace OpenSim.Data.MySQL } } } + dbcon.Close(); } return ret; diff --git a/OpenSim/Data/MySQL/MySQLUserProfilesData.cs b/OpenSim/Data/MySQL/MySQLUserProfilesData.cs index 8af2a3ef29..2669aca4d2 100644 --- a/OpenSim/Data/MySQL/MySQLUserProfilesData.cs +++ b/OpenSim/Data/MySQL/MySQLUserProfilesData.cs @@ -69,6 +69,7 @@ namespace OpenSim.Data.MySQL Migration m = new Migration(dbcon, Assembly, "UserProfiles"); m.Update(); + dbcon.Close(); } } #endregion Member Functions @@ -89,7 +90,7 @@ namespace OpenSim.Data.MySQL using (MySqlConnection dbcon = new MySqlConnection(ConnectionString)) { - string query = "SELECT classifieduuid, name FROM classifieds WHERE creatoruuid = ?Id"; + const string query = "SELECT classifieduuid, name FROM classifieds WHERE creatoruuid = ?Id"; dbcon.Open(); using (MySqlCommand cmd = new MySqlCommand(query, dbcon)) { @@ -111,8 +112,7 @@ namespace OpenSim.Data.MySQL } catch (Exception e) { - m_log.ErrorFormat("[PROFILES_DATA]" + - ": UserAccount exception {0}", e.Message); + m_log.ErrorFormat("[PROFILES_DATA] GetClassifiedRecords exception {0}", e.Message); } n.Add("classifieduuid", OSD.FromUUID(Id)); n.Add("name", OSD.FromString(Name)); @@ -121,58 +121,58 @@ namespace OpenSim.Data.MySQL } } } + dbcon.Close(); } return data; } public bool UpdateClassifiedRecord(UserClassifiedAdd ad, ref string result) { - string query = string.Empty; - - - query += "INSERT INTO classifieds ("; - query += "`classifieduuid`,"; - query += "`creatoruuid`,"; - query += "`creationdate`,"; - query += "`expirationdate`,"; - query += "`category`,"; - query += "`name`,"; - query += "`description`,"; - query += "`parceluuid`,"; - query += "`parentestate`,"; - query += "`snapshotuuid`,"; - query += "`simname`,"; - query += "`posglobal`,"; - query += "`parcelname`,"; - query += "`classifiedflags`,"; - query += "`priceforlisting`) "; - query += "VALUES ("; - query += "?ClassifiedId,"; - query += "?CreatorId,"; - query += "?CreatedDate,"; - query += "?ExpirationDate,"; - query += "?Category,"; - query += "?Name,"; - query += "?Description,"; - query += "?ParcelId,"; - query += "?ParentEstate,"; - query += "?SnapshotId,"; - query += "?SimName,"; - query += "?GlobalPos,"; - query += "?ParcelName,"; - query += "?Flags,"; - query += "?ListingPrice ) "; - query += "ON DUPLICATE KEY UPDATE "; - query += "category=?Category, "; - query += "expirationdate=?ExpirationDate, "; - query += "name=?Name, "; - query += "description=?Description, "; - query += "parentestate=?ParentEstate, "; - query += "posglobal=?GlobalPos, "; - query += "parcelname=?ParcelName, "; - query += "classifiedflags=?Flags, "; - query += "priceforlisting=?ListingPrice, "; - query += "snapshotuuid=?SnapshotId"; + const string query = + "INSERT INTO classifieds (" + + "`classifieduuid`," + + "`creatoruuid`," + + "`creationdate`," + + "`expirationdate`," + + "`category`," + + "`name`," + + "`description`," + + "`parceluuid`," + + "`parentestate`," + + "`snapshotuuid`," + + "`simname`," + + "`posglobal`," + + "`parcelname`," + + "`classifiedflags`," + + "`priceforlisting`) " + + "VALUES (" + + "?ClassifiedId," + + "?CreatorId," + + "?CreatedDate," + + "?ExpirationDate," + + "?Category," + + "?Name," + + "?Description," + + "?ParcelId," + + "?ParentEstate," + + "?SnapshotId," + + "?SimName," + + "?GlobalPos," + + "?ParcelName," + + "?Flags," + + "?ListingPrice ) " + + "ON DUPLICATE KEY UPDATE " + + "category=?Category, " + + "expirationdate=?ExpirationDate, " + + "name=?Name, " + + "description=?Description, " + + "parentestate=?ParentEstate, " + + "posglobal=?GlobalPos, " + + "parcelname=?ParcelName, " + + "classifiedflags=?Flags, " + + "priceforlisting=?ListingPrice, " + + "snapshotuuid=?SnapshotId" + ; if(string.IsNullOrEmpty(ad.ParcelName)) ad.ParcelName = "Unknown"; @@ -228,12 +228,12 @@ namespace OpenSim.Data.MySQL cmd.ExecuteNonQuery(); } + dbcon.Close(); } } catch (Exception e) { - m_log.ErrorFormat("[PROFILES_DATA]" + - ": ClassifiedesUpdate exception {0}", e.Message); + m_log.ErrorFormat("[PROFILES_DATA]: UpdateClassifiedRecord exception {0}", e.Message); result = e.Message; return false; } @@ -242,10 +242,7 @@ namespace OpenSim.Data.MySQL public bool DeleteClassifiedRecord(UUID recordId) { - string query = string.Empty; - - query += "DELETE FROM classifieds WHERE "; - query += "classifieduuid = ?recordId"; + const string query = "DELETE FROM classifieds WHERE classifieduuid = ?recordId"; try { @@ -258,12 +255,12 @@ namespace OpenSim.Data.MySQL cmd.Parameters.AddWithValue("?recordId", recordId.ToString()); cmd.ExecuteNonQuery(); } + dbcon.Close(); } } catch (Exception e) { - m_log.ErrorFormat("[PROFILES_DATA]" + - ": DeleteClassifiedRecord exception {0}", e.Message); + m_log.ErrorFormat("[PROFILES_DATA]: DeleteClassifiedRecord exception {0}", e.Message); return false; } return true; @@ -271,10 +268,8 @@ namespace OpenSim.Data.MySQL public bool GetClassifiedInfo(ref UserClassifiedAdd ad, ref string result) { - string query = string.Empty; - query += "SELECT * FROM classifieds WHERE "; - query += "classifieduuid = ?AdId"; + const string query = "SELECT * FROM classifieds WHERE classifieduuid = ?AdId"; try { @@ -312,8 +307,7 @@ namespace OpenSim.Data.MySQL } catch (Exception e) { - m_log.ErrorFormat("[PROFILES_DATA]" + - ": GetPickInfo exception {0}", e.Message); + m_log.ErrorFormat("[PROFILES_DATA]: GetClassifiedInfo exception {0}", e.Message); } return true; } @@ -322,10 +316,8 @@ namespace OpenSim.Data.MySQL #region Picks Queries public OSDArray GetAvatarPicks(UUID avatarId) { - string query = string.Empty; + const string query = "SELECT `pickuuid`,`name` FROM userpicks WHERE creatoruuid = ?Id"; - query += "SELECT `pickuuid`,`name` FROM userpicks WHERE "; - query += "creatoruuid = ?Id"; OSDArray data = new OSDArray(); try @@ -352,24 +344,20 @@ namespace OpenSim.Data.MySQL } } } + dbcon.Close(); } } catch (Exception e) { - m_log.ErrorFormat("[PROFILES_DATA]" + - ": GetAvatarPicks exception {0}", e.Message); + m_log.ErrorFormat("[PROFILES_DATA]: GetAvatarPicks exception {0}", e.Message); } return data; } public UserProfilePick GetPickInfo(UUID avatarId, UUID pickId) { - string query = string.Empty; UserProfilePick pick = new UserProfilePick(); - - query += "SELECT * FROM userpicks WHERE "; - query += "creatoruuid = ?CreatorId AND "; - query += "pickuuid = ?PickId"; + const string query = "SELECT * FROM userpicks WHERE creatoruuid = ?CreatorId AND pickuuid = ?PickId"; try { @@ -414,41 +402,40 @@ namespace OpenSim.Data.MySQL } catch (Exception e) { - m_log.ErrorFormat("[PROFILES_DATA]" + - ": GetPickInfo exception {0}", e.Message); + m_log.ErrorFormat("[PROFILES_DATA]: GetPickInfo exception {0}", e.Message); } return pick; } public bool UpdatePicksRecord(UserProfilePick pick) { - string query = string.Empty; - - query += "INSERT INTO userpicks VALUES ("; - query += "?PickId,"; - query += "?CreatorId,"; - query += "?TopPick,"; - query += "?ParcelId,"; - query += "?Name,"; - query += "?Desc,"; - query += "?SnapshotId,"; - query += "?User,"; - query += "?Original,"; - query += "?SimName,"; - query += "?GlobalPos,"; - query += "?SortOrder,"; - query += "?Enabled,"; - query += "?Gatekeeper)"; - query += "ON DUPLICATE KEY UPDATE "; - query += "parceluuid=?ParcelId,"; - query += "name=?Name,"; - query += "description=?Desc,"; - query += "user=?User,"; - query += "simname=?SimName,"; - query += "snapshotuuid=?SnapshotId,"; - query += "pickuuid=?PickId,"; - query += "posglobal=?GlobalPos,"; - query += "gatekeeper=?Gatekeeper"; + const string query = + "INSERT INTO userpicks VALUES (" + + "?PickId," + + "?CreatorId," + + "?TopPick," + + "?ParcelId," + + "?Name," + + "?Desc," + + "?SnapshotId," + + "?User," + + "?Original," + + "?SimName," + + "?GlobalPos," + + "?SortOrder," + + "?Enabled," + + "?Gatekeeper)" + + "ON DUPLICATE KEY UPDATE " + + "parceluuid=?ParcelId," + + "name=?Name," + + "description=?Desc," + + "user=?User," + + "simname=?SimName," + + "snapshotuuid=?SnapshotId," + + "pickuuid=?PickId," + + "posglobal=?GlobalPos," + + "gatekeeper=?Gatekeeper" + ; try { @@ -474,12 +461,12 @@ namespace OpenSim.Data.MySQL cmd.ExecuteNonQuery(); } + dbcon.Close(); } } catch (Exception e) { - m_log.ErrorFormat("[PROFILES_DATA]" + - ": UpdateAvatarNotes exception {0}", e.Message); + m_log.ErrorFormat("[PROFILES_DATA]: UpdatePicksRecord exception {0}", e.Message); return false; } return true; @@ -487,10 +474,7 @@ namespace OpenSim.Data.MySQL public bool DeletePicksRecord(UUID pickId) { - string query = string.Empty; - - query += "DELETE FROM userpicks WHERE "; - query += "pickuuid = ?PickId"; + string query = "DELETE FROM userpicks WHERE pickuuid = ?PickId"; try { @@ -504,12 +488,12 @@ namespace OpenSim.Data.MySQL cmd.ExecuteNonQuery(); } + dbcon.Close(); } } catch (Exception e) { - m_log.ErrorFormat("[PROFILES_DATA]" + - ": DeleteUserPickRecord exception {0}", e.Message); + m_log.ErrorFormat("[PROFILES_DATA]: DeletePicksRecord exception {0}", e.Message); return false; } return true; @@ -519,11 +503,7 @@ namespace OpenSim.Data.MySQL #region Avatar Notes Queries public bool GetAvatarNotes(ref UserProfileNotes notes) { // WIP - string query = string.Empty; - - query += "SELECT `notes` FROM usernotes WHERE "; - query += "useruuid = ?Id AND "; - query += "targetuuid = ?TargetId"; + const string query = "SELECT `notes` FROM usernotes WHERE useruuid = ?Id AND targetuuid = ?TargetId"; try { @@ -548,38 +528,37 @@ namespace OpenSim.Data.MySQL } } } + dbcon.Close(); } } catch (Exception e) { - m_log.ErrorFormat("[PROFILES_DATA]" + - ": GetAvatarNotes exception {0}", e.Message); + m_log.ErrorFormat("[PROFILES_DATA]: GetAvatarNotes exception {0}", e.Message); } return true; } public bool UpdateAvatarNotes(ref UserProfileNotes note, ref string result) { - string query = string.Empty; + string query; bool remove; if(string.IsNullOrEmpty(note.Notes)) { remove = true; - query += "DELETE FROM usernotes WHERE "; - query += "useruuid=?UserId AND "; - query += "targetuuid=?TargetId"; + query = "DELETE FROM usernotes WHERE useruuid=?UserId AND targetuuid=?TargetId"; } else { remove = false; - query += "INSERT INTO usernotes VALUES ( "; - query += "?UserId,"; - query += "?TargetId,"; - query += "?Notes )"; - query += "ON DUPLICATE KEY "; - query += "UPDATE "; - query += "notes=?Notes"; + query = "INSERT INTO usernotes VALUES (" + + "?UserId," + + "?TargetId," + + "?Notes )" + + "ON DUPLICATE KEY " + + "UPDATE " + + "notes=?Notes" + ; } try @@ -596,12 +575,12 @@ namespace OpenSim.Data.MySQL cmd.ExecuteNonQuery(); } + dbcon.Close(); } } catch (Exception e) { - m_log.ErrorFormat("[PROFILES_DATA]" + - ": UpdateAvatarNotes exception {0}", e.Message); + m_log.ErrorFormat("[PROFILES_DATA]: UpdateAvatarNotes exception {0}", e.Message); return false; } return true; @@ -612,10 +591,7 @@ namespace OpenSim.Data.MySQL #region Avatar Properties public bool GetAvatarProperties(ref UserProfileProperties props, ref string result) { - string query = string.Empty; - - query += "SELECT * FROM userprofile WHERE "; - query += "useruuid = ?Id"; + string query = "SELECT * FROM userprofile WHERE useruuid = ?Id"; try { @@ -664,35 +640,36 @@ namespace OpenSim.Data.MySQL props.PublishProfile = false; props.PublishMature = false; - query = "INSERT INTO userprofile ("; - query += "useruuid, "; - query += "profilePartner, "; - query += "profileAllowPublish, "; - query += "profileMaturePublish, "; - query += "profileURL, "; - query += "profileWantToMask, "; - query += "profileWantToText, "; - query += "profileSkillsMask, "; - query += "profileSkillsText, "; - query += "profileLanguages, "; - query += "profileImage, "; - query += "profileAboutText, "; - query += "profileFirstImage, "; - query += "profileFirstText) VALUES ("; - query += "?userId, "; - query += "?profilePartner, "; - query += "?profileAllowPublish, "; - query += "?profileMaturePublish, "; - query += "?profileURL, "; - query += "?profileWantToMask, "; - query += "?profileWantToText, "; - query += "?profileSkillsMask, "; - query += "?profileSkillsText, "; - query += "?profileLanguages, "; - query += "?profileImage, "; - query += "?profileAboutText, "; - query += "?profileFirstImage, "; - query += "?profileFirstText)"; + query = "INSERT INTO userprofile (" + + "useruuid, " + + "profilePartner, " + + "profileAllowPublish, " + + "profileMaturePublish, " + + "profileURL, " + + "profileWantToMask, " + + "profileWantToText, " + + "profileSkillsMask, " + + "profileSkillsText, " + + "profileLanguages, " + + "profileImage, " + + "profileAboutText, " + + "profileFirstImage, " + + "profileFirstText) VALUES (" + + "?userId, " + + "?profilePartner, " + + "?profileAllowPublish, " + + "?profileMaturePublish, " + + "?profileURL, " + + "?profileWantToMask, " + + "?profileWantToText, " + + "?profileSkillsMask, " + + "?profileSkillsText, " + + "?profileLanguages, " + + "?profileImage, " + + "?profileAboutText, " + + "?profileFirstImage, " + + "?profileFirstText)" + ; dbcon.Close(); dbcon.Open(); @@ -719,12 +696,12 @@ namespace OpenSim.Data.MySQL } } } + dbcon.Close(); } } catch (Exception e) { - m_log.ErrorFormat("[PROFILES_DATA]" + - ": Requst properties exception {0}", e.Message); + m_log.ErrorFormat("[PROFILES_DATA]: GetAvatarProperties exception {0}", e.Message); result = e.Message; return false; } @@ -733,15 +710,10 @@ namespace OpenSim.Data.MySQL public bool UpdateAvatarProperties(ref UserProfileProperties props, ref string result) { - string query = string.Empty; - - query += "UPDATE userprofile SET "; - query += "profileURL=?profileURL, "; - query += "profileImage=?image, "; - query += "profileAboutText=?abouttext,"; - query += "profileFirstImage=?firstlifeimage,"; - query += "profileFirstText=?firstlifetext "; - query += "WHERE useruuid=?uuid"; + const string query = "UPDATE userprofile SET profileURL=?profileURL," + + "profileImage=?image, profileAboutText=?abouttext," + + "profileFirstImage=?firstlifeimage, profileFirstText=?firstlifetext " + + "WHERE useruuid=?uuid"; try { @@ -759,12 +731,12 @@ namespace OpenSim.Data.MySQL cmd.ExecuteNonQuery(); } + dbcon.Close(); } } catch (Exception e) { - m_log.ErrorFormat("[PROFILES_DATA]" + - ": AgentPropertiesUpdate exception {0}", e.Message); + m_log.ErrorFormat("[PROFILES_DATA]: UpdateAvatarProperties exception {0}", e.Message); return false; } @@ -775,15 +747,13 @@ namespace OpenSim.Data.MySQL #region Avatar Interests public bool UpdateAvatarInterests(UserProfileProperties up, ref string result) { - string query = string.Empty; - - query += "UPDATE userprofile SET "; - query += "profileWantToMask=?WantMask, "; - query += "profileWantToText=?WantText,"; - query += "profileSkillsMask=?SkillsMask,"; - query += "profileSkillsText=?SkillsText, "; - query += "profileLanguages=?Languages "; - query += "WHERE useruuid=?uuid"; + const string query = "UPDATE userprofile SET " + + "profileWantToMask=?WantMask, " + + "profileWantToText=?WantText," + + "profileSkillsMask=?SkillsMask," + + "profileSkillsText=?SkillsText, " + + "profileLanguages=?Languages " + + "WHERE useruuid=?uuid"; try { @@ -805,8 +775,7 @@ namespace OpenSim.Data.MySQL } catch (Exception e) { - m_log.ErrorFormat("[PROFILES_DATA]" + - ": AgentInterestsUpdate exception {0}", e.Message); + m_log.ErrorFormat("[PROFILES_DATA]: UpdateAvatarInterests exception {0}", e.Message); result = e.Message; return false; } @@ -817,18 +786,17 @@ namespace OpenSim.Data.MySQL public OSDArray GetUserImageAssets(UUID avatarId) { OSDArray data = new OSDArray(); - string query = "SELECT `snapshotuuid` FROM {0} WHERE `creatoruuid` = ?Id"; + const string queryA = "SELECT `snapshotuuid` FROM {0} WHERE `creatoruuid` = ?Id"; // Get classified image assets - try { using (MySqlConnection dbcon = new MySqlConnection(ConnectionString)) { dbcon.Open(); - using (MySqlCommand cmd = new MySqlCommand(string.Format (query,"`classifieds`"), dbcon)) + using (MySqlCommand cmd = new MySqlCommand(string.Format (queryA,"`classifieds`"), dbcon)) { cmd.Parameters.AddWithValue("?Id", avatarId.ToString()); @@ -847,7 +815,7 @@ namespace OpenSim.Data.MySQL dbcon.Close(); dbcon.Open(); - using (MySqlCommand cmd = new MySqlCommand(string.Format (query,"`userpicks`"), dbcon)) + using (MySqlCommand cmd = new MySqlCommand(string.Format (queryA,"`userpicks`"), dbcon)) { cmd.Parameters.AddWithValue("?Id", avatarId.ToString()); @@ -866,9 +834,9 @@ namespace OpenSim.Data.MySQL dbcon.Close(); dbcon.Open(); - query = "SELECT `profileImage`, `profileFirstImage` FROM `userprofile` WHERE `useruuid` = ?Id"; + const string queryB = "SELECT `profileImage`, `profileFirstImage` FROM `userprofile` WHERE `useruuid` = ?Id"; - using (MySqlCommand cmd = new MySqlCommand(string.Format (query,"`userpicks`"), dbcon)) + using (MySqlCommand cmd = new MySqlCommand(queryB, dbcon)) { cmd.Parameters.AddWithValue("?Id", avatarId.ToString()); @@ -884,12 +852,12 @@ namespace OpenSim.Data.MySQL } } } + dbcon.Close(); } } catch (Exception e) { - m_log.ErrorFormat("[PROFILES_DATA]" + - ": GetAvatarNotes exception {0}", e.Message); + m_log.ErrorFormat("[PROFILES_DATA]: GetUserImageAssets exception {0}", e.Message); } return data; } @@ -897,11 +865,7 @@ namespace OpenSim.Data.MySQL #region User Preferences public bool GetUserPreferences(ref UserPreferences pref, ref string result) { - string query = string.Empty; - - query += "SELECT imviaemail,visible,email FROM "; - query += "usersettings WHERE "; - query += "useruuid = ?Id"; + const string query = "SELECT imviaemail,visible,email FROM usersettings WHERE useruuid = ?Id"; try { @@ -925,10 +889,9 @@ namespace OpenSim.Data.MySQL dbcon.Close(); dbcon.Open(); - query = "INSERT INTO usersettings VALUES "; - query += "(?uuid,'false','false', ?Email)"; + const string queryB = "INSERT INTO usersettings VALUES (?uuid,'false','false', ?Email)"; - using (MySqlCommand put = new MySqlCommand(query, dbcon)) + using (MySqlCommand put = new MySqlCommand(queryB, dbcon)) { put.Parameters.AddWithValue("?Email", pref.EMail); @@ -939,12 +902,12 @@ namespace OpenSim.Data.MySQL } } } + dbcon.Close(); } } catch (Exception e) { - m_log.ErrorFormat("[PROFILES_DATA]" + - ": Get preferences exception {0}", e.Message); + m_log.ErrorFormat("[PROFILES_DATA]: GetUserPreferences exception {0}", e.Message); result = e.Message; return false; } @@ -953,13 +916,9 @@ namespace OpenSim.Data.MySQL public bool UpdateUserPreferences(ref UserPreferences pref, ref string result) { - string query = string.Empty; - - query += "UPDATE usersettings SET "; - query += "imviaemail=?ImViaEmail, "; - query += "visible=?Visible, "; - query += "email=?EMail "; - query += "WHERE useruuid=?uuid"; + const string query = "UPDATE usersettings SET imviaemail=?ImViaEmail," + + "visible=?Visible, email=?EMail " + + "WHERE useruuid=?uuid"; try { @@ -975,12 +934,12 @@ namespace OpenSim.Data.MySQL cmd.ExecuteNonQuery(); } + dbcon.Close(); } } catch (Exception e) { - m_log.ErrorFormat("[PROFILES_DATA]" + - ": UserPreferencesUpdate exception {0} {1}", e.Message, e.InnerException); + m_log.ErrorFormat("[PROFILES_DATA]: UpdateUserPreferences exception {0} {1}", e.Message, e.InnerException); result = e.Message; return false; } @@ -991,11 +950,7 @@ namespace OpenSim.Data.MySQL #region Integration public bool GetUserAppData(ref UserAppData props, ref string result) { - string query = string.Empty; - - query += "SELECT * FROM `userdata` WHERE "; - query += "UserId = ?Id AND "; - query += "TagId = ?TagId"; + const string query = "SELECT * FROM `userdata` WHERE UserId = ?Id AND TagId = ?TagId"; try { @@ -1017,13 +972,8 @@ namespace OpenSim.Data.MySQL } else { - query += "INSERT INTO userdata VALUES ( "; - query += "?UserId,"; - query += "?TagId,"; - query += "?DataKey,"; - query += "?DataVal) "; - - using (MySqlCommand put = new MySqlCommand(query, dbcon)) + const string queryB = "INSERT INTO userdata VALUES (?UserId, ?TagId, ?DataKey, ?DataVal)"; + using (MySqlCommand put = new MySqlCommand(queryB, dbcon)) { put.Parameters.AddWithValue("?UserId", props.UserId.ToString()); put.Parameters.AddWithValue("?TagId", props.TagId.ToString()); @@ -1035,12 +985,12 @@ namespace OpenSim.Data.MySQL } } } + dbcon.Close(); } } catch (Exception e) { - m_log.ErrorFormat("[PROFILES_DATA]" + - ": Requst application data exception {0}", e.Message); + m_log.ErrorFormat("[PROFILES_DATA]: GetUserAppData exception {0}", e.Message); result = e.Message; return false; } @@ -1049,14 +999,7 @@ namespace OpenSim.Data.MySQL public bool SetUserAppData(UserAppData props, ref string result) { - string query = string.Empty; - - query += "UPDATE userdata SET "; - query += "TagId = ?TagId, "; - query += "DataKey = ?DataKey, "; - query += "DataVal = ?DataVal WHERE "; - query += "UserId = ?UserId AND "; - query += "TagId = ?TagId"; + const string query = "UPDATE userdata SET TagId = ?TagId, DataKey = ?DataKey, DataVal = ?DataVal WHERE UserId = ?UserId AND TagId = ?TagId"; try { @@ -1072,12 +1015,12 @@ namespace OpenSim.Data.MySQL cmd.ExecuteNonQuery(); } + dbcon.Close(); } } catch (Exception e) { - m_log.ErrorFormat("[PROFILES_DATA]" + - ": SetUserData exception {0}", e.Message); + m_log.ErrorFormat("[PROFILES_DATA]: SetUserAppData exception {0}", e.Message); return false; } return true; diff --git a/OpenSim/Data/MySQL/MySQLXAssetData.cs b/OpenSim/Data/MySQL/MySQLXAssetData.cs index 2c6acdef32..9f9c9cf4fa 100644 --- a/OpenSim/Data/MySQL/MySQLXAssetData.cs +++ b/OpenSim/Data/MySQL/MySQLXAssetData.cs @@ -97,6 +97,7 @@ namespace OpenSim.Data.MySQL dbcon.Open(); Migration m = new Migration(dbcon, Assembly, "XAssetStore"); m.Update(); + dbcon.Close(); } } @@ -130,6 +131,7 @@ namespace OpenSim.Data.MySQL // m_log.DebugFormat("[MYSQL XASSET DATA]: Looking for asset {0}", assetID); AssetBase asset = null; + int accessTime = 0; using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { @@ -140,7 +142,6 @@ namespace OpenSim.Data.MySQL dbcon)) { cmd.Parameters.AddWithValue("?ID", assetID.ToString()); - try { using (MySqlDataReader dbReader = cmd.ExecuteReader(CommandBehavior.SingleRow)) @@ -159,23 +160,7 @@ namespace OpenSim.Data.MySQL asset.Temporary = Convert.ToBoolean(dbReader["Temporary"]); asset.Flags = (AssetFlags)Convert.ToInt32(dbReader["AssetFlags"]); - - if (m_enableCompression) - { - using (GZipStream decompressionStream = new GZipStream(new MemoryStream(asset.Data), CompressionMode.Decompress)) - { - MemoryStream outputStream = new MemoryStream(); - WebUtil.CopyStream(decompressionStream, outputStream, int.MaxValue); -// int compressedLength = asset.Data.Length; - asset.Data = outputStream.ToArray(); - -// m_log.DebugFormat( -// "[XASSET DB]: Decompressed {0} {1} to {2} bytes from {3}", -// asset.ID, asset.Name, asset.Data.Length, compressedLength); - } - } - - UpdateAccessTime(asset.Metadata, (int)dbReader["AccessTime"]); + accessTime = (int)dbReader["AccessTime"]; } } } @@ -184,9 +169,38 @@ namespace OpenSim.Data.MySQL m_log.Error(string.Format("[MYSQL XASSET DATA]: Failure fetching asset {0}", assetID), e); } } + dbcon.Close(); } - return asset; + if(asset == null) + return asset; + + if(accessTime > 0) + { + try + { + UpdateAccessTime(asset.Metadata, accessTime); + } + catch { } + } + + if (m_enableCompression && asset.Data != null) + { + using(MemoryStream ms = new MemoryStream(asset.Data)) + using(GZipStream decompressionStream = new GZipStream(ms, CompressionMode.Decompress)) + { + using(MemoryStream outputStream = new MemoryStream()) + { + decompressionStream.CopyTo(outputStream, int.MaxValue); +// int compressedLength = asset.Data.Length; + asset.Data = outputStream.ToArray(); + } +// m_log.DebugFormat( +// "[XASSET DB]: Decompressed {0} {1} to {2} bytes from {3}", +// asset.ID, asset.Name, asset.Data.Length, compressedLength); + } + } + return asset; } /// @@ -303,6 +317,7 @@ namespace OpenSim.Data.MySQL transaction.Commit(); } + dbcon.Close(); } } @@ -344,6 +359,7 @@ namespace OpenSim.Data.MySQL "[XASSET MYSQL DB]: Failure updating access_time for asset {0} with name {1}", assetMetadata.ID, assetMetadata.Name); } + dbcon.Close(); } } @@ -474,6 +490,7 @@ namespace OpenSim.Data.MySQL m_log.Error("[XASSETS DB]: MySql failure fetching asset set" + Environment.NewLine + e.ToString()); } } + dbcon.Close(); } return retList; @@ -492,9 +509,9 @@ namespace OpenSim.Data.MySQL cmd.Parameters.AddWithValue("?ID", id); cmd.ExecuteNonQuery(); } - // TODO: How do we deal with data from deleted assets? Probably not easily reapable unless we // keep a reference count (?) + dbcon.Close(); } return true; diff --git a/OpenSim/Data/MySQL/MySQLXInventoryData.cs b/OpenSim/Data/MySQL/MySQLXInventoryData.cs index 4e41fec9cd..501999425d 100644 --- a/OpenSim/Data/MySQL/MySQLXInventoryData.cs +++ b/OpenSim/Data/MySQL/MySQLXInventoryData.cs @@ -328,7 +328,6 @@ namespace OpenSim.Data.MySQL { return false; } - cmd.Dispose(); } dbcon.Close(); diff --git a/OpenSim/Data/MySQL/Resources/MuteListStore.migrations b/OpenSim/Data/MySQL/Resources/MuteListStore.migrations new file mode 100644 index 0000000000..5bde63edd8 --- /dev/null +++ b/OpenSim/Data/MySQL/Resources/MuteListStore.migrations @@ -0,0 +1,16 @@ +:VERSION 1 + +BEGIN; + +CREATE TABLE `MuteList` ( + `AgentID` char(36) NOT NULL, + `MuteID` char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', + `MuteName` varchar(64) NOT NULL DEFAULT '', + `MuteType` int(11) NOT NULL DEFAULT '1', + `MuteFlags` int(11) NOT NULL DEFAULT '0', + `Stamp` int(11) NOT NULL, + UNIQUE KEY `AgentID_2` (`AgentID`,`MuteID`,`MuteName`), + KEY `AgentID` (`AgentID`) +); + +COMMIT; diff --git a/OpenSim/Data/MySQL/Resources/RegionStore.migrations b/OpenSim/Data/MySQL/Resources/RegionStore.migrations index c63cc95d22..0577392184 100644 --- a/OpenSim/Data/MySQL/Resources/RegionStore.migrations +++ b/OpenSim/Data/MySQL/Resources/RegionStore.migrations @@ -461,3 +461,9 @@ BEGIN; ALTER TABLE `prims` ADD COLUMN `RezzerID` char(36) DEFAULT NULL; COMMIT; + +:VERSION 57 #----- Add physics inertia data + +BEGIN; +ALTER TABLE `prims` ADD COLUMN `PhysInertia` TEXT default NULL; +COMMIT; diff --git a/OpenSim/Data/MySQL/Resources/os_groups_Store.migrations b/OpenSim/Data/MySQL/Resources/os_groups_Store.migrations index 1a499000fb..6ec89144b5 100644 --- a/OpenSim/Data/MySQL/Resources/os_groups_Store.migrations +++ b/OpenSim/Data/MySQL/Resources/os_groups_Store.migrations @@ -18,7 +18,7 @@ CREATE TABLE `os_groups_groups` ( PRIMARY KEY (`GroupID`), UNIQUE KEY `Name` (`Name`), FULLTEXT KEY `Name_2` (`Name`) -) ENGINE=InnoDB; +) ENGINE=MyISAM; CREATE TABLE `os_groups_membership` ( diff --git a/OpenSim/Data/PGSQL/PGSQLFSAssetData.cs b/OpenSim/Data/PGSQL/PGSQLFSAssetData.cs new file mode 100644 index 0000000000..59b857c61f --- /dev/null +++ b/OpenSim/Data/PGSQL/PGSQLFSAssetData.cs @@ -0,0 +1,316 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Reflection; +using System.Collections.Generic; +using System.Data; +using OpenSim.Framework; +using OpenSim.Framework.Console; +using log4net; +using OpenMetaverse; +using Npgsql; +using NpgsqlTypes; + +namespace OpenSim.Data.PGSQL +{ + public class PGSQLFSAssetData : IFSAssetDataPlugin + { + private const string _migrationStore = "FSAssetStore"; + private static string m_Table = "fsassets"; + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private long m_ticksToEpoch; + + private PGSQLManager m_database; + private string m_connectionString; + + public PGSQLFSAssetData() + { + } + + public void Initialise(string connect, string realm, int UpdateAccessTime) + { + DaysBetweenAccessTimeUpdates = UpdateAccessTime; + + m_ticksToEpoch = new System.DateTime(1970, 1, 1).Ticks; + + m_connectionString = connect; + m_database = new PGSQLManager(m_connectionString); + + //New migration to check for DB changes + m_database.CheckMigration(_migrationStore); + } + + public void Initialise() + { + throw new NotImplementedException(); + } + + /// + /// Number of days that must pass before we update the access time on an asset when it has been fetched + /// Config option to change this is "DaysBetweenAccessTimeUpdates" + /// + private int DaysBetweenAccessTimeUpdates = 0; + + protected virtual Assembly Assembly + { + get { return GetType().Assembly; } + } + + #region IPlugin Members + + public string Version { get { return "1.0.0.0"; } } + + public void Dispose() { } + + public string Name + { + get { return "PGSQL FSAsset storage engine"; } + } + + #endregion + + #region IFSAssetDataPlugin Members + + public AssetMetadata Get(string id, out string hash) + { + hash = String.Empty; + AssetMetadata meta = null; + UUID uuid = new UUID(id); + + string query = String.Format("select \"id\", \"type\", \"hash\", \"create_time\", \"access_time\", \"asset_flags\" from {0} where \"id\" = :id", m_Table); + using (NpgsqlConnection dbcon = new NpgsqlConnection(m_connectionString)) + using (NpgsqlCommand cmd = new NpgsqlCommand(query, dbcon)) + { + dbcon.Open(); + cmd.Parameters.Add(m_database.CreateParameter("id", uuid)); + using (NpgsqlDataReader reader = cmd.ExecuteReader(CommandBehavior.Default)) + { + if (reader.Read()) + { + meta = new AssetMetadata(); + hash = reader["hash"].ToString(); + meta.ID = id; + meta.FullID = uuid; + meta.Name = String.Empty; + meta.Description = String.Empty; + meta.Type = (sbyte)Convert.ToInt32(reader["type"]); + meta.ContentType = SLUtil.SLAssetTypeToContentType(meta.Type); + meta.CreationDate = Util.ToDateTime(Convert.ToInt32(reader["create_time"])); + meta.Flags = (AssetFlags)Convert.ToInt32(reader["asset_flags"]); + int atime = Convert.ToInt32(reader["access_time"]); + UpdateAccessTime(atime, uuid); + } + } + } + + return meta; + } + + private void UpdateAccessTime(int AccessTime, UUID id) + { + // Reduce DB work by only updating access time if asset hasn't recently been accessed + // 0 By Default, Config option is "DaysBetweenAccessTimeUpdates" + if (DaysBetweenAccessTimeUpdates > 0 && (DateTime.UtcNow - Utils.UnixTimeToDateTime(AccessTime)).TotalDays < DaysBetweenAccessTimeUpdates) + return; + + string query = String.Format("UPDATE {0} SET \"access_time\" = :access_time WHERE \"id\" = :id", m_Table); + using (NpgsqlConnection dbcon = new NpgsqlConnection(m_connectionString)) + using (NpgsqlCommand cmd = new NpgsqlCommand(query, dbcon)) + { + dbcon.Open(); + int now = (int)((System.DateTime.Now.Ticks - m_ticksToEpoch) / 10000000); + cmd.Parameters.Add(m_database.CreateParameter("id", id)); + cmd.Parameters.Add(m_database.CreateParameter("access_time", now)); + cmd.ExecuteNonQuery(); + } + } + + public bool Store(AssetMetadata meta, string hash) + { + try + { + bool found = false; + string oldhash; + AssetMetadata existingAsset = Get(meta.ID, out oldhash); + + string query = String.Format("UPDATE {0} SET \"access_time\" = :access_time WHERE \"id\" = :id", m_Table); + if (existingAsset == null) + { + query = String.Format("insert into {0} (\"id\", \"type\", \"hash\", \"asset_flags\", \"create_time\", \"access_time\") values ( :id, :type, :hash, :asset_flags, :create_time, :access_time)", m_Table); + found = true; + } + + using (NpgsqlConnection dbcon = new NpgsqlConnection(m_connectionString)) + using (NpgsqlCommand cmd = new NpgsqlCommand(query, dbcon)) + { + dbcon.Open(); + int now = (int)((System.DateTime.Now.Ticks - m_ticksToEpoch) / 10000000); + cmd.Parameters.Add(m_database.CreateParameter("id", meta.FullID)); + cmd.Parameters.Add(m_database.CreateParameter("type", meta.Type)); + cmd.Parameters.Add(m_database.CreateParameter("hash", hash)); + cmd.Parameters.Add(m_database.CreateParameter("asset_flags", Convert.ToInt32(meta.Flags))); + cmd.Parameters.Add(m_database.CreateParameter("create_time", now)); + cmd.Parameters.Add(m_database.CreateParameter("access_time", now)); + cmd.ExecuteNonQuery(); + } + return found; + } + catch(Exception e) + { + m_log.Error("[PGSQL FSASSETS] Failed to store asset with ID " + meta.ID); + m_log.Error(e.ToString()); + return false; + } + } + + /// + /// Check if the assets exist in the database. + /// + /// The asset UUID's + /// For each asset: true if it exists, false otherwise + public bool[] AssetsExist(UUID[] uuids) + { + if (uuids.Length == 0) + return new bool[0]; + + HashSet exists = new HashSet(); + + string ids = "'" + string.Join("','", uuids) + "'"; + string query = string.Format("select \"id\" from {1} where id in ({0})", ids, m_Table); + using (NpgsqlConnection dbcon = new NpgsqlConnection(m_connectionString)) + using (NpgsqlCommand cmd = new NpgsqlCommand(query, dbcon)) + { + dbcon.Open(); + using (NpgsqlDataReader reader = cmd.ExecuteReader(CommandBehavior.Default)) + { + while (reader.Read()) + { + UUID id = DBGuid.FromDB(reader["id"]);; + exists.Add(id); + } + } + } + + bool[] results = new bool[uuids.Length]; + for (int i = 0; i < uuids.Length; i++) + results[i] = exists.Contains(uuids[i]); + return results; + } + + public int Count() + { + int count = 0; + string query = String.Format("select count(*) as count from {0}", m_Table); + using (NpgsqlConnection dbcon = new NpgsqlConnection(m_connectionString)) + using (NpgsqlCommand cmd = new NpgsqlCommand(query, dbcon)) + { + dbcon.Open(); + IDataReader reader = cmd.ExecuteReader(); + reader.Read(); + count = Convert.ToInt32(reader["count"]); + reader.Close(); + } + + return count; + } + + public bool Delete(string id) + { + string query = String.Format("delete from {0} where \"id\" = :id", m_Table); + using (NpgsqlConnection dbcon = new NpgsqlConnection(m_connectionString)) + using (NpgsqlCommand cmd = new NpgsqlCommand(query, dbcon)) + { + dbcon.Open(); + cmd.Parameters.Add(m_database.CreateParameter("id", new UUID(id))); + cmd.ExecuteNonQuery(); + } + + return true; + } + + public void Import(string conn, string table, int start, int count, bool force, FSStoreDelegate store) + { + int imported = 0; + string limit = String.Empty; + if(count != -1) + { + limit = String.Format(" limit {0} offset {1}", start, count); + } + string query = String.Format("select * from {0}{1}", table, limit); + try + { + using (NpgsqlConnection remote = new NpgsqlConnection(conn)) + using (NpgsqlCommand cmd = new NpgsqlCommand(query, remote)) + { + remote.Open(); + MainConsole.Instance.Output("Querying database"); + MainConsole.Instance.Output("Reading data"); + using (NpgsqlDataReader reader = cmd.ExecuteReader(CommandBehavior.Default)) + { + while (reader.Read()) + { + if ((imported % 100) == 0) + { + MainConsole.Instance.Output(String.Format("{0} assets imported so far", imported)); + } + + AssetBase asset = new AssetBase(); + AssetMetadata meta = new AssetMetadata(); + + meta.ID = reader["id"].ToString(); + meta.FullID = new UUID(meta.ID); + + meta.Name = String.Empty; + meta.Description = String.Empty; + meta.Type = (sbyte)Convert.ToInt32(reader["assetType"]); + meta.ContentType = SLUtil.SLAssetTypeToContentType(meta.Type); + meta.CreationDate = Util.ToDateTime(Convert.ToInt32(reader["create_time"])); + + asset.Metadata = meta; + asset.Data = (byte[])reader["data"]; + + store(asset, force); + + imported++; + } + } + } + } + catch (Exception e) + { + m_log.ErrorFormat("[PGSQL FSASSETS]: Error importing assets: {0}", + e.Message.ToString()); + return; + } + + MainConsole.Instance.Output(String.Format("Import done, {0} assets imported", imported)); + } + + #endregion + } +} diff --git a/OpenSim/Data/PGSQL/PGSQLGroupsData.cs b/OpenSim/Data/PGSQL/PGSQLGroupsData.cs index 6ef576bccc..f398256863 100755 --- a/OpenSim/Data/PGSQL/PGSQLGroupsData.cs +++ b/OpenSim/Data/PGSQL/PGSQLGroupsData.cs @@ -435,7 +435,7 @@ namespace OpenSim.Data.PGSQL using (NpgsqlCommand cmd = new NpgsqlCommand()) { - cmd.CommandText = String.Format("delete from {0} where \"TMStamp\" < CURRENT_DATE - INTERVAL '2 week'", m_Realm); + cmd.CommandText = String.Format("delete from {0} where \"TMStamp\"::abstime::timestamp < now() - INTERVAL '2 week'", m_Realm); ExecuteNonQuery(cmd); } @@ -461,7 +461,7 @@ namespace OpenSim.Data.PGSQL using (NpgsqlCommand cmd = new NpgsqlCommand()) { - cmd.CommandText = String.Format("delete from {0} where \"TMStamp\" < CURRENT_DATE - INTERVAL '2 week'", m_Realm); + cmd.CommandText = String.Format("delete from {0} where \"TMStamp\"::abstime::timestamp < now() - INTERVAL '2 week'", m_Realm); ExecuteNonQuery(cmd); } diff --git a/OpenSim/Data/PGSQL/PGSQLSimulationData.cs b/OpenSim/Data/PGSQL/PGSQLSimulationData.cs index 33d12bd71e..f4af40ba88 100755 --- a/OpenSim/Data/PGSQL/PGSQLSimulationData.cs +++ b/OpenSim/Data/PGSQL/PGSQLSimulationData.cs @@ -350,10 +350,11 @@ namespace OpenSim.Data.PGSQL ""CameraEyeOffsetY"" = :CameraEyeOffsetY, ""CameraEyeOffsetZ"" = :CameraEyeOffsetZ, ""CameraAtOffsetX"" = :CameraAtOffsetX, ""CameraAtOffsetY"" = :CameraAtOffsetY, ""CameraAtOffsetZ"" = :CameraAtOffsetZ, ""ForceMouselook"" = :ForceMouselook, ""ScriptAccessPin"" = :ScriptAccessPin, ""AllowedDrop"" = :AllowedDrop, ""DieAtEdge"" = :DieAtEdge, ""SalePrice"" = :SalePrice, - ""SaleType"" = :SaleType, ""ColorR"" = :ColorR, ""ColorG"" = :ColorG, ""ColorB"" = :ColorB, ""ColorA"" = :ColorA, ""ParticleSystem"" = :ParticleSystem, + ""PhysicsShapeType"" = :PhysicsShapeType, ""Density"" = :Density, ""GravityModifier"" = :GravityModifier, ""Friction"" = :Friction, ""Restitution"" = :Restitution, + ""PassCollisions"" = :PassCollisions, ""RotationAxisLocks"" = :RotationAxisLocks, ""RezzerID"" = :RezzerID, ""ClickAction"" = :ClickAction, ""Material"" = :Material, ""CollisionSound"" = :CollisionSound, ""CollisionSoundVolume"" = :CollisionSoundVolume, ""PassTouches"" = :PassTouches, ""LinkNumber"" = :LinkNumber, ""MediaURL"" = :MediaURL, ""DynAttrs"" = :DynAttrs, - ""PhysicsShapeType"" = :PhysicsShapeType, ""Density"" = :Density, ""GravityModifier"" = :GravityModifier, ""Friction"" = :Friction, ""Restitution"" = :Restitution + ""PhysInertia"" = :PhysInertia WHERE ""UUID"" = :UUID ; INSERT INTO @@ -367,7 +368,7 @@ namespace OpenSim.Data.PGSQL ""OmegaY"", ""OmegaZ"", ""CameraEyeOffsetX"", ""CameraEyeOffsetY"", ""CameraEyeOffsetZ"", ""CameraAtOffsetX"", ""CameraAtOffsetY"", ""CameraAtOffsetZ"", ""ForceMouselook"", ""ScriptAccessPin"", ""AllowedDrop"", ""DieAtEdge"", ""SalePrice"", ""SaleType"", ""ColorR"", ""ColorG"", ""ColorB"", ""ColorA"", ""ParticleSystem"", ""ClickAction"", ""Material"", ""CollisionSound"", ""CollisionSoundVolume"", ""PassTouches"", ""LinkNumber"", ""MediaURL"", ""DynAttrs"", - ""PhysicsShapeType"", ""Density"", ""GravityModifier"", ""Friction"", ""Restitution"" + ""PhysicsShapeType"", ""Density"", ""GravityModifier"", ""Friction"", ""Restitution"", ""PassCollisions"", ""RotationAxisLocks"", ""RezzerID"" , ""PhysInertia"" ) Select :UUID, :CreationDate, :Name, :Text, :Description, :SitName, :TouchName, :ObjectFlags, :OwnerMask, :NextOwnerMask, :GroupMask, :EveryoneMask, :BaseMask, :PositionX, :PositionY, :PositionZ, :GroupPositionX, :GroupPositionY, :GroupPositionZ, :VelocityX, @@ -378,7 +379,7 @@ namespace OpenSim.Data.PGSQL :OmegaY, :OmegaZ, :CameraEyeOffsetX, :CameraEyeOffsetY, :CameraEyeOffsetZ, :CameraAtOffsetX, :CameraAtOffsetY, :CameraAtOffsetZ, :ForceMouselook, :ScriptAccessPin, :AllowedDrop, :DieAtEdge, :SalePrice, :SaleType, :ColorR, :ColorG, :ColorB, :ColorA, :ParticleSystem, :ClickAction, :Material, :CollisionSound, :CollisionSoundVolume, :PassTouches, :LinkNumber, :MediaURL, :DynAttrs, - :PhysicsShapeType, :Density, :GravityModifier, :Friction, :Restitution + :PhysicsShapeType, :Density, :GravityModifier, :Friction, :Restitution, :PassCollisions, :RotationAxisLocks, :RezzerID, :PhysInertia where not EXISTS (SELECT ""UUID"" FROM prims WHERE ""UUID"" = :UUID); "; @@ -1678,6 +1679,12 @@ namespace OpenSim.Data.PGSQL prim.OwnerID = new UUID((Guid)primRow["OwnerID"]); prim.GroupID = new UUID((Guid)primRow["GroupID"]); prim.LastOwnerID = new UUID((Guid)primRow["LastOwnerID"]); + + if (primRow["RezzerID"] != DBNull.Value) + prim.RezzerID = new UUID((Guid)primRow["RezzerID"]); + else + prim.RezzerID = UUID.Zero; + prim.OwnerMask = Convert.ToUInt32(primRow["OwnerMask"]); prim.NextOwnerMask = Convert.ToUInt32(primRow["NextOwnerMask"]); prim.GroupMask = Convert.ToUInt32(primRow["GroupMask"]); @@ -1782,6 +1789,7 @@ namespace OpenSim.Data.PGSQL prim.CollisionSoundVolume = Convert.ToSingle(primRow["CollisionSoundVolume"]); prim.PassTouches = (bool)primRow["PassTouches"]; + prim.PassCollisions = (bool)primRow["PassCollisions"]; if (!(primRow["MediaURL"] is System.DBNull)) prim.MediaUrl = (string)primRow["MediaURL"]; @@ -1796,6 +1804,13 @@ namespace OpenSim.Data.PGSQL prim.GravityModifier = Convert.ToSingle(primRow["GravityModifier"]); prim.Friction = Convert.ToSingle(primRow["Friction"]); prim.Restitution = Convert.ToSingle(primRow["Restitution"]); + prim.RotationAxisLocks = Convert.ToByte(primRow["RotationAxisLocks"]); + + + PhysicsInertiaData pdata = null; + if (!(primRow["PhysInertia"] is System.DBNull)) + pdata = PhysicsInertiaData.FromXml2(primRow["PhysInertia"].ToString()); + prim.PhysicsInertia = pdata; return prim; } @@ -2097,6 +2112,7 @@ namespace OpenSim.Data.PGSQL parameters.Add(_Database.CreateParameter("OwnerID", prim.OwnerID)); parameters.Add(_Database.CreateParameter("GroupID", prim.GroupID)); parameters.Add(_Database.CreateParameter("LastOwnerID", prim.LastOwnerID)); + parameters.Add(_Database.CreateParameter("RezzerID", prim.RezzerID)); parameters.Add(_Database.CreateParameter("OwnerMask", prim.OwnerMask)); parameters.Add(_Database.CreateParameter("NextOwnerMask", prim.NextOwnerMask)); parameters.Add(_Database.CreateParameter("GroupMask", prim.GroupMask)); @@ -2196,10 +2212,28 @@ namespace OpenSim.Data.PGSQL parameters.Add(_Database.CreateParameter("CollisionSound", prim.CollisionSound)); parameters.Add(_Database.CreateParameter("CollisionSoundVolume", prim.CollisionSoundVolume)); - parameters.Add(_Database.CreateParameter("PassTouches", prim.PassTouches)); + parameters.Add(_Database.CreateParameter("PassTouches", (bool)prim.PassTouches)); + parameters.Add(_Database.CreateParameter("PassCollisions", (bool)prim.PassCollisions)); + + + if (prim.PassTouches) + parameters.Add(_Database.CreateParameter("PassTouches", true)); + else + parameters.Add(_Database.CreateParameter("PassTouches", false)); + + if (prim.PassCollisions) + parameters.Add(_Database.CreateParameter("PassCollisions", true)); + else + parameters.Add(_Database.CreateParameter("PassCollisions", false)); parameters.Add(_Database.CreateParameter("LinkNumber", prim.LinkNum)); parameters.Add(_Database.CreateParameter("MediaURL", prim.MediaUrl)); + + if (prim.PhysicsInertia != null) + parameters.Add(_Database.CreateParameter("PhysInertia", prim.PhysicsInertia.ToXml2())); + else + parameters.Add(_Database.CreateParameter("PhysInertia", String.Empty)); + if (prim.DynAttrs.CountNamespaces > 0) parameters.Add(_Database.CreateParameter("DynAttrs", prim.DynAttrs.ToXml())); @@ -2211,12 +2245,13 @@ namespace OpenSim.Data.PGSQL parameters.Add(_Database.CreateParameter("GravityModifier", (double)prim.GravityModifier)); parameters.Add(_Database.CreateParameter("Friction", (double)prim.Friction)); parameters.Add(_Database.CreateParameter("Restitution", (double)prim.Restitution)); + parameters.Add(_Database.CreateParameter("RotationAxisLocks", prim.RotationAxisLocks)); return parameters.ToArray(); } /// - /// Creates the primshape parameters for stroing in DB. + /// Creates the primshape parameters for storing in DB. /// /// Basic data of SceneObjectpart prim. /// The scene group ID. diff --git a/OpenSim/Data/PGSQL/PGSQLUserProfilesData.cs b/OpenSim/Data/PGSQL/PGSQLUserProfilesData.cs index 75a51e2de1..5800de9e84 100644 --- a/OpenSim/Data/PGSQL/PGSQLUserProfilesData.cs +++ b/OpenSim/Data/PGSQL/PGSQLUserProfilesData.cs @@ -845,7 +845,7 @@ namespace OpenSim.Data.PGSQL query = "SELECT \"profileImage\", \"profileFirstImage\" FROM \"userprofile\" WHERE \"useruuid\" = :Id"; - using (NpgsqlCommand cmd = new NpgsqlCommand(string.Format(query, "\"userpicks\""), dbcon)) + using (NpgsqlCommand cmd = new NpgsqlCommand(query, dbcon)) { cmd.Parameters.Add(m_database.CreateParameter("Id", avatarId)); diff --git a/OpenSim/Data/PGSQL/PGSQLXAssetData.cs b/OpenSim/Data/PGSQL/PGSQLXAssetData.cs index 6e884898f5..1798d20508 100644 --- a/OpenSim/Data/PGSQL/PGSQLXAssetData.cs +++ b/OpenSim/Data/PGSQL/PGSQLXAssetData.cs @@ -173,16 +173,18 @@ namespace OpenSim.Data.PGSQL if (m_enableCompression) { - using (GZipStream decompressionStream = new GZipStream(new MemoryStream(asset.Data), CompressionMode.Decompress)) + using(MemoryStream ms = new MemoryStream(asset.Data)) + using(GZipStream decompressionStream = new GZipStream(ms, CompressionMode.Decompress)) { - MemoryStream outputStream = new MemoryStream(); - WebUtil.CopyStream(decompressionStream, outputStream, int.MaxValue); - // int compressedLength = asset.Data.Length; - asset.Data = outputStream.ToArray(); - - // m_log.DebugFormat( - // "[XASSET DB]: Decompressed {0} {1} to {2} bytes from {3}", - // asset.ID, asset.Name, asset.Data.Length, compressedLength); + using(MemoryStream outputStream = new MemoryStream()) + { + decompressionStream.CopyTo(outputStream,int.MaxValue); + // int compressedLength = asset.Data.Length; + asset.Data = outputStream.ToArray(); + } + // m_log.DebugFormat( + // "[XASSET DB]: Decompressed {0} {1} to {2} bytes from {3}", + // asset.ID, asset.Name, asset.Data.Length, compressedLength); } } diff --git a/OpenSim/Data/PGSQL/PGSQLXInventoryData.cs b/OpenSim/Data/PGSQL/PGSQLXInventoryData.cs index 55a1996f51..4c10ac99b7 100644 --- a/OpenSim/Data/PGSQL/PGSQLXInventoryData.cs +++ b/OpenSim/Data/PGSQL/PGSQLXInventoryData.cs @@ -206,7 +206,7 @@ namespace OpenSim.Data.PGSQL cmd.CommandText = String.Format(@"select bit_or(""inventoryCurrentPermissions"") as ""inventoryCurrentPermissions"" from inventoryitems where ""avatarID""::uuid = :PrincipalID - and ""assetID"" = :AssetID + and ""assetID""::uuid = :AssetID group by ""assetID"" "); cmd.Parameters.Add(m_database.CreateParameter("PrincipalID", principalID)); diff --git a/OpenSim/Data/PGSQL/Resources/AgentPrefs.migrations b/OpenSim/Data/PGSQL/Resources/AgentPrefs.migrations new file mode 100644 index 0000000000..ca3cca21f6 --- /dev/null +++ b/OpenSim/Data/PGSQL/Resources/AgentPrefs.migrations @@ -0,0 +1,19 @@ +:VERSION 1 + +BEGIN TRANSACTION; + +CREATE TABLE IF NOT EXISTS "public"."agentprefs" ( + "PrincipalID" uuid NOT NULL, + "AccessPrefs" char(2) NOT NULL DEFAULT 'M'::bpchar COLLATE "default", + "HoverHeight" float8 NOT NULL DEFAULT 0, + "Language" char(5) NOT NULL DEFAULT 'en-us'::bpchar COLLATE "default", + "LanguageIsPublic" bool NOT NULL DEFAULT true, + "PermEveryone" int4 NOT NULL DEFAULT 0, + "PermGroup" int4 NOT NULL DEFAULT 0, + "PermNextOwner" int4 NOT NULL DEFAULT 532480 +) +WITH (OIDS=FALSE); + +ALTER TABLE "public"."agentprefs" ADD PRIMARY KEY ("PrincipalID") NOT DEFERRABLE INITIALLY IMMEDIATE; + +COMMIT; diff --git a/OpenSim/Data/PGSQL/Resources/EstateStore.migrations b/OpenSim/Data/PGSQL/Resources/EstateStore.migrations index 59270f8b01..5b450aa45f 100644 --- a/OpenSim/Data/PGSQL/Resources/EstateStore.migrations +++ b/OpenSim/Data/PGSQL/Resources/EstateStore.migrations @@ -1,307 +1,127 @@ -:VERSION 1 +:VERSION 12 BEGIN TRANSACTION; -CREATE TABLE estate_managers( - "EstateID" int NOT NULL Primary Key, - uuid varchar(36) NOT NULL - ); - -CREATE TABLE estate_groups( - "EstateID" int NOT NULL, - uuid varchar(36) NOT NULL - ); +-- ---------------------------- +-- Table structure for estate_groups +-- ---------------------------- +CREATE TABLE IF NOT EXISTS "public"."estate_groups" ( + "EstateID" int4 NOT NULL, + "uuid" uuid NOT NULL +) +WITH (OIDS=FALSE); +-- Indexes structure for table estate_groups +-- ---------------------------- +CREATE INDEX IF NOT EXISTS "ix_estate_groups" ON "public"."estate_groups" USING btree("EstateID" "pg_catalog"."int4_ops" ASC NULLS LAST); -CREATE TABLE estate_users( - "EstateID" int NOT NULL, - uuid varchar(36) NOT NULL - ); +-- ---------------------------- +-- Table structure for estate_managers +-- ---------------------------- +CREATE TABLE IF NOT EXISTS "public"."estate_managers" ( + "EstateID" int4 NOT NULL, + "uuid" uuid NOT NULL +) +WITH (OIDS=FALSE); +-- Indexes structure for table estate_managers +-- ---------------------------- +CREATE INDEX IF NOT EXISTS "ix_estate_managers" ON "public"."estate_managers" USING btree("EstateID" "pg_catalog"."int4_ops" ASC NULLS LAST); -CREATE TABLE estateban( - "EstateID" int NOT NULL, - "bannedUUID" varchar(36) NOT NULL, - "bannedIp" varchar(16) NOT NULL, - "bannedIpHostMask" varchar(16) NOT NULL, - "bannedNameMask" varchar(64) NULL DEFAULT NULL - ); +-- ---------------------------- +-- Table structure for estate_map +-- ---------------------------- +CREATE TABLE IF NOT EXISTS "public"."estate_map" ( + "RegionID" uuid NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000'::uuid, + "EstateID" int4 NOT NULL +) +WITH (OIDS=FALSE); -Create Sequence estate_settings_id increment by 100 start with 100; +-- Primary key structure for table estate_map +-- ---------------------------- +ALTER TABLE "public"."estate_map" ADD PRIMARY KEY ("RegionID") NOT DEFERRABLE INITIALLY IMMEDIATE; -CREATE TABLE estate_settings( - "EstateID" integer DEFAULT nextval('estate_settings_id') NOT NULL, - "EstateName" varchar(64) NULL DEFAULT (NULL), - "AbuseEmailToEstateOwner" boolean NOT NULL, - "DenyAnonymous" boolean NOT NULL, - "ResetHomeOnTeleport" boolean NOT NULL, - "FixedSun" boolean NOT NULL, - "DenyTransacted" boolean NOT NULL, - "BlockDwell" boolean NOT NULL, - "DenyIdentified" boolean NOT NULL, - "AllowVoice" boolean NOT NULL, - "UseGlobalTime" boolean NOT NULL, - "PricePerMeter" int NOT NULL, - "TaxFree" boolean NOT NULL, - "AllowDirectTeleport" boolean NOT NULL, - "RedirectGridX" int NOT NULL, - "RedirectGridY" int NOT NULL, - "ParentEstateID" int NOT NULL, - "SunPosition" double precision NOT NULL, - "EstateSkipScripts" boolean NOT NULL, - "BillableFactor" double precision NOT NULL, - "PublicAccess" boolean NOT NULL, - "AbuseEmail" varchar(255) NOT NULL, - "EstateOwner" varchar(36) NOT NULL, - "DenyMinors" boolean NOT NULL - ); - - -CREATE TABLE estate_map( - "RegionID" varchar(36) NOT NULL DEFAULT ('00000000-0000-0000-0000-000000000000'), - "EstateID" int NOT NULL - ); - -COMMIT; - -:VERSION 2 - -BEGIN TRANSACTION; - -CREATE INDEX IX_estate_managers ON estate_managers - ( - "EstateID" - ); - - -CREATE INDEX IX_estate_groups ON estate_groups - ( - "EstateID" - ); - - -CREATE INDEX IX_estate_users ON estate_users - ( - "EstateID" - ); - -COMMIT; - -:VERSION 3 - -BEGIN TRANSACTION; - -CREATE TABLE Tmp_estateban - ( - "EstateID" int NOT NULL, - "bannedUUID" varchar(36) NOT NULL, - "bannedIp" varchar(16) NULL, - "bannedIpHostMask" varchar(16) NULL, - "bannedNameMask" varchar(64) NULL - ); - - INSERT INTO Tmp_estateban ("EstateID", "bannedUUID", "bannedIp", "bannedIpHostMask", "bannedNameMask") - SELECT "EstateID", "bannedUUID", "bannedIp", "bannedIpHostMask", "bannedNameMask" FROM estateban; - -DROP TABLE estateban; - -Alter table Tmp_estateban - rename to estateban; - -CREATE INDEX IX_estateban ON estateban - ( - "EstateID" - ); - -COMMIT; - - -:VERSION 4 - -BEGIN TRANSACTION; - -CREATE TABLE Tmp_estate_managers - ( - "EstateID" int NOT NULL, - uuid uuid NOT NULL - ); - -INSERT INTO Tmp_estate_managers ("EstateID", uuid) - SELECT "EstateID", cast(uuid as uuid) FROM estate_managers; - -DROP TABLE estate_managers; - -Alter table Tmp_estate_managers - rename to estate_managers; - -CREATE INDEX IX_estate_managers ON estate_managers - ( - "EstateID" - ); - -COMMIT; - - -:VERSION 5 - -BEGIN TRANSACTION; - -CREATE TABLE Tmp_estate_groups - ( - "EstateID" int NOT NULL, - uuid uuid NOT NULL - ) ; - - INSERT INTO Tmp_estate_groups ("EstateID", uuid) - SELECT "EstateID", cast(uuid as uuid) FROM estate_groups; - -DROP TABLE estate_groups; - -Alter table Tmp_estate_groups - rename to estate_groups; - -CREATE INDEX IX_estate_groups ON estate_groups - ( - "EstateID" - ); - -COMMIT; - - -:VERSION 6 - -BEGIN TRANSACTION; - -CREATE TABLE Tmp_estate_users - ( - "EstateID" int NOT NULL, - uuid uuid NOT NULL - ); - -INSERT INTO Tmp_estate_users ("EstateID", uuid) - SELECT "EstateID", cast(uuid as uuid) FROM estate_users ; - -DROP TABLE estate_users; - -Alter table Tmp_estate_users - rename to estate_users; - -CREATE INDEX IX_estate_users ON estate_users - ( - "EstateID" - ); - -COMMIT; - - -:VERSION 7 - -BEGIN TRANSACTION; - -CREATE TABLE Tmp_estateban - ( - "EstateID" int NOT NULL, - "bannedUUID" uuid NOT NULL, - "bannedIp" varchar(16) NULL, - "bannedIpHostMask" varchar(16) NULL, - "bannedNameMask" varchar(64) NULL - ); - -INSERT INTO Tmp_estateban ("EstateID", "bannedUUID", "bannedIp", "bannedIpHostMask", "bannedNameMask") - SELECT "EstateID", cast("bannedUUID" as uuid), "bannedIp", "bannedIpHostMask", "bannedNameMask" FROM estateban ; - -DROP TABLE estateban; - -Alter table Tmp_estateban - rename to estateban; - -CREATE INDEX IX_estateban ON estateban - ( - "EstateID" - ); - -COMMIT; - - -:VERSION 8 - -BEGIN TRANSACTION; - -CREATE TABLE Tmp_estate_settings - ( - "EstateID" integer default nextval('estate_settings_id') NOT NULL, - "EstateName" varchar(64) NULL DEFAULT (NULL), - "AbuseEmailToEstateOwner" boolean NOT NULL, - "DenyAnonymous" boolean NOT NULL, - "ResetHomeOnTeleport" boolean NOT NULL, - "FixedSun" boolean NOT NULL, - "DenyTransacted" boolean NOT NULL, - "BlockDwell" boolean NOT NULL, - "DenyIdentified" boolean NOT NULL, - "AllowVoice" boolean NOT NULL, - "UseGlobalTime" boolean NOT NULL, - "PricePerMeter" int NOT NULL, - "TaxFree" boolean NOT NULL, - "AllowDirectTeleport" boolean NOT NULL, - "RedirectGridX" int NOT NULL, - "RedirectGridY" int NOT NULL, - "ParentEstateID" int NOT NULL, - "SunPosition" double precision NOT NULL, - "EstateSkipScripts" boolean NOT NULL, - "BillableFactor" double precision NOT NULL, - "PublicAccess" boolean NOT NULL, - "AbuseEmail" varchar(255) NOT NULL, +-- ---------------------------- +-- Table structure for estate_settings +-- ---------------------------- +CREATE TABLE IF NOT EXISTS "public"."estate_settings" ( + "EstateID" int4 NOT NULL DEFAULT nextval('estate_settings_id'::regclass), + "EstateName" varchar(64) DEFAULT NULL::character varying COLLATE "default", + "AbuseEmailToEstateOwner" bool NOT NULL, + "DenyAnonymous" bool NOT NULL, + "ResetHomeOnTeleport" bool NOT NULL, + "FixedSun" bool NOT NULL, + "DenyTransacted" bool NOT NULL, + "BlockDwell" bool NOT NULL, + "DenyIdentified" bool NOT NULL, + "AllowVoice" bool NOT NULL, + "UseGlobalTime" bool NOT NULL, + "PricePerMeter" int4 NOT NULL, + "TaxFree" bool NOT NULL, + "AllowDirectTeleport" bool NOT NULL, + "RedirectGridX" int4 NOT NULL, + "RedirectGridY" int4 NOT NULL, + "ParentEstateID" int4 NOT NULL, + "SunPosition" float8 NOT NULL, + "EstateSkipScripts" bool NOT NULL, + "BillableFactor" float8 NOT NULL, + "PublicAccess" bool NOT NULL, + "AbuseEmail" varchar(255) NOT NULL COLLATE "default", "EstateOwner" uuid NOT NULL, - "DenyMinors" boolean NOT NULL - ); + "DenyMinors" bool NOT NULL, + "AllowLandmark" bool NOT NULL DEFAULT true, + "AllowParcelChanges" bool NOT NULL DEFAULT true, + "AllowSetHome" bool NOT NULL DEFAULT true +) +WITH (OIDS=FALSE); -INSERT INTO Tmp_estate_settings ("EstateID", "EstateName", "AbuseEmailToEstateOwner", "DenyAnonymous", "ResetHomeOnTeleport", "FixedSun", "DenyTransacted", "BlockDwell", "DenyIdentified", "AllowVoice", "UseGlobalTime", "PricePerMeter", "TaxFree", "AllowDirectTeleport", "RedirectGridX", "RedirectGridY", "ParentEstateID", "SunPosition", "EstateSkipScripts", "BillableFactor", "PublicAccess", "AbuseEmail", "EstateOwner", "DenyMinors") - SELECT "EstateID", "EstateName", "AbuseEmailToEstateOwner", "DenyAnonymous", "ResetHomeOnTeleport", "FixedSun", "DenyTransacted", "BlockDwell", "DenyIdentified", "AllowVoice", "UseGlobalTime", "PricePerMeter", "TaxFree", "AllowDirectTeleport", "RedirectGridX", "RedirectGridY", "ParentEstateID", "SunPosition", "EstateSkipScripts", "BillableFactor", "PublicAccess", "AbuseEmail", cast("EstateOwner" as uuid), "DenyMinors" FROM estate_settings ; +-- Primary key structure for table estate_settings +-- ---------------------------- +ALTER TABLE "public"."estate_settings" ADD PRIMARY KEY ("EstateID") NOT DEFERRABLE INITIALLY IMMEDIATE; -DROP TABLE estate_settings; +-- ---------------------------- +-- Table structure for estate_users +-- ---------------------------- +CREATE TABLE IF NOT EXISTS "public"."estate_users" ( + "EstateID" int4 NOT NULL, + "uuid" uuid NOT NULL +) +WITH (OIDS=FALSE); +-- Indexes structure for table estate_users +-- ---------------------------- +CREATE INDEX IF NOT EXISTS "ix_estate_users" ON "public"."estate_users" USING btree("EstateID" "pg_catalog"."int4_ops" ASC NULLS LAST); -Alter table Tmp_estate_settings - rename to estate_settings; +-- ---------------------------- +-- Table structure for estateban +-- ---------------------------- +CREATE TABLE IF NOT EXISTS "public"."estateban" ( + "EstateID" int4 NOT NULL, + "bannedUUID" uuid NOT NULL, + "bannedIp" varchar(16) COLLATE "default", + "bannedIpHostMask" varchar(16) COLLATE "default", + "bannedNameMask" varchar(64) COLLATE "default" +) +WITH (OIDS=FALSE); - -Create index on estate_settings (lower("EstateName")); +-- Indexes structure for table estateban +-- ---------------------------- +CREATE INDEX IF NOT EXISTS "ix_estateban" ON "public"."estateban" USING btree("EstateID" "pg_catalog"."int4_ops" ASC NULLS LAST); COMMIT; +:VERSION 13 -:VERSION 9 + BEGIN TRASACTION; -BEGIN TRANSACTION; - -CREATE TABLE Tmp_estate_map - ( - "RegionID" uuid NOT NULL DEFAULT ('00000000-0000-0000-0000-000000000000'), - "EstateID" int NOT NULL - ); - -INSERT INTO Tmp_estate_map ("RegionID", "EstateID") - SELECT cast("RegionID" as uuid), "EstateID" FROM estate_map ; - -DROP TABLE estate_map; - -Alter table Tmp_estate_map - rename to estate_map; +-- ---------------------------- +-- SEQUENCE estate_settings_id +-- ---------------------------- +CREATE SEQUENCE IF NOT EXISTS "public"."estate_settings_id" + INCREMENT 100 + MINVALUE 1 + MAXVALUE 9223372036854775807 + START 100 + CACHE 1; COMMIT; - -:VERSION 10 - -BEGIN TRANSACTION; -ALTER TABLE estate_settings ADD COLUMN "AllowLandmark" boolean NOT NULL default true; -ALTER TABLE estate_settings ADD COLUMN "AllowParcelChanges" boolean NOT NULL default true; -ALTER TABLE estate_settings ADD COLUMN "AllowSetHome" boolean NOT NULL default true; -COMMIT; - -:VERSION 11 - -Begin transaction; - - -Commit; - diff --git a/OpenSim/Data/PGSQL/Resources/FSAssetStore.migrations b/OpenSim/Data/PGSQL/Resources/FSAssetStore.migrations new file mode 100644 index 0000000000..3a072e566e --- /dev/null +++ b/OpenSim/Data/PGSQL/Resources/FSAssetStore.migrations @@ -0,0 +1,14 @@ +:VERSION 1 + +BEGIN TRANSACTION; + +CREATE TABLE fsassets ( + "id" uuid NOT NULL PRIMARY KEY, + "type" integer NOT NULL, + "hash" char(64) NOT NULL, + "create_time" integer NOT NULL DEFAULT '0', + "access_time" integer NOT NULL DEFAULT '0', + "asset_flags" integer NOT NULL DEFAULT '0' +); + +COMMIT; diff --git a/OpenSim/Data/PGSQL/Resources/RegionStore.migrations b/OpenSim/Data/PGSQL/Resources/RegionStore.migrations index c08593917d..fcefb6baa3 100644 --- a/OpenSim/Data/PGSQL/Resources/RegionStore.migrations +++ b/OpenSim/Data/PGSQL/Resources/RegionStore.migrations @@ -1195,3 +1195,33 @@ CREATE TABLE bakedterrain ); COMMIT; + +:VERSION 45 #---- Add RezzerID filed in table prims + +BEGIN TRANSACTION; + +ALTER TABLE prims ADD "RezzerID" uuid NULL; + +COMMIT; + +:VERSION 46 #---- Add physics inertia data to table prims + +BEGIN TRANSACTION; + +ALTER TABLE prims ADD "PhysInertia" TEXT; + +COMMIT; + + +:VERSION 47 #---- Convert field PassCollisions in table prims to BOOLEAN + +BEGIN TRANSACTION; + +ALTER TABLE "public"."prims" ALTER COLUMN "PassCollisions" DROP DEFAULT; +ALTER TABLE "public"."prims" + ALTER COLUMN "PassCollisions" TYPE BOOLEAN + USING CASE WHEN "PassCollisions" = 0 THEN FALSE + WHEN "PassCollisions" = 1 THEN TRUE + ELSE NULL + END; +COMMIT; diff --git a/OpenSim/Data/SQLite/Resources/MuteListStore.migrations b/OpenSim/Data/SQLite/Resources/MuteListStore.migrations new file mode 100644 index 0000000000..f981ded2af --- /dev/null +++ b/OpenSim/Data/SQLite/Resources/MuteListStore.migrations @@ -0,0 +1,16 @@ +:VERSION 1 + +BEGIN TRANSACTION; + +CREATE TABLE MuteList ( + AgentID char(36) NOT NULL, + MuteID char(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000', + MuteName varchar(64) NOT NULL DEFAULT '', + MuteType int(11) NOT NULL DEFAULT '1', + MuteFlags int(11) NOT NULL DEFAULT '0', + Stamp int(11) NOT NULL, + UNIQUE (AgentID, MuteID, MuteName), + PRIMARY KEY(AgentID) +); + +COMMIT; diff --git a/OpenSim/Data/SQLite/Resources/RegionStore.migrations b/OpenSim/Data/SQLite/Resources/RegionStore.migrations index eef14d6a46..fb154cf84a 100644 --- a/OpenSim/Data/SQLite/Resources/RegionStore.migrations +++ b/OpenSim/Data/SQLite/Resources/RegionStore.migrations @@ -371,3 +371,9 @@ BEGIN; ALTER TABLE `prims` ADD COLUMN `RezzerID` char(36) DEFAULT NULL; COMMIT; + +:VERSION 36 #----- Add physics inertia data + +BEGIN; +ALTER TABLE `prims` ADD COLUMN `PhysInertia` TEXT default NULL; +COMMIT; diff --git a/OpenSim/Data/SQLite/SQLiteMuteListData.cs b/OpenSim/Data/SQLite/SQLiteMuteListData.cs new file mode 100644 index 0000000000..80fd0192ad --- /dev/null +++ b/OpenSim/Data/SQLite/SQLiteMuteListData.cs @@ -0,0 +1,71 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Data; +using OpenMetaverse; +using OpenSim.Framework; +#if CSharpSqlite + using Community.CsharpSqlite.Sqlite; +#else + using Mono.Data.Sqlite; +#endif + +namespace OpenSim.Data.SQLite +{ + public class SQLiteMuteListData : SQLiteGenericTableHandler, IMuteListData + { + public SQLiteMuteListData(string connectionString) + : base(connectionString, "MuteList", "MuteListStore") + { + } + + public MuteData[] Get(UUID agentID) + { + MuteData[] data = base.Get("AgentID", agentID.ToString()); + return data; + } + + public bool Delete(UUID agentID, UUID muteID, string muteName) + { + using (SqliteCommand cmd = new SqliteCommand()) + { + cmd.CommandText = "delete from MuteList where `AgentID` = :AgentID and `MuteID` = :MuteID and `MuteName` = :MuteName"; + + cmd.Parameters.AddWithValue(":AgentID", agentID.ToString()); + cmd.Parameters.AddWithValue(":MuteID", muteID.ToString()); + cmd.Parameters.AddWithValue(":MuteName", muteName); + + if (ExecuteNonQuery(cmd, m_Connection) > 0) + return true; + return false; + } + } + } +} \ No newline at end of file diff --git a/OpenSim/Data/SQLite/SQLiteSimulationData.cs b/OpenSim/Data/SQLite/SQLiteSimulationData.cs index eec386fcb0..19880dec20 100644 --- a/OpenSim/Data/SQLite/SQLiteSimulationData.cs +++ b/OpenSim/Data/SQLite/SQLiteSimulationData.cs @@ -1843,6 +1843,12 @@ namespace OpenSim.Data.SQLite if (vehicle != null) prim.VehicleParams = vehicle; } + + PhysicsInertiaData pdata = null; + if (!(row["PhysInertia"] is DBNull) && row["PhysInertia"].ToString() != String.Empty) + pdata = PhysicsInertiaData.FromXml2(row["PhysInertia"].ToString()); + prim.PhysicsInertia = pdata; + return prim; } @@ -2266,6 +2272,11 @@ namespace OpenSim.Data.SQLite else row["Vehicle"] = String.Empty; + if (prim.PhysicsInertia != null) + row["PhysInertia"] = prim.PhysicsInertia.ToXml2(); + else + row["PhysInertia"] = String.Empty; + } /// diff --git a/OpenSim/Data/SQLite/SQLiteUserProfilesData.cs b/OpenSim/Data/SQLite/SQLiteUserProfilesData.cs index 13aac79049..2f22d544f5 100644 --- a/OpenSim/Data/SQLite/SQLiteUserProfilesData.cs +++ b/OpenSim/Data/SQLite/SQLiteUserProfilesData.cs @@ -926,7 +926,7 @@ namespace OpenSim.Data.SQLite { using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) { - cmd.CommandText = query; + cmd.CommandText = string.Format(query, "\"classifieds\""); cmd.Parameters.AddWithValue(":Id", avatarId.ToString()); using (reader = cmd.ExecuteReader(CommandBehavior.SingleRow)) @@ -940,7 +940,7 @@ namespace OpenSim.Data.SQLite using (SqliteCommand cmd = (SqliteCommand)m_connection.CreateCommand()) { - cmd.CommandText = query; + cmd.CommandText = string.Format(query, "\"userpicks\""); cmd.Parameters.AddWithValue(":Id", avatarId.ToString()); using (reader = cmd.ExecuteReader(CommandBehavior.SingleRow)) diff --git a/OpenSim/Data/SQLite/SQLiteXInventoryData.cs b/OpenSim/Data/SQLite/SQLiteXInventoryData.cs index 7f44a651e9..4ef1f30a8d 100644 --- a/OpenSim/Data/SQLite/SQLiteXInventoryData.cs +++ b/OpenSim/Data/SQLite/SQLiteXInventoryData.cs @@ -305,17 +305,11 @@ namespace OpenSim.Data.SQLite using (SqliteCommand cmd = new SqliteCommand()) { - cmd.CommandText = "update inventoryfolders set version=version+1 where folderID = ?folderID"; + cmd.CommandText = "update inventoryfolders set version=version+1 where folderID = :folderID"; cmd.Parameters.Add(new SqliteParameter(":folderID", folderID)); - try - { - cmd.ExecuteNonQuery(); - } - catch (Exception) - { + if(ExecuteNonQuery(cmd, m_Connection) == 0) return false; - } } return true; diff --git a/OpenSim/Framework/AgentUpdateArgs.cs b/OpenSim/Framework/AgentUpdateArgs.cs index f04d692092..cd1c3a0745 100644 --- a/OpenSim/Framework/AgentUpdateArgs.cs +++ b/OpenSim/Framework/AgentUpdateArgs.cs @@ -83,6 +83,7 @@ namespace OpenSim.Framework public bool UseClientAgentPosition; public bool NeedsCameraCollision; public uint lastpacketSequence; + public double lastUpdateTS; public AgentUpdateArgs() { diff --git a/OpenSim/Framework/AnimationSet.cs b/OpenSim/Framework/AnimationSet.cs index 87c4a78ea9..8753088cc7 100644 --- a/OpenSim/Framework/AnimationSet.cs +++ b/OpenSim/Framework/AnimationSet.cs @@ -31,7 +31,8 @@ using OpenMetaverse; namespace OpenSim.Framework { - public delegate bool AnimationSetValidator(UUID animID); +// public delegate bool AnimationSetValidator(UUID animID); + public delegate uint AnimationSetValidator(UUID animID); public class AnimationSet { @@ -141,7 +142,7 @@ namespace OpenSim.Framework assetData += String.Format("{0} {1} {2}\n", kvp.Key, kvp.Value.Value.ToString(), kvp.Value.Key); return System.Text.Encoding.ASCII.GetBytes(assetData); } - +/* public bool Validate(AnimationSetValidator val) { if (m_parseError) @@ -164,5 +165,22 @@ namespace OpenSim.Framework return allOk; } +*/ + public uint Validate(AnimationSetValidator val) + { + if (m_parseError) + return 0; + + uint ret = 0x7fffffff; + uint t; + foreach (KeyValuePair> kvp in m_animations) + { + t = val(kvp.Value.Value); + if (t == 0) + return 0; + ret &= t; + } + return ret; + } } } diff --git a/OpenSim/Framework/AssetLoader/Filesystem/AssetLoaderFileSystem.cs b/OpenSim/Framework/AssetLoader/Filesystem/AssetLoaderFileSystem.cs index 097ad7d6a3..efccc35080 100644 --- a/OpenSim/Framework/AssetLoader/Filesystem/AssetLoaderFileSystem.cs +++ b/OpenSim/Framework/AssetLoader/Filesystem/AssetLoaderFileSystem.cs @@ -42,11 +42,13 @@ namespace OpenSim.Framework.AssetLoader.Filesystem public class AssetLoaderFileSystem : IAssetLoader { private static readonly UUID LIBRARY_OWNER_ID = new UUID("11111111-1111-0000-0000-000100bba000"); + private static readonly string LIBRARY_OWNER_IDstr = "11111111-1111-0000-0000-000100bba000"; + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); protected static AssetBase CreateAsset(string assetIdStr, string name, string path, sbyte type) { - AssetBase asset = new AssetBase(new UUID(assetIdStr), name, type, LIBRARY_OWNER_ID.ToString()); + AssetBase asset = new AssetBase(new UUID(assetIdStr), name, type, LIBRARY_OWNER_IDstr); if (!String.IsNullOrEmpty(path)) { diff --git a/OpenSim/Framework/AvatarWearable.cs b/OpenSim/Framework/AvatarWearable.cs index 0e8f9608f0..fddd0f06ea 100644 --- a/OpenSim/Framework/AvatarWearable.cs +++ b/OpenSim/Framework/AvatarWearable.cs @@ -91,11 +91,11 @@ namespace OpenSim.Framework public static readonly UUID DEFAULT_PANTS_ITEM = new UUID("77c41e39-38f9-f75a-0000-5859892f1111"); public static readonly UUID DEFAULT_PANTS_ASSET = new UUID("00000000-38f9-1111-024e-222222111120"); -// public static readonly UUID DEFAULT_ALPHA_ITEM = new UUID("bfb9923c-4838-4d2d-bf07-608c5b1165c8"); -// public static readonly UUID DEFAULT_ALPHA_ASSET = new UUID("1578a2b1-5179-4b53-b618-fe00ca5a5594"); + public static readonly UUID DEFAULT_ALPHA_ITEM = new UUID("bfb9923c-4838-4d2d-bf07-608c5b1165c8"); + public static readonly UUID DEFAULT_ALPHA_ASSET = new UUID("1578a2b1-5179-4b53-b618-fe00ca5a5594"); -// public static readonly UUID DEFAULT_TATTOO_ITEM = new UUID("c47e22bd-3021-4ba4-82aa-2b5cb34d35e1"); -// public static readonly UUID DEFAULT_TATTOO_ASSET = new UUID("00000000-0000-2222-3333-100000001007"); + public static readonly UUID DEFAULT_TATTOO_ITEM = new UUID("c47e22bd-3021-4ba4-82aa-2b5cb34d35e1"); + public static readonly UUID DEFAULT_TATTOO_ASSET = new UUID("00000000-0000-2222-3333-100000001007"); protected Dictionary m_items = new Dictionary(); protected List m_ids = new List(); diff --git a/OpenSim/Framework/BlockingQueue.cs b/OpenSim/Framework/BlockingQueue.cs deleted file mode 100644 index 2461049107..0000000000 --- a/OpenSim/Framework/BlockingQueue.cs +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System.Collections.Generic; -using System.Threading; - -namespace OpenSim.Framework -{ - public class BlockingQueue - { - private readonly Queue m_pqueue = new Queue(); - private readonly Queue m_queue = new Queue(); - private readonly object m_queueSync = new object(); - - public void PriorityEnqueue(T value) - { - lock (m_queueSync) - { - m_pqueue.Enqueue(value); - Monitor.Pulse(m_queueSync); - } - } - - public void Enqueue(T value) - { - lock (m_queueSync) - { - m_queue.Enqueue(value); - Monitor.Pulse(m_queueSync); - } - } - - public T Dequeue() - { - lock (m_queueSync) - { - while (m_queue.Count < 1 && m_pqueue.Count < 1) - { - Monitor.Wait(m_queueSync); - } - - if (m_pqueue.Count > 0) - return m_pqueue.Dequeue(); - - if (m_queue.Count > 0) - return m_queue.Dequeue(); - return default(T); - } - } - - public T Dequeue(int msTimeout) - { - lock (m_queueSync) - { - if (m_queue.Count < 1 && m_pqueue.Count < 1) - { - if(!Monitor.Wait(m_queueSync, msTimeout)) - return default(T); - } - - if (m_pqueue.Count > 0) - return m_pqueue.Dequeue(); - if (m_queue.Count > 0) - return m_queue.Dequeue(); - return default(T); - } - } - - /// - /// Indicate whether this queue contains the given item. - /// - /// - /// This method is not thread-safe. Do not rely on the result without consistent external locking. - /// - public bool Contains(T item) - { - lock (m_queueSync) - { - if (m_queue.Count < 1 && m_pqueue.Count < 1) - return false; - - if (m_pqueue.Contains(item)) - return true; - return m_queue.Contains(item); - } - } - - /// - /// Return a count of the number of requests on this queue. - /// - public int Count() - { - lock (m_queueSync) - return m_queue.Count + m_pqueue.Count; - } - - /// - /// Return the array of items on this queue. - /// - /// - /// This method is not thread-safe. Do not rely on the result without consistent external locking. - /// - public T[] GetQueueArray() - { - lock (m_queueSync) - { - if (m_queue.Count < 1 && m_pqueue.Count < 1) - return new T[0]; - - return m_queue.ToArray(); - } - } - - public void Clear() - { - lock (m_queueSync) - { - m_pqueue.Clear(); - m_queue.Clear(); - Monitor.Pulse(m_queueSync); - } - } - } -} diff --git a/OpenSim/Framework/Cache.cs b/OpenSim/Framework/Cache.cs index 7ccc320acd..3ca85d7d1a 100644 --- a/OpenSim/Framework/Cache.cs +++ b/OpenSim/Framework/Cache.cs @@ -390,17 +390,21 @@ namespace OpenSim.Framework Object data = fetch(index); - if (data == null && (m_Flags & CacheFlags.CacheMissing) == 0) - return null; - - lock (m_Index) + if (data == null) { - CacheItemBase missing = new CacheItemBase(index); - if (!m_Index.Contains(missing)) - { - m_Index.Add(missing); - m_Lookup[index] = missing; - } + if((m_Flags & CacheFlags.CacheMissing) != 0) + { + lock (m_Index) + { + CacheItemBase missing = new CacheItemBase(index); + if (!m_Index.Contains(missing)) + { + m_Index.Add(missing); + m_Lookup[index] = missing; + } + } + } + return null; } Store(index, data); diff --git a/OpenSim/Framework/ChildAgentDataUpdate.cs b/OpenSim/Framework/ChildAgentDataUpdate.cs index d6d8dde6fe..ee5007abf8 100644 --- a/OpenSim/Framework/ChildAgentDataUpdate.cs +++ b/OpenSim/Framework/ChildAgentDataUpdate.cs @@ -375,6 +375,7 @@ namespace OpenSim.Framework public string ActiveGroupTitle = null; public UUID agentCOF; public byte CrossingFlags; + public byte CrossExtraFlags; public Dictionary ChildrenCapSeeds = null; public Animation[] Anims; @@ -454,6 +455,8 @@ namespace OpenSim.Framework args["agent_cof"] = OSD.FromUUID(agentCOF); args["crossingflags"] = OSD.FromInteger(CrossingFlags); + if(CrossingFlags != 0) + args["crossExtraFlags"] = OSD.FromInteger(CrossExtraFlags); args["active_group_id"] = OSD.FromUUID(ActiveGroupID); args["active_group_name"] = OSD.FromString(ActiveGroupName); @@ -646,6 +649,12 @@ namespace OpenSim.Framework if (args.ContainsKey("crossingflags") && args["crossingflags"] != null) CrossingFlags = (byte)args["crossingflags"].AsInteger(); + if(CrossingFlags != 0) + { + if (args.ContainsKey("crossExtraFlags") && args["crossExtraFlags"] != null) + CrossExtraFlags = (byte)args["crossExtraFlags"].AsInteger(); + } + if (args.ContainsKey("active_group_id") && args["active_group_id"] != null) ActiveGroupID = args["active_group_id"].AsUUID(); diff --git a/OpenSim/Framework/Client/IClientIPEndpoint.cs b/OpenSim/Framework/Client/IClientIPEndpoint.cs index 2b99bf0a99..2194616a02 100644 --- a/OpenSim/Framework/Client/IClientIPEndpoint.cs +++ b/OpenSim/Framework/Client/IClientIPEndpoint.cs @@ -34,6 +34,6 @@ namespace OpenSim.Framework.Client { public interface IClientIPEndpoint { - IPAddress EndPoint { get; } + IPEndPoint RemoteEndPoint { get; } } } diff --git a/OpenSim/Framework/ClientInfo.cs b/OpenSim/Framework/ClientInfo.cs index 98e4465cf8..a1ca9bc32b 100644 --- a/OpenSim/Framework/ClientInfo.cs +++ b/OpenSim/Framework/ClientInfo.cs @@ -36,14 +36,8 @@ namespace OpenSim.Framework public readonly DateTime StartedTime = DateTime.Now; public AgentCircuitData agentcircuit = null; - public Dictionary needAck; - - public List out_packets = new List(); - public Dictionary pendingAcks = new Dictionary(); public EndPoint proxyEP; - public uint sequence; - public byte[] usecircuit; public EndPoint userEP; public int resendThrottle; @@ -59,9 +53,5 @@ namespace OpenSim.Framework public int targetThrottle; public int maxThrottle; - - public Dictionary SyncRequests = new Dictionary(); - public Dictionary AsyncRequests = new Dictionary(); - public Dictionary GenericRequests = new Dictionary(); } } diff --git a/OpenSim/Framework/ClientManager.cs b/OpenSim/Framework/ClientManager.cs index baff2f4354..45c54e4989 100644 --- a/OpenSim/Framework/ClientManager.cs +++ b/OpenSim/Framework/ClientManager.cs @@ -27,10 +27,8 @@ using System; using System.Collections.Generic; -using System.Reflection; using System.Net; using OpenMetaverse; -using OpenMetaverse.Packets; namespace OpenSim.Framework { @@ -76,20 +74,16 @@ namespace OpenSim.Framework { lock (m_syncRoot) { - if (m_dict1.ContainsKey(value.AgentId) || m_dict2.ContainsKey(value.RemoteEndPoint)) - return false; + // allow self healing +// if (m_dict1.ContainsKey(value.AgentId) || m_dict2.ContainsKey(value.RemoteEndPoint)) +// return false; m_dict1[value.AgentId] = value; m_dict2[value.RemoteEndPoint] = value; - IClientAPI[] oldArray = m_array; - int oldLength = oldArray.Length; - - IClientAPI[] newArray = new IClientAPI[oldLength + 1]; - for (int i = 0; i < oldLength; i++) - newArray[i] = oldArray[i]; - newArray[oldLength] = value; - + // dict1 is the master + IClientAPI[] newArray = new IClientAPI[m_dict1.Count]; + m_dict1.Values.CopyTo(newArray, 0); m_array = newArray; } @@ -112,22 +106,12 @@ namespace OpenSim.Framework m_dict1.Remove(key); m_dict2.Remove(value.RemoteEndPoint); - IClientAPI[] oldArray = m_array; - int oldLength = oldArray.Length; - - IClientAPI[] newArray = new IClientAPI[oldLength - 1]; - int j = 0; - for (int i = 0; i < oldLength; i++) - { - if (oldArray[i] != value) - newArray[j++] = oldArray[i]; - } - + IClientAPI[] newArray = new IClientAPI[m_dict1.Count]; + m_dict1.Values.CopyTo(newArray, 0); m_array = newArray; return true; } } - return false; } @@ -196,26 +180,12 @@ namespace OpenSim.Framework } } - /// - /// Performs a given task in parallel for each of the elements in the - /// collection - /// - /// Action to perform on each element - public void ForEach(Action action) - { - IClientAPI[] localArray = m_array; - Parallel.For(0, localArray.Length, - delegate(int i) - { action(localArray[i]); } - ); - } - /// /// Performs a given task synchronously for each of the elements in /// the collection /// /// Action to perform on each element - public void ForEachSync(Action action) + public void ForEach(Action action) { IClientAPI[] localArray = m_array; for (int i = 0; i < localArray.Length; i++) diff --git a/OpenSim/Framework/Console/LocalConsole.cs b/OpenSim/Framework/Console/LocalConsole.cs index 73f0323874..ba32f5008e 100644 --- a/OpenSim/Framework/Console/LocalConsole.cs +++ b/OpenSim/Framework/Console/LocalConsole.cs @@ -46,6 +46,7 @@ namespace OpenSim.Framework.Console private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private string m_historyPath; private bool m_historyEnable; + private bool m_historytimestamps; // private readonly object m_syncRoot = new object(); private const string LOGLEVEL_NONE = "(none)"; @@ -98,15 +99,30 @@ namespace OpenSim.Framework.Console string m_historyFile = startupConfig.GetString("ConsoleHistoryFile", "OpenSimConsoleHistory.txt"); int m_historySize = startupConfig.GetInt("ConsoleHistoryFileLines", 100); m_historyPath = Path.GetFullPath(Path.Combine(Util.configDir(), m_historyFile)); - m_log.InfoFormat("[LOCAL CONSOLE]: Persistent command line history is Enabled, up to {0} lines from file {1}", m_historySize, m_historyPath); + m_historytimestamps = startupConfig.GetBoolean("ConsoleHistoryTimeStamp", false); + m_log.InfoFormat("[LOCAL CONSOLE]: Persistent command line history is Enabled, up to {0} lines from file {1} {2} timestamps", + m_historySize, m_historyPath, m_historytimestamps?"with":"without"); if (File.Exists(m_historyPath)) { + List originallines = new List(); using (StreamReader history_file = new StreamReader(m_historyPath)) { string line; while ((line = history_file.ReadLine()) != null) { + originallines.Add(line); + if(line.StartsWith("[")) + { + int indx = line.IndexOf("]:> "); + if(indx > 0) + { + if(indx + 4 >= line.Length) + line = String.Empty; + else + line = line.Substring(indx + 4); + } + } m_history.Add(line); } } @@ -114,11 +130,14 @@ namespace OpenSim.Framework.Console if (m_history.Count > m_historySize) { while (m_history.Count > m_historySize) + { m_history.RemoveAt(0); + originallines.RemoveAt(0); + } using (StreamWriter history_file = new StreamWriter(m_historyPath)) { - foreach (string line in m_history) + foreach (string line in originallines) { history_file.WriteLine(line); } @@ -141,6 +160,8 @@ namespace OpenSim.Framework.Console m_history.Add(text); if (m_historyEnable) { + if (m_historytimestamps) + text = String.Format("[{0} {1}]:> {2}", DateTime.Now.ToShortDateString(), DateTime.Now.ToShortTimeString(), text); File.AppendAllText(m_historyPath, text + Environment.NewLine); } } diff --git a/OpenSim/Framework/Console/RemoteConsole.cs b/OpenSim/Framework/Console/RemoteConsole.cs index f59c9024be..b90b75f2df 100644 --- a/OpenSim/Framework/Console/RemoteConsole.cs +++ b/OpenSim/Framework/Console/RemoteConsole.cs @@ -403,7 +403,7 @@ namespace OpenSim.Framework.Console string uri = "/ReadResponses/" + sessionID.ToString() + "/"; m_Server.AddPollServiceHTTPHandler( - uri, new PollServiceEventArgs(null, uri, HasEvents, GetEvents, NoEvents, sessionID,25000)); // 25 secs timeout + uri, new PollServiceEventArgs(null, uri, HasEvents, GetEvents, NoEvents, null, sessionID,25000)); // 25 secs timeout // Our reply is an XML document. // TODO: Change this to Linq.Xml @@ -687,7 +687,6 @@ namespace OpenSim.Framework.Console result["int_response_code"] = 200; result["content_type"] = "application/xml"; result["keepalive"] = false; - result["reusecontext"] = false; result = CheckOrigin(result); return result; @@ -713,7 +712,6 @@ namespace OpenSim.Framework.Console result["int_response_code"] = 200; result["content_type"] = "text/xml"; result["keepalive"] = false; - result["reusecontext"] = false; result = CheckOrigin(result); return result; diff --git a/OpenSim/Framework/Crc32.cs b/OpenSim/Framework/Crc32.cs new file mode 100644 index 0000000000..7ad156646f --- /dev/null +++ b/OpenSim/Framework/Crc32.cs @@ -0,0 +1,139 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Security.Cryptography; + +namespace OpenSim.Framework +{ + // this is more generic than openmetaverse CRC32 + + public class Crc32 : HashAlgorithm + { + public const UInt32 DefaultPolynomial = 0xedb88320; + public const UInt32 DefaultSeed = 0xffffffff; + + private UInt32 hash; + private UInt32 seed; + private UInt32[] table; + private static UInt32[] defaultTable; + + public Crc32() + { + table = InitializeTable(DefaultPolynomial); + seed = DefaultSeed; + Initialize(); + } + + public Crc32(UInt32 polynomial, UInt32 seed) + { + table = InitializeTable(polynomial); + this.seed = seed; + Initialize(); + } + + public override void Initialize() + { + hash = seed; + } + + protected override void HashCore(byte[] buffer, int start, int length) + { + hash = CalculateHash(table, hash, buffer, start, length); + } + + protected override byte[] HashFinal() + { + byte[] hashBuffer = UInt32ToBigEndianBytes(~hash); + this.HashValue = hashBuffer; + return hashBuffer; + } + + public override int HashSize + { + get { return 32; } + } + + public static UInt32 Compute(byte[] buffer) + { + return ~CalculateHash(InitializeTable(DefaultPolynomial), DefaultSeed, buffer, 0, buffer.Length); + } + + public static UInt32 Compute(UInt32 seed, byte[] buffer) + { + return ~CalculateHash(InitializeTable(DefaultPolynomial), seed, buffer, 0, buffer.Length); + } + + public static UInt32 Compute(UInt32 polynomial, UInt32 seed, byte[] buffer) + { + return ~CalculateHash(InitializeTable(polynomial), seed, buffer, 0, buffer.Length); + } + + private static UInt32[] InitializeTable(UInt32 polynomial) + { + if (polynomial == DefaultPolynomial && defaultTable != null) + return defaultTable; + + UInt32[] createTable = new UInt32[256]; + for (int i = 0; i < 256; i++) + { + UInt32 entry = (UInt32)i; + for (int j = 0; j < 8; j++) + if ((entry & 1) == 1) + entry = (entry >> 1) ^ polynomial; + else + entry = entry >> 1; + createTable[i] = entry; + } + + if (polynomial == DefaultPolynomial) + defaultTable = createTable; + + return createTable; + } + + private static UInt32 CalculateHash(UInt32[] table, UInt32 seed, byte[] buffer, int start, int size) + { + UInt32 crc = seed; + for (int i = start; i < size; i++) + unchecked + { + crc = (crc >> 8) ^ table[buffer[i] ^ crc & 0xff]; + } + return crc; + } + + private byte[] UInt32ToBigEndianBytes(UInt32 x) + { + return new byte[] { + (byte)((x >> 24) & 0xff), + (byte)((x >> 16) & 0xff), + (byte)((x >> 8) & 0xff), + (byte)(x & 0xff) }; + } + } +} diff --git a/OpenSim/Framework/DoubleDictionaryThreadAbortSafe.cs b/OpenSim/Framework/DoubleDictionaryThreadAbortSafe.cs index 55ec13e5d3..816523b770 100644 --- a/OpenSim/Framework/DoubleDictionaryThreadAbortSafe.cs +++ b/OpenSim/Framework/DoubleDictionaryThreadAbortSafe.cs @@ -74,21 +74,19 @@ namespace OpenSim.Framework { rwLock.EnterWriteLock(); gotLock = true; + if (Dictionary1.ContainsKey(key1)) + { + if (!Dictionary2.ContainsKey(key2)) + throw new ArgumentException("key1 exists in the dictionary but not key2"); + } + else if (Dictionary2.ContainsKey(key2)) + { + if (!Dictionary1.ContainsKey(key1)) + throw new ArgumentException("key2 exists in the dictionary but not key1"); + } + Dictionary1[key1] = value; + Dictionary2[key2] = value; } - - if (Dictionary1.ContainsKey(key1)) - { - if (!Dictionary2.ContainsKey(key2)) - throw new ArgumentException("key1 exists in the dictionary but not key2"); - } - else if (Dictionary2.ContainsKey(key2)) - { - if (!Dictionary1.ContainsKey(key1)) - throw new ArgumentException("key2 exists in the dictionary but not key1"); - } - - Dictionary1[key1] = value; - Dictionary2[key2] = value; } finally { @@ -112,10 +110,9 @@ namespace OpenSim.Framework { rwLock.EnterWriteLock(); gotLock = true; + Dictionary1.Remove(key1); + success = Dictionary2.Remove(key2); } - - Dictionary1.Remove(key1); - success = Dictionary2.Remove(key2); } finally { @@ -151,8 +148,12 @@ namespace OpenSim.Framework { if (kvp.Value.Equals(value)) { - Dictionary1.Remove(key1); - Dictionary2.Remove(kvp.Key); + try { } + finally + { + Dictionary1.Remove(key1); + Dictionary2.Remove(kvp.Key); + } found = true; break; } @@ -193,8 +194,12 @@ namespace OpenSim.Framework { if (kvp.Value.Equals(value)) { - Dictionary2.Remove(key2); - Dictionary1.Remove(kvp.Key); + try { } + finally + { + Dictionary2.Remove(key2); + Dictionary1.Remove(kvp.Key); + } found = true; break; } @@ -224,10 +229,9 @@ namespace OpenSim.Framework { rwLock.EnterWriteLock(); gotLock = true; + Dictionary1.Clear(); + Dictionary2.Clear(); } - - Dictionary1.Clear(); - Dictionary2.Clear(); } finally { @@ -485,15 +489,15 @@ namespace OpenSim.Framework try {} finally { - rwLock.EnterUpgradeableReadLock(); + rwLock.EnterWriteLock(); gotWriteLock = true; + + for (int i = 0; i < list.Count; i++) + Dictionary1.Remove(list[i]); + + for (int i = 0; i < list2.Count; i++) + Dictionary2.Remove(list2[i]); } - - for (int i = 0; i < list.Count; i++) - Dictionary1.Remove(list[i]); - - for (int i = 0; i < list2.Count; i++) - Dictionary2.Remove(list2[i]); } finally { diff --git a/OpenSim/Framework/EstateSettings.cs b/OpenSim/Framework/EstateSettings.cs index 7134cbf825..1b5ebfaafb 100644 --- a/OpenSim/Framework/EstateSettings.cs +++ b/OpenSim/Framework/EstateSettings.cs @@ -44,7 +44,6 @@ namespace OpenSim.Framework // Only the client uses these // private uint m_EstateID = 0; - public uint EstateID { get { return m_EstateID; } @@ -52,7 +51,6 @@ namespace OpenSim.Framework } private string m_EstateName = "My Estate"; - public string EstateName { get { return m_EstateName; } @@ -60,7 +58,6 @@ namespace OpenSim.Framework } private bool m_AllowLandmark = true; - public bool AllowLandmark { get { return m_AllowLandmark; } @@ -68,7 +65,6 @@ namespace OpenSim.Framework } private bool m_AllowParcelChanges = true; - public bool AllowParcelChanges { get { return m_AllowParcelChanges; } @@ -76,7 +72,6 @@ namespace OpenSim.Framework } private bool m_AllowSetHome = true; - public bool AllowSetHome { get { return m_AllowSetHome; } @@ -84,7 +79,6 @@ namespace OpenSim.Framework } private uint m_ParentEstateID = 1; - public uint ParentEstateID { get { return m_ParentEstateID; } @@ -92,7 +86,6 @@ namespace OpenSim.Framework } private float m_BillableFactor = 0.0f; - public float BillableFactor { get { return m_BillableFactor; } @@ -100,7 +93,6 @@ namespace OpenSim.Framework } private int m_PricePerMeter = 1; - public int PricePerMeter { get { return m_PricePerMeter; } @@ -108,7 +100,6 @@ namespace OpenSim.Framework } private int m_RedirectGridX = 0; - public int RedirectGridX { get { return m_RedirectGridX; } @@ -116,7 +107,6 @@ namespace OpenSim.Framework } private int m_RedirectGridY = 0; - public int RedirectGridY { get { return m_RedirectGridY; } @@ -126,7 +116,6 @@ namespace OpenSim.Framework // Used by the sim // private bool m_UseGlobalTime = true; - public bool UseGlobalTime { get { return m_UseGlobalTime; } @@ -134,7 +123,6 @@ namespace OpenSim.Framework } private bool m_FixedSun = false; - public bool FixedSun { get { return m_FixedSun; } @@ -142,7 +130,6 @@ namespace OpenSim.Framework } private double m_SunPosition = 0.0; - public double SunPosition { get { return m_SunPosition; } @@ -150,7 +137,6 @@ namespace OpenSim.Framework } private bool m_AllowVoice = true; - public bool AllowVoice { get { return m_AllowVoice; } @@ -158,7 +144,6 @@ namespace OpenSim.Framework } private bool m_AllowDirectTeleport = true; - public bool AllowDirectTeleport { get { return m_AllowDirectTeleport; } @@ -166,23 +151,22 @@ namespace OpenSim.Framework } private bool m_DenyAnonymous = false; - public bool DenyAnonymous { get { return m_DenyAnonymous; } set { m_DenyAnonymous = value; } } + // no longer in used, may be reassigned private bool m_DenyIdentified = false; - public bool DenyIdentified { get { return m_DenyIdentified; } set { m_DenyIdentified = value; } } + // no longer in used, may be reassigned private bool m_DenyTransacted = false; - public bool DenyTransacted { get { return m_DenyTransacted; } @@ -190,7 +174,6 @@ namespace OpenSim.Framework } private bool m_AbuseEmailToEstateOwner = false; - public bool AbuseEmailToEstateOwner { get { return m_AbuseEmailToEstateOwner; } @@ -198,7 +181,6 @@ namespace OpenSim.Framework } private bool m_BlockDwell = false; - public bool BlockDwell { get { return m_BlockDwell; } @@ -206,7 +188,6 @@ namespace OpenSim.Framework } private bool m_EstateSkipScripts = false; - public bool EstateSkipScripts { get { return m_EstateSkipScripts; } @@ -214,7 +195,6 @@ namespace OpenSim.Framework } private bool m_ResetHomeOnTeleport = false; - public bool ResetHomeOnTeleport { get { return m_ResetHomeOnTeleport; } @@ -222,15 +202,13 @@ namespace OpenSim.Framework } private bool m_TaxFree = false; - - public bool TaxFree + public bool TaxFree // this is now AllowAccessOverride, keeping same name to reuse DB entries { get { return m_TaxFree; } set { m_TaxFree = value; } } private bool m_PublicAccess = true; - public bool PublicAccess { get { return m_PublicAccess; } @@ -246,7 +224,6 @@ namespace OpenSim.Framework } private UUID m_EstateOwner = UUID.Zero; - public UUID EstateOwner { get { return m_EstateOwner; } @@ -254,7 +231,6 @@ namespace OpenSim.Framework } private bool m_DenyMinors = false; - public bool DenyMinors { get { return m_DenyMinors; } @@ -280,7 +256,6 @@ namespace OpenSim.Framework } private List l_EstateAccess = new List(); - public UUID[] EstateAccess { get { return l_EstateAccess.ToArray(); } @@ -288,13 +263,15 @@ namespace OpenSim.Framework } private List l_EstateGroups = new List(); - public UUID[] EstateGroups { get { return l_EstateGroups.ToArray(); } set { l_EstateGroups = new List(value); } } + public bool DoDenyMinors = true; + public bool DoDenyAnonymous = true; + public EstateSettings() { } @@ -402,14 +379,14 @@ namespace OpenSim.Framework if (!HasAccess(avatarID)) { - if (DenyMinors) + if (DoDenyMinors && DenyMinors) { if ((userFlags & 32) == 0) { return true; } } - if (DenyAnonymous) + if (DoDenyAnonymous && DenyAnonymous) { if ((userFlags & 4) == 0) { @@ -572,14 +549,41 @@ namespace OpenSim.Framework // EstateBans are special if (map.ContainsKey("EstateBans")) - { - var banData = ((Dictionary)map["EstateBans"]).Values; - EstateBan[] bans = new EstateBan[banData.Count]; - int b = 0; - foreach (Dictionary ban in banData) - bans[b++] = new EstateBan(ban); - PropertyInfo bansProperty = this.GetType().GetProperty("EstateBans", BindingFlags.Public | BindingFlags.Instance); - bansProperty.SetValue(this, bans, null); + { + if(map["EstateBans"] is string) + { + // JSON encoded bans map + Dictionary bdata = new Dictionary(); + try + { + // bypass libovm, we dont need even more useless high level maps + // this should only be called once.. but no problem, i hope + // (other uses may need more..) + LitJson.JsonMapper.RegisterImporter((input) => new UUID(input)); + bdata = LitJson.JsonMapper.ToObject>((string)map["EstateBans"]); + } + // catch(Exception e) + catch + { + return; + } + EstateBan[] jbans = new EstateBan[bdata.Count]; + bdata.Values.CopyTo(jbans,0); + + PropertyInfo jbansProperty = this.GetType().GetProperty("EstateBans", BindingFlags.Public | BindingFlags.Instance); + jbansProperty.SetValue(this, jbans, null); + } + else + { + var banData = ((Dictionary)map["EstateBans"]).Values; + EstateBan[] bans = new EstateBan[banData.Count]; + + int b = 0; + foreach (Dictionary ban in banData) + bans[b++] = new EstateBan(ban); + PropertyInfo bansProperty = this.GetType().GetProperty("EstateBans", BindingFlags.Public | BindingFlags.Instance); + bansProperty.SetValue(this, bans, null); + } } } } diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs index ab6d58fb05..f8bf583fad 100644 --- a/OpenSim/Framework/IClientAPI.cs +++ b/OpenSim/Framework/IClientAPI.cs @@ -443,7 +443,7 @@ namespace OpenSim.Framework public delegate void DeclineCallingCard(IClientAPI remoteClient, UUID transactionID); public delegate void SoundTrigger( - UUID soundId, UUID ownerid, UUID objid, UUID parentid, double Gain, Vector3 Position, UInt64 Handle, float radius); + UUID soundId, UUID ownerid, UUID objid, UUID parentid, double Gain, Vector3 Position, UInt64 Handle); public delegate void StartLure(byte lureType, string message, UUID targetID, IClientAPI client); public delegate void TeleportLureRequest(UUID lureID, uint teleportFlags, IClientAPI client); @@ -685,9 +685,10 @@ namespace OpenSim.Framework ExtraData = 1 << 20, Sound = 1 << 21, Joint = 1 << 22, - FullUpdate = 0x3fffffff, - CancelKill = 0x7fffffff, - Kill = 0x80000000 + FullUpdate = 0x0fffffff, + SendInTransit = 0x20000000, + CancelKill = 0x4fffffff, // 1 << 30 + Kill = 0x80000000 // 1 << 31 } /* included in .net 4.0 @@ -1187,7 +1188,8 @@ namespace OpenSim.Framework void SetAgentThrottleSilent(int throttle, int setting); int GetAgentThrottleSilent(int throttle); - void SendAvatarDataImmediate(ISceneEntity avatar); + void SendEntityFullUpdateImmediate(ISceneEntity entity); + void SendEntityTerseUpdateImmediate(ISceneEntity entity); /// /// Send a positional, velocity, etc. update to the viewer for a given entity. @@ -1483,7 +1485,7 @@ namespace OpenSim.Framework void SendUserInfoReply(bool imViaEmail, bool visible, string email); void SendUseCachedMuteList(); - + void SendEmpytMuteList(); void SendMuteListUpdate(string filename); void SendGroupActiveProposals(UUID groupID, UUID transactionID, GroupActiveProposals[] Proposals); diff --git a/OpenSim/Framework/ILandChannel.cs b/OpenSim/Framework/ILandChannel.cs index 44a24b94a3..e5ea596327 100644 --- a/OpenSim/Framework/ILandChannel.cs +++ b/OpenSim/Framework/ILandChannel.cs @@ -33,6 +33,8 @@ namespace OpenSim.Region.Framework.Interfaces { public interface ILandChannel { + + float BanLineSafeHeight {get;} /// /// Get all parcels /// @@ -76,6 +78,8 @@ namespace OpenSim.Region.Framework.Interfaces /// ILandObject GetLandObject(int localID); + ILandObject GetLandObject(UUID GlobalID); + /// /// Clear the land channel of all parcels. /// @@ -86,6 +90,7 @@ namespace OpenSim.Region.Framework.Interfaces bool IsForcefulBansAllowed(); void UpdateLandObject(int localID, LandData data); + void SendParcelsOverlay(IClientAPI client); void ReturnObjectsInParcel(int localID, uint returnType, UUID[] agentIDs, UUID[] taskIDs, IClientAPI remoteClient); void setParcelObjectMaxOverride(overrideParcelMaxPrimCountDelegate overrideDel); void setSimulatorObjectMaxOverride(overrideSimulatorMaxPrimCountDelegate overrideDel); @@ -94,6 +99,5 @@ namespace OpenSim.Region.Framework.Interfaces void Join(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id); void Subdivide(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id); void sendClientInitialLandInfo(IClientAPI remoteClient); - } } diff --git a/OpenSim/Framework/ILandObject.cs b/OpenSim/Framework/ILandObject.cs index f3b850d528..a7832568a2 100644 --- a/OpenSim/Framework/ILandObject.cs +++ b/OpenSim/Framework/ILandObject.cs @@ -189,5 +189,7 @@ namespace OpenSim.Framework /// /// The music url. string GetMusicUrl(); + + void Clear(); } } diff --git a/OpenSim/Framework/IMoneyModule.cs b/OpenSim/Framework/IMoneyModule.cs index be454385db..c72c742151 100644 --- a/OpenSim/Framework/IMoneyModule.cs +++ b/OpenSim/Framework/IMoneyModule.cs @@ -41,6 +41,7 @@ namespace OpenSim.Framework void ApplyCharge(UUID agentID, int amount, MoneyTransactionType type, string extraData = ""); void ApplyUploadCharge(UUID agentID, int amount, string text); void MoveMoney(UUID fromUser, UUID toUser, int amount, string text); + bool MoveMoney(UUID fromUser, UUID toUser, int amount, MoneyTransactionType type, string text); int UploadCharge { get; } int GroupCreationCharge { get; } diff --git a/OpenSim/Framework/InventoryItemBase.cs b/OpenSim/Framework/InventoryItemBase.cs index c359a0cca3..b7f27bdade 100644 --- a/OpenSim/Framework/InventoryItemBase.cs +++ b/OpenSim/Framework/InventoryItemBase.cs @@ -26,6 +26,7 @@ */ using System; +using System.Text; using OpenMetaverse; namespace OpenSim.Framework @@ -415,5 +416,40 @@ namespace OpenSim.Framework { return MemberwiseClone(); } + + public void ToLLSDxml(StringBuilder lsl) + { + LLSDxmlEncode.AddMap(lsl); + LLSDxmlEncode.AddElem("parent_id", Folder, lsl); + LLSDxmlEncode.AddElem("asset_id", AssetID, lsl); + LLSDxmlEncode.AddElem("item_id", ID, lsl); + + LLSDxmlEncode.AddMap("permissions",lsl); + LLSDxmlEncode.AddElem("creator_id", CreatorIdAsUuid, lsl); + LLSDxmlEncode.AddElem("owner_id", Owner, lsl); + LLSDxmlEncode.AddElem("group_id", GroupID, lsl); + LLSDxmlEncode.AddElem("base_mask", (int)CurrentPermissions, lsl); + LLSDxmlEncode.AddElem("owner_mask", (int)CurrentPermissions, lsl); + LLSDxmlEncode.AddElem("group_mask", (int)GroupPermissions, lsl); + LLSDxmlEncode.AddElem("everyone_mask", (int)EveryOnePermissions, lsl); + LLSDxmlEncode.AddElem("next_owner_mask", (int)NextPermissions, lsl); + LLSDxmlEncode.AddElem("is_owner_group", GroupOwned, lsl); + LLSDxmlEncode.AddEndMap(lsl); + + LLSDxmlEncode.AddElem("type", AssetType, lsl); + LLSDxmlEncode.AddElem("inv_type", InvType, lsl); + LLSDxmlEncode.AddElem("flags", ((int)Flags) & 0xff, lsl); + + LLSDxmlEncode.AddMap("sale_info",lsl); + LLSDxmlEncode.AddElem("sale_price", SalePrice, lsl); + LLSDxmlEncode.AddElem("sale_type", SaleType, lsl); + LLSDxmlEncode.AddEndMap(lsl); + + LLSDxmlEncode.AddElem("name", Name, lsl); + LLSDxmlEncode.AddElem("desc", Description, lsl); + LLSDxmlEncode.AddElem("created_at", CreationDate, lsl); + + LLSDxmlEncode.AddEndMap(lsl); + } } } diff --git a/OpenSim/Framework/LLSDxmlEncode.cs b/OpenSim/Framework/LLSDxmlEncode.cs new file mode 100644 index 0000000000..ed5c4db284 --- /dev/null +++ b/OpenSim/Framework/LLSDxmlEncode.cs @@ -0,0 +1,725 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// a class for low level LLSD encoding into a provided StringBuilder +// for cases where we already need to know the low level detail +// and so using something like OSD or even protbuf is just a pure waste + +using System; +using System.Globalization; +using System.Text; +using OpenMetaverse; + +namespace OpenSim.Framework +{ + public static class LLSDxmlEncode + { + static readonly DateTime depoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); + + public static void AddStart(StringBuilder sb, bool addxmlversion = false) + { + if(addxmlversion) + sb.Append(""); // legacy llsd xml name still valid + else + sb.Append(""); + } + + // got tired of creating a stringbuilder all the time; + public static StringBuilder Start(int size = 256, bool addxmlversion = false) + { + StringBuilder sb = new StringBuilder(size); + if(addxmlversion) + sb.Append(""); // legacy llsd xml name still valid + else + sb.Append(""); + return sb; + } + + public static void AddEnd(StringBuilder sb) + { + sb.Append(""); + } + + public static string End(StringBuilder sb) + { + sb.Append(""); + return sb.ToString(); + } + + // map == a list of key value pairs + public static void AddMap(StringBuilder sb) + { + sb.Append(""); + } + + public static void AddEndMap(StringBuilder sb) + { + sb.Append(""); + } + + public static void AddEmptyMap(StringBuilder sb) + { + sb.Append(""); + } + + // array == a list values + public static void AddArray(StringBuilder sb) + { + sb.Append(""); + } + + public static void AddEndArray(StringBuilder sb) + { + sb.Append(""); + } + + public static void AddEmptyArray(StringBuilder sb) + { + sb.Append(""); + } + + // undefined or null + public static void AddUnknownElem(StringBuilder sb) + { + sb.Append(""); + } + + public static void AddElem(bool e, StringBuilder sb) + { + if(e) + sb.Append("1"); + else + sb.Append(""); + } + + public static void AddElem(byte e, StringBuilder sb) + { + if(e == 0) + sb.Append(""); + else + { + sb.Append(""); + sb.Append(e.ToString()); + sb.Append(""); + } + } + + public static void AddElem(byte[] e, StringBuilder sb) + { + if(e == null || e.Length == 0) + sb.Append("binary />"); + else + { + sb.Append(""); // encode64 is default + sb.Append(Convert.ToBase64String(e,Base64FormattingOptions.None)); + sb.Append(""); + } + } + + public static void AddElem(int e, StringBuilder sb) + { + if(e == 0) + sb.Append(""); + else + { + sb.Append(""); + sb.Append(e.ToString()); + sb.Append(""); + } + } + + public static void AddElem(float e, StringBuilder sb) + { + if(e == 0) + sb.Append(""); + else + { + sb.Append(""); + sb.Append(e.ToString(CultureInfo.InvariantCulture)); + sb.Append(""); + } + } + + public static void AddElem(Vector2 e, StringBuilder sb) + { + sb.Append("x"); + + if(e.X == 0) + sb.Append("y"); + else + { + sb.Append(""); + sb.Append(e.X.ToString(CultureInfo.InvariantCulture)); + sb.Append("y"); + } + + if(e.Y == 0) + sb.Append(""); + else + { + sb.Append(""); + sb.Append(e.Y.ToString(CultureInfo.InvariantCulture)); + sb.Append(""); + } + } + + public static void AddElem(Vector3 e, StringBuilder sb) + { + sb.Append("key>x"); + + if(e.X == 0) + sb.Append("y"); + else + { + sb.Append(""); + sb.Append(e.X.ToString(CultureInfo.InvariantCulture)); + sb.Append("y"); + } + + if(e.Y == 0) + sb.Append("z"); + else + { + sb.Append(""); + sb.Append(e.Y.ToString(CultureInfo.InvariantCulture)); + sb.Append("z"); + } + + if(e.Z == 0) + sb.Append(""); + else + { + sb.Append(""); + sb.Append(e.Z.ToString(CultureInfo.InvariantCulture)); + sb.Append(""); + } + } + + public static void AddElem(Quaternion e, StringBuilder sb) + { + sb.Append("x"); + + if(e.X == 0) + sb.Append("y"); + else + { + sb.Append(""); + sb.Append(e.X.ToString(CultureInfo.InvariantCulture)); + sb.Append("y"); + } + + if(e.Y == 0) + sb.Append("z"); + else + { + sb.Append(""); + sb.Append(e.Y.ToString(CultureInfo.InvariantCulture)); + sb.Append("z"); + } + if(e.Z == 0) + sb.Append("w"); + else + { + sb.Append(""); + sb.Append(e.Z.ToString(CultureInfo.InvariantCulture)); + sb.Append("w"); + } + + if(e.W == 0) + sb.Append(""); + else + { + sb.Append(""); + sb.Append(e.W.ToString(CultureInfo.InvariantCulture)); + sb.Append(""); + } + } + + public static void AddElem(double e, StringBuilder sb) + { + if(e == 0) + sb.Append(""); + else + { + sb.Append(""); + sb.Append(e.ToString(CultureInfo.InvariantCulture)); + sb.Append(""); + } + } + + public static void AddElem(UUID e, StringBuilder sb) + { + if(e == UUID.Zero) + sb.Append(""); + else + { + sb.Append(""); + EscapeToXML(e.ToString(), sb); + sb.Append(""); + } + } + + public static void AddElem(string e, StringBuilder sb) + { + if(String.IsNullOrEmpty(e)) + sb.Append(""); + else + { + sb.Append(""); + EscapeToXML(e.ToString(), sb); + sb.Append(""); + } + } + + public static void AddRawElem(string e, StringBuilder sb) + { + if(String.IsNullOrEmpty(e)) + sb.Append(""); + else + { + sb.Append(""); + sb.Append(e); + sb.Append(""); + } + } + + public static void AddElem(Uri e, StringBuilder sb) + { + if(e == null) + { + sb.Append(""); + return; + } + + string s; + if (e.IsAbsoluteUri) + s = e.AbsoluteUri; + else + s = e.ToString(); + + if(String.IsNullOrEmpty(s)) + sb.Append(""); + else + { + sb.Append(""); + sb.Append(s); + sb.Append(""); + } + } + + public static void AddElem(DateTime e, StringBuilder sb) + { + DateTime u = e.ToUniversalTime(); + if(u == depoch) + { + sb.Append(""); + return; + } + string format; + if(u.Hour == 0 && u.Minute == 0 && u.Second == 0) + format = "yyyy-MM-dd"; + else if (u.Millisecond > 0) + format = "yyyy-MM-ddTHH:mm:ss.ffZ"; + else + format = "yyyy-MM-ddTHH:mm:ssZ"; + sb.Append(""); + sb.Append(u.ToString(format,CultureInfo.InvariantCulture)); + sb.Append(""); + } + +//************ key value ******************* +// assumes name is a valid llsd key + + public static void AddMap(string name, StringBuilder sb) + { + sb.Append(""); + sb.Append(name); + sb.Append(""); + } + + public static void AddEmptyMap(string name, StringBuilder sb) + { + sb.Append(""); + sb.Append(name); + sb.Append(""); + } + + // array == a list values + public static void AddArray(string name, StringBuilder sb) + { + sb.Append(""); + sb.Append(name); + sb.Append(""); + } + + public static void AddEmptyArray(string name, StringBuilder sb) + { + sb.Append(""); + sb.Append(name); + sb.Append(""); + } + + // undefined or null + public static void AddUnknownElem(string name, StringBuilder sb) + { + sb.Append(""); + sb.Append(name); + sb.Append(""); + } + + public static void AddElem(string name, bool e, StringBuilder sb) + { + sb.Append(""); + sb.Append(name); + sb.Append(""); + + if(e) + sb.Append("1"); + else + sb.Append(""); + } + + public static void AddElem(string name, byte e, StringBuilder sb) + { + sb.Append(""); + sb.Append(name); + sb.Append(""); + + if(e == 0) + sb.Append(""); + else + { + sb.Append(""); + sb.Append(e.ToString()); + sb.Append(""); + } + } + + public static void AddElem(string name, byte[] e, StringBuilder sb) + { + sb.Append(""); + sb.Append(name); + sb.Append(""); + + if(e == null || e.Length == 0) + sb.Append("binary />"); + else + { + sb.Append(""); // encode64 is default + sb.Append(Convert.ToBase64String(e,Base64FormattingOptions.None)); + sb.Append(""); + } + } + + public static void AddElem(string name, int e, StringBuilder sb) + { + sb.Append(""); + sb.Append(name); + sb.Append(""); + + if(e == 0) + sb.Append(""); + else + { + sb.Append(""); + sb.Append(e.ToString()); + sb.Append(""); + } + } + + public static void AddElem(string name, float e, StringBuilder sb) + { + sb.Append(""); + sb.Append(name); + sb.Append(""); + + if(e == 0) + sb.Append(""); + else + { + sb.Append(""); + sb.Append(e.ToString(CultureInfo.InvariantCulture)); + sb.Append(""); + } + } + + public static void AddElem(string name, Vector2 e, StringBuilder sb) + { + sb.Append(""); + sb.Append(name); + sb.Append("x"); + + if(e.X == 0) + sb.Append("y"); + else + { + sb.Append(""); + sb.Append(e.X.ToString(CultureInfo.InvariantCulture)); + sb.Append("y"); + } + + if(e.Y == 0) + sb.Append(""); + else + { + sb.Append(""); + sb.Append(e.Y.ToString(CultureInfo.InvariantCulture)); + sb.Append(""); + } + } + + public static void AddElem(string name, Vector3 e, StringBuilder sb) + { + sb.Append(""); + sb.Append(name); + sb.Append("key>x"); + + if(e.X == 0) + sb.Append("y"); + else + { + sb.Append(""); + sb.Append(e.X.ToString(CultureInfo.InvariantCulture)); + sb.Append("y"); + } + + if(e.Y == 0) + sb.Append("z"); + else + { + sb.Append(""); + sb.Append(e.Y.ToString(CultureInfo.InvariantCulture)); + sb.Append("z"); + } + + if(e.Z == 0) + sb.Append(""); + else + { + sb.Append(""); + sb.Append(e.Z.ToString(CultureInfo.InvariantCulture)); + sb.Append(""); + } + } + + public static void AddElem(string name, Quaternion e, StringBuilder sb) + { + sb.Append(""); + sb.Append(name); + sb.Append("x"); + + if(e.X == 0) + sb.Append("y"); + else + { + sb.Append(""); + sb.Append(e.X.ToString(CultureInfo.InvariantCulture)); + sb.Append("y"); + } + + if(e.Y == 0) + sb.Append("z"); + else + { + sb.Append(""); + sb.Append(e.Y.ToString(CultureInfo.InvariantCulture)); + sb.Append("z"); + } + if(e.Z == 0) + sb.Append("w"); + else + { + sb.Append(""); + sb.Append(e.Z.ToString(CultureInfo.InvariantCulture)); + sb.Append("w"); + } + + if(e.W == 0) + sb.Append(""); + else + { + sb.Append(""); + sb.Append(e.W.ToString(CultureInfo.InvariantCulture)); + sb.Append(""); + } + } + + public static void AddElem(string name, double e, StringBuilder sb) + { + sb.Append(""); + sb.Append(name); + sb.Append(""); + + if(e == 0) + sb.Append(""); + else + { + sb.Append(""); + sb.Append(e.ToString(CultureInfo.InvariantCulture)); + sb.Append(""); + } + } + + public static void AddElem(string name, UUID e, StringBuilder sb) + { + sb.Append(""); + sb.Append(name); + sb.Append(""); + + if(e == UUID.Zero) + sb.Append(""); + else + { + sb.Append(""); + EscapeToXML(e.ToString(), sb); + sb.Append(""); + } + } + + public static void AddElem(string name, string e, StringBuilder sb) + { + sb.Append(""); + sb.Append(name); + sb.Append(""); + + if(String.IsNullOrEmpty(e)) + sb.Append(""); + else + { + sb.Append(""); + EscapeToXML(e.ToString(), sb); + sb.Append(""); + } + } + + public static void AddRawElem(string name, string e, StringBuilder sb) + { + sb.Append(""); + sb.Append(name); + sb.Append(""); + + if(String.IsNullOrEmpty(e)) + sb.Append(""); + else + { + sb.Append(""); + sb.Append(e); + sb.Append(""); + } + } + + public static void AddElem(string name, Uri e, StringBuilder sb) + { + sb.Append(""); + sb.Append(name); + sb.Append(""); + + if(e == null) + { + sb.Append(""); + return; + } + + string s; + if (e.IsAbsoluteUri) + s = e.AbsoluteUri; + else + s = e.ToString(); + + if(String.IsNullOrEmpty(s)) + sb.Append(""); + else + { + sb.Append(""); + sb.Append(s); + sb.Append(""); + } + } + + public static void AddElem(string name, DateTime e, StringBuilder sb) + { + sb.Append(""); + sb.Append(name); + sb.Append(""); + + DateTime u = e.ToUniversalTime(); + if(u == depoch) + { + sb.Append(""); + return; + } + string format; + if(u.Hour == 0 && u.Minute == 0 && u.Second == 0) + format = "yyyy-MM-dd"; + else if (u.Millisecond > 0) + format = "yyyy-MM-ddTHH:mm:ss.ffZ"; + else + format = "yyyy-MM-ddTHH:mm:ssZ"; + sb.Append(""); + sb.Append(u.ToString(format,CultureInfo.InvariantCulture)); + sb.Append(""); + } + + public static void AddLLSD(string e, StringBuilder sb) + { + sb.Append(e); + } + + public static void EscapeToXML(string s, StringBuilder sb) + { + int i; + char c; + int len = s.Length; + + for (i = 0; i < len; i++) + { + c = s[i]; + switch (c) + { + case '<': + sb.Append("<"); + break; + case '>': + sb.Append(">"); + break; + case '&': + sb.Append("&"); + break; + case '"': + sb.Append("""); + break; + case '\\': + sb.Append("'"); + break; + default: + sb.Append(c); + break; + } + } + } + } +} diff --git a/OpenSim/Framework/LandData.cs b/OpenSim/Framework/LandData.cs index 13d29776c5..13b58be3dd 100644 --- a/OpenSim/Framework/LandData.cs +++ b/OpenSim/Framework/LandData.cs @@ -97,7 +97,9 @@ namespace OpenSim.Framework private bool _mediaLoop = false; private bool _obscureMusic = false; private bool _obscureMedia = false; - private float _dwell = 0; + + private float m_dwell = 0; + public double LastDwellTimeMS; public bool SeeAVs { get; set; } public bool AnyAVSounds { get; set; } @@ -111,11 +113,12 @@ namespace OpenSim.Framework { get { - return _dwell; + return m_dwell; } set { - _dwell = value; + m_dwell = value; + LastDwellTimeMS = Util.GetTimeStampMS(); } } @@ -735,6 +738,7 @@ namespace OpenSim.Framework SeeAVs = true; AnyAVSounds = true; GroupAVSounds = true; + LastDwellTimeMS = Util.GetTimeStampMS(); } /// @@ -784,7 +788,7 @@ namespace OpenSim.Framework landData._obscureMedia = _obscureMedia; landData._simwideArea = _simwideArea; landData._simwidePrims = _simwidePrims; - landData._dwell = _dwell; + landData.m_dwell = m_dwell; landData.SeeAVs = SeeAVs; landData.AnyAVSounds = AnyAVSounds; landData.GroupAVSounds = GroupAVSounds; diff --git a/OpenSim/Framework/MinHeap.cs b/OpenSim/Framework/MinHeap.cs index 99ac25d09d..68f66683e0 100644 --- a/OpenSim/Framework/MinHeap.cs +++ b/OpenSim/Framework/MinHeap.cs @@ -45,8 +45,8 @@ namespace OpenSim.Framework internal void Clear() { - this.index = -1; - this.heap = null; + index = -1; + heap = null; } } @@ -55,23 +55,26 @@ namespace OpenSim.Framework internal T value; internal Handle handle; - internal HeapItem(T value, Handle handle) + internal HeapItem(T _value, Handle _handle) { - this.value = value; - this.handle = handle; + value = _value; + handle = _handle; } internal void Clear() { - if (this.handle != null) - this.handle.Clear(); - ClearRef(); + if (handle != null) + { + handle.Clear(); + handle = null; + } + value = default(T); } internal void ClearRef() { - this.value = default(T); - this.handle = null; + value = default(T); + handle = null; } } @@ -81,6 +84,7 @@ namespace OpenSim.Framework private int size; private object sync_root; private int version; + private int capacity; private Comparison comparison; @@ -90,14 +94,15 @@ namespace OpenSim.Framework public MinHeap(int capacity, IComparer comparer) : this(capacity, new Comparison(comparer.Compare)) { } public MinHeap(Comparison comparison) : this(DEFAULT_CAPACITY, comparison) { } - public MinHeap(int capacity, Comparison comparison) + public MinHeap(int _capacity, Comparison _comparison) { - this.items = new HeapItem[capacity]; - this.comparison = comparison; - this.size = this.version = 0; + capacity = _capacity; + items = new HeapItem[capacity]; + comparison = _comparison; + size = version = 0; } - public int Count { get { return this.size; } } + public int Count { get { return size; } } public bool IsReadOnly { get { return false; } } @@ -108,15 +113,16 @@ namespace OpenSim.Framework get { Handle handle = ValidateThisHandle(key); - return this.items[handle.index].value; + return items[handle.index].value; } set { Handle handle = ValidateThisHandle(key); - this.items[handle.index].value = value; - if (!BubbleUp(handle.index)) - BubbleDown(handle.index); + int indx = handle.index; + items[indx].value = value; + if (!BubbleUp(indx)) + BubbleDown(indx); } } @@ -124,9 +130,9 @@ namespace OpenSim.Framework { get { - if (this.sync_root == null) - Interlocked.CompareExchange(ref this.sync_root, new object(), null); - return this.sync_root; + if (sync_root == null) + Interlocked.CompareExchange(ref sync_root, new object(), null); + return sync_root; } } @@ -152,27 +158,27 @@ namespace OpenSim.Framework private void Set(HeapItem item, int index) { - this.items[index] = item; + items[index] = item; if (item.handle != null) item.handle.index = index; } private bool BubbleUp(int index) { - HeapItem item = this.items[index]; + HeapItem item = items[index]; int current, parent; for (current = index, parent = (current - 1) / 2; - (current > 0) && (this.comparison(this.items[parent].value, item.value)) > 0; + (current > 0) && (comparison(items[parent].value, item.value)) > 0; current = parent, parent = (current - 1) / 2) { - Set(this.items[parent], current); + Set(items[parent], current); } if (current != index) { Set(item, current); - ++this.version; + ++version; return true; } return false; @@ -180,24 +186,24 @@ namespace OpenSim.Framework private void BubbleDown(int index) { - HeapItem item = this.items[index]; + HeapItem item = items[index]; int current, child; for (current = index, child = (2 * current) + 1; - current < this.size / 2; + current < size / 2; current = child, child = (2 * current) + 1) { - if ((child < this.size - 1) && this.comparison(this.items[child].value, this.items[child + 1].value) > 0) + if ((child < size - 1) && comparison(items[child].value, items[child + 1].value) > 0) ++child; - if (this.comparison(this.items[child].value, item.value) >= 0) + if (comparison(items[child].value, item.value) >= 0) break; - Set(this.items[child], current); + Set(items[child], current); } if (current != index) { Set(item, current); - ++this.version; + ++version; } } @@ -206,7 +212,7 @@ namespace OpenSim.Framework Handle handle = ValidateHandle(key); if (handle.index > -1) { - value = this.items[handle.index].value; + value = items[handle.index].value; return true; } value = default(T); @@ -228,12 +234,12 @@ namespace OpenSim.Framework public void Add(T value, IHandle ihandle) { - if (this.size == this.items.Length) + if (size == items.Length) { - int capacity = (int)((this.items.Length * 200L) / 100L); - if (capacity < (this.items.Length + DEFAULT_CAPACITY)) - capacity = this.items.Length + DEFAULT_CAPACITY; - Array.Resize(ref this.items, capacity); + int capacity = (int)((items.Length * 200L) / 100L); + if (capacity < (items.Length + DEFAULT_CAPACITY)) + capacity = items.Length + DEFAULT_CAPACITY; + Array.Resize(ref items, capacity); } Handle handle = null; @@ -245,8 +251,8 @@ namespace OpenSim.Framework HeapItem item = new MinHeap.HeapItem(value, handle); - Set(item, this.size); - BubbleUp(this.size++); + Set(item, size); + BubbleUp(size++); } public void Add(T value) @@ -256,50 +262,54 @@ namespace OpenSim.Framework public T Min() { - if (this.size == 0) + if (size == 0) throw new InvalidOperationException("Heap is empty"); - return this.items[0].value; + return items[0].value; } public void Clear() { - for (int index = 0; index < this.size; ++index) - this.items[index].Clear(); - this.size = 0; - ++this.version; + for (int index = 0; index < size; ++index) + items[index].Clear(); + size = 0; + if(items.Length > capacity) + items = new HeapItem[capacity]; + ++version; } public void TrimExcess() { - int length = (int)(this.items.Length * 0.9); - if (this.size < length) - Array.Resize(ref this.items, Math.Min(this.size, DEFAULT_CAPACITY)); + int length = (int)(items.Length * 0.9); + if (size < length) + Array.Resize(ref items, Math.Min(size, capacity)); } private void RemoveAt(int index) { - if (this.size == 0) + if (size == 0) throw new InvalidOperationException("Heap is empty"); - if (index >= this.size) + if (index >= size) throw new ArgumentOutOfRangeException("index"); - this.items[index].Clear(); - if (--this.size > 0 && index != this.size) + items[index].Clear(); + if (--size > 0 && index != size) { - Set(this.items[this.size], index); - this.items[this.size].ClearRef(); + Set(items[size], index); + items[size].ClearRef(); if (!BubbleUp(index)) BubbleDown(index); } + if(size == 0 && items.Length > 4 * capacity) + items = new HeapItem[capacity]; } public T RemoveMin() { - if (this.size == 0) + if (size == 0) throw new InvalidOperationException("Heap is empty"); - HeapItem item = this.items[0]; + HeapItem item = items[0]; RemoveAt(0); return item.value; } @@ -307,7 +317,7 @@ namespace OpenSim.Framework public T Remove(IHandle ihandle) { Handle handle = ValidateThisHandle(ihandle); - HeapItem item = this.items[handle.index]; + HeapItem item = items[handle.index]; RemoveAt(handle.index); return item.value; } @@ -317,9 +327,9 @@ namespace OpenSim.Framework EqualityComparer comparer = EqualityComparer.Default; int index; - for (index = 0; index < this.size; ++index) + for (index = 0; index < size; ++index) { - if (comparer.Equals(this.items[index].value, value)) + if (comparer.Equals(items[index].value, value)) return index; } return -1; @@ -356,8 +366,8 @@ namespace OpenSim.Framework if ((length - index) < this.size) throw new ArgumentException("Not enough space available in array starting at index"); - for (int i = 0; i < this.size; ++i) - array[index + i] = this.items[i].value; + for (int i = 0; i < size; ++i) + array[index + i] = items[i].value; } public void CopyTo(Array array, int index) @@ -372,13 +382,13 @@ namespace OpenSim.Framework int length = array.Length; if ((index < 0) || (index > length)) throw new ArgumentOutOfRangeException("index"); - if ((length - index) < this.size) + if ((length - index) < size) throw new ArgumentException("Not enough space available in array starting at index"); try { - for (int i = 0; i < this.size; ++i) - array.SetValue(this.items[i].value, index + i); + for (int i = 0; i < size; ++i) + array.SetValue(items[i].value, index + i); } catch (ArrayTypeMismatchException) { @@ -388,13 +398,13 @@ namespace OpenSim.Framework public IEnumerator GetEnumerator() { - int version = this.version; + int cversion = version; - for (int index = 0; index < this.size; ++index) + for (int index = 0; index < size; ++index) { - if (version != this.version) + if (cversion != version) throw new InvalidOperationException("Heap was modified while enumerating"); - yield return this.items[index].value; + yield return items[index].value; } } diff --git a/OpenSim/Framework/Monitoring/JobEngine.cs b/OpenSim/Framework/Monitoring/JobEngine.cs index 0a39e4b6be..6c388b3b76 100644 --- a/OpenSim/Framework/Monitoring/JobEngine.cs +++ b/OpenSim/Framework/Monitoring/JobEngine.cs @@ -57,7 +57,8 @@ namespace OpenSim.Framework.Monitoring /// /// Will be null if no job is currently running. /// - public Job CurrentJob { get; private set; } + private Job m_currentJob; + public Job CurrentJob { get { return m_currentJob;} } /// /// Number of jobs waiting to be processed. @@ -78,20 +79,19 @@ namespace OpenSim.Framework.Monitoring /// private bool m_warnOverMaxQueue = true; - private BlockingCollection m_jobQueue = new BlockingCollection(new ConcurrentQueue(), 5000); + private BlockingCollection m_jobQueue = new BlockingCollection(5000); private CancellationTokenSource m_cancelSource; - /// - /// Used to signal that we are ready to complete stop. - /// - private ManualResetEvent m_finishedProcessingAfterStop = new ManualResetEvent(false); + private int m_timeout = -1; - public JobEngine(string name, string loggingName) + private bool m_threadRunnig = false; + + public JobEngine(string name, string loggingName, int timeout = -1) { Name = name; LoggingName = loggingName; - + m_timeout = timeout; RequestProcessTimeoutOnStop = 5000; } @@ -104,18 +104,9 @@ namespace OpenSim.Framework.Monitoring IsRunning = true; - m_finishedProcessingAfterStop.Reset(); - m_cancelSource = new CancellationTokenSource(); - - WorkManager.StartThread( - ProcessRequests, - Name, - ThreadPriority.Normal, - false, - true, - null, - int.MaxValue); + WorkManager.RunInThreadPool(ProcessRequests, null, Name, false); + m_threadRunnig = true; } } @@ -131,17 +122,16 @@ namespace OpenSim.Framework.Monitoring m_log.DebugFormat("[JobEngine] Stopping {0}", Name); IsRunning = false; - - m_finishedProcessingAfterStop.Reset(); - if(m_jobQueue.Count <= 0) + if(m_threadRunnig) + { m_cancelSource.Cancel(); - - if(m_finishedProcessingAfterStop.WaitOne(RequestProcessTimeoutOnStop)) - m_finishedProcessingAfterStop.Close(); + m_threadRunnig = false; + } } finally { - m_cancelSource.Dispose(); + if(m_cancelSource != null) + m_cancelSource.Dispose(); } } } @@ -200,6 +190,18 @@ namespace OpenSim.Framework.Monitoring /// public bool QueueJob(Job job) { + lock(JobLock) + { + if(!IsRunning) + return false; + + if(!m_threadRunnig) + { + WorkManager.RunInThreadPool(ProcessRequests, null, Name, false); + m_threadRunnig = true; + } + } + if (m_jobQueue.Count < m_jobQueue.BoundedCapacity) { m_jobQueue.Add(job); @@ -219,59 +221,53 @@ namespace OpenSim.Framework.Monitoring m_warnOverMaxQueue = false; } - return false; } } - private void ProcessRequests() + private void ProcessRequests(Object o) { - while(IsRunning || m_jobQueue.Count > 0) + while(IsRunning) { try { - CurrentJob = m_jobQueue.Take(m_cancelSource.Token); - } - catch(ObjectDisposedException e) - { - // If we see this whilst not running then it may be due to a race where this thread checks - // IsRunning after the stopping thread sets it to false and disposes of the cancellation source. - if(IsRunning) - throw e; - else + if(!m_jobQueue.TryTake(out m_currentJob, m_timeout, m_cancelSource.Token)) { - m_log.DebugFormat("[JobEngine] {0} stopping ignoring {1} jobs in queue", - Name,m_jobQueue.Count); + lock(JobLock) + m_threadRunnig = false; break; } } + catch(ObjectDisposedException) + { + m_log.DebugFormat("[JobEngine] {0} stopping ignoring {1} jobs in queue", + Name,m_jobQueue.Count); + break; + } catch(OperationCanceledException) { break; } if(LogLevel >= 1) - m_log.DebugFormat("[{0}]: Processing job {1}",LoggingName,CurrentJob.Name); + m_log.DebugFormat("[{0}]: Processing job {1}",LoggingName,m_currentJob.Name); try { - CurrentJob.Action(); + m_currentJob.Action(); } catch(Exception e) { m_log.Error( string.Format( - "[{0}]: Job {1} failed, continuing. Exception ",LoggingName,CurrentJob.Name),e); + "[{0}]: Job {1} failed, continuing. Exception ",LoggingName,m_currentJob.Name),e); } if(LogLevel >= 1) - m_log.DebugFormat("[{0}]: Processed job {1}",LoggingName,CurrentJob.Name); + m_log.DebugFormat("[{0}]: Processed job {1}",LoggingName,m_currentJob.Name); - CurrentJob = null; + m_currentJob = null; } - - Watchdog.RemoveThread(false); - m_finishedProcessingAfterStop.Set(); } public class Job diff --git a/OpenSim/Framework/Monitoring/ServerStatsCollector.cs b/OpenSim/Framework/Monitoring/ServerStatsCollector.cs index 3391240ce5..a26a6e0366 100644 --- a/OpenSim/Framework/Monitoring/ServerStatsCollector.cs +++ b/OpenSim/Framework/Monitoring/ServerStatsCollector.cs @@ -88,7 +88,7 @@ namespace OpenSim.Framework.Monitoring IConfig cfg = source.Configs["Monitoring"]; if (cfg != null) - Enabled = cfg.GetBoolean("ServerStatsEnabled", true); + Enabled = cfg.GetBoolean("ServerStatsEnabled", false); if (Enabled) { @@ -98,12 +98,18 @@ namespace OpenSim.Framework.Monitoring public void Start() { + if(!Enabled) + return; + if (RegisteredStats.Count == 0) RegisterServerStats(); } public void Close() { + if(!Enabled) + return; + if (RegisteredStats.Count > 0) { foreach (Stat stat in RegisteredStats.Values) diff --git a/OpenSim/Framework/Monitoring/Stats/Stat.cs b/OpenSim/Framework/Monitoring/Stats/Stat.cs index 2402acd2d1..4b1a2290c9 100644 --- a/OpenSim/Framework/Monitoring/Stats/Stat.cs +++ b/OpenSim/Framework/Monitoring/Stats/Stat.cs @@ -242,11 +242,7 @@ namespace OpenSim.Framework.Monitoring public virtual OSDMap ToBriefOSDMap() { OSDMap ret = new OSDMap(); - ret.Add("Value", OSD.FromReal(Value)); - - double lastChangeOverTime, averageChangeOverTime; - return ret; } diff --git a/OpenSim/Framework/Monitoring/Watchdog.cs b/OpenSim/Framework/Monitoring/Watchdog.cs index 9cc61ee62d..ad21d938a1 100644 --- a/OpenSim/Framework/Monitoring/Watchdog.cs +++ b/OpenSim/Framework/Monitoring/Watchdog.cs @@ -180,6 +180,33 @@ namespace OpenSim.Framework.Monitoring m_watchdogTimer.Elapsed += WatchdogTimerElapsed; } + public static void Stop() + { + if(m_threads == null) + return; + + lock(m_threads) + { + m_enabled = false; + if(m_watchdogTimer != null) + { + m_watchdogTimer.Dispose(); + m_watchdogTimer = null; + } + + foreach(ThreadWatchdogInfo twi in m_threads.Values) + { + Thread t = twi.Thread; + // m_log.DebugFormat( + // "[WATCHDOG]: Stop: Removing thread {0}, ID {1}", twi.Thread.Name, twi.Thread.ManagedThreadId); + + if(t.IsAlive) + t.Abort(); + } + m_threads.Clear(); + } + } + /// /// Add a thread to the watchdog tracker. /// @@ -230,14 +257,12 @@ namespace OpenSim.Framework.Monitoring twi.Cleanup(); m_threads.Remove(threadID); - return true; } else { m_log.WarnFormat( "[WATCHDOG]: Requested to remove thread with ID {0} but this is not being monitored", threadID); - return false; } } @@ -317,6 +342,8 @@ namespace OpenSim.Framework.Monitoring /// private static void WatchdogTimerElapsed(object sender, System.Timers.ElapsedEventArgs e) { + if(!m_enabled) + return; int now = Environment.TickCount & Int32.MaxValue; int msElapsed = now - LastWatchdogThreadTick; @@ -334,21 +361,26 @@ namespace OpenSim.Framework.Monitoring List callbackInfos = null; List threadsToRemove = null; + const ThreadState thgone = ThreadState.Stopped; + lock (m_threads) { foreach(ThreadWatchdogInfo threadInfo in m_threads.Values) { - if(threadInfo.Thread.ThreadState == ThreadState.Stopped) + if(!m_enabled) + return; + if((threadInfo.Thread.ThreadState & thgone) != 0) { if(threadsToRemove == null) threadsToRemove = new List(); threadsToRemove.Add(threadInfo); - +/* if(callbackInfos == null) callbackInfos = new List(); callbackInfos.Add(threadInfo); +*/ } else if(!threadInfo.IsTimedOut && now - threadInfo.LastTick >= threadInfo.Timeout) { diff --git a/OpenSim/Framework/Monitoring/WorkManager.cs b/OpenSim/Framework/Monitoring/WorkManager.cs index 43130f9a0b..5d9b185f29 100644 --- a/OpenSim/Framework/Monitoring/WorkManager.cs +++ b/OpenSim/Framework/Monitoring/WorkManager.cs @@ -57,7 +57,7 @@ namespace OpenSim.Framework.Monitoring static WorkManager() { - JobEngine = new JobEngine("Non-blocking non-critical job engine", "JOB ENGINE"); + JobEngine = new JobEngine("Non-blocking non-critical job engine", "JOB ENGINE", 30000); StatsManager.RegisterStat( new Stat( @@ -82,6 +82,12 @@ namespace OpenSim.Framework.Monitoring HandleControlCommand); } + public static void Stop() + { + JobEngine.Stop(); + Watchdog.Stop(); + } + /// /// Start a new long-lived thread. /// @@ -131,7 +137,6 @@ namespace OpenSim.Framework.Monitoring thread.Start(); - return thread; } @@ -177,9 +182,9 @@ namespace OpenSim.Framework.Monitoring /// /// /// The name of the job. This is used in monitoring and debugging. - public static void RunInThreadPool(System.Threading.WaitCallback callback, object obj, string name) + public static void RunInThreadPool(System.Threading.WaitCallback callback, object obj, string name, bool timeout = true) { - Util.FireAndForget(callback, obj, name); + Util.FireAndForget(callback, obj, name, timeout); } /// @@ -226,10 +231,8 @@ namespace OpenSim.Framework.Monitoring JobEngine.QueueJob(name, () => callback(obj)); else if (canRunInThisThread) callback(obj); - else if (mustNotTimeout) - RunInThread(callback, obj, name, log); else - Util.FireAndForget(callback, obj, name); + Util.FireAndForget(callback, obj, name, !mustNotTimeout); } private static void HandleControlCommand(string module, string[] args) diff --git a/OpenSim/Framework/MuteData.cs b/OpenSim/Framework/MuteData.cs new file mode 100644 index 0000000000..7c946d6650 --- /dev/null +++ b/OpenSim/Framework/MuteData.cs @@ -0,0 +1,41 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using OpenMetaverse; + +namespace OpenSim.Framework +{ + public class MuteData + { + public UUID AgentID; + public UUID MuteID; + public string MuteName; + public int MuteType; + public int MuteFlags; + public int Stamp; + } +} diff --git a/OpenSim/Framework/NetworkServersInfo.cs b/OpenSim/Framework/NetworkServersInfo.cs index dfe9695abe..d79eb0dec9 100644 --- a/OpenSim/Framework/NetworkServersInfo.cs +++ b/OpenSim/Framework/NetworkServersInfo.cs @@ -37,6 +37,8 @@ namespace OpenSim.Framework public bool isSandbox; public bool HttpUsesSSL = false; public string HttpSSLCN = ""; + public string HttpSSLCertPath = ""; + public string HttpSSLCNCertPass = ""; public uint httpSSLPort = 9001; // "Out of band" managemnt https @@ -62,6 +64,8 @@ namespace OpenSim.Framework (uint)config.Configs["Network"].GetInt("http_listener_sslport", ((int)ConfigSettings.DefaultRegionHttpPort+1)); HttpUsesSSL = config.Configs["Network"].GetBoolean("http_listener_ssl", false); HttpSSLCN = config.Configs["Network"].GetString("http_listener_cn", "localhost"); + HttpSSLCertPath = config.Configs["Network"].GetString("http_listener_cert_path", HttpSSLCertPath); + HttpSSLCNCertPass = config.Configs["Network"].GetString("http_listener_cert_pass", HttpSSLCNCertPass); // "Out of band management https" ssl_listener = config.Configs["Network"].GetBoolean("https_listener",false); diff --git a/OpenSim/Framework/PermissionsUtil.cs b/OpenSim/Framework/PermissionsUtil.cs index 3dce04dde0..e50d4df8ea 100644 --- a/OpenSim/Framework/PermissionsUtil.cs +++ b/OpenSim/Framework/PermissionsUtil.cs @@ -60,9 +60,57 @@ namespace OpenSim.Framework str += "C"; if ((perms & (int)PermissionMask.Transfer) != 0) str += "T"; + if ((perms & (int)PermissionMask.Export) != 0) + str += "X"; if (str == "") str = "."; return str; } + + public static void ApplyFoldedPermissions(uint foldedSourcePerms, ref uint targetPerms) + { + uint folded = foldedSourcePerms & (uint)PermissionMask.FoldedMask; + if(folded == 0 || folded == (uint)PermissionMask.FoldedMask) // invalid we need to ignore, or nothing to do + return; + + folded <<= (int)PermissionMask.FoldingShift; + folded |= ~(uint)PermissionMask.UnfoldedMask; + + uint tmp = targetPerms; + tmp &= folded; + targetPerms = tmp; + } + + // do not touch MOD + public static void ApplyNoModFoldedPermissions(uint foldedSourcePerms, ref uint target) + { + uint folded = foldedSourcePerms & (uint)PermissionMask.FoldedMask; + if(folded == 0 || folded == (uint)PermissionMask.FoldedMask) // invalid we need to ignore, or nothing to do + return; + + folded <<= (int)PermissionMask.FoldingShift; + folded |= (~(uint)PermissionMask.UnfoldedMask | (uint)PermissionMask.Modify); + + uint tmp = target; + tmp &= folded; + target = tmp; + } + + public static uint FixAndFoldPermissions(uint perms) + { + uint tmp = perms; + + // C & T rule + if((tmp & (uint)(PermissionMask.Copy | PermissionMask.Transfer)) == 0) + tmp |= (uint)PermissionMask.Transfer; + + // unlock + tmp |= (uint)PermissionMask.Move; + + tmp &= ~(uint)PermissionMask.FoldedMask; + tmp |= ((tmp >> (int)PermissionMask.FoldingShift) & (uint)PermissionMask.FoldedMask); + + return tmp; + } } } diff --git a/OpenSim/Framework/PhysicsInertia.cs b/OpenSim/Framework/PhysicsInertia.cs new file mode 100644 index 0000000000..5aae6d5517 --- /dev/null +++ b/OpenSim/Framework/PhysicsInertia.cs @@ -0,0 +1,261 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using OpenMetaverse; +using System.Text; +using System.IO; +using System.Xml; + +namespace OpenSim.Framework +{ + public class PhysicsInertiaData + { + public float TotalMass; // the total mass of a linkset + public Vector3 CenterOfMass; // the center of mass position relative to root part position + public Vector3 Inertia; // (Ixx, Iyy, Izz) moment of inertia relative to center of mass and principal axis in local coords + public Vector4 InertiaRotation; // if principal axis don't match local axis, the principal axis rotation + // or the upper triangle of the inertia tensor + // Ixy (= Iyx), Ixz (= Izx), Iyz (= Izy)) + + public PhysicsInertiaData() + { + } + + public PhysicsInertiaData(PhysicsInertiaData source) + { + TotalMass = source.TotalMass; + CenterOfMass = source.CenterOfMass; + Inertia = source.Inertia; + InertiaRotation = source.InertiaRotation; + } + + private XmlTextWriter writer; + + private void XWint(string name, int i) + { + writer.WriteElementString(name, i.ToString()); + } + + private void XWfloat(string name, float f) + { + writer.WriteElementString(name, f.ToString(Culture.FormatProvider)); + } + + private void XWVector(string name, Vector3 vec) + { + writer.WriteStartElement(name); + writer.WriteElementString("X", vec.X.ToString(Culture.FormatProvider)); + writer.WriteElementString("Y", vec.Y.ToString(Culture.FormatProvider)); + writer.WriteElementString("Z", vec.Z.ToString(Culture.FormatProvider)); + writer.WriteEndElement(); + } + + private void XWVector4(string name, Vector4 quat) + { + writer.WriteStartElement(name); + writer.WriteElementString("X", quat.X.ToString(Culture.FormatProvider)); + writer.WriteElementString("Y", quat.Y.ToString(Culture.FormatProvider)); + writer.WriteElementString("Z", quat.Z.ToString(Culture.FormatProvider)); + writer.WriteElementString("W", quat.W.ToString(Culture.FormatProvider)); + writer.WriteEndElement(); + } + + public void ToXml2(XmlTextWriter twriter) + { + writer = twriter; + writer.WriteStartElement("PhysicsInertia"); + + XWfloat("MASS", TotalMass); + XWVector("CM", CenterOfMass); + XWVector("INERTIA", Inertia); + XWVector4("IROT", InertiaRotation); + + writer.WriteEndElement(); + writer = null; + } + + XmlReader reader; + + private int XRint() + { + return reader.ReadElementContentAsInt(); + } + + private float XRfloat() + { + return reader.ReadElementContentAsFloat(); + } + + public Vector3 XRvector() + { + Vector3 vec; + reader.ReadStartElement(); + vec.X = reader.ReadElementContentAsFloat(); + vec.Y = reader.ReadElementContentAsFloat(); + vec.Z = reader.ReadElementContentAsFloat(); + reader.ReadEndElement(); + return vec; + } + + public Vector4 XRVector4() + { + Vector4 q; + reader.ReadStartElement(); + q.X = reader.ReadElementContentAsFloat(); + q.Y = reader.ReadElementContentAsFloat(); + q.Z = reader.ReadElementContentAsFloat(); + q.W = reader.ReadElementContentAsFloat(); + reader.ReadEndElement(); + return q; + } + + public static bool EReadProcessors( + Dictionary processors, + XmlReader xtr) + { + bool errors = false; + + string nodeName = string.Empty; + while (xtr.NodeType != XmlNodeType.EndElement) + { + nodeName = xtr.Name; + + Action p = null; + if (processors.TryGetValue(xtr.Name, out p)) + { + try + { + p(); + } + catch + { + errors = true; + if (xtr.NodeType == XmlNodeType.EndElement) + xtr.Read(); + } + } + else + { + xtr.ReadOuterXml(); // ignore + } + } + + return errors; + } + + public string ToXml2() + { + using (StringWriter sw = new StringWriter()) + { + using (XmlTextWriter xwriter = new XmlTextWriter(sw)) + { + ToXml2(xwriter); + } + + return sw.ToString(); + } + } + + public static PhysicsInertiaData FromXml2(string text) + { + if (text == String.Empty) + return null; + + bool error; + PhysicsInertiaData v; + UTF8Encoding enc = new UTF8Encoding(); + using(MemoryStream ms = new MemoryStream(enc.GetBytes(text))) + using(XmlTextReader xreader = new XmlTextReader(ms)) + { + v = new PhysicsInertiaData(); + v.FromXml2(xreader, out error); + } + + if (error) + return null; + + return v; + } + + public static PhysicsInertiaData FromXml2(XmlReader reader) + { + PhysicsInertiaData data = new PhysicsInertiaData(); + + bool errors = false; + + data.FromXml2(reader, out errors); + if (errors) + return null; + + return data; + } + + private void FromXml2(XmlReader _reader, out bool errors) + { + errors = false; + reader = _reader; + + Dictionary m_XmlProcessors = new Dictionary(); + + m_XmlProcessors.Add("MASS", ProcessXR_Mass); + m_XmlProcessors.Add("CM", ProcessXR_CM); + m_XmlProcessors.Add("INERTIA", ProcessXR_Inertia); + m_XmlProcessors.Add("IROT", ProcessXR_InertiaRotation); + + reader.ReadStartElement("PhysicsInertia", String.Empty); + + errors = EReadProcessors( + m_XmlProcessors, + reader); + + reader.ReadEndElement(); + reader = null; + } + + private void ProcessXR_Mass() + { + TotalMass = XRfloat(); + } + + private void ProcessXR_CM() + { + CenterOfMass = XRvector(); + } + + private void ProcessXR_Inertia() + { + Inertia = XRvector(); + } + + private void ProcessXR_InertiaRotation() + { + InertiaRotation = XRVector4(); + } + } +} diff --git a/OpenSim/Framework/PrimitiveBaseShape.cs b/OpenSim/Framework/PrimitiveBaseShape.cs index 29985d2586..5056c04156 100644 --- a/OpenSim/Framework/PrimitiveBaseShape.cs +++ b/OpenSim/Framework/PrimitiveBaseShape.cs @@ -328,6 +328,72 @@ namespace OpenSim.Framework return shape; } + public static PrimitiveBaseShape CreateMesh(int numberOfFaces, UUID meshAssetID) + { + PrimitiveBaseShape shape = new PrimitiveBaseShape(); + + shape._pathScaleX = 100; + shape._pathScaleY = 100; + + if(numberOfFaces <= 0) // oops ? + numberOfFaces = 1; + + switch(numberOfFaces) + { + case 1: // torus + shape.ProfileCurve = (byte)ProfileShape.Circle | (byte)HollowShape.Triangle; + shape.PathCurve = (byte)Extrusion.Curve1; + shape._pathScaleY = 150; + break; + + case 2: // torus with hollow (a sl viewer whould see 4 faces on a hollow sphere) + shape.ProfileCurve = (byte)ProfileShape.Circle | (byte)HollowShape.Triangle; + shape.PathCurve = (byte)Extrusion.Curve1; + shape.ProfileHollow = 27500; + shape._pathScaleY = 150; + break; + + case 3: // cylinder + shape.ProfileCurve = (byte)ProfileShape.Circle | (byte)HollowShape.Triangle; + shape.PathCurve = (byte)Extrusion.Straight; + break; + + case 4: // cylinder with hollow + shape.ProfileCurve = (byte)ProfileShape.Circle | (byte)HollowShape.Triangle; + shape.PathCurve = (byte)Extrusion.Straight; + shape.ProfileHollow = 27500; + break; + + case 5: // prism + shape.ProfileCurve = (byte)ProfileShape.EquilateralTriangle | (byte)HollowShape.Triangle; + shape.PathCurve = (byte)Extrusion.Straight; + break; + + case 6: // box + shape.ProfileCurve = (byte)ProfileShape.Square | (byte)HollowShape.Triangle; + shape.PathCurve = (byte)Extrusion.Straight; + break; + + case 7: // box with hollow + shape.ProfileCurve = (byte)ProfileShape.Square | (byte)HollowShape.Triangle; + shape.PathCurve = (byte)Extrusion.Straight; + shape.ProfileHollow = 27500; + break; + + default: // 8 faces box with cut + shape.ProfileCurve = (byte)ProfileShape.Square | (byte)HollowShape.Triangle; + shape.PathCurve = (byte)Extrusion.Straight; + shape.ProfileBegin = 9375; + break; + } + + shape.SculptEntry = true; + shape.SculptType = (byte)OpenMetaverse.SculptType.Mesh; + shape.SculptTexture = meshAssetID; + + return shape; + } + public void SetScale(float side) { _scale = new Vector3(side, side, side); @@ -1516,35 +1582,48 @@ namespace OpenSim.Framework { MediaList ml = new MediaList(); ml.ReadXml(rawXml); + if(ml.Count == 0) + return null; return ml; } public void ReadXml(string rawXml) { - using (StringReader sr = new StringReader(rawXml)) + try { - using (XmlTextReader xtr = new XmlTextReader(sr)) + using (StringReader sr = new StringReader(rawXml)) { - xtr.MoveToContent(); - - string type = xtr.GetAttribute("type"); - //m_log.DebugFormat("[MOAP]: Loaded media texture entry with type {0}", type); - - if (type != MEDIA_TEXTURE_TYPE) - return; - - xtr.ReadStartElement("OSMedia"); - - OSDArray osdMeArray = (OSDArray)OSDParser.DeserializeLLSDXml(xtr.ReadInnerXml()); - foreach (OSD osdMe in osdMeArray) + using (XmlTextReader xtr = new XmlTextReader(sr)) { - MediaEntry me = (osdMe is OSDMap ? MediaEntry.FromOSD(osdMe) : new MediaEntry()); - Add(me); - } + xtr.MoveToContent(); - xtr.ReadEndElement(); + string type = xtr.GetAttribute("type"); + //m_log.DebugFormat("[MOAP]: Loaded media texture entry with type {0}", type); + + if (type != MEDIA_TEXTURE_TYPE) + return; + + xtr.ReadStartElement("OSMedia"); + OSD osdp = OSDParser.DeserializeLLSDXml(xtr.ReadInnerXml()); + if(osdp == null || !(osdp is OSDArray)) + return; + + OSDArray osdMeArray = osdp as OSDArray; + if(osdMeArray.Count == 0) + return; + + foreach (OSD osdMe in osdMeArray) + { + MediaEntry me = (osdMe is OSDMap ? MediaEntry.FromOSD(osdMe) : new MediaEntry()); + Add(me); + } + } } } + catch + { + m_log.Debug("PrimitiveBaseShape] error decoding MOAP xml" ); + } } public void ReadXml(XmlReader reader) diff --git a/OpenSim/Framework/PriorityQueue.cs b/OpenSim/Framework/PriorityQueue.cs index 5b9185e5c8..22ffcdc8b6 100644 --- a/OpenSim/Framework/PriorityQueue.cs +++ b/OpenSim/Framework/PriorityQueue.cs @@ -216,6 +216,27 @@ namespace OpenSim.Framework return false; } + public bool TryOrderedDequeue(out EntityUpdate value, out Int32 timeinqueue) + { + // If there is anything in imediate queues, return it first no + // matter what else. Breaks fairness. But very useful. + for (int iq = 0; iq < NumberOfQueues; iq++) + { + if (m_heaps[iq].Count > 0) + { + MinHeapItem item = m_heaps[iq].RemoveMin(); + m_lookupTable.Remove(item.Value.Entity.LocalId); + timeinqueue = Util.EnvironmentTickCountSubtract(item.EntryTime); + value = item.Value; + return true; + } + } + + timeinqueue = 0; + value = default(EntityUpdate); + return false; + } + /// /// Reapply the prioritization function to each of the updates currently /// stored in the priority queues. diff --git a/OpenSim/Framework/RegionInfo.cs b/OpenSim/Framework/RegionInfo.cs index 7de8c526b2..75ed999601 100644 --- a/OpenSim/Framework/RegionInfo.cs +++ b/OpenSim/Framework/RegionInfo.cs @@ -420,6 +420,7 @@ namespace OpenSim.Framework set { m_remotingPort = value; } } + /// /// This accessor can throw all the exceptions that Dns.GetHostAddresses can throw. /// @@ -427,42 +428,7 @@ namespace OpenSim.Framework /// public IPEndPoint ExternalEndPoint { - get - { - // Old one defaults to IPv6 - //return new IPEndPoint(Dns.GetHostAddresses(m_externalHostName)[0], m_internalEndPoint.Port); - - IPAddress ia = null; - // If it is already an IP, don't resolve it - just return directly - if (IPAddress.TryParse(m_externalHostName, out ia)) - return new IPEndPoint(ia, m_internalEndPoint.Port); - - // Reset for next check - ia = null; - try - { - foreach (IPAddress Adr in Dns.GetHostAddresses(m_externalHostName)) - { - if (ia == null) - ia = Adr; - - if (Adr.AddressFamily == AddressFamily.InterNetwork) - { - ia = Adr; - break; - } - } - } - catch (SocketException e) - { - throw new Exception( - "Unable to resolve local hostname " + m_externalHostName + " innerException of type '" + - e + "' attached to this exception", e); - } - - return new IPEndPoint(ia, m_internalEndPoint.Port); - } - + get { return Util.getEndPoint(m_externalHostName, m_internalEndPoint.Port); } set { m_externalHostName = value.ToString(); } } diff --git a/OpenSim/Framework/RestClient.cs b/OpenSim/Framework/RestClient.cs index 0166d9d37e..4939cf7bfd 100644 --- a/OpenSim/Framework/RestClient.cs +++ b/OpenSim/Framework/RestClient.cs @@ -428,22 +428,23 @@ namespace OpenSim.Framework if (WebUtil.DebugLevel >= 5) WebUtil.LogOutgoingDetail(string.Format("SEND {0}: ", reqnum), src); - using (Stream dst = _request.GetRequestStream()) - { - m_log.Debug("[REST]: GetRequestStream is ok"); - - byte[] buf = new byte[1024]; - int length = src.Read(buf, 0, 1024); - m_log.Debug("[REST]: First Read is ok"); - while (length > 0) - { - dst.Write(buf, 0, length); - length = src.Read(buf, 0, 1024); - } - } - + try { + using (Stream dst = _request.GetRequestStream()) + { +// m_log.Debug("[REST]: GetRequestStream is ok"); + + byte[] buf = new byte[1024]; + int length = src.Read(buf, 0, 1024); +// m_log.Debug("[REST]: First Read is ok"); + while (length > 0) + { + dst.Write(buf, 0, length); + length = src.Read(buf, 0, 1024); + } + } + _response = (HttpWebResponse)_request.GetResponse(); } catch (WebException e) diff --git a/OpenSim/Framework/Serialization/External/ExternalRepresentationUtils.cs b/OpenSim/Framework/Serialization/External/ExternalRepresentationUtils.cs index 1523fa9e0b..238ebb1793 100644 --- a/OpenSim/Framework/Serialization/External/ExternalRepresentationUtils.cs +++ b/OpenSim/Framework/Serialization/External/ExternalRepresentationUtils.cs @@ -156,6 +156,7 @@ namespace OpenSim.Framework.Serialization.External return xml; XmlDocument doc = new XmlDocument(); + doc.LoadXml(xml); XmlNodeList sops = doc.GetElementsByTagName("SceneObjectPart"); @@ -220,7 +221,7 @@ namespace OpenSim.Framework.Serialization.External using (StringWriter sw = new StringWriter()) using (XmlTextWriter writer = new XmlTextWriter(sw)) using (XmlTextReader wrappedReader = new XmlTextReader(xmlData, XmlNodeType.Element, null)) - using (XmlReader reader = XmlReader.Create(wrappedReader, new XmlReaderSettings() { IgnoreWhitespace = true, ConformanceLevel = ConformanceLevel.Fragment })) + using (XmlReader reader = XmlReader.Create(wrappedReader, new XmlReaderSettings() { IgnoreWhitespace = true, ConformanceLevel = ConformanceLevel.Fragment})) { TransformXml(reader, writer, sceneName, homeURL, userService, scopeID); diff --git a/OpenSim/Framework/Servers/BaseOpenSimServer.cs b/OpenSim/Framework/Servers/BaseOpenSimServer.cs index f761813560..f832f81bc0 100644 --- a/OpenSim/Framework/Servers/BaseOpenSimServer.cs +++ b/OpenSim/Framework/Servers/BaseOpenSimServer.cs @@ -33,6 +33,9 @@ using System.Text; using System.Text.RegularExpressions; using System.Threading; using System.Timers; +using System.Net; +using System.Net.Security; +using System.Security.Cryptography.X509Certificates; using log4net; using log4net.Appender; using log4net.Core; @@ -86,6 +89,26 @@ namespace OpenSim.Framework.Servers m_osSecret = UUID.Random().ToString(); } + private static bool m_NoVerifyCertChain = false; + private static bool m_NoVerifyCertHostname = false; + + public static bool ValidateServerCertificate( + object sender, + X509Certificate certificate, + X509Chain chain, + SslPolicyErrors sslPolicyErrors) + { + if (m_NoVerifyCertChain) + sslPolicyErrors &= ~SslPolicyErrors.RemoteCertificateChainErrors; + + if (m_NoVerifyCertHostname) + sslPolicyErrors &= ~SslPolicyErrors.RemoteCertificateNameMismatch; + + if (sslPolicyErrors == SslPolicyErrors.None) + return true; + + return false; + } /// /// Must be overriden by child classes for their own server specific startup behaviour. /// @@ -96,6 +119,11 @@ namespace OpenSim.Framework.Servers RegisterCommonComponents(Config); IConfig startupConfig = Config.Configs["Startup"]; + + m_NoVerifyCertChain = startupConfig.GetBoolean("NoVerifyCertChain", m_NoVerifyCertChain); + m_NoVerifyCertHostname = startupConfig.GetBoolean("NoVerifyCertHostname", m_NoVerifyCertHostname); + ServicePointManager.ServerCertificateValidationCallback = ValidateServerCertificate; + int logShowStatsSeconds = startupConfig.GetInt("LogShowStatsSeconds", m_periodDiagnosticTimerMS / 1000); m_periodDiagnosticTimerMS = logShowStatsSeconds * 1000; m_periodicDiagnosticsTimer.Elapsed += new ElapsedEventHandler(LogDiagnostics); @@ -108,13 +136,21 @@ namespace OpenSim.Framework.Servers protected override void ShutdownSpecific() { - m_log.Info("[SHUTDOWN]: Shutdown processing on main thread complete. Exiting..."); + Watchdog.Enabled = false; + base.ShutdownSpecific(); + + MainServer.Stop(); + Thread.Sleep(5000); + Util.StopThreadPool(); + WorkManager.Stop(); + + Thread.Sleep(1000); RemovePIDFile(); - base.ShutdownSpecific(); + m_log.Info("[SHUTDOWN]: Shutdown processing on main thread complete. Exiting..."); - if (!SuppressExit) + if (!SuppressExit) Environment.Exit(0); } @@ -163,8 +199,7 @@ namespace OpenSim.Framework.Servers } catch(Exception e) { - m_log.FatalFormat("Fatal error: {0}", - (e.Message == null || e.Message == String.Empty) ? "Unknown reason":e.Message ); + m_log.Fatal("Fatal error: " + e.ToString()); Environment.Exit(1); } diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs index fb92b9237a..2819bc9daf 100644 --- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs +++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs @@ -32,6 +32,7 @@ using System.Collections.Specialized; using System.IO; using System.Net; using System.Net.Sockets; +using System.Net.Security; using System.Security.Cryptography.X509Certificates; using System.Reflection; using System.Globalization; @@ -43,10 +44,11 @@ using log4net; using Nwc.XmlRpc; using OpenMetaverse.StructuredData; using CoolHTTPListener = HttpServer.HttpListener; -using HttpListener=System.Net.HttpListener; -using LogPrio=HttpServer.LogPrio; +using HttpListener = System.Net.HttpListener; +using LogPrio = HttpServer.LogPrio; using OpenSim.Framework.Monitoring; using System.IO.Compression; +using System.Security.Cryptography; namespace OpenSim.Framework.Servers.HttpServer { @@ -107,19 +109,26 @@ namespace OpenSim.Framework.Servers.HttpServer new Dictionary(); protected uint m_port; - protected uint m_sslport; protected bool m_ssl; private X509Certificate2 m_cert; - protected bool m_firstcaps = true; protected string m_SSLCommonName = ""; + protected List m_certNames = new List(); + protected List m_certIPs = new List(); + protected string m_certCN= ""; + protected RemoteCertificateValidationCallback m_certificateValidationCallback = null; protected IPAddress m_listenIPAddress = IPAddress.Any; public PollServiceRequestManager PollServiceRequestManager { get; private set; } + public string Protocol + { + get { return m_ssl ? "https://" : "http://"; } + } + public uint SSLPort { - get { return m_sslport; } + get { return m_port; } } public string SSLCommonName @@ -148,27 +157,166 @@ namespace OpenSim.Framework.Servers.HttpServer m_port = port; } - public BaseHttpServer(uint port, bool ssl) : this (port) + private void load_cert(string CPath, string CPass) { - m_ssl = ssl; - } - - public BaseHttpServer(uint port, bool ssl, uint sslport, string CN) : this (port, ssl) - { - if (m_ssl) + try { - m_sslport = sslport; + m_cert = new X509Certificate2(CPath, CPass); + X509Extension ext = m_cert.Extensions["2.5.29.17"]; + if(ext != null) + { + AsnEncodedData asndata = new AsnEncodedData(ext.Oid, ext.RawData); + string datastr = asndata.Format(true); + string[] lines = datastr.Split(new char[] {'\n','\r'}); + foreach(string s in lines) + { + if(String.IsNullOrEmpty(s)) + continue; + string[] parts = s.Split(new char[] {'='}); + if(String.IsNullOrEmpty(parts[0])) + continue; + string entryName = parts[0].Replace(" ",""); + if(entryName == "DNSName") + m_certNames.Add(parts[1]); + else if(entryName == "IPAddress") + m_certIPs.Add(parts[1]); + else if(entryName == "Unknown(135)") // stupid mono + { + try + { + if(parts[1].Length == 8) + { + long tmp = long.Parse(parts[1], NumberStyles.AllowHexSpecifier); + tmp = IPAddress.HostToNetworkOrder(tmp); + tmp = (long)((ulong) tmp >> 32); + IPAddress ia = new IPAddress(tmp); + m_certIPs.Add(ia.ToString()); + } + } + catch {} + } + } + } + m_certCN = m_cert.GetNameInfo(X509NameType.SimpleName, false); + } + catch + { + throw new Exception("SSL cert load error"); } } - public BaseHttpServer(uint port, bool ssl, string CPath, string CPass) : this (port, ssl) + public BaseHttpServer(uint port, bool ssl, string CN, string CPath, string CPass) { - if (m_ssl) + m_port = port; + if (ssl) { - m_cert = new X509Certificate2(CPath, CPass); + if(string.IsNullOrEmpty(CPath)) + throw new Exception("invalid main http server cert path"); + + if(Uri.CheckHostName(CN) == UriHostNameType.Unknown) + throw new Exception("invalid main http server CN (ExternalHostName)"); + + m_certNames.Clear(); + m_certIPs.Clear(); + m_certCN= ""; + + m_ssl = true; + load_cert(CPath, CPass); + + if(!CheckSSLCertHost(CN)) + throw new Exception("invalid main http server CN (ExternalHostName)"); + + m_SSLCommonName = CN; + + if(m_cert.Issuer == m_cert.Subject ) + m_log.Warn("Self signed certificate. Clients need to allow this (some viewers debug option NoVerifySSLcert must be set to true"); } + else + m_ssl = false; } + public BaseHttpServer(uint port, bool ssl, string CPath, string CPass) + { + m_port = port; + if (ssl) + { + load_cert(CPath, CPass); + if(m_cert.Issuer == m_cert.Subject ) + m_log.Warn("Self signed certificate. Http clients need to allow this"); + m_ssl = true; + } + else + m_ssl = false; + } + + static bool MatchDNS (string hostname, string dns) + { + int indx = dns.IndexOf ('*'); + if (indx == -1) + return (String.Compare(hostname, dns, true, CultureInfo.InvariantCulture) == 0); + + int dnslen = dns.Length; + dnslen--; + if(indx == dnslen) + return true; // just * ? + + if(indx > dnslen - 2) + return false; // 2 short ? + + if (dns[indx + 1] != '.') + return false; + + int indx2 = dns.IndexOf ('*', indx + 1); + if (indx2 != -1) + return false; // there can only be one; + + string end = dns.Substring(indx + 1); + int hostlen = hostname.Length; + int endlen = end.Length; + int length = hostlen - endlen; + if (length <= 0) + return false; + + if (String.Compare(hostname, length, end, 0, endlen, true, CultureInfo.InvariantCulture) != 0) + return false; + + if (indx == 0) + { + indx2 = hostname.IndexOf ('.'); + return ((indx2 == -1) || (indx2 >= length)); + } + + string start = dns.Substring (0, indx); + return (String.Compare (hostname, 0, start, 0, start.Length, true, CultureInfo.InvariantCulture) == 0); + } + + public bool CheckSSLCertHost(string hostname) + { + UriHostNameType htype = Uri.CheckHostName(hostname); + + if(htype == UriHostNameType.Unknown || htype == UriHostNameType.Basic) + return false; + if(htype == UriHostNameType.Dns) + { + foreach(string name in m_certNames) + { + if(MatchDNS(hostname, name)) + return true; + } + if(MatchDNS(hostname, m_certCN)) + return true; + } + else + { + foreach(string ip in m_certIPs) + { + if (String.Compare(hostname, ip, true, CultureInfo.InvariantCulture) == 0) + return true; + } + } + + return false; + } /// /// Add a stream handler to the http server. If the handler already exists, then nothing happens. /// @@ -396,14 +544,10 @@ namespace OpenSim.Framework.Servers.HttpServer if (psEvArgs.Request != null) { OSHttpRequest req = new OSHttpRequest(context, request); - - Stream requestStream = req.InputStream; - + string requestBody; Encoding encoding = Encoding.UTF8; - StreamReader reader = new StreamReader(requestStream, encoding); - - string requestBody = reader.ReadToEnd(); - reader.Close(); + using(StreamReader reader = new StreamReader(req.InputStream, encoding)) + requestBody = reader.ReadToEnd(); Hashtable keysvals = new Hashtable(); Hashtable headervals = new Hashtable(); @@ -461,8 +605,7 @@ namespace OpenSim.Framework.Servers.HttpServer } OSHttpResponse resp = new OSHttpResponse(new HttpResponse(context, request),context); - resp.ReuseContext = true; -// resp.ReuseContext = false; + HandleRequest(req, resp); // !!!HACK ALERT!!! @@ -494,6 +637,8 @@ namespace OpenSim.Framework.Servers.HttpServer { try { + if(request.InputStream != null && request.InputStream.CanRead) + request.InputStream.Close(); byte[] buffer500 = SendHTML500(response); response.OutputStream.Write(buffer500, 0, buffer500.Length); response.Send(); @@ -541,7 +686,6 @@ namespace OpenSim.Framework.Servers.HttpServer // } // } - //response.KeepAlive = true; response.SendChunked = false; string path = request.RawUrl; @@ -565,15 +709,11 @@ namespace OpenSim.Framework.Servers.HttpServer { //m_log.Debug("[BASE HTTP SERVER]: Found Caps based HTTP Handler"); IGenericHTTPHandler HTTPRequestHandler = requestHandler as IGenericHTTPHandler; - Stream requestStream = request.InputStream; + string requestBody; Encoding encoding = Encoding.UTF8; - StreamReader reader = new StreamReader(requestStream, encoding); - - string requestBody = reader.ReadToEnd(); - - reader.Close(); - //requestStream.Close(); + using(StreamReader reader = new StreamReader(request.InputStream, encoding)) + requestBody = reader.ReadToEnd(); Hashtable keysvals = new Hashtable(); Hashtable headervals = new Hashtable(); @@ -613,7 +753,6 @@ namespace OpenSim.Framework.Servers.HttpServer else { IStreamHandler streamHandler = (IStreamHandler)requestHandler; - using (MemoryStream memoryStream = new MemoryStream()) { streamHandler.Handle(path, request.InputStream, memoryStream, request, response); @@ -690,7 +829,8 @@ namespace OpenSim.Framework.Servers.HttpServer } } - request.InputStream.Close(); + if(request.InputStream != null && request.InputStream.CanRead) + request.InputStream.Dispose(); if (buffer != null) { @@ -723,10 +863,6 @@ namespace OpenSim.Framework.Servers.HttpServer requestEndTick = Environment.TickCount; response.Send(); - - //response.OutputStream.Close(); - - //response.FreeContext(); } catch (SocketException e) { @@ -758,6 +894,9 @@ namespace OpenSim.Framework.Servers.HttpServer } finally { + if(request.InputStream != null && request.InputStream.CanRead) + request.InputStream.Close(); + // Every month or so this will wrap and give bad numbers, not really a problem // since its just for reporting int tickdiff = requestEndTick - requestStartTick; @@ -998,7 +1137,7 @@ namespace OpenSim.Framework.Servers.HttpServer { String requestBody; - Stream requestStream = request.InputStream; + Stream requestStream = Util.Copy(request.InputStream); Stream innerStream = null; try { @@ -1009,15 +1148,15 @@ namespace OpenSim.Framework.Servers.HttpServer } using (StreamReader reader = new StreamReader(requestStream, Encoding.UTF8)) - { requestBody = reader.ReadToEnd(); + } - } finally { - if (innerStream != null) + if (innerStream != null && innerStream.CanRead) innerStream.Dispose(); - requestStream.Dispose(); + if (requestStream.CanRead) + requestStream.Dispose(); } //m_log.Debug(requestBody); @@ -1098,6 +1237,17 @@ namespace OpenSim.Framework.Servers.HttpServer if (gridproxy) xmlRprcRequest.Params.Add("gridproxy"); // Param[4] + + // reserve this for + // ... by Fumi.Iseki for DTLNSLMoneyServer + // BUT make its presence possible to detect/parse + string rcn = request.IHttpClientContext.SSLCommonName; + if(!string.IsNullOrWhiteSpace(rcn)) + { + rcn = "SSLCN:" + rcn; + xmlRprcRequest.Params.Add(rcn); // Param[4] or Param[5] + } + try { xmlRpcResponse = method(xmlRprcRequest, request.RemoteIPEndPoint); @@ -1263,15 +1413,12 @@ namespace OpenSim.Framework.Servers.HttpServer //m_log.Warn("[BASE HTTP SERVER]: We've figured out it's a LLSD Request"); Stream requestStream = request.InputStream; + string requestBody; Encoding encoding = Encoding.UTF8; - StreamReader reader = new StreamReader(requestStream, encoding); - - string requestBody = reader.ReadToEnd(); - reader.Close(); - requestStream.Close(); + using(StreamReader reader = new StreamReader(requestStream, encoding)) + requestBody= reader.ReadToEnd(); //m_log.DebugFormat("[OGP]: {0}:{1}", request.RawUrl, requestBody); - response.KeepAlive = true; OSD llsdRequest = null; OSD llsdResponse = null; @@ -1592,15 +1739,10 @@ namespace OpenSim.Framework.Servers.HttpServer byte[] buffer; Stream requestStream = request.InputStream; - + string requestBody; Encoding encoding = Encoding.UTF8; - StreamReader reader = new StreamReader(requestStream, encoding); - - string requestBody = reader.ReadToEnd(); - // avoid warning for now - reader.ReadToEnd(); - reader.Close(); - requestStream.Close(); + using(StreamReader reader = new StreamReader(requestStream, encoding)) + requestBody = reader.ReadToEnd(); Hashtable keysvals = new Hashtable(); Hashtable headervals = new Hashtable(); @@ -1792,20 +1934,13 @@ namespace OpenSim.Framework.Servers.HttpServer { response.ProtocolVersion = (string)responsedata["http_protocol_version"]; } -/* + if (responsedata.ContainsKey("keepalive")) { bool keepalive = (bool)responsedata["keepalive"]; response.KeepAlive = keepalive; } - if (responsedata.ContainsKey("reusecontext")) - response.ReuseContext = (bool) responsedata["reusecontext"]; -*/ - // disable this things - response.KeepAlive = false; - response.ReuseContext = false; - // Cross-Origin Resource Sharing with simple requests if (responsedata.ContainsKey("access_control_allow_origin")) response.AddHeader("Access-Control-Allow-Origin", (string)responsedata["access_control_allow_origin"]); @@ -1818,11 +1953,8 @@ namespace OpenSim.Framework.Servers.HttpServer contentType = "text/html"; } - - // The client ignores anything but 200 here for web login, so ensure that this is 200 for that - response.StatusCode = responsecode; if (responsecode == (int)OSHttpStatusCode.RedirectMovedPermanently) @@ -1832,13 +1964,12 @@ namespace OpenSim.Framework.Servers.HttpServer } response.AddHeader("Content-Type", contentType); - if (responsedata.ContainsKey("headers")) { Hashtable headerdata = (Hashtable)responsedata["headers"]; foreach (string header in headerdata.Keys) - response.AddHeader(header, (string)headerdata[header]); + response.AddHeader(header, headerdata[header].ToString()); } byte[] buffer; @@ -1906,7 +2037,7 @@ namespace OpenSim.Framework.Servers.HttpServer public void Start() { - Start(true); + Start(true,true); } /// @@ -1916,7 +2047,7 @@ namespace OpenSim.Framework.Servers.HttpServer /// If true then poll responses are performed asynchronsly. /// Option exists to allow regression tests to perform processing synchronously. /// - public void Start(bool performPollResponsesAsync) + public void Start(bool performPollResponsesAsync, bool runPool) { m_log.InfoFormat( "[BASE HTTP SERVER]: Starting {0} server on port {1}", UseSSL ? "HTTPS" : "HTTP", Port); @@ -1945,6 +2076,8 @@ namespace OpenSim.Framework.Servers.HttpServer //m_httpListener.Prefixes.Add("https://+:" + (m_sslport) + "/"); //m_httpListener.Prefixes.Add("http://+:" + m_port + "/"); m_httpListener2 = CoolHTTPListener.Create(IPAddress.Any, (int)m_port, m_cert); + if(m_certificateValidationCallback != null) + m_httpListener2.CertificateValidationCallback = m_certificateValidationCallback; m_httpListener2.ExceptionThrown += httpServerException; m_httpListener2.LogWriter = httpserverlog; } @@ -1954,9 +2087,11 @@ namespace OpenSim.Framework.Servers.HttpServer m_httpListener2.Start(64); // Long Poll Service Manager with 3 worker threads a 25 second timeout for no events - - PollServiceRequestManager = new PollServiceRequestManager(this, performPollResponsesAsync, 2, 25000); - PollServiceRequestManager.Start(); + if(runPool) + { + PollServiceRequestManager = new PollServiceRequestManager(this, performPollResponsesAsync, 2, 25000); + PollServiceRequestManager.Start(); + } HTTPDRunning = true; @@ -1970,7 +2105,7 @@ namespace OpenSim.Framework.Servers.HttpServer catch (Exception e) { m_log.Error("[BASE HTTP SERVER]: Error - " + e.Message); - m_log.Error("[BASE HTTP SERVER]: Tip: Do you have permission to listen on port " + m_port + ", " + m_sslport + "?"); + m_log.Error("[BASE HTTP SERVER]: Tip: Do you have permission to listen on port " + m_port + "?"); // We want this exception to halt the entire server since in current configurations we aren't too // useful without inbound HTTP. @@ -2028,7 +2163,8 @@ namespace OpenSim.Framework.Servers.HttpServer try { - PollServiceRequestManager.Stop(); + if(PollServiceRequestManager != null) + PollServiceRequestManager.Stop(); m_httpListener2.ExceptionThrown -= httpServerException; //m_httpListener2.DisconnectHandler = null; @@ -2135,10 +2271,9 @@ namespace OpenSim.Framework.Servers.HttpServer string file = Path.Combine(".", "http_500.html"); if (!File.Exists(file)) return getDefaultHTTP500(); - - StreamReader sr = File.OpenText(file); - string result = sr.ReadToEnd(); - sr.Close(); + string result; + using(StreamReader sr = File.OpenText(file)) + result = sr.ReadToEnd(); return result; } diff --git a/OpenSim/Framework/Servers/HttpServer/Interfaces/IOSHttpResponse.cs b/OpenSim/Framework/Servers/HttpServer/Interfaces/IOSHttpResponse.cs index f61b090be4..d26b68a7fb 100644 --- a/OpenSim/Framework/Servers/HttpServer/Interfaces/IOSHttpResponse.cs +++ b/OpenSim/Framework/Servers/HttpServer/Interfaces/IOSHttpResponse.cs @@ -118,7 +118,7 @@ namespace OpenSim.Framework.Servers.HttpServer /// string StatusDescription { get; set; } - bool ReuseContext { get; set; } +// bool ReuseContext { get; set; } /// /// Add a header field and content to the response. diff --git a/OpenSim/Framework/Servers/HttpServer/OSHttpResponse.cs b/OpenSim/Framework/Servers/HttpServer/OSHttpResponse.cs index d7744fceea..a107ced52f 100644 --- a/OpenSim/Framework/Servers/HttpServer/OSHttpResponse.cs +++ b/OpenSim/Framework/Servers/HttpServer/OSHttpResponse.cs @@ -257,25 +257,6 @@ namespace OpenSim.Framework.Servers.HttpServer } } - public bool ReuseContext - { - get - { - if (_httpClientContext != null) - { - return !_httpClientContext.EndWhenDone; - } - return true; - } - set - { - if (_httpClientContext != null) - { - _httpClientContext.EndWhenDone = !value; - } - } - } - protected IHttpResponse _httpResponse; private IHttpClientContext _httpClientContext; diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs index 8ace7a99d0..7c7d08dbc0 100644 --- a/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs +++ b/OpenSim/Framework/Servers/HttpServer/PollServiceEventArgs.cs @@ -37,6 +37,7 @@ namespace OpenSim.Framework.Servers.HttpServer public delegate Hashtable GetEventsMethod(UUID requestID, UUID pId); public delegate Hashtable NoEventsMethod(UUID requestID, UUID pId); + public delegate void DropMethod(UUID requestID, UUID pId); public class PollServiceEventArgs : EventArgs { @@ -44,13 +45,14 @@ namespace OpenSim.Framework.Servers.HttpServer public GetEventsMethod GetEvents; public NoEventsMethod NoEvents; public RequestMethod Request; + public DropMethod Drop; public UUID Id; public int TimeOutms; public EventType Type; public enum EventType : int { - LongPoll = 0, + Poll = 0, LslHttp = 1, Inventory = 2, Texture = 3, @@ -73,16 +75,17 @@ namespace OpenSim.Framework.Servers.HttpServer RequestMethod pRequest, string pUrl, HasEventsMethod pHasEvents, GetEventsMethod pGetEvents, NoEventsMethod pNoEvents, - UUID pId, int pTimeOutms) + DropMethod pDrop, UUID pId, int pTimeOutms) { Request = pRequest; Url = pUrl; HasEvents = pHasEvents; GetEvents = pGetEvents; NoEvents = pNoEvents; + Drop = pDrop; Id = pId; TimeOutms = pTimeOutms; - Type = EventType.LongPoll; + Type = EventType.Poll; } } } diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceHttpRequest.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceHttpRequest.cs index 3eb330a7c7..4fd69f3de0 100644 --- a/OpenSim/Framework/Servers/HttpServer/PollServiceHttpRequest.cs +++ b/OpenSim/Framework/Servers/HttpServer/PollServiceHttpRequest.cs @@ -47,8 +47,10 @@ namespace OpenSim.Framework.Servers.HttpServer public readonly UUID RequestID; public int contextHash; +/* private void GenContextHash() { + Random rnd = new Random(); contextHash = 0; if (Request.Headers["remote_addr"] != null) @@ -62,8 +64,9 @@ namespace OpenSim.Framework.Servers.HttpServer } else contextHash += rnd.Next() & 0xffff; - } + } +*/ public PollServiceHttpRequest( PollServiceEventArgs pPollServiceArgs, IHttpClientContext pHttpContext, IHttpRequest pRequest) { @@ -72,7 +75,8 @@ namespace OpenSim.Framework.Servers.HttpServer Request = pRequest; RequestTime = System.Environment.TickCount; RequestID = UUID.Random(); - GenContextHash(); +// GenContextHash(); + contextHash = HttpContext.contextID; } internal void DoHTTPGruntWork(BaseHttpServer server, Hashtable responsedata) @@ -82,10 +86,12 @@ namespace OpenSim.Framework.Servers.HttpServer byte[] buffer = server.DoHTTPGruntWork(responsedata, response); + if(Request.Body.CanRead) + Request.Body.Dispose(); + response.SendChunked = false; response.ContentLength64 = buffer.Length; response.ContentEncoding = Encoding.UTF8; - response.ReuseContext = false; try { @@ -114,10 +120,12 @@ namespace OpenSim.Framework.Servers.HttpServer OSHttpResponse response = new OSHttpResponse(new HttpResponse(HttpContext, Request), HttpContext); + if(Request.Body.CanRead) + Request.Body.Dispose(); + response.SendChunked = false; response.ContentLength64 = 0; response.ContentEncoding = Encoding.UTF8; - response.ReuseContext = false; response.KeepAlive = false; response.SendChunked = false; response.StatusCode = 503; @@ -127,7 +135,7 @@ namespace OpenSim.Framework.Servers.HttpServer response.OutputStream.Flush(); response.Send(); } - catch (Exception e) + catch { } } diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs index 936146d904..a2f6a119d7 100644 --- a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs +++ b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs @@ -30,13 +30,10 @@ using System.Collections; using System.Threading; using System.Reflection; using log4net; -using HttpServer; -using OpenSim.Framework; using OpenSim.Framework.Monitoring; using Amib.Threading; -using System.IO; -using System.Text; using System.Collections.Generic; +using System.Collections.Concurrent; namespace OpenSim.Framework.Servers.HttpServer { @@ -46,21 +43,18 @@ namespace OpenSim.Framework.Servers.HttpServer private readonly BaseHttpServer m_server; - private Dictionary> m_bycontext; - private BlockingQueue m_requests = new BlockingQueue(); - private static Queue m_slowRequests = new Queue(); - private static Queue m_retryRequests = new Queue(); + private Dictionary> m_bycontext; + private BlockingCollection m_requests = new BlockingCollection(); + private static ConcurrentQueue m_retryRequests = new ConcurrentQueue(); private uint m_WorkerThreadCount = 0; private Thread[] m_workerThreads; private Thread m_retrysThread; private bool m_running = false; - private int slowCount = 0; private SmartThreadPool m_threadPool; - public PollServiceRequestManager( BaseHttpServer pSrv, bool performResponsesAsync, uint pWorkerThreadCount, int pTimeout) { @@ -68,8 +62,7 @@ namespace OpenSim.Framework.Servers.HttpServer m_WorkerThreadCount = pWorkerThreadCount; m_workerThreads = new Thread[m_WorkerThreadCount]; - PollServiceHttpRequestComparer preqCp = new PollServiceHttpRequestComparer(); - m_bycontext = new Dictionary>(preqCp); + m_bycontext = new Dictionary>(256); STPStartInfo startInfo = new STPStartInfo(); startInfo.IdleTimeout = 30000; @@ -80,7 +73,6 @@ namespace OpenSim.Framework.Servers.HttpServer startInfo.ThreadPoolName = "PoolService"; m_threadPool = new SmartThreadPool(startInfo); - } public void Start() @@ -95,7 +87,7 @@ namespace OpenSim.Framework.Servers.HttpServer PoolWorkerJob, string.Format("PollServiceWorkerThread {0}:{1}", i, m_server.Port), ThreadPriority.Normal, - false, + true, false, null, int.MaxValue); @@ -105,36 +97,32 @@ namespace OpenSim.Framework.Servers.HttpServer this.CheckRetries, string.Format("PollServiceWatcherThread:{0}", m_server.Port), ThreadPriority.Normal, - false, + true, true, null, 1000 * 60 * 10); - - } private void ReQueueEvent(PollServiceHttpRequest req) { if (m_running) - { - lock (m_retryRequests) - m_retryRequests.Enqueue(req); - } + m_retryRequests.Enqueue(req); } public void Enqueue(PollServiceHttpRequest req) { + Queue ctxQeueue; + int rhash = req.contextHash; lock (m_bycontext) { - Queue ctxQeueue; - if (m_bycontext.TryGetValue(req, out ctxQeueue)) + if (m_bycontext.TryGetValue(rhash, out ctxQeueue)) { ctxQeueue.Enqueue(req); } else { ctxQeueue = new Queue(); - m_bycontext[req] = ctxQeueue; + m_bycontext[rhash] = ctxQeueue; EnqueueInt(req); } } @@ -143,9 +131,10 @@ namespace OpenSim.Framework.Servers.HttpServer public void byContextDequeue(PollServiceHttpRequest req) { Queue ctxQeueue; + int rhash = req.contextHash; lock (m_bycontext) { - if (m_bycontext.TryGetValue(req, out ctxQeueue)) + if (m_bycontext.TryGetValue(rhash, out ctxQeueue)) { if (ctxQeueue.Count > 0) { @@ -154,51 +143,41 @@ namespace OpenSim.Framework.Servers.HttpServer } else { - m_bycontext.Remove(req); + m_bycontext.Remove(rhash); } } } } + public void DropByContext(PollServiceHttpRequest req) + { + Queue ctxQeueue; + int rhash = req.contextHash; + lock (m_bycontext) + { + if (m_bycontext.TryGetValue(rhash, out ctxQeueue)) + { + ctxQeueue.Clear(); + m_bycontext.Remove(rhash); + } + } + } + public void EnqueueInt(PollServiceHttpRequest req) { if (m_running) - { - if (req.PollServiceArgs.Type != PollServiceEventArgs.EventType.LongPoll) - { - m_requests.Enqueue(req); - } - else - { - lock (m_slowRequests) - m_slowRequests.Enqueue(req); - } - } + m_requests.Add(req); } private void CheckRetries() { + PollServiceHttpRequest preq; while (m_running) - { - Thread.Sleep(100); // let the world move .. back to faster rate + Thread.Sleep(100); Watchdog.UpdateThread(); - lock (m_retryRequests) - { - while (m_retryRequests.Count > 0 && m_running) - m_requests.Enqueue(m_retryRequests.Dequeue()); - } - slowCount++; - if (slowCount >= 10) - { - slowCount = 0; - - lock (m_slowRequests) - { - while (m_slowRequests.Count > 0 && m_running) - m_requests.Enqueue(m_slowRequests.Dequeue()); - } - } + while (m_running && m_retryRequests.TryDequeue(out preq)) + m_requests.Add(preq); } } @@ -206,117 +185,130 @@ namespace OpenSim.Framework.Servers.HttpServer { m_running = false; - Thread.Sleep(1000); // let the world move + Thread.Sleep(100); // let the world move foreach (Thread t in m_workerThreads) Watchdog.AbortThread(t.ManagedThreadId); + m_threadPool.Shutdown(); + // any entry in m_bycontext should have a active request on the other queues // so just delete contents to easy GC foreach (Queue qu in m_bycontext.Values) qu.Clear(); m_bycontext.Clear(); + PollServiceHttpRequest req; try { - foreach (PollServiceHttpRequest req in m_retryRequests) - { + while(m_retryRequests.TryDequeue(out req)) req.DoHTTPstop(m_server); - } } catch { } - PollServiceHttpRequest wreq; - m_retryRequests.Clear(); - - lock (m_slowRequests) + try + { + while(m_requests.TryTake(out req, 0)) + req.DoHTTPstop(m_server); + } + catch { - while (m_slowRequests.Count > 0) - m_requests.Enqueue(m_slowRequests.Dequeue()); - } - while (m_requests.Count() > 0) - { - try - { - wreq = m_requests.Dequeue(0); - wreq.DoHTTPstop(m_server); + m_requests.Dispose(); - } - catch - { - } - } - - m_requests.Clear(); } // work threads private void PoolWorkerJob() { + PollServiceHttpRequest req; while (m_running) { - PollServiceHttpRequest req = m_requests.Dequeue(5000); - - Watchdog.UpdateThread(); - if (req != null) + req = null; + if(!m_requests.TryTake(out req, 4500) || req == null) { - try - { - if (req.PollServiceArgs.HasEvents(req.RequestID, req.PollServiceArgs.Id)) - { - Hashtable responsedata = req.PollServiceArgs.GetEvents(req.RequestID, req.PollServiceArgs.Id); + Watchdog.UpdateThread(); + continue; + } + Watchdog.UpdateThread(); + + try + { + if(!req.HttpContext.CanSend()) + { + req.PollServiceArgs.Drop(req.RequestID, req.PollServiceArgs.Id); + byContextDequeue(req); + continue; + } + + if(req.HttpContext.IsSending()) + { + if ((Environment.TickCount - req.RequestTime) > req.PollServiceArgs.TimeOutms) + { + req.PollServiceArgs.Drop(req.RequestID, req.PollServiceArgs.Id); + byContextDequeue(req); + } + else + ReQueueEvent(req); + continue; + } + + if (req.PollServiceArgs.HasEvents(req.RequestID, req.PollServiceArgs.Id)) + { + PollServiceHttpRequest nreq = req; + m_threadPool.QueueWorkItem(x => + { + try + { + Hashtable responsedata = nreq.PollServiceArgs.GetEvents(nreq.RequestID, nreq.PollServiceArgs.Id); + nreq.DoHTTPGruntWork(m_server, responsedata); + } + catch (ObjectDisposedException) { } + finally + { + byContextDequeue(nreq); + nreq = null; + } + return null; + }, null); + } + else + { + if ((Environment.TickCount - req.RequestTime) > req.PollServiceArgs.TimeOutms) + { + PollServiceHttpRequest nreq = req; m_threadPool.QueueWorkItem(x => { try { - req.DoHTTPGruntWork(m_server, responsedata); - byContextDequeue(req); + nreq.DoHTTPGruntWork(m_server, + nreq.PollServiceArgs.NoEvents(nreq.RequestID, nreq.PollServiceArgs.Id)); } - catch (ObjectDisposedException) // Browser aborted before we could read body, server closed the stream + catch (ObjectDisposedException) {} + finally { - // Ignore it, no need to reply + byContextDequeue(nreq); + nreq = null; } return null; }, null); } else { - if ((Environment.TickCount - req.RequestTime) > req.PollServiceArgs.TimeOutms) - { - m_threadPool.QueueWorkItem(x => - { - try - { - req.DoHTTPGruntWork(m_server, - req.PollServiceArgs.NoEvents(req.RequestID, req.PollServiceArgs.Id)); - byContextDequeue(req); - } - catch (ObjectDisposedException) - { - // Ignore it, no need to reply - } - return null; - }, null); - } - else - { - ReQueueEvent(req); - } + ReQueueEvent(req); } } - catch (Exception e) - { - m_log.ErrorFormat("Exception in poll service thread: " + e.ToString()); - } + } + catch (Exception e) + { + m_log.ErrorFormat("Exception in poll service thread: " + e.ToString()); } } } - } } diff --git a/OpenSim/Framework/Servers/HttpServer/RestStreamHandler.cs b/OpenSim/Framework/Servers/HttpServer/RestStreamHandler.cs index 0305dee118..dfc27157a3 100644 --- a/OpenSim/Framework/Servers/HttpServer/RestStreamHandler.cs +++ b/OpenSim/Framework/Servers/HttpServer/RestStreamHandler.cs @@ -50,11 +50,10 @@ namespace OpenSim.Framework.Servers.HttpServer protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { + string requestBody; Encoding encoding = Encoding.UTF8; - StreamReader streamReader = new StreamReader(request, encoding); - - string requestBody = streamReader.ReadToEnd(); - streamReader.Close(); + using(StreamReader streamReader = new StreamReader(request,encoding)) + requestBody = streamReader.ReadToEnd(); string param = GetParam(path); string responseString = m_restMethod(requestBody, path, param, httpRequest, httpResponse); diff --git a/OpenSim/Framework/Servers/MainServer.cs b/OpenSim/Framework/Servers/MainServer.cs index ea7b2b56c4..523ccba1cd 100644 --- a/OpenSim/Framework/Servers/MainServer.cs +++ b/OpenSim/Framework/Servers/MainServer.cs @@ -42,6 +42,7 @@ namespace OpenSim.Framework.Servers // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static BaseHttpServer instance = null; + private static BaseHttpServer unsecureinstance = null; private static Dictionary m_Servers = new Dictionary(); /// @@ -93,6 +94,21 @@ namespace OpenSim.Framework.Servers } } + + public static BaseHttpServer UnSecureInstance + { + get { return unsecureinstance; } + + set + { + lock (m_Servers) + if (!m_Servers.ContainsValue(value)) + throw new Exception("HTTP server must already have been registered to be set as the main instance"); + + unsecureinstance = value; + } + } + /// /// Get all the registered servers. /// @@ -353,5 +369,17 @@ namespace OpenSim.Framework.Servers return m_Servers[port]; } } + + public static void Stop() + { + lock (m_Servers) + { + foreach (BaseHttpServer httpServer in m_Servers.Values) + { + httpServer.Stop(); + } + } + } + } } \ No newline at end of file diff --git a/OpenSim/Framework/Servers/ServerBase.cs b/OpenSim/Framework/Servers/ServerBase.cs index f627ae61ee..3c2dce81c8 100644 --- a/OpenSim/Framework/Servers/ServerBase.cs +++ b/OpenSim/Framework/Servers/ServerBase.cs @@ -274,18 +274,6 @@ namespace OpenSim.Framework.Servers "Show thread status. Synonym for \"show threads\"", (string module, string[] args) => Notice(GetThreadsReport())); - m_console.Commands.AddCommand ( - "Debug", false, "debug comms set", - "debug comms set serialosdreq true|false", - "Set comms parameters. For debug purposes.", - HandleDebugCommsSet); - - m_console.Commands.AddCommand ( - "Debug", false, "debug comms status", - "debug comms status", - "Show current debug comms parameters.", - HandleDebugCommsStatus); - m_console.Commands.AddCommand ( "Debug", false, "debug threadpool set", "debug threadpool set worker|iocp min|max ", @@ -343,47 +331,13 @@ namespace OpenSim.Framework.Servers public void RegisterCommonComponents(IConfigSource configSource) { - IConfig networkConfig = configSource.Configs["Network"]; - - if (networkConfig != null) - { - WebUtil.SerializeOSDRequestsPerEndpoint = networkConfig.GetBoolean("SerializeOSDRequests", false); - } +// IConfig networkConfig = configSource.Configs["Network"]; m_serverStatsCollector = new ServerStatsCollector(); m_serverStatsCollector.Initialise(configSource); m_serverStatsCollector.Start(); } - private void HandleDebugCommsStatus(string module, string[] args) - { - Notice("serialosdreq is {0}", WebUtil.SerializeOSDRequestsPerEndpoint); - } - - private void HandleDebugCommsSet(string module, string[] args) - { - if (args.Length != 5) - { - Notice("Usage: debug comms set serialosdreq true|false"); - return; - } - - if (args[3] != "serialosdreq") - { - Notice("Usage: debug comms set serialosdreq true|false"); - return; - } - - bool setSerializeOsdRequests; - - if (!ConsoleUtil.TryParseConsoleBool(m_console, args[4], out setSerializeOsdRequests)) - return; - - WebUtil.SerializeOSDRequestsPerEndpoint = setSerializeOsdRequests; - - Notice("serialosdreq is now {0}", setSerializeOsdRequests); - } - private void HandleShowThreadpoolCallsActive(string module, string[] args) { List> calls = Util.GetFireAndForgetCallsInProgress().ToList(); @@ -928,16 +882,12 @@ namespace OpenSim.Framework.Servers sb.Append("\n"); } - sb.Append("\n"); + sb.Append(GetThreadPoolReport()); - // For some reason mono 2.6.7 returns an empty threads set! Not going to confuse people by reporting - // zero active threads. + sb.Append("\n"); int totalThreads = Process.GetCurrentProcess().Threads.Count; if (totalThreads > 0) - sb.AppendFormat("Total threads active: {0}\n\n", totalThreads); - - sb.Append("Main threadpool (excluding script engine pools)\n"); - sb.Append(GetThreadPoolReport()); + sb.AppendFormat("Total process threads active: {0}\n\n", totalThreads); return sb.ToString(); } @@ -948,15 +898,46 @@ namespace OpenSim.Framework.Servers /// public static string GetThreadPoolReport() { + + StringBuilder sb = new StringBuilder(); + + // framework pool is alwasy active + int maxWorkers; + int minWorkers; + int curWorkers; + int maxComp; + int minComp; + int curComp; + + try + { + ThreadPool.GetMaxThreads(out maxWorkers, out maxComp); + ThreadPool.GetMinThreads(out minWorkers, out minComp); + ThreadPool.GetAvailableThreads(out curWorkers, out curComp); + curWorkers = maxWorkers - curWorkers; + curComp = maxComp - curComp; + + sb.Append("\nFramework main threadpool \n"); + sb.AppendFormat("workers: {0} ({1} / {2})\n", curWorkers, maxWorkers, minWorkers); + sb.AppendFormat("Completion: {0} ({1} / {2})\n", curComp, maxComp, minComp); + } + catch { } + + if ( + Util.FireAndForgetMethod == FireAndForgetMethod.QueueUserWorkItem + || Util.FireAndForgetMethod == FireAndForgetMethod.UnsafeQueueUserWorkItem) + { + sb.AppendFormat("\nThread pool used: Framework main threadpool\n"); + return sb.ToString(); + } + string threadPoolUsed = null; int maxThreads = 0; int minThreads = 0; int allocatedThreads = 0; int inUseThreads = 0; int waitingCallbacks = 0; - int completionPortThreads = 0; - StringBuilder sb = new StringBuilder(); if (Util.FireAndForgetMethod == FireAndForgetMethod.SmartThreadPool) { STPInfo stpi = Util.GetSmartThreadPoolInfo(); @@ -972,22 +953,10 @@ namespace OpenSim.Framework.Servers waitingCallbacks = stpi.WaitingCallbacks; } } - else if ( - Util.FireAndForgetMethod == FireAndForgetMethod.QueueUserWorkItem - || Util.FireAndForgetMethod == FireAndForgetMethod.UnsafeQueueUserWorkItem) - { - threadPoolUsed = "BuiltInThreadPool"; - ThreadPool.GetMaxThreads(out maxThreads, out completionPortThreads); - ThreadPool.GetMinThreads(out minThreads, out completionPortThreads); - int availableThreads; - ThreadPool.GetAvailableThreads(out availableThreads, out completionPortThreads); - inUseThreads = maxThreads - availableThreads; - allocatedThreads = -1; - waitingCallbacks = -1; - } - + if (threadPoolUsed != null) { + sb.Append("\nThreadpool (excluding script engine pools)\n"); sb.AppendFormat("Thread pool used : {0}\n", threadPoolUsed); sb.AppendFormat("Max threads : {0}\n", maxThreads); sb.AppendFormat("Min threads : {0}\n", minThreads); diff --git a/OpenSim/Framework/Servers/Tests/VersionInfoTests.cs b/OpenSim/Framework/Servers/Tests/VersionInfoTests.cs index 480f2bb41d..68a1c78aa4 100644 --- a/OpenSim/Framework/Servers/Tests/VersionInfoTests.cs +++ b/OpenSim/Framework/Servers/Tests/VersionInfoTests.cs @@ -41,14 +41,5 @@ namespace OpenSim.Framework.Servers.Tests { Assert.AreEqual(VersionInfo.VERSIONINFO_VERSION_LENGTH, VersionInfo.Version.Length," VersionInfo.Version string not " + VersionInfo.VERSIONINFO_VERSION_LENGTH + " chars."); } - - [Test] - public void TestGetVersionStringLength() - { - foreach (VersionInfo.Flavour flavour in Enum.GetValues(typeof(VersionInfo.Flavour))) - { - Assert.AreEqual(VersionInfo.VERSIONINFO_VERSION_LENGTH, VersionInfo.GetVersionString("0.0.0", flavour).Length, "0.0.0/" + flavour + " failed"); - } - } } } diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs index 0ec24e60f4..c5c4ab3970 100644 --- a/OpenSim/Framework/Util.cs +++ b/OpenSim/Framework/Util.cs @@ -30,6 +30,8 @@ using System.Collections; using System.Collections.Generic; using System.Data; using System.Diagnostics; +using System.Drawing; +using System.Drawing.Imaging; using System.Globalization; using System.IO; using System.IO.Compression; @@ -79,7 +81,9 @@ namespace OpenSim.Framework FoldedMask = 0x0f, - // + FoldingShift = 13 , // number of bit shifts from normal perm to folded or back (same as Transfer shift below) + // when doing as a block + Transfer = 1 << 13, // 0x02000 Modify = 1 << 14, // 0x04000 Copy = 1 << 15, // 0x08000 @@ -90,7 +94,9 @@ namespace OpenSim.Framework // explicitly given All = 0x8e000, AllAndExport = 0x9e000, - AllEffective = 0x9e000 + AllAndExportNoMod = 0x9a000, + AllEffective = 0x9e000, + UnfoldedMask = 0x1e000 } /// @@ -153,12 +159,14 @@ namespace OpenSim.Framework public static readonly int MAX_THREADPOOL_LEVEL = 3; public static double TimeStampClockPeriodMS; + public static double TimeStampClockPeriod; static Util() { LogThreadPool = 0; LogOverloads = true; - TimeStampClockPeriodMS = 1000.0D / (double)Stopwatch.Frequency; + TimeStampClockPeriod = 1.0D/ (double)Stopwatch.Frequency; + TimeStampClockPeriodMS = 1e3 * TimeStampClockPeriod; m_log.InfoFormat("[UTIL] TimeStamp clock with period of {0}ms", Math.Round(TimeStampClockPeriodMS,6,MidpointRounding.AwayFromZero)); } @@ -256,10 +264,7 @@ namespace OpenSim.Framework /// The distance between the two vectors public static double GetDistanceTo(Vector3 a, Vector3 b) { - float dx = a.X - b.X; - float dy = a.Y - b.Y; - float dz = a.Z - b.Z; - return Math.Sqrt(dx * dx + dy * dy + dz * dz); + return Vector3.Distance(a,b); } /// @@ -271,10 +276,7 @@ namespace OpenSim.Framework /// public static bool DistanceLessThan(Vector3 a, Vector3 b, double amount) { - float dx = a.X - b.X; - float dy = a.Y - b.Y; - float dz = a.Z - b.Z; - return (dx*dx + dy*dy + dz*dz) < (amount*amount); + return Vector3.DistanceSquared(a,b) < (amount * amount); } /// @@ -375,15 +377,17 @@ namespace OpenSim.Framework get { return randomClass; } } + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public static ulong UIntsToLong(uint X, uint Y) { - return Utils.UIntsToLong(X, Y); + return ((ulong)X << 32) | (ulong)Y; } // Regions are identified with a 'handle' made up of its world coordinates packed into a ulong. // Region handles are based on the coordinate of the region corner with lower X and Y // var regions need more work than this to get that right corner from a generic world position // this corner must be on a grid point + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public static ulong RegionWorldLocToHandle(uint X, uint Y) { ulong handle = X & 0xffffff00; // make sure it matchs grid coord points. @@ -392,6 +396,7 @@ namespace OpenSim.Framework return handle; } + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public static ulong RegionGridLocToHandle(uint X, uint Y) { ulong handle = X; @@ -400,12 +405,14 @@ namespace OpenSim.Framework return handle; } + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public static void RegionHandleToWorldLoc(ulong handle, out uint X, out uint Y) { X = (uint)(handle >> 32); Y = (uint)(handle & 0xfffffffful); } + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public static void RegionHandleToRegionLoc(ulong handle, out uint X, out uint Y) { X = (uint)(handle >> 40) & 0x00ffffffu; // bring from higher half, divide by 256 and clean @@ -415,17 +422,20 @@ namespace OpenSim.Framework // A region location can be 'world coordinates' (meters) or 'region grid coordinates' // grid coordinates have a fixed step of 256m as defined by viewers + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public static uint WorldToRegionLoc(uint worldCoord) { return worldCoord >> 8; } // Convert a region's 'region grid coordinate' to its 'world coordinate'. + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public static uint RegionToWorldLoc(uint regionCoord) { return regionCoord << 8; } + public static bool checkServiceURI(string uristr, out string serviceURI) { serviceURI = string.Empty; @@ -569,14 +579,15 @@ namespace OpenSim.Framework } // Clamp the maximum magnitude of a vector + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public static Vector3 ClampV(Vector3 x, float max) { float lenSq = x.LengthSquared(); if (lenSq > (max * max)) { - x = x / x.Length() * max; + lenSq = max / (float)Math.Sqrt(lenSq); + x = x * lenSq; } - return x; } @@ -665,6 +676,7 @@ namespace OpenSim.Framework public static string GetFormattedXml(string rawXml) { XmlDocument xd = new XmlDocument(); + xd.LoadXml(rawXml); StringBuilder sb = new StringBuilder(); @@ -818,8 +830,8 @@ namespace OpenSim.Framework private static byte[] ComputeMD5Hash(string data, Encoding encoding) { - MD5 md5 = MD5.Create(); - return md5.ComputeHash(encoding.GetBytes(data)); + using(MD5 md5 = MD5.Create()) + return md5.ComputeHash(encoding.GetBytes(data)); } /// @@ -987,6 +999,8 @@ namespace OpenSim.Framework return output.ToString(); } + private static ExpiringCache dnscache = new ExpiringCache(); + /// /// Converts a URL to a IPAddress /// @@ -1004,38 +1018,128 @@ namespace OpenSim.Framework /// An IP address, or null public static IPAddress GetHostFromDNS(string dnsAddress) { - // Is it already a valid IP? No need to look it up. - IPAddress ipa; - if (IPAddress.TryParse(dnsAddress, out ipa)) - return ipa; + if(String.IsNullOrWhiteSpace(dnsAddress)) + return null; - IPAddress[] hosts = null; + IPAddress ia = null; + if(dnscache.TryGetValue(dnsAddress, out ia) && ia != null) + { + dnscache.AddOrUpdate(dnsAddress, ia, 300); + return ia; + } - // Not an IP, lookup required + ia = null; + // If it is already an IP, don't let GetHostEntry see it + if (IPAddress.TryParse(dnsAddress, out ia) && ia != null) + { + if (ia.Equals(IPAddress.Any) || ia.Equals(IPAddress.IPv6Any)) + return null; + dnscache.AddOrUpdate(dnsAddress, ia, 300); + return ia; + } + + IPHostEntry IPH; try { - hosts = Dns.GetHostEntry(dnsAddress).AddressList; + IPH = Dns.GetHostEntry(dnsAddress); } - catch (Exception e) + catch // (SocketException e) { - m_log.WarnFormat("[UTIL]: An error occurred while resolving host name {0}, {1}", dnsAddress, e); - - // Still going to throw the exception on for now, since this was what was happening in the first place - throw e; + return null; } - foreach (IPAddress host in hosts) + if(IPH == null || IPH.AddressList.Length == 0) + return null; + + ia = null; + foreach (IPAddress Adr in IPH.AddressList) { - if (host.AddressFamily == AddressFamily.InterNetwork) + if (ia == null) + ia = Adr; + + if (Adr.AddressFamily == AddressFamily.InterNetwork) { - return host; + ia = Adr; + break; + } + } + if(ia != null) + dnscache.AddOrUpdate(dnsAddress, ia, 300); + return ia; + } + + public static IPEndPoint getEndPoint(IPAddress ia, int port) + { + if(ia == null) + return null; + + IPEndPoint newEP = null; + try + { + newEP = new IPEndPoint(ia, port); + } + catch + { + newEP = null; + } + return newEP; + } + + public static IPEndPoint getEndPoint(string hostname, int port) + { + if(String.IsNullOrWhiteSpace(hostname)) + return null; + + IPAddress ia = null; + if(dnscache.TryGetValue(hostname, out ia) && ia != null) + { + dnscache.AddOrUpdate(hostname, ia, 300); + return getEndPoint(ia, port); + } + + ia = null; + + // If it is already an IP, don't let GetHostEntry see it + if (IPAddress.TryParse(hostname, out ia) && ia != null) + { + if (ia.Equals(IPAddress.Any) || ia.Equals(IPAddress.IPv6Any)) + return null; + + dnscache.AddOrUpdate(hostname, ia, 300); + return getEndPoint(ia, port); + } + + + IPHostEntry IPH; + try + { + IPH = Dns.GetHostEntry(hostname); + } + catch // (SocketException e) + { + return null; + } + + if(IPH == null || IPH.AddressList.Length == 0) + return null; + + ia = null; + foreach (IPAddress Adr in IPH.AddressList) + { + if (ia == null) + ia = Adr; + + if (Adr.AddressFamily == AddressFamily.InterNetwork) + { + ia = Adr; + break; } } - if (hosts.Length > 0) - return hosts[0]; + if(ia != null) + dnscache.AddOrUpdate(hostname, ia, 300); - return null; + return getEndPoint(ia,port); } public static Uri GetURI(string protocol, string hostname, int port, string path) @@ -1815,7 +1919,9 @@ namespace OpenSim.Framework string ru = String.Empty; if (Environment.OSVersion.Platform == PlatformID.Unix) - ru = "Unix/Mono"; + { + ru = "Unix/Mono"; + } else if (Environment.OSVersion.Platform == PlatformID.MacOSX) ru = "OSX/Mono"; @@ -2125,9 +2231,9 @@ namespace OpenSim.Framework // might have gotten an oversized array even after the string trim byte[] data = UTF8.GetBytes(str); - if (data.Length > 256) + if (data.Length > 255) //play safe { - int cut = 255; + int cut = 254; if((data[cut] & 0x80 ) != 0 ) { while(cut > 0 && (data[cut] & 0xc0) != 0xc0) @@ -2229,7 +2335,7 @@ namespace OpenSim.Framework if (data.Length > MaxLength) { - int cut = MaxLength -1 ; + int cut = MaxLength - 1 ; if((data[cut] & 0x80 ) != 0 ) { while(cut > 0 && (data[cut] & 0xc0) != 0xc0) @@ -2396,8 +2502,9 @@ namespace OpenSim.Framework public bool Running { get; set; } public bool Aborted { get; set; } private int started; + public bool DoTimeout; - public ThreadInfo(long threadFuncNum, string context) + public ThreadInfo(long threadFuncNum, string context, bool dotimeout = true) { ThreadFuncNum = threadFuncNum; this.context = context; @@ -2405,6 +2512,7 @@ namespace OpenSim.Framework Thread = null; Running = false; Aborted = false; + DoTimeout = dotimeout; } public void Started() @@ -2475,7 +2583,7 @@ namespace OpenSim.Framework foreach (KeyValuePair entry in activeThreads) { ThreadInfo t = entry.Value; - if (t.Running && !t.Aborted && (t.Elapsed() >= THREAD_TIMEOUT)) + if (t.DoTimeout && t.Running && !t.Aborted && (t.Elapsed() >= THREAD_TIMEOUT)) { m_log.WarnFormat("Timeout in threadfunc {0} ({1}) {2}", t.ThreadFuncNum, t.Thread.Name, t.GetStackTrace()); t.Abort(); @@ -2516,10 +2624,10 @@ namespace OpenSim.Framework FireAndForget(callback, obj, null); } - public static void FireAndForget(System.Threading.WaitCallback callback, object obj, string context) + public static void FireAndForget(System.Threading.WaitCallback callback, object obj, string context, bool dotimeout = true) { Interlocked.Increment(ref numTotalThreadFuncsCalled); - +/* if (context != null) { if (!m_fireAndForgetCallsMade.ContainsKey(context)) @@ -2532,13 +2640,13 @@ namespace OpenSim.Framework else m_fireAndForgetCallsInProgress[context]++; } - +*/ WaitCallback realCallback; bool loggingEnabled = LogThreadPool > 0; long threadFuncNum = Interlocked.Increment(ref nextThreadFuncNum); - ThreadInfo threadInfo = new ThreadInfo(threadFuncNum, context); + ThreadInfo threadInfo = new ThreadInfo(threadFuncNum, context, dotimeout); if (FireAndForgetMethod == FireAndForgetMethod.RegressionTest) { @@ -2549,8 +2657,8 @@ namespace OpenSim.Framework Culture.SetCurrentCulture(); callback(o); - if (context != null) - m_fireAndForgetCallsInProgress[context]--; +// if (context != null) +// m_fireAndForgetCallsInProgress[context]--; }; } else @@ -2574,9 +2682,8 @@ namespace OpenSim.Framework callback(o); } - catch (ThreadAbortException e) + catch (ThreadAbortException) { - m_log.Error(string.Format("Aborted threadfunc {0} ", threadFuncNum), e); } catch (Exception e) { @@ -2591,8 +2698,8 @@ namespace OpenSim.Framework if ((loggingEnabled || (threadFuncOverloadMode == 1)) && threadInfo.LogThread) m_log.DebugFormat("Exit threadfunc {0} ({1})", threadFuncNum, FormatDuration(threadInfo.Elapsed())); - if (context != null) - m_fireAndForgetCallsInProgress[context]--; +// if (context != null) +// m_fireAndForgetCallsInProgress[context]--; } }; } @@ -2758,6 +2865,12 @@ namespace OpenSim.Framework /// The stack trace, or null if failed to get it private static StackTrace GetStackTrace(Thread targetThread) { + + return null; +/* + not only this does not work on mono but it is not longer recomended on windows. + can cause deadlocks etc. + if (IsPlatformMono) { // This doesn't work in Mono @@ -2820,6 +2933,7 @@ namespace OpenSim.Framework // Signal the fallack-thread to stop exitedSafely.Set(); } +*/ } #pragma warning restore 0618 @@ -2849,6 +2963,16 @@ namespace OpenSim.Framework return stpi; } + public static void StopThreadPool() + { + if (m_ThreadPool == null) + return; + SmartThreadPool pool = m_ThreadPool; + m_ThreadPool = null; + + try { pool.Shutdown(); } catch {} + } + #endregion FireAndForget Threading Pattern /// @@ -2862,6 +2986,7 @@ namespace OpenSim.Framework { return Environment.TickCount & EnvironmentTickCountMask; } + const Int32 EnvironmentTickCountMask = 0x3fffffff; /// @@ -2906,11 +3031,36 @@ namespace OpenSim.Framework return tcA - tcB; } + public static long GetPhysicalMemUse() + { + return System.Diagnostics.Process.GetCurrentProcess().WorkingSet64; + } + // returns a timestamp in ms as double // using the time resolution avaiable to StopWatch + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static double GetTimeStamp() + { + return Stopwatch.GetTimestamp() * TimeStampClockPeriod; + } + + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public static double GetTimeStampMS() { - return (double)Stopwatch.GetTimestamp() * TimeStampClockPeriodMS; + return Stopwatch.GetTimestamp() * TimeStampClockPeriodMS; + } + + // doing math in ticks is usefull to avoid loss of resolution + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static long GetTimeStampTicks() + { + return Stopwatch.GetTimestamp(); + } + + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static double TimeStampTicksToMS(long ticks) + { + return ticks * TimeStampClockPeriodMS; } /// @@ -3294,6 +3444,34 @@ namespace OpenSim.Framework m_log.ErrorFormat("{0} Failed XML ({1} bytes) = {2}", message, length, xml); } + /// + /// Performs a high quality image resize + /// + /// Image to resize + /// New width + /// New height + /// Resized image + public static Bitmap ResizeImageSolid(Image image, int width, int height) + { + Bitmap result = new Bitmap(width, height, PixelFormat.Format24bppRgb); + + using (ImageAttributes atrib = new ImageAttributes()) + using (Graphics graphics = Graphics.FromImage(result)) + { + atrib.SetWrapMode(System.Drawing.Drawing2D.WrapMode.TileFlipXY); + atrib.SetWrapMode(System.Drawing.Drawing2D.WrapMode.TileFlipXY); + graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality; + graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; + graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; + graphics.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.None; + + graphics.DrawImage(image,new Rectangle(0,0, result.Width, result.Height), + 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, atrib); + } + + return result; + } + } /* don't like this code @@ -3458,5 +3636,6 @@ namespace OpenSim.Framework { rng.GetBytes(buff); } + } } diff --git a/OpenSim/Framework/VersionInfo.cs b/OpenSim/Framework/VersionInfo.cs index 1e6efe54ef..eac5aae9f1 100644 --- a/OpenSim/Framework/VersionInfo.cs +++ b/OpenSim/Framework/VersionInfo.cs @@ -30,9 +30,9 @@ namespace OpenSim public class VersionInfo { public const string VersionNumber = "0.9.1.0"; - public const string AssemblyVersionNumber = "0.9.1.*"; + public const string AssemblyVersionNumber = "0.9.1.0"; - private const Flavour VERSION_FLAVOUR = Flavour.Dev; + public const Flavour VERSION_FLAVOUR = Flavour.Dev; public enum Flavour { @@ -53,7 +53,7 @@ namespace OpenSim public static string GetVersionString(string versionNumber, Flavour flavour) { - string versionString = "OpenSim " + versionNumber + " " + flavour; + string versionString = "OpenSim " + versionNumber + " Snail " + flavour; return versionString.PadRight(VERSIONINFO_VERSION_LENGTH); } diff --git a/OpenSim/Framework/WebUtil.cs b/OpenSim/Framework/WebUtil.cs index 12f58feb79..417e1cf5e4 100644 --- a/OpenSim/Framework/WebUtil.cs +++ b/OpenSim/Framework/WebUtil.cs @@ -33,7 +33,6 @@ using System.Globalization; using System.IO; using System.IO.Compression; using System.Net; -using System.Net.Security; using System.Reflection; using System.Text; using System.Web; @@ -43,9 +42,9 @@ using System.Xml.Linq; using log4net; using Nwc.XmlRpc; using OpenMetaverse.StructuredData; +using OpenSim.Framework.ServiceAuth; using XMLResponseHelper = OpenSim.Framework.SynchronousRestObjectRequester.XMLResponseHelper; -using OpenSim.Framework.ServiceAuth; namespace OpenSim.Framework { @@ -71,11 +70,6 @@ namespace OpenSim.Framework /// public static int RequestNumber { get; set; } - /// - /// Control where OSD requests should be serialized per endpoint. - /// - public static bool SerializeOSDRequestsPerEndpoint { get; set; } - /// /// this is the header field used to communicate the local request id /// used for performance and debugging @@ -98,31 +92,6 @@ namespace OpenSim.Framework /// public const int MaxRequestDiagLength = 200; - /// - /// Dictionary of end points - /// - private static Dictionary m_endpointSerializer = new Dictionary(); - - private static object EndPointLock(string url) - { - System.Uri uri = new System.Uri(url); - string endpoint = string.Format("{0}:{1}",uri.Host,uri.Port); - - lock (m_endpointSerializer) - { - object eplock = null; - - if (! m_endpointSerializer.TryGetValue(endpoint,out eplock)) - { - eplock = new object(); - m_endpointSerializer.Add(endpoint,eplock); - // m_log.WarnFormat("[WEB UTIL] add a new host to end point serializer {0}",endpoint); - } - - return eplock; - } - } - #region JSONRequest /// @@ -154,21 +123,6 @@ namespace OpenSim.Framework return ServiceOSDRequest(url, null, "GET", timeout, false, false); } - public static OSDMap ServiceOSDRequest(string url, OSDMap data, string method, int timeout, bool compressed, bool rpc) - { - if (SerializeOSDRequestsPerEndpoint) - { - lock (EndPointLock(url)) - { - return ServiceOSDRequestWorker(url, data, method, timeout, compressed, rpc); - } - } - else - { - return ServiceOSDRequestWorker(url, data, method, timeout, compressed, rpc); - } - } - public static void LogOutgoingDetail(Stream outputStream) { LogOutgoingDetail("", outputStream); @@ -222,7 +176,7 @@ namespace OpenSim.Framework LogOutgoingDetail(string.Format("RESPONSE {0}: ", reqnum), input); } - private static OSDMap ServiceOSDRequestWorker(string url, OSDMap data, string method, int timeout, bool compressed, bool rpc) + public static OSDMap ServiceOSDRequest(string url, OSDMap data, string method, int timeout, bool compressed, bool rpc) { int reqnum = RequestNumber++; @@ -245,7 +199,7 @@ namespace OpenSim.Framework request.Timeout = timeout; request.KeepAlive = false; request.MaximumAutomaticRedirections = 10; - request.ReadWriteTimeout = timeout / 4; + request.ReadWriteTimeout = timeout / 2; request.Headers[OSHeaderRequestID] = reqnum.ToString(); // If there is some input, write it into the request @@ -421,14 +375,6 @@ namespace OpenSim.Framework } public static OSDMap ServiceFormRequest(string url, NameValueCollection data, int timeout) - { - lock (EndPointLock(url)) - { - return ServiceFormRequestWorker(url,data,timeout); - } - } - - private static OSDMap ServiceFormRequestWorker(string url, NameValueCollection data, int timeout) { int reqnum = RequestNumber++; string method = (data != null && data["RequestMethod"] != null) ? data["RequestMethod"] : "unknown"; @@ -449,7 +395,7 @@ namespace OpenSim.Framework request.Timeout = timeout; request.KeepAlive = false; request.MaximumAutomaticRedirections = 10; - request.ReadWriteTimeout = timeout / 4; + request.ReadWriteTimeout = timeout / 2; request.Headers[OSHeaderRequestID] = reqnum.ToString(); if (data != null) @@ -1315,18 +1261,24 @@ namespace OpenSim.Framework { if (hwr.StatusCode == HttpStatusCode.NotFound) return deserial; + if (hwr.StatusCode == HttpStatusCode.Unauthorized) { - m_log.Error(string.Format( - "[SynchronousRestObjectRequester]: Web request {0} requires authentication ", - requestUrl)); - return deserial; + m_log.ErrorFormat("[SynchronousRestObjectRequester]: Web request {0} requires authentication", + requestUrl); + } + else + { + m_log.WarnFormat("[SynchronousRestObjectRequester]: Web request {0} returned error: {1}", + requestUrl, hwr.StatusCode); } } else - m_log.Error(string.Format( - "[SynchronousRestObjectRequester]: WebException for {0} {1} {2} ", - verb, requestUrl, typeof(TResponse).ToString()), e); + m_log.ErrorFormat( + "[SynchronousRestObjectRequester]: WebException for {0} {1} {2} {3}", + verb, requestUrl, typeof(TResponse).ToString(), e.Message); + + return deserial; } } catch (System.InvalidOperationException) @@ -1381,16 +1333,42 @@ namespace OpenSim.Framework public static TResponse LogAndDeserialize(int reqnum, Stream respStream, long contentLength) { XmlSerializer deserializer = new XmlSerializer(typeof(TResponse)); - if (WebUtil.DebugLevel >= 5) { - byte[] data = new byte[contentLength]; - Util.ReadStream(respStream, data); + const int blockLength = 4096; + byte[] dataBuffer = new byte[blockLength]; + int curcount; + using (MemoryStream ms = new MemoryStream(4 * blockLength)) + { + if(contentLength == -1) + { + while (true) + { + curcount = respStream.Read(dataBuffer, 0, blockLength); + if (curcount <= 0) + break; + ms.Write(dataBuffer, 0, curcount); + } + } + else + { + int remaining = (int)contentLength; + while (remaining > 0) + { + curcount = respStream.Read(dataBuffer, 0, remaining); + if (curcount <= 0) + throw new EndOfStreamException(String.Format("End of stream reached with {0} bytes left to read", remaining)); + ms.Write(dataBuffer, 0, curcount); + remaining -= curcount; + } + } - WebUtil.LogResponseDetail(reqnum, System.Text.Encoding.UTF8.GetString(data)); + dataBuffer = ms.ToArray(); + WebUtil.LogResponseDetail(reqnum, System.Text.Encoding.UTF8.GetString(dataBuffer)); - using (MemoryStream temp = new MemoryStream(data)) - return (TResponse)deserializer.Deserialize(temp); + ms.Position = 0; + return (TResponse)deserializer.Deserialize(ms); + } } else { @@ -1474,6 +1452,5 @@ namespace OpenSim.Framework } } } - } } diff --git a/OpenSim/Region/Application/Application.cs b/OpenSim/Region/Application/Application.cs index 5cb6a88e94..66ce8e5e3d 100644 --- a/OpenSim/Region/Application/Application.cs +++ b/OpenSim/Region/Application/Application.cs @@ -74,7 +74,15 @@ namespace OpenSim AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); - ServicePointManager.DefaultConnectionLimit = 12; + if(Util.IsWindows()) + ServicePointManager.DefaultConnectionLimit = 32; + else + { + ServicePointManager.DefaultConnectionLimit = 12; + } + + try { ServicePointManager.DnsRefreshTimeout = 300000; } catch { } + ServicePointManager.Expect100Continue = false; ServicePointManager.UseNagleAlgorithm = false; // Add the arguments supplied when running the application to the configuration diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs index 58178bcf50..fcc87177a6 100644 --- a/OpenSim/Region/Application/OpenSim.cs +++ b/OpenSim/Region/Application/OpenSim.cs @@ -33,6 +33,7 @@ using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; +using System.Runtime; using System.Text; using System.Text.RegularExpressions; using System.Timers; @@ -124,8 +125,11 @@ namespace OpenSim Util.InitThreadPool(stpMinThreads, stpMaxThreads); m_log.Info("[OPENSIM MAIN]: Using async_call_method " + Util.FireAndForgetMethod); + + m_log.InfoFormat("[OPENSIM MAIN] Running GC in {0} mode", GCSettings.IsServerGC ? "server":"workstation"); } +#if (_MONO) private static Mono.Unix.UnixSignal[] signals; @@ -139,7 +143,8 @@ namespace OpenSim //Mono.Unix.Native.Signum signal = signals [index].Signum; MainConsole.Instance.RunCommand("shutdown"); } - }); + }); +#endif /// /// Performs initialisation of the scene, such as loading configuration from disk. @@ -150,6 +155,7 @@ namespace OpenSim m_log.Info("========================= STARTING OPENSIM ========================="); m_log.Info("===================================================================="); +#if (_MONO) if(!Util.IsWindows()) { try @@ -159,6 +165,7 @@ namespace OpenSim { new Mono.Unix.UnixSignal(Mono.Unix.Native.Signum.SIGTERM) }; + signal_thread.IsBackground = true; signal_thread.Start(); } catch (Exception e) @@ -168,6 +175,7 @@ namespace OpenSim m_log.Debug("Exception was: ", e); } } +#endif //m_log.InfoFormat("[OPENSIM MAIN]: GC Is Server GC: {0}", GCSettings.IsServerGC.ToString()); // http://msdn.microsoft.com/en-us/library/bb384202.aspx //GCSettings.LatencyMode = GCLatencyMode.Batch; @@ -478,6 +486,12 @@ namespace OpenSim RunCommandScript(m_shutdownCommandsFile); } + if (m_timedScript != "disabled") + { + m_scriptTimer.Dispose(); + m_timedScript = "disabled"; + } + base.ShutdownSpecific(); } @@ -497,7 +511,6 @@ namespace OpenSim private void WatchdogTimeoutHandler(Watchdog.ThreadWatchdogInfo twi) { int now = Environment.TickCount & Int32.MaxValue; - m_log.ErrorFormat( "[WATCHDOG]: Timeout detected for thread \"{0}\". ThreadState={1}. Last tick was {2}ms ago. {3}", twi.Thread.Name, diff --git a/OpenSim/Region/Application/OpenSimBase.cs b/OpenSim/Region/Application/OpenSimBase.cs index 168836c1e9..7a221c4123 100644 --- a/OpenSim/Region/Application/OpenSimBase.cs +++ b/OpenSim/Region/Application/OpenSimBase.cs @@ -237,7 +237,7 @@ namespace OpenSim string permissionModules = Util.GetConfigVarFromSections(Config, "permissionmodules", new string[] { "Startup", "Permissions" }, "DefaultPermissionsModule"); - m_permsModules = new List(permissionModules.Split(',')); + m_permsModules = new List(permissionModules.Split(',').Select(m => m.Trim())); managedStatsURI = startupConfig.GetString("ManagedStatsRemoteFetchURI", String.Empty); managedStatsPassword = startupConfig.GetString("ManagedStatsRemoteFetchPassword", String.Empty); @@ -353,7 +353,18 @@ namespace OpenSim if (startupConfig == null || startupConfig.GetBoolean("JobEngineEnabled", true)) WorkManager.JobEngine.Start(); - m_httpServerPort = m_networkServersInfo.HttpListenerPort; + + if(m_networkServersInfo.HttpUsesSSL) + { + m_httpServerSSL = true; + m_httpServerPort = m_networkServersInfo.httpSSLPort; + } + else + { + m_httpServerSSL = false; + m_httpServerPort = m_networkServersInfo.HttpListenerPort; + } + SceneManager.OnRestartSim += HandleRestartRegion; // Only enable the watchdogs when all regions are ready. Otherwise we get false positives when cpu is @@ -406,7 +417,18 @@ namespace OpenSim // set initial ServerURI regionInfo.HttpPort = m_httpServerPort; - regionInfo.ServerURI = "http://" + regionInfo.ExternalHostName + ":" + regionInfo.HttpPort.ToString() + "/"; + if(m_httpServerSSL) + { + if(!m_httpServer.CheckSSLCertHost(regionInfo.ExternalHostName)) + throw new Exception("main http cert CN doesn't match region External IP"); + + regionInfo.ServerURI = "https://" + regionInfo.ExternalHostName + + ":" + regionInfo.HttpPort.ToString() + "/"; + } + else + regionInfo.ServerURI = "http://" + regionInfo.ExternalHostName + + ":" + regionInfo.HttpPort.ToString() + "/"; + regionInfo.osSecret = m_osSecret; @@ -455,7 +477,7 @@ namespace OpenSim if (scene.SnmpService != null) { - scene.SnmpService.BootInfo("Loading prins", scene); + scene.SnmpService.BootInfo("Loading prims", scene); } while (regionInfo.EstateSettings.EstateOwner == UUID.Zero && MainConsole.Instance != null) @@ -1104,10 +1126,10 @@ namespace OpenSim MainConsole.Instance.Output("Joining the estate failed. Please try again."); } } - } + } - return true; // need to update the database - } + return true; // need to update the database + } } public class OpenSimConfigSource diff --git a/OpenSim/Region/Application/Properties/AssemblyInfo.cs b/OpenSim/Region/Application/Properties/AssemblyInfo.cs index 09772d369d..0a75094168 100644 --- a/OpenSim/Region/Application/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/Application/Properties/AssemblyInfo.cs @@ -7,7 +7,7 @@ using Mono.Addins; // set of attributes. Change these attribute values to modify the information // associated with an assembly. [assembly: AssemblyTitle("OpenSim")] -[assembly: AssemblyDescription("The executable for for simulator")] +[assembly: AssemblyDescription("The executable for regions simulator")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("http://opensimulator.org")] [assembly: AssemblyProduct("OpenSim")] diff --git a/OpenSim/Region/Application/RegionApplicationBase.cs b/OpenSim/Region/Application/RegionApplicationBase.cs index 83a9fff31d..0112c1e927 100644 --- a/OpenSim/Region/Application/RegionApplicationBase.cs +++ b/OpenSim/Region/Application/RegionApplicationBase.cs @@ -50,6 +50,7 @@ namespace OpenSim protected Dictionary m_clientCircuits = new Dictionary(); protected NetworkServersInfo m_networkServersInfo; protected uint m_httpServerPort; + protected bool m_httpServerSSL; protected ISimulationDataService m_simulationDataService; protected IEstateDataService m_estateDataService; @@ -68,20 +69,37 @@ namespace OpenSim Initialize(); - m_httpServer - = new BaseHttpServer( - m_httpServerPort, m_networkServersInfo.HttpUsesSSL, m_networkServersInfo.httpSSLPort, - m_networkServersInfo.HttpSSLCN); + uint mainport = m_networkServersInfo.HttpListenerPort; + uint mainSSLport = m_networkServersInfo.httpSSLPort; - if (m_networkServersInfo.HttpUsesSSL && (m_networkServersInfo.HttpListenerPort == m_networkServersInfo.httpSSLPort)) + if (m_networkServersInfo.HttpUsesSSL && (mainport == mainSSLport)) { m_log.Error("[REGION SERVER]: HTTP Server config failed. HTTP Server and HTTPS server must be on different ports"); } - m_log.InfoFormat("[REGION SERVER]: Starting HTTP server on port {0}", m_httpServerPort); - m_httpServer.Start(); + if(m_networkServersInfo.HttpUsesSSL) + { + m_httpServer = new BaseHttpServer( + mainSSLport, m_networkServersInfo.HttpUsesSSL, + m_networkServersInfo.HttpSSLCN, + m_networkServersInfo.HttpSSLCertPath, m_networkServersInfo.HttpSSLCNCertPass); + m_httpServer.Start(true,true); + MainServer.AddHttpServer(m_httpServer); + } + + // unsecure main server + BaseHttpServer server = new BaseHttpServer(mainport); + if(!m_networkServersInfo.HttpUsesSSL) + { + m_httpServer = server; + server.Start(true, true); + } + else + server.Start(false, false); + + MainServer.AddHttpServer(server); + MainServer.UnSecureInstance = server; - MainServer.AddHttpServer(m_httpServer); MainServer.Instance = m_httpServer; // "OOB" Server @@ -89,22 +107,22 @@ namespace OpenSim { if (!m_networkServersInfo.ssl_external) { - BaseHttpServer server = new BaseHttpServer( - m_networkServersInfo.https_port, m_networkServersInfo.ssl_listener, m_networkServersInfo.cert_path, + server = new BaseHttpServer( + m_networkServersInfo.https_port, m_networkServersInfo.ssl_listener, + m_networkServersInfo.cert_path, m_networkServersInfo.cert_pass); - m_log.InfoFormat("[REGION SERVER]: Starting HTTPS server on port {0}", server.Port); + m_log.InfoFormat("[REGION SERVER]: Starting OOB HTTPS server on port {0}", server.SSLPort); + server.Start(false, false); MainServer.AddHttpServer(server); - server.Start(); } else { - BaseHttpServer server = new BaseHttpServer( - m_networkServersInfo.https_port); + server = new BaseHttpServer(m_networkServersInfo.https_port); m_log.InfoFormat("[REGION SERVER]: Starting HTTP server on port {0} for external HTTPS", server.Port); + server.Start(false, false); MainServer.AddHttpServer(server); - server.Start(); } } diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs index 58b7b00169..a02ef9d7e1 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs @@ -503,7 +503,6 @@ namespace OpenSim.Region.ClientStack.Linden errorResponse.state = "error"; errorResponse.error = resperror; return errorResponse; - break; case FileAgentInventoryState.waitUpload: // todo stop current uploader server break; @@ -611,9 +610,8 @@ namespace OpenSim.Region.ClientStack.Linden IsAtestUpload = (assetName.Length > 5 && assetName.StartsWith("TEST-")); } - if(IsAtestUpload) // let user know, still showing cost estimation - warning += "Upload will have no cost, for testing purposes only. Other uses are prohibited. Items will not work after 48 hours or on other regions"; + warning += "Upload will have no cost, for testing purposes only. Other uses are prohibited. Items will be local to region only, Inventory entry will be lost on logout"; // check funds else @@ -634,6 +632,12 @@ namespace OpenSim.Region.ClientStack.Linden } } } + else if (m_enableFreeTestUpload) // only if prefixed with "TEST-" + { + IsAtestUpload = (assetName.Length > 5 && assetName.StartsWith("TEST-")); + if(IsAtestUpload) + warning += "Upload for testing purposes only. Items will be local to region only, Inventory entry will be lost on logout"; + } if (client != null && warning != String.Empty) client.SendAgentAlertMessage(warning, true); @@ -716,7 +720,7 @@ namespace OpenSim.Region.ClientStack.Linden UUID owner_id = m_HostCapsObj.AgentID; UUID creatorID; - bool istest = IsAtestUpload && m_enableFreeTestUpload && (cost > 0); + bool istest = IsAtestUpload && m_enableFreeTestUpload; bool restrictPerms = m_RestrictFreeTestUploadPerms && istest; @@ -946,17 +950,26 @@ namespace OpenSim.Region.ClientStack.Linden continue; } - PrimitiveBaseShape pbs = PrimitiveBaseShape.CreateBox(); + OSDArray face_list = (OSDArray)inner_instance_list["face_list"]; + + PrimitiveBaseShape pbs = null; + if (inner_instance_list.ContainsKey("mesh")) // seems to happen always but ... + { + int meshindx = inner_instance_list["mesh"].AsInteger(); + if (meshAssets.Count > meshindx) + pbs = PrimitiveBaseShape.CreateMesh(face_list.Count, meshAssets[meshindx]); + } + if(pbs == null) // fallback + pbs = PrimitiveBaseShape.CreateBox(); Primitive.TextureEntry textureEntry = new Primitive.TextureEntry(Primitive.TextureEntry.WHITE_TEXTURE); - - OSDArray face_list = (OSDArray)inner_instance_list["face_list"]; for (uint face = 0; face < face_list.Count; face++) { OSDMap faceMap = (OSDMap)face_list[(int)face]; - Primitive.TextureEntryFace f = pbs.Textures.CreateFace(face); + + Primitive.TextureEntryFace f = textureEntry.CreateFace(face); //clone the default if (faceMap.ContainsKey("fullbright")) f.Fullbright = faceMap["fullbright"].AsBoolean(); if (faceMap.ContainsKey("diffuse_color")) @@ -986,51 +999,11 @@ namespace OpenSim.Region.ClientStack.Linden if (textures.Count > textureNum) f.TextureID = textures[textureNum]; - else - f.TextureID = Primitive.TextureEntry.WHITE_TEXTURE; - + textureEntry.FaceTextures[face] = f; } - pbs.TextureEntry = textureEntry.GetBytes(); - if (inner_instance_list.ContainsKey("mesh")) // seems to happen always but ... - { - int meshindx = inner_instance_list["mesh"].AsInteger(); - if (meshAssets.Count > meshindx) - { - pbs.SculptEntry = true; - pbs.SculptType = (byte)SculptType.Mesh; - pbs.SculptTexture = meshAssets[meshindx]; // actual asset UUID after meshs suport introduction - // data will be requested from asset on rez (i hope) - } - } - - // faces number to pbs shape - switch(face_list.Count) - { - case 1: - case 2: - pbs.ProfileCurve = (byte)ProfileCurve.Circle; - pbs.PathCurve = (byte)PathCurve.Circle; - break; - - case 3: - case 4: - pbs.ProfileCurve = (byte)ProfileCurve.Circle; - pbs.PathCurve = (byte)PathCurve.Line; - break; - case 5: - pbs.ProfileCurve = (byte)ProfileCurve.EqualTriangle; - pbs.PathCurve = (byte)PathCurve.Line; - break; - - default: - pbs.ProfileCurve = (byte)ProfileCurve.Square; - pbs.PathCurve = (byte)PathCurve.Line; - break; - } - Vector3 position = inner_instance_list["position"].AsVector3(); Quaternion rotation = inner_instance_list["rotation"].AsQuaternion(); @@ -1408,30 +1381,37 @@ namespace OpenSim.Region.ClientStack.Linden IOSHttpResponse httpResponse) { OSDMap req = (OSDMap)OSDParser.DeserializeLLSDXml(request); - OSDMap resp = new OSDMap(); OSDArray object_ids = (OSDArray)req["object_ids"]; - for (int i = 0 ; i < object_ids.Count ; i++) + StringBuilder lsl = LLSDxmlEncode.Start(); + + if(object_ids.Count == 0) + LLSDxmlEncode.AddEmptyMap(lsl); + else { - UUID uuid = object_ids[i].AsUUID(); - - SceneObjectPart obj = m_Scene.GetSceneObjectPart(uuid); - if (obj != null) + LLSDxmlEncode.AddMap(lsl); + for (int i = 0 ; i < object_ids.Count ; i++) { - OSDMap object_data = new OSDMap(); + UUID uuid = object_ids[i].AsUUID(); - object_data["PhysicsShapeType"] = obj.PhysicsShapeType; - object_data["Density"] = obj.Density; - object_data["Friction"] = obj.Friction; - object_data["Restitution"] = obj.Restitution; - object_data["GravityMultiplier"] = obj.GravityModifier; + SceneObjectPart obj = m_Scene.GetSceneObjectPart(uuid); + if (obj != null) + { + LLSDxmlEncode.AddMap(uuid.ToString(),lsl); - resp[uuid.ToString()] = object_data; + LLSDxmlEncode.AddElem("PhysicsShapeType", obj.PhysicsShapeType, lsl); + LLSDxmlEncode.AddElem("Density", obj.Density, lsl); + LLSDxmlEncode.AddElem("Friction", obj.Friction, lsl); + LLSDxmlEncode.AddElem("Restitution", obj.Restitution, lsl); + LLSDxmlEncode.AddElem("GravityMultiplier", obj.GravityModifier, lsl); + + LLSDxmlEncode.AddEndMap(lsl); + } + LLSDxmlEncode.AddEndMap(lsl); } } - - string response = OSDParser.SerializeLLSDXmlString(resp); - return response; + + return LLSDxmlEncode.End(lsl); } public string GetObjectCost(string request, string path, @@ -1439,47 +1419,59 @@ namespace OpenSim.Region.ClientStack.Linden IOSHttpResponse httpResponse) { OSDMap req = (OSDMap)OSDParser.DeserializeLLSDXml(request); - OSDMap resp = new OSDMap(); - OSDArray object_ids = (OSDArray)req["object_ids"]; - for (int i = 0; i < object_ids.Count; i++) + StringBuilder lsl = LLSDxmlEncode.Start(512); + + if(object_ids.Count == 0) + LLSDxmlEncode.AddEmptyMap(lsl); + else { - UUID uuid = object_ids[i].AsUUID(); - - SceneObjectPart part = m_Scene.GetSceneObjectPart(uuid); - SceneObjectGroup grp = null; - if (part != null) - grp = part.ParentGroup; - if (grp != null) + bool haveone = false; + LLSDxmlEncode.AddMap(lsl); + for (int i = 0; i < object_ids.Count; i++) { - float linksetCost; - float linksetPhysCost; - float partCost; - float partPhysCost; + UUID uuid = object_ids[i].AsUUID(); - grp.GetResourcesCosts(part,out linksetCost,out linksetPhysCost,out partCost,out partPhysCost); + SceneObjectPart part = m_Scene.GetSceneObjectPart(uuid); + SceneObjectGroup grp = null; + if (part != null) + grp = part.ParentGroup; + if (grp != null) + { + haveone = true; + float linksetCost; + float linksetPhysCost; + float partCost; + float partPhysCost; - OSDMap object_data = new OSDMap(); - object_data["linked_set_resource_cost"] = linksetCost; - object_data["resource_cost"] = partCost; - object_data["physics_cost"] = partPhysCost; - object_data["linked_set_physics_cost"] = linksetPhysCost; - object_data["resource_limiting_type"] = "legacy"; - resp[uuid.ToString()] = object_data; + grp.GetResourcesCosts(part,out linksetCost,out linksetPhysCost,out partCost,out partPhysCost); + + LLSDxmlEncode.AddMap(uuid.ToString(), lsl); + + LLSDxmlEncode.AddElem("linked_set_resource_cost", linksetCost, lsl); + LLSDxmlEncode.AddElem("resource_cost", partCost, lsl); + LLSDxmlEncode.AddElem("physics_cost", partPhysCost, lsl); + LLSDxmlEncode.AddElem("linked_set_physics_cost", linksetPhysCost, lsl); + LLSDxmlEncode.AddElem("resource_limiting_type", "legacy", lsl); + + LLSDxmlEncode.AddEndMap(lsl); + } } + if(!haveone) + { + LLSDxmlEncode.AddMap(UUID.Zero.ToString(), lsl); + LLSDxmlEncode.AddElem("linked_set_resource_cost", 0, lsl); + LLSDxmlEncode.AddElem("resource_cost", 0, lsl); + LLSDxmlEncode.AddElem("physics_cost", 0, lsl); + LLSDxmlEncode.AddElem("linked_set_physics_cost", 0, lsl); + LLSDxmlEncode.AddElem("resource_limiting_type", "legacy", lsl); + LLSDxmlEncode.AddEndMap(lsl); + } + LLSDxmlEncode.AddEndMap(lsl); } - if(resp.Count == 0) - { - OSDMap object_data = new OSDMap(); - object_data["linked_set_resource_cost"] = 0; - object_data["resource_cost"] = 0; - object_data["physics_cost"] = 0; - object_data["linked_set_physics_cost"] = 0; - resp[UUID.Zero.ToString()] = object_data; - } - string response = OSDParser.SerializeLLSDXmlString(resp); - return response; + + return LLSDxmlEncode.End(lsl); } public string ResourceCostSelected(string request, string path, @@ -1487,8 +1479,6 @@ namespace OpenSim.Region.ClientStack.Linden IOSHttpResponse httpResponse) { OSDMap req = (OSDMap)OSDParser.DeserializeLLSDXml(request); - OSDMap resp = new OSDMap(); - float phys=0; float stream=0; @@ -1539,16 +1529,21 @@ namespace OpenSim.Region.ClientStack.Linden } } - OSDMap object_data = new OSDMap(); + StringBuilder lsl = LLSDxmlEncode.Start(); + LLSDxmlEncode.AddMap(lsl); - object_data["physics"] = phys; - object_data["streaming"] = stream; - object_data["simulation"] = simul; + LLSDxmlEncode.AddMap("selected", lsl); - resp["selected"] = object_data; + LLSDxmlEncode.AddElem("physics", phys, lsl); + LLSDxmlEncode.AddElem("streaming", stream, lsl); + LLSDxmlEncode.AddElem("simulation", simul, lsl); + + LLSDxmlEncode.AddEndMap(lsl); + LLSDxmlEncode.AddEndMap(lsl); + // resp["transaction_id"] = "undef"; - string response = OSDParser.SerializeLLSDXmlString(resp); - return response; + return LLSDxmlEncode.End(lsl); + } public string UpdateAgentInformation(string request, string path, @@ -1608,7 +1603,10 @@ namespace OpenSim.Region.ClientStack.Linden break; m_Scene.TryGetScenePresence(m_AgentID, out sp); - if(sp == null || sp.IsChildAgent || sp.IsDeleted || sp.IsInTransit) + if(sp == null || sp.IsChildAgent || sp.IsDeleted) + break; + + if(sp.IsInTransit && !sp.IsInLocalTransit) break; client = sp.ControllingClient; @@ -1730,7 +1728,10 @@ namespace OpenSim.Region.ClientStack.Linden break; m_Scene.TryGetScenePresence(m_AgentID, out sp); - if(sp == null || sp.IsChildAgent || sp.IsDeleted || sp.IsInTransit) + if(sp == null || sp.IsChildAgent || sp.IsDeleted) + break; + + if(sp.IsInTransit && !sp.IsInLocalTransit) break; client = sp.ControllingClient; @@ -1838,59 +1839,60 @@ namespace OpenSim.Region.ClientStack.Linden if(sp == null || sp.IsDeleted) return ""; - if(sp.IsInTransit) + if(sp.IsInTransit && !sp.IsInLocalTransit) { httpResponse.StatusCode = (int)System.Net.HttpStatusCode.ServiceUnavailable; httpResponse.AddHeader("Retry-After","30"); return ""; } - NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query); - string[] ids = query.GetValues("ids"); - - - Dictionary names = m_UserManager.GetUsersNames(ids); - - OSDMap osdReply = new OSDMap(); - OSDArray agents = new OSDArray(); - - osdReply["agents"] = agents; - foreach (KeyValuePair kvp in names) - { - if (string.IsNullOrEmpty(kvp.Value)) - continue; - if(kvp.Key == UUID.Zero) - continue; - - string[] parts = kvp.Value.Split(new char[] {' '}); - OSDMap osdname = new OSDMap(); - if(parts[0] == "Unknown") - { - osdname["display_name_next_update"] = OSD.FromDate(DateTime.UtcNow.AddHours(1)); - osdname["display_name_expires"] = OSD.FromDate(DateTime.UtcNow.AddHours(2)); - } - else - { - osdname["display_name_next_update"] = OSD.FromDate(DateTime.UtcNow.AddDays(8)); - osdname["display_name_expires"] = OSD.FromDate(DateTime.UtcNow.AddMonths(1)); - } - osdname["display_name"] = OSD.FromString(kvp.Value); - osdname["legacy_first_name"] = parts[0]; - osdname["legacy_last_name"] = parts[1]; - osdname["username"] = OSD.FromString(kvp.Value); - osdname["id"] = OSD.FromUUID(kvp.Key); - osdname["is_display_name_default"] = OSD.FromBoolean(true); - - agents.Add(osdname); - } - // Full content request httpResponse.StatusCode = (int)System.Net.HttpStatusCode.OK; //httpResponse.ContentLength = ??; httpResponse.ContentType = "application/llsd+xml"; - string reply = OSDParser.SerializeLLSDXmlString(osdReply); - return reply; + NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query); + string[] ids = query.GetValues("ids"); + + Dictionary names = m_UserManager.GetUsersNames(ids); + + StringBuilder lsl = LLSDxmlEncode.Start(names.Count * 256 + 256); + LLSDxmlEncode.AddMap(lsl); + if(names.Count == 0) + LLSDxmlEncode.AddEmptyArray("agents", lsl); + else + { + LLSDxmlEncode.AddArray("agents", lsl); + + foreach (KeyValuePair kvp in names) + { + if (string.IsNullOrEmpty(kvp.Value)) + continue; + if(kvp.Key == UUID.Zero) + continue; + + string[] parts = kvp.Value.Split(new char[] {' '}); + + // dont tell about unknown users, we can't send them back on Bad either + if(parts[0] == "Unknown") + continue; + + LLSDxmlEncode.AddMap(lsl); + LLSDxmlEncode.AddElem("display_name_next_update", DateTime.UtcNow.AddDays(8), lsl); + LLSDxmlEncode.AddElem("display_name_expires", DateTime.UtcNow.AddMonths(1), lsl); + LLSDxmlEncode.AddElem("display_name", kvp.Value, lsl); + LLSDxmlEncode.AddElem("legacy_first_name", parts[0], lsl); + LLSDxmlEncode.AddElem("legacy_last_name", parts[1], lsl); + LLSDxmlEncode.AddElem("username", kvp.Value, lsl); + LLSDxmlEncode.AddElem("id", kvp.Key, lsl); + LLSDxmlEncode.AddElem("is_display_name_default", true, lsl); + LLSDxmlEncode.AddEndMap(lsl); + } + LLSDxmlEncode.AddEndArray(lsl); + } + + LLSDxmlEncode.AddEndMap(lsl); + return LLSDxmlEncode.End(lsl);; } } @@ -2008,34 +2010,30 @@ namespace OpenSim.Region.ClientStack.Linden uploadComplete.new_group_mask = m_groupMask; uploadComplete.new_everyone_mask = m_everyoneMask; - if (m_IsAtestUpload) + if (m_error == String.Empty) { - LLSDAssetUploadError resperror = new LLSDAssetUploadError(); - resperror.message = "Upload SUCESSEFULL for testing purposes only. Other uses are prohibited. Item will not work after 48 hours or on other regions"; - resperror.identifier = inv; - - uploadComplete.error = resperror; - uploadComplete.state = "Upload4Testing"; + uploadComplete.new_asset = newAssetID.ToString(); + uploadComplete.new_inventory_item = inv; + // if (m_texturesFolder != UUID.Zero) + // uploadComplete.new_texture_folder_id = m_texturesFolder; + if (m_IsAtestUpload) + { + LLSDAssetUploadError resperror = new LLSDAssetUploadError(); + resperror.message = "Upload SUCCESSFUL for testing purposes only. Other uses are prohibited. Item will not work after 48 hours or on other regions"; + resperror.identifier = inv; + + uploadComplete.error = resperror; + } + uploadComplete.state = "complete"; } else { - if (m_error == String.Empty) - { - uploadComplete.new_asset = newAssetID.ToString(); - uploadComplete.new_inventory_item = inv; - // if (m_texturesFolder != UUID.Zero) - // uploadComplete.new_texture_folder_id = m_texturesFolder; - uploadComplete.state = "complete"; - } - else - { - LLSDAssetUploadError resperror = new LLSDAssetUploadError(); - resperror.message = m_error; - resperror.identifier = inv; + LLSDAssetUploadError resperror = new LLSDAssetUploadError(); + resperror.message = m_error; + resperror.identifier = inv; - uploadComplete.error = resperror; - uploadComplete.state = "failed"; - } + uploadComplete.error = resperror; + uploadComplete.state = "failed"; } res = LLSDHelpers.SerialiseLLSDReply(uploadComplete); diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs index 1feece1f70..442cc65ca5 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs @@ -30,7 +30,7 @@ using System.Collections; using System.Collections.Generic; using System.Net; using System.Reflection; -using System.Threading; +using System.Text; using log4net; using Nini.Config; using Mono.Addins; @@ -44,7 +44,6 @@ using OpenSim.Framework.Servers; using OpenSim.Framework.Servers.HttpServer; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; -using BlockingLLSDQueue = OpenSim.Framework.BlockingQueue; using Caps=OpenSim.Framework.Capabilities.Caps; namespace OpenSim.Region.ClientStack.Linden @@ -292,8 +291,6 @@ namespace OpenSim.Region.ClientStack.Linden Queue queue; Random rnd = new Random(Environment.TickCount); int nrnd = rnd.Next(30000000); - if (nrnd < 0) - nrnd = -nrnd; lock (queues) { @@ -307,21 +304,11 @@ namespace OpenSim.Region.ClientStack.Linden queue = new Queue(); queues[agentID] = queue; - // push markers to handle old responses still waiting - // this will cost at most viewer getting two forced noevents - // even being a new queue better be safe - queue.Enqueue(null); - queue.Enqueue(null); // one should be enough - lock (m_AvatarQueueUUIDMapping) { eventQueueGetUUID = UUID.Random(); - if (m_AvatarQueueUUIDMapping.ContainsKey(agentID)) - { - // oops this should not happen ? - m_log.DebugFormat("[EVENTQUEUE]: Found Existing UUID without a queue"); - eventQueueGetUUID = m_AvatarQueueUUIDMapping[agentID]; - } + while(m_AvatarQueueUUIDMapping.ContainsKey(agentID)) + eventQueueGetUUID = UUID.Random(); m_AvatarQueueUUIDMapping.Add(agentID, eventQueueGetUUID); } lock (m_ids) @@ -329,18 +316,14 @@ namespace OpenSim.Region.ClientStack.Linden if (!m_ids.ContainsKey(agentID)) m_ids.Add(agentID, nrnd); else - m_ids[agentID] = nrnd; + m_ids[agentID]++; } } else { - // push markers to handle old responses still waiting - // this will cost at most viewer getting two forced noevents - // even being a new queue better be safe queue.Enqueue(null); queue.Enqueue(null); // one should be enough - - // reuse or not to reuse TODO FIX + // reuse or not to reuse lock (m_AvatarQueueUUIDMapping) { // Reuse open queues. The client does! @@ -349,30 +332,39 @@ namespace OpenSim.Region.ClientStack.Linden { m_log.DebugFormat("[EVENTQUEUE]: Found Existing UUID!"); eventQueueGetUUID = m_AvatarQueueUUIDMapping[agentID]; + lock (m_ids) + { + // change to negative numbers so they are changed at end of sending first marker + // old data on a queue may be sent on a response for a new caps + // but at least will be sent with coerent IDs + if (!m_ids.ContainsKey(agentID)) + m_ids.Add(agentID, -nrnd); // should not happen + else + m_ids[agentID] = -m_ids[agentID]; + } } else { eventQueueGetUUID = UUID.Random(); + while(m_AvatarQueueUUIDMapping.ContainsKey(agentID)) + eventQueueGetUUID = UUID.Random(); m_AvatarQueueUUIDMapping.Add(agentID, eventQueueGetUUID); m_log.DebugFormat("[EVENTQUEUE]: Using random UUID!"); + lock (m_ids) + { + if (!m_ids.ContainsKey(agentID)) + m_ids.Add(agentID, nrnd); + else + m_ids[agentID]++; + } } } - lock (m_ids) - { - // change to negative numbers so they are changed at end of sending first marker - // old data on a queue may be sent on a response for a new caps - // but at least will be sent with coerent IDs - if (!m_ids.ContainsKey(agentID)) - m_ids.Add(agentID, -nrnd); // should not happen - else - m_ids[agentID] = -m_ids[agentID]; - } } } - caps.RegisterPollHandler( - "EventQueueGet", - new PollServiceEventArgs(null, GenerateEqgCapPath(eventQueueGetUUID), HasEvents, GetEvents, NoEvents, agentID, SERVER_EQ_TIME_NO_EVENTS)); + caps.RegisterPollHandler( + "EventQueueGet", + new PollServiceEventArgs(null, GenerateEqgCapPath(eventQueueGetUUID), HasEvents, GetEvents, NoEvents, Drop, agentID, SERVER_EQ_TIME_NO_EVENTS)); } public bool HasEvents(UUID requestID, UUID agentID) @@ -448,7 +440,6 @@ namespace OpenSim.Region.ClientStack.Linden if (DebugLevel > 0) LogOutboundDebugMessage(element, pAgentId); array.Add(element); - thisID++; } } @@ -465,8 +456,6 @@ namespace OpenSim.Region.ClientStack.Linden { Random rnd = new Random(Environment.TickCount); thisID = rnd.Next(30000000); - if (thisID < 0) - thisID = -thisID; } lock (m_ids) @@ -474,16 +463,19 @@ namespace OpenSim.Region.ClientStack.Linden m_ids[pAgentId] = thisID + 1; } + Hashtable responsedata; // if there where no elements before a marker send a NoEvents - if (array.Count == 0) - return NoEvents(requestID, pAgentId); - - Hashtable responsedata = new Hashtable(); - responsedata["int_response_code"] = 200; - responsedata["content_type"] = "application/xml"; - responsedata["keepalive"] = false; - responsedata["reusecontext"] = false; - responsedata["str_response_string"] = OSDParser.SerializeLLSDXmlString(events); + if (events == null) + { + return NoEvents(requestID, pAgentId); + } + else + { + responsedata = new Hashtable(); + responsedata["int_response_code"] = 200; + responsedata["content_type"] = "application/xml"; + responsedata["bin_response_data"] = Encoding.UTF8.GetBytes(OSDParser.SerializeLLSDXmlString(events)); + } //m_log.DebugFormat("[EVENTQUEUE]: sending response for {0} in region {1}: {2}", pAgentId, m_scene.RegionInfo.RegionName, responsedata["str_response_string"]); return responsedata; } @@ -493,20 +485,20 @@ namespace OpenSim.Region.ClientStack.Linden Hashtable responsedata = new Hashtable(); responsedata["int_response_code"] = 502; responsedata["content_type"] = "text/plain"; - responsedata["keepalive"] = false; - responsedata["reusecontext"] = false; responsedata["str_response_string"] = ""; responsedata["error_status_text"] = ""; responsedata["http_protocol_version"] = "HTTP/1.0"; + responsedata["keepalive"] = false; return responsedata; } +/* this is not a event message public void DisableSimulator(ulong handle, UUID avatarID) { OSD item = EventQueueHelper.DisableSimulator(handle); Enqueue(item, avatarID); } - +*/ public virtual void EnableSimulator(ulong handle, IPEndPoint endPoint, UUID avatarID, int regionSizeX, int regionSizeY) { if (DebugLevel > 0) diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueHelper.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueHelper.cs index e1e88aedb8..52cfd488cf 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueHelper.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueHelper.cs @@ -43,16 +43,16 @@ namespace OpenSim.Region.ClientStack.Linden private static byte[] ulongToByteArray(ulong uLongValue) { // Reverse endianness of RegionHandle - return new byte[] + return new byte[8] { - (byte)((uLongValue >> 56) % 256), - (byte)((uLongValue >> 48) % 256), - (byte)((uLongValue >> 40) % 256), - (byte)((uLongValue >> 32) % 256), - (byte)((uLongValue >> 24) % 256), - (byte)((uLongValue >> 16) % 256), - (byte)((uLongValue >> 8) % 256), - (byte)(uLongValue % 256) + (byte)((uLongValue >> 56) & 0xff), + (byte)((uLongValue >> 48) & 0xff), + (byte)((uLongValue >> 40) & 0xff), + (byte)((uLongValue >> 32) & 0xff), + (byte)((uLongValue >> 24) & 0xff), + (byte)((uLongValue >> 16) & 0xff), + (byte)((uLongValue >> 8) & 0xff), + (byte)(uLongValue & 0xff) }; } @@ -90,7 +90,7 @@ namespace OpenSim.Region.ClientStack.Linden return BuildEvent("EnableSimulator", llsdBody); } - +/* public static OSD DisableSimulator(ulong handle) { //OSDMap llsdSimInfo = new OSDMap(1); @@ -105,7 +105,7 @@ namespace OpenSim.Region.ClientStack.Linden return BuildEvent("DisableSimulator", llsdBody); } - +*/ public static OSD CrossRegion(ulong handle, Vector3 pos, Vector3 lookAt, IPEndPoint newRegionExternalEndPoint, string capsURL, UUID agentID, UUID sessionID, diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs index ee3f4f1a4c..080cef929a 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs @@ -29,6 +29,7 @@ using System; using System.Collections; using System.Collections.Generic; using System.Net; +using System.Text; using log4net.Config; using Nini.Config; using NUnit.Framework; @@ -59,13 +60,12 @@ namespace OpenSim.Region.ClientStack.Linden.Tests base.SetUp(); uint port = 9999; - uint sslPort = 9998; // This is an unfortunate bit of clean up we have to do because MainServer manages things through static // variables and the VM is not restarted between tests. MainServer.RemoveHttpServer(port); - BaseHttpServer server = new BaseHttpServer(port, false, sslPort, ""); + BaseHttpServer server = new BaseHttpServer(port, false, "","",""); MainServer.AddHttpServer(server); MainServer.Instance = server; @@ -126,7 +126,7 @@ namespace OpenSim.Region.ClientStack.Linden.Tests Hashtable eventsResponse = m_eqgMod.GetEvents(UUID.Zero, sp.UUID); // initial queue as null events - eventsResponse = m_eqgMod.GetEvents(UUID.Zero, sp.UUID); +// eventsResponse = m_eqgMod.GetEvents(UUID.Zero, sp.UUID); if((int)eventsResponse["int_response_code"] != (int)HttpStatusCode.OK) { eventsResponse = m_eqgMod.GetEvents(UUID.Zero, sp.UUID); @@ -137,8 +137,11 @@ namespace OpenSim.Region.ClientStack.Linden.Tests Assert.That((int)eventsResponse["int_response_code"], Is.EqualTo((int)HttpStatusCode.OK)); // Console.WriteLine("Response [{0}]", (string)eventsResponse["str_response_string"]); + string data = String.Empty; + if(eventsResponse["bin_response_data"] != null) + data = Encoding.UTF8.GetString((byte[])eventsResponse["bin_response_data"]); - OSDMap rawOsd = (OSDMap)OSDParser.DeserializeLLSDXml((string)eventsResponse["str_response_string"]); + OSDMap rawOsd = (OSDMap)OSDParser.DeserializeLLSDXml(data); OSDArray eventsOsd = (OSDArray)rawOsd["events"]; bool foundUpdate = false; diff --git a/OpenSim/Region/ClientStack/Linden/Caps/FetchInventory2Module.cs b/OpenSim/Region/ClientStack/Linden/Caps/FetchInventory2Module.cs index e0a11ccff6..eef94354c8 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/FetchInventory2Module.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/FetchInventory2Module.cs @@ -51,7 +51,7 @@ namespace OpenSim.Region.ClientStack.Linden private Scene m_scene; private IInventoryService m_inventoryService; - + private ILibraryService m_LibraryService; private string m_fetchInventory2Url; #region ISharedRegionModule Members @@ -91,7 +91,7 @@ namespace OpenSim.Region.ClientStack.Linden return; m_inventoryService = m_scene.InventoryService; - + m_LibraryService = m_scene.LibraryService; m_scene.EventManager.OnRegisterCaps += RegisterCaps; } diff --git a/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs index 69ff713c77..542d52a42e 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs @@ -28,17 +28,14 @@ using System; using System.Collections; using System.Collections.Generic; -using System.Collections.Specialized; +using System.Collections.Concurrent; using System.Reflection; -using System.IO; using System.Threading; -using System.Web; using Mono.Addins; using OpenSim.Framework.Monitoring; using log4net; using Nini.Config; using OpenMetaverse; -using OpenMetaverse.StructuredData; using OpenSim.Capabilities.Handlers; using OpenSim.Framework; using OpenSim.Framework.Servers; @@ -57,7 +54,6 @@ namespace OpenSim.Region.ClientStack.Linden // LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private Scene m_scene; - private IAssetService m_AssetService; private bool m_Enabled = true; private string m_URL; @@ -65,21 +61,19 @@ namespace OpenSim.Region.ClientStack.Linden private string m_RedirectURL = null; private string m_RedirectURL2 = null; - struct aPollRequest + class APollRequest { public PollServiceMeshEventArgs thepoll; public UUID reqID; public Hashtable request; } - public class aPollResponse + public class APollResponse { public Hashtable response; public int bytes; - public int lod; } - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static GetMeshHandler m_getMeshHandler; @@ -89,8 +83,7 @@ namespace OpenSim.Region.ClientStack.Linden private Dictionary m_capsDict = new Dictionary(); private static Thread[] m_workerThreads = null; private static int m_NumberScenes = 0; - private static OpenMetaverse.BlockingQueue m_queue = - new OpenMetaverse.BlockingQueue(); + private static BlockingCollection m_queue = new BlockingCollection(); private Dictionary m_pollservices = new Dictionary(); @@ -132,33 +125,35 @@ namespace OpenSim.Region.ClientStack.Linden return; m_scene = pScene; - - m_assetService = pScene.AssetService; } - public void RemoveRegion(Scene scene) + public void RemoveRegion(Scene s) { if (!m_Enabled) return; - m_scene.EventManager.OnRegisterCaps -= RegisterCaps; - m_scene.EventManager.OnDeregisterCaps -= DeregisterCaps; - m_scene.EventManager.OnThrottleUpdate -= ThrottleUpdate; + s.EventManager.OnRegisterCaps -= RegisterCaps; + s.EventManager.OnDeregisterCaps -= DeregisterCaps; + s.EventManager.OnThrottleUpdate -= ThrottleUpdate; m_NumberScenes--; m_scene = null; } - public void RegionLoaded(Scene scene) + public void RegionLoaded(Scene s) { if (!m_Enabled) return; - m_AssetService = m_scene.RequestModuleInterface(); - m_scene.EventManager.OnRegisterCaps += RegisterCaps; - // We'll reuse the same handler for all requests. - m_getMeshHandler = new GetMeshHandler(m_assetService); - m_scene.EventManager.OnDeregisterCaps += DeregisterCaps; - m_scene.EventManager.OnThrottleUpdate += ThrottleUpdate; + if(m_assetService == null) + { + m_assetService = m_scene.RequestModuleInterface(); + // We'll reuse the same handler for all requests. + m_getMeshHandler = new GetMeshHandler(m_assetService); + } + + s.EventManager.OnRegisterCaps += RegisterCaps; + s.EventManager.OnDeregisterCaps += DeregisterCaps; + s.EventManager.OnThrottleUpdate += ThrottleUpdate; m_NumberScenes++; @@ -171,7 +166,7 @@ namespace OpenSim.Region.ClientStack.Linden m_workerThreads[i] = WorkManager.StartThread(DoMeshRequests, String.Format("GetMeshWorker{0}", i), ThreadPriority.Normal, - false, + true, false, null, int.MaxValue); @@ -190,7 +185,7 @@ namespace OpenSim.Region.ClientStack.Linden // Prevent red ink. try { - m_queue.Clear(); + m_queue.Dispose(); } catch {} } @@ -202,11 +197,18 @@ namespace OpenSim.Region.ClientStack.Linden private static void DoMeshRequests() { - while(true) + while (m_NumberScenes > 0) { - aPollRequest poolreq = m_queue.Dequeue(); - Watchdog.UpdateThread(); - poolreq.thepoll.Process(poolreq); + APollRequest poolreq; + if(m_queue.TryTake(out poolreq, 4500)) + { + if(m_NumberScenes <= 0) + break; + + if(poolreq.reqID != UUID.Zero) + poolreq.thepoll.Process(poolreq); + } + Watchdog.UpdateThread(); } } @@ -218,7 +220,7 @@ namespace OpenSim.Region.ClientStack.Linden PollServiceMeshEventArgs args; if (m_pollservices.TryGetValue(user, out args)) { - args.UpdateThrottle(imagethrottle, p); + args.UpdateThrottle(imagethrottle); } } @@ -226,27 +228,36 @@ namespace OpenSim.Region.ClientStack.Linden { private List requests = new List(); - private Dictionary responses = - new Dictionary(); + private Dictionary responses = + new Dictionary(); + private HashSet dropedResponses = new HashSet(); private Scene m_scene; private MeshCapsDataThrottler m_throttler; public PollServiceMeshEventArgs(string uri, UUID pId, Scene scene) : - base(null, uri, null, null, null, pId, int.MaxValue) + base(null, uri, null, null, null, null, pId, int.MaxValue) { m_scene = scene; - m_throttler = new MeshCapsDataThrottler(100000, 1400000, 10000, scene, pId); + m_throttler = new MeshCapsDataThrottler(100000); // x is request id, y is userid HasEvents = (x, y) => { lock (responses) { - bool ret = m_throttler.hasEvents(x, responses); - m_throttler.ProcessTime(); - return ret; - + return m_throttler.hasEvents(x, responses); } }; + + Drop = (x, y) => + { + lock (responses) + { + responses.Remove(x); + lock(dropedResponses) + dropedResponses.Add(x); + } + }; + GetEvents = (x, y) => { lock (responses) @@ -257,20 +268,21 @@ namespace OpenSim.Region.ClientStack.Linden } finally { - m_throttler.ProcessTime(); responses.Remove(x); + m_throttler.PassTime(); } } }; // x is request id, y is request data hashtable Request = (x, y) => { - aPollRequest reqinfo = new aPollRequest(); + APollRequest reqinfo = new APollRequest(); reqinfo.thepoll = this; reqinfo.reqID = x; reqinfo.request = y; - m_queue.Enqueue(reqinfo); + m_queue.Add(reqinfo); + m_throttler.PassTime(); }; // this should never happen except possible on shutdown @@ -289,13 +301,11 @@ namespace OpenSim.Region.ClientStack.Linden response["str_response_string"] = "Script timeout"; response["content_type"] = "text/plain"; response["keepalive"] = false; - response["reusecontext"] = false; - return response; }; } - public void Process(aPollRequest requestinfo) + public void Process(APollRequest requestinfo) { Hashtable response; @@ -304,40 +314,61 @@ namespace OpenSim.Region.ClientStack.Linden if(m_scene.ShuttingDown) return; - // If the avatar is gone, don't bother to get the texture - if (m_scene.GetScenePresence(Id) == null) + lock(responses) { - response = new Hashtable(); + lock(dropedResponses) + { + if(dropedResponses.Contains(requestID)) + { + dropedResponses.Remove(requestID); + return; + } + } + + // If the avatar is gone, don't bother to get the texture + if (m_scene.GetScenePresence(Id) == null) + { + response = new Hashtable(); - response["int_response_code"] = 500; - response["str_response_string"] = "Script timeout"; - response["content_type"] = "text/plain"; - response["keepalive"] = false; - response["reusecontext"] = false; + response["int_response_code"] = 500; + response["str_response_string"] = "Script timeout"; + response["content_type"] = "text/plain"; + response["keepalive"] = false; + responses[requestID] = new APollResponse() { bytes = 0, response = response}; - lock (responses) - responses[requestID] = new aPollResponse() { bytes = 0, response = response, lod = 0 }; - - return; + return; + } } response = m_getMeshHandler.Handle(requestinfo.request); + lock (responses) { - responses[requestID] = new aPollResponse() + lock(dropedResponses) + { + if(dropedResponses.Contains(requestID)) + { + dropedResponses.Remove(requestID); + return; + } + } + + responses[requestID] = new APollResponse() { bytes = (int)response["int_bytes"], - lod = (int)response["int_lod"], response = response }; } - m_throttler.ProcessTime(); + m_throttler.PassTime(); } - internal void UpdateThrottle(int pimagethrottle, ScenePresence p) + internal void UpdateThrottle(int pthrottle) { - m_throttler.UpdateThrottle(pimagethrottle, p); + int tmp = 2 * pthrottle; + if(tmp < 10000) + tmp = 10000; + m_throttler.ThrottleBytes = tmp; } } @@ -391,94 +422,49 @@ namespace OpenSim.Region.ClientStack.Linden internal sealed class MeshCapsDataThrottler { + private double lastTimeElapsed = 0; + private double BytesSent = 0; - private volatile int currenttime = 0; - private volatile int lastTimeElapsed = 0; - private volatile int BytesSent = 0; - private int CapSetThrottle = 0; - private float CapThrottleDistributon = 0.30f; - private readonly Scene m_scene; - private ThrottleOutPacketType Throttle; - private readonly UUID User; - - public MeshCapsDataThrottler(int pBytes, int max, int min, Scene pScene, UUID puser) + public MeshCapsDataThrottler(int pBytes) { + if(pBytes < 10000) + pBytes = 10000; ThrottleBytes = pBytes; - if(ThrottleBytes < 10000) - ThrottleBytes = 10000; - lastTimeElapsed = Util.EnvironmentTickCount(); - Throttle = ThrottleOutPacketType.Asset; - m_scene = pScene; - User = puser; + lastTimeElapsed = Util.GetTimeStamp(); } - public bool hasEvents(UUID key, Dictionary responses) + public bool hasEvents(UUID key, Dictionary responses) { PassTime(); - // Note, this is called IN LOCK - bool haskey = responses.ContainsKey(key); - - if (!haskey) - { - return false; - } - aPollResponse response; + APollResponse response; if (responses.TryGetValue(key, out response)) { // Normal - if (BytesSent <= ThrottleBytes) + if (response.bytes == 0 || BytesSent <= ThrottleBytes) { BytesSent += response.bytes; return true; } - else - { - return false; - } } - return haskey; + return false; } - public void ProcessTime() + public void PassTime() { - PassTime(); - } - - private void PassTime() - { - currenttime = Util.EnvironmentTickCount(); - int timeElapsed = Util.EnvironmentTickCountSubtract(currenttime, lastTimeElapsed); - if (timeElapsed >= 100) + double currenttime = Util.GetTimeStamp(); + double timeElapsed = currenttime - lastTimeElapsed; + if(timeElapsed < .05) + return; + int add = (int)(ThrottleBytes * timeElapsed); + if (add >= 1000) { lastTimeElapsed = currenttime; - BytesSent -= (ThrottleBytes * timeElapsed / 1000); + BytesSent -= add; if (BytesSent < 0) BytesSent = 0; } } - private void AlterThrottle(int setting, ScenePresence p) - { - p.ControllingClient.SetAgentThrottleSilent((int)Throttle,setting); - } - - public int ThrottleBytes - { - get { return CapSetThrottle; } - set - { - if (value > 10000) - CapSetThrottle = value; - else - CapSetThrottle = 10000; - } - } - - internal void UpdateThrottle(int pimagethrottle, ScenePresence p) - { - // Client set throttle ! - CapSetThrottle = 2 * pimagethrottle; - ProcessTime(); - } + public int ThrottleBytes; } } } diff --git a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs index 0c20e0417e..7d1a38002c 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs @@ -28,6 +28,7 @@ using System; using System.Collections; using System.Collections.Generic; +using System.Collections.Concurrent; using System.Reflection; using System.Threading; using log4net; @@ -51,7 +52,7 @@ namespace OpenSim.Region.ClientStack.Linden public class GetTextureModule : INonSharedRegionModule { - struct aPollRequest + class APollRequest { public PollServiceTextureEventArgs thepoll; public UUID reqID; @@ -59,7 +60,7 @@ namespace OpenSim.Region.ClientStack.Linden public bool send503; } - public class aPollResponse + public class APollResponse { public Hashtable response; public int bytes; @@ -77,8 +78,7 @@ namespace OpenSim.Region.ClientStack.Linden private Dictionary m_capsDict = new Dictionary(); private static Thread[] m_workerThreads = null; private static int m_NumberScenes = 0; - private static OpenMetaverse.BlockingQueue m_queue = - new OpenMetaverse.BlockingQueue(); + private static BlockingCollection m_queue = new BlockingCollection(); private Dictionary m_pollservices = new Dictionary(); @@ -107,26 +107,29 @@ namespace OpenSim.Region.ClientStack.Linden public void AddRegion(Scene s) { m_scene = s; - m_assetService = s.AssetService; } public void RemoveRegion(Scene s) { - m_scene.EventManager.OnRegisterCaps -= RegisterCaps; - m_scene.EventManager.OnDeregisterCaps -= DeregisterCaps; - m_scene.EventManager.OnThrottleUpdate -= ThrottleUpdate; + s.EventManager.OnRegisterCaps -= RegisterCaps; + s.EventManager.OnDeregisterCaps -= DeregisterCaps; + s.EventManager.OnThrottleUpdate -= ThrottleUpdate; m_NumberScenes--; m_scene = null; } public void RegionLoaded(Scene s) { - // We'll reuse the same handler for all requests. - m_getTextureHandler = new GetTextureHandler(m_assetService); + if(m_assetService == null) + { + m_assetService = s.RequestModuleInterface(); + // We'll reuse the same handler for all requests. + m_getTextureHandler = new GetTextureHandler(m_assetService); + } - m_scene.EventManager.OnRegisterCaps += RegisterCaps; - m_scene.EventManager.OnDeregisterCaps += DeregisterCaps; - m_scene.EventManager.OnThrottleUpdate += ThrottleUpdate; + s.EventManager.OnRegisterCaps += RegisterCaps; + s.EventManager.OnDeregisterCaps += DeregisterCaps; + s.EventManager.OnThrottleUpdate += ThrottleUpdate; m_NumberScenes++; @@ -139,46 +142,20 @@ namespace OpenSim.Region.ClientStack.Linden m_workerThreads[i] = WorkManager.StartThread(DoTextureRequests, String.Format("GetTextureWorker{0}", i), ThreadPriority.Normal, - false, + true, false, null, int.MaxValue); } } } - private int ExtractImageThrottle(byte[] pthrottles) - { - - byte[] adjData; - int pos = 0; - - if (!BitConverter.IsLittleEndian) - { - byte[] newData = new byte[7 * 4]; - Buffer.BlockCopy(pthrottles, 0, newData, 0, 7 * 4); - - for (int i = 0; i < 7; i++) - Array.Reverse(newData, i * 4, 4); - - adjData = newData; - } - else - { - adjData = pthrottles; - } - - pos = pos + 20; - int texture = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); //pos += 4; - //int asset = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); - return texture; - } - + // Now we know when the throttle is changed by the client in the case of a root agent or by a neighbor region in the case of a child agent. public void ThrottleUpdate(ScenePresence p) { byte[] throttles = p.ControllingClient.GetThrottlesPacked(1); UUID user = p.UUID; - int imagethrottle = ExtractImageThrottle(throttles); + int imagethrottle = p.ControllingClient.GetAgentThrottleSilent((int)ThrottleOutPacketType.Texture); PollServiceTextureEventArgs args; if (m_pollservices.TryGetValue(user,out args)) { @@ -199,7 +176,7 @@ namespace OpenSim.Region.ClientStack.Linden foreach (Thread t in m_workerThreads) Watchdog.AbortThread(t.ManagedThreadId); - m_queue.Clear(); + m_queue.Dispose(); } } @@ -216,26 +193,37 @@ namespace OpenSim.Region.ClientStack.Linden { private List requests = new List(); - private Dictionary responses = - new Dictionary(); + private Dictionary responses = + new Dictionary(); + private HashSet dropedResponses = new HashSet(); private Scene m_scene; - private CapsDataThrottler m_throttler = new CapsDataThrottler(100000, 1400000,10000); + private CapsDataThrottler m_throttler; public PollServiceTextureEventArgs(UUID pId, Scene scene) : - base(null, "", null, null, null, pId, int.MaxValue) + base(null, "", null, null, null, null, pId, int.MaxValue) { m_scene = scene; + m_throttler = new CapsDataThrottler(100000); // x is request id, y is userid HasEvents = (x, y) => { lock (responses) { bool ret = m_throttler.hasEvents(x, responses); - m_throttler.ProcessTime(); return ret; } }; + + Drop = (x, y) => + { + lock (responses) + { + responses.Remove(x); + dropedResponses.Add(x); + } + }; + GetEvents = (x, y) => { lock (responses) @@ -247,13 +235,14 @@ namespace OpenSim.Region.ClientStack.Linden finally { responses.Remove(x); + m_throttler.PassTime(); } } }; // x is request id, y is request data hashtable Request = (x, y) => { - aPollRequest reqinfo = new aPollRequest(); + APollRequest reqinfo = new APollRequest(); reqinfo.thepoll = this; reqinfo.reqID = x; reqinfo.request = y; @@ -270,7 +259,8 @@ namespace OpenSim.Region.ClientStack.Linden } } } - m_queue.Enqueue(reqinfo); + m_queue.Add(reqinfo); + m_throttler.PassTime(); }; // this should never happen except possible on shutdown @@ -289,13 +279,11 @@ namespace OpenSim.Region.ClientStack.Linden response["str_response_string"] = "Script timeout"; response["content_type"] = "text/plain"; response["keepalive"] = false; - response["reusecontext"] = false; - return response; }; } - public void Process(aPollRequest requestinfo) + public void Process(APollRequest requestinfo) { Hashtable response; @@ -304,61 +292,79 @@ namespace OpenSim.Region.ClientStack.Linden if(m_scene.ShuttingDown) return; - if (requestinfo.send503) + lock (responses) { - response = new Hashtable(); + lock(dropedResponses) + { + if(dropedResponses.Contains(requestID)) + { + dropedResponses.Remove(requestID); + return; + } + } - response["int_response_code"] = 503; - response["str_response_string"] = "Throttled"; - response["content_type"] = "text/plain"; - response["keepalive"] = false; - response["reusecontext"] = false; + if (requestinfo.send503) + { + response = new Hashtable(); - Hashtable headers = new Hashtable(); - headers["Retry-After"] = 30; - response["headers"] = headers; + response["int_response_code"] = 503; + response["str_response_string"] = "Throttled"; + response["content_type"] = "text/plain"; + response["keepalive"] = false; - lock (responses) - responses[requestID] = new aPollResponse() {bytes = 0, response = response}; + Hashtable headers = new Hashtable(); + headers["Retry-After"] = 30; + response["headers"] = headers; - return; - } + responses[requestID] = new APollResponse() {bytes = 0, response = response}; + + return; + } // If the avatar is gone, don't bother to get the texture - if (m_scene.GetScenePresence(Id) == null) - { - response = new Hashtable(); + if (m_scene.GetScenePresence(Id) == null) + { + response = new Hashtable(); - response["int_response_code"] = 500; - response["str_response_string"] = "Script timeout"; - response["content_type"] = "text/plain"; - response["keepalive"] = false; - response["reusecontext"] = false; + response["int_response_code"] = 500; + response["str_response_string"] = "Script timeout"; + response["content_type"] = "text/plain"; + response["keepalive"] = false; - lock (responses) - responses[requestID] = new aPollResponse() {bytes = 0, response = response}; + responses[requestID] = new APollResponse() {bytes = 0, response = response}; - return; + return; + } } response = m_getTextureHandler.Handle(requestinfo.request); + lock (responses) { - responses[requestID] = new aPollResponse() - { - bytes = (int) response["int_bytes"], - response = response - }; - - } - m_throttler.ProcessTime(); + lock(dropedResponses) + { + if(dropedResponses.Contains(requestID)) + { + dropedResponses.Remove(requestID); + m_throttler.PassTime(); + return; + } + } + responses[requestID] = new APollResponse() + { + bytes = (int) response["int_bytes"], + response = response + }; + } + m_throttler.PassTime(); } internal void UpdateThrottle(int pimagethrottle) { - m_throttler.ThrottleBytes = 2 * pimagethrottle; - if(m_throttler.ThrottleBytes < 10000) - m_throttler.ThrottleBytes = 10000; + int tmp = 2 * pimagethrottle; + if(tmp < 10000) + tmp = 10000; + m_throttler.ThrottleBytes = tmp; } } @@ -413,72 +419,63 @@ namespace OpenSim.Region.ClientStack.Linden private static void DoTextureRequests() { - while (true) + APollRequest poolreq; + while (m_NumberScenes > 0) { - aPollRequest poolreq = m_queue.Dequeue(); + poolreq = null; + if(!m_queue.TryTake(out poolreq, 4500) || poolreq == null) + { + Watchdog.UpdateThread(); + continue; + } + + if(m_NumberScenes <= 0) + break; + Watchdog.UpdateThread(); - poolreq.thepoll.Process(poolreq); + if(poolreq.reqID != UUID.Zero) + poolreq.thepoll.Process(poolreq); } } internal sealed class CapsDataThrottler { - - private volatile int currenttime = 0; - private volatile int lastTimeElapsed = 0; + private double lastTimeElapsed = 0; private volatile int BytesSent = 0; - public CapsDataThrottler(int pBytes, int max, int min) + public CapsDataThrottler(int pBytes) { + if(pBytes < 10000) + pBytes = 10000; ThrottleBytes = pBytes; - if(ThrottleBytes < 10000) - ThrottleBytes = 10000; - lastTimeElapsed = Util.EnvironmentTickCount(); + lastTimeElapsed = Util.GetTimeStamp(); } - public bool hasEvents(UUID key, Dictionary responses) + public bool hasEvents(UUID key, Dictionary responses) { PassTime(); // Note, this is called IN LOCK - bool haskey = responses.ContainsKey(key); - if (!haskey) - { - return false; - } - GetTextureModule.aPollResponse response; + GetTextureModule.APollResponse response; if (responses.TryGetValue(key, out response)) { - // This is any error response - if (response.bytes == 0) - return true; - - // Normal - if (BytesSent <= ThrottleBytes) + if (response.bytes == 0 || BytesSent <= ThrottleBytes) { BytesSent += response.bytes; return true; } - else - { - return false; - } } - - return haskey; + return false; } - public void ProcessTime() + public void PassTime() { - PassTime(); - } - - private void PassTime() + double currenttime = Util.GetTimeStamp(); + double timeElapsed = currenttime - lastTimeElapsed; + if(timeElapsed < .05) + return; + int add = (int)(ThrottleBytes * timeElapsed); + if (add >= 1000) { - currenttime = Util.EnvironmentTickCount(); - int timeElapsed = Util.EnvironmentTickCountSubtract(currenttime, lastTimeElapsed); - //processTimeBasedActions(responses); - if (timeElapsed >= 100) - { lastTimeElapsed = currenttime; - BytesSent -= (ThrottleBytes * timeElapsed / 1000); + BytesSent -= add; if (BytesSent < 0) BytesSent = 0; } } diff --git a/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/ObjectAdd.cs b/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/ObjectAdd.cs index 69fcb7d107..b044e564fb 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/ObjectAdd.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/ObjectAdd.cs @@ -357,7 +357,7 @@ namespace OpenSim.Region.ClientStack.Linden rootpart.NextOwnerMask = next_owner_mask; rootpart.Material = (byte)material; - obj.AggregatePerms(); + obj.InvalidateDeepEffectivePerms(); m_scene.PhysicsScene.AddPhysicsActorTaint(rootpart.PhysActor); diff --git a/OpenSim/Region/ClientStack/Linden/Caps/RegionConsoleModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/RegionConsoleModule.cs index b3e3ac3795..e8387e3de2 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/RegionConsoleModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/RegionConsoleModule.cs @@ -185,8 +185,9 @@ namespace OpenSim.Region.ClientStack.Linden protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { - StreamReader reader = new StreamReader(request); - string message = reader.ReadToEnd(); + string message; + using(StreamReader reader = new StreamReader(request)) + message = reader.ReadToEnd(); OSD osd = OSDParser.DeserializeLLSDXml(message); diff --git a/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs index 39f5bafe83..cbcbd2d7bd 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs @@ -253,7 +253,6 @@ namespace OpenSim.Region.ClientStack.Linden Hashtable responsedata = new Hashtable(); responsedata["int_response_code"] = 200; responsedata["content_type"] = "text/plain"; - responsedata["keepalive"] = false; responsedata["str_response_string"] = OSDParser.SerializeLLSDXmlString(copy); diff --git a/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs index dfe097ef97..b406b3743a 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs @@ -63,9 +63,7 @@ namespace OpenSim.Region.ClientStack.Linden private static readonly string m_uploadBakedTexturePath = "0010/";// This is in the LandManagementModule. private Scene m_scene; - private bool m_persistBakedTextures; - private IBakedTextureModule m_BakedTextureModule; private string m_URL; public void Initialise(IConfigSource source) @@ -76,15 +74,12 @@ namespace OpenSim.Region.ClientStack.Linden m_URL = config.GetString("Cap_UploadBakedTexture", string.Empty); - IConfig appearanceConfig = source.Configs["Appearance"]; - if (appearanceConfig != null) - m_persistBakedTextures = appearanceConfig.GetBoolean("PersistBakedTextures", m_persistBakedTextures); +// IConfig appearanceConfig = source.Configs["Appearance"]; } public void AddRegion(Scene s) { m_scene = s; - } public void RemoveRegion(Scene s) @@ -92,7 +87,6 @@ namespace OpenSim.Region.ClientStack.Linden s.EventManager.OnRegisterCaps -= RegisterCaps; s.EventManager.OnNewPresence -= RegisterNewPresence; s.EventManager.OnRemovePresence -= DeRegisterPresence; - m_BakedTextureModule = null; m_scene = null; } @@ -101,7 +95,6 @@ namespace OpenSim.Region.ClientStack.Linden m_scene.EventManager.OnRegisterCaps += RegisterCaps; m_scene.EventManager.OnNewPresence += RegisterNewPresence; m_scene.EventManager.OnRemovePresence += DeRegisterPresence; - } private void DeRegisterPresence(UUID agentId) @@ -110,156 +103,12 @@ namespace OpenSim.Region.ClientStack.Linden private void RegisterNewPresence(ScenePresence presence) { -// presence.ControllingClient.OnSetAppearance += CaptureAppearanceSettings; } -/* not in use. work done in AvatarFactoryModule ValidateBakedTextureCache() and UpdateBakedTextureCache() - private void CaptureAppearanceSettings(IClientAPI remoteClient, Primitive.TextureEntry textureEntry, byte[] visualParams, Vector3 avSize, WearableCacheItem[] cacheItems) - { - // if cacheItems.Length > 0 viewer is giving us current textures information. - // baked ones should had been uploaded and in assets cache as local itens - - - if (cacheItems.Length == 0) - return; // no textures information, nothing to do - - ScenePresence p = null; - if (!m_scene.TryGetScenePresence(remoteClient.AgentId, out p)) - return; // what are we doing if there is no presence to cache for? - - if (p.IsDeleted) - return; // does this really work? - - int maxCacheitemsLoop = cacheItems.Length; - if (maxCacheitemsLoop > 20) - { - maxCacheitemsLoop = AvatarWearable.MAX_WEARABLES; - m_log.WarnFormat("[CACHEDBAKES]: Too Many Cache items Provided {0}, the max is {1}. Truncating!", cacheItems.Length, AvatarWearable.MAX_WEARABLES); - } - - m_BakedTextureModule = m_scene.RequestModuleInterface(); - - - // some nice debug - m_log.Debug("[Cacheitems]: " + cacheItems.Length); - for (int iter = 0; iter < maxCacheitemsLoop; iter++) - { - m_log.Debug("[Cacheitems] {" + iter + "/" + cacheItems[iter].TextureIndex + "}: c-" + cacheItems[iter].CacheId + ", t-" + - cacheItems[iter].TextureID); - } - - // p.Appearance.WearableCacheItems is in memory primary cashID to textures mapper - - WearableCacheItem[] existingitems = p.Appearance.WearableCacheItems; - - if (existingitems == null) - { - if (m_BakedTextureModule != null) - { - WearableCacheItem[] savedcache = null; - try - { - if (p.Appearance.WearableCacheItemsDirty) - { - savedcache = m_BakedTextureModule.Get(p.UUID); - p.Appearance.WearableCacheItems = savedcache; - p.Appearance.WearableCacheItemsDirty = false; - } - } - - catch (Exception) - { - // The service logs a sufficient error message. - } - - - if (savedcache != null) - existingitems = savedcache; - } - } - - // Existing items null means it's a fully new appearance - if (existingitems == null) - { - for (int i = 0; i < maxCacheitemsLoop; i++) - { - if (textureEntry.FaceTextures.Length > cacheItems[i].TextureIndex) - { - Primitive.TextureEntryFace face = textureEntry.FaceTextures[cacheItems[i].TextureIndex]; - if (face == null) - { - textureEntry.CreateFace(cacheItems[i].TextureIndex); - textureEntry.FaceTextures[cacheItems[i].TextureIndex].TextureID = - AppearanceManager.DEFAULT_AVATAR_TEXTURE; - continue; - } - cacheItems[i].TextureID = face.TextureID; - if (m_scene.AssetService != null) - cacheItems[i].TextureAsset = - m_scene.AssetService.GetCached(cacheItems[i].TextureID.ToString()); - } - else - { - m_log.WarnFormat("[CACHEDBAKES]: Invalid Texture Index Provided, Texture doesn't exist or hasn't been uploaded yet {0}, the max is {1}. Skipping!", cacheItems[i].TextureIndex, textureEntry.FaceTextures.Length); - } - } - } - else - { - for (int i = 0; i < maxCacheitemsLoop; i++) - { - if (textureEntry.FaceTextures.Length > cacheItems[i].TextureIndex) - { - Primitive.TextureEntryFace face = textureEntry.FaceTextures[cacheItems[i].TextureIndex]; - if (face == null) - { - textureEntry.CreateFace(cacheItems[i].TextureIndex); - textureEntry.FaceTextures[cacheItems[i].TextureIndex].TextureID = - AppearanceManager.DEFAULT_AVATAR_TEXTURE; - continue; - } - cacheItems[i].TextureID = - face.TextureID; - } - else - { - m_log.WarnFormat("[CACHEDBAKES]: Invalid Texture Index Provided, Texture doesn't exist or hasn't been uploaded yet {0}, the max is {1}. Skipping!", cacheItems[i].TextureIndex, textureEntry.FaceTextures.Length); - } - } - - for (int i = 0; i < maxCacheitemsLoop; i++) - { - if (cacheItems[i].TextureAsset == null) - { - cacheItems[i].TextureAsset = - m_scene.AssetService.GetCached(cacheItems[i].TextureID.ToString()); - } - } - } - p.Appearance.WearableCacheItems = cacheItems; - - if (m_BakedTextureModule != null) - { - m_BakedTextureModule.Store(remoteClient.AgentId, cacheItems); - p.Appearance.WearableCacheItemsDirty = true; - - } - else - p.Appearance.WearableCacheItemsDirty = false; - - for (int iter = 0; iter < maxCacheitemsLoop; iter++) - { - m_log.Debug("[CacheitemsLeaving] {" + iter + "/" + cacheItems[iter].TextureIndex + "}: c-" + cacheItems[iter].CacheId + ", t-" + - cacheItems[iter].TextureID); - } - } - */ public void PostInitialise() { } - - public void Close() { } public string Name { get { return "UploadBakedTextureModule"; } } @@ -275,7 +124,7 @@ namespace OpenSim.Region.ClientStack.Linden if (m_URL == "localhost") { UploadBakedTextureHandler avatarhandler = new UploadBakedTextureHandler( - caps, m_scene.AssetService, m_persistBakedTextures); + caps, m_scene.AssetService); caps.RegisterHandler( "UploadBakedTexture", diff --git a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs index e0ec842c9e..bae82a07e4 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs @@ -28,14 +28,13 @@ using System; using System.Collections; using System.Collections.Generic; +using System.Collections.Concurrent; using System.Reflection; using System.Threading; using log4net; using Nini.Config; using Mono.Addins; using OpenMetaverse; -using OpenSim.Framework; -using OpenSim.Framework.Servers; using OpenSim.Framework.Servers.HttpServer; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; @@ -55,13 +54,12 @@ namespace OpenSim.Region.ClientStack.Linden [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "WebFetchInvDescModule")] public class WebFetchInvDescModule : INonSharedRegionModule { - class aPollRequest + class APollRequest { public PollServiceInventoryEventArgs thepoll; public UUID reqID; public Hashtable request; public ScenePresence presence; - public List folders; } private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -99,8 +97,7 @@ namespace OpenSim.Region.ClientStack.Linden private static Thread[] m_workerThreads = null; - private static OpenSim.Framework.BlockingQueue m_queue = - new OpenSim.Framework.BlockingQueue(); + private static BlockingCollection m_queue = new BlockingCollection(); private static int m_NumberScenes = 0; @@ -181,7 +178,7 @@ namespace OpenSim.Region.ClientStack.Linden "httpfetch", StatType.Pull, MeasuresOfInterest.AverageChangeOverTime, - stat => { stat.Value = m_queue.Count(); }, + stat => { stat.Value = m_queue.Count; }, StatVerbosity.Debug); StatsManager.RegisterStat(s_processedRequestsStat); @@ -207,7 +204,7 @@ namespace OpenSim.Region.ClientStack.Linden m_workerThreads[i] = WorkManager.StartThread(DoInventoryRequests, String.Format("InventoryWorkerThread{0}", i), ThreadPriority.Normal, - false, + true, true, null, int.MaxValue); @@ -235,6 +232,7 @@ namespace OpenSim.Region.ClientStack.Linden m_workerThreads = null; } } +// m_queue.Dispose(); } public string Name { get { return "WebFetchInvDescModule"; } } @@ -250,17 +248,28 @@ namespace OpenSim.Region.ClientStack.Linden { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - private Dictionary responses = - new Dictionary(); + private Dictionary responses = new Dictionary(); + private HashSet dropedResponses = new HashSet(); private WebFetchInvDescModule m_module; public PollServiceInventoryEventArgs(WebFetchInvDescModule module, string url, UUID pId) : - base(null, url, null, null, null, pId, int.MaxValue) + base(null, url, null, null, null, null, pId, int.MaxValue) { m_module = module; HasEvents = (x, y) => { lock (responses) return responses.ContainsKey(x); }; + + Drop = (x, y) => + { + lock (responses) + { + responses.Remove(x); + lock(dropedResponses) + dropedResponses.Add(x); + } + }; + GetEvents = (x, y) => { lock (responses) @@ -280,13 +289,15 @@ namespace OpenSim.Region.ClientStack.Linden { ScenePresence sp = m_module.Scene.GetScenePresence(Id); - aPollRequest reqinfo = new aPollRequest(); + APollRequest reqinfo = new APollRequest(); reqinfo.thepoll = this; reqinfo.reqID = x; reqinfo.request = y; reqinfo.presence = sp; - reqinfo.folders = new List(); +/* why where we doing this? just to get cof ? + List folders = new List(); + // Decode the request here string request = y["body"].ToString(); @@ -322,11 +333,11 @@ namespace OpenSim.Region.ClientStack.Linden UUID folderID; if (UUID.TryParse(folder, out folderID)) { - if (!reqinfo.folders.Contains(folderID)) + if (!folders.Contains(folderID)) { if (sp.COF != UUID.Zero && sp.COF == folderID) highPriority = true; - reqinfo.folders.Add(folderID); + folders.Add(folderID); } } } @@ -334,7 +345,8 @@ namespace OpenSim.Region.ClientStack.Linden if (highPriority) m_queue.PriorityEnqueue(reqinfo); else - m_queue.Enqueue(reqinfo); +*/ + m_queue.Add(reqinfo); }; NoEvents = (x, y) => @@ -352,36 +364,61 @@ namespace OpenSim.Region.ClientStack.Linden response["str_response_string"] = "Script timeout"; response["content_type"] = "text/plain"; response["keepalive"] = false; - response["reusecontext"] = false; return response; }; } - public void Process(aPollRequest requestinfo) + public void Process(APollRequest requestinfo) { if(m_module == null || m_module.Scene == null || m_module.Scene.ShuttingDown) return; UUID requestID = requestinfo.reqID; + + lock(responses) + { + lock(dropedResponses) + { + if(dropedResponses.Contains(requestID)) + { + dropedResponses.Remove(requestID); + return; + } + } + } + Hashtable response = new Hashtable(); response["int_response_code"] = 200; response["content_type"] = "text/plain"; - response["keepalive"] = false; - response["reusecontext"] = false; - response["str_response_string"] = m_webFetchHandler.FetchInventoryDescendentsRequest( - requestinfo.request["body"].ToString(), String.Empty, String.Empty, null, null); +// response["str_response_string"] = m_webFetchHandler.FetchInventoryDescendentsRequest( +// requestinfo.request["body"].ToString(), String.Empty, String.Empty, null, null); + response["bin_response_data"] = System.Text.Encoding.UTF8.GetBytes( + m_webFetchHandler.FetchInventoryDescendentsRequest( + requestinfo.request["body"].ToString(), + String.Empty, String.Empty, null, null) + ); lock (responses) { + lock(dropedResponses) + { + if(dropedResponses.Contains(requestID)) + { + dropedResponses.Remove(requestID); + requestinfo.request.Clear(); + WebFetchInvDescModule.ProcessedRequestsCount++; + return; + } + } + if (responses.ContainsKey(requestID)) m_log.WarnFormat("[FETCH INVENTORY DESCENDENTS2 MODULE]: Caught in the act of loosing responses! Please report this on mantis #7054"); responses[requestID] = response; } - requestinfo.folders.Clear(); requestinfo.request.Clear(); WebFetchInvDescModule.ProcessedRequestsCount++; } @@ -441,24 +478,26 @@ namespace OpenSim.Region.ClientStack.Linden private static void DoInventoryRequests() { + APollRequest poolreq; while (true) { - Watchdog.UpdateThread(); - - aPollRequest poolreq = m_queue.Dequeue(5000); - - if (poolreq != null && poolreq.thepoll != null) + if(!m_queue.TryTake(out poolreq, 4500) || poolreq == null || poolreq.thepoll == null) { - try - { - poolreq.thepoll.Process(poolreq); - } - catch (Exception e) - { - m_log.ErrorFormat( - "[INVENTORY]: Failed to process queued inventory request {0} for {1}. Exception {3}", - poolreq.reqID, poolreq.presence != null ? poolreq.presence.Name : "unknown", e); - } + Watchdog.UpdateThread(); + continue; + } + + Watchdog.UpdateThread(); + try + { + APollRequest req = poolreq; + req.thepoll.Process(req); + } + catch (Exception e) + { + m_log.ErrorFormat( + "[INVENTORY]: Failed to process queued inventory request {0} for {1}. Exception {2}", + poolreq.reqID, poolreq.presence != null ? poolreq.presence.Name : "unknown", e); } } } diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 410ac0052b..bd178c07bc 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -62,7 +62,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// Handles new client connections /// Constructor takes a single Packet and authenticates everything /// - public class LLClientView : IClientAPI, IClientCore, IClientIM, IClientChat, IClientInventory, IStatsCollector + public class LLClientView : IClientAPI, IClientCore, IClientIM, IClientChat, IClientInventory, IStatsCollector, IClientIPEndpoint { /// /// Debug packet level. See OpenSim.RegisterConsoleCommands() for more details. @@ -99,8 +99,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP public event AgentRequestSit OnAgentRequestSit; public event AgentSit OnAgentSit; public event AvatarPickerRequest OnAvatarPickerRequest; - public event StartAnim OnStartAnim; - public event StopAnim OnStopAnim; public event ChangeAnim OnChangeAnim; public event Action OnRequestAvatarsData; public event LinkObjects OnLinkObjects; @@ -131,12 +129,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP public event UpdatePrimTexture OnUpdatePrimTexture; public event ClientChangeObject onClientChangeObject; public event UpdateVector OnUpdatePrimGroupPosition; - public event UpdateVector OnUpdatePrimSinglePosition; public event UpdatePrimRotation OnUpdatePrimGroupRotation; - public event UpdatePrimSingleRotation OnUpdatePrimSingleRotation; - public event UpdatePrimSingleRotationPosition OnUpdatePrimSingleRotationPosition; - public event UpdatePrimGroupRotation OnUpdatePrimGroupMouseRotation; - public event UpdateVector OnUpdatePrimScale; public event UpdateVector OnUpdatePrimGroupScale; public event RequestMapBlocks OnRequestMapBlocks; public event RequestMapName OnMapNameRequest; @@ -292,7 +285,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP public event GodUpdateRegionInfoUpdate OnGodUpdateRegionInfoUpdate; public event GenericCall2 OnUpdateThrottles; + #pragma warning disable 0067 + // still unused public event GenericMessage OnGenericMessage; public event TextureRequest OnRequestTexture; public event StatusChange OnChildAgentStatus; @@ -304,6 +299,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP public event SetEstateTerrainBaseTexture OnSetEstateTerrainBaseTexture; public event TerrainUnacked OnUnackedTerrain; public event CachedTextureRequest OnCachedTextureRequest; + + public event UpdateVector OnUpdatePrimSinglePosition; + public event StartAnim OnStartAnim; + public event StopAnim OnStopAnim; + public event UpdatePrimSingleRotation OnUpdatePrimSingleRotation; + public event UpdatePrimSingleRotationPosition OnUpdatePrimSingleRotationPosition; + public event UpdatePrimGroupRotation OnUpdatePrimGroupMouseRotation; + public event UpdateVector OnUpdatePrimScale; + + #pragma warning restore 0067 #endregion Events @@ -325,6 +330,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// public LLImageManager ImageManager { get; private set; } + public JobEngine m_asyncPacketProcess; private readonly LLUDPServer m_udpServer; private readonly LLUDPClient m_udpClient; private readonly UUID m_sessionId; @@ -334,16 +340,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP private readonly byte[] m_channelVersion = Utils.EmptyBytes; private readonly IGroupsModule m_GroupsModule; - private int m_cachedTextureSerial; +// private int m_cachedTextureSerial; private PriorityQueue m_entityUpdates; private PriorityQueue m_entityProps; private Prioritizer m_prioritizer; - private bool m_disableFacelights = false; + private bool m_disableFacelights; // needs optimazation private HashSet GroupsInView = new HashSet(); - - private bool m_VelocityInterpolate = false; +#pragma warning disable 0414 + private bool m_VelocityInterpolate; +#pragma warning restore 0414 private const uint MaxTransferBytesPerPacket = 600; /// @@ -378,7 +385,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP protected Scene m_scene; protected string m_firstName; protected string m_lastName; - protected Thread m_clientThread; protected Vector3 m_startpos; protected UUID m_activeGroupID; protected string m_activeGroupName = String.Empty; @@ -503,8 +509,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP RegisterInterface(this); m_scene = scene; - m_entityUpdates = new PriorityQueue(m_scene.Entities.Count); - m_entityProps = new PriorityQueue(m_scene.Entities.Count); + int pcap = 512; + if(pcap > m_scene.Entities.Count) + pcap = m_scene.Entities.Count; + m_entityUpdates = new PriorityQueue(pcap); + m_entityProps = new PriorityQueue(pcap); m_killRecord = new List(); // m_attachmentsSent = new HashSet(); @@ -529,7 +538,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_prioritizer = new Prioritizer(m_scene); RegisterLocalPacketHandlers(); - + string name = string.Format("AsyncInUDP-{0}",m_agentId.ToString()); + m_asyncPacketProcess = new JobEngine(name, name, 10000); IsActive = true; } @@ -592,6 +602,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (OnConnectionClosed != null) OnConnectionClosed(this); + m_asyncPacketProcess.Stop(); // Flush all of the packets out of the UDP server for this client if (m_udpServer != null) @@ -615,6 +626,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP ImageManager.Close(); ImageManager = null; +// m_entityUpdates.Close(); +// m_entityProps.Close(); m_entityUpdates = new PriorityQueue(1); m_entityProps = new PriorityQueue(1); m_killRecord.Clear(); @@ -703,29 +716,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// /// true if the handler was added. This is currently always the case. public bool AddLocalPacketHandler(PacketType packetType, PacketMethod handler, bool doAsync) - { - return AddLocalPacketHandler(packetType, handler, doAsync, false); - } - - /// - /// Add a handler for the given packet type. - /// - /// - /// - /// - /// If true, when the packet is received handle it on a different thread. Whether this is given direct to - /// a threadpool thread or placed in a queue depends on the inEngine parameter. - /// - /// - /// If async is false then this parameter is ignored. - /// If async is true and inEngine is false, then the packet is sent directly to a - /// threadpool thread. - /// If async is true and inEngine is true, then the packet is sent to the IncomingPacketAsyncHandlingEngine. - /// This may result in slower handling but reduces the risk of overloading the simulator when there are many - /// simultaneous async requests. - /// - /// true if the handler was added. This is currently always the case. - public bool AddLocalPacketHandler(PacketType packetType, PacketMethod handler, bool doAsync, bool inEngine) { bool result = false; lock (m_packetHandlers) @@ -733,7 +723,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (!m_packetHandlers.ContainsKey(packetType)) { m_packetHandlers.Add( - packetType, new PacketProcessor() { method = handler, Async = doAsync, InEngine = inEngine }); + packetType, new PacketProcessor() { method = handler, Async = doAsync}); result = true; } } @@ -768,30 +758,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP PacketProcessor pprocessor; if (m_packetHandlers.TryGetValue(packet.Type, out pprocessor)) { - ClientInfo cinfo = UDPClient.GetClientInfo(); //there is a local handler for this packet type if (pprocessor.Async) { - if (!cinfo.AsyncRequests.ContainsKey(packet.Type.ToString())) - cinfo.AsyncRequests[packet.Type.ToString()] = 0; - cinfo.AsyncRequests[packet.Type.ToString()]++; - object obj = new AsyncPacketProcess(this, pprocessor.method, packet); - - if (pprocessor.InEngine) - m_udpServer.IpahEngine.QueueJob(packet.Type.ToString(), () => ProcessSpecificPacketAsync(obj)); - else - Util.FireAndForget(ProcessSpecificPacketAsync, obj, packet.Type.ToString()); - + m_asyncPacketProcess.QueueJob(packet.Type.ToString(), () => ProcessSpecificPacketAsync(obj)); result = true; } else { - if (!cinfo.SyncRequests.ContainsKey(packet.Type.ToString())) - cinfo.SyncRequests[packet.Type.ToString()] = 0; - cinfo.SyncRequests[packet.Type.ToString()]++; - result = pprocessor.method(this, packet); } } @@ -806,11 +782,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP } if (found) { - ClientInfo cinfo = UDPClient.GetClientInfo(); - if (!cinfo.GenericRequests.ContainsKey(packet.Type.ToString())) - cinfo.GenericRequests[packet.Type.ToString()] = 0; - cinfo.GenericRequests[packet.Type.ToString()]++; - result = method(this, packet); } } @@ -841,6 +812,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP public virtual void Start() { + m_asyncPacketProcess.Start(); m_scene.AddNewAgent(this, PresenceType.User); // RefreshGroupMembership(); @@ -2346,11 +2318,23 @@ namespace OpenSim.Region.ClientStack.LindenUDP OutPacket(remove, ThrottleOutPacketType.Asset); } +/* + private uint adjustControls(int input) + { + uint ret = (uint)input; + uint masked = ret & 0x0f; + masked <<= 19; + ret |= masked; + return ret; + } +*/ + public void SendTakeControls(int controls, bool passToAgent, bool TakeControls) { ScriptControlChangePacket scriptcontrol = (ScriptControlChangePacket)PacketPool.Instance.GetPacket(PacketType.ScriptControlChange); ScriptControlChangePacket.DataBlock[] data = new ScriptControlChangePacket.DataBlock[1]; ScriptControlChangePacket.DataBlock ddata = new ScriptControlChangePacket.DataBlock(); +// ddata.Controls = adjustControls(controls); ddata.Controls = (uint)controls; ddata.PassToAgent = passToAgent; ddata.TakeControls = TakeControls; @@ -3111,10 +3095,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP public void SendParcelInfo(RegionInfo info, LandData land, UUID parcelID, uint x, uint y) { - float dwell = 0.0f; - IDwellModule dwellModule = m_scene.RequestModuleInterface(); - if (dwellModule != null) - dwell = dwellModule.GetDwell(land.GlobalID); ParcelInfoReplyPacket reply = (ParcelInfoReplyPacket)PacketPool.Instance.GetPacket(PacketType.ParcelInfoReply); reply.AgentData.AgentID = m_agentId; reply.Data.ParcelID = parcelID; @@ -3141,7 +3121,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP reply.Data.GlobalZ = pos.Z; reply.Data.SimName = Utils.StringToBytes(info.RegionName); reply.Data.SnapshotID = land.SnapshotID; - reply.Data.Dwell = dwell; + reply.Data.Dwell = land.Dwell; reply.Data.SalePrice = land.SalePrice; reply.Data.AuctionID = (int)land.AuctionID; @@ -3805,6 +3785,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP OutPacket(useCachedMuteList, ThrottleOutPacketType.Task); } + public void SendEmpytMuteList() + { + GenericMessagePacket gmp = new GenericMessagePacket(); + + gmp.AgentData.AgentID = AgentId; + gmp.AgentData.SessionID = m_sessionId; + gmp.AgentData.TransactionID = UUID.Zero; + + gmp.MethodData.Method = Util.StringToBytes256("emptymutelist"); + gmp.ParamList = new GenericMessagePacket.ParamListBlock[1]; + gmp.ParamList[0] = new GenericMessagePacket.ParamListBlock(); + gmp.ParamList[0].Parameter = new byte[0]; + + OutPacket(gmp, ThrottleOutPacketType.Task); + } + public void SendMuteListUpdate(string filename) { MuteListUpdatePacket muteListUpdate = (MuteListUpdatePacket)PacketPool.Instance.GetPacket(PacketType.MuteListUpdate); @@ -3950,24 +3946,68 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// /// Send an ObjectUpdate packet with information about an avatar /// - public void SendAvatarDataImmediate(ISceneEntity avatar) + public void SendEntityFullUpdateImmediate(ISceneEntity ent) { // m_log.DebugFormat( // "[LLCLIENTVIEW]: Sending immediate object update for avatar {0} {1} to {2} {3}", // avatar.Name, avatar.UUID, Name, AgentId); - ScenePresence presence = avatar as ScenePresence; - if (presence == null) + if (ent == null) return; ObjectUpdatePacket objupdate = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); objupdate.Header.Zerocoded = true; - objupdate.RegionData.RegionHandle = presence.RegionHandle; -// objupdate.RegionData.TimeDilation = ushort.MaxValue; objupdate.RegionData.TimeDilation = Utils.FloatToUInt16(m_scene.TimeDilation, 0.0f, 1.0f); objupdate.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1]; - objupdate.ObjectData[0] = CreateAvatarUpdateBlock(presence); + + if(ent is ScenePresence) + { + ScenePresence presence = ent as ScenePresence; + objupdate.RegionData.RegionHandle = presence.RegionHandle; + objupdate.ObjectData[0] = CreateAvatarUpdateBlock(presence); + } + else if(ent is SceneObjectPart) + { + SceneObjectPart part = ent as SceneObjectPart; + objupdate.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; + objupdate.ObjectData[0] = CreatePrimUpdateBlock(part, (ScenePresence)SceneAgent); + } + + OutPacket(objupdate, ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority); + + // We need to record the avatar local id since the root prim of an attachment points to this. +// m_attachmentsSent.Add(avatar.LocalId); + } + + public void SendEntityTerseUpdateImmediate(ISceneEntity ent) + { +// m_log.DebugFormat( +// "[LLCLIENTVIEW]: Sending immediate object update for avatar {0} {1} to {2} {3}", +// avatar.Name, avatar.UUID, Name, AgentId); + + if (ent == null) + return; + + ImprovedTerseObjectUpdatePacket objupdate = + (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate); + objupdate.Header.Zerocoded = true; + + objupdate.RegionData.TimeDilation = Utils.FloatToUInt16(m_scene.TimeDilation, 0.0f, 1.0f); + objupdate.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[1]; + + if(ent is ScenePresence) + { + ScenePresence presence = ent as ScenePresence; + objupdate.RegionData.RegionHandle = presence.RegionHandle; + objupdate.ObjectData[0] = CreateImprovedTerseBlock(ent, false); + } + else if(ent is SceneObjectPart) + { + SceneObjectPart part = ent as SceneObjectPart; + objupdate.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; + objupdate.ObjectData[0] = CreateImprovedTerseBlock(ent, false); + } OutPacket(objupdate, ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority); @@ -4021,7 +4061,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP #region Primitive Packet/Data Sending Methods - /// /// Generate one of the object update packets based on PrimUpdateFlags /// and broadcast the packet to clients @@ -4044,10 +4083,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP */ if (entity is SceneObjectPart) { - SceneObjectPart e = (SceneObjectPart)entity; - SceneObjectGroup g = e.ParentGroup; + SceneObjectPart p = (SceneObjectPart)entity; + SceneObjectGroup g = p.ParentGroup; if (g.HasPrivateAttachmentPoint && g.OwnerID != AgentId) return; // Don't send updates for other people's HUDs + + if((updateFlags ^ PrimUpdateFlags.SendInTransit) == 0) + { + List partIDs = (new List {p.LocalId}); + lock (m_entityProps.SyncRoot) + m_entityProps.Remove(partIDs); + lock (m_entityUpdates.SyncRoot) + m_entityUpdates.Remove(partIDs); + return; + } } //double priority = m_prioritizer.GetUpdatePriority(this, entity); @@ -4127,6 +4176,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP Vector3 mypos = Vector3.Zero; ScenePresence mysp = (ScenePresence)SceneAgent; + bool orderedDequeue = m_scene.UpdatePrioritizationScheme == UpdatePrioritizationSchemes.SimpleAngularDistance; // we should have a presence if(mysp == null) return; @@ -4141,8 +4191,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP while (maxUpdatesBytes > 0) { lock (m_entityUpdates.SyncRoot) - if (!m_entityUpdates.TryDequeue(out update, out timeinqueue)) - break; + { + if(orderedDequeue) + { + if (!m_entityUpdates.TryOrderedDequeue(out update, out timeinqueue)) + break; + } + else + { + if (!m_entityUpdates.TryDequeue(out update, out timeinqueue)) + break; + } + } PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags; @@ -4157,9 +4217,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP { SceneObjectPart part = (SceneObjectPart)update.Entity; SceneObjectGroup grp = part.ParentGroup; - if (grp.inTransit) + if (grp.inTransit && !update.Flags.HasFlag(PrimUpdateFlags.SendInTransit)) continue; +/* debug + if (update.Flags.HasFlag(PrimUpdateFlags.SendInTransit)) + { + + } +*/ if (grp.IsDeleted) { // Don't send updates for objects that have been marked deleted. @@ -4216,14 +4282,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP { part.Shape.LightEntry = false; } - - if (part.Shape != null && (part.Shape.SculptType == (byte)SculptType.Mesh)) - { - // Ensure that mesh has at least 8 valid faces - part.Shape.ProfileBegin = 12500; - part.Shape.ProfileEnd = 0; - part.Shape.ProfileHollow = 27500; - } } if(doCulling && !grp.IsAttachment) @@ -4251,14 +4309,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP continue; } } - - if (part.Shape != null && (part.Shape.SculptType == (byte)SculptType.Mesh)) - { - // Ensure that mesh has at least 8 valid faces - part.Shape.ProfileBegin = 12500; - part.Shape.ProfileEnd = 0; - part.Shape.ProfileHollow = 27500; - } } else if (update.Entity is ScenePresence) { @@ -4850,6 +4900,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP // OpenSim.Framework.Lazy> propertyUpdates = // new OpenSim.Framework.Lazy>(); + bool orderedDequeue = m_scene.UpdatePrioritizationScheme == UpdatePrioritizationSchemes.SimpleAngularDistance; EntityUpdate iupdate; Int32 timeinqueue; // this is just debugging code & can be dropped later @@ -4857,8 +4908,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP while (maxUpdateBytes > 0) { lock (m_entityProps.SyncRoot) - if (!m_entityProps.TryDequeue(out iupdate, out timeinqueue)) - break; + { + if(orderedDequeue) + { + if (!m_entityProps.TryOrderedDequeue(out iupdate, out timeinqueue)) + break; + } + else + { + if (!m_entityProps.TryDequeue(out iupdate, out timeinqueue)) + break; + } + } ObjectPropertyUpdate update = (ObjectPropertyUpdate)iupdate; if (update.SendFamilyProps) @@ -5526,6 +5587,26 @@ namespace OpenSim.Region.ClientStack.LindenUDP #endregion #region Helper Methods + private void ClampVectorForUint(ref Vector3 v, float max) + { + float a,b; + + a = Math.Abs(v.X); + b = Math.Abs(v.Y); + if(b > a) + a = b; + b= Math.Abs(v.Z); + if(b > a) + a = b; + + if (a > max) + { + a = max / a; + v.X *= a; + v.Y *= a; + v.Z *= a; + } + } protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateImprovedTerseBlock(ISceneEntity entity, bool sendTexture) { @@ -5547,6 +5628,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP velocity = presence.Velocity; acceleration = Vector3.Zero; rotation = presence.Rotation; + // tpvs can only see rotations around Z in some cases + if(!presence.Flying && !presence.IsSatOnObject) + { + rotation.X = 0f; + rotation.Y = 0f; + rotation.Normalize(); + } angularVelocity = presence.AngularVelocity; // m_log.DebugFormat( @@ -5616,11 +5704,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP pos += 12; // Velocity + ClampVectorForUint(ref velocity, 128f); Utils.UInt16ToBytes(Utils.FloatToUInt16(velocity.X, -128.0f, 128.0f), data, pos); pos += 2; Utils.UInt16ToBytes(Utils.FloatToUInt16(velocity.Y, -128.0f, 128.0f), data, pos); pos += 2; Utils.UInt16ToBytes(Utils.FloatToUInt16(velocity.Z, -128.0f, 128.0f), data, pos); pos += 2; // Acceleration + ClampVectorForUint(ref acceleration, 64f); Utils.UInt16ToBytes(Utils.FloatToUInt16(acceleration.X, -64.0f, 64.0f), data, pos); pos += 2; Utils.UInt16ToBytes(Utils.FloatToUInt16(acceleration.Y, -64.0f, 64.0f), data, pos); pos += 2; Utils.UInt16ToBytes(Utils.FloatToUInt16(acceleration.Z, -64.0f, 64.0f), data, pos); pos += 2; @@ -5632,6 +5722,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP Utils.UInt16ToBytes(Utils.FloatToUInt16(rotation.W, -1.0f, 1.0f), data, pos); pos += 2; // Angular Velocity + ClampVectorForUint(ref angularVelocity, 64f); Utils.UInt16ToBytes(Utils.FloatToUInt16(angularVelocity.X, -64.0f, 64.0f), data, pos); pos += 2; Utils.UInt16ToBytes(Utils.FloatToUInt16(angularVelocity.Y, -64.0f, 64.0f), data, pos); pos += 2; Utils.UInt16ToBytes(Utils.FloatToUInt16(angularVelocity.Z, -64.0f, 64.0f), data, pos); pos += 2; @@ -5673,6 +5764,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP Vector3 velocity = new Vector3(0, 0, 0); Vector3 acceleration = new Vector3(0, 0, 0); + // tpvs can only see rotations around Z in some cases + if(!data.Flying && !data.IsSatOnObject) + { + rotation.X = 0f; + rotation.Y = 0f; + } rotation.Normalize(); data.CollisionPlane.ToBytes(objectData, 0); @@ -5753,7 +5850,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP //update.JointPivot = Vector3.Zero; //update.JointType = 0; update.Material = part.Material; - update.MediaURL = Utils.EmptyBytes; // FIXME: Support this in OpenSim /* if (data.ParentGroup.IsAttachment) { @@ -5799,7 +5895,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP update.State = part.Shape.State; // not sure about this } - update.ObjectData = objectData; update.ParentID = part.ParentID; update.PathBegin = part.Shape.PathBegin; @@ -5819,15 +5914,37 @@ namespace OpenSim.Region.ClientStack.LindenUDP update.PCode = part.Shape.PCode; update.ProfileBegin = part.Shape.ProfileBegin; update.ProfileCurve = part.Shape.ProfileCurve; + + ushort profileBegin = part.Shape.ProfileBegin; + ushort profileHollow = part.Shape.ProfileHollow; + + if(part.Shape.SculptType == (byte)SculptType.Mesh) // filter out hack + { + update.ProfileCurve = (byte)(part.Shape.ProfileCurve & 0x0f); + // fix old values that confused viewers + if(profileBegin == 1) + profileBegin = 9375; + if(profileHollow == 1) + profileHollow = 27500; + // fix torus hole size Y that also confuse some viewers + if(update.ProfileCurve == (byte)ProfileShape.Circle && update.PathScaleY < 150) + update.PathScaleY = 150; + } + else + { + update.ProfileCurve = part.Shape.ProfileCurve; + } + + update.ProfileHollow = profileHollow; + update.ProfileBegin = profileBegin; update.ProfileEnd = part.Shape.ProfileEnd; - update.ProfileHollow = part.Shape.ProfileHollow; update.PSBlock = part.ParticleSystem ?? Utils.EmptyBytes; update.TextColor = part.GetTextColor().GetBytes(false); update.TextureAnim = part.TextureAnimation ?? Utils.EmptyBytes; update.TextureEntry = part.Shape.TextureEntry ?? Utils.EmptyBytes; update.Scale = part.Shape.Scale; - update.Text = Util.StringToBytes256(part.Text); - update.MediaURL = Util.StringToBytes256(part.MediaUrl); + update.Text = Util.StringToBytes(part.Text, 255); + update.MediaURL = Util.StringToBytes(part.MediaUrl, 255); #region PrimFlags @@ -5854,7 +5971,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP #endregion PrimFlags - if (part.Sound != UUID.Zero) + if (part.Sound != UUID.Zero || part.SoundFlags != 0) { update.Sound = part.Sound; update.OwnerID = part.OwnerID; @@ -5946,10 +6063,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP AddLocalPacketHandler(PacketType.ParcelBuy, HandleParcelBuyRequest, false); AddLocalPacketHandler(PacketType.UUIDGroupNameRequest, HandleUUIDGroupNameRequest); AddLocalPacketHandler(PacketType.ObjectGroup, HandleObjectGroupRequest); - AddLocalPacketHandler(PacketType.GenericMessage, HandleGenericMessage, true, true); - AddLocalPacketHandler(PacketType.AvatarPropertiesRequest, HandleAvatarPropertiesRequest, true, true); + AddLocalPacketHandler(PacketType.GenericMessage, HandleGenericMessage); + AddLocalPacketHandler(PacketType.AvatarPropertiesRequest, HandleAvatarPropertiesRequest); AddLocalPacketHandler(PacketType.ChatFromViewer, HandleChatFromViewer); - AddLocalPacketHandler(PacketType.AvatarPropertiesUpdate, HandlerAvatarPropertiesUpdate, true, true); + AddLocalPacketHandler(PacketType.AvatarPropertiesUpdate, HandlerAvatarPropertiesUpdate); AddLocalPacketHandler(PacketType.ScriptDialogReply, HandlerScriptDialogReply); AddLocalPacketHandler(PacketType.ImprovedInstantMessage, HandlerImprovedInstantMessage); AddLocalPacketHandler(PacketType.AcceptFriendship, HandlerAcceptFriendship); @@ -6136,8 +6253,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP AddLocalPacketHandler(PacketType.PickDelete, HandlePickDelete); AddLocalPacketHandler(PacketType.PickGodDelete, HandlePickGodDelete); AddLocalPacketHandler(PacketType.PickInfoUpdate, HandlePickInfoUpdate); - AddLocalPacketHandler(PacketType.AvatarNotesUpdate, HandleAvatarNotesUpdate, true, true); - AddLocalPacketHandler(PacketType.AvatarInterestsUpdate, HandleAvatarInterestsUpdate, true, true); + AddLocalPacketHandler(PacketType.AvatarNotesUpdate, HandleAvatarNotesUpdate); + AddLocalPacketHandler(PacketType.AvatarInterestsUpdate, HandleAvatarInterestsUpdate); AddLocalPacketHandler(PacketType.GrantUserRights, HandleGrantUserRights); AddLocalPacketHandler(PacketType.PlacesQuery, HandlePlacesQuery); AddLocalPacketHandler(PacketType.UpdateMuteListEntry, HandleUpdateMuteListEntry); @@ -6228,20 +6345,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// private bool CheckAgentCameraUpdateSignificance(AgentUpdatePacket.AgentDataBlock x) { - float vdelta = Vector3.Distance(x.CameraAtAxis, m_thisAgentUpdateArgs.CameraAtAxis); - if((vdelta > VDELTA)) - return true; + if(Math.Abs(x.CameraCenter.X - m_thisAgentUpdateArgs.CameraCenter.X) > VDELTA || + Math.Abs(x.CameraCenter.Y - m_thisAgentUpdateArgs.CameraCenter.Y) > VDELTA || + Math.Abs(x.CameraCenter.Z - m_thisAgentUpdateArgs.CameraCenter.Z) > VDELTA || - vdelta = Vector3.Distance(x.CameraCenter, m_thisAgentUpdateArgs.CameraCenter); - if((vdelta > VDELTA)) - return true; + Math.Abs(x.CameraAtAxis.X - m_thisAgentUpdateArgs.CameraAtAxis.X) > VDELTA || + Math.Abs(x.CameraAtAxis.Y - m_thisAgentUpdateArgs.CameraAtAxis.Y) > VDELTA || +// Math.Abs(x.CameraAtAxis.Z - m_thisAgentUpdateArgs.CameraAtAxis.Z) > VDELTA || - vdelta = Vector3.Distance(x.CameraLeftAxis, m_thisAgentUpdateArgs.CameraLeftAxis); - if((vdelta > VDELTA)) - return true; + Math.Abs(x.CameraLeftAxis.X - m_thisAgentUpdateArgs.CameraLeftAxis.X) > VDELTA || + Math.Abs(x.CameraLeftAxis.Y - m_thisAgentUpdateArgs.CameraLeftAxis.Y) > VDELTA || +// Math.Abs(x.CameraLeftAxis.Z - m_thisAgentUpdateArgs.CameraLeftAxis.Z) > VDELTA || - vdelta = Vector3.Distance(x.CameraUpAxis, m_thisAgentUpdateArgs.CameraUpAxis); - if((vdelta > VDELTA)) + Math.Abs(x.CameraUpAxis.X - m_thisAgentUpdateArgs.CameraUpAxis.X) > VDELTA || + Math.Abs(x.CameraUpAxis.Y - m_thisAgentUpdateArgs.CameraUpAxis.Y) > VDELTA +// Math.Abs(x.CameraLeftAxis.Z - m_thisAgentUpdateArgs.CameraLeftAxis.Z) > VDELTA || + ) return true; return false; @@ -6347,6 +6466,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP ParcelGodMarkAsContentPacket ParcelGodMarkAsContent = (ParcelGodMarkAsContentPacket)Packet; + if(SessionId != ParcelGodMarkAsContent.AgentData.SessionID || AgentId != ParcelGodMarkAsContent.AgentData.AgentID) + return false; + ParcelGodMark ParcelGodMarkAsContentHandler = OnParcelGodMark; if (ParcelGodMarkAsContentHandler != null) { @@ -6362,6 +6484,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP { FreezeUserPacket FreezeUser = (FreezeUserPacket)Packet; + if(SessionId != FreezeUser.AgentData.SessionID || AgentId != FreezeUser.AgentData.AgentID) + return false; + FreezeUserUpdate FreezeUserHandler = OnParcelFreezeUser; if (FreezeUserHandler != null) { @@ -6379,6 +6504,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP EjectUserPacket EjectUser = (EjectUserPacket)Packet; + if(SessionId != EjectUser.AgentData.SessionID || AgentId != EjectUser.AgentData.AgentID) + return false; + EjectUserUpdate EjectUserHandler = OnParcelEjectUser; if (EjectUserHandler != null) { @@ -6396,6 +6524,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP ParcelBuyPassPacket ParcelBuyPass = (ParcelBuyPassPacket)Packet; + if(SessionId != ParcelBuyPass.AgentData.SessionID || AgentId != ParcelBuyPass.AgentData.AgentID) + return false; + ParcelBuyPass ParcelBuyPassHandler = OnParcelBuyPass; if (ParcelBuyPassHandler != null) { @@ -6428,8 +6559,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP private bool HandleUUIDGroupNameRequest(IClientAPI sender, Packet Pack) { - UUIDGroupNameRequestPacket upack = (UUIDGroupNameRequestPacket)Pack; + ScenePresence sp = (ScenePresence)SceneAgent; + if(sp == null || sp.IsDeleted || (sp.IsInTransit && !sp.IsInLocalTransit)) + return true; + UUIDGroupNameRequestPacket upack = (UUIDGroupNameRequestPacket)Pack; for (int i = 0; i < upack.UUIDNameBlock.Length; i++) { @@ -7381,8 +7515,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP handlerSoundTrigger(soundTriggerPacket.SoundData.SoundID, AgentId, AgentId, AgentId, soundTriggerPacket.SoundData.Gain, soundTriggerPacket.SoundData.Position, - soundTriggerPacket.SoundData.Handle, 0); - + soundTriggerPacket.SoundData.Handle); } return true; } @@ -7448,7 +7581,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP SendUserInfoReply(false, true, ""); } return true; - } private bool HandleUpdateUserInfo(IClientAPI sender, Packet Pack) @@ -7983,19 +8115,41 @@ namespace OpenSim.Region.ClientStack.LindenUDP return true; } + Dictionary objImageSeqs = null; + double lastobjImageSeqsMS = 0.0; + private bool HandleObjectImage(IClientAPI sender, Packet Pack) { ObjectImagePacket imagePack = (ObjectImagePacket)Pack; - UpdatePrimTexture handlerUpdatePrimTexture = null; + UpdatePrimTexture handlerUpdatePrimTexture = OnUpdatePrimTexture; + if (handlerUpdatePrimTexture == null) + return true; + + double now = Util.GetTimeStampMS(); + if(objImageSeqs == null || ( now - lastobjImageSeqsMS > 30000.0)) + { + objImageSeqs = null; // yeah i know superstition... + objImageSeqs = new Dictionary(16); + } + + lastobjImageSeqsMS = now; + uint seq = Pack.Header.Sequence; + uint id; + uint lastseq; + + ObjectImagePacket.ObjectDataBlock o; for (int i = 0; i < imagePack.ObjectData.Length; i++) { - handlerUpdatePrimTexture = OnUpdatePrimTexture; - if (handlerUpdatePrimTexture != null) - { - handlerUpdatePrimTexture(imagePack.ObjectData[i].ObjectLocalID, - imagePack.ObjectData[i].TextureEntry, this); - } + o = imagePack.ObjectData[i]; + id = o.ObjectLocalID; + if(objImageSeqs.TryGetValue(id, out lastseq)) + { + if(seq <= lastseq) + continue; + } + objImageSeqs[id] = seq; + handlerUpdatePrimTexture(id, o.TextureEntry, this); } return true; } @@ -9603,6 +9757,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP private bool HandleUUIDNameRequest(IClientAPI sender, Packet Pack) { + ScenePresence sp = (ScenePresence)SceneAgent; + if(sp == null || sp.IsDeleted || (sp.IsInTransit && !sp.IsInLocalTransit)) + return true; + UUIDNameRequestPacket incoming = (UUIDNameRequestPacket)Pack; foreach (UUIDNameRequestPacket.UUIDNameBlockBlock UUIDBlock in incoming.UUIDNameBlock) @@ -10888,6 +11046,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP } else { + if(muteListRequest.MuteData.MuteCRC == 0) + SendEmpytMuteList(); + else SendUseCachedMuteList(); } return true; @@ -12520,11 +12681,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP } int maxWearablesLoop = cachedtex.WearableData.Length; - if (maxWearablesLoop > cacheItems.Length) - maxWearablesLoop = cacheItems.Length; if (cacheItems != null) { + if (maxWearablesLoop > cacheItems.Length) + maxWearablesLoop = cacheItems.Length; for (int i = 0; i < maxWearablesLoop; i++) { int idx = cachedtex.WearableData[i].TextureIndex; @@ -13359,7 +13520,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP SendAssetNotFound(req); return; } - } if (transferRequest.TransferInfo.SourceType == (int)SourceType.Asset) @@ -13436,11 +13596,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// public bool Async { get; set; } - /// - /// If async is true, should this packet be handled in the async engine or given directly to a threadpool - /// thread? - /// - public bool InEngine { get; set; } } public class AsyncPacketProcess diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index ec51e28488..552c51e192 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs @@ -27,6 +27,7 @@ using System; using System.Collections.Generic; +using System.Collections.Concurrent; using System.Diagnostics; using System.IO; using System.Net; @@ -285,7 +286,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// Incoming packets that are awaiting handling //protected OpenMetaverse.BlockingQueue packetInbox = new OpenMetaverse.BlockingQueue(); - protected OpenSim.Framework.BlockingQueue packetInbox = new OpenSim.Framework.BlockingQueue(); + protected BlockingCollection packetInbox = new BlockingCollection(); /// Bandwidth throttle for this UDP server public TokenBucket Throttle { get; protected set; } @@ -312,9 +313,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// stack. Use zero to leave this value as the default protected int m_recvBufferSize; - /// Flag to process packets asynchronously or synchronously - protected bool m_asyncPacketHandling; - /// Tracks whether or not a packet was sent each round so we know /// whether or not to sleep protected bool m_packetSent; @@ -417,7 +415,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// Queue some low priority but potentially high volume async requests so that they don't overwhelm available /// threadpool threads. /// - public JobEngine IpahEngine { get; protected set; } +// public JobEngine IpahEngine { get; protected set; } /// /// Run queue empty processing within a single persistent thread. @@ -473,7 +471,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP IConfig config = configSource.Configs["ClientStack.LindenUDP"]; if (config != null) { - m_asyncPacketHandling = config.GetBoolean("async_packet_handling", true); m_recvBufferSize = config.GetInt("client_socket_rcvbuf_size", 0); sceneThrottleBps = config.GetInt("scene_throttle_max_bps", 0); @@ -531,7 +528,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP { StartInbound(); StartOutbound(); - IpahEngine.Start(); +// IpahEngine.Start(); OqrEngine.Start(); m_elapsedMSSinceLastStatReport = Environment.TickCount; @@ -540,10 +537,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP public void StartInbound() { m_log.InfoFormat( - "[LLUDPSERVER]: Starting inbound packet processing for the LLUDP server in {0} mode with UsePools = {1}", - m_asyncPacketHandling ? "asynchronous" : "synchronous", UsePools); + "[LLUDPSERVER]: Starting inbound packet processing for the LLUDP server"); - base.StartInbound(m_recvBufferSize, m_asyncPacketHandling); + base.StartInbound(m_recvBufferSize); // This thread will process the packets received that are placed on the packetInbox WorkManager.StartThread( @@ -577,7 +573,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_log.Info("[LLUDPSERVER]: Shutting down the LLUDP server for " + Scene.Name); base.StopOutbound(); base.StopInbound(); - IpahEngine.Stop(); +// IpahEngine.Stop(); OqrEngine.Stop(); } @@ -696,12 +692,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP Scene = (Scene)scene; m_location = new Location(Scene.RegionInfo.RegionHandle); - +/* IpahEngine = new JobEngine( string.Format("Incoming Packet Async Handling Engine ({0})", Scene.Name), "INCOMING PACKET ASYNC HANDLING ENGINE"); - +*/ OqrEngine = new JobEngine( string.Format("Outgoing Queue Refill Engine ({0})", Scene.Name), @@ -717,7 +713,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP scene.Name, StatType.Pull, MeasuresOfInterest.AverageChangeOverTime, - stat => stat.Value = packetInbox.Count(), + stat => {try{stat.Value = packetInbox.Count;}catch{}}, StatVerbosity.Debug)); // XXX: These stats are also pool stats but we register them separately since they are currently not @@ -786,7 +782,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP MeasuresOfInterest.AverageChangeOverTime, stat => stat.Value = GetTotalQueuedOutgoingPackets(), StatVerbosity.Info)); - +/* StatsManager.RegisterStat( new Stat( "IncomingPacketAsyncRequestsWaiting", @@ -799,7 +795,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP MeasuresOfInterest.None, stat => stat.Value = IpahEngine.JobsWaiting, StatVerbosity.Debug)); - +*/ StatsManager.RegisterStat( new Stat( "OQRERequestsWaiting", @@ -903,7 +899,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (packet.Type == PacketType.CoarseLocationUpdate && allowSplitting) allowSplitting = false; - bool packetQueued = false; +// bool packetQueued = false; if (allowSplitting && packet.HasVariableBlocks) { @@ -916,15 +912,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP for (int i = 0; i < packetCount; i++) { byte[] data = datas[i]; - if (!SendPacketData(udpClient, data, packet.Type, category, method)) - packetQueued = true; +// if (!SendPacketData(udpClient, data, packet.Type, category, method)) +// packetQueued = true; + SendPacketData(udpClient, data, packet.Type, category, method); } } else { byte[] data = packet.ToBytes(); - if (!SendPacketData(udpClient, data, packet.Type, category, method)) - packetQueued = true; +// if (!SendPacketData(udpClient, data, packet.Type, category, method)) +// packetQueued = true; + SendPacketData(udpClient, data, packet.Type, category, method); } PacketPool.Instance.ReturnPacket(packet); @@ -1227,7 +1225,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP outgoingPacket.SequenceNumber, isReliable, isResend, udpClient.AgentID, Scene.Name); // Put the UDP payload on the wire - AsyncBeginSend(buffer); +// AsyncBeginSend(buffer); + SyncSend(buffer); // Keep track of when this packet was sent out (right now) outgoingPacket.TickCount = Environment.TickCount & Int32.MaxValue; @@ -1548,10 +1547,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP // if (incomingPacket.Packet.Type == PacketType.AgentUpdate || // incomingPacket.Packet.Type == PacketType.ChatFromViewer) - if (incomingPacket.Packet.Type == PacketType.ChatFromViewer) - packetInbox.PriorityEnqueue(incomingPacket); - else - packetInbox.Enqueue(incomingPacket); +// if (incomingPacket.Packet.Type == PacketType.ChatFromViewer) +// packetInbox.PriorityEnqueue(incomingPacket); +// else +// packetInbox.Enqueue(incomingPacket); + packetInbox.Add(incomingPacket); } @@ -1912,7 +1912,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP Buffer.BlockCopy(packetData, 0, buffer.Data, 0, length); - AsyncBeginSend(buffer); +// AsyncBeginSend(buffer); + SyncSend(buffer); } protected bool IsClientAuthorized(UseCircuitCodePacket useCircuitCode, out AuthenticateResponse sessionInfo) @@ -2019,7 +2020,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP Scene.ThreadAlive(1); try { - incomingPacket = packetInbox.Dequeue(250); + packetInbox.TryTake(out incomingPacket, 250); if (incomingPacket != null && IsRunningInbound) { @@ -2041,9 +2042,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP Watchdog.UpdateThread(); } - if (packetInbox.Count() > 0) - m_log.Warn("[LLUDPSERVER]: IncomingPacketHandler is shutting down, dropping " + packetInbox.Count() + " packets"); - packetInbox.Clear(); + if (packetInbox.Count > 0) + m_log.Warn("[LLUDPSERVER]: IncomingPacketHandler is shutting down, dropping " + packetInbox.Count + " packets"); + packetInbox.Dispose(); Watchdog.RemoveThread(); } diff --git a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs index 35a07111df..f362b06f0a 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs @@ -57,9 +57,6 @@ namespace OpenMetaverse /// UDP socket, used in either client or server mode private Socket m_udpSocket; - /// Flag to process packets asynchronously or synchronously - private bool m_asyncPacketHandling; - /// /// Are we to use object pool(s) to reduce memory churn when receiving data? /// @@ -205,10 +202,8 @@ namespace OpenMetaverse /// manner (not throwing an exception when the remote side resets the /// connection). This call is ignored on Mono where the flag is not /// necessary - public virtual void StartInbound(int recvBufferSize, bool asyncPacketHandling) + public virtual void StartInbound(int recvBufferSize) { - m_asyncPacketHandling = asyncPacketHandling; - if (!IsRunningInbound) { m_log.DebugFormat("[UDPBASE]: Starting inbound UDP loop"); @@ -233,14 +228,23 @@ namespace OpenMetaverse { m_log.Debug("[UDPBASE]: Failed to increase default TTL"); } + try { // This udp socket flag is not supported under mono, // so we'll catch the exception and continue - m_udpSocket.IOControl(SIO_UDP_CONNRESET, new byte[] { 0 }, null); - m_log.Debug("[UDPBASE]: SIO_UDP_CONNRESET flag set"); + // Try does not protect some mono versions on mac + if(Util.IsWindows()) + { + m_udpSocket.IOControl(SIO_UDP_CONNRESET, new byte[] { 0 }, null); + m_log.Debug("[UDPBASE]: SIO_UDP_CONNRESET flag set"); + } + else + { + m_log.Debug("[UDPBASE]: SIO_UDP_CONNRESET flag not supported on this platform, ignoring"); + } } - catch (SocketException) + catch { m_log.Debug("[UDPBASE]: SIO_UDP_CONNRESET flag not supported on this platform, ignoring"); } @@ -407,12 +411,7 @@ namespace OpenMetaverse if (IsRunningInbound) { UdpReceives++; - - // Asynchronous mode will start another receive before the - // callback for this packet is even fired. Very parallel :-) - if (m_asyncPacketHandling) - AsyncBeginReceive(); - + try { // get the buffer that was created in AsyncBeginReceive @@ -469,10 +468,7 @@ namespace OpenMetaverse // if (UsePools) // Pool.ReturnObject(buffer); - // Synchronous mode waits until the packet callback completes - // before starting the receive to fetch another packet - if (!m_asyncPacketHandling) - AsyncBeginReceive(); + AsyncBeginReceive(); } } } @@ -500,7 +496,7 @@ namespace OpenMetaverse } catch (SocketException) { } catch (ObjectDisposedException) { } -// } + // } } void AsyncEndSend(IAsyncResult result) @@ -515,5 +511,25 @@ namespace OpenMetaverse catch (SocketException) { } catch (ObjectDisposedException) { } } + + public void SyncSend(UDPPacketBuffer buf) + { + try + { + m_udpSocket.SendTo( + buf.Data, + 0, + buf.DataLength, + SocketFlags.None, + buf.RemoteEndPoint + ); + UdpSends++; + } + catch (SocketException e) + { + m_log.Warn("[UDPBASE]: sync send SocketException {0} " + e.Message); + } + catch (ObjectDisposedException) { } + } } } diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs index 0e1a9e3d10..eb262d27f7 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs @@ -91,6 +91,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests /// /// Test adding a client to the stack /// +/* [Test] public void TestAddClient() { @@ -165,7 +166,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests ScenePresence spAfterAckTimeout = m_scene.GetScenePresence(sp.UUID); Assert.That(spAfterAckTimeout, Is.Null); } - +*/ // /// // /// Test removing a client from the stack // /// diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs index d2aa17793c..52b9d0ee84 100644 --- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs +++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs @@ -258,24 +258,24 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction { m_uploadState = UploadState.Complete; - ourClient.SendAssetUploadCompleteMessage(m_asset.Type, true, m_asset.FullID); - + bool sucess = true; if (m_createItem) { - CompleteCreateItem(m_createItemCallback); + sucess = CompleteCreateItem(m_createItemCallback); } else if (m_updateItem) { - CompleteItemUpdate(m_updateItemData); + sucess = CompleteItemUpdate(m_updateItemData); } else if (m_updateTaskItem) { - CompleteTaskItemUpdate(m_updateTaskItemData); + sucess = CompleteTaskItemUpdate(m_updateTaskItemData); } else if (m_asset.Local) { m_Scene.AssetService.Store(m_asset); } + ourClient.SendAssetUploadCompleteMessage(m_asset.Type, sucess, m_asset.FullID); } m_log.DebugFormat( @@ -411,46 +411,70 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction /// Store the asset for the given item when it has been uploaded. /// /// - private void CompleteItemUpdate(InventoryItemBase item) + private bool CompleteItemUpdate(InventoryItemBase item) { // m_log.DebugFormat( // "[ASSET XFER UPLOADER]: Storing asset {0} for earlier item update for {1} for {2}", // m_asset.FullID, item.Name, ourClient.Name); - ValidateAssets(); - m_Scene.AssetService.Store(m_asset); - if (m_asset.FullID != UUID.Zero) + uint perms = ValidateAssets(); + if(perms == 0) { - item.AssetID = m_asset.FullID; - m_Scene.InventoryService.UpdateItem(item); + string error = string.Format("Not enough permissions on asset(s) referenced by item '{0}', update failed", item.Name); + ourClient.SendAlertMessage(error); + m_transactions.RemoveXferUploader(m_transactionID); + ourClient.SendBulkUpdateInventory(item); // invalid the change item on viewer cache + } + else + { + m_Scene.AssetService.Store(m_asset); + if (m_asset.FullID != UUID.Zero) + { + item.AssetID = m_asset.FullID; + m_Scene.InventoryService.UpdateItem(item); + } + ourClient.SendInventoryItemCreateUpdate(item, m_transactionID, 0); + m_transactions.RemoveXferUploader(m_transactionID); + m_Scene.EventManager.TriggerOnNewInventoryItemUploadComplete(item, 0); } - ourClient.SendInventoryItemCreateUpdate(item, m_transactionID, 0); - - m_transactions.RemoveXferUploader(m_transactionID); - - m_Scene.EventManager.TriggerOnNewInventoryItemUploadComplete(item, 0); + return perms != 0; } /// /// Store the asset for the given task item when it has been uploaded. /// /// - private void CompleteTaskItemUpdate(TaskInventoryItem taskItem) + private bool CompleteTaskItemUpdate(TaskInventoryItem taskItem) { // m_log.DebugFormat( // "[ASSET XFER UPLOADER]: Storing asset {0} for earlier task item update for {1} for {2}", // m_asset.FullID, taskItem.Name, ourClient.Name); - ValidateAssets(); - m_Scene.AssetService.Store(m_asset); + if(ValidateAssets() == 0) + { + m_transactions.RemoveXferUploader(m_transactionID); + string error = string.Format("Not enough permissions on asset(s) referenced by task item '{0}', update failed", taskItem.Name); + ourClient.SendAlertMessage(error); + // force old asset to viewers ?? + return false; + } + m_Scene.AssetService.Store(m_asset); m_transactions.RemoveXferUploader(m_transactionID); + return true; } - private void CompleteCreateItem(uint callbackID) + private bool CompleteCreateItem(uint callbackID) { - ValidateAssets(); + if(ValidateAssets() == 0) + { + m_transactions.RemoveXferUploader(m_transactionID); + string error = string.Format("Not enough permissions on asset(s) referenced by item '{0}', creation failed", m_name); + ourClient.SendAlertMessage(error); + return false; + } + m_Scene.AssetService.Store(m_asset); InventoryItemBase item = new InventoryItemBase(); @@ -480,35 +504,40 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction ourClient.SendAlertMessage("Unable to create inventory item"); m_transactions.RemoveXferUploader(m_transactionID); + return true; } - - private void ValidateAssets() + private uint ValidateAssets() { + uint retPerms = 0x7fffffff; +// if(m_Scene.Permissions.BypassPermissions()) +// return retPerms; + if (m_asset.Type == (sbyte)CustomAssetType.AnimationSet) { + AnimationSet animSet = new AnimationSet(m_asset.Data); - bool allOk = animSet.Validate(x => { - int perms = m_Scene.InventoryService.GetAssetPermissions(ourClient.AgentId, x); - int required = (int)(PermissionMask.Transfer | PermissionMask.Copy); + retPerms &= animSet.Validate(x => { + const uint required = (uint)(PermissionMask.Transfer | PermissionMask.Copy); + uint perms = (uint)m_Scene.InventoryService.GetAssetPermissions(ourClient.AgentId, x); + // currrent yes/no rule if ((perms & required) != required) - return false; - return true; + return 0; + return perms; }); - if (!allOk) - m_asset.Data = animSet.ToBytes(); + return retPerms; } if (m_asset.Type == (sbyte)AssetType.Clothing || m_asset.Type == (sbyte)AssetType.Bodypart) { + const uint texturesfullPermMask = (uint)(PermissionMask.Modify | PermissionMask.Transfer | PermissionMask.Copy); string content = System.Text.Encoding.ASCII.GetString(m_asset.Data); string[] lines = content.Split(new char[] {'\n'}); - List validated = new List(); - + // on current requiriment of full rigths assume old assets where accepted Dictionary allowed = ExtractTexturesFromOldData(); int textures = 0; @@ -518,10 +547,8 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction try { if (line.StartsWith("textures ")) - { textures = Convert.ToInt32(line.Substring(9)); - validated.Add(line); - } + else if (textures > 0) { string[] parts = line.Split(new char[] {' '}); @@ -532,42 +559,35 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction if (defaultIDs.Contains(tx) || tx == UUID.Zero || (allowed.ContainsKey(id) && allowed[id] == tx)) { - validated.Add(parts[0] + " " + tx.ToString()); + continue; } else { - int perms = m_Scene.InventoryService.GetAssetPermissions(ourClient.AgentId, tx); - int full = (int)(PermissionMask.Modify | PermissionMask.Transfer | PermissionMask.Copy); + uint perms = (uint)m_Scene.InventoryService.GetAssetPermissions(ourClient.AgentId, tx); - if ((perms & full) != full) + if ((perms & texturesfullPermMask) != texturesfullPermMask) { m_log.ErrorFormat("[ASSET UPLOADER]: REJECTED update with texture {0} from {1} because they do not own the texture", tx, ourClient.AgentId); - validated.Add(parts[0] + " " + UUID.Zero.ToString()); + return 0; } else { - validated.Add(line); + retPerms &= perms; } } textures--; } - else - { - validated.Add(line); - } } catch { // If it's malformed, skip it } } - - string final = String.Join("\n", validated.ToArray()); - - m_asset.Data = System.Text.Encoding.ASCII.GetBytes(final); } + return retPerms; } +/* not in use /// /// Get the asset data uploaded in this transfer. /// @@ -582,7 +602,7 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction return null; } - +*/ public void SetOldData(byte[] d) { m_oldData = d; diff --git a/OpenSim/Region/CoreModules/Agent/IPBan/SceneBanner.cs b/OpenSim/Region/CoreModules/Agent/IPBan/SceneBanner.cs index 8502006cd7..b4c68e2a65 100644 --- a/OpenSim/Region/CoreModules/Agent/IPBan/SceneBanner.cs +++ b/OpenSim/Region/CoreModules/Agent/IPBan/SceneBanner.cs @@ -53,9 +53,9 @@ namespace OpenSim.Region.CoreModules.Agent.IPBan if (bans.Count > 0) { IClientIPEndpoint ipEndpoint; - if (client.TryGet(out ipEndpoint)) + if (client.TryGet(out ipEndpoint) && ipEndpoint.RemoteEndPoint != null) { - IPAddress end = ipEndpoint.EndPoint; + IPAddress end = ipEndpoint.RemoteEndPoint.Address; try { diff --git a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs index 610e279a24..d1cb5e89fb 100644 --- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs +++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs @@ -646,7 +646,7 @@ namespace OpenSim.Region.CoreModules.Asset if (m_LogLevel >= 2) m_log.Debug("[FLOTSAM ASSET CACHE]: Clearing caches."); - if (m_FileCacheEnabled) + if (m_FileCacheEnabled && Directory.Exists(m_CacheDirectory)) { foreach (string dir in Directory.GetDirectories(m_CacheDirectory)) { @@ -681,10 +681,10 @@ namespace OpenSim.Region.CoreModules.Asset // before cleaning up expired files we must scan the objects in the scene to make sure that we retain // such local assets if they have not been recently accessed. TouchAllSceneAssets(false); - - foreach (string dir in Directory.GetDirectories(m_CacheDirectory)) + if(Directory.Exists(m_CacheDirectory)) { - CleanExpiredFiles(dir, purgeLine); + foreach (string dir in Directory.GetDirectories(m_CacheDirectory)) + CleanExpiredFiles(dir, purgeLine); } lock(timerLock) @@ -706,6 +706,9 @@ namespace OpenSim.Region.CoreModules.Asset { try { + if(!Directory.Exists(dir)) + return; + foreach (string file in Directory.GetFiles(dir)) { if (File.GetLastAccessTime(file) < purgeLine) @@ -806,7 +809,7 @@ namespace OpenSim.Region.CoreModules.Asset return; } - catch (UnauthorizedAccessException e) + catch (UnauthorizedAccessException) { } finally @@ -869,6 +872,9 @@ namespace OpenSim.Region.CoreModules.Asset /// private int GetFileCacheCount(string dir) { + if(!Directory.Exists(dir)) + return 0; + int count = Directory.GetFiles(dir).Length; foreach (string subdir in Directory.GetDirectories(dir)) @@ -987,6 +993,9 @@ namespace OpenSim.Region.CoreModules.Asset /// private void ClearFileCache() { + if(!Directory.Exists(m_CacheDirectory)) + return; + foreach (string dir in Directory.GetDirectories(m_CacheDirectory)) { try @@ -1151,15 +1160,15 @@ namespace OpenSim.Region.CoreModules.Asset { if(m_cleanupRunning) { - con.OutputFormat("FloatSam assets check already running"); + con.OutputFormat("Flotsam assets check already running"); return; } m_cleanupRunning = true; } - con.Output("FloatSam Ensuring assets are cached for all scenes."); + con.Output("Flotsam Ensuring assets are cached for all scenes."); - WorkManager.RunInThread(delegate + WorkManager.RunInThreadPool(delegate { bool wasRunning= false; lock(timerLock) @@ -1184,7 +1193,7 @@ namespace OpenSim.Region.CoreModules.Asset m_cleanupRunning = false; } con.OutputFormat("Completed check with {0} assets.", assetReferenceTotal); - }, null, "TouchAllSceneAssets"); + }, null, "TouchAllSceneAssets", false); break; diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index cf188aacd3..e175db49b6 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -42,6 +42,7 @@ using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes.Serialization; using OpenSim.Services.Interfaces; +using PermissionMask = OpenSim.Framework.PermissionMask; namespace OpenSim.Region.CoreModules.Avatar.Attachments { @@ -367,7 +368,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments { string xmlData; XmlDocument d = null; - UUID asset; + if (itemData.TryGetValue(attach.ItemID, out xmlData)) { d = new XmlDocument(); @@ -492,17 +493,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments return false; } - List attachments = sp.GetAttachments(attachmentPt); - if (attachments.Contains(group)) - { -// if (DebugLevel > 0) -// m_log.WarnFormat( -// "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since it's already attached", -// group.Name, group.LocalId, sp.Name, attachmentPt); - - return false; - } - Vector3 attachPos = group.AbsolutePosition; // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should @@ -546,6 +536,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments attachPos = Vector3.Zero; } + List attachments = sp.GetAttachments(attachmentPt); + if (attachments.Contains(group)) + { +// if (DebugLevel > 0) +// m_log.WarnFormat( +// "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since it's already attached", +// group.Name, group.LocalId, sp.Name, attachmentPt); + + return false; + } + // If we already have 5, remove the oldest until only 4 are left. Skip over temp ones while (attachments.Count >= 5) { @@ -896,6 +897,30 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments if (item != null) { + // attach is rez, need to update permissions + item.Flags &= ~(uint)(InventoryItemFlags.ObjectSlamPerm | InventoryItemFlags.ObjectOverwriteBase | + InventoryItemFlags.ObjectOverwriteOwner | InventoryItemFlags.ObjectOverwriteGroup | + InventoryItemFlags.ObjectOverwriteEveryone | InventoryItemFlags.ObjectOverwriteNextOwner); + + uint permsBase = (uint)(PermissionMask.Copy | PermissionMask.Transfer | + PermissionMask.Modify | PermissionMask.Move | + PermissionMask.Export | PermissionMask.FoldedMask); + + permsBase &= grp.CurrentAndFoldedNextPermissions(); + permsBase |= (uint)PermissionMask.Move; + item.BasePermissions = permsBase; + item.CurrentPermissions = permsBase; + item.NextPermissions = permsBase & grp.RootPart.NextOwnerMask | (uint)PermissionMask.Move; + item.EveryOnePermissions = permsBase & grp.RootPart.EveryoneMask; + item.GroupPermissions = permsBase & grp.RootPart.GroupMask; + item.CurrentPermissions &= + ((uint)PermissionMask.Copy | + (uint)PermissionMask.Transfer | + (uint)PermissionMask.Modify | + (uint)PermissionMask.Move | + (uint)PermissionMask.Export | + (uint)PermissionMask.FoldedMask); // Preserve folded permissions ?? + AssetBase asset = m_scene.CreateAsset( grp.GetPartName(grp.LocalId), grp.GetPartDescription(grp.LocalId), diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index 535d946710..1a0b7baa7c 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs @@ -369,7 +369,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory return true; // uploaded baked textures will be in assets local cache - IAssetService cache = m_scene.AssetService; + IAssetCache cache = m_scene.RequestModuleInterface(); IBakedTextureModule m_BakedTextureModule = m_scene.RequestModuleInterface(); int validDirtyBakes = 0; @@ -385,7 +385,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory List missing = new List(); - bool haveSkirt = (wearableCache[19].TextureAsset != null); + bool haveSkirt = (wearableCache[19].TextureID != UUID.Zero); bool haveNewSkirt = false; // Process received baked textures @@ -436,7 +436,11 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory */ wearableCache[idx].TextureAsset = null; if (cache != null) - wearableCache[idx].TextureAsset = cache.GetCached(face.TextureID.ToString()); + { + AssetBase asb = null; + cache.Get(face.TextureID.ToString(), out asb); + wearableCache[idx].TextureAsset = asb; + } if (wearableCache[idx].TextureAsset != null) { @@ -481,25 +485,26 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory // if we got a full set of baked textures save all in BakedTextureModule if (m_BakedTextureModule != null) { - m_log.Debug("[UpdateBakedCache] start async uploading to bakedModule cache"); + m_log.DebugFormat("[UpdateBakedCache] Uploading to Bakes Server: cache hits: {0} changed entries: {1} rebakes {2}", + hits.ToString(), validDirtyBakes.ToString(), missing.Count); m_BakedTextureModule.Store(sp.UUID, wearableCache); } } + else + m_log.DebugFormat("[UpdateBakedCache] cache hits: {0} changed entries: {1} rebakes {2}", + hits.ToString(), validDirtyBakes.ToString(), missing.Count); - - // debug - m_log.Debug("[UpdateBakedCache] cache hits: " + hits.ToString() + " changed entries: " + validDirtyBakes.ToString() + " rebakes " + missing.Count); -/* for (int iter = 0; iter < AvatarAppearance.BAKE_INDICES.Length; iter++) { int j = AvatarAppearance.BAKE_INDICES[iter]; - m_log.Debug("[UpdateBCache] {" + iter + "/" + - sp.Appearance.WearableCacheItems[j].TextureIndex + "}: c-" + - sp.Appearance.WearableCacheItems[j].CacheId + ", t-" + - sp.Appearance.WearableCacheItems[j].TextureID); + sp.Appearance.WearableCacheItems[j].TextureAsset = null; +// m_log.Debug("[UpdateBCache] {" + iter + "/" + +// sp.Appearance.WearableCacheItems[j].TextureIndex + "}: c-" + +// sp.Appearance.WearableCacheItems[j].CacheId + ", t-" + +// sp.Appearance.WearableCacheItems[j].TextureID); } -*/ + return (hits == cacheItems.Length); } @@ -513,7 +518,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory lock (m_setAppearanceLock) { - IAssetService cache = m_scene.AssetService; + IAssetCache cache = m_scene.RequestModuleInterface(); IBakedTextureModule bakedModule = m_scene.RequestModuleInterface(); WearableCacheItem[] bakedModuleCache = null; @@ -523,7 +528,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory WearableCacheItem[] wearableCache = sp.Appearance.WearableCacheItems; // big debug - m_log.DebugFormat("[AVFACTORY]: ValidateBakedTextureCache start for {0} {1}", sp.Name, sp.UUID); +// m_log.DebugFormat("[AVFACTORY]: ValidateBakedTextureCache start for {0} {1}", sp.Name, sp.UUID); /* for (int iter = 0; iter < AvatarAppearance.BAKE_INDICES.Length; iter++) { @@ -553,6 +558,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory } } */ + bool wearableCacheValid = false; if (wearableCache == null) { @@ -577,10 +583,12 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory hits++; wearableCache[idx].TextureAsset.Temporary = true; wearableCache[idx].TextureAsset.Local = true; - cache.Store(wearableCache[idx].TextureAsset); + cache.Cache(wearableCache[idx].TextureAsset); + wearableCache[idx].TextureAsset = null; continue; } - if (cache.GetCached((wearableCache[idx].TextureID).ToString()) != null) + + if (cache.Check((wearableCache[idx].TextureID).ToString())) { hits++; continue; @@ -592,7 +600,9 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory wearableCacheValid = (wearableCacheValid && (hits >= AvatarAppearance.BAKE_INDICES.Length - 1)); if (wearableCacheValid) - m_log.Debug("[ValidateBakedCache] have valid local cache"); + { +// m_log.Debug("[ValidateBakedCache] have valid local cache"); + } else wearableCache[19].TextureAsset = null; // clear optional skirt } @@ -619,7 +629,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory { bool gotbacked = false; - m_log.Debug("[ValidateBakedCache] local cache invalid, checking bakedModule"); +// m_log.Debug("[ValidateBakedCache] local cache invalid, checking bakedModule"); try { bakedModuleCache = bakedModule.Get(sp.UUID); @@ -645,7 +655,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory wearableCache[j].TextureAsset = bakedModuleCache[i].TextureAsset; bakedModuleCache[i].TextureAsset.Temporary = true; bakedModuleCache[i].TextureAsset.Local = true; - cache.Store(bakedModuleCache[i].TextureAsset); + cache.Cache(bakedModuleCache[i].TextureAsset); } } gotbacked = true; @@ -677,6 +687,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory face.TextureID = wearableCache[idx].TextureID; hits++; + wearableCache[idx].TextureAsset = null; } } } @@ -686,7 +697,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory } // debug - m_log.DebugFormat("[ValidateBakedCache]: Completed texture check for {0} {1} with {2} hits", sp.Name, sp.UUID, hits); +// m_log.DebugFormat("[ValidateBakedCache]: Completed texture check for {0} {1} with {2} hits", sp.Name, sp.UUID, hits); /* for (int iter = 0; iter < AvatarAppearance.BAKE_INDICES.Length; iter++) { @@ -706,7 +717,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory return 0; int texturesRebaked = 0; -// IAssetCache cache = m_scene.RequestModuleInterface(); + IAssetCache cache = m_scene.RequestModuleInterface(); for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++) { @@ -722,18 +733,12 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory if (missingTexturesOnly) { - if (m_scene.AssetService.Get(face.TextureID.ToString()) != null) + if (cache != null && cache.Check(face.TextureID.ToString())) { continue; } else { - // On inter-simulator teleports, this occurs if baked textures are not being stored by the - // grid asset service (which means that they are not available to the new region and so have - // to be re-requested from the client). - // - // The only available core OpenSimulator behaviour right now - // is not to store these textures, temporarily or otherwise. m_log.DebugFormat( "[AVFACTORY]: Missing baked texture {0} ({1}) for {2}, requesting rebake.", face.TextureID, idx, sp.Name); diff --git a/OpenSim/Region/CoreModules/Avatar/BakedTextures/XBakesModule.cs b/OpenSim/Region/CoreModules/Avatar/BakedTextures/XBakesModule.cs index 27e84b0f13..cfa9581d82 100644 --- a/OpenSim/Region/CoreModules/Avatar/BakedTextures/XBakesModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/BakedTextures/XBakesModule.cs @@ -216,6 +216,8 @@ namespace OpenSim.Region.CoreModules.Avatar.BakedTextures rc.Request(reqStream, m_Auth); m_log.DebugFormat("[XBakes]: stored {0} textures for user {1}", numberWears, agentId); } + if(reqStream != null) + reqStream.Dispose(); }, null, "XBakesModule.Store" ); } diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs index 35b48d9924..772485cfeb 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs @@ -247,11 +247,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends { FriendInfo[] friends = GetFriendsFromCache(principalID); FriendInfo finfo = GetFriend(friends, friendID); - if (finfo != null) + if (finfo != null && finfo.TheirFlags != -1) { return finfo.TheirFlags; } - return 0; } @@ -512,18 +511,20 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends if (((fi.MyFlags & (int)FriendRights.CanSeeOnline) != 0) && (fi.TheirFlags != -1)) friendList.Add(fi); } + if(friendList.Count > 0) + { + Util.FireAndForget( + delegate + { +// m_log.DebugFormat( +// "[FRIENDS MODULE]: Notifying {0} friends of {1} of online status {2}", +// friendList.Count, agentID, online); - Util.FireAndForget( - delegate - { -// m_log.DebugFormat( -// "[FRIENDS MODULE]: Notifying {0} friends of {1} of online status {2}", -// friendList.Count, agentID, online); - - // Notify about this user status - StatusNotify(friendList, agentID, online); - }, null, "FriendsModule.StatusChange" - ); + // Notify about this user status + StatusNotify(friendList, agentID, online); + }, null, "FriendsModule.StatusChange" + ); + } } } @@ -552,6 +553,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends // We do this regrouping so that we can efficiently send a single request rather than one for each // friend in what may be a very large friends list. PresenceInfo[] friendSessions = PresenceService.GetAgents(remoteFriendStringIds.ToArray()); + if(friendSessions == null) + return; foreach (PresenceInfo friendSession in friendSessions) { @@ -752,7 +755,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends if (friend == null) return; - if((friend.TheirFlags & (int)FriendRights.CanSeeOnMap) == 0) + if(friend.TheirFlags == -1 || (friend.TheirFlags & (int)FriendRights.CanSeeOnMap) == 0) return; Scene hunterScene = (Scene)remoteClient.Scene; diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsRequestHandler.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsRequestHandler.cs index 81aa8829a4..091b1975e4 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsRequestHandler.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsRequestHandler.cs @@ -65,9 +65,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends protected override byte[] ProcessRequest( string path, Stream requestData, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { - StreamReader sr = new StreamReader(requestData); - string body = sr.ReadToEnd(); - sr.Close(); + string body; + using(StreamReader sr = new StreamReader(requestData)) + body = sr.ReadToEnd(); + body = body.Trim(); //m_log.DebugFormat("[XXX]: query String: {0}", body); diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs index 82154bcc9e..fae1e05349 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs @@ -214,7 +214,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends FriendInfo[] friends = GetFriendsFromCache(client.AgentId); foreach (FriendInfo f in friends) { - client.SendChangeUserRights(new UUID(f.Friend), client.AgentId, f.TheirFlags); + int rights = f.TheirFlags; + if(rights != -1 ) + client.SendChangeUserRights(new UUID(f.Friend), client.AgentId, rights); } } } diff --git a/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs b/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs index f699c0c889..6e6974a5c8 100644 --- a/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs @@ -59,21 +59,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods /// Special UUID for actions that apply to all agents private static readonly UUID ALL_AGENTS = new UUID("44e87126-e794-4ded-05b3-7c42da3d5cdb"); + private static readonly UUID UUID_GRID_GOD = new UUID("6571e388-6218-4574-87db-f9379718315e"); protected Scene m_scene; protected IDialogModule m_dialogModule; - protected IDialogModule DialogModule - { - get - { - if (m_dialogModule == null) - m_dialogModule = m_scene.RequestModuleInterface(); - - return m_dialogModule; - } - } - public void Initialise(IConfigSource source) { } @@ -97,6 +87,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods public void RegionLoaded(Scene scene) { + m_dialogModule = m_scene.RequestModuleInterface(); } public void Close() {} @@ -152,7 +143,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods if (god == null || god.ControllingClient.SessionId != godSessionID) return String.Empty; - KickUser(godID, agentID, kickFlags, Util.StringToBytes1024(reason)); + KickUser(godID, agentID, kickFlags, reason); } else { @@ -173,8 +164,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods sp.GrantGodlikePowers(token, godLike); - if (godLike && !sp.IsViewerUIGod && DialogModule != null) - DialogModule.SendAlertToUser(agentID, "Request for god powers denied"); + if (godLike && !sp.IsViewerUIGod && m_dialogModule != null) + m_dialogModule.SendAlertToUser(agentID, "Request for god powers denied"); + } + + public void KickUser(UUID godID, UUID agentID, uint kickflags, byte[] reason) + { + KickUser(godID, agentID, kickflags, Utils.BytesToString(reason)); } /// @@ -184,7 +180,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods /// the person that is being kicked /// Tells what to do to the user /// The message to send to the user after it's been turned into a field - public void KickUser(UUID godID, UUID agentID, uint kickflags, byte[] reason) + public void KickUser(UUID godID, UUID agentID, uint kickflags, string reason) { // assuming automatic god rights on this for fast griefing reaction // this is also needed for kick via message @@ -200,10 +196,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods if(agentID == ALL_AGENTS) { m_scene.ForEachRootScenePresence(delegate(ScenePresence p) + { + if (p.UUID != godID) { - if (p.UUID != godID && godlevel > p.GodController.GodLevel) + if(godlevel > p.GodController.GodLevel) doKickmodes(godID, p, kickflags, reason); - }); + else if(m_dialogModule != null) + m_dialogModule.SendAlertToUser(p.UUID, "Kick from " + godID.ToString() + " ignored, kick reason: " + reason); + } + }); return; } @@ -217,7 +218,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods m_log.DebugFormat("[GODS]: Sending nonlocal kill for agent {0}", agentID); transferModule.SendInstantMessage(new GridInstantMessage( m_scene, godID, "God", agentID, (byte)250, false, - Utils.BytesToString(reason), UUID.Zero, true, + reason, UUID.Zero, true, new Vector3(), new byte[] {(byte)kickflags}, true), delegate(bool success) {} ); } @@ -225,7 +226,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods } if (godlevel <= sp.GodController.GodLevel) // no god wars + { + if(m_dialogModule != null) + m_dialogModule.SendAlertToUser(sp.UUID, "Kick from " + godID.ToString() + " ignored, kick reason: " + reason); return; + } if(sp.UUID == godID) return; @@ -233,29 +238,34 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods doKickmodes(godID, sp, kickflags, reason); } - private void doKickmodes(UUID godID, ScenePresence sp, uint kickflags, byte[] reason) + private void doKickmodes(UUID godID, ScenePresence sp, uint kickflags, string reason) { switch (kickflags) { case 0: - KickPresence(sp, Utils.BytesToString(reason)); + KickPresence(sp, reason); break; case 1: sp.AllowMovement = false; - m_dialogModule.SendAlertToUser(sp.UUID, Utils.BytesToString(reason)); - m_dialogModule.SendAlertToUser(godID, "User Frozen"); + if(m_dialogModule != null) + { + m_dialogModule.SendAlertToUser(sp.UUID, reason); + m_dialogModule.SendAlertToUser(godID, "User Frozen"); + } break; case 2: sp.AllowMovement = true; - m_dialogModule.SendAlertToUser(sp.UUID, Utils.BytesToString(reason)); - m_dialogModule.SendAlertToUser(godID, "User Unfrozen"); + if(m_dialogModule != null) + { + m_dialogModule.SendAlertToUser(sp.UUID, reason); + m_dialogModule.SendAlertToUser(godID, "User Unfrozen"); + } break; default: break; } } - private void KickPresence(ScenePresence sp, string reason) { if(sp.IsDeleted || sp.IsChildAgent) @@ -264,6 +274,41 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods sp.Scene.CloseAgent(sp.UUID, true); } + public void GridKickUser(UUID agentID, string reason) + { + int godlevel = 240; // grid god default + + ScenePresence sp = m_scene.GetScenePresence(agentID); + if (sp == null || sp.IsChildAgent) + { + IMessageTransferModule transferModule = + m_scene.RequestModuleInterface(); + if (transferModule != null) + { + m_log.DebugFormat("[GODS]: Sending nonlocal kill for agent {0}", agentID); + transferModule.SendInstantMessage(new GridInstantMessage( + m_scene, UUID_GRID_GOD, "GRID", agentID, (byte)250, false, + reason, UUID.Zero, true, + new Vector3(), new byte[] {0}, true), + delegate(bool success) {} ); + } + return; + } + + if(sp.IsDeleted) + return; + + if (godlevel <= sp.GodController.GodLevel) // no god wars + { + if(m_dialogModule != null) + m_dialogModule.SendAlertToUser(sp.UUID, "GRID kick detected and ignored, kick reason: " + reason); + return; + } + + sp.ControllingClient.Kick(reason); + sp.Scene.CloseAgent(sp.UUID, true); + } + private void OnIncomingInstantMessage(GridInstantMessage msg) { if (msg.dialog == (uint)250) // Nonlocal kick @@ -273,7 +318,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods UUID godID = new UUID(msg.fromAgentID); uint kickMode = (uint)msg.binaryBucket[0]; - KickUser(godID, agentID, kickMode, Util.StringToBytes1024(reason)); + if(godID == UUID_GRID_GOD) + GridKickUser(agentID, reason); + else + KickUser(godID, agentID, kickMode, reason); } } } diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MuteListModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MuteListModule.cs index 2d571932a1..9cbfd4a03e 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MuteListModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MuteListModule.cs @@ -27,86 +27,99 @@ using System; using System.Collections.Generic; using System.Reflection; +using System.Text; using log4net; using Nini.Config; -using Mono.Addins; using OpenMetaverse; using OpenSim.Framework; using OpenSim.Framework.Servers; using OpenSim.Framework.Client; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; +using Mono.Addins; + +using OpenSim.Server.Base; +using OpenSim.Services.Interfaces; namespace OpenSim.Region.CoreModules.Avatar.InstantMessage { [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "MuteListModule")] public class MuteListModule : ISharedRegionModule { - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private static readonly ILog m_log = LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); - private bool enabled = true; - private List m_SceneList = new List(); - private string m_RestURL = String.Empty; + protected bool m_Enabled = false; + protected List m_SceneList = new List(); + protected IMuteListService m_service = null; + private IUserManagement m_userManagementModule; public void Initialise(IConfigSource config) { IConfig cnf = config.Configs["Messaging"]; if (cnf == null) - { - enabled = false; return; - } - if (cnf != null && cnf.GetString("MuteListModule", "None") != - "MuteListModule") - { - enabled = false; + if (cnf.GetString("MuteListModule", "None") != "MuteListModule") return; - } - m_RestURL = cnf.GetString("MuteListURL", ""); - if (m_RestURL == "") - { - m_log.Error("[MUTE LIST] Module was enabled, but no URL is given, disabling"); - enabled = false; - return; - } + m_Enabled = true; } public void AddRegion(Scene scene) { - if (!enabled) - return; - - lock (m_SceneList) - { - m_SceneList.Add(scene); - - scene.EventManager.OnNewClient += OnNewClient; - } } public void RegionLoaded(Scene scene) { + if (!m_Enabled) + return; + + IXfer xfer = scene.RequestModuleInterface(); + if (xfer == null) + { + m_log.ErrorFormat("[MuteListModule]: Xfer not availble in region {0}. Module Disabled", scene.Name); + m_Enabled = false; + return; + } + + IMuteListService srv = scene.RequestModuleInterface(); + if(srv == null) + { + m_log.ErrorFormat("[MuteListModule]: MuteListService not availble in region {0}. Module Disabled", scene.Name); + m_Enabled = false; + return; + } + + lock (m_SceneList) + { + if(m_service == null) + m_service = srv; + if(m_userManagementModule == null) + m_userManagementModule = scene.RequestModuleInterface(); + m_SceneList.Add(scene); + scene.EventManager.OnNewClient += OnNewClient; + } } public void RemoveRegion(Scene scene) { - if (!enabled) - return; - lock (m_SceneList) { - m_SceneList.Remove(scene); + if(m_SceneList.Contains(scene)) + { + m_SceneList.Remove(scene); + scene.EventManager.OnNewClient -= OnNewClient; + } } } public void PostInitialise() { - if (!enabled) + if (!m_Enabled) return; - m_log.Debug("[MUTE LIST] Mute list enabled"); + m_log.Debug("[MuteListModule]: enabled"); } public string Name @@ -118,27 +131,110 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage { get { return null; } } - + public void Close() { } + private bool IsForeign(IClientAPI client) + { + if(m_userManagementModule == null) + return false; // we can't check + + return !m_userManagementModule.IsLocalGridUser(client.AgentId); + } + private void OnNewClient(IClientAPI client) { client.OnMuteListRequest += OnMuteListRequest; + client.OnUpdateMuteListEntry += OnUpdateMuteListEntry; + client.OnRemoveMuteListEntry += OnRemoveMuteListEntry; } private void OnMuteListRequest(IClientAPI client, uint crc) { - m_log.DebugFormat("[MUTE LIST] Got mute list request for crc {0}", crc); - string filename = "mutes"+client.AgentId.ToString(); + if (!m_Enabled || IsForeign(client)) + { + if(crc == 0) + client.SendEmpytMuteList(); + else + client.SendUseCachedMuteList(); + return; + } IXfer xfer = client.Scene.RequestModuleInterface(); - if (xfer != null) + if (xfer == null) { - xfer.AddNewFile(filename, new Byte[0]); - client.SendMuteListUpdate(filename); + if(crc == 0) + client.SendEmpytMuteList(); + else + client.SendUseCachedMuteList(); + return; } + + Byte[] data = m_service.MuteListRequest(client.AgentId, crc); + if (data == null) + { + if(crc == 0) + client.SendEmpytMuteList(); + else + client.SendUseCachedMuteList(); + return; + } + + if (data.Length == 0) + { + client.SendEmpytMuteList(); + return; + } + + if (data.Length == 1) + { + if(crc == 0) + client.SendEmpytMuteList(); + else + client.SendUseCachedMuteList(); + return; + } + + string filename = "mutes" + client.AgentId.ToString(); + xfer.AddNewFile(filename, data); + client.SendMuteListUpdate(filename); + } + + private void OnUpdateMuteListEntry(IClientAPI client, UUID muteID, string muteName, int muteType, uint muteFlags) + { + if (!m_Enabled || IsForeign(client)) + return; + + UUID agentID = client.AgentId; + if(muteType == 1) // agent + { + if(agentID == muteID) + return; + if(m_SceneList[0].Permissions.IsAdministrator(muteID)) + { + OnMuteListRequest(client, 0); + return; + } + } + + MuteData mute = new MuteData(); + mute.AgentID = agentID; + mute.MuteID = muteID; + mute.MuteName = muteName; + mute.MuteType = muteType; + mute.MuteFlags = (int)muteFlags; + mute.Stamp = Util.UnixTimeSinceEpoch(); + + m_service.UpdateMute(mute); + } + + private void OnRemoveMuteListEntry(IClientAPI client, UUID muteID, string muteName) + { + if (!m_Enabled || IsForeign(client)) + return; + m_service.RemoveMute(client.AgentId, muteID, muteName); } } } diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs index 38383165d7..1e21b743bf 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs @@ -109,7 +109,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver /// /// Inventory nodes loaded from the iar. /// - protected HashSet m_loadedNodes = new HashSet(); + protected Dictionary m_loadedNodes = new Dictionary(); /// /// In order to load identically named folders, we need to keep track of the folders that we have already @@ -122,6 +122,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver /// after OSP resolution (since OSP creators are only stored in the item /// protected Dictionary m_creatorIdForAssetId = new Dictionary(); + protected Dictionary m_itemIDs = new Dictionary(); + protected List m_invLinks = new List(); + protected Dictionary m_invLinksFolders = new Dictionary(); public InventoryArchiveReadRequest( IInventoryService inv, IAssetService assets, IUserAccountService uacc, UserAccount userInfo, string invPath, string loadPath, bool merge) @@ -181,7 +184,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver /// returned /// /// Thrown if load fails. - public HashSet Execute() + public Dictionary Execute() { try { @@ -223,6 +226,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver } archive.Close(); + LoadInventoryLinks(); m_log.DebugFormat( "[INVENTORY ARCHIVER]: Successfully loaded {0} assets with {1} failures", @@ -271,7 +275,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver string iarPath, InventoryFolderBase rootDestFolder, Dictionary resolvedFolders, - HashSet loadedNodes) + Dictionary loadedNodes) { string iarPathExisting = iarPath; @@ -392,7 +396,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver string iarPathExisting, string iarPathToReplicate, Dictionary resolvedFolders, - HashSet loadedNodes) + Dictionary loadedNodes) { string[] rawDirsToCreate = iarPathToReplicate.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries); @@ -424,7 +428,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver resolvedFolders[iarPathExisting] = destFolder; if (0 == i) - loadedNodes.Add(destFolder); + loadedNodes[destFolder.ID] = destFolder; } } @@ -439,8 +443,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver { InventoryItemBase item = UserInventoryItemSerializer.Deserialize(data); + UUID oldID = item.ID; // Don't use the item ID that's in the file item.ID = UUID.Random(); + m_itemIDs[oldID] = item.ID; UUID ospResolvedId = OspResolver.ResolveOspa(item.CreatorId, m_UserAccountService); if (UUID.Zero != ospResolvedId) // The user exists in this grid @@ -457,7 +463,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver else if (string.IsNullOrEmpty(item.CreatorData)) { item.CreatorId = m_userInfo.PrincipalID.ToString(); -// item.CreatorIdAsUuid = new UUID(item.CreatorId); } item.Owner = m_userInfo.PrincipalID; @@ -470,10 +475,19 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver // FIXME: This relies on the items coming before the assets in the TAR file. Need to create stronger // checks for this, and maybe even an external tool for creating OARs which enforces this, rather than // relying on native tar tools. - m_creatorIdForAssetId[item.AssetID] = item.CreatorIdAsUuid; - - if (!m_InventoryService.AddItem(item)) - m_log.WarnFormat("[INVENTORY ARCHIVER]: Unable to save item {0} in folder {1}", item.Name, item.Folder); + if(item.AssetType == (int)AssetType.Link) + { + m_invLinks.Add(item); + if(!m_loadedNodes.ContainsKey(item.Folder) && !m_invLinksFolders.ContainsKey(item.Folder)) + m_invLinksFolders[item.Folder] = loadFolder; + return null; + } + else + { + m_creatorIdForAssetId[item.AssetID] = item.CreatorIdAsUuid; + if (!m_InventoryService.AddItem(item)) + m_log.WarnFormat("[INVENTORY ARCHIVER]: Unable to save item {0} in folder {1}", item.Name, item.Folder); + } return item; } @@ -504,56 +518,57 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver string rawUuid = filename.Remove(filename.Length - extension.Length); UUID assetId = new UUID(rawUuid); - if (ArchiveConstants.EXTENSION_TO_ASSET_TYPE.ContainsKey(extension)) - { - sbyte assetType = ArchiveConstants.EXTENSION_TO_ASSET_TYPE[extension]; - - if (assetType == (sbyte)AssetType.Unknown) - { - m_log.WarnFormat("[INVENTORY ARCHIVER]: Importing {0} byte asset {1} with unknown type", data.Length, assetId); - } - else if (assetType == (sbyte)AssetType.Object) - { - if (m_creatorIdForAssetId.ContainsKey(assetId)) - { - data = SceneObjectSerializer.ModifySerializedObject(assetId, data, - sog => { - bool modified = false; - - foreach (SceneObjectPart sop in sog.Parts) - { - if (string.IsNullOrEmpty(sop.CreatorData)) - { - sop.CreatorID = m_creatorIdForAssetId[assetId]; - modified = true; - } - } - - return modified; - }); - - if (data == null) - return false; - } - } - - //m_log.DebugFormat("[INVENTORY ARCHIVER]: Importing asset {0}, type {1}", uuid, assetType); - - AssetBase asset = new AssetBase(assetId, "From IAR", assetType, UUID.Zero.ToString()); - asset.Data = data; - - m_AssetService.Store(asset); - - return true; - } - else + if (!ArchiveConstants.EXTENSION_TO_ASSET_TYPE.ContainsKey(extension)) { m_log.ErrorFormat( "[INVENTORY ARCHIVER]: Tried to dearchive data with path {0} with an unknown type extension {1}", assetPath, extension); - return false; } + + sbyte assetType = ArchiveConstants.EXTENSION_TO_ASSET_TYPE[extension]; + if (assetType == (sbyte)AssetType.Unknown) + { + m_log.WarnFormat("[INVENTORY ARCHIVER]: Importing {0} byte asset {1} with unknown type", data.Length, assetId); + return false; + } + + if(assetType == (sbyte)AssetType.Object) + { + UUID owner = m_userInfo.PrincipalID; + bool doCreatorID = m_creatorIdForAssetId.ContainsKey(assetId); + + data = SceneObjectSerializer.ModifySerializedObject(assetId, data, + sog => + { + foreach(SceneObjectPart sop in sog.Parts) + { + sop.OwnerID = owner; + if(doCreatorID && string.IsNullOrEmpty(sop.CreatorData)) + sop.CreatorID = m_creatorIdForAssetId[assetId]; + + foreach(TaskInventoryItem it in sop.Inventory.GetInventoryItems()) + { + it.OwnerID = owner; + if(string.IsNullOrEmpty(it.CreatorData) && m_creatorIdForAssetId.ContainsKey(it.AssetID)) + it.CreatorID = m_creatorIdForAssetId[it.AssetID]; + } + } + return true; + }); + + if(data == null) + return false; + } + + //m_log.DebugFormat("[INVENTORY ARCHIVER]: Importing asset {0}, type {1}", uuid, assetType); + + AssetBase asset = new AssetBase(assetId, "From IAR", assetType, UUID.Zero.ToString()); + asset.Data = data; + + m_AssetService.Store(asset); + + return true; } /// @@ -621,14 +636,38 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver // If we aren't loading the folder containing the item then well need to update the // viewer separately for that item. - if (!m_loadedNodes.Contains(foundFolder)) - m_loadedNodes.Add(item); + if (!m_loadedNodes.ContainsKey(foundFolder.ID)) + m_loadedNodes[foundFolder.ID] = item; } } m_inventoryNodesLoaded = true; } + private void LoadInventoryLinks() + { + foreach(InventoryItemBase it in m_invLinks) + { + UUID target = it.AssetID; + if(m_itemIDs.ContainsKey(target)) + { + it.AssetID = m_itemIDs[target]; + if(!m_InventoryService.AddItem(it)) + m_log.WarnFormat("[INVENTORY ARCHIVER]: Unable to save item {0} in folder {1}",it.Name,it.Folder); + else + { + m_successfulItemRestores++; + UUID fid = it.Folder; + if (!m_loadedNodes.ContainsKey(fid) && m_invLinksFolders.ContainsKey(fid)) + m_loadedNodes[fid] = m_invLinksFolders[fid]; + } + } + } + + m_itemIDs.Clear(); + m_invLinks.Clear(); + m_invLinksFolders.Clear(); + } /// /// Load asset file /// diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs index f002ad7a40..ad46107768 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs @@ -218,10 +218,39 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver // Count inventory items (different to asset count) CountItems++; - + // Don't chase down link asset items as they actually point to their target item IDs rather than an asset if (SaveAssets && itemAssetType != AssetType.Link && itemAssetType != AssetType.LinkFolder) + { + int curErrorCntr = m_assetGatherer.ErrorCount; + int possible = m_assetGatherer.possibleNotAssetCount; m_assetGatherer.AddForInspection(inventoryItem.AssetID); + m_assetGatherer.GatherAll(); + curErrorCntr = m_assetGatherer.ErrorCount - curErrorCntr; + possible = m_assetGatherer.possibleNotAssetCount - possible; + + if(curErrorCntr > 0 || possible > 0) + { + string spath; + int indx = path.IndexOf("__"); + if(indx > 0) + spath = path.Substring(0,indx); + else + spath = path; + + if(curErrorCntr > 0) + { + m_log.ErrorFormat("[INVENTORY ARCHIVER Warning]: item {0} '{1}', type {2}, in '{3}', contains {4} references to missing or damaged assets", + inventoryItem.ID, inventoryItem.Name, itemAssetType.ToString(), spath, curErrorCntr); + if(possible > 0) + m_log.WarnFormat("[INVENTORY ARCHIVER Warning]: item also contains {0} references that may be to missing or damaged assets or not a problem", possible); + } + else if(possible > 0) + { + m_log.WarnFormat("[INVENTORY ARCHIVER Warning]: item {0} '{1}', type {2}, in '{3}', contains {4} references that may be to missing or damaged assets or not a problem", inventoryItem.ID, inventoryItem.Name, itemAssetType.ToString(), spath, possible); + } + } + } } /// @@ -381,6 +410,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver string errorMessage = string.Format("Aborted save. Could not find inventory path {0}", m_invPath); Exception e = new InventoryArchiverException(errorMessage); m_module.TriggerInventoryArchiveSaved(m_id, false, m_userInfo, m_invPath, m_saveStream, e, 0, 0); + if(m_saveStream != null && m_saveStream.CanWrite) + m_saveStream.Close(); throw e; } @@ -420,17 +451,20 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver { m_assetGatherer.GatherAll(); - m_log.DebugFormat( - "[INVENTORY ARCHIVER]: Saving {0} assets for items", m_assetGatherer.GatheredUuids.Count); + int errors = m_assetGatherer.FailedUUIDs.Count; - AssetsRequest ar - = new AssetsRequest( + m_log.DebugFormat( + "[INVENTORY ARCHIVER]: The items to save reference {0} possible assets", m_assetGatherer.GatheredUuids.Count + errors); + if(errors > 0) + m_log.DebugFormat("[INVENTORY ARCHIVER]: {0} of these have problems or are not assets and will be ignored", errors); + + AssetsRequest ar = new AssetsRequest( new AssetsArchiver(m_archiveWriter), - m_assetGatherer.GatheredUuids, m_scene.AssetService, + m_assetGatherer.GatheredUuids, m_assetGatherer.FailedUUIDs.Count, + m_scene.AssetService, m_scene.UserAccountService, m_scene.RegionInfo.ScopeID, options, ReceivedAllAssets); - - WorkManager.RunInThread(o => ar.Execute(), null, string.Format("AssetsRequest ({0})", m_scene.Name)); + ar.Execute(); } else { diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs index be59eb5957..d50ebf5bb5 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs @@ -218,7 +218,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver // { try { - new InventoryArchiveWriteRequest(id, this, m_aScene, userInfo, invPath, saveStream).Execute(options, UserAccountService); + InventoryArchiveWriteRequest iarReq = new InventoryArchiveWriteRequest(id, this, m_aScene, userInfo, invPath, saveStream); + iarReq.Execute(options, UserAccountService); } catch (EntryPointNotFoundException e) { @@ -261,7 +262,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver // { try { - new InventoryArchiveWriteRequest(id, this, m_aScene, userInfo, invPath, savePath).Execute(options, UserAccountService); + InventoryArchiveWriteRequest iarReq = new InventoryArchiveWriteRequest(id, this, m_aScene, userInfo, invPath, savePath); + iarReq.Execute(options, UserAccountService); } catch (EntryPointNotFoundException e) { @@ -591,7 +593,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver /// Notify the client of loaded nodes if they are logged in /// /// Can be empty. In which case, nothing happens - private void UpdateClientWithLoadedNodes(UserAccount userInfo, HashSet loadedNodes) + private void UpdateClientWithLoadedNodes(UserAccount userInfo, Dictionary loadedNodes) { if (loadedNodes.Count == 0) return; @@ -602,7 +604,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver if (user != null && !user.IsChildAgent) { - foreach (InventoryNodeBase node in loadedNodes) + foreach (InventoryNodeBase node in loadedNodes.Values) { // m_log.DebugFormat( // "[INVENTORY ARCHIVER]: Notifying {0} of loaded inventory node {1}", diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveLoadPathTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveLoadPathTests.cs index f559c2e62c..86eca17d3b 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveLoadPathTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveLoadPathTests.cs @@ -212,7 +212,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene); Dictionary foldersCreated = new Dictionary(); - HashSet nodesLoaded = new HashSet(); + Dictionary nodesLoaded = new Dictionary(); string folder1Name = "1"; string folder2aName = "2a"; @@ -293,7 +293,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests new InventoryArchiveReadRequest(UUID.Random(), null, scene.InventoryService, scene.AssetService, scene.UserAccountService, ua1, null, (Stream)null, false) .ReplicateArchivePathToUserInventory( itemArchivePath, scene.InventoryService.GetRootFolder(ua1.PrincipalID), - new Dictionary(), new HashSet()); + new Dictionary(), new Dictionary()); List folder1PostCandidates = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, ua1.PrincipalID, folder1ExistingName); @@ -344,7 +344,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests new InventoryArchiveReadRequest(UUID.Random(), null, scene.InventoryService, scene.AssetService, scene.UserAccountService, ua1, folder1ExistingName, (Stream)null, true) .ReplicateArchivePathToUserInventory( itemArchivePath, scene.InventoryService.GetRootFolder(ua1.PrincipalID), - new Dictionary(), new HashSet()); + new Dictionary(), new Dictionary()); List folder1PostCandidates = InventoryArchiveUtils.FindFoldersByPath(scene.InventoryService, ua1.PrincipalID, folder1ExistingName); diff --git a/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs b/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs index 89e30206f1..22984ef40d 100644 --- a/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/UserProfiles/UserProfileModule.cs @@ -71,6 +71,9 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles ExpiringCache m_profilesCache = new ExpiringCache(); IAssetCache m_assetCache; + static readonly UUID m_MrOpenSimID = new UUID("11111111-1111-0000-0000-000100bba000"); + static readonly DateTime m_MrOpenSimBorn = new DateTime(2007,1,1,0,0,0,DateTimeKind.Utc); + private JsonRpcRequestManager rpc = new JsonRpcRequestManager(); private bool m_allowUserProfileWebURLs = true; @@ -355,6 +358,12 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles if(!UUID.TryParse(args[0], out targetID) || targetID == UUID.Zero) return; + if (targetID == m_MrOpenSimID) + { + remoteClient.SendAvatarClassifiedReply(targetID, classifieds); + return; + } + ScenePresence p = FindPresence(targetID); if (p != null && p.IsNPC) { @@ -750,6 +759,12 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles Dictionary picks = new Dictionary(); + if (targetId == m_MrOpenSimID) + { + remoteClient.SendAvatarPicksReply(targetId, picks); + return; + } + ScenePresence p = FindPresence(targetId); if (p != null && p.IsNPC) { @@ -1164,6 +1179,9 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles /// public void NotesUpdate(IClientAPI remoteClient, UUID queryTargetID, string queryNotes) { + if (queryTargetID == m_MrOpenSimID) + return; + ScenePresence p = FindPresence(queryTargetID); if (p != null && p.IsNPC) { @@ -1328,6 +1346,15 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles return; } + if (avatarID == m_MrOpenSimID) + { + remoteClient.SendAvatarProperties(avatarID, "Creator of OpenSimulator shared assets library", m_MrOpenSimBorn.ToString(), + Utils.StringToBytes("System agent"), "MrOpenSim has no life", 0x10, + UUID.Zero, UUID.Zero, "", UUID.Zero); + remoteClient.SendAvatarInterestsReply(avatarID, 0, "", + 0, "Getting into trouble", "Droidspeak"); + return; + } ScenePresence p = FindPresence(avatarID); if (p != null && p.IsNPC) { @@ -1839,12 +1866,12 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles webRequest.ContentType = "application/json-rpc"; webRequest.Method = "POST"; - using(Stream dataStream = webRequest.GetRequestStream()) - dataStream.Write(content,0,content.Length); - WebResponse webResponse = null; try { + using(Stream dataStream = webRequest.GetRequestStream()) + dataStream.Write(content,0,content.Length); + webResponse = webRequest.GetResponse(); } catch (WebException e) @@ -1920,12 +1947,12 @@ namespace OpenSim.Region.CoreModules.Avatar.UserProfiles webRequest.ContentType = "application/json-rpc"; webRequest.Method = "POST"; - using(Stream dataStream = webRequest.GetRequestStream()) - dataStream.Write(content,0,content.Length); - WebResponse webResponse = null; try { + using(Stream dataStream = webRequest.GetRequestStream()) + dataStream.Write(content,0,content.Length); + webResponse = webRequest.GetResponse(); } catch (WebException e) diff --git a/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs b/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs index 292099d864..c0afe7c49d 100644 --- a/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs +++ b/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs @@ -142,9 +142,9 @@ namespace OpenSim.Region.CoreModules.Framework if (capsObjectPath == oldCaps.CapsObjectPath) { - m_log.WarnFormat( - "[CAPS]: Reusing caps for agent {0} in region {1}. Old caps path {2}, new caps path {3}. ", - agentId, m_scene.RegionInfo.RegionName, oldCaps.CapsObjectPath, capsObjectPath); +// m_log.WarnFormat( +// "[CAPS]: Reusing caps for agent {0} in region {1}. Old caps path {2}, new caps path {3}. ", +// agentId, m_scene.RegionInfo.RegionName, oldCaps.CapsObjectPath, capsObjectPath); return; } else diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 92485a130e..e1145a11d0 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -157,7 +157,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer m_idCache = new ExpiringCache(); m_bannedRegions.Add(pAgentID, m_idCache, TimeSpan.FromSeconds(newTime)); } - m_idCache.Add(pRegionHandle, DateTime.UtcNow + TimeSpan.FromSeconds(extendTime), TimeSpan.FromSeconds(extendTime)); + m_idCache.Add(pRegionHandle, DateTime.UtcNow + TimeSpan.FromSeconds(extendTime), extendTime); } // Remove the agent from the region's banned list @@ -371,7 +371,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer teleportFlags |= (uint)TeleportFlags.Godlike; } - if (!sp.Scene.Permissions.CanTeleport(sp.UUID)) + else if (!sp.Scene.Permissions.CanTeleport(sp.UUID)) return; string destinationRegionName = "(not found)"; @@ -391,17 +391,27 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer try { - // Reset animations; the viewer does that in teleports. - sp.Animator.ResetAnimations(); if (regionHandle == sp.Scene.RegionInfo.RegionHandle) { + if(!sp.AllowMovement) + { + sp.ControllingClient.SendTeleportFailed("You are frozen"); + m_entityTransferStateMachine.ResetFromTransit(sp.UUID); + return; + } + + // Reset animations; the viewer does that in teleports. + sp.Animator.ResetAnimations(); destinationRegionName = sp.Scene.RegionInfo.RegionName; TeleportAgentWithinRegion(sp, position, lookAt, teleportFlags); } else // Another region possibly in another simulator { + // Reset animations; the viewer does that in teleports. + sp.Animator.ResetAnimations(); + GridRegion finalDestination = null; try { @@ -417,12 +427,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer } catch (Exception e) { + m_log.ErrorFormat( "[ENTITY TRANSFER MODULE]: Exception on teleport of {0} from {1}@{2} to {3}@{4}: {5}{6}", sp.Name, sp.AbsolutePosition, sp.Scene.RegionInfo.RegionName, position, destinationRegionName, e.Message, e.StackTrace); - - sp.ControllingClient.SendTeleportFailed("Internal error"); + if(sp != null && sp.ControllingClient != null && !sp.IsDeleted) + sp.ControllingClient.SendTeleportFailed("Internal error"); } finally { @@ -527,15 +538,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { string homeURI = Scene.GetAgentHomeURI(sp.ControllingClient.AgentId); - string message; - finalDestination = GetFinalDestination(reg, sp.ControllingClient.AgentId, homeURI, out message); + string reason = String.Empty; + finalDestination = GetFinalDestination(reg, sp.ControllingClient.AgentId, homeURI, out reason); if (finalDestination == null) { m_log.WarnFormat( "{0} Final destination is having problems. Unable to teleport {1} {2}: {3}", - LogHeader, sp.Name, sp.UUID, message); + LogHeader, sp.Name, sp.UUID, reason); - sp.ControllingClient.SendTeleportFailed(message); + sp.ControllingClient.SendTeleportFailed(reason); return; } @@ -548,17 +559,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return; } - // Validate assorted conditions - string reason = string.Empty; if (!ValidateGenericConditions(sp, reg, finalDestination, teleportFlags, out reason)) { sp.ControllingClient.SendTeleportFailed(reason); return; } - if (message != null) - sp.ControllingClient.SendAgentAlertMessage(message, true); - // // This is it // @@ -735,8 +741,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer IPEndPoint endPoint = finalDestination.ExternalEndPoint; if (endPoint == null || endPoint.Address == null) { - sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down"); - + sp.ControllingClient.SendTeleportFailed("Could not resolve destination Address"); return; } @@ -776,30 +781,22 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer else if (sp.Flying) teleportFlags |= (uint)TeleportFlags.IsFlying; + sp.IsInLocalTransit = finalDestination.RegionLocY != 0; // HG sp.IsInTransit = true; + if (DisableInterRegionTeleportCancellation) teleportFlags |= (uint)TeleportFlags.DisableCancel; // At least on LL 3.3.4, this is not strictly necessary - a teleport will succeed without sending this to // the viewer. However, it might mean that the viewer does not see the black teleport screen (untested). sp.ControllingClient.SendTeleportStart(teleportFlags); - - // the avatar.Close below will clear the child region list. We need this below for (possibly) - // closing the child agents, so save it here (we need a copy as it is Clear()-ed). - //List childRegions = avatar.KnownRegionHandles; - // Compared to ScenePresence.CrossToNewRegion(), there's no obvious code to handle a teleport - // failure at this point (unlike a border crossing failure). So perhaps this can never fail - // once we reach here... - //avatar.Scene.RemoveCapsHandler(avatar.UUID); - + AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode); AgentCircuitData agentCircuit = sp.ControllingClient.RequestClientInfo(); agentCircuit.startpos = position; agentCircuit.child = true; -// agentCircuit.Appearance = sp.Appearance; -// agentCircuit.Appearance = new AvatarAppearance(sp.Appearance, true, false); agentCircuit.Appearance = new AvatarAppearance(); agentCircuit.Appearance.AvatarHeight = sp.Appearance.AvatarHeight; @@ -813,8 +810,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer agentCircuit.Id0 = currentAgentCircuit.Id0; } - IClientIPEndpoint ipepClient; - uint newRegionX, newRegionY, oldRegionX, oldRegionY; Util.RegionHandleToRegionLoc(destinationHandle, out newRegionX, out newRegionY); Util.RegionHandleToRegionLoc(sourceRegion.RegionHandle, out oldRegionX, out oldRegionY); @@ -833,13 +828,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer finalDestination.RegionName, newRegionX, newRegionY,newSizeX, newSizeY, sp.Name, Scene.Name); //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Creating agent..."); - #region IP Translation for NAT - // Uses ipepClient above - if (sp.ClientView.TryGet(out ipepClient)) - { - endPoint.Address = NetworkUtil.GetIPFor(ipepClient.EndPoint, endPoint.Address); - } - #endregion agentCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath(); } else @@ -867,6 +855,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer sp.Name, Scene.Name, finalDestination.RegionName); string capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); + List childRegionsToClose = sp.GetChildAgentsToClose(destinationHandle, finalDestination.RegionSizeX, finalDestination.RegionSizeY); + if(agentCircuit.ChildrenCapSeeds != null) + { + foreach(ulong handler in childRegionsToClose) + { + agentCircuit.ChildrenCapSeeds.Remove(handler); + } + } // Let's create an agent there if one doesn't exist yet. // NOTE: logout will always be false for a non-HG teleport. @@ -952,7 +948,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer agent.Position = agentCircuit.startpos; SetCallbackURL(agent, sp.Scene.RegionInfo); - // We will check for an abort before UpdateAgent since UpdateAgent will require an active viewer to // establish th econnection to the destination which makes it return true. if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting) @@ -1051,7 +1046,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return; } - /* // TODO: This may be 0.6. Check if still needed // For backwards compatibility @@ -1065,7 +1059,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp); - sp.CloseChildAgents(logout, destinationHandle, finalDestination.RegionSizeX, finalDestination.RegionSizeY); + if(logout) + sp.closeAllChildAgents(); + else + sp.CloseChildAgents(childRegionsToClose); // call HG hook AgentHasMovedAway(sp, logout); @@ -1091,9 +1088,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // This sleep can be increased if necessary. However, whilst it's active, // an agent cannot teleport back to this region if it has teleported away. Thread.Sleep(2000); -// if (m_eqModule != null && !sp.DoNotCloseAfterTeleport) -// m_eqModule.DisableSimulator(sourceRegionHandle,sp.UUID); - Thread.Sleep(500); sp.Scene.CloseAgent(sp.UUID, false); } sp.IsInTransit = false; @@ -1103,7 +1097,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer IPEndPoint endPoint, uint teleportFlags, bool OutSideViewRange, EntityTransferContext ctx, out string reason) { ulong destinationHandle = finalDestination.RegionHandle; - AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode); + + List childRegionsToClose = sp.GetChildAgentsToClose(destinationHandle, finalDestination.RegionSizeX, finalDestination.RegionSizeY); + + if(agentCircuit.ChildrenCapSeeds != null) + { + foreach(ulong handler in childRegionsToClose) + { + agentCircuit.ChildrenCapSeeds.Remove(handler); + } + } string capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath);; @@ -1175,6 +1178,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer agent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY; agent.SenderWantsToWaitForRoot = true; + //SetCallbackURL(agent, sp.Scene.RegionInfo); // Reset the do not close flag. This must be done before the destination opens child connections (here @@ -1203,20 +1207,17 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer "[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1}. Keeping avatar in {2}", sp.Name, finalDestination.RegionName, sp.Scene.Name); - Fail(sp, finalDestination, logout, currentAgentCircuit.SessionID.ToString(), "Connection between viewer and destination region could not be established."); + Fail(sp, finalDestination, logout, agentCircuit.SessionID.ToString(), "Connection between viewer and destination region could not be established."); sp.IsInTransit = false; return; } m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp); - // Need to signal neighbours whether child agents may need closing irrespective of whether this - // one needed closing. We also need to close child agents as quickly as possible to avoid complicated - // race conditions with rapid agent releporting (e.g. from A1 to a non-neighbour B, back - // to a neighbour A2 then off to a non-neighbour C). Closing child agents any later requires complex - // distributed checks to avoid problems in rapid reteleporting scenarios and where child agents are - // abandoned without proper close by viewer but then re-used by an incoming connection. - sp.CloseChildAgents(logout, destinationHandle, finalDestination.RegionSizeX, finalDestination.RegionSizeY); + if(logout) + sp.closeAllChildAgents(); + else + sp.CloseChildAgents(childRegionsToClose); sp.HasMovedAway(!(OutSideViewRange || logout)); @@ -1243,9 +1244,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // IN THE AVIE BEING PLACED IN INFINITY FOR A COUPLE OF SECONDS. Thread.Sleep(15000); -// if (m_eqModule != null && !sp.DoNotCloseAfterTeleport) -// m_eqModule.DisableSimulator(sourceRegionHandle,sp.UUID); -// Thread.Sleep(1000); // OK, it got this agent. Let's close everything // If we shouldn't close the agent due to some other region renewing the connection @@ -1255,13 +1253,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer sp.Scene.CloseAgent(sp.UUID, false); } -/* - else - { - // now we have a child agent in this region. - sp.Reset(); - } - */ sp.IsInTransit = false; } @@ -1488,9 +1479,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // Given a position relative to the current region and outside of it - // find the new region that the point is actually in. - // returns 'null' if new region not found or if information - // and new position relative to it + // find the new region that the point is actually in + // returns 'null' if new region not found or if agent as no access + // else also returns new target position in the new region local coords // now only works for crossings public GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, @@ -1509,15 +1500,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // Call the grid service to lookup the region containing the new position. GridRegion neighbourRegion = GetRegionContainingWorldLocation( scene.GridService, scene.RegionInfo.ScopeID, - presenceWorldX, presenceWorldY, - Math.Max(scene.RegionInfo.RegionSizeX, scene.RegionInfo.RegionSizeY)); + presenceWorldX, presenceWorldY); if (neighbourRegion == null) - { return null; - } + if (m_bannedRegionCache.IfBanned(neighbourRegion.RegionHandle, agentID)) { + failureReason = "Access Denied or Temporary not possible"; return null; } @@ -1529,13 +1519,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer pos.Z); string homeURI = scene.GetAgentHomeURI(agentID); - + if (!scene.SimulationService.QueryAccess( neighbourRegion, agentID, homeURI, false, newpos, scene.GetFormatsOffered(), ctx, out failureReason)) { // remember the fail m_bannedRegionCache.Add(neighbourRegion.RegionHandle, agentID); + if(String.IsNullOrWhiteSpace(failureReason)) + failureReason = "Access Denied"; return null; } @@ -1544,6 +1536,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer public bool Cross(ScenePresence agent, bool isFlying) { + agent.IsInLocalTransit = true; agent.IsInTransit = true; CrossAsyncDelegate d = CrossAsync; d.BeginInvoke(agent, isFlying, CrossCompleted, d); @@ -1555,13 +1548,17 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer CrossAsyncDelegate icon = (CrossAsyncDelegate)iar.AsyncState; ScenePresence agent = icon.EndInvoke(iar); - m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Crossing agent {0} {1} completed.", agent.Firstname, agent.Lastname); + if(agent == null || agent.IsDeleted) + return; if(!agent.IsChildAgent) { // crossing failed agent.CrossToNewRegionFail(); } + else + m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Crossing agent {0} {1} completed.", agent.Firstname, agent.Lastname); + agent.IsInTransit = false; } @@ -1580,7 +1577,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer ctx, out newpos, out failureReason); if (neighbourRegion == null) { - if (failureReason != String.Empty) + if (!agent.IsDeleted && failureReason != String.Empty && agent.ControllingClient != null) agent.ControllingClient.SendAlertMessage(failureReason); return agent; } @@ -1662,7 +1659,73 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer icon.EndInvoke(iar); } + public bool CrossAgentCreateFarChild(ScenePresence agent, GridRegion neighbourRegion, Vector3 pos, EntityTransferContext ctx) + { + ulong regionhandler = neighbourRegion.RegionHandle; + if(agent.knowsNeighbourRegion(regionhandler)) + return true; + + string reason; + ulong currentRegionHandler = agent.Scene.RegionInfo.RegionHandle; + GridRegion source = new GridRegion(agent.Scene.RegionInfo); + + AgentCircuitData currentAgentCircuit = + agent.Scene.AuthenticateHandler.GetAgentCircuitData(agent.ControllingClient.CircuitCode); + AgentCircuitData agentCircuit = agent.ControllingClient.RequestClientInfo(); + agentCircuit.startpos = pos; + agentCircuit.child = true; + + agentCircuit.Appearance = new AvatarAppearance(); + agentCircuit.Appearance.AvatarHeight = agent.Appearance.AvatarHeight; + + if (currentAgentCircuit != null) + { + agentCircuit.ServiceURLs = currentAgentCircuit.ServiceURLs; + agentCircuit.IPAddress = currentAgentCircuit.IPAddress; + agentCircuit.Viewer = currentAgentCircuit.Viewer; + agentCircuit.Channel = currentAgentCircuit.Channel; + agentCircuit.Mac = currentAgentCircuit.Mac; + agentCircuit.Id0 = currentAgentCircuit.Id0; + } + + agentCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath(); + agent.AddNeighbourRegion(neighbourRegion, agentCircuit.CapsPath); + + IPEndPoint endPoint = neighbourRegion.ExternalEndPoint; + if(endPoint == null) + { + m_log.DebugFormat("CrossAgentCreateFarChild failed to resolve neighbour address {0}", neighbourRegion.ExternalHostName); + return false; + } + if (!Scene.SimulationService.CreateAgent(source, neighbourRegion, agentCircuit, (int)TeleportFlags.Default, ctx, out reason)) + { + agent.RemoveNeighbourRegion(regionhandler); + return false; + } + + string capsPath = neighbourRegion.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); + int newSizeX = neighbourRegion.RegionSizeX; + int newSizeY = neighbourRegion.RegionSizeY; + + if (m_eqModule != null) + { + m_log.DebugFormat("{0} {1} is sending {2} EnableSimulator for neighbour region {3}(loc=<{4},{5}>,siz=<{6},{7}>) " + + "and EstablishAgentCommunication with seed cap {8}", LogHeader, + source.RegionName, agent.Name, + neighbourRegion.RegionName, neighbourRegion.RegionLocX, neighbourRegion.RegionLocY, newSizeX, newSizeY , capsPath); + + m_eqModule.EnableSimulator(regionhandler, + endPoint, agent.UUID, newSizeX, newSizeY); + m_eqModule.EstablishAgentCommunication(agent.UUID, endPoint, capsPath, + regionhandler, newSizeX, newSizeY); + } + else + { + agent.ControllingClient.InformClientOfNeighbour(regionhandler, endPoint); + } + return true; + } /// /// This Closes child agents on neighbouring regions @@ -1683,39 +1746,51 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return agent; } - m_entityTransferStateMachine.SetInTransit(agent.UUID); - agent.RemoveFromPhysicalScene(); - - if (!CrossAgentIntoNewRegionMain(agent, pos, neighbourRegion, isFlying, ctx)) + IPEndPoint endpoint = neighbourRegion.ExternalEndPoint; + if(endpoint == null) { - m_log.DebugFormat("{0}: CrossAgentToNewRegionAsync: cross main failed. Resetting transfer state", LogHeader); - m_entityTransferStateMachine.ResetFromTransit(agent.UUID); + m_log.DebugFormat("{0}: CrossAgentToNewRegionAsync: failed to resolve neighbour address {0} ",neighbourRegion.ExternalHostName); return agent; } - CrossAgentToNewRegionPost(agent, pos, neighbourRegion, isFlying, ctx); + m_entityTransferStateMachine.SetInTransit(agent.UUID); + agent.RemoveFromPhysicalScene(); + + if (!CrossAgentIntoNewRegionMain(agent, pos, neighbourRegion, endpoint, isFlying, ctx)) + { + m_log.DebugFormat("{0}: CrossAgentToNewRegionAsync: cross main failed. Resetting transfer state", LogHeader); + m_entityTransferStateMachine.ResetFromTransit(agent.UUID); + } } catch (Exception e) { m_log.Error(string.Format("{0}: CrossAgentToNewRegionAsync: failed with exception ", LogHeader), e); } - return agent; } - public bool CrossAgentIntoNewRegionMain(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, bool isFlying, EntityTransferContext ctx) + public bool CrossAgentIntoNewRegionMain(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, + IPEndPoint endpoint, bool isFlying, EntityTransferContext ctx) { int ts = Util.EnvironmentTickCount(); + bool sucess = true; + string reason = String.Empty; + List childRegionsToClose = null; try { AgentData cAgent = new AgentData(); agent.CopyTo(cAgent,true); -// agent.Appearance.WearableCacheItems = null; - cAgent.Position = pos; cAgent.ChildrenCapSeeds = agent.KnownRegions; + childRegionsToClose = agent.GetChildAgentsToClose(neighbourRegion.RegionHandle, neighbourRegion.RegionSizeX, neighbourRegion.RegionSizeY); + if(cAgent.ChildrenCapSeeds != null) + { + foreach(ulong regh in childRegionsToClose) + cAgent.ChildrenCapSeeds.Remove(regh); + } + if (isFlying) cAgent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY; @@ -1725,24 +1800,31 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // Beyond this point, extra cleanup is needed beyond removing transit state m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.Transferring); - if (!agent.Scene.SimulationService.UpdateAgent(neighbourRegion, cAgent, ctx)) + if (sucess && !agent.Scene.SimulationService.UpdateAgent(neighbourRegion, cAgent, ctx)) + { + sucess = false; + reason = "agent update failed"; + } + + if(!sucess) { // region doesn't take it m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp); m_log.WarnFormat( - "[ENTITY TRANSFER MODULE]: Region {0} would not accept update for agent {1} on cross attempt. Returning to original region.", - neighbourRegion.RegionName, agent.Name); + "[ENTITY TRANSFER MODULE]: agent {0} crossing to {1} failed: {2}", + agent.Name, neighbourRegion.RegionName, reason); ReInstantiateScripts(agent); if(agent.ParentID == 0 && agent.ParentUUID == UUID.Zero) + { agent.AddToPhysicalScene(isFlying); + } return false; } m_log.DebugFormat("[CrossAgentIntoNewRegionMain] ok, time {0}ms",Util.EnvironmentTickCountSubtract(ts)); - } catch (Exception e) { @@ -1754,19 +1836,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return false; } - return true; - } - - public void CrossAgentToNewRegionPost(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, - bool isFlying, EntityTransferContext ctx) - { - string agentcaps; if (!agent.KnownRegions.TryGetValue(neighbourRegion.RegionHandle, out agentcaps)) { m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: No ENTITY TRANSFER MODULE information for region handle {0}, exiting CrossToNewRegion.", neighbourRegion.RegionHandle); - return; + return false; } // No turning back @@ -1777,21 +1852,22 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, agent.UUID); - Vector3 vel2 = new Vector3(agent.Velocity.X, agent.Velocity.Y, 0); + Vector3 vel2 = Vector3.Zero; + if((agent.crossingFlags & 2) != 0) + vel2 = new Vector3(agent.Velocity.X, agent.Velocity.Y, 0); if (m_eqModule != null) { m_eqModule.CrossRegion( neighbourRegion.RegionHandle, pos, vel2 /* agent.Velocity */, - neighbourRegion.ExternalEndPoint, - capsPath, agent.UUID, agent.ControllingClient.SessionId, + endpoint, capsPath, agent.UUID, agent.ControllingClient.SessionId, neighbourRegion.RegionSizeX, neighbourRegion.RegionSizeY); } else { m_log.ErrorFormat("{0} Using old CrossRegion packet. Varregion will not work!!", LogHeader); - agent.ControllingClient.CrossRegion(neighbourRegion.RegionHandle, pos, agent.Velocity, neighbourRegion.ExternalEndPoint, - capsPath); + agent.ControllingClient.CrossRegion(neighbourRegion.RegionHandle, pos, agent.Velocity, + endpoint,capsPath); } // SUCCESS! @@ -1800,11 +1876,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // Unlike a teleport, here we do not wait for the destination region to confirm the receipt. m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp); - agent.CloseChildAgents(false, neighbourRegion.RegionHandle, neighbourRegion.RegionSizeX, neighbourRegion.RegionSizeY); + if(childRegionsToClose != null) + agent.CloseChildAgents(childRegionsToClose); - // this may need the attachments + if((agent.crossingFlags & 8) == 0) + agent.ClearControls(); // don't let attachments delete (called in HasMovedAway) disturb taken controls on viewers - agent.HasMovedAway(true); + agent.HasMovedAway((agent.crossingFlags & 8) == 0); agent.MakeChildAgent(neighbourRegion.RegionHandle); @@ -1812,20 +1890,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // but not sure yet what the side effects would be. m_entityTransferStateMachine.ResetFromTransit(agent.UUID); - // the user may change their profile information in other region, - // so the userinfo in UserProfileCache is not reliable any more, delete it - // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE! -// if (agent.Scene.NeedSceneCacheClear(agent.UUID)) -// { -// m_log.DebugFormat( -// "[ENTITY TRANSFER MODULE]: User {0} is going to another region", agent.UUID); -// } - - //m_log.Debug("AFTER CROSS"); - //Scene.DumpChildrenSeeds(UUID); - //DumpKnownRegions(); - - return; + return true; } private void CrossAgentToNewRegionCompleted(IAsyncResult iar) @@ -1888,7 +1953,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer seeds.Add(regionhandler, agent.CapsPath); - // agent.ChildrenCapSeeds = new Dictionary(seeds); agent.ChildrenCapSeeds = null; @@ -2094,6 +2158,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { Thread.Sleep(200); // the original delay that was at InformClientOfNeighbourAsync start int count = 0; + IPEndPoint ipe; foreach (GridRegion neighbour in neighbours) { @@ -2102,8 +2167,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { if (newneighbours.Contains(handler)) { - InformClientOfNeighbourAsync(sp, cagents[count], neighbour, - neighbour.ExternalEndPoint, true); + ipe = neighbour.ExternalEndPoint; + if (ipe != null) + InformClientOfNeighbourAsync(sp, cagents[count], neighbour, ipe, true); + else + { + m_log.DebugFormat("[ENTITY TRANSFER MODULE]: lost DNS resolution for neighbour {0}", neighbour.ExternalHostName); + } count++; } else if (!previousRegionNeighbourHandles.Contains(handler)) @@ -2135,7 +2205,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer sp.Scene.RegionInfo.WorldLocY - neighbour.RegionLocY, 0f); } - + #endregion #region NotFoundLocationCache class // A collection of not found locations to make future lookups 'not found' lookups quick. @@ -2201,73 +2271,51 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer } #endregion // NotFoundLocationCache class + #region getregions private NotFoundLocationCache m_notFoundLocationCache = new NotFoundLocationCache(); protected GridRegion GetRegionContainingWorldLocation(IGridService pGridService, UUID pScopeID, double px, double py) { - // Since we don't know how big the regions could be, we have to search a very large area - // to find possible regions. - return GetRegionContainingWorldLocation(pGridService, pScopeID, px, py, Constants.MaximumRegionSize); - } - - // Given a world position, get the GridRegion info for - // the region containing that point. - // for compatibility with old grids it does a scan to find large regions - // 0.9 grids to that - - protected GridRegion GetRegionContainingWorldLocation(IGridService pGridService, UUID pScopeID, - double px, double py, uint pSizeHint) - { - m_log.DebugFormat("{0} GetRegionContainingWorldLocation: call, XY=<{1},{2}>", LogHeader, px, py); + // Given a world position, get the GridRegion info for + // the region containing that point. + // for compatibility with old grids it does a scan to find large regions + // 0.9 grids to that +// m_log.DebugFormat("{0} GetRegionContainingWorldLocation: call, XY=<{1},{2}>", LogHeader, px, py); GridRegion ret = null; - const double fudge = 2.0; + // check if we already found it does not exist if (m_notFoundLocationCache.Contains(px, py)) - { -// m_log.DebugFormat("{0} GetRegionContainingWorldLocation: Not found via cache. loc=<{1},{2}>", LogHeader, px, py); return null; - } - // As an optimization, since most regions will be legacy sized regions (256x256), first try to get - // the region at the appropriate legacy region location. + // reduce to next grid corner // this is all that is needed on 0.9 grids uint possibleX = (uint)px & 0xffffff00u; uint possibleY = (uint)py & 0xffffff00u; ret = pGridService.GetRegionByPosition(pScopeID, (int)possibleX, (int)possibleY); if (ret != null) - { -// m_log.DebugFormat("{0} GetRegionContainingWorldLocation: Found region using legacy size. rloc=<{1},{2}>. Rname={3}", -// LogHeader, possibleX, possibleY, ret.RegionName); return ret; - } - + // for 0.8 regions just make a BIG area request. old code whould do it plus 4 more smaller on region open edges // this is what 0.9 grids now do internally List possibleRegions = pGridService.GetRegionRange(pScopeID, (int)(px - Constants.MaximumRegionSize), (int)(px + 1), // +1 bc left mb not part of range (int)(py - Constants.MaximumRegionSize), (int)(py + 1)); -// m_log.DebugFormat("{0} GetRegionContainingWorldLocation: possibleRegions cnt={1}, range={2}", -// LogHeader, possibleRegions.Count, range); if (possibleRegions != null && possibleRegions.Count > 0) { // If we found some regions, check to see if the point is within foreach (GridRegion gr in possibleRegions) { -// m_log.DebugFormat("{0} GetRegionContainingWorldLocation: possibleRegion nm={1}, regionLoc=<{2},{3}>, regionSize=<{4},{5}>", -// LogHeader, gr.RegionName, gr.RegionLocX, gr.RegionLocY, gr.RegionSizeX, gr.RegionSizeY); if (px >= (double)gr.RegionLocX && px < (double)(gr.RegionLocX + gr.RegionSizeX) && py >= (double)gr.RegionLocY && py < (double)(gr.RegionLocY + gr.RegionSizeY)) { // Found a region that contains the point return gr; -// m_log.DebugFormat("{0} GetRegionContainingWorldLocation: found. RegionName={1}", LogHeader, ret.RegionName); } } } // remember this location was not found so we can quickly not find it next time m_notFoundLocationCache.Add(px, py); -// m_log.DebugFormat("{0} GetRegionContainingWorldLocation: Not found. Remembering loc=<{1},{2}>", LogHeader, px, py); return null; } @@ -2291,7 +2339,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer private void InformClientOfNeighbourAsync(ScenePresence sp, AgentCircuitData agentCircData, GridRegion reg, IPEndPoint endPoint, bool newAgent) { - if (newAgent) { // we may already had lost this sp @@ -2318,17 +2365,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (m_eqModule != null) { - #region IP Translation for NAT if(sp == null || sp.IsDeleted || sp.ClientView == null) // something bad already happened return; - IClientIPEndpoint ipepClient; - if (sp.ClientView.TryGet(out ipepClient)) - { - endPoint.Address = NetworkUtil.GetIPFor(ipepClient.EndPoint, endPoint.Address); - } - #endregion - m_log.DebugFormat("{0} {1} is sending {2} EnableSimulator for neighbour region {3}(loc=<{4},{5}>,siz=<{6},{7}>) " + "and EstablishAgentCommunication with seed cap {8}", LogHeader, scene.RegionInfo.RegionName, sp.Name, @@ -2372,7 +2411,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer uint dd = (uint)avatar.RegionViewDistance; - // until avatar movement updates client connections, we need to seend at least this current region imediate neighbors + // until avatar movement updates client connections, we need to send at least this current region immediate neighbors uint ddX = Math.Max(dd, Constants.RegionSize); uint ddY = Math.Max(dd, Constants.RegionSize); diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs index 1ce69276b4..56c654f224 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs @@ -163,7 +163,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer m_incomingSceneObjectEngine = new JobEngine( string.Format("HG Incoming Scene Object Engine ({0})", scene.Name), - "HG INCOMING SCENE OBJECT ENGINE"); + "HG INCOMING SCENE OBJECT ENGINE", 30000); StatsManager.RegisterStat( new Stat( diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index 67c847b21d..788ed1c667 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -212,6 +212,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess if (m_Scene.TryGetScenePresence(remoteClient.AgentId, out presence)) { byte[] data = null; + uint everyonemask = 0; + uint groupmask = 0; if (invType == (sbyte)InventoryType.Landmark && presence != null) { @@ -220,6 +222,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess data = Encoding.ASCII.GetBytes(strdata); name = prefix + name; description += suffix; + groupmask = (uint)PermissionMask.AllAndExport; + everyonemask = (uint)(PermissionMask.AllAndExport & ~PermissionMask.Modify); } AssetBase asset = m_Scene.CreateAsset(name, description, assetType, data, remoteClient.AgentId); @@ -227,9 +231,10 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess m_Scene.CreateNewInventoryItem( remoteClient, remoteClient.AgentId.ToString(), string.Empty, folderID, name, description, 0, callbackID, asset.FullID, asset.Type, invType, - (uint)PermissionMask.All | (uint)PermissionMask.Export, // Base - (uint)PermissionMask.All | (uint)PermissionMask.Export, // Current - 0, nextOwnerMask, 0, creationDate, false); // Data from viewer + (uint)PermissionMask.AllAndExport, // Base + (uint)PermissionMask.AllAndExport, // Current + everyonemask, + nextOwnerMask, groupmask, creationDate, false); // Data from viewer } else { @@ -294,15 +299,18 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess else if ((CustomInventoryType)item.InvType == CustomInventoryType.AnimationSet) { AnimationSet animSet = new AnimationSet(data); - if (!animSet.Validate(x => { + uint res = animSet.Validate(x => { + const int required = (int)(PermissionMask.Transfer | PermissionMask.Copy); int perms = m_Scene.InventoryService.GetAssetPermissions(remoteClient.AgentId, x); - int required = (int)(PermissionMask.Transfer | PermissionMask.Copy); + // enforce previus perm rule if ((perms & required) != required) - return false; - return true; - })) + return 0; + return (uint) perms; + }); + if(res == 0) { - data = animSet.ToBytes(); + remoteClient.SendAgentAlertMessage("Not enought permissions on asset(s) referenced by animation set '{0}', update failed", false); + return UUID.Zero; } } @@ -407,7 +415,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess Dictionary originalPositions = new Dictionary(); Dictionary originalRotations = new Dictionary(); // this possible is not needed if keyframes are saved - Dictionary originalKeyframes = new Dictionary(); +// Dictionary originalKeyframes = new Dictionary(); foreach (SceneObjectGroup objectGroup in objlist) { @@ -418,8 +426,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess objectGroup.RootPart.SetForce(Vector3.Zero); objectGroup.RootPart.SetAngularImpulse(Vector3.Zero, false); - originalKeyframes[objectGroup.UUID] = objectGroup.RootPart.KeyframeMotion; - objectGroup.RootPart.KeyframeMotion = null; +// originalKeyframes[objectGroup.UUID] = objectGroup.RootPart.KeyframeMotion; +// objectGroup.RootPart.KeyframeMotion = null; Vector3 inventoryStoredPosition = objectGroup.AbsolutePosition; originalPositions[objectGroup.UUID] = inventoryStoredPosition; @@ -471,7 +479,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess { objectGroup.AbsolutePosition = originalPositions[objectGroup.UUID]; objectGroup.RootPart.RotationOffset = originalRotations[objectGroup.UUID]; - objectGroup.RootPart.KeyframeMotion = originalKeyframes[objectGroup.UUID]; +// objectGroup.RootPart.KeyframeMotion = originalKeyframes[objectGroup.UUID]; if (objectGroup.RootPart.KeyframeMotion != null) objectGroup.RootPart.KeyframeMotion.Resume(); } @@ -573,41 +581,27 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess InventoryItemBase item, SceneObjectGroup so, List objsForEffectivePermissions, IClientAPI remoteClient) { - uint effectivePerms = (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify | PermissionMask.Move | PermissionMask.Export) | 7; - uint allObjectsNextOwnerPerms = 0x7fffffff; - - // For the porposes of inventory, an object is modify if the prims - // are modify. This allows renaming an object that contains no - // mod items. + uint effectivePerms = (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify | PermissionMask.Move | PermissionMask.Export | PermissionMask.FoldedMask); + foreach (SceneObjectGroup grp in objsForEffectivePermissions) { - uint groupPerms = grp.GetEffectivePermissions(true); - if ((grp.RootPart.BaseMask & (uint)PermissionMask.Modify) != 0) - groupPerms |= (uint)PermissionMask.Modify; - - effectivePerms &= groupPerms; + effectivePerms &= grp.CurrentAndFoldedNextPermissions(); } - effectivePerms |= (uint)PermissionMask.Move; - + if (remoteClient != null && (remoteClient.AgentId != so.RootPart.OwnerID) && m_Scene.Permissions.PropagatePermissions()) { - uint perms = effectivePerms; - uint nextPerms = (perms & 7) << 13; - if ((nextPerms & (uint)PermissionMask.Copy) == 0) - perms &= ~(uint)PermissionMask.Copy; - if ((nextPerms & (uint)PermissionMask.Transfer) == 0) - perms &= ~(uint)PermissionMask.Transfer; - if ((nextPerms & (uint)PermissionMask.Modify) == 0) - perms &= ~(uint)PermissionMask.Modify; - -// item.BasePermissions = perms & so.RootPart.NextOwnerMask; - - uint nextp = so.RootPart.NextOwnerMask | (uint)PermissionMask.FoldedMask; - item.BasePermissions = perms & nextp; - item.CurrentPermissions = item.BasePermissions; - item.NextPermissions = perms & so.RootPart.NextOwnerMask; - item.EveryOnePermissions = so.RootPart.EveryoneMask & so.RootPart.NextOwnerMask; - item.GroupPermissions = so.RootPart.GroupMask & so.RootPart.NextOwnerMask; + // apply parts inventory items next owner + PermissionsUtil.ApplyNoModFoldedPermissions(effectivePerms, ref effectivePerms); + // change to next owner + uint basePerms = effectivePerms & so.RootPart.NextOwnerMask; + // fix and update folded + basePerms = PermissionsUtil.FixAndFoldPermissions(basePerms); + + item.BasePermissions = basePerms; + item.CurrentPermissions = basePerms; + item.NextPermissions = basePerms & so.RootPart.NextOwnerMask; + item.EveryOnePermissions = basePerms & so.RootPart.EveryoneMask; + item.GroupPermissions = basePerms & so.RootPart.GroupMask; // apply next owner perms on rez item.Flags |= (uint)InventoryItemFlags.ObjectSlamPerm; @@ -626,7 +620,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess (uint)PermissionMask.Modify | (uint)PermissionMask.Move | (uint)PermissionMask.Export | - 7); // Preserve folded permissions + (uint)PermissionMask.FoldedMask); // Preserve folded permissions ?? } return item; @@ -998,11 +992,11 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess // one full update during the attachment // process causes some clients to fail to display the // attachment properly. - m_Scene.AddNewSceneObject(group, true, false); if (!attachment) { group.AbsolutePosition = pos + veclist[i]; + m_Scene.AddNewSceneObject(group, true, false); // Fire on_rez group.CreateScriptInstances(0, true, m_Scene.DefaultScriptEngine, 1); @@ -1010,6 +1004,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess group.ScheduleGroupForFullUpdate(); } + else + m_Scene.AddNewSceneObject(group, true, false); + // m_log.DebugFormat( // "[INVENTORY ACCESS MODULE]: Rezzed {0} {1} {2} ownermask={3:X} nextownermask={4:X} groupmask={5:X} everyonemask={6:X} for {7}", @@ -1144,9 +1141,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess if ((item.BasePermissions & (uint)PermissionMask.FoldedMask) != 0) { // We have permissions stored there so use them - part.NextOwnerMask = ((item.BasePermissions & 7) << 13); - if ((item.BasePermissions & (uint)PermissionMask.FoldedExport) != 0) - part.NextOwnerMask |= (uint)PermissionMask.Export; + part.NextOwnerMask = ((item.BasePermissions & (uint)PermissionMask.FoldedMask) << (int)PermissionMask.FoldingShift); part.NextOwnerMask |= (uint)PermissionMask.Move; } else @@ -1193,7 +1188,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess } rootPart.TrimPermissions(); - so.AggregateDeepPerms(); + so.InvalidateDeepEffectivePerms(); if (isAttachment) so.FromItemID = item.ID; diff --git a/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs b/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs index df9d4f96fd..5d77201320 100644 --- a/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs +++ b/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs @@ -178,7 +178,7 @@ namespace OpenSim.Region.CoreModules.Framework.Library InventoryArchiveReadRequest archread = new InventoryArchiveReadRequest(m_MockScene.InventoryService, m_MockScene.AssetService, m_MockScene.UserAccountService, uinfo, simpleName, iarFileName, false); try { - HashSet nodes = archread.Execute(); + Dictionary nodes = archread.Execute(); if (nodes != null && nodes.Count == 0) { // didn't find the subfolder with the given name; place it on the top @@ -188,7 +188,7 @@ namespace OpenSim.Region.CoreModules.Framework.Library archread.Execute(); } - foreach (InventoryNodeBase node in nodes) + foreach (InventoryNodeBase node in nodes.Values) FixPerms(node); } catch (Exception e) diff --git a/OpenSim/Region/CoreModules/Framework/ServiceThrottle/ServiceThrottleModule.cs b/OpenSim/Region/CoreModules/Framework/ServiceThrottle/ServiceThrottleModule.cs index 924a1a3c1a..2c74c0e0c0 100644 --- a/OpenSim/Region/CoreModules/Framework/ServiceThrottle/ServiceThrottleModule.cs +++ b/OpenSim/Region/CoreModules/Framework/ServiceThrottle/ServiceThrottleModule.cs @@ -119,7 +119,15 @@ namespace OpenSim.Region.CoreModules.Framework if(!client.IsActive) return; - GridRegion r = m_scenes[0].GridService.GetRegionByUUID(UUID.Zero, regionID); + if(m_scenes.Count == 0) + return; + + Scene baseScene = m_scenes[0]; + + if(baseScene == null || baseScene.ShuttingDown) + return; + + GridRegion r = baseScene.GridService.GetRegionByUUID(UUID.Zero, regionID); if(!client.IsActive) return; diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs index 32cb5a383a..269546430f 100644 --- a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs +++ b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs @@ -175,6 +175,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement { client.OnNameFromUUIDRequest -= new UUIDNameRequest(HandleUUIDNameRequest); client.OnAvatarPickerRequest -= new AvatarPickerRequest(HandleAvatarPickerRequest); + client.OnConnectionClosed -= new Action(HandleConnectionClosed); } protected virtual void HandleUUIDNameRequest(UUID uuid, IClientAPI client) diff --git a/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs b/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs index 5d66d34a2b..8c44ee2f93 100644 --- a/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs +++ b/OpenSim/Region/CoreModules/Hypergrid/HGWorldMapModule.cs @@ -106,6 +106,8 @@ namespace OpenSim.Region.CoreModules.Hypergrid if (!m_Enabled) return; + base.RemoveRegion(scene); + scene.EventManager.OnClientClosed -= EventManager_OnClientClosed; } diff --git a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs index c369d87b05..00c46826de 100644 --- a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs @@ -135,17 +135,13 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture m_reuseableDynamicTextures.Store( GenerateReusableTextureKey(texture.InputCommands, texture.InputParams), newTextureID); } + updater.newTextureID = newTextureID; } - } - if (updater.UpdateTimer == 0) - { lock (Updaters) { - if (!Updaters.ContainsKey(updater.UpdaterID)) - { + if (Updaters.ContainsKey(updater.UpdaterID)) Updaters.Remove(updater.UpdaterID); - } } } } @@ -172,21 +168,20 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture } public UUID AddDynamicTextureURL(UUID simID, UUID primID, string contentType, string url, - string extraParams, int updateTimer) + string extraParams) { - return AddDynamicTextureURL(simID, primID, contentType, url, extraParams, updateTimer, false, 255); + return AddDynamicTextureURL(simID, primID, contentType, url, extraParams, false, 255); } public UUID AddDynamicTextureURL(UUID simID, UUID primID, string contentType, string url, - string extraParams, int updateTimer, bool SetBlending, byte AlphaValue) + string extraParams, bool SetBlending, byte AlphaValue) { - return AddDynamicTextureURL(simID, primID, contentType, url, - extraParams, updateTimer, SetBlending, - (int)(DISP_TEMP|DISP_EXPIRE), AlphaValue, ALL_SIDES); + return AddDynamicTextureURL(simID, primID, contentType, url, extraParams, SetBlending, + (DISP_TEMP|DISP_EXPIRE), AlphaValue, ALL_SIDES); } public UUID AddDynamicTextureURL(UUID simID, UUID primID, string contentType, string url, - string extraParams, int updateTimer, bool SetBlending, + string extraParams, bool SetBlending, int disp, byte AlphaValue, int face) { if (RenderPlugins.ContainsKey(contentType)) @@ -196,7 +191,6 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture updater.PrimID = primID; updater.ContentType = contentType; updater.Url = url; - updater.UpdateTimer = updateTimer; updater.UpdaterID = UUID.Random(); updater.Params = extraParams; updater.BlendWithOldTexture = SetBlending; @@ -213,26 +207,27 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture } RenderPlugins[contentType].AsyncConvertUrl(updater.UpdaterID, url, extraParams); - return updater.UpdaterID; + return updater.newTextureID; } return UUID.Zero; } public UUID AddDynamicTextureData(UUID simID, UUID primID, string contentType, string data, - string extraParams, int updateTimer) + string extraParams) { - return AddDynamicTextureData(simID, primID, contentType, data, extraParams, updateTimer, false, 255); + return AddDynamicTextureData(simID, primID, contentType, data, extraParams, false, + (DISP_TEMP|DISP_EXPIRE), 255, ALL_SIDES); } public UUID AddDynamicTextureData(UUID simID, UUID primID, string contentType, string data, - string extraParams, int updateTimer, bool SetBlending, byte AlphaValue) + string extraParams, bool SetBlending, byte AlphaValue) { - return AddDynamicTextureData(simID, primID, contentType, data, extraParams, updateTimer, SetBlending, - (int) (DISP_TEMP|DISP_EXPIRE), AlphaValue, ALL_SIDES); + return AddDynamicTextureData(simID, primID, contentType, data, extraParams, SetBlending, + (DISP_TEMP|DISP_EXPIRE), AlphaValue, ALL_SIDES); } public UUID AddDynamicTextureData(UUID simID, UUID primID, string contentType, string data, - string extraParams, int updateTimer, bool SetBlending, int disp, byte AlphaValue, int face) + string extraParams, bool SetBlending, int disp, byte AlphaValue, int face) { if (!RenderPlugins.ContainsKey(contentType)) return UUID.Zero; @@ -258,7 +253,6 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture updater.PrimID = primID; updater.ContentType = contentType; updater.BodyData = data; - updater.UpdateTimer = updateTimer; updater.UpdaterID = UUID.Random(); updater.Params = extraParams; updater.BlendWithOldTexture = SetBlending; @@ -314,7 +308,7 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture updater.UpdatePart(part, (UUID)objReusableTextureUUID); } - return updater.UpdaterID; + return updater.newTextureID; } private string GenerateReusableTextureKey(string data, string extraParams) @@ -404,17 +398,15 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture public byte FrontAlpha = 255; public string Params; public UUID PrimID; - public bool SetNewFrontAlpha = false; public UUID SimUUID; public UUID UpdaterID; - public int UpdateTimer; public int Face; public int Disp; public string Url; + public UUID newTextureID; public DynamicTextureUpdater() { - UpdateTimer = 0; BodyData = null; } @@ -436,16 +428,23 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture // FIXME: Need to return the appropriate ID if only a single face is replaced. oldID = tmptex.DefaultTexture.TextureID; + // not using parts number of faces because that fails on old meshs if (Face == ALL_SIDES) { oldID = tmptex.DefaultTexture.TextureID; tmptex.DefaultTexture.TextureID = textureID; + for(int i = 0; i < tmptex.FaceTextures.Length; i++) + { + if(tmptex.FaceTextures[i] != null) + tmptex.FaceTextures[i].TextureID = textureID; + } } else { try { Primitive.TextureEntryFace texface = tmptex.CreateFace((uint)Face); + oldID = texface.TextureID; texface.TextureID = textureID; tmptex.FaceTextures[Face] = texface; } @@ -455,10 +454,6 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture } } - // I'm pretty sure we always want to force this to true - // I'm pretty sure noone whats to set fullbright true if it wasn't true before. - // tmptex.DefaultTexture.Fullbright = true; - part.UpdateTextureEntry(tmptex.GetBytes()); } @@ -491,13 +486,26 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture if (BlendWithOldTexture) { - Primitive.TextureEntryFace defaultFace = part.Shape.Textures.DefaultTexture; - if (defaultFace != null) + Primitive.TextureEntryFace curFace; + if(Face == ALL_SIDES) + curFace = part.Shape.Textures.DefaultTexture; + else { - oldAsset = scene.AssetService.Get(defaultFace.TextureID.ToString()); + try + { + curFace = part.Shape.Textures.GetFace((uint)Face); + } + catch + { + curFace = null; + } + } + if (curFace != null) + { + oldAsset = scene.AssetService.Get(curFace.TextureID.ToString()); if (oldAsset != null) - assetData = BlendTextures(data, oldAsset.Data, SetNewFrontAlpha, FrontAlpha); + assetData = BlendTextures(data, oldAsset.Data, FrontAlpha); } } @@ -548,7 +556,7 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture return asset.FullID; } - private byte[] BlendTextures(byte[] frontImage, byte[] backImage, bool setNewAlpha, byte newAlpha) + private byte[] BlendTextures(byte[] frontImage, byte[] backImage, byte newAlpha) { ManagedImage managedImage; Image image; @@ -568,7 +576,7 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture Bitmap image2 = new Bitmap(image); image.Dispose(); - if (setNewAlpha) + if (newAlpha < 255) SetAlpha(ref image1, newAlpha); using(Bitmap joint = MergeBitMaps(image1, image2)) @@ -580,7 +588,7 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture try { - result = OpenJPEG.EncodeFromImage(joint, true); + result = OpenJPEG.EncodeFromImage(joint, false); } catch (Exception e) { diff --git a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs index 09891f7876..3d3a76861b 100644 --- a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs +++ b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs @@ -110,49 +110,8 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest public HttpRequestModule() { - ServicePointManager.ServerCertificateValidationCallback +=ValidateServerCertificate; } - public static bool ValidateServerCertificate( - object sender, - X509Certificate certificate, - X509Chain chain, - SslPolicyErrors sslPolicyErrors) - { - // If this is a web request we need to check the headers first - // We may want to ignore SSL - if (sender is HttpWebRequest) - { - HttpWebRequest Request = (HttpWebRequest)sender; - ServicePoint sp = Request.ServicePoint; - - // We don't case about encryption, get out of here - if (Request.Headers.Get("NoVerifyCert") != null) - { - return true; - } - - // If there was an upstream cert verification error, bail - if ((((int)sslPolicyErrors) & ~4) != 0) - return false; - - // Check for policy and execute it if defined -#pragma warning disable 0618 - if (ServicePointManager.CertificatePolicy != null) - { - return ServicePointManager.CertificatePolicy.CheckValidationResult (sp, certificate, Request, 0); - } -#pragma warning restore 0618 - - return true; - } - - // If it's not HTTP, trust .NET to check it - if ((((int)sslPolicyErrors) & ~4) != 0) - return false; - - return true; - } #region IHttpRequestModule Members public UUID MakeHttpRequest(string url, string parameters, string body) @@ -223,20 +182,16 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest if (parms.Length - i < 2) break; - //Have we reached the end of the list of headers? - //End is marked by a string with a single digit. - //We already know we have at least one parameter - //so it is safe to do this check at top of loop. - if (Char.IsDigit(parms[i][0])) - break; - if (htc.HttpCustomHeaders == null) htc.HttpCustomHeaders = new List(); htc.HttpCustomHeaders.Add(parms[i]); htc.HttpCustomHeaders.Add(parms[i+1]); + int nexti = i + 2; + if (nexti >= parms.Length || Char.IsDigit(parms[nexti][0])) + break; - i += 2; + i = nexti; } break; @@ -383,9 +338,9 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest if (ThreadPool == null) { STPStartInfo startInfo = new STPStartInfo(); - startInfo.IdleTimeout = 20000; + startInfo.IdleTimeout = 2000; startInfo.MaxWorkerThreads = maxThreads; - startInfo.MinWorkerThreads = 1; + startInfo.MinWorkerThreads = 0; startInfo.ThreadPriority = ThreadPriority.BelowNormal; startInfo.StartSuspended = true; startInfo.ThreadPoolName = "ScriptsHttpReq"; @@ -419,6 +374,7 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest public void Close() { + ThreadPool.Shutdown(); } public string Name @@ -525,6 +481,47 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest return null; } + public static bool ValidateServerCertificate( + object sender, + X509Certificate certificate, + X509Chain chain, + SslPolicyErrors sslPolicyErrors) + { + // If this is a web request we need to check the headers first + // We may want to ignore SSL + if (sender is HttpWebRequest) + { + HttpWebRequest Request = (HttpWebRequest)sender; + ServicePoint sp = Request.ServicePoint; + + // We don't case about encryption, get out of here + if (Request.Headers.Get("NoVerifyCert") != null) + { + return true; + } + + // If there was an upstream cert verification error, bail + if ((((int)sslPolicyErrors) & ~4) != 0) + return false; + + // Check for policy and execute it if defined +#pragma warning disable 0618 + if (ServicePointManager.CertificatePolicy != null) + { + return ServicePointManager.CertificatePolicy.CheckValidationResult (sp, certificate, Request, 0); + } +#pragma warning restore 0618 + + return true; + } + + // If it's not HTTP, trust .NET to check it + if ((((int)sslPolicyErrors) & ~4) != 0) + return false; + + return true; + } + /* * TODO: More work on the response codes. Right now * returning 200 for success or 499 for exception @@ -541,7 +538,10 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest try { Request = (HttpWebRequest)WebRequest.Create(Url); + Request.ServerCertificateValidationCallback = ValidateServerCertificate; + Request.AllowAutoRedirect = false; + Request.KeepAlive = false; //This works around some buggy HTTP Servers like Lighttpd Request.ServicePoint.Expect100Continue = false; @@ -667,14 +667,9 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest Status = (int)OSHttpStatusCode.ClientErrorJoker; ResponseBody = e.Message; } - - if (ResponseBody == null) - ResponseBody = String.Empty; - - _finished = true; - return; } - catch (Exception e) +// catch (Exception e) + catch { // Don't crash on anything else } @@ -731,13 +726,10 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest else { _finished = true; + if (ResponseBody == null) + ResponseBody = String.Empty; } } - - if (ResponseBody == null) - ResponseBody = String.Empty; - - _finished = true; } public void Stop() diff --git a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs index 311deabe76..31c317cf51 100644 --- a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs @@ -26,10 +26,11 @@ */ using System; -using System.Threading; using System.Collections.Generic; using System.Collections; using System.Reflection; +using System.Net; +using System.Net.Sockets; using log4net; using Mono.Addins; using Nini.Config; @@ -89,6 +90,8 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp protected Dictionary m_UrlMap = new Dictionary(); + protected bool m_enabled = false; + protected string m_ErrorStr; protected uint m_HttpsPort = 0; protected IHttpServer m_HttpServer = null; protected IHttpServer m_HttpsServer = null; @@ -118,6 +121,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp public void Initialise(IConfigSource config) { IConfig networkConfig = config.Configs["Network"]; + m_enabled = false; if (networkConfig != null) { @@ -128,9 +132,31 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp if (ssl_enabled) m_HttpsPort = (uint)config.Configs["Network"].GetInt("https_port", (int)m_HttpsPort); } + else + { + m_ErrorStr = "[Network] configuration missing, HTTP listener for LSL disabled"; + m_log.Warn("[URL MODULE]: " + m_ErrorStr); + return; + } - if (ExternalHostNameForLSL == null) - ExternalHostNameForLSL = System.Environment.MachineName; + if (String.IsNullOrWhiteSpace(ExternalHostNameForLSL)) + { + m_ErrorStr = "ExternalHostNameForLSL not defined in configuration, HTTP listener for LSL disabled"; + m_log.Warn("[URL MODULE]: " + m_ErrorStr); + return; + } + + IPAddress ia = null; + ia = Util.GetHostFromDNS(ExternalHostNameForLSL); + if (ia == null) + { + m_ErrorStr = "Could not resolve ExternalHostNameForLSL, HTTP listener for LSL disabled"; + m_log.Warn("[URL MODULE]: " + m_ErrorStr); + return; + } + + m_enabled = true; + m_ErrorStr = String.Empty; IConfig llFunctionsConfig = config.Configs["LL-Functions"]; @@ -146,7 +172,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp public void AddRegion(Scene scene) { - if (m_HttpServer == null) + if (m_enabled && m_HttpServer == null) { // There can only be one // @@ -197,11 +223,18 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp { UUID urlcode = UUID.Random(); + if(!m_enabled) + { + engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_DENIED", m_ErrorStr }); + return urlcode; + } + lock (m_UrlMap) { if (m_UrlMap.Count >= TotalUrls) { - engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_DENIED", "" }); + engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_DENIED", + "Too many URLs already open" }); return urlcode; } string url = "http://" + ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + "/lslhttp/" + urlcode.ToString() + "/"; @@ -225,7 +258,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp string uri = "/lslhttp/" + urlcode.ToString() + "/"; PollServiceEventArgs args - = new PollServiceEventArgs(HttpRequestHandler, uri, HasEvents, GetEvents, NoEvents, urlcode, 25000); + = new PollServiceEventArgs(HttpRequestHandler, uri, HasEvents, GetEvents, NoEvents, Drop, urlcode, 25000); args.Type = PollServiceEventArgs.EventType.LslHttp; m_HttpServer.AddPollServiceHTTPHandler(uri, args); @@ -243,6 +276,12 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp { UUID urlcode = UUID.Random(); + if(!m_enabled) + { + engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_DENIED", m_ErrorStr }); + return urlcode; + } + if (m_HttpsServer == null) { engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_DENIED", "" }); @@ -253,7 +292,8 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp { if (m_UrlMap.Count >= TotalUrls) { - engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_DENIED", "" }); + engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_DENIED", + "Too many URLs already open" }); return urlcode; } string url = "https://" + ExternalHostNameForLSL + ":" + m_HttpsServer.Port.ToString() + "/lslhttps/" + urlcode.ToString() + "/"; @@ -276,7 +316,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp string uri = "/lslhttps/" + urlcode.ToString() + "/"; PollServiceEventArgs args - = new PollServiceEventArgs(HttpRequestHandler, uri, HasEvents, GetEvents, NoEvents, urlcode, 25000); + = new PollServiceEventArgs(HttpRequestHandler, uri, HasEvents, GetEvents, NoEvents, Drop, urlcode, 25000); args.Type = PollServiceEventArgs.EventType.LslHttp; m_HttpsServer.AddPollServiceHTTPHandler(uri, args); @@ -480,7 +520,6 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp response["str_response_string"] = "Script timeout"; response["content_type"] = "text/plain"; response["keepalive"] = false; - response["reusecontext"] = false; //remove from map lock (url.requests) @@ -530,6 +569,28 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp } } } + + protected void Drop(UUID requestID, UUID sessionID) + { + UrlData url = null; + lock (m_RequestMap) + { + if (m_RequestMap.ContainsKey(requestID)) + { + url = m_RequestMap[requestID]; + m_RequestMap.Remove(requestID); + if(url != null) + { + lock (url.requests) + { + if(url.requests.ContainsKey(requestID)) + url.requests.Remove(requestID); + } + } + } + } + } + protected Hashtable GetEvents(UUID requestID, UUID sessionID) { UrlData url = null; @@ -557,7 +618,6 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp response["str_response_string"] = "Script timeout"; response["content_type"] = "text/plain"; response["keepalive"] = false; - response["reusecontext"] = false; return response; } //put response @@ -565,7 +625,6 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp response["str_response_string"] = requestData.responseBody; response["content_type"] = requestData.responseType; response["keepalive"] = false; - response["reusecontext"] = false; if (url.allowXss) response["access_control_allow_origin"] = "*"; @@ -689,9 +748,9 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp else { queryString = queryString + val + "&"; - } } } + } if (queryString.Length > 1) queryString = queryString.Substring(0, queryString.Length - 1); diff --git a/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs b/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs index 673a453e75..4f18d00107 100644 --- a/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs @@ -215,43 +215,47 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL { try { - Bitmap image = new Bitmap(stream); + using(Bitmap image = new Bitmap(stream)) + { + // TODO: make this a bit less hard coded + if((image.Height < 64) && (image.Width < 64)) + { + newSize.Width = 32; + newSize.Height = 32; + } + else if((image.Height < 128) && (image.Width < 128)) + { + newSize.Width = 64; + newSize.Height = 64; + } + else if((image.Height < 256) && (image.Width < 256)) + { + newSize.Width = 128; + newSize.Height = 128; + } + else if((image.Height < 512 && image.Width < 512)) + { + newSize.Width = 256; + newSize.Height = 256; + } + else if((image.Height < 1024 && image.Width < 1024)) + { + newSize.Width = 512; + newSize.Height = 512; + } + else + { + newSize.Width = 1024; + newSize.Height = 1024; + } - // TODO: make this a bit less hard coded - if ((image.Height < 64) && (image.Width < 64)) - { - newSize.Width = 32; - newSize.Height = 32; - } - else if ((image.Height < 128) && (image.Width < 128)) - { - newSize.Width = 64; - newSize.Height = 64; - } - else if ((image.Height < 256) && (image.Width < 256)) - { - newSize.Width = 128; - newSize.Height = 128; - } - else if ((image.Height < 512 && image.Width < 512)) - { - newSize.Width = 256; - newSize.Height = 256; - } - else if ((image.Height < 1024 && image.Width < 1024)) - { - newSize.Width = 512; - newSize.Height = 512; - } - else - { - newSize.Width = 1024; - newSize.Height = 1024; - } - - using (Bitmap resize = new Bitmap(image, newSize)) - { - imageJ2000 = OpenJPEG.EncodeFromImage(resize, true); + if(newSize.Width != image.Width || newSize.Height != image.Height) + { + using(Bitmap resize = new Bitmap(image, newSize)) + imageJ2000 = OpenJPEG.EncodeFromImage(resize, false); + } + else + imageJ2000 = OpenJPEG.EncodeFromImage(image, false); } } catch (Exception) diff --git a/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs b/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs index ed255bfcb3..325f7f9ccf 100644 --- a/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs +++ b/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs @@ -77,8 +77,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests so.UUID, m_vrm.GetContentType(), "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;", - "", - 0); + ""); Assert.That(originalTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID)); } @@ -98,8 +97,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests so.UUID, m_vrm.GetContentType(), dtText, - "", - 0); + ""); UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID; @@ -108,8 +106,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests so.UUID, m_vrm.GetContentType(), dtText, - "", - 0); + ""); Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID)); } @@ -129,8 +126,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests so.UUID, m_vrm.GetContentType(), dtText, - "", - 0); + ""); UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID; @@ -139,8 +135,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests so.UUID, m_vrm.GetContentType(), dtText, - "alpha:250", - 0); + "alpha:250"); Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID)); } @@ -161,8 +156,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests so.UUID, m_vrm.GetContentType(), dtText, - "", - 0); + ""); UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID; @@ -171,8 +165,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests so.UUID, m_vrm.GetContentType(), dtText, - "", - 0); + ""); Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID)); } @@ -191,8 +184,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests so.UUID, m_vrm.GetContentType(), "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;", - "", - 0); + ""); Assert.That(originalTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID)); } @@ -213,8 +205,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests so.UUID, m_vrm.GetContentType(), dtText, - "", - 0); + ""); UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID; @@ -223,8 +214,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests so.UUID, m_vrm.GetContentType(), dtText, - "", - 0); + ""); Assert.That(firstDynamicTextureID, Is.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID)); } @@ -253,8 +243,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests so.UUID, m_vrm.GetContentType(), dtText, - "1024", - 0); + "1024"); UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID; @@ -263,8 +252,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests so.UUID, m_vrm.GetContentType(), dtText, - "1024", - 0); + "1024"); Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID)); } @@ -284,8 +272,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests so.UUID, m_vrm.GetContentType(), dtText, - "", - 0); + ""); UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID; @@ -294,8 +281,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests so.UUID, m_vrm.GetContentType(), dtText, - "alpha:250", - 0); + "alpha:250"); Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID)); } @@ -316,8 +302,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests so.UUID, m_vrm.GetContentType(), dtText, - "", - 0); + ""); UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID; @@ -326,8 +311,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests so.UUID, m_vrm.GetContentType(), dtText, - "", - 0); + ""); Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID)); } diff --git a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs index f12286dafd..475e8e970c 100644 --- a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs @@ -355,30 +355,22 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender lock (this) { if (alpha == 256) - bitmap = new Bitmap(width, height, PixelFormat.Format32bppRgb); - else - bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb); - - graph = Graphics.FromImage(bitmap); - - // this is really just to save people filling the - // background color in their scripts, only do when fully opaque - if (alpha >= 255) { + bitmap = new Bitmap(width, height, PixelFormat.Format32bppRgb); + graph = Graphics.FromImage(bitmap); using (SolidBrush bgFillBrush = new SolidBrush(bgColor)) { graph.FillRectangle(bgFillBrush, 0, 0, width, height); } } - - for (int w = 0; w < bitmap.Width; w++) + else { - if (alpha <= 255) + bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb); + graph = Graphics.FromImage(bitmap); + Color newbg = Color.FromArgb(alpha,bgColor); + using (SolidBrush bgFillBrush = new SolidBrush(newbg)) { - for (int h = 0; h < bitmap.Height; h++) - { - bitmap.SetPixel(w, h, Color.FromArgb(alpha, bitmap.GetPixel(w, h))); - } + graph.FillRectangle(bgFillBrush, 0, 0, width, height); } } @@ -397,7 +389,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender try { - imageJ2000 = OpenJPEG.EncodeFromImage(bitmap, true); + imageJ2000 = OpenJPEG.EncodeFromImage(bitmap, false); } catch (Exception e) { @@ -519,8 +511,32 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender // m_log.DebugFormat("[VECTOR RENDER MODULE]: Processing line '{0}'", nextLine); + if (nextLine.StartsWith("ResetTransf")) + { + graph.ResetTransform(); + } + else if (nextLine.StartsWith("TransTransf")) + { + float x = 0; + float y = 0; + GetParams(partsDelimiter, ref nextLine, 11, ref x, ref y); + graph.TranslateTransform(x, y); + } + else if (nextLine.StartsWith("ScaleTransf")) + { + float x = 0; + float y = 0; + GetParams(partsDelimiter, ref nextLine, 11, ref x, ref y); + graph.ScaleTransform(x, y); + } + else if (nextLine.StartsWith("RotTransf")) + { + float x = 0; + GetParams(partsDelimiter, ref nextLine, 9, ref x); + graph.RotateTransform(x); + } //replace with switch, or even better, do some proper parsing - if (nextLine.StartsWith("MoveTo")) + else if (nextLine.StartsWith("MoveTo")) { float x = 0; float y = 0; @@ -625,6 +641,17 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender startPoint.X += endPoint.X; startPoint.Y += endPoint.Y; } + else if (nextLine.StartsWith("FillEllipse")) + { + float x = 0; + float y = 0; + GetParams(partsDelimiter, ref nextLine, 11, ref x, ref y); + endPoint.X = (int)x; + endPoint.Y = (int)y; + graph.FillEllipse(myBrush, startPoint.X, startPoint.Y, endPoint.X, endPoint.Y); + startPoint.X += endPoint.X; + startPoint.Y += endPoint.Y; + } else if (nextLine.StartsWith("FontSize")) { nextLine = nextLine.Remove(0, 8); @@ -636,59 +663,39 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender } else if (nextLine.StartsWith("FontProp")) { + FontStyle myFontStyle = myFont.Style; + nextLine = nextLine.Remove(0, 8); nextLine = nextLine.Trim(); string[] fprops = nextLine.Split(partsDelimiter); foreach (string prop in fprops) { - switch (prop) { case "B": - if (!(myFont.Bold)) - { - Font newFont = new Font(myFont, myFont.Style | FontStyle.Bold); - myFont.Dispose(); - myFont = newFont; - } + myFontStyle |= FontStyle.Bold; break; case "I": - if (!(myFont.Italic)) - { - Font newFont = new Font(myFont, myFont.Style | FontStyle.Italic); - myFont.Dispose(); - myFont = newFont; - } + myFontStyle |= FontStyle.Italic; break; case "U": - if (!(myFont.Underline)) - { - Font newFont = new Font(myFont, myFont.Style | FontStyle.Underline); - myFont.Dispose(); - myFont = newFont; - } + myFontStyle |= FontStyle.Underline; break; case "S": - if (!(myFont.Strikeout)) - { - Font newFont = new Font(myFont, myFont.Style | FontStyle.Strikeout); - myFont.Dispose(); - myFont = newFont; - } + myFontStyle |= FontStyle.Strikeout; break; - case "R": - // We need to place this newFont inside its own context so that the .NET compiler - // doesn't complain about a redefinition of an existing newFont, even though there is none - // The mono compiler doesn't produce this error. - { - Font newFont = new Font(myFont, FontStyle.Regular); - myFont.Dispose(); - myFont = newFont; - } + case "R": //This special case resets all font properties + myFontStyle = FontStyle.Regular; break; } } + if (myFontStyle != myFont.Style) + { + Font newFont = new Font(myFont, myFontStyle); + myFont.Dispose(); + myFont = newFont; + } } else if (nextLine.StartsWith("FontName")) { @@ -790,6 +797,17 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender } } + private static void GetParams(char[] partsDelimiter, ref string line, int startLength, ref float x) + { + line = line.Remove(0, startLength); + string[] parts = line.Split(partsDelimiter); + if (parts.Length > 0) + { + string xVal = parts[0].Trim(); + x = Convert.ToSingle(xVal, CultureInfo.InvariantCulture); + } + } + private static void GetParams(char[] partsDelimiter, ref string line, int startLength, ref float x, ref float y) { line = line.Remove(0, startLength); diff --git a/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs b/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs index 660e03f232..a5203ea750 100644 --- a/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs @@ -113,7 +113,7 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm // wrap this in a try block so that defaults will work if // the config file doesn't specify otherwise. int maxlisteners = 1000; - int maxhandles = 64; + int maxhandles = 65; try { m_whisperdistance = config.Configs["Chat"].GetInt( @@ -130,8 +130,15 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm catch (Exception) { } - if (maxlisteners < 1) maxlisteners = int.MaxValue; - if (maxhandles < 1) maxhandles = int.MaxValue; + + if (maxlisteners < 1) + maxlisteners = int.MaxValue; + if (maxhandles < 1) + maxhandles = int.MaxValue; + + if (maxlisteners < maxhandles) + maxlisteners = maxhandles; + m_listenerManager = new ListenerManager(maxlisteners, maxhandles); m_pendingQ = new Queue(); m_pending = Queue.Synchronized(m_pendingQ); @@ -605,11 +612,9 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm li.GetHandle().Equals(handle)) { lis.Value.Remove(li); + m_curlisteners--; if (lis.Value.Count == 0) - { - m_listeners.Remove(lis.Key); - m_curlisteners--; - } + m_listeners.Remove(lis.Key); // bailing of loop so this does not smoke // there should be only one, so we bail out early return; } @@ -718,6 +723,9 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm } } + if(handles.Count >= m_maxhandles) + return -1; + // Note: 0 is NOT a valid handle for llListen() to return for (int i = 1; i <= m_maxhandles; i++) { diff --git a/OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs b/OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs index aed137231d..6028eefd37 100644 --- a/OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs @@ -658,7 +658,7 @@ namespace OpenSim.Region.CoreModules.Scripting.XMLRPC public void Process() { _finished = false; - httpThread = WorkManager.StartThread(SendRequest, "HttpRequestThread", ThreadPriority.BelowNormal, true, false); + httpThread = WorkManager.StartThread(SendRequest, "XMLRPCreqThread", ThreadPriority.BelowNormal, true, false, null, int.MaxValue); } /* diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Land/LandServiceInConnectorModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Land/LandServiceInConnectorModule.cs index 21483c5e9e..fb8c3065d8 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Land/LandServiceInConnectorModule.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Land/LandServiceInConnectorModule.cs @@ -151,7 +151,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Land x = rx - s.RegionInfo.WorldLocX; y = ry - s.RegionInfo.WorldLocY; regionAccess = s.RegionInfo.AccessLevel; - return s.GetLandData(x, y); + LandData land = s.GetLandData(x, y); + IDwellModule dwellModule = s.RequestModuleInterface(); + if (dwellModule != null) + land.Dwell = dwellModule.GetDwell(land); + return land; } } m_log.DebugFormat("[LAND IN CONNECTOR]: region handle {0} not found", regionHandle); diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsIn/UserProfiles/LocalUserProfilesServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsIn/UserProfiles/LocalUserProfilesServiceConnector.cs index 2e6f472399..e6da6c3c31 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsIn/UserProfiles/LocalUserProfilesServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsIn/UserProfiles/LocalUserProfilesServiceConnector.cs @@ -163,7 +163,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Profile #region ISharedRegionModule implementation - void ISharedRegionModule.PostInitialise() + public void PostInitialise() { if(!Enabled) return; @@ -173,7 +173,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Profile #region IRegionModuleBase implementation - void IRegionModuleBase.Initialise(IConfigSource source) + public void Initialise(IConfigSource source) { IConfig moduleConfig = source.Configs["Modules"]; if (moduleConfig != null) @@ -187,12 +187,12 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Profile } } - void IRegionModuleBase.Close() + public void Close() { return; } - void IRegionModuleBase.AddRegion(Scene scene) + public void AddRegion(Scene scene) { if (!Enabled) return; @@ -206,7 +206,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Profile } } - void IRegionModuleBase.RemoveRegion(Scene scene) + public void RemoveRegion(Scene scene) { if (!Enabled) return; @@ -218,7 +218,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Profile } } - void IRegionModuleBase.RegionLoaded(Scene scene) + public void RegionLoaded(Scene scene) { if (!Enabled) return; diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionInfoCache.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionInfoCache.cs index 84e52f7602..f6fff58aef 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionInfoCache.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/RegionInfoCache.cs @@ -385,7 +385,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid storage[handle] = region; byname[region.RegionName] = handle; byuuid[region.RegionID] = handle; - } public void Remove(GridRegion region) @@ -400,7 +399,13 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid ulong handle = region.RegionHandle & HANDLEMASK; if(storage != null) - storage.Remove(handle); + { + if(storage.ContainsKey(handle)) + { + storage[handle] = null; + storage.Remove(handle); + } + } removeFromInner(region); if(expires != null) { @@ -424,6 +429,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid if(byuuid != null) byuuid.Remove(r.RegionID); removeFromInner(r); + storage[handle] = null; } storage.Remove(handle); } @@ -581,27 +587,32 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid { if(expires == null || expires.Count == 0) return 0; - + + int expiresCount = expires.Count; List toexpire = new List(); + foreach(KeyValuePair kvp in expires) { if(kvp.Value < now) toexpire.Add(kvp.Key); } - if(toexpire.Count == 0) - return expires.Count; + int toexpireCount = toexpire.Count; + if(toexpireCount == 0) + return expiresCount; - if(toexpire.Count == expires.Count) + if(toexpireCount == expiresCount) { Clear(); return 0; } - foreach(ulong h in toexpire) + if(storage != null) { - if(storage != null) + ulong h; + for(int i = 0; i < toexpireCount; i++) { + h = toexpire[i]; if(storage.ContainsKey(h)) { GridRegion r = storage[h]; @@ -610,14 +621,22 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid if(byuuid != null) byuuid.Remove(r.RegionID); removeFromInner(r); + + storage[h] = null; + storage.Remove(h); } - storage.Remove(h); + if(expires != null) + expires.Remove(h); } - if(expires != null) - expires.Remove(h); + } + else + { + Clear(); + return 0; } - if(expires.Count == 0) + expiresCount = expires.Count; + if(expiresCount == 0) { byname = null; byuuid = null; @@ -626,7 +645,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid return 0; } - return expires.Count; + return expiresCount; } public int Count() @@ -693,7 +712,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid public class RegionsExpiringCache { - const double CACHE_PURGE_HZ = 60; // seconds + const double CACHE_PURGE_TIME = 60000; // milliseconds const int MAX_LOCK_WAIT = 10000; // milliseconds /// For thread safety @@ -702,7 +721,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid object isPurging = new object(); Dictionary InfobyScope = new Dictionary(); - private System.Timers.Timer timer = new System.Timers.Timer(TimeSpan.FromSeconds(CACHE_PURGE_HZ).TotalMilliseconds); + private System.Timers.Timer timer = new System.Timers.Timer(CACHE_PURGE_TIME); public RegionsExpiringCache() { @@ -965,7 +984,10 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid if (expiredscopes.Count > 0) { foreach (UUID sid in expiredscopes) + { + InfobyScope[sid] = null; InfobyScope.Remove(sid); + } } } finally { Monitor.Exit(syncRoot); } diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs index 5efdd9b7cf..7a4f981da6 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs @@ -250,7 +250,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory if (inventoryURL != null && inventoryURL != string.Empty) { inventoryURL = inventoryURL.Trim(new char[] { '/' }); - m_InventoryURLs[userID] = inventoryURL; + lock (m_InventoryURLs) + m_InventoryURLs[userID] = inventoryURL; m_log.DebugFormat("[HG INVENTORY CONNECTOR]: Added {0} to the cache of inventory URLs", inventoryURL); return; } @@ -268,35 +269,42 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory if (!string.IsNullOrEmpty(inventoryURL)) { inventoryURL = inventoryURL.Trim(new char[] { '/' }); - m_InventoryURLs.Add(userID, inventoryURL); + lock (m_InventoryURLs) + m_InventoryURLs[userID] = inventoryURL; m_log.DebugFormat("[HG INVENTORY CONNECTOR]: Added {0} to the cache of inventory URLs", inventoryURL); } - } - } } private void DropInventoryServiceURL(UUID userID) { lock (m_InventoryURLs) + { if (m_InventoryURLs.ContainsKey(userID)) { string url = m_InventoryURLs[userID]; m_InventoryURLs.Remove(userID); m_log.DebugFormat("[HG INVENTORY CONNECTOR]: Removed {0} from the cache of inventory URLs", url); } + } } public string GetInventoryServiceURL(UUID userID) { - if (m_InventoryURLs.ContainsKey(userID)) - return m_InventoryURLs[userID]; + lock (m_InventoryURLs) + { + if (m_InventoryURLs.ContainsKey(userID)) + return m_InventoryURLs[userID]; + } CacheInventoryServiceURL(userID); - if (m_InventoryURLs.ContainsKey(userID)) - return m_InventoryURLs[userID]; + lock (m_InventoryURLs) + { + if (m_InventoryURLs.ContainsKey(userID)) + return m_InventoryURLs[userID]; + } return null; //it means that the methods should forward to local grid's inventory diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Land/LocalLandServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Land/LocalLandServiceConnector.cs index cad2061946..8baf41a3d9 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Land/LocalLandServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Land/LocalLandServiceConnector.cs @@ -143,6 +143,10 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Land { LandData land = s.GetLandData(x, y); regionAccess = s.RegionInfo.AccessLevel; + IDwellModule dwellModule = s.RequestModuleInterface(); + if (dwellModule != null) + land.Dwell = dwellModule.GetDwell(land); + return land; } } diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs index 9888c3b189..8f9bbe878c 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/MapImage/MapImageServiceModule.cs @@ -244,11 +244,15 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.MapImage (int)Constants.RegionSize, (int)Constants.RegionSize); using (Bitmap subMapTile = mapTile.Clone(rect, mapTile.PixelFormat)) { - ConvertAndUploadMaptile(scene, subMapTile, + if(!ConvertAndUploadMaptile(scene, subMapTile, scene.RegionInfo.RegionLocX + (xx / Constants.RegionSize), scene.RegionInfo.RegionLocY + (yy / Constants.RegionSize), - scene.Name); - } + scene.Name)) + { + m_log.DebugFormat("{0} Upload maptileS for {1} aborted!", LogHeader, scene.Name); + return; // abort rest; + } + } } } } @@ -280,7 +284,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.MapImage } } - private void ConvertAndUploadMaptile(IScene scene, Image tileImage, uint locX, uint locY, string regionName) + private bool ConvertAndUploadMaptile(IScene scene, Image tileImage, uint locX, uint locY, string regionName) { byte[] jpgData = Utils.EmptyBytes; @@ -289,19 +293,21 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.MapImage tileImage.Save(stream, ImageFormat.Jpeg); jpgData = stream.ToArray(); } - if (jpgData != Utils.EmptyBytes) - { - string reason = string.Empty; - if (!m_MapService.AddMapTile((int)locX, (int)locY, jpgData, scene.RegionInfo.ScopeID, out reason)) - { - m_log.DebugFormat("{0} Unable to upload tile image for {1} at {2}-{3}: {4}", LogHeader, - regionName, locX, locY, reason); - } - } - else + + if (jpgData == Utils.EmptyBytes) { m_log.WarnFormat("{0} Tile image generation failed for region {1}", LogHeader, regionName); + return false; } + + string reason = string.Empty; + if (!m_MapService.AddMapTile((int)locX, (int)locY, jpgData, scene.RegionInfo.ScopeID, out reason)) + { + m_log.DebugFormat("{0} Unable to upload tile image for {1} at {2}-{3}: {4}", LogHeader, + regionName, locX, locY, reason); + return false; + } + return true; } } } diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/MuteList/LocalMuteListServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/MuteList/LocalMuteListServiceConnector.cs new file mode 100644 index 0000000000..1fc1a6e520 --- /dev/null +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/MuteList/LocalMuteListServiceConnector.cs @@ -0,0 +1,188 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using log4net; +using Mono.Addins; +using Nini.Config; +using System; +using System.Collections.Generic; +using System.Reflection; +using OpenSim.Framework; +using OpenSim.Server.Base; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Services.Interfaces; +using OpenMetaverse; + +namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.MuteList +{ + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "LocalMuteListServicesConnector")] + public class LocalMuteListServicesConnector : ISharedRegionModule, IMuteListService + { + private static readonly ILog m_log = + LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); + + private List m_Scenes = new List(); + protected IMuteListService m_service = null; + + private bool m_Enabled = false; + + #region ISharedRegionModule + + public Type ReplaceableInterface + { + get { return null; } + } + + public string Name + { + get { return "LocalMuteListServicesConnector"; } + } + + public void Initialise(IConfigSource source) + { + // only active for core mute lists module + IConfig moduleConfig = source.Configs["Messaging"]; + if (moduleConfig == null) + return; + + if (moduleConfig.GetString("MuteListModule", "None") != "MuteListModule") + return; + + moduleConfig = source.Configs["Modules"]; + + if (moduleConfig == null) + return; + + string name = moduleConfig.GetString("MuteListService", ""); + if(name != Name) + return; + + IConfig userConfig = source.Configs["MuteListService"]; + if (userConfig == null) + { + m_log.Error("[MuteList LOCALCONNECTOR]: MuteListService missing from configuration"); + return; + } + + string serviceDll = userConfig.GetString("LocalServiceModule", + String.Empty); + + if (serviceDll == String.Empty) + { + m_log.Error("[MuteList LOCALCONNECTOR]: No LocalServiceModule named in section MuteListService"); + return; + } + + Object[] args = new Object[] { source }; + try + { + m_service = ServerUtils.LoadPlugin(serviceDll, args); + } + catch + { + m_log.Error("[MuteList LOCALCONNECTOR]: Failed to load mute service"); + return; + } + + if (m_service == null) + { + m_log.Error("[MuteList LOCALCONNECTOR]: Can't load MuteList service"); + return; + } + + m_Enabled = true; + m_log.Info("[MuteList LOCALCONNECTOR]: enabled"); + } + + public void Close() + { + } + + public void AddRegion(Scene scene) + { + if (!m_Enabled) + return; + + lock(m_Scenes) + { + m_Scenes.Add(scene); + scene.RegisterModuleInterface(this); + } + } + + public void RegionLoaded(Scene scene) + { + } + + public void PostInitialise() + { + } + + public void RemoveRegion(Scene scene) + { + if (!m_Enabled) + return; + + lock(m_Scenes) + { + if (m_Scenes.Contains(scene)) + { + m_Scenes.Remove(scene); + scene.UnregisterModuleInterface(this); + } + } + } + + #endregion ISharedRegionModule + + #region IMuteListService + public Byte[] MuteListRequest(UUID agentID, uint crc) + { + if (!m_Enabled) + return null; + return m_service.MuteListRequest(agentID, crc); + } + + public bool UpdateMute(MuteData mute) + { + if (!m_Enabled) + return false; + return m_service.UpdateMute(mute); + } + + public bool RemoveMute(UUID agentID, UUID muteID, string muteName) + { + if (!m_Enabled) + return false; + return m_service.RemoveMute(agentID, muteID, muteName); + } + + #endregion IMuteListService + } +} diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Neighbour/RemoteNeighourServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/MuteList/RemoteMuteListServiceConnector.cs similarity index 50% rename from OpenSim/Region/CoreModules/ServiceConnectorsOut/Neighbour/RemoteNeighourServiceConnector.cs rename to OpenSim/Region/CoreModules/ServiceConnectorsOut/MuteList/RemoteMuteListServiceConnector.cs index fcb55216ec..a65e2bdf4f 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Neighbour/RemoteNeighourServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/MuteList/RemoteMuteListServiceConnector.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) Contributors, http://opensimulator.org/ * See CONTRIBUTORS.TXT for a full list of copyright holders. * @@ -24,34 +24,33 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - -using log4net; -using Mono.Addins; using System; using System.Collections.Generic; using System.Reflection; -using Nini.Config; using OpenSim.Framework; -using OpenSim.Services.Connectors; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; -using OpenSim.Services.Interfaces; using OpenSim.Server.Base; +using OpenSim.Services.Interfaces; +using OpenSim.Services.Connectors; -namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Neighbour +using OpenMetaverse; +using log4net; +using Mono.Addins; +using Nini.Config; + +namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.MuteList { - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "RemoteNeighbourServicesConnector")] - public class RemoteNeighbourServicesConnector : - NeighbourServicesConnector, ISharedRegionModule, INeighbourService + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "RemoteMuteListServicesConnector")] + public class RemoteMuteListServicesConnector : ISharedRegionModule, IMuteListService { - private static readonly ILog m_log = - LogManager.GetLogger( - MethodBase.GetCurrentMethod().DeclaringType); + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + #region ISharedRegionModule private bool m_Enabled = false; - private LocalNeighbourServicesConnector m_LocalService; - //private string serviceDll; - //private List m_Scenes = new List(); + + private IMuteListService m_remoteConnector; public Type ReplaceableInterface { @@ -60,55 +59,33 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Neighbour public string Name { - get { return "RemoteNeighbourServicesConnector"; } + get { return "RemoteMuteListServicesConnector"; } } public void Initialise(IConfigSource source) { - IConfig moduleConfig = source.Configs["Modules"]; + // only active for core mute lists module + IConfig moduleConfig = source.Configs["Messaging"]; + if (moduleConfig == null) + return; + + if (moduleConfig.GetString("MuteListModule", "None") != "MuteListModule") + return; + + moduleConfig = source.Configs["Modules"]; if (moduleConfig != null) { - string name = moduleConfig.GetString("NeighbourServices"); + string name = moduleConfig.GetString("MuteListService", ""); if (name == Name) { - m_LocalService = new LocalNeighbourServicesConnector(); - - //IConfig neighbourConfig = source.Configs["NeighbourService"]; - //if (neighbourConfig == null) - //{ - // m_log.Error("[NEIGHBOUR CONNECTOR]: NeighbourService missing from OpenSim.ini"); - // return; - //} - //serviceDll = neighbourConfig.GetString("LocalServiceModule", String.Empty); - //if (serviceDll == String.Empty) - //{ - // m_log.Error("[NEIGHBOUR CONNECTOR]: No LocalServiceModule named in section NeighbourService"); - // return; - //} - + m_remoteConnector = new MuteListServicesConnector(source); m_Enabled = true; - - m_log.Info("[NEIGHBOUR CONNECTOR]: Remote Neighbour connector enabled"); } } } public void PostInitialise() { - //if (m_Enabled) - //{ - // Object[] args = new Object[] { m_Scenes }; - // m_LocalService = - // ServerUtils.LoadPlugin(serviceDll, - // args); - - // if (m_LocalService == null) - // { - // m_log.Error("[NEIGHBOUR CONNECTOR]: Can't load neighbour service"); - // Unregister(); - // return; - // } - //} } public void Close() @@ -120,38 +97,47 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Neighbour if (!m_Enabled) return; - m_LocalService.AddRegion(scene); - scene.RegisterModuleInterface(this); + scene.RegisterModuleInterface(this); + m_log.InfoFormat("[MUTELIST CONNECTOR]: Enabled for region {0}", scene.RegionInfo.RegionName); } public void RemoveRegion(Scene scene) { - if (m_Enabled) - m_LocalService.RemoveRegion(scene); + if (!m_Enabled) + return; } public void RegionLoaded(Scene scene) { if (!m_Enabled) return; - - m_GridService = scene.GridService; - - m_log.InfoFormat("[NEIGHBOUR CONNECTOR]: Enabled remote neighbours for region {0}", scene.RegionInfo.RegionName); - } - #region INeighbourService + #endregion - public override GridRegion HelloNeighbour(ulong regionHandle, RegionInfo thisRegion) + #region IMuteListService + public Byte[] MuteListRequest(UUID agentID, uint crc) { - GridRegion region = m_LocalService.HelloNeighbour(regionHandle, thisRegion); - if (region != null) - return region; - - return base.HelloNeighbour(regionHandle, thisRegion); + if (!m_Enabled) + return null; + return m_remoteConnector.MuteListRequest(agentID, crc); } - #endregion INeighbourService + public bool UpdateMute(MuteData mute) + { + if (!m_Enabled) + return false; + return m_remoteConnector.UpdateMute(mute); + } + + public bool RemoveMute(UUID agentID, UUID muteID, string muteName) + { + if (!m_Enabled) + return false; + return m_remoteConnector.RemoveMute(agentID, muteID, muteName); + } + + #endregion IMuteListService + } } diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Neighbour/LocalNeighbourServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Neighbour/NeighbourServiceOutConnector.cs similarity index 72% rename from OpenSim/Region/CoreModules/ServiceConnectorsOut/Neighbour/LocalNeighbourServiceConnector.cs rename to OpenSim/Region/CoreModules/ServiceConnectorsOut/Neighbour/NeighbourServiceOutConnector.cs index e8d01b01c1..60addec12c 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Neighbour/LocalNeighbourServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Neighbour/NeighbourServiceOutConnector.cs @@ -25,44 +25,32 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -using System; -using System.Collections.Generic; -using System.Reflection; using log4net; using Mono.Addins; +using System; +using System.Reflection; +using System.Collections.Generic; using Nini.Config; -using OpenMetaverse; using OpenSim.Framework; -using OpenSim.Server.Base; +using OpenSim.Services.Connectors; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; using OpenSim.Services.Interfaces; + namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Neighbour { - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "LocalNeighbourServicesConnector")] - public class LocalNeighbourServicesConnector : - ISharedRegionModule, INeighbourService + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "NeighbourServicesOutConnector")] + public class NeighbourServicesOutConnector : + NeighbourServicesConnector, ISharedRegionModule, INeighbourService { private static readonly ILog m_log = LogManager.GetLogger( MethodBase.GetCurrentMethod().DeclaringType); private List m_Scenes = new List(); - private bool m_Enabled = false; - public LocalNeighbourServicesConnector() - { - } - - public LocalNeighbourServicesConnector(List scenes) - { - m_Scenes = scenes; - } - - #region ISharedRegionModule - public Type ReplaceableInterface { get { return null; } @@ -70,7 +58,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Neighbour public string Name { - get { return "LocalNeighbourServicesConnector"; } + get { return "NeighbourServicesOutConnector"; } } public void Initialise(IConfigSource source) @@ -78,39 +66,32 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Neighbour IConfig moduleConfig = source.Configs["Modules"]; if (moduleConfig != null) { - string name = moduleConfig.GetString("NeighbourServices", this.Name); + string name = moduleConfig.GetString("NeighbourServices"); if (name == Name) { - // m_Enabled rules whether this module registers as INeighbourService or not m_Enabled = true; - m_log.Info("[NEIGHBOUR CONNECTOR]: Local neighbour connector enabled"); + m_log.Info("[NEIGHBOUR CONNECTOR]: Neighbour out connector enabled"); } } } + public void PostInitialise() + { + } + public void Close() { } public void AddRegion(Scene scene) { - m_Scenes.Add(scene); - if (!m_Enabled) return; + m_Scenes.Add(scene); scene.RegisterModuleInterface(this); } - public void RegionLoaded(Scene scene) - { - m_log.Info("[NEIGHBOUR CONNECTOR]: Local neighbour connector enabled for region " + scene.RegionInfo.RegionName); - } - - public void PostInitialise() - { - } - public void RemoveRegion(Scene scene) { // Always remove @@ -118,28 +99,36 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Neighbour m_Scenes.Remove(scene); } - #endregion ISharedRegionModule + public void RegionLoaded(Scene scene) + { + if (!m_Enabled) + return; + + m_GridService = scene.GridService; + m_log.InfoFormat("[NEIGHBOUR CONNECTOR]: Enabled out neighbours for region {0}", scene.RegionInfo.RegionName); + + } #region INeighbourService - public OpenSim.Services.Interfaces.GridRegion HelloNeighbour(ulong regionHandle, RegionInfo thisRegion) + public override GridRegion HelloNeighbour(ulong regionHandle, RegionInfo thisRegion) { - uint x, y; - Util.RegionHandleToRegionLoc(regionHandle, out x, out y); + if (!m_Enabled) + return null; foreach (Scene s in m_Scenes) { if (s.RegionInfo.RegionHandle == regionHandle) { - m_log.DebugFormat("[LOCAL NEIGHBOUR SERVICE CONNECTOR]: HelloNeighbour from region {0} to neighbour {1} at {2}-{3}", - thisRegion.RegionName, s.Name, x, y ); - - //m_log.Debug("[NEIGHBOUR CONNECTOR]: Found region to SendHelloNeighbour"); +// uint x, y; +// Util.RegionHandleToRegionLoc(regionHandle, out x, out y); +// m_log.DebugFormat("[NEIGHBOUR SERVICE OUT CONNECTOR]: HelloNeighbour from region {0} to neighbour {1} at {2}-{3}", +// thisRegion.RegionName, s.Name, x, y ); return s.IncomingHelloNeighbour(thisRegion); } } - //m_log.DebugFormat("[NEIGHBOUR CONNECTOR]: region handle {0} not found", regionHandle); - return null; + + return base.HelloNeighbour(regionHandle, thisRegion); } #endregion INeighbourService diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs index 6ba8cec22f..e5c9841833 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs @@ -285,6 +285,11 @@ namespace OpenSim.Region.CoreModules.World.Archiver /// Dearchive the region embodied in this request. /// public void DearchiveRegion() + { + DearchiveRegion(true); + } + + public void DearchiveRegion(bool shouldStartScripts) { int successfulAssetRestores = 0; int failedAssetRestores = 0; @@ -425,22 +430,26 @@ namespace OpenSim.Region.CoreModules.World.Archiver // Start the scripts. We delayed this because we want the OAR to finish loading ASAP, so // that users can enter the scene. If we allow the scripts to start in the loop above // then they significantly increase the time until the OAR finishes loading. - WorkManager.RunInThread(o => + if (shouldStartScripts) { - Thread.Sleep(15000); - m_log.Info("[ARCHIVER]: Starting scripts in scene objects"); - - foreach (DearchiveContext sceneContext in sceneContexts.Values) + WorkManager.RunInThread(o => { - foreach (SceneObjectGroup sceneObject in sceneContext.SceneObjects) - { - sceneObject.CreateScriptInstances(0, false, sceneContext.Scene.DefaultScriptEngine, 0); // StateSource.RegionStart - sceneObject.ResumeScripts(); - } + Thread.Sleep(15000); + m_log.Info("[ARCHIVER]: Starting scripts in scene objects..."); - sceneContext.SceneObjects.Clear(); - } - }, null, string.Format("ReadArchiveStartScripts (request {0})", m_requestId)); + foreach (DearchiveContext sceneContext in sceneContexts.Values) + { + foreach (SceneObjectGroup sceneObject in sceneContext.SceneObjects) + { + sceneObject.CreateScriptInstances(0, false, sceneContext.Scene.DefaultScriptEngine, 0); // StateSource.RegionStart + sceneObject.ResumeScripts(); + } + + sceneContext.SceneObjects.Clear(); + } + m_log.Info("[ARCHIVER]: Start scripts done"); + }, null, string.Format("ReadArchiveStartScripts (request {0})", m_requestId)); + } m_log.InfoFormat("[ARCHIVER]: Successfully loaded archive"); @@ -937,10 +946,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver if (m_assetService.GetMetadata(uuid) != null) { sbyte asype = ArchiveConstants.EXTENSION_TO_ASSET_TYPE[extension]; - if(asype == -2) - { - - } // m_log.DebugFormat("[ARCHIVER]: found existing asset {0}",uuid); return true; @@ -950,10 +955,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver { sbyte assetType = ArchiveConstants.EXTENSION_TO_ASSET_TYPE[extension]; - if(assetType == -2) - { - - } if (assetType == (sbyte)AssetType.Unknown) { m_log.WarnFormat("[ARCHIVER]: Importing {0} byte asset {1} with unknown type", data.Length, uuid); diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs index 8dabceeba7..11c53d75d0 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequest.cs @@ -181,11 +181,13 @@ namespace OpenSim.Region.CoreModules.World.Archiver // Archive the regions Dictionary assetUuids = new Dictionary(); + HashSet failedIDs = new HashSet(); + HashSet uncertainAssetsUUIDs = new HashSet(); scenesGroup.ForEachScene(delegate(Scene scene) { string regionDir = MultiRegionFormat ? scenesGroup.GetRegionDir(scene.RegionInfo.RegionID) : ""; - ArchiveOneRegion(scene, regionDir, assetUuids); + ArchiveOneRegion(scene, regionDir, assetUuids, failedIDs, uncertainAssetsUUIDs); }); // Archive the assets @@ -193,23 +195,21 @@ namespace OpenSim.Region.CoreModules.World.Archiver if (SaveAssets) { m_log.DebugFormat("[ARCHIVER]: Saving {0} assets", assetUuids.Count); - - // Asynchronously request all the assets required to perform this archive operation - AssetsRequest ar - = new AssetsRequest( + + AssetsRequest ar = new AssetsRequest( new AssetsArchiver(m_archiveWriter), assetUuids, + failedIDs.Count, m_rootScene.AssetService, m_rootScene.UserAccountService, - m_rootScene.RegionInfo.ScopeID, options, ReceivedAllAssets); - - WorkManager.RunInThread(o => ar.Execute(), null, "Archive Assets Request"); - - // CloseArchive() will be called from ReceivedAllAssets() + m_rootScene.RegionInfo.ScopeID, options, null); + ar.Execute(); + assetUuids = null; } else { m_log.DebugFormat("[ARCHIVER]: Not saving assets since --noassets was specified"); - CloseArchive(string.Empty); +// CloseArchive(string.Empty); } + CloseArchive(string.Empty); } catch (Exception e) { @@ -218,7 +218,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver } } - private void ArchiveOneRegion(Scene scene, string regionDir, Dictionary assetUuids) + private void ArchiveOneRegion(Scene scene, string regionDir, Dictionary assetUuids, + HashSet failedIDs, HashSet uncertainAssetsUUIDs) { m_log.InfoFormat("[ARCHIVER]: Writing region {0}", scene.Name); @@ -237,7 +238,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver { SceneObjectGroup sceneObject = (SceneObjectGroup)entity; - if (!sceneObject.IsDeleted && !sceneObject.IsAttachment) + if (!sceneObject.IsDeleted && !sceneObject.IsAttachment && !sceneObject.IsTemporary && !sceneObject.inTransit) { if (!CanUserArchiveObject(scene.RegionInfo.EstateSettings.EstateOwner, sceneObject, FilterContent, permissionsModule)) { @@ -254,17 +255,39 @@ namespace OpenSim.Region.CoreModules.World.Archiver if (SaveAssets) { - UuidGatherer assetGatherer = new UuidGatherer(scene.AssetService, assetUuids); + UuidGatherer assetGatherer = new UuidGatherer(scene.AssetService, assetUuids, failedIDs, uncertainAssetsUUIDs); int prevAssets = assetUuids.Count; foreach (SceneObjectGroup sceneObject in sceneObjects) + { + int curErrorCntr = assetGatherer.ErrorCount; + int possible = assetGatherer.possibleNotAssetCount; assetGatherer.AddForInspection(sceneObject); + assetGatherer.GatherAll(); + curErrorCntr = assetGatherer.ErrorCount - curErrorCntr; + possible = assetGatherer.possibleNotAssetCount - possible; + if(curErrorCntr > 0) + { + m_log.ErrorFormat("[ARCHIVER]: object {0} '{1}', at {2}, contains {3} references to missing or damaged assets", + sceneObject.UUID, sceneObject.Name ,sceneObject.AbsolutePosition.ToString(), curErrorCntr); + if(possible > 0) + m_log.WarnFormat("[ARCHIVER Warning]: object also contains {0} references that may be to missing or damaged assets or not a problem", possible); + } + else if(possible > 0) + { + m_log.WarnFormat("[ARCHIVER Warning]: object {0} '{1}', at {2}, contains {3} references that may be to missing or damaged assets or not a problem", + sceneObject.UUID, sceneObject.Name ,sceneObject.AbsolutePosition.ToString(), possible); + } + } assetGatherer.GatherAll(); + int errors = assetGatherer.FailedUUIDs.Count; m_log.DebugFormat( - "[ARCHIVER]: {0} scene objects to serialize requiring save of {1} assets", - sceneObjects.Count, assetUuids.Count - prevAssets); + "[ARCHIVER]: {0} region scene objects to save reference {1} possible assets", + sceneObjects.Count, assetUuids.Count - prevAssets + errors); + if(errors > 0) + m_log.DebugFormat("[ARCHIVER]: {0} of these have problems or are not assets and will be ignored", errors); } if (numObjectsSkippedPermissions > 0) @@ -572,7 +595,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver foreach (SceneObjectGroup sceneObject in sceneObjects) { //m_log.DebugFormat("[ARCHIVER]: Saving {0} {1}, {2}", entity.Name, entity.UUID, entity.GetType()); - + if(sceneObject.IsDeleted || sceneObject.inTransit) + continue; string serializedObject = serializer.SerializeGroupToXml2(sceneObject, m_options); string objectPath = string.Format("{0}{1}", regionDir, ArchiveHelpers.CreateObjectPath(sceneObject)); m_archiveWriter.WriteFile(objectPath, serializedObject); diff --git a/OpenSim/Region/CoreModules/World/Archiver/AssetsArchiver.cs b/OpenSim/Region/CoreModules/World/Archiver/AssetsArchiver.cs index efacae372f..3092fe0a8d 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/AssetsArchiver.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/AssetsArchiver.cs @@ -46,7 +46,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver /// /// Post a message to the log every x assets as a progress bar /// - protected static int LOG_ASSET_LOAD_NOTIFICATION_INTERVAL = 50; + protected static int LOG_ASSET_LOAD_NOTIFICATION_INTERVAL = 100; /// /// Keep a count of the number of assets written so that we can provide status updates diff --git a/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs index d380da8d8a..91f4dc354f 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs @@ -61,28 +61,11 @@ namespace OpenSim.Region.CoreModules.World.Archiver Aborted }; - /// - /// Timeout threshold if we still need assets or missing asset notifications but have stopped receiving them - /// from the asset service - /// - protected const int TIMEOUT = 60 * 1000; - - /// - /// If a timeout does occur, limit the amount of UUID information put to the console. - /// - protected const int MAX_UUID_DISPLAY_ON_TIMEOUT = 3; - - protected System.Timers.Timer m_requestCallbackTimer; - - /// - /// State of this request - /// - private RequestState m_requestState = RequestState.Initial; - /// /// uuids to request /// protected IDictionary m_uuids; + private int m_previousErrorsCount; /// /// Callback used when all the assets requested have been received. @@ -104,6 +87,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver /// private int m_repliesRequired; + private System.Timers.Timer m_timeOutTimer; + private bool m_timeout; + /// /// Asset service used to request the assets /// @@ -117,205 +103,98 @@ namespace OpenSim.Region.CoreModules.World.Archiver protected internal AssetsRequest( AssetsArchiver assetsArchiver, IDictionary uuids, + int previousErrorsCount, IAssetService assetService, IUserAccountService userService, UUID scope, Dictionary options, AssetsRequestCallback assetsRequestCallback) { m_assetsArchiver = assetsArchiver; m_uuids = uuids; + m_previousErrorsCount = previousErrorsCount; m_assetsRequestCallback = assetsRequestCallback; m_assetService = assetService; m_userAccountService = userService; m_scopeID = scope; m_options = options; m_repliesRequired = uuids.Count; - - // FIXME: This is a really poor way of handling the timeout since it will always leave the original requesting thread - // hanging. Need to restructure so an original request thread waits for a ManualResetEvent on asset received - // so we can properly abort that thread. Or request all assets synchronously, though that would be a more - // radical change - m_requestCallbackTimer = new System.Timers.Timer(TIMEOUT); - m_requestCallbackTimer.AutoReset = false; - m_requestCallbackTimer.Elapsed += new ElapsedEventHandler(OnRequestCallbackTimeout); } protected internal void Execute() { - m_requestState = RequestState.Running; - - m_log.DebugFormat("[ARCHIVER]: AssetsRequest executed looking for {0} possible assets", m_repliesRequired); - + Culture.SetCurrentCulture(); // We can stop here if there are no assets to fetch if (m_repliesRequired == 0) { - m_requestState = RequestState.Completed; PerformAssetsRequestCallback(false); return; } - m_requestCallbackTimer.Enabled = true; + m_timeOutTimer = new System.Timers.Timer(60000); + m_timeOutTimer .AutoReset = false; + m_timeOutTimer.Elapsed += OnTimeout; + m_timeout = false; foreach (KeyValuePair kvp in m_uuids) { -// m_log.DebugFormat("[ARCHIVER]: Requesting asset {0}", kvp.Key); - -// m_assetService.Get(kvp.Key.ToString(), kvp.Value, PreAssetRequestCallback); - AssetBase asset = m_assetService.Get(kvp.Key.ToString()); - PreAssetRequestCallback(kvp.Key.ToString(), kvp.Value, asset); - } - } - - protected void OnRequestCallbackTimeout(object source, ElapsedEventArgs args) - { - bool timedOut = true; - - try - { - lock (this) + string thiskey = kvp.Key.ToString(); + try { - // Take care of the possibilty that this thread started but was paused just outside the lock before - // the final request came in (assuming that such a thing is possible) - if (m_requestState == RequestState.Completed) - { - timedOut = false; - return; - } - - m_requestState = RequestState.Aborted; - } - - // Calculate which uuids were not found. This is an expensive way of doing it, but this is a failure - // case anyway. - List uuids = new List(); - foreach (UUID uuid in m_uuids.Keys) - { - uuids.Add(uuid); - } - - foreach (UUID uuid in m_foundAssetUuids) - { - uuids.Remove(uuid); - } - - foreach (UUID uuid in m_notFoundAssetUuids) - { - uuids.Remove(uuid); - } - - m_log.ErrorFormat( - "[ARCHIVER]: Asset service failed to return information about {0} requested assets", uuids.Count); - - int i = 0; - foreach (UUID uuid in uuids) - { - m_log.ErrorFormat("[ARCHIVER]: No information about asset {0} received", uuid); - - if (++i >= MAX_UUID_DISPLAY_ON_TIMEOUT) + m_timeOutTimer.Enabled = true; + AssetBase asset = m_assetService.Get(thiskey); + if(m_timeout) break; + + m_timeOutTimer.Enabled = false; + + if(asset == null) + { + m_notFoundAssetUuids.Add(new UUID(thiskey)); + continue; + } + + sbyte assetType = kvp.Value; + if (asset != null && assetType == (sbyte)AssetType.Unknown) + { + m_log.InfoFormat("[ARCHIVER]: Rewriting broken asset type for {0} to {1}", thiskey, SLUtil.AssetTypeFromCode(assetType)); + asset.Type = assetType; + } + + m_foundAssetUuids.Add(asset.FullID); + m_assetsArchiver.WriteAsset(PostProcess(asset)); } - if (uuids.Count > MAX_UUID_DISPLAY_ON_TIMEOUT) - m_log.ErrorFormat( - "[ARCHIVER]: (... {0} more not shown)", uuids.Count - MAX_UUID_DISPLAY_ON_TIMEOUT); - - m_log.Error("[ARCHIVER]: Archive save aborted. PLEASE DO NOT USE THIS ARCHIVE, IT WILL BE INCOMPLETE."); - } - catch (Exception e) - { - m_log.ErrorFormat("[ARCHIVER]: Timeout handler exception {0}{1}", e.Message, e.StackTrace); - } - finally - { - if (timedOut) - WorkManager.RunInThread(PerformAssetsRequestCallback, true, "Archive Assets Request Callback"); - } - } - - protected void PreAssetRequestCallback(string fetchedAssetID, object assetType, AssetBase fetchedAsset) - { - // Check for broken asset types and fix them with the AssetType gleaned by UuidGatherer - if (fetchedAsset != null && fetchedAsset.Type == (sbyte)AssetType.Unknown) - { - m_log.InfoFormat("[ARCHIVER]: Rewriting broken asset type for {0} to {1}", fetchedAsset.ID, SLUtil.AssetTypeFromCode((sbyte)assetType)); - fetchedAsset.Type = (sbyte)assetType; - } - - AssetRequestCallback(fetchedAssetID, this, fetchedAsset); - } - - /// - /// Called back by the asset cache when it has the asset - /// - /// - /// - public void AssetRequestCallback(string id, object sender, AssetBase asset) - { - Culture.SetCurrentCulture(); - - try - { - lock (this) + catch (Exception e) { - //m_log.DebugFormat("[ARCHIVER]: Received callback for asset {0}", id); - - m_requestCallbackTimer.Stop(); - - if ((m_requestState == RequestState.Aborted) || (m_requestState == RequestState.Completed)) - { - m_log.WarnFormat( - "[ARCHIVER]: Received information about asset {0} while in state {1}. Ignoring.", - id, m_requestState); - - return; - } - - if (asset != null) - { -// m_log.DebugFormat("[ARCHIVER]: Writing asset {0}", id); - m_foundAssetUuids.Add(asset.FullID); - - m_assetsArchiver.WriteAsset(PostProcess(asset)); - } - else - { -// m_log.DebugFormat("[ARCHIVER]: Recording asset {0} as not found", id); - m_notFoundAssetUuids.Add(new UUID(id)); - } - - if (m_foundAssetUuids.Count + m_notFoundAssetUuids.Count >= m_repliesRequired) - { - m_requestState = RequestState.Completed; - if(m_notFoundAssetUuids.Count == 0) - m_log.DebugFormat( - "[ARCHIVER]: Successfully added {0} assets", - m_foundAssetUuids.Count); - else - m_log.DebugFormat( - "[ARCHIVER]: Successfully added {0} assets ({1} assets not found but these may be expected invalid references)", - m_foundAssetUuids.Count, m_notFoundAssetUuids.Count); - - - // We want to stop using the asset cache thread asap - // as we now need to do the work of producing the rest of the archive - WorkManager.RunInThread(PerformAssetsRequestCallback, false, "Archive Assets Request Callback"); - } - else - { - m_requestCallbackTimer.Start(); - } + m_log.ErrorFormat("[ARCHIVER]: Execute failed with {0}", e); } } - catch (Exception e) - { - m_log.ErrorFormat("[ARCHIVER]: AssetRequestCallback failed with {0}", e); - } + + m_timeOutTimer.Dispose(); + int totalerrors = m_notFoundAssetUuids.Count + m_previousErrorsCount; + + if(m_timeout) + m_log.DebugFormat("[ARCHIVER]: Aborted because AssetService request timeout. Successfully added {0} assets", m_foundAssetUuids.Count); + else if(totalerrors == 0) + m_log.DebugFormat("[ARCHIVER]: Successfully added all {0} assets", m_foundAssetUuids.Count); + else + m_log.DebugFormat("[ARCHIVER]: Successfully added {0} assets ({1} of total possible assets requested were not found, were damaged or were not assets)", + m_foundAssetUuids.Count, totalerrors); + + PerformAssetsRequestCallback(m_timeout); + } + + private void OnTimeout(object source, ElapsedEventArgs args) + { + m_timeout = true; } /// /// Perform the callback on the original requester of the assets /// - protected void PerformAssetsRequestCallback(object o) + private void PerformAssetsRequestCallback(object o) { + if(m_assetsRequestCallback == null) + return; Culture.SetCurrentCulture(); Boolean timedOut = (Boolean)o; @@ -331,7 +210,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver } } - protected AssetBase PostProcess(AssetBase asset) + private AssetBase PostProcess(AssetBase asset) { if (asset.Type == (sbyte)AssetType.Object && asset.Data != null && m_options.ContainsKey("home")) { diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateConnector.cs b/OpenSim/Region/CoreModules/World/Estate/EstateConnector.cs index 051ff71dfd..8001c3ca7e 100644 --- a/OpenSim/Region/CoreModules/World/Estate/EstateConnector.cs +++ b/OpenSim/Region/CoreModules/World/Estate/EstateConnector.cs @@ -192,12 +192,12 @@ namespace OpenSim.Region.CoreModules.World.Estate { string url = ""; if(port != 0) - url = "http://" + region.ExternalHostName + ":" + port; + url = "http://" + region.ExternalHostName + ":" + port + "/"; else url = region.ServerURI; string reply = SynchronousRestFormsRequester.MakeRequest("POST", - url + "/estate", + url + "estate", reqString); if (reply != string.Empty) { diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs index 3c45b68717..2e801e35b4 100644 --- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs @@ -26,7 +26,7 @@ */ using System; -using System.Collections; +using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using System.Linq; @@ -64,6 +64,8 @@ namespace OpenSim.Region.CoreModules.World.Estate /// If false, region restart requests from the client are blocked even if they are otherwise legitimate. /// public bool AllowRegionRestartFromClient { get; set; } + private bool m_ignoreEstateMinorAccessControl; + private bool m_ignoreEstatePaymentAccessControl; private EstateTerrainXferHandler TerrainUploader; public TelehubManager m_Telehub; @@ -89,7 +91,11 @@ namespace OpenSim.Region.CoreModules.World.Estate IConfig config = source.Configs["EstateManagement"]; if (config != null) + { AllowRegionRestartFromClient = config.GetBoolean("AllowRegionRestartFromClient", true); + m_ignoreEstateMinorAccessControl = config.GetBoolean("IgnoreEstateMinorAccessControl", false); + m_ignoreEstatePaymentAccessControl = config.GetBoolean("IgnoreEstatePaymentAccessControl", false); + } } public void AddRegion(Scene scene) @@ -118,6 +124,9 @@ namespace OpenSim.Region.CoreModules.World.Estate scene.TriggerEstateSunUpdate(); UserManager = scene.RequestModuleInterface(); + + scene.RegionInfo.EstateSettings.DoDenyMinors = !m_ignoreEstateMinorAccessControl; + scene.RegionInfo.EstateSettings.DoDenyAnonymous = !m_ignoreEstateMinorAccessControl; } public void Close() @@ -668,7 +677,7 @@ namespace OpenSim.Region.CoreModules.World.Estate public UUID user; } - private OpenSim.Framework.BlockingQueue deltaRequests = new OpenSim.Framework.BlockingQueue(); + private BlockingCollection deltaRequests = new BlockingCollection(); private void handleEstateAccessDeltaRequest(IClientAPI _remote_client, UUID _invoice, int _estateAccessType, UUID _user) { @@ -683,7 +692,7 @@ namespace OpenSim.Region.CoreModules.World.Estate newreq.estateAccessType = _estateAccessType; newreq.user = _user; - deltaRequests.Enqueue(newreq); + deltaRequests.Add(newreq); lock(deltareqLock) { @@ -713,9 +722,11 @@ namespace OpenSim.Region.CoreModules.World.Estate bool sentGroupsFull = false; bool sentManagersFull = false; + EstateAccessDeltaRequest req; while(Scene.IsRunning) { - EstateAccessDeltaRequest req = deltaRequests.Dequeue(500); + req = null; + deltaRequests.TryTake(out req, 500); if(!Scene.IsRunning) break; @@ -757,7 +768,7 @@ namespace OpenSim.Region.CoreModules.World.Estate changed.Clear(); lock(deltareqLock) { - if(deltaRequests.Count() != 0) + if(deltaRequests.Count != 0) continue; runnigDeltaExec = false; return; @@ -1554,20 +1565,21 @@ namespace OpenSim.Region.CoreModules.World.Estate // Warning: FixedSun should be set to True, otherwise this sun position won't be used. } - if ((parms1 & 0x00000010) != 0) - Scene.RegionInfo.EstateSettings.FixedSun = true; - else - Scene.RegionInfo.EstateSettings.FixedSun = false; - if ((parms1 & 0x00008000) != 0) Scene.RegionInfo.EstateSettings.PublicAccess = true; else Scene.RegionInfo.EstateSettings.PublicAccess = false; - if ((parms1 & 0x10000000) != 0) - Scene.RegionInfo.EstateSettings.AllowVoice = true; + if ((parms1 & 0x00000010) != 0) + Scene.RegionInfo.EstateSettings.FixedSun = true; else - Scene.RegionInfo.EstateSettings.AllowVoice = false; + Scene.RegionInfo.EstateSettings.FixedSun = false; + + // taxfree is now AllowAccessOverride + if ((parms1 & 0x00000020) != 0) + Scene.RegionInfo.EstateSettings.TaxFree = true; + else + Scene.RegionInfo.EstateSettings.TaxFree = false; if ((parms1 & 0x00100000) != 0) Scene.RegionInfo.EstateSettings.AllowDirectTeleport = true; @@ -1579,16 +1591,23 @@ namespace OpenSim.Region.CoreModules.World.Estate else Scene.RegionInfo.EstateSettings.DenyAnonymous = false; + // no longer in used, may be reassigned if ((parms1 & 0x01000000) != 0) Scene.RegionInfo.EstateSettings.DenyIdentified = true; else Scene.RegionInfo.EstateSettings.DenyIdentified = false; + // no longer in used, may be reassigned if ((parms1 & 0x02000000) != 0) Scene.RegionInfo.EstateSettings.DenyTransacted = true; else Scene.RegionInfo.EstateSettings.DenyTransacted = false; + if ((parms1 & 0x10000000) != 0) + Scene.RegionInfo.EstateSettings.AllowVoice = true; + else + Scene.RegionInfo.EstateSettings.AllowVoice = false; + if ((parms1 & 0x40000000) != 0) Scene.RegionInfo.EstateSettings.DenyMinors = true; else diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateRequestHandler.cs b/OpenSim/Region/CoreModules/World/Estate/EstateRequestHandler.cs index 7ab92d1a47..5eda8ab02b 100644 --- a/OpenSim/Region/CoreModules/World/Estate/EstateRequestHandler.cs +++ b/OpenSim/Region/CoreModules/World/Estate/EstateRequestHandler.cs @@ -60,9 +60,10 @@ namespace OpenSim.Region.CoreModules.World.Estate protected override byte[] ProcessRequest(string path, Stream requestData, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { - StreamReader sr = new StreamReader(requestData); - string body = sr.ReadToEnd(); - sr.Close(); + string body; + using(StreamReader sr = new StreamReader(requestData)) + body = sr.ReadToEnd(); + body = body.Trim(); // m_log.DebugFormat("[XESTATE HANDLER]: query String: {0}", body); diff --git a/OpenSim/Region/CoreModules/World/Land/DwellModule.cs b/OpenSim/Region/CoreModules/World/Land/DwellModule.cs index 70c6028176..22480e68df 100644 --- a/OpenSim/Region/CoreModules/World/Land/DwellModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/DwellModule.cs @@ -53,7 +53,7 @@ using GridRegion = OpenSim.Services.Interfaces.GridRegion; namespace OpenSim.Region.CoreModules.World.Land { [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "DefaultDwellModule")] - public class DefaultDwellModule : IDwellModule, INonSharedRegionModule + public class DefaultDwellModule : INonSharedRegionModule, IDwellModule { private Scene m_scene; private IConfigSource m_Config; @@ -88,16 +88,21 @@ namespace OpenSim.Region.CoreModules.World.Land return; m_scene = scene; - - m_scene.EventManager.OnNewClient += OnNewClient; + m_scene.RegisterModuleInterface(this); } public void RegionLoaded(Scene scene) { + if (!m_Enabled) + return; + m_scene.EventManager.OnNewClient += OnNewClient; } public void RemoveRegion(Scene scene) { + if (!m_Enabled) + return; + m_scene.EventManager.OnNewClient -= OnNewClient; } public void Close() @@ -115,12 +120,26 @@ namespace OpenSim.Region.CoreModules.World.Land if (parcel == null) return; - client.SendParcelDwellReply(localID, parcel.LandData.GlobalID, parcel.LandData.Dwell); + LandData land = parcel.LandData; + if(land!= null) + client.SendParcelDwellReply(localID, land.GlobalID, land.Dwell); } + public int GetDwell(UUID parcelID) { + ILandObject parcel = m_scene.LandChannel.GetLandObject(parcelID); + if (parcel != null && parcel.LandData != null) + return (int)(parcel.LandData.Dwell); return 0; } + + public int GetDwell(LandData land) + { + if (land != null) + return (int)(land.Dwell); + return 0; + } + } } diff --git a/OpenSim/Region/CoreModules/World/Land/LandChannel.cs b/OpenSim/Region/CoreModules/World/Land/LandChannel.cs index e4c037371e..993b7825c0 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandChannel.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandChannel.cs @@ -37,11 +37,9 @@ namespace OpenSim.Region.CoreModules.World.Land { #region Constants - public const float BAN_LINE_SAFETY_HEIGHT = 100; //Land types set with flags in ParcelOverlay. //Only one of these can be used. - //RequestResults (I think these are right, they seem to work): public const int LAND_RESULT_MULTIPLE = 1; // The request they made contained more than a single peice of land public const int LAND_RESULT_SINGLE = 0; // The request they made contained only a single piece of land @@ -77,10 +75,28 @@ namespace OpenSim.Region.CoreModules.World.Land private readonly Scene m_scene; private readonly LandManagementModule m_landManagementModule; + private float m_BanLineSafeHeight = 100.0f; + public float BanLineSafeHeight + { + get + { + return m_BanLineSafeHeight; + } + private set + { + if (value >= 20f && value <= 5000f) + m_BanLineSafeHeight = value; + else + m_BanLineSafeHeight = 100.0f; + } + } + public LandChannel(Scene scene, LandManagementModule landManagementMod) { m_scene = scene; m_landManagementModule = landManagementMod; + if(landManagementMod != null) + m_BanLineSafeHeight = landManagementMod.BanLineSafeHeight; } #region ILandChannel Members @@ -106,6 +122,15 @@ namespace OpenSim.Region.CoreModules.World.Land return null; } + public ILandObject GetLandObject(UUID GlobalID) + { + if (m_landManagementModule != null) + { + return m_landManagementModule.GetLandObject(GlobalID); + } + return null; + } + public ILandObject GetLandObject(Vector3 position) { return GetLandObject(position.X, position.Y); @@ -167,6 +192,14 @@ namespace OpenSim.Region.CoreModules.World.Land } } + public void SendParcelsOverlay(IClientAPI client) + { + if (m_landManagementModule != null) + { + m_landManagementModule.SendParcelOverlay(client); + } + } + public void Join(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id) { if (m_landManagementModule != null) diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs index 53b9796f63..19b714e612 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs @@ -41,6 +41,7 @@ using OpenSim.Framework; using OpenSim.Framework.Capabilities; using OpenSim.Framework.Console; using OpenSim.Framework.Servers; +using OpenSim.Framework.Monitoring; using OpenSim.Framework.Servers.HttpServer; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; @@ -92,6 +93,7 @@ namespace OpenSim.Region.CoreModules.World.Land //ubit: removed the readonly so i can move it around private Dictionary m_landList = new Dictionary(); + private Dictionary m_landUUIDList = new Dictionary(); private int m_lastLandLocalID = LandChannel.START_LAND_LOCAL_ID - 1; @@ -114,6 +116,19 @@ namespace OpenSim.Region.CoreModules.World.Land // "View distance" for sending parcel layer info if asked for from a view point in the region private int parcelLayerViewDistance { get; set; } + private float m_BanLineSafeHeight = 100.0f; + public float BanLineSafeHeight + { + get { return m_BanLineSafeHeight; } + private set + { + if (value > 20f && value <= 5000f) + m_BanLineSafeHeight = value; + else + m_BanLineSafeHeight = 100.0f; + } + } + #region INonSharedRegionModule Members public Type ReplaceableInterface @@ -135,6 +150,7 @@ namespace OpenSim.Region.CoreModules.World.Land bool disablebans = landManagementConfig.GetBoolean("DisableParcelBans", !m_allowedForcefulBans); m_allowedForcefulBans = !disablebans; m_showBansLines = landManagementConfig.GetBoolean("ShowParcelBansLines", m_showBansLines); + m_BanLineSafeHeight = landManagementConfig.GetFloat("BanLineSafeHeight", m_BanLineSafeHeight); } } @@ -215,6 +231,7 @@ namespace OpenSim.Region.CoreModules.World.Land client.OnParcelEjectUser += ClientOnParcelEjectUser; client.OnParcelFreezeUser += ClientOnParcelFreezeUser; client.OnSetStartLocationRequest += ClientOnSetHome; + client.OnParcelBuyPass += ClientParcelBuyPass; } public void EventMakeChildAgent(ScenePresence avatar) @@ -249,7 +266,10 @@ namespace OpenSim.Region.CoreModules.World.Land lock (m_landList) { if (m_landList.TryGetValue(local_id, out land)) + { land.LandData = newData; + m_landUUIDList[newData.GlobalID] = local_id; + } } if (land != null) @@ -270,7 +290,11 @@ namespace OpenSim.Region.CoreModules.World.Land //Remove all the land objects in the sim and add a blank, full sim land object set to public lock (m_landList) { + foreach(ILandObject parcel in m_landList.Values) + parcel.Clear(); + m_landList.Clear(); + m_landUUIDList.Clear(); m_lastLandLocalID = LandChannel.START_LAND_LOCAL_ID - 1; m_landIDList = new int[m_scene.RegionInfo.RegionSizeX / LandUnit, m_scene.RegionInfo.RegionSizeY / LandUnit]; @@ -331,7 +355,7 @@ namespace OpenSim.Region.CoreModules.World.Land public bool EnforceBans(ILandObject land, ScenePresence avatar) { Vector3 agentpos = avatar.AbsolutePosition; - float h = m_scene.GetGroundHeight(agentpos.X, agentpos.Y) + LandChannel.BAN_LINE_SAFETY_HEIGHT; + float h = m_scene.GetGroundHeight(agentpos.X, agentpos.Y) + m_scene.LandChannel.BanLineSafeHeight; float zdif = avatar.AbsolutePosition.Z - h; if (zdif > 0 ) { @@ -529,6 +553,118 @@ namespace OpenSim.Region.CoreModules.World.Land } } + public void ClientParcelBuyPass(IClientAPI remote_client, UUID targetID, int landLocalID) + { + ILandObject land; + lock (m_landList) + { + m_landList.TryGetValue(landLocalID, out land); + } + // trivial checks + if(land == null) + return; + + LandData ldata = land.LandData; + + if(ldata == null) + return; + + if(ldata.OwnerID == targetID) + return; + + if(ldata.PassHours == 0) + return; + + // don't allow passes on group owned until we can give money to groups + if(ldata.IsGroupOwned) + { + remote_client.SendAgentAlertMessage("pass to group owned parcel not suported", false); + return; + } + + if((ldata.Flags & (uint)ParcelFlags.UsePassList) == 0) + return; + + int cost = ldata.PassPrice; + + int idx = land.LandData.ParcelAccessList.FindIndex( + delegate(LandAccessEntry e) + { + if (e.AgentID == targetID && e.Flags == AccessList.Access) + return true; + return false; + }); + int now = Util.UnixTimeSinceEpoch(); + int expires = (int)(3600.0 * ldata.PassHours + 0.5f); + int currenttime = -1; + if (idx != -1) + { + if(ldata.ParcelAccessList[idx].Expires == 0) + { + remote_client.SendAgentAlertMessage("You already have access to parcel", false); + return; + } + + currenttime = ldata.ParcelAccessList[idx].Expires - now; + if(currenttime > (int)(0.25f * expires + 0.5f)) + { + if(currenttime > 3600) + remote_client.SendAgentAlertMessage(string.Format("You already have a pass valid for {0:0.###} hours", + currenttime/3600f), false); + else if(currenttime > 60) + remote_client.SendAgentAlertMessage(string.Format("You already have a pass valid for {0:0.##} minutes", + currenttime/60f), false); + else + remote_client.SendAgentAlertMessage(string.Format("You already have a pass valid for {0:0.#} seconds", + currenttime), false); + return; + } + } + + LandAccessEntry entry = new LandAccessEntry(); + entry.AgentID = targetID; + entry.Flags = AccessList.Access; + entry.Expires = now + expires; + if(currenttime > 0) + entry.Expires += currenttime; + IMoneyModule mm = m_scene.RequestModuleInterface(); + if(cost != 0 && mm != null) + { + WorkManager.RunInThreadPool( + delegate + { + string regionName = m_scene.RegionInfo.RegionName; + + if (!mm.AmountCovered(remote_client.AgentId, cost)) + { + remote_client.SendAgentAlertMessage(String.Format("Insufficient funds in region '{0}' money system", regionName), true); + return; + } + + string payDescription = String.Format("Parcel '{0}' at region '{1} {2:0.###} hours access pass", ldata.Name, regionName, ldata.PassHours); + + if(!mm.MoveMoney(remote_client.AgentId, ldata.OwnerID, cost,MoneyTransactionType.LandPassSale, payDescription)) + { + remote_client.SendAgentAlertMessage("Sorry pass payment processing failed, please try again later", true); + return; + } + + if (idx != -1) + ldata.ParcelAccessList.RemoveAt(idx); + ldata.ParcelAccessList.Add(entry); + m_scene.EventManager.TriggerLandObjectUpdated((uint)land.LandData.LocalID, land); + return; + }, null, "ParcelBuyPass"); + } + else + { + if (idx != -1) + ldata.ParcelAccessList.RemoveAt(idx); + ldata.ParcelAccessList.Add(entry); + m_scene.EventManager.TriggerLandObjectUpdated((uint)land.LandData.LocalID, land); + } + } + public void ClientOnParcelAccessListRequest(UUID agentID, UUID sessionID, uint flags, int sequenceID, int landLocalID, IClientAPI remote_client) { @@ -588,10 +724,8 @@ namespace OpenSim.Region.CoreModules.World.Land /// The land object being added. /// Will return null if this overlaps with an existing parcel that has not had its bitmap adjusted. /// - public ILandObject AddLandObject(ILandObject land) + public ILandObject AddLandObject(ILandObject new_land) { - ILandObject new_land = land.Copy(); - // Only now can we add the prim counts to the land object - we rely on the global ID which is generated // as a random UUID inside LandData initialization if (m_primCountModule != null) @@ -656,6 +790,7 @@ namespace OpenSim.Region.CoreModules.World.Land } m_landList.Add(newLandLocalID, new_land); + m_landUUIDList[new_land.LandData.GlobalID] = newLandLocalID; m_lastLandLocalID++; } @@ -672,6 +807,7 @@ namespace OpenSim.Region.CoreModules.World.Land public void removeLandObject(int local_id) { ILandObject land; + UUID landGlobalID = UUID.Zero; lock (m_landList) { for (int x = 0; x < m_landIDList.GetLength(0); x++) @@ -690,9 +826,18 @@ namespace OpenSim.Region.CoreModules.World.Land land = m_landList[local_id]; m_landList.Remove(local_id); + if(land != null && land.LandData != null) + { + landGlobalID = land.LandData.GlobalID; + m_landUUIDList.Remove(landGlobalID); + } } - m_scene.EventManager.TriggerLandObjectRemoved(land.LandData.GlobalID); + if(landGlobalID != UUID.Zero) + { + m_scene.EventManager.TriggerLandObjectRemoved(landGlobalID); + land.Clear(); + } } /// @@ -740,11 +885,29 @@ namespace OpenSim.Region.CoreModules.World.Land } } } - + master.LandData.Dwell += slave.LandData.Dwell; removeLandObject(slave.LandData.LocalID); UpdateLandObject(master.LandData.LocalID, master.LandData); } + public ILandObject GetLandObject(UUID globalID) + { + lock (m_landList) + { + int lid = -1; + if(m_landUUIDList.TryGetValue(globalID, out lid) && lid >= 0) + { + if (m_landList.ContainsKey(lid)) + { + return m_landList[lid]; + } + else + m_landUUIDList.Remove(globalID); // auto heal + } + } + return null; + } + public ILandObject GetLandObject(int parcelLocalID) { lock (m_landList) @@ -824,7 +987,7 @@ namespace OpenSim.Region.CoreModules.World.Land { try { - return m_landList[m_landIDList[x / 4, y / 4]]; + return m_landList[m_landIDList[x / LandUnit, y / LandUnit]]; } catch (IndexOutOfRangeException) { @@ -1257,7 +1420,7 @@ namespace OpenSim.Region.CoreModules.World.Land { if (!temp.Contains(currentParcel)) { - if (!currentParcel.IsEitherBannedOrRestricted(remote_client.AgentId)) + if (!currentParcel.IsBannedFromLand(remote_client.AgentId)) { currentParcel.ForceUpdateLandInfo(); temp.Add(currentParcel); @@ -1351,7 +1514,7 @@ namespace OpenSim.Region.CoreModules.World.Land public void ClientOnParcelObjectOwnerRequest(int local_id, IClientAPI remote_client) { - ILandObject land; + ILandObject land = null; lock (m_landList) { m_landList.TryGetValue(local_id, out land); @@ -1360,7 +1523,7 @@ namespace OpenSim.Region.CoreModules.World.Land if (land != null) { m_scene.EventManager.TriggerParcelPrimCountUpdate(); - m_landList[local_id].SendLandObjectOwners(remote_client); + land.SendLandObjectOwners(remote_client); } else { @@ -1370,7 +1533,7 @@ namespace OpenSim.Region.CoreModules.World.Land public void ClientOnParcelGodForceOwner(int local_id, UUID ownerID, IClientAPI remote_client) { - ILandObject land; + ILandObject land = null; lock (m_landList) { m_landList.TryGetValue(local_id, out land); @@ -1393,7 +1556,7 @@ namespace OpenSim.Region.CoreModules.World.Land public void ClientOnParcelAbandonRequest(int local_id, IClientAPI remote_client) { - ILandObject land; + ILandObject land = null; lock (m_landList) { m_landList.TryGetValue(local_id, out land); @@ -1417,7 +1580,7 @@ namespace OpenSim.Region.CoreModules.World.Land public void ClientOnParcelReclaim(int local_id, IClientAPI remote_client) { - ILandObject land; + ILandObject land = null; lock (m_landList) { m_landList.TryGetValue(local_id, out land); @@ -1503,17 +1666,16 @@ namespace OpenSim.Region.CoreModules.World.Land void ClientOnParcelDeedToGroup(int parcelLocalID, UUID groupID, IClientAPI remote_client) { - ILandObject land; + ILandObject land = null; lock (m_landList) { m_landList.TryGetValue(parcelLocalID, out land); } - if (!m_scene.Permissions.CanDeedParcel(remote_client.AgentId, land)) - return; - if (land != null) { + if (!m_scene.Permissions.CanDeedParcel(remote_client.AgentId, land)) + return; land.DeedToGroup(groupID); } } @@ -1587,8 +1749,7 @@ namespace OpenSim.Region.CoreModules.World.Land private void IncomingLandObjectFromStorage(LandData data) { - ILandObject new_land = new LandObject(data.OwnerID, data.IsGroupOwned, m_scene); - new_land.LandData = data.Copy(); + ILandObject new_land = new LandObject(data.OwnerID, data.IsGroupOwned, m_scene, data); new_land.SetLandBitmapFromByteArray(); AddLandObject(new_land); @@ -1686,26 +1847,23 @@ namespace OpenSim.Region.CoreModules.World.Land private void EventManagerOnRegisterCaps(UUID agentID, Caps caps) { - //string capsBase = "/CAPS/" + UUID.Random(); - string capsBase = "/CAPS/" + caps.CapsObjectPath; + string cap = "/CAPS/" + UUID.Random(); caps.RegisterHandler( "RemoteParcelRequest", new RestStreamHandler( - "POST", - capsBase, + "POST", cap, (request, path, param, httpRequest, httpResponse) => RemoteParcelRequest(request, path, param, agentID, caps), "RemoteParcelRequest", agentID.ToString())); - UUID parcelCapID = UUID.Random(); + cap = "/CAPS/" + UUID.Random(); caps.RegisterHandler( "ParcelPropertiesUpdate", new RestStreamHandler( - "POST", - "/CAPS/" + parcelCapID, - (request, path, param, httpRequest, httpResponse) - => ProcessPropertiesUpdate(request, path, param, agentID, caps), + "POST", cap, + (request, path, param, httpRequest, httpResponse) + => ProcessPropertiesUpdate(request, path, param, agentID, caps), "ParcelPropertiesUpdate", agentID.ToString())); } @@ -1736,7 +1894,7 @@ namespace OpenSim.Region.CoreModules.World.Land land_update.MusicURL = properties.MusicURL; land_update.Name = properties.Name; land_update.ParcelFlags = (uint) properties.ParcelFlags; - land_update.PassHours = (int) properties.PassHours; + land_update.PassHours = properties.PassHours; land_update.PassPrice = (int) properties.PassPrice; land_update.SalePrice = (int) properties.SalePrice; land_update.SnapshotID = properties.SnapshotID; @@ -1763,7 +1921,7 @@ namespace OpenSim.Region.CoreModules.World.Land land_update.GroupAVSounds = true; } - ILandObject land; + ILandObject land = null; lock (m_landList) { m_landList.TryGetValue(parcelID, out land); @@ -1900,7 +2058,13 @@ namespace OpenSim.Region.CoreModules.World.Land // for this region or for somewhere else? if (extLandData.RegionHandle == m_scene.RegionInfo.RegionHandle) { - extLandData.LandData = this.GetLandObject(extLandData.X, extLandData.Y).LandData; + ILandObject extLandObject = this.GetLandObject(extLandData.X, extLandData.Y); + if (extLandObject == null) + { + m_log.DebugFormat("[LAND MANAGEMENT MODULE]: ParcelInfoRequest: a FakeParcelID points to outside the region"); + return null; + } + extLandData.LandData = extLandObject.LandData; extLandData.RegionAccess = m_scene.RegionInfo.AccessLevel; } else @@ -1926,6 +2090,9 @@ namespace OpenSim.Region.CoreModules.World.Land if (data.RegionHandle == m_scene.RegionInfo.RegionHandle) { info = new GridRegion(m_scene.RegionInfo); + IDwellModule dwellModule = m_scene.RequestModuleInterface(); + if (dwellModule != null) + data.LandData.Dwell = dwellModule.GetDwell(data.LandData); } else { @@ -1951,7 +2118,7 @@ namespace OpenSim.Region.CoreModules.World.Land public void setParcelOtherCleanTime(IClientAPI remoteClient, int localID, int otherCleanTime) { - ILandObject land; + ILandObject land = null; lock (m_landList) { m_landList.TryGetValue(localID, out land); @@ -2054,12 +2221,12 @@ namespace OpenSim.Region.CoreModules.World.Land ((Scene)client.Scene).TryGetScenePresence(client.AgentId, out parcelManager); System.Threading.Timer Timer; - if (targetAvatar.GodController.UserLevel == 0) + if (targetAvatar.GodController.UserLevel < 200) { ILandObject land = ((Scene)client.Scene).LandChannel.GetLandObject(targetAvatar.AbsolutePosition.X, targetAvatar.AbsolutePosition.Y); if (!((Scene)client.Scene).Permissions.CanEditParcelProperties(client.AgentId, land, GroupPowers.LandEjectAndFreeze, true)) return; - if (flags == 0) + if ((flags & 1) == 0) // only lowest bit has meaning for now { targetAvatar.AllowMovement = false; targetAvatar.ControllingClient.SendAlertMessage(parcelManager.Firstname + " " + parcelManager.Lastname + " has frozen you for 30 seconds. You cannot move or interact with the world."); @@ -2111,7 +2278,7 @@ namespace OpenSim.Region.CoreModules.World.Land Vector3 pos = m_scene.GetNearestAllowedPosition(targetAvatar, land); - targetAvatar.TeleportWithMomentum(pos, null); + targetAvatar.TeleportOnEject(pos); targetAvatar.ControllingClient.SendAlertMessage("You have been ejected by " + parcelManager.Firstname + " " + parcelManager.Lastname); parcelManager.ControllingClient.SendAlertMessage("Avatar Ejected."); @@ -2248,7 +2415,7 @@ namespace OpenSim.Region.CoreModules.World.Land if (!ConsoleUtil.TryParseConsoleInt(MainConsole.Instance, args[2], out landLocalId)) return; - ILandObject lo; + ILandObject lo = null; lock (m_landList) { diff --git a/OpenSim/Region/CoreModules/World/Land/LandObject.cs b/OpenSim/Region/CoreModules/World/Land/LandObject.cs index 2b5cb31eeb..2c9ff00c6a 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandObject.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandObject.cs @@ -58,6 +58,7 @@ namespace OpenSim.Region.CoreModules.World.Land protected ExpiringCache m_groupMemberCache = new ExpiringCache(); protected TimeSpan m_groupMemberCacheTimeout = TimeSpan.FromSeconds(30); // cache invalidation after 30 seconds + IDwellModule m_dwellModule; private bool[,] m_landBitmap; public bool[,] LandBitmap @@ -268,27 +269,46 @@ namespace OpenSim.Region.CoreModules.World.Land { LandData = landData.Copy(); m_scene = scene; + m_scene.EventManager.OnFrame += OnFrame; + m_dwellModule = m_scene.RequestModuleInterface(); } - public LandObject(UUID owner_id, bool is_group_owned, Scene scene) + public LandObject(UUID owner_id, bool is_group_owned, Scene scene, LandData data = null) { m_scene = scene; if (m_scene == null) LandBitmap = new bool[Constants.RegionSize / landUnit, Constants.RegionSize / landUnit]; else + { LandBitmap = new bool[m_scene.RegionInfo.RegionSizeX / landUnit, m_scene.RegionInfo.RegionSizeY / landUnit]; + m_dwellModule = m_scene.RequestModuleInterface(); + } + + if(data == null) + LandData = new LandData(); + else + LandData = data; - LandData = new LandData(); LandData.OwnerID = owner_id; if (is_group_owned) LandData.GroupID = owner_id; - else - LandData.GroupID = UUID.Zero; + LandData.IsGroupOwned = is_group_owned; + if(m_dwellModule == null) + LandData.Dwell = 0; + m_scene.EventManager.OnFrame += OnFrame; } + public void Clear() + { + if(m_scene != null) + m_scene.EventManager.OnFrame -= OnFrame; + LandData = null; + } + + #endregion #region Member Functions @@ -520,7 +540,8 @@ namespace OpenSim.Region.CoreModules.World.Land ParcelFlags.UseEstateVoiceChan); } - if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId,this, GroupPowers.LandManagePasses, false)) + // don't allow passes on group owned until we can give money to groups + if (!newData.IsGroupOwned && m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId,this, GroupPowers.LandManagePasses, false)) { newData.PassHours = args.PassHours; newData.PassPrice = args.PassPrice; @@ -612,7 +633,7 @@ namespace OpenSim.Region.CoreModules.World.Land public bool CanBeOnThisLand(UUID avatar, float posHeight) { - if (posHeight < LandChannel.BAN_LINE_SAFETY_HEIGHT && IsBannedFromLand(avatar)) + if (posHeight < m_scene.LandChannel.BanLineSafeHeight && IsBannedFromLand(avatar)) { return false; } @@ -1375,9 +1396,9 @@ namespace OpenSim.Region.CoreModules.World.Land byte[] tempConvertArr = new byte[LandBitmap.GetLength(0) * LandBitmap.GetLength(1) / 8]; int tempByte = 0; - int i, byteNum = 0; + int byteNum = 0; int mask = 1; - i = 0; + for (int y = 0; y < LandBitmap.GetLength(1); y++) { for (int x = 0; x < LandBitmap.GetLength(0); x++) @@ -1439,9 +1460,9 @@ namespace OpenSim.Region.CoreModules.World.Land for (int i = 0; i < bitmapLen; i++) { tempByte = LandData.Bitmap[i]; - for (int bitNum = 0; bitNum < 8; bitNum++) + for (int bitmask = 0x01; bitmask < 0x100; bitmask = bitmask << 1) { - bool bit = Convert.ToBoolean(Convert.ToByte(tempByte >> bitNum) & (byte) 1); + bool bit = (tempByte & bitmask) == bitmask; try { tempConvertMap[x, y] = bit; @@ -1812,6 +1833,37 @@ namespace OpenSim.Region.CoreModules.World.Land ExpireAccessList(); m_expiryCounter = 0; } + + // need to update dwell here bc landdata has no parent info + if(LandData != null && m_dwellModule != null) + { + double now = Util.GetTimeStampMS(); + double elapsed = now - LandData.LastDwellTimeMS; + if(elapsed > 150000) //2.5 minutes resolution / throttle + { + float dwell = LandData.Dwell; + double cur = dwell * 60000.0; + double decay = 1.5e-8 * cur * elapsed; + cur -= decay; + if(cur < 0) + cur = 0; + + UUID lgid = LandData.GlobalID; + m_scene.ForEachRootScenePresence(delegate(ScenePresence sp) + { + if(sp.IsNPC || sp.IsLoggingIn || sp.IsDeleted || sp.currentParcelUUID != lgid) + return; + cur += (now - sp.ParcelDwellTickMS); + sp.ParcelDwellTickMS = now; + }); + + float newdwell = (float)(cur * 1.666666666667e-5); + LandData.Dwell = newdwell; + + if(Math.Abs(newdwell - dwell) >= 0.9) + m_scene.EventManager.TriggerLandObjectAdded(this); + } + } } private void ExpireAccessList() @@ -1834,7 +1886,7 @@ namespace OpenSim.Region.CoreModules.World.Land if (land.LandData.LocalID == LandData.LocalID) { Vector3 pos = m_scene.GetNearestAllowedPosition(presence, land); - presence.TeleportWithMomentum(pos, null); + presence.TeleportOnEject(pos); presence.ControllingClient.SendAlertMessage("You have been ejected from this land"); } } diff --git a/OpenSim/Region/CoreModules/World/LegacyMap/MapImageModule.cs b/OpenSim/Region/CoreModules/World/LegacyMap/MapImageModule.cs index b927cfa7ea..ce82c2658c 100644 --- a/OpenSim/Region/CoreModules/World/LegacyMap/MapImageModule.cs +++ b/OpenSim/Region/CoreModules/World/LegacyMap/MapImageModule.cs @@ -153,7 +153,7 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap using (Bitmap mapbmp = CreateMapTile()) { if (mapbmp != null) - return OpenJPEG.EncodeFromImage(mapbmp, true); + return OpenJPEG.EncodeFromImage(mapbmp, false); } } catch (Exception e) // LEGIT: Catching problems caused by OpenJPEG p/invoke diff --git a/OpenSim/Region/CoreModules/World/LegacyMap/ShadedMapTileRenderer.cs b/OpenSim/Region/CoreModules/World/LegacyMap/ShadedMapTileRenderer.cs index 708286c906..0b37179710 100644 --- a/OpenSim/Region/CoreModules/World/LegacyMap/ShadedMapTileRenderer.cs +++ b/OpenSim/Region/CoreModules/World/LegacyMap/ShadedMapTileRenderer.cs @@ -38,18 +38,20 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap { public class ShadedMapTileRenderer : IMapTileTerrainRenderer { - private static readonly Color WATER_COLOR = Color.FromArgb(29, 71, 95); - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly string LogHeader = "[SHADED MAPTILE RENDERER]"; private Scene m_scene; - //private IConfigSource m_config; // not used currently + private IConfigSource m_config; + private Color m_color_water; public void Initialise(Scene scene, IConfigSource config) { m_scene = scene; - // m_config = config; // not used currently + m_config = config; + + string[] configSections = new string[] { "Map", "Startup" }; + m_color_water = System.Drawing.ColorTranslator.FromHtml(Util.GetConfigVarFromSections(m_config, "MapColorWater", configSections, "#1D475F")); } public void TerrainToBitmap(Bitmap mapbmp) @@ -231,7 +233,7 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap try { - mapbmp.SetPixel(x, yr, WATER_COLOR); + mapbmp.SetPixel(x, yr, m_color_water); } catch (ArgumentException) { diff --git a/OpenSim/Region/CoreModules/World/LegacyMap/TexturedMapTileRenderer.cs b/OpenSim/Region/CoreModules/World/LegacyMap/TexturedMapTileRenderer.cs index 4b3ee182eb..c71f5c0d89 100644 --- a/OpenSim/Region/CoreModules/World/LegacyMap/TexturedMapTileRenderer.cs +++ b/OpenSim/Region/CoreModules/World/LegacyMap/TexturedMapTileRenderer.cs @@ -130,21 +130,19 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap // some hardcoded terrain UUIDs that work with SL 1.20 (the four default textures and "Blank"). // The color-values were choosen because they "look right" (at least to me) ;-) private static readonly UUID defaultTerrainTexture1 = new UUID("0bc58228-74a0-7e83-89bc-5c23464bcec5"); - private static readonly Color defaultColor1 = Color.FromArgb(165, 137, 118); private static readonly UUID defaultTerrainTexture2 = new UUID("63338ede-0037-c4fd-855b-015d77112fc8"); - private static readonly Color defaultColor2 = Color.FromArgb(69, 89, 49); private static readonly UUID defaultTerrainTexture3 = new UUID("303cd381-8560-7579-23f1-f0a880799740"); - private static readonly Color defaultColor3 = Color.FromArgb(162, 154, 141); private static readonly UUID defaultTerrainTexture4 = new UUID("53a2f406-4895-1d13-d541-d2e3b86bc19c"); - private static readonly Color defaultColor4 = Color.FromArgb(200, 200, 200); - - private static readonly Color WATER_COLOR = Color.FromArgb(29, 71, 95); #endregion - private Scene m_scene; - // private IConfigSource m_config; // not used currently + private IConfigSource m_config; + private Color m_color_water; + private Color m_color_1; + private Color m_color_2; + private Color m_color_3; + private Color m_color_4; // mapping from texture UUIDs to averaged color. This will contain 5-9 values, in general; new values are only // added when the terrain textures are changed in the estate dialog and a new map is generated (and will stay in @@ -156,12 +154,21 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap public void Initialise(Scene scene, IConfigSource source) { m_scene = scene; - // m_config = source; // not used currently + m_config = source; + + string[] configSections = new string[] { "Map", "Startup" }; + + m_color_water = System.Drawing.ColorTranslator.FromHtml(Util.GetConfigVarFromSections(m_config, "MapColorWater", configSections, "#1D475F")); + m_color_1 = System.Drawing.ColorTranslator.FromHtml(Util.GetConfigVarFromSections(m_config, "MapColor1", configSections, "#A58976")); + m_color_2 = System.Drawing.ColorTranslator.FromHtml(Util.GetConfigVarFromSections(m_config, "MapColor2", configSections, "#455931")); + m_color_3 = System.Drawing.ColorTranslator.FromHtml(Util.GetConfigVarFromSections(m_config, "MapColor3", configSections, "#A29A8D")); + m_color_4 = System.Drawing.ColorTranslator.FromHtml(Util.GetConfigVarFromSections(m_config, "MapColor4", configSections, "#C8C8C8")); + m_mapping = new Dictionary(); - m_mapping.Add(defaultTerrainTexture1, defaultColor1); - m_mapping.Add(defaultTerrainTexture2, defaultColor2); - m_mapping.Add(defaultTerrainTexture3, defaultColor3); - m_mapping.Add(defaultTerrainTexture4, defaultColor4); + m_mapping.Add(defaultTerrainTexture1, m_color_1); + m_mapping.Add(defaultTerrainTexture2, m_color_2); + m_mapping.Add(defaultTerrainTexture3, m_color_3); + m_mapping.Add(defaultTerrainTexture4, m_color_4); m_mapping.Add(Util.BLANK_TEXTURE_UUID, Color.White); } @@ -298,10 +305,10 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap RegionSettings settings = m_scene.RegionInfo.RegionSettings; // the four terrain colors as HSVs for interpolation - HSV hsv1 = new HSV(computeAverageColor(settings.TerrainTexture1, defaultColor1)); - HSV hsv2 = new HSV(computeAverageColor(settings.TerrainTexture2, defaultColor2)); - HSV hsv3 = new HSV(computeAverageColor(settings.TerrainTexture3, defaultColor3)); - HSV hsv4 = new HSV(computeAverageColor(settings.TerrainTexture4, defaultColor4)); + HSV hsv1 = new HSV(computeAverageColor(settings.TerrainTexture1, m_color_1)); + HSV hsv2 = new HSV(computeAverageColor(settings.TerrainTexture2, m_color_2)); + HSV hsv3 = new HSV(computeAverageColor(settings.TerrainTexture3, m_color_3)); + HSV hsv4 = new HSV(computeAverageColor(settings.TerrainTexture4, m_color_4)); float levelNElow = (float)settings.Elevation1NE; float levelNEhigh = (float)settings.Elevation2NE; @@ -417,7 +424,7 @@ namespace OpenSim.Region.CoreModules.World.LegacyMap heightvalue = 100f - (heightvalue * 100f) / 19f; // 0 - 19 => 100 - 0 - mapbmp.SetPixel(x, yr, WATER_COLOR); + mapbmp.SetPixel(x, yr, m_color_water); } } } diff --git a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs index 1070ae6403..f5aa40a856 100644 --- a/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs +++ b/OpenSim/Region/CoreModules/World/Media/Moap/MoapModule.cs @@ -256,6 +256,7 @@ namespace OpenSim.Region.CoreModules.World.Media.Moap SetPartMediaFlags(part, face, me != null); + part.ParentGroup.HasGroupChanged = true; part.ScheduleFullUpdate(); part.TriggerScriptChangedEvent(Changed.MEDIA); } @@ -461,6 +462,7 @@ namespace OpenSim.Region.CoreModules.World.Media.Moap UpdateMediaUrl(part, agentId); // Arguably, we could avoid sending a full update to the avatar that just changed the texture. + part.ParentGroup.HasGroupChanged = true; part.ScheduleFullUpdate(); part.TriggerScriptChangedEvent(Changed.MEDIA); @@ -539,6 +541,7 @@ namespace OpenSim.Region.CoreModules.World.Media.Moap UpdateMediaUrl(part, agentId); + part.ParentGroup.HasGroupChanged = true; part.ScheduleFullUpdate(); part.TriggerScriptChangedEvent(Changed.MEDIA); diff --git a/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs b/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs index 90d65c7101..6a8f4c04af 100644 --- a/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs +++ b/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs @@ -118,6 +118,11 @@ namespace OpenSim.Region.CoreModules.World.Objects.BuySell return false; SceneObjectGroup group = part.ParentGroup; + if(group == null || group.IsDeleted || group.inTransit) + return false; + + // make sure we are not buying a child part + part = group.RootPart; switch (saleType) { @@ -141,7 +146,7 @@ namespace OpenSim.Region.CoreModules.World.Objects.BuySell child.TriggerScriptChangedEvent(Changed.OWNER); child.ApplyNextOwnerPermissions(); } - group.AggregatePerms(); + group.InvalidateDeepEffectivePerms(); } part.ObjectSaleType = 0; @@ -157,18 +162,6 @@ namespace OpenSim.Region.CoreModules.World.Objects.BuySell break; case 2: // Sell a copy - Vector3 inventoryStoredPosition = new Vector3( - Math.Min(group.AbsolutePosition.X, m_scene.RegionInfo.RegionSizeX - 6), - Math.Min(group.AbsolutePosition.Y, m_scene.RegionInfo.RegionSizeY - 6), - group.AbsolutePosition.Z); - - Vector3 originalPosition = group.AbsolutePosition; - - group.AbsolutePosition = inventoryStoredPosition; - - string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(group); - group.AbsolutePosition = originalPosition; - uint perms = group.EffectiveOwnerPerms; if ((perms & (uint)PermissionMask.Transfer) == 0) @@ -185,6 +178,8 @@ namespace OpenSim.Region.CoreModules.World.Objects.BuySell return false; } + string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(group); + AssetBase asset = m_scene.CreateAsset( group.GetPartName(localID), group.GetPartDescription(localID), @@ -205,22 +200,21 @@ namespace OpenSim.Region.CoreModules.World.Objects.BuySell item.AssetType = asset.Type; item.InvType = (int)InventoryType.Object; item.Folder = categoryID; + + perms = group.CurrentAndFoldedNextPermissions(); + // apply parts inventory next perms + PermissionsUtil.ApplyNoModFoldedPermissions(perms, ref perms); + // change to next owner perms + perms &= part.NextOwnerMask; + // update folded + perms = PermissionsUtil.FixAndFoldPermissions(perms); - uint nextPerms=(perms & 7) << 13; - if ((nextPerms & (uint)PermissionMask.Copy) == 0) - perms &= ~(uint)PermissionMask.Copy; - if ((nextPerms & (uint)PermissionMask.Transfer) == 0) - perms &= ~(uint)PermissionMask.Transfer; - if ((nextPerms & (uint)PermissionMask.Modify) == 0) - perms &= ~(uint)PermissionMask.Modify; + item.BasePermissions = perms; + item.CurrentPermissions = perms; + item.NextPermissions = part.NextOwnerMask & perms; + item.EveryOnePermissions = part.EveryoneMask & perms; + item.GroupPermissions = part.GroupMask & perms; - item.BasePermissions = perms & part.NextOwnerMask; - item.CurrentPermissions = perms & part.NextOwnerMask; - item.NextPermissions = part.NextOwnerMask; - item.EveryOnePermissions = part.EveryoneMask & - part.NextOwnerMask; - item.GroupPermissions = part.GroupMask & - part.NextOwnerMask; item.Flags |= (uint)InventoryItemFlags.ObjectSlamPerm; item.CreationDate = Util.UnixTimeSinceEpoch(); diff --git a/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs b/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs index 79c47133be..3d786dda04 100644 --- a/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs +++ b/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs @@ -123,8 +123,8 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands "Objects", false, "delete object pos", - "delete object pos to ", - "Delete scene objects within the given area.", + "delete object pos ", + "Delete scene objects within the given volume.", ConsoleUtil.CoordHelp, HandleDeleteObject); @@ -162,8 +162,8 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands "Objects", false, "show object pos", - "show object pos [--full] to ", - "Show details of scene objects within the given area.", + "show object pos [--full] ", + "Show details of scene objects within give volume", "The --full option will print out information on all the parts of the object.\n" + "For yet more detailed part information, use the \"show part\" commands.\n" + ConsoleUtil.CoordHelp, @@ -189,8 +189,8 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands "Objects", false, "show part pos", - "show part pos to ", - "Show details of scene object parts within the given area.", + "show part pos ", + "Show details of scene object parts within the given volume.", ConsoleUtil.CoordHelp, HandleShowPartByPos); @@ -803,12 +803,15 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands else so = m_scene.GetSceneObjectGroup(localId); - if (so!= null && !so.IsAttachment) - deletes.Add(so); - - // if (deletes.Count == 0) - // m_console.OutputFormat("No objects were found with uuid {0}", match); - + if (so!= null) + { + deletes.Add(so); + if(so.IsAttachment) + { + requireConfirmation = true; + m_console.OutputFormat("Warning: object with uuid {0} is a attachment", uuid); + } + } break; case "name": @@ -904,11 +907,11 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands if (useRegex) { Regex nameRegex = new Regex(name); - searchAction = so => { if (nameRegex.IsMatch(so.Name)) { sceneObjects.Add(so); }}; + searchAction = so => { if (nameRegex.IsMatch(so.Name)) {if(!so.IsAttachment) sceneObjects.Add(so);}}; } else { - searchAction = so => { if (so.Name == name) { sceneObjects.Add(so); }}; + searchAction = so => { if (so.Name == name) {if(!so.IsAttachment) sceneObjects.Add(so);}}; } m_scene.ForEachSOG(searchAction); diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs index ab8fb514e8..45c1c561e7 100644 --- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs +++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs @@ -286,12 +286,14 @@ namespace OpenSim.Region.CoreModules.World.Permissions scenePermissions.OnRezObject += CanRezObject; scenePermissions.OnObjectEntry += CanObjectEntry; + scenePermissions.OnObjectEnterWithScripts += OnObjectEnterWithScripts; scenePermissions.OnDuplicateObject += CanDuplicateObject; scenePermissions.OnDeleteObjectByIDs += CanDeleteObjectByIDs; scenePermissions.OnDeleteObject += CanDeleteObject; scenePermissions.OnEditObjectByIDs += CanEditObjectByIDs; scenePermissions.OnEditObject += CanEditObject; + scenePermissions.OnEditObjectPerms += CanEditObjectPerms; scenePermissions.OnInventoryTransfer += CanInventoryTransfer; scenePermissions.OnMoveObject += CanMoveObject; scenePermissions.OnTakeObject += CanTakeObject; @@ -381,6 +383,8 @@ namespace OpenSim.Region.CoreModules.World.Permissions scenePermissions.OnRezObject -= CanRezObject; scenePermissions.OnObjectEntry -= CanObjectEntry; + scenePermissions.OnObjectEnterWithScripts -= OnObjectEnterWithScripts; + scenePermissions.OnReturnObjects -= CanReturnObjects; scenePermissions.OnDuplicateObject -= CanDuplicateObject; @@ -388,6 +392,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions scenePermissions.OnDeleteObject -= CanDeleteObject; scenePermissions.OnEditObjectByIDs -= CanEditObjectByIDs; scenePermissions.OnEditObject -= CanEditObject; + scenePermissions.OnEditObjectPerms -= CanEditObjectPerms; scenePermissions.OnInventoryTransfer -= CanInventoryTransfer; scenePermissions.OnMoveObject -= CanMoveObject; scenePermissions.OnTakeObject -= CanTakeObject; @@ -1384,6 +1389,35 @@ namespace OpenSim.Region.CoreModules.World.Permissions return true; } + private bool CanEditObjectPerms(SceneObjectGroup sog, UUID userID) + { + DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); + if (m_bypassPermissions) return m_bypassPermissionsValue; + + if (sog == null) + return false; + + if(sog.OwnerID == userID || IsAdministrator(userID)) + return true; + + UUID sogGroupID = sog.GroupID; + if(sogGroupID == UUID.Zero || sogGroupID != sog.OwnerID) + return false; + + uint perms = sog.EffectiveOwnerPerms; + if((perms & (uint)PermissionMask.Modify) == 0) + return false; + + ulong powers = 0; + if(GroupMemberPowers(sogGroupID, userID, ref powers)) + { + if((powers & (ulong)GroupPowers.ObjectManipulate) != 0) + return true; + } + + return false; + } + private bool CanEditObjectInventory(UUID objectID, UUID userID) { DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); @@ -1627,6 +1661,54 @@ namespace OpenSim.Region.CoreModules.World.Permissions return false; } + private bool OnObjectEnterWithScripts(SceneObjectGroup sog, ILandObject parcel) + { + DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); + + if(sog == null || sog.IsDeleted) + return false; + + if (m_bypassPermissions) + return m_bypassPermissionsValue; + + if (parcel == null) + return true; + + int checkflags = ((int)ParcelFlags.AllowAPrimitiveEntry); + bool scripts = (sog.ScriptCount() > 0); + if(scripts) + checkflags |= ((int)ParcelFlags.AllowOtherScripts); + + if ((parcel.LandData.Flags & checkflags) == checkflags) + return true; + + UUID userID = sog.OwnerID; + LandData landdata = parcel.LandData; + + if (landdata.OwnerID == userID) + return true; + + if (IsAdministrator(userID)) + return true; + + UUID landGroupID = landdata.GroupID; + if (landGroupID != UUID.Zero) + { + checkflags = (int)ParcelFlags.AllowGroupObjectEntry; + if(scripts) + checkflags |= ((int)ParcelFlags.AllowGroupScripts); + + if ((parcel.LandData.Flags & checkflags) == checkflags) + return IsGroupMember(landGroupID, userID, 0); + + if (landdata.IsGroupOwned && IsGroupMember(landGroupID, userID, (ulong)GroupPowers.AllowRez)) + return true; + } + + //Otherwise, false! + return false; + } + private bool CanReturnObjects(ILandObject land, ScenePresence sp, List objects) { DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); @@ -1970,7 +2052,10 @@ namespace OpenSim.Region.CoreModules.World.Permissions uint perms = GetObjectPermissions(sp, sog, true); if((perms & (uint)PermissionMask.Copy) == 0) + { + sp.ControllingClient.SendAgentAlertMessage("Copying this item has been denied by the permissions system", false); return false; + } if(sog.OwnerID != sp.UUID && (perms & (uint)PermissionMask.Transfer) == 0) return false; @@ -2234,23 +2319,31 @@ namespace OpenSim.Region.CoreModules.World.Permissions if (sog == null) return false; - uint perms = GetObjectPermissions(userID, sog, true); - if((perms & (uint)PermissionMask.Modify) == 0) + if(sog.OwnerID == userID || IsAdministrator(userID)) + return true; + + if(sog.IsAttachment) + return false; + + UUID sogGroupID = sog.GroupID; + + if(sogGroupID == UUID.Zero || sogGroupID != sog.OwnerID) return false; TaskInventoryItem ti = part.Inventory.GetInventoryItem(itemID); if(ti == null) return false; - uint itperms = GetObjectItemPermissions(userID, ti); + ulong powers = 0; + if(GroupMemberPowers(sogGroupID, userID, ref powers)) + { + if((powers & (ulong)GroupPowers.ObjectManipulate) != 0) + return true; - if((itperms & (uint)PermissionMask.Copy) == 0) - return false; - - if(sog.OwnerID != userID && (itperms & (uint)PermissionMask.Transfer) == 0) - return false; - - return true; + if((ti.EveryonePermissions & (uint)PermissionMask.Copy) != 0) + return true; + } + return false; } // object inventory to object inventory item drag and drop diff --git a/OpenSim/Region/CoreModules/World/Serialiser/SerialiseObjects.cs b/OpenSim/Region/CoreModules/World/Serialiser/SerialiseObjects.cs index 65f464afea..0d84a1f0aa 100644 --- a/OpenSim/Region/CoreModules/World/Serialiser/SerialiseObjects.cs +++ b/OpenSim/Region/CoreModules/World/Serialiser/SerialiseObjects.cs @@ -69,7 +69,6 @@ namespace OpenSim.Region.CoreModules.World.Serialiser MemoryStream stream = new MemoryStream(); XmlTextWriter formatter = new XmlTextWriter(stream, Encoding.UTF8); XmlDocument doc = new XmlDocument(); - doc.LoadXml(xmlstream); formatter.Formatting = Formatting.Indented; doc.WriteContentTo(formatter); diff --git a/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs b/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs index 2b7db189a7..64f46df01c 100644 --- a/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs +++ b/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs @@ -125,20 +125,23 @@ namespace OpenSim.Region.CoreModules.World.Sound #region ISoundModule public virtual void PlayAttachedSound( - UUID soundID, UUID ownerID, UUID objectID, double gain, Vector3 position, byte flags, float radius) + UUID soundID, UUID ownerID, UUID objectID, double gain, Vector3 position, byte flags) { SceneObjectPart part; if (!m_scene.TryGetSceneObjectPart(objectID, out part)) return; - SceneObjectGroup grp = part.ParentGroup; - - if (radius == 0) - radius = MaxDistance; + if (part.SoundRadius == 0) + part.SoundRadius = MaxDistance; + part.SoundFlags = 0; if (part.SoundQueueing) flags |= (byte)SoundFlags.QUEUE; + SceneObjectGroup grp = part.ParentGroup; + if(grp == null | grp.IsDeleted) + return; + if (grp.IsAttachment) { ScenePresence ssp = null; @@ -164,8 +167,9 @@ namespace OpenSim.Region.CoreModules.World.Sound } public virtual void TriggerSound( - UUID soundId, UUID ownerID, UUID objectID, UUID parentID, double gain, Vector3 position, UInt64 handle, float radius) + UUID soundId, UUID ownerID, UUID objectID, UUID parentID, double gain, Vector3 position, UInt64 handle) { + float radius; SceneObjectPart part; ScenePresence ssp = null; if (!m_scene.TryGetSceneObjectPart(objectID, out part)) @@ -174,38 +178,36 @@ namespace OpenSim.Region.CoreModules.World.Sound return; if (!ssp.ParcelAllowThisAvatarSounds) return; + + radius = MaxDistance; } else { SceneObjectGroup grp = part.ParentGroup; - if (grp.IsAttachment) + if(grp.IsAttachment) { - if (!m_scene.TryGetScenePresence(grp.AttachedAvatar, out ssp)) + if(!m_scene.TryGetScenePresence(grp.AttachedAvatar, out ssp)) return; - if (!ssp.ParcelAllowThisAvatarSounds) + if(!ssp.ParcelAllowThisAvatarSounds) return; -/* mantis 7942: coment out to allow trigger in HUDs to send sounds to all - if (grp.HasPrivateAttachmentPoint) - { - ssp.ControllingClient.SendTriggeredSound(soundId, ownerID, - objectID, parentID, handle, position, - (float)gain); - return; - } -*/ } + + radius = (float)part.SoundRadius; + if(radius == 0) + { + radius = MaxDistance; + part.SoundRadius = MaxDistance; + } + part.SoundFlags = 0; } - if (radius == 0) - radius = MaxDistance; - + radius *= radius; m_scene.ForEachRootScenePresence(delegate(ScenePresence sp) { - double dis = Util.GetDistanceTo(sp.AbsolutePosition, position); - if (dis > radius) // Max audio distance + if (Vector3.DistanceSquared(sp.AbsolutePosition, position) > radius) // Max audio distance return; sp.ControllingClient.SendTriggeredSound(soundId, ownerID, @@ -225,16 +227,14 @@ namespace OpenSim.Region.CoreModules.World.Sound private static void StopSound(SceneObjectPart m_host) { -// m_host.AdjustSoundGain(0); m_host.Sound = UUID.Zero; m_host.SoundFlags = (byte)SoundFlags.STOP; - m_host.SoundRadius = 0; m_host.SoundGain = 0; m_host.ScheduleFullUpdate(); m_host.SendFullUpdateToAllClients(); } - public virtual void PreloadSound(UUID objectID, UUID soundID, float radius) + public virtual void PreloadSound(UUID objectID, UUID soundID) { SceneObjectPart part; if (soundID == UUID.Zero @@ -243,12 +243,17 @@ namespace OpenSim.Region.CoreModules.World.Sound return; } + float radius = (float)part.SoundRadius; if (radius == 0) + { radius = MaxDistance; + part.SoundRadius = radius; + } + radius *= 4.0f * radius; // avatars and prims do move m_scene.ForEachRootScenePresence(delegate(ScenePresence sp) { - if (Util.GetDistanceTo(sp.AbsolutePosition, part.AbsolutePosition) < radius) + if (Vector3.DistanceSquared(sp.AbsolutePosition, part.AbsolutePosition) < radius) sp.ControllingClient.SendPreLoadSound(objectID, objectID, soundID); }); } @@ -262,7 +267,7 @@ namespace OpenSim.Region.CoreModules.World.Sound // 20080530 Updated to remove code duplication // 20080530 Stop sound if there is one, otherwise volume only changes don't work public void LoopSound(UUID objectID, UUID soundID, - double volume, double radius, bool isMaster, bool isSlave) + double volume, bool isMaster, bool isSlave) { SceneObjectPart m_host; if (!m_scene.TryGetSceneObjectPart(objectID, out m_host)) @@ -280,14 +285,15 @@ namespace OpenSim.Region.CoreModules.World.Sound m_host.Sound = soundID; m_host.SoundGain = volume; m_host.SoundFlags = iflags; - m_host.SoundRadius = radius; + if (m_host.SoundRadius == 0) + m_host.SoundRadius = MaxDistance; m_host.ScheduleFullUpdate(); m_host.SendFullUpdateToAllClients(); } public void SendSound(UUID objectID, UUID soundID, double volume, - bool triggered, byte flags, float radius, bool useMaster, + bool triggered, byte flags, bool useMaster, bool isMaster) { if (soundID == UUID.Zero) @@ -305,7 +311,7 @@ namespace OpenSim.Region.CoreModules.World.Sound ulong regionHandle = m_scene.RegionInfo.RegionHandle; if(triggered) - TriggerSound(soundID, part.OwnerID, part.UUID, parentID, volume, position, regionHandle, radius); + TriggerSound(soundID, part.OwnerID, part.UUID, parentID, volume, position, regionHandle); else { byte bflags = 0; @@ -315,7 +321,7 @@ namespace OpenSim.Region.CoreModules.World.Sound // TODO check viewer seems to accept both if (useMaster) bflags |= (byte)SoundFlags.SYNC_SLAVE; - PlayAttachedSound(soundID, part.OwnerID, part.UUID, volume, position, bflags, radius); + PlayAttachedSound(soundID, part.OwnerID, part.UUID, volume, position, bflags); } } @@ -336,6 +342,7 @@ namespace OpenSim.Region.CoreModules.World.Sound if (dis > MaxDistance) // Max audio distance return; + else if (!Util.IsInsideBox(sp.AbsolutePosition, min, max)) return; diff --git a/OpenSim/Region/CoreModules/World/Vegetation/VegetationModule.cs b/OpenSim/Region/CoreModules/World/Vegetation/VegetationModule.cs index 167f6b50d2..4cee7a5f3b 100644 --- a/OpenSim/Region/CoreModules/World/Vegetation/VegetationModule.cs +++ b/OpenSim/Region/CoreModules/World/Vegetation/VegetationModule.cs @@ -107,7 +107,7 @@ namespace OpenSim.Region.CoreModules.World.Vegetation sceneObject.SetGroup(groupID, null); m_scene.AddNewSceneObject(sceneObject, true); - sceneObject.AggregatePerms(); + sceneObject.InvalidateDeepEffectivePerms(); return sceneObject; } diff --git a/OpenSim/Region/CoreModules/World/Warp3DMap/Perlin.cs b/OpenSim/Region/CoreModules/World/Warp3DMap/Perlin.cs index 522a7eb120..2279b7688a 100644 --- a/OpenSim/Region/CoreModules/World/Warp3DMap/Perlin.cs +++ b/OpenSim/Region/CoreModules/World/Warp3DMap/Perlin.cs @@ -103,41 +103,39 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap public static float noise2(float x, float y) { - int bx0, bx1, by0, by1, b00, b10, b01, b11; + int bx, by, b00, b10, b01, b11; float rx0, rx1, ry0, ry1, sx, sy, a, b, t, u, v; int i, j; t = x + N; - bx0 = ((int)t) & BM; - bx1 = (bx0 + 1) & BM; rx0 = t - (int)t; - rx1 = rx0 - 1f; + bx = ((int)t) & BM; + i = p[bx]; + bx = (bx + 1) & BM; + j = p[bx]; t = y + N; - by0 = ((int)t) & BM; - by1 = (by0 + 1) & BM; ry0 = t - (int)t; - ry1 = ry0 - 1f; + by = ((int)t) & BM; + b00 = p[i + by]; + b10 = p[j + by]; - i = p[bx0]; - j = p[bx1]; - - b00 = p[i + by0]; - b10 = p[j + by0]; - b01 = p[i + by1]; - b11 = p[j + by1]; + by = (by + 1) & BM; + b01 = p[i + by]; + b11 = p[j + by]; sx = s_curve(rx0); - sy = s_curve(ry0); - u = rx0 * g2[b00, 0] + ry0 * g2[b00, 1]; + rx1 = rx0 - 1f; v = rx1 * g2[b10, 0] + ry0 * g2[b10, 1]; a = Utils.Lerp(u, v, sx); + ry1 = ry0 - 1f; u = rx0 * g2[b01, 0] + ry1 * g2[b01, 1]; v = rx1 * g2[b11, 0] + ry1 * g2[b11, 1]; b = Utils.Lerp(u, v, sx); + sy = s_curve(ry0); return Utils.Lerp(a, b, sy); } @@ -202,12 +200,10 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap public static float turbulence1(float x, float freq) { float t; - float v; for (t = 0f; freq >= 1f; freq *= 0.5f) { - v = freq * x; - t += noise1(v) / freq; + t += noise1(freq * x) / freq; } return t; } @@ -215,28 +211,20 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap public static float turbulence2(float x, float y, float freq) { float t; - Vector2 vec; for (t = 0f; freq >= 1f; freq *= 0.5f) - { - vec.X = freq * x; - vec.Y = freq * y; - t += noise2(vec.X, vec.Y) / freq; - } + t += noise2(freq * x, freq * y) / freq; + return t; } public static float turbulence3(float x, float y, float z, float freq) { float t; - Vector3 vec; for (t = 0f; freq >= 1f; freq *= 0.5f) { - vec.X = freq * x; - vec.Y = freq * y; - vec.Z = freq * z; - t += noise3(vec.X, vec.Y, vec.Z) / freq; + t += noise3(freq * x, freq * y, freq * z) / freq; } return t; } @@ -244,23 +232,28 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap private static void normalize2(float[,] v, int i) { float s; + float a = v[i, 0]; + float b = v[i, 1]; - s = (float)Math.Sqrt(v[i, 0] * v[i, 0] + v[i, 1] * v[i, 1]); + s = (float)Math.Sqrt(a * a + b * b); s = 1.0f / s; - v[i, 0] = v[i, 0] * s; - v[i, 1] = v[i, 1] * s; + v[i, 0] = a * s; + v[i, 1] = b * s; } private static void normalize3(float[,] v, int i) { float s; + float a = v[i, 0]; + float b = v[i, 1]; + float c = v[i, 2]; - s = (float)Math.Sqrt(v[i, 0] * v[i, 0] + v[i, 1] * v[i, 1] + v[i, 2] * v[i, 2]); + s = (float)Math.Sqrt(a * a + b * b + c * c); s = 1.0f / s; - v[i, 0] = v[i, 0] * s; - v[i, 1] = v[i, 1] * s; - v[i, 2] = v[i, 2] * s; + v[i, 0] = a * s; + v[i, 1] = b * s; + v[i, 2] = c * s; } private static float s_curve(float t) diff --git a/OpenSim/Region/CoreModules/World/Warp3DMap/TerrainSplat.cs b/OpenSim/Region/CoreModules/World/Warp3DMap/TerrainSplat.cs index 226b330bda..4b9f207d71 100644 --- a/OpenSim/Region/CoreModules/World/Warp3DMap/TerrainSplat.cs +++ b/OpenSim/Region/CoreModules/World/Warp3DMap/TerrainSplat.cs @@ -80,9 +80,12 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap /// Note we create a 256x256 dimension texture even if the actual terrain is larger. /// - public static Bitmap Splat(ITerrainChannel terrain, - UUID[] textureIDs, float[] startHeights, float[] heightRanges, - Vector3d regionPosition, IAssetService assetService, bool textureTerrain) + public static Bitmap Splat(ITerrainChannel terrain, UUID[] textureIDs, + float[] startHeights, float[] heightRanges, + uint regionPositionX, uint regionPositionY, + IAssetService assetService, IJ2KDecoder decoder, + bool textureTerrain, bool averagetextureTerrain, + int twidth, int theight) { Debug.Assert(textureIDs.Length == 4); Debug.Assert(startHeights.Length == 4); @@ -90,70 +93,80 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap Bitmap[] detailTexture = new Bitmap[4]; + byte[] mapColorsRed = new byte[4]; + byte[] mapColorsGreen = new byte[4]; + byte[] mapColorsBlue = new byte[4]; + + bool usecolors = false; + if (textureTerrain) { // Swap empty terrain textureIDs with default IDs - for (int i = 0; i < textureIDs.Length; i++) + for(int i = 0; i < textureIDs.Length; i++) { - if (textureIDs[i] == UUID.Zero) + if(textureIDs[i] == UUID.Zero) textureIDs[i] = DEFAULT_TERRAIN_DETAIL[i]; } #region Texture Fetching - if (assetService != null) + if(assetService != null) { - for (int i = 0; i < 4; i++) + for(int i = 0; i < 4; i++) { - AssetBase asset; - UUID cacheID = UUID.Combine(TERRAIN_CACHE_MAGIC, textureIDs[i]); + AssetBase asset = null; + + // asset cache indexes are strings + string cacheName ="MAP-Patch" + textureIDs[i].ToString(); // Try to fetch a cached copy of the decoded/resized version of this texture - asset = assetService.GetCached(cacheID.ToString()); - if (asset != null) + asset = assetService.GetCached(cacheName); + if(asset != null) { try { - using (System.IO.MemoryStream stream = new System.IO.MemoryStream(asset.Data)) + using(System.IO.MemoryStream stream = new System.IO.MemoryStream(asset.Data)) detailTexture[i] = (Bitmap)Image.FromStream(stream); + + if(detailTexture[i].PixelFormat != PixelFormat.Format24bppRgb || + detailTexture[i].Width != 16 || detailTexture[i].Height != 16) + { + detailTexture[i].Dispose(); + detailTexture[i] = null; + } } - catch (Exception ex) + catch(Exception ex) { - m_log.Warn("Failed to decode cached terrain texture " + cacheID + - " (textureID: " + textureIDs[i] + "): " + ex.Message); + m_log.Warn("Failed to decode cached terrain patch texture" + textureIDs[i] + "): " + ex.Message); } } - if (detailTexture[i] == null) + if(detailTexture[i] == null) { // Try to fetch the original JPEG2000 texture, resize if needed, and cache as PNG asset = assetService.Get(textureIDs[i].ToString()); - if (asset != null) + if(asset != null) { - // m_log.DebugFormat( - // "[TERRAIN SPLAT]: Got cached original JPEG2000 terrain texture {0} {1}", i, asset.ID); - - try { detailTexture[i] = (Bitmap)CSJ2K.J2kImage.FromBytes(asset.Data); } - catch (Exception ex) + try + { + detailTexture[i] = (Bitmap)decoder.DecodeToImage(asset.Data); + } + catch(Exception ex) { m_log.Warn("Failed to decode terrain texture " + asset.ID + ": " + ex.Message); } } - if (detailTexture[i] != null) + if(detailTexture[i] != null) { - // Make sure this texture is the correct size, otherwise resize - if (detailTexture[i].Width != 256 || detailTexture[i].Height != 256) - { - using (Bitmap origBitmap = detailTexture[i]) - { - detailTexture[i] = ImageUtils.ResizeImage(origBitmap, 256, 256); - } - } + if(detailTexture[i].PixelFormat != PixelFormat.Format24bppRgb || + detailTexture[i].Width != 16 || detailTexture[i].Height != 16) + using(Bitmap origBitmap = detailTexture[i]) + detailTexture[i] = Util.ResizeImageSolid(origBitmap, 16, 16); // Save the decoded and resized texture to the cache byte[] data; - using (System.IO.MemoryStream stream = new System.IO.MemoryStream()) + using(System.IO.MemoryStream stream = new System.IO.MemoryStream()) { detailTexture[i].Save(stream, ImageFormat.Png); data = stream.ToArray(); @@ -165,8 +178,8 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap Data = data, Description = "PNG", Flags = AssetFlags.Collectable, - FullID = cacheID, - ID = cacheID.ToString(), + FullID = UUID.Zero, + ID = cacheName, Local = true, Name = String.Empty, Temporary = true, @@ -180,209 +193,275 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap } #endregion Texture Fetching - } - - // Fill in any missing textures with a solid color - for (int i = 0; i < 4; i++) - { - if (detailTexture[i] == null) + if(averagetextureTerrain) { - m_log.DebugFormat("{0} Missing terrain texture for layer {1}. Filling with solid default color", - LogHeader, i); - // Create a solid color texture for this layer - detailTexture[i] = new Bitmap(256, 256, PixelFormat.Format24bppRgb); - using (Graphics gfx = Graphics.FromImage(detailTexture[i])) + for(int t = 0; t < 4; t++) { - using (SolidBrush brush = new SolidBrush(DEFAULT_TERRAIN_COLOR[i])) - gfx.FillRectangle(brush, 0, 0, 256, 256); + usecolors = true; + if(detailTexture[t] == null) + { + mapColorsRed[t] = DEFAULT_TERRAIN_COLOR[t].R; + mapColorsGreen[t] = DEFAULT_TERRAIN_COLOR[t].G; + mapColorsBlue[t] = DEFAULT_TERRAIN_COLOR[t].B; + continue; + } + + int npixeis = 0; + int cR = 0; + int cG = 0; + int cB = 0; + + BitmapData bmdata = detailTexture[t].LockBits(new Rectangle(0, 0, 16, 16), + ImageLockMode.ReadOnly, detailTexture[t].PixelFormat); + + npixeis = bmdata.Height * bmdata.Width; + int ylen = bmdata.Height * bmdata.Stride; + + unsafe + { + for(int y = 0; y < ylen; y += bmdata.Stride) + { + byte* ptrc = (byte*)bmdata.Scan0 + y; + for(int x = 0 ; x < bmdata.Width; ++x) + { + cR += *(ptrc++); + cG += *(ptrc++); + cB += *(ptrc++); + } + } + + } + detailTexture[t].UnlockBits(bmdata); + detailTexture[t].Dispose(); + + mapColorsRed[t] = (byte)Util.Clamp(cR / npixeis, 0 , 255); + mapColorsGreen[t] = (byte)Util.Clamp(cG / npixeis, 0 , 255); + mapColorsBlue[t] = (byte)Util.Clamp(cB / npixeis, 0 , 255); } } else { - if (detailTexture[i].Width != 256 || detailTexture[i].Height != 256) + // Fill in any missing textures with a solid color + for(int i = 0; i < 4; i++) { - detailTexture[i] = ResizeBitmap(detailTexture[i], 256, 256); + if(detailTexture[i] == null) + { + m_log.DebugFormat("{0} Missing terrain texture for layer {1}. Filling with solid default color", LogHeader, i); + + // Create a solid color texture for this layer + detailTexture[i] = new Bitmap(16, 16, PixelFormat.Format24bppRgb); + using(Graphics gfx = Graphics.FromImage(detailTexture[i])) + { + using(SolidBrush brush = new SolidBrush(DEFAULT_TERRAIN_COLOR[i])) + gfx.FillRectangle(brush, 0, 0, 16, 16); + } + } + else + { + if(detailTexture[i].Width != 16 || detailTexture[i].Height != 16) + { + using(Bitmap origBitmap = detailTexture[i]) + detailTexture[i] = Util.ResizeImageSolid(origBitmap, 16, 16); + } + } } } } + else + { + usecolors = true; + for(int t = 0; t < 4; t++) + { + mapColorsRed[t] = DEFAULT_TERRAIN_COLOR[t].R; + mapColorsGreen[t] = DEFAULT_TERRAIN_COLOR[t].G; + mapColorsBlue[t] = DEFAULT_TERRAIN_COLOR[t].B; + } + } #region Layer Map - float[,] layermap = new float[256, 256]; - - // Scale difference between actual region size and the 256 texture being created - int xFactor = terrain.Width / 256; - int yFactor = terrain.Height / 256; - - // Create 'layermap' where each value is the fractional layer number to place - // at that point. For instance, a value of 1.345 gives the blending of - // layer 1 and layer 2 for that point. - for (int y = 0; y < 256; y++) - { - for (int x = 0; x < 256; x++) - { - float height = (float)terrain[x * xFactor, y * yFactor]; - - float pctX = (float)x / 255f; - float pctY = (float)y / 255f; - - // Use bilinear interpolation between the four corners of start height and - // height range to select the current values at this position - float startHeight = ImageUtils.Bilinear( - startHeights[0], - startHeights[2], - startHeights[1], - startHeights[3], - pctX, pctY); - startHeight = Utils.Clamp(startHeight, 0f, 255f); - - float heightRange = ImageUtils.Bilinear( - heightRanges[0], - heightRanges[2], - heightRanges[1], - heightRanges[3], - pctX, pctY); - heightRange = Utils.Clamp(heightRange, 0f, 255f); - - // Generate two frequencies of perlin noise based on our global position - // The magic values were taken from http://opensimulator.org/wiki/Terrain_Splatting - Vector3 vec = new Vector3 - ( - ((float)regionPosition.X + (x * xFactor)) * 0.20319f, - ((float)regionPosition.Y + (y * yFactor)) * 0.20319f, - height * 0.25f - ); - - float lowFreq = Perlin.noise2(vec.X * 0.222222f, vec.Y * 0.222222f) * 6.5f; - float highFreq = Perlin.turbulence2(vec.X, vec.Y, 2f) * 2.25f; - float noise = (lowFreq + highFreq) * 2f; - - // Combine the current height, generated noise, start height, and height range parameters, then scale all of it - float layer = ((height + noise - startHeight) / heightRange) * 4f; - if (Single.IsNaN(layer)) - layer = 0f; - layermap[x, y] = Utils.Clamp(layer, 0f, 3f); - } - } + float xFactor = terrain.Width / twidth; + float yFactor = terrain.Height / theight; #endregion Layer Map #region Texture Compositing - Bitmap output = new Bitmap(256, 256, PixelFormat.Format24bppRgb); - BitmapData outputData = output.LockBits(new Rectangle(0, 0, 256, 256), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb); + Bitmap output = new Bitmap(twidth, theight, PixelFormat.Format24bppRgb); + BitmapData outputData = output.LockBits(new Rectangle(0, 0, twidth, theight), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb); // Unsafe work as we lock down the source textures for quicker access and access the // pixel data directly - unsafe + float invtwitdthMinus1 = 1.0f / (twidth - 1); + float invtheightMinus1 = 1.0f / (theight - 1); + int ty; + int tx; + float pctx; + float pcty; + float height; + float layer; + float layerDiff; + int l0; + int l1; + uint yglobalpos; + + if(usecolors) { - // Get handles to all of the texture data arrays - BitmapData[] datas = new BitmapData[] + float a; + float b; + unsafe { - detailTexture[0].LockBits(new Rectangle(0, 0, 256, 256), ImageLockMode.ReadOnly, detailTexture[0].PixelFormat), - detailTexture[1].LockBits(new Rectangle(0, 0, 256, 256), ImageLockMode.ReadOnly, detailTexture[1].PixelFormat), - detailTexture[2].LockBits(new Rectangle(0, 0, 256, 256), ImageLockMode.ReadOnly, detailTexture[2].PixelFormat), - detailTexture[3].LockBits(new Rectangle(0, 0, 256, 256), ImageLockMode.ReadOnly, detailTexture[3].PixelFormat) - }; - - // Compute size of each pixel data (used to address into the pixel data array) - int[] comps = new int[] - { - (datas[0].PixelFormat == PixelFormat.Format32bppArgb) ? 4 : 3, - (datas[1].PixelFormat == PixelFormat.Format32bppArgb) ? 4 : 3, - (datas[2].PixelFormat == PixelFormat.Format32bppArgb) ? 4 : 3, - (datas[3].PixelFormat == PixelFormat.Format32bppArgb) ? 4 : 3 - }; - - for (int y = 0; y < 256; y++) - { - for (int x = 0; x < 256; x++) + byte* ptrO; + for(int y = 0; y < theight; ++y) { - float layer = layermap[x, y]; + pcty = y * invtheightMinus1; + ptrO = (byte*)outputData.Scan0 + y * outputData.Stride; + ty = (int)(y * yFactor); + yglobalpos = (uint)ty + regionPositionY; - // Select two textures - int l0 = (int)Math.Floor(layer); - int l1 = Math.Min(l0 + 1, 3); + for(int x = 0; x < twidth; ++x) + { + tx = (int)(x * xFactor); + pctx = x * invtwitdthMinus1; + height = (float)terrain[tx, ty]; + layer = getLayerTex(height, pctx, pcty, + (uint)tx + regionPositionX, yglobalpos, + startHeights, heightRanges); - byte* ptrA = (byte*)datas[l0].Scan0 + y * datas[l0].Stride + x * comps[l0]; - byte* ptrB = (byte*)datas[l1].Scan0 + y * datas[l1].Stride + x * comps[l1]; - byte* ptrO = (byte*)outputData.Scan0 + y * outputData.Stride + x * 3; + // Select two textures + l0 = (int)layer; + l1 = Math.Min(l0 + 1, 3); - float aB = *(ptrA + 0); - float aG = *(ptrA + 1); - float aR = *(ptrA + 2); + layerDiff = layer - l0; - float bB = *(ptrB + 0); - float bG = *(ptrB + 1); - float bR = *(ptrB + 2); + a = mapColorsRed[l0]; + b = mapColorsRed[l1]; + *(ptrO++) = (byte)(a + layerDiff * (b - a)); - float layerDiff = layer - l0; + a = mapColorsGreen[l0]; + b = mapColorsGreen[l1]; + *(ptrO++) = (byte)(a + layerDiff * (b - a)); - // Interpolate between the two selected textures - *(ptrO + 0) = (byte)Math.Floor(aB + layerDiff * (bB - aB)); - *(ptrO + 1) = (byte)Math.Floor(aG + layerDiff * (bG - aG)); - *(ptrO + 2) = (byte)Math.Floor(aR + layerDiff * (bR - aR)); + a = mapColorsBlue[l0]; + b = mapColorsBlue[l1]; + *(ptrO++) = (byte)(a + layerDiff * (b - a)); + } } } - - for (int i = 0; i < detailTexture.Length; i++) - detailTexture[i].UnlockBits(datas[i]); } + else + { + float aB; + float aG; + float aR; + float bB; + float bG; + float bR; - for (int i = 0; i < detailTexture.Length; i++) - if (detailTexture[i] != null) - detailTexture[i].Dispose(); + unsafe + { + // Get handles to all of the texture data arrays + BitmapData[] datas = new BitmapData[] + { + detailTexture[0].LockBits(new Rectangle(0, 0, 16, 16), ImageLockMode.ReadOnly, detailTexture[0].PixelFormat), + detailTexture[1].LockBits(new Rectangle(0, 0, 16, 16), ImageLockMode.ReadOnly, detailTexture[1].PixelFormat), + detailTexture[2].LockBits(new Rectangle(0, 0, 16, 16), ImageLockMode.ReadOnly, detailTexture[2].PixelFormat), + detailTexture[3].LockBits(new Rectangle(0, 0, 16, 16), ImageLockMode.ReadOnly, detailTexture[3].PixelFormat) + }; + + byte* ptr; + byte* ptrO; + for(int y = 0; y < theight; y++) + { + pcty = y * invtheightMinus1; + int ypatch = ((int)(y * yFactor) & 0x0f) * datas[0].Stride; + ptrO = (byte*)outputData.Scan0 + y * outputData.Stride; + ty = (int)(y * yFactor); + yglobalpos = (uint)ty + regionPositionY; + + for(int x = 0; x < twidth; x++) + { + tx = (int)(x * xFactor); + pctx = x * invtwitdthMinus1; + height = (float)terrain[tx, ty]; + layer = getLayerTex(height, pctx, pcty, + (uint)tx + regionPositionX, yglobalpos, + startHeights, heightRanges); + + // Select two textures + l0 = (int)layer; + layerDiff = layer - l0; + + int patchOffset = (tx & 0x0f) * 3 + ypatch; + + ptr = (byte*)datas[l0].Scan0 + patchOffset; + aB = *(ptr++); + aG = *(ptr++); + aR = *(ptr); + + l1 = Math.Min(l0 + 1, 3); + ptr = (byte*)datas[l1].Scan0 + patchOffset; + bB = *(ptr++); + bG = *(ptr++); + bR = *(ptr); + + + // Interpolate between the two selected textures + *(ptrO++) = (byte)(aB + layerDiff * (bB - aB)); + *(ptrO++) = (byte)(aG + layerDiff * (bG - aG)); + *(ptrO++) = (byte)(aR + layerDiff * (bR - aR)); + } + } + + for(int i = 0; i < detailTexture.Length; i++) + detailTexture[i].UnlockBits(datas[i]); + } + + for(int i = 0; i < detailTexture.Length; i++) + if(detailTexture[i] != null) + detailTexture[i].Dispose(); + } output.UnlockBits(outputData); - // We generated the texture upside down, so flip it - output.RotateFlip(RotateFlipType.RotateNoneFlipY); +//output.Save("terr.png",ImageFormat.Png); #endregion Texture Compositing return output; } - public static Bitmap ResizeBitmap(Bitmap b, int nWidth, int nHeight) + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + private static float getLayerTex(float height, float pctX, float pctY, uint X, uint Y, + float[] startHeights, float[] heightRanges) { - m_log.DebugFormat("{0} ResizeBitmap. From <{1},{2}> to <{3},{4}>", - LogHeader, b.Width, b.Height, nWidth, nHeight); - Bitmap result = new Bitmap(nWidth, nHeight); - using (Graphics g = Graphics.FromImage(result)) - g.DrawImage(b, 0, 0, nWidth, nHeight); - b.Dispose(); - return result; - } - public static Bitmap SplatSimple(float[] heightmap) - { - const float BASE_HSV_H = 93f / 360f; - const float BASE_HSV_S = 44f / 100f; - const float BASE_HSV_V = 34f / 100f; + // Use bilinear interpolation between the four corners of start height and + // height range to select the current values at this position + float startHeight = ImageUtils.Bilinear( + startHeights[0], startHeights[2], + startHeights[1], startHeights[3], + pctX, pctY); + startHeight = Utils.Clamp(startHeight, 0f, 255f); - Bitmap img = new Bitmap(256, 256); - BitmapData bitmapData = img.LockBits(new Rectangle(0, 0, 256, 256), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb); + float heightRange = ImageUtils.Bilinear( + heightRanges[0], heightRanges[2], + heightRanges[1], heightRanges[3], + pctX, pctY); + heightRange = Utils.Clamp(heightRange, 0f, 255f); + if(heightRange == 0f) + return 0; - unsafe - { - for (int y = 255; y >= 0; y--) - { - for (int x = 0; x < 256; x++) - { - float normHeight = heightmap[y * 256 + x] / 255f; - normHeight = Utils.Clamp(normHeight, BASE_HSV_V, 1.0f); + // Generate two frequencies of perlin noise based on our global position + // The magic values were taken from http://opensimulator.org/wiki/Terrain_Splatting + float sX = X * 0.20319f; + float sY = Y * 0.20319f; - Color4 color = Color4.FromHSV(BASE_HSV_H, BASE_HSV_S, normHeight); + float noise = Perlin.noise2(sX * 0.222222f, sY * 0.222222f) * 13.0f; + noise += Perlin.turbulence2(sX, sY, 2f) * 4.5f; - byte* ptr = (byte*)bitmapData.Scan0 + y * bitmapData.Stride + x * 3; - *(ptr + 0) = (byte)(color.B * 255f); - *(ptr + 1) = (byte)(color.G * 255f); - *(ptr + 2) = (byte)(color.R * 255f); - } - } - } - - img.UnlockBits(bitmapData); - return img; + // Combine the current height, generated noise, start height, and height range parameters, then scale all of it + float layer = ((height + noise - startHeight) / heightRange) * 4f; + return Utils.Clamp(layer, 0f, 3f); } } } diff --git a/OpenSim/Region/CoreModules/World/Warp3DMap/Viewport.cs b/OpenSim/Region/CoreModules/World/Warp3DMap/Viewport.cs deleted file mode 100644 index 472f86e5fa..0000000000 --- a/OpenSim/Region/CoreModules/World/Warp3DMap/Viewport.cs +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System; -using System.Drawing; -using OpenMetaverse; - -namespace OpenSim.Region.CoreModules.World.Warp3DMap -{ - public class Viewport - { - private const float DEG_TO_RAD = (float)Math.PI / 180f; - private static readonly Vector3 UP_DIRECTION = Vector3.UnitZ; - - public Vector3 Position; - public Vector3 LookDirection; - public float FieldOfView; - public float NearPlaneDistance; - public float FarPlaneDistance; - public int Width; - public int Height; - public bool Orthographic; - public float OrthoWindowWidth; - public float OrthoWindowHeight; - - public Viewport(Vector3 position, Vector3 lookDirection, float fieldOfView, float farPlaneDist, float nearPlaneDist, int width, int height) - { - // Perspective projection mode - Position = position; - LookDirection = lookDirection; - FieldOfView = fieldOfView; - FarPlaneDistance = farPlaneDist; - NearPlaneDistance = nearPlaneDist; - Width = width; - Height = height; - } - - public Viewport(Vector3 position, Vector3 lookDirection, float farPlaneDist, float nearPlaneDist, int width, int height, float orthoWindowWidth, float orthoWindowHeight) - { - // Orthographic projection mode - Position = position; - LookDirection = lookDirection; - FarPlaneDistance = farPlaneDist; - NearPlaneDistance = nearPlaneDist; - Width = width; - Height = height; - OrthoWindowWidth = orthoWindowWidth; - OrthoWindowHeight = orthoWindowHeight; - Orthographic = true; - } - - public Point VectorToScreen(Vector3 v) - { - Matrix4 m = GetWorldToViewportMatrix(); - Vector3 screenPoint = v * m; - return new Point((int)screenPoint.X, (int)screenPoint.Y); - } - - public Matrix4 GetWorldToViewportMatrix() - { - Matrix4 result = GetViewMatrix(); - result *= GetPerspectiveProjectionMatrix(); - result *= GetViewportMatrix(); - - return result; - } - - public Matrix4 GetViewMatrix() - { - Vector3 zAxis = -LookDirection; - zAxis.Normalize(); - - Vector3 xAxis = Vector3.Cross(UP_DIRECTION, zAxis); - xAxis.Normalize(); - - Vector3 yAxis = Vector3.Cross(zAxis, xAxis); - - Vector3 position = Position; - float offsetX = -Vector3.Dot(xAxis, position); - float offsetY = -Vector3.Dot(yAxis, position); - float offsetZ = -Vector3.Dot(zAxis, position); - - return new Matrix4( - xAxis.X, yAxis.X, zAxis.X, 0f, - xAxis.Y, yAxis.Y, zAxis.Y, 0f, - xAxis.Z, yAxis.Z, zAxis.Z, 0f, - offsetX, offsetY, offsetZ, 1f); - } - - public Matrix4 GetPerspectiveProjectionMatrix() - { - float aspectRatio = (float)Width / (float)Height; - - float hFoV = FieldOfView * DEG_TO_RAD; - float zn = NearPlaneDistance; - float zf = FarPlaneDistance; - - float xScale = 1f / (float)Math.Tan(hFoV / 2f); - float yScale = aspectRatio * xScale; - float m33 = (zf == double.PositiveInfinity) ? -1 : (zf / (zn - zf)); - float m43 = zn * m33; - - return new Matrix4( - xScale, 0f, 0f, 0f, - 0f, yScale, 0f, 0f, - 0f, 0f, m33, -1f, - 0f, 0f, m43, 0f); - } - - public Matrix4 GetOrthographicProjectionMatrix(float aspectRatio) - { - float w = Width; - float h = Height; - float zn = NearPlaneDistance; - float zf = FarPlaneDistance; - - float m33 = 1 / (zn - zf); - float m43 = zn * m33; - - return new Matrix4( - 2f / w, 0f, 0f, 0f, - 0f, 2f / h, 0f, 0f, - 0f, 0f, m33, 0f, - 0f, 0f, m43, 1f); - } - - public Matrix4 GetViewportMatrix() - { - float scaleX = (float)Width * 0.5f; - float scaleY = (float)Height * 0.5f; - float offsetX = 0f + scaleX; - float offsetY = 0f + scaleY; - - return new Matrix4( - scaleX, 0f, 0f, 0f, - 0f, -scaleY, 0f, 0f, - 0f, 0f, 1f, 0f, - offsetX, offsetY, 0f, 1f); - } - } -} diff --git a/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs b/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs index 4934ebddb2..82cc12cf65 100644 --- a/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs +++ b/OpenSim/Region/CoreModules/World/Warp3DMap/Warp3DImageModule.cs @@ -50,15 +50,15 @@ using OpenMetaverse.Imaging; using OpenMetaverse.Rendering; using OpenMetaverse.StructuredData; -using WarpRenderer = global::Warp3D.Warp3D; +using WarpRenderer = Warp3D.Warp3D; namespace OpenSim.Region.CoreModules.World.Warp3DMap { [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "Warp3DImageModule")] public class Warp3DImageModule : IMapImageGenerator, INonSharedRegionModule { - private static readonly UUID TEXTURE_METADATA_MAGIC = new UUID("802dc0e0-f080-4931-8b57-d1be8611c4f3"); private static readonly Color4 WATER_COLOR = new Color4(29, 72, 96, 216); +// private static readonly Color4 WATER_COLOR = new Color4(29, 72, 96, 128); private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -66,13 +66,18 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap private static string LogHeader = "[WARP 3D IMAGE MODULE]"; #pragma warning restore 414 - private Scene m_scene; + internal Scene m_scene; private IRendering m_primMesher; - private Dictionary m_colors = new Dictionary(); + internal IJ2KDecoder m_imgDecoder; + + // caches per rendering + private Dictionary m_warpTextures = new Dictionary(); + private Dictionary m_colors = new Dictionary(); private IConfigSource m_config; private bool m_drawPrimVolume = true; // true if should render the prims on the tile private bool m_textureTerrain = true; // true if to create terrain splatting texture + private bool m_textureAverageTerrain = false; // replace terrain textures by their average color private bool m_texturePrims = true; // true if should texture the rendered prims private float m_texturePrimSize = 48f; // size of prim before we consider texturing it private bool m_renderMeshes = false; // true if to render meshes rather than just bounding boxes @@ -96,17 +101,22 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap m_Enabled = true; - m_drawPrimVolume - = Util.GetConfigVarFromSections(m_config, "DrawPrimOnMapTile", configSections, m_drawPrimVolume); - m_textureTerrain - = Util.GetConfigVarFromSections(m_config, "TextureOnMapTile", configSections, m_textureTerrain); - m_texturePrims - = Util.GetConfigVarFromSections(m_config, "TexturePrims", configSections, m_texturePrims); - m_texturePrimSize - = Util.GetConfigVarFromSections(m_config, "TexturePrimSize", configSections, m_texturePrimSize); - m_renderMeshes - = Util.GetConfigVarFromSections(m_config, "RenderMeshes", configSections, m_renderMeshes); - } + m_drawPrimVolume = + Util.GetConfigVarFromSections(m_config, "DrawPrimOnMapTile", configSections, m_drawPrimVolume); + m_textureTerrain = + Util.GetConfigVarFromSections(m_config, "TextureOnMapTile", configSections, m_textureTerrain); + m_textureAverageTerrain = + Util.GetConfigVarFromSections(m_config, "AverageTextureColorOnMapTile", configSections, m_textureAverageTerrain); + if (m_textureAverageTerrain) + m_textureTerrain = true; + m_texturePrims = + Util.GetConfigVarFromSections(m_config, "TexturePrims", configSections, m_texturePrims); + m_texturePrimSize = + Util.GetConfigVarFromSections(m_config, "TexturePrimSize", configSections, m_texturePrimSize); + m_renderMeshes = + Util.GetConfigVarFromSections(m_config, "RenderMeshes", configSections, m_renderMeshes); + + } public void AddRegion(Scene scene) { @@ -126,6 +136,10 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap public void RegionLoaded(Scene scene) { + if (!m_Enabled) + return; + + m_imgDecoder = m_scene.RequestModuleInterface(); } public void RemoveRegion(Scene scene) @@ -150,86 +164,93 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap #region IMapImageGenerator Members + private Vector3 cameraPos; + private Vector3 cameraDir; + private int viewWitdh = 256; + private int viewHeight = 256; + private float fov; + private bool orto; + public Bitmap CreateMapTile() { - /* this must be on all map, not just its image - if ((DateTime.Now - lastImageTime).TotalSeconds < 3600) - { - return (Bitmap)lastImage.Clone(); - } - */ - List renderers = RenderingLoader.ListRenderers(Util.ExecutingDirectory()); if (renderers.Count > 0) { m_primMesher = RenderingLoader.LoadRenderer(renderers[0]); } - Vector3 camPos = new Vector3( - m_scene.RegionInfo.RegionSizeX / 2 - 0.5f, - m_scene.RegionInfo.RegionSizeY / 2 - 0.5f, - 221.7025033688163f); - // Viewport viewing down onto the region - Viewport viewport = new Viewport(camPos, -Vector3.UnitZ, 1024f, 0.1f, - (int)m_scene.RegionInfo.RegionSizeX, (int)m_scene.RegionInfo.RegionSizeY, - (float)m_scene.RegionInfo.RegionSizeX, (float)m_scene.RegionInfo.RegionSizeY); + cameraPos = new Vector3( + (m_scene.RegionInfo.RegionSizeX) * 0.5f, + (m_scene.RegionInfo.RegionSizeY) * 0.5f, + 4096f); - Bitmap tile = CreateMapTile(viewport, false); + cameraDir = -Vector3.UnitZ; + viewWitdh = (int)m_scene.RegionInfo.RegionSizeX; + viewHeight = (int)m_scene.RegionInfo.RegionSizeY; + orto = true; + +// fov = warp_Math.rad2deg(2f * (float)Math.Atan2(viewWitdh, 4096f)); +// orto = false; + + Bitmap tile = GenImage(); + // image may be reloaded elsewhere, so no compression format + string filename = "MAP-" + m_scene.RegionInfo.RegionID.ToString() + ".png"; + tile.Save(filename, ImageFormat.Png); m_primMesher = null; return tile; -/* - lastImage = tile; - lastImageTime = DateTime.Now; - return (Bitmap)lastImage.Clone(); - */ } - public Bitmap CreateViewImage(Vector3 camPos, Vector3 camDir, float fov, int width, int height, bool useTextures) + public Bitmap CreateViewImage(Vector3 camPos, Vector3 camDir, float pfov, int width, int height, bool useTextures) { - Viewport viewport = new Viewport(camPos, camDir, fov, Constants.RegionSize, 0.1f, width, height); - return CreateMapTile(viewport, useTextures); + List renderers = RenderingLoader.ListRenderers(Util.ExecutingDirectory()); + if (renderers.Count > 0) + { + m_primMesher = RenderingLoader.LoadRenderer(renderers[0]); + } + + cameraPos = camPos; + cameraDir = camDir; + viewWitdh = width; + viewHeight = height; + fov = pfov; + orto = false; + + Bitmap tile = GenImage(); + m_primMesher = null; + return tile; } - public Bitmap CreateMapTile(Viewport viewport, bool useTextures) + private Bitmap GenImage() { m_colors.Clear(); - - int width = viewport.Width; - int height = viewport.Height; + m_warpTextures.Clear(); WarpRenderer renderer = new WarpRenderer(); - if(!renderer.CreateScene(width, height)) - return new Bitmap(width,height); + if (!renderer.CreateScene(viewWitdh, viewHeight)) + return new Bitmap(viewWitdh, viewHeight); #region Camera - warp_Vector pos = ConvertVector(viewport.Position); - warp_Vector lookat = warp_Vector.add(ConvertVector(viewport.Position), ConvertVector(viewport.LookDirection)); + warp_Vector pos = ConvertVector(cameraPos); + warp_Vector lookat = warp_Vector.add(pos, ConvertVector(cameraDir)); + + if (orto) + renderer.Scene.defaultCamera.setOrthographic(true, viewWitdh, viewHeight); + else + renderer.Scene.defaultCamera.setFov(fov); renderer.Scene.defaultCamera.setPos(pos); renderer.Scene.defaultCamera.lookAt(lookat); - - if (viewport.Orthographic) - { - renderer.Scene.defaultCamera.setOrthographic(true,viewport.OrthoWindowWidth, viewport.OrthoWindowHeight); - } - else - { - float fov = viewport.FieldOfView; - fov *= 1.75f; // FIXME: ??? - renderer.Scene.defaultCamera.setFov(fov); - } - #endregion Camera - renderer.Scene.addLight("Light1", new warp_Light(new warp_Vector(1.0f, 0.5f, 1f), 0xffffff, 0, 320, 40)); - renderer.Scene.addLight("Light2", new warp_Light(new warp_Vector(-1f, -1f, 1f), 0xffffff, 0, 100, 40)); + renderer.Scene.setAmbient(warp_Color.getColor(192, 191, 173)); + renderer.Scene.addLight("Light1", new warp_Light(new warp_Vector(0f, 1f, 8f), warp_Color.White, 0, 320, 40)); CreateWater(renderer); - CreateTerrain(renderer, m_textureTerrain); + CreateTerrain(renderer); if (m_drawPrimVolume) - CreateAllPrims(renderer, useTextures); + CreateAllPrims(renderer); renderer.Render(); Bitmap bitmap = renderer.Scene.getImage(); @@ -237,11 +258,11 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap renderer.Scene.destroy(); renderer.Reset(); renderer = null; - viewport = null; m_colors.Clear(); + m_warpTextures.Clear(); GC.Collect(); - m_log.Debug("[WARP 3D IMAGE MODULE]: GC.Collect()"); +// m_log.Debug("[WARP 3D IMAGE MODULE]: GC.Collect()"); return bitmap; } @@ -251,7 +272,7 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap try { using (Bitmap mapbmp = CreateMapTile()) - return OpenJPEG.EncodeFromImage(mapbmp, true); + return OpenJPEG.EncodeFromImage(mapbmp, false); } catch (Exception e) { @@ -272,21 +293,19 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap float waterHeight = (float)m_scene.RegionInfo.RegionSettings.WaterHeight; renderer.AddPlane("Water", m_scene.RegionInfo.RegionSizeX * 0.5f); - renderer.Scene.sceneobject("Water").setPos(m_scene.RegionInfo.RegionSizeX * 0.5f - 0.5f, + renderer.Scene.sceneobject("Water").setPos(m_scene.RegionInfo.RegionSizeX * 0.5f, waterHeight, - m_scene.RegionInfo.RegionSizeY * 0.5f - 0.5f); + m_scene.RegionInfo.RegionSizeY * 0.5f); - warp_Material waterColorMaterial = new warp_Material(ConvertColor(WATER_COLOR)); - waterColorMaterial.setReflectivity(0); // match water color with standard map module thanks lkalif - waterColorMaterial.setTransparency((byte)((1f - WATER_COLOR.A) * 255f)); - renderer.Scene.addMaterial("WaterColor", waterColorMaterial); - renderer.SetObjectMaterial("Water", "WaterColor"); + warp_Material waterMaterial = new warp_Material(ConvertColor(WATER_COLOR)); + renderer.Scene.addMaterial("WaterMat", waterMaterial); + renderer.SetObjectMaterial("Water", "WaterMat"); } // Add a terrain to the renderer. - // Note that we create a 'low resolution' 256x256 vertex terrain rather than trying for + // Note that we create a 'low resolution' 257x257 vertex terrain rather than trying for // full resolution. This saves a lot of memory especially for very large regions. - private void CreateTerrain(WarpRenderer renderer, bool textureTerrain) + private void CreateTerrain(WarpRenderer renderer) { ITerrainChannel terrain = m_scene.Heightmap; @@ -294,51 +313,78 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap float regionsy = m_scene.RegionInfo.RegionSizeY; // 'diff' is the difference in scale between the real region size and the size of terrain we're buiding - float diff = regionsx / 256f; - int npointsx =(int)(regionsx / diff); - int npointsy =(int)(regionsy / diff); + int bitWidth; + int bitHeight; - float invsx = 1.0f / regionsx; - float invsy = 1.0f / (float)m_scene.RegionInfo.RegionSizeY; + const double log2inv = 1.4426950408889634073599246810019; + bitWidth = (int)Math.Ceiling((Math.Log(terrain.Width) * log2inv)); + bitHeight = (int)Math.Ceiling((Math.Log(terrain.Height) * log2inv)); + + if (bitWidth > 8) // more than 256 is very heavy :( + bitWidth = 8; + if (bitHeight > 8) + bitHeight = 8; + + int twidth = (int)Math.Pow(2, bitWidth); + int theight = (int)Math.Pow(2, bitHeight); + + float diff = regionsx / twidth; + + int npointsx = (int)(regionsx / diff); + int npointsy = (int)(regionsy / diff); + + float invsx = 1.0f / (npointsx * diff); + float invsy = 1.0f / (npointsy * diff); + + npointsx++; + npointsy++; // Create all the vertices for the terrain warp_Object obj = new warp_Object(); - for (float y = 0; y < regionsy; y += diff) + warp_Vector pos; + float x, y; + float tv; + for (y = 0; y < regionsy; y += diff) { - for (float x = 0; x < regionsx; x += diff) + tv = y * invsy; + for (x = 0; x < regionsx; x += diff) { - warp_Vector pos = ConvertVector(x , y , (float)terrain[(int)x, (int)y]); - obj.addVertex(new warp_Vertex(pos, x * invsx, 1.0f - y * invsy)); + pos = ConvertVector(x, y, (float)terrain[(int)x, (int)y]); + obj.addVertex(new warp_Vertex(pos, x * invsx, tv)); } + pos = ConvertVector(x, y, (float)terrain[(int)(x - diff), (int)y]); + obj.addVertex(new warp_Vertex(pos, 1.0f, tv)); } - // Now that we have all the vertices, make another pass and - // create the list of triangle indices. - float invdiff = 1.0f / diff; + int lastY = (int)(y - diff); + for (x = 0; x < regionsx; x += diff) + { + pos = ConvertVector(x, y, (float)terrain[(int)x, lastY]); + obj.addVertex(new warp_Vertex(pos, x * invsx, 1.0f)); + } + pos = ConvertVector(x, y, (float)terrain[(int)(x - diff), lastY]); + obj.addVertex(new warp_Vertex(pos, 1.0f, 1.0f)); + + // create triangles. int limx = npointsx - 1; int limy = npointsy - 1; - for (float y = 0; y < regionsy; y += diff) + for (int j = 0; j < limy; j++) { - for (float x = 0; x < regionsx; x += diff) + for (int i = 0; i < limx; i++) { - float newX = x * invdiff; - float newY = y * invdiff; - if (newX < limx && newY < limy) - { - int v = (int)newY * npointsx + (int)newX; + int v = j * npointsx + i; - // Make two triangles for each of the squares in the grid of vertices - obj.addTriangle( - v, - v + 1, - v + npointsx); + // Make two triangles for each of the squares in the grid of vertices + obj.addTriangle( + v, + v + 1, + v + npointsx); - obj.addTriangle( - v + npointsx + 1, - v + npointsx, - v + 1); - } + obj.addTriangle( + v + npointsx + 1, + v + npointsx, + v + 1); } } @@ -365,48 +411,54 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap heightRanges[2] = (float)regionInfo.Elevation2SE; heightRanges[3] = (float)regionInfo.Elevation2NE; - uint globalX, globalY; - Util.RegionHandleToWorldLoc(m_scene.RegionInfo.RegionHandle, out globalX, out globalY); - warp_Texture texture; - using (Bitmap image = TerrainSplat.Splat( - terrain, textureIDs, startHeights, heightRanges, - new Vector3d(globalX, globalY, 0.0), m_scene.AssetService, textureTerrain)) + using (Bitmap image = TerrainSplat.Splat(terrain, textureIDs, startHeights, heightRanges, + m_scene.RegionInfo.WorldLocX, m_scene.RegionInfo.WorldLocY, + m_scene.AssetService, m_imgDecoder, m_textureTerrain, m_textureAverageTerrain, + twidth, twidth)) texture = new warp_Texture(image); warp_Material material = new warp_Material(texture); - material.setReflectivity(50); - renderer.Scene.addMaterial("TerrainColor", material); - renderer.Scene.material("TerrainColor").setReflectivity(0); // reduces tile seams a bit thanks lkalif - renderer.SetObjectMaterial("Terrain", "TerrainColor"); + renderer.Scene.addMaterial("TerrainMat", material); + renderer.SetObjectMaterial("Terrain", "TerrainMat"); } - private void CreateAllPrims(WarpRenderer renderer, bool useTextures) + private void CreateAllPrims(WarpRenderer renderer) { if (m_primMesher == null) return; m_scene.ForEachSOG( - delegate(SceneObjectGroup group) + delegate (SceneObjectGroup group) { foreach (SceneObjectPart child in group.Parts) - CreatePrim(renderer, child, useTextures); + CreatePrim(renderer, child); } ); } - private void CreatePrim(WarpRenderer renderer, SceneObjectPart prim, - bool useTextures) + private void CreatePrim(WarpRenderer renderer, SceneObjectPart prim) { - const float MIN_SIZE_SQUARE = 4f; - if ((PCode)prim.Shape.PCode != PCode.Prim) return; - float primScaleLenSquared = prim.Scale.LengthSquared(); - if (primScaleLenSquared < MIN_SIZE_SQUARE) + warp_Vector primPos = ConvertVector(prim.GetWorldPosition()); + warp_Quaternion primRot = ConvertQuaternion(prim.GetWorldRotation()); + warp_Matrix m = warp_Matrix.quaternionMatrix(primRot); + + float screenFactor = renderer.Scene.EstimateBoxProjectedArea(primPos, ConvertVector(prim.Scale), m); + if (screenFactor < 0) return; + int p2 = (int)(-(float)Math.Log(screenFactor) * 1.442695f * 0.5 - 1); + + if (p2 < 0) + p2 = 0; + else if (p2 > 3) + p2 = 3; + + DetailLevel lod = (DetailLevel)(3 - p2); + FacetedMesh renderMesh = null; Primitive omvPrim = prim.Shape.ToOmvPrimitive(prim.OffsetPosition, prim.RotationOffset); @@ -422,19 +474,17 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap if (omvPrim.Sculpt.Type == SculptType.Mesh) { AssetMesh meshAsset = new AssetMesh(omvPrim.Sculpt.SculptTexture, sculptAsset); - FacetedMesh.TryDecodeFromAsset(omvPrim, meshAsset, DetailLevel.Highest, out renderMesh); + FacetedMesh.TryDecodeFromAsset(omvPrim, meshAsset, lod, out renderMesh); meshAsset = null; } else // It's sculptie { - IJ2KDecoder imgDecoder = m_scene.RequestModuleInterface(); - if(imgDecoder != null) + if (m_imgDecoder != null) { - Image sculpt = imgDecoder.DecodeToImage(sculptAsset); - if(sculpt != null) + Image sculpt = m_imgDecoder.DecodeToImage(sculptAsset); + if (sculpt != null) { - renderMesh = m_primMesher.GenerateFacetedSculptMesh(omvPrim,(Bitmap)sculpt, - DetailLevel.Medium); + renderMesh = m_primMesher.GenerateFacetedSculptMesh(omvPrim, (Bitmap)sculpt, lod); sculpt.Dispose(); } } @@ -446,7 +496,7 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap // If not a mesh or sculptie, try the regular mesher if (renderMesh == null) { - renderMesh = m_primMesher.GenerateFacetedMesh(omvPrim, DetailLevel.Medium); + renderMesh = m_primMesher.GenerateFacetedMesh(omvPrim, lod); } if (renderMesh == null) @@ -466,12 +516,86 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap continue; warp_Object faceObj = new warp_Object(); - for (int j = 0; j < face.Vertices.Count; j++) + + Primitive.TextureEntryFace teFace = prim.Shape.Textures.GetFace((uint)i); + Color4 faceColor = teFace.RGBA; + if (faceColor.A == 0) + continue; + + string materialName = String.Empty; + if (m_texturePrims) { - Vertex v = face.Vertices[j]; - warp_Vector pos = ConvertVector(v.Position); - warp_Vertex vert = new warp_Vertex(pos, v.TexCoord.X, v.TexCoord.Y); - faceObj.addVertex(vert); + // if(lod > DetailLevel.Low) + { + // materialName = GetOrCreateMaterial(renderer, faceColor, teFace.TextureID, lod == DetailLevel.Low); + materialName = GetOrCreateMaterial(renderer, faceColor, teFace.TextureID, false); + if (String.IsNullOrEmpty(materialName)) + continue; + int c = renderer.Scene.material(materialName).getColor(); + if ((c & warp_Color.MASKALPHA) == 0) + continue; + } + } + else + materialName = GetOrCreateMaterial(renderer, faceColor); + + if (renderer.Scene.material(materialName).getTexture() == null) + { + // uv map details dont not matter for color; + for (int j = 0; j < face.Vertices.Count; j++) + { + Vertex v = face.Vertices[j]; + warp_Vector pos = ConvertVector(v.Position); + warp_Vertex vert = new warp_Vertex(pos, v.TexCoord.X, v.TexCoord.Y); + faceObj.addVertex(vert); + } + } + else + { + float tu; + float tv; + float offsetu = teFace.OffsetU + 0.5f; + float offsetv = teFace.OffsetV + 0.5f; + float scaleu = teFace.RepeatU; + float scalev = teFace.RepeatV; + float rotation = teFace.Rotation; + float rc = 0; + float rs = 0; + if (rotation != 0) + { + rc = (float)Math.Cos(rotation); + rs = (float)Math.Sin(rotation); + } + + for (int j = 0; j < face.Vertices.Count; j++) + { + warp_Vertex vert; + Vertex v = face.Vertices[j]; + warp_Vector pos = ConvertVector(v.Position); + tu = v.TexCoord.X - 0.5f; + tv = 0.5f - v.TexCoord.Y; + if (rotation != 0) + { + float tur = tu * rc - tv * rs; + float tvr = tu * rs + tv * rc; + tur *= scaleu; + tur += offsetu; + + tvr *= scalev; + tvr += offsetv; + vert = new warp_Vertex(pos, tur, tvr); + } + else + { + tu *= scaleu; + tu += offsetu; + tv *= scalev; + tv += offsetv; + vert = new warp_Vertex(pos, tu, tv); + } + + faceObj.addVertex(vert); + } } for (int j = 0; j < face.Indices.Count; j += 3) @@ -482,40 +606,30 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap face.Indices[j + 2]); } - Primitive.TextureEntryFace teFace = prim.Shape.Textures.GetFace((uint)i); - Color4 faceColor = GetFaceColor(teFace); - string materialName = String.Empty; - if (m_texturePrims && primScaleLenSquared > m_texturePrimSize*m_texturePrimSize) - materialName = GetOrCreateMaterial(renderer, faceColor, teFace.TextureID); - else - materialName = GetOrCreateMaterial(renderer, faceColor); - - warp_Vector primPos = ConvertVector(prim.GetWorldPosition()); - warp_Quaternion primRot = ConvertQuaternion(prim.GetWorldRotation()); - warp_Matrix m = warp_Matrix.quaternionMatrix(primRot); + faceObj.scaleSelf(prim.Scale.X, prim.Scale.Z, prim.Scale.Y); faceObj.transform(m); faceObj.setPos(primPos); - faceObj.scaleSelf(prim.Scale.X, prim.Scale.Z, prim.Scale.Y); renderer.Scene.addObject(meshName, faceObj); renderer.SetObjectMaterial(meshName, materialName); } } - private Color4 GetFaceColor(Primitive.TextureEntryFace face) + private int GetFaceColor(Primitive.TextureEntryFace face) { - Color4 color; + int color; + Color4 ctmp = Color4.White; if (face.TextureID == UUID.Zero) - return face.RGBA; + return warp_Color.White; if (!m_colors.TryGetValue(face.TextureID, out color)) { bool fetched = false; // Attempt to fetch the texture metadata - UUID metadataID = UUID.Combine(face.TextureID, TEXTURE_METADATA_MAGIC); - AssetBase metadata = m_scene.AssetService.GetCached(metadataID.ToString()); + string cacheName = "MAPCLR" + face.TextureID.ToString(); + AssetBase metadata = m_scene.AssetService.GetCached(cacheName); if (metadata != null) { OSDMap map = null; @@ -523,7 +637,7 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap if (map != null) { - color = map["X-JPEG2000-RGBA"].AsColor4(); + ctmp = map["X-RGBA"].AsColor4(); fetched = true; } } @@ -536,16 +650,16 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap if (textureAsset != null) { int width, height; - color = GetAverageColor(textureAsset.FullID, textureAsset.Data, out width, out height); + ctmp = GetAverageColor(textureAsset.FullID, textureAsset.Data, out width, out height); - OSDMap data = new OSDMap { { "X-JPEG2000-RGBA", OSD.FromColor4(color) } }; + OSDMap data = new OSDMap { { "X-RGBA", OSD.FromColor4(ctmp) } }; metadata = new AssetBase { Data = System.Text.Encoding.UTF8.GetBytes(OSDParser.SerializeJsonString(data)), - Description = "Metadata for JPEG2000 texture " + face.TextureID.ToString(), + Description = "Metadata for texture color" + face.TextureID.ToString(), Flags = AssetFlags.Collectable, - FullID = metadataID, - ID = metadataID.ToString(), + FullID = UUID.Zero, + ID = cacheName, Local = true, Temporary = true, Name = String.Empty, @@ -555,14 +669,14 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap } else { - color = new Color4(0.5f, 0.5f, 0.5f, 1.0f); + ctmp = new Color4(0.5f, 0.5f, 0.5f, 1.0f); } } - + color = ConvertColor(ctmp); m_colors[face.TextureID] = color; } - return color * face.RGBA; + return color; } private string GetOrCreateMaterial(WarpRenderer renderer, Color4 color) @@ -574,26 +688,32 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap return name; renderer.AddMaterial(name, ConvertColor(color)); - if (color.A < 1f) - renderer.Scene.material(name).setTransparency((byte)((1f - color.A) * 255f)); return name; } - public string GetOrCreateMaterial(WarpRenderer renderer, Color4 faceColor, UUID textureID) + public string GetOrCreateMaterial(WarpRenderer renderer, Color4 faceColor, UUID textureID, bool useAverageTextureColor) { - string materialName = "Color-" + faceColor.ToString() + "-Texture-" + textureID.ToString(); + int color = ConvertColor(faceColor); + string idstr = textureID.ToString() + color.ToString(); + string materialName = "MAPMAT" + idstr; - if (renderer.Scene.material(materialName) == null) + if (renderer.Scene.material(materialName) != null) + return materialName; + + warp_Material mat = new warp_Material(); + warp_Texture texture = GetTexture(textureID); + if (texture != null) { - renderer.AddMaterial(materialName, ConvertColor(faceColor)); - if (faceColor.A < 1f) - { - renderer.Scene.material(materialName).setTransparency((byte) ((1f - faceColor.A)*255f)); - } - warp_Texture texture = GetTexture(textureID); - if (texture != null) - renderer.Scene.material(materialName).setTexture(texture); + if (useAverageTextureColor) + color = warp_Color.multiply(color, texture.averageColor); + else + mat.setTexture(texture); } + else + color = warp_Color.multiply(color, warp_Color.Grey); + + mat.setColor(color); + renderer.Scene.addMaterial(materialName, mat); return materialName; } @@ -601,16 +721,19 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap private warp_Texture GetTexture(UUID id) { warp_Texture ret = null; + if (id == UUID.Zero) + return ret; + + if (m_warpTextures.TryGetValue(id.ToString(), out ret)) + return ret; byte[] asset = m_scene.AssetService.GetData(id.ToString()); if (asset != null) { - IJ2KDecoder imgDecoder = m_scene.RequestModuleInterface(); - try { - using (Bitmap img = (Bitmap)imgDecoder.DecodeToImage(asset)) + using (Bitmap img = (Bitmap)m_imgDecoder.DecodeToImage(asset)) ret = new warp_Texture(img); } catch (Exception e) @@ -618,7 +741,7 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap m_log.Warn(string.Format("[WARP 3D IMAGE MODULE]: Failed to decode asset {0}, exception ", id), e); } } - + m_warpTextures[id.ToString()] = ret; return ret; } @@ -643,10 +766,7 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap private static int ConvertColor(Color4 color) { - int c = warp_Color.getColor((byte)(color.R * 255f), (byte)(color.G * 255f), (byte)(color.B * 255f)); - if (color.A < 1f) - c |= (byte)(color.A * 255f) << 24; - + int c = warp_Color.getColor((byte)(color.R * 255f), (byte)(color.G * 255f), (byte)(color.B * 255f), (byte)(color.A * 255f)); return c; } @@ -661,86 +781,83 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap return normal; } - public static Color4 GetAverageColor(UUID textureID, byte[] j2kData, out int width, out int height) + public Color4 GetAverageColor(UUID textureID, byte[] j2kData, out int width, out int height) { ulong r = 0; ulong g = 0; ulong b = 0; ulong a = 0; + int pixelBytes; - using (MemoryStream stream = new MemoryStream(j2kData)) + try { - try + using (MemoryStream stream = new MemoryStream(j2kData)) + using (Bitmap bitmap = (Bitmap)J2kImage.FromStream(stream)) { - int pixelBytes; + width = bitmap.Width; + height = bitmap.Height; - using (Bitmap bitmap = (Bitmap)J2kImage.FromStream(stream)) + BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, bitmap.PixelFormat); + pixelBytes = (bitmap.PixelFormat == PixelFormat.Format24bppRgb) ? 3 : 4; + + // Sum up the individual channels + unsafe { - width = bitmap.Width; - height = bitmap.Height; - - BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, bitmap.PixelFormat); - pixelBytes = (bitmap.PixelFormat == PixelFormat.Format24bppRgb) ? 3 : 4; - - // Sum up the individual channels - unsafe + if (pixelBytes == 4) { - if (pixelBytes == 4) + for (int y = 0; y < height; y++) { - for (int y = 0; y < height; y++) - { - byte* row = (byte*)bitmapData.Scan0 + (y * bitmapData.Stride); + byte* row = (byte*)bitmapData.Scan0 + (y * bitmapData.Stride); - for (int x = 0; x < width; x++) - { - b += row[x * pixelBytes + 0]; - g += row[x * pixelBytes + 1]; - r += row[x * pixelBytes + 2]; - a += row[x * pixelBytes + 3]; - } + for (int x = 0; x < width; x++) + { + b += row[x * pixelBytes + 0]; + g += row[x * pixelBytes + 1]; + r += row[x * pixelBytes + 2]; + a += row[x * pixelBytes + 3]; } } - else + } + else + { + for (int y = 0; y < height; y++) { - for (int y = 0; y < height; y++) - { - byte* row = (byte*)bitmapData.Scan0 + (y * bitmapData.Stride); + byte* row = (byte*)bitmapData.Scan0 + (y * bitmapData.Stride); - for (int x = 0; x < width; x++) - { - b += row[x * pixelBytes + 0]; - g += row[x * pixelBytes + 1]; - r += row[x * pixelBytes + 2]; - } + for (int x = 0; x < width; x++) + { + b += row[x * pixelBytes + 0]; + g += row[x * pixelBytes + 1]; + r += row[x * pixelBytes + 2]; } } } } - - // Get the averages for each channel - const decimal OO_255 = 1m / 255m; - decimal totalPixels = (decimal)(width * height); - - decimal rm = ((decimal)r / totalPixels) * OO_255; - decimal gm = ((decimal)g / totalPixels) * OO_255; - decimal bm = ((decimal)b / totalPixels) * OO_255; - decimal am = ((decimal)a / totalPixels) * OO_255; - - if (pixelBytes == 3) - am = 1m; - - return new Color4((float)rm, (float)gm, (float)bm, (float)am); } - catch (Exception ex) - { - m_log.WarnFormat( - "[WARP 3D IMAGE MODULE]: Error decoding JPEG2000 texture {0} ({1} bytes): {2}", - textureID, j2kData.Length, ex.Message); + // Get the averages for each channel + const decimal OO_255 = 1m / 255m; + decimal totalPixels = (decimal)(width * height); - width = 0; - height = 0; - return new Color4(0.5f, 0.5f, 0.5f, 1.0f); - } + decimal rm = ((decimal)r / totalPixels) * OO_255; + decimal gm = ((decimal)g / totalPixels) * OO_255; + decimal bm = ((decimal)b / totalPixels) * OO_255; + decimal am = ((decimal)a / totalPixels) * OO_255; + + if (pixelBytes == 3) + am = 1m; + + return new Color4((float)rm, (float)gm, (float)bm, (float)am); + + } + catch (Exception ex) + { + m_log.WarnFormat( + "[WARP 3D IMAGE MODULE]: Error decoding JPEG2000 texture {0} ({1} bytes): {2}", + textureID, j2kData.Length, ex.Message); + + width = 0; + height = 0; + return new Color4(0.5f, 0.5f, 0.5f, 1.0f); } } @@ -763,29 +880,5 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap { return Utils.Lerp(Utils.Lerp(v00, v01, xPercent), Utils.Lerp(v10, v11, xPercent), yPercent); } - - /// - /// Performs a high quality image resize - /// - /// Image to resize - /// New width - /// New height - /// Resized image - public static Bitmap ResizeImage(Image image, int width, int height) - { - Bitmap result = new Bitmap(width, height); - - using (Graphics graphics = Graphics.FromImage(result)) - { - graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality; - graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; - graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; - graphics.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality; - - graphics.DrawImage(image, 0, 0, result.Width, result.Height); - } - - return result; - } } } diff --git a/OpenSim/Region/CoreModules/World/Wind/WindModule.cs b/OpenSim/Region/CoreModules/World/Wind/WindModule.cs index a1fff62dd7..ebcb678ad7 100644 --- a/OpenSim/Region/CoreModules/World/Wind/WindModule.cs +++ b/OpenSim/Region/CoreModules/World/Wind/WindModule.cs @@ -47,7 +47,6 @@ namespace OpenSim.Region.CoreModules private uint m_frame = 0; private int m_dataVersion = 0; - private int m_regionID = 0; private int m_frameUpdateRate = 150; //private Random m_rndnums = new Random(Environment.TickCount); private Scene m_scene = null; diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs index 5dcf3266a9..da54c543dd 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs @@ -27,6 +27,7 @@ using System; using System.Collections; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Drawing; using System.Drawing.Imaging; @@ -67,7 +68,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap private static readonly string DEFAULT_WORLD_MAP_EXPORT_PATH = "exportmap.jpg"; private static readonly UUID STOP_UUID = UUID.Random(); - private OpenSim.Framework.BlockingQueue requests = new OpenSim.Framework.BlockingQueue(); + private BlockingCollection requests = new BlockingCollection(); private ManualResetEvent m_mapBlockRequestEvent = new ManualResetEvent(false); private Dictionary> m_mapBlockRequests = new Dictionary>(); @@ -92,6 +93,9 @@ namespace OpenSim.Region.CoreModules.World.WorldMap private const double expireResponsesTime = 120.0; // 2 minutes ? //private int CacheRegionsDistance = 256; + private bool m_exportPrintScale = false; // prints the scale of map in meters on exported map + private bool m_exportPrintRegionName = false; // prints the region name exported map + #region INonSharedRegionModule Members public virtual void Initialise(IConfigSource config) { @@ -102,6 +106,11 @@ namespace OpenSim.Region.CoreModules.World.WorldMap m_Enabled = true; expireBlackListTime = (double)Util.GetConfigVarFromSections(config, "BlacklistTimeout", configSections, 10 * 60); + + m_exportPrintScale = + Util.GetConfigVarFromSections(config, "ExportMapAddScale", configSections, m_exportPrintScale); + m_exportPrintRegionName = + Util.GetConfigVarFromSections(config, "ExportMapAddRegionName", configSections, m_exportPrintRegionName); } public virtual void AddRegion(Scene scene) @@ -215,6 +224,8 @@ namespace OpenSim.Region.CoreModules.World.WorldMap m_scene.EventManager.OnNewClient -= OnNewClient; m_scene.EventManager.OnRegisterCaps -= OnRegisterCaps; + m_scene.UnregisterModuleInterface(this); + string regionimage = "regionImage" + m_scene.RegionInfo.RegionID.ToString(); regionimage = regionimage.Replace("-", ""); MainServer.Instance.RemoveLLSDHandler("/MAP/MapItems/" + m_scene.RegionInfo.RegionHandle.ToString(), @@ -420,7 +431,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap st.itemtype = 0; st.regionhandle = 0; - requests.Enqueue(st); + requests.Add(st); MapBlockRequestData req = new MapBlockRequestData(); @@ -714,12 +725,11 @@ namespace OpenSim.Region.CoreModules.World.WorldMap { while (true) { - Watchdog.UpdateThread(); - av = null; st = null; - st = requests.Dequeue(4900); // timeout to make watchdog happy + requests.TryTake(out st, 4500); + Watchdog.UpdateThread(); if (st == null || st.agentID == UUID.Zero) continue; @@ -794,8 +804,8 @@ namespace OpenSim.Region.CoreModules.World.WorldMap else { // request still beeing processed, enqueue it back - requests.Enqueue(st); - if (requests.Count() < 3) + requests.Add(st); + if (requests.Count < 3) Thread.Sleep(100); } } @@ -838,7 +848,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap st.itemtype = itemtype; st.regionhandle = regionhandle; - requests.Enqueue(st); + requests.Add(st); } uint[] itemTypesForcedSend = new uint[] { 6, 1, 7, 10 }; // green dots, infohub, land sells @@ -1148,7 +1158,13 @@ namespace OpenSim.Region.CoreModules.World.WorldMap List thisRunData = new List(); while (true) { - m_mapBlockRequestEvent.WaitOne(); + while(!m_mapBlockRequestEvent.WaitOne(4900)) + { + Watchdog.UpdateThread(); + if(m_scene == null) + return; + } + Watchdog.UpdateThread(); lock (m_mapBlockRequestEvent) { int total = 0; @@ -1391,53 +1407,127 @@ namespace OpenSim.Region.CoreModules.World.WorldMap m_log.InfoFormat( "[WORLD MAP]: Exporting world map for {0} to {1}", m_scene.RegionInfo.RegionName, exportPath); - List mapBlocks = new List(); - List regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID, - (int)Util.RegionToWorldLoc(m_scene.RegionInfo.RegionLocX - 9), - (int)Util.RegionToWorldLoc(m_scene.RegionInfo.RegionLocX + 9), - (int)Util.RegionToWorldLoc(m_scene.RegionInfo.RegionLocY - 9), - (int)Util.RegionToWorldLoc(m_scene.RegionInfo.RegionLocY + 9)); - List textures = new List(); - List bitImages = new List(); + // assumed this is 1m less than next grid line + int regionsView = (int)m_scene.MaxRegionViewDistance; + + string regionName = m_scene.RegionInfo.RegionName; + ulong regionHandle = m_scene.RegionInfo.RegionHandle; - foreach (GridRegion r in regions) - { - MapBlockData mapBlock = new MapBlockData(); - MapBlockFromGridRegion(mapBlock, r, 0); - AssetBase texAsset = m_scene.AssetService.Get(mapBlock.MapImageId.ToString()); + int regionSizeX = (int)m_scene.RegionInfo.RegionSizeX; + int regionSizeY = (int)m_scene.RegionInfo.RegionSizeY; - if (texAsset != null) - { - textures.Add(texAsset); - } - } + int regionX = (int)m_scene.RegionInfo.WorldLocX; + int regionY = (int)m_scene.RegionInfo.WorldLocY; - foreach (AssetBase asset in textures) - { - ManagedImage managedImage; - Image image; + int startX = regionX - regionsView; + int startY = regionY - regionsView; - if (OpenJPEG.DecodeToImage(asset.Data, out managedImage, out image)) - bitImages.Add(image); - } + int endX = regionX + regionSizeX + regionsView; + int endY = regionY + regionSizeY + regionsView; + + int spanX = endX - startX + 2; + int spanY = endY - startY + 2; + + Bitmap mapTexture = new Bitmap(spanX, spanY); + ImageAttributes gatrib = new ImageAttributes(); + gatrib.SetWrapMode(System.Drawing.Drawing2D.WrapMode.TileFlipXY); + + Graphics g = Graphics.FromImage(mapTexture); + g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality; + g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; + g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; + g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.None; - Bitmap mapTexture = new Bitmap(2560, 2560); - Graphics g = Graphics.FromImage(mapTexture); SolidBrush sea = new SolidBrush(Color.DarkBlue); - g.FillRectangle(sea, 0, 0, 2560, 2560); + g.FillRectangle(sea, 0, 0, spanX, spanY); + sea.Dispose(); - for (int i = 0; i < mapBlocks.Count; i++) + Font drawFont = new Font("Arial", 32); + SolidBrush drawBrush = new SolidBrush(Color.White); + + List regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID, + startX, startY, endX, endY); + + startX--; + startY--; + + bool doneLocal = false; + string filename = "MAP-" + m_scene.RegionInfo.RegionID.ToString() + ".png"; + try { - ushort x = (ushort)((mapBlocks[i].X - m_scene.RegionInfo.RegionLocX) + 10); - ushort y = (ushort)((mapBlocks[i].Y - m_scene.RegionInfo.RegionLocY) + 10); - g.DrawImage(bitImages[i], (x * 128), 2560 - (y * 128), 128, 128); // y origin is top + using(Image localMap = Bitmap.FromFile(filename)) + { + int x = regionX - startX; + int y = regionY - startY; + int sx = regionSizeX; + int sy = regionSizeY; + // y origin is top + g.DrawImage(localMap,new Rectangle(x, spanY - y - sy, sx, sy), + 0, 0, localMap.Width, localMap.Height, GraphicsUnit.Pixel, gatrib); + + if(m_exportPrintRegionName) + { + SizeF stringSize = g.MeasureString(regionName, drawFont); + g.DrawString(regionName, drawFont, drawBrush, x + 30, spanY - y - 30 - stringSize.Height); + } + } + doneLocal = true; } + catch {} + + if(regions.Count > 0) + { + ManagedImage managedImage = null; + Image image = null; + + foreach(GridRegion r in regions) + { + if(r.TerrainImage == UUID.Zero) + continue; + + if(doneLocal && r.RegionHandle == regionHandle) + continue; + + AssetBase texAsset = m_scene.AssetService.Get(r.TerrainImage.ToString()); + if(texAsset == null) + continue; + + if(OpenJPEG.DecodeToImage(texAsset.Data, out managedImage, out image)) + { + int x = r.RegionLocX - startX; + int y = r.RegionLocY - startY; + int sx = r.RegionSizeX; + int sy = r.RegionSizeY; + // y origin is top + g.DrawImage(image,new Rectangle(x, spanY - y - sy, sx, sy), + 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, gatrib); + + if(m_exportPrintRegionName && r.RegionHandle == regionHandle) + { + SizeF stringSize = g.MeasureString(r.RegionName, drawFont); + g.DrawString(r.RegionName, drawFont, drawBrush, x + 30, spanY - y - 30 - stringSize.Height); + } + } + } + + if(image != null) + image.Dispose(); + + } + + if(m_exportPrintScale) + { + String drawString = string.Format("{0}m x {1}m", spanX, spanY); + g.DrawString(drawString, drawFont, drawBrush, 30, 30); + } + + drawBrush.Dispose(); + drawFont.Dispose(); + gatrib.Dispose(); + g.Dispose(); mapTexture.Save(exportPath, ImageFormat.Jpeg); - - g.Dispose(); mapTexture.Dispose(); - sea.Dispose(); m_log.InfoFormat( "[WORLD MAP]: Successfully exported world map for {0} to {1}", @@ -1628,11 +1718,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap if(mb > Constants.RegionSize && mb > 0) { float scale = (float)Constants.RegionSize/(float)mb; - Size newsize = new Size(); - newsize.Width = (int)(bx * scale); - newsize.Height = (int)(by * scale); - - using(Bitmap scaledbmp = new Bitmap(mapbmp,newsize)) + using(Bitmap scaledbmp = Util.ResizeImageSolid(mapbmp, (int)(bx * scale), (int)(by * scale))) data = OpenJPEG.EncodeFromImage(scaledbmp, true); } else @@ -1817,7 +1903,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap try { - return OpenJPEG.EncodeFromImage(overlay, true); + return OpenJPEG.EncodeFromImage(overlay, false); } catch (Exception e) { diff --git a/OpenSim/Region/Framework/Interfaces/IDwellModule.cs b/OpenSim/Region/Framework/Interfaces/IDwellModule.cs index db504393a2..ebef5a4749 100644 --- a/OpenSim/Region/Framework/Interfaces/IDwellModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IDwellModule.cs @@ -33,5 +33,6 @@ namespace OpenSim.Region.Framework.Interfaces public interface IDwellModule { int GetDwell(UUID parcelID); + int GetDwell(LandData land); } } diff --git a/OpenSim/Region/Framework/Interfaces/IDynamicTextureManager.cs b/OpenSim/Region/Framework/Interfaces/IDynamicTextureManager.cs index 441076dd23..093ea9c801 100644 --- a/OpenSim/Region/Framework/Interfaces/IDynamicTextureManager.cs +++ b/OpenSim/Region/Framework/Interfaces/IDynamicTextureManager.cs @@ -44,14 +44,13 @@ namespace OpenSim.Region.Framework.Interfaces /// void ReturnData(UUID id, IDynamicTexture texture); + UUID AddDynamicTextureURL(UUID simID, UUID primID, string contentType, string url, string extraParams); UUID AddDynamicTextureURL(UUID simID, UUID primID, string contentType, string url, string extraParams, - int updateTimer); + bool SetBlending, byte AlphaValue); UUID AddDynamicTextureURL(UUID simID, UUID primID, string contentType, string url, string extraParams, - int updateTimer, bool SetBlending, byte AlphaValue); - UUID AddDynamicTextureURL(UUID simID, UUID primID, string contentType, string url, string extraParams, - int updateTimer, bool SetBlending, int disp, byte AlphaValue, int face); - UUID AddDynamicTextureData(UUID simID, UUID primID, string contentType, string data, string extraParams, - int updateTimer); + bool SetBlending, int disp, byte AlphaValue, int face); + + UUID AddDynamicTextureData(UUID simID, UUID primID, string contentType, string data, string extraParams); /// Apply a dynamically generated texture to all sides of the given prim. The texture is not persisted to the /// asset service. @@ -62,8 +61,6 @@ namespace OpenSim.Region.Framework.Interfaces /// based texture or "image" to create a texture from an image at a particular URL /// The data for the generator /// Parameters for the generator that don't form part of the main data. - /// If zero, the image is never updated after the first generation. If positive - /// the image is updated at the given interval. Not implemented for /// /// If true, the newly generated texture is blended with the appropriate existing ones on the prim /// @@ -76,7 +73,7 @@ namespace OpenSim.Region.Framework.Interfaces /// can be obtained as SceneObjectPart.Shape.Textures.DefaultTexture.TextureID /// UUID AddDynamicTextureData(UUID simID, UUID primID, string contentType, string data, string extraParams, - int updateTimer, bool SetBlending, byte AlphaValue); + bool SetBlending, byte AlphaValue); /// /// Apply a dynamically generated texture to the given prim. @@ -87,8 +84,6 @@ namespace OpenSim.Region.Framework.Interfaces /// based texture or "image" to create a texture from an image at a particular URL /// The data for the generator /// Parameters for the generator that don't form part of the main data. - /// If zero, the image is never updated after the first generation. If positive - /// the image is updated at the given interval. Not implemented for /// /// If true, the newly generated texture is blended with the appropriate existing ones on the prim /// @@ -109,9 +104,8 @@ namespace OpenSim.Region.Framework.Interfaces /// to obtain it directly from the SceneObjectPart. For instance, if ALL_SIDES is set then this texture /// can be obtained as SceneObjectPart.Shape.Textures.DefaultTexture.TextureID /// - UUID AddDynamicTextureData( - UUID simID, UUID primID, string contentType, string data, string extraParams, - int updateTimer, bool SetBlending, int disp, byte AlphaValue, int face); + UUID AddDynamicTextureData(UUID simID, UUID primID, string contentType, string data, string extraParams, + bool SetBlending, int disp, byte AlphaValue, int face); void GetDrawStringSize(string contentType, string text, string fontName, int fontSize, out double xSize, out double ySize); diff --git a/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs b/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs index 9585082719..1b690bad3f 100644 --- a/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs @@ -102,6 +102,8 @@ namespace OpenSim.Region.Framework.Interfaces ScenePresence CrossAgentToNewRegionAsync(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, bool isFlying, EntityTransferContext ctx); + bool CrossAgentCreateFarChild(ScenePresence agent, GridRegion neighbourRegion, Vector3 pos, EntityTransferContext ctx); + bool HandleIncomingSceneObject(SceneObjectGroup so, Vector3 newPosition); } diff --git a/OpenSim/Region/Framework/Interfaces/IEventQueue.cs b/OpenSim/Region/Framework/Interfaces/IEventQueue.cs index 7af56cb809..7edd75aaba 100644 --- a/OpenSim/Region/Framework/Interfaces/IEventQueue.cs +++ b/OpenSim/Region/Framework/Interfaces/IEventQueue.cs @@ -39,7 +39,7 @@ namespace OpenSim.Region.Framework.Interfaces bool Enqueue(OSD o, UUID avatarID); // These are required to decouple Scenes from EventQueueHelper - void DisableSimulator(ulong handle, UUID avatarID); +// void DisableSimulator(ulong handle, UUID avatarID); void EnableSimulator(ulong handle, IPEndPoint endPoint, UUID avatarID, int regionSizeX, int regionSizeY); void EstablishAgentCommunication(UUID avatarID, IPEndPoint endPoint, string capsPath, ulong regionHandle, int regionSizeX, int regionSizeY); diff --git a/OpenSim/Region/Framework/Interfaces/IMaterialsModule.cs b/OpenSim/Region/Framework/Interfaces/IMaterialsModule.cs new file mode 100644 index 0000000000..837806338f --- /dev/null +++ b/OpenSim/Region/Framework/Interfaces/IMaterialsModule.cs @@ -0,0 +1,40 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using OpenSim.Region.Framework.Scenes; +using OpenMetaverse; + +namespace OpenSim.Region.Framework.Interfaces +{ + public interface IMaterialsModule + { + FaceMaterial GetMaterial(UUID ID); + FaceMaterial GetMaterialCopy(UUID ID); + UUID AddNewMaterial(FaceMaterial fm); + void RemoveMaterial(UUID id); + } +} diff --git a/OpenSim/Region/Framework/Interfaces/ISoundModule.cs b/OpenSim/Region/Framework/Interfaces/ISoundModule.cs index f7c6513cd1..aaa99315f3 100644 --- a/OpenSim/Region/Framework/Interfaces/ISoundModule.cs +++ b/OpenSim/Region/Framework/Interfaces/ISoundModule.cs @@ -46,11 +46,9 @@ namespace OpenSim.Region.Framework.Interfaces /// Sound volume /// Sound source position /// Sound flags - /// - /// Radius used to affect gain over distance. /// void PlayAttachedSound(UUID soundID, UUID ownerID, UUID objectID, - double gain, Vector3 position, byte flags, float radius); + double gain, Vector3 position, byte flags); /// /// Trigger a sound in the scene. @@ -67,7 +65,7 @@ namespace OpenSim.Region.Framework.Interfaces /// void TriggerSound( UUID soundId, UUID ownerID, UUID objectID, UUID parentID, - double gain, Vector3 position, UInt64 handle, float radius); + double gain, Vector3 position, UInt64 handle); /// /// Stop sounds eminating from an object. @@ -80,10 +78,8 @@ namespace OpenSim.Region.Framework.Interfaces /// /// Sound source ID /// Sound asset ID - /// - /// Radius used to determine which viewers should preload the sound. /// - void PreloadSound(UUID objectID, UUID soundID, float radius); + void PreloadSound(UUID objectID, UUID soundID); /// /// Loop specified sound at specified volume with specified radius, @@ -92,10 +88,9 @@ namespace OpenSim.Region.Framework.Interfaces /// Sound source ID /// Sound asset ID /// Sound volume - /// Sound radius /// Set object to sync master if true void LoopSound(UUID objectID, UUID soundID, double gain, - double radius, bool isMaster, bool isSlave); + bool isMaster, bool isSlave); /// /// Trigger or play an attached sound in this part's inventory. @@ -104,11 +99,10 @@ namespace OpenSim.Region.Framework.Interfaces /// Sound asset ID /// Sound volume /// Triggered or not. - /// Sound radius /// Play using sound master /// Play as sound master void SendSound(UUID objectID, UUID sound, double volume, - bool triggered, byte flags, float radius, bool useMaster, + bool triggered, byte flags, bool useMaster, bool isMaster); /// diff --git a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs index 6b31555fb6..5c33f1272e 100644 --- a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs +++ b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs @@ -618,13 +618,147 @@ namespace OpenSim.Region.Framework.Scenes.Animation int rnditerations = 3; BinBVHAnimation anim = new BinBVHAnimation(); List parts = new List(); - parts.Add("mPelvis"); parts.Add("mHead"); parts.Add("mTorso"); - parts.Add("mHipLeft"); parts.Add("mHipRight"); parts.Add("mHipLeft"); parts.Add("mKneeLeft"); - parts.Add("mKneeRight"); parts.Add("mCollarLeft"); parts.Add("mCollarRight"); parts.Add("mNeck"); - parts.Add("mElbowLeft"); parts.Add("mElbowRight"); parts.Add("mWristLeft"); parts.Add("mWristRight"); - parts.Add("mShoulderLeft"); parts.Add("mShoulderRight"); parts.Add("mAnkleLeft"); parts.Add("mAnkleRight"); - parts.Add("mEyeRight"); parts.Add("mChest"); parts.Add("mToeLeft"); parts.Add("mToeRight"); - parts.Add("mFootLeft"); parts.Add("mFootRight"); parts.Add("mEyeLeft"); + + /// Torso and Head + parts.Add("mPelvis"); + parts.Add("mTorso"); + parts.Add("mChest"); + parts.Add("mNeck"); + parts.Add("mHead"); + parts.Add("mSkull"); + parts.Add("mEyeRight"); + parts.Add("mEyeLeft"); + /// Arms + parts.Add("mCollarLeft"); + parts.Add("mShoulderLeft"); + parts.Add("mElbowLeft"); + parts.Add("mWristLeft"); + parts.Add("mCollarRight"); + parts.Add("mShoulderRight"); + parts.Add("mElbowRight"); + parts.Add("mWristRight"); + /// Legs + parts.Add("mHipLeft"); + parts.Add("mKneeLeft"); + parts.Add("mAnkleLeft"); + parts.Add("mFootLeft"); + parts.Add("mToeLeft"); + parts.Add("mHipRight"); + parts.Add("mKneeRight"); + parts.Add("mAnkleRight"); + parts.Add("mFootRight"); + parts.Add("mToeRight"); + ///Hands + parts.Add("mHandThumb1Left"); + parts.Add("mHandThumb1Right"); + parts.Add("mHandThumb2Left"); + parts.Add("mHandThumb2Right"); + parts.Add("mHandThumb3Left"); + parts.Add("mHandThumb3Right"); + parts.Add("mHandIndex1Left"); + parts.Add("mHandIndex1Right"); + parts.Add("mHandIndex2Left"); + parts.Add("mHandIndex2Right"); + parts.Add("mHandIndex3Left"); + parts.Add("mHandIndex3Right"); + parts.Add("mHandMiddle1Left"); + parts.Add("mHandMiddle1Right"); + parts.Add("mHandMiddle2Left"); + parts.Add("mHandMiddle2Right"); + parts.Add("mHandMiddle3Left"); + parts.Add("mHandMiddle3Right"); + parts.Add("mHandRing1Left"); + parts.Add("mHandRing1Right"); + parts.Add("mHandRing2Left"); + parts.Add("mHandRing2Right"); + parts.Add("mHandRing3Left"); + parts.Add("mHandRing3Right"); + parts.Add("mHandPinky1Left"); + parts.Add("mHandPinky1Right"); + parts.Add("mHandPinky2Left"); + parts.Add("mHandPinky2Right"); + parts.Add("mHandPinky3Left"); + parts.Add("mHandPinky3Right"); + ///Face + parts.Add("mFaceForeheadLeft"); + parts.Add("mFaceForeheadCenter"); + parts.Add("mFaceForeheadRight"); + parts.Add("mFaceEyebrowOuterLeft"); + parts.Add("mFaceEyebrowCenterLeft"); + parts.Add("mFaceEyebrowInnerLeft"); + parts.Add("mFaceEyebrowOuterRight"); + parts.Add("mFaceEyebrowCenterRight"); + parts.Add("mFaceEyebrowInnerRight"); + parts.Add("mFaceEyeLidUpperLeft"); + parts.Add("mFaceEyeLidLowerLeft"); + parts.Add("mFaceEyeLidUpperRight"); + parts.Add("mFaceEyeLidLowerRight"); + parts.Add("mFaceEyeAltLeft"); + parts.Add("mFaceEyeAltRight"); + parts.Add("mFaceEyecornerInnerLeft"); + parts.Add("mFaceEyecornerInnerRight"); + parts.Add("mFaceEar1Left"); + parts.Add("mFaceEar2Left"); + parts.Add("mFaceEar1Right"); + parts.Add("mFaceEar2Right"); + parts.Add("mFaceNoseLeft"); + parts.Add("mFaceNoseCenter"); + parts.Add("mFaceNoseRight"); + parts.Add("mFaceNoseBase"); + parts.Add("mFaceNoseBridge"); + parts.Add("mFaceCheekUpperInnerLeft"); + parts.Add("mFaceCheekUpperOuterLeft"); + parts.Add("mFaceCheekUpperInnerRight"); + parts.Add("mFaceCheekUpperOuterRight"); + parts.Add("mFaceJaw"); + parts.Add("mFaceLipUpperLeft"); + parts.Add("mFaceLipUpperCenter"); + parts.Add("mFaceLipUpperRight"); + parts.Add("mFaceLipCornerLeft"); + parts.Add("mFaceLipCornerRight"); + parts.Add("mFaceTongueBase"); + parts.Add("mFaceTongueTip"); + parts.Add("mFaceLipLowerLeft"); + parts.Add("mFaceLipLowerCenter"); + parts.Add("mFaceLipLowerRight"); + parts.Add("mFaceTeethLower"); + parts.Add("mFaceTeethUpper"); + parts.Add("mFaceChin"); + ///Spine + parts.Add("mSpine1"); + parts.Add("mSpine2"); + parts.Add("mSpine3"); + parts.Add("mSpine4"); + ///Wings + parts.Add("mWingsRoot"); + parts.Add("mWing1Left"); + parts.Add("mWing2Left"); + parts.Add("mWing3Left"); + parts.Add("mWing4Left"); + parts.Add("mWing1Right"); + parts.Add("mWing2Right"); + parts.Add("mWing3Right"); + parts.Add("mWing4Right"); + parts.Add("mWing4FanRight"); + parts.Add("mWing4FanLeft"); + ///Hind Limbs + parts.Add("mHindLimbsRoot"); + parts.Add("mHindLimb1Left"); + parts.Add("mHindLimb2Left"); + parts.Add("mHindLimb3Left"); + parts.Add("mHindLimb4Left"); + parts.Add("mHindLimb1Right"); + parts.Add("mHindLimb2Right"); + parts.Add("mHindLimb3Right"); + parts.Add("mHindLimb4Right"); + ///Tail + parts.Add("mTail1"); + parts.Add("mTail2"); + parts.Add("mTail3"); + parts.Add("mTail4"); + parts.Add("mTail5"); + parts.Add("mTail6"); + anim.HandPose = 1; anim.InPoint = 0; anim.OutPoint = (rnditerations * .10f); diff --git a/OpenSim/Region/Framework/Scenes/CollisionSounds.cs b/OpenSim/Region/Framework/Scenes/CollisionSounds.cs index e76fef4a79..63aafcd066 100644 --- a/OpenSim/Region/Framework/Scenes/CollisionSounds.cs +++ b/OpenSim/Region/Framework/Scenes/CollisionSounds.cs @@ -116,16 +116,20 @@ namespace OpenSim.Region.Framework.Scenes public static void PartCollisionSound(SceneObjectPart part, List collidersinfolist) { + if (part.CollisionSoundType < 0) + return; + if (collidersinfolist.Count == 0 || part == null) return; if (part.VolumeDetectActive || (part.Flags & PrimFlags.Physics) == 0) return; - if (part.ParentGroup == null) + SceneObjectGroup sog = part.ParentGroup; + if (sog == null || sog.IsDeleted || sog.inTransit) return; - if (part.CollisionSoundType < 0) + if(sog.CollisionSoundThrottled(part.CollisionSoundType)) return; float volume = part.CollisionSoundVolume; @@ -189,15 +193,23 @@ namespace OpenSim.Region.Framework.Scenes continue; } - SceneObjectPart otherPart = part.ParentGroup.Scene.GetSceneObjectPart(id); + SceneObjectPart otherPart = sog.Scene.GetSceneObjectPart(id); if (otherPart != null) { - if (otherPart.CollisionSoundType < 0 || otherPart.VolumeDetectActive) + SceneObjectGroup othersog = otherPart.ParentGroup; + if(othersog == null || othersog.IsDeleted || othersog.inTransit) + continue; + + int otherType = otherPart.CollisionSoundType; + if (otherType < 0 || otherPart.VolumeDetectActive) continue; if (!HaveSound) { - if (otherPart.CollisionSoundType == 1) + if(othersog.CollisionSoundThrottled(otherType)) + continue; + + if (otherType == 1) { soundID = otherPart.CollisionSound; volume = otherPart.CollisionSoundVolume; @@ -206,7 +218,7 @@ namespace OpenSim.Region.Framework.Scenes } else { - if (otherPart.CollisionSoundType == 2) + if (otherType == 2) { volume = otherPart.CollisionSoundVolume; if (volume == 0.0f) diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs index 827f91ee56..f76f8828d0 100644 --- a/OpenSim/Region/Framework/Scenes/EventManager.cs +++ b/OpenSim/Region/Framework/Scenes/EventManager.cs @@ -855,7 +855,7 @@ namespace OpenSim.Region.Framework.Scenes /// , /// , /// , - /// , + /// , /// /// public event ParcelPrimCountTainted OnParcelPrimCountTainted; diff --git a/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs b/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs index e4aa196497..bf20c32540 100644 --- a/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs +++ b/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs @@ -295,6 +295,7 @@ namespace OpenSim.Region.Framework.Scenes lock (m_frames) { KeyframeTimer.Add(this); + m_lasttickMS = Util.GetTimeStampMS(); m_timerStopped = false; } } @@ -326,8 +327,8 @@ namespace OpenSim.Region.Framework.Scenes newMotion.m_selected = true; } - newMotion.m_timerStopped = false; - newMotion.m_running = true; +// newMotion.m_timerStopped = false; +// newMotion.m_running = true; newMotion.m_isCrossing = false; newMotion.m_waitingCrossing = false; } @@ -483,9 +484,10 @@ namespace OpenSim.Region.Framework.Scenes m_group.RootPart.Velocity = Vector3.Zero; m_group.RootPart.AngularVelocity = Vector3.Zero; - m_group.SendGroupRootTerseUpdate(); -// m_group.RootPart.ScheduleTerseUpdate(); +// m_group.SendGroupRootTerseUpdate(); + m_group.RootPart.ScheduleTerseUpdate(); m_frames.Clear(); + m_group.Scene.EventManager.TriggerMovingEndEvent(m_group.RootPart.LocalId); } public void Pause() @@ -495,8 +497,10 @@ namespace OpenSim.Region.Framework.Scenes m_group.RootPart.Velocity = Vector3.Zero; m_group.RootPart.AngularVelocity = Vector3.Zero; - m_group.SendGroupRootTerseUpdate(); -// m_group.RootPart.ScheduleTerseUpdate(); +// m_skippedUpdates = 1000; +// m_group.SendGroupRootTerseUpdate(); + m_group.RootPart.ScheduleTerseUpdate(); + m_group.Scene.EventManager.TriggerMovingEndEvent(m_group.RootPart.LocalId); } public void Suspend() @@ -517,6 +521,7 @@ namespace OpenSim.Region.Framework.Scenes return; if (m_running && !m_waitingCrossing) StartTimer(); +// m_skippedUpdates = 1000; } } @@ -642,11 +647,17 @@ namespace OpenSim.Region.Framework.Scenes m_group.RootPart.Velocity = Vector3.Zero; m_group.RootPart.AngularVelocity = Vector3.Zero; - m_group.SendGroupRootTerseUpdate(); - // m_group.RootPart.ScheduleTerseUpdate(); +// m_group.SendGroupRootTerseUpdate(); + m_group.RootPart.ScheduleTerseUpdate(); m_frames.Clear(); } +// [NonSerialized()] Vector3 m_lastPosUpdate; +// [NonSerialized()] Quaternion m_lastRotationUpdate; + [NonSerialized()] Vector3 m_currentVel; +// [NonSerialized()] int m_skippedUpdates; + [NonSerialized()] double m_lasttickMS; + private void DoOnTimer(double tickDuration) { if (m_skipLoops > 0) @@ -658,14 +669,16 @@ namespace OpenSim.Region.Framework.Scenes if (m_group == null) return; - bool update = false; +// bool update = false; if (m_selected) { if (m_group.RootPart.Velocity != Vector3.Zero) { m_group.RootPart.Velocity = Vector3.Zero; - m_group.SendGroupRootTerseUpdate(); +// m_skippedUpdates = 1000; +// m_group.SendGroupRootTerseUpdate(); + m_group.RootPart.ScheduleTerseUpdate(); } return; } @@ -677,7 +690,9 @@ namespace OpenSim.Region.Framework.Scenes // retry to set the position that evtually caused the outbound // if still outside region this will call startCrossing below m_isCrossing = false; +// m_skippedUpdates = 1000; m_group.AbsolutePosition = m_nextPosition; + if (!m_isCrossing) { StopTimer(); @@ -686,6 +701,8 @@ namespace OpenSim.Region.Framework.Scenes return; } + double nowMS = Util.GetTimeStampMS(); + if (m_frames.Count == 0) { lock (m_frames) @@ -700,19 +717,27 @@ namespace OpenSim.Region.Framework.Scenes } m_currentFrame = m_frames[0]; - m_currentFrame.TimeMS += (int)tickDuration; } - //force a update on a keyframe transition m_nextPosition = m_group.AbsolutePosition; - update = true; + m_currentVel = (Vector3)m_currentFrame.Position - m_nextPosition; + m_currentVel /= (m_currentFrame.TimeMS * 0.001f); + + m_currentFrame.TimeMS += (int)tickDuration; + m_lasttickMS = nowMS - 50f; +// update = true; } - m_currentFrame.TimeMS -= (int)tickDuration; + int elapsed = (int)(nowMS - m_lasttickMS); + if( elapsed > 3 * tickDuration) + elapsed = (int)tickDuration; + + m_currentFrame.TimeMS -= elapsed; + m_lasttickMS = nowMS; // Do the frame processing double remainingSteps = (double)m_currentFrame.TimeMS / tickDuration; - if (remainingSteps <= 0.0) + if (remainingSteps <= 1.0) { m_group.RootPart.Velocity = Vector3.Zero; m_group.RootPart.AngularVelocity = Vector3.Zero; @@ -720,94 +745,77 @@ namespace OpenSim.Region.Framework.Scenes m_nextPosition = (Vector3)m_currentFrame.Position; m_group.AbsolutePosition = m_nextPosition; - // we are sending imediate updates, no doing force a extra terseUpdate - // m_group.UpdateGroupRotationR((Quaternion)m_currentFrame.Rotation); - m_group.RootPart.RotationOffset = (Quaternion)m_currentFrame.Rotation; lock (m_frames) { m_frames.RemoveAt(0); if (m_frames.Count > 0) + { m_currentFrame = m_frames[0]; + m_currentVel = (Vector3)m_currentFrame.Position - m_nextPosition; + m_currentVel /= (m_currentFrame.TimeMS * 0.001f); + m_group.RootPart.Velocity = m_currentVel; + m_currentFrame.TimeMS += (int)tickDuration; + } + else + m_group.RootPart.Velocity = Vector3.Zero; } - - update = true; +// update = true; } else { - float completed = ((float)m_currentFrame.TimeTotal - (float)m_currentFrame.TimeMS) / (float)m_currentFrame.TimeTotal; - bool lastStep = m_currentFrame.TimeMS <= tickDuration; +// bool lastSteps = remainingSteps < 4; + + Vector3 currentPosition = m_group.AbsolutePosition; + Vector3 motionThisFrame = (Vector3)m_currentFrame.Position - currentPosition; + motionThisFrame /= (float)remainingSteps; + + m_nextPosition = currentPosition + motionThisFrame; - Vector3 v = (Vector3)m_currentFrame.Position - m_group.AbsolutePosition; - Vector3 motionThisFrame = v / (float)remainingSteps; - v = v * 1000 / m_currentFrame.TimeMS; - - m_nextPosition = m_group.AbsolutePosition + motionThisFrame; - - if (Vector3.Mag(motionThisFrame) >= 0.05f) - update = true; - - //int totalSteps = m_currentFrame.TimeTotal / (int)tickDuration; - //m_log.DebugFormat("KeyframeMotion.OnTimer: step {0}/{1}, curPosition={2}, finalPosition={3}, motionThisStep={4} (scene {5})", - // totalSteps - remainingSteps + 1, totalSteps, m_group.AbsolutePosition, m_currentFrame.Position, motionThisStep, m_scene.RegionInfo.RegionName); - - if ((Quaternion)m_currentFrame.Rotation != m_group.GroupRotation) + Quaternion currentRotation = m_group.GroupRotation; + if ((Quaternion)m_currentFrame.Rotation != currentRotation) { - Quaternion current = m_group.GroupRotation; - + float completed = ((float)m_currentFrame.TimeTotal - (float)m_currentFrame.TimeMS) / (float)m_currentFrame.TimeTotal; Quaternion step = Quaternion.Slerp(m_currentFrame.StartRotation, (Quaternion)m_currentFrame.Rotation, completed); step.Normalize(); - /* use simpler change detection - * float angle = 0; - - float aa = current.X * current.X + current.Y * current.Y + current.Z * current.Z + current.W * current.W; - float bb = step.X * step.X + step.Y * step.Y + step.Z * step.Z + step.W * step.W; - float aa_bb = aa * bb; - - if (aa_bb == 0) - { - angle = 0; - } - else - { - float ab = current.X * step.X + - current.Y * step.Y + - current.Z * step.Z + - current.W * step.W; - float q = (ab * ab) / aa_bb; - - if (q > 1.0f) - { - angle = 0; - } - else - { - angle = (float)Math.Acos(2 * q - 1); - } - } - - if (angle > 0.01f) - */ - if (Math.Abs(step.X - current.X) > 0.001f - || Math.Abs(step.Y - current.Y) > 0.001f - || Math.Abs(step.Z - current.Z) > 0.001f) - // assuming w is a dependente var - { -// m_group.UpdateGroupRotationR(step); - m_group.RootPart.RotationOffset = step; - - //m_group.RootPart.UpdateAngularVelocity(m_currentFrame.AngularVelocity / 2); + m_group.RootPart.RotationOffset = step; +/* + if (Math.Abs(step.X - m_lastRotationUpdate.X) > 0.001f + || Math.Abs(step.Y - m_lastRotationUpdate.Y) > 0.001f + || Math.Abs(step.Z - m_lastRotationUpdate.Z) > 0.001f) update = true; - } +*/ } - } - if (update) - { m_group.AbsolutePosition = m_nextPosition; - m_group.SendGroupRootTerseUpdate(); +// if(lastSteps) +// m_group.RootPart.Velocity = Vector3.Zero; +// else + m_group.RootPart.Velocity = m_currentVel; +/* + if(!update && ( +// lastSteps || + m_skippedUpdates * tickDuration > 0.5 || + Math.Abs(m_nextPosition.X - currentPosition.X) > 5f || + Math.Abs(m_nextPosition.Y - currentPosition.Y) > 5f || + Math.Abs(m_nextPosition.Z - currentPosition.Z) > 5f + )) + { + update = true; + } + else + m_skippedUpdates++; +*/ } +// if(update) +// { +// m_lastPosUpdate = m_nextPosition; +// m_lastRotationUpdate = m_group.GroupRotation; +// m_skippedUpdates = 0; +// m_group.SendGroupRootTerseUpdate(); + m_group.RootPart.ScheduleTerseUpdate(); +// } } public Byte[] Serialize() @@ -850,8 +858,9 @@ namespace OpenSim.Region.Framework.Scenes if (m_group.RootPart.Velocity != Vector3.Zero) { m_group.RootPart.Velocity = Vector3.Zero; - m_group.SendGroupRootTerseUpdate(); -// m_group.RootPart.ScheduleTerseUpdate(); +// m_skippedUpdates = 1000; +// m_group.SendGroupRootTerseUpdate(); + m_group.RootPart.ScheduleTerseUpdate(); } } @@ -862,8 +871,9 @@ namespace OpenSim.Region.Framework.Scenes if (m_group != null) { m_group.RootPart.Velocity = Vector3.Zero; - m_group.SendGroupRootTerseUpdate(); -// m_group.RootPart.ScheduleTerseUpdate(); +// m_skippedUpdates = 1000; +// m_group.SendGroupRootTerseUpdate(); + m_group.RootPart.ScheduleTerseUpdate(); if (m_running) { diff --git a/OpenSim/Region/Framework/Scenes/Prioritizer.cs b/OpenSim/Region/Framework/Scenes/Prioritizer.cs index cbf40c80c5..53ca849fb1 100644 --- a/OpenSim/Region/Framework/Scenes/Prioritizer.cs +++ b/OpenSim/Region/Framework/Scenes/Prioritizer.cs @@ -172,14 +172,22 @@ namespace OpenSim.Region.Framework.Scenes if (entity is SceneObjectPart) { + SceneObjectGroup sog = ((SceneObjectPart)entity).ParentGroup; // Attachments are high priority, - if (((SceneObjectPart)entity).ParentGroup.IsAttachment) + if (sog.IsAttachment) return 2; + + + if(presence.ParentPart != null) + { + if(presence.ParentPart.ParentGroup == sog) + return 2; + } pqueue = ComputeDistancePriority(client, entity, false); // Non physical prims are lower priority than physical prims - PhysicsActor physActor = ((SceneObjectPart)entity).ParentGroup.RootPart.PhysActor; + PhysicsActor physActor = sog.RootPart.PhysActor; if (physActor == null || !physActor.IsPhysical) pqueue++; } @@ -302,6 +310,17 @@ namespace OpenSim.Region.Framework.Scenes else { SceneObjectGroup group = (entity as SceneObjectPart).ParentGroup; + if(presence.ParentPart != null) + { + if(presence.ParentPart.ParentGroup == group) + return pqueue; + } + if(group.IsAttachment) + { + if(group.RootPart.LocalId == presence.LocalId) + return pqueue; + } + float bradius = group.GetBoundsRadius(); Vector3 grppos = group.AbsolutePosition + group.getBoundsCenter(); distance = Vector3.Distance(presencePos, grppos); diff --git a/OpenSim/Region/Framework/Scenes/SOPMaterial.cs b/OpenSim/Region/Framework/Scenes/SOPMaterial.cs index 651c52eee5..e4b9380271 100644 --- a/OpenSim/Region/Framework/Scenes/SOPMaterial.cs +++ b/OpenSim/Region/Framework/Scenes/SOPMaterial.cs @@ -26,9 +26,12 @@ */ using System; -using System.Collections.Generic; -using OpenMetaverse; +using System.Text; +using System.Runtime.InteropServices; +using System.Security.Cryptography; // for computing md5 hash using OpenSim.Framework; +using OpenMetaverse; +using OpenMetaverse.StructuredData; namespace OpenSim.Region.Framework.Scenes { @@ -90,6 +93,250 @@ namespace OpenSim.Region.Framework.Scenes else return 0; } + } + [StructLayout(LayoutKind.Sequential)] + public class FaceMaterial + { + // ll material data + public byte DiffuseAlphaMode = 1; + public byte AlphaMaskCutoff = 0; + public byte SpecularLightExponent = 51; + public byte EnvironmentIntensity = 0; + // need to have 4 bytes here + public float NormalOffsetX = 0.0f; + public float NormalOffsetY = 0.0f; + public float NormalRepeatX = 1.0f; + public float NormalRepeatY = 1.0f; + public float NormalRotation = 0.0f; + + public float SpecularOffsetX = 0.0f; + public float SpecularOffsetY = 0.0f; + public float SpecularRepeatX = 1.0f; + public float SpecularRepeatY = 1.0f; + public float SpecularRotation = 0.0f; + + public byte SpecularLightColorR = 255; + public byte SpecularLightColorG = 255; + public byte SpecularLightColorB = 255; + public byte SpecularLightColorA = 255; + // data size 12 ints so far + public UUID NormalMapID = UUID.Zero; + public UUID SpecularMapID = UUID.Zero; + + // other data + public UUID ID; + private int inthash; + private bool validinthash; + + public FaceMaterial() + { } + + public FaceMaterial(FaceMaterial other) + { + if(other == null) + return; + + DiffuseAlphaMode = other.DiffuseAlphaMode; + AlphaMaskCutoff = other.AlphaMaskCutoff; + SpecularLightExponent = other.SpecularLightExponent; + EnvironmentIntensity = other.EnvironmentIntensity; + NormalOffsetX = other.NormalOffsetX; + NormalOffsetY = other.NormalOffsetY; + NormalRepeatX = other.NormalRepeatX; + NormalRepeatY = other.NormalRepeatY; + NormalRotation = other.NormalRotation; + SpecularOffsetX = other.SpecularOffsetX; + SpecularOffsetY = other.SpecularOffsetY; + SpecularRepeatX = other.SpecularRepeatX; + SpecularRepeatY = other.SpecularRepeatY; + SpecularRotation = other.SpecularRotation; + SpecularLightColorR = other.SpecularLightColorR; + SpecularLightColorG = other.SpecularLightColorG; + SpecularLightColorB = other.SpecularLightColorB; + NormalMapID = other.NormalMapID; + SpecularMapID = other.SpecularMapID; + } + + public FaceMaterial(OSDMap mat) + { + if(mat == null) + return; + const float scale = 0.0001f; + NormalMapID = mat["NormMap"].AsUUID(); + NormalOffsetX = scale * (float)mat["NormOffsetX"].AsReal(); + NormalOffsetY = scale * (float)mat["NormOffsetY"].AsReal(); + NormalRepeatX = scale * (float)mat["NormRepeatX"].AsReal(); + NormalRepeatY = scale * (float)mat["NormRepeatY"].AsReal(); + NormalRotation = scale * (float)mat["NormRotation"].AsReal(); + + SpecularMapID = mat["SpecMap"].AsUUID(); + SpecularOffsetX = scale * (float)mat["SpecOffsetX"].AsReal(); + SpecularOffsetY = scale * (float)mat["SpecOffsetY"].AsReal(); + SpecularRepeatX = scale * (float)mat["SpecRepeatX"].AsReal(); + SpecularRepeatY = scale * (float)mat["SpecRepeatY"].AsReal(); + SpecularRotation = scale * (float)mat["SpecRotation"].AsReal(); + + Color4 SpecularLightColortmp = mat["SpecColor"].AsColor4(); // we can read as color4 + SpecularLightColorR = (byte)(SpecularLightColortmp.R); + SpecularLightColorG = (byte)(SpecularLightColortmp.G); + SpecularLightColorB = (byte)(SpecularLightColortmp.B); + + SpecularLightExponent = (Byte)mat["SpecExp"].AsUInteger(); + EnvironmentIntensity = (Byte)mat["EnvIntensity"].AsUInteger(); + DiffuseAlphaMode = (Byte)mat["DiffuseAlphaMode"].AsUInteger(); + AlphaMaskCutoff = (Byte)mat["AlphaMaskCutoff"].AsUInteger(); + } + + public void genID() + { + string lslx = toLLSDxml(); + Byte[] data = System.Text.Encoding.ASCII.GetBytes(lslx); + using (var md5 = MD5.Create()) + ID = new UUID(md5.ComputeHash(data), 0); + } + + public unsafe override int GetHashCode() + { + if(!validinthash) + { + unchecked + { + // if you don't like this, don't read... + int* ptr; + fixed(byte* ptrbase = &DiffuseAlphaMode) + { + ptr = (int*)ptrbase; + inthash = *ptr; + for(int i = 0; i < 11; i++) + inthash ^= *ptr++; + } + fixed(Guid* ptrbase = &NormalMapID.Guid) + { + ptr = (int*)ptrbase; + for(int i = 0; i < 16; i++) + inthash ^= ptr[i]; + } + fixed(Guid* ptrbase = &SpecularMapID.Guid) + { + ptr = (int*)ptrbase; + for(int i = 0; i < 16; i++) + inthash ^= ptr[i]; + } + } + validinthash = true; + } + return inthash; + } + + public override bool Equals(Object o) + { + if(o == null || !(o is FaceMaterial)) + return false; + + FaceMaterial other = (FaceMaterial)o; + return ( + DiffuseAlphaMode == other.DiffuseAlphaMode + && AlphaMaskCutoff == other.AlphaMaskCutoff + && SpecularLightExponent == other.SpecularLightExponent + && EnvironmentIntensity == other.EnvironmentIntensity + && NormalMapID == other.NormalMapID + && NormalOffsetX == other.NormalOffsetX + && NormalOffsetY == other.NormalOffsetY + && NormalRepeatX == other.NormalRepeatX + && NormalRepeatY == other.NormalRepeatY + && NormalRotation == other.NormalRotation + && SpecularMapID == other.SpecularMapID + && SpecularOffsetX == other.SpecularOffsetX + && SpecularOffsetY == other.SpecularOffsetY + && SpecularRepeatX == other.SpecularRepeatX + && SpecularRepeatY == other.SpecularRepeatY + && SpecularRotation == other.SpecularRotation + && SpecularLightColorR == other.SpecularLightColorR + && SpecularLightColorG == other.SpecularLightColorG + && SpecularLightColorB == other.SpecularLightColorB + ); + } + + public OSDMap toOSD() + { + OSDMap mat = new OSDMap(); + float scale = 10000f; + + mat["NormMap"] = NormalMapID; + mat["NormOffsetX"] = (int) (scale * NormalOffsetX); + mat["NormOffsetY"] = (int) (scale * NormalOffsetY); + mat["NormRepeatX"] = (int) (scale * NormalRepeatX); + mat["NormRepeatY"] = (int) (scale * NormalRepeatY); + mat["NormRotation"] = (int) (scale * NormalRotation); + + mat["SpecMap"] = SpecularMapID; + mat["SpecOffsetX"] = (int) (scale * SpecularOffsetX); + mat["SpecOffsetY"] = (int) (scale * SpecularOffsetY); + mat["SpecRepeatX"] = (int) (scale * SpecularRepeatX); + mat["SpecRepeatY"] = (int) (scale * SpecularRepeatY); + mat["SpecRotation"] = (int) (scale * SpecularRotation); + + OSDArray carray = new OSDArray(4); + carray.Add(SpecularLightColorR); + carray.Add(SpecularLightColorG); + carray.Add(SpecularLightColorB); + carray.Add(255); // solid color + mat["SpecColor"] = carray; + mat["SpecExp"] = SpecularLightExponent; + mat["EnvIntensity"] = EnvironmentIntensity; + mat["DiffuseAlphaMode"] = DiffuseAlphaMode; + mat["AlphaMaskCutoff"] = AlphaMaskCutoff; + + return mat; + } + + public string toLLSDxml(StringBuilder sb = null) + { + const float scale = 10000f; + bool fullLLSD = false; + if(sb == null) + { + + sb = LLSDxmlEncode.Start(1024,false); + fullLLSD = true; + } + + LLSDxmlEncode.AddMap(sb); + LLSDxmlEncode.AddElem("NormMap", NormalMapID, sb); + LLSDxmlEncode.AddElem("NormOffsetX", (int) (scale * NormalOffsetX + 0.5f), sb); + LLSDxmlEncode.AddElem("NormOffsetY", (int) (scale * NormalOffsetY + 0.5f), sb); + LLSDxmlEncode.AddElem("NormRepeatX", (int) (scale * NormalRepeatX + 0.5f), sb); + LLSDxmlEncode.AddElem("NormRepeatY", (int) (scale * NormalRepeatY + 0.5f), sb); + LLSDxmlEncode.AddElem("NormRotation", (int) (scale * NormalRotation + 0.5f), sb); + + LLSDxmlEncode.AddElem("SpecMap", SpecularMapID, sb); + LLSDxmlEncode.AddElem("SpecOffsetX", (int) (scale * SpecularOffsetX + 0.5f), sb); + LLSDxmlEncode.AddElem("SpecOffsetY", (int) (scale * SpecularOffsetY + 0.5f), sb); + LLSDxmlEncode.AddElem("SpecRepeatX", (int) (scale * SpecularRepeatX + 0.5f), sb); + LLSDxmlEncode.AddElem("SpecRepeatY", (int) (scale * SpecularRepeatY + 0.5f), sb); + LLSDxmlEncode.AddElem("SpecRotation", (int) (scale * SpecularRotation + 0.5f), sb); + + LLSDxmlEncode.AddArray("SpecColor", sb); + LLSDxmlEncode.AddElem(SpecularLightColorR, sb); + LLSDxmlEncode.AddElem(SpecularLightColorG, sb); + LLSDxmlEncode.AddElem(SpecularLightColorB, sb); + LLSDxmlEncode.AddElem(255, sb); + LLSDxmlEncode.AddEndArray(sb); + + LLSDxmlEncode.AddElem("SpecExp", SpecularLightExponent, sb); + LLSDxmlEncode.AddElem("EnvIntensity", EnvironmentIntensity, sb); + LLSDxmlEncode.AddElem("DiffuseAlphaMode", DiffuseAlphaMode, sb); + LLSDxmlEncode.AddElem("AlphaMaskCutoff", AlphaMaskCutoff, sb); + + LLSDxmlEncode.AddEndMap(sb); + + if(fullLLSD) + { + return LLSDxmlEncode.End(sb); + } + else + return String.Empty; // ignored if appending + } } } \ No newline at end of file diff --git a/OpenSim/Region/Framework/Scenes/SOPVehicle.cs b/OpenSim/Region/Framework/Scenes/SOPVehicle.cs index 8d11331740..351eda35ed 100644 --- a/OpenSim/Region/Framework/Scenes/SOPVehicle.cs +++ b/OpenSim/Region/Framework/Scenes/SOPVehicle.cs @@ -425,25 +425,25 @@ namespace OpenSim.Region.Framework.Scenes private void XWfloat(string name, float f) { - writer.WriteElementString(name, f.ToString(Utils.EnUsCulture)); + writer.WriteElementString(name, f.ToString(Culture.FormatProvider)); } private void XWVector(string name, Vector3 vec) { writer.WriteStartElement(name); - writer.WriteElementString("X", vec.X.ToString(Utils.EnUsCulture)); - writer.WriteElementString("Y", vec.Y.ToString(Utils.EnUsCulture)); - writer.WriteElementString("Z", vec.Z.ToString(Utils.EnUsCulture)); + writer.WriteElementString("X", vec.X.ToString(Culture.FormatProvider)); + writer.WriteElementString("Y", vec.Y.ToString(Culture.FormatProvider)); + writer.WriteElementString("Z", vec.Z.ToString(Culture.FormatProvider)); writer.WriteEndElement(); } private void XWQuat(string name, Quaternion quat) { writer.WriteStartElement(name); - writer.WriteElementString("X", quat.X.ToString(Utils.EnUsCulture)); - writer.WriteElementString("Y", quat.Y.ToString(Utils.EnUsCulture)); - writer.WriteElementString("Z", quat.Z.ToString(Utils.EnUsCulture)); - writer.WriteElementString("W", quat.W.ToString(Utils.EnUsCulture)); + writer.WriteElementString("X", quat.X.ToString(Culture.FormatProvider)); + writer.WriteElementString("Y", quat.Y.ToString(Culture.FormatProvider)); + writer.WriteElementString("Z", quat.Z.ToString(Culture.FormatProvider)); + writer.WriteElementString("W", quat.W.ToString(Culture.FormatProvider)); writer.WriteEndElement(); } diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 2f016fa276..e6e035402f 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -338,7 +338,7 @@ namespace OpenSim.Region.Framework.Scenes // Update item with new asset item.AssetID = asset.FullID; group.UpdateInventoryItem(item); - group.AggregatePerms(); + group.InvalidateEffectivePerms(); part.SendPropertiesToClient(remoteClient); @@ -682,30 +682,26 @@ namespace OpenSim.Region.Framework.Scenes // These will be applied to the root prim at next rez. // The legacy slam bit (bit 3) and folded permission (bits 0-2) // are preserved due to the above mangling - ownerPerms &= nextPerms; +// ownerPerms &= nextPerms; // Mask the base permissions. This is a conservative // approach altering only the three main perms - basePerms &= nextPerms; +// basePerms &= nextPerms; // Mask out the folded portion of the base mask. // While the owner mask carries the actual folded // permissions, the base mask carries the original // base mask, before masking with the folded perms. // We need this later for rezzing. - basePerms &= ~(uint)PermissionMask.FoldedMask; - basePerms |= ((basePerms >> 13) & 7) | (((basePerms & (uint)PermissionMask.Export) != 0) ? (uint)PermissionMask.FoldedExport : 0); +// basePerms &= ~(uint)PermissionMask.FoldedMask; +// basePerms |= ((basePerms >> 13) & 7) | (((basePerms & (uint)PermissionMask.Export) != 0) ? (uint)PermissionMask.FoldedExport : 0); // If this is an object, root prim perms may be more // permissive than folded perms. Use folded perms as // a mask - if (item.InvType == (int)InventoryType.Object) + uint foldedPerms = (item.CurrentPermissions & (uint)PermissionMask.FoldedMask) << (int)PermissionMask.FoldingShift; + if (foldedPerms != 0 && item.InvType == (int)InventoryType.Object) { - // Create a safe mask for the current perms - uint foldedPerms = (item.CurrentPermissions & 7) << 13; - if ((item.CurrentPermissions & (uint)PermissionMask.FoldedExport) != 0) - foldedPerms |= (uint)PermissionMask.Export; - foldedPerms |= permsMask; bool isRootMod = (item.CurrentPermissions & @@ -729,6 +725,11 @@ namespace OpenSim.Region.Framework.Scenes } } + // move here so nextperms are mandatory + ownerPerms &= nextPerms; + basePerms &= nextPerms; + basePerms &= ~(uint)PermissionMask.FoldedMask; + basePerms |= ((basePerms >> 13) & 7) | (((basePerms & (uint)PermissionMask.Export) != 0) ? (uint)PermissionMask.FoldedExport : 0); // Assign to the actual item. Make sure the slam bit is // set, if it wasn't set before. itemCopy.BasePermissions = basePerms; @@ -1208,14 +1209,14 @@ namespace OpenSim.Region.Framework.Scenes if (group.GetInventoryItem(localID, itemID) != null) { - if (item.Type == 10) + if (item.Type == (int)InventoryType.LSL) { part.RemoveScriptEvents(itemID); - EventManager.TriggerRemoveScript(localID, itemID); + part.ParentGroup.AddActiveScriptCount(-1); } group.RemoveInventoryItem(localID, itemID); - group.AggregatePerms(); + group.InvalidateEffectivePerms(); } part.SendPropertiesToClient(remoteClient); @@ -1266,20 +1267,26 @@ namespace OpenSim.Region.Framework.Scenes // TODO: Fix this after the inventory fixer exists and has beenr run if ((part.OwnerID != destAgent) && Permissions.PropagatePermissions()) { - agentItem.BasePermissions = taskItem.BasePermissions & (taskItem.NextPermissions | (uint)PermissionMask.Move); + uint perms = taskItem.BasePermissions & taskItem.NextPermissions; if (taskItem.InvType == (int)InventoryType.Object) - agentItem.CurrentPermissions = agentItem.BasePermissions & (((taskItem.CurrentPermissions & 7) << 13) | (taskItem.CurrentPermissions & (uint)PermissionMask.Move)); + { + PermissionsUtil.ApplyFoldedPermissions(taskItem.CurrentPermissions, ref perms ); + perms = PermissionsUtil.FixAndFoldPermissions(perms); + } else - agentItem.CurrentPermissions = agentItem.BasePermissions & taskItem.CurrentPermissions; - - agentItem.BasePermissions = agentItem.CurrentPermissions; + perms &= taskItem.CurrentPermissions; + // always unlock + perms |= (uint)PermissionMask.Move; + + agentItem.BasePermissions = perms; + agentItem.CurrentPermissions = perms; + agentItem.NextPermissions = perms & taskItem.NextPermissions; + agentItem.EveryOnePermissions = perms & taskItem.EveryonePermissions; + agentItem.GroupPermissions = perms & taskItem.GroupPermissions; + agentItem.Flags |= (uint)InventoryItemFlags.ObjectSlamPerm; agentItem.Flags &= ~(uint)(InventoryItemFlags.ObjectOverwriteBase | InventoryItemFlags.ObjectOverwriteOwner | InventoryItemFlags.ObjectOverwriteGroup | InventoryItemFlags.ObjectOverwriteEveryone | InventoryItemFlags.ObjectOverwriteNextOwner); - agentItem.NextPermissions = taskItem.NextPermissions; - agentItem.EveryOnePermissions = taskItem.EveryonePermissions & (taskItem.NextPermissions | (uint)PermissionMask.Move); - // Group permissions make no sense here - agentItem.GroupPermissions = 0; } else { @@ -1287,7 +1294,7 @@ namespace OpenSim.Region.Framework.Scenes agentItem.CurrentPermissions = taskItem.CurrentPermissions; agentItem.NextPermissions = taskItem.NextPermissions; agentItem.EveryOnePermissions = taskItem.EveryonePermissions; - agentItem.GroupPermissions = 0; + agentItem.GroupPermissions = taskItem.GroupPermissions; } message = null; @@ -1310,7 +1317,7 @@ namespace OpenSim.Region.Framework.Scenes if (taskItem.Type == (int)AssetType.LSLText) { part.RemoveScriptEvents(itemId); - EventManager.TriggerRemoveScript(part.LocalId, itemId); + part.ParentGroup.AddActiveScriptCount(-1); } part.Inventory.RemoveInventoryItem(itemId); @@ -1381,11 +1388,7 @@ namespace OpenSim.Region.Framework.Scenes } if (!Permissions.CanCopyObjectInventory(itemId, part.UUID, remoteClient.AgentId)) - { - // check also if we can delete the no copy item - if(!Permissions.CanEditObject(part.UUID, remoteClient.AgentId)) - return; - } + return; string message; InventoryItemBase item = MoveTaskInventoryItem(remoteClient, folderId, part, itemId, out message); @@ -1735,7 +1738,24 @@ namespace OpenSim.Region.Framework.Scenes // Check if we're allowed to mess with permissions if (!Permissions.IsGod(remoteClient.AgentId)) // Not a god { + bool noChange; if (remoteClient.AgentId != part.OwnerID) // Not owner + { + noChange = true; + if(itemInfo.OwnerID == UUID.Zero && itemInfo.GroupID != UUID.Zero) + { + if(remoteClient.IsGroupMember(itemInfo.GroupID)) + { + ulong powers = remoteClient.GetGroupPowers(itemInfo.GroupID); + if((powers & (ulong)GroupPowers.ObjectManipulate) != 0) + noChange = false; + } + } + } + else + noChange = false; + + if(noChange) { // Friends and group members can't change any perms itemInfo.BasePermissions = currentItem.BasePermissions; @@ -1762,7 +1782,6 @@ namespace OpenSim.Region.Framework.Scenes itemInfo.CurrentPermissions &= currentItem.BasePermissions; itemInfo.NextPermissions &= currentItem.BasePermissions; } - } else { @@ -1948,7 +1967,7 @@ namespace OpenSim.Region.Framework.Scenes part.Inventory.AddInventoryItem(taskItem, false); part.Inventory.CreateScriptInstance(taskItem, 0, false, DefaultScriptEngine, 0); - part.ParentGroup.AggregatePerms(); + part.ParentGroup.InvalidateEffectivePerms(); // tell anyone managing scripts that a new script exists EventManager.TriggerNewScript(agentID, part, taskItem.ItemID); @@ -2370,7 +2389,7 @@ namespace OpenSim.Region.Framework.Scenes { using (XmlTextReader wrappedReader = new XmlTextReader(xmlData, XmlNodeType.Element, null)) { - using (XmlReader reader = XmlReader.Create(wrappedReader, new XmlReaderSettings() { IgnoreWhitespace = true, ConformanceLevel = ConformanceLevel.Fragment })) + using (XmlReader reader = XmlReader.Create(wrappedReader, new XmlReaderSettings() { IgnoreWhitespace = true, ConformanceLevel = ConformanceLevel.Fragment})) { reader.Read(); bool isSingleObject = reader.Name != "CoalescedObject"; @@ -2636,7 +2655,7 @@ namespace OpenSim.Region.Framework.Scenes // We can only call this after adding the scene object, since the scene object references the scene // to find out if scripts should be activated at all. - group.AggregatePerms(); + group.InvalidateEffectivePerms(); group.CreateScriptInstances(param, true, DefaultScriptEngine, 3); group.ScheduleGroupForFullUpdate(); @@ -2733,7 +2752,7 @@ namespace OpenSim.Region.Framework.Scenes // and with this comented code, if user does not set next permissions on the object // and on ALL contents of ALL prims, he may loose rights, making the object useless sog.ApplyNextOwnerPermissions(); - sog.AggregatePerms(); + sog.InvalidateEffectivePerms(); sog.ScheduleGroupForFullUpdate(); @@ -2846,7 +2865,7 @@ namespace OpenSim.Region.Framework.Scenes root.SendPropertiesToClient(sp.ControllingClient); if (oldUsePhysics && (root.Flags & PrimFlags.Physics) == 0) { - sp.ControllingClient.SendAlertMessage("Object physics canceled"); + sp.ControllingClient.SendAlertMessage("Object physics cancelled"); } } } diff --git a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs index 4fef9c3012..04605a2017 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs @@ -306,14 +306,14 @@ namespace OpenSim.Region.Framework.Scenes // If the touched prim handles touches, deliver it if ((part.ScriptEvents & scriptEvents.touch_start) != 0) - EventManager.TriggerObjectGrab(part.LocalId, 0, part.OffsetPosition, remoteClient, surfaceArg); + EventManager.TriggerObjectGrab(part.LocalId, 0, offsetPos, remoteClient, surfaceArg); // Deliver to the root prim if the touched prim doesn't handle touches // or if we're meant to pass on touches anyway. if (((part.ScriptEvents & scriptEvents.touch_start) == 0) || (part.PassTouches && (part.LocalId != obj.RootPart.LocalId))) { - EventManager.TriggerObjectGrab(obj.RootPart.LocalId, part.LocalId, part.OffsetPosition, remoteClient, surfaceArg); + EventManager.TriggerObjectGrab(obj.RootPart.LocalId, part.LocalId, offsetPos, remoteClient, surfaceArg); } } @@ -343,15 +343,18 @@ namespace OpenSim.Region.Framework.Scenes if (surfaceArgs != null && surfaceArgs.Count > 0) surfaceArg = surfaceArgs[0]; + Vector3 grabOffset = pos - part.AbsolutePosition; // If the touched prim handles touches, deliver it if ((part.ScriptEvents & scriptEvents.touch) != 0) - EventManager.TriggerObjectGrabbing(part.LocalId, 0, part.OffsetPosition, remoteClient, surfaceArg); +// EventManager.TriggerObjectGrabbing(part.LocalId, 0, part.OffsetPosition, remoteClient, surfaceArg); + EventManager.TriggerObjectGrabbing(part.LocalId, 0, grabOffset, remoteClient, surfaceArg); // Deliver to the root prim if the touched prim doesn't handle touches // or if we're meant to pass on touches anyway. if (((part.ScriptEvents & scriptEvents.touch) == 0) || (part.PassTouches && (part.LocalId != group.RootPart.LocalId))) { - EventManager.TriggerObjectGrabbing(group.RootPart.LocalId, part.LocalId, part.OffsetPosition, remoteClient, surfaceArg); +// EventManager.TriggerObjectGrabbing(group.RootPart.LocalId, part.LocalId, part.OffsetPosition, remoteClient, surfaceArg); + EventManager.TriggerObjectGrabbing(group.RootPart.LocalId, part.LocalId, grabOffset, remoteClient, surfaceArg); } } @@ -474,7 +477,7 @@ namespace OpenSim.Region.Framework.Scenes if (sp.ControllingClient.AgentId != remoteClient.AgentId) { if (!discardableEffects || - (discardableEffects && ShouldSendDiscardableEffect(remoteClient, sp))) + (discardableEffects && ShouldSendDiscardableEffect(remoteClient, sp))) { //m_log.DebugFormat("[YYY]: Sending to {0}", sp.UUID); sp.ControllingClient.SendViewerEffect(effectBlockArray); @@ -487,7 +490,7 @@ namespace OpenSim.Region.Framework.Scenes private bool ShouldSendDiscardableEffect(IClientAPI thisClient, ScenePresence other) { - return Vector3.Distance(other.CameraPosition, thisClient.SceneAgent.AbsolutePosition) < 10; + return Vector3.DistanceSquared(other.CameraPosition, thisClient.SceneAgent.AbsolutePosition) < 100; } private class DescendentsRequestData @@ -700,10 +703,17 @@ namespace OpenSim.Region.Framework.Scenes { InventoryFolderBase folder = new InventoryFolderBase(folderID, userID); - if (InventoryService.PurgeFolder(folder)) - m_log.DebugFormat("[AGENT INVENTORY]: folder {0} purged successfully", folderID); - else - m_log.WarnFormat("[AGENT INVENTORY]: could not purge folder {0}", folderID); + try + { + if (InventoryService.PurgeFolder(folder)) + m_log.DebugFormat("[AGENT INVENTORY]: folder {0} purged successfully", folderID); + else + m_log.WarnFormat("[AGENT INVENTORY]: could not purge folder {0}", folderID); + } + catch (Exception e) + { + m_log.WarnFormat("[AGENT INVENTORY]: Exception on async purge folder for user {0}: {1}", userID, e.Message); + } } private void PurgeFolderCompleted(IAsyncResult iar) diff --git a/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs b/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs index 7d69a9b663..a75671e6fd 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs @@ -53,9 +53,11 @@ namespace OpenSim.Region.Framework.Scenes public delegate bool DuplicateObjectHandler(SceneObjectGroup sog, ScenePresence sp); public delegate bool EditObjectByIDsHandler(UUID objectID, UUID editorID); public delegate bool EditObjectHandler(SceneObjectGroup sog, ScenePresence sp); + public delegate bool EditObjectPermsHandler(SceneObjectGroup sog, UUID editorID); public delegate bool EditObjectInventoryHandler(UUID objectID, UUID editorID); public delegate bool MoveObjectHandler(SceneObjectGroup sog, ScenePresence sp); public delegate bool ObjectEntryHandler(SceneObjectGroup sog, bool enteringRegion, Vector3 newPoint); + public delegate bool ObjectEnterWithScriptsHandler(SceneObjectGroup sog, ILandObject land); public delegate bool ReturnObjectsHandler(ILandObject land, ScenePresence sp, List objects); public delegate bool InstantMessageHandler(UUID user, UUID target); public delegate bool InventoryTransferHandler(UUID user, UUID target); @@ -132,9 +134,11 @@ namespace OpenSim.Region.Framework.Scenes public event DuplicateObjectHandler OnDuplicateObject; public event EditObjectByIDsHandler OnEditObjectByIDs; public event EditObjectHandler OnEditObject; + public event EditObjectPermsHandler OnEditObjectPerms; public event EditObjectInventoryHandler OnEditObjectInventory; public event MoveObjectHandler OnMoveObject; public event ObjectEntryHandler OnObjectEntry; + public event ObjectEnterWithScriptsHandler OnObjectEnterWithScripts; public event ReturnObjectsHandler OnReturnObjects; public event InstantMessageHandler OnInstantMessage; public event InventoryTransferHandler OnInventoryTransfer; @@ -509,6 +513,24 @@ namespace OpenSim.Region.Framework.Scenes return true; } + public bool CanEditObjectPermissions(SceneObjectGroup sog, UUID editorID) + { + EditObjectPermsHandler handler = OnEditObjectPerms; + if (handler != null) + { + if(sog == null) + return false; + Delegate[] list = handler.GetInvocationList(); + foreach (EditObjectPermsHandler h in list) + { + if (h(sog, editorID) == false) + return false; + } + } + return true; + } + + public bool CanEditObjectInventory(UUID objectID, UUID editorID) { EditObjectInventoryHandler handler = OnEditObjectInventory; @@ -565,6 +587,21 @@ namespace OpenSim.Region.Framework.Scenes return true; } + public bool CanObjectEnterWithScripts(SceneObjectGroup sog, ILandObject land) + { + ObjectEnterWithScriptsHandler handler = OnObjectEnterWithScripts; + if (handler != null) + { + Delegate[] list = handler.GetInvocationList(); + foreach (ObjectEnterWithScriptsHandler h in list) + { + if (h(sog, land) == false) + return false; + } + } + return true; + } + #endregion #region RETURN OBJECT diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index c5b082c1ac..15a0493405 100755 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -257,37 +257,7 @@ namespace OpenSim.Region.Framework.Scenes public bool m_useFlySlow; public bool m_useTrashOnDelete = true; - /// - /// Temporarily setting to trigger appearance resends at 60 second intervals. - /// - public bool SendPeriodicAppearanceUpdates { get; set; } - - /// - /// How much a root agent has to change position before updates are sent to viewers. - /// - public float RootPositionUpdateTolerance { get; set; } - - /// - /// How much a root agent has to rotate before updates are sent to viewers. - /// - public float RootRotationUpdateTolerance { get; set; } - - /// - /// How much a root agent has to change velocity before updates are sent to viewers. - /// - public float RootVelocityUpdateTolerance { get; set; } - - /// - /// If greater than 1, we only send terse updates to other root agents on every n updates. - /// - public int RootTerseUpdatePeriod { get; set; } - - /// - /// If greater than 1, we only send terse updates to child agents on every n updates. - /// - public int ChildTerseUpdatePeriod { get; set; } - - protected float m_defaultDrawDistance = 255f; + protected float m_defaultDrawDistance = 255f; protected float m_defaultCullingDrawDistance = 16f; public float DefaultDrawDistance { @@ -375,11 +345,6 @@ namespace OpenSim.Region.Framework.Scenes protected set; } - /// - /// Current maintenance run number - /// - public uint MaintenanceRun { get; private set; } - /// /// Frame time /// @@ -391,14 +356,6 @@ namespace OpenSim.Region.Framework.Scenes // see SimStatsReporter.cs public bool Normalized55FPS { get; private set; } - /// - /// The minimum length of time in seconds that will be taken for a scene frame. - /// - /// - /// Always derived from MinFrameTicks. - /// - public float MinMaintenanceTime { get; private set; } - private int m_update_physics = 1; private int m_update_entitymovement = 1; private int m_update_objects = 1; @@ -407,9 +364,8 @@ namespace OpenSim.Region.Framework.Scenes private int m_update_backup = 200; private int m_update_terrain = 1000; - private int m_update_land = 10; - private int m_update_coarse_locations = 50; + private int m_update_coarse_locations = 5; private int m_update_temp_cleaning = 180; private float agentMS; @@ -428,11 +384,6 @@ namespace OpenSim.Region.Framework.Scenes /// private int m_lastFrameTick; - /// - /// Tick at which the last maintenance run occurred. - /// - private int m_lastMaintenanceTick; - /// /// Total script execution time (in Stopwatch Ticks) since the last frame /// @@ -443,17 +394,13 @@ namespace OpenSim.Region.Framework.Scenes /// asynchronously from the update loop. /// private bool m_cleaningTemps = false; + private bool m_sendingCoarseLocations = false; // same for async course locations sending /// /// Used to control main scene thread looping time when not updating via timer. /// private ManualResetEvent m_updateWaitEvent = new ManualResetEvent(false); - /// - /// Used to control maintenance thread runs. - /// - private ManualResetEvent m_maintenanceWaitEvent = new ManualResetEvent(false); - // TODO: Possibly stop other classes being able to manipulate this directly. private SceneGraph m_sceneGraph; private readonly Timer m_restartTimer = new Timer(15000); // Wait before firing @@ -497,7 +444,7 @@ namespace OpenSim.Region.Framework.Scenes /// Is the scene active? /// /// - /// If false, maintenance and update loops are not being run, though after setting to false update may still + /// If false, update loop is not being run, though after setting to false update may still /// be active for a period (and IsRunning will still be true). Updates can still be triggered manually if /// the scene is not active. /// @@ -527,7 +474,6 @@ namespace OpenSim.Region.Framework.Scenes public bool IsRunning { get { return m_isRunning; } } private volatile bool m_isRunning; -// private int m_lastUpdate; private bool m_firstHeartbeat = true; // private UpdatePrioritizationSchemes m_priorityScheme = UpdatePrioritizationSchemes.Time; @@ -808,6 +754,8 @@ namespace OpenSim.Region.Framework.Scenes private float m_minReprioritizationDistance = 32f; public bool ObjectsCullingByDistance = false; + private ExpiringCache TeleportTargetsCoolDown = new ExpiringCache(); + public AgentCircuitManager AuthenticateHandler { get { return m_authenticateHandler; } @@ -881,7 +829,6 @@ namespace OpenSim.Region.Framework.Scenes FrameTimeWarnPercent = 60; FrameTimeCritPercent = 40; Normalized55FPS = true; - MinMaintenanceTime = 1; SeeIntoRegion = true; Random random = new Random(); @@ -976,6 +923,7 @@ namespace OpenSim.Region.Framework.Scenes m_maxDrawDistance = startupConfig.GetFloat("MaxDrawDistance", m_maxDrawDistance); m_maxRegionViewDistance = startupConfig.GetFloat("MaxRegionsViewDistance", m_maxRegionViewDistance); + // old versions compatibility LegacySitOffsets = startupConfig.GetBoolean("LegacySitOffsets", LegacySitOffsets); if (m_defaultDrawDistance > m_maxDrawDistance) @@ -1144,17 +1092,6 @@ namespace OpenSim.Region.Framework.Scenes } - - // FIXME: Ultimately this should be in a module. - SendPeriodicAppearanceUpdates = false; - - IConfig appearanceConfig = m_config.Configs["Appearance"]; - if (appearanceConfig != null) - { - SendPeriodicAppearanceUpdates - = appearanceConfig.GetBoolean("ResendAppearanceUpdates", SendPeriodicAppearanceUpdates); - } - #endregion Region Config IConfig entityTransferConfig = m_config.Configs["EntityTransfer"]; @@ -1194,16 +1131,6 @@ namespace OpenSim.Region.Framework.Scenes ObjectsCullingByDistance = interestConfig.GetBoolean("ObjectsCullingByDistance", ObjectsCullingByDistance); - - RootTerseUpdatePeriod = interestConfig.GetInt("RootTerseUpdatePeriod", RootTerseUpdatePeriod); - ChildTerseUpdatePeriod = interestConfig.GetInt("ChildTerseUpdatePeriod", ChildTerseUpdatePeriod); - - RootPositionUpdateTolerance - = interestConfig.GetFloat("RootPositionUpdateTolerance", RootPositionUpdateTolerance); - RootRotationUpdateTolerance - = interestConfig.GetFloat("RootRotationUpdateTolerance", RootRotationUpdateTolerance); - RootVelocityUpdateTolerance - = interestConfig.GetFloat("RootVelocityUpdateTolerance", RootVelocityUpdateTolerance); } m_log.DebugFormat("[SCENE]: Using the {0} prioritization scheme", UpdatePrioritizationScheme); @@ -1272,9 +1199,6 @@ namespace OpenSim.Region.Framework.Scenes UpdatePrioritizationScheme = UpdatePrioritizationSchemes.Time; ReprioritizationInterval = 5000; - RootRotationUpdateTolerance = 0.1f; - RootVelocityUpdateTolerance = 0.001f; - RootPositionUpdateTolerance = 0.05f; ReprioritizationDistance = m_minReprioritizationDistance; m_eventManager = new EventManager(); @@ -1665,100 +1589,12 @@ namespace OpenSim.Region.Framework.Scenes // alarms for scenes with many objects. Update(1); - WorkManager.StartThread( - Maintenance, string.Format("Maintenance ({0})", RegionInfo.RegionName), ThreadPriority.Normal, false, true); - Watchdog.GetCurrentThreadInfo().AlarmIfTimeout = true; m_lastFrameTick = Util.EnvironmentTickCount(); Update(-1); - Watchdog.RemoveThread(); } - private void Maintenance() - { - DoMaintenance(-1); - - Watchdog.RemoveThread(); - } - - public void DoMaintenance(int runs) - { - long? endRun = null; - int runtc, tmpMS; - int previousMaintenanceTick; - - if (runs >= 0) - endRun = MaintenanceRun + runs; - - List coarseLocations; - List avatarUUIDs; - - while (!m_shuttingDown && ((endRun == null && Active) || MaintenanceRun < endRun)) - { - runtc = Util.EnvironmentTickCount(); - ++MaintenanceRun; - - // m_log.DebugFormat("[SCENE]: Maintenance run {0} in {1}", MaintenanceRun, Name); - - // Coarse locations relate to positions of green dots on the mini-map (on a SecondLife client) - if (MaintenanceRun % (m_update_coarse_locations / 10) == 0) - { - SceneGraph.GetCoarseLocations(out coarseLocations, out avatarUUIDs, 60); - // Send coarse locations to clients - ForEachScenePresence(delegate(ScenePresence presence) - { - presence.SendCoarseLocations(coarseLocations, avatarUUIDs); - }); - } - - if (SendPeriodicAppearanceUpdates && MaintenanceRun % 60 == 0) - { - // m_log.DebugFormat("[SCENE]: Sending periodic appearance updates"); - - if (AvatarFactory != null) - { - ForEachRootScenePresence(sp => AvatarFactory.SendAppearance(sp.UUID)); - } - } - - // Delete temp-on-rez stuff - if (MaintenanceRun % m_update_temp_cleaning == 0 && !m_cleaningTemps) - { - // m_log.DebugFormat("[SCENE]: Running temp-on-rez cleaning in {0}", Name); - tmpMS = Util.EnvironmentTickCount(); - m_cleaningTemps = true; - - WorkManager.RunInThread( - delegate { CleanTempObjects(); m_cleaningTemps = false; }, - null, - string.Format("CleanTempObjects ({0})", Name)); - - tempOnRezMS = Util.EnvironmentTickCountSubtract(tmpMS); - } - - Watchdog.UpdateThread(); - - previousMaintenanceTick = m_lastMaintenanceTick; - m_lastMaintenanceTick = Util.EnvironmentTickCount(); - runtc = Util.EnvironmentTickCountSubtract(m_lastMaintenanceTick, runtc); - runtc = (int)(MinMaintenanceTime * 1000) - runtc; - - if (runtc > 0) - m_maintenanceWaitEvent.WaitOne(runtc); - - // Optionally warn if a frame takes double the amount of time that it should. - if (DebugUpdates - && Util.EnvironmentTickCountSubtract( - m_lastMaintenanceTick, previousMaintenanceTick) > (int)(MinMaintenanceTime * 1000 * 2)) - m_log.WarnFormat( - "[SCENE]: Maintenance took {0} ms (desired max {1} ms) in {2}", - Util.EnvironmentTickCountSubtract(m_lastMaintenanceTick, previousMaintenanceTick), - MinMaintenanceTime * 1000, - RegionInfo.RegionName); - } - } - public override void Update(int frames) { long? endFrame = null; @@ -1815,9 +1651,28 @@ namespace OpenSim.Region.Framework.Scenes physicsMS2 = (float)(tmpMS2 - tmpMS); tmpMS = tmpMS2; +/* // Apply any pending avatar force input to the avatar's velocity if (Frame % m_update_entitymovement == 0) m_sceneGraph.UpdateScenePresenceMovement(); +*/ + if (Frame % (m_update_coarse_locations) == 0 && !m_sendingCoarseLocations) + { + m_sendingCoarseLocations = true; + WorkManager.RunInThreadPool( + delegate + { + List coarseLocations; + List avatarUUIDs; + SceneGraph.GetCoarseLocations(out coarseLocations, out avatarUUIDs, 60); + // Send coarse locations to clients + ForEachScenePresence(delegate(ScenePresence presence) + { + presence.SendCoarseLocations(coarseLocations, avatarUUIDs); + }); + m_sendingCoarseLocations = false; + }, null, string.Format("SendCoarseLocations ({0})", Name)); + } // Get the simulation frame time that the avatar force input // took @@ -1861,7 +1716,8 @@ namespace OpenSim.Region.Framework.Scenes if (Frame % m_update_temp_cleaning == 0 && !m_cleaningTemps) { m_cleaningTemps = true; - Util.FireAndForget(delegate { CleanTempObjects(); m_cleaningTemps = false; }); + WorkManager.RunInThreadPool( + delegate { CleanTempObjects(); m_cleaningTemps = false; }, null, string.Format("CleanTempObjects ({0})", Name)); tmpMS2 = Util.GetTimeStampMS(); tempOnRezMS = (float)(tmpMS2 - tmpMS); // bad.. counts the FireAndForget, not CleanTempObjects tmpMS = tmpMS2; @@ -2087,8 +1943,7 @@ namespace OpenSim.Region.Framework.Scenes { if (!m_backingup) { - m_backingup = true; - WorkManager.RunInThread(o => Backup(false), null, string.Format("BackupWaitCallback ({0})", Name)); + WorkManager.RunInThreadPool(o => Backup(false), null, string.Format("BackupWorker ({0}", Name), false); } } @@ -2116,38 +1971,58 @@ namespace OpenSim.Region.Framework.Scenes { lock (m_returns) { - EventManager.TriggerOnBackup(SimulationDataService, forced); - m_backingup = false; - - foreach (KeyValuePair ret in m_returns) + if(m_backingup) { - UUID transaction = UUID.Random(); + m_log.WarnFormat("[Scene] Backup of {0} already running. New call skipped", RegionInfo.RegionName); + return; + } - GridInstantMessage msg = new GridInstantMessage(); - msg.fromAgentID = new Guid(UUID.Zero.ToString()); // From server - msg.toAgentID = new Guid(ret.Key.ToString()); - msg.imSessionID = new Guid(transaction.ToString()); - msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); - msg.fromAgentName = "Server"; - msg.dialog = (byte)19; // Object msg - msg.fromGroup = false; - msg.offline = (byte)1; - msg.ParentEstateID = RegionInfo.EstateSettings.ParentEstateID; - msg.Position = Vector3.Zero; - msg.RegionID = RegionInfo.RegionID.Guid; + m_backingup = true; + try + { + EventManager.TriggerOnBackup(SimulationDataService, forced); - // We must fill in a null-terminated 'empty' string here since bytes[0] will crash viewer 3. - msg.binaryBucket = Util.StringToBytes256("\0"); - if (ret.Value.count > 1) - msg.message = string.Format("Your {0} objects were returned from {1} in region {2} due to {3}", ret.Value.count, ret.Value.location.ToString(), RegionInfo.RegionName, ret.Value.reason); - else - msg.message = string.Format("Your object {0} was returned from {1} in region {2} due to {3}", ret.Value.objectName, ret.Value.location.ToString(), RegionInfo.RegionName, ret.Value.reason); + if(m_returns.Count == 0) + return; IMessageTransferModule tr = RequestModuleInterface(); - if (tr != null) + if (tr == null) + return; + + uint unixtime = (uint)Util.UnixTimeSinceEpoch(); + uint estateid = RegionInfo.EstateSettings.ParentEstateID; + Guid regionguid = RegionInfo.RegionID.Guid; + + foreach (KeyValuePair ret in m_returns) + { + GridInstantMessage msg = new GridInstantMessage(); + msg.fromAgentID = Guid.Empty; // From server + msg.toAgentID = ret.Key.Guid; + msg.imSessionID = Guid.NewGuid(); + msg.timestamp = unixtime; + msg.fromAgentName = "Server"; + msg.dialog = 19; // Object msg + msg.fromGroup = false; + msg.offline = 1; + msg.ParentEstateID = estateid; + msg.Position = Vector3.Zero; + msg.RegionID = regionguid; + + // We must fill in a null-terminated 'empty' string here since bytes[0] will crash viewer 3. + msg.binaryBucket = new Byte[1] {0}; + if (ret.Value.count > 1) + msg.message = string.Format("Your {0} objects were returned from {1} in region {2} due to {3}", ret.Value.count, ret.Value.location.ToString(), RegionInfo.RegionName, ret.Value.reason); + else + msg.message = string.Format("Your object {0} was returned from {1} in region {2} due to {3}", ret.Value.objectName, ret.Value.location.ToString(), RegionInfo.RegionName, ret.Value.reason); + tr.SendInstantMessage(msg, delegate(bool success) { }); + } + m_returns.Clear(); + } + finally + { + m_backingup = false; } - m_returns.Clear(); } } @@ -2388,8 +2263,9 @@ namespace OpenSim.Region.Framework.Scenes EventManager.TriggerOnSceneObjectLoaded(group); SceneObjectPart rootPart = group.GetPart(group.UUID); rootPart.Flags &= ~PrimFlags.Scripted; - group.AggregateDeepPerms(); + rootPart.TrimPermissions(); + group.InvalidateDeepEffectivePerms(); // Don't do this here - it will get done later on when sculpt data is loaded. // group.CheckSculptAndLoad(); @@ -2660,7 +2536,7 @@ namespace OpenSim.Region.Framework.Scenes if (UserManagementModule != null) sceneObject.RootPart.CreatorIdentification = UserManagementModule.GetUserUUI(ownerID); - sceneObject.AggregateDeepPerms(); + sceneObject.InvalidateDeepEffectivePerms();; sceneObject.ScheduleGroupForFullUpdate(); return sceneObject; @@ -2983,15 +2859,15 @@ namespace OpenSim.Region.Framework.Scenes // Return 'true' if position inside region. public bool PositionIsInCurrentRegion(Vector3 pos) { - bool ret = false; - int xx = (int)Math.Floor(pos.X); - int yy = (int)Math.Floor(pos.Y); - if (xx < 0 || yy < 0) + float t = pos.X; + if (t < 0 || t >= RegionInfo.RegionSizeX) return false; - if (xx < RegionInfo.RegionSizeX && yy < RegionInfo.RegionSizeY ) - ret = true; - return ret; + t = pos.Y; + if (t < 0 || t >= RegionInfo.RegionSizeY) + return false; + + return true; } /// @@ -4756,10 +4632,10 @@ Label_GroupsDone: /// protected virtual ScenePresence WaitGetScenePresence(UUID agentID) { - int ntimes = 30; + int ntimes = 120; // 30s ScenePresence sp = null; while ((sp = GetScenePresence(agentID)) == null && (ntimes-- > 0)) - Thread.Sleep(1000); + Thread.Sleep(250); if (sp == null) m_log.WarnFormat( @@ -4949,16 +4825,34 @@ Label_GroupsDone: public void RequestTeleportLocation(IClientAPI remoteClient, string regionName, Vector3 position, Vector3 lookat, uint teleportFlags) { - GridRegion region = GridService.GetRegionByName(RegionInfo.ScopeID, regionName); + if (EntityTransferModule == null) + { + m_log.DebugFormat("[SCENE]: Unable to perform teleports: no AgentTransferModule is active"); + return; + } - if (region == null) + ScenePresence sp = GetScenePresence(remoteClient.AgentId); + if (sp == null || sp.IsDeleted || sp.IsInTransit) + return; + + ulong regionHandle = 0; + if(regionName == RegionInfo.RegionName) + regionHandle = RegionInfo.RegionHandle; + else + { + GridRegion region = GridService.GetRegionByName(RegionInfo.ScopeID, regionName); + if (region != null) + regionHandle = region.RegionHandle; + } + + if(regionHandle == 0) { // can't find the region: Tell viewer and abort remoteClient.SendTeleportFailed("The region '" + regionName + "' could not be found."); return; } - RequestTeleportLocation(remoteClient, region.RegionHandle, position, lookat, teleportFlags); + EntityTransferModule.Teleport(sp, regionHandle, position, lookat, teleportFlags); } /// @@ -4972,19 +4866,17 @@ Label_GroupsDone: public void RequestTeleportLocation(IClientAPI remoteClient, ulong regionHandle, Vector3 position, Vector3 lookAt, uint teleportFlags) { - ScenePresence sp = GetScenePresence(remoteClient.AgentId); - if (sp != null) + if (EntityTransferModule == null) { - if (EntityTransferModule != null) - { - EntityTransferModule.Teleport(sp, regionHandle, position, lookAt, teleportFlags); - } - else - { - m_log.DebugFormat("[SCENE]: Unable to perform teleports: no AgentTransferModule is active"); - sp.ControllingClient.SendTeleportFailed("Unable to perform teleports on this simulator."); - } + m_log.DebugFormat("[SCENE]: Unable to perform teleports: no AgentTransferModule is active"); + return; } + + ScenePresence sp = GetScenePresence(remoteClient.AgentId); + if (sp == null || sp.IsDeleted || sp.IsInTransit) + return; + + EntityTransferModule.Teleport(sp, regionHandle, position, lookAt, teleportFlags); } public bool CrossAgentToNewRegion(ScenePresence agent, bool isFlying) @@ -5442,7 +5334,7 @@ Label_GroupsDone: /// public void ForEachClient(Action action) { - m_clientManager.ForEachSync(action); + m_clientManager.ForEach(action); } public int GetNumberOfClients() @@ -6526,5 +6418,21 @@ Environment.Exit(1); m_eventManager.TriggerExtraSettingChanged(this, name, String.Empty); } + + public bool InTeleportTargetsCoolDown(UUID sourceID, UUID targetID, double timeout) + { + lock(TeleportTargetsCoolDown) + { + UUID lastSource = UUID.Zero; + TeleportTargetsCoolDown.TryGetValue(targetID, out lastSource); + if(lastSource == UUID.Zero) + { + TeleportTargetsCoolDown.Add(targetID, sourceID, timeout); + return false; + } + TeleportTargetsCoolDown.AddOrUpdate(targetID, sourceID, timeout); + return lastSource == sourceID; + } + } } } diff --git a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs index 6304778c18..932e826802 100644 --- a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs +++ b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs @@ -84,7 +84,7 @@ namespace OpenSim.Region.Framework.Scenes if (neighbourService != null) neighbour = neighbourService.HelloNeighbour(regionhandle, region); else - m_log.DebugFormat("{0} neighbour service provided for region {0} to inform neigbhours of status", LogHeader, m_scene.Name); + m_log.DebugFormat("{0} neighbour service provided for region {1} to inform neigbhours of status", LogHeader, m_scene.Name); if (neighbour != null) { diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 49e98e7d3a..61a243dd20 100755 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -343,7 +343,7 @@ namespace OpenSim.Region.Framework.Scenes sceneObject.ForceInventoryPersistence(); sceneObject.HasGroupChanged = true; } - sceneObject.AggregateDeepPerms(); + sceneObject.InvalidateDeepEffectivePerms(); return ret; } @@ -388,19 +388,19 @@ namespace OpenSim.Region.Framework.Scenes public bool AddNewSceneObject( SceneObjectGroup sceneObject, bool attachToBackup, Vector3? pos, Quaternion? rot, Vector3 vel) { - AddNewSceneObject(sceneObject, attachToBackup, false); - if (pos != null) sceneObject.AbsolutePosition = (Vector3)pos; + if (rot != null) + sceneObject.UpdateGroupRotationR((Quaternion)rot); + + AddNewSceneObject(sceneObject, attachToBackup, false); + if (sceneObject.RootPart.Shape.PCode == (byte)PCode.Prim) { sceneObject.ClearPartAttachmentData(); } - if (rot != null) - sceneObject.UpdateGroupRotationR((Quaternion)rot); - PhysicsActor pa = sceneObject.RootPart.PhysActor; if (pa != null && pa.IsPhysical && vel != Vector3.Zero) { @@ -549,6 +549,8 @@ namespace OpenSim.Region.Framework.Scenes // that are part of the Scene Object being removed m_numTotalPrim -= grp.PrimCount; + bool isPh = (grp.RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics; + int nphysparts = 0; // Go through all parts (primitives and meshes) of this Scene Object foreach (SceneObjectPart part in grp.Parts) { @@ -559,10 +561,13 @@ namespace OpenSim.Region.Framework.Scenes m_numMesh--; else m_numPrim--; + + if(isPh && part.PhysicsShapeType != (byte)PhysShapeType.none) + nphysparts++; } - if ((grp.RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics) - RemovePhysicalPrim(grp.PrimCount); + if (nphysparts > 0 ) + RemovePhysicalPrim(nphysparts); } bool ret = Entities.Remove(uuid); @@ -1599,13 +1604,16 @@ namespace OpenSim.Region.Framework.Scenes /// protected internal void UpdatePrimTexture(uint localID, byte[] texture, IClientAPI remoteClient) { - SceneObjectGroup group = GetGroupByPrim(localID); + SceneObjectPart part = GetSceneObjectPart(localID); + if(part == null) + return; - if (group != null) + SceneObjectGroup group = part.ParentGroup; + if (group != null && !group.IsDeleted) { if (m_parentScene.Permissions.CanEditObject(group, remoteClient)) { - group.UpdateTextureEntry(localID, texture); + part.UpdateTextureEntry(texture); } } } @@ -1641,7 +1649,7 @@ namespace OpenSim.Region.Framework.Scenes else // else turn it off vdtc = false; - group.UpdatePrimFlags(localID, UsePhysics, SetTemporary, SetPhantom, vdtc); + group.UpdateFlags(UsePhysics, SetTemporary, SetPhantom, vdtc); } else { @@ -1656,8 +1664,11 @@ namespace OpenSim.Region.Framework.Scenes if (wantedPhys != group.UsesPhysics && remoteClient != null) { - remoteClient.SendAlertMessage("Object physics canceled because exceeds the limit of " + - m_parentScene.m_linksetPhysCapacity + " physical prims with shape type not set to None"); + if(m_parentScene.m_linksetPhysCapacity != 0) + remoteClient.SendAlertMessage("Object physics cancelled because it exceeds limits for physical prims, either size or number of primswith shape type not set to None"); + else + remoteClient.SendAlertMessage("Object physics cancelled because it exceeds size limits for physical prims"); + group.RootPart.ScheduleFullUpdate(); } } @@ -1985,6 +1996,7 @@ namespace OpenSim.Region.Framework.Scenes { newRoot.TriggerScriptChangedEvent(Changed.LINK); newRoot.ParentGroup.HasGroupChanged = true; + newRoot.ParentGroup.InvalidatePartsLinkMaps(); newRoot.ParentGroup.ScheduleGroupForFullUpdate(); } } @@ -2001,6 +2013,7 @@ namespace OpenSim.Region.Framework.Scenes // from the database. They will be rewritten immediately, // minus the rows for the unlinked child prims. m_parentScene.SimulationDataService.RemoveObject(g.UUID, m_parentScene.RegionInfo.RegionID); + g.InvalidatePartsLinkMaps(); g.TriggerScriptChangedEvent(Changed.LINK); g.HasGroupChanged = true; // Persist g.ScheduleGroupForFullUpdate(); @@ -2087,7 +2100,7 @@ namespace OpenSim.Region.Framework.Scenes child.TriggerScriptChangedEvent(Changed.OWNER); child.ApplyNextOwnerPermissions(); } - copy.AggregatePerms(); + copy.InvalidateEffectivePerms(); } } diff --git a/OpenSim/Region/Framework/Scenes/SceneManager.cs b/OpenSim/Region/Framework/Scenes/SceneManager.cs index 1e418df94d..f454908d9c 100644 --- a/OpenSim/Region/Framework/Scenes/SceneManager.cs +++ b/OpenSim/Region/Framework/Scenes/SceneManager.cs @@ -196,8 +196,6 @@ namespace OpenSim.Region.Framework.Scenes public void SendSimOnlineNotification(ulong regionHandle) { - RegionInfo Result = null; - Scene s = m_localScenes.FindValue(delegate(Scene x) { if (x.RegionInfo.RegionHandle == regionHandle) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs index 12e53a8d27..bf217a5f3c 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs @@ -183,7 +183,7 @@ namespace OpenSim.Region.Framework.Scenes addFromAllowedDrop = (part.ParentGroup.RootPart.GetEffectiveObjectFlags() & (uint)PrimFlags.AllowInventoryDrop) != 0; part.Inventory.AddInventoryItem(taskItem, addFromAllowedDrop); - part.ParentGroup.AggregatePerms(); + part.ParentGroup.InvalidateEffectivePerms(); return true; } @@ -252,18 +252,39 @@ namespace OpenSim.Region.Framework.Scenes } // new test code, to place in better place later - private object PermissionsLock = new object(); + private object m_PermissionsLock = new object(); + private bool m_EffectivePermsInvalid = true; + private bool m_DeepEffectivePermsInvalid = true; + + // should called when parts chanced by their contents did not, so we know their cacche is valid + // in case of doubt call InvalidateDeepEffectivePerms(), it only costs a bit more cpu time + public void InvalidateEffectivePerms() + { + lock(m_PermissionsLock) + m_EffectivePermsInvalid = true; + } + + // should called when parts chanced and their contents where accounted for + public void InvalidateDeepEffectivePerms() + { + lock(m_PermissionsLock) + { + m_DeepEffectivePermsInvalid = true; + m_EffectivePermsInvalid = true; + } + } private uint m_EffectiveEveryOnePerms; public uint EffectiveEveryOnePerms { get { - // this can't be done here but on every place where a change may happen (rez, (de)link, contents , perms, etc) - // bc this is on heavy duty code paths - // but for now we need to test the concept -// AggregateDeepPerms(); - return m_EffectiveEveryOnePerms; + lock(m_PermissionsLock) + { + if(m_EffectivePermsInvalid) + AggregatePerms(); + return m_EffectiveEveryOnePerms; + } } } @@ -272,11 +293,12 @@ namespace OpenSim.Region.Framework.Scenes { get { - // this can't be done here but on every place where a change may happen (rez, (de)link, contents , perms, etc) - // bc this is on heavy duty code paths - // but for now we need to test the concept -// AggregateDeepPerms(); - return m_EffectiveGroupPerms; + lock(m_PermissionsLock) + { + if(m_EffectivePermsInvalid) + AggregatePerms(); + return m_EffectiveGroupPerms; + } } } @@ -285,11 +307,12 @@ namespace OpenSim.Region.Framework.Scenes { get { - // this can't be done here but on every place where a change may happen (rez, (de)link, contents , perms, etc) - // bc this is on heavy duty code paths - // but for now we need to test the concept -// AggregateDeepPerms(); - return m_EffectiveGroupOrEveryOnePerms; + lock(m_PermissionsLock) + { + if(m_EffectivePermsInvalid) + AggregatePerms(); + return m_EffectiveGroupOrEveryOnePerms; + } } } @@ -298,86 +321,18 @@ namespace OpenSim.Region.Framework.Scenes { get { - // this can't be done here but on every place where a change may happen (rez, (de)link, contents , perms, etc) - // bc this is on heavy duty code paths - // but for now we need to test the concept - // AggregateDeepPerms(); - return m_EffectiveOwnerPerms; - } - } - - // aggregates perms scanning parts and their contents - // AggregatePerms does same using cached parts content perms - public void AggregateDeepPerms() - { - lock(PermissionsLock) - { - // aux - const uint allmask = (uint)PermissionMask.AllEffective; - const uint movemodmask = (uint)(PermissionMask.Move | PermissionMask.Modify); - const uint copytransfermast = (uint)(PermissionMask.Copy | PermissionMask.Transfer); - - uint basePerms = (RootPart.BaseMask & allmask) | (uint)PermissionMask.Move; - bool noBaseTransfer = (basePerms & (uint)PermissionMask.Transfer) == 0; - - uint rootOwnerPerms = RootPart.OwnerMask; - uint owner = rootOwnerPerms; - uint rootGroupPerms = RootPart.GroupMask; - uint group = rootGroupPerms; - uint rootEveryonePerms = RootPart.EveryoneMask; - uint everyone = rootEveryonePerms; - - SceneObjectPart[] parts = m_parts.GetArray(); - for (int i = 0; i < parts.Length; i++) + lock(m_PermissionsLock) { - SceneObjectPart part = parts[i]; - part.AggregateInnerPerms(); - owner &= part.AggregatedInnerOwnerPerms; - group &= part.AggregatedInnerGroupPerms; - everyone &= part.AggregatedInnerEveryonePerms; + if(m_EffectivePermsInvalid) + AggregatePerms(); + return m_EffectiveOwnerPerms; } - // recover modify and move - rootOwnerPerms &= movemodmask; - owner |= rootOwnerPerms; - if((owner & copytransfermast) == 0) - owner |= (uint)PermissionMask.Transfer; - - owner &= basePerms; - m_EffectiveOwnerPerms = owner; - uint ownertransfermask = owner & (uint)PermissionMask.Transfer; - - // recover modify and move - rootGroupPerms &= movemodmask; - group |= rootGroupPerms; - if(noBaseTransfer) - group &=~(uint)PermissionMask.Copy; - else - group |= ownertransfermask; - - uint groupOrEveryone = group; - m_EffectiveGroupPerms = group & owner; - - // recover move - rootEveryonePerms &= (uint)PermissionMask.Move; - everyone |= rootEveryonePerms; - everyone &= ~(uint)PermissionMask.Modify; - if(noBaseTransfer) - everyone &=~(uint)PermissionMask.Copy; - else - everyone |= ownertransfermask; - - groupOrEveryone |= everyone; - - m_EffectiveEveryOnePerms = everyone & owner; - m_EffectiveGroupOrEveryOnePerms = groupOrEveryone & owner; } } - // aggregates perms scanning parts, assuming their contents was already aggregated and cached - // ie is AggregateDeepPerms without the part.AggregateInnerPerms() call on parts loop public void AggregatePerms() { - lock(PermissionsLock) + lock(m_PermissionsLock) { // aux const uint allmask = (uint)PermissionMask.AllEffective; @@ -394,13 +349,23 @@ namespace OpenSim.Region.Framework.Scenes uint rootEveryonePerms = RootPart.EveryoneMask; uint everyone = rootEveryonePerms; + bool needUpdate = false; + // date is time of writing april 30th 2017 + bool newobj = (RootPart.CreationDate == 0 || RootPart.CreationDate > 1493574994); SceneObjectPart[] parts = m_parts.GetArray(); for (int i = 0; i < parts.Length; i++) { SceneObjectPart part = parts[i]; + + if(m_DeepEffectivePermsInvalid) + part.AggregatedInnerPermsForGroup(); + owner &= part.AggregatedInnerOwnerPerms; group &= part.AggregatedInnerGroupPerms; - everyone &= part.AggregatedInnerEveryonePerms; + if(newobj) + group &= part.AggregatedInnerGroupPerms; + if(newobj) + everyone &= part.AggregatedInnerEveryonePerms; } // recover modify and move rootOwnerPerms &= movemodmask; @@ -409,7 +374,12 @@ namespace OpenSim.Region.Framework.Scenes owner |= (uint)PermissionMask.Transfer; owner &= basePerms; - m_EffectiveOwnerPerms = owner; + if(owner != m_EffectiveOwnerPerms) + { + needUpdate = true; + m_EffectiveOwnerPerms = owner; + } + uint ownertransfermask = owner & (uint)PermissionMask.Transfer; // recover modify and move @@ -421,7 +391,12 @@ namespace OpenSim.Region.Framework.Scenes group |= ownertransfermask; uint groupOrEveryone = group; - m_EffectiveGroupPerms = group & owner; + uint tmpPerms = group & owner; + if(tmpPerms != m_EffectiveGroupPerms) + { + needUpdate = true; + m_EffectiveGroupPerms = tmpPerms; + } // recover move rootEveryonePerms &= (uint)PermissionMask.Move; @@ -434,35 +409,43 @@ namespace OpenSim.Region.Framework.Scenes groupOrEveryone |= everyone; - m_EffectiveEveryOnePerms = everyone & owner; - m_EffectiveGroupOrEveryOnePerms = groupOrEveryone & owner; + tmpPerms = everyone & owner; + if(tmpPerms != m_EffectiveEveryOnePerms) + { + needUpdate = true; + m_EffectiveEveryOnePerms = tmpPerms; + } + + tmpPerms = groupOrEveryone & owner; + if(tmpPerms != m_EffectiveGroupOrEveryOnePerms) + { + needUpdate = true; + m_EffectiveGroupOrEveryOnePerms = tmpPerms; + } + + m_DeepEffectivePermsInvalid = false; + m_EffectivePermsInvalid = false; + + if(needUpdate) + RootPart.ScheduleFullUpdate(); } } - public uint GetEffectivePermissions() - { - return GetEffectivePermissions(false); - } - - public uint GetEffectivePermissions(bool useBase) + public uint CurrentAndFoldedNextPermissions() { uint perms=(uint)(PermissionMask.Modify | PermissionMask.Copy | PermissionMask.Move | - PermissionMask.Transfer) | 7; + PermissionMask.Transfer | + PermissionMask.FoldedMask); - uint ownerMask = 0x7fffffff; + uint ownerMask = RootPart.OwnerMask; SceneObjectPart[] parts = m_parts.GetArray(); for (int i = 0; i < parts.Length; i++) { SceneObjectPart part = parts[i]; - - if (useBase) - ownerMask &= part.BaseMask; - else - ownerMask &= part.OwnerMask; - + ownerMask &= part.BaseMask; perms &= part.Inventory.MaskEffectivePermissions(); } @@ -472,17 +455,8 @@ namespace OpenSim.Region.Framework.Scenes perms &= ~(uint)PermissionMask.Copy; if ((ownerMask & (uint)PermissionMask.Transfer) == 0) perms &= ~(uint)PermissionMask.Transfer; - - // If root prim permissions are applied here, this would screw - // with in-inventory manipulation of the next owner perms - // in a major way. So, let's move this to the give itself. - // Yes. I know. Evil. -// if ((ownerMask & RootPart.NextOwnerMask & (uint)PermissionMask.Modify) == 0) -// perms &= ~((uint)PermissionMask.Modify >> 13); -// if ((ownerMask & RootPart.NextOwnerMask & (uint)PermissionMask.Copy) == 0) -// perms &= ~((uint)PermissionMask.Copy >> 13); -// if ((ownerMask & RootPart.NextOwnerMask & (uint)PermissionMask.Transfer) == 0) -// perms &= ~((uint)PermissionMask.Transfer >> 13); + if ((ownerMask & (uint)PermissionMask.Export) == 0) + perms &= ~(uint)PermissionMask.Export; return perms; } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index bf4d60cd61..21311b0bcb 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -153,7 +153,7 @@ namespace OpenSim.Region.Framework.Scenes timeLastChanged = DateTime.UtcNow.Ticks; if (!m_hasGroupChanged) timeFirstChanged = DateTime.UtcNow.Ticks; - if (m_rootPart != null && m_rootPart.UUID != null && m_scene != null) + if (m_rootPart != null && m_scene != null) { /* if (m_rand == null) @@ -538,7 +538,7 @@ namespace OpenSim.Region.Framework.Scenes public bool inTransit = false; - public delegate SceneObjectGroup SOGCrossDelegate(SceneObjectGroup sog,Vector3 pos); + private delegate SceneObjectGroup SOGCrossDelegate(SceneObjectGroup sog,Vector3 pos, TeleportObjectData tpData); /// /// The absolute position of this scene object in the scene @@ -560,7 +560,7 @@ namespace OpenSim.Region.Framework.Scenes { inTransit = true; SOGCrossDelegate d = CrossAsync; - d.BeginInvoke(this, val, CrossAsyncCompleted, d); + d.BeginInvoke(this, val, null, CrossAsyncCompleted, d); } return; } @@ -601,7 +601,6 @@ namespace OpenSim.Region.Framework.Scenes av.sitSOGmoved(); } - // now that position is changed tell it to scripts if (triggerScriptEvent) { @@ -617,64 +616,78 @@ namespace OpenSim.Region.Framework.Scenes } } - public SceneObjectGroup CrossAsync(SceneObjectGroup sog, Vector3 val) + private SceneObjectGroup CrossAsync(SceneObjectGroup sog, Vector3 val, TeleportObjectData tpdata) { Scene sogScene = sog.m_scene; + SceneObjectPart root = sog.RootPart; + + bool isTeleport = tpdata != null; + + if(!isTeleport) + { + if (root.DIE_AT_EDGE) + { + try + { + sogScene.DeleteSceneObject(sog, false); + } + catch (Exception) + { + m_log.Warn("[SCENE]: exception when trying to remove the prim that crossed the border."); + } + return sog; + } + + if (root.RETURN_AT_EDGE) + { + // We remove the object here + try + { + List localIDs = new List(); + localIDs.Add(root.LocalId); + sogScene.AddReturn(sog.OwnerID, sog.Name, sog.AbsolutePosition, + "Returned at region cross"); + sogScene.DeRezObjects(null, localIDs, UUID.Zero, DeRezAction.Return, UUID.Zero, false); + } + catch (Exception) + { + m_log.Warn("[SCENE]: exception when trying to return the prim that crossed the border."); + } + return sog; + } + } + +// if(!m_scene.IsRunning) +// return sog; + + if (root.KeyframeMotion != null) + root.KeyframeMotion.StartCrossingCheck(); + + if(root.PhysActor != null) + root.PhysActor.CrossingStart(); + IEntityTransferModule entityTransfer = sogScene.RequestModuleInterface(); - Vector3 newpos = Vector3.Zero; - OpenSim.Services.Interfaces.GridRegion destination = null; - - if (sog.RootPart.DIE_AT_EDGE) - { - try - { - sogScene.DeleteSceneObject(sog, false); - } - catch (Exception) - { - m_log.Warn("[SCENE]: exception when trying to remove the prim that crossed the border."); - } - return sog; - } - - if (sog.RootPart.RETURN_AT_EDGE) - { - // We remove the object here - try - { - List localIDs = new List(); - localIDs.Add(sog.RootPart.LocalId); - sogScene.AddReturn(sog.OwnerID, sog.Name, sog.AbsolutePosition, - "Returned at region cross"); - sogScene.DeRezObjects(null, localIDs, UUID.Zero, DeRezAction.Return, UUID.Zero, false); - } - catch (Exception) - { - m_log.Warn("[SCENE]: exception when trying to return the prim that crossed the border."); - } - return sog; - } - - if (sog.m_rootPart.KeyframeMotion != null) - sog.m_rootPart.KeyframeMotion.StartCrossingCheck(); - if (entityTransfer == null) return sog; + Vector3 newpos = Vector3.Zero; + OpenSim.Services.Interfaces.GridRegion destination = null; + destination = entityTransfer.GetObjectDestination(sog, val, out newpos); if (destination == null) return sog; if (sog.m_sittingAvatars.Count == 0) { - entityTransfer.CrossPrimGroupIntoNewRegion(destination, newpos, sog, true, true); + entityTransfer.CrossPrimGroupIntoNewRegion(destination, newpos, sog, !isTeleport, true); return sog; } string reason = String.Empty; EntityTransferContext ctx = new EntityTransferContext(); + Vector3 curPos = root.GroupPosition; foreach (ScenePresence av in sog.m_sittingAvatars) { // We need to cross these agents. First, let's find @@ -685,10 +698,15 @@ namespace OpenSim.Region.Framework.Scenes // We set the avatar position as being the object // position to get the region to send to - if(!entityTransfer.checkAgentAccessToRegion(av, destination, newpos, ctx, out reason)) - { + if(av.IsNPC) + continue; + + if(av.IsInTransit) return sog; - } + + if(!entityTransfer.checkAgentAccessToRegion(av, destination, newpos, ctx, out reason)) + return sog; + m_log.DebugFormat("[SCENE OBJECT]: Avatar {0} needs to be crossed to {1}", av.Name, destination.RegionName); } @@ -696,8 +714,10 @@ namespace OpenSim.Region.Framework.Scenes // be made to stand up List avsToCross = new List(); - - foreach (ScenePresence av in sog.m_sittingAvatars) + List avsToCrossFar = new List(); + ulong destHandle = destination.RegionHandle; + List sittingAvatars = GetSittingAvatars(); + foreach (ScenePresence av in sittingAvatars) { byte cflags = 1; @@ -711,68 +731,176 @@ namespace OpenSim.Region.Framework.Scenes else cflags = 3; } + if(!av.knowsNeighbourRegion(destHandle)) + cflags |= 8; // 1 is crossing // 2 is sitting // 4 is sitting at sittarget - av.crossingFlags = cflags; + // 8 far crossing avinfo.av = av; avinfo.ParentID = av.ParentID; avsToCross.Add(avinfo); + if(!av.knowsNeighbourRegion(destHandle)) + { + cflags |= 8; + avsToCrossFar.Add(av); + } + + if(av.IsNPC) + av.crossingFlags = 0; + else + av.crossingFlags = cflags; + av.PrevSitOffset = av.OffsetPosition; av.ParentID = 0; } + Vector3 vel = root.Velocity; + Vector3 avel = root.AngularVelocity; + Vector3 acc = root.Acceleration; + Quaternion ori = root.RotationOffset; + + if(isTeleport) + { + root.Stop(); + sogScene.ForEachScenePresence(delegate(ScenePresence av) + { + av.ControllingClient.SendEntityUpdate(root,PrimUpdateFlags.SendInTransit); + av.ControllingClient.SendEntityTerseUpdateImmediate(root); + }); + + root.Velocity = tpdata.vel; + root.AngularVelocity = tpdata.avel; + root.Acceleration = tpdata.acc; + root.RotationOffset = tpdata.ori; + } + if (entityTransfer.CrossPrimGroupIntoNewRegion(destination, newpos, sog, true, false)) { + if(isTeleport) + { + sogScene.ForEachScenePresence(delegate(ScenePresence oav) + { + if(sittingAvatars.Contains(oav)) + return; + if(oav.knowsNeighbourRegion(destHandle)) + return; + oav.ControllingClient.SendEntityUpdate(root, PrimUpdateFlags.Kill); + foreach (ScenePresence sav in sittingAvatars) + { + sav.SendKillTo(oav); + } + }); + } + bool crossedfar = false; + foreach (ScenePresence av in avsToCrossFar) + { + if(entityTransfer.CrossAgentCreateFarChild(av,destination, newpos, ctx)) + crossedfar = true; + else + av.crossingFlags = 0; + } + + if(crossedfar) + Thread.Sleep(1000); + foreach (avtocrossInfo avinfo in avsToCross) { ScenePresence av = avinfo.av; - if (!av.IsInTransit) // just in case... + av.IsInLocalTransit = true; + av.IsInTransit = true; + m_log.DebugFormat("[SCENE OBJECT]: Crossing avatar {0} to {1}", av.Name, val); + + if(av.crossingFlags > 0) + entityTransfer.CrossAgentToNewRegionAsync(av, newpos, destination, false, ctx); + + if (av.IsChildAgent) { - m_log.DebugFormat("[SCENE OBJECT]: Crossing avatar {0} to {1}", av.Name, val); - - av.IsInTransit = true; - -// CrossAgentToNewRegionDelegate d = entityTransfer.CrossAgentToNewRegionAsync; -// d.BeginInvoke(av, val, destination, av.Flying, version, CrossAgentToNewRegionCompleted, d); - entityTransfer.CrossAgentToNewRegionAsync(av, newpos, destination, av.Flying, ctx); - if (av.IsChildAgent) + // avatar crossed do some extra cleanup + if (av.ParentUUID != UUID.Zero) { - // avatar crossed do some extra cleanup - if (av.ParentUUID != UUID.Zero) - { - av.ClearControls(); - av.ParentPart = null; - } + av.ClearControls(); + av.ParentPart = null; } - else - { - // avatar cross failed we need do dedicated standUp - // part of it was done at CrossAgentToNewRegionAsync - // so for now just remove the sog controls - // this may need extra care - av.UnRegisterSeatControls(sog.UUID); - } - av.ParentUUID = UUID.Zero; + av.ParentPart = null; // In any case av.IsInTransit = false; av.crossingFlags = 0; m_log.DebugFormat("[SCENE OBJECT]: Crossing agent {0} {1} completed.", av.Firstname, av.Lastname); } else - m_log.DebugFormat("[SCENE OBJECT]: Crossing avatar already in transit {0} to {1}", av.Name, val); + { + // avatar cross failed we need do dedicated standUp + // part of it was done at CrossAgentToNewRegionAsync + // so for now just remove the sog controls + // this may need extra care + av.UnRegisterSeatControls(sog.UUID); + av.ParentUUID = UUID.Zero; + av.ParentPart = null; + Vector3 oldp = curPos; + oldp.X = Util.Clamp(oldp.X, 0.5f, sog.m_scene.RegionInfo.RegionSizeX - 0.5f); + oldp.Y = Util.Clamp(oldp.Y, 0.5f, sog.m_scene.RegionInfo.RegionSizeY - 0.5f); + av.AbsolutePosition = oldp; + av.crossingFlags = 0; + av.sitAnimation = "SIT"; + av.IsInTransit = false; + if(av.Animator!= null) + av.Animator.SetMovementAnimations("STAND"); + av.AddToPhysicalScene(false); + sogScene.ForEachScenePresence(delegate(ScenePresence oav) + { + if(sittingAvatars.Contains(oav)) + return; + if(oav.knowsNeighbourRegion(destHandle)) + av.SendAvatarDataToAgent(oav); + else + { + av.SendAvatarDataToAgent(oav); + av.SendAppearanceToAgent(oav); + if (av.Animator != null) + av.Animator.SendAnimPackToClient(oav.ControllingClient); + av.SendAttachmentsToAgentNF(oav); // not ok + } + }); + m_log.DebugFormat("[SCENE OBJECT]: Crossing agent {0} {1} failed.", av.Firstname, av.Lastname); + } } + + if(crossedfar) + { + Thread.Sleep(10000); + foreach (ScenePresence av in avsToCrossFar) + { + if(av.IsChildAgent) + { + av.Scene.CloseAgent(av.UUID, false); + } + else + av.RemoveNeighbourRegion(destHandle); + } + } + avsToCrossFar.Clear(); avsToCross.Clear(); sog.RemoveScriptInstances(true); sog.Clear(); return sog; } - else // cross failed, put avas back ?? + else { + if(isTeleport) + { + if((tpdata.flags & OSTPOBJ_STOPONFAIL) == 0) + { + root.Velocity = vel; + root.AngularVelocity = avel; + root.Acceleration = acc; + } + root.RotationOffset = ori; + } foreach (avtocrossInfo avinfo in avsToCross) { ScenePresence av = avinfo.av; @@ -782,7 +910,6 @@ namespace OpenSim.Region.Framework.Scenes } } avsToCross.Clear(); - return sog; } @@ -794,11 +921,14 @@ namespace OpenSim.Region.Framework.Scenes if (!sog.IsDeleted) { SceneObjectPart rootp = sog.m_rootPart; + Vector3 oldp = rootp.GroupPosition; oldp.X = Util.Clamp(oldp.X, 0.5f, sog.m_scene.RegionInfo.RegionSizeX - 0.5f); oldp.Y = Util.Clamp(oldp.Y, 0.5f, sog.m_scene.RegionInfo.RegionSizeY - 0.5f); rootp.GroupPosition = oldp; + rootp.Stop(); + SceneObjectPart[] parts = sog.m_parts.GetArray(); foreach (SceneObjectPart part in parts) @@ -812,47 +942,150 @@ namespace OpenSim.Region.Framework.Scenes av.sitSOGmoved(); } - sog.Velocity = Vector3.Zero; - if (sog.m_rootPart.KeyframeMotion != null) sog.m_rootPart.KeyframeMotion.CrossingFailure(); if (sog.RootPart.PhysActor != null) - { sog.RootPart.PhysActor.CrossingFailure(); - } sog.inTransit = false; + AttachToBackup(); sog.ScheduleGroupForFullUpdate(); } } -/* outdated - private void CrossAgentToNewRegionCompleted(ScenePresence agent) + private class TeleportObjectData { - //// If the cross was successful, this agent is a child agent - if (agent.IsChildAgent) + public int flags; + public Vector3 vel; + public Vector3 avel; + public Vector3 acc; + public Quaternion ori; + public UUID sourceID; + } + + // copy from LSL_constants.cs + const int OSTPOBJ_STOPATTARGET = 0x1; // stops at destination + const int OSTPOBJ_STOPONFAIL = 0x2; // stops at start if tp fails + const int OSTPOBJ_SETROT = 0x4; // the rotation is the final rotation, otherwise is a added rotation + + public int TeleportObject(UUID sourceID, Vector3 targetPosition, Quaternion rotation, int flags) + { + if(inTransit || IsDeleted || IsAttachmentCheckFull() || IsSelected || Scene == null) + return -1; + + inTransit = true; + + PhysicsActor pa = RootPart.PhysActor; + if(pa == null || RootPart.KeyframeMotion != null /*|| m_sittingAvatars.Count == 0*/) { - if (agent.ParentUUID != UUID.Zero) - { - agent.HandleForceReleaseControls(agent.ControllingClient,agent.UUID); - agent.ParentPart = null; -// agent.ParentPosition = Vector3.Zero; -// agent.ParentUUID = UUID.Zero; - } + inTransit = false; + return -1; } - agent.ParentUUID = UUID.Zero; -// agent.Reset(); -// else // Not successful -// agent.RestoreInCurrentScene(); + bool stop = (flags & OSTPOBJ_STOPATTARGET) != 0; + bool setrot = (flags & OSTPOBJ_SETROT) != 0; - // In any case - agent.IsInTransit = false; + rotation.Normalize(); + + Quaternion currentRot = RootPart.RotationOffset; + if(setrot) + rotation = Quaternion.Conjugate(currentRot) * rotation; - m_log.DebugFormat("[SCENE OBJECT]: Crossing agent {0} {1} completed.", agent.Firstname, agent.Lastname); + bool dorot = setrot | (Math.Abs(rotation.W) < 0.99999); + + Vector3 vel = Vector3.Zero; + Vector3 avel = Vector3.Zero; + Vector3 acc = Vector3.Zero; + + if(!stop) + { + vel = RootPart.Velocity; + avel = RootPart.AngularVelocity; + acc = RootPart.Acceleration; + } + Quaternion ori = RootPart.RotationOffset; + + if(dorot) + { + if(!stop) + { + vel *= rotation; + avel *= rotation; + acc *= rotation; + } + ori *= rotation; + } + + if(Scene.PositionIsInCurrentRegion(targetPosition)) + { + if(Scene.InTeleportTargetsCoolDown(UUID, sourceID, 1.0)) + { + inTransit = false; + return -2; + } + + Vector3 curPos = AbsolutePosition; + ILandObject curLand = Scene.LandChannel.GetLandObject(curPos.X, curPos.Y); + float posX = targetPosition.X; + float posY = targetPosition.Y; + ILandObject land = Scene.LandChannel.GetLandObject(posX, posY); + if(land != null && land != curLand) + { + if(!Scene.Permissions.CanObjectEnterWithScripts(this, land)) + { + inTransit = false; + return -3; + } + + UUID agentID; + foreach (ScenePresence av in m_sittingAvatars) + { + agentID = av.UUID; + if(land.IsRestrictedFromLand(agentID) || land.IsBannedFromLand(agentID)) + { + inTransit = false; + return -4; + } + } + } + + RootPart.Velocity = vel; + RootPart.AngularVelocity = avel; + RootPart.Acceleration = acc; + RootPart.RotationOffset = ori; + + Vector3 s = RootPart.Scale * RootPart.RotationOffset; + float h = Scene.GetGroundHeight(posX, posY) + 0.5f * (float)Math.Abs(s.Z) + 0.01f; + if(targetPosition.Z < h) + targetPosition.Z = h; + + inTransit = false; + AbsolutePosition = targetPosition; + RootPart.ScheduleTerseUpdate(); + return 1; + } + + if(Scene.InTeleportTargetsCoolDown(UUID, sourceID, 20.0)) + { + inTransit = false; + return -1; + } + + TeleportObjectData tdata = new TeleportObjectData(); + tdata.flags = flags; + tdata.vel = vel; + tdata.avel = avel; + tdata.acc = acc; + tdata.ori = ori; + tdata.sourceID = sourceID; + + + SOGCrossDelegate d = CrossAsync; + d.BeginInvoke(this, targetPosition, tdata, CrossAsyncCompleted, d); + return 0; } -*/ + public override Vector3 Velocity { get { return RootPart.Velocity; } @@ -1029,6 +1262,8 @@ namespace OpenSim.Region.Framework.Scenes set { m_LoopSoundSlavePrims = value; } } + private double m_lastCollisionSoundMS; + /// /// The UUID for the region this object is in. /// @@ -1106,7 +1341,7 @@ namespace OpenSim.Region.Framework.Scenes /// public SceneObjectGroup() { - + m_lastCollisionSoundMS = Util.GetTimeStampMS() + 1000.0; } /// @@ -1759,6 +1994,7 @@ namespace OpenSim.Region.Framework.Scenes public void SaveScriptedState(XmlTextWriter writer, bool oldIDs) { XmlDocument doc = new XmlDocument(); + doc.XmlResolver=null; Dictionary states = new Dictionary(); SceneObjectPart[] parts = m_parts.GetArray(); @@ -1899,6 +2135,7 @@ namespace OpenSim.Region.Framework.Scenes if (part.LinkNum == 2) RootPart.LinkNum = 1; + InvalidatePartsLinkMaps(); } /// @@ -2447,7 +2684,7 @@ namespace OpenSim.Region.Framework.Scenes if (dupe.m_rootPart.PhysActor != null) dupe.m_rootPart.PhysActor.Building = false; // tell physics to finish building - dupe.AggregateDeepPerms(); + dupe.InvalidateDeepEffectivePerms(); dupe.HasGroupChanged = true; dupe.AttachToBackup(); @@ -2455,6 +2692,7 @@ namespace OpenSim.Region.Framework.Scenes dupe.ScheduleGroupForFullUpdate(); } + dupe.InvalidatePartsLinkMaps(); m_dupeInProgress = false; return dupe; } @@ -2484,35 +2722,22 @@ namespace OpenSim.Region.Framework.Scenes RootPart.KeyframeMotion.Stop(); RootPart.KeyframeMotion = null; } - UpdatePrimFlags(RootPart.LocalId, usePhysics, IsTemporary, IsPhantom, IsVolumeDetect); + UpdateFlags(usePhysics, IsTemporary, IsPhantom, IsVolumeDetect); } public void ScriptSetTemporaryStatus(bool makeTemporary) { - UpdatePrimFlags(RootPart.LocalId, UsesPhysics, makeTemporary, IsPhantom, IsVolumeDetect); + UpdateFlags(UsesPhysics, makeTemporary, IsPhantom, IsVolumeDetect); } public void ScriptSetPhantomStatus(bool makePhantom) { - UpdatePrimFlags(RootPart.LocalId, UsesPhysics, IsTemporary, makePhantom, IsVolumeDetect); + UpdateFlags(UsesPhysics, IsTemporary, makePhantom, IsVolumeDetect); } public void ScriptSetVolumeDetect(bool makeVolumeDetect) { - UpdatePrimFlags(RootPart.LocalId, UsesPhysics, IsTemporary, IsPhantom, makeVolumeDetect); - - /* - ScriptSetPhantomStatus(false); // What ever it was before, now it's not phantom anymore - - if (PhysActor != null) // Should always be the case now - { - PhysActor.SetVolumeDetect(param); - } - if (param != 0) - AddFlag(PrimFlags.Phantom); - - ScheduleFullUpdate(); - */ + UpdateFlags(UsesPhysics, IsTemporary, IsPhantom, makeVolumeDetect); } public void applyImpulse(Vector3 impulse) @@ -2558,7 +2783,7 @@ namespace OpenSim.Region.Framework.Scenes return RootPart.Torque; } - // This is used by both Double-Click Auto-Pilot and llMoveToTarget() in an attached object + // This is used by llMoveToTarget() in an attached object public void MoveToTarget(Vector3 target, float tau) { if (IsAttachment) @@ -2566,7 +2791,7 @@ namespace OpenSim.Region.Framework.Scenes ScenePresence avatar = m_scene.GetScenePresence(AttachedAvatar); if (avatar != null) - avatar.MoveToTarget(target, false, false); + avatar.MoveToTarget(target, false, false, tau); } else { @@ -2712,7 +2937,7 @@ namespace OpenSim.Region.Framework.Scenes if (!m_scene.Permissions.BypassPermissions()) { ApplyNextOwnerPermissions(); - AggregatePerms(); + InvalidateEffectivePerms(); } } @@ -2797,12 +3022,13 @@ namespace OpenSim.Region.Framework.Scenes // If we somehow got here to updating the SOG and its root part is not scheduled for update, // check to see if the physical position or rotation warrant an update. +/* if (m_rootPart.UpdateFlag == UpdateRequired.NONE) { // rootpart SendScheduledUpdates will check if a update is needed m_rootPart.UpdateFlag = UpdateRequired.TERSE; } - +*/ if (IsAttachment) { ScenePresence sp = m_scene.GetScenePresence(AttachedAvatar); @@ -2817,11 +3043,14 @@ namespace OpenSim.Region.Framework.Scenes if (!IsSelected) RootPart.UpdateLookAt(); + double now = Util.GetTimeStampMS(); + RootPart.SendScheduledUpdates(now); SceneObjectPart[] parts = m_parts.GetArray(); for (int i = 0; i < parts.Length; i++) { SceneObjectPart part = parts[i]; - part.SendScheduledUpdates(); + if(part != RootPart) + part.SendScheduledUpdates(now); } } @@ -2888,7 +3117,6 @@ namespace OpenSim.Region.Framework.Scenes } RootPart.SendFullUpdateToAllClientsInternal(); - SceneObjectPart[] parts = m_parts.GetArray(); for (int i = 0; i < parts.Length; i++) { @@ -3216,6 +3444,7 @@ namespace OpenSim.Region.Framework.Scenes ResetChildPrimPhysicsPositions(); InvalidBoundsRadius(); + InvalidatePartsLinkMaps(); if (m_rootPart.PhysActor != null) m_rootPart.PhysActor.Building = false; @@ -3372,7 +3601,8 @@ namespace OpenSim.Region.Framework.Scenes objectGroup.HasGroupChangedDueToDelink = true; InvalidBoundsRadius(); - objectGroup.AggregatePerms(); + InvalidatePartsLinkMaps(); + objectGroup.InvalidateEffectivePerms(); if (sendEvents) linkPart.TriggerScriptChangedEvent(Changed.LINK); @@ -3795,84 +4025,80 @@ namespace OpenSim.Region.Framework.Scenes /// /// /// - public void UpdatePrimFlags(uint localID, bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVolumeDetect) + public void UpdateFlags(bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVolumeDetect) { + if (m_scene == null || IsDeleted) + return; + HasGroupChanged = true; - SceneObjectPart selectionPart = GetPart(localID); - - if (Scene != null) + if (SetTemporary) { - if (SetTemporary) - { - DetachFromBackup(); - // Remove from database and parcel prim count - // - m_scene.DeleteFromStorage(UUID); - } - else if (!Backup) - { - // Previously been temporary now switching back so make it - // available for persisting again - AttachToBackup(); - } - - m_scene.EventManager.TriggerParcelPrimCountTainted(); + DetachFromBackup(); + // Remove from database and parcel prim count + // + m_scene.DeleteFromStorage(UUID); + } + else if (!Backup) + { + // Previously been temporary now switching back so make it + // available for persisting again + AttachToBackup(); } - if (selectionPart != null) + + SceneObjectPart[] parts = m_parts.GetArray(); + + if (UsePhysics) { - SceneObjectPart[] parts = m_parts.GetArray(); + int maxprims = m_scene.m_linksetPhysCapacity; + bool checkShape = (maxprims > 0 && + parts.Length > maxprims); - if (Scene != null && UsePhysics) + for (int i = 0; i < parts.Length; i++) { - int maxprims = m_scene.m_linksetPhysCapacity; - bool checkShape = (maxprims > 0 && - parts.Length > maxprims); + SceneObjectPart part = parts[i]; - for (int i = 0; i < parts.Length; i++) + if(part.PhysicsShapeType == (byte)PhysicsShapeType.None) + continue; // assuming root type was checked elsewhere + + if (checkShape) { - SceneObjectPart part = parts[i]; - - if(part.PhysicsShapeType == (byte)PhysicsShapeType.None) - continue; // assuming root type was checked elsewhere - - if (checkShape) + if (--maxprims < 0) { - if (--maxprims < 0) - { - UsePhysics = false; - break; - } - } - - if (part.Scale.X > m_scene.m_maxPhys || - part.Scale.Y > m_scene.m_maxPhys || - part.Scale.Z > m_scene.m_maxPhys ) - { - UsePhysics = false; // Reset physics + UsePhysics = false; break; } } - } - if (parts.Length > 1) - { - m_rootPart.UpdatePrimFlags(UsePhysics, SetTemporary, SetPhantom, SetVolumeDetect, true); - - for (int i = 0; i < parts.Length; i++) + if (part.Scale.X > m_scene.m_maxPhys || + part.Scale.Y > m_scene.m_maxPhys || + part.Scale.Z > m_scene.m_maxPhys ) { - - if (parts[i].UUID != m_rootPart.UUID) - parts[i].UpdatePrimFlags(UsePhysics, SetTemporary, SetPhantom, SetVolumeDetect, true); + UsePhysics = false; // Reset physics + break; } - - if (m_rootPart.PhysActor != null) - m_rootPart.PhysActor.Building = false; } - else - m_rootPart.UpdatePrimFlags(UsePhysics, SetTemporary, SetPhantom, SetVolumeDetect, false); } + + if (parts.Length > 1) + { + m_rootPart.UpdatePrimFlags(UsePhysics, SetTemporary, SetPhantom, SetVolumeDetect, true); + + for (int i = 0; i < parts.Length; i++) + { + + if (parts[i].UUID != m_rootPart.UUID) + parts[i].UpdatePrimFlags(UsePhysics, SetTemporary, SetPhantom, SetVolumeDetect, true); + } + + if (m_rootPart.PhysActor != null) + m_rootPart.PhysActor.Building = false; + } + else + m_rootPart.UpdatePrimFlags(UsePhysics, SetTemporary, SetPhantom, SetVolumeDetect, false); + + m_scene.EventManager.TriggerParcelPrimCountTainted(); } public void UpdateExtraParam(uint localID, ushort type, bool inUse, byte[] data) @@ -3895,20 +4121,6 @@ namespace OpenSim.Region.Framework.Scenes return Parts.Count(); } - /// - /// Update the texture entry for this part - /// - /// - /// - public void UpdateTextureEntry(uint localID, byte[] textureEntry) - { - SceneObjectPart part = GetPart(localID); - if (part != null) - { - part.UpdateTextureEntry(textureEntry); - } - } - public void AdjustChildPrimPermissions(bool forceTaskInventoryPermissive) { uint newOwnerMask = (uint)(PermissionMask.All | PermissionMask.Export) & 0xfffffff0; // Mask folded bits @@ -3930,7 +4142,7 @@ namespace OpenSim.Region.Framework.Scenes // m_log.DebugFormat( // "[SCENE OBJECT GROUP]: RootPart.OwnerMask now {0} for {1} in {2}", // (OpenMetaverse.PermissionMask)RootPart.OwnerMask, Name, Scene.Name); - AggregatePerms(); + InvalidateEffectivePerms(); RootPart.ScheduleFullUpdate(); } @@ -3955,7 +4167,7 @@ namespace OpenSim.Region.Framework.Scenes { foreach (SceneObjectPart part in Parts) part.Inventory.ApplyGodPermissions(RootPart.BaseMask); - AggregatePerms(); + InvalidateEffectivePerms(); } HasGroupChanged = true; @@ -5010,6 +5222,49 @@ namespace OpenSim.Region.Framework.Scenes return Ptot; } + public void GetInertiaData(out float TotalMass, out Vector3 CenterOfMass, out Vector3 Inertia, out Vector4 aux ) + { + PhysicsActor pa = RootPart.PhysActor; + + if(((RootPart.Flags & PrimFlags.Physics) !=0) && pa !=null) + { + PhysicsInertiaData inertia; + + inertia = pa.GetInertiaData(); + + TotalMass = inertia.TotalMass; + CenterOfMass = inertia.CenterOfMass; + Inertia = inertia.Inertia; + aux = inertia.InertiaRotation; + + return; + } + + TotalMass = GetMass(); + CenterOfMass = GetCenterOfMass() - AbsolutePosition; + CenterOfMass *= Quaternion.Conjugate(RootPart.RotationOffset); + Inertia = Vector3.Zero; + aux = Vector4.Zero; + } + + public void SetInertiaData(float TotalMass, Vector3 CenterOfMass, Vector3 Inertia, Vector4 aux ) + { + PhysicsInertiaData inertia = new PhysicsInertiaData(); + inertia.TotalMass = TotalMass; + inertia.CenterOfMass = CenterOfMass; + inertia.Inertia = Inertia; + inertia.InertiaRotation = aux; + + if(TotalMass < 0) + RootPart.PhysicsInertia = null; + else + RootPart.PhysicsInertia = new PhysicsInertiaData(inertia); + + PhysicsActor pa = RootPart.PhysActor; + if(pa !=null) + pa.SetInertiaData(inertia); + } + /// /// Set the user group to which this scene object belongs. /// @@ -5171,7 +5426,7 @@ namespace OpenSim.Region.Framework.Scenes { part.ResetOwnerChangeFlag(); }); - AggregatePerms(); + InvalidateEffectivePerms(); } // clear some references to easy cg @@ -5185,9 +5440,113 @@ namespace OpenSim.Region.Framework.Scenes m_PlaySoundSlavePrims.Clear(); m_LoopSoundMasterPrim = null; m_targets.Clear(); + m_partsNameToLinkMap.Clear(); + } + + private Dictionary m_partsNameToLinkMap = new Dictionary(); + private string GetLinkNumber_lastname; + private int GetLinkNumber_lastnumber; + + // this scales bad but so does GetLinkNumPart + public int GetLinkNumber(string name) + { + if(String.IsNullOrEmpty(name) || name == "Object") + return -1; + + lock(m_partsNameToLinkMap) + { + if(m_partsNameToLinkMap.Count == 0) + { + GetLinkNumber_lastname = String.Empty; + GetLinkNumber_lastnumber = -1; + SceneObjectPart[] parts = m_parts.GetArray(); + for (int i = 0; i < parts.Length; i++) + { + string s = parts[i].Name; + if(String.IsNullOrEmpty(s) || s == "Object" || s == "Primitive") + continue; + + if(m_partsNameToLinkMap.ContainsKey(s)) + { + int ol = parts[i].LinkNum; + if(ol < m_partsNameToLinkMap[s]) + m_partsNameToLinkMap[s] = ol; + } + else + m_partsNameToLinkMap[s] = parts[i].LinkNum; + } + } + + if(name == GetLinkNumber_lastname) + return GetLinkNumber_lastnumber; + + if(m_partsNameToLinkMap.ContainsKey(name)) + { + lock(m_partsNameToLinkMap) + { + GetLinkNumber_lastname = name; + GetLinkNumber_lastnumber = m_partsNameToLinkMap[name]; + return GetLinkNumber_lastnumber; + } + } + } + + if(m_sittingAvatars.Count > 0) + { + int j = m_parts.Count + 1; + + ScenePresence[] avs = m_sittingAvatars.ToArray(); + for (int i = 0; i < avs.Length; i++, j++) + { + if (avs[i].Name == name) + { + GetLinkNumber_lastname = name; + GetLinkNumber_lastnumber = j; + return j; + } + } + } + + return -1; + } + + public void InvalidatePartsLinkMaps() + { + lock(m_partsNameToLinkMap) + { + m_partsNameToLinkMap.Clear(); + GetLinkNumber_lastname = String.Empty; + GetLinkNumber_lastnumber = -1; + } + } + + public bool CollisionSoundThrottled(int collisionSoundType) + { + double time = m_lastCollisionSoundMS; +// m_lastCollisionSoundMS = Util.GetTimeStampMS(); +// time = m_lastCollisionSoundMS - time; + double now = Util.GetTimeStampMS(); + time = now - time; + switch (collisionSoundType) + { + case 0: // default sounds + case 2: // default sounds with volume set by script + if(time < 300.0) + return true; + break; + case 1: // selected sound + if(time < 200.0) + return true; + break; + default: + break; + } + m_lastCollisionSoundMS = now; + return false; } #endregion } + } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index bf0e31b673..6c035f048e 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -238,12 +238,6 @@ namespace OpenSim.Region.Framework.Scenes /// public bool SoundQueueing { get; set; } - public uint TimeStampFull; - - public uint TimeStampLastActivity; // Will be used for AutoReturn - - public uint TimeStampTerse; - [XmlIgnore] public Quaternion AttachRotation = Quaternion.Identity; @@ -329,7 +323,8 @@ namespace OpenSim.Region.Framework.Scenes private byte[] m_TextureAnimation; private byte m_clickAction; private Color m_color = Color.Black; - private readonly List m_lastColliders = new List(); + private List m_lastColliders = new List(); + private bool m_lastLandCollide; private int m_linkNum; private int m_scriptAccessPin; @@ -369,9 +364,9 @@ namespace OpenSim.Region.Framework.Scenes protected Vector3 m_lastPosition; protected Quaternion m_lastRotation; protected Vector3 m_lastVelocity; - protected Vector3 m_lastAcceleration; + protected Vector3 m_lastAcceleration; // acceleration is a derived var with high noise protected Vector3 m_lastAngularVelocity; - protected int m_lastUpdateSentTime; + protected double m_lastUpdateSentTime; protected float m_buoyancy = 0.0f; protected Vector3 m_force; protected Vector3 m_torque; @@ -406,6 +401,8 @@ namespace OpenSim.Region.Framework.Scenes private SOPVehicle m_vehicleParams = null; + private PhysicsInertiaData m_physicsInertia; + public KeyframeMotion KeyframeMotion { get; set; @@ -636,6 +633,8 @@ namespace OpenSim.Region.Framework.Scenes set { m_name = value; + if(ParentGroup != null) + ParentGroup.InvalidatePartsLinkMaps(); PhysicsActor pa = PhysActor; @@ -805,7 +804,7 @@ namespace OpenSim.Region.Framework.Scenes { // If this is a linkset, we don't want the physics engine mucking up our group position here. PhysicsActor actor = PhysActor; - if (ParentID == 0) + if (_parentID == 0) { if (actor != null) m_groupPosition = actor.Position; @@ -834,7 +833,7 @@ namespace OpenSim.Region.Framework.Scenes try { // Root prim actually goes at Position - if (ParentID == 0) + if (_parentID == 0) { actor.Position = value; } @@ -876,7 +875,7 @@ namespace OpenSim.Region.Framework.Scenes ParentGroup.InvalidBoundsRadius(); PhysicsActor actor = PhysActor; - if (ParentID != 0 && actor != null) + if (_parentID != 0 && actor != null) { actor.Position = GetWorldPosition(); actor.Orientation = GetWorldRotation(); @@ -936,21 +935,8 @@ namespace OpenSim.Region.Framework.Scenes PhysicsActor actor = PhysActor; // If this is a root of a linkset, the real rotation is what the physics engine thinks. // If not a root prim, the offset rotation is computed by SOG and is relative to the root. - if (ParentID == 0 && (Shape.PCode != 9 || Shape.State == 0) && actor != null) - { - if (actor.Orientation.X != 0f || actor.Orientation.Y != 0f - || actor.Orientation.Z != 0f || actor.Orientation.W != 0f) - { - m_rotationOffset = actor.Orientation; - } - } - -// float roll, pitch, yaw = 0; -// m_rotationOffset.GetEulerAngles(out roll, out pitch, out yaw); -// -// m_log.DebugFormat( -// "[SCENE OBJECT PART]: Got euler {0} for RotationOffset on {1} {2}", -// new Vector3(roll, pitch, yaw), Name, LocalId); + if (_parentID == 0 && (Shape.PCode != 9 || Shape.State == 0) && actor != null) + m_rotationOffset = actor.Orientation; return m_rotationOffset; } @@ -966,7 +952,7 @@ namespace OpenSim.Region.Framework.Scenes try { // Root prim gets value directly - if (ParentID == 0) + if (_parentID == 0) { actor.Orientation = value; //m_log.Info("[PART]: RO1:" + actor.Orientation.ToString()); @@ -1062,7 +1048,7 @@ namespace OpenSim.Region.Framework.Scenes m_angularVelocity = value; PhysicsActor actor = PhysActor; - if ((actor != null) && actor.IsPhysical && ParentGroup.RootPart == this && VehicleType == (int)Vehicle.TYPE_NONE) + if ((actor != null) && actor.IsPhysical && ParentGroup.RootPart == this) { actor.RotationalVelocity = m_angularVelocity; } @@ -1088,6 +1074,12 @@ namespace OpenSim.Region.Framework.Scenes m_acceleration = Vector3.Zero; else m_acceleration = value; + + PhysicsActor actor = PhysActor; + if ((actor != null) && actor.IsPhysical && ParentGroup.RootPart == this) + { + actor.Acceleration = m_acceleration; + } } } @@ -1106,8 +1098,8 @@ namespace OpenSim.Region.Framework.Scenes { get { - if (m_text.Length > 255) - return m_text.Substring(0, 254); + if (m_text.Length > 256) // yes > 254 + return m_text.Substring(0, 256); return m_text; } set { m_text = value; } @@ -1221,6 +1213,7 @@ namespace OpenSim.Region.Framework.Scenes } public UpdateRequired UpdateFlag { get; set; } + private object UpdateFlagLock = new object(); /// /// Used for media on a prim. @@ -1261,6 +1254,9 @@ namespace OpenSim.Region.Framework.Scenes { get { + if (_parentID == 0) + return GroupPosition; + return GroupPosition + (m_offsetPosition * ParentGroup.RootPart.RotationOffset); } } @@ -1382,7 +1378,8 @@ namespace OpenSim.Region.Framework.Scenes public UUID LastOwnerID { get { return _lastOwnerID; } - set { _lastOwnerID = value; } + set { + _lastOwnerID = value; } } public UUID RezzerID @@ -1639,8 +1636,10 @@ namespace OpenSim.Region.Framework.Scenes PhysActor.SetMaterial((int)value); } if(ParentGroup != null) + { ParentGroup.HasGroupChanged = true; - ScheduleFullUpdateIfNone(); + ScheduleFullUpdate(); + } } } } @@ -1673,7 +1672,7 @@ namespace OpenSim.Region.Framework.Scenes get { byte pst = PhysicsShapeType; - if(pst == (byte) PhysShapeType.none || pst == (byte) PhysShapeType.convex || HasMesh()) + if(pst == (byte) PhysShapeType.none || HasMesh()) return true; return false; } @@ -1728,7 +1727,12 @@ namespace OpenSim.Region.Framework.Scenes public byte PhysicsShapeType { - get { return m_physicsShapeType; } + get + { +// if (PhysActor != null) +// m_physicsShapeType = PhysActor.PhysicsShapeType; + return m_physicsShapeType; + } set { byte oldv = m_physicsShapeType; @@ -1779,10 +1783,12 @@ namespace OpenSim.Region.Framework.Scenes { m_density = value; - ScheduleFullUpdateIfNone(); if (ParentGroup != null) + { ParentGroup.HasGroupChanged = true; + ScheduleFullUpdate(); + } PhysicsActor pa = PhysActor; if (pa != null) @@ -1800,10 +1806,11 @@ namespace OpenSim.Region.Framework.Scenes { m_gravitymod = value; - ScheduleFullUpdateIfNone(); - if (ParentGroup != null) + { ParentGroup.HasGroupChanged = true; + ScheduleFullUpdate(); + } PhysicsActor pa = PhysActor; if (pa != null) @@ -1821,10 +1828,11 @@ namespace OpenSim.Region.Framework.Scenes { m_friction = value; - ScheduleFullUpdateIfNone(); - if (ParentGroup != null) + { ParentGroup.HasGroupChanged = true; + ScheduleFullUpdate(); + } PhysicsActor pa = PhysActor; if (pa != null) @@ -1842,10 +1850,11 @@ namespace OpenSim.Region.Framework.Scenes { m_bounce = value; - ScheduleFullUpdateIfNone(); - if (ParentGroup != null) + { ParentGroup.HasGroupChanged = true; + ScheduleFullUpdate(); + } PhysicsActor pa = PhysActor; if (pa != null) @@ -1874,7 +1883,8 @@ namespace OpenSim.Region.Framework.Scenes /// public void ClearUpdateSchedule() { - UpdateFlag = UpdateRequired.NONE; + lock(UpdateFlagLock) + UpdateFlag = UpdateRequired.NONE; } /// @@ -2012,7 +2022,7 @@ namespace OpenSim.Region.Framework.Scenes // SetVelocity for LSL llSetVelocity.. may need revision if having other uses in future public void SetVelocity(Vector3 pVel, bool localGlobalTF) { - if (ParentGroup == null || ParentGroup.IsDeleted) + if (ParentGroup == null || ParentGroup.IsDeleted || ParentGroup.inTransit) return; if (ParentGroup.IsAttachment) @@ -2039,7 +2049,7 @@ namespace OpenSim.Region.Framework.Scenes // SetAngularVelocity for LSL llSetAngularVelocity.. may need revision if having other uses in future public void SetAngularVelocity(Vector3 pAngVel, bool localGlobalTF) { - if (ParentGroup == null || ParentGroup.IsDeleted) + if (ParentGroup == null || ParentGroup.IsDeleted || ParentGroup.inTransit) return; if (ParentGroup.IsAttachment) @@ -2073,6 +2083,9 @@ namespace OpenSim.Region.Framework.Scenes /// true for the local frame, false for the global frame public void ApplyAngularImpulse(Vector3 impulsei, bool localGlobalTF) { + if (ParentGroup == null || ParentGroup.IsDeleted || ParentGroup.inTransit) + return; + Vector3 impulse = impulsei; if (localGlobalTF) @@ -2422,7 +2435,7 @@ namespace OpenSim.Region.Framework.Scenes PhysActor.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate; PhysActor.OnOutOfBounds += PhysicsOutOfBounds; - if (ParentID != 0 && ParentID != LocalId) + if (_parentID != 0 && _parentID != LocalId) { PhysicsActor parentPa = ParentGroup.RootPart.PhysActor; @@ -2558,6 +2571,30 @@ namespace OpenSim.Region.Framework.Scenes uint group = mask; uint everyone = mask; + lock(InnerPermsLock) // do we really need this? + { + if(Inventory != null) + Inventory.AggregateInnerPerms(ref owner, ref group, ref everyone); + + AggregatedInnerOwnerPerms = owner & mask; + AggregatedInnerGroupPerms = group & mask; + AggregatedInnerEveryonePerms = everyone & mask; + } + if(ParentGroup != null) + ParentGroup.InvalidateEffectivePerms(); + } + + // same as above but called during group Effective Permission validation + public void AggregatedInnerPermsForGroup() + { + // assuming child prims permissions masks are irrelevant on a linkset + // root part is handle at SOG since its masks are the sog masks + const uint mask = (uint)PermissionMask.AllEffective; + + uint owner = mask; + uint group = mask; + uint everyone = mask; + lock(InnerPermsLock) // do we really need this? { if(Inventory != null) @@ -2786,12 +2823,13 @@ namespace OpenSim.Region.Framework.Scenes { ColliderArgs colliderArgs = new ColliderArgs(); List colliding = new List(); + Scene parentScene = ParentGroup.Scene; foreach (uint localId in colliders) { if (localId == 0) continue; - SceneObjectPart obj = ParentGroup.Scene.GetSceneObjectPart(localId); + SceneObjectPart obj = parentScene.GetSceneObjectPart(localId); if (obj != null) { if (!dest.CollisionFilteredOut(obj.UUID, obj.Name)) @@ -2799,7 +2837,7 @@ namespace OpenSim.Region.Framework.Scenes } else { - ScenePresence av = ParentGroup.Scene.GetScenePresence(localId); + ScenePresence av = parentScene.GetScenePresence(localId); if (av != null && (!av.IsChildAgent)) { if (!dest.CollisionFilteredOut(av.UUID, av.Name)) @@ -2872,10 +2910,13 @@ namespace OpenSim.Region.Framework.Scenes public void PhysicsCollision(EventArgs e) { - if (ParentGroup.Scene == null || ParentGroup.IsDeleted) + if (ParentGroup.Scene == null || ParentGroup.IsDeleted || ParentGroup.inTransit) return; // this a thread from physics ( heartbeat ) + bool thisHitLand = false; + bool startLand = false; + bool endedLand = false; CollisionEventUpdate a = (CollisionEventUpdate)e; Dictionary collissionswith = a.m_objCollisionList; @@ -2885,13 +2926,17 @@ namespace OpenSim.Region.Framework.Scenes if (collissionswith.Count == 0) { - if (m_lastColliders.Count == 0) + if (m_lastColliders.Count == 0 && !m_lastLandCollide) return; // nothing to do + endedLand = m_lastLandCollide; + m_lastLandCollide = false; + foreach (uint localID in m_lastColliders) { endedColliders.Add(localID); } + m_lastColliders.Clear(); } else @@ -2907,19 +2952,39 @@ namespace OpenSim.Region.Framework.Scenes foreach (uint id in collissionswith.Keys) { - thisHitColliders.Add(id); - if (!m_lastColliders.Contains(id)) + if(id == 0) { - startedColliders.Add(id); - - curcontact = collissionswith[id]; - if (Math.Abs(curcontact.RelativeSpeed) > 0.2) + thisHitLand = true; + if (!m_lastLandCollide) { - soundinfo = new CollisionForSoundInfo(); - soundinfo.colliderID = id; - soundinfo.position = curcontact.Position; - soundinfo.relativeVel = curcontact.RelativeSpeed; - soundinfolist.Add(soundinfo); + startLand = true; + curcontact = collissionswith[id]; + if (Math.Abs(curcontact.RelativeSpeed) > 0.2) + { + soundinfo = new CollisionForSoundInfo(); + soundinfo.colliderID = id; + soundinfo.position = curcontact.Position; + soundinfo.relativeVel = curcontact.RelativeSpeed; + soundinfolist.Add(soundinfo); + } + } + } + else + { + thisHitColliders.Add(id); + if (!m_lastColliders.Contains(id)) + { + startedColliders.Add(id); + + curcontact = collissionswith[id]; + if (Math.Abs(curcontact.RelativeSpeed) > 0.2) + { + soundinfo = new CollisionForSoundInfo(); + soundinfo.colliderID = id; + soundinfo.position = curcontact.Position; + soundinfo.relativeVel = curcontact.RelativeSpeed; + soundinfolist.Add(soundinfo); + } } } } @@ -2928,9 +2993,18 @@ namespace OpenSim.Region.Framework.Scenes { foreach (uint id in collissionswith.Keys) { - thisHitColliders.Add(id); - if (!m_lastColliders.Contains(id)) - startedColliders.Add(id); + if(id == 0) + { + thisHitLand = true; + if (!m_lastLandCollide) + startLand = true; + } + else + { + thisHitColliders.Add(id); + if (!m_lastColliders.Contains(id)) + startedColliders.Add(id); + } } } @@ -2949,22 +3023,32 @@ namespace OpenSim.Region.Framework.Scenes foreach (uint localID in endedColliders) m_lastColliders.Remove(localID); + if(m_lastLandCollide && !thisHitLand) + endedLand = true; + + m_lastLandCollide = thisHitLand; + // play sounds. if (soundinfolist.Count > 0) CollisionSounds.PartCollisionSound(this, soundinfolist); } + + EventManager eventmanager = ParentGroup.Scene.EventManager; - SendCollisionEvent(scriptEvents.collision_start, startedColliders, ParentGroup.Scene.EventManager.TriggerScriptCollidingStart); + SendCollisionEvent(scriptEvents.collision_start, startedColliders, eventmanager.TriggerScriptCollidingStart); if (!VolumeDetectActive) - SendCollisionEvent(scriptEvents.collision , m_lastColliders , ParentGroup.Scene.EventManager.TriggerScriptColliding); - SendCollisionEvent(scriptEvents.collision_end , endedColliders , ParentGroup.Scene.EventManager.TriggerScriptCollidingEnd); + SendCollisionEvent(scriptEvents.collision , m_lastColliders , eventmanager.TriggerScriptColliding); + SendCollisionEvent(scriptEvents.collision_end , endedColliders , eventmanager.TriggerScriptCollidingEnd); - if (startedColliders.Contains(0)) - SendLandCollisionEvent(scriptEvents.land_collision_start, ParentGroup.Scene.EventManager.TriggerScriptLandCollidingStart); - if (m_lastColliders.Contains(0)) - SendLandCollisionEvent(scriptEvents.land_collision, ParentGroup.Scene.EventManager.TriggerScriptLandColliding); - if (endedColliders.Contains(0)) - SendLandCollisionEvent(scriptEvents.land_collision_end, ParentGroup.Scene.EventManager.TriggerScriptLandCollidingEnd); + if (!VolumeDetectActive) + { + if (startLand) + SendLandCollisionEvent(scriptEvents.land_collision_start, eventmanager.TriggerScriptLandCollidingStart); + if (m_lastLandCollide) + SendLandCollisionEvent(scriptEvents.land_collision, eventmanager.TriggerScriptLandColliding); + if (endedLand) + SendLandCollisionEvent(scriptEvents.land_collision_end, eventmanager.TriggerScriptLandCollidingEnd); + } } // The Collision sounds code calls this @@ -2983,7 +3067,7 @@ namespace OpenSim.Region.Framework.Scenes volume = 0; int now = Util.EnvironmentTickCount(); - if(Util.EnvironmentTickCountSubtract(now,LastColSoundSentTime) <200) + if(Util.EnvironmentTickCountSubtract(now, LastColSoundSentTime) < 200) return; LastColSoundSentTime = now; @@ -2993,7 +3077,7 @@ namespace OpenSim.Region.Framework.Scenes UUID parentID = ParentGroup.UUID; ulong regionHandle = ParentGroup.Scene.RegionInfo.RegionHandle; - soundModule.TriggerSound(soundID, ownerID, objectID, parentID, volume, position, regionHandle, 0 ); + soundModule.TriggerSound(soundID, ownerID, objectID, parentID, volume, position, regionHandle); } public void PhysicsOutOfBounds(Vector3 pos) @@ -3024,7 +3108,7 @@ namespace OpenSim.Region.Framework.Scenes //ParentGroup.RootPart.m_groupPosition = newpos; } /* - if (pa != null && ParentID != 0 && ParentGroup != null) + if (pa != null && _parentID != 0 && ParentGroup != null) { // Special case where a child object is requesting property updates. // This happens when linksets are modified to use flexible links rather than @@ -3185,17 +3269,6 @@ namespace OpenSim.Region.Framework.Scenes APIDActive = false; } - public void ScheduleFullUpdateIfNone() - { - if (ParentGroup == null) - return; - -// ??? ParentGroup.HasGroupChanged = true; - - if (UpdateFlag != UpdateRequired.FULL) - ScheduleFullUpdate(); - } - /// /// Schedules this prim for a full update /// @@ -3205,41 +3278,44 @@ namespace OpenSim.Region.Framework.Scenes if (ParentGroup == null) return; + if (ParentGroup.Scene == null) + return; - ParentGroup.QueueForUpdateCheck(); + if(ParentGroup.Scene.GetNumberOfClients() == 0) + return; - int timeNow = Util.UnixTimeSinceEpoch(); + ParentGroup.QueueForUpdateCheck(); // just in case - // If multiple updates are scheduled on the same second, we still need to perform all of them - // So we'll force the issue by bumping up the timestamp so that later processing sees these need - // to be performed. - if (timeNow <= TimeStampFull) + lock(UpdateFlagLock) { - TimeStampFull += 1; + if(UpdateFlag != UpdateRequired.FULL) + { + UpdateFlag = UpdateRequired.FULL; + + // m_log.DebugFormat( + // "[SCENE OBJECT PART]: Scheduling full update for {0}, {1} at {2}", + // UUID, Name, TimeStampFull); + + } } - else - { - TimeStampFull = (uint)timeNow; - } - - UpdateFlag = UpdateRequired.FULL; - - // m_log.DebugFormat( - // "[SCENE OBJECT PART]: Scheduling full update for {0}, {1} at {2}", - // UUID, Name, TimeStampFull); - - if (ParentGroup.Scene != null) - ParentGroup.Scene.EventManager.TriggerSceneObjectPartUpdated(this, true); + ParentGroup.Scene.EventManager.TriggerSceneObjectPartUpdated(this, true); } /// /// Schedule a terse update for this prim. Terse updates only send position, - /// rotation, velocity and rotational velocity information. + /// rotation, velocity and rotational velocity information. WRONG!!!! /// public void ScheduleTerseUpdate() { if (ParentGroup == null) return; + if (ParentGroup.Scene == null) + return; + + ParentGroup.HasGroupChanged = true; + + if(ParentGroup.Scene.GetNumberOfClients() == 0) + return; // This was pulled from SceneViewer. Attachments always receive full updates. // This is needed because otherwise if only the root prim changes position, then @@ -3250,21 +3326,19 @@ namespace OpenSim.Region.Framework.Scenes return; } - if (UpdateFlag == UpdateRequired.NONE) + ParentGroup.QueueForUpdateCheck(); + lock(UpdateFlagLock) { - ParentGroup.HasGroupChanged = true; - ParentGroup.QueueForUpdateCheck(); + if (UpdateFlag == UpdateRequired.NONE) + { + UpdateFlag = UpdateRequired.TERSE; - TimeStampTerse = (uint) Util.UnixTimeSinceEpoch(); - UpdateFlag = UpdateRequired.TERSE; - - // m_log.DebugFormat( - // "[SCENE OBJECT PART]: Scheduling terse update for {0}, {1} at {2}", - // UUID, Name, TimeStampTerse); + // m_log.DebugFormat( + // "[SCENE OBJECT PART]: Scheduling terse update for {0}, {1}", + // UUID, Name); + } } - - if (ParentGroup.Scene != null) - ParentGroup.Scene.EventManager.TriggerSceneObjectPartUpdated(this, false); + ParentGroup.Scene.EventManager.TriggerSceneObjectPartUpdated(this, false); } public void ScriptSetPhysicsStatus(bool UsePhysics) @@ -3293,21 +3367,6 @@ namespace OpenSim.Region.Framework.Scenes sp.SendAttachmentUpdate(this, UpdateRequired.FULL); } } - -/* this does nothing -SendFullUpdateToClient(remoteClient, Position) ignores position parameter - if (IsRoot) - { - if (ParentGroup.IsAttachment) - { - SendFullUpdateToClient(remoteClient, AttachedPos); - } - else - { - SendFullUpdateToClient(remoteClient, AbsolutePosition); - } - } -*/ else { SendFullUpdateToClient(remoteClient); @@ -3323,12 +3382,15 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter return; // Update the "last" values - m_lastPosition = OffsetPosition; - m_lastRotation = RotationOffset; - m_lastVelocity = Velocity; - m_lastAcceleration = Acceleration; - m_lastAngularVelocity = AngularVelocity; - m_lastUpdateSentTime = Environment.TickCount; + lock(UpdateFlagLock) + { + m_lastPosition = AbsolutePosition; + m_lastRotation = RotationOffset; + m_lastVelocity = Velocity; + m_lastAcceleration = Acceleration; + m_lastAngularVelocity = AngularVelocity; + m_lastUpdateSentTime = Util.GetTimeStampMS(); + } ParentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar) { @@ -3342,12 +3404,15 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter return; // Update the "last" values - m_lastPosition = OffsetPosition; - m_lastRotation = RotationOffset; - m_lastVelocity = Velocity; - m_lastAcceleration = Acceleration; - m_lastAngularVelocity = AngularVelocity; - m_lastUpdateSentTime = Environment.TickCount; + lock(UpdateFlagLock) + { + m_lastPosition = AbsolutePosition; + m_lastRotation = RotationOffset; + m_lastVelocity = Velocity; + m_lastAcceleration = Acceleration; + m_lastAngularVelocity = AngularVelocity; + m_lastUpdateSentTime = Util.GetTimeStampMS(); + } if (ParentGroup.IsAttachment) { @@ -3372,25 +3437,7 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter /// public void SendFullUpdateToClient(IClientAPI remoteClient) { - SendFullUpdateToClient(remoteClient, OffsetPosition); - } - - /// - /// Sends a full update to the client - /// - /// - /// - public void SendFullUpdateToClient(IClientAPI remoteClient, Vector3 lPos) - { - if (ParentGroup == null) - return; - - // Suppress full updates during attachment editing - // sl Does send them - // if (ParentGroup.IsSelected && ParentGroup.IsAttachment) - // return; - - if (ParentGroup.IsDeleted) + if (ParentGroup == null || ParentGroup.IsDeleted) return; if (ParentGroup.IsAttachment @@ -3411,44 +3458,149 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter ParentGroup.Scene.StatsReporter.AddObjectUpdates(1); } + private const float ROTATION_TOLERANCE = 0.01f; + private const float VELOCITY_TOLERANCE = 0.1f; + private const float ANGVELOCITY_TOLERANCE = 0.005f; + private const float POSITION_TOLERANCE = 0.05f; // I don't like this, but I suppose it's necessary + private const double TIME_MS_TOLERANCE = 200.0; //llSetPos has a 200ms delay. This should NOT be 3 seconds. + /// /// Tell all the prims which have had updates scheduled /// - public void SendScheduledUpdates() - { - const float ROTATION_TOLERANCE = 0.01f; - const float VELOCITY_TOLERANCE = 0.001f; - const float POSITION_TOLERANCE = 0.05f; // I don't like this, but I suppose it's necessary - const int TIME_MS_TOLERANCE = 200; //llSetPos has a 200ms delay. This should NOT be 3 seconds. + public void SendScheduledUpdates(double now) + { + bool sendterse = false; + bool sendfull = false; - switch (UpdateFlag) + lock(UpdateFlagLock) { - case UpdateRequired.TERSE: + switch (UpdateFlag) { - ClearUpdateSchedule(); - // Throw away duplicate or insignificant updates - if (!RotationOffset.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE) || - !Acceleration.Equals(m_lastAcceleration) || - !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) || - Velocity.ApproxEquals(Vector3.Zero, VELOCITY_TOLERANCE) || - !AngularVelocity.ApproxEquals(m_lastAngularVelocity, VELOCITY_TOLERANCE) || - !OffsetPosition.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) || - Environment.TickCount - m_lastUpdateSentTime > TIME_MS_TOLERANCE) - { - SendTerseUpdateToAllClientsInternal(); - } - break; - } - case UpdateRequired.FULL: - { - ClearUpdateSchedule(); - SendFullUpdateToAllClientsInternal(); - break; + case UpdateRequired.NONE: + break; + + case UpdateRequired.TERSE: + sendterse = true; + + Vector3 curvel = Velocity; + Vector3 curacc = Acceleration; + Vector3 angvel = AngularVelocity; + + while(true) // just to avoid ugly goto + { + double elapsed = now - m_lastUpdateSentTime; + if (elapsed > TIME_MS_TOLERANCE) + break; + + if( Math.Abs(curacc.X - m_lastAcceleration.X) > VELOCITY_TOLERANCE || + Math.Abs(curacc.Y - m_lastAcceleration.Y) > VELOCITY_TOLERANCE || + Math.Abs(curacc.Z - m_lastAcceleration.Z) > VELOCITY_TOLERANCE) + break; + + if( Math.Abs(curvel.X - m_lastVelocity.X) > VELOCITY_TOLERANCE || + Math.Abs(curvel.Y - m_lastVelocity.Y) > VELOCITY_TOLERANCE || + Math.Abs(curvel.Z - m_lastVelocity.Z) > VELOCITY_TOLERANCE) + break; + + float vx = Math.Abs(curvel.X); + if(vx > 128.0) + break; + float vy = Math.Abs(curvel.Y); + if(vy > 128.0) + break; + float vz = Math.Abs(curvel.Z); + if(vz > 128.0) + break; + + if ( + vx < VELOCITY_TOLERANCE && + vy < VELOCITY_TOLERANCE && + vz < VELOCITY_TOLERANCE + ) + { + if(!AbsolutePosition.ApproxEquals(m_lastPosition, POSITION_TOLERANCE)) + break; + + if (vx < 1e-4 && + vy < 1e-4 && + vz < 1e-4 && + ( + Math.Abs(m_lastVelocity.X) > 1e-4 || + Math.Abs(m_lastVelocity.Y) > 1e-4 || + Math.Abs(m_lastVelocity.Z) > 1e-4 + )) + break; + } + + if( Math.Abs(angvel.X - m_lastAngularVelocity.X) > ANGVELOCITY_TOLERANCE || + Math.Abs(angvel.Y - m_lastAngularVelocity.Y) > ANGVELOCITY_TOLERANCE || + Math.Abs(angvel.Z - m_lastAngularVelocity.Z) > ANGVELOCITY_TOLERANCE) + break; + + // viewer interpolators have a limit of 64rad/s + float ax = Math.Abs(angvel.X); + if(ax > 64.0) + break; + float ay = Math.Abs(angvel.Y); + if(ay > 64.0) + break; + float az = Math.Abs(angvel.Z); + if(az > 64.0) + break; + + if ( + ax < ANGVELOCITY_TOLERANCE && + ay < ANGVELOCITY_TOLERANCE && + az < ANGVELOCITY_TOLERANCE && + !RotationOffset.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE) + ) + break; + + sendterse = false; + break; + } + + if(sendterse) + { + // Update the "last" values + m_lastPosition = AbsolutePosition; + m_lastRotation = RotationOffset; + m_lastVelocity = curvel; + m_lastAcceleration = curacc; + m_lastAngularVelocity = angvel; + m_lastUpdateSentTime = now; + ClearUpdateSchedule(); + } + break; + + case UpdateRequired.FULL: + m_lastPosition = AbsolutePosition; + m_lastRotation = RotationOffset; + m_lastVelocity = Velocity; + m_lastAcceleration = Acceleration; + m_lastAngularVelocity = AngularVelocity; + m_lastUpdateSentTime = now; + ClearUpdateSchedule(); + sendfull = true; + break; } } + if(sendterse) + { + ParentGroup.Scene.ForEachClient(delegate(IClientAPI client) + { + SendTerseUpdateToClient(client); + }); + } + else if(sendfull) + { + ParentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar) + { + SendFullUpdate(avatar.ControllingClient); + }); + } } - /// /// Send a terse update to all clients /// @@ -3456,14 +3608,19 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter { if (ParentGroup == null || ParentGroup.Scene == null) return; + lock(UpdateFlagLock) + { + if(UpdateFlag != UpdateRequired.NONE) + return; - // Update the "last" values - m_lastPosition = OffsetPosition; - m_lastRotation = RotationOffset; - m_lastVelocity = Velocity; - m_lastAcceleration = Acceleration; - m_lastAngularVelocity = AngularVelocity; - m_lastUpdateSentTime = Environment.TickCount; + // Update the "last" values + m_lastPosition = AbsolutePosition; + m_lastRotation = RotationOffset; + m_lastVelocity = Velocity; + m_lastAcceleration = Acceleration; + m_lastAngularVelocity = AngularVelocity; + m_lastUpdateSentTime = Util.GetTimeStampMS(); + } ParentGroup.Scene.ForEachClient(delegate(IClientAPI client) { @@ -3476,13 +3633,19 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter if (ParentGroup == null || ParentGroup.Scene == null) return; - // Update the "last" values - m_lastPosition = OffsetPosition; - m_lastRotation = RotationOffset; - m_lastVelocity = Velocity; - m_lastAcceleration = Acceleration; - m_lastAngularVelocity = AngularVelocity; - m_lastUpdateSentTime = Environment.TickCount; + lock(UpdateFlagLock) + { + if(UpdateFlag != UpdateRequired.NONE) + return; + + // Update the "last" values + m_lastPosition = AbsolutePosition; + m_lastRotation = RotationOffset; + m_lastVelocity = Velocity; + m_lastAcceleration = Acceleration; + m_lastAngularVelocity = AngularVelocity; + m_lastUpdateSentTime = Util.GetTimeStampMS(); + } if (ParentGroup.IsAttachment) { @@ -3548,6 +3711,18 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter Force = force; } + public PhysicsInertiaData PhysicsInertia + { + get + { + return m_physicsInertia; + } + set + { + m_physicsInertia = value; + } + } + public SOPVehicle VehicleParams { get @@ -3664,7 +3839,8 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter Byte[] buf = Shape.Textures.GetBytes(); Primitive.TextureEntry tex = new Primitive.TextureEntry(buf, 0, buf.Length); Color4 texcolor; - if (face >= 0 && face < GetNumberOfSides()) + int nsides = GetNumberOfSides(); + if (face >= 0 && face < nsides) { texcolor = tex.CreateFace((uint)face).RGBA; texcolor.R = clippedColor.X; @@ -3680,7 +3856,7 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter } else if (face == ALL_SIDES) { - for (uint i = 0; i < GetNumberOfSides(); i++) + for (uint i = 0; i < nsides; i++) { if (tex.FaceTextures[i] != null) { @@ -3716,64 +3892,145 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter public int GetNumberOfSides() { int ret = 0; - bool hasCut; - bool hasHollow; - bool hasDimple; - bool hasProfileCut; + int cut; - PrimType primType = GetPrimType(); - HasCutHollowDimpleProfileCut(primType, Shape, out hasCut, out hasHollow, out hasDimple, out hasProfileCut); + if(Shape.SculptEntry) + { + if (Shape.SculptType != (byte)SculptType.Mesh) + return 1; // sculp + + //hack to detect new upload with faces data enconded on pbs + if ((Shape.ProfileCurve & 0xf0) != (byte)HollowShape.Triangle) + // old broken upload TODO + return 8; + } + + PrimType primType = GetPrimType(true); switch (primType) { case PrimType.BOX: ret = 6; - if (hasCut) ret += 2; - if (hasHollow) ret += 1; - break; - case PrimType.CYLINDER: - ret = 3; - if (hasCut) ret += 2; - if (hasHollow) ret += 1; + if (Shape.ProfileBegin > 0 || Shape.ProfileEnd > 0) // cut case + { + // removed sides + if (Shape.ProfileBegin > 0) + { + cut = Shape.ProfileBegin; + cut /= 12500; + ret -= cut; + } + if (Shape.ProfileEnd > 0) + { + cut = Shape.ProfileEnd; + cut /= 12500; + ret -= cut; + } + ret += 2; + } break; case PrimType.PRISM: ret = 5; - if (hasCut) ret += 2; - if (hasHollow) ret += 1; + if (Shape.ProfileBegin > 0 || Shape.ProfileEnd > 0) // cut case + { + // removed sides + if (Shape.ProfileBegin > 0) + { + cut = (Shape.ProfileBegin); + if(cut >= 16667 ) + ret--; + if(cut >= 33333 ) + ret--; + } + if (Shape.ProfileEnd > 0) + { + cut = (Shape.ProfileEnd); + if(cut >= 16667 ) + ret--; + if(cut >= 33333 ) + ret--; + } + ret += 2; // both cut faces + } + break; + case PrimType.CYLINDER: + ret = 3; + if (Shape.ProfileBegin > 0 || Shape.ProfileEnd > 0) // cut + ret += 2; break; case PrimType.SPHERE: ret = 1; - if (hasCut) ret += 2; - if (hasDimple) ret += 2; - if (hasHollow) ret += 1; + // cut faces exist if cut or skew or unequal twist limits + if (Shape.PathBegin > 0 || Shape.PathEnd > 0 || Shape.PathSkew != 0 || (Shape.PathTwistBegin != Shape.PathTwist)) + ret += 2; + if (Shape.ProfileBegin > 0 || Shape.ProfileEnd > 0 || Shape.ProfileHollow > 0) // dimple also if hollow + ret += 2; break; case PrimType.TORUS: ret = 1; - if (hasCut) ret += 2; - if (hasProfileCut) ret += 2; - if (hasHollow) ret += 1; + if (Shape.PathBegin > 0 || Shape.PathEnd > 0 || Shape.PathSkew != 0 + || Shape.PathTaperX != 0 || Shape.PathTaperY != 0 || Shape.PathRevolutions > 0 + || Shape.PathRadiusOffset != 0 || (Shape.PathTwistBegin != Shape.PathTwist)) + ret += 2; + if (Shape.ProfileBegin > 0 || Shape.ProfileEnd > 0) // profile cut + ret += 2; break; case PrimType.TUBE: ret = 4; - if (hasCut) ret += 2; - if (hasProfileCut) ret += 2; - if (hasHollow) ret += 1; + if (Shape.PathBegin > 0 || Shape.PathEnd > 0 || Shape.PathSkew != 0 + || Shape.PathTaperX != 0 || Shape.PathTaperY != 0 || Shape.PathRevolutions > 0 + || Shape.PathRadiusOffset != 0 || (Shape.PathTwistBegin != Shape.PathTwist)) + ret += 2; + if (Shape.ProfileBegin > 0 || Shape.ProfileEnd > 0) // profile cut + { + if (Shape.ProfileBegin > 0) + { + cut = Shape.ProfileBegin; + cut /= 12500; + ret -= cut; + } + if (Shape.ProfileEnd > 0) + { + cut = Shape.ProfileEnd; + cut /= 12500; + ret -= cut; + } + ret += 2; + } break; case PrimType.RING: ret = 3; - if (hasCut) ret += 2; - if (hasProfileCut) ret += 2; - if (hasHollow) ret += 1; - break; - case PrimType.SCULPT: - // Special mesh handling - if (Shape.SculptType == (byte)SculptType.Mesh) - ret = 8; // if it's a mesh then max 8 faces - else - ret = 1; // if it's a sculpt then max 1 face + if (Shape.PathBegin > 0 || Shape.PathEnd > 0 || Shape.PathSkew != 0 + || Shape.PathTaperX != 0 || Shape.PathTaperY != 0 || Shape.PathRevolutions > 0 + || Shape.PathRadiusOffset != 0 || (Shape.PathTwistBegin != Shape.PathTwist)) + ret += 2; + if (Shape.ProfileBegin > 0 || Shape.ProfileEnd > 0) // profile cut + { + if (Shape.ProfileBegin > 0) + { + cut = Shape.ProfileBegin; + if(cut >= 16667 ) + ret--; + if(cut >= 33333 ) + ret--; + } + if (Shape.ProfileEnd > 0) + { + cut = Shape.ProfileEnd; + if(cut >= 16667 ) + ret--; + if(cut >= 33333 ) + ret--; + } + ret += 2; + } break; } + // hollow face commum to all + if (Shape.ProfileHollow > 0) + ret += 1; + return ret; } @@ -3782,9 +4039,9 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter /// /// /// - public PrimType GetPrimType() + public PrimType GetPrimType(bool ignoreSculpt = false) { - if (Shape.SculptEntry) + if (Shape.SculptEntry && !ignoreSculpt) return PrimType.SCULPT; if ((Shape.ProfileCurve & 0x07) == (byte)ProfileShape.Square) @@ -3818,33 +4075,6 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter return PrimType.BOX; } - /// - /// Tell us if this object has cut, hollow, dimple, and other factors affecting the number of faces - /// - /// - /// - /// - /// - /// - /// - protected static void HasCutHollowDimpleProfileCut(PrimType primType, PrimitiveBaseShape shape, out bool hasCut, out bool hasHollow, - out bool hasDimple, out bool hasProfileCut) - { - if (primType == PrimType.BOX - || - primType == PrimType.CYLINDER - || - primType == PrimType.PRISM) - - hasCut = (shape.ProfileBegin > 0) || (shape.ProfileEnd > 0); - else - hasCut = (shape.PathBegin > 0) || (shape.PathEnd > 0); - - hasHollow = shape.ProfileHollow > 0; - hasDimple = (shape.ProfileBegin > 0) || (shape.ProfileEnd > 0); // taken from llSetPrimitiveParms - hasProfileCut = hasDimple; // is it the same thing? - } - public void SetGroup(UUID groupID, IClientAPI client) { // Scene.AddNewPrims() calls with client == null so can't use this. @@ -4447,8 +4677,11 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter if (god) baseMask = 0x7ffffff0; - // Are we the owner? - if ((AgentID == OwnerID) || god) + bool canChange = (AgentID == OwnerID) || god; + if(!canChange) + canChange = ParentGroup.Scene.Permissions.CanEditObjectPermissions(ParentGroup, AgentID); + + if (canChange) { switch (field) { @@ -4748,8 +4981,13 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter if (VolumeDetectActive) // change if not the default only pa.SetVolumeDetect(1); + + bool isroot = (m_localId == ParentGroup.RootPart.LocalId); - if (m_vehicleParams != null && m_localId == ParentGroup.RootPart.LocalId) + if(isroot && m_physicsInertia != null) + pa.SetInertiaData(m_physicsInertia); + + if (isroot && m_vehicleParams != null ) { m_vehicleParams.SetVehicle(pa); if(isPhysical && !isPhantom && m_vehicleParams.CameraDecoupled) @@ -4775,7 +5013,7 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter pa.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate; pa.OnOutOfBounds += PhysicsOutOfBounds; - if (ParentID != 0 && ParentID != LocalId) + if (_parentID != 0 && _parentID != LocalId) { PhysicsActor parentPa = ParentGroup.RootPart.PhysActor; @@ -4973,20 +5211,20 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter Changed changeFlags = 0; - Primitive.TextureEntryFace fallbackNewFace = newTex.DefaultTexture; - Primitive.TextureEntryFace fallbackOldFace = oldTex.DefaultTexture; + Primitive.TextureEntryFace defaultNewFace = newTex.DefaultTexture; + Primitive.TextureEntryFace defaultOldFace = oldTex.DefaultTexture; // On Incoming packets, sometimes newText.DefaultTexture is null. The assumption is that all // other prim-sides are set, but apparently that's not always the case. Lets assume packet/data corruption at this point. - if (fallbackNewFace == null) + if (defaultNewFace == null) { - fallbackNewFace = new Primitive.TextureEntry(Util.BLANK_TEXTURE_UUID).CreateFace(0); - newTex.DefaultTexture = fallbackNewFace; + defaultNewFace = new Primitive.TextureEntry(Util.BLANK_TEXTURE_UUID).CreateFace(0); + newTex.DefaultTexture = defaultNewFace; } - if (fallbackOldFace == null) + if (defaultOldFace == null) { - fallbackOldFace = new Primitive.TextureEntry(Util.BLANK_TEXTURE_UUID).CreateFace(0); - oldTex.DefaultTexture = fallbackOldFace; + defaultOldFace = new Primitive.TextureEntry(Util.BLANK_TEXTURE_UUID).CreateFace(0); + oldTex.DefaultTexture = defaultOldFace; } // Materials capable viewers can send a ObjectImage packet @@ -4996,18 +5234,19 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter // we should ignore any changes and not update Shape.TextureEntry bool otherFieldsChanged = false; - - for (int i = 0 ; i < GetNumberOfSides(); i++) + int nsides = GetNumberOfSides(); + for (int i = 0 ; i < nsides; i++) { - - Primitive.TextureEntryFace newFace = newTex.DefaultTexture; - Primitive.TextureEntryFace oldFace = oldTex.DefaultTexture; - + Primitive.TextureEntryFace newFace = defaultNewFace; + Primitive.TextureEntryFace oldFace = defaultOldFace; if (oldTex.FaceTextures[i] != null) oldFace = oldTex.FaceTextures[i]; if (newTex.FaceTextures[i] != null) newFace = newTex.FaceTextures[i]; + if (oldFace.TextureID != newFace.TextureID) + changeFlags |= Changed.TEXTURE; + Color4 oldRGBA = oldFace.RGBA; Color4 newRGBA = newFace.RGBA; @@ -5017,9 +5256,6 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter oldRGBA.A != newRGBA.A) changeFlags |= Changed.COLOR; - if (oldFace.TextureID != newFace.TextureID) - changeFlags |= Changed.TEXTURE; - // Max change, skip the rest of testing if (changeFlags == (Changed.TEXTURE | Changed.COLOR)) break; @@ -5037,25 +5273,19 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter if (oldFace.Rotation != newFace.Rotation) otherFieldsChanged = true; if (oldFace.Shiny != newFace.Shiny) otherFieldsChanged = true; if (oldFace.TexMapType != newFace.TexMapType) otherFieldsChanged = true; + if(otherFieldsChanged) + changeFlags |= Changed.TEXTURE; } } - if (changeFlags != 0 || otherFieldsChanged) - { - m_shape.TextureEntry = newTex.GetBytes(); - if (changeFlags != 0) - TriggerScriptChangedEvent(changeFlags); - UpdateFlag = UpdateRequired.FULL; - ParentGroup.HasGroupChanged = true; - - //This is madness.. - //ParentGroup.ScheduleGroupForFullUpdate(); - //This is sparta - ScheduleFullUpdate(); - } + if (changeFlags == 0) + return; + m_shape.TextureEntry = newTex.GetBytes(); + TriggerScriptChangedEvent(changeFlags); + ParentGroup.HasGroupChanged = true; + ScheduleFullUpdate(); } - internal void UpdatePhysicsSubscribedEvents() { PhysicsActor pa = PhysActor; @@ -5270,9 +5500,9 @@ SendFullUpdateToClient(remoteClient, Position) ignores position parameter // Export needs to be preserved in the base and everyone // mask, but removed in the owner mask as a next owner // can never change the export status - BaseMask &= NextOwnerMask | (uint)PermissionMask.Export; + BaseMask &= (NextOwnerMask | (uint)PermissionMask.Export); OwnerMask &= NextOwnerMask; - EveryoneMask &= NextOwnerMask | (uint)PermissionMask.Export; + EveryoneMask &= (NextOwnerMask | (uint)PermissionMask.Export); GroupMask = 0; // Giving an object zaps group permissions Inventory.ApplyNextOwnerPermissions(); diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index b53c355333..4934b8327c 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -91,7 +91,8 @@ namespace OpenSim.Region.Framework.Scenes /// protected internal TaskInventoryDictionary Items { - get { + get + { return m_items; } set @@ -141,45 +142,53 @@ namespace OpenSim.Region.Framework.Scenes /// public void ResetInventoryIDs() { - if (null == m_part) - m_items.LockItemsForWrite(true); + if (m_part == null) + return; - if (Items.Count == 0) + m_items.LockItemsForWrite(true); + if (m_items.Count == 0) { m_items.LockItemsForWrite(false); return; } - IList items = new List(Items.Values); - Items.Clear(); + UUID partID = m_part.UUID; + IList items = new List(m_items.Values); + m_items.Clear(); foreach (TaskInventoryItem item in items) { - item.ResetIDs(m_part.UUID); - Items.Add(item.ItemID, item); + item.ResetIDs(partID); + m_items.Add(item.ItemID, item); } + m_inventorySerial++; m_items.LockItemsForWrite(false); } public void ResetObjectID() { + if (m_part == null) + return; + m_items.LockItemsForWrite(true); - if (Items.Count == 0) + if (m_items.Count == 0) { m_items.LockItemsForWrite(false); return; } - IList items = new List(Items.Values); - Items.Clear(); + IList items = new List(m_items.Values); + m_items.Clear(); + UUID partID = m_part.UUID; foreach (TaskInventoryItem item in items) { - item.ParentPartID = m_part.UUID; - item.ParentID = m_part.UUID; - Items.Add(item.ItemID, item); + item.ParentPartID = partID; + item.ParentID = partID; + m_items.Add(item.ItemID, item); } + m_inventorySerial++; m_items.LockItemsForWrite(false); } @@ -189,15 +198,17 @@ namespace OpenSim.Region.Framework.Scenes /// public void ChangeInventoryOwner(UUID ownerId) { - List items = GetInventoryItems(); - - if (items.Count == 0) + if(m_part == null) return; m_items.LockItemsForWrite(true); - HasInventoryChanged = true; - m_part.ParentGroup.HasGroupChanged = true; - foreach (TaskInventoryItem item in items) + if (m_items.Count == 0) + { + m_items.LockItemsForWrite(false); + return; + } + + foreach (TaskInventoryItem item in m_items.Values) { if (ownerId != item.OwnerID) item.LastOwnerID = item.OwnerID; @@ -207,6 +218,9 @@ namespace OpenSim.Region.Framework.Scenes item.PermsGranter = UUID.Zero; item.OwnerChanged = true; } + HasInventoryChanged = true; + m_part.ParentGroup.HasGroupChanged = true; + m_inventorySerial++; m_items.LockItemsForWrite(false); } @@ -216,13 +230,16 @@ namespace OpenSim.Region.Framework.Scenes /// public void ChangeInventoryGroup(UUID groupID) { + if(m_part == null) + return; + m_items.LockItemsForWrite(true); - if (0 == Items.Count) + if (m_items.Count == 0) { m_items.LockItemsForWrite(false); return; } - + m_inventorySerial++; // Don't let this set the HasGroupChanged flag for attachments // as this happens during rez and we don't want a new asset // for each attachment each time @@ -232,14 +249,9 @@ namespace OpenSim.Region.Framework.Scenes m_part.ParentGroup.HasGroupChanged = true; } - IList items = new List(Items.Values); - foreach (TaskInventoryItem item in items) - { - if (groupID != item.GroupID) - { + foreach (TaskInventoryItem item in m_items.Values) item.GroupID = groupID; - } - } + m_items.LockItemsForWrite(false); } @@ -248,8 +260,8 @@ namespace OpenSim.Region.Framework.Scenes if (m_part == null || m_part.ParentGroup == null || m_part.ParentGroup.Scene == null) return; - Items.LockItemsForRead(true); - foreach (TaskInventoryItem item in Items.Values) + m_items.LockItemsForRead(true); + foreach (TaskInventoryItem item in m_items.Values) { if (item.InvType == (int)InventoryType.LSL) { @@ -259,7 +271,7 @@ namespace OpenSim.Region.Framework.Scenes } } - Items.LockItemsForRead(false); + m_items.LockItemsForRead(false); } public bool TryGetScriptInstanceRunning(UUID itemId, out bool running) @@ -347,7 +359,9 @@ namespace OpenSim.Region.Framework.Scenes /// public void StopScriptInstances() { - GetInventoryItems(InventoryType.LSL).ForEach(i => StopScriptInstance(i)); + List scripts = GetInventoryItems(InventoryType.LSL); + foreach (TaskInventoryItem item in scripts) + StopScriptInstance(item); } /// @@ -441,7 +455,6 @@ namespace OpenSim.Region.Framework.Scenes if (m_part.ParentGroup.m_savedScriptState.ContainsKey(stateID)) { XmlDocument doc = new XmlDocument(); - doc.LoadXml(m_part.ParentGroup.m_savedScriptState[stateID]); ////////// CRUFT WARNING /////////////////////////////////// @@ -809,7 +822,6 @@ namespace OpenSim.Region.Framework.Scenes m_part.AggregateInnerPerms(); m_inventorySerial++; - //m_inventorySerial += 2; HasInventoryChanged = true; m_part.ParentGroup.HasGroupChanged = true; } @@ -981,7 +993,7 @@ namespace OpenSim.Region.Framework.Scenes } // old code end rootPart.TrimPermissions(); - group.AggregateDeepPerms(); + group.InvalidateDeepEffectivePerms(); } return true; @@ -1019,6 +1031,9 @@ namespace OpenSim.Region.Framework.Scenes if (item.GroupPermissions != (uint)PermissionMask.None) item.GroupID = m_part.GroupID; + if(item.OwnerID == UUID.Zero) // viewer to internal enconding of group owned + item.OwnerID = item.GroupID; + if (item.AssetID == UUID.Zero) item.AssetID = m_items[item.ItemID].AssetID; @@ -1030,8 +1045,7 @@ namespace OpenSim.Region.Framework.Scenes if (considerChanged) { - m_part.AggregateInnerPerms(); - m_part.ParentGroup.AggregatePerms(); + m_part.ParentGroup.InvalidateDeepEffectivePerms(); HasInventoryChanged = true; m_part.ParentGroup.HasGroupChanged = true; } @@ -1066,7 +1080,7 @@ namespace OpenSim.Region.Framework.Scenes { int type = m_items[itemID].InvType; m_items.LockItemsForRead(false); - if (type == 10) // Script + if (type == (int)InventoryType.LSL) // Script { m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID); } @@ -1074,8 +1088,7 @@ namespace OpenSim.Region.Framework.Scenes m_items.Remove(itemID); m_items.LockItemsForWrite(false); - m_part.AggregateInnerPerms(); - m_part.ParentGroup.AggregatePerms(); + m_part.ParentGroup.InvalidateDeepEffectivePerms(); m_inventorySerial++; m_part.TriggerScriptChangedEvent(Changed.INVENTORY); @@ -1087,7 +1100,7 @@ namespace OpenSim.Region.Framework.Scenes m_items.LockItemsForRead(true); foreach (TaskInventoryItem item in m_items.Values) { - if (item.Type == 10) + if (item.Type == (int)InventoryType.LSL) { scriptcount++; } @@ -1127,18 +1140,18 @@ namespace OpenSim.Region.Framework.Scenes { bool changed = false; - Items.LockItemsForRead(true); + m_items.LockItemsForRead(true); if (m_inventorySerial == 0) // No inventory { - Items.LockItemsForRead(false); + m_items.LockItemsForRead(false); client.SendTaskInventory(m_part.UUID, 0, new byte[0]); return; } if (m_items.Count == 0) // No inventory { - Items.LockItemsForRead(false); + m_items.LockItemsForRead(false); client.SendTaskInventory(m_part.UUID, 0, new byte[0]); return; } @@ -1149,7 +1162,7 @@ namespace OpenSim.Region.Framework.Scenes changed = true; } - Items.LockItemsForRead(false); + m_items.LockItemsForRead(false); if (m_inventoryFileData.Length < 2) changed = true; @@ -1174,11 +1187,12 @@ namespace OpenSim.Region.Framework.Scenes InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero); - Items.LockItemsForRead(true); + m_items.LockItemsForRead(true); foreach (TaskInventoryItem item in m_items.Values) { UUID ownerID = item.OwnerID; + UUID groupID = item.GroupID; uint everyoneMask = item.EveryonePermissions; uint baseMask = item.BasePermissions; uint ownerMask = item.CurrentPermissions; @@ -1197,11 +1211,21 @@ namespace OpenSim.Region.Framework.Scenes invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions)); invString.AddNameValueLine("creator_id", item.CreatorID.ToString()); - invString.AddNameValueLine("owner_id", ownerID.ToString()); invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString()); - invString.AddNameValueLine("group_id", item.GroupID.ToString()); + invString.AddNameValueLine("group_id",groupID.ToString()); + if(groupID != UUID.Zero && ownerID == groupID) + { + invString.AddNameValueLine("owner_id", UUID.Zero.ToString()); + invString.AddNameValueLine("group_owned","1"); + } + else + { + invString.AddNameValueLine("owner_id", ownerID.ToString()); + invString.AddNameValueLine("group_owned","0"); + } + invString.AddSectionEnd(); if (includeAssets) @@ -1224,7 +1248,7 @@ namespace OpenSim.Region.Framework.Scenes invString.AddSectionEnd(); } - Items.LockItemsForRead(false); + m_items.LockItemsForRead(false); m_inventoryFileData = Utils.StringToBytes(invString.GetString()); @@ -1254,10 +1278,10 @@ namespace OpenSim.Region.Framework.Scenes // of prim inventory loss. // if (HasInventoryChanged) // { - Items.LockItemsForRead(true); - ICollection itemsvalues = Items.Values; + m_items.LockItemsForRead(true); + ICollection itemsvalues = m_items.Values; HasInventoryChanged = false; - Items.LockItemsForRead(false); + m_items.LockItemsForRead(false); try { datastore.StorePrimInventory(m_part.UUID, itemsvalues); @@ -1332,6 +1356,8 @@ namespace OpenSim.Region.Framework.Scenes { foreach (TaskInventoryItem item in m_items.Values) { + if(item.InvType == (sbyte)InventoryType.Landmark) + continue; owner &= item.CurrentPermissions; group &= item.GroupPermissions; everyone &= item.EveryonePermissions; @@ -1340,33 +1366,35 @@ namespace OpenSim.Region.Framework.Scenes public uint MaskEffectivePermissions() { + // used to propagate permissions restrictions outwards + // Modify does not propagate outwards. uint mask=0x7fffffff; - + foreach (TaskInventoryItem item in m_items.Values) { - if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0) - mask &= ~((uint)PermissionMask.Copy >> 13); - if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0) - mask &= ~((uint)PermissionMask.Transfer >> 13); - if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0) - mask &= ~((uint)PermissionMask.Modify >> 13); + if(item.InvType == (sbyte)InventoryType.Landmark) + continue; - if (item.InvType == (int)InventoryType.Object) - { - if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) - mask &= ~((uint)PermissionMask.Copy >> 13); - if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) - mask &= ~((uint)PermissionMask.Transfer >> 13); - if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0) - mask &= ~((uint)PermissionMask.Modify >> 13); - } + // apply current to normal permission bits + uint newperms = item.CurrentPermissions; - if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) + if ((newperms & (uint)PermissionMask.Copy) == 0) mask &= ~(uint)PermissionMask.Copy; - if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0) + if ((newperms & (uint)PermissionMask.Transfer) == 0) mask &= ~(uint)PermissionMask.Transfer; - if ((item.CurrentPermissions & (uint)PermissionMask.Modify) == 0) - mask &= ~(uint)PermissionMask.Modify; + if ((newperms & (uint)PermissionMask.Export) == 0) + mask &= ~((uint)PermissionMask.Export); + + // apply next owner restricted by current to folded bits + newperms &= item.NextPermissions; + + if ((newperms & (uint)PermissionMask.Copy) == 0) + mask &= ~((uint)PermissionMask.FoldedCopy); + if ((newperms & (uint)PermissionMask.Transfer) == 0) + mask &= ~((uint)PermissionMask.FoldedTransfer); + if ((newperms & (uint)PermissionMask.Export) == 0) + mask &= ~((uint)PermissionMask.FoldedExport); + } return mask; } @@ -1375,19 +1403,6 @@ namespace OpenSim.Region.Framework.Scenes { foreach (TaskInventoryItem item in m_items.Values) { - if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0) - { -// m_log.DebugFormat ( -// "[SCENE OBJECT PART INVENTORY]: Applying next permissions {0} to {1} in {2} with current {3}, base {4}, everyone {5}", -// item.NextPermissions, item.Name, m_part.Name, item.CurrentPermissions, item.BasePermissions, item.EveryonePermissions); - - if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) - item.CurrentPermissions &= ~(uint)PermissionMask.Copy; - if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) - item.CurrentPermissions &= ~(uint)PermissionMask.Transfer; - if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0) - item.CurrentPermissions &= ~(uint)PermissionMask.Modify; - } item.CurrentPermissions &= item.NextPermissions; item.BasePermissions &= item.NextPermissions; item.EveryonePermissions &= item.NextPermissions; @@ -1433,15 +1448,13 @@ namespace OpenSim.Region.Framework.Scenes public int ScriptCount() { int count = 0; - Items.LockItemsForRead(true); + m_items.LockItemsForRead(true); foreach (TaskInventoryItem item in m_items.Values) { if (item.InvType == (int)InventoryType.LSL) - { count++; } - } - Items.LockItemsForRead(false); + m_items.LockItemsForRead(false); return count; } /// @@ -1464,48 +1477,44 @@ namespace OpenSim.Region.Framework.Scenes if (engine != null) { if (engine.GetScriptState(item.ItemID)) - { count++; } } } - } return count; } public List GetInventoryList() { - List ret = new List(); + m_items.LockItemsForRead(true); + List ret = new List(m_items.Count); foreach (TaskInventoryItem item in m_items.Values) ret.Add(item.ItemID); + m_items.LockItemsForRead(false); return ret; } public List GetInventoryItems() { - List ret = new List(); - - Items.LockItemsForRead(true); - ret = new List(m_items.Values); - Items.LockItemsForRead(false); + m_items.LockItemsForRead(true); + List ret = new List(m_items.Values); + m_items.LockItemsForRead(false); return ret; } public List GetInventoryItems(InventoryType type) { - List ret = new List(); - - Items.LockItemsForRead(true); + m_items.LockItemsForRead(true); + List ret = new List(m_items.Count); foreach (TaskInventoryItem item in m_items.Values) if (item.InvType == (int)type) ret.Add(item); - Items.LockItemsForRead(false); - + m_items.LockItemsForRead(false); return ret; } diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index a5af7e187c..9c929a7891 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -77,7 +77,6 @@ namespace OpenSim.Region.Framework.Scenes public class ScenePresence : EntityBase, IScenePresence { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - private static readonly String LogHeader = "[SCENE PRESENCE]"; // ~ScenePresence() // { @@ -101,7 +100,8 @@ namespace OpenSim.Region.Framework.Scenes public bool IsGod { get; set; } private PresenceType m_presenceType; - public PresenceType PresenceType { + public PresenceType PresenceType + { get {return m_presenceType;} private set { @@ -170,6 +170,7 @@ namespace OpenSim.Region.Framework.Scenes private bool m_previusParcelHide = false; private bool m_currentParcelHide = false; private object parcelLock = new Object(); + public double ParcelDwellTickMS; public UUID currentParcelUUID { @@ -182,6 +183,7 @@ namespace OpenSim.Region.Framework.Scenes bool checksame = true; if (value != m_currentParcelUUID) { + ParcelDwellTickMS = Util.GetTimeStampMS(); m_previusParcelHide = m_currentParcelHide; m_previusParcelUUID = m_currentParcelUUID; checksame = false; @@ -277,16 +279,17 @@ namespace OpenSim.Region.Framework.Scenes private bool MouseDown = false; public Vector3 lastKnownAllowedPosition; public bool sentMessageAboutRestrictedParcelFlyingDown; + public Vector4 CollisionPlane = Vector4.UnitW; + public Vector4 m_lastCollisionPlane = Vector4.UnitW; + private byte m_lastState; private Vector3 m_lastPosition; private Quaternion m_lastRotation; private Vector3 m_lastVelocity; private Vector3 m_lastSize = new Vector3(0.45f,0.6f,1.9f); private bool SentInitialData = false; - private bool m_followCamAuto = false; - private int m_userFlags; public int UserFlags { @@ -339,6 +342,11 @@ namespace OpenSim.Region.Framework.Scenes private Vector3 m_lastChildAgentUpdatePosition; // private Vector3 m_lastChildAgentUpdateCamPosition; + private Vector3 m_lastCameraRayCastCam; + private Vector3 m_lastCameraRayCastPos; + + private float m_FOV = 1.04f; + private const int LAND_VELOCITYMAG_MAX = 12; private const float FLY_ROLL_MAX_RADIANS = 1.1f; @@ -360,17 +368,35 @@ namespace OpenSim.Region.Framework.Scenes private Quaternion m_headrotation = Quaternion.Identity; //PauPaw:Proper PID Controler for autopilot************ - public bool MovingToTarget { get; private set; } - public Vector3 MoveToPositionTarget { get; private set; } + + private bool m_movingToTarget; + public bool MovingToTarget + { + get {return m_movingToTarget;} + private set {m_movingToTarget = value; } + } + + private Vector3 m_moveToPositionTarget; + public Vector3 MoveToPositionTarget + { + get {return m_moveToPositionTarget;} + private set {m_moveToPositionTarget = value; } + } + + private float m_moveToSpeed; + public float MoveToSpeed + { + get {return m_moveToSpeed;} + private set {m_moveToSpeed = value; } + } + + private double m_delayedStop = -1.0; /// /// Controls whether an avatar automatically moving to a target will land when it gets there (if flying). /// public bool LandAtTarget { get; private set; } - private int m_movementUpdateCount; - private const int NumMovementsBetweenRayCast = 5; - private bool CameraConstraintActive; private object m_collisionEventLock = new Object(); @@ -451,6 +477,9 @@ namespace OpenSim.Region.Framework.Scenes /// private object m_originRegionIDAccessLock = new object(); + + private AutoResetEvent m_updateAgentReceivedAfterTransferEvent = new AutoResetEvent(false); + /// /// Used by the entity transfer module to signal when the presence should not be closed because a subsequent /// teleport is reusing the connection. @@ -968,6 +997,10 @@ namespace OpenSim.Region.Framework.Scenes m_inTransit = value; } } + // this is is only valid if IsInTransit is true + // only false on HG tps + // used work arounf viewers asking source region about destination user + public bool IsInLocalTransit {get; set; } /// @@ -1037,6 +1070,7 @@ namespace OpenSim.Region.Framework.Scenes m_uuid = client.AgentId; LocalId = m_scene.AllocateLocalId(); LegacySitOffsets = m_scene.LegacySitOffsets; + IsInLocalTransit = true; UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, m_uuid); if (account != null) @@ -1146,8 +1180,9 @@ namespace OpenSim.Region.Framework.Scenes ControllingClient.OnStopAnim += HandleStopAnim; ControllingClient.OnChangeAnim += avnHandleChangeAnim; ControllingClient.OnForceReleaseControls += HandleForceReleaseControls; - ControllingClient.OnAutoPilotGo += MoveToTarget; + ControllingClient.OnAutoPilotGo += MoveToTargetHandle; ControllingClient.OnUpdateThrottles += RaiseUpdateThrottles; +// ControllingClient.OnAgentFOV += HandleAgentFOV; // ControllingClient.OnChildAgentStatus += new StatusChange(this.ChildStatusChange); // ControllingClient.OnStopMovement += new GenericCall2(this.StopMovement); @@ -1165,8 +1200,9 @@ namespace OpenSim.Region.Framework.Scenes ControllingClient.OnStopAnim -= HandleStopAnim; ControllingClient.OnChangeAnim -= avnHandleChangeAnim; ControllingClient.OnForceReleaseControls -= HandleForceReleaseControls; - ControllingClient.OnAutoPilotGo -= MoveToTarget; + ControllingClient.OnAutoPilotGo -= MoveToTargetHandle; ControllingClient.OnUpdateThrottles -= RaiseUpdateThrottles; +// ControllingClient.OnAgentFOV += HandleAgentFOV; } private void SetDirectionVectors() @@ -1210,14 +1246,14 @@ namespace OpenSim.Region.Framework.Scenes // other uses need fix private bool MakeRootAgent(Vector3 pos, bool isFlying, ref Vector3 lookat) { - int ts = Util.EnvironmentTickCount(); + //int ts = Util.EnvironmentTickCount(); lock (m_completeMovementLock) { if (!IsChildAgent) return false; - m_log.DebugFormat("[MakeRootAgent] enter lock: {0}ms", Util.EnvironmentTickCountSubtract(ts)); + //m_log.DebugFormat("[MakeRootAgent] enter lock: {0}ms", Util.EnvironmentTickCountSubtract(ts)); //m_log.DebugFormat("[SCENE]: known regions in {0}: {1}", Scene.RegionInfo.RegionName, KnownChildRegionHandles.Count); // m_log.InfoFormat( @@ -1267,7 +1303,7 @@ namespace OpenSim.Region.Framework.Scenes IsChildAgent = false; } - m_log.DebugFormat("[MakeRootAgent] out lock: {0}ms", Util.EnvironmentTickCountSubtract(ts)); + //m_log.DebugFormat("[MakeRootAgent] out lock: {0}ms", Util.EnvironmentTickCountSubtract(ts)); // Must reset this here so that a teleport to a region next to an existing region does not keep the flag // set and prevent the close of the connection on a subsequent re-teleport. @@ -1277,7 +1313,7 @@ namespace OpenSim.Region.Framework.Scenes RegionHandle = m_scene.RegionInfo.RegionHandle; m_scene.EventManager.TriggerSetRootAgentScene(m_uuid, m_scene); - m_log.DebugFormat("[MakeRootAgent] TriggerSetRootAgentScene: {0}ms", Util.EnvironmentTickCountSubtract(ts)); + //m_log.DebugFormat("[MakeRootAgent] TriggerSetRootAgentScene: {0}ms", Util.EnvironmentTickCountSubtract(ts)); if (ParentID == 0) { @@ -1416,7 +1452,7 @@ namespace OpenSim.Region.Framework.Scenes } } - m_log.DebugFormat("[MakeRootAgent] position and physical: {0}ms", Util.EnvironmentTickCountSubtract(ts)); + //m_log.DebugFormat("[MakeRootAgent] position and physical: {0}ms", Util.EnvironmentTickCountSubtract(ts)); m_scene.SwapRootAgentCount(false); // If we don't reset the movement flag here, an avatar that crosses to a neighbouring sim and returns will @@ -1425,7 +1461,7 @@ namespace OpenSim.Region.Framework.Scenes MovementFlag = 0; m_scene.EventManager.TriggerOnMakeRootAgent(this); - m_log.DebugFormat("[MakeRootAgent] TriggerOnMakeRootAgent and done: {0}ms", Util.EnvironmentTickCountSubtract(ts)); + //m_log.DebugFormat("[MakeRootAgent] TriggerOnMakeRootAgent and done: {0}ms", Util.EnvironmentTickCountSubtract(ts)); return true; } @@ -1497,6 +1533,7 @@ namespace OpenSim.Region.Framework.Scenes */ public int GetStateSource() { +/* AgentCircuitData aCircuit = m_scene.AuthenticateHandler.GetAgentCircuitData(UUID); if (aCircuit != null && (aCircuit.teleportFlags != (uint)TeleportFlags.Default)) @@ -1507,6 +1544,8 @@ namespace OpenSim.Region.Framework.Scenes return 5; // StateSource.Teleporting } return 2; // StateSource.PrimCrossing +*/ + return m_teleportFlags == TeleportFlags.Default ? 2 : 5; } /// @@ -1609,7 +1648,7 @@ namespace OpenSim.Region.Framework.Scenes public void TeleportWithMomentum(Vector3 pos, Vector3? v) { if(!CheckLocalTPLandingPoint(ref pos)) - return; + return; if (ParentID != (uint)0) StandUp(); @@ -1631,6 +1670,20 @@ namespace OpenSim.Region.Framework.Scenes SendTerseUpdateToAllClients(); } + public void TeleportOnEject(Vector3 pos) + { + if (ParentID != (uint)0) + StandUp(); + + bool isFlying = Flying; + RemoveFromPhysicalScene(); + + AbsolutePosition = pos; + + AddToPhysicalScene(isFlying); + SendTerseUpdateToAllClients(); + } + public void avnLocalTeleport(Vector3 newpos, Vector3? newvel, bool rotateToVelXY) { if(!CheckLocalTPLandingPoint(ref newpos)) @@ -1778,6 +1831,20 @@ namespace OpenSim.Region.Framework.Scenes private Dictionary m_knownChildRegionsSizeInfo = new Dictionary(); + public void AddNeighbourRegion(GridRegion region, string capsPath) + { + lock (m_knownChildRegions) + { + ulong regionHandle = region.RegionHandle; + m_knownChildRegions.Add(regionHandle,capsPath); + + spRegionSizeInfo sizeInfo = new spRegionSizeInfo(); + sizeInfo.sizeX = region.RegionSizeX; + sizeInfo.sizeY = region.RegionSizeY; + m_knownChildRegionsSizeInfo[regionHandle] = sizeInfo; + } + } + public void AddNeighbourRegionSizeInfo(GridRegion region) { lock (m_knownChildRegions) @@ -1802,6 +1869,7 @@ namespace OpenSim.Region.Framework.Scenes lock (m_knownChildRegions) { m_knownChildRegionsSizeInfo.Clear(); + foreach (GridRegion region in regionsList) { spRegionSizeInfo sizeInfo = new spRegionSizeInfo(); @@ -1826,6 +1894,12 @@ namespace OpenSim.Region.Framework.Scenes } } + public bool knowsNeighbourRegion(ulong regionHandle) + { + lock (m_knownChildRegions) + return m_knownChildRegions.ContainsKey(regionHandle); + } + public void DropOldNeighbours(List oldRegions) { foreach (ulong handle in oldRegions) @@ -1862,7 +1936,8 @@ namespace OpenSim.Region.Framework.Scenes { get { - return new List(KnownRegions.Keys); + lock (m_knownChildRegions) + return new List(m_knownChildRegions.Keys); } } @@ -1901,30 +1976,32 @@ namespace OpenSim.Region.Framework.Scenes // (which triggers Scene.IncomingUpdateChildAgent(AgentData cAgentData) here in the destination, // m_originRegionID is UUID.Zero; after, it's non-Zero. The CompleteMovement sequence initiated from the // viewer (in turn triggered by the source region sending it a TeleportFinish event) waits until it's non-zero -// m_updateAgentReceivedAfterTransferEvent.WaitOne(10000); - int count = 50; - UUID originID = UUID.Zero; - lock (m_originRegionIDAccessLock) - originID = m_originRegionID; - - while (originID.Equals(UUID.Zero) && count-- > 0) + try { - lock (m_originRegionIDAccessLock) - originID = m_originRegionID; + if(m_updateAgentReceivedAfterTransferEvent.WaitOne(10000)) + { + UUID originID = UUID.Zero; - m_log.DebugFormat("[SCENE PRESENCE]: Agent {0} waiting for update in {1}", client.Name, Scene.Name); - Thread.Sleep(200); + lock (m_originRegionIDAccessLock) + originID = m_originRegionID; + if (originID.Equals(UUID.Zero)) + { + // Movement into region will fail + m_log.WarnFormat("[SCENE PRESENCE]: Update agent {0} at {1} got invalid origin region id ", client.Name, Scene.Name); + return false; + } + return true; + } + else + { + m_log.WarnFormat("[SCENE PRESENCE]: Update agent {0} at {1} did not receive agent update ", client.Name, Scene.Name); + return false; + } } + catch { } - if (originID.Equals(UUID.Zero)) - { - // Movement into region will fail - m_log.WarnFormat("[SCENE PRESENCE]: Update agent {0} never arrived in {1}", client.Name, Scene.Name); - return false; - } - - return true; + return false; } public void RotateToLookAt(Vector3 lookAt) @@ -1983,7 +2060,7 @@ namespace OpenSim.Region.Framework.Scenes return; } - m_log.DebugFormat("[CompleteMovement] WaitForUpdateAgent: {0}ms", Util.EnvironmentTickCountSubtract(ts)); + //m_log.DebugFormat("[CompleteMovement] WaitForUpdateAgent: {0}ms", Util.EnvironmentTickCountSubtract(ts)); bool flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); @@ -2010,7 +2087,8 @@ namespace OpenSim.Region.Framework.Scenes return; } - m_log.DebugFormat("[CompleteMovement] MakeRootAgent: {0}ms", Util.EnvironmentTickCountSubtract(ts)); + + //m_log.DebugFormat("[CompleteMovement] MakeRootAgent: {0}ms", Util.EnvironmentTickCountSubtract(ts)); if(!haveGroupInformation && !IsChildAgent && !IsNPC) { @@ -2018,7 +2096,7 @@ namespace OpenSim.Region.Framework.Scenes if (gm != null) Grouptitle = gm.GetGroupTitle(m_uuid); - m_log.DebugFormat("[CompleteMovement] Missing Grouptitle: {0}ms", Util.EnvironmentTickCountSubtract(ts)); + //m_log.DebugFormat("[CompleteMovement] Missing Grouptitle: {0}ms", Util.EnvironmentTickCountSubtract(ts)); InventoryFolderBase cof = m_scene.InventoryService.GetFolderForType(client.AgentId, (FolderType)46); if (cof == null) @@ -2049,7 +2127,7 @@ namespace OpenSim.Region.Framework.Scenes Scene.SimulationService.ReleaseAgent(originID, UUID, m_callbackURI); m_callbackURI = null; - m_log.DebugFormat("[CompleteMovement] ReleaseAgent: {0}ms", Util.EnvironmentTickCountSubtract(ts)); + //m_log.DebugFormat("[CompleteMovement] ReleaseAgent: {0}ms", Util.EnvironmentTickCountSubtract(ts)); } // else // { @@ -2061,7 +2139,7 @@ namespace OpenSim.Region.Framework.Scenes // Tell the client that we're totally ready ControllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look); - m_log.DebugFormat("[CompleteMovement] MoveAgentIntoRegion: {0}ms", Util.EnvironmentTickCountSubtract(ts)); + //m_log.DebugFormat("[CompleteMovement] MoveAgentIntoRegion: {0}ms", Util.EnvironmentTickCountSubtract(ts)); bool isHGTP = (m_teleportFlags & TeleportFlags.ViaHGLogin) != 0; @@ -2069,6 +2147,16 @@ namespace OpenSim.Region.Framework.Scenes if (!IsChildAgent) { + if( ParentPart != null && !IsNPC && (crossingFlags & 0x08) != 0) + { + +// SceneObjectPart root = ParentPart.ParentGroup.RootPart; +// if(root.LocalId != ParentPart.LocalId) +// ControllingClient.SendEntityTerseUpdateImmediate(root); +// ControllingClient.SendEntityTerseUpdateImmediate(ParentPart); + ParentPart.ParentGroup.SendFullUpdateToClient(ControllingClient); + } + // verify baked textures and cache bool cachedbaked = false; @@ -2086,7 +2174,7 @@ namespace OpenSim.Region.Framework.Scenes m_scene.AvatarFactory.QueueAppearanceSave(UUID); } } - m_log.DebugFormat("[CompleteMovement] Baked check: {0}ms", Util.EnvironmentTickCountSubtract(ts)); + //m_log.DebugFormat("[CompleteMovement] Baked check: {0}ms", Util.EnvironmentTickCountSubtract(ts)); } if(m_teleportFlags > 0) @@ -2110,6 +2198,7 @@ namespace OpenSim.Region.Framework.Scenes m_previusParcelUUID = UUID.Zero; m_currentParcelHide = false; m_currentParcelUUID = UUID.Zero; + ParcelDwellTickMS = Util.GetTimeStampMS(); if(!IsNPC) { @@ -2130,6 +2219,7 @@ namespace OpenSim.Region.Framework.Scenes // send avatar object to all presences including us, so they cross it into region // then hide if necessary + SendInitialAvatarDataToAllAgents(allpresences); // send this look @@ -2172,7 +2262,7 @@ namespace OpenSim.Region.Framework.Scenes } } // greys if - m_log.DebugFormat("[CompleteMovement] ValidateAndSendAppearanceAndAgentData: {0}ms", Util.EnvironmentTickCountSubtract(ts)); + //m_log.DebugFormat("[CompleteMovement] ValidateAndSendAppearanceAndAgentData: {0}ms", Util.EnvironmentTickCountSubtract(ts)); // attachments if (IsNPC || IsRealLogin(m_teleportFlags)) @@ -2221,7 +2311,7 @@ namespace OpenSim.Region.Framework.Scenes } } - m_log.DebugFormat("[CompleteMovement] attachments: {0}ms", Util.EnvironmentTickCountSubtract(ts)); + //m_log.DebugFormat("[CompleteMovement] attachments: {0}ms", Util.EnvironmentTickCountSubtract(ts)); if (openChildAgents) { // Create child agents in neighbouring regions @@ -2239,7 +2329,7 @@ namespace OpenSim.Region.Framework.Scenes m_childUpdatesBusy = false; // allow them } - m_log.DebugFormat("[CompleteMovement] openChildAgents: {0}ms", Util.EnvironmentTickCountSubtract(ts)); + //m_log.DebugFormat("[CompleteMovement] openChildAgents: {0}ms", Util.EnvironmentTickCountSubtract(ts)); // send the rest of the world if (m_teleportFlags > 0 && !IsNPC || m_currentParcelHide) @@ -2251,7 +2341,7 @@ namespace OpenSim.Region.Framework.Scenes // m_reprioritizationLastTime = Util.EnvironmentTickCount() + 15000; // delay it // m_reprioritizationBusy = false; - m_log.DebugFormat("[CompleteMovement] SendInitialDataToMe: {0}ms", Util.EnvironmentTickCountSubtract(ts)); + //m_log.DebugFormat("[CompleteMovement] SendInitialDataToMe: {0}ms", Util.EnvironmentTickCountSubtract(ts)); if (!IsChildAgent && openChildAgents) { @@ -2263,7 +2353,7 @@ namespace OpenSim.Region.Framework.Scenes else friendsModule.SendFriendsOnlineIfNeeded(ControllingClient); } - m_log.DebugFormat("[CompleteMovement] friendsModule: {0}ms", Util.EnvironmentTickCountSubtract(ts)); + //m_log.DebugFormat("[CompleteMovement] friendsModule: {0}ms", Util.EnvironmentTickCountSubtract(ts)); } } @@ -2292,34 +2382,41 @@ namespace OpenSim.Region.Framework.Scenes private void checkCameraCollision() { - if(!m_scene.PhysicsScene.SupportsRayCast()) + if(m_doingCamRayCast || !m_scene.PhysicsScene.SupportsRayCast()) return; - ++m_movementUpdateCount; - if (m_movementUpdateCount < 1) - m_movementUpdateCount = 1; - - if (m_doingCamRayCast || m_movementUpdateCount % NumMovementsBetweenRayCast != 0) - return; - - if (m_followCamAuto && !m_mouseLook) + if(m_mouseLook || ParentID != 0) { - Vector3 posAdjusted = AbsolutePosition; -// posAdjusted.Z += 0.5f * Appearance.AvatarSize.Z - 0.5f; - // not good for tiny or huge avatars - posAdjusted.Z += 1.0f; // viewer current camera focus point - Vector3 tocam = CameraPosition - posAdjusted; - - float distTocamlen = tocam.LengthSquared(); - if (distTocamlen > 0.01f && distTocamlen < 400) + if (CameraConstraintActive) { - distTocamlen = (float)Math.Sqrt(distTocamlen); - tocam *= (1.0f / distTocamlen); - - m_doingCamRayCast = true; - m_scene.PhysicsScene.RaycastWorld(posAdjusted, tocam, distTocamlen + 1.0f, RayCastCameraCallback); - return; + Vector4 plane = new Vector4(0.9f, 0.0f, 0.361f, -10000f); // not right... + UpdateCameraCollisionPlane(plane); + CameraConstraintActive = false; } + return; + } + + Vector3 posAdjusted = AbsolutePosition; + posAdjusted.Z += 1.0f; // viewer current camera focus point + + if(posAdjusted.ApproxEquals(m_lastCameraRayCastPos, 0.2f) && + CameraPosition.ApproxEquals(m_lastCameraRayCastCam, 0.2f)) + return; + + m_lastCameraRayCastCam = CameraPosition; + m_lastCameraRayCastPos = posAdjusted; + + Vector3 tocam = CameraPosition - posAdjusted; + + float distTocamlen = tocam.LengthSquared(); + if (distTocamlen > 0.01f && distTocamlen < 400) + { + distTocamlen = (float)Math.Sqrt(distTocamlen); + tocam *= (1.0f / distTocamlen); + + m_doingCamRayCast = true; + m_scene.PhysicsScene.RaycastWorld(posAdjusted, tocam, distTocamlen + 1.0f, RayCastCameraCallback); + return; } if (CameraConstraintActive) @@ -2341,9 +2438,6 @@ namespace OpenSim.Region.Framework.Scenes public void RayCastCameraCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 pNormal) { -// const float POSITION_TOLERANCE = 0.02f; -// const float ROTATION_TOLERANCE = 0.02f; - if (hitYN && localid != LocalId) { if (localid != 0) @@ -2381,8 +2475,6 @@ namespace OpenSim.Region.Framework.Scenes UpdateCameraCollisionPlane(plane); } } -// else if (!m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) || -// !Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE)) else if(CameraConstraintActive) { Vector4 plane = new Vector4(0.9f, 0.0f, 0.361f, -9000f); // not right... @@ -2416,7 +2508,9 @@ namespace OpenSim.Region.Framework.Scenes // This is irritating. Really. if (!AbsolutePosition.IsFinite()) { - RemoveFromPhysicalScene(); + bool isphysical = PhysicsActor != null; + if(isphysical) + RemoveFromPhysicalScene(); m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999902"); m_pos = m_LastFinitePos; @@ -2428,7 +2522,8 @@ namespace OpenSim.Region.Framework.Scenes m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999903"); } - AddToPhysicalScene(false); + if(isphysical) + AddToPhysicalScene(false); } else { @@ -2475,7 +2570,7 @@ namespace OpenSim.Region.Framework.Scenes // Raycast from the avatar's head to the camera to see if there's anything blocking the view // this exclude checks may not be complete - if(agentData.NeedsCameraCollision && ParentID == 0) // condition parentID may be wrong + if(agentData.NeedsCameraCollision) // condition parentID may be wrong checkCameraCollision(); uint flagsForScripts = (uint)flags; @@ -2515,11 +2610,12 @@ namespace OpenSim.Region.Framework.Scenes } bool update_movementflag = false; - + bool mvToTarget = m_movingToTarget; if (agentData.UseClientAgentPosition) { - MovingToTarget = (agentData.ClientAgentPosition - AbsolutePosition).Length() > 0.2f; - MoveToPositionTarget = agentData.ClientAgentPosition; + m_movingToTarget = (agentData.ClientAgentPosition - AbsolutePosition).LengthSquared() > 0.04f; + m_moveToPositionTarget = agentData.ClientAgentPosition; + m_moveToSpeed = -1f; } int i = 0; @@ -2532,6 +2628,8 @@ namespace OpenSim.Region.Framework.Scenes newFlying = true; else if (FlyDisabled) newFlying = false; + else if(mvToTarget) + newFlying = actor.Flying; else newFlying = ((flags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); @@ -2612,7 +2710,7 @@ namespace OpenSim.Region.Framework.Scenes update_movementflag = true; } - if (MovingToTarget) + if (m_movingToTarget) { // If the user has pressed a key then we want to cancel any move to target. if (DCFlagKeyPressed) @@ -2688,7 +2786,6 @@ namespace OpenSim.Region.Framework.Scenes agent_control_v3.Z = 0; // else if(AgentControlStopActive %% Velocity.Z <0.01f) - // m_log.DebugFormat("[SCENE PRESENCE]: MovementFlag {0} for {1}", MovementFlag, Name); // If the agent update does move the avatar, then calculate the force ready for the velocity update, @@ -2697,6 +2794,7 @@ namespace OpenSim.Region.Framework.Scenes // held down AGENT_CONTROL_STOP whilst normal walking/running). However, we do not want to update // if the user rotated whilst holding down AGENT_CONTROL_STOP when already still (which locks the // avatar location in place). + if (update_movementflag || (update_rotation && DCFlagKeyPressed && (!AgentControlStopActive || MovementFlag != 0))) { @@ -2713,17 +2811,27 @@ namespace OpenSim.Region.Framework.Scenes } else { - AddNewMovement(agent_control_v3); + if(m_movingToTarget || + (Animator.currentControlState != ScenePresenceAnimator.motionControlStates.flying && + Animator.currentControlState != ScenePresenceAnimator.motionControlStates.onsurface) + ) + AddNewMovement(agent_control_v3); + else + { + if (MovementFlag != 0) + AddNewMovement(agent_control_v3); + else + m_delayedStop = Util.GetTimeStampMS() + 200.0; + } } - } - - if (update_movementflag && ParentID == 0) +/* + if (update_movementflag && ParentID == 0 && m_delayedStop < 0) { // m_log.DebugFormat("[SCENE PRESENCE]: Updating movement animations for {0}", Name); Animator.UpdateMovementAnimations(); } - +*/ SendControlsToScripts(flagsForScripts); } @@ -2734,6 +2842,10 @@ namespace OpenSim.Region.Framework.Scenes // m_scene.EventManager.TriggerOnClientMovement(this); } + private void HandleAgentFOV(IClientAPI remoteClient, float _fov) + { + m_FOV = _fov; + } /// /// This is the event handler for client cameras. If a client is moving, or moving the camera, this event is triggering. @@ -2762,34 +2874,13 @@ namespace OpenSim.Region.Framework.Scenes CameraAtAxis = agentData.CameraAtAxis; CameraLeftAxis = agentData.CameraLeftAxis; CameraUpAxis = agentData.CameraUpAxis; - Quaternion camRot = Util.Axes2Rot(CameraAtAxis, CameraLeftAxis, CameraUpAxis); - CameraRotation = camRot; - - // The Agent's Draw distance setting - // When we get to the point of re-computing neighbors everytime this - // changes, then start using the agent's drawdistance rather than the - // region's draw distance. - DrawDistance = agentData.Far; - - // Check if Client has camera in 'follow cam' or 'build' mode. -// Vector3 camdif = (Vector3.One * Rotation - Vector3.One * CameraRotation); - m_followCamAuto = false; - if(!m_mouseLook) - { - if((CameraUpAxis.Z > 0.959f && CameraUpAxis.Z < 0.99f)) - { - Vector3 camdif = new Vector3(1f, 0f, 0f) * Rotation; - float ftmp = camdif.X - CameraAtAxis.X; - if(Math.Abs(ftmp) < 0.1f) - { - ftmp = camdif.Y - CameraAtAxis.Y; - if(Math.Abs(ftmp) < 0.1f) - m_followCamAuto = true; - } - } - } + CameraAtAxis.Normalize(); + CameraLeftAxis.Normalize(); + CameraUpAxis.Normalize(); + Quaternion camRot = Util.Axes2Rot(CameraAtAxis, CameraLeftAxis, CameraUpAxis); + CameraRotation = camRot; if(agentData.NeedsCameraCollision) checkCameraCollision(); @@ -2811,7 +2902,7 @@ namespace OpenSim.Region.Framework.Scenes bool updated = false; - Vector3 LocalVectorToTarget3D = MoveToPositionTarget - AbsolutePosition; + Vector3 LocalVectorToTarget3D = m_moveToPositionTarget - AbsolutePosition; // m_log.DebugFormat( // "[SCENE PRESENCE]: bAllowUpdateMoveToPosition {0}, m_moveToPositionInProgress {1}, m_autopilotMoving {2}", @@ -2824,9 +2915,8 @@ namespace OpenSim.Region.Framework.Scenes } else { - Vector3 hdist = LocalVectorToTarget3D; - hdist.Z = 0; - distanceToTarget = hdist.Length(); + distanceToTarget = (float)Math.Sqrt(LocalVectorToTarget3D.X * LocalVectorToTarget3D.X + + LocalVectorToTarget3D.Y * LocalVectorToTarget3D.Y); } // m_log.DebugFormat( @@ -2838,126 +2928,126 @@ namespace OpenSim.Region.Framework.Scenes { // We are close enough to the target Velocity = Vector3.Zero; - AbsolutePosition = MoveToPositionTarget; + AbsolutePosition = m_moveToPositionTarget; if (Flying) { - if (LandAtTarget) - Flying = false; + if (LandAtTarget) + Flying = false; // A horrible hack to stop the avatar dead in its tracks rather than having them overshoot // the target if flying. // We really need to be more subtle (slow the avatar as it approaches the target) or at // least be able to set collision status once, rather than 5 times to give it enough // weighting so that that PhysicsActor thinks it really is colliding. - for (int i = 0; i < 5; i++) - IsColliding = true; + for (int i = 0; i < 5; i++) + IsColliding = true; } ResetMoveToTarget(); return false; } - else + + if(m_moveToSpeed > 0 && distanceToTarget <= m_moveToSpeed * Scene.FrameTime) + m_moveToSpeed = distanceToTarget / Scene.FrameTime; + + try { - try + // move avatar in 3D towards target, in avatar coordinate frame. + // This movement vector gets added to the velocity through AddNewMovement(). + // Theoretically we might need a more complex PID approach here if other + // unknown forces are acting on the avatar and we need to adaptively respond + // to such forces, but the following simple approach seems to works fine. + + float angle = 0.5f * (float)Math.Atan2(LocalVectorToTarget3D.Y, LocalVectorToTarget3D.X); + Quaternion rot = new Quaternion(0,0, (float)Math.Sin(angle),(float)Math.Cos(angle)); + Rotation = rot; + LocalVectorToTarget3D = LocalVectorToTarget3D * Quaternion.Inverse(rot); // change to avatar coords + LocalVectorToTarget3D.Normalize(); + + // update avatar movement flags. the avatar coordinate system is as follows: + // + // +X (forward) + // + // ^ + // | + // | + // | + // | + // (left) +Y <--------o--------> -Y + // avatar + // | + // | + // | + // | + // v + // -X + // + + // based on the above avatar coordinate system, classify the movement into + // one of left/right/back/forward. + + const uint noMovFlagsMask = (uint)(~(Dir_ControlFlags.DIR_CONTROL_FLAG_BACK | + Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD | Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT | + Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT | Dir_ControlFlags.DIR_CONTROL_FLAG_UP | + Dir_ControlFlags.DIR_CONTROL_FLAG_DOWN)); + + MovementFlag &= noMovFlagsMask; + uint tmpAgentControlFlags = (uint)m_AgentControlFlags; + tmpAgentControlFlags &= noMovFlagsMask; + + if (LocalVectorToTarget3D.X < 0) //MoveBack { - // move avatar in 3D at one meter/second towards target, in avatar coordinate frame. - // This movement vector gets added to the velocity through AddNewMovement(). - // Theoretically we might need a more complex PID approach here if other - // unknown forces are acting on the avatar and we need to adaptively respond - // to such forces, but the following simple approach seems to works fine. - - LocalVectorToTarget3D = LocalVectorToTarget3D * Quaternion.Inverse(Rotation); // change to avatar coords - - LocalVectorToTarget3D.Normalize(); - - // update avatar movement flags. the avatar coordinate system is as follows: - // - // +X (forward) - // - // ^ - // | - // | - // | - // | - // (left) +Y <--------o--------> -Y - // avatar - // | - // | - // | - // | - // v - // -X - // - - // based on the above avatar coordinate system, classify the movement into - // one of left/right/back/forward. - - const uint noMovFlagsMask = (uint)(~(Dir_ControlFlags.DIR_CONTROL_FLAG_BACK | - Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD | Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT | - Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT | Dir_ControlFlags.DIR_CONTROL_FLAG_UP | - Dir_ControlFlags.DIR_CONTROL_FLAG_DOWN)); - - MovementFlag &= noMovFlagsMask; - AgentControlFlags &= noMovFlagsMask; - - if (LocalVectorToTarget3D.X < 0) //MoveBack - { - MovementFlag |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_BACK; - AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_BACK; - updated = true; - } - else if (LocalVectorToTarget3D.X > 0) //Move Forward - { - MovementFlag |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD; - AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD; - updated = true; - } - - if (LocalVectorToTarget3D.Y > 0) //MoveLeft - { - MovementFlag |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT; - AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT; - updated = true; - } - else if (LocalVectorToTarget3D.Y < 0) //MoveRight - { - MovementFlag |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT; - AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT; - updated = true; - } - - if (LocalVectorToTarget3D.Z > 0) //Up - { - // Don't set these flags for up or down - doing so will make the avatar crouch or - // keep trying to jump even if walking along level ground - //MovementFlag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_UP; - //AgentControlFlags - //AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_UP; - updated = true; - } - else if (LocalVectorToTarget3D.Z < 0) //Down - { - //MovementFlag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_DOWN; - //AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_DOWN; - updated = true; - } + MovementFlag |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_BACK; + tmpAgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_BACK; + updated = true; + } + else if (LocalVectorToTarget3D.X > 0) //Move Forward + { + MovementFlag |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD; + tmpAgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD; + updated = true; + } + if (LocalVectorToTarget3D.Y > 0) //MoveLeft + { + MovementFlag |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT; + tmpAgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT; + updated = true; + } + else if (LocalVectorToTarget3D.Y < 0) //MoveRight + { + MovementFlag |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT; + tmpAgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT; + updated = true; + } + + if (LocalVectorToTarget3D.Z > 0) //Up + updated = true; + + else if (LocalVectorToTarget3D.Z < 0) //Down + updated = true; + // m_log.DebugFormat( // "[SCENE PRESENCE]: HandleMoveToTargetUpdate adding {0} to move vector {1} for {2}", // LocalVectorToTarget3D, agent_control_v3, Name); + m_AgentControlFlags = (AgentManager.ControlFlags) tmpAgentControlFlags; + if(updated) agent_control_v3 += LocalVectorToTarget3D; - } - catch (Exception e) - { - //Avoid system crash, can be slower but... - m_log.DebugFormat("Crash! {0}", e.ToString()); - } + } + catch (Exception e) + { + //Avoid system crash, can be slower but... + m_log.DebugFormat("Crash! {0}", e.ToString()); } return updated; // AddNewMovement(agent_control_v3); } + public void MoveToTargetHandle(Vector3 pos, bool noFly, bool landAtTarget) + { + MoveToTarget(pos, noFly, landAtTarget); + } /// /// Move to the given target over time. /// @@ -2970,8 +3060,10 @@ namespace OpenSim.Region.Framework.Scenes /// /// If true and the avatar starts flying during the move then land at the target. /// - public void MoveToTarget(Vector3 pos, bool noFly, bool landAtTarget) - { + public void MoveToTarget(Vector3 pos, bool noFly, bool landAtTarget, float tau = -1f) + { + m_delayedStop = -1; + if (SitGround) StandUp(); @@ -3002,29 +3094,36 @@ namespace OpenSim.Region.Framework.Scenes // "[SCENE PRESENCE]: Avatar {0} set move to target {1} (terrain height {2}) in {3}", // Name, pos, terrainHeight, m_scene.RegionInfo.RegionName); + terrainHeight += Appearance.AvatarHeight; // so 1.5 * AvatarHeight above ground at target + bool shouldfly = Flying; if (noFly) - Flying = false; + shouldfly = false; else if (pos.Z > terrainHeight || Flying) - Flying = true; + shouldfly = true; - LandAtTarget = landAtTarget; - MovingToTarget = true; - MoveToPositionTarget = pos; - - // Rotate presence around the z-axis to point in same direction as movement. - // Ignore z component of vector Vector3 localVectorToTarget3D = pos - AbsolutePosition; - Vector3 localVectorToTarget2D = new Vector3((float)(localVectorToTarget3D.X), (float)(localVectorToTarget3D.Y), 0f); -// m_log.DebugFormat("[SCENE PRESENCE]: Local vector to target is {0}", localVectorToTarget2D); +// m_log.DebugFormat("[SCENE PRESENCE]: Local vector to target is {0},[1}", localVectorToTarget3D.X,localVectorToTarget3D.Y); + + m_movingToTarget = true; + LandAtTarget = landAtTarget; + m_moveToPositionTarget = pos; + if(tau > 0) + { + if(tau < Scene.FrameTime) + tau = Scene.FrameTime; + m_moveToSpeed = localVectorToTarget3D.Length() / tau; + if(m_moveToSpeed < 0.5f) //to tune + m_moveToSpeed = 0.5f; + else if(m_moveToSpeed > 50f) + m_moveToSpeed = 50f; - // Calculate the yaw. - Vector3 angle = new Vector3(0, 0, (float)(Math.Atan2(localVectorToTarget2D.Y, localVectorToTarget2D.X))); + SetAlwaysRun = false; + } + else + m_moveToSpeed = 4.096f * m_speedModifier; -// m_log.DebugFormat("[SCENE PRESENCE]: Angle is {0}", angle); - - Rotation = Quaternion.CreateFromEulers(angle); -// m_log.DebugFormat("[SCENE PRESENCE]: Body rot for {0} set to {1}", Name, Rotation); + Flying = shouldfly; Vector3 control = Vector3.Zero; if(HandleMoveToTargetUpdate(1f, ref control)) @@ -3038,7 +3137,8 @@ namespace OpenSim.Region.Framework.Scenes { // m_log.DebugFormat("[SCENE PRESENCE]: Resetting move to target for {0}", Name); - MovingToTarget = false; + m_movingToTarget = false; + m_moveToSpeed = -1f; // MoveToPositionTarget = Vector3.Zero; // lock(m_forceToApplyLock) // m_forceToApplyValid = false; // cancel possible last action @@ -3222,7 +3322,7 @@ namespace OpenSim.Region.Framework.Scenes RemoveFromPhysicalScene(); } - if (MovingToTarget) + if (m_movingToTarget) ResetMoveToTarget(); Velocity = Vector3.Zero; @@ -3364,7 +3464,7 @@ namespace OpenSim.Region.Framework.Scenes RemoveFromPhysicalScene(); - if (MovingToTarget) + if (m_movingToTarget) ResetMoveToTarget(); Velocity = Vector3.Zero; @@ -3627,7 +3727,7 @@ namespace OpenSim.Region.Framework.Scenes // m_log.DebugFormat( // "[SCENE PRESENCE]: Adding new movement {0} with rotation {1}, thisAddSpeedModifier {2} for {3}", // vec, Rotation, thisAddSpeedModifier, Name); - + m_delayedStop = -1; // rotate from avatar coord space to world Quaternion rot = Rotation; if (!Flying && PresenceType != PresenceType.Npc) @@ -3644,8 +3744,12 @@ namespace OpenSim.Region.Framework.Scenes if ((vec.Z == 0f) && !Flying) direc.Z = 0f; // Prevent camera WASD up. + bool notmvtrgt = !m_movingToTarget || m_moveToSpeed <= 0; // odd rescalings - direc *= 0.03f * 128f * SpeedModifier * thisAddSpeedModifier; + if(notmvtrgt) + direc *= 4.096f * SpeedModifier * thisAddSpeedModifier; + else + direc *= m_moveToSpeed; // m_log.DebugFormat("[SCENE PRESENCE]: Force to apply before modification was {0} for {1}", direc, Name); @@ -3663,12 +3767,12 @@ namespace OpenSim.Region.Framework.Scenes // landing situation, prevent avatar moving or it may fail to land // animator will handle this condition and do the land direc = Vector3.Zero; - else + else if(notmvtrgt) direc *= 4.0f; } else if (IsColliding) { - if (direc.Z > 2.0f) // reinforce jumps + if (direc.Z > 2.0f && notmvtrgt) // reinforce jumps { direc.Z *= 2.6f; } @@ -3708,41 +3812,42 @@ namespace OpenSim.Region.Framework.Scenes if (IsInTransit || IsLoggingIn) return; - if(MovingToTarget) + if(m_movingToTarget) { + m_delayedStop = -1; Vector3 control = Vector3.Zero; if(HandleMoveToTargetUpdate(1f, ref control)) AddNewMovement(control); } + else if(m_delayedStop > 0) + { + if(IsSatOnObject) + m_delayedStop = -1; + else + if(Util.GetTimeStampMS() > m_delayedStop) + AddNewMovement(Vector3.Zero); + } if (Appearance.AvatarSize != m_lastSize) SendAvatarDataToAllAgents(); // Send terse position update if not sitting and position, velocity, or rotation // has changed significantly from last sent update - if (!IsSatOnObject && ( - !Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE) - || !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) - || !m_pos.ApproxEquals(m_lastPosition, POSITION_LARGETOLERANCE) - // if velocity is zero and it wasn't zero last time, send the update - || (Velocity == Vector3.Zero && m_lastVelocity != Vector3.Zero) - // if position has moved just a little and velocity is very low, send the update - || (!m_pos.ApproxEquals(m_lastPosition, POSITION_SMALLTOLERANCE) && Velocity.LengthSquared() < LOWVELOCITYSQ ) - ) ) - { -/* if (!IsSatOnObject) { // this does need to be more complex later Vector3 vel = Velocity; Vector3 dpos = m_pos - m_lastPosition; - if( Math.Abs(vel.X - m_lastVelocity.X) > VELOCITY_TOLERANCE || + if( State != m_lastState || + Math.Abs(vel.X - m_lastVelocity.X) > VELOCITY_TOLERANCE || Math.Abs(vel.Y - m_lastVelocity.Y) > VELOCITY_TOLERANCE || Math.Abs(vel.Z - m_lastVelocity.Z) > VELOCITY_TOLERANCE || Math.Abs(m_bodyRot.X - m_lastRotation.X) > ROTATION_TOLERANCE || Math.Abs(m_bodyRot.Y - m_lastRotation.Y) > ROTATION_TOLERANCE || Math.Abs(m_bodyRot.Z - m_lastRotation.Z) > ROTATION_TOLERANCE || + + (vel == Vector3.Zero && m_lastVelocity != Vector3.Zero) || Math.Abs(dpos.X) > POSITION_LARGETOLERANCE || Math.Abs(dpos.Y) > POSITION_LARGETOLERANCE || @@ -3752,11 +3857,15 @@ namespace OpenSim.Region.Framework.Scenes Math.Abs(dpos.Y) > POSITION_SMALLTOLERANCE || Math.Abs(dpos.Z) > POSITION_SMALLTOLERANCE) && vel.LengthSquared() < LOWVELOCITYSQ - )) + ) || + + Math.Abs(CollisionPlane.X - m_lastCollisionPlane.X) > POSITION_SMALLTOLERANCE || + Math.Abs(CollisionPlane.Y - m_lastCollisionPlane.Y) > POSITION_SMALLTOLERANCE || + Math.Abs(CollisionPlane.W - m_lastCollisionPlane.W) > POSITION_SMALLTOLERANCE + ) { -*/ SendTerseUpdateToAllClients(); -// } + } } CheckForSignificantMovement(); } @@ -3852,11 +3961,14 @@ namespace OpenSim.Region.Framework.Scenes /// public void SendTerseUpdateToAllClients() { - m_scene.ForEachScenePresence(SendTerseUpdateToAgent); - // Update the "last" values + m_lastState = State; m_lastPosition = m_pos; m_lastRotation = m_bodyRot; m_lastVelocity = Velocity; + m_lastCollisionPlane = CollisionPlane; + + m_scene.ForEachScenePresence(SendTerseUpdateToAgent); + // Update the "last" values TriggerScenePresenceUpdated(); } @@ -3979,7 +4091,7 @@ namespace OpenSim.Region.Framework.Scenes int count = 0; foreach (ScenePresence p in presences) { - p.ControllingClient.SendAvatarDataImmediate(this); + p.ControllingClient.SendEntityFullUpdateImmediate(this); if (p != this && ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && !p.IsViewerUIGod) // either just kill the object // p.ControllingClient.SendKillObject(new List {LocalId}); @@ -3992,7 +4104,7 @@ namespace OpenSim.Region.Framework.Scenes public void SendInitialAvatarDataToAgent(ScenePresence p) { - p.ControllingClient.SendAvatarDataImmediate(this); + p.ControllingClient.SendEntityFullUpdateImmediate(this); if (p != this && ParcelHideThisAvatar && currentParcelUUID != p.currentParcelUUID && !p.IsViewerUIGod) // either just kill the object // p.ControllingClient.SendKillObject(new List {LocalId}); @@ -4009,12 +4121,12 @@ namespace OpenSim.Region.Framework.Scenes //m_log.DebugFormat("[SCENE PRESENCE] SendAvatarDataToAgent from {0} ({1}) to {2} ({3})", Name, UUID, avatar.Name, avatar.UUID); if (ParcelHideThisAvatar && currentParcelUUID != avatar.currentParcelUUID && !avatar.IsViewerUIGod) return; - avatar.ControllingClient.SendAvatarDataImmediate(this); + avatar.ControllingClient.SendEntityFullUpdateImmediate(this); } public void SendAvatarDataToAgentNF(ScenePresence avatar) { - avatar.ControllingClient.SendAvatarDataImmediate(this); + avatar.ControllingClient.SendEntityFullUpdateImmediate(this); } /// @@ -4364,72 +4476,75 @@ namespace OpenSim.Region.Framework.Scenes } - /* useless. Either use MakeChild or delete the presence - public void Reset() - { - // m_log.DebugFormat("[SCENE PRESENCE]: Resetting {0} in {1}", Name, Scene.RegionInfo.RegionName); - - // Put the child agent back at the center - AbsolutePosition - = new Vector3(((float)m_scene.RegionInfo.RegionSizeX * 0.5f), ((float)m_scene.RegionInfo.RegionSizeY * 0.5f), 70); - - Animator.ResetAnimations(); - } - */ /// /// Computes which child agents to close when the scene presence moves to another region. /// Removes those regions from m_knownRegions. /// - /// The new region's x on the map - /// The new region's y on the map + /// The new region's handle + /// The new region's size x + /// The new region's size y /// - public void CloseChildAgents(bool logout, ulong newRegionHandle, int newRegionSizeX, int newRegionSizeY) + public List GetChildAgentsToClose(ulong newRegionHandle, int newRegionSizeX, int newRegionSizeY) { - uint newRegionX, newRegionY; + ulong curRegionHandle = m_scene.RegionInfo.RegionHandle; List byebyeRegions = new List(); + + if(newRegionHandle == curRegionHandle) //?? + return byebyeRegions; + + uint newRegionX, newRegionY; List knownRegions = KnownRegionHandles; m_log.DebugFormat( "[SCENE PRESENCE]: Closing child agents. Checking {0} regions in {1}", knownRegions.Count, Scene.RegionInfo.RegionName); Util.RegionHandleToRegionLoc(newRegionHandle, out newRegionX, out newRegionY); - uint x, y; spRegionSizeInfo regInfo; foreach (ulong handle in knownRegions) { - // Don't close the agent on this region yet - if (handle != Scene.RegionInfo.RegionHandle) + if(newRegionY == 0) // HG + byebyeRegions.Add(handle); + else if(handle == curRegionHandle) { - if (logout) + RegionInfo curreg = m_scene.RegionInfo; + if (Util.IsOutsideView(255, curreg.RegionLocX, newRegionX, curreg.RegionLocY, newRegionY, + (int)curreg.RegionSizeX, (int)curreg.RegionSizeX, newRegionSizeX, newRegionSizeY)) + { byebyeRegions.Add(handle); + } + } + else + { + Util.RegionHandleToRegionLoc(handle, out x, out y); + if (m_knownChildRegionsSizeInfo.TryGetValue(handle, out regInfo)) + { +// if (Util.IsOutsideView(RegionViewDistance, x, newRegionX, y, newRegionY, + // for now need to close all but first order bc RegionViewDistance it the target value not ours + if (Util.IsOutsideView(255, x, newRegionX, y, newRegionY, + regInfo.sizeX, regInfo.sizeY, newRegionSizeX, newRegionSizeY)) + { + byebyeRegions.Add(handle); + } + } else { - Util.RegionHandleToRegionLoc(handle, out x, out y); - if (m_knownChildRegionsSizeInfo.TryGetValue(handle, out regInfo)) +// if (Util.IsOutsideView(RegionViewDistance, x, newRegionX, y, newRegionY, + if (Util.IsOutsideView(255, x, newRegionX, y, newRegionY, + (int)Constants.RegionSize, (int)Constants.RegionSize, newRegionSizeX, newRegionSizeY)) { - if (Util.IsOutsideView(RegionViewDistance, x, newRegionX, y, newRegionY, - regInfo.sizeX, regInfo.sizeY, newRegionSizeX, newRegionSizeY)) - { - byebyeRegions.Add(handle); - } - } - else - { - if (Util.IsOutsideView(RegionViewDistance, x, newRegionX, y, newRegionY, - (int)Constants.RegionSize, (int)Constants.RegionSize, newRegionSizeX, newRegionSizeY)) - { - byebyeRegions.Add(handle); - // this should not be here -// if(eventQueue != null) -// eventQueue.DisableSimulator(handle,UUID); - } + byebyeRegions.Add(handle); } } } } + return byebyeRegions; + } + public void CloseChildAgents(List byebyeRegions) + { + byebyeRegions.Remove(Scene.RegionInfo.RegionHandle); if (byebyeRegions.Count > 0) { m_log.Debug("[SCENE PRESENCE]: Closing " + byebyeRegions.Count + " child agents"); @@ -4499,7 +4614,7 @@ namespace OpenSim.Region.Framework.Scenes return; CopyFrom(cAgentData); - + m_updateAgentReceivedAfterTransferEvent.Set(); } private static Vector3 marker = new Vector3(-1f, -1f, -1f); @@ -4635,6 +4750,11 @@ namespace OpenSim.Region.Framework.Scenes { cAgent.CrossingFlags = crossingFlags; cAgent.CrossingFlags |= 1; + cAgent.CrossExtraFlags = 0; + if((LastCommands & ScriptControlled.CONTROL_LBUTTON) != 0) + cAgent.CrossExtraFlags |= 1; + if((LastCommands & ScriptControlled.CONTROL_ML_LBUTTON) != 0) + cAgent.CrossExtraFlags |= 2; } else cAgent.CrossingFlags = 0; @@ -4644,7 +4764,10 @@ namespace OpenSim.Region.Framework.Scenes cAgent.agentCOF = COF; cAgent.ActiveGroupID = ControllingClient.ActiveGroupId; cAgent.ActiveGroupName = ControllingClient.ActiveGroupName; - cAgent.ActiveGroupTitle = Grouptitle; + if(Grouptitle == null) + cAgent.ActiveGroupTitle = String.Empty; + else + cAgent.ActiveGroupTitle = Grouptitle; } } @@ -4704,6 +4827,10 @@ namespace OpenSim.Region.Framework.Scenes AddToPhysicalScene(isFlying); } */ + + if (Scene.AttachmentsModule != null) + Scene.AttachmentsModule.CopyAttachments(cAgent, this); + try { lock (scriptedcontrols) @@ -4711,6 +4838,7 @@ namespace OpenSim.Region.Framework.Scenes if (cAgent.Controllers != null) { scriptedcontrols.Clear(); + IgnoredControls = ScriptControlled.CONTROL_ZERO; foreach (ControllerData c in cAgent.Controllers) { @@ -4721,6 +4849,7 @@ namespace OpenSim.Region.Framework.Scenes sc.eventControls = (ScriptControlled)c.EventControls; scriptedcontrols[sc.itemID] = sc; + IgnoredControls |= sc.ignoreControls; // this is not correct, aparently only last applied should count } } } @@ -4741,11 +4870,18 @@ namespace OpenSim.Region.Framework.Scenes if (cAgent.MotionState != 0) Animator.currentControlState = (ScenePresenceAnimator.motionControlStates) cAgent.MotionState; - if (Scene.AttachmentsModule != null) - Scene.AttachmentsModule.CopyAttachments(cAgent, this); crossingFlags = cAgent.CrossingFlags; gotCrossUpdate = (crossingFlags != 0); + if(gotCrossUpdate) + { + LastCommands &= ~(ScriptControlled.CONTROL_LBUTTON | ScriptControlled.CONTROL_ML_LBUTTON); + if((cAgent.CrossExtraFlags & 1) != 0) + LastCommands |= ScriptControlled.CONTROL_LBUTTON; + if((cAgent.CrossExtraFlags & 2) != 0) + LastCommands |= ScriptControlled.CONTROL_ML_LBUTTON; + MouseDown = (cAgent.CrossExtraFlags & 3) != 0; + } haveGroupInformation = false; // using this as protocol detection don't want to mess with the numbers for now @@ -4840,6 +4976,7 @@ namespace OpenSim.Region.Framework.Scenes PhysicsActor.OnOutOfBounds += OutOfBoundsCall; // Called for PhysicsActors when there's something wrong PhysicsActor.SubscribeEvents(100); PhysicsActor.LocalID = LocalId; + PhysicsActor.SetAlwaysRun = m_setAlwaysRun; } private void OutOfBoundsCall(Vector3 pos) @@ -4877,8 +5014,8 @@ namespace OpenSim.Region.Framework.Scenes // if (m_updateCount > 0) // { - if (Animator != null && Animator.UpdateMovementAnimations()) - TriggerScenePresenceUpdated(); +// if (Animator != null && Animator.UpdateMovementAnimations()) +// TriggerScenePresenceUpdated(); // m_updateCount--; // } @@ -5015,6 +5152,8 @@ namespace OpenSim.Region.Framework.Scenes ControllingClient = null; LifecycleState = ScenePresenceState.Removed; IsDeleted = true; + m_updateAgentReceivedAfterTransferEvent.Dispose(); + m_updateAgentReceivedAfterTransferEvent = null; } public void AddAttachment(SceneObjectGroup gobj) @@ -5574,7 +5713,6 @@ namespace OpenSim.Region.Framework.Scenes { IgnoredControls = ScriptControlled.CONTROL_ZERO; obj.eventControls = (ScriptControlled)controls; - obj.ignoreControls = ScriptControlled.CONTROL_ZERO; } lock (scriptedcontrols) @@ -5690,7 +5828,7 @@ namespace OpenSim.Region.Framework.Scenes { if (scriptedcontrols.TryGetValue(Script_item_UUID, out takecontrols)) { - ScriptControlled sctc = takecontrols.eventControls; + ScriptControlled sctc = takecontrols.eventControls; ControllingClient.SendTakeControls((int)sctc, false, false); ControllingClient.SendTakeControls((int)sctc, true, false); @@ -5714,29 +5852,21 @@ namespace OpenSim.Region.Framework.Scenes if (scriptedcontrols.Count <= 0) return; - ScriptControlled allflags = ScriptControlled.CONTROL_ZERO; - - if (MouseDown) + ScriptControlled allflags; + // convert mouse from edge to level + if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_UP) != 0 || + (flags & unchecked((uint)AgentManager.ControlFlags.AGENT_CONTROL_ML_LBUTTON_UP)) != 0) { - allflags = LastCommands & (ScriptControlled.CONTROL_ML_LBUTTON | ScriptControlled.CONTROL_LBUTTON); - if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_UP) != 0 || (flags & unchecked((uint)AgentManager.ControlFlags.AGENT_CONTROL_ML_LBUTTON_UP)) != 0) - { - allflags = ScriptControlled.CONTROL_ZERO; - MouseDown = true; - } + allflags = ScriptControlled.CONTROL_ZERO; } + else // recover last state of mouse + allflags = LastCommands & (ScriptControlled.CONTROL_ML_LBUTTON | ScriptControlled.CONTROL_LBUTTON); if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_ML_LBUTTON_DOWN) != 0) - { allflags |= ScriptControlled.CONTROL_ML_LBUTTON; - MouseDown = true; - } if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN) != 0) - { allflags |= ScriptControlled.CONTROL_LBUTTON; - MouseDown = true; - } // find all activated controls, whether the scripts are interested in them or not if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS) != 0) @@ -5800,6 +5930,7 @@ namespace OpenSim.Region.Framework.Scenes } LastCommands = allflags; + MouseDown = (allflags & (ScriptControlled.CONTROL_ML_LBUTTON | ScriptControlled.CONTROL_LBUTTON)) != 0; } } @@ -6451,7 +6582,7 @@ namespace OpenSim.Region.Framework.Scenes if (check) { // check is relative to current parcel only - if (currentParcelUUID == null || oldhide == currentParcelHide) + if (oldhide == currentParcelHide) return; allpresences = m_scene.GetScenePresences(); diff --git a/OpenSim/Region/Framework/Scenes/Serialization/CoalescedSceneObjectsSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/CoalescedSceneObjectsSerializer.cs index 7f7977ea25..41f3ef4020 100644 --- a/OpenSim/Region/Framework/Scenes/Serialization/CoalescedSceneObjectsSerializer.cs +++ b/OpenSim/Region/Framework/Scenes/Serialization/CoalescedSceneObjectsSerializer.cs @@ -86,9 +86,9 @@ namespace OpenSim.Region.Framework.Scenes.Serialization writer.WriteStartElement("CoalescedObject"); - writer.WriteAttributeString("x", size.X.ToString()); - writer.WriteAttributeString("y", size.Y.ToString()); - writer.WriteAttributeString("z", size.Z.ToString()); + writer.WriteAttributeString("x", size.X.ToString(Culture.FormatProvider)); + writer.WriteAttributeString("y", size.Y.ToString(Culture.FormatProvider)); + writer.WriteAttributeString("z", size.Z.ToString(Culture.FormatProvider)); // Embed the offsets into the group XML for (int i = 0; i < coaObjects.Count; i++) @@ -100,9 +100,9 @@ namespace OpenSim.Region.Framework.Scenes.Serialization // i, obj.Name); writer.WriteStartElement("SceneObjectGroup"); - writer.WriteAttributeString("offsetx", offsets[i].X.ToString()); - writer.WriteAttributeString("offsety", offsets[i].Y.ToString()); - writer.WriteAttributeString("offsetz", offsets[i].Z.ToString()); + writer.WriteAttributeString("offsetx", offsets[i].X.ToString(Culture.FormatProvider)); + writer.WriteAttributeString("offsety", offsets[i].Y.ToString(Culture.FormatProvider)); + writer.WriteAttributeString("offsetz", offsets[i].Z.ToString(Culture.FormatProvider)); SceneObjectSerializer.ToOriginalXmlFormat(obj, writer, doScriptStates); diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs index a12a40126b..590a5d49f2 100644 --- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs +++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs @@ -63,9 +63,10 @@ namespace OpenSim.Region.Framework.Scenes.Serialization String fixedData = ExternalRepresentationUtils.SanitizeXml(xmlData); using (XmlTextReader wrappedReader = new XmlTextReader(fixedData, XmlNodeType.Element, null)) { - using (XmlReader reader = XmlReader.Create(wrappedReader, new XmlReaderSettings() { IgnoreWhitespace = true, ConformanceLevel = ConformanceLevel.Fragment })) + using (XmlReader reader = XmlReader.Create(wrappedReader, new XmlReaderSettings() { IgnoreWhitespace = true, ConformanceLevel = ConformanceLevel.Fragment})) { - try { + try + { return FromOriginalXmlFormat(reader); } catch (Exception e) @@ -109,12 +110,24 @@ namespace OpenSim.Region.Framework.Scenes.Serialization } } while (reader.ReadToNextSibling("Part")); + reader.ReadEndElement(); } + if (reader.Name == "KeyframeMotion" && reader.NodeType == XmlNodeType.Element) + { + + string innerkeytxt = reader.ReadElementContentAsString(); + sceneObject.RootPart.KeyframeMotion = + KeyframeMotion.FromData(sceneObject, Convert.FromBase64String(innerkeytxt)); + } + else + sceneObject.RootPart.KeyframeMotion = null; + // Script state may, or may not, exist. Not having any, is NOT // ever a problem. sceneObject.LoadScriptState(reader); - sceneObject.AggregateDeepPerms(); + + sceneObject.InvalidateDeepEffectivePerms(); return sceneObject; } @@ -210,9 +223,19 @@ namespace OpenSim.Region.Framework.Scenes.Serialization writer.WriteEndElement(); // OtherParts + if (sceneObject.RootPart.KeyframeMotion != null) + { + Byte[] data = sceneObject.RootPart.KeyframeMotion.Serialize(); + + writer.WriteStartElement(String.Empty, "KeyframeMotion", String.Empty); + writer.WriteBase64(data, 0, data.Length); + writer.WriteEndElement(); + } + if (doScriptStates) sceneObject.SaveScriptedState(writer); + if (!noRootElement) writer.WriteEndElement(); // SceneObjectGroup @@ -243,18 +266,24 @@ namespace OpenSim.Region.Framework.Scenes.Serialization return null; } - StringReader sr = new StringReader(parts[0].OuterXml); - XmlTextReader reader = new XmlTextReader(sr); - SceneObjectGroup sceneObject = new SceneObjectGroup(SceneObjectPart.FromXml(reader)); - reader.Close(); - sr.Close(); + SceneObjectGroup sceneObject; + using(StringReader sr = new StringReader(parts[0].OuterXml)) + { + using(XmlTextReader reader = new XmlTextReader(sr)) + sceneObject = new SceneObjectGroup(SceneObjectPart.FromXml(reader)); + } // Then deal with the rest + SceneObjectPart part; for (int i = 1; i < parts.Count; i++) { - sr = new StringReader(parts[i].OuterXml); - reader = new XmlTextReader(sr); - SceneObjectPart part = SceneObjectPart.FromXml(reader); + using(StringReader sr = new StringReader(parts[i].OuterXml)) + { + using(XmlTextReader reader = new XmlTextReader(sr)) + { + part = SceneObjectPart.FromXml(reader); + } + } int originalLinkNum = part.LinkNum; @@ -265,8 +294,6 @@ namespace OpenSim.Region.Framework.Scenes.Serialization if (originalLinkNum != 0) part.LinkNum = originalLinkNum; - reader.Close(); - sr.Close(); } XmlNodeList keymotion = doc.GetElementsByTagName("KeyframeMotion"); @@ -278,7 +305,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization // Script state may, or may not, exist. Not having any, is NOT // ever a problem. sceneObject.LoadScriptState(doc); - sceneObject.AggregatePerms(); +// sceneObject.AggregatePerms(); return sceneObject; } catch (Exception e) @@ -453,9 +480,10 @@ namespace OpenSim.Region.Framework.Scenes.Serialization m_SOPXmlProcessors.Add("Torque", ProcessTorque); m_SOPXmlProcessors.Add("VolumeDetectActive", ProcessVolumeDetectActive); - m_SOPXmlProcessors.Add("Vehicle", ProcessVehicle); + m_SOPXmlProcessors.Add("PhysicsInertia", ProcessPhysicsInertia); + m_SOPXmlProcessors.Add("RotationAxisLocks", ProcessRotationAxisLocks); m_SOPXmlProcessors.Add("PhysicsShapeType", ProcessPhysicsShapeType); m_SOPXmlProcessors.Add("Density", ProcessDensity); @@ -781,6 +809,23 @@ namespace OpenSim.Region.Framework.Scenes.Serialization } } + private static void ProcessPhysicsInertia(SceneObjectPart obj, XmlReader reader) + { + PhysicsInertiaData pdata = PhysicsInertiaData.FromXml2(reader); + + if (pdata == null) + { + obj.PhysicsInertia = null; + m_log.DebugFormat( + "[SceneObjectSerializer]: Parsing PhysicsInertiaData for object part {0} {1} encountered errors. Please see earlier log entries.", + obj.Name, obj.UUID); + } + else + { + obj.PhysicsInertia = pdata; + } + } + private static void ProcessShape(SceneObjectPart obj, XmlReader reader) { List errorNodeNames; @@ -1343,8 +1388,27 @@ namespace OpenSim.Region.Framework.Scenes.Serialization private static void ProcessShpMedia(PrimitiveBaseShape shp, XmlReader reader) { - string value = reader.ReadElementContentAsString("Media", String.Empty); - shp.Media = PrimitiveBaseShape.MediaList.FromXml(value); + string value = String.Empty; + try + { + // The STANDARD content of Media elemet is escaped XML string (with > etc). + value = reader.ReadElementContentAsString("Media", String.Empty); + shp.Media = PrimitiveBaseShape.MediaList.FromXml(value); + } + catch (XmlException) + { + // There are versions of OAR files that contain unquoted XML. + // ie ONE comercial fork that never wanted their oars to be read by our code + try + { + value = reader.ReadInnerXml(); + shp.Media = PrimitiveBaseShape.MediaList.FromXml(value); + } + catch + { + m_log.ErrorFormat("[SERIALIZER] Failed parsing halcyon MOAP information"); + } + } } #endregion @@ -1422,10 +1486,10 @@ namespace OpenSim.Region.Framework.Scenes.Serialization writer.WriteElementString("Description", sop.Description); writer.WriteStartElement("Color"); - writer.WriteElementString("R", sop.Color.R.ToString(Utils.EnUsCulture)); - writer.WriteElementString("G", sop.Color.G.ToString(Utils.EnUsCulture)); - writer.WriteElementString("B", sop.Color.B.ToString(Utils.EnUsCulture)); - writer.WriteElementString("A", sop.Color.A.ToString(Utils.EnUsCulture)); + writer.WriteElementString("R", sop.Color.R.ToString(Culture.FormatProvider)); + writer.WriteElementString("G", sop.Color.G.ToString(Culture.FormatProvider)); + writer.WriteElementString("B", sop.Color.B.ToString(Culture.FormatProvider)); + writer.WriteElementString("A", sop.Color.A.ToString(Culture.FormatProvider)); writer.WriteEndElement(); writer.WriteElementString("Text", sop.Text); @@ -1468,7 +1532,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization writer.WriteElementString("NextOwnerMask", sop.NextOwnerMask.ToString()); WriteFlags(writer, "Flags", sop.Flags.ToString(), options); WriteUUID(writer, "CollisionSound", sop.CollisionSound, options); - writer.WriteElementString("CollisionSoundVolume", sop.CollisionSoundVolume.ToString()); + writer.WriteElementString("CollisionSoundVolume", sop.CollisionSoundVolume.ToString(Culture.FormatProvider)); if (sop.MediaUrl != null) writer.WriteElementString("MediaUrl", sop.MediaUrl.ToString()); WriteVector(writer, "AttachedPos", sop.AttachedPos); @@ -1488,7 +1552,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization writer.WriteElementString("PayPrice3", sop.PayPrice[3].ToString()); writer.WriteElementString("PayPrice4", sop.PayPrice[4].ToString()); - writer.WriteElementString("Buoyancy", sop.Buoyancy.ToString()); + writer.WriteElementString("Buoyancy", sop.Buoyancy.ToString(Culture.FormatProvider)); WriteVector(writer, "Force", sop.Force); WriteVector(writer, "Torque", sop.Torque); @@ -1498,26 +1562,29 @@ namespace OpenSim.Region.Framework.Scenes.Serialization if (sop.VehicleParams != null) sop.VehicleParams.ToXml2(writer); + if (sop.PhysicsInertia != null) + sop.PhysicsInertia.ToXml2(writer); + if(sop.RotationAxisLocks != 0) writer.WriteElementString("RotationAxisLocks", sop.RotationAxisLocks.ToString().ToLower()); writer.WriteElementString("PhysicsShapeType", sop.PhysicsShapeType.ToString().ToLower()); if (sop.Density != 1000.0f) - writer.WriteElementString("Density", sop.Density.ToString().ToLower()); + writer.WriteElementString("Density", sop.Density.ToString(Culture.FormatProvider)); if (sop.Friction != 0.6f) - writer.WriteElementString("Friction", sop.Friction.ToString().ToLower()); + writer.WriteElementString("Friction", sop.Friction.ToString(Culture.FormatProvider)); if (sop.Restitution != 0.5f) - writer.WriteElementString("Bounce", sop.Restitution.ToString().ToLower()); + writer.WriteElementString("Bounce", sop.Restitution.ToString(Culture.FormatProvider)); if (sop.GravityModifier != 1.0f) - writer.WriteElementString("GravityModifier", sop.GravityModifier.ToString().ToLower()); + writer.WriteElementString("GravityModifier", sop.GravityModifier.ToString(Culture.FormatProvider)); WriteVector(writer, "CameraEyeOffset", sop.GetCameraEyeOffset()); WriteVector(writer, "CameraAtOffset", sop.GetCameraAtOffset()); // if (sop.Sound != UUID.Zero) force it till sop crossing does clear it on child prim { WriteUUID(writer, "SoundID", sop.Sound, options); - writer.WriteElementString("SoundGain", sop.SoundGain.ToString().ToLower()); + writer.WriteElementString("SoundGain", sop.SoundGain.ToString(Culture.FormatProvider)); writer.WriteElementString("SoundFlags", sop.SoundFlags.ToString().ToLower()); - writer.WriteElementString("SoundRadius", sop.SoundRadius.ToString().ToLower()); + writer.WriteElementString("SoundRadius", sop.SoundRadius.ToString(Culture.FormatProvider)); } writer.WriteElementString("SoundQueueing", sop.SoundQueueing.ToString().ToLower()); @@ -1537,19 +1604,19 @@ namespace OpenSim.Region.Framework.Scenes.Serialization static void WriteVector(XmlTextWriter writer, string name, Vector3 vec) { writer.WriteStartElement(name); - writer.WriteElementString("X", vec.X.ToString(Utils.EnUsCulture)); - writer.WriteElementString("Y", vec.Y.ToString(Utils.EnUsCulture)); - writer.WriteElementString("Z", vec.Z.ToString(Utils.EnUsCulture)); + writer.WriteElementString("X", vec.X.ToString(Culture.FormatProvider)); + writer.WriteElementString("Y", vec.Y.ToString(Culture.FormatProvider)); + writer.WriteElementString("Z", vec.Z.ToString(Culture.FormatProvider)); writer.WriteEndElement(); } static void WriteQuaternion(XmlTextWriter writer, string name, Quaternion quat) { writer.WriteStartElement(name); - writer.WriteElementString("X", quat.X.ToString(Utils.EnUsCulture)); - writer.WriteElementString("Y", quat.Y.ToString(Utils.EnUsCulture)); - writer.WriteElementString("Z", quat.Z.ToString(Utils.EnUsCulture)); - writer.WriteElementString("W", quat.W.ToString(Utils.EnUsCulture)); + writer.WriteElementString("X", quat.X.ToString(Culture.FormatProvider)); + writer.WriteElementString("Y", quat.Y.ToString(Culture.FormatProvider)); + writer.WriteElementString("Z", quat.Z.ToString(Culture.FormatProvider)); + writer.WriteElementString("W", quat.W.ToString(Culture.FormatProvider)); writer.WriteEndElement(); } @@ -1691,22 +1758,22 @@ namespace OpenSim.Region.Framework.Scenes.Serialization // Don't serialize SculptData. It's just a copy of the asset, which can be loaded separately using 'SculptTexture'. writer.WriteElementString("FlexiSoftness", shp.FlexiSoftness.ToString()); - writer.WriteElementString("FlexiTension", shp.FlexiTension.ToString()); - writer.WriteElementString("FlexiDrag", shp.FlexiDrag.ToString()); - writer.WriteElementString("FlexiGravity", shp.FlexiGravity.ToString()); - writer.WriteElementString("FlexiWind", shp.FlexiWind.ToString()); - writer.WriteElementString("FlexiForceX", shp.FlexiForceX.ToString()); - writer.WriteElementString("FlexiForceY", shp.FlexiForceY.ToString()); - writer.WriteElementString("FlexiForceZ", shp.FlexiForceZ.ToString()); + writer.WriteElementString("FlexiTension", shp.FlexiTension.ToString(Culture.FormatProvider)); + writer.WriteElementString("FlexiDrag", shp.FlexiDrag.ToString(Culture.FormatProvider)); + writer.WriteElementString("FlexiGravity", shp.FlexiGravity.ToString(Culture.FormatProvider)); + writer.WriteElementString("FlexiWind", shp.FlexiWind.ToString(Culture.FormatProvider)); + writer.WriteElementString("FlexiForceX", shp.FlexiForceX.ToString(Culture.FormatProvider)); + writer.WriteElementString("FlexiForceY", shp.FlexiForceY.ToString(Culture.FormatProvider)); + writer.WriteElementString("FlexiForceZ", shp.FlexiForceZ.ToString(Culture.FormatProvider)); - writer.WriteElementString("LightColorR", shp.LightColorR.ToString()); - writer.WriteElementString("LightColorG", shp.LightColorG.ToString()); - writer.WriteElementString("LightColorB", shp.LightColorB.ToString()); - writer.WriteElementString("LightColorA", shp.LightColorA.ToString()); - writer.WriteElementString("LightRadius", shp.LightRadius.ToString()); - writer.WriteElementString("LightCutoff", shp.LightCutoff.ToString()); - writer.WriteElementString("LightFalloff", shp.LightFalloff.ToString()); - writer.WriteElementString("LightIntensity", shp.LightIntensity.ToString()); + writer.WriteElementString("LightColorR", shp.LightColorR.ToString(Culture.FormatProvider)); + writer.WriteElementString("LightColorG", shp.LightColorG.ToString(Culture.FormatProvider)); + writer.WriteElementString("LightColorB", shp.LightColorB.ToString(Culture.FormatProvider)); + writer.WriteElementString("LightColorA", shp.LightColorA.ToString(Culture.FormatProvider)); + writer.WriteElementString("LightRadius", shp.LightRadius.ToString(Culture.FormatProvider)); + writer.WriteElementString("LightCutoff", shp.LightCutoff.ToString(Culture.FormatProvider)); + writer.WriteElementString("LightFalloff", shp.LightFalloff.ToString(Culture.FormatProvider)); + writer.WriteElementString("LightIntensity", shp.LightIntensity.ToString(Culture.FormatProvider)); writer.WriteElementString("FlexiEntry", shp.FlexiEntry.ToString().ToLower()); writer.WriteElementString("LightEntry", shp.LightEntry.ToString().ToLower()); diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneXmlLoader.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneXmlLoader.cs index 0f022dd58f..42381f6fd3 100644 --- a/OpenSim/Region/Framework/Scenes/Serialization/SceneXmlLoader.cs +++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneXmlLoader.cs @@ -53,10 +53,12 @@ namespace OpenSim.Region.Framework.Scenes.Serialization if (fileName.StartsWith("http:") || File.Exists(fileName)) { - XmlTextReader reader = new XmlTextReader(fileName); - reader.WhitespaceHandling = WhitespaceHandling.None; - doc.Load(reader); - reader.Close(); + using(XmlTextReader reader = new XmlTextReader(fileName)) + { + reader.WhitespaceHandling = WhitespaceHandling.None; + + doc.Load(reader); + } rootNode = doc.FirstChild; foreach (XmlNode aPrimNode in rootNode.ChildNodes) { @@ -70,7 +72,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization //obj.RegenerateFullIDs(); scene.AddNewSceneObject(obj, true); - obj.AggregateDeepPerms(); + obj.InvalidateDeepEffectivePerms(); } } else diff --git a/OpenSim/Region/Framework/Scenes/TerrainChannel.cs b/OpenSim/Region/Framework/Scenes/TerrainChannel.cs index 89d78cf83e..92fd314cae 100644 --- a/OpenSim/Region/Framework/Scenes/TerrainChannel.cs +++ b/OpenSim/Region/Framework/Scenes/TerrainChannel.cs @@ -196,13 +196,11 @@ namespace OpenSim.Region.Framework.Scenes // ITerrainChannel.LoadFromXmlString() public void LoadFromXmlString(string data) { - StringReader sr = new StringReader(data); - XmlTextReader reader = new XmlTextReader(sr); - reader.Read(); - - ReadXml(reader); - reader.Close(); - sr.Close(); + using(StringReader sr = new StringReader(data)) + { + using(XmlTextReader reader = new XmlTextReader(sr)) + ReadXml(reader); + } } // ITerrainChannel.Merge diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAnimationTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAnimationTests.cs index 42d91b954a..d650c4346d 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAnimationTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAnimationTests.cs @@ -60,7 +60,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests TestScene scene = new SceneHelpers().SetupScene(); ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1)); sp.Flying = true; - sp.PhysicsCollisionUpdate(new CollisionEventUpdate()); + sp.Animator.UpdateMovementAnimations(); Assert.That(sp.Animator.CurrentMovementAnimation, Is.EqualTo("HOVER")); } diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAutopilotTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAutopilotTests.cs index e5c847e3eb..90c51973dd 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAutopilotTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAutopilotTests.cs @@ -97,7 +97,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests Assert.That(sp.AbsolutePosition.Z, Is.EqualTo(startPos.Z)); Assert.That(sp.AbsolutePosition.Z, Is.LessThan(targetPos.X)); - m_scene.Update(10); + m_scene.Update(50); double distanceToTarget = Util.GetDistanceTo(sp.AbsolutePosition, targetPos); Assert.That(distanceToTarget, Is.LessThan(1), "Avatar not within 1 unit of target position on first move"); @@ -121,7 +121,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests Assert.That(sp.AbsolutePosition.Y, Is.EqualTo(startPos.Y)); Assert.That(sp.AbsolutePosition.Z, Is.EqualTo(startPos.Z)); - m_scene.Update(10); + m_scene.Update(50); distanceToTarget = Util.GetDistanceTo(sp.AbsolutePosition, targetPos); Assert.That(distanceToTarget, Is.LessThan(1), "Avatar not within 1 unit of target position on second move"); diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneStatisticsTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneStatisticsTests.cs index 045fd3cec5..4ce6a95f36 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneStatisticsTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneStatisticsTests.cs @@ -54,8 +54,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests UUID ownerId = TestHelpers.ParseTail(0x1); SceneObjectGroup so1 = SceneHelpers.CreateSceneObject(3, ownerId, "so1", 0x10); - so1.ScriptSetPhysicsStatus(true); m_scene.AddSceneObject(so1); + so1.ScriptSetPhysicsStatus(true); Assert.That(m_scene.SceneGraph.GetTotalObjectsCount(), Is.EqualTo(3)); Assert.That(m_scene.SceneGraph.GetActiveObjectsCount(), Is.EqualTo(3)); diff --git a/OpenSim/Region/Framework/Scenes/UuidGatherer.cs b/OpenSim/Region/Framework/Scenes/UuidGatherer.cs index 93406cbb79..80d3f62339 100644 --- a/OpenSim/Region/Framework/Scenes/UuidGatherer.cs +++ b/OpenSim/Region/Framework/Scenes/UuidGatherer.cs @@ -65,7 +65,10 @@ namespace OpenSim.Region.Framework.Scenes /// /// The gathered uuids. public IDictionary GatheredUuids { get; private set; } - + public HashSet FailedUUIDs { get; private set; } + public HashSet UncertainAssetsUUIDs { get; private set; } + public int possibleNotAssetCount { get; set; } + public int ErrorCount { get; private set; } /// /// Gets the next UUID to inspect. /// @@ -92,7 +95,10 @@ namespace OpenSim.Region.Framework.Scenes /// /// Asset service. /// - public UuidGatherer(IAssetService assetService) : this(assetService, new Dictionary()) {} + public UuidGatherer(IAssetService assetService) : this(assetService, new Dictionary(), + new HashSet (),new HashSet ()) {} + public UuidGatherer(IAssetService assetService, IDictionary collector) : this(assetService, collector, + new HashSet (), new HashSet ()) {} /// /// Initializes a new instance of the class. @@ -101,16 +107,20 @@ namespace OpenSim.Region.Framework.Scenes /// Asset service. /// /// - /// Gathered UUIDs will be collected in this dictinaory. + /// Gathered UUIDs will be collected in this dictionary. /// It can be pre-populated if you want to stop the gatherer from analyzing assets that have already been fetched and inspected. /// - public UuidGatherer(IAssetService assetService, IDictionary collector) + public UuidGatherer(IAssetService assetService, IDictionary collector, HashSet failedIDs, HashSet uncertainAssetsUUIDs) { m_assetService = assetService; GatheredUuids = collector; // FIXME: Not efficient for searching, can improve. m_assetUuidsToInspect = new Queue(); + FailedUUIDs = failedIDs; + UncertainAssetsUUIDs = uncertainAssetsUUIDs; + ErrorCount = 0; + possibleNotAssetCount = 0; } /// @@ -120,6 +130,19 @@ namespace OpenSim.Region.Framework.Scenes /// UUID. public bool AddForInspection(UUID uuid) { + if(uuid == UUID.Zero) + return false; + + if(FailedUUIDs.Contains(uuid)) + { + if(UncertainAssetsUUIDs.Contains(uuid)) + possibleNotAssetCount++; + else + ErrorCount++; + return false; + } + if(GatheredUuids.ContainsKey(uuid)) + return false; if (m_assetUuidsToInspect.Contains(uuid)) return false; @@ -141,7 +164,9 @@ namespace OpenSim.Region.Framework.Scenes public void AddForInspection(SceneObjectGroup sceneObject) { // m_log.DebugFormat( - // "[ASSET GATHERER]: Getting assets for object {0}, {1}", sceneObject.Name, sceneObject.UUID); + // "[UUID GATHERER]: Getting assets for object {0}, {1}", sceneObject.Name, sceneObject.UUID); + if(sceneObject.IsDeleted) + return; SceneObjectPart[] parts = sceneObject.Parts; for (int i = 0; i < parts.Length; i++) @@ -149,7 +174,7 @@ namespace OpenSim.Region.Framework.Scenes SceneObjectPart part = parts[i]; // m_log.DebugFormat( - // "[ARCHIVER]: Getting part {0}, {1} for object {2}", part.Name, part.UUID, sceneObject.UUID); + // "[UUID GATHERER]: Getting part {0}, {1} for object {2}", part.Name, part.UUID, sceneObject.UUID); try { @@ -207,9 +232,7 @@ namespace OpenSim.Region.Framework.Scenes // m_log.DebugFormat( // "[ARCHIVER]: Analysing item {0} asset type {1} in {2} {3}", // tii.Name, tii.Type, part.Name, part.UUID); - - if (!GatheredUuids.ContainsKey(tii.AssetID)) - AddForInspection(tii.AssetID, (sbyte)tii.Type); + AddForInspection(tii.AssetID, (sbyte)tii.Type); } // FIXME: We need to make gathering modular but we cannot yet, since gatherers are not guaranteed @@ -225,9 +248,6 @@ namespace OpenSim.Region.Framework.Scenes catch (Exception e) { m_log.ErrorFormat("[UUID GATHERER]: Failed to get part - {0}", e); - m_log.DebugFormat( - "[UUID GATHERER]: Texture entry length for prim was {0} (min is 46)", - part.Shape.TextureEntry.Length); } } } @@ -278,55 +298,112 @@ namespace OpenSim.Region.Framework.Scenes /// The uuid of the asset for which to gather referenced assets private void GetAssetUuids(UUID assetUuid) { + if(assetUuid == UUID.Zero) + return; + + if(FailedUUIDs.Contains(assetUuid)) + { + if(UncertainAssetsUUIDs.Contains(assetUuid)) + possibleNotAssetCount++; + else + ErrorCount++; + return; + } + // avoid infinite loops if (GatheredUuids.ContainsKey(assetUuid)) return; + AssetBase assetBase; try { - AssetBase assetBase = GetAsset(assetUuid); + assetBase = GetAsset(assetUuid); + } + catch (Exception e) + { + m_log.ErrorFormat("[UUID GATHERER]: Failed to get asset {0} : {1}", assetUuid, e.Message); + ErrorCount++; + FailedUUIDs.Add(assetUuid); + return; + } - if (null != assetBase) + if(assetBase == null) + { +// m_log.ErrorFormat("[UUID GATHERER]: asset {0} not found", assetUuid); + FailedUUIDs.Add(assetUuid); + if(UncertainAssetsUUIDs.Contains(assetUuid)) + possibleNotAssetCount++; + else + ErrorCount++; + return; + } + + if(UncertainAssetsUUIDs.Contains(assetUuid)) + UncertainAssetsUUIDs.Remove(assetUuid); + + sbyte assetType = assetBase.Type; + + if(assetBase.Data == null || assetBase.Data.Length == 0) + { +// m_log.ErrorFormat("[UUID GATHERER]: asset {0}, type {1} has no data", assetUuid, assetType); + ErrorCount++; + FailedUUIDs.Add(assetUuid); + return; + } + + GatheredUuids[assetUuid] = assetType; + try + { + if ((sbyte)AssetType.Bodypart == assetType || (sbyte)AssetType.Clothing == assetType) { - sbyte assetType = assetBase.Type; - GatheredUuids[assetUuid] = assetType; - - if ((sbyte)AssetType.Bodypart == assetType || (sbyte)AssetType.Clothing == assetType) - { - RecordWearableAssetUuids(assetBase); - } - else if ((sbyte)AssetType.Gesture == assetType) - { - RecordGestureAssetUuids(assetBase); - } - else if ((sbyte)AssetType.Notecard == assetType) - { - RecordTextEmbeddedAssetUuids(assetBase); - } - else if ((sbyte)AssetType.LSLText == assetType) - { - RecordTextEmbeddedAssetUuids(assetBase); - } - else if ((sbyte)OpenSimAssetType.Material == assetType) - { - RecordMaterialAssetUuids(assetBase); - } - else if ((sbyte)AssetType.Object == assetType) - { - RecordSceneObjectAssetUuids(assetBase); - } + RecordWearableAssetUuids(assetBase); + } + else if ((sbyte)AssetType.Gesture == assetType) + { + RecordGestureAssetUuids(assetBase); + } + else if ((sbyte)AssetType.Notecard == assetType) + { + RecordTextEmbeddedAssetUuids(assetBase); + } + else if ((sbyte)AssetType.LSLText == assetType) + { + RecordTextEmbeddedAssetUuids(assetBase); + } + else if ((sbyte)OpenSimAssetType.Material == assetType) + { + RecordMaterialAssetUuids(assetBase); + } + else if ((sbyte)AssetType.Object == assetType) + { + RecordSceneObjectAssetUuids(assetBase); } } - catch (Exception) + catch (Exception e) { - m_log.ErrorFormat("[UUID GATHERER]: Failed to gather uuids for asset id {0}", assetUuid); - throw; + m_log.ErrorFormat("[UUID GATHERER]: Failed to gather uuids for asset with id {0} type {1}: {2}", assetUuid, assetType, e.Message); + GatheredUuids.Remove(assetUuid); + ErrorCount++; + FailedUUIDs.Add(assetUuid); } } private void AddForInspection(UUID assetUuid, sbyte assetType) { + if(assetUuid == UUID.Zero) + return; + // Here, we want to collect uuids which require further asset fetches but mark the others as gathered + if(FailedUUIDs.Contains(assetUuid)) + { + if(UncertainAssetsUUIDs.Contains(assetUuid)) + possibleNotAssetCount++; + else + ErrorCount++; + return; + } + if(GatheredUuids.ContainsKey(assetUuid)) + return; try { if ((sbyte)AssetType.Bodypart == assetType @@ -458,8 +535,11 @@ namespace OpenSim.Region.Framework.Scenes foreach (Match uuidMatch in uuidMatches) { UUID uuid = new UUID(uuidMatch.Value); + if(uuid == UUID.Zero) + continue; // m_log.DebugFormat("[UUID GATHERER]: Recording {0} in text", uuid); - + if(!UncertainAssetsUUIDs.Contains(uuid)) + UncertainAssetsUUIDs.Add(uuid); AddForInspection(uuid); } } @@ -550,7 +630,16 @@ namespace OpenSim.Region.Framework.Scenes /// private void RecordMaterialAssetUuids(AssetBase materialAsset) { - OSDMap mat = (OSDMap)OSDParser.DeserializeLLSDXml(materialAsset.Data); + OSDMap mat; + try + { + mat = (OSDMap)OSDParser.DeserializeLLSDXml(materialAsset.Data); + } + catch (Exception e) + { + m_log.WarnFormat("[Materials]: cannot decode material asset {0}: {1}", materialAsset.ID, e.Message); + return; + } UUID normMap = mat["NormMap"].AsUUID(); if (normMap != UUID.Zero) diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs index 83b534b0ca..469dd67437 100644 --- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs +++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs @@ -1097,7 +1097,12 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server } - public void SendAvatarDataImmediate(ISceneEntity avatar) + public void SendEntityFullUpdateImmediate(ISceneEntity ent) + { + + } + + public void SendEntityTerseUpdateImmediate(ISceneEntity ent) { } @@ -1697,6 +1702,11 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server } + public void SendEmpytMuteList() + { + + } + public void SendMuteListUpdate(string filename) { diff --git a/OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs b/OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs index 3be5a07d27..490809eae1 100644 --- a/OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs +++ b/OpenSim/Region/OptionalModules/Agent/UDP/Linden/LindenUDPInfoModule.cs @@ -124,15 +124,6 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden "Without the 'full' option, only root agents are shown." + " With the 'full' option child agents are also shown.", (mod, cmd) => MainConsole.Instance.Output(GetThrottlesReport(cmd))); - - scene.AddCommand( - "Comms", this, "show client stats", - "show client stats [first_name last_name]", - "Show client request stats", - "Without the 'first_name last_name' option, all clients are shown." - + " With the 'first_name last_name' option only a specific client is shown.", - (mod, cmd) => MainConsole.Instance.Output(HandleClientStatsReport(cmd))); - } public void RemoveRegion(Scene scene) @@ -540,107 +531,6 @@ namespace OpenSim.Region.OptionalModules.UDP.Linden return report.ToString(); } - /// - /// Show client stats data - /// - /// - /// - protected string HandleClientStatsReport(string[] showParams) - { - // NOTE: This writes to m_log on purpose. We want to store this information - // in case we need to analyze it later. - // - if (showParams.Length <= 4) - { - m_log.InfoFormat("[INFO]: {0,-12} {1,-20} {2,-6} {3,-11} {4,-11} {5,-16}", "Region", "Name", "Root", "Time", "Reqs/min", "AgentUpdates"); - foreach (Scene scene in m_scenes.Values) - { - scene.ForEachClient( - delegate(IClientAPI client) - { - if (client is LLClientView) - { - LLClientView llClient = client as LLClientView; - ClientInfo cinfo = llClient.UDPClient.GetClientInfo(); - int avg_reqs = cinfo.AsyncRequests.Values.Sum() + cinfo.GenericRequests.Values.Sum() + cinfo.SyncRequests.Values.Sum(); - avg_reqs = avg_reqs / ((DateTime.Now - cinfo.StartedTime).Minutes + 1); - - string childAgentStatus; - - if (llClient.SceneAgent != null) - childAgentStatus = llClient.SceneAgent.IsChildAgent ? "N" : "Y"; - else - childAgentStatus = "Off!"; - - m_log.InfoFormat("[INFO]: {0,-12} {1,-20} {2,-6} {3,-11} {4,-11} {5,-16}", - scene.RegionInfo.RegionName, llClient.Name, - childAgentStatus, - (DateTime.Now - cinfo.StartedTime).Minutes, - avg_reqs, - string.Format( - "{0} ({1:0.00}%)", - llClient.TotalAgentUpdates, - cinfo.SyncRequests.ContainsKey("AgentUpdate") - ? (float)cinfo.SyncRequests["AgentUpdate"] / llClient.TotalAgentUpdates * 100 - : 0)); - } - }); - } - return string.Empty; - } - - string fname = "", lname = ""; - - if (showParams.Length > 3) - fname = showParams[3]; - if (showParams.Length > 4) - lname = showParams[4]; - - foreach (Scene scene in m_scenes.Values) - { - scene.ForEachClient( - delegate(IClientAPI client) - { - if (client is LLClientView) - { - LLClientView llClient = client as LLClientView; - - if (llClient.Name == fname + " " + lname) - { - - ClientInfo cinfo = llClient.GetClientInfo(); - AgentCircuitData aCircuit = scene.AuthenticateHandler.GetAgentCircuitData(llClient.CircuitCode); - if (aCircuit == null) // create a dummy one - aCircuit = new AgentCircuitData(); - - if (!llClient.SceneAgent.IsChildAgent) - m_log.InfoFormat("[INFO]: {0} # {1} # {2}", llClient.Name, Util.GetViewerName(aCircuit), aCircuit.Id0); - - int avg_reqs = cinfo.AsyncRequests.Values.Sum() + cinfo.GenericRequests.Values.Sum() + cinfo.SyncRequests.Values.Sum(); - avg_reqs = avg_reqs / ((DateTime.Now - cinfo.StartedTime).Minutes + 1); - - m_log.InfoFormat("[INFO]:"); - m_log.InfoFormat("[INFO]: {0} # {1} # Time: {2}min # Avg Reqs/min: {3}", scene.RegionInfo.RegionName, - (llClient.SceneAgent.IsChildAgent ? "Child" : "Root"), (DateTime.Now - cinfo.StartedTime).Minutes, avg_reqs); - - Dictionary sortedDict = (from entry in cinfo.AsyncRequests orderby entry.Value descending select entry) - .ToDictionary(pair => pair.Key, pair => pair.Value); - PrintRequests("TOP ASYNC", sortedDict, cinfo.AsyncRequests.Values.Sum()); - - sortedDict = (from entry in cinfo.SyncRequests orderby entry.Value descending select entry) - .ToDictionary(pair => pair.Key, pair => pair.Value); - PrintRequests("TOP SYNC", sortedDict, cinfo.SyncRequests.Values.Sum()); - - sortedDict = (from entry in cinfo.GenericRequests orderby entry.Value descending select entry) - .ToDictionary(pair => pair.Key, pair => pair.Value); - PrintRequests("TOP GENERIC", sortedDict, cinfo.GenericRequests.Values.Sum()); - } - } - }); - } - return string.Empty; - } - private void PrintRequests(string type, Dictionary sortedDict, int sum) { m_log.InfoFormat("[INFO]:"); diff --git a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs index 60ae0cb587..c04f40c36a 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs @@ -407,15 +407,21 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance { sb.AppendFormat("Wearables checks for {0}\n\n", sp.Name); - for (int i = (int)WearableType.Shape; i < (int)WearableType.Physics; i++) + AvatarWearable[] wearables = sp.Appearance.Wearables; + if(wearables.Count() == 0) { - AvatarWearable aw = sp.Appearance.Wearables[i]; + MainConsole.Instance.OutputFormat("avatar has no wearables"); + return; + } + + for (int i = 0; i < wearables.Count(); i++) + { + AvatarWearable aw = wearables[i]; + sb.Append(Enum.GetName(typeof(WearableType), i)); + sb.Append("\n"); if (aw.Count > 0) { - sb.Append(Enum.GetName(typeof(WearableType), i)); - sb.Append("\n"); - for (int j = 0; j < aw.Count; j++) { WearableItem wi = aw[j]; @@ -448,6 +454,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance sb.Append("\n"); } } + else + sb.Append(" Empty\n"); } } } diff --git a/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs b/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs index 92b583136c..c3f38511dd 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs @@ -174,7 +174,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments child.TriggerScriptChangedEvent(Changed.OWNER); child.ApplyNextOwnerPermissions(); } - hostgroup.AggregatePerms(); + hostgroup.InvalidateEffectivePerms(); } hostgroup.RootPart.ObjectSaleType = 0; diff --git a/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs b/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs index c0de3d95db..a5dc0ad0d0 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs @@ -460,9 +460,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge if (resp.ContentLength > 0) { - StreamReader content = new StreamReader(resp.GetResponseStream()); - m_log.ErrorFormat("[Concierge] response from {0} content: {1}", bs.Uri, content.ReadToEnd()); - content.Close(); + using(StreamReader content = new StreamReader(resp.GetResponseStream())) + m_log.ErrorFormat("[Concierge] response from {0} content: {1}", bs.Uri, content.ReadToEnd()); } } } diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs index 57930d7979..582df22e6f 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs @@ -1146,7 +1146,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice using (HttpWebResponse rsp = (HttpWebResponse)req.GetResponse()) using (Stream s = rsp.GetResponseStream()) using (XmlTextReader rdr = new XmlTextReader(s)) - doc.Load(rdr); + doc.Load(rdr); } catch (Exception e) { diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index d52a1d53db..65d50bb9a0 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -901,7 +901,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups remoteClient.SendCreateGroupReply(groupID, true, "Group created successfully"); // Update the founder with new group information. - SendAgentGroupDataUpdate(remoteClient, false); + SendAgentGroupDataUpdate(remoteClient, true); return groupID; } @@ -1520,6 +1520,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups lastname, activeGroupPowers, activeGroupName, activeGroupTitle); + if (tellOthers) SendScenePresenceUpdate(agentID, activeGroupTitle); diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs index 50d3f9471d..fab7e8c894 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs @@ -666,6 +666,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups data.ListInProfile = ((string)membership["ListInProfile"]) == "1"; data.AgentPowers = ulong.Parse((string)membership["AgentPowers"]); data.Title = (string)membership["Title"]; + if(membership.ContainsKey("OnlineStatus")) + data.OnlineStatus = (string)membership["OnlineStatus"]; members.Add(data); } diff --git a/OpenSim/Region/OptionalModules/DataSnapshot/DataRequestHandler.cs b/OpenSim/Region/OptionalModules/DataSnapshot/DataRequestHandler.cs index 50276ae010..817170f352 100644 --- a/OpenSim/Region/OptionalModules/DataSnapshot/DataRequestHandler.cs +++ b/OpenSim/Region/OptionalModules/DataSnapshot/DataRequestHandler.cs @@ -45,6 +45,7 @@ namespace OpenSim.Region.DataSnapshot // private Scene m_scene = null; private DataSnapshotManager m_externalData = null; private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private ExpiringCache throotleGen = new ExpiringCache(); public DataRequestHandler(Scene scene, DataSnapshotManager externalData) { @@ -52,29 +53,91 @@ namespace OpenSim.Region.DataSnapshot m_externalData = externalData; //Register HTTP handler - if (MainServer.Instance.AddHTTPHandler("collector", OnGetSnapshot)) + if (MainServer.UnSecureInstance.AddHTTPHandler("collector", OnGetSnapshot)) { m_log.Info("[DATASNAPSHOT]: Set up snapshot service"); } // Register validation callback handler - MainServer.Instance.AddHTTPHandler("validate", OnValidate); + MainServer.UnSecureInstance.AddHTTPHandler("validate", OnValidate); } + private string GetClientString(Hashtable request) + { + string clientstring = ""; + if (!request.ContainsKey("headers")) + return clientstring; + + Hashtable requestinfo = (Hashtable)request["headers"]; + if (requestinfo.ContainsKey("x-forwarded-for")) + { + object str = requestinfo["x-forwarded-for"]; + if (str != null) + { + if (!string.IsNullOrEmpty(str.ToString())) + { + return str.ToString(); + } + } + } + if (!requestinfo.ContainsKey("remote_addr")) + return clientstring; + + object remote_addrobj = requestinfo["remote_addr"]; + if (remote_addrobj != null) + { + if (!string.IsNullOrEmpty(remote_addrobj.ToString())) + { + clientstring = remote_addrobj.ToString(); + } + } + + return clientstring; + } + public Hashtable OnGetSnapshot(Hashtable keysvals) { - m_log.Debug("[DATASNAPSHOT] Received collection request"); Hashtable reply = new Hashtable(); - int statuscode = 200; - + string reqtag; string snapObj = (string)keysvals["region"]; + if(string.IsNullOrWhiteSpace(snapObj)) + reqtag = GetClientString(keysvals); + else + reqtag = snapObj + GetClientString(keysvals); + + + if(!string.IsNullOrWhiteSpace(reqtag)) + { + if(throotleGen.Contains(reqtag)) + { + reply["str_response_string"] = "Please try your request again later"; + reply["int_response_code"] = 503; + reply["content_type"] = "text/plain"; + m_log.Debug("[DATASNAPSHOT] Collection request spam. reply try later"); + return reply; + } + + throotleGen.AddOrUpdate(reqtag, 0, 60); + } + + if(string.IsNullOrWhiteSpace(snapObj)) + m_log.DebugFormat("[DATASNAPSHOT] Received collection request for all"); + else + m_log.DebugFormat("[DATASNAPSHOT] Received collection request for {0}", snapObj); XmlDocument response = m_externalData.GetSnapshot(snapObj); + if(response == null) + { + reply["str_response_string"] = "Please try your request again later"; + reply["int_response_code"] = 503; + reply["content_type"] = "text/plain"; + m_log.Debug("[DATASNAPSHOT] Collection request spam. reply try later"); + return reply; + } reply["str_response_string"] = response.OuterXml; - reply["int_response_code"] = statuscode; + reply["int_response_code"] = 200; reply["content_type"] = "text/xml"; - return reply; } diff --git a/OpenSim/Region/OptionalModules/DataSnapshot/DataSnapshotManager.cs b/OpenSim/Region/OptionalModules/DataSnapshot/DataSnapshotManager.cs index 0436f96a28..d7e9114ffc 100644 --- a/OpenSim/Region/OptionalModules/DataSnapshot/DataSnapshotManager.cs +++ b/OpenSim/Region/OptionalModules/DataSnapshot/DataSnapshotManager.cs @@ -32,6 +32,7 @@ using System.IO; using System.Linq; using System.Net; using System.Reflection; +using System.Threading; using System.Text; using System.Xml; using log4net; @@ -64,6 +65,7 @@ namespace OpenSim.Region.DataSnapshot //Various internal objects private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); internal object m_syncInit = new object(); + private object m_serializeGen = new object(); //DataServices and networking private string m_dataServices = "noservices"; @@ -125,7 +127,15 @@ namespace OpenSim.Region.DataSnapshot m_gridinfo.Add( "name", config.Configs["DataSnapshot"].GetString("gridname", "the lost continent of hippo")); + m_exposure_level = config.Configs["DataSnapshot"].GetString("data_exposure", m_exposure_level); + m_exposure_level = m_exposure_level.ToLower(); + if(m_exposure_level !="all" && m_exposure_level != "minimum") + { + m_log.ErrorFormat("[DATASNAPSHOT]: unknown data_exposure option: '{0}'. defaulting to minimum",m_exposure_level); + m_exposure_level = "minimum"; + } + m_period = config.Configs["DataSnapshot"].GetInt("default_snapshot_period", m_period); m_maxStales = config.Configs["DataSnapshot"].GetInt("max_changes_before_update", m_maxStales); m_snapsDir = config.Configs["DataSnapshot"].GetString("snapshot_cache_directory", m_snapsDir); @@ -148,11 +158,8 @@ namespace OpenSim.Region.DataSnapshot m_enabled = false; return; } - } - } - } public void AddRegion(Scene scene) @@ -160,23 +167,14 @@ namespace OpenSim.Region.DataSnapshot if (!m_enabled) return; - m_log.DebugFormat("[DATASNAPSHOT]: Module added to Scene {0}.", scene.RegionInfo.RegionName); + m_scenes.Add(scene); - if (!m_servicesNotified) + if (m_snapStore == null) { m_hostname = scene.RegionInfo.ExternalHostName; - m_snapStore = new SnapshotStore(m_snapsDir, m_gridinfo, m_listener_port, m_hostname); - - //Hand it the first scene, assuming that all scenes have the same BaseHTTPServer - new DataRequestHandler(scene, this); - - if (m_dataServices != "" && m_dataServices != "noservices") - NotifyDataServices(m_dataServices, "online"); - - m_servicesNotified = true; + m_snapStore = new SnapshotStore(m_snapsDir, m_gridinfo); } - m_scenes.Add(scene); m_snapStore.AddScene(scene); Assembly currentasm = Assembly.GetExecutingAssembly(); @@ -201,7 +199,7 @@ namespace OpenSim.Region.DataSnapshot } } } - + m_log.DebugFormat("[DATASNAPSHOT]: Module added to Scene {0}.", scene.RegionInfo.RegionName); } public void RemoveRegion(Scene scene) @@ -244,8 +242,16 @@ namespace OpenSim.Region.DataSnapshot if (!m_enabled) return; - m_log.DebugFormat("[DATASNAPSHOT]: Marking scene {0} as stale.", scene.RegionInfo.RegionName); - m_snapStore.ForceSceneStale(scene); + if (!m_servicesNotified) + { + //Hand it the first scene, assuming that all scenes have the same BaseHTTPServer + new DataRequestHandler(scene, this); + + if (m_dataServices != "" && m_dataServices != "noservices") + NotifyDataServices(m_dataServices, "online"); + + m_servicesNotified = true; + } } public void Close() @@ -257,7 +263,6 @@ namespace OpenSim.Region.DataSnapshot NotifyDataServices(m_dataServices, "offline"); } - public string Name { get { return "External Data Generator"; } @@ -319,8 +324,14 @@ namespace OpenSim.Region.DataSnapshot /** * Reply to the http request */ + public XmlDocument GetSnapshot(string regionName) { + if(!Monitor.TryEnter(m_serializeGen,30000)) + { + return null; + } + CheckStale(); XmlDocument requestedSnap = new XmlDocument(); @@ -360,9 +371,13 @@ namespace OpenSim.Region.DataSnapshot m_log.Warn("[DATASNAPSHOT]: Caught unknown exception while trying to load snapshot: " + e.StackTrace); requestedSnap = GetErrorMessage(regionName, e); } - + finally + { + Monitor.Exit(m_serializeGen); + } return requestedSnap; + } private XmlDocument GetErrorMessage(string regionName, Exception e) diff --git a/OpenSim/Region/OptionalModules/DataSnapshot/SnapshotStore.cs b/OpenSim/Region/OptionalModules/DataSnapshot/SnapshotStore.cs index 480aaafef5..f384c9a011 100644 --- a/OpenSim/Region/OptionalModules/DataSnapshot/SnapshotStore.cs +++ b/OpenSim/Region/OptionalModules/DataSnapshot/SnapshotStore.cs @@ -47,17 +47,13 @@ namespace OpenSim.Region.DataSnapshot private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private Dictionary m_gridinfo = null; private bool m_cacheEnabled = true; - private string m_listener_port = "9000"; //TODO: Set default port over 9000 - private string m_hostname = "127.0.0.1"; #endregion - public SnapshotStore(string directory, Dictionary gridinfo, string port, string hostname) { + public SnapshotStore(string directory, Dictionary gridinfo) { m_directory = directory; m_scenes = new Dictionary(); m_providers = new List(); m_gridinfo = gridinfo; - m_listener_port = port; - m_hostname = hostname; if (Directory.Exists(m_directory)) { @@ -82,8 +78,14 @@ namespace OpenSim.Region.DataSnapshot } } - public void ForceSceneStale(Scene scene) { + public void ForceSceneStale(Scene scene) + { m_scenes[scene] = true; + foreach(IDataSnapshotProvider pv in m_providers) + { + if(pv.GetParentScene == scene && pv.Name == "LandSnapshot") + pv.Stale = true; + } } #region Fragment storage @@ -107,6 +109,7 @@ namespace OpenSim.Region.DataSnapshot snapXWriter.WriteStartDocument(); data.WriteTo(snapXWriter); snapXWriter.WriteEndDocument(); + snapXWriter.Flush(); } } catch (Exception e) @@ -263,7 +266,7 @@ namespace OpenSim.Region.DataSnapshot infoblock.AppendChild(infopiece); infopiece = basedoc.CreateNode(XmlNodeType.Element, "url", ""); - infopiece.InnerText = "http://" + m_hostname + ":" + m_listener_port; + infopiece.InnerText = scene.RegionInfo.ServerURI; infoblock.AppendChild(infopiece); infopiece = basedoc.CreateNode(XmlNodeType.Element, "name", ""); diff --git a/OpenSim/Region/OptionalModules/Materials/MaterialsModule.cs b/OpenSim/Region/OptionalModules/Materials/MaterialsModule.cs index e8cb052263..c66126800e 100644 --- a/OpenSim/Region/OptionalModules/Materials/MaterialsModule.cs +++ b/OpenSim/Region/OptionalModules/Materials/MaterialsModule.cs @@ -46,16 +46,10 @@ using OpenSimAssetType = OpenSim.Framework.SLUtil.OpenSimAssetType; using Ionic.Zlib; -// You will need to uncomment these lines if you are adding a region module to some other assembly which does not already -// specify its assembly. Otherwise, the region modules in the assembly will not be picked up when OpenSimulator scans -// the available DLLs -//[assembly: Addin("MaterialsModule", "1.0")] -//[assembly: AddinDependency("OpenSim", "0.8.1")] - namespace OpenSim.Region.OptionalModules.Materials { [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "MaterialsModule")] - public class MaterialsModule : INonSharedRegionModule + public class MaterialsModule : INonSharedRegionModule, IMaterialsModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -67,12 +61,12 @@ namespace OpenSim.Region.OptionalModules.Materials private Scene m_scene = null; private bool m_enabled = false; private int m_maxMaterialsPerTransaction = 50; + private object materialslock = new object(); - public Dictionary m_Materials = new Dictionary(); + public Dictionary m_Materials = new Dictionary(); public Dictionary m_MaterialsRefCount = new Dictionary(); - private Dictionary m_changes = new Dictionary(); - private Dictionary m_changesTime = new Dictionary(); + private Dictionary m_changed = new Dictionary(); public void Initialise(IConfigSource source) { @@ -101,54 +95,72 @@ namespace OpenSim.Region.OptionalModules.Materials return; m_scene = scene; + m_scene.RegisterModuleInterface(this); m_scene.EventManager.OnRegisterCaps += OnRegisterCaps; m_scene.EventManager.OnObjectAddedToScene += EventManager_OnObjectAddedToScene; + m_scene.EventManager.OnObjectBeingRemovedFromScene += EventManager_OnObjectDeleteFromScene; m_scene.EventManager.OnBackup += EventManager_OnBackup; } + public void RemoveRegion(Scene scene) + { + if (!m_enabled) + return; + + m_scene.EventManager.OnRegisterCaps -= OnRegisterCaps; + m_scene.EventManager.OnObjectAddedToScene -= EventManager_OnObjectAddedToScene; + m_scene.EventManager.OnObjectBeingRemovedFromScene -= EventManager_OnObjectDeleteFromScene; + m_scene.EventManager.OnBackup -= EventManager_OnBackup; + m_scene.UnregisterModuleInterface(this); + } + + public void RegionLoaded(Scene scene) + { + if (!m_enabled) return; + + m_cache = scene.RequestModuleInterface(); + ISimulatorFeaturesModule featuresModule = scene.RequestModuleInterface(); + if (featuresModule != null) + featuresModule.OnSimulatorFeaturesRequest += OnSimulatorFeaturesRequest; + } + private void EventManager_OnBackup(ISimulationDataService datastore, bool forcedBackup) { - List toStore; - List hashlist; + List toStore; - - lock (m_Materials) + lock (materialslock) { - if(m_changes.Count == 0) + if(m_changed.Count == 0) return; if(forcedBackup) { - toStore = new List(m_changes.Values); - m_changes.Clear(); - m_changesTime.Clear(); + toStore = new List(m_changed.Keys); + m_changed.Clear(); } else { - toStore = new List(); - hashlist = new List(); - double storetime = Util.GetTimeStampMS() - 60000; - foreach(KeyValuePair kvp in m_changesTime) + toStore = new List(); + double storetime = Util.GetTimeStamp() - 60.0; + foreach(KeyValuePair kvp in m_changed) { if(kvp.Value < storetime) { - toStore.Add(m_changes[kvp.Key]); - hashlist.Add(kvp.Key); + toStore.Add(kvp.Key); } } - foreach(ulong u in hashlist) + foreach(FaceMaterial fm in toStore) { - m_changesTime.Remove(u); - m_changes.Remove(u); + m_changed.Remove(fm); } } if(toStore.Count > 0) Util.FireAndForget(delegate { - foreach(AssetBase a in toStore) + foreach(FaceMaterial fm in toStore) { - a.Local = false; + AssetBase a = MakeAsset(fm, false); m_scene.AssetService.Store(a); } }); @@ -162,6 +174,13 @@ namespace OpenSim.Region.OptionalModules.Materials GetStoredMaterialsInPart(part); } + private void EventManager_OnObjectDeleteFromScene(SceneObjectGroup obj) + { + foreach (var part in obj.Parts) + if (part != null) + RemoveMaterialsInPart(part); + } + private void OnRegisterCaps(OpenMetaverse.UUID agentID, OpenSim.Framework.Capabilities.Caps caps) { string capsBase = "/CAPS/" + caps.CapsObjectPath; @@ -193,26 +212,6 @@ namespace OpenSim.Region.OptionalModules.Materials MainServer.Instance.AddStreamHandler(renderMaterialsPutHandler); } - public void RemoveRegion(Scene scene) - { - if (!m_enabled) - return; - - m_scene.EventManager.OnRegisterCaps -= OnRegisterCaps; - m_scene.EventManager.OnObjectAddedToScene -= EventManager_OnObjectAddedToScene; - m_scene.EventManager.OnBackup -= EventManager_OnBackup; - } - - public void RegionLoaded(Scene scene) - { - if (!m_enabled) return; - - m_cache = scene.RequestModuleInterface(); - ISimulatorFeaturesModule featuresModule = scene.RequestModuleInterface(); - if (featuresModule != null) - featuresModule.OnSimulatorFeaturesRequest += OnSimulatorFeaturesRequest; - } - private void OnSimulatorFeaturesRequest(UUID agentID, ref OSDMap features) { features["MaxMaterialsPerTransaction"] = m_maxMaterialsPerTransaction; @@ -222,14 +221,16 @@ namespace OpenSim.Region.OptionalModules.Materials /// Finds any legacy materials stored in DynAttrs that may exist for this part and add them to 'm_regionMaterials'. /// /// - private void GetLegacyStoredMaterialsInPart(SceneObjectPart part) + private bool GetLegacyStoredMaterialsInPart(SceneObjectPart part) { if (part.DynAttrs == null) - return; + return false; OSD OSMaterials = null; OSDArray matsArr = null; + bool partchanged = false; + lock (part.DynAttrs) { if (part.DynAttrs.ContainsStore("OpenSim", "Materials")) @@ -237,20 +238,22 @@ namespace OpenSim.Region.OptionalModules.Materials OSDMap materialsStore = part.DynAttrs.GetStore("OpenSim", "Materials"); if (materialsStore == null) - return; + return false; materialsStore.TryGetValue("Materials", out OSMaterials); + part.DynAttrs.RemoveStore("OpenSim", "Materials"); + partchanged = true; } if (OSMaterials != null && OSMaterials is OSDArray) matsArr = OSMaterials as OSDArray; else - return; + return partchanged; } if (matsArr == null) - return; - + return partchanged; + foreach (OSD elemOsd in matsArr) { if (elemOsd != null && elemOsd is OSDMap) @@ -260,16 +263,24 @@ namespace OpenSim.Region.OptionalModules.Materials { try { - lock (m_Materials) + lock (materialslock) { UUID id = matMap["ID"].AsUUID(); if(m_Materials.ContainsKey(id)) - m_MaterialsRefCount[id]++; - else - { - m_Materials[id] = (OSDMap)matMap["Material"]; - m_MaterialsRefCount[id] = 1; - } + continue; + + OSDMap theMatMap = (OSDMap)matMap["Material"]; + FaceMaterial fmat = new FaceMaterial(theMatMap); + + if(fmat == null || + ( fmat.DiffuseAlphaMode == 1 + && fmat.NormalMapID == UUID.Zero + && fmat.SpecularMapID == UUID.Zero)) + continue; + + fmat.ID = id; + m_Materials[id] = fmat; + m_MaterialsRefCount[id] = 0; } } catch (Exception e) @@ -279,6 +290,7 @@ namespace OpenSim.Region.OptionalModules.Materials } } } + return partchanged; } /// @@ -289,14 +301,16 @@ namespace OpenSim.Region.OptionalModules.Materials if (part.Shape == null) return; + bool partchanged = false; + bool facechanged = false; var te = new Primitive.TextureEntry(part.Shape.TextureEntry, 0, part.Shape.TextureEntry.Length); if (te == null) return; - GetLegacyStoredMaterialsInPart(part); + partchanged = GetLegacyStoredMaterialsInPart(part); if (te.DefaultTexture != null) - GetStoredMaterialInFace(part, te.DefaultTexture); + facechanged = GetStoredMaterialInFace(part, te.DefaultTexture); else m_log.WarnFormat( "[Materials]: Default texture for part {0} (part of object {1}) in {2} unexpectedly null. Ignoring.", @@ -305,36 +319,47 @@ namespace OpenSim.Region.OptionalModules.Materials foreach (Primitive.TextureEntryFace face in te.FaceTextures) { if (face != null) - GetStoredMaterialInFace(part, face); + facechanged |= GetStoredMaterialInFace(part, face); + } + + if(facechanged) + part.Shape.TextureEntry = te.GetBytes(); + + if(facechanged || partchanged) + { + if (part.ParentGroup != null && !part.ParentGroup.IsDeleted) + part.ParentGroup.HasGroupChanged = true; } } /// /// Find the materials used in one Face, and add them to 'm_regionMaterials'. /// - private void GetStoredMaterialInFace(SceneObjectPart part, Primitive.TextureEntryFace face) + private bool GetStoredMaterialInFace(SceneObjectPart part, Primitive.TextureEntryFace face) { UUID id = face.MaterialID; if (id == UUID.Zero) - return; + return false; - lock (m_Materials) + OSDMap mat; + lock (materialslock) { - if (m_Materials.ContainsKey(id)) + if(m_Materials.ContainsKey(id)) { m_MaterialsRefCount[id]++; - return; + return false; } AssetBase matAsset = m_scene.AssetService.Get(id.ToString()); if (matAsset == null || matAsset.Data == null || matAsset.Data.Length == 0 ) { - //m_log.WarnFormat("[Materials]: Prim \"{0}\" ({1}) contains unknown material ID {2}", part.Name, part.UUID, id); - return; + // grid may just be down... + return false; } byte[] data = matAsset.Data; - OSDMap mat; + + // string txt = System.Text.Encoding.ASCII.GetString(data); try { mat = (OSDMap)OSDParser.DeserializeLLSDXml(data); @@ -342,11 +367,76 @@ namespace OpenSim.Region.OptionalModules.Materials catch (Exception e) { m_log.WarnFormat("[Materials]: cannot decode material asset {0}: {1}", id, e.Message); - return; + return false; } - m_Materials[id] = mat; - m_MaterialsRefCount[id] = 1; + FaceMaterial fmat = new FaceMaterial(mat); + + if(fmat == null || + (fmat.DiffuseAlphaMode == 1 + && fmat.NormalMapID == UUID.Zero + && fmat.SpecularMapID == UUID.Zero)) + { + face.MaterialID = UUID.Zero; + return true; + } + + fmat.ID = id; + + if (m_Materials.ContainsKey(id)) + { + m_MaterialsRefCount[id]++; + } + else + { + m_Materials[id] = fmat; + m_MaterialsRefCount[id] = 1; + } + return false; + } + } + + private void RemoveMaterialsInPart(SceneObjectPart part) + { + if (part.Shape == null) + return; + + var te = new Primitive.TextureEntry(part.Shape.TextureEntry, 0, part.Shape.TextureEntry.Length); + if (te == null) + return; + + if (te.DefaultTexture != null) + RemoveMaterialInFace(te.DefaultTexture); + + foreach (Primitive.TextureEntryFace face in te.FaceTextures) + { + if(face != null) + RemoveMaterialInFace(face); + } + } + + private void RemoveMaterialInFace(Primitive.TextureEntryFace face) + { + UUID id = face.MaterialID; + if (id == UUID.Zero) + return; + + lock (materialslock) + { + if(!m_Materials.ContainsKey(id)) + return; + else + { + m_MaterialsRefCount[id]--; + if(m_MaterialsRefCount[id] <= 0) + { + FaceMaterial oldFaceMat = m_Materials[id]; + m_changed.Remove(oldFaceMat); + m_Materials.Remove(id); + m_MaterialsRefCount.Remove(id); + m_cache.Expire(id.ToString()); + } + } } } @@ -375,13 +465,13 @@ namespace OpenSim.Region.OptionalModules.Materials { UUID id = new UUID(elem.AsBinary(), 0); - lock (m_Materials) + lock (materialslock) { if (m_Materials.ContainsKey(id)) { OSDMap matMap = new OSDMap(); matMap["ID"] = OSD.FromBinary(id.GetBytes()); - matMap["Material"] = m_Materials[id]; + matMap["Material"] = m_Materials[id].toOSD(); respArr.Add(matMap); } else @@ -455,10 +545,12 @@ namespace OpenSim.Region.OptionalModules.Materials foreach (OSDMap matsMap in matsArr) { uint primLocalID = 0; - try { + try + { primLocalID = matsMap["ID"].AsUInteger(); } - catch (Exception e) { + catch (Exception e) + { m_log.Warn("[Materials]: cannot decode \"ID\" from matsMap: " + e.Message); continue; } @@ -494,7 +586,22 @@ namespace OpenSim.Region.OptionalModules.Materials continue; } + int face = -1; + UUID oldid = UUID.Zero; + Primitive.TextureEntryFace faceEntry = null; + if (matsMap.ContainsKey("Face")) + { + face = matsMap["Face"].AsInteger(); + faceEntry = te.CreateFace((uint)face); + } + else + faceEntry = te.DefaultTexture; + + if (faceEntry == null) + continue; + UUID id; + FaceMaterial newFaceMat = null; if (mat == null) { // This happens then the user removes a material from a prim @@ -502,60 +609,48 @@ namespace OpenSim.Region.OptionalModules.Materials } else { - id = getNewID(mat); - } - - int face = -1; - UUID oldid = UUID.Zero; - if (matsMap.ContainsKey("Face")) - { - face = matsMap["Face"].AsInteger(); - Primitive.TextureEntryFace faceEntry = te.CreateFace((uint)face); - oldid = faceEntry.MaterialID; - faceEntry.MaterialID = id; - } - else - { - if (te.DefaultTexture == null) - m_log.WarnFormat("[Materials]: TextureEntry.DefaultTexture is null in {0} {1}", sop.Name, sop.UUID); + newFaceMat = new FaceMaterial(mat); + if(newFaceMat.DiffuseAlphaMode == 1 + && newFaceMat.NormalMapID == UUID.Zero + && newFaceMat.SpecularMapID == UUID.Zero + ) + id = UUID.Zero; else { - oldid = te.DefaultTexture.MaterialID; - te.DefaultTexture.MaterialID = id; + newFaceMat.genID(); + id = newFaceMat.ID; } } - //m_log.DebugFormat("[Materials]: in \"{0}\" {1}, setting material ID for face {2} to {3}", sop.Name, sop.UUID, face, id); + oldid = faceEntry.MaterialID; - // We can't use sop.UpdateTextureEntry(te) because it filters, so do it manually - sop.Shape.TextureEntry = te.GetBytes(); + if(oldid == id) + continue; - lock(m_Materials) + if (faceEntry != null) { - if(oldid != UUID.Zero && m_MaterialsRefCount.ContainsKey(oldid)) - { - m_MaterialsRefCount[oldid]--; - if(m_MaterialsRefCount[oldid] <= 0) - { - m_Materials.Remove(oldid); - m_MaterialsRefCount.Remove(oldid); - m_cache.Expire(oldid.ToString()); - } - } + faceEntry.MaterialID = id; + //m_log.DebugFormat("[Materials]: in \"{0}\" {1}, setting material ID for face {2} to {3}", sop.Name, sop.UUID, face, id); + + // We can't use sop.UpdateTextureEntry(te) because it filters, so do it manually + sop.Shape.TextureEntry = te.GetBytes(); + } + + if(oldid != UUID.Zero) + RemoveMaterial(oldid); + + lock(materialslock) + { if(id != UUID.Zero) { - AssetBase asset = CacheMaterialAsAsset(id, agentID, mat, sop); - if(asset != null) + if (m_Materials.ContainsKey(id)) + m_MaterialsRefCount[id]++; + else { - ulong materialHash = (ulong)primLocalID << 32; - if(face < 0) - materialHash += 0xffffffff; - else - materialHash +=(ulong)face; - - m_changes[materialHash] = asset; - m_changesTime[materialHash] = Util.GetTimeStampMS(); + m_Materials[id] = newFaceMat; + m_MaterialsRefCount[id] = 1; + m_changed[newFaceMat] = Util.GetTimeStamp(); } } } @@ -598,119 +693,39 @@ namespace OpenSim.Region.OptionalModules.Materials return response; } - private UUID getNewID(OSDMap mat) - { - // ugly and done twice but keep compatibility for now - Byte[] data = System.Text.Encoding.ASCII.GetBytes(OSDParser.SerializeLLSDXmlString(mat)); - using (var md5 = MD5.Create()) - return new UUID(md5.ComputeHash(data), 0); - } - - private AssetBase CacheMaterialAsAsset(UUID id, UUID agentID, OSDMap mat, SceneObjectPart sop) + private AssetBase MakeAsset(FaceMaterial fm, bool local) { + // this are not true assets, should had never been... AssetBase asset = null; - lock (m_Materials) - { - if (!m_Materials.ContainsKey(id)) - { - m_Materials[id] = mat; - m_MaterialsRefCount[id] = 1; + string txt = fm.toLLSDxml(); + byte[] data = System.Text.Encoding.ASCII.GetBytes(txt); - byte[] data = System.Text.Encoding.ASCII.GetBytes(OSDParser.SerializeLLSDXmlString(mat)); - - // This asset might exist already, but it's ok to try to store it again - string name = "Material " + ChooseMaterialName(mat, sop); - name = name.Substring(0, Math.Min(64, name.Length)).Trim(); - asset = new AssetBase(id, name, (sbyte)OpenSimAssetType.Material, agentID.ToString()); - asset.Data = data; - asset.Local = true; - m_cache.Cache(asset); - } - else - m_MaterialsRefCount[id]++; - } + asset = new AssetBase(fm.ID, "llmaterial", (sbyte)OpenSimAssetType.Material, "00000000-0000-0000-0000-000000000000"); + asset.Data = data; + asset.Local = local; return asset; } - private UUID StoreMaterialAsAsset(UUID agentID, OSDMap mat, SceneObjectPart sop) - { - UUID id; - // Material UUID = hash of the material's data. - // This makes materials deduplicate across the entire grid (but isn't otherwise required). - byte[] data = System.Text.Encoding.ASCII.GetBytes(OSDParser.SerializeLLSDXmlString(mat)); - using (var md5 = MD5.Create()) - id = new UUID(md5.ComputeHash(data), 0); - - lock (m_Materials) - { - if (!m_Materials.ContainsKey(id)) - { - m_Materials[id] = mat; - m_MaterialsRefCount[id] = 1; - - // This asset might exist already, but it's ok to try to store it again - string name = "Material " + ChooseMaterialName(mat, sop); - name = name.Substring(0, Math.Min(64, name.Length)).Trim(); - AssetBase asset = new AssetBase(id, name, (sbyte)OpenSimAssetType.Material, agentID.ToString()); - asset.Data = data; - m_scene.AssetService.Store(asset); - } - else - m_MaterialsRefCount[id]++; - } - return id; - } - - /// - /// Use heuristics to choose a good name for the material. - /// - private string ChooseMaterialName(OSDMap mat, SceneObjectPart sop) - { - UUID normMap = mat["NormMap"].AsUUID(); - if (normMap != UUID.Zero) - { - AssetBase asset = m_scene.AssetService.GetCached(normMap.ToString()); - if ((asset != null) && (asset.Name.Length > 0) && !asset.Name.Equals("From IAR")) - return asset.Name; - } - - UUID specMap = mat["SpecMap"].AsUUID(); - if (specMap != UUID.Zero) - { - AssetBase asset = m_scene.AssetService.GetCached(specMap.ToString()); - if ((asset != null) && (asset.Name.Length > 0) && !asset.Name.Equals("From IAR")) - return asset.Name; - } - - if (sop.Name != "Primitive") - return sop.Name; - - if ((sop.ParentGroup != null) && (sop.ParentGroup.Name != "Primitive")) - return sop.ParentGroup.Name; - - return ""; - } - - public string RenderMaterialsGetCap(string request) { OSDMap resp = new OSDMap(); - int matsCount = 0; OSDArray allOsd = new OSDArray(); +/* + // this violates all idea of caching and geting things only if needed, so disabled + int matsCount = 0; lock (m_Materials) { - foreach (KeyValuePair kvp in m_Materials) + foreach (KeyValuePair kvp in m_Materials) { OSDMap matMap = new OSDMap(); - matMap["ID"] = OSD.FromBinary(kvp.Key.GetBytes()); - matMap["Material"] = kvp.Value; + matMap["Material"] = kvp.Value.toOSD(); allOsd.Add(matMap); matsCount++; } } - +*/ resp["Zipped"] = ZCompressOSD(allOsd, false); return OSDParser.SerializeLLSDXmlString(resp); @@ -728,18 +743,6 @@ namespace OpenSim.Region.OptionalModules.Materials } } - /// - /// computes a UUID by hashing a OSD object - /// - /// - /// - private static UUID HashOsd(OSD osd) - { - byte[] data = OSDParser.SerializeLLSDBinary(osd, false); - using (var md5 = MD5.Create()) - return new UUID(md5.ComputeHash(data), 0); - } - public static OSD ZCompressOSD(OSD inOsd, bool useHeader) { OSD osd = null; @@ -761,7 +764,6 @@ namespace OpenSim.Region.OptionalModules.Materials return osd; } - public static OSD ZDecompressBytesToOsd(byte[] input) { OSD osd = null; @@ -779,5 +781,67 @@ namespace OpenSim.Region.OptionalModules.Materials return osd; } + + public FaceMaterial GetMaterial(UUID ID) + { + FaceMaterial fm = null; + if(m_Materials.TryGetValue(ID, out fm)) + return fm; + return null; + } + + public FaceMaterial GetMaterialCopy(UUID ID) + { + FaceMaterial fm = null; + if(m_Materials.TryGetValue(ID, out fm)) + return new FaceMaterial(fm); + return null; + } + + public UUID AddNewMaterial(FaceMaterial fm) + { + if(fm.DiffuseAlphaMode == 1 && fm.NormalMapID == UUID.Zero && fm.SpecularMapID == UUID.Zero) + { + fm.ID = UUID.Zero; + return UUID.Zero; + } + + fm.genID(); + UUID id = fm.ID; + lock(materialslock) + { + if(m_Materials.ContainsKey(id)) + m_MaterialsRefCount[id]++; + else + { + m_Materials[id] = fm; + m_MaterialsRefCount[id] = 1; + m_changed[fm] = Util.GetTimeStamp(); + } + } + return id; + } + + public void RemoveMaterial(UUID id) + { + if(id == UUID.Zero) + return; + + lock(materialslock) + { + if(m_Materials.ContainsKey(id)) + { + m_MaterialsRefCount[id]--; + if(m_MaterialsRefCount[id] <= 0) + { + FaceMaterial fm = m_Materials[id]; + m_changed.Remove(fm); + m_Materials.Remove(id); + m_MaterialsRefCount.Remove(id); + m_cache.Expire(id.ToString()); + } + } + } + } } } diff --git a/OpenSim/Region/OptionalModules/PrimLimitsModule/PrimLimitsModule.cs b/OpenSim/Region/OptionalModules/PrimLimitsModule/PrimLimitsModule.cs index af32d0515a..61b6d682e6 100644 --- a/OpenSim/Region/OptionalModules/PrimLimitsModule/PrimLimitsModule.cs +++ b/OpenSim/Region/OptionalModules/PrimLimitsModule/PrimLimitsModule.cs @@ -83,6 +83,7 @@ namespace OpenSim.Region.OptionalModules m_scene = scene; scene.Permissions.OnRezObject += CanRezObject; scene.Permissions.OnObjectEntry += CanObjectEnter; + scene.Permissions.OnObjectEnterWithScripts += CanObjectEnterWithScripts; scene.Permissions.OnDuplicateObject += CanDuplicateObject; m_log.DebugFormat("[PRIM LIMITS]: Region {0} added", scene.RegionInfo.RegionName); @@ -95,6 +96,7 @@ namespace OpenSim.Region.OptionalModules m_scene.Permissions.OnRezObject -= CanRezObject; m_scene.Permissions.OnObjectEntry -= CanObjectEnter; + scene.Permissions.OnObjectEnterWithScripts -= CanObjectEnterWithScripts; m_scene.Permissions.OnDuplicateObject -= CanDuplicateObject; } @@ -173,6 +175,26 @@ namespace OpenSim.Region.OptionalModules return true; } + private bool CanObjectEnterWithScripts(SceneObjectGroup sog, ILandObject newParcel) + { + if (sog == null) + return false; + + if (newParcel == null) + return true; + + int objectCount = sog.PrimCount; + + // TODO: Add Special Case here for temporary prims + + string response = DoCommonChecks(objectCount, sog.OwnerID, newParcel); + + if (response != null) + return false; + + return true; + } + private string DoCommonChecks(int objectCount, UUID ownerID, ILandObject lo) { string response = null; diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs index 6cf0092266..fe8d9621e1 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs @@ -665,7 +665,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore taskItem.AssetID = asset.FullID; host.Inventory.AddInventoryItem(taskItem, false); - host.ParentGroup.AggregatePerms(); + host.ParentGroup.InvalidateEffectivePerms(); m_comms.DispatchReply(scriptID,1,assetID.ToString(),reqID.ToString()); } diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/SOPObject.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/SOPObject.cs index 5513cd5374..1ff9cb5890 100644 --- a/OpenSim/Region/OptionalModules/Scripting/Minimodule/SOPObject.cs +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/SOPObject.cs @@ -824,7 +824,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule ISoundModule module = m_rootScene.RequestModuleInterface(); if (module != null) { - module.SendSound(GetSOP().UUID, asset, volume, true, 0, 0, false, false); + module.SendSound(GetSOP().UUID, asset, volume, true, 0, false, false); } } diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/World.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/World.cs index 36f70d02eb..eff70efbe1 100644 --- a/OpenSim/Region/OptionalModules/Scripting/Minimodule/World.cs +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/World.cs @@ -231,7 +231,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule if (soundModule != null) { soundModule.TriggerSound(audio, UUID.Zero, UUID.Zero, UUID.Zero, volume, position, - m_internalScene.RegionInfo.RegionHandle, 0); + m_internalScene.RegionInfo.RegionHandle); } } @@ -241,7 +241,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule if (soundModule != null) { soundModule.TriggerSound(audio, UUID.Zero, UUID.Zero, UUID.Zero, 1.0, position, - m_internalScene.RegionInfo.RegionHandle, 0); + m_internalScene.RegionInfo.RegionHandle); } } diff --git a/OpenSim/Region/OptionalModules/World/AutoBackup/AutoBackupModule.cs b/OpenSim/Region/OptionalModules/World/AutoBackup/AutoBackupModule.cs index 79b80f88f4..64513a0f0c 100644 --- a/OpenSim/Region/OptionalModules/World/AutoBackup/AutoBackupModule.cs +++ b/OpenSim/Region/OptionalModules/World/AutoBackup/AutoBackupModule.cs @@ -59,23 +59,23 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup /// /// /// Config Settings Documentation. - /// Each configuration setting can be specified in two places: OpenSim.ini or Regions.ini. - /// If specified in Regions.ini, the settings should be within the region's section name. - /// If specified in OpenSim.ini, the settings should be within the [AutoBackupModule] section. - /// Region-specific settings take precedence. + /// Configuration setting can be specified in two places: OpenSim.ini and/or Regions.ini. /// - /// AutoBackupModuleEnabled: True/False. Default: False. If True, use the auto backup module. This setting does not support per-region basis. - /// All other settings under [AutoBackupModule] are ignored if AutoBackupModuleEnabled is false, even per-region settings! - /// AutoBackup: True/False. Default: False. If True, activate auto backup functionality. - /// This is the only required option for enabling auto-backup; the other options have sane defaults. - /// If False for a particular region, the auto-backup module becomes a no-op for the region, and all other AutoBackup* settings are ignored. - /// If False globally (the default), only regions that specifically override it in Regions.ini will get AutoBackup functionality. + /// OpenSim.ini only settings section [AutoBackupModule] + /// AutoBackupModuleEnabled: True/False. Default: False. If True, use the auto backup module. + /// if false module is disable and all rest is ignored /// AutoBackupInterval: Double, non-negative value. Default: 720 (12 hours). /// The number of minutes between each backup attempt. - /// If a negative or zero value is given, it is equivalent to setting AutoBackup = False. - /// AutoBackupBusyCheck: True/False. Default: True. - /// If True, we will only take an auto-backup if a set of conditions are met. - /// These conditions are heuristics to try and avoid taking a backup when the sim is busy. + /// AutoBackupDir: String. Default: "." (the current directory). + /// A directory (absolute or relative) where backups should be saved. + /// AutoBackupKeepFilesForDays remove files older than this number of days. 0 disables + /// + /// Next can be set on OpenSim.ini, as default, and or per region in Regions.ini + /// Region-specific settings take precedence. + /// + /// AutoBackup: True/False. Default: False. If True, activate auto backup functionality. + /// controls backup per region, with default optionaly set on OpenSim.ini + /// AutoBackupSkipAssets /// If true, assets are not saved to the oar file. Considerably reduces impact on simulator when backing up. Intended for when assets db is backed up separately /// AutoBackupKeepFilesForDays @@ -89,40 +89,28 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup /// AutoBackupNaming: string. Default: Time. /// One of three strings (case insensitive): /// "Time": Current timestamp is appended to file name. An existing file will never be overwritten. - /// "Sequential": A number is appended to the file name. So if RegionName_x.oar exists, we'll save to RegionName_{x+1}.oar next. An existing file will never be overwritten. - /// "Overwrite": Always save to file named "${AutoBackupDir}/RegionName.oar", even if we have to overwrite an existing file. - /// AutoBackupDir: String. Default: "." (the current directory). - /// A directory (absolute or relative) where backups should be saved. - /// AutoBackupDilationThreshold: float. Default: 0.5. Lower bound on time dilation required for BusyCheck heuristics to pass. - /// If the time dilation is below this value, don't take a backup right now. - /// AutoBackupAgentThreshold: int. Default: 10. Upper bound on # of agents in region required for BusyCheck heuristics to pass. - /// If the number of agents is greater than this value, don't take a backup right now - /// Save memory by setting low initial capacities. Minimizes impact in common cases of all regions using same interval, and instances hosting 1 ~ 4 regions. - /// Also helps if you don't want AutoBackup at all. + /// "Sequential": A number is appended to the file name. So if RegionName_x.oar exists, we'll save to RegionName_{x+1}.oar next. An existing file will never be overwritten. + /// "Overwrite": Always save to file named "${AutoBackupDir}/RegionName.oar", even if we have to overwrite an existing file. /// [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "AutoBackupModule")] public class AutoBackupModule : ISharedRegionModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - private readonly Dictionary m_pendingSaves = new Dictionary(1); private readonly AutoBackupModuleState m_defaultState = new AutoBackupModuleState(); private readonly Dictionary m_states = new Dictionary(1); - private readonly Dictionary> m_timerMap = - new Dictionary>(1); - private readonly Dictionary m_timers = new Dictionary(1); private delegate T DefaultGetter(string settingName, T defaultValue); private bool m_enabled; private ICommandConsole m_console; private List m_Scenes = new List (); - - - /// - /// Whether the shared module should be enabled at all. NOT the same as m_Enabled in AutoBackupModuleState! - /// - private bool m_closed; + private Timer m_masterTimer; + private bool m_busy; + private int m_KeepFilesForDays = -1; + private string m_backupDir; + private bool m_doneFirst; + private double m_baseInterval; private IConfigSource m_configSource; @@ -139,7 +127,7 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup /// /// Identifies the module to the system. /// - string IRegionModuleBase.Name + public string Name { get { return "AutoBackupModule"; } } @@ -147,7 +135,7 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup /// /// We don't implement an interface, this is a single-use module. /// - Type IRegionModuleBase.ReplaceableInterface + public Type ReplaceableInterface { get { return null; } } @@ -156,103 +144,82 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup /// Called once in the lifetime of the module at startup. /// /// The input config source for OpenSim.ini. - void IRegionModuleBase.Initialise(IConfigSource source) + public void Initialise(IConfigSource source) { // Determine if we have been enabled at all in OpenSim.ini -- this is part and parcel of being an optional module - this.m_configSource = source; + m_configSource = source; IConfig moduleConfig = source.Configs["AutoBackupModule"]; if (moduleConfig == null) { - this.m_enabled = false; + m_enabled = false; return; } - else - { - this.m_enabled = moduleConfig.GetBoolean("AutoBackupModuleEnabled", false); - if (this.m_enabled) - { - m_log.Info("[AUTO BACKUP]: AutoBackupModule enabled"); - } - else - { - return; - } - } - Timer defTimer = new Timer(43200000); - this.m_defaultState.Timer = defTimer; - this.m_timers.Add(43200000, defTimer); - defTimer.Elapsed += this.HandleElapsed; - defTimer.AutoReset = true; - defTimer.Start(); + m_enabled = moduleConfig.GetBoolean("AutoBackupModuleEnabled", false); + if(!m_enabled) + return; - AutoBackupModuleState abms = this.ParseConfig(null, true); - m_log.Debug("[AUTO BACKUP]: Here is the default config:"); - m_log.Debug(abms.ToString()); + ParseDefaultConfig(moduleConfig); + if(!m_enabled) + return; + + m_log.Debug("[AUTO BACKUP]: Default config:"); + m_log.Debug(m_defaultState.ToString()); + + m_log.Info("[AUTO BACKUP]: AutoBackupModule enabled"); + m_masterTimer = new Timer(); + m_masterTimer.Interval = m_baseInterval; + m_masterTimer.Elapsed += HandleElapsed; + m_masterTimer.AutoReset = false; + + m_console = MainConsole.Instance; + + m_console.Commands.AddCommand ( + "AutoBackup", true, "dooarbackup", + "dooarbackup | ALL", + "saves the single region to a oar or ALL regions in instance to oars, using same settings as AutoBackup. Note it restarts time interval", DoBackup); + m_busy = true; } /// /// Called once at de-init (sim shutting down). /// - void IRegionModuleBase.Close() + public void Close() { - if (!this.m_enabled) - { + if (!m_enabled) return; - } // We don't want any timers firing while the sim's coming down; strange things may happen. - this.StopAllTimers(); + m_masterTimer.Dispose(); } /// /// Currently a no-op for AutoBackup because we have to wait for region to be fully loaded. /// /// - void IRegionModuleBase.AddRegion (Scene scene) + public void AddRegion (Scene scene) { - if (!this.m_enabled) { + if (!m_enabled) return; - } - lock (m_Scenes) { - m_Scenes.Add (scene); - } - m_console = MainConsole.Instance; - m_console.Commands.AddCommand ( - "AutoBackup", false, "dobackup", - "dobackup", - "do backup.", DoBackup); + lock (m_Scenes) + m_Scenes.Add (scene); } /// /// Here we just clean up some resources and stop the OAR backup (if any) for the given scene. /// /// The scene (region) to stop performing AutoBackup on. - void IRegionModuleBase.RemoveRegion(Scene scene) + public void RemoveRegion(Scene scene) { - if (!this.m_enabled) - { + if (m_enabled) return; - } - m_Scenes.Remove (scene); - if (this.m_states.ContainsKey(scene)) + + lock(m_Scenes) { - AutoBackupModuleState abms = this.m_states[scene]; - - // Remove this scene out of the timer map list - Timer timer = abms.Timer; - List list = this.m_timerMap[timer]; - list.Remove(scene); - - // Shut down the timer if this was the last scene for the timer - if (list.Count == 0) - { - this.m_timerMap.Remove(timer); - this.m_timers.Remove(timer.Interval); - timer.Close(); - } - this.m_states.Remove(scene); + if (m_states.ContainsKey(scene)) + m_states.Remove(scene); + m_Scenes.Remove(scene); } } @@ -261,30 +228,37 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup /// We read lots of Nini config, maybe set a timer, add members to state tracking Dictionaries, etc. /// /// The scene to (possibly) perform AutoBackup on. - void IRegionModuleBase.RegionLoaded(Scene scene) + public void RegionLoaded(Scene scene) { - if (!this.m_enabled) - { + if (!m_enabled) return; - } // This really ought not to happen, but just in case, let's pretend it didn't... if (scene == null) - { return; + + AutoBackupModuleState abms = ParseConfig(scene); + if(abms == null) + { + m_log.Debug("[AUTO BACKUP]: Config for " + scene.RegionInfo.RegionName); + m_log.Debug("DEFAULT"); + abms = new AutoBackupModuleState(m_defaultState); + } + else + { + m_log.Debug("[AUTO BACKUP]: Config for " + scene.RegionInfo.RegionName); + m_log.Debug(abms.ToString()); } - AutoBackupModuleState abms = this.ParseConfig(scene, false); - m_log.Debug("[AUTO BACKUP]: Config for " + scene.RegionInfo.RegionName); - m_log.Debug((abms == null ? "DEFAULT" : abms.ToString())); - m_states.Add(scene, abms); + m_busy = false; + m_masterTimer.Start(); } /// /// Currently a no-op. /// - void ISharedRegionModule.PostInitialise() + public void PostInitialise() { } @@ -292,24 +266,122 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup private void DoBackup (string module, string[] args) { - if (args.Length != 2) { - MainConsole.Instance.OutputFormat ("Usage: dobackup "); + if (!m_enabled) + return; + + if (args.Length != 2) + { + MainConsole.Instance.OutputFormat ("Usage: dooarbackup "); return; } + + if(m_busy) + { + MainConsole.Instance.OutputFormat ("Already doing a backup, please try later"); + return; + } + + m_masterTimer.Stop(); + m_busy = true; + bool found = false; string name = args [1]; - lock (m_Scenes) { - foreach (Scene s in m_Scenes) { - string test = s.Name.ToString (); - if (test == name) { + Scene[] scenes; + lock (m_Scenes) + scenes = m_Scenes.ToArray(); + + if(scenes == null) + return; + + Scene s; + try + { + if(name == "ALL") + { + for(int i = 0; i < scenes.Length; i++) + { + s = scenes[i]; + DoRegionBackup(s); + if (!m_enabled) + return; + } + return; + } + + for(int i = 0; i < scenes.Length; i++) + { + s = scenes[i]; + if (s.Name == name) + { found = true; - DoRegionBackup (s); + DoRegionBackup(s); + break; } } - if (!found) { + } + catch { } + finally + { + if (m_enabled) + m_masterTimer.Start(); + m_busy = false; + } + if (!found) MainConsole.Instance.OutputFormat ("No such region {0}. Nothing to backup", name); + } + + private void ParseDefaultConfig(IConfig config) + { + + m_backupDir = "."; + string backupDir = config.GetString("AutoBackupDir", "."); + if (backupDir != ".") + { + try + { + DirectoryInfo dirinfo = new DirectoryInfo(backupDir); + if (!dirinfo.Exists) + dirinfo.Create(); + } + catch (Exception e) + { + m_enabled = false; + m_log.WarnFormat("[AUTO BACKUP]: Error accessing backup folder {0}. Module disabled. {1}", + backupDir, e); + return; } } + m_backupDir = backupDir; + + double interval = config.GetDouble("AutoBackupInterval", 720); + interval *= 60000.0; + m_baseInterval = interval; + + // How long to keep backup files in days, 0 Disables this feature + m_KeepFilesForDays = config.GetInt("AutoBackupKeepFilesForDays",m_KeepFilesForDays); + + m_defaultState.Enabled = config.GetBoolean("AutoBackup", m_defaultState.Enabled); + + m_defaultState.SkipAssets = config.GetBoolean("AutoBackupSkipAssets",m_defaultState.SkipAssets); + + // Set file naming algorithm + string stmpNamingType = config.GetString("AutoBackupNaming", m_defaultState.NamingType.ToString()); + NamingType tmpNamingType; + if (stmpNamingType.Equals("Time", StringComparison.CurrentCultureIgnoreCase)) + tmpNamingType = NamingType.Time; + else if (stmpNamingType.Equals("Sequential", StringComparison.CurrentCultureIgnoreCase)) + tmpNamingType = NamingType.Sequential; + else if (stmpNamingType.Equals("Overwrite", StringComparison.CurrentCultureIgnoreCase)) + tmpNamingType = NamingType.Overwrite; + else + { + m_log.Warn("Unknown naming type specified for Default"); + tmpNamingType = NamingType.Time; + } + m_defaultState.NamingType = tmpNamingType; + + m_defaultState.Script = config.GetString("AutoBackupScript", m_defaultState.Script); + } /// @@ -319,329 +391,49 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup /// The scene to look at. /// Whether this call is intended to figure out what we consider the "default" config (applied to all regions unless overridden by per-region settings). /// An AutoBackupModuleState contains most information you should need to know relevant to auto-backup, as applicable to a single region. - private AutoBackupModuleState ParseConfig(IScene scene, bool parseDefault) + private AutoBackupModuleState ParseConfig(IScene scene) { - string sRegionName; - string sRegionLabel; -// string prepend; - AutoBackupModuleState state; + if(scene == null) + return null; - if (parseDefault) - { - sRegionName = null; - sRegionLabel = "DEFAULT"; -// prepend = ""; - state = this.m_defaultState; - } - else - { - sRegionName = scene.RegionInfo.RegionName; - sRegionLabel = sRegionName; -// prepend = sRegionName + "."; - state = null; - } + string sRegionName; + AutoBackupModuleState state = null; + + sRegionName = scene.RegionInfo.RegionName; // Read the config settings and set variables. - IConfig regionConfig = (scene != null ? scene.Config.Configs[sRegionName] : null); - IConfig config = this.m_configSource.Configs["AutoBackupModule"]; - if (config == null) - { - // defaultState would be disabled too if the section doesn't exist. - state = this.m_defaultState; - return state; - } + IConfig regionConfig = scene.Config.Configs[sRegionName]; + if (regionConfig == null) + return null; - bool tmpEnabled = ResolveBoolean("AutoBackup", this.m_defaultState.Enabled, config, regionConfig); - if (state == null && tmpEnabled != this.m_defaultState.Enabled) - //Varies from default state - { - state = new AutoBackupModuleState(); - } + state = new AutoBackupModuleState(); - if (state != null) - { - state.Enabled = tmpEnabled; - } - - // If you don't want AutoBackup, we stop. - if ((state == null && !this.m_defaultState.Enabled) || (state != null && !state.Enabled)) - { - return state; - } - else - { - m_log.Info("[AUTO BACKUP]: Region " + sRegionLabel + " is AutoBackup ENABLED."); - } - - // Borrow an existing timer if one exists for the same interval; otherwise, make a new one. - double interval = - this.ResolveDouble("AutoBackupInterval", this.m_defaultState.IntervalMinutes, - config, regionConfig) * 60000.0; - if (state == null && interval != this.m_defaultState.IntervalMinutes * 60000.0) - { - state = new AutoBackupModuleState(); - } - - if (this.m_timers.ContainsKey(interval)) - { - if (state != null) - { - state.Timer = this.m_timers[interval]; - } - m_log.Debug("[AUTO BACKUP]: Reusing timer for " + interval + " msec for region " + - sRegionLabel); - } - else - { - // 0 or negative interval == do nothing. - if (interval <= 0.0 && state != null) - { - state.Enabled = false; - return state; - } - if (state == null) - { - state = new AutoBackupModuleState(); - } - Timer tim = new Timer(interval); - state.Timer = tim; - //Milliseconds -> minutes - this.m_timers.Add(interval, tim); - tim.Elapsed += this.HandleElapsed; - tim.AutoReset = true; - tim.Start(); - } - - // Add the current region to the list of regions tied to this timer. - if (scene != null) - { - if (state != null) - { - if (this.m_timerMap.ContainsKey(state.Timer)) - { - this.m_timerMap[state.Timer].Add(scene); - } - else - { - List scns = new List(1); - scns.Add(scene); - this.m_timerMap.Add(state.Timer, scns); - } - } - else - { - if (this.m_timerMap.ContainsKey(this.m_defaultState.Timer)) - { - this.m_timerMap[this.m_defaultState.Timer].Add(scene); - } - else - { - List scns = new List(1); - scns.Add(scene); - this.m_timerMap.Add(this.m_defaultState.Timer, scns); - } - } - } - - bool tmpBusyCheck = ResolveBoolean("AutoBackupBusyCheck", - this.m_defaultState.BusyCheck, config, regionConfig); - if (state == null && tmpBusyCheck != this.m_defaultState.BusyCheck) - { - state = new AutoBackupModuleState(); - } - - if (state != null) - { - state.BusyCheck = tmpBusyCheck; - } + state.Enabled = regionConfig.GetBoolean("AutoBackup", m_defaultState.Enabled); // Included Option To Skip Assets - bool tmpSkipAssets = ResolveBoolean("AutoBackupSkipAssets", - this.m_defaultState.SkipAssets, config, regionConfig); - if (state == null && tmpSkipAssets != this.m_defaultState.SkipAssets) - { - state = new AutoBackupModuleState(); - } - - if (state != null) - { - state.SkipAssets = tmpSkipAssets; - } - - // How long to keep backup files in days, 0 Disables this feature - int tmpKeepFilesForDays = ResolveInt("AutoBackupKeepFilesForDays", - this.m_defaultState.KeepFilesForDays, config, regionConfig); - if (state == null && tmpKeepFilesForDays != this.m_defaultState.KeepFilesForDays) - { - state = new AutoBackupModuleState(); - } - - if (state != null) - { - state.KeepFilesForDays = tmpKeepFilesForDays; - } + state.SkipAssets = regionConfig.GetBoolean("AutoBackupSkipAssets", m_defaultState.SkipAssets); // Set file naming algorithm - string stmpNamingType = ResolveString("AutoBackupNaming", - this.m_defaultState.NamingType.ToString(), config, regionConfig); + string stmpNamingType = regionConfig.GetString("AutoBackupNaming", m_defaultState.NamingType.ToString()); NamingType tmpNamingType; if (stmpNamingType.Equals("Time", StringComparison.CurrentCultureIgnoreCase)) - { tmpNamingType = NamingType.Time; - } else if (stmpNamingType.Equals("Sequential", StringComparison.CurrentCultureIgnoreCase)) - { tmpNamingType = NamingType.Sequential; - } else if (stmpNamingType.Equals("Overwrite", StringComparison.CurrentCultureIgnoreCase)) - { tmpNamingType = NamingType.Overwrite; - } else { - m_log.Warn("Unknown naming type specified for region " + sRegionLabel + ": " + + m_log.Warn("Unknown naming type specified for region " + sRegionName + ": " + stmpNamingType); tmpNamingType = NamingType.Time; } + m_defaultState.NamingType = tmpNamingType; - if (state == null && tmpNamingType != this.m_defaultState.NamingType) - { - state = new AutoBackupModuleState(); - } - - if (state != null) - { - state.NamingType = tmpNamingType; - } - - string tmpScript = ResolveString("AutoBackupScript", - this.m_defaultState.Script, config, regionConfig); - if (state == null && tmpScript != this.m_defaultState.Script) - { - state = new AutoBackupModuleState(); - } - - if (state != null) - { - state.Script = tmpScript; - } - - string tmpBackupDir = ResolveString("AutoBackupDir", ".", config, regionConfig); - if (state == null && tmpBackupDir != this.m_defaultState.BackupDir) - { - state = new AutoBackupModuleState(); - } - - if (state != null) - { - state.BackupDir = tmpBackupDir; - // Let's give the user some convenience and auto-mkdir - if (state.BackupDir != ".") - { - try - { - DirectoryInfo dirinfo = new DirectoryInfo(state.BackupDir); - if (!dirinfo.Exists) - { - dirinfo.Create(); - } - } - catch (Exception e) - { - m_log.Warn( - "[AUTO BACKUP]: BAD NEWS. You won't be able to save backups to directory " + - state.BackupDir + - " because it doesn't exist or there's a permissions issue with it. Here's the exception.", - e); - } - } - } - - if(state == null) - return m_defaultState; - + state.Script = regionConfig.GetString("AutoBackupScript", m_defaultState.Script); return state; } - /// - /// Helper function for ParseConfig. - /// - /// - /// - /// - /// - /// - private bool ResolveBoolean(string settingName, bool defaultValue, IConfig global, IConfig local) - { - if(local != null) - { - return local.GetBoolean(settingName, global.GetBoolean(settingName, defaultValue)); - } - else - { - return global.GetBoolean(settingName, defaultValue); - } - } - - /// - /// Helper function for ParseConfig. - /// - /// - /// - /// - /// - /// - private double ResolveDouble(string settingName, double defaultValue, IConfig global, IConfig local) - { - if (local != null) - { - return local.GetDouble(settingName, global.GetDouble(settingName, defaultValue)); - } - else - { - return global.GetDouble(settingName, defaultValue); - } - } - - /// - /// Helper function for ParseConfig. - /// - /// - /// - /// - /// - /// - private int ResolveInt(string settingName, int defaultValue, IConfig global, IConfig local) - { - if (local != null) - { - return local.GetInt(settingName, global.GetInt(settingName, defaultValue)); - } - else - { - return global.GetInt(settingName, defaultValue); - } - } - - /// - /// Helper function for ParseConfig. - /// - /// - /// - /// - /// - /// - private string ResolveString(string settingName, string defaultValue, IConfig global, IConfig local) - { - if (local != null) - { - return local.GetString(settingName, global.GetString(settingName, defaultValue)); - } - else - { - return global.GetString(settingName, defaultValue); - } - } /// /// Called when any auto-backup timer expires. This starts the code path for actually performing a backup. @@ -650,63 +442,27 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup /// private void HandleElapsed(object sender, ElapsedEventArgs e) { - // TODO: heuristic thresholds are per-region, so we should probably run heuristics once per region - // XXX: Running heuristics once per region could add undue performance penalty for something that's supposed to - // check whether the region is too busy! Especially on sims with LOTS of regions. - // Alternative: make heuristics thresholds global to the module rather than per-region. Less flexible, - // but would allow us to be semantically correct while being easier on perf. - // Alternative 2: Run heuristics once per unique set of heuristics threshold parameters! Ay yi yi... - // Alternative 3: Don't support per-region heuristics at all; just accept them as a global only parameter. - // Since this is pretty experimental, I haven't decided which alternative makes the most sense. - if (this.m_closed) - { + if (!m_enabled || m_busy) return; - } - bool heuristicsRun = false; - bool heuristicsPassed = false; - if (!this.m_timerMap.ContainsKey((Timer) sender)) + + m_busy = true; + if(m_doneFirst && m_KeepFilesForDays > 0) + RemoveOldFiles(); + + foreach (IScene scene in m_Scenes) { - m_log.Debug("[AUTO BACKUP]: Code-up error: timerMap doesn't contain timer " + sender); + if (!m_enabled) + return; + DoRegionBackup(scene); } - List tmap = this.m_timerMap[(Timer) sender]; - if (tmap != null && tmap.Count > 0) + if (m_enabled) { - foreach (IScene scene in tmap) - { - AutoBackupModuleState state = this.m_states[scene]; - bool heuristics = state.BusyCheck; - - // Fast path: heuristics are on; already ran em; and sim is fine; OR, no heuristics for the region. - if ((heuristics && heuristicsRun && heuristicsPassed) || !heuristics) - { - this.DoRegionBackup(scene); - // Heuristics are on; ran but we're too busy -- keep going. Maybe another region will have heuristics off! - } - else if (heuristicsRun) - { - m_log.Info("[AUTO BACKUP]: Heuristics: too busy to backup " + - scene.RegionInfo.RegionName + " right now."); - continue; - // Logical Deduction: heuristics are on but haven't been run - } - else - { - heuristicsPassed = this.RunHeuristics(scene); - heuristicsRun = true; - if (!heuristicsPassed) - { - m_log.Info("[AUTO BACKUP]: Heuristics: too busy to backup " + - scene.RegionInfo.RegionName + " right now."); - continue; - } - this.DoRegionBackup(scene); - } - - // Remove Old Backups - this.RemoveOldFiles(state); - } + m_masterTimer.Start(); + m_busy = false; } + + m_doneFirst = true; } /// @@ -723,21 +479,29 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup return; } - AutoBackupModuleState state = this.m_states[scene]; + m_busy = true; + + AutoBackupModuleState state; + if(!m_states.TryGetValue(scene, out state)) + return; + + if(state == null || !state.Enabled) + return; + IRegionArchiverModule iram = scene.RequestModuleInterface(); + if(iram == null) + return; + string savePath = BuildOarPath(scene.RegionInfo.RegionName, - state.BackupDir, + m_backupDir, state.NamingType); if (savePath == null) { m_log.Warn("[AUTO BACKUP]: savePath is null in HandleElapsed"); return; } - Guid guid = Guid.NewGuid(); - m_pendingSaves.Add(guid, scene); - state.LiveRequests.Add(guid, savePath); - ((Scene) scene).EventManager.OnOarFileSaved += new EventManager.OarFileSaved(EventManager_OnOarFileSaved); + Guid guid = Guid.NewGuid(); m_log.Info("[AUTO BACKUP]: Backing up region " + scene.RegionInfo.RegionName); // Must pass options, even if dictionary is empty! @@ -747,47 +511,37 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup options["noassets"] = true; iram.ArchiveRegion(savePath, guid, options); + ExecuteScript(state.Script, savePath); } // For the given state, remove backup files older than the states KeepFilesForDays property - private void RemoveOldFiles(AutoBackupModuleState state) + private void RemoveOldFiles() { - // 0 Means Disabled, Keep Files Indefinitely - if (state.KeepFilesForDays > 0) + string[] files; + try { - string[] files = Directory.GetFiles(state.BackupDir, "*.oar"); - DateTime CuttOffDate = DateTime.Now.AddDays(0 - state.KeepFilesForDays); - - foreach (string file in files) - { - try - { - FileInfo fi = new FileInfo(file); - if (fi.CreationTime < CuttOffDate) - fi.Delete(); - } - catch (Exception Ex) - { - m_log.Error("[AUTO BACKUP]: Error deleting old backup file '" + file + "': " + Ex.Message); - } - } + files = Directory.GetFiles(m_backupDir, "*.oar"); } - } - - /// - /// Called by the Event Manager when the OnOarFileSaved event is fired. - /// - /// - /// - void EventManager_OnOarFileSaved(Guid guid, string message) - { - // Ignore if the OAR save is being done by some other part of the system - if (m_pendingSaves.ContainsKey(guid)) + catch (Exception Ex) { - AutoBackupModuleState abms = m_states[(m_pendingSaves[guid])]; - ExecuteScript(abms.Script, abms.LiveRequests[guid]); - m_pendingSaves.Remove(guid); - abms.LiveRequests.Remove(guid); + m_log.Error("[AUTO BACKUP]: Error reading backup folder " + m_backupDir + ": " + Ex.Message); + return; + } + + DateTime CuttOffDate = DateTime.Now.AddDays(-m_KeepFilesForDays); + + foreach (string file in files) + { + try + { + FileInfo fi = new FileInfo(file); + if (fi.CreationTime < CuttOffDate) + fi.Delete(); + } + catch (Exception Ex) + { + m_log.Error("[AUTO BACKUP]: Error deleting old backup file '" + file + "': " + Ex.Message); + } } } @@ -817,63 +571,6 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup return output; } - /// Return value of true ==> not too busy; false ==> too busy to backup an OAR right now, or error. - private bool RunHeuristics(IScene region) - { - try - { - return this.RunTimeDilationHeuristic(region) && this.RunAgentLimitHeuristic(region); - } - catch (Exception e) - { - m_log.Warn("[AUTO BACKUP]: Exception in RunHeuristics", e); - return false; - } - } - - /// - /// If the time dilation right at this instant is less than the threshold specified in AutoBackupDilationThreshold (default 0.5), - /// then we return false and trip the busy heuristic's "too busy" path (i.e. don't save an OAR). - /// AutoBackupDilationThreshold is a _LOWER BOUND_. Lower Time Dilation is bad, so if you go lower than our threshold, it's "too busy". - /// - /// - /// Returns true if we're not too busy; false means we've got worse time dilation than the threshold. - private bool RunTimeDilationHeuristic(IScene region) - { - string regionName = region.RegionInfo.RegionName; - return region.TimeDilation >= - this.m_configSource.Configs["AutoBackupModule"].GetFloat( - regionName + ".AutoBackupDilationThreshold", 0.5f); - } - - /// - /// If the root agent count right at this instant is less than the threshold specified in AutoBackupAgentThreshold (default 10), - /// then we return false and trip the busy heuristic's "too busy" path (i.e., don't save an OAR). - /// AutoBackupAgentThreshold is an _UPPER BOUND_. Higher Agent Count is bad, so if you go higher than our threshold, it's "too busy". - /// - /// - /// Returns true if we're not too busy; false means we've got more agents on the sim than the threshold. - private bool RunAgentLimitHeuristic(IScene region) - { - string regionName = region.RegionInfo.RegionName; - try - { - Scene scene = (Scene) region; - // TODO: Why isn't GetRootAgentCount() a method in the IScene interface? Seems generally useful... - return scene.GetRootAgentCount() <= - this.m_configSource.Configs["AutoBackupModule"].GetInt( - regionName + ".AutoBackupAgentThreshold", 10); - } - catch (InvalidCastException ice) - { - m_log.Debug( - "[AUTO BACKUP]: I NEED MAINTENANCE: IScene is not a Scene; can't get root agent count!", - ice); - return true; - // Non-obstructionist safest answer... - } - } - /// /// Run the script or executable specified by the "AutoBackupScript" config setting. /// Of course this is a security risk if you let anyone modify OpenSim.ini and they want to run some nasty bash script. @@ -919,18 +616,6 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup " is yacking on stderr: " + e.Data); } - /// - /// Quickly stop all timers from firing. - /// - private void StopAllTimers() - { - foreach (Timer t in this.m_timerMap.Keys) - { - t.Close(); - } - this.m_closed = true; - } - /// /// Determine the next unique filename by number, for "Sequential" AutoBackupNamingType. /// @@ -1033,5 +718,3 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup } } } - - diff --git a/OpenSim/Region/OptionalModules/World/AutoBackup/AutoBackupModuleState.cs b/OpenSim/Region/OptionalModules/World/AutoBackup/AutoBackupModuleState.cs index b90f0c4740..fb87677d62 100644 --- a/OpenSim/Region/OptionalModules/World/AutoBackup/AutoBackupModuleState.cs +++ b/OpenSim/Region/OptionalModules/World/AutoBackup/AutoBackupModuleState.cs @@ -38,26 +38,20 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup /// public class AutoBackupModuleState { - private Dictionary m_liveRequests = null; - public AutoBackupModuleState() { - this.Enabled = false; - this.BackupDir = "."; - this.BusyCheck = true; - this.SkipAssets = false; - this.Timer = null; - this.NamingType = NamingType.Time; - this.Script = null; - this.KeepFilesForDays = 0; + Enabled = false; + SkipAssets = false; + NamingType = NamingType.Time; + Script = null; } - public Dictionary LiveRequests + public AutoBackupModuleState(AutoBackupModuleState copyFrom) { - get { - return this.m_liveRequests ?? - (this.m_liveRequests = new Dictionary(1)); - } + Enabled = copyFrom.Enabled; + SkipAssets = copyFrom.SkipAssets; + NamingType = copyFrom.NamingType; + Script = copyFrom.Script; } public bool Enabled @@ -66,33 +60,6 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup set; } - public System.Timers.Timer Timer - { - get; - set; - } - - public double IntervalMinutes - { - get - { - if (this.Timer == null) - { - return -1.0; - } - else - { - return this.Timer.Interval / 60000.0; - } - } - } - - public bool BusyCheck - { - get; - set; - } - public bool SkipAssets { get; @@ -105,36 +72,19 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup set; } - public string BackupDir - { - get; - set; - } - public NamingType NamingType { get; set; } - public int KeepFilesForDays - { - get; - set; - } - public new string ToString() { string retval = ""; - retval += "[AUTO BACKUP]: AutoBackup: " + (Enabled ? "ENABLED" : "DISABLED") + "\n"; - retval += "[AUTO BACKUP]: Interval: " + IntervalMinutes + " minutes" + "\n"; - retval += "[AUTO BACKUP]: Do Busy Check: " + (BusyCheck ? "Yes" : "No") + "\n"; retval += "[AUTO BACKUP]: Naming Type: " + NamingType.ToString() + "\n"; - retval += "[AUTO BACKUP]: Backup Dir: " + BackupDir + "\n"; retval += "[AUTO BACKUP]: Script: " + Script + "\n"; return retval; } } } - diff --git a/OpenSim/Region/OptionalModules/World/MoneyModule/SampleMoneyModule.cs b/OpenSim/Region/OptionalModules/World/MoneyModule/SampleMoneyModule.cs index 47edeb9221..b32a4290c6 100644 --- a/OpenSim/Region/OptionalModules/World/MoneyModule/SampleMoneyModule.cs +++ b/OpenSim/Region/OptionalModules/World/MoneyModule/SampleMoneyModule.cs @@ -65,10 +65,10 @@ namespace OpenSim.Region.OptionalModules.World.MoneyModule /// // private UUID EconomyBaseAccount = UUID.Zero; - private float EnergyEfficiency = 0f; + private float EnergyEfficiency = 1f; // private ObjectPaid handerOnObjectPaid; private bool m_enabled = true; - private bool m_sellEnabled = false; + private bool m_sellEnabled = true; private IConfigSource m_gConfig; @@ -85,12 +85,12 @@ namespace OpenSim.Region.OptionalModules.World.MoneyModule private int ObjectCount = 0; private int PriceEnergyUnit = 0; - private int PriceGroupCreate = 0; + private int PriceGroupCreate = -1; private int PriceObjectClaim = 0; private float PriceObjectRent = 0f; - private float PriceObjectScaleFactor = 0f; + private float PriceObjectScaleFactor = 10f; private int PriceParcelClaim = 0; - private float PriceParcelClaimFactor = 0f; + private float PriceParcelClaimFactor = 1f; private int PriceParcelRent = 0; private int PricePublicObjectDecay = 0; private int PricePublicObjectDelete = 0; @@ -98,7 +98,7 @@ namespace OpenSim.Region.OptionalModules.World.MoneyModule private int PriceUpload = 0; private int TeleportMinPrice = 0; - private float TeleportPriceExponent = 0f; + private float TeleportPriceExponent = 2f; #region IMoneyModule Members @@ -124,13 +124,7 @@ namespace OpenSim.Region.OptionalModules.World.MoneyModule public void Initialise(IConfigSource config) { m_gConfig = config; - - IConfig startupConfig = m_gConfig.Configs["Startup"]; - IConfig economyConfig = m_gConfig.Configs["Economy"]; - - - ReadConfigAndPopulate(startupConfig, "Startup"); - ReadConfigAndPopulate(economyConfig, "Economy"); + ReadConfigAndPopulate(); } public void AddRegion(Scene scene) @@ -241,35 +235,51 @@ namespace OpenSim.Region.OptionalModules.World.MoneyModule /// /// Parse Configuration /// - /// - /// - /// - private void ReadConfigAndPopulate(IConfig startupConfig, string config) + private void ReadConfigAndPopulate() { - if (config == "Startup" && startupConfig != null) + // we are enabled by default + + IConfig startupConfig = m_gConfig.Configs["Startup"]; + + if(startupConfig == null) // should not happen + return; + + IConfig economyConfig = m_gConfig.Configs["Economy"]; + + // economymodule may be at startup or Economy (legacy) + string mmodule = startupConfig.GetString("economymodule",""); + if(String.IsNullOrEmpty(mmodule)) { - m_enabled = (startupConfig.GetString("economymodule", "BetaGridLikeMoneyModule") == "BetaGridLikeMoneyModule"); + if(economyConfig != null) + mmodule = economyConfig.GetString("economymodule",""); } - if (config == "Economy" && startupConfig != null) + if(!String.IsNullOrEmpty(mmodule) && mmodule != Name) { - PriceEnergyUnit = startupConfig.GetInt("PriceEnergyUnit", 100); - PriceObjectClaim = startupConfig.GetInt("PriceObjectClaim", 10); - PricePublicObjectDecay = startupConfig.GetInt("PricePublicObjectDecay", 4); - PricePublicObjectDelete = startupConfig.GetInt("PricePublicObjectDelete", 4); - PriceParcelClaim = startupConfig.GetInt("PriceParcelClaim", 1); - PriceParcelClaimFactor = startupConfig.GetFloat("PriceParcelClaimFactor", 1f); - PriceUpload = startupConfig.GetInt("PriceUpload", 0); - PriceRentLight = startupConfig.GetInt("PriceRentLight", 5); - TeleportMinPrice = startupConfig.GetInt("TeleportMinPrice", 2); - TeleportPriceExponent = startupConfig.GetFloat("TeleportPriceExponent", 2f); - EnergyEfficiency = startupConfig.GetFloat("EnergyEfficiency", 1); - PriceObjectRent = startupConfig.GetFloat("PriceObjectRent", 1); - PriceObjectScaleFactor = startupConfig.GetFloat("PriceObjectScaleFactor", 10); - PriceParcelRent = startupConfig.GetInt("PriceParcelRent", 1); - PriceGroupCreate = startupConfig.GetInt("PriceGroupCreate", -1); - m_sellEnabled = startupConfig.GetBoolean("SellEnabled", false); + // some other money module selected + m_enabled = false; + return; } + + if(economyConfig == null) + return; + + PriceEnergyUnit = economyConfig.GetInt("PriceEnergyUnit", 0); + PriceObjectClaim = economyConfig.GetInt("PriceObjectClaim", 0); + PricePublicObjectDecay = economyConfig.GetInt("PricePublicObjectDecay", 4); + PricePublicObjectDelete = economyConfig.GetInt("PricePublicObjectDelete", 0); + PriceParcelClaim = economyConfig.GetInt("PriceParcelClaim", 0); + PriceParcelClaimFactor = economyConfig.GetFloat("PriceParcelClaimFactor", 1f); + PriceUpload = economyConfig.GetInt("PriceUpload", 0); + PriceRentLight = economyConfig.GetInt("PriceRentLight", 0); + TeleportMinPrice = economyConfig.GetInt("TeleportMinPrice", 0); + TeleportPriceExponent = economyConfig.GetFloat("TeleportPriceExponent", 2f); + EnergyEfficiency = economyConfig.GetFloat("EnergyEfficiency", 1); + PriceObjectRent = economyConfig.GetFloat("PriceObjectRent", 0); + PriceObjectScaleFactor = economyConfig.GetFloat("PriceObjectScaleFactor", 10); + PriceParcelRent = economyConfig.GetInt("PriceParcelRent", 0); + PriceGroupCreate = economyConfig.GetInt("PriceGroupCreate", -1); + m_sellEnabled = economyConfig.GetBoolean("SellEnabled", true); } private void GetClientFunds(IClientAPI client) @@ -844,9 +854,14 @@ namespace OpenSim.Region.OptionalModules.World.MoneyModule module.BuyObject(remoteClient, categoryID, localID, saleType, salePrice); } - public void MoveMoney(UUID fromAgentID, UUID toAgentID, int amount, string text) + public void MoveMoney(UUID fromUser, UUID toUser, int amount, string text) { } + + public bool MoveMoney(UUID fromUser, UUID toUser, int amount, MoneyTransactionType type, string text) + { + return true; + } } public enum TransactionType : int diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs index 6a7c735fd6..bb23f2fb1f 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs @@ -813,7 +813,11 @@ namespace OpenSim.Region.OptionalModules.World.NPC { } - public void SendAvatarDataImmediate(ISceneEntity avatar) + public void SendEntityFullUpdateImmediate(ISceneEntity avatar) + { + } + + public void SendEntityTerseUpdateImmediate(ISceneEntity ent) { } @@ -1310,6 +1314,10 @@ namespace OpenSim.Region.OptionalModules.World.NPC { } + public void SendEmpytMuteList() + { + } + public void SendMuteListUpdate(string filename) { } diff --git a/OpenSim/Region/OptionalModules/World/SceneCommands/SceneCommandsModule.cs b/OpenSim/Region/OptionalModules/World/SceneCommands/SceneCommandsModule.cs index d0d726c96b..f406ca6adc 100644 --- a/OpenSim/Region/OptionalModules/World/SceneCommands/SceneCommandsModule.cs +++ b/OpenSim/Region/OptionalModules/World/SceneCommands/SceneCommandsModule.cs @@ -96,18 +96,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments "List current scene options.", "active - if false then main scene update and maintenance loops are suspended.\n" + "animations - if true then extra animations debug information is logged.\n" - + "appear-refresh - if true then appearance is resent to other avatars every 60 seconds.\n" - + "client-pos-upd - the tolerance before clients are updated with new rotation information for an avatar.\n" - + "client-rot-upd - the tolerance before clients are updated with new rotation information for an avatar.\n" - + "client-vel-upd - the tolerance before clients are updated with new velocity information for an avatar.\n" - + "root-upd-per - if greater than 1, terse updates are only sent to root agents other than the originator on every n updates.\n" - + "child-upd-per - if greater than 1, terse updates are only sent to child agents on every n updates.\n" + "collisions - if false then collisions with other objects are turned off.\n" + "pbackup - if false then periodic scene backup is turned off.\n" + "physics - if false then all physics objects are non-physical.\n" + "scripting - if false then no scripting operations happen.\n" + "teleport - if true then some extra teleport debug information is logged.\n" - + "update-on-timer - If true then the scene is updated via a timer. If false then a thread with sleep is used.\n" + "updates - if true then any frame which exceeds double the maximum desired frame time is logged.", HandleDebugSceneGetCommand); @@ -117,18 +110,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments "Turn on scene debugging options.", "active - if false then main scene update and maintenance loops are suspended.\n" + "animations - if true then extra animations debug information is logged.\n" - + "appear-refresh - if true then appearance is resent to other avatars every 60 seconds.\n" - + "client-pos-upd - the tolerance before clients are updated with new rotation information for an avatar.\n" - + "client-rot-upd - the tolerance before clients are updated with new rotation information for an avatar.\n" - + "client-vel-upd - the tolerance before clients are updated with new velocity information for an avatar.\n" - + "root-upd-per - if greater than 1, terse updates are only sent to root agents other than the originator on every n updates.\n" - + "child-upd-per - if greater than 1, terse updates are only sent to child agents on every n updates.\n" + "collisions - if false then collisions with other objects are turned off.\n" + "pbackup - if false then periodic scene backup is turned off.\n" + "physics - if false then all physics objects are non-physical.\n" + "scripting - if false then no scripting operations happen.\n" + "teleport - if true then some extra teleport debug information is logged.\n" - + "update-on-timer - If true then the scene is updated via a timer. If false then a thread with sleep is used.\n" + "updates - if true then any frame which exceeds double the maximum desired frame time is logged.", HandleDebugSceneSetCommand); } @@ -153,17 +139,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments ConsoleDisplayList cdl = new ConsoleDisplayList(); cdl.AddRow("active", m_scene.Active); cdl.AddRow("animations", m_scene.DebugAnimations); - cdl.AddRow("appear-refresh", m_scene.SendPeriodicAppearanceUpdates); - cdl.AddRow("client-pos-upd", m_scene.RootPositionUpdateTolerance); - cdl.AddRow("client-rot-upd", m_scene.RootRotationUpdateTolerance); - cdl.AddRow("client-vel-upd", m_scene.RootVelocityUpdateTolerance); - cdl.AddRow("root-upd-per", m_scene.RootTerseUpdatePeriod); - cdl.AddRow("child-upd-per", m_scene.ChildTerseUpdatePeriod); cdl.AddRow("pbackup", m_scene.PeriodicBackup); cdl.AddRow("physics", m_scene.PhysicsEnabled); cdl.AddRow("scripting", m_scene.ScriptsEnabled); cdl.AddRow("teleport", m_scene.DebugTeleporting); -// cdl.AddRow("update-on-timer", m_scene.UpdateOnTimer); cdl.AddRow("updates", m_scene.DebugUpdates); MainConsole.Instance.OutputFormat("Scene {0} options:", m_scene.Name); @@ -207,60 +186,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments m_scene.DebugAnimations = active; } - if (options.ContainsKey("appear-refresh")) - { - bool newValue; - - // FIXME: This can only come from the console at the moment but might not always be true. - if (ConsoleUtil.TryParseConsoleBool(MainConsole.Instance, options["appear-refresh"], out newValue)) - m_scene.SendPeriodicAppearanceUpdates = newValue; - } - - if (options.ContainsKey("client-pos-upd")) - { - float newValue; - - // FIXME: This can only come from the console at the moment but might not always be true. - if (ConsoleUtil.TryParseConsoleFloat(MainConsole.Instance, options["client-pos-upd"], out newValue)) - m_scene.RootPositionUpdateTolerance = newValue; - } - - if (options.ContainsKey("client-rot-upd")) - { - float newValue; - - // FIXME: This can only come from the console at the moment but might not always be true. - if (ConsoleUtil.TryParseConsoleFloat(MainConsole.Instance, options["client-rot-upd"], out newValue)) - m_scene.RootRotationUpdateTolerance = newValue; - } - - if (options.ContainsKey("client-vel-upd")) - { - float newValue; - - // FIXME: This can only come from the console at the moment but might not always be true. - if (ConsoleUtil.TryParseConsoleFloat(MainConsole.Instance, options["client-vel-upd"], out newValue)) - m_scene.RootVelocityUpdateTolerance = newValue; - } - - if (options.ContainsKey("root-upd-per")) - { - int newValue; - - // FIXME: This can only come from the console at the moment but might not always be true. - if (ConsoleUtil.TryParseConsoleNaturalInt(MainConsole.Instance, options["root-upd-per"], out newValue)) - m_scene.RootTerseUpdatePeriod = newValue; - } - - if (options.ContainsKey("child-upd-per")) - { - int newValue; - - // FIXME: This can only come from the console at the moment but might not always be true. - if (ConsoleUtil.TryParseConsoleNaturalInt(MainConsole.Instance, options["child-upd-per"], out newValue)) - m_scene.ChildTerseUpdatePeriod = newValue; - } - if (options.ContainsKey("pbackup")) { bool active; @@ -296,28 +221,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments m_scene.DebugTeleporting = enableTeleportDebugging; } - if (options.ContainsKey("update-on-timer")) - { - bool enableUpdateOnTimer; - if (bool.TryParse(options["update-on-timer"], out enableUpdateOnTimer)) - { -// m_scene.UpdateOnTimer = enableUpdateOnTimer; - m_scene.Active = false; - - while (m_scene.IsRunning) - Thread.Sleep(20); - - m_scene.Active = true; - } - } - if (options.ContainsKey("updates")) { bool enableUpdateDebugging; if (bool.TryParse(options["updates"], out enableUpdateDebugging)) { m_scene.DebugUpdates = enableUpdateDebugging; - GcNotify.Enabled = enableUpdateDebugging; } } } diff --git a/OpenSim/Region/OptionalModules/World/TreePopulator/TreePopulatorModule.cs b/OpenSim/Region/OptionalModules/World/TreePopulator/TreePopulatorModule.cs index b26fa3298d..6e1f8bb654 100644 --- a/OpenSim/Region/OptionalModules/World/TreePopulator/TreePopulatorModule.cs +++ b/OpenSim/Region/OptionalModules/World/TreePopulator/TreePopulatorModule.cs @@ -27,8 +27,13 @@ using System; using System.Collections.Generic; +using System.IO; using System.Reflection; using System.Timers; +using System.Threading; +using System.Xml; +using System.Xml.Serialization; + using OpenMetaverse; using log4net; using Mono.Addins; @@ -38,9 +43,7 @@ using OpenSim.Region.CoreModules.Framework.InterfaceCommander; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; -using System.Xml; -using System.Xml.Serialization; -using System.IO; +using Timer= System.Timers.Timer; namespace OpenSim.Region.OptionalModules.World.TreePopulator { @@ -48,7 +51,7 @@ namespace OpenSim.Region.OptionalModules.World.TreePopulator /// Version 2.02 - Still hacky /// [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "TreePopulatorModule")] - public class TreePopulatorModule : INonSharedRegionModule, ICommandableModule, IVegetationModule + public class TreePopulatorModule : INonSharedRegionModule, ICommandableModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private readonly Commander m_commander = new Commander("tree"); @@ -82,20 +85,20 @@ namespace OpenSim.Region.OptionalModules.World.TreePopulator { Copse cp = (Copse)DeserializeObject(fileName); - this.m_name = cp.m_name; - this.m_frozen = cp.m_frozen; - this.m_tree_quantity = cp.m_tree_quantity; - this.m_treeline_high = cp.m_treeline_high; - this.m_treeline_low = cp.m_treeline_low; - this.m_range = cp.m_range; - this.m_tree_type = cp.m_tree_type; - this.m_seed_point = cp.m_seed_point; - this.m_initial_scale = cp.m_initial_scale; - this.m_maximum_scale = cp.m_maximum_scale; - this.m_initial_scale = cp.m_initial_scale; - this.m_rate = cp.m_rate; - this.m_planted = planted; - this.m_trees = new List(); + m_name = cp.m_name; + m_frozen = cp.m_frozen; + m_tree_quantity = cp.m_tree_quantity; + m_treeline_high = cp.m_treeline_high; + m_treeline_low = cp.m_treeline_low; + m_range = cp.m_range; + m_tree_type = cp.m_tree_type; + m_seed_point = cp.m_seed_point; + m_initial_scale = cp.m_initial_scale; + m_maximum_scale = cp.m_maximum_scale; + m_initial_scale = cp.m_initial_scale; + m_rate = cp.m_rate; + m_planted = planted; + m_trees = new List(); } public Copse(string copsedef) @@ -103,61 +106,63 @@ namespace OpenSim.Region.OptionalModules.World.TreePopulator char[] delimiterChars = {':', ';'}; string[] field = copsedef.Split(delimiterChars); - this.m_name = field[1].Trim(); - this.m_frozen = (copsedef[0] == 'F'); - this.m_tree_quantity = int.Parse(field[2]); - this.m_treeline_high = float.Parse(field[3], Culture.NumberFormatInfo); - this.m_treeline_low = float.Parse(field[4], Culture.NumberFormatInfo); - this.m_range = double.Parse(field[5], Culture.NumberFormatInfo); - this.m_tree_type = (Tree) Enum.Parse(typeof(Tree),field[6]); - this.m_seed_point = Vector3.Parse(field[7]); - this.m_initial_scale = Vector3.Parse(field[8]); - this.m_maximum_scale = Vector3.Parse(field[9]); - this.m_rate = Vector3.Parse(field[10]); - this.m_planted = true; - this.m_trees = new List(); + m_name = field[1].Trim(); + m_frozen = (copsedef[0] == 'F'); + m_tree_quantity = int.Parse(field[2]); + m_treeline_high = float.Parse(field[3], Culture.NumberFormatInfo); + m_treeline_low = float.Parse(field[4], Culture.NumberFormatInfo); + m_range = double.Parse(field[5], Culture.NumberFormatInfo); + m_tree_type = (Tree) Enum.Parse(typeof(Tree),field[6]); + m_seed_point = Vector3.Parse(field[7]); + m_initial_scale = Vector3.Parse(field[8]); + m_maximum_scale = Vector3.Parse(field[9]); + m_rate = Vector3.Parse(field[10]); + m_planted = true; + m_trees = new List(); } public Copse(string name, int quantity, float high, float low, double range, Vector3 point, Tree type, Vector3 scale, Vector3 max_scale, Vector3 rate, List trees) { - this.m_name = name; - this.m_frozen = false; - this.m_tree_quantity = quantity; - this.m_treeline_high = high; - this.m_treeline_low = low; - this.m_range = range; - this.m_tree_type = type; - this.m_seed_point = point; - this.m_initial_scale = scale; - this.m_maximum_scale = max_scale; - this.m_rate = rate; - this.m_planted = false; - this.m_trees = trees; + m_name = name; + m_frozen = false; + m_tree_quantity = quantity; + m_treeline_high = high; + m_treeline_low = low; + m_range = range; + m_tree_type = type; + m_seed_point = point; + m_initial_scale = scale; + m_maximum_scale = max_scale; + m_rate = rate; + m_planted = false; + m_trees = trees; } public override string ToString() { - string frozen = (this.m_frozen ? "F" : "A"); + string frozen = (m_frozen ? "F" : "A"); return string.Format("{0}TPM: {1}; {2}; {3:0.0}; {4:0.0}; {5:0.0}; {6}; {7:0.0}; {8:0.0}; {9:0.0}; {10:0.00};", frozen, - this.m_name, - this.m_tree_quantity, - this.m_treeline_high, - this.m_treeline_low, - this.m_range, - this.m_tree_type, - this.m_seed_point.ToString(), - this.m_initial_scale.ToString(), - this.m_maximum_scale.ToString(), - this.m_rate.ToString()); + m_name, + m_tree_quantity, + m_treeline_high, + m_treeline_low, + m_range, + m_tree_type, + m_seed_point.ToString(), + m_initial_scale.ToString(), + m_maximum_scale.ToString(), + m_rate.ToString()); } } - private List m_copse; - + private List m_copses = new List(); + private object mylock; private double m_update_ms = 1000.0; // msec between updates private bool m_active_trees = false; + private bool m_enabled = true; // original default + private bool m_allowGrow = true; // original default Timer CalculateTrees; @@ -174,51 +179,51 @@ namespace OpenSim.Region.OptionalModules.World.TreePopulator public void Initialise(IConfigSource config) { - - // ini file settings - try + IConfig moduleConfig = config.Configs["Trees"]; + if (moduleConfig != null) { - m_active_trees = config.Configs["Trees"].GetBoolean("active_trees", m_active_trees); - } - catch (Exception) - { - m_log.Debug("[TREES]: ini failure for active_trees - using default"); + m_enabled = moduleConfig.GetBoolean("enabled", m_enabled); + m_active_trees = moduleConfig.GetBoolean("active_trees", m_active_trees); + m_allowGrow = moduleConfig.GetBoolean("allowGrow", m_allowGrow); + m_update_ms = moduleConfig.GetDouble("update_rate", m_update_ms); } - try - { - m_update_ms = config.Configs["Trees"].GetDouble("update_rate", m_update_ms); - } - catch (Exception) - { - m_log.Debug("[TREES]: ini failure for update_rate - using default"); - } + if(!m_enabled) + return; + + m_copses = new List(); + mylock = new object(); InstallCommands(); - m_log.Debug("[TREES]: Initialised tree module"); + m_log.Debug("[TREES]: Initialised tree populator module"); } public void AddRegion(Scene scene) { + if(!m_enabled) + return; m_scene = scene; m_scene.RegisterModuleCommander(m_commander); m_scene.EventManager.OnPluginConsole += EventManager_OnPluginConsole; - + m_scene.EventManager.OnPrimsLoaded += EventManager_OnPrimsLoaded; } public void RemoveRegion(Scene scene) { - } + if(!m_enabled) + return; + if(m_active_trees && CalculateTrees != null) + { + CalculateTrees.Dispose(); + CalculateTrees = null; + } + m_scene.EventManager.OnPluginConsole -= EventManager_OnPluginConsole; + m_scene.EventManager.OnPrimsLoaded -= EventManager_OnPrimsLoaded; + } public void RegionLoaded(Scene scene) { - ReloadCopse(); - if (m_copse.Count > 0) - m_log.Info("[TREES]: Copse load complete"); - - if (m_active_trees) - activeizeTreeze(true); } public void Close() @@ -240,6 +245,16 @@ namespace OpenSim.Region.OptionalModules.World.TreePopulator //-------------------------------------------------------------- + private void EventManager_OnPrimsLoaded(Scene s) + { + ReloadCopse(); + if (m_copses.Count > 0) + m_log.Info("[TREES]: Copses loaded" ); + + if (m_active_trees) + activeizeTreeze(true); + } + #region ICommandableModule Members private void HandleTreeActive(Object[] args) @@ -267,25 +282,57 @@ namespace OpenSim.Region.OptionalModules.World.TreePopulator string copsename = ((string)args[0]).Trim(); Boolean freezeState = (Boolean) args[1]; - foreach (Copse cp in m_copse) + lock(mylock) { - if (cp.m_name == copsename && (!cp.m_frozen && freezeState || cp.m_frozen && !freezeState)) + foreach (Copse cp in m_copses) { - cp.m_frozen = freezeState; - foreach (UUID tree in cp.m_trees) - { - SceneObjectPart sop = ((SceneObjectGroup)m_scene.Entities[tree]).RootPart; - sop.Name = (freezeState ? sop.Name.Replace("ATPM", "FTPM") : sop.Name.Replace("FTPM", "ATPM")); - sop.ParentGroup.HasGroupChanged = true; - } + if (cp.m_name != copsename) + continue; - m_log.InfoFormat("[TREES]: Activity for copse {0} is frozen {1}", copsename, freezeState); - return; - } - else if (cp.m_name == copsename && (cp.m_frozen && freezeState || !cp.m_frozen && !freezeState)) - { - m_log.InfoFormat("[TREES]: Copse {0} is already in the requested freeze state", copsename); - return; + if(!cp.m_frozen && freezeState || cp.m_frozen && !freezeState) + { + cp.m_frozen = freezeState; + List losttrees = new List(); + foreach (UUID tree in cp.m_trees) + { + SceneObjectGroup sog = m_scene.GetSceneObjectGroup(tree); + if(sog != null && !sog.IsDeleted) + { + SceneObjectPart sop = sog.RootPart; + string name = sop.Name; + if(freezeState) + { + if(name.StartsWith("FTPM")) + continue; + if(!name.StartsWith("ATPM")) + continue; + sop.Name = sop.Name.Replace("ATPM", "FTPM"); + } + else + { + if(name.StartsWith("ATPM")) + continue; + if(!name.StartsWith("FTPM")) + continue; + sop.Name = sop.Name.Replace("FTPM", "ATPM"); + } + sop.ParentGroup.HasGroupChanged = true; + sog.ScheduleGroupForFullUpdate(); + } + else + losttrees.Add(tree); + } + foreach (UUID tree in losttrees) + cp.m_trees.Remove(tree); + + m_log.InfoFormat("[TREES]: Activity for copse {0} is frozen {1}", copsename, freezeState); + return; + } + else + { + m_log.InfoFormat("[TREES]: Copse {0} is already in the requested freeze state", copsename); + return; + } } } m_log.InfoFormat("[TREES]: Copse {0} was not found - command failed", copsename); @@ -297,17 +344,21 @@ namespace OpenSim.Region.OptionalModules.World.TreePopulator m_log.InfoFormat("[TREES]: Loading copse definition...."); - copse = new Copse(((string)args[0]), false); - foreach (Copse cp in m_copse) + lock(mylock) { - if (cp.m_name == copse.m_name) + copse = new Copse(((string)args[0]), false); { - m_log.InfoFormat("[TREES]: Copse: {0} is already defined - command failed", copse.m_name); - return; + foreach (Copse cp in m_copses) + { + if (cp.m_name == copse.m_name) + { + m_log.InfoFormat("[TREES]: Copse: {0} is already defined - command failed", copse.m_name); + return; + } + } } + m_copses.Add(copse); } - - m_copse.Add(copse); m_log.InfoFormat("[TREES]: Loaded copse: {0}", copse.ToString()); } @@ -318,20 +369,24 @@ namespace OpenSim.Region.OptionalModules.World.TreePopulator m_log.InfoFormat("[TREES]: New tree planting for copse {0}", copsename); UUID uuid = m_scene.RegionInfo.EstateSettings.EstateOwner; - foreach (Copse copse in m_copse) + lock(mylock) { - if (copse.m_name == copsename) + foreach (Copse copse in m_copses) { - if (!copse.m_planted) + if (copse.m_name == copsename) { - // The first tree for a copse is created here - CreateTree(uuid, copse, copse.m_seed_point); - copse.m_planted = true; - return; - } - else - { - m_log.InfoFormat("[TREES]: Copse {0} has already been planted", copsename); + if (!copse.m_planted) + { + // The first tree for a copse is created here + CreateTree(uuid, copse, copse.m_seed_point, true); + copse.m_planted = true; + return; + } + else + { + m_log.InfoFormat("[TREES]: Copse {0} has already been planted", copsename); + return; + } } } } @@ -376,45 +431,49 @@ namespace OpenSim.Region.OptionalModules.World.TreePopulator string copsename = ((string)args[0]).Trim(); Copse copseIdentity = null; - foreach (Copse cp in m_copse) + lock(mylock) { - if (cp.m_name == copsename) + foreach (Copse cp in m_copses) { - copseIdentity = cp; + if (cp.m_name == copsename) + { + copseIdentity = cp; + } } - } - if (copseIdentity != null) - { - foreach (UUID tree in copseIdentity.m_trees) + if (copseIdentity != null) { - if (m_scene.Entities.ContainsKey(tree)) + foreach (UUID tree in copseIdentity.m_trees) { - SceneObjectPart selectedTree = ((SceneObjectGroup)m_scene.Entities[tree]).RootPart; - // Delete tree and alert clients (not silent) - m_scene.DeleteSceneObject(selectedTree.ParentGroup, false); - } - else - { - m_log.DebugFormat("[TREES]: Tree not in scene {0}", tree); + if (m_scene.Entities.ContainsKey(tree)) + { + SceneObjectPart selectedTree = ((SceneObjectGroup)m_scene.Entities[tree]).RootPart; + // Delete tree and alert clients (not silent) + m_scene.DeleteSceneObject(selectedTree.ParentGroup, false); + } + else + { + m_log.DebugFormat("[TREES]: Tree not in scene {0}", tree); + } } + copseIdentity.m_trees = null; + m_copses.Remove(copseIdentity); + m_log.InfoFormat("[TREES]: Copse {0} has been removed", copsename); + } + else + { + m_log.InfoFormat("[TREES]: Copse {0} was not found - command failed", copsename); } - copseIdentity.m_trees = new List(); - m_copse.Remove(copseIdentity); - m_log.InfoFormat("[TREES]: Copse {0} has been removed", copsename); - } - else - { - m_log.InfoFormat("[TREES]: Copse {0} was not found - command failed", copsename); } } private void HandleTreeStatistics(Object[] args) { - m_log.InfoFormat("[TREES]: Activity State: {0}; Update Rate: {1}", m_active_trees, m_update_ms); - foreach (Copse cp in m_copse) + m_log.InfoFormat("[TREES]: region {0}:", m_scene.Name); + m_log.InfoFormat("[TREES]: Activity State: {0}; Update Rate: {1}", m_active_trees, m_update_ms); + foreach (Copse cp in m_copses) { - m_log.InfoFormat("[TREES]: Copse {0}; {1} trees; frozen {2}", cp.m_name, cp.m_trees.Count, cp.m_frozen); + m_log.InfoFormat("[TREES]: Copse {0}; {1} trees; frozen {2}", cp.m_name, cp.m_trees.Count, cp.m_frozen); } } @@ -442,7 +501,7 @@ namespace OpenSim.Region.OptionalModules.World.TreePopulator treeRateCommand.AddArgument("updateRate", "The required update rate (minimum 1000.0)", "Double"); Command treeReloadCommand = - new Command("reload", CommandIntentions.COMMAND_HAZARDOUS, HandleTreeReload, "Reload copse definitions from the in-scene trees"); + new Command("reload", CommandIntentions.COMMAND_HAZARDOUS, HandleTreeReload, "Reload copses from the in-scene trees"); Command treeRemoveCommand = new Command("remove", CommandIntentions.COMMAND_HAZARDOUS, HandleTreeRemove, "Remove a copse definition and all its in-scene trees"); @@ -499,34 +558,17 @@ namespace OpenSim.Region.OptionalModules.World.TreePopulator treeShape.Scale = scale; treeShape.State = (byte)treeType; - return m_scene.AddNewPrim(uuid, groupID, position, rotation, treeShape); - } - - #endregion - - #region IEntityCreator Members - - protected static readonly PCode[] creationCapabilities = new PCode[] { PCode.NewTree, PCode.Tree }; - public PCode[] CreationCapabilities { get { return creationCapabilities; } } - - public SceneObjectGroup CreateEntity( - UUID ownerID, UUID groupID, Vector3 pos, Quaternion rot, PrimitiveBaseShape shape) - { - if (Array.IndexOf(creationCapabilities, (PCode)shape.PCode) < 0) - { - m_log.DebugFormat("[VEGETATION]: PCode {0} not handled by {1}", shape.PCode, Name); - return null; - } - - SceneObjectGroup sceneObject = new SceneObjectGroup(ownerID, pos, rot, shape); - SceneObjectPart rootPart = sceneObject.GetPart(sceneObject.UUID); + SceneObjectGroup sog = new SceneObjectGroup(uuid, position, rotation, treeShape); + SceneObjectPart rootPart = sog.RootPart; rootPart.AddFlag(PrimFlags.Phantom); - sceneObject.SetGroup(groupID, null); - m_scene.AddNewSceneObject(sceneObject, true); - sceneObject.AggregatePerms(); - return sceneObject; + sog.SetGroup(groupID, null); + m_scene.AddNewSceneObject(sog, true, false); + sog.IsSelected = false; + rootPart.IsSelected = false; + sog.InvalidateEffectivePerms(); + return sog; } #endregion @@ -569,26 +611,27 @@ namespace OpenSim.Region.OptionalModules.World.TreePopulator private void ReloadCopse() { - m_copse = new List(); + m_copses = new List(); - EntityBase[] objs = m_scene.GetEntities(); - foreach (EntityBase obj in objs) + List grps = m_scene.GetSceneObjectGroups(); + foreach (SceneObjectGroup grp in grps) { - if (obj is SceneObjectGroup) + if(grp.RootPart.Shape.PCode != (byte)PCode.NewTree && grp.RootPart.Shape.PCode != (byte)PCode.Tree) + continue; + + if (grp.Name.Length > 5 && (grp.Name.Substring(0, 5) == "ATPM:" || grp.Name.Substring(0, 5) == "FTPM:")) { - SceneObjectGroup grp = (SceneObjectGroup)obj; - - if (grp.Name.Length > 5 && (grp.Name.Substring(0, 5) == "ATPM:" || grp.Name.Substring(0, 5) == "FTPM:")) + // Create a new copse definition or add uuid to an existing definition + try { - // Create a new copse definition or add uuid to an existing definition - try - { - Boolean copsefound = false; - Copse copse = new Copse(grp.Name); + Boolean copsefound = false; + Copse grpcopse = new Copse(grp.Name); - foreach (Copse cp in m_copse) + lock(mylock) + { + foreach (Copse cp in m_copses) { - if (cp.m_name == copse.m_name) + if (cp.m_name == grpcopse.m_name) { copsefound = true; cp.m_trees.Add(grp.UUID); @@ -598,15 +641,15 @@ namespace OpenSim.Region.OptionalModules.World.TreePopulator if (!copsefound) { - m_log.InfoFormat("[TREES]: Found copse {0}", grp.Name); - m_copse.Add(copse); - copse.m_trees.Add(grp.UUID); + m_log.InfoFormat("[TREES]: adding copse {0}", grpcopse.m_name); + grpcopse.m_trees.Add(grp.UUID); + m_copses.Add(grpcopse); } } - catch - { - m_log.InfoFormat("[TREES]: Ill formed copse definition {0} - ignoring", grp.Name); - } + } + catch + { + m_log.InfoFormat("[TREES]: Ill formed copse definition {0} - ignoring", grp.Name); } } } @@ -617,8 +660,10 @@ namespace OpenSim.Region.OptionalModules.World.TreePopulator { if (activeYN) { - CalculateTrees = new Timer(m_update_ms); + if(CalculateTrees == null) + CalculateTrees = new Timer(m_update_ms); CalculateTrees.Elapsed += CalculateTrees_Elapsed; + CalculateTrees.AutoReset = false; CalculateTrees.Start(); } else @@ -629,154 +674,251 @@ namespace OpenSim.Region.OptionalModules.World.TreePopulator private void growTrees() { - foreach (Copse copse in m_copse) - { - if (!copse.m_frozen) - { - foreach (UUID tree in copse.m_trees) - { - if (m_scene.Entities.ContainsKey(tree)) - { - SceneObjectPart s_tree = ((SceneObjectGroup)m_scene.Entities[tree]).RootPart; + if(!m_allowGrow) + return; - if (s_tree.Scale.X < copse.m_maximum_scale.X && s_tree.Scale.Y < copse.m_maximum_scale.Y && s_tree.Scale.Z < copse.m_maximum_scale.Z) - { - s_tree.Scale += copse.m_rate; - s_tree.ParentGroup.HasGroupChanged = true; - s_tree.ScheduleFullUpdate(); - } - } - else + foreach (Copse copse in m_copses) + { + if (copse.m_frozen) + continue; + + if(copse.m_trees.Count == 0) + continue; + + float maxscale = copse.m_maximum_scale.Z; + float ratescale = 1.0f; + List losttrees = new List(); + foreach (UUID tree in copse.m_trees) + { + SceneObjectGroup sog = m_scene.GetSceneObjectGroup(tree); + + if (sog != null && !sog.IsDeleted) + { + SceneObjectPart s_tree = sog.RootPart; + if (s_tree.Scale.Z < maxscale) { - m_log.DebugFormat("[TREES]: Tree not in scene {0}", tree); + ratescale = (float)Util.RandomClass.NextDouble(); + if(ratescale < 0.2f) + ratescale = 0.2f; + s_tree.Scale += copse.m_rate * ratescale; + sog.HasGroupChanged = true; + s_tree.ScheduleFullUpdate(); } } + else + losttrees.Add(tree); } + + foreach (UUID tree in losttrees) + copse.m_trees.Remove(tree); } } private void seedTrees() { - foreach (Copse copse in m_copse) + foreach (Copse copse in m_copses) { - if (!copse.m_frozen) - { - foreach (UUID tree in copse.m_trees) - { - if (m_scene.Entities.ContainsKey(tree)) - { - SceneObjectPart s_tree = ((SceneObjectGroup)m_scene.Entities[tree]).RootPart; + if (copse.m_frozen) + continue; - if (copse.m_trees.Count < copse.m_tree_quantity) - { - // Tree has grown enough to seed if it has grown by at least 25% of seeded to full grown height - if (s_tree.Scale.Z > copse.m_initial_scale.Z + (copse.m_maximum_scale.Z - copse.m_initial_scale.Z) / 4.0) - { - if (Util.RandomClass.NextDouble() > 0.75) - { - SpawnChild(copse, s_tree); - } - } - } - } - else - { - m_log.DebugFormat("[TREES]: Tree not in scene {0}", tree); - } + if(copse.m_trees.Count == 0) + return; + + bool low = copse.m_trees.Count < (int)(copse.m_tree_quantity * 0.8f); + + if (!low && Util.RandomClass.NextDouble() < 0.75) + return; + + int maxbirths = (int)(copse.m_tree_quantity) - copse.m_trees.Count; + if(maxbirths <= 1) + return; + + if(maxbirths > 20) + maxbirths = 20; + + float minscale = 0; + if(!low && m_allowGrow) + minscale = copse.m_maximum_scale.Z * 0.75f;; + + int i = 0; + UUID[] current = copse.m_trees.ToArray(); + while(--maxbirths > 0) + { + if(current.Length > 1) + i = Util.RandomClass.Next(current.Length -1); + + UUID tree = current[i]; + SceneObjectGroup sog = m_scene.GetSceneObjectGroup(tree); + + if (sog != null && !sog.IsDeleted) + { + SceneObjectPart s_tree = sog.RootPart; + + // Tree has grown enough to seed if it has grown by at least 25% of seeded to full grown height + if (s_tree.Scale.Z > minscale) + SpawnChild(copse, s_tree, true); } - } + else if(copse.m_trees.Contains(tree)) + copse.m_trees.Remove(tree); + } } } private void killTrees() { - foreach (Copse copse in m_copse) + foreach (Copse copse in m_copses) { - if (!copse.m_frozen && copse.m_trees.Count >= copse.m_tree_quantity) + if (copse.m_frozen) + continue; + + if (Util.RandomClass.NextDouble() < 0.25) + return; + + int maxbdeaths = copse.m_trees.Count - (int)(copse.m_tree_quantity * .98f) ; + if(maxbdeaths < 1) + return; + + float odds; + float scale = 1.0f / copse.m_maximum_scale.Z; + + int ntries = maxbdeaths * 4; + while(ntries-- > 0 ) { - foreach (UUID tree in copse.m_trees) + int next = 0; + if (copse.m_trees.Count > 1) + next = Util.RandomClass.Next(copse.m_trees.Count - 1); + UUID tree = copse.m_trees[next]; + SceneObjectGroup sog = m_scene.GetSceneObjectGroup(tree); + if (sog != null && !sog.IsDeleted) { - double killLikelyhood = 0.0; - - if (m_scene.Entities.ContainsKey(tree)) + if(m_allowGrow) { - SceneObjectPart selectedTree = ((SceneObjectGroup)m_scene.Entities[tree]).RootPart; - double selectedTreeScale = Math.Sqrt(Math.Pow(selectedTree.Scale.X, 2) + - Math.Pow(selectedTree.Scale.Y, 2) + - Math.Pow(selectedTree.Scale.Z, 2)); - - foreach (UUID picktree in copse.m_trees) - { - if (picktree != tree) - { - SceneObjectPart pickedTree = ((SceneObjectGroup)m_scene.Entities[picktree]).RootPart; - - double pickedTreeScale = Math.Sqrt(Math.Pow(pickedTree.Scale.X, 2) + - Math.Pow(pickedTree.Scale.Y, 2) + - Math.Pow(pickedTree.Scale.Z, 2)); - - double pickedTreeDistance = Vector3.Distance(pickedTree.AbsolutePosition, selectedTree.AbsolutePosition); - - killLikelyhood += (selectedTreeScale / (pickedTreeScale * pickedTreeDistance)) * 0.1; - } - } - - if (Util.RandomClass.NextDouble() < killLikelyhood) - { - // Delete tree and alert clients (not silent) - m_scene.DeleteSceneObject(selectedTree.ParentGroup, false); - copse.m_trees.Remove(selectedTree.ParentGroup.UUID); - break; - } + odds = sog.RootPart.Scale.Z * scale; + odds = odds * odds * odds; + odds *= (float)Util.RandomClass.NextDouble(); } else { - m_log.DebugFormat("[TREES]: Tree not in scene {0}", tree); + odds = (float)Util.RandomClass.NextDouble(); + odds = odds * odds * odds; } + + if(odds > 0.9f) + { + m_scene.DeleteSceneObject(sog, false); + if(maxbdeaths <= 0) + break; + } + } + else + { + copse.m_trees.Remove(tree); + if(copse.m_trees.Count - (int)(copse.m_tree_quantity * .98f) <= 0 ) + break; } } } } - private void SpawnChild(Copse copse, SceneObjectPart s_tree) + private void SpawnChild(Copse copse, SceneObjectPart s_tree, bool low) { Vector3 position = new Vector3(); - - double randX = ((Util.RandomClass.NextDouble() * 2.0) - 1.0) * (s_tree.Scale.X * 3); - double randY = ((Util.RandomClass.NextDouble() * 2.0) - 1.0) * (s_tree.Scale.X * 3); - + + float randX = copse.m_maximum_scale.X * 1.25f; + float randY = copse.m_maximum_scale.Y * 1.25f; + + float r = (float)Util.RandomClass.NextDouble(); + randX *= 2.0f * r - 1.0f; position.X = s_tree.AbsolutePosition.X + (float)randX; + + r = (float)Util.RandomClass.NextDouble(); + randY *= 2.0f * r - 1.0f; position.Y = s_tree.AbsolutePosition.Y + (float)randY; - if (position.X <= (m_scene.RegionInfo.RegionSizeX - 1) && position.X >= 0 && - position.Y <= (m_scene.RegionInfo.RegionSizeY - 1) && position.Y >= 0 && - Util.GetDistanceTo(position, copse.m_seed_point) <= copse.m_range) - { - UUID uuid = m_scene.RegionInfo.EstateSettings.EstateOwner; + if (position.X > (m_scene.RegionInfo.RegionSizeX - 1) || position.X <= 0 || + position.Y > (m_scene.RegionInfo.RegionSizeY - 1) || position.Y <= 0) + return; - CreateTree(uuid, copse, position); - } + randX = position.X - copse.m_seed_point.X; + randX *= randX; + randY = position.Y - copse.m_seed_point.Y; + randY *= randY; + randX += randY; + + if(randX > copse.m_range * copse.m_range) + return; + + UUID uuid = m_scene.RegionInfo.EstateSettings.EstateOwner; + CreateTree(uuid, copse, position, low); } - private void CreateTree(UUID uuid, Copse copse, Vector3 position) + private void CreateTree(UUID uuid, Copse copse, Vector3 position, bool randomScale) { - position.Z = (float)m_scene.Heightmap[(int)position.X, (int)position.Y]; - if (position.Z >= copse.m_treeline_low && position.Z <= copse.m_treeline_high) - { - SceneObjectGroup tree = AddTree(uuid, UUID.Zero, copse.m_initial_scale, Quaternion.Identity, position, copse.m_tree_type, false); + if (position.Z < copse.m_treeline_low || position.Z > copse.m_treeline_high) + return; - tree.Name = copse.ToString(); - copse.m_trees.Add(tree.UUID); - tree.SendGroupFullUpdate(); + Vector3 scale = copse.m_initial_scale; + if(randomScale) + { + try + { + float t; + float r = (float)Util.RandomClass.NextDouble(); + r *= (float)Util.RandomClass.NextDouble(); + r *= (float)Util.RandomClass.NextDouble(); + + t = copse.m_maximum_scale.X / copse.m_initial_scale.X; + if(t < 1.0) + t = 1 / t; + t = t * r + 1.0f; + scale.X *= t; + + t = copse.m_maximum_scale.Y / copse.m_initial_scale.Y; + if(t < 1.0) + t = 1 / t; + t = t * r + 1.0f; + scale.Y *= t; + + t = copse.m_maximum_scale.Z / copse.m_initial_scale.Z; + if(t < 1.0) + t = 1 / t; + t = t * r + 1.0f; + scale.Z *= t; + } + catch + { + scale = copse.m_initial_scale; + } } + + SceneObjectGroup tree = AddTree(uuid, UUID.Zero, scale, Quaternion.Identity, position, copse.m_tree_type, false); + tree.Name = copse.ToString(); + copse.m_trees.Add(tree.UUID); + tree.RootPart.ScheduleFullUpdate(); } private void CalculateTrees_Elapsed(object sender, ElapsedEventArgs e) { - growTrees(); - seedTrees(); - killTrees(); + if(!m_scene.IsRunning) + return; + + if(Monitor.TryEnter(mylock)) + { + try + { + if(m_scene.LoginsEnabled ) + { + growTrees(); + seedTrees(); + killTrees(); + } + } + catch { } + if(CalculateTrees != null) + CalculateTrees.Start(); + Monitor.Exit(mylock); + } } } } diff --git a/OpenSim/Region/PhysicsModules/BasicPhysics/BasicPhysicsScene.cs b/OpenSim/Region/PhysicsModules/BasicPhysics/BasicPhysicsScene.cs index 2a1ae45e08..5ce1515cb4 100644 --- a/OpenSim/Region/PhysicsModules/BasicPhysics/BasicPhysicsScene.cs +++ b/OpenSim/Region/PhysicsModules/BasicPhysics/BasicPhysicsScene.cs @@ -163,7 +163,7 @@ namespace OpenSim.Region.PhysicsModule.BasicPhysics { // Console.WriteLine("Simulating"); - float fps = 0; + float fps = 1.0f / timeStep; for (int i = 0; i < _actors.Count; ++i) { BasicActor actor = _actors[i]; @@ -226,7 +226,7 @@ namespace OpenSim.Region.PhysicsModule.BasicPhysics actor.Velocity = actorVelocity; } - return 1.0f; + return fps; } public override void GetResults() diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSAPIUnman.cs b/OpenSim/Region/PhysicsModules/BulletS/BSAPIUnman.cs index 42db7fedb6..840e453b0c 100755 --- a/OpenSim/Region/PhysicsModules/BulletS/BSAPIUnman.cs +++ b/OpenSim/Region/PhysicsModules/BulletS/BSAPIUnman.cs @@ -1404,6 +1404,19 @@ public override float GetMargin(BulletShape shape) return BSAPICPP.GetMargin2(shapeu.ptr); } +// ===================================================================================== +// Raycast +public override SweepHit ConvexSweepTest2(BulletWorld world, BulletBody sweepObject, Vector3 from, Vector3 to, float margin) { + BulletWorldUnman worldu = world as BulletWorldUnman; + BulletBodyUnman bodyu = sweepObject as BulletBodyUnman; + return BSAPICPP.ConvexSweepTest2(worldu.ptr, bodyu.ptr, from, to, margin); +} + +public override RaycastHit RayTest2(BulletWorld world, Vector3 from, Vector3 to, uint filterGroup, uint filterMask) { + BulletWorldUnman worldu = world as BulletWorldUnman; + return BSAPICPP.RayTest2(worldu.ptr, from, to, filterGroup, filterMask); +} + // ===================================================================================== // Debugging public override void DumpRigidBody(BulletWorld world, BulletBody collisionObject) @@ -2084,6 +2097,15 @@ public static extern void SetMargin2(IntPtr shape, float val); [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] public static extern float GetMargin2(IntPtr shape); + +// ===================================================================================== +// Raycast +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern SweepHit ConvexSweepTest2(IntPtr sim, IntPtr obj, Vector3 from, Vector3 to, float margin); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern RaycastHit RayTest2(IntPtr sim, Vector3 from, Vector3 to, uint filterGroup, uint filterMask); + // ===================================================================================== // Debugging [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSAPIXNA.cs b/OpenSim/Region/PhysicsModules/BulletS/BSAPIXNA.cs index 37017b09a4..7d58728337 100755 --- a/OpenSim/Region/PhysicsModules/BulletS/BSAPIXNA.cs +++ b/OpenSim/Region/PhysicsModules/BulletS/BSAPIXNA.cs @@ -2459,6 +2459,14 @@ private sealed class BulletConstraintXNA : BulletConstraint } return false; } + + public override SweepHit ConvexSweepTest2(BulletWorld world, BulletBody obj, Vector3 from, Vector3 to, float margin) { + return new SweepHit(); + } + + public override RaycastHit RayTest2(BulletWorld world, Vector3 from, Vector3 to, uint filterGroup, uint filterMask) { + return new RaycastHit(); + } } diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSApiTemplate.cs b/OpenSim/Region/PhysicsModules/BulletS/BSApiTemplate.cs index 816189f608..a2880487c2 100644 --- a/OpenSim/Region/PhysicsModules/BulletS/BSApiTemplate.cs +++ b/OpenSim/Region/PhysicsModules/BulletS/BSApiTemplate.cs @@ -121,6 +121,14 @@ public struct SweepHit public float Fraction; public Vector3 Normal; public Vector3 Point; + + public bool hasHit() + { + float sum = Fraction + + Normal.X + Normal.Y + Normal.Z + + Point.X + Point.Y + Point.Z; + return (sum != 0) || (ID != 0); + } } [StructLayout(LayoutKind.Sequential)] public struct RaycastHit @@ -128,6 +136,13 @@ public struct RaycastHit public UInt32 ID; public float Fraction; public Vector3 Normal; + public Vector3 Point; + + public bool hasHit() + { + float sum = Normal.X + Normal.Y + Normal.Z + Point.X + Point.Y + Point.Z; + return (sum != 0); + } } [StructLayout(LayoutKind.Sequential)] public struct CollisionDesc @@ -741,6 +756,12 @@ public abstract void SetMargin(BulletShape shape, float val); public abstract float GetMargin(BulletShape shape); +// ===================================================================================== +// Raycast +public abstract SweepHit ConvexSweepTest2(BulletWorld world, BulletBody obj, Vector3 from, Vector3 to, float margin); + +public abstract RaycastHit RayTest2(BulletWorld world, Vector3 from, Vector3 to, uint filterGroup, uint filterMask); + // ===================================================================================== // Debugging public virtual void DumpRigidBody(BulletWorld sim, BulletBody collisionObject) { } diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSCharacter.cs b/OpenSim/Region/PhysicsModules/BulletS/BSCharacter.cs index 57f03fb9e3..2ca7dbc498 100644 --- a/OpenSim/Region/PhysicsModules/BulletS/BSCharacter.cs +++ b/OpenSim/Region/PhysicsModules/BulletS/BSCharacter.cs @@ -92,6 +92,7 @@ public sealed class BSCharacter : BSPhysObject Density = BSParam.AvatarDensity; _isPhysical = true; + _footOffset = footOffset; // Adjustments for zero X and Y made in Size() // This also computes avatar scale, volume, and mass SetAvatarSize(size, footOffset, true /* initializing */); @@ -460,13 +461,19 @@ public sealed class BSCharacter : BSPhysObject set { DetailLog("{0},BSCharacter.setTargetVelocity,call,vel={1}", LocalID, value); - base.m_targetVelocity = value; OMV.Vector3 targetVel = value; - if (_setAlwaysRun && !_flying) - targetVel *= new OMV.Vector3(BSParam.AvatarAlwaysRunFactor, BSParam.AvatarAlwaysRunFactor, 1f); + if (!_flying) + { + if (_setAlwaysRun) + targetVel *= new OMV.Vector3(BSParam.AvatarAlwaysRunFactor, BSParam.AvatarAlwaysRunFactor, 1f); + else + if (BSParam.AvatarWalkVelocityFactor != 1f) + targetVel *= new OMV.Vector3(BSParam.AvatarWalkVelocityFactor, BSParam.AvatarWalkVelocityFactor, 1f); + } + base.m_targetVelocity = targetVel; if (m_moveActor != null) - m_moveActor.SetVelocityAndTarget(RawVelocity, targetVel, false /* inTaintTime */); + m_moveActor.SetVelocityAndTarget(RawVelocity, base.m_targetVelocity, false /* inTaintTime */); } } // Directly setting velocity means this is what the user really wants now. @@ -496,8 +503,7 @@ public sealed class BSCharacter : BSPhysObject public override OMV.Vector3 ForceVelocity { get { return RawVelocity; } set { - PhysScene.AssertInTaintTime("BSCharacter.ForceVelocity"); - DetailLog("{0}: BSCharacter.ForceVelocity.set = {1}", LocalID, value); + DetailLog("{0},BSCharacter.ForceVelocity.set={1}", LocalID, value); RawVelocity = Util.ClampV(value, BSParam.MaxLinearVelocity); PhysScene.PE.SetLinearVelocity(PhysBody, RawVelocity); @@ -638,8 +644,6 @@ public sealed class BSCharacter : BSPhysObject public override float ForceBuoyancy { get { return _buoyancy; } set { - PhysScene.AssertInTaintTime("BSCharacter.ForceBuoyancy"); - _buoyancy = value; DetailLog("{0},BSCharacter.setForceBuoyancy,taint,buoy={1}", LocalID, _buoyancy); // Buoyancy is faked by changing the gravity applied to the object diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSLinksetCompound.cs b/OpenSim/Region/PhysicsModules/BulletS/BSLinksetCompound.cs index 953ddee0dd..dc390b2e8d 100755 --- a/OpenSim/Region/PhysicsModules/BulletS/BSLinksetCompound.cs +++ b/OpenSim/Region/PhysicsModules/BulletS/BSLinksetCompound.cs @@ -450,6 +450,7 @@ public sealed class BSLinksetCompound : BSLinkset m_physicsScene.PE.AddObjectToWorld(m_physicsScene.World, LinksetRoot.PhysBody); DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addBody,body={1},shape={2}", LinksetRoot.LocalID, LinksetRoot.PhysBody, linksetShape); + m_physicsScene.PE.ResetBroadphasePool(m_physicsScene.World); // DEBUG DEBUG // With all of the linkset packed into the root prim, it has the mass of everyone. LinksetMass = ComputeLinksetMass(); diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSParam.cs b/OpenSim/Region/PhysicsModules/BulletS/BSParam.cs index 352c03eac8..495f752e46 100755 --- a/OpenSim/Region/PhysicsModules/BulletS/BSParam.cs +++ b/OpenSim/Region/PhysicsModules/BulletS/BSParam.cs @@ -135,6 +135,7 @@ public static class BSParam public static bool AvatarToAvatarCollisionsByDefault { get; private set; } public static float AvatarFriction { get; private set; } public static float AvatarStandingFriction { get; private set; } + public static float AvatarWalkVelocityFactor { get; private set; } public static float AvatarAlwaysRunFactor { get; private set; } public static float AvatarDensity { get; private set; } public static float AvatarRestitution { get; private set; } @@ -230,6 +231,8 @@ public static class BSParam public static float LinkConstraintCFM { get; private set; } public static float LinkConstraintSolverIterations { get; private set; } + public static bool UseBulletRaycast { get; private set; } + public static float PID_D { get; private set; } // derivative public static float PID_P { get; private set; } // proportional @@ -602,6 +605,8 @@ public static class BSParam 0.2f ), new ParameterDefn("AvatarStandingFriction", "Avatar friction when standing. Changed on avatar recreation.", 0.95f ), + new ParameterDefn("AvatarWalkVelocityFactor", "Speed multiplier if avatar is walking", + 1.0f ), new ParameterDefn("AvatarAlwaysRunFactor", "Speed multiplier if avatar is set to always run", 1.3f ), // For historical reasons, density is reported * 100 @@ -823,6 +828,9 @@ public static class BSParam new ParameterDefn("LinkConstraintSolverIterations", "Number of solver iterations when computing constraint. (0 = Bullet default)", 40 ), + new ParameterDefn("UseBulletRaycast", "If 'true', use the raycast function of the Bullet physics engine", + true ), + new ParameterDefn("DebugNumber", "A console setable number sometimes used for debugging", 1.0f ), @@ -833,7 +841,7 @@ public static class BSParam new ParameterDefn("ResetBroadphasePool", "Setting this is any value resets the broadphase collision pool", 0f, (s) => { return 0f; }, - (s,v) => { BSParam.ResetBroadphasePoolTainted(s, v, false /* inTaintTime */); } ), + (s,v) => { BSParam.ResetBroadphasePoolTainted(s, v); } ), new ParameterDefn("ResetConstraintSolver", "Setting this is any value resets the constraint solver", 0f, (s) => { return 0f; }, @@ -919,10 +927,10 @@ public static class BSParam // ===================================================================== // There are parameters that, when set, cause things to happen in the physics engine. // This causes the broadphase collision cache to be cleared. - private static void ResetBroadphasePoolTainted(BSScene pPhysScene, float v, bool inTaintTime) + private static void ResetBroadphasePoolTainted(BSScene pPhysScene, float v) { BSScene physScene = pPhysScene; - physScene.TaintedObject(inTaintTime, "BSParam.ResetBroadphasePoolTainted", delegate() + physScene.TaintedObject(BSScene.DetailLogZero, "BSParam.ResetBroadphasePoolTainted", delegate() { physScene.PE.ResetBroadphasePool(physScene.World); }); diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSPrim.cs b/OpenSim/Region/PhysicsModules/BulletS/BSPrim.cs index b1537615a1..f085d70550 100644 --- a/OpenSim/Region/PhysicsModules/BulletS/BSPrim.cs +++ b/OpenSim/Region/PhysicsModules/BulletS/BSPrim.cs @@ -790,8 +790,6 @@ public class BSPrim : BSPhysObject public override OMV.Vector3 ForceVelocity { get { return RawVelocity; } set { - PhysScene.AssertInTaintTime("BSPrim.ForceVelocity"); - RawVelocity = Util.ClampV(value, BSParam.MaxLinearVelocity); if (PhysBody.HasPhysicalBody) { diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSPrimDisplaced.cs b/OpenSim/Region/PhysicsModules/BulletS/BSPrimDisplaced.cs index d8ed56b4a4..3f90fc55b2 100755 --- a/OpenSim/Region/PhysicsModules/BulletS/BSPrimDisplaced.cs +++ b/OpenSim/Region/PhysicsModules/BulletS/BSPrimDisplaced.cs @@ -81,7 +81,6 @@ public class BSPrimDisplaced : BSPrim // Called at taint time. public virtual Vector3 SetEffectiveCenterOfMassDisplacement(Vector3 centerOfMassDisplacement) { - PhysScene.AssertInTaintTime("BSPrimDisplaced.SetEffectiveCenterOfMassDisplacement"); Vector3 comDisp; if (UserSetCenterOfMassDisplacement.HasValue) comDisp = (OMV.Vector3)UserSetCenterOfMassDisplacement; diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSScene.cs b/OpenSim/Region/PhysicsModules/BulletS/BSScene.cs index 7ff0a07d5a..163efaa8e0 100644 --- a/OpenSim/Region/PhysicsModules/BulletS/BSScene.cs +++ b/OpenSim/Region/PhysicsModules/BulletS/BSScene.cs @@ -124,9 +124,10 @@ namespace OpenSim.Region.PhysicsModule.BulletS // True if initialized and ready to do simulation steps private bool m_initialized = false; - // Flag which is true when processing taints. - // Not guaranteed to be correct all the time (don't depend on this) but good for debugging. - public bool InTaintTime { get; private set; } + // Object locked whenever execution is inside the physics engine + public Object PhysicsEngineLock = new object(); + // Flag that is true when the simulator is active and shouldn't be touched + public bool InSimulationTime { get; private set; } // Pinned memory used to pass step information between managed and unmanaged internal int m_maxCollisionsPerFrame; @@ -344,7 +345,7 @@ namespace OpenSim.Region.PhysicsModule.BulletS // Put some informational messages into the log file. m_log.InfoFormat("{0} Linksets implemented with {1}", LogHeader, (BSLinkset.LinksetImplementation)BSParam.LinksetImplementation); - InTaintTime = false; + InSimulationTime = false; m_initialized = true; // If the physics engine runs on its own thread, start same. @@ -657,48 +658,57 @@ namespace OpenSim.Region.PhysicsModule.BulletS int beforeTime = Util.EnvironmentTickCount(); int simTime = 0; - - int numTaints = _taintOperations.Count; - InTaintTime = true; // Only used for debugging so locking is not necessary. - - // update the prim states while we know the physics engine is not busy - ProcessTaints(); - - // Some of the physical objects requre individual, pre-step calls - // (vehicles and avatar movement, in particular) - TriggerPreStepEvent(timeStep); - - // the prestep actions might have added taints - numTaints += _taintOperations.Count; - ProcessTaints(); - - InTaintTime = false; // Only used for debugging so locking is not necessary. - - // The following causes the unmanaged code to output ALL the values found in ALL the objects in the world. - // Only enable this in a limited test world with few objects. - if (m_physicsPhysicalDumpEnabled) - PE.DumpAllInfo(World); - - // step the physical world one interval - m_simulationStep++; + int numTaints = 0; int numSubSteps = 0; - try - { - numSubSteps = PE.PhysicsStep(World, timeStep, m_maxSubSteps, m_fixedTimeStep, out updatedEntityCount, out collidersCount); - } - catch (Exception e) - { - m_log.WarnFormat("{0},PhysicsStep Exception: nTaints={1}, substeps={2}, updates={3}, colliders={4}, e={5}", - LogHeader, numTaints, numSubSteps, updatedEntityCount, collidersCount, e); - DetailLog("{0},PhysicsStepException,call, nTaints={1}, substeps={2}, updates={3}, colliders={4}", - DetailLogZero, numTaints, numSubSteps, updatedEntityCount, collidersCount); - updatedEntityCount = 0; - collidersCount = 0; - } - // Make the physics engine dump useful statistics periodically - if (PhysicsMetricDumpFrames != 0 && ((m_simulationStep % PhysicsMetricDumpFrames) == 0)) - PE.DumpPhysicsStatistics(World); + lock (PhysicsEngineLock) + { + InSimulationTime = true; + // update the prim states while we know the physics engine is not busy + numTaints += ProcessTaints(); + + // Some of the physical objects requre individual, pre-step calls + // (vehicles and avatar movement, in particular) + TriggerPreStepEvent(timeStep); + + // the prestep actions might have added taints + numTaints += ProcessTaints(); + + // The following causes the unmanaged code to output ALL the values found in ALL the objects in the world. + // Only enable this in a limited test world with few objects. + if (m_physicsPhysicalDumpEnabled) + PE.DumpAllInfo(World); + + // step the physical world one interval + m_simulationStep++; + try + { + numSubSteps = PE.PhysicsStep(World, timeStep, m_maxSubSteps, m_fixedTimeStep, out updatedEntityCount, out collidersCount); + } + catch (Exception e) + { + m_log.WarnFormat("{0},PhysicsStep Exception: nTaints={1}, substeps={2}, updates={3}, colliders={4}, e={5}", + LogHeader, numTaints, numSubSteps, updatedEntityCount, collidersCount, e); + DetailLog("{0},PhysicsStepException,call, nTaints={1}, substeps={2}, updates={3}, colliders={4}", + DetailLogZero, numTaints, numSubSteps, updatedEntityCount, collidersCount); + updatedEntityCount = 0; + collidersCount = 0; + } + + // Make the physics engine dump useful statistics periodically + if (PhysicsMetricDumpFrames != 0 && ((m_simulationStep % PhysicsMetricDumpFrames) == 0)) + PE.DumpPhysicsStatistics(World); + + InSimulationTime = false; + + // Some actors want to know when the simulation step is complete. + TriggerPostStepEvent(timeStep); + + // In case there were any parameter updates that happened during the simulation step + numTaints += ProcessTaints(); + + InSimulationTime = false; + } // Get a value for 'now' so all the collision and update routines don't have to get their own. SimulationNowTime = Util.EnvironmentTickCount(); @@ -748,9 +758,6 @@ namespace OpenSim.Region.PhysicsModule.BulletS } } - // Some actors want to know when the simulation step is complete. - TriggerPostStepEvent(timeStep); - simTime = Util.EnvironmentTickCountSubtract(beforeTime); if (PhysicsLogging.Enabled) { @@ -956,6 +963,149 @@ namespace OpenSim.Region.PhysicsModule.BulletS #endregion // Terrain + #region Raycast + + public override bool SupportsRayCast() + { + return BSParam.UseBulletRaycast; + } + + public override bool SupportsRaycastWorldFiltered() + { + return BSParam.UseBulletRaycast; + } + + + /// + /// Queue a raycast against the physics scene. + /// The provided callback method will be called when the raycast is complete + /// + /// Many physics engines don't support collision testing at the same time as + /// manipulating the physics scene, so we queue the request up and callback + /// a custom method when the raycast is complete. + /// This allows physics engines that give an immediate result to callback immediately + /// and ones that don't, to callback when it gets a result back. + /// public delegate void RayCallback(List list); + /// + /// ODE for example will not allow you to change the scene while collision testing or + /// it asserts, 'opteration not valid for locked space'. This includes adding a ray to the scene. + /// + /// This is named RayCastWorld to not conflict with modrex's Raycast method. + /// + /// Origin of the ray + /// Direction of the ray + /// Length of ray in meters + /// Method to call when the raycast is complete + public override void RaycastWorld(Vector3 position, Vector3 direction, float length, RaycastCallback retMethod) + { + if (retMethod != null) + { + if (BSParam.UseBulletRaycast) + { + Vector3 posFrom = position; + Vector3 posTo = Vector3.Normalize(direction) * length + position; + + TaintedObject(DetailLogZero, "BSScene.RaycastWorld1", delegate () + { + RaycastHit hitInfo = PE.RayTest2(World, posFrom, posTo, 0xffff, 0xffff); + retMethod(true, hitInfo.Point, hitInfo.ID, hitInfo.Fraction, hitInfo.Normal); + }); + } + else + { + retMethod(false, Vector3.Zero, 0, 999999999999f, Vector3.Zero); + } + } + } + + public override void RaycastWorld(Vector3 position, Vector3 direction, float length, int count, RayCallback retMethod) + { + if (retMethod != null) + { + if (BSParam.UseBulletRaycast) + { + List hitInfo = RaycastWorld(position, direction, length, count); + retMethod(hitInfo); + } + else + { + retMethod(new List()); + } + } + } + + public override List RaycastWorld(Vector3 position, Vector3 direction, float length, int count) + { + return (List)RaycastWorld(position, direction, length, count, RayFilterFlags.All); + } + + public override object RaycastWorld(Vector3 position, Vector3 direction, float length, int count, RayFilterFlags filter) + { + List ret = new List(); + if (BSParam.UseBulletRaycast) + { + uint collisionFilter = 0; + uint collisionMask = 0; + if ((filter & RayFilterFlags.land) != 0) + { + collisionFilter |= BulletSimData.CollisionTypeMasks[CollisionType.Terrain].group; + collisionMask |= BulletSimData.CollisionTypeMasks[CollisionType.Terrain].mask; + } + if ((filter & RayFilterFlags.agent) != 0) + { + collisionFilter |= BulletSimData.CollisionTypeMasks[CollisionType.Avatar].group; + collisionMask |= BulletSimData.CollisionTypeMasks[CollisionType.Avatar].mask; + } + if ((filter & RayFilterFlags.nonphysical) != 0) + { + collisionFilter |= BulletSimData.CollisionTypeMasks[CollisionType.Static].group; + collisionMask |= BulletSimData.CollisionTypeMasks[CollisionType.Static].mask; + } + if ((filter & RayFilterFlags.physical) != 0) + { + collisionFilter |= BulletSimData.CollisionTypeMasks[CollisionType.Dynamic].group; + collisionMask |= BulletSimData.CollisionTypeMasks[CollisionType.Dynamic].mask; + } + // if ((filter & RayFilterFlags.phantom) != 0) + // { + // collisionFilter |= BulletSimData.CollisionTypeMasks[CollisionType.VolumeDetect].group; + // collisionMask |= BulletSimData.CollisionTypeMasks[CollisionType.VolumeDetect].mask; + // } + if ((filter & RayFilterFlags.volumedtc) != 0) + { + collisionFilter |= BulletSimData.CollisionTypeMasks[CollisionType.VolumeDetect].group; + collisionMask |= BulletSimData.CollisionTypeMasks[CollisionType.VolumeDetect].mask; + } + DetailLog("{0},RaycastWorld,pos={1},dir={2},len={3},count={4},filter={5},filter={6},mask={7}", + DetailLogZero, position, direction, length, count, filter, collisionFilter, collisionMask); + // NOTE: locking ensures the physics engine is not executing. + // The caller might have to wait for the physics engine to finish. + lock (PhysicsEngineLock) + { + Vector3 posFrom = position; + Vector3 posTo = Vector3.Normalize(direction) * length + position; + DetailLog("{0},RaycastWorld,RayTest2,from={1},to={2}", + DetailLogZero, posFrom, posTo); + RaycastHit hitInfo = PE.RayTest2(World, posFrom, posTo, collisionFilter, collisionMask); + if (hitInfo.hasHit()) + { + ContactResult result = new ContactResult(); + result.Pos = hitInfo.Point; + result.Normal = hitInfo.Normal; + result.ConsumerID = hitInfo.ID; + result.Depth = hitInfo.Fraction; + ret.Add(result); + DetailLog("{0},RaycastWorld,hit,pos={1},norm={2},depth={3},id={4}", + DetailLogZero, result.Pos, result.Normal, result.Depth, result.ConsumerID); + } + } + } + return ret; + } + + #endregion Raycast + + public override Dictionary GetTopColliders() { Dictionary topColliders; @@ -1068,32 +1218,35 @@ namespace OpenSim.Region.PhysicsModule.BulletS // Calls to the PhysicsActors can't directly call into the physics engine // because it might be busy. We delay changes to a known time. // We rely on C#'s closure to save and restore the context for the delegate. - public void TaintedObject(string pOriginator, string pIdent, TaintCallback pCallback) + // NOTE: 'inTaintTime' is no longer used. This entry exists so all the calls don't have to be changed. + // public void TaintedObject(bool inTaintTime, String pIdent, TaintCallback pCallback) + // { + // TaintedObject(BSScene.DetailLogZero, pIdent, pCallback); + // } + // NOTE: 'inTaintTime' is no longer used. This entry exists so all the calls don't have to be changed. + public void TaintedObject(bool inTaintTime, uint pOriginator, String pIdent, TaintCallback pCallback) { - TaintedObject(false /*inTaintTime*/, pOriginator, pIdent, pCallback); + TaintedObject(m_physicsLoggingEnabled ? pOriginator.ToString() : BSScene.DetailLogZero, pIdent, pCallback); } public void TaintedObject(uint pOriginator, String pIdent, TaintCallback pCallback) { - TaintedObject(false /*inTaintTime*/, m_physicsLoggingEnabled ? pOriginator.ToString() : BSScene.DetailLogZero, pIdent, pCallback); - } - public void TaintedObject(bool inTaintTime, String pIdent, TaintCallback pCallback) - { - TaintedObject(inTaintTime, BSScene.DetailLogZero, pIdent, pCallback); - } - public void TaintedObject(bool inTaintTime, uint pOriginator, String pIdent, TaintCallback pCallback) - { - TaintedObject(inTaintTime, m_physicsLoggingEnabled ? pOriginator.ToString() : BSScene.DetailLogZero, pIdent, pCallback); + TaintedObject(m_physicsLoggingEnabled ? pOriginator.ToString() : BSScene.DetailLogZero, pIdent, pCallback); } // Sometimes a potentially tainted operation can be used in and out of taint time. // This routine executes the command immediately if in taint-time otherwise it is queued. - public void TaintedObject(bool inTaintTime, string pOriginator, string pIdent, TaintCallback pCallback) + public void TaintedObject(string pOriginator, string pIdent, TaintCallback pCallback) { if (!m_initialized) return; - if (inTaintTime) + if (Monitor.TryEnter(PhysicsEngineLock)) + { + // If we can get exclusive access to the physics engine, just do the operation pCallback(); + Monitor.Exit(PhysicsEngineLock); + } else { + // The physics engine is busy, queue the operation lock (_taintLock) { _taintOperations.Add(new TaintCallbackEntry(pOriginator, pIdent, pCallback)); @@ -1120,14 +1273,21 @@ namespace OpenSim.Region.PhysicsModule.BulletS // When someone tries to change a property on a BSPrim or BSCharacter, the object queues // a callback into itself to do the actual property change. That callback is called // here just before the physics engine is called to step the simulation. - public void ProcessTaints() + // Returns the number of taints processed + // NOTE: Called while PhysicsEngineLock is locked + public int ProcessTaints() { - ProcessRegularTaints(); - ProcessPostTaintTaints(); + int ret = 0; + ret += ProcessRegularTaints(); + ret += ProcessPostTaintTaints(); + return ret; } - private void ProcessRegularTaints() + // Returns the number of taints processed + // NOTE: Called while PhysicsEngineLock is locked + private int ProcessRegularTaints() { + int ret = 0; if (m_initialized && _taintOperations.Count > 0) // save allocating new list if there is nothing to process { // swizzle a new list into the list location so we can process what's there @@ -1144,6 +1304,7 @@ namespace OpenSim.Region.PhysicsModule.BulletS { DetailLog("{0},BSScene.ProcessTaints,doTaint,id={1}", tcbe.originator, tcbe.ident); // DEBUG DEBUG DEBUG tcbe.callback(); + ret++; } catch (Exception e) { @@ -1152,6 +1313,7 @@ namespace OpenSim.Region.PhysicsModule.BulletS } oldList.Clear(); } + return ret; } // Schedule an update to happen after all the regular taints are processed. @@ -1170,8 +1332,11 @@ namespace OpenSim.Region.PhysicsModule.BulletS } // Taints that happen after the normal taint processing but before the simulation step. - private void ProcessPostTaintTaints() + // Returns the number of taints processed + // NOTE: Called while PhysicsEngineLock is locked + private int ProcessPostTaintTaints() { + int ret = 0; if (m_initialized && _postTaintOperations.Count > 0) { Dictionary oldList; @@ -1187,6 +1352,7 @@ namespace OpenSim.Region.PhysicsModule.BulletS { DetailLog("{0},BSScene.ProcessPostTaintTaints,doTaint,id={1}", DetailLogZero, kvp.Key); // DEBUG DEBUG DEBUG kvp.Value.callback(); + ret++; } catch (Exception e) { @@ -1195,20 +1361,8 @@ namespace OpenSim.Region.PhysicsModule.BulletS } oldList.Clear(); } + return ret; } - - // Only used for debugging. Does not change state of anything so locking is not necessary. - public bool AssertInTaintTime(string whereFrom) - { - if (!InTaintTime) - { - DetailLog("{0},BSScene.AssertInTaintTime,NOT IN TAINT TIME,Region={1},Where={2}", DetailLogZero, RegionName, whereFrom); - m_log.ErrorFormat("{0} NOT IN TAINT TIME!! Region={1}, Where={2}", LogHeader, RegionName, whereFrom); - // Util.PrintCallStack(DetailLog); - } - return InTaintTime; - } - #endregion // Taints #region IPhysicsParameters diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSShapeCollection.cs b/OpenSim/Region/PhysicsModules/BulletS/BSShapeCollection.cs index 4ec6f514be..86bf23f226 100755 --- a/OpenSim/Region/PhysicsModules/BulletS/BSShapeCollection.cs +++ b/OpenSim/Region/PhysicsModules/BulletS/BSShapeCollection.cs @@ -75,8 +75,6 @@ public sealed class BSShapeCollection : IDisposable // Called at taint-time. public bool GetBodyAndShape(bool forceRebuild, BulletWorld sim, BSPhysObject prim, PhysicalDestructionCallback bodyCallback) { - m_physicsScene.AssertInTaintTime("BSShapeCollection.GetBodyAndShape"); - bool ret = false; // This lock could probably be pushed down lower but building shouldn't take long @@ -229,6 +227,8 @@ public sealed class BSShapeCollection : IDisposable ret = CreateGeomMeshOrHull(prim, shapeCallback); } + m_physicsScene.PE.ResetBroadphasePool(m_physicsScene.World); // DEBUG DEBUG + return ret; } @@ -344,8 +344,6 @@ public sealed class BSShapeCollection : IDisposable if (!body.HasPhysicalBody) return; - m_physicsScene.AssertInTaintTime("BSShapeCollection.DereferenceBody"); - lock (m_collectionActivityLock) { if (DDetail) DetailLog("{0},BSShapeCollection.DereferenceBody,DestroyingBody,body={1}", body.ID, body); diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSTerrainHeightmap.cs b/OpenSim/Region/PhysicsModules/BulletS/BSTerrainHeightmap.cs index 42fc11bcd5..f72ad28600 100755 --- a/OpenSim/Region/PhysicsModules/BulletS/BSTerrainHeightmap.cs +++ b/OpenSim/Region/PhysicsModules/BulletS/BSTerrainHeightmap.cs @@ -141,14 +141,30 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys } // The passed position is relative to the base of the region. + // There are many assumptions herein that the heightmap increment is 1. public override float GetTerrainHeightAtXYZ(Vector3 pos) { float ret = BSTerrainManager.HEIGHT_GETHEIGHT_RET; - int mapIndex = (int)pos.Y * (int)m_mapInfo.sizeY + (int)pos.X; - try - { - ret = m_mapInfo.heightMap[mapIndex]; + try { + int baseX = (int)pos.X; + int baseY = (int)pos.Y; + int maxX = (int)m_mapInfo.sizeX; + int maxY = (int)m_mapInfo.sizeY; + float diffX = pos.X - (float)baseX; + float diffY = pos.Y - (float)baseY; + + float mapHeight1 = m_mapInfo.heightMap[baseY * maxY + baseX]; + float mapHeight2 = m_mapInfo.heightMap[Math.Min(baseY + 1, maxY - 1) * maxY + baseX]; + float mapHeight3 = m_mapInfo.heightMap[baseY * maxY + Math.Min(baseX + 1, maxX - 1)]; + float mapHeight4 = m_mapInfo.heightMap[Math.Min(baseY + 1, maxY - 1) * maxY + Math.Min(baseX + 1, maxX - 1)]; + + float Xrise = (mapHeight4 - mapHeight3) * diffX; + float Yrise = (mapHeight2 - mapHeight1) * diffY; + + ret = mapHeight1 + ((Xrise + Yrise) / 2f); + // m_physicsScene.DetailLog("{0},BSTerrainHeightMap,GetTerrainHeightAtXYZ,pos={1},{2}/{3}/{4}/{5},ret={6}", + // BSScene.DetailLogZero, pos, mapHeight1, mapHeight2, mapHeight3, mapHeight4, ret); } catch { diff --git a/OpenSim/Region/PhysicsModules/BulletS/BulletSimData.cs b/OpenSim/Region/PhysicsModules/BulletS/BulletSimData.cs index 3329395274..308769b3d0 100755 --- a/OpenSim/Region/PhysicsModules/BulletS/BulletSimData.cs +++ b/OpenSim/Region/PhysicsModules/BulletS/BulletSimData.cs @@ -100,6 +100,7 @@ public class BulletBody } } +// Handle to btCollisionObject - a shape that can be added to a btRidgidBody public class BulletShape { public BulletShape() diff --git a/OpenSim/Region/PhysicsModules/BulletS/Tests/Raycast.cs b/OpenSim/Region/PhysicsModules/BulletS/Tests/Raycast.cs new file mode 100755 index 0000000000..a6f587e974 --- /dev/null +++ b/OpenSim/Region/PhysicsModules/BulletS/Tests/Raycast.cs @@ -0,0 +1,124 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using NUnit.Framework; +using log4net; + +using OpenSim.Framework; +using OpenSim.Region.PhysicsModule.BulletS; +using OpenSim.Region.PhysicsModules.SharedBase; +using OpenSim.Tests.Common; + +using OpenMetaverse; + +namespace OpenSim.Region.PhysicsModule.BulletS.Tests +{ + [TestFixture] + public class BulletSimRaycast : OpenSimTestCase + { + // Documentation on attributes: http://www.nunit.org/index.php?p=attributes&r=2.6.1 + // Documentation on assertions: http://www.nunit.org/index.php?p=assertions&r=2.6.1 + + BSScene _physicsScene { get; set; } + BSPrim _targetSphere { get; set; } + Vector3 _targetSpherePosition { get; set; } +// float _simulationTimeStep = 0.089f; + + uint _targetLocalID = 123; + + [TestFixtureSetUp] + public void Init() + { + Dictionary engineParams = new Dictionary(); + engineParams.Add("UseBulletRaycast", "true"); + _physicsScene = BulletSimTestsUtil.CreateBasicPhysicsEngine(engineParams); + + PrimitiveBaseShape pbs = PrimitiveBaseShape.CreateSphere(); + Vector3 pos = new Vector3(100.0f, 100.0f, 50f); + _targetSpherePosition = pos; + Vector3 size = new Vector3(10f, 10f, 10f); + pbs.Scale = size; + Quaternion rot = Quaternion.Identity; + bool isPhys = false; + + _physicsScene.AddPrimShape("TargetSphere", pbs, pos, size, rot, isPhys, _targetLocalID); + _targetSphere = (BSPrim)_physicsScene.PhysObjects[_targetLocalID]; + // The actual prim shape creation happens at taint time + _physicsScene.ProcessTaints(); + + } + + [TestFixtureTearDown] + public void TearDown() + { + if (_physicsScene != null) + { + // The Dispose() will also free any physical objects in the scene + _physicsScene.Dispose(); + _physicsScene = null; + } + } + + // There is a 10x10x10 sphere at <100,100,50> + // Shoot rays around the sphere and verify it hits and doesn't hit + // TestCase parameters are of start and of end and expected result + [TestCase(100f, 50f, 50f, 100f, 150f, 50f, true, "Pass through sphere from front")] + [TestCase(50f, 100f, 50f, 150f, 100f, 50f, true, "Pass through sphere from side")] + [TestCase(50f, 50f, 50f, 150f, 150f, 50f, true, "Pass through sphere diaginally")] + [TestCase(100f, 100f, 100f, 100f, 100f, 20f, true, "Pass through sphere from above")] + [TestCase(20f, 20f, 50f, 80f, 80f, 50f, false, "Not reach sphere")] + [TestCase(50f, 50f, 65f, 150f, 150f, 65f, false, "Passed over sphere")] + public void RaycastAroundObject(float fromX, float fromY, float fromZ, float toX, float toY, float toZ, bool expected, string msg) { + Vector3 fromPos = new Vector3(fromX, fromY, fromZ); + Vector3 toPos = new Vector3(toX, toY, toZ); + Vector3 direction = toPos - fromPos; + float len = Vector3.Distance(fromPos, toPos); + + List results = _physicsScene.RaycastWorld(fromPos, direction, len, 1); + + if (expected) { + // The test coordinates should generate a hit + Assert.True(results.Count != 0, msg + ": Did not return a hit but expected to."); + Assert.True(results.Count == 1, msg + ": Raycast returned not just one hit result."); + Assert.True(results[0].ConsumerID == _targetLocalID, msg + ": Raycast returned a collision object other than the target"); + } + else + { + // The test coordinates should not generate a hit + if (results.Count > 0) + { + Assert.False(results.Count > 0, msg + ": Returned a hit at " + results[0].Pos.ToString()); + } + } + } + } +} \ No newline at end of file diff --git a/OpenSim/Region/PhysicsModules/Meshing/Meshmerizer/Meshmerizer.cs b/OpenSim/Region/PhysicsModules/Meshing/Meshmerizer/Meshmerizer.cs index 4f95554863..0d4b6b96f2 100644 --- a/OpenSim/Region/PhysicsModules/Meshing/Meshmerizer/Meshmerizer.cs +++ b/OpenSim/Region/PhysicsModules/Meshing/Meshmerizer/Meshmerizer.cs @@ -66,7 +66,7 @@ namespace OpenSim.Region.PhysicsModule.Meshing private bool cacheSculptMaps = true; private string decodedSculptMapPath = null; - private bool useMeshiesPhysicsMesh = false; + private bool useMeshiesPhysicsMesh = true; private float minSizeForComplexMesh = 0.2f; // prims with all dimensions smaller than this will have a bounding box mesh diff --git a/OpenSim/Region/PhysicsModules/Ode/ODEApi.cs b/OpenSim/Region/PhysicsModules/Ode/ODEApi.cs index c851b12ff2..cc3077ea03 100644 --- a/OpenSim/Region/PhysicsModules/Ode/ODEApi.cs +++ b/OpenSim/Region/PhysicsModules/Ode/ODEApi.cs @@ -55,18 +55,18 @@ namespace OpenSim.Region.PhysicsModule.ODE using dReal = System.Single; //#endif - public static class d + internal static class SafeNativeMethods { - public static dReal Infinity = dReal.MaxValue; - public static int NTotalBodies = 0; - public static int NTotalGeoms = 0; + internal static dReal Infinity = dReal.MaxValue; + internal static int NTotalBodies = 0; + internal static int NTotalGeoms = 0; - public const uint CONTACTS_UNIMPORTANT = 0x80000000; + internal const uint CONTACTS_UNIMPORTANT = 0x80000000; #region Flags and Enumerations [Flags] - public enum AllocateODEDataFlags : uint + internal enum AllocateODEDataFlags : uint { BasicData = 0, CollisionData = 0x00000001, @@ -74,13 +74,13 @@ namespace OpenSim.Region.PhysicsModule.ODE } [Flags] - public enum IniteODEFlags : uint + internal enum IniteODEFlags : uint { dInitFlagManualThreadCleanup = 0x00000001 } [Flags] - public enum ContactFlags : int + internal enum ContactFlags : int { Mu2 = 0x001, FDir1 = 0x002, @@ -98,7 +98,7 @@ namespace OpenSim.Region.PhysicsModule.ODE Approx1 = 0x3000 } - public enum GeomClassID : int + internal enum GeomClassID : int { SphereClass, BoxClass, @@ -122,7 +122,7 @@ namespace OpenSim.Region.PhysicsModule.ODE MaxUserClasses = 5 } - public enum JointType : int + internal enum JointType : int { None, Ball, @@ -138,7 +138,7 @@ namespace OpenSim.Region.PhysicsModule.ODE Plane2D } - public enum JointParam : int + internal enum JointParam : int { LoStop, HiStop, @@ -175,7 +175,7 @@ namespace OpenSim.Region.PhysicsModule.ODE SuspensionCFM3 } - public enum dSweepAndPruneAxis : int + internal enum dSweepAndPruneAxis : int { XYZ = ((0)|(1<<2)|(2<<4)), XZY = ((0)|(2<<2)|(1<<4)), @@ -190,126 +190,126 @@ namespace OpenSim.Region.PhysicsModule.ODE #region Callbacks [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate int AABBTestFn(IntPtr o1, IntPtr o2, ref AABB aabb); + internal delegate int AABBTestFn(IntPtr o1, IntPtr o2, ref AABB aabb); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate int ColliderFn(IntPtr o1, IntPtr o2, int flags, out ContactGeom contact, int skip); + internal delegate int ColliderFn(IntPtr o1, IntPtr o2, int flags, out ContactGeom contact, int skip); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate void GetAABBFn(IntPtr geom, out AABB aabb); + internal delegate void GetAABBFn(IntPtr geom, out AABB aabb); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate ColliderFn GetColliderFnFn(int num); + internal delegate ColliderFn GetColliderFnFn(int num); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate void GeomDtorFn(IntPtr o); + internal delegate void GeomDtorFn(IntPtr o); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate dReal HeightfieldGetHeight(IntPtr p_user_data, int x, int z); + internal delegate dReal HeightfieldGetHeight(IntPtr p_user_data, int x, int z); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate dReal OSTerrainGetHeight(IntPtr p_user_data, int x, int z); + internal delegate dReal OSTerrainGetHeight(IntPtr p_user_data, int x, int z); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate void NearCallback(IntPtr data, IntPtr geom1, IntPtr geom2); + internal delegate void NearCallback(IntPtr data, IntPtr geom1, IntPtr geom2); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate int TriCallback(IntPtr trimesh, IntPtr refObject, int triangleIndex); + internal delegate int TriCallback(IntPtr trimesh, IntPtr refObject, int triangleIndex); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate int TriArrayCallback(IntPtr trimesh, IntPtr refObject, int[] triangleIndex, int triCount); + internal delegate int TriArrayCallback(IntPtr trimesh, IntPtr refObject, int[] triangleIndex, int triCount); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate int TriRayCallback(IntPtr trimesh, IntPtr ray, int triangleIndex, dReal u, dReal v); + internal delegate int TriRayCallback(IntPtr trimesh, IntPtr ray, int triangleIndex, dReal u, dReal v); #endregion #region Structs [StructLayout(LayoutKind.Sequential)] - public struct AABB + internal struct AABB { - public dReal MinX, MaxX; - public dReal MinY, MaxY; - public dReal MinZ, MaxZ; + internal dReal MinX, MaxX; + internal dReal MinY, MaxY; + internal dReal MinZ, MaxZ; } [StructLayout(LayoutKind.Sequential)] - public struct Contact + internal struct Contact { - public SurfaceParameters surface; - public ContactGeom geom; - public Vector3 fdir1; - public static readonly int unmanagedSizeOf = Marshal.SizeOf(typeof(Contact)); + internal SurfaceParameters surface; + internal ContactGeom geom; + internal Vector3 fdir1; + internal static readonly int unmanagedSizeOf = Marshal.SizeOf(typeof(Contact)); } [StructLayout(LayoutKind.Sequential)] - public struct ContactGeom + internal struct ContactGeom { - public Vector3 pos; - public Vector3 normal; - public dReal depth; - public IntPtr g1; - public IntPtr g2; - public int side1; - public int side2; - public static readonly int unmanagedSizeOf = Marshal.SizeOf(typeof(ContactGeom)); + internal Vector3 pos; + internal Vector3 normal; + internal dReal depth; + internal IntPtr g1; + internal IntPtr g2; + internal int side1; + internal int side2; + internal static readonly int unmanagedSizeOf = Marshal.SizeOf(typeof(ContactGeom)); } [StructLayout(LayoutKind.Sequential)] - public struct GeomClass + internal struct GeomClass { - public int bytes; - public GetColliderFnFn collider; - public GetAABBFn aabb; - public AABBTestFn aabb_test; - public GeomDtorFn dtor; + internal int bytes; + internal GetColliderFnFn collider; + internal GetAABBFn aabb; + internal AABBTestFn aabb_test; + internal GeomDtorFn dtor; } [StructLayout(LayoutKind.Sequential)] - public struct JointFeedback + internal struct JointFeedback { - public Vector3 f1; - public Vector3 t1; - public Vector3 f2; - public Vector3 t2; + internal Vector3 f1; + internal Vector3 t1; + internal Vector3 f2; + internal Vector3 t2; } [StructLayout(LayoutKind.Sequential)] - public struct Mass + internal struct Mass { - public dReal mass; - public Vector4 c; - public Matrix3 I; + internal dReal mass; + internal Vector4 c; + internal Matrix3 I; } [StructLayout(LayoutKind.Sequential)] - public struct Matrix3 + internal struct Matrix3 { - public Matrix3(dReal m00, dReal m10, dReal m20, dReal m01, dReal m11, dReal m21, dReal m02, dReal m12, dReal m22) + internal Matrix3(dReal m00, dReal m10, dReal m20, dReal m01, dReal m11, dReal m21, dReal m02, dReal m12, dReal m22) { M00 = m00; M10 = m10; M20 = m20; _m30 = 0.0f; M01 = m01; M11 = m11; M21 = m21; _m31 = 0.0f; M02 = m02; M12 = m12; M22 = m22; _m32 = 0.0f; } - public dReal M00, M10, M20; + internal dReal M00, M10, M20; private dReal _m30; - public dReal M01, M11, M21; + internal dReal M01, M11, M21; private dReal _m31; - public dReal M02, M12, M22; + internal dReal M02, M12, M22; private dReal _m32; } [StructLayout(LayoutKind.Sequential)] - public struct Matrix4 + internal struct Matrix4 { - public Matrix4(dReal m00, dReal m10, dReal m20, dReal m30, + internal Matrix4(dReal m00, dReal m10, dReal m20, dReal m30, dReal m01, dReal m11, dReal m21, dReal m31, dReal m02, dReal m12, dReal m22, dReal m32, dReal m03, dReal m13, dReal m23, dReal m33) @@ -319,312 +319,312 @@ namespace OpenSim.Region.PhysicsModule.ODE M02 = m02; M12 = m12; M22 = m22; M32 = m32; M03 = m03; M13 = m13; M23 = m23; M33 = m33; } - public dReal M00, M10, M20, M30; - public dReal M01, M11, M21, M31; - public dReal M02, M12, M22, M32; - public dReal M03, M13, M23, M33; + internal dReal M00, M10, M20, M30; + internal dReal M01, M11, M21, M31; + internal dReal M02, M12, M22, M32; + internal dReal M03, M13, M23, M33; } [StructLayout(LayoutKind.Sequential)] - public struct Quaternion + internal struct Quaternion { - public dReal W, X, Y, Z; + internal dReal W, X, Y, Z; } [StructLayout(LayoutKind.Sequential)] - public struct SurfaceParameters + internal struct SurfaceParameters { - public ContactFlags mode; - public dReal mu; - public dReal mu2; - public dReal bounce; - public dReal bounce_vel; - public dReal soft_erp; - public dReal soft_cfm; - public dReal motion1; - public dReal motion2; - public dReal motionN; - public dReal slip1; - public dReal slip2; + internal ContactFlags mode; + internal dReal mu; + internal dReal mu2; + internal dReal bounce; + internal dReal bounce_vel; + internal dReal soft_erp; + internal dReal soft_cfm; + internal dReal motion1; + internal dReal motion2; + internal dReal motionN; + internal dReal slip1; + internal dReal slip2; } [StructLayout(LayoutKind.Sequential)] - public struct Vector3 + internal struct Vector3 { - public Vector3(dReal x, dReal y, dReal z) + internal Vector3(dReal x, dReal y, dReal z) { X = x; Y = y; Z = z; _w = 0.0f; } - public dReal X, Y, Z; + internal dReal X, Y, Z; private dReal _w; } [StructLayout(LayoutKind.Sequential)] - public struct Vector4 + internal struct Vector4 { - public Vector4(dReal x, dReal y, dReal z, dReal w) + internal Vector4(dReal x, dReal y, dReal z, dReal w) { X = x; Y = y; Z = z; W = w; } - public dReal X, Y, Z, W; + internal dReal X, Y, Z, W; } #endregion [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dAllocateODEDataForThread"), SuppressUnmanagedCodeSecurity] - public static extern int AllocateODEDataForThread(uint ODEInitFlags); + internal static extern int AllocateODEDataForThread(uint ODEInitFlags); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dAreConnected"), SuppressUnmanagedCodeSecurity] - public static extern bool AreConnected(IntPtr b1, IntPtr b2); + internal static extern bool AreConnected(IntPtr b1, IntPtr b2); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dAreConnectedExcluding"), SuppressUnmanagedCodeSecurity] - public static extern bool AreConnectedExcluding(IntPtr b1, IntPtr b2, JointType joint_type); + internal static extern bool AreConnectedExcluding(IntPtr b1, IntPtr b2, JointType joint_type); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyAddForce"), SuppressUnmanagedCodeSecurity] - public static extern void BodyAddForce(IntPtr body, dReal fx, dReal fy, dReal fz); + internal static extern void BodyAddForce(IntPtr body, dReal fx, dReal fy, dReal fz); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyAddForceAtPos"), SuppressUnmanagedCodeSecurity] - public static extern void BodyAddForceAtPos(IntPtr body, dReal fx, dReal fy, dReal fz, dReal px, dReal py, dReal pz); + internal static extern void BodyAddForceAtPos(IntPtr body, dReal fx, dReal fy, dReal fz, dReal px, dReal py, dReal pz); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyAddForceAtRelPos"), SuppressUnmanagedCodeSecurity] - public static extern void BodyAddForceAtRelPos(IntPtr body, dReal fx, dReal fy, dReal fz, dReal px, dReal py, dReal pz); + internal static extern void BodyAddForceAtRelPos(IntPtr body, dReal fx, dReal fy, dReal fz, dReal px, dReal py, dReal pz); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyAddRelForce"), SuppressUnmanagedCodeSecurity] - public static extern void BodyAddRelForce(IntPtr body, dReal fx, dReal fy, dReal fz); + internal static extern void BodyAddRelForce(IntPtr body, dReal fx, dReal fy, dReal fz); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyAddRelForceAtPos"), SuppressUnmanagedCodeSecurity] - public static extern void BodyAddRelForceAtPos(IntPtr body, dReal fx, dReal fy, dReal fz, dReal px, dReal py, dReal pz); + internal static extern void BodyAddRelForceAtPos(IntPtr body, dReal fx, dReal fy, dReal fz, dReal px, dReal py, dReal pz); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyAddRelForceAtRelPos"), SuppressUnmanagedCodeSecurity] - public static extern void BodyAddRelForceAtRelPos(IntPtr body, dReal fx, dReal fy, dReal fz, dReal px, dReal py, dReal pz); + internal static extern void BodyAddRelForceAtRelPos(IntPtr body, dReal fx, dReal fy, dReal fz, dReal px, dReal py, dReal pz); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyAddRelTorque"), SuppressUnmanagedCodeSecurity] - public static extern void BodyAddRelTorque(IntPtr body, dReal fx, dReal fy, dReal fz); + internal static extern void BodyAddRelTorque(IntPtr body, dReal fx, dReal fy, dReal fz); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyAddTorque"), SuppressUnmanagedCodeSecurity] - public static extern void BodyAddTorque(IntPtr body, dReal fx, dReal fy, dReal fz); + internal static extern void BodyAddTorque(IntPtr body, dReal fx, dReal fy, dReal fz); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyCopyPosition"), SuppressUnmanagedCodeSecurity] - public static extern void BodyCopyPosition(IntPtr body, out Vector3 pos); + internal static extern void BodyCopyPosition(IntPtr body, out Vector3 pos); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyCopyPosition"), SuppressUnmanagedCodeSecurity] - public static extern void BodyCopyPosition(IntPtr body, out dReal X); + internal static extern void BodyCopyPosition(IntPtr body, out dReal X); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyCopyQuaternion"), SuppressUnmanagedCodeSecurity] - public static extern void BodyCopyQuaternion(IntPtr body, out Quaternion quat); + internal static extern void BodyCopyQuaternion(IntPtr body, out Quaternion quat); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyCopyQuaternion"), SuppressUnmanagedCodeSecurity] - public static extern void BodyCopyQuaternion(IntPtr body, out dReal X); + internal static extern void BodyCopyQuaternion(IntPtr body, out dReal X); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyCopyRotation"), SuppressUnmanagedCodeSecurity] - public static extern void BodyCopyRotation(IntPtr body, out Matrix3 R); + internal static extern void BodyCopyRotation(IntPtr body, out Matrix3 R); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyCopyRotation"), SuppressUnmanagedCodeSecurity] - public static extern void BodyCopyRotation(IntPtr body, out dReal M00); + internal static extern void BodyCopyRotation(IntPtr body, out dReal M00); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyCreate"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr BodyiCreate(IntPtr world); - public static IntPtr BodyCreate(IntPtr world) + internal static extern IntPtr BodyiCreate(IntPtr world); + internal static IntPtr BodyCreate(IntPtr world) { NTotalBodies++; return BodyiCreate(world); } [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyDestroy"), SuppressUnmanagedCodeSecurity] - public static extern void BodyiDestroy(IntPtr body); - public static void BodyDestroy(IntPtr body) + internal static extern void BodyiDestroy(IntPtr body); + internal static void BodyDestroy(IntPtr body) { NTotalBodies--; BodyiDestroy(body); } [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyDisable"), SuppressUnmanagedCodeSecurity] - public static extern void BodyDisable(IntPtr body); + internal static extern void BodyDisable(IntPtr body); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyEnable"), SuppressUnmanagedCodeSecurity] - public static extern void BodyEnable(IntPtr body); + internal static extern void BodyEnable(IntPtr body); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetAutoDisableAngularThreshold"), SuppressUnmanagedCodeSecurity] - public static extern dReal BodyGetAutoDisableAngularThreshold(IntPtr body); + internal static extern dReal BodyGetAutoDisableAngularThreshold(IntPtr body); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetAutoDisableFlag"), SuppressUnmanagedCodeSecurity] - public static extern bool BodyGetAutoDisableFlag(IntPtr body); + internal static extern bool BodyGetAutoDisableFlag(IntPtr body); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetAutoDisableDefaults"), SuppressUnmanagedCodeSecurity] - public static extern void BodyGetAutoDisableDefaults(IntPtr body); + internal static extern void BodyGetAutoDisableDefaults(IntPtr body); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetAutoDisableLinearThreshold"), SuppressUnmanagedCodeSecurity] - public static extern dReal BodyGetAutoDisableLinearThreshold(IntPtr body); + internal static extern dReal BodyGetAutoDisableLinearThreshold(IntPtr body); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetAutoDisableSteps"), SuppressUnmanagedCodeSecurity] - public static extern int BodyGetAutoDisableSteps(IntPtr body); + internal static extern int BodyGetAutoDisableSteps(IntPtr body); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetAutoDisableTime"), SuppressUnmanagedCodeSecurity] - public static extern dReal BodyGetAutoDisableTime(IntPtr body); + internal static extern dReal BodyGetAutoDisableTime(IntPtr body); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetAngularVel"), SuppressUnmanagedCodeSecurity] - public extern unsafe static Vector3* BodyGetAngularVelUnsafe(IntPtr body); - public static Vector3 BodyGetAngularVel(IntPtr body) + internal extern unsafe static Vector3* BodyGetAngularVelUnsafe(IntPtr body); + internal static Vector3 BodyGetAngularVel(IntPtr body) { unsafe { return *(BodyGetAngularVelUnsafe(body)); } } [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetData"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr BodyGetData(IntPtr body); + internal static extern IntPtr BodyGetData(IntPtr body); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetFiniteRotationMode"), SuppressUnmanagedCodeSecurity] - public static extern int BodyGetFiniteRotationMode(IntPtr body); + internal static extern int BodyGetFiniteRotationMode(IntPtr body); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetFiniteRotationAxis"), SuppressUnmanagedCodeSecurity] - public static extern void BodyGetFiniteRotationAxis(IntPtr body, out Vector3 result); + internal static extern void BodyGetFiniteRotationAxis(IntPtr body, out Vector3 result); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetForce"), SuppressUnmanagedCodeSecurity] - public extern unsafe static Vector3* BodyGetForceUnsafe(IntPtr body); - public static Vector3 BodyGetForce(IntPtr body) + internal extern unsafe static Vector3* BodyGetForceUnsafe(IntPtr body); + internal static Vector3 BodyGetForce(IntPtr body) { unsafe { return *(BodyGetForceUnsafe(body)); } } [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetGravityMode"), SuppressUnmanagedCodeSecurity] - public static extern bool BodyGetGravityMode(IntPtr body); + internal static extern bool BodyGetGravityMode(IntPtr body); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetGyroscopicMode"), SuppressUnmanagedCodeSecurity] - public static extern int BodyGetGyroscopicMode(IntPtr body); + internal static extern int BodyGetGyroscopicMode(IntPtr body); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetJoint"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr BodyGetJoint(IntPtr body, int index); + internal static extern IntPtr BodyGetJoint(IntPtr body, int index); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetLinearVel"), SuppressUnmanagedCodeSecurity] - public extern unsafe static Vector3* BodyGetLinearVelUnsafe(IntPtr body); - public static Vector3 BodyGetLinearVel(IntPtr body) + internal extern unsafe static Vector3* BodyGetLinearVelUnsafe(IntPtr body); + internal static Vector3 BodyGetLinearVel(IntPtr body) { unsafe { return *(BodyGetLinearVelUnsafe(body)); } } [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetMass"), SuppressUnmanagedCodeSecurity] - public static extern void BodyGetMass(IntPtr body, out Mass mass); + internal static extern void BodyGetMass(IntPtr body, out Mass mass); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetNumJoints"), SuppressUnmanagedCodeSecurity] - public static extern int BodyGetNumJoints(IntPtr body); + internal static extern int BodyGetNumJoints(IntPtr body); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetPointVel"), SuppressUnmanagedCodeSecurity] - public static extern void BodyGetPointVel(IntPtr body, dReal px, dReal py, dReal pz, out Vector3 result); + internal static extern void BodyGetPointVel(IntPtr body, dReal px, dReal py, dReal pz, out Vector3 result); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetPosition"), SuppressUnmanagedCodeSecurity] - public extern unsafe static Vector3* BodyGetPositionUnsafe(IntPtr body); - public static Vector3 BodyGetPosition(IntPtr body) + internal extern unsafe static Vector3* BodyGetPositionUnsafe(IntPtr body); + internal static Vector3 BodyGetPosition(IntPtr body) { unsafe { return *(BodyGetPositionUnsafe(body)); } } [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetPosRelPoint"), SuppressUnmanagedCodeSecurity] - public static extern void BodyGetPosRelPoint(IntPtr body, dReal px, dReal py, dReal pz, out Vector3 result); + internal static extern void BodyGetPosRelPoint(IntPtr body, dReal px, dReal py, dReal pz, out Vector3 result); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetQuaternion"), SuppressUnmanagedCodeSecurity] - public extern unsafe static Quaternion* BodyGetQuaternionUnsafe(IntPtr body); - public static Quaternion BodyGetQuaternion(IntPtr body) + internal extern unsafe static Quaternion* BodyGetQuaternionUnsafe(IntPtr body); + internal static Quaternion BodyGetQuaternion(IntPtr body) { unsafe { return *(BodyGetQuaternionUnsafe(body)); } } [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetRelPointPos"), SuppressUnmanagedCodeSecurity] - public static extern void BodyGetRelPointPos(IntPtr body, dReal px, dReal py, dReal pz, out Vector3 result); + internal static extern void BodyGetRelPointPos(IntPtr body, dReal px, dReal py, dReal pz, out Vector3 result); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetRelPointVel"), SuppressUnmanagedCodeSecurity] - public static extern void BodyGetRelPointVel(IntPtr body, dReal px, dReal py, dReal pz, out Vector3 result); + internal static extern void BodyGetRelPointVel(IntPtr body, dReal px, dReal py, dReal pz, out Vector3 result); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetRotation"), SuppressUnmanagedCodeSecurity] - public extern unsafe static Matrix3* BodyGetRotationUnsafe(IntPtr body); - public static Matrix3 BodyGetRotation(IntPtr body) + internal extern unsafe static Matrix3* BodyGetRotationUnsafe(IntPtr body); + internal static Matrix3 BodyGetRotation(IntPtr body) { unsafe { return *(BodyGetRotationUnsafe(body)); } } [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetTorque"), SuppressUnmanagedCodeSecurity] - public extern unsafe static Vector3* BodyGetTorqueUnsafe(IntPtr body); - public static Vector3 BodyGetTorque(IntPtr body) + internal extern unsafe static Vector3* BodyGetTorqueUnsafe(IntPtr body); + internal static Vector3 BodyGetTorque(IntPtr body) { unsafe { return *(BodyGetTorqueUnsafe(body)); } } [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetWorld"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr BodyGetWorld(IntPtr body); + internal static extern IntPtr BodyGetWorld(IntPtr body); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetFirstGeom"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr BodyGetFirstGeom(IntPtr body); + internal static extern IntPtr BodyGetFirstGeom(IntPtr body); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetNextGeom"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr dBodyGetNextGeom(IntPtr Geom); + internal static extern IntPtr dBodyGetNextGeom(IntPtr Geom); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyIsEnabled"), SuppressUnmanagedCodeSecurity] - public static extern bool BodyIsEnabled(IntPtr body); + internal static extern bool BodyIsEnabled(IntPtr body); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetAngularVel"), SuppressUnmanagedCodeSecurity] - public static extern void BodySetAngularVel(IntPtr body, dReal x, dReal y, dReal z); + internal static extern void BodySetAngularVel(IntPtr body, dReal x, dReal y, dReal z); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetAutoDisableAngularThreshold"), SuppressUnmanagedCodeSecurity] - public static extern void BodySetAutoDisableAngularThreshold(IntPtr body, dReal angular_threshold); + internal static extern void BodySetAutoDisableAngularThreshold(IntPtr body, dReal angular_threshold); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetAutoDisableDefaults"), SuppressUnmanagedCodeSecurity] - public static extern void BodySetAutoDisableDefaults(IntPtr body); + internal static extern void BodySetAutoDisableDefaults(IntPtr body); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetAutoDisableFlag"), SuppressUnmanagedCodeSecurity] - public static extern void BodySetAutoDisableFlag(IntPtr body, bool do_auto_disable); + internal static extern void BodySetAutoDisableFlag(IntPtr body, bool do_auto_disable); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetAutoDisableLinearThreshold"), SuppressUnmanagedCodeSecurity] - public static extern void BodySetAutoDisableLinearThreshold(IntPtr body, dReal linear_threshold); + internal static extern void BodySetAutoDisableLinearThreshold(IntPtr body, dReal linear_threshold); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetAutoDisableSteps"), SuppressUnmanagedCodeSecurity] - public static extern void BodySetAutoDisableSteps(IntPtr body, int steps); + internal static extern void BodySetAutoDisableSteps(IntPtr body, int steps); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetAutoDisableTime"), SuppressUnmanagedCodeSecurity] - public static extern void BodySetAutoDisableTime(IntPtr body, dReal time); + internal static extern void BodySetAutoDisableTime(IntPtr body, dReal time); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetData"), SuppressUnmanagedCodeSecurity] - public static extern void BodySetData(IntPtr body, IntPtr data); + internal static extern void BodySetData(IntPtr body, IntPtr data); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetFiniteRotationMode"), SuppressUnmanagedCodeSecurity] - public static extern void BodySetFiniteRotationMode(IntPtr body, int mode); + internal static extern void BodySetFiniteRotationMode(IntPtr body, int mode); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetFiniteRotationAxis"), SuppressUnmanagedCodeSecurity] - public static extern void BodySetFiniteRotationAxis(IntPtr body, dReal x, dReal y, dReal z); + internal static extern void BodySetFiniteRotationAxis(IntPtr body, dReal x, dReal y, dReal z); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetLinearDamping"), SuppressUnmanagedCodeSecurity] - public static extern void BodySetLinearDamping(IntPtr body, dReal scale); + internal static extern void BodySetLinearDamping(IntPtr body, dReal scale); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetAngularDamping"), SuppressUnmanagedCodeSecurity] - public static extern void BodySetAngularDamping(IntPtr body, dReal scale); + internal static extern void BodySetAngularDamping(IntPtr body, dReal scale); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetLinearDamping"), SuppressUnmanagedCodeSecurity] - public static extern dReal BodyGetLinearDamping(IntPtr body); + internal static extern dReal BodyGetLinearDamping(IntPtr body); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetAngularDamping"), SuppressUnmanagedCodeSecurity] - public static extern dReal BodyGetAngularDamping(IntPtr body); + internal static extern dReal BodyGetAngularDamping(IntPtr body); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetAngularDamping"), SuppressUnmanagedCodeSecurity] - public static extern void BodySetDamping(IntPtr body, dReal linear_scale, dReal angular_scale); + internal static extern void BodySetDamping(IntPtr body, dReal linear_scale, dReal angular_scale); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetAngularDampingThreshold"), SuppressUnmanagedCodeSecurity] - public static extern void BodySetAngularDampingThreshold(IntPtr body, dReal threshold); + internal static extern void BodySetAngularDampingThreshold(IntPtr body, dReal threshold); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetLinearDampingThreshold"), SuppressUnmanagedCodeSecurity] - public static extern void BodySetLinearDampingThreshold(IntPtr body, dReal threshold); + internal static extern void BodySetLinearDampingThreshold(IntPtr body, dReal threshold); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetLinearDampingThreshold"), SuppressUnmanagedCodeSecurity] - public static extern dReal BodyGetLinearDampingThreshold(IntPtr body); + internal static extern dReal BodyGetLinearDampingThreshold(IntPtr body); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetAngularDampingThreshold"), SuppressUnmanagedCodeSecurity] - public static extern dReal BodyGetAngularDampingThreshold(IntPtr body); + internal static extern dReal BodyGetAngularDampingThreshold(IntPtr body); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetForce"), SuppressUnmanagedCodeSecurity] - public static extern void BodySetForce(IntPtr body, dReal x, dReal y, dReal z); + internal static extern void BodySetForce(IntPtr body, dReal x, dReal y, dReal z); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetGravityMode"), SuppressUnmanagedCodeSecurity] - public static extern void BodySetGravityMode(IntPtr body, bool mode); + internal static extern void BodySetGravityMode(IntPtr body, bool mode); /// /// Sets the Gyroscopic term status on the body specified. @@ -632,112 +632,112 @@ namespace OpenSim.Region.PhysicsModule.ODE /// Pointer to body /// NonZero enabled, Zero disabled [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetGyroscopicMode"), SuppressUnmanagedCodeSecurity] - public static extern void dBodySetGyroscopicMode(IntPtr body, int enabled); + internal static extern void dBodySetGyroscopicMode(IntPtr body, int enabled); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetLinearVel"), SuppressUnmanagedCodeSecurity] - public static extern void BodySetLinearVel(IntPtr body, dReal x, dReal y, dReal z); + internal static extern void BodySetLinearVel(IntPtr body, dReal x, dReal y, dReal z); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetMass"), SuppressUnmanagedCodeSecurity] - public static extern void BodySetMass(IntPtr body, ref Mass mass); + internal static extern void BodySetMass(IntPtr body, ref Mass mass); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetPosition"), SuppressUnmanagedCodeSecurity] - public static extern void BodySetPosition(IntPtr body, dReal x, dReal y, dReal z); + internal static extern void BodySetPosition(IntPtr body, dReal x, dReal y, dReal z); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetQuaternion"), SuppressUnmanagedCodeSecurity] - public static extern void BodySetQuaternion(IntPtr body, ref Quaternion q); + internal static extern void BodySetQuaternion(IntPtr body, ref Quaternion q); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetQuaternion"), SuppressUnmanagedCodeSecurity] - public static extern void BodySetQuaternion(IntPtr body, ref dReal w); + internal static extern void BodySetQuaternion(IntPtr body, ref dReal w); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetRotation"), SuppressUnmanagedCodeSecurity] - public static extern void BodySetRotation(IntPtr body, ref Matrix3 R); + internal static extern void BodySetRotation(IntPtr body, ref Matrix3 R); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetRotation"), SuppressUnmanagedCodeSecurity] - public static extern void BodySetRotation(IntPtr body, ref dReal M00); + internal static extern void BodySetRotation(IntPtr body, ref dReal M00); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetTorque"), SuppressUnmanagedCodeSecurity] - public static extern void BodySetTorque(IntPtr body, dReal x, dReal y, dReal z); + internal static extern void BodySetTorque(IntPtr body, dReal x, dReal y, dReal z); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyVectorFromWorld"), SuppressUnmanagedCodeSecurity] - public static extern void BodyVectorFromWorld(IntPtr body, dReal px, dReal py, dReal pz, out Vector3 result); + internal static extern void BodyVectorFromWorld(IntPtr body, dReal px, dReal py, dReal pz, out Vector3 result); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyVectorToWorld"), SuppressUnmanagedCodeSecurity] - public static extern void BodyVectorToWorld(IntPtr body, dReal px, dReal py, dReal pz, out Vector3 result); + internal static extern void BodyVectorToWorld(IntPtr body, dReal px, dReal py, dReal pz, out Vector3 result); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBoxBox"), SuppressUnmanagedCodeSecurity] - public static extern void BoxBox(ref Vector3 p1, ref Matrix3 R1, + internal static extern void BoxBox(ref Vector3 p1, ref Matrix3 R1, ref Vector3 side1, ref Vector3 p2, ref Matrix3 R2, ref Vector3 side2, ref Vector3 normal, out dReal depth, out int return_code, int maxc, out ContactGeom contact, int skip); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBoxTouchesBox"), SuppressUnmanagedCodeSecurity] - public static extern void BoxTouchesBox(ref Vector3 _p1, ref Matrix3 R1, + internal static extern void BoxTouchesBox(ref Vector3 _p1, ref Matrix3 R1, ref Vector3 side1, ref Vector3 _p2, ref Matrix3 R2, ref Vector3 side2); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCleanupODEAllDataForThread"), SuppressUnmanagedCodeSecurity] - public static extern void CleanupODEAllDataForThread(); + internal static extern void CleanupODEAllDataForThread(); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dClosestLineSegmentPoints"), SuppressUnmanagedCodeSecurity] - public static extern void ClosestLineSegmentPoints(ref Vector3 a1, ref Vector3 a2, + internal static extern void ClosestLineSegmentPoints(ref Vector3 a1, ref Vector3 a2, ref Vector3 b1, ref Vector3 b2, ref Vector3 cp1, ref Vector3 cp2); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCloseODE"), SuppressUnmanagedCodeSecurity] - public static extern void CloseODE(); + internal static extern void CloseODE(); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCollide"), SuppressUnmanagedCodeSecurity] - public static extern int Collide(IntPtr o1, IntPtr o2, int flags, [In, Out] ContactGeom[] contact, int skip); + internal static extern int Collide(IntPtr o1, IntPtr o2, int flags, [In, Out] ContactGeom[] contact, int skip); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCollide"), SuppressUnmanagedCodeSecurity] - public static extern int CollidePtr(IntPtr o1, IntPtr o2, int flags, IntPtr contactgeomarray, int skip); + internal static extern int CollidePtr(IntPtr o1, IntPtr o2, int flags, IntPtr contactgeomarray, int skip); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dConnectingJoint"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr ConnectingJoint(IntPtr j1, IntPtr j2); + internal static extern IntPtr ConnectingJoint(IntPtr j1, IntPtr j2); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateBox"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr CreateiBox(IntPtr space, dReal lx, dReal ly, dReal lz); - public static IntPtr CreateBox(IntPtr space, dReal lx, dReal ly, dReal lz) + internal static extern IntPtr CreateiBox(IntPtr space, dReal lx, dReal ly, dReal lz); + internal static IntPtr CreateBox(IntPtr space, dReal lx, dReal ly, dReal lz) { NTotalGeoms++; return CreateiBox(space, lx, ly, lz); } [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateCapsule"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr CreateiCapsule(IntPtr space, dReal radius, dReal length); - public static IntPtr CreateCapsule(IntPtr space, dReal radius, dReal length) + internal static extern IntPtr CreateiCapsule(IntPtr space, dReal radius, dReal length); + internal static IntPtr CreateCapsule(IntPtr space, dReal radius, dReal length) { NTotalGeoms++; return CreateiCapsule(space, radius, length); } [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateConvex"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr CreateiConvex(IntPtr space, dReal[] planes, int planeCount, dReal[] points, int pointCount, int[] polygons); - public static IntPtr CreateConvex(IntPtr space, dReal[] planes, int planeCount, dReal[] points, int pointCount, int[] polygons) + internal static extern IntPtr CreateiConvex(IntPtr space, dReal[] planes, int planeCount, dReal[] points, int pointCount, int[] polygons); + internal static IntPtr CreateConvex(IntPtr space, dReal[] planes, int planeCount, dReal[] points, int pointCount, int[] polygons) { NTotalGeoms++; return CreateiConvex(space, planes, planeCount, points, pointCount, polygons); } [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateCylinder"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr CreateiCylinder(IntPtr space, dReal radius, dReal length); - public static IntPtr CreateCylinder(IntPtr space, dReal radius, dReal length) + internal static extern IntPtr CreateiCylinder(IntPtr space, dReal radius, dReal length); + internal static IntPtr CreateCylinder(IntPtr space, dReal radius, dReal length) { NTotalGeoms++; return CreateiCylinder(space, radius, length); } [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateHeightfield"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr CreateiHeightfield(IntPtr space, IntPtr data, int bPlaceable); - public static IntPtr CreateHeightfield(IntPtr space, IntPtr data, int bPlaceable) + internal static extern IntPtr CreateiHeightfield(IntPtr space, IntPtr data, int bPlaceable); + internal static IntPtr CreateHeightfield(IntPtr space, IntPtr data, int bPlaceable) { NTotalGeoms++; return CreateiHeightfield(space, data, bPlaceable); } [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateOSTerrain"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr CreateiOSTerrain(IntPtr space, IntPtr data, int bPlaceable); - public static IntPtr CreateOSTerrain(IntPtr space, IntPtr data, int bPlaceable) + internal static extern IntPtr CreateiOSTerrain(IntPtr space, IntPtr data, int bPlaceable); + internal static IntPtr CreateOSTerrain(IntPtr space, IntPtr data, int bPlaceable) { NTotalGeoms++; return CreateiOSTerrain(space, data, bPlaceable); @@ -748,127 +748,127 @@ namespace OpenSim.Region.PhysicsModule.ODE [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateGeom"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr CreateiGeom(int classnum); - public static IntPtr CreateGeom(int classnum) + internal static extern IntPtr CreateiGeom(int classnum); + internal static IntPtr CreateGeom(int classnum) { NTotalGeoms++; return CreateiGeom(classnum); } [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateGeomClass"), SuppressUnmanagedCodeSecurity] - public static extern int CreateGeomClass(ref GeomClass classptr); + internal static extern int CreateGeomClass(ref GeomClass classptr); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateGeomTransform"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr CreateGeomTransform(IntPtr space); + internal static extern IntPtr CreateGeomTransform(IntPtr space); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreatePlane"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr CreateiPlane(IntPtr space, dReal a, dReal b, dReal c, dReal d); - public static IntPtr CreatePlane(IntPtr space, dReal a, dReal b, dReal c, dReal d) + internal static extern IntPtr CreateiPlane(IntPtr space, dReal a, dReal b, dReal c, dReal d); + internal static IntPtr CreatePlane(IntPtr space, dReal a, dReal b, dReal c, dReal d) { NTotalGeoms++; return CreateiPlane(space, a, b, c, d); } [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateRay"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr CreateiRay(IntPtr space, dReal length); - public static IntPtr CreateRay(IntPtr space, dReal length) + internal static extern IntPtr CreateiRay(IntPtr space, dReal length); + internal static IntPtr CreateRay(IntPtr space, dReal length) { NTotalGeoms++; return CreateiRay(space, length); } [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateSphere"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr CreateiSphere(IntPtr space, dReal radius); - public static IntPtr CreateSphere(IntPtr space, dReal radius) + internal static extern IntPtr CreateiSphere(IntPtr space, dReal radius); + internal static IntPtr CreateSphere(IntPtr space, dReal radius) { NTotalGeoms++; return CreateiSphere(space, radius); } [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateTriMesh"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr CreateiTriMesh(IntPtr space, IntPtr data, + internal static extern IntPtr CreateiTriMesh(IntPtr space, IntPtr data, TriCallback callback, TriArrayCallback arrayCallback, TriRayCallback rayCallback); - public static IntPtr CreateTriMesh(IntPtr space, IntPtr data, + internal static IntPtr CreateTriMesh(IntPtr space, IntPtr data, TriCallback callback, TriArrayCallback arrayCallback, TriRayCallback rayCallback) { NTotalGeoms++; return CreateiTriMesh(space, data, callback, arrayCallback, rayCallback); } [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dDot"), SuppressUnmanagedCodeSecurity] - public static extern dReal Dot(ref dReal X0, ref dReal X1, int n); + internal static extern dReal Dot(ref dReal X0, ref dReal X1, int n); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dDQfromW"), SuppressUnmanagedCodeSecurity] - public static extern void DQfromW(dReal[] dq, ref Vector3 w, ref Quaternion q); + internal static extern void DQfromW(dReal[] dq, ref Vector3 w, ref Quaternion q); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dFactorCholesky"), SuppressUnmanagedCodeSecurity] - public static extern int FactorCholesky(ref dReal A00, int n); + internal static extern int FactorCholesky(ref dReal A00, int n); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dFactorLDLT"), SuppressUnmanagedCodeSecurity] - public static extern void FactorLDLT(ref dReal A, out dReal d, int n, int nskip); + internal static extern void FactorLDLT(ref dReal A, out dReal d, int n, int nskip); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomBoxGetLengths"), SuppressUnmanagedCodeSecurity] - public static extern void GeomBoxGetLengths(IntPtr geom, out Vector3 len); + internal static extern void GeomBoxGetLengths(IntPtr geom, out Vector3 len); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomBoxGetLengths"), SuppressUnmanagedCodeSecurity] - public static extern void GeomBoxGetLengths(IntPtr geom, out dReal x); + internal static extern void GeomBoxGetLengths(IntPtr geom, out dReal x); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomBoxPointDepth"), SuppressUnmanagedCodeSecurity] - public static extern dReal GeomBoxPointDepth(IntPtr geom, dReal x, dReal y, dReal z); + internal static extern dReal GeomBoxPointDepth(IntPtr geom, dReal x, dReal y, dReal z); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomBoxSetLengths"), SuppressUnmanagedCodeSecurity] - public static extern void GeomBoxSetLengths(IntPtr geom, dReal x, dReal y, dReal z); + internal static extern void GeomBoxSetLengths(IntPtr geom, dReal x, dReal y, dReal z); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomCapsuleGetParams"), SuppressUnmanagedCodeSecurity] - public static extern void GeomCapsuleGetParams(IntPtr geom, out dReal radius, out dReal length); + internal static extern void GeomCapsuleGetParams(IntPtr geom, out dReal radius, out dReal length); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomCapsulePointDepth"), SuppressUnmanagedCodeSecurity] - public static extern dReal GeomCapsulePointDepth(IntPtr geom, dReal x, dReal y, dReal z); + internal static extern dReal GeomCapsulePointDepth(IntPtr geom, dReal x, dReal y, dReal z); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomCapsuleSetParams"), SuppressUnmanagedCodeSecurity] - public static extern void GeomCapsuleSetParams(IntPtr geom, dReal radius, dReal length); + internal static extern void GeomCapsuleSetParams(IntPtr geom, dReal radius, dReal length); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomClearOffset"), SuppressUnmanagedCodeSecurity] - public static extern void GeomClearOffset(IntPtr geom); + internal static extern void GeomClearOffset(IntPtr geom); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomCopyOffsetPosition"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr GeomCopyOffsetPosition(IntPtr geom, ref Vector3 pos); + internal static extern IntPtr GeomCopyOffsetPosition(IntPtr geom, ref Vector3 pos); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomCopyOffsetPosition"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr GeomCopyOffsetPosition(IntPtr geom, ref dReal X); + internal static extern IntPtr GeomCopyOffsetPosition(IntPtr geom, ref dReal X); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetOffsetQuaternion"), SuppressUnmanagedCodeSecurity] - public static extern void GeomCopyOffsetQuaternion(IntPtr geom, ref Quaternion Q); + internal static extern void GeomCopyOffsetQuaternion(IntPtr geom, ref Quaternion Q); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetOffsetQuaternion"), SuppressUnmanagedCodeSecurity] - public static extern void GeomCopyOffsetQuaternion(IntPtr geom, ref dReal X); + internal static extern void GeomCopyOffsetQuaternion(IntPtr geom, ref dReal X); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomCopyOffsetRotation"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr GeomCopyOffsetRotation(IntPtr geom, ref Matrix3 R); + internal static extern IntPtr GeomCopyOffsetRotation(IntPtr geom, ref Matrix3 R); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomCopyOffsetRotation"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr GeomCopyOffsetRotation(IntPtr geom, ref dReal M00); + internal static extern IntPtr GeomCopyOffsetRotation(IntPtr geom, ref dReal M00); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomCopyPosition"), SuppressUnmanagedCodeSecurity] - public static extern void GeomCopyPosition(IntPtr geom, out Vector3 pos); + internal static extern void GeomCopyPosition(IntPtr geom, out Vector3 pos); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomCopyPosition"), SuppressUnmanagedCodeSecurity] - public static extern void GeomCopyPosition(IntPtr geom, out dReal X); + internal static extern void GeomCopyPosition(IntPtr geom, out dReal X); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomCopyRotation"), SuppressUnmanagedCodeSecurity] - public static extern void GeomCopyRotation(IntPtr geom, out Matrix3 R); + internal static extern void GeomCopyRotation(IntPtr geom, out Matrix3 R); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomCopyRotation"), SuppressUnmanagedCodeSecurity] - public static extern void GeomCopyRotation(IntPtr geom, out dReal M00); + internal static extern void GeomCopyRotation(IntPtr geom, out dReal M00); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomCylinderGetParams"), SuppressUnmanagedCodeSecurity] - public static extern void GeomCylinderGetParams(IntPtr geom, out dReal radius, out dReal length); + internal static extern void GeomCylinderGetParams(IntPtr geom, out dReal radius, out dReal length); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomCylinderSetParams"), SuppressUnmanagedCodeSecurity] - public static extern void GeomCylinderSetParams(IntPtr geom, dReal radius, dReal length); + internal static extern void GeomCylinderSetParams(IntPtr geom, dReal radius, dReal length); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomDestroy"), SuppressUnmanagedCodeSecurity] - public static extern void GeomiDestroy(IntPtr geom); - public static void GeomDestroy(IntPtr geom) + internal static extern void GeomiDestroy(IntPtr geom); + internal static void GeomDestroy(IntPtr geom) { NTotalGeoms--; GeomiDestroy(geom); @@ -876,64 +876,64 @@ namespace OpenSim.Region.PhysicsModule.ODE [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomDisable"), SuppressUnmanagedCodeSecurity] - public static extern void GeomDisable(IntPtr geom); + internal static extern void GeomDisable(IntPtr geom); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomEnable"), SuppressUnmanagedCodeSecurity] - public static extern void GeomEnable(IntPtr geom); + internal static extern void GeomEnable(IntPtr geom); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetAABB"), SuppressUnmanagedCodeSecurity] - public static extern void GeomGetAABB(IntPtr geom, out AABB aabb); + internal static extern void GeomGetAABB(IntPtr geom, out AABB aabb); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetAABB"), SuppressUnmanagedCodeSecurity] - public static extern void GeomGetAABB(IntPtr geom, out dReal minX); + internal static extern void GeomGetAABB(IntPtr geom, out dReal minX); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetBody"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr GeomGetBody(IntPtr geom); + internal static extern IntPtr GeomGetBody(IntPtr geom); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetCategoryBits"), SuppressUnmanagedCodeSecurity] - public static extern uint GeomGetCategoryBits(IntPtr geom); + internal static extern uint GeomGetCategoryBits(IntPtr geom); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetClassData"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr GeomGetClassData(IntPtr geom); + internal static extern IntPtr GeomGetClassData(IntPtr geom); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetCollideBits"), SuppressUnmanagedCodeSecurity] - public static extern uint GeomGetCollideBits(IntPtr geom); + internal static extern uint GeomGetCollideBits(IntPtr geom); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetClass"), SuppressUnmanagedCodeSecurity] - public static extern GeomClassID GeomGetClass(IntPtr geom); + internal static extern GeomClassID GeomGetClass(IntPtr geom); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetData"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr GeomGetData(IntPtr geom); + internal static extern IntPtr GeomGetData(IntPtr geom); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetOffsetPosition"), SuppressUnmanagedCodeSecurity] - public extern unsafe static Vector3* GeomGetOffsetPositionUnsafe(IntPtr geom); - public static Vector3 GeomGetOffsetPosition(IntPtr geom) + internal extern unsafe static Vector3* GeomGetOffsetPositionUnsafe(IntPtr geom); + internal static Vector3 GeomGetOffsetPosition(IntPtr geom) { unsafe { return *(GeomGetOffsetPositionUnsafe(geom)); } } [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetOffsetRotation"), SuppressUnmanagedCodeSecurity] - public extern unsafe static Matrix3* GeomGetOffsetRotationUnsafe(IntPtr geom); - public static Matrix3 GeomGetOffsetRotation(IntPtr geom) + internal extern unsafe static Matrix3* GeomGetOffsetRotationUnsafe(IntPtr geom); + internal static Matrix3 GeomGetOffsetRotation(IntPtr geom) { unsafe { return *(GeomGetOffsetRotationUnsafe(geom)); } } [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetPosition"), SuppressUnmanagedCodeSecurity] - public extern unsafe static Vector3* GeomGetPositionUnsafe(IntPtr geom); - public static Vector3 GeomGetPosition(IntPtr geom) + internal extern unsafe static Vector3* GeomGetPositionUnsafe(IntPtr geom); + internal static Vector3 GeomGetPosition(IntPtr geom) { unsafe { return *(GeomGetPositionUnsafe(geom)); } } - public static OMV.Vector3 GeomGetPositionOMV(IntPtr geom) + internal static OMV.Vector3 GeomGetPositionOMV(IntPtr geom) { Vector3 vtmp = GeomGetPosition(geom); return new OMV.Vector3(vtmp.X, vtmp.Y, vtmp.Z); } [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetQuaternion"), SuppressUnmanagedCodeSecurity] - public static extern void GeomCopyQuaternion(IntPtr geom, out Quaternion q); - public static OMV.Quaternion GeomGetQuaternionOMV(IntPtr geom) + internal static extern void GeomCopyQuaternion(IntPtr geom, out Quaternion q); + internal static OMV.Quaternion GeomGetQuaternionOMV(IntPtr geom) { Quaternion qtmp; GeomCopyQuaternion(geom, out qtmp); @@ -941,393 +941,393 @@ namespace OpenSim.Region.PhysicsModule.ODE } [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetQuaternion"), SuppressUnmanagedCodeSecurity] - public static extern void GeomCopyQuaternion(IntPtr geom, out dReal X); + internal static extern void GeomCopyQuaternion(IntPtr geom, out dReal X); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetRotation"), SuppressUnmanagedCodeSecurity] - public extern unsafe static Matrix3* GeomGetRotationUnsafe(IntPtr geom); - public static Matrix3 GeomGetRotation(IntPtr geom) + internal extern unsafe static Matrix3* GeomGetRotationUnsafe(IntPtr geom); + internal static Matrix3 GeomGetRotation(IntPtr geom) { unsafe { return *(GeomGetRotationUnsafe(geom)); } } [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetSpace"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr GeomGetSpace(IntPtr geom); + internal static extern IntPtr GeomGetSpace(IntPtr geom); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomHeightfieldDataBuildByte"), SuppressUnmanagedCodeSecurity] - public static extern void GeomHeightfieldDataBuildByte(IntPtr d, byte[] pHeightData, int bCopyHeightData, + internal static extern void GeomHeightfieldDataBuildByte(IntPtr d, byte[] pHeightData, int bCopyHeightData, dReal width, dReal depth, int widthSamples, int depthSamples, dReal scale, dReal offset, dReal thickness, int bWrap); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomHeightfieldDataBuildByte"), SuppressUnmanagedCodeSecurity] - public static extern void GeomHeightfieldDataBuildByte(IntPtr d, IntPtr pHeightData, int bCopyHeightData, + internal static extern void GeomHeightfieldDataBuildByte(IntPtr d, IntPtr pHeightData, int bCopyHeightData, dReal width, dReal depth, int widthSamples, int depthSamples, dReal scale, dReal offset, dReal thickness, int bWrap); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomHeightfieldDataBuildCallback"), SuppressUnmanagedCodeSecurity] - public static extern void GeomHeightfieldDataBuildCallback(IntPtr d, IntPtr pUserData, HeightfieldGetHeight pCallback, + internal static extern void GeomHeightfieldDataBuildCallback(IntPtr d, IntPtr pUserData, HeightfieldGetHeight pCallback, dReal width, dReal depth, int widthSamples, int depthSamples, dReal scale, dReal offset, dReal thickness, int bWrap); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomHeightfieldDataBuildShort"), SuppressUnmanagedCodeSecurity] - public static extern void GeomHeightfieldDataBuildShort(IntPtr d, ushort[] pHeightData, int bCopyHeightData, + internal static extern void GeomHeightfieldDataBuildShort(IntPtr d, ushort[] pHeightData, int bCopyHeightData, dReal width, dReal depth, int widthSamples, int depthSamples, dReal scale, dReal offset, dReal thickness, int bWrap); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomHeightfieldDataBuildShort"), SuppressUnmanagedCodeSecurity] - public static extern void GeomHeightfieldDataBuildShort(IntPtr d, short[] pHeightData, int bCopyHeightData, + internal static extern void GeomHeightfieldDataBuildShort(IntPtr d, short[] pHeightData, int bCopyHeightData, dReal width, dReal depth, int widthSamples, int depthSamples, dReal scale, dReal offset, dReal thickness, int bWrap); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomHeightfieldDataBuildShort"), SuppressUnmanagedCodeSecurity] - public static extern void GeomHeightfieldDataBuildShort(IntPtr d, IntPtr pHeightData, int bCopyHeightData, + internal static extern void GeomHeightfieldDataBuildShort(IntPtr d, IntPtr pHeightData, int bCopyHeightData, dReal width, dReal depth, int widthSamples, int depthSamples, dReal scale, dReal offset, dReal thickness, int bWrap); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomHeightfieldDataBuildSingle"), SuppressUnmanagedCodeSecurity] - public static extern void GeomHeightfieldDataBuildSingle(IntPtr d, float[] pHeightData, int bCopyHeightData, + internal static extern void GeomHeightfieldDataBuildSingle(IntPtr d, float[] pHeightData, int bCopyHeightData, dReal width, dReal depth, int widthSamples, int depthSamples, dReal scale, dReal offset, dReal thickness, int bWrap); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomHeightfieldDataBuildSingle"), SuppressUnmanagedCodeSecurity] - public static extern void GeomHeightfieldDataBuildSingle(IntPtr d, IntPtr pHeightData, int bCopyHeightData, + internal static extern void GeomHeightfieldDataBuildSingle(IntPtr d, IntPtr pHeightData, int bCopyHeightData, dReal width, dReal depth, int widthSamples, int depthSamples, dReal scale, dReal offset, dReal thickness, int bWrap); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomHeightfieldDataBuildDouble"), SuppressUnmanagedCodeSecurity] - public static extern void GeomHeightfieldDataBuildDouble(IntPtr d, double[] pHeightData, int bCopyHeightData, + internal static extern void GeomHeightfieldDataBuildDouble(IntPtr d, double[] pHeightData, int bCopyHeightData, dReal width, dReal depth, int widthSamples, int depthSamples, dReal scale, dReal offset, dReal thickness, int bWrap); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomHeightfieldDataBuildDouble"), SuppressUnmanagedCodeSecurity] - public static extern void GeomHeightfieldDataBuildDouble(IntPtr d, IntPtr pHeightData, int bCopyHeightData, + internal static extern void GeomHeightfieldDataBuildDouble(IntPtr d, IntPtr pHeightData, int bCopyHeightData, dReal width, dReal depth, int widthSamples, int depthSamples, dReal scale, dReal offset, dReal thickness, int bWrap); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomHeightfieldDataCreate"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr GeomHeightfieldDataCreate(); + internal static extern IntPtr GeomHeightfieldDataCreate(); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomHeightfieldDataDestroy"), SuppressUnmanagedCodeSecurity] - public static extern void GeomHeightfieldDataDestroy(IntPtr d); + internal static extern void GeomHeightfieldDataDestroy(IntPtr d); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomHeightfieldDataSetBounds"), SuppressUnmanagedCodeSecurity] - public static extern void GeomHeightfieldDataSetBounds(IntPtr d, dReal minHeight, dReal maxHeight); + internal static extern void GeomHeightfieldDataSetBounds(IntPtr d, dReal minHeight, dReal maxHeight); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomHeightfieldGetHeightfieldData"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr GeomHeightfieldGetHeightfieldData(IntPtr g); + internal static extern IntPtr GeomHeightfieldGetHeightfieldData(IntPtr g); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomHeightfieldSetHeightfieldData"), SuppressUnmanagedCodeSecurity] - public static extern void GeomHeightfieldSetHeightfieldData(IntPtr g, IntPtr d); + internal static extern void GeomHeightfieldSetHeightfieldData(IntPtr g, IntPtr d); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomUbitTerrainDataBuild"), SuppressUnmanagedCodeSecurity] - public static extern void GeomOSTerrainDataBuild(IntPtr d, float[] pHeightData, int bCopyHeightData, + internal static extern void GeomOSTerrainDataBuild(IntPtr d, float[] pHeightData, int bCopyHeightData, dReal sampleSize, int widthSamples, int depthSamples, dReal offset, dReal thickness, int bWrap); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomOSTerrainDataBuild"), SuppressUnmanagedCodeSecurity] - public static extern void GeomOSTerrainDataBuild(IntPtr d, IntPtr pHeightData, int bCopyHeightData, + internal static extern void GeomOSTerrainDataBuild(IntPtr d, IntPtr pHeightData, int bCopyHeightData, dReal sampleSize, int widthSamples, int depthSamples, dReal thickness, int bWrap); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomOSTerrainDataCreate"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr GeomOSTerrainDataCreate(); + internal static extern IntPtr GeomOSTerrainDataCreate(); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomOSTerrainDataDestroy"), SuppressUnmanagedCodeSecurity] - public static extern void GeomOSTerrainDataDestroy(IntPtr d); + internal static extern void GeomOSTerrainDataDestroy(IntPtr d); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomOSTerrainDataSetBounds"), SuppressUnmanagedCodeSecurity] - public static extern void GeomOSTerrainDataSetBounds(IntPtr d, dReal minHeight, dReal maxHeight); + internal static extern void GeomOSTerrainDataSetBounds(IntPtr d, dReal minHeight, dReal maxHeight); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomOSTerrainGetHeightfieldData"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr GeomOSTerrainGetHeightfieldData(IntPtr g); + internal static extern IntPtr GeomOSTerrainGetHeightfieldData(IntPtr g); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomOSTerrainSetHeightfieldData"), SuppressUnmanagedCodeSecurity] - public static extern void GeomOSTerrainSetHeightfieldData(IntPtr g, IntPtr d); + internal static extern void GeomOSTerrainSetHeightfieldData(IntPtr g, IntPtr d); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomIsEnabled"), SuppressUnmanagedCodeSecurity] - public static extern bool GeomIsEnabled(IntPtr geom); + internal static extern bool GeomIsEnabled(IntPtr geom); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomIsOffset"), SuppressUnmanagedCodeSecurity] - public static extern bool GeomIsOffset(IntPtr geom); + internal static extern bool GeomIsOffset(IntPtr geom); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomIsSpace"), SuppressUnmanagedCodeSecurity] - public static extern bool GeomIsSpace(IntPtr geom); + internal static extern bool GeomIsSpace(IntPtr geom); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomPlaneGetParams"), SuppressUnmanagedCodeSecurity] - public static extern void GeomPlaneGetParams(IntPtr geom, ref Vector4 result); + internal static extern void GeomPlaneGetParams(IntPtr geom, ref Vector4 result); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomPlaneGetParams"), SuppressUnmanagedCodeSecurity] - public static extern void GeomPlaneGetParams(IntPtr geom, ref dReal A); + internal static extern void GeomPlaneGetParams(IntPtr geom, ref dReal A); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomPlanePointDepth"), SuppressUnmanagedCodeSecurity] - public static extern dReal GeomPlanePointDepth(IntPtr geom, dReal x, dReal y, dReal z); + internal static extern dReal GeomPlanePointDepth(IntPtr geom, dReal x, dReal y, dReal z); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomPlaneSetParams"), SuppressUnmanagedCodeSecurity] - public static extern void GeomPlaneSetParams(IntPtr plane, dReal a, dReal b, dReal c, dReal d); + internal static extern void GeomPlaneSetParams(IntPtr plane, dReal a, dReal b, dReal c, dReal d); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomRayGet"), SuppressUnmanagedCodeSecurity] - public static extern void GeomRayGet(IntPtr ray, ref Vector3 start, ref Vector3 dir); + internal static extern void GeomRayGet(IntPtr ray, ref Vector3 start, ref Vector3 dir); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomRayGet"), SuppressUnmanagedCodeSecurity] - public static extern void GeomRayGet(IntPtr ray, ref dReal startX, ref dReal dirX); + internal static extern void GeomRayGet(IntPtr ray, ref dReal startX, ref dReal dirX); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomRayGetClosestHit"), SuppressUnmanagedCodeSecurity] - public static extern int GeomRayGetClosestHit(IntPtr ray); + internal static extern int GeomRayGetClosestHit(IntPtr ray); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomRayGetLength"), SuppressUnmanagedCodeSecurity] - public static extern dReal GeomRayGetLength(IntPtr ray); + internal static extern dReal GeomRayGetLength(IntPtr ray); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomRayGetParams"), SuppressUnmanagedCodeSecurity] - public static extern dReal GeomRayGetParams(IntPtr g, out int firstContact, out int backfaceCull); + internal static extern dReal GeomRayGetParams(IntPtr g, out int firstContact, out int backfaceCull); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomRaySet"), SuppressUnmanagedCodeSecurity] - public static extern void GeomRaySet(IntPtr ray, dReal px, dReal py, dReal pz, dReal dx, dReal dy, dReal dz); + internal static extern void GeomRaySet(IntPtr ray, dReal px, dReal py, dReal pz, dReal dx, dReal dy, dReal dz); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomRaySetClosestHit"), SuppressUnmanagedCodeSecurity] - public static extern void GeomRaySetClosestHit(IntPtr ray, int closestHit); + internal static extern void GeomRaySetClosestHit(IntPtr ray, int closestHit); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomRaySetLength"), SuppressUnmanagedCodeSecurity] - public static extern void GeomRaySetLength(IntPtr ray, dReal length); + internal static extern void GeomRaySetLength(IntPtr ray, dReal length); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomRaySetParams"), SuppressUnmanagedCodeSecurity] - public static extern void GeomRaySetParams(IntPtr ray, int firstContact, int backfaceCull); + internal static extern void GeomRaySetParams(IntPtr ray, int firstContact, int backfaceCull); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetBody"), SuppressUnmanagedCodeSecurity] - public static extern void GeomSetBody(IntPtr geom, IntPtr body); + internal static extern void GeomSetBody(IntPtr geom, IntPtr body); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetCategoryBits"), SuppressUnmanagedCodeSecurity] - public static extern void GeomSetCategoryBits(IntPtr geom, uint bits); + internal static extern void GeomSetCategoryBits(IntPtr geom, uint bits); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetCollideBits"), SuppressUnmanagedCodeSecurity] - public static extern void GeomSetCollideBits(IntPtr geom, uint bits); + internal static extern void GeomSetCollideBits(IntPtr geom, uint bits); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetConvex"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr GeomSetConvex(IntPtr geom, dReal[] planes, int planeCount, dReal[] points, int pointCount, int[] polygons); + internal static extern IntPtr GeomSetConvex(IntPtr geom, dReal[] planes, int planeCount, dReal[] points, int pointCount, int[] polygons); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetData"), SuppressUnmanagedCodeSecurity] - public static extern void GeomSetData(IntPtr geom, IntPtr data); + internal static extern void GeomSetData(IntPtr geom, IntPtr data); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetOffsetPosition"), SuppressUnmanagedCodeSecurity] - public static extern void GeomSetOffsetPosition(IntPtr geom, dReal x, dReal y, dReal z); + internal static extern void GeomSetOffsetPosition(IntPtr geom, dReal x, dReal y, dReal z); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetOffsetQuaternion"), SuppressUnmanagedCodeSecurity] - public static extern void GeomSetOffsetQuaternion(IntPtr geom, ref Quaternion Q); + internal static extern void GeomSetOffsetQuaternion(IntPtr geom, ref Quaternion Q); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetOffsetQuaternion"), SuppressUnmanagedCodeSecurity] - public static extern void GeomSetOffsetQuaternion(IntPtr geom, ref dReal X); + internal static extern void GeomSetOffsetQuaternion(IntPtr geom, ref dReal X); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetOffsetRotation"), SuppressUnmanagedCodeSecurity] - public static extern void GeomSetOffsetRotation(IntPtr geom, ref Matrix3 R); + internal static extern void GeomSetOffsetRotation(IntPtr geom, ref Matrix3 R); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetOffsetRotation"), SuppressUnmanagedCodeSecurity] - public static extern void GeomSetOffsetRotation(IntPtr geom, ref dReal M00); + internal static extern void GeomSetOffsetRotation(IntPtr geom, ref dReal M00); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetOffsetWorldPosition"), SuppressUnmanagedCodeSecurity] - public static extern void GeomSetOffsetWorldPosition(IntPtr geom, dReal x, dReal y, dReal z); + internal static extern void GeomSetOffsetWorldPosition(IntPtr geom, dReal x, dReal y, dReal z); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetOffsetWorldQuaternion"), SuppressUnmanagedCodeSecurity] - public static extern void GeomSetOffsetWorldQuaternion(IntPtr geom, ref Quaternion Q); + internal static extern void GeomSetOffsetWorldQuaternion(IntPtr geom, ref Quaternion Q); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetOffsetWorldQuaternion"), SuppressUnmanagedCodeSecurity] - public static extern void GeomSetOffsetWorldQuaternion(IntPtr geom, ref dReal X); + internal static extern void GeomSetOffsetWorldQuaternion(IntPtr geom, ref dReal X); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetOffsetWorldRotation"), SuppressUnmanagedCodeSecurity] - public static extern void GeomSetOffsetWorldRotation(IntPtr geom, ref Matrix3 R); + internal static extern void GeomSetOffsetWorldRotation(IntPtr geom, ref Matrix3 R); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetOffsetWorldRotation"), SuppressUnmanagedCodeSecurity] - public static extern void GeomSetOffsetWorldRotation(IntPtr geom, ref dReal M00); + internal static extern void GeomSetOffsetWorldRotation(IntPtr geom, ref dReal M00); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetPosition"), SuppressUnmanagedCodeSecurity] - public static extern void GeomSetPosition(IntPtr geom, dReal x, dReal y, dReal z); + internal static extern void GeomSetPosition(IntPtr geom, dReal x, dReal y, dReal z); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetQuaternion"), SuppressUnmanagedCodeSecurity] - public static extern void GeomSetQuaternion(IntPtr geom, ref Quaternion quat); + internal static extern void GeomSetQuaternion(IntPtr geom, ref Quaternion quat); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetQuaternion"), SuppressUnmanagedCodeSecurity] - public static extern void GeomSetQuaternion(IntPtr geom, ref dReal w); + internal static extern void GeomSetQuaternion(IntPtr geom, ref dReal w); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetRotation"), SuppressUnmanagedCodeSecurity] - public static extern void GeomSetRotation(IntPtr geom, ref Matrix3 R); + internal static extern void GeomSetRotation(IntPtr geom, ref Matrix3 R); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetRotation"), SuppressUnmanagedCodeSecurity] - public static extern void GeomSetRotation(IntPtr geom, ref dReal M00); + internal static extern void GeomSetRotation(IntPtr geom, ref dReal M00); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSphereGetRadius"), SuppressUnmanagedCodeSecurity] - public static extern dReal GeomSphereGetRadius(IntPtr geom); + internal static extern dReal GeomSphereGetRadius(IntPtr geom); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSpherePointDepth"), SuppressUnmanagedCodeSecurity] - public static extern dReal GeomSpherePointDepth(IntPtr geom, dReal x, dReal y, dReal z); + internal static extern dReal GeomSpherePointDepth(IntPtr geom, dReal x, dReal y, dReal z); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSphereSetRadius"), SuppressUnmanagedCodeSecurity] - public static extern void GeomSphereSetRadius(IntPtr geom, dReal radius); + internal static extern void GeomSphereSetRadius(IntPtr geom, dReal radius); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTransformGetCleanup"), SuppressUnmanagedCodeSecurity] - public static extern int GeomTransformGetCleanup(IntPtr geom); + internal static extern int GeomTransformGetCleanup(IntPtr geom); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTransformGetGeom"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr GeomTransformGetGeom(IntPtr geom); + internal static extern IntPtr GeomTransformGetGeom(IntPtr geom); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTransformGetInfo"), SuppressUnmanagedCodeSecurity] - public static extern int GeomTransformGetInfo(IntPtr geom); + internal static extern int GeomTransformGetInfo(IntPtr geom); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTransformSetCleanup"), SuppressUnmanagedCodeSecurity] - public static extern void GeomTransformSetCleanup(IntPtr geom, int mode); + internal static extern void GeomTransformSetCleanup(IntPtr geom, int mode); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTransformSetGeom"), SuppressUnmanagedCodeSecurity] - public static extern void GeomTransformSetGeom(IntPtr geom, IntPtr obj); + internal static extern void GeomTransformSetGeom(IntPtr geom, IntPtr obj); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTransformSetInfo"), SuppressUnmanagedCodeSecurity] - public static extern void GeomTransformSetInfo(IntPtr geom, int info); + internal static extern void GeomTransformSetInfo(IntPtr geom, int info); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshDataBuildDouble"), SuppressUnmanagedCodeSecurity] - public static extern void GeomTriMeshDataBuildDouble(IntPtr d, + internal static extern void GeomTriMeshDataBuildDouble(IntPtr d, double[] vertices, int vertexStride, int vertexCount, int[] indices, int indexCount, int triStride); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshDataBuildDouble"), SuppressUnmanagedCodeSecurity] - public static extern void GeomTriMeshDataBuildDouble(IntPtr d, + internal static extern void GeomTriMeshDataBuildDouble(IntPtr d, IntPtr vertices, int vertexStride, int vertexCount, IntPtr indices, int indexCount, int triStride); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshDataBuildDouble1"), SuppressUnmanagedCodeSecurity] - public static extern void GeomTriMeshDataBuildDouble1(IntPtr d, + internal static extern void GeomTriMeshDataBuildDouble1(IntPtr d, double[] vertices, int vertexStride, int vertexCount, int[] indices, int indexCount, int triStride, double[] normals); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshDataBuildDouble1"), SuppressUnmanagedCodeSecurity] - public static extern void GeomTriMeshDataBuildDouble(IntPtr d, + internal static extern void GeomTriMeshDataBuildDouble(IntPtr d, IntPtr vertices, int vertexStride, int vertexCount, IntPtr indices, int indexCount, int triStride, IntPtr normals); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshDataBuildSimple"), SuppressUnmanagedCodeSecurity] - public static extern void GeomTriMeshDataBuildSingle(IntPtr d, + internal static extern void GeomTriMeshDataBuildSingle(IntPtr d, dReal[] vertices, int vertexStride, int vertexCount, int[] indices, int indexCount, int triStride); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshDataBuildSimple"), SuppressUnmanagedCodeSecurity] - public static extern void GeomTriMeshDataBuildSingle(IntPtr d, + internal static extern void GeomTriMeshDataBuildSingle(IntPtr d, IntPtr vertices, int vertexStride, int vertexCount, IntPtr indices, int indexCount, int triStride); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshDataBuildSimple1"), SuppressUnmanagedCodeSecurity] - public static extern void GeomTriMeshDataBuildSingle1(IntPtr d, + internal static extern void GeomTriMeshDataBuildSingle1(IntPtr d, dReal[] vertices, int vertexStride, int vertexCount, int[] indices, int indexCount, int triStride, dReal[] normals); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshDataBuildSimple1"), SuppressUnmanagedCodeSecurity] - public static extern void GeomTriMeshDataBuildSingle1(IntPtr d, + internal static extern void GeomTriMeshDataBuildSingle1(IntPtr d, IntPtr vertices, int vertexStride, int vertexCount, IntPtr indices, int indexCount, int triStride, IntPtr normals); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshDataBuildSingle"), SuppressUnmanagedCodeSecurity] - public static extern void GeomTriMeshDataBuildSimple(IntPtr d, + internal static extern void GeomTriMeshDataBuildSimple(IntPtr d, float[] vertices, int vertexStride, int vertexCount, int[] indices, int indexCount, int triStride); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshDataBuildSingle"), SuppressUnmanagedCodeSecurity] - public static extern void GeomTriMeshDataBuildSimple(IntPtr d, + internal static extern void GeomTriMeshDataBuildSimple(IntPtr d, IntPtr vertices, int vertexStride, int vertexCount, IntPtr indices, int indexCount, int triStride); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshDataBuildSingle1"), SuppressUnmanagedCodeSecurity] - public static extern void GeomTriMeshDataBuildSimple1(IntPtr d, + internal static extern void GeomTriMeshDataBuildSimple1(IntPtr d, float[] vertices, int vertexStride, int vertexCount, int[] indices, int indexCount, int triStride, float[] normals); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshDataBuildSingle1"), SuppressUnmanagedCodeSecurity] - public static extern void GeomTriMeshDataBuildSimple1(IntPtr d, + internal static extern void GeomTriMeshDataBuildSimple1(IntPtr d, IntPtr vertices, int vertexStride, int vertexCount, IntPtr indices, int indexCount, int triStride, IntPtr normals); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshClearTCCache"), SuppressUnmanagedCodeSecurity] - public static extern void GeomTriMeshClearTCCache(IntPtr g); + internal static extern void GeomTriMeshClearTCCache(IntPtr g); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshDataCreate"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr GeomTriMeshDataCreate(); + internal static extern IntPtr GeomTriMeshDataCreate(); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshDataDestroy"), SuppressUnmanagedCodeSecurity] - public static extern void GeomTriMeshDataDestroy(IntPtr d); + internal static extern void GeomTriMeshDataDestroy(IntPtr d); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshDataGet"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr GeomTriMeshDataGet(IntPtr d, int data_id); + internal static extern IntPtr GeomTriMeshDataGet(IntPtr d, int data_id); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshDataPreprocess"), SuppressUnmanagedCodeSecurity] - public static extern void GeomTriMeshDataPreprocess(IntPtr d); + internal static extern void GeomTriMeshDataPreprocess(IntPtr d); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshDataSet"), SuppressUnmanagedCodeSecurity] - public static extern void GeomTriMeshDataSet(IntPtr d, int data_id, IntPtr in_data); + internal static extern void GeomTriMeshDataSet(IntPtr d, int data_id, IntPtr in_data); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshDataUpdate"), SuppressUnmanagedCodeSecurity] - public static extern void GeomTriMeshDataUpdate(IntPtr d); + internal static extern void GeomTriMeshDataUpdate(IntPtr d); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshEnableTC"), SuppressUnmanagedCodeSecurity] - public static extern void GeomTriMeshEnableTC(IntPtr g, int geomClass, bool enable); + internal static extern void GeomTriMeshEnableTC(IntPtr g, int geomClass, bool enable); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshGetArrayCallback"), SuppressUnmanagedCodeSecurity] - public static extern TriArrayCallback GeomTriMeshGetArrayCallback(IntPtr g); + internal static extern TriArrayCallback GeomTriMeshGetArrayCallback(IntPtr g); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshGetCallback"), SuppressUnmanagedCodeSecurity] - public static extern TriCallback GeomTriMeshGetCallback(IntPtr g); + internal static extern TriCallback GeomTriMeshGetCallback(IntPtr g); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshGetData"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr GeomTriMeshGetData(IntPtr g); + internal static extern IntPtr GeomTriMeshGetData(IntPtr g); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshGetLastTransform"), SuppressUnmanagedCodeSecurity] - public extern unsafe static Matrix4* GeomTriMeshGetLastTransformUnsafe(IntPtr geom); - public static Matrix4 GeomTriMeshGetLastTransform(IntPtr geom) + internal extern unsafe static Matrix4* GeomTriMeshGetLastTransformUnsafe(IntPtr geom); + internal static Matrix4 GeomTriMeshGetLastTransform(IntPtr geom) { unsafe { return *(GeomTriMeshGetLastTransformUnsafe(geom)); } } [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshGetPoint"), SuppressUnmanagedCodeSecurity] - public extern static void GeomTriMeshGetPoint(IntPtr g, int index, dReal u, dReal v, ref Vector3 outVec); + internal extern static void GeomTriMeshGetPoint(IntPtr g, int index, dReal u, dReal v, ref Vector3 outVec); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshGetRayCallback"), SuppressUnmanagedCodeSecurity] - public static extern TriRayCallback GeomTriMeshGetRayCallback(IntPtr g); + internal static extern TriRayCallback GeomTriMeshGetRayCallback(IntPtr g); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshGetTriangle"), SuppressUnmanagedCodeSecurity] - public extern static void GeomTriMeshGetTriangle(IntPtr g, int index, ref Vector3 v0, ref Vector3 v1, ref Vector3 v2); + internal extern static void GeomTriMeshGetTriangle(IntPtr g, int index, ref Vector3 v0, ref Vector3 v1, ref Vector3 v2); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshGetTriangleCount"), SuppressUnmanagedCodeSecurity] - public extern static int GeomTriMeshGetTriangleCount(IntPtr g); + internal extern static int GeomTriMeshGetTriangleCount(IntPtr g); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshGetTriMeshDataID"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr GeomTriMeshGetTriMeshDataID(IntPtr g); + internal static extern IntPtr GeomTriMeshGetTriMeshDataID(IntPtr g); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshIsTCEnabled"), SuppressUnmanagedCodeSecurity] - public static extern bool GeomTriMeshIsTCEnabled(IntPtr g, int geomClass); + internal static extern bool GeomTriMeshIsTCEnabled(IntPtr g, int geomClass); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshSetArrayCallback"), SuppressUnmanagedCodeSecurity] - public static extern void GeomTriMeshSetArrayCallback(IntPtr g, TriArrayCallback arrayCallback); + internal static extern void GeomTriMeshSetArrayCallback(IntPtr g, TriArrayCallback arrayCallback); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshSetCallback"), SuppressUnmanagedCodeSecurity] - public static extern void GeomTriMeshSetCallback(IntPtr g, TriCallback callback); + internal static extern void GeomTriMeshSetCallback(IntPtr g, TriCallback callback); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshSetData"), SuppressUnmanagedCodeSecurity] - public static extern void GeomTriMeshSetData(IntPtr g, IntPtr data); + internal static extern void GeomTriMeshSetData(IntPtr g, IntPtr data); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshSetLastTransform"), SuppressUnmanagedCodeSecurity] - public static extern void GeomTriMeshSetLastTransform(IntPtr g, ref Matrix4 last_trans); + internal static extern void GeomTriMeshSetLastTransform(IntPtr g, ref Matrix4 last_trans); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshSetLastTransform"), SuppressUnmanagedCodeSecurity] - public static extern void GeomTriMeshSetLastTransform(IntPtr g, ref dReal M00); + internal static extern void GeomTriMeshSetLastTransform(IntPtr g, ref dReal M00); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshSetRayCallback"), SuppressUnmanagedCodeSecurity] - public static extern void GeomTriMeshSetRayCallback(IntPtr g, TriRayCallback callback); + internal static extern void GeomTriMeshSetRayCallback(IntPtr g, TriRayCallback callback); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGetConfiguration"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr iGetConfiguration(); + internal static extern IntPtr iGetConfiguration(); - public static string GetConfiguration() + internal static string GetConfiguration() { IntPtr ptr = iGetConfiguration(); string s = Marshal.PtrToStringAnsi(ptr); @@ -1335,691 +1335,691 @@ namespace OpenSim.Region.PhysicsModule.ODE } [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dHashSpaceCreate"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr HashSpaceCreate(IntPtr space); + internal static extern IntPtr HashSpaceCreate(IntPtr space); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dHashSpaceGetLevels"), SuppressUnmanagedCodeSecurity] - public static extern void HashSpaceGetLevels(IntPtr space, out int minlevel, out int maxlevel); + internal static extern void HashSpaceGetLevels(IntPtr space, out int minlevel, out int maxlevel); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dHashSpaceSetLevels"), SuppressUnmanagedCodeSecurity] - public static extern void HashSpaceSetLevels(IntPtr space, int minlevel, int maxlevel); + internal static extern void HashSpaceSetLevels(IntPtr space, int minlevel, int maxlevel); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dInfiniteAABB"), SuppressUnmanagedCodeSecurity] - public static extern void InfiniteAABB(IntPtr geom, out AABB aabb); + internal static extern void InfiniteAABB(IntPtr geom, out AABB aabb); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dInitODE"), SuppressUnmanagedCodeSecurity] - public static extern void InitODE(); + internal static extern void InitODE(); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dInitODE2"), SuppressUnmanagedCodeSecurity] - public static extern int InitODE2(uint ODEInitFlags); + internal static extern int InitODE2(uint ODEInitFlags); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dIsPositiveDefinite"), SuppressUnmanagedCodeSecurity] - public static extern int IsPositiveDefinite(ref dReal A, int n); + internal static extern int IsPositiveDefinite(ref dReal A, int n); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dInvertPDMatrix"), SuppressUnmanagedCodeSecurity] - public static extern int InvertPDMatrix(ref dReal A, out dReal Ainv, int n); + internal static extern int InvertPDMatrix(ref dReal A, out dReal Ainv, int n); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointAddAMotorTorques"), SuppressUnmanagedCodeSecurity] - public static extern void JointAddAMotorTorques(IntPtr joint, dReal torque1, dReal torque2, dReal torque3); + internal static extern void JointAddAMotorTorques(IntPtr joint, dReal torque1, dReal torque2, dReal torque3); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointAddHingeTorque"), SuppressUnmanagedCodeSecurity] - public static extern void JointAddHingeTorque(IntPtr joint, dReal torque); + internal static extern void JointAddHingeTorque(IntPtr joint, dReal torque); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointAddHinge2Torque"), SuppressUnmanagedCodeSecurity] - public static extern void JointAddHinge2Torques(IntPtr joint, dReal torque1, dReal torque2); + internal static extern void JointAddHinge2Torques(IntPtr joint, dReal torque1, dReal torque2); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointAddPRTorque"), SuppressUnmanagedCodeSecurity] - public static extern void JointAddPRTorque(IntPtr joint, dReal torque); + internal static extern void JointAddPRTorque(IntPtr joint, dReal torque); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointAddUniversalTorque"), SuppressUnmanagedCodeSecurity] - public static extern void JointAddUniversalTorques(IntPtr joint, dReal torque1, dReal torque2); + internal static extern void JointAddUniversalTorques(IntPtr joint, dReal torque1, dReal torque2); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointAddSliderForce"), SuppressUnmanagedCodeSecurity] - public static extern void JointAddSliderForce(IntPtr joint, dReal force); + internal static extern void JointAddSliderForce(IntPtr joint, dReal force); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointAttach"), SuppressUnmanagedCodeSecurity] - public static extern void JointAttach(IntPtr joint, IntPtr body1, IntPtr body2); + internal static extern void JointAttach(IntPtr joint, IntPtr body1, IntPtr body2); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointCreateAMotor"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr JointCreateAMotor(IntPtr world, IntPtr group); + internal static extern IntPtr JointCreateAMotor(IntPtr world, IntPtr group); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointCreateBall"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr JointCreateBall(IntPtr world, IntPtr group); + internal static extern IntPtr JointCreateBall(IntPtr world, IntPtr group); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointCreateContact"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr JointCreateContact(IntPtr world, IntPtr group, ref Contact contact); + internal static extern IntPtr JointCreateContact(IntPtr world, IntPtr group, ref Contact contact); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointCreateContact"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr JointCreateContactPtr(IntPtr world, IntPtr group, IntPtr contact); + internal static extern IntPtr JointCreateContactPtr(IntPtr world, IntPtr group, IntPtr contact); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointCreateFixed"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr JointCreateFixed(IntPtr world, IntPtr group); + internal static extern IntPtr JointCreateFixed(IntPtr world, IntPtr group); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointCreateHinge"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr JointCreateHinge(IntPtr world, IntPtr group); + internal static extern IntPtr JointCreateHinge(IntPtr world, IntPtr group); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointCreateHinge2"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr JointCreateHinge2(IntPtr world, IntPtr group); + internal static extern IntPtr JointCreateHinge2(IntPtr world, IntPtr group); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointCreateLMotor"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr JointCreateLMotor(IntPtr world, IntPtr group); + internal static extern IntPtr JointCreateLMotor(IntPtr world, IntPtr group); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointCreateNull"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr JointCreateNull(IntPtr world, IntPtr group); + internal static extern IntPtr JointCreateNull(IntPtr world, IntPtr group); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointCreatePR"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr JointCreatePR(IntPtr world, IntPtr group); + internal static extern IntPtr JointCreatePR(IntPtr world, IntPtr group); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointCreatePlane2D"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr JointCreatePlane2D(IntPtr world, IntPtr group); + internal static extern IntPtr JointCreatePlane2D(IntPtr world, IntPtr group); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointCreateSlider"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr JointCreateSlider(IntPtr world, IntPtr group); + internal static extern IntPtr JointCreateSlider(IntPtr world, IntPtr group); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointCreateUniversal"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr JointCreateUniversal(IntPtr world, IntPtr group); + internal static extern IntPtr JointCreateUniversal(IntPtr world, IntPtr group); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointDestroy"), SuppressUnmanagedCodeSecurity] - public static extern void JointDestroy(IntPtr j); + internal static extern void JointDestroy(IntPtr j); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetAMotorAngle"), SuppressUnmanagedCodeSecurity] - public static extern dReal JointGetAMotorAngle(IntPtr j, int anum); + internal static extern dReal JointGetAMotorAngle(IntPtr j, int anum); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetAMotorAngleRate"), SuppressUnmanagedCodeSecurity] - public static extern dReal JointGetAMotorAngleRate(IntPtr j, int anum); + internal static extern dReal JointGetAMotorAngleRate(IntPtr j, int anum); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetAMotorAxis"), SuppressUnmanagedCodeSecurity] - public static extern void JointGetAMotorAxis(IntPtr j, int anum, out Vector3 result); + internal static extern void JointGetAMotorAxis(IntPtr j, int anum, out Vector3 result); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetAMotorAxisRel"), SuppressUnmanagedCodeSecurity] - public static extern int JointGetAMotorAxisRel(IntPtr j, int anum); + internal static extern int JointGetAMotorAxisRel(IntPtr j, int anum); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetAMotorMode"), SuppressUnmanagedCodeSecurity] - public static extern int JointGetAMotorMode(IntPtr j); + internal static extern int JointGetAMotorMode(IntPtr j); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetAMotorNumAxes"), SuppressUnmanagedCodeSecurity] - public static extern int JointGetAMotorNumAxes(IntPtr j); + internal static extern int JointGetAMotorNumAxes(IntPtr j); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetAMotorParam"), SuppressUnmanagedCodeSecurity] - public static extern dReal JointGetAMotorParam(IntPtr j, int parameter); + internal static extern dReal JointGetAMotorParam(IntPtr j, int parameter); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetBallAnchor"), SuppressUnmanagedCodeSecurity] - public static extern void JointGetBallAnchor(IntPtr j, out Vector3 result); + internal static extern void JointGetBallAnchor(IntPtr j, out Vector3 result); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetBallAnchor2"), SuppressUnmanagedCodeSecurity] - public static extern void JointGetBallAnchor2(IntPtr j, out Vector3 result); + internal static extern void JointGetBallAnchor2(IntPtr j, out Vector3 result); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetBody"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr JointGetBody(IntPtr j); + internal static extern IntPtr JointGetBody(IntPtr j); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetData"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr JointGetData(IntPtr j); + internal static extern IntPtr JointGetData(IntPtr j); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetFeedback"), SuppressUnmanagedCodeSecurity] - public extern unsafe static JointFeedback* JointGetFeedbackUnsafe(IntPtr j); - public static JointFeedback JointGetFeedback(IntPtr j) + internal extern unsafe static JointFeedback* JointGetFeedbackUnsafe(IntPtr j); + internal static JointFeedback JointGetFeedback(IntPtr j) { unsafe { return *(JointGetFeedbackUnsafe(j)); } } [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetHingeAnchor"), SuppressUnmanagedCodeSecurity] - public static extern void JointGetHingeAnchor(IntPtr j, out Vector3 result); + internal static extern void JointGetHingeAnchor(IntPtr j, out Vector3 result); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetHingeAngle"), SuppressUnmanagedCodeSecurity] - public static extern dReal JointGetHingeAngle(IntPtr j); + internal static extern dReal JointGetHingeAngle(IntPtr j); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetHingeAngleRate"), SuppressUnmanagedCodeSecurity] - public static extern dReal JointGetHingeAngleRate(IntPtr j); + internal static extern dReal JointGetHingeAngleRate(IntPtr j); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetHingeAxis"), SuppressUnmanagedCodeSecurity] - public static extern void JointGetHingeAxis(IntPtr j, out Vector3 result); + internal static extern void JointGetHingeAxis(IntPtr j, out Vector3 result); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetHingeParam"), SuppressUnmanagedCodeSecurity] - public static extern dReal JointGetHingeParam(IntPtr j, int parameter); + internal static extern dReal JointGetHingeParam(IntPtr j, int parameter); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetHinge2Angle1"), SuppressUnmanagedCodeSecurity] - public static extern dReal JointGetHinge2Angle1(IntPtr j); + internal static extern dReal JointGetHinge2Angle1(IntPtr j); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetHinge2Angle1Rate"), SuppressUnmanagedCodeSecurity] - public static extern dReal JointGetHinge2Angle1Rate(IntPtr j); + internal static extern dReal JointGetHinge2Angle1Rate(IntPtr j); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetHinge2Angle2Rate"), SuppressUnmanagedCodeSecurity] - public static extern dReal JointGetHinge2Angle2Rate(IntPtr j); + internal static extern dReal JointGetHinge2Angle2Rate(IntPtr j); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetHingeAnchor2"), SuppressUnmanagedCodeSecurity] - public static extern void JointGetHingeAnchor2(IntPtr j, out Vector3 result); + internal static extern void JointGetHingeAnchor2(IntPtr j, out Vector3 result); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetHinge2Anchor"), SuppressUnmanagedCodeSecurity] - public static extern void JointGetHinge2Anchor(IntPtr j, out Vector3 result); + internal static extern void JointGetHinge2Anchor(IntPtr j, out Vector3 result); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetHinge2Anchor2"), SuppressUnmanagedCodeSecurity] - public static extern void JointGetHinge2Anchor2(IntPtr j, out Vector3 result); + internal static extern void JointGetHinge2Anchor2(IntPtr j, out Vector3 result); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetHinge2Axis1"), SuppressUnmanagedCodeSecurity] - public static extern void JointGetHinge2Axis1(IntPtr j, out Vector3 result); + internal static extern void JointGetHinge2Axis1(IntPtr j, out Vector3 result); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetHinge2Axis2"), SuppressUnmanagedCodeSecurity] - public static extern void JointGetHinge2Axis2(IntPtr j, out Vector3 result); + internal static extern void JointGetHinge2Axis2(IntPtr j, out Vector3 result); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetHinge2Param"), SuppressUnmanagedCodeSecurity] - public static extern dReal JointGetHinge2Param(IntPtr j, int parameter); + internal static extern dReal JointGetHinge2Param(IntPtr j, int parameter); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetLMotorAxis"), SuppressUnmanagedCodeSecurity] - public static extern void JointGetLMotorAxis(IntPtr j, int anum, out Vector3 result); + internal static extern void JointGetLMotorAxis(IntPtr j, int anum, out Vector3 result); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetLMotorNumAxes"), SuppressUnmanagedCodeSecurity] - public static extern int JointGetLMotorNumAxes(IntPtr j); + internal static extern int JointGetLMotorNumAxes(IntPtr j); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetLMotorParam"), SuppressUnmanagedCodeSecurity] - public static extern dReal JointGetLMotorParam(IntPtr j, int parameter); + internal static extern dReal JointGetLMotorParam(IntPtr j, int parameter); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetPRAnchor"), SuppressUnmanagedCodeSecurity] - public static extern void JointGetPRAnchor(IntPtr j, out Vector3 result); + internal static extern void JointGetPRAnchor(IntPtr j, out Vector3 result); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetPRAxis1"), SuppressUnmanagedCodeSecurity] - public static extern void JointGetPRAxis1(IntPtr j, out Vector3 result); + internal static extern void JointGetPRAxis1(IntPtr j, out Vector3 result); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetPRAxis2"), SuppressUnmanagedCodeSecurity] - public static extern void JointGetPRAxis2(IntPtr j, out Vector3 result); + internal static extern void JointGetPRAxis2(IntPtr j, out Vector3 result); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetPRParam"), SuppressUnmanagedCodeSecurity] - public static extern dReal JointGetPRParam(IntPtr j, int parameter); + internal static extern dReal JointGetPRParam(IntPtr j, int parameter); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetPRPosition"), SuppressUnmanagedCodeSecurity] - public static extern dReal JointGetPRPosition(IntPtr j); + internal static extern dReal JointGetPRPosition(IntPtr j); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetPRPositionRate"), SuppressUnmanagedCodeSecurity] - public static extern dReal JointGetPRPositionRate(IntPtr j); + internal static extern dReal JointGetPRPositionRate(IntPtr j); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetSliderAxis"), SuppressUnmanagedCodeSecurity] - public static extern void JointGetSliderAxis(IntPtr j, out Vector3 result); + internal static extern void JointGetSliderAxis(IntPtr j, out Vector3 result); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetSliderParam"), SuppressUnmanagedCodeSecurity] - public static extern dReal JointGetSliderParam(IntPtr j, int parameter); + internal static extern dReal JointGetSliderParam(IntPtr j, int parameter); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetSliderPosition"), SuppressUnmanagedCodeSecurity] - public static extern dReal JointGetSliderPosition(IntPtr j); + internal static extern dReal JointGetSliderPosition(IntPtr j); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetSliderPositionRate"), SuppressUnmanagedCodeSecurity] - public static extern dReal JointGetSliderPositionRate(IntPtr j); + internal static extern dReal JointGetSliderPositionRate(IntPtr j); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetType"), SuppressUnmanagedCodeSecurity] - public static extern JointType JointGetType(IntPtr j); + internal static extern JointType JointGetType(IntPtr j); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetUniversalAnchor"), SuppressUnmanagedCodeSecurity] - public static extern void JointGetUniversalAnchor(IntPtr j, out Vector3 result); + internal static extern void JointGetUniversalAnchor(IntPtr j, out Vector3 result); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetUniversalAnchor2"), SuppressUnmanagedCodeSecurity] - public static extern void JointGetUniversalAnchor2(IntPtr j, out Vector3 result); + internal static extern void JointGetUniversalAnchor2(IntPtr j, out Vector3 result); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetUniversalAngle1"), SuppressUnmanagedCodeSecurity] - public static extern dReal JointGetUniversalAngle1(IntPtr j); + internal static extern dReal JointGetUniversalAngle1(IntPtr j); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetUniversalAngle1Rate"), SuppressUnmanagedCodeSecurity] - public static extern dReal JointGetUniversalAngle1Rate(IntPtr j); + internal static extern dReal JointGetUniversalAngle1Rate(IntPtr j); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetUniversalAngle2"), SuppressUnmanagedCodeSecurity] - public static extern dReal JointGetUniversalAngle2(IntPtr j); + internal static extern dReal JointGetUniversalAngle2(IntPtr j); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetUniversalAngle2Rate"), SuppressUnmanagedCodeSecurity] - public static extern dReal JointGetUniversalAngle2Rate(IntPtr j); + internal static extern dReal JointGetUniversalAngle2Rate(IntPtr j); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetUniversalAngles"), SuppressUnmanagedCodeSecurity] - public static extern void JointGetUniversalAngles(IntPtr j, out dReal angle1, out dReal angle2); + internal static extern void JointGetUniversalAngles(IntPtr j, out dReal angle1, out dReal angle2); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetUniversalAxis1"), SuppressUnmanagedCodeSecurity] - public static extern void JointGetUniversalAxis1(IntPtr j, out Vector3 result); + internal static extern void JointGetUniversalAxis1(IntPtr j, out Vector3 result); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetUniversalAxis2"), SuppressUnmanagedCodeSecurity] - public static extern void JointGetUniversalAxis2(IntPtr j, out Vector3 result); + internal static extern void JointGetUniversalAxis2(IntPtr j, out Vector3 result); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetUniversalParam"), SuppressUnmanagedCodeSecurity] - public static extern dReal JointGetUniversalParam(IntPtr j, int parameter); + internal static extern dReal JointGetUniversalParam(IntPtr j, int parameter); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGroupCreate"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr JointGroupCreate(int max_size); + internal static extern IntPtr JointGroupCreate(int max_size); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGroupDestroy"), SuppressUnmanagedCodeSecurity] - public static extern void JointGroupDestroy(IntPtr group); + internal static extern void JointGroupDestroy(IntPtr group); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGroupEmpty"), SuppressUnmanagedCodeSecurity] - public static extern void JointGroupEmpty(IntPtr group); + internal static extern void JointGroupEmpty(IntPtr group); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetAMotorAngle"), SuppressUnmanagedCodeSecurity] - public static extern void JointSetAMotorAngle(IntPtr j, int anum, dReal angle); + internal static extern void JointSetAMotorAngle(IntPtr j, int anum, dReal angle); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetAMotorAxis"), SuppressUnmanagedCodeSecurity] - public static extern void JointSetAMotorAxis(IntPtr j, int anum, int rel, dReal x, dReal y, dReal z); + internal static extern void JointSetAMotorAxis(IntPtr j, int anum, int rel, dReal x, dReal y, dReal z); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetAMotorMode"), SuppressUnmanagedCodeSecurity] - public static extern void JointSetAMotorMode(IntPtr j, int mode); + internal static extern void JointSetAMotorMode(IntPtr j, int mode); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetAMotorNumAxes"), SuppressUnmanagedCodeSecurity] - public static extern void JointSetAMotorNumAxes(IntPtr group, int num); + internal static extern void JointSetAMotorNumAxes(IntPtr group, int num); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetAMotorParam"), SuppressUnmanagedCodeSecurity] - public static extern void JointSetAMotorParam(IntPtr group, int parameter, dReal value); + internal static extern void JointSetAMotorParam(IntPtr group, int parameter, dReal value); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetBallAnchor"), SuppressUnmanagedCodeSecurity] - public static extern void JointSetBallAnchor(IntPtr j, dReal x, dReal y, dReal z); + internal static extern void JointSetBallAnchor(IntPtr j, dReal x, dReal y, dReal z); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetBallAnchor2"), SuppressUnmanagedCodeSecurity] - public static extern void JointSetBallAnchor2(IntPtr j, dReal x, dReal y, dReal z); + internal static extern void JointSetBallAnchor2(IntPtr j, dReal x, dReal y, dReal z); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetData"), SuppressUnmanagedCodeSecurity] - public static extern void JointSetData(IntPtr j, IntPtr data); + internal static extern void JointSetData(IntPtr j, IntPtr data); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetFeedback"), SuppressUnmanagedCodeSecurity] - public static extern void JointSetFeedback(IntPtr j, out JointFeedback feedback); + internal static extern void JointSetFeedback(IntPtr j, out JointFeedback feedback); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetFixed"), SuppressUnmanagedCodeSecurity] - public static extern void JointSetFixed(IntPtr j); + internal static extern void JointSetFixed(IntPtr j); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetHingeAnchor"), SuppressUnmanagedCodeSecurity] - public static extern void JointSetHingeAnchor(IntPtr j, dReal x, dReal y, dReal z); + internal static extern void JointSetHingeAnchor(IntPtr j, dReal x, dReal y, dReal z); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetHingeAnchorDelta"), SuppressUnmanagedCodeSecurity] - public static extern void JointSetHingeAnchorDelta(IntPtr j, dReal x, dReal y, dReal z, dReal ax, dReal ay, dReal az); + internal static extern void JointSetHingeAnchorDelta(IntPtr j, dReal x, dReal y, dReal z, dReal ax, dReal ay, dReal az); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetHingeAxis"), SuppressUnmanagedCodeSecurity] - public static extern void JointSetHingeAxis(IntPtr j, dReal x, dReal y, dReal z); + internal static extern void JointSetHingeAxis(IntPtr j, dReal x, dReal y, dReal z); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetHingeParam"), SuppressUnmanagedCodeSecurity] - public static extern void JointSetHingeParam(IntPtr j, int parameter, dReal value); + internal static extern void JointSetHingeParam(IntPtr j, int parameter, dReal value); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetHinge2Anchor"), SuppressUnmanagedCodeSecurity] - public static extern void JointSetHinge2Anchor(IntPtr j, dReal x, dReal y, dReal z); + internal static extern void JointSetHinge2Anchor(IntPtr j, dReal x, dReal y, dReal z); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetHinge2Axis1"), SuppressUnmanagedCodeSecurity] - public static extern void JointSetHinge2Axis1(IntPtr j, dReal x, dReal y, dReal z); + internal static extern void JointSetHinge2Axis1(IntPtr j, dReal x, dReal y, dReal z); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetHinge2Axis2"), SuppressUnmanagedCodeSecurity] - public static extern void JointSetHinge2Axis2(IntPtr j, dReal x, dReal y, dReal z); + internal static extern void JointSetHinge2Axis2(IntPtr j, dReal x, dReal y, dReal z); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetHinge2Param"), SuppressUnmanagedCodeSecurity] - public static extern void JointSetHinge2Param(IntPtr j, int parameter, dReal value); + internal static extern void JointSetHinge2Param(IntPtr j, int parameter, dReal value); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetLMotorAxis"), SuppressUnmanagedCodeSecurity] - public static extern void JointSetLMotorAxis(IntPtr j, int anum, int rel, dReal x, dReal y, dReal z); + internal static extern void JointSetLMotorAxis(IntPtr j, int anum, int rel, dReal x, dReal y, dReal z); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetLMotorNumAxes"), SuppressUnmanagedCodeSecurity] - public static extern void JointSetLMotorNumAxes(IntPtr j, int num); + internal static extern void JointSetLMotorNumAxes(IntPtr j, int num); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetLMotorParam"), SuppressUnmanagedCodeSecurity] - public static extern void JointSetLMotorParam(IntPtr j, int parameter, dReal value); + internal static extern void JointSetLMotorParam(IntPtr j, int parameter, dReal value); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetPlane2DAngleParam"), SuppressUnmanagedCodeSecurity] - public static extern void JointSetPlane2DAngleParam(IntPtr j, int parameter, dReal value); + internal static extern void JointSetPlane2DAngleParam(IntPtr j, int parameter, dReal value); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetPlane2DXParam"), SuppressUnmanagedCodeSecurity] - public static extern void JointSetPlane2DXParam(IntPtr j, int parameter, dReal value); + internal static extern void JointSetPlane2DXParam(IntPtr j, int parameter, dReal value); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetPlane2DYParam"), SuppressUnmanagedCodeSecurity] - public static extern void JointSetPlane2DYParam(IntPtr j, int parameter, dReal value); + internal static extern void JointSetPlane2DYParam(IntPtr j, int parameter, dReal value); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetPRAnchor"), SuppressUnmanagedCodeSecurity] - public static extern void JointSetPRAnchor(IntPtr j, dReal x, dReal y, dReal z); + internal static extern void JointSetPRAnchor(IntPtr j, dReal x, dReal y, dReal z); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetPRAxis1"), SuppressUnmanagedCodeSecurity] - public static extern void JointSetPRAxis1(IntPtr j, dReal x, dReal y, dReal z); + internal static extern void JointSetPRAxis1(IntPtr j, dReal x, dReal y, dReal z); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetPRAxis2"), SuppressUnmanagedCodeSecurity] - public static extern void JointSetPRAxis2(IntPtr j, dReal x, dReal y, dReal z); + internal static extern void JointSetPRAxis2(IntPtr j, dReal x, dReal y, dReal z); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetPRParam"), SuppressUnmanagedCodeSecurity] - public static extern void JointSetPRParam(IntPtr j, int parameter, dReal value); + internal static extern void JointSetPRParam(IntPtr j, int parameter, dReal value); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetSliderAxis"), SuppressUnmanagedCodeSecurity] - public static extern void JointSetSliderAxis(IntPtr j, dReal x, dReal y, dReal z); + internal static extern void JointSetSliderAxis(IntPtr j, dReal x, dReal y, dReal z); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetSliderAxisDelta"), SuppressUnmanagedCodeSecurity] - public static extern void JointSetSliderAxisDelta(IntPtr j, dReal x, dReal y, dReal z, dReal ax, dReal ay, dReal az); + internal static extern void JointSetSliderAxisDelta(IntPtr j, dReal x, dReal y, dReal z, dReal ax, dReal ay, dReal az); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetSliderParam"), SuppressUnmanagedCodeSecurity] - public static extern void JointSetSliderParam(IntPtr j, int parameter, dReal value); + internal static extern void JointSetSliderParam(IntPtr j, int parameter, dReal value); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetUniversalAnchor"), SuppressUnmanagedCodeSecurity] - public static extern void JointSetUniversalAnchor(IntPtr j, dReal x, dReal y, dReal z); + internal static extern void JointSetUniversalAnchor(IntPtr j, dReal x, dReal y, dReal z); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetUniversalAxis1"), SuppressUnmanagedCodeSecurity] - public static extern void JointSetUniversalAxis1(IntPtr j, dReal x, dReal y, dReal z); + internal static extern void JointSetUniversalAxis1(IntPtr j, dReal x, dReal y, dReal z); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetUniversalAxis2"), SuppressUnmanagedCodeSecurity] - public static extern void JointSetUniversalAxis2(IntPtr j, dReal x, dReal y, dReal z); + internal static extern void JointSetUniversalAxis2(IntPtr j, dReal x, dReal y, dReal z); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetUniversalParam"), SuppressUnmanagedCodeSecurity] - public static extern void JointSetUniversalParam(IntPtr j, int parameter, dReal value); + internal static extern void JointSetUniversalParam(IntPtr j, int parameter, dReal value); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dLDLTAddTL"), SuppressUnmanagedCodeSecurity] - public static extern void LDLTAddTL(ref dReal L, ref dReal d, ref dReal a, int n, int nskip); + internal static extern void LDLTAddTL(ref dReal L, ref dReal d, ref dReal a, int n, int nskip); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMassAdd"), SuppressUnmanagedCodeSecurity] - public static extern void MassAdd(ref Mass a, ref Mass b); + internal static extern void MassAdd(ref Mass a, ref Mass b); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMassAdjust"), SuppressUnmanagedCodeSecurity] - public static extern void MassAdjust(ref Mass m, dReal newmass); + internal static extern void MassAdjust(ref Mass m, dReal newmass); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMassCheck"), SuppressUnmanagedCodeSecurity] - public static extern bool MassCheck(ref Mass m); + internal static extern bool MassCheck(ref Mass m); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMassRotate"), SuppressUnmanagedCodeSecurity] - public static extern void MassRotate(ref Mass mass, ref Matrix3 R); + internal static extern void MassRotate(ref Mass mass, ref Matrix3 R); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMassRotate"), SuppressUnmanagedCodeSecurity] - public static extern void MassRotate(ref Mass mass, ref dReal M00); + internal static extern void MassRotate(ref Mass mass, ref dReal M00); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMassSetBox"), SuppressUnmanagedCodeSecurity] - public static extern void MassSetBox(out Mass mass, dReal density, dReal lx, dReal ly, dReal lz); + internal static extern void MassSetBox(out Mass mass, dReal density, dReal lx, dReal ly, dReal lz); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMassSetBoxTotal"), SuppressUnmanagedCodeSecurity] - public static extern void MassSetBoxTotal(out Mass mass, dReal total_mass, dReal lx, dReal ly, dReal lz); + internal static extern void MassSetBoxTotal(out Mass mass, dReal total_mass, dReal lx, dReal ly, dReal lz); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMassSetCapsule"), SuppressUnmanagedCodeSecurity] - public static extern void MassSetCapsule(out Mass mass, dReal density, int direction, dReal radius, dReal length); + internal static extern void MassSetCapsule(out Mass mass, dReal density, int direction, dReal radius, dReal length); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMassSetCapsuleTotal"), SuppressUnmanagedCodeSecurity] - public static extern void MassSetCapsuleTotal(out Mass mass, dReal total_mass, int direction, dReal radius, dReal length); + internal static extern void MassSetCapsuleTotal(out Mass mass, dReal total_mass, int direction, dReal radius, dReal length); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMassSetCylinder"), SuppressUnmanagedCodeSecurity] - public static extern void MassSetCylinder(out Mass mass, dReal density, int direction, dReal radius, dReal length); + internal static extern void MassSetCylinder(out Mass mass, dReal density, int direction, dReal radius, dReal length); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMassSetCylinderTotal"), SuppressUnmanagedCodeSecurity] - public static extern void MassSetCylinderTotal(out Mass mass, dReal total_mass, int direction, dReal radius, dReal length); + internal static extern void MassSetCylinderTotal(out Mass mass, dReal total_mass, int direction, dReal radius, dReal length); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMassSetParameters"), SuppressUnmanagedCodeSecurity] - public static extern void MassSetParameters(out Mass mass, dReal themass, + internal static extern void MassSetParameters(out Mass mass, dReal themass, dReal cgx, dReal cgy, dReal cgz, dReal i11, dReal i22, dReal i33, dReal i12, dReal i13, dReal i23); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMassSetSphere"), SuppressUnmanagedCodeSecurity] - public static extern void MassSetSphere(out Mass mass, dReal density, dReal radius); + internal static extern void MassSetSphere(out Mass mass, dReal density, dReal radius); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMassSetSphereTotal"), SuppressUnmanagedCodeSecurity] - public static extern void dMassSetSphereTotal(out Mass mass, dReal total_mass, dReal radius); + internal static extern void dMassSetSphereTotal(out Mass mass, dReal total_mass, dReal radius); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMassSetTrimesh"), SuppressUnmanagedCodeSecurity] - public static extern void MassSetTrimesh(out Mass mass, dReal density, IntPtr g); + internal static extern void MassSetTrimesh(out Mass mass, dReal density, IntPtr g); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMassSetZero"), SuppressUnmanagedCodeSecurity] - public static extern void MassSetZero(out Mass mass); + internal static extern void MassSetZero(out Mass mass); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMassTranslate"), SuppressUnmanagedCodeSecurity] - public static extern void MassTranslate(ref Mass mass, dReal x, dReal y, dReal z); + internal static extern void MassTranslate(ref Mass mass, dReal x, dReal y, dReal z); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMultiply0"), SuppressUnmanagedCodeSecurity] - public static extern void Multiply0(out dReal A00, ref dReal B00, ref dReal C00, int p, int q, int r); + internal static extern void Multiply0(out dReal A00, ref dReal B00, ref dReal C00, int p, int q, int r); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMultiply0"), SuppressUnmanagedCodeSecurity] private static extern void MultiplyiM3V3(out Vector3 vout, ref Matrix3 matrix, ref Vector3 vect,int p, int q, int r); - public static void MultiplyM3V3(out Vector3 outvector, ref Matrix3 matrix, ref Vector3 invector) + internal static void MultiplyM3V3(out Vector3 outvector, ref Matrix3 matrix, ref Vector3 invector) { MultiplyiM3V3(out outvector, ref matrix, ref invector, 3, 3, 1); } [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMultiply1"), SuppressUnmanagedCodeSecurity] - public static extern void Multiply1(out dReal A00, ref dReal B00, ref dReal C00, int p, int q, int r); + internal static extern void Multiply1(out dReal A00, ref dReal B00, ref dReal C00, int p, int q, int r); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMultiply2"), SuppressUnmanagedCodeSecurity] - public static extern void Multiply2(out dReal A00, ref dReal B00, ref dReal C00, int p, int q, int r); + internal static extern void Multiply2(out dReal A00, ref dReal B00, ref dReal C00, int p, int q, int r); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dQFromAxisAndAngle"), SuppressUnmanagedCodeSecurity] - public static extern void QFromAxisAndAngle(out Quaternion q, dReal ax, dReal ay, dReal az, dReal angle); + internal static extern void QFromAxisAndAngle(out Quaternion q, dReal ax, dReal ay, dReal az, dReal angle); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dQfromR"), SuppressUnmanagedCodeSecurity] - public static extern void QfromR(out Quaternion q, ref Matrix3 R); + internal static extern void QfromR(out Quaternion q, ref Matrix3 R); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dQMultiply0"), SuppressUnmanagedCodeSecurity] - public static extern void QMultiply0(out Quaternion qa, ref Quaternion qb, ref Quaternion qc); + internal static extern void QMultiply0(out Quaternion qa, ref Quaternion qb, ref Quaternion qc); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dQMultiply1"), SuppressUnmanagedCodeSecurity] - public static extern void QMultiply1(out Quaternion qa, ref Quaternion qb, ref Quaternion qc); + internal static extern void QMultiply1(out Quaternion qa, ref Quaternion qb, ref Quaternion qc); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dQMultiply2"), SuppressUnmanagedCodeSecurity] - public static extern void QMultiply2(out Quaternion qa, ref Quaternion qb, ref Quaternion qc); + internal static extern void QMultiply2(out Quaternion qa, ref Quaternion qb, ref Quaternion qc); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dQMultiply3"), SuppressUnmanagedCodeSecurity] - public static extern void QMultiply3(out Quaternion qa, ref Quaternion qb, ref Quaternion qc); + internal static extern void QMultiply3(out Quaternion qa, ref Quaternion qb, ref Quaternion qc); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dQSetIdentity"), SuppressUnmanagedCodeSecurity] - public static extern void QSetIdentity(out Quaternion q); + internal static extern void QSetIdentity(out Quaternion q); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dQuadTreeSpaceCreate"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr QuadTreeSpaceCreate(IntPtr space, ref Vector3 center, ref Vector3 extents, int depth); + internal static extern IntPtr QuadTreeSpaceCreate(IntPtr space, ref Vector3 center, ref Vector3 extents, int depth); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dQuadTreeSpaceCreate"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr QuadTreeSpaceCreate(IntPtr space, ref dReal centerX, ref dReal extentsX, int depth); + internal static extern IntPtr QuadTreeSpaceCreate(IntPtr space, ref dReal centerX, ref dReal extentsX, int depth); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dRandReal"), SuppressUnmanagedCodeSecurity] - public static extern dReal RandReal(); + internal static extern dReal RandReal(); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dRFrom2Axes"), SuppressUnmanagedCodeSecurity] - public static extern void RFrom2Axes(out Matrix3 R, dReal ax, dReal ay, dReal az, dReal bx, dReal by, dReal bz); + internal static extern void RFrom2Axes(out Matrix3 R, dReal ax, dReal ay, dReal az, dReal bx, dReal by, dReal bz); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dRFromAxisAndAngle"), SuppressUnmanagedCodeSecurity] - public static extern void RFromAxisAndAngle(out Matrix3 R, dReal x, dReal y, dReal z, dReal angle); + internal static extern void RFromAxisAndAngle(out Matrix3 R, dReal x, dReal y, dReal z, dReal angle); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dRFromEulerAngles"), SuppressUnmanagedCodeSecurity] - public static extern void RFromEulerAngles(out Matrix3 R, dReal phi, dReal theta, dReal psi); + internal static extern void RFromEulerAngles(out Matrix3 R, dReal phi, dReal theta, dReal psi); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dRfromQ"), SuppressUnmanagedCodeSecurity] - public static extern void RfromQ(out Matrix3 R, ref Quaternion q); + internal static extern void RfromQ(out Matrix3 R, ref Quaternion q); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dRFromZAxis"), SuppressUnmanagedCodeSecurity] - public static extern void RFromZAxis(out Matrix3 R, dReal ax, dReal ay, dReal az); + internal static extern void RFromZAxis(out Matrix3 R, dReal ax, dReal ay, dReal az); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dRSetIdentity"), SuppressUnmanagedCodeSecurity] - public static extern void RSetIdentity(out Matrix3 R); + internal static extern void RSetIdentity(out Matrix3 R); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSetValue"), SuppressUnmanagedCodeSecurity] - public static extern void SetValue(out dReal a, int n); + internal static extern void SetValue(out dReal a, int n); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSetZero"), SuppressUnmanagedCodeSecurity] - public static extern void SetZero(out dReal a, int n); + internal static extern void SetZero(out dReal a, int n); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSimpleSpaceCreate"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr SimpleSpaceCreate(IntPtr space); + internal static extern IntPtr SimpleSpaceCreate(IntPtr space); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSolveCholesky"), SuppressUnmanagedCodeSecurity] - public static extern void SolveCholesky(ref dReal L, out dReal b, int n); + internal static extern void SolveCholesky(ref dReal L, out dReal b, int n); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSolveL1"), SuppressUnmanagedCodeSecurity] - public static extern void SolveL1(ref dReal L, out dReal b, int n, int nskip); + internal static extern void SolveL1(ref dReal L, out dReal b, int n, int nskip); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSolveL1T"), SuppressUnmanagedCodeSecurity] - public static extern void SolveL1T(ref dReal L, out dReal b, int n, int nskip); + internal static extern void SolveL1T(ref dReal L, out dReal b, int n, int nskip); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSolveLDLT"), SuppressUnmanagedCodeSecurity] - public static extern void SolveLDLT(ref dReal L, ref dReal d, out dReal b, int n, int nskip); + internal static extern void SolveLDLT(ref dReal L, ref dReal d, out dReal b, int n, int nskip); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSpaceAdd"), SuppressUnmanagedCodeSecurity] - public static extern void SpaceAdd(IntPtr space, IntPtr geom); + internal static extern void SpaceAdd(IntPtr space, IntPtr geom); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSpaceLockQuery"), SuppressUnmanagedCodeSecurity] - public static extern bool SpaceLockQuery(IntPtr space); + internal static extern bool SpaceLockQuery(IntPtr space); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSpaceClean"), SuppressUnmanagedCodeSecurity] - public static extern void SpaceClean(IntPtr space); + internal static extern void SpaceClean(IntPtr space); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSpaceCollide"), SuppressUnmanagedCodeSecurity] - public static extern void SpaceCollide(IntPtr space, IntPtr data, NearCallback callback); + internal static extern void SpaceCollide(IntPtr space, IntPtr data, NearCallback callback); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSpaceCollide2"), SuppressUnmanagedCodeSecurity] - public static extern void SpaceCollide2(IntPtr space1, IntPtr space2, IntPtr data, NearCallback callback); + internal static extern void SpaceCollide2(IntPtr space1, IntPtr space2, IntPtr data, NearCallback callback); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSpaceDestroy"), SuppressUnmanagedCodeSecurity] - public static extern void SpaceDestroy(IntPtr space); + internal static extern void SpaceDestroy(IntPtr space); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSpaceGetCleanup"), SuppressUnmanagedCodeSecurity] - public static extern bool SpaceGetCleanup(IntPtr space); + internal static extern bool SpaceGetCleanup(IntPtr space); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSpaceGetNumGeoms"), SuppressUnmanagedCodeSecurity] - public static extern int SpaceGetNumGeoms(IntPtr space); + internal static extern int SpaceGetNumGeoms(IntPtr space); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSpaceGetGeom"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr SpaceGetGeom(IntPtr space, int i); + internal static extern IntPtr SpaceGetGeom(IntPtr space, int i); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSpaceGetSublevel"), SuppressUnmanagedCodeSecurity] - public static extern int SpaceGetSublevel(IntPtr space); + internal static extern int SpaceGetSublevel(IntPtr space); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSpaceQuery"), SuppressUnmanagedCodeSecurity] - public static extern bool SpaceQuery(IntPtr space, IntPtr geom); + internal static extern bool SpaceQuery(IntPtr space, IntPtr geom); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSpaceRemove"), SuppressUnmanagedCodeSecurity] - public static extern void SpaceRemove(IntPtr space, IntPtr geom); + internal static extern void SpaceRemove(IntPtr space, IntPtr geom); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSpaceSetCleanup"), SuppressUnmanagedCodeSecurity] - public static extern void SpaceSetCleanup(IntPtr space, bool mode); + internal static extern void SpaceSetCleanup(IntPtr space, bool mode); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSpaceSetSublevel"), SuppressUnmanagedCodeSecurity] - public static extern void SpaceSetSublevel(IntPtr space, int sublevel); + internal static extern void SpaceSetSublevel(IntPtr space, int sublevel); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSweepAndPruneSpaceCreate"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr SweepAndPruneSpaceCreate(IntPtr space, int AxisOrder); + internal static extern IntPtr SweepAndPruneSpaceCreate(IntPtr space, int AxisOrder); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dVectorScale"), SuppressUnmanagedCodeSecurity] - public static extern void VectorScale(out dReal a, ref dReal d, int n); + internal static extern void VectorScale(out dReal a, ref dReal d, int n); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldCreate"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr WorldCreate(); + internal static extern IntPtr WorldCreate(); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldDestroy"), SuppressUnmanagedCodeSecurity] - public static extern void WorldDestroy(IntPtr world); + internal static extern void WorldDestroy(IntPtr world); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetAutoDisableAverageSamplesCount"), SuppressUnmanagedCodeSecurity] - public static extern int WorldGetAutoDisableAverageSamplesCount(IntPtr world); + internal static extern int WorldGetAutoDisableAverageSamplesCount(IntPtr world); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetAutoDisableAngularThreshold"), SuppressUnmanagedCodeSecurity] - public static extern dReal WorldGetAutoDisableAngularThreshold(IntPtr world); + internal static extern dReal WorldGetAutoDisableAngularThreshold(IntPtr world); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetAutoDisableFlag"), SuppressUnmanagedCodeSecurity] - public static extern bool WorldGetAutoDisableFlag(IntPtr world); + internal static extern bool WorldGetAutoDisableFlag(IntPtr world); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetAutoDisableLinearThreshold"), SuppressUnmanagedCodeSecurity] - public static extern dReal WorldGetAutoDisableLinearThreshold(IntPtr world); + internal static extern dReal WorldGetAutoDisableLinearThreshold(IntPtr world); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetAutoDisableSteps"), SuppressUnmanagedCodeSecurity] - public static extern int WorldGetAutoDisableSteps(IntPtr world); + internal static extern int WorldGetAutoDisableSteps(IntPtr world); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetAutoDisableTime"), SuppressUnmanagedCodeSecurity] - public static extern dReal WorldGetAutoDisableTime(IntPtr world); + internal static extern dReal WorldGetAutoDisableTime(IntPtr world); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetAutoEnableDepthSF1"), SuppressUnmanagedCodeSecurity] - public static extern int WorldGetAutoEnableDepthSF1(IntPtr world); + internal static extern int WorldGetAutoEnableDepthSF1(IntPtr world); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetCFM"), SuppressUnmanagedCodeSecurity] - public static extern dReal WorldGetCFM(IntPtr world); + internal static extern dReal WorldGetCFM(IntPtr world); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetERP"), SuppressUnmanagedCodeSecurity] - public static extern dReal WorldGetERP(IntPtr world); + internal static extern dReal WorldGetERP(IntPtr world); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetGravity"), SuppressUnmanagedCodeSecurity] - public static extern void WorldGetGravity(IntPtr world, out Vector3 gravity); + internal static extern void WorldGetGravity(IntPtr world, out Vector3 gravity); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetGravity"), SuppressUnmanagedCodeSecurity] - public static extern void WorldGetGravity(IntPtr world, out dReal X); + internal static extern void WorldGetGravity(IntPtr world, out dReal X); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetContactMaxCorrectingVel"), SuppressUnmanagedCodeSecurity] - public static extern dReal WorldGetContactMaxCorrectingVel(IntPtr world); + internal static extern dReal WorldGetContactMaxCorrectingVel(IntPtr world); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetContactSurfaceLayer"), SuppressUnmanagedCodeSecurity] - public static extern dReal WorldGetContactSurfaceLayer(IntPtr world); + internal static extern dReal WorldGetContactSurfaceLayer(IntPtr world); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetAngularDamping"), SuppressUnmanagedCodeSecurity] - public static extern dReal WorldGetAngularDamping(IntPtr world); + internal static extern dReal WorldGetAngularDamping(IntPtr world); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetAngularDampingThreshold"), SuppressUnmanagedCodeSecurity] - public static extern dReal WorldGetAngularDampingThreshold(IntPtr world); + internal static extern dReal WorldGetAngularDampingThreshold(IntPtr world); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetLinearDamping"), SuppressUnmanagedCodeSecurity] - public static extern dReal WorldGetLinearDamping(IntPtr world); + internal static extern dReal WorldGetLinearDamping(IntPtr world); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetLinearDampingThreshold"), SuppressUnmanagedCodeSecurity] - public static extern dReal WorldGetLinearDampingThreshold(IntPtr world); + internal static extern dReal WorldGetLinearDampingThreshold(IntPtr world); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetQuickStepNumIterations"), SuppressUnmanagedCodeSecurity] - public static extern int WorldGetQuickStepNumIterations(IntPtr world); + internal static extern int WorldGetQuickStepNumIterations(IntPtr world); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetQuickStepW"), SuppressUnmanagedCodeSecurity] - public static extern dReal WorldGetQuickStepW(IntPtr world); + internal static extern dReal WorldGetQuickStepW(IntPtr world); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetMaxAngularSpeed"), SuppressUnmanagedCodeSecurity] - public static extern dReal WorldGetMaxAngularSpeed(IntPtr world); + internal static extern dReal WorldGetMaxAngularSpeed(IntPtr world); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldImpulseToForce"), SuppressUnmanagedCodeSecurity] - public static extern void WorldImpulseToForce(IntPtr world, dReal stepsize, dReal ix, dReal iy, dReal iz, out Vector3 force); + internal static extern void WorldImpulseToForce(IntPtr world, dReal stepsize, dReal ix, dReal iy, dReal iz, out Vector3 force); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldImpulseToForce"), SuppressUnmanagedCodeSecurity] - public static extern void WorldImpulseToForce(IntPtr world, dReal stepsize, dReal ix, dReal iy, dReal iz, out dReal forceX); + internal static extern void WorldImpulseToForce(IntPtr world, dReal stepsize, dReal ix, dReal iy, dReal iz, out dReal forceX); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldQuickStep"), SuppressUnmanagedCodeSecurity] - public static extern void WorldQuickStep(IntPtr world, dReal stepsize); + internal static extern void WorldQuickStep(IntPtr world, dReal stepsize); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetAngularDamping"), SuppressUnmanagedCodeSecurity] - public static extern void WorldSetAngularDamping(IntPtr world, dReal scale); + internal static extern void WorldSetAngularDamping(IntPtr world, dReal scale); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetAngularDampingThreshold"), SuppressUnmanagedCodeSecurity] - public static extern void WorldSetAngularDampingThreshold(IntPtr world, dReal threshold); + internal static extern void WorldSetAngularDampingThreshold(IntPtr world, dReal threshold); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetAutoDisableAngularThreshold"), SuppressUnmanagedCodeSecurity] - public static extern void WorldSetAutoDisableAngularThreshold(IntPtr world, dReal angular_threshold); + internal static extern void WorldSetAutoDisableAngularThreshold(IntPtr world, dReal angular_threshold); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetAutoDisableAverageSamplesCount"), SuppressUnmanagedCodeSecurity] - public static extern void WorldSetAutoDisableAverageSamplesCount(IntPtr world, int average_samples_count); + internal static extern void WorldSetAutoDisableAverageSamplesCount(IntPtr world, int average_samples_count); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetAutoDisableFlag"), SuppressUnmanagedCodeSecurity] - public static extern void WorldSetAutoDisableFlag(IntPtr world, bool do_auto_disable); + internal static extern void WorldSetAutoDisableFlag(IntPtr world, bool do_auto_disable); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetAutoDisableLinearThreshold"), SuppressUnmanagedCodeSecurity] - public static extern void WorldSetAutoDisableLinearThreshold(IntPtr world, dReal linear_threshold); + internal static extern void WorldSetAutoDisableLinearThreshold(IntPtr world, dReal linear_threshold); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetAutoDisableSteps"), SuppressUnmanagedCodeSecurity] - public static extern void WorldSetAutoDisableSteps(IntPtr world, int steps); + internal static extern void WorldSetAutoDisableSteps(IntPtr world, int steps); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetAutoDisableTime"), SuppressUnmanagedCodeSecurity] - public static extern void WorldSetAutoDisableTime(IntPtr world, dReal time); + internal static extern void WorldSetAutoDisableTime(IntPtr world, dReal time); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetAutoEnableDepthSF1"), SuppressUnmanagedCodeSecurity] - public static extern void WorldSetAutoEnableDepthSF1(IntPtr world, int autoEnableDepth); + internal static extern void WorldSetAutoEnableDepthSF1(IntPtr world, int autoEnableDepth); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetCFM"), SuppressUnmanagedCodeSecurity] - public static extern void WorldSetCFM(IntPtr world, dReal cfm); + internal static extern void WorldSetCFM(IntPtr world, dReal cfm); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetContactMaxCorrectingVel"), SuppressUnmanagedCodeSecurity] - public static extern void WorldSetContactMaxCorrectingVel(IntPtr world, dReal vel); + internal static extern void WorldSetContactMaxCorrectingVel(IntPtr world, dReal vel); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetContactSurfaceLayer"), SuppressUnmanagedCodeSecurity] - public static extern void WorldSetContactSurfaceLayer(IntPtr world, dReal depth); + internal static extern void WorldSetContactSurfaceLayer(IntPtr world, dReal depth); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetDamping"), SuppressUnmanagedCodeSecurity] - public static extern void WorldSetDamping(IntPtr world, dReal linear_scale, dReal angular_scale); + internal static extern void WorldSetDamping(IntPtr world, dReal linear_scale, dReal angular_scale); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetERP"), SuppressUnmanagedCodeSecurity] - public static extern void WorldSetERP(IntPtr world, dReal erp); + internal static extern void WorldSetERP(IntPtr world, dReal erp); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetGravity"), SuppressUnmanagedCodeSecurity] - public static extern void WorldSetGravity(IntPtr world, dReal x, dReal y, dReal z); + internal static extern void WorldSetGravity(IntPtr world, dReal x, dReal y, dReal z); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetLinearDamping"), SuppressUnmanagedCodeSecurity] - public static extern void WorldSetLinearDamping(IntPtr world, dReal scale); + internal static extern void WorldSetLinearDamping(IntPtr world, dReal scale); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetLinearDampingThreshold"), SuppressUnmanagedCodeSecurity] - public static extern void WorldSetLinearDampingThreshold(IntPtr world, dReal threshold); + internal static extern void WorldSetLinearDampingThreshold(IntPtr world, dReal threshold); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetQuickStepNumIterations"), SuppressUnmanagedCodeSecurity] - public static extern void WorldSetQuickStepNumIterations(IntPtr world, int num); + internal static extern void WorldSetQuickStepNumIterations(IntPtr world, int num); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetQuickStepW"), SuppressUnmanagedCodeSecurity] - public static extern void WorldSetQuickStepW(IntPtr world, dReal over_relaxation); + internal static extern void WorldSetQuickStepW(IntPtr world, dReal over_relaxation); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetMaxAngularSpeed"), SuppressUnmanagedCodeSecurity] - public static extern void WorldSetMaxAngularSpeed(IntPtr world, dReal max_speed); + internal static extern void WorldSetMaxAngularSpeed(IntPtr world, dReal max_speed); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldStep"), SuppressUnmanagedCodeSecurity] - public static extern void WorldStep(IntPtr world, dReal stepsize); + internal static extern void WorldStep(IntPtr world, dReal stepsize); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldStepFast1"), SuppressUnmanagedCodeSecurity] - public static extern void WorldStepFast1(IntPtr world, dReal stepsize, int maxiterations); + internal static extern void WorldStepFast1(IntPtr world, dReal stepsize, int maxiterations); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldExportDIF"), SuppressUnmanagedCodeSecurity] - public static extern void WorldExportDIF(IntPtr world, string filename, bool append, string prefix); + internal static extern void WorldExportDIF(IntPtr world, string filename, bool append, string prefix); } } diff --git a/OpenSim/Region/PhysicsModules/Ode/ODECharacter.cs b/OpenSim/Region/PhysicsModules/Ode/ODECharacter.cs index 98bfd1c01b..441aa227dd 100644 --- a/OpenSim/Region/PhysicsModules/Ode/ODECharacter.cs +++ b/OpenSim/Region/PhysicsModules/Ode/ODECharacter.cs @@ -68,7 +68,7 @@ namespace OpenSim.Region.PhysicsModule.ODE private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private Vector3 _position; - private d.Vector3 _zeroPosition; + private SafeNativeMethods.Vector3 _zeroPosition; private bool _zeroFlag = false; private bool m_lastUpdateSent = false; private Vector3 _velocity; @@ -151,7 +151,7 @@ namespace OpenSim.Region.PhysicsModule.ODE internal IntPtr Shell { get; private set; } private IntPtr Amotor = IntPtr.Zero; - private d.Mass ShellMass; + private SafeNativeMethods.Mass ShellMass; private int m_eventsubscription = 0; private CollisionEventUpdate CollisionEventsThisFrame = new CollisionEventUpdate(); @@ -569,12 +569,12 @@ namespace OpenSim.Region.PhysicsModule.ODE float yTiltComponent = -movementVector.Y * m_tiltMagnitudeWhenProjectedOnXYPlane; //m_log.Debug("[ODE CHARACTER]: changing avatar tilt"); - d.JointSetAMotorParam(Amotor, (int)dParam.LowStop, xTiltComponent); - d.JointSetAMotorParam(Amotor, (int)dParam.HiStop, xTiltComponent); // must be same as lowstop, else a different, spurious tilt is introduced - d.JointSetAMotorParam(Amotor, (int)dParam.LoStop2, yTiltComponent); - d.JointSetAMotorParam(Amotor, (int)dParam.HiStop2, yTiltComponent); // same as lowstop - d.JointSetAMotorParam(Amotor, (int)dParam.LoStop3, 0f); - d.JointSetAMotorParam(Amotor, (int)dParam.HiStop3, 0f); // same as lowstop + SafeNativeMethods.JointSetAMotorParam(Amotor, (int)dParam.LowStop, xTiltComponent); + SafeNativeMethods.JointSetAMotorParam(Amotor, (int)dParam.HiStop, xTiltComponent); // must be same as lowstop, else a different, spurious tilt is introduced + SafeNativeMethods.JointSetAMotorParam(Amotor, (int)dParam.LoStop2, yTiltComponent); + SafeNativeMethods.JointSetAMotorParam(Amotor, (int)dParam.HiStop2, yTiltComponent); // same as lowstop + SafeNativeMethods.JointSetAMotorParam(Amotor, (int)dParam.LoStop3, 0f); + SafeNativeMethods.JointSetAMotorParam(Amotor, (int)dParam.HiStop3, 0f); // same as lowstop } /// @@ -805,11 +805,11 @@ namespace OpenSim.Region.PhysicsModule.ODE if (m_pidControllerActive == false) { - _zeroPosition = d.BodyGetPosition(Body); + _zeroPosition = SafeNativeMethods.BodyGetPosition(Body); } //PidStatus = true; - d.Vector3 localpos = d.BodyGetPosition(Body); + SafeNativeMethods.Vector3 localpos = SafeNativeMethods.BodyGetPosition(Body); Vector3 localPos = new Vector3(localpos.X, localpos.Y, localpos.Z); if (!localPos.IsFinite()) @@ -824,7 +824,7 @@ namespace OpenSim.Region.PhysicsModule.ODE } Vector3 vec = Vector3.Zero; - d.Vector3 vel = d.BodyGetLinearVel(Body); + SafeNativeMethods.Vector3 vel = SafeNativeMethods.BodyGetLinearVel(Body); // m_log.DebugFormat( // "[ODE CHARACTER]: Current velocity in Move() is <{0},{1},{2}>, target {3} for {4}", @@ -848,7 +848,7 @@ namespace OpenSim.Region.PhysicsModule.ODE if (!_zeroFlag) { _zeroFlag = true; - _zeroPosition = d.BodyGetPosition(Body); + _zeroPosition = SafeNativeMethods.BodyGetPosition(Body); } if (m_pidControllerActive) @@ -858,7 +858,7 @@ namespace OpenSim.Region.PhysicsModule.ODE // Avatar to Avatar collisions // Prim to avatar collisions - d.Vector3 pos = d.BodyGetPosition(Body); + SafeNativeMethods.Vector3 pos = SafeNativeMethods.BodyGetPosition(Body); vec.X = (_target_velocity.X - vel.X) * (PID_D) + (_zeroPosition.X - pos.X) * (PID_P * 2); vec.Y = (_target_velocity.Y - vel.Y) * (PID_D) + (_zeroPosition.Y - pos.Y)* (PID_P * 2); if (flying) @@ -906,7 +906,7 @@ namespace OpenSim.Region.PhysicsModule.ODE { // We're colliding with something and we're not flying but we're moving // This means we're walking or running. - d.Vector3 pos = d.BodyGetPosition(Body); + SafeNativeMethods.Vector3 pos = SafeNativeMethods.BodyGetPosition(Body); vec.Z = (_target_velocity.Z - vel.Z) * PID_D + (_zeroPosition.Z - pos.Z) * PID_P; vec.X = ((_target_velocity.X - vel.X) / 1.2f) * PID_D; vec.Y = ((_target_velocity.Y - vel.Y) / 1.2f) * PID_D; @@ -940,7 +940,7 @@ namespace OpenSim.Region.PhysicsModule.ODE if (vec.IsFinite()) { // Apply the total force acting on this avatar - d.BodyAddForce(Body, vec.X, vec.Y, vec.Z); + SafeNativeMethods.BodyAddForce(Body, vec.X, vec.Y, vec.Z); if (!_zeroFlag) AlignAvatarTiltWithCurrentDirectionOfMovement(vec); @@ -956,7 +956,7 @@ namespace OpenSim.Region.PhysicsModule.ODE return; } - d.Vector3 newVel = d.BodyGetLinearVel(Body); + SafeNativeMethods.Vector3 newVel = SafeNativeMethods.BodyGetLinearVel(Body); if (newVel.X >= 256 || newVel.X <= 256 || newVel.Y >= 256 || newVel.Y <= 256 || newVel.Z >= 256 || newVel.Z <= 256) { // m_log.DebugFormat( @@ -972,7 +972,7 @@ namespace OpenSim.Region.PhysicsModule.ODE else newVel.Z = Util.Clamp(newVel.Z, -255f, 255f); - d.BodySetLinearVel(Body, newVel.X, newVel.Y, newVel.Z); + SafeNativeMethods.BodySetLinearVel(Body, newVel.X, newVel.Y, newVel.Z); } } @@ -985,16 +985,16 @@ namespace OpenSim.Region.PhysicsModule.ODE internal void UpdatePositionAndVelocity(List defects) { // no lock; called from Simulate() -- if you call this from elsewhere, gotta lock or do Monitor.Enter/Exit! - d.Vector3 newPos; + SafeNativeMethods.Vector3 newPos; try { - newPos = d.BodyGetPosition(Body); + newPos = SafeNativeMethods.BodyGetPosition(Body); } catch (NullReferenceException) { bad = true; defects.Add(this); - newPos = new d.Vector3(_position.X, _position.Y, _position.Z); + newPos = new SafeNativeMethods.Vector3(_position.X, _position.Y, _position.Z); base.RaiseOutOfBounds(_position); // Tells ScenePresence that there's a problem! m_log.WarnFormat("[ODE CHARACTER]: Avatar Null reference for Avatar {0}, physical actor {1}", Name, m_uuid); @@ -1031,11 +1031,11 @@ namespace OpenSim.Region.PhysicsModule.ODE else { m_lastUpdateSent = false; - d.Vector3 newVelocity; + SafeNativeMethods.Vector3 newVelocity; try { - newVelocity = d.BodyGetLinearVel(Body); + newVelocity = SafeNativeMethods.BodyGetLinearVel(Body); } catch (NullReferenceException) { @@ -1102,14 +1102,14 @@ namespace OpenSim.Region.PhysicsModule.ODE } // lock (OdeScene.UniversalColliderSyncObject) - Shell = d.CreateCapsule(_parent_scene.space, CAPSULE_RADIUS, CAPSULE_LENGTH); + Shell = SafeNativeMethods.CreateCapsule(_parent_scene.space, CAPSULE_RADIUS, CAPSULE_LENGTH); - d.GeomSetCategoryBits(Shell, (uint)m_collisionCategories); - d.GeomSetCollideBits(Shell, (uint)m_collisionFlags); + SafeNativeMethods.GeomSetCategoryBits(Shell, (uint)m_collisionCategories); + SafeNativeMethods.GeomSetCollideBits(Shell, (uint)m_collisionFlags); - d.MassSetCapsuleTotal(out ShellMass, m_mass, 2, CAPSULE_RADIUS, CAPSULE_LENGTH); - Body = d.BodyCreate(_parent_scene.world); - d.BodySetPosition(Body, npositionX, npositionY, npositionZ); + SafeNativeMethods.MassSetCapsuleTotal(out ShellMass, m_mass, 2, CAPSULE_RADIUS, CAPSULE_LENGTH); + Body = SafeNativeMethods.BodyCreate(_parent_scene.world); + SafeNativeMethods.BodySetPosition(Body, npositionX, npositionY, npositionZ); _position.X = npositionX; _position.Y = npositionY; @@ -1117,45 +1117,45 @@ namespace OpenSim.Region.PhysicsModule.ODE m_taintPosition = _position; - d.BodySetMass(Body, ref ShellMass); - d.Matrix3 m_caprot; + SafeNativeMethods.BodySetMass(Body, ref ShellMass); + SafeNativeMethods.Matrix3 m_caprot; // 90 Stand up on the cap of the capped cyllinder if (_parent_scene.IsAvCapsuleTilted) { - d.RFromAxisAndAngle(out m_caprot, 1, 0, 1, (float)(Math.PI / 2)); + SafeNativeMethods.RFromAxisAndAngle(out m_caprot, 1, 0, 1, (float)(Math.PI / 2)); } else { - d.RFromAxisAndAngle(out m_caprot, 0, 0, 1, (float)(Math.PI / 2)); + SafeNativeMethods.RFromAxisAndAngle(out m_caprot, 0, 0, 1, (float)(Math.PI / 2)); } - d.GeomSetRotation(Shell, ref m_caprot); - d.BodySetRotation(Body, ref m_caprot); + SafeNativeMethods.GeomSetRotation(Shell, ref m_caprot); + SafeNativeMethods.BodySetRotation(Body, ref m_caprot); - d.GeomSetBody(Shell, Body); + SafeNativeMethods.GeomSetBody(Shell, Body); // The purpose of the AMotor here is to keep the avatar's physical // surrogate from rotating while moving - Amotor = d.JointCreateAMotor(_parent_scene.world, IntPtr.Zero); - d.JointAttach(Amotor, Body, IntPtr.Zero); - d.JointSetAMotorMode(Amotor, dAMotorEuler); - d.JointSetAMotorNumAxes(Amotor, 3); - d.JointSetAMotorAxis(Amotor, 0, 0, 1, 0, 0); - d.JointSetAMotorAxis(Amotor, 1, 0, 0, 1, 0); - d.JointSetAMotorAxis(Amotor, 2, 0, 0, 0, 1); - d.JointSetAMotorAngle(Amotor, 0, 0); - d.JointSetAMotorAngle(Amotor, 1, 0); - d.JointSetAMotorAngle(Amotor, 2, 0); + Amotor = SafeNativeMethods.JointCreateAMotor(_parent_scene.world, IntPtr.Zero); + SafeNativeMethods.JointAttach(Amotor, Body, IntPtr.Zero); + SafeNativeMethods.JointSetAMotorMode(Amotor, dAMotorEuler); + SafeNativeMethods.JointSetAMotorNumAxes(Amotor, 3); + SafeNativeMethods.JointSetAMotorAxis(Amotor, 0, 0, 1, 0, 0); + SafeNativeMethods.JointSetAMotorAxis(Amotor, 1, 0, 0, 1, 0); + SafeNativeMethods.JointSetAMotorAxis(Amotor, 2, 0, 0, 0, 1); + SafeNativeMethods.JointSetAMotorAngle(Amotor, 0, 0); + SafeNativeMethods.JointSetAMotorAngle(Amotor, 1, 0); + SafeNativeMethods.JointSetAMotorAngle(Amotor, 2, 0); // These lowstops and high stops are effectively (no wiggle room) if (_parent_scene.IsAvCapsuleTilted) { - d.JointSetAMotorParam(Amotor, (int)dParam.LowStop, -0.000000000001f); - d.JointSetAMotorParam(Amotor, (int)dParam.LoStop3, -0.000000000001f); - d.JointSetAMotorParam(Amotor, (int)dParam.LoStop2, -0.000000000001f); - d.JointSetAMotorParam(Amotor, (int)dParam.HiStop, 0.000000000001f); - d.JointSetAMotorParam(Amotor, (int)dParam.HiStop3, 0.000000000001f); - d.JointSetAMotorParam(Amotor, (int)dParam.HiStop2, 0.000000000001f); + SafeNativeMethods.JointSetAMotorParam(Amotor, (int)dParam.LowStop, -0.000000000001f); + SafeNativeMethods.JointSetAMotorParam(Amotor, (int)dParam.LoStop3, -0.000000000001f); + SafeNativeMethods.JointSetAMotorParam(Amotor, (int)dParam.LoStop2, -0.000000000001f); + SafeNativeMethods.JointSetAMotorParam(Amotor, (int)dParam.HiStop, 0.000000000001f); + SafeNativeMethods.JointSetAMotorParam(Amotor, (int)dParam.HiStop3, 0.000000000001f); + SafeNativeMethods.JointSetAMotorParam(Amotor, (int)dParam.HiStop2, 0.000000000001f); } else { @@ -1167,18 +1167,18 @@ namespace OpenSim.Region.PhysicsModule.ODE // to be comprehended in their entirety. #endregion AlignAvatarTiltWithCurrentDirectionOfMovement(Vector3.Zero); - d.JointSetAMotorParam(Amotor, (int)dParam.LowStop, 0.08f); - d.JointSetAMotorParam(Amotor, (int)dParam.LoStop3, -0f); - d.JointSetAMotorParam(Amotor, (int)dParam.LoStop2, 0.08f); - d.JointSetAMotorParam(Amotor, (int)dParam.HiStop, 0.08f); // must be same as lowstop, else a different, spurious tilt is introduced - d.JointSetAMotorParam(Amotor, (int)dParam.HiStop3, 0f); // same as lowstop - d.JointSetAMotorParam(Amotor, (int)dParam.HiStop2, 0.08f); // same as lowstop + SafeNativeMethods.JointSetAMotorParam(Amotor, (int)dParam.LowStop, 0.08f); + SafeNativeMethods.JointSetAMotorParam(Amotor, (int)dParam.LoStop3, -0f); + SafeNativeMethods.JointSetAMotorParam(Amotor, (int)dParam.LoStop2, 0.08f); + SafeNativeMethods.JointSetAMotorParam(Amotor, (int)dParam.HiStop, 0.08f); // must be same as lowstop, else a different, spurious tilt is introduced + SafeNativeMethods.JointSetAMotorParam(Amotor, (int)dParam.HiStop3, 0f); // same as lowstop + SafeNativeMethods.JointSetAMotorParam(Amotor, (int)dParam.HiStop2, 0.08f); // same as lowstop } // Fudge factor is 1f by default, we're setting it to 0. We don't want it to Fudge or the // capped cyllinder will fall over - d.JointSetAMotorParam(Amotor, (int)dParam.FudgeFactor, 0f); - d.JointSetAMotorParam(Amotor, (int)dParam.FMax, tensor); + SafeNativeMethods.JointSetAMotorParam(Amotor, (int)dParam.FudgeFactor, 0f); + SafeNativeMethods.JointSetAMotorParam(Amotor, (int)dParam.FMax, tensor); //d.Matrix3 bodyrotation = d.BodyGetRotation(Body); //d.QfromR( @@ -1217,7 +1217,7 @@ namespace OpenSim.Region.PhysicsModule.ODE if (Amotor != IntPtr.Zero) { // Kill the Amotor - d.JointDestroy(Amotor); + SafeNativeMethods.JointDestroy(Amotor); Amotor = IntPtr.Zero; } @@ -1227,14 +1227,14 @@ namespace OpenSim.Region.PhysicsModule.ODE if (Body != IntPtr.Zero) { //kill the body - d.BodyDestroy(Body); + SafeNativeMethods.BodyDestroy(Body); Body = IntPtr.Zero; } if (Shell != IntPtr.Zero) { // lock (OdeScene.UniversalColliderSyncObject) - d.GeomDestroy(Shell); + SafeNativeMethods.GeomDestroy(Shell); _parent_scene.geom_name_map.Remove(Shell); _parent_scene.actor_name_map.Remove(Shell); @@ -1325,7 +1325,7 @@ namespace OpenSim.Region.PhysicsModule.ODE { if (Body != IntPtr.Zero) { - d.BodySetPosition(Body, m_taintPosition.X, m_taintPosition.Y, m_taintPosition.Z); + SafeNativeMethods.BodySetPosition(Body, m_taintPosition.X, m_taintPosition.Y, m_taintPosition.Z); _position = m_taintPosition; } } @@ -1337,7 +1337,7 @@ namespace OpenSim.Region.PhysicsModule.ODE // FIXME: This is not a good solution since it's subject to a race condition if a force is another // thread sets a new force while we're in this loop (since it could be obliterated by // m_taintForce = Vector3.Zero. Need to lock ProcessTaints() when we set a new tainted force. - d.BodyAddForce(Body, m_taintForce.X, m_taintForce.Y, m_taintForce.Z); + SafeNativeMethods.BodyAddForce(Body, m_taintForce.X, m_taintForce.Y, m_taintForce.Z); } m_taintForce = Vector3.Zero; diff --git a/OpenSim/Region/PhysicsModules/Ode/ODEDynamics.cs b/OpenSim/Region/PhysicsModules/Ode/ODEDynamics.cs index 7e95d7fd9c..39aea59673 100644 --- a/OpenSim/Region/PhysicsModules/Ode/ODEDynamics.cs +++ b/OpenSim/Region/PhysicsModules/Ode/ODEDynamics.cs @@ -93,7 +93,7 @@ namespace OpenSim.Region.PhysicsModule.ODE private float m_linearMotorDecayTimescale = 0; private float m_linearMotorTimescale = 0; private Vector3 m_lastLinearVelocityVector = Vector3.Zero; - private d.Vector3 m_lastPositionVector = new d.Vector3(); + private SafeNativeMethods.Vector3 m_lastPositionVector = new SafeNativeMethods.Vector3(); // private bool m_LinearMotorSetLastFrame = false; // private Vector3 m_linearMotorOffset = Vector3.Zero; @@ -611,7 +611,7 @@ namespace OpenSim.Region.PhysicsModule.ODE { m_lastLinearVelocityVector = Vector3.Zero; m_lastAngularVelocity = Vector3.Zero; - m_lastPositionVector = d.BodyGetPosition(Body); + m_lastPositionVector = SafeNativeMethods.BodyGetPosition(Body); } internal void Step(float pTimestep, OdeScene pParentScene) @@ -631,8 +631,8 @@ namespace OpenSim.Region.PhysicsModule.ODE { if (!m_linearMotorDirection.ApproxEquals(Vector3.Zero, 0.01f)) // requested m_linearMotorDirection is significant { - if (!d.BodyIsEnabled(Body)) - d.BodyEnable(Body); + if (!SafeNativeMethods.BodyIsEnabled(Body)) + SafeNativeMethods.BodyEnable(Body); // add drive to body Vector3 addAmount = m_linearMotorDirection/(m_linearMotorTimescale/pTimestep); @@ -662,7 +662,7 @@ namespace OpenSim.Region.PhysicsModule.ODE // convert requested object velocity to world-referenced vector m_dir = m_lastLinearVelocityVector; - d.Quaternion rot = d.BodyGetQuaternion(Body); + SafeNativeMethods.Quaternion rot = SafeNativeMethods.BodyGetQuaternion(Body); Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W); // rotq = rotation of object m_dir *= rotq; // apply obj rotation to velocity vector @@ -673,15 +673,15 @@ namespace OpenSim.Region.PhysicsModule.ODE Vector3 grav = Vector3.Zero; // There is some gravity, make a gravity force vector // that is applied after object velocity. - d.Mass objMass; - d.BodyGetMass(Body, out objMass); + SafeNativeMethods.Mass objMass; + SafeNativeMethods.BodyGetMass(Body, out objMass); // m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g; grav.Z = _pParentScene.gravityz * objMass.mass * (1f - m_VehicleBuoyancy); // Preserve the current Z velocity - d.Vector3 vel_now = d.BodyGetLinearVel(Body); + SafeNativeMethods.Vector3 vel_now = SafeNativeMethods.BodyGetLinearVel(Body); m_dir.Z = vel_now.Z; // Preserve the accumulated falling velocity - d.Vector3 pos = d.BodyGetPosition(Body); + SafeNativeMethods.Vector3 pos = SafeNativeMethods.BodyGetPosition(Body); // Vector3 accel = new Vector3(-(m_dir.X - m_lastLinearVelocityVector.X / 0.1f), -(m_dir.Y - m_lastLinearVelocityVector.Y / 0.1f), m_dir.Z - m_lastLinearVelocityVector.Z / 0.1f); Vector3 posChange = new Vector3(); posChange.X = pos.X - m_lastPositionVector.X; @@ -693,33 +693,33 @@ namespace OpenSim.Region.PhysicsModule.ODE if (pos.X >= (m_BlockingEndPoint.X - (float)1)) { pos.X -= posChange.X + 1; - d.BodySetPosition(Body, pos.X, pos.Y, pos.Z); + SafeNativeMethods.BodySetPosition(Body, pos.X, pos.Y, pos.Z); } if (pos.Y >= (m_BlockingEndPoint.Y - (float)1)) { pos.Y -= posChange.Y + 1; - d.BodySetPosition(Body, pos.X, pos.Y, pos.Z); + SafeNativeMethods.BodySetPosition(Body, pos.X, pos.Y, pos.Z); } if (pos.Z >= (m_BlockingEndPoint.Z - (float)1)) { pos.Z -= posChange.Z + 1; - d.BodySetPosition(Body, pos.X, pos.Y, pos.Z); + SafeNativeMethods.BodySetPosition(Body, pos.X, pos.Y, pos.Z); } if (pos.X <= 0) { pos.X += posChange.X + 1; - d.BodySetPosition(Body, pos.X, pos.Y, pos.Z); + SafeNativeMethods.BodySetPosition(Body, pos.X, pos.Y, pos.Z); } if (pos.Y <= 0) { pos.Y += posChange.Y + 1; - d.BodySetPosition(Body, pos.X, pos.Y, pos.Z); + SafeNativeMethods.BodySetPosition(Body, pos.X, pos.Y, pos.Z); } } if (pos.Z < _pParentScene.GetTerrainHeightAtXY(pos.X, pos.Y)) { pos.Z = _pParentScene.GetTerrainHeightAtXY(pos.X, pos.Y) + 2; - d.BodySetPosition(Body, pos.X, pos.Y, pos.Z); + SafeNativeMethods.BodySetPosition(Body, pos.X, pos.Y, pos.Z); } // Check if hovering @@ -748,7 +748,7 @@ namespace OpenSim.Region.PhysicsModule.ODE { if ((pos.Z - m_VhoverTargetHeight) > .2 || (pos.Z - m_VhoverTargetHeight) < -.2) { - d.BodySetPosition(Body, pos.X, pos.Y, m_VhoverTargetHeight); + SafeNativeMethods.BodySetPosition(Body, pos.X, pos.Y, m_VhoverTargetHeight); } } else @@ -815,12 +815,12 @@ namespace OpenSim.Region.PhysicsModule.ODE m_dir.Z = 0; } - m_lastPositionVector = d.BodyGetPosition(Body); + m_lastPositionVector = SafeNativeMethods.BodyGetPosition(Body); // Apply velocity - d.BodySetLinearVel(Body, m_dir.X, m_dir.Y, m_dir.Z); + SafeNativeMethods.BodySetLinearVel(Body, m_dir.X, m_dir.Y, m_dir.Z); // apply gravity force - d.BodyAddForce(Body, grav.X, grav.Y, grav.Z); + SafeNativeMethods.BodyAddForce(Body, grav.X, grav.Y, grav.Z); // apply friction @@ -841,7 +841,7 @@ namespace OpenSim.Region.PhysicsModule.ODE */ // Get what the body is doing, this includes 'external' influences - d.Vector3 angularVelocity = d.BodyGetAngularVel(Body); + SafeNativeMethods.Vector3 angularVelocity = SafeNativeMethods.BodyGetAngularVel(Body); // Vector3 angularVelocity = Vector3.Zero; if (m_angularMotorApply > 0) @@ -874,7 +874,7 @@ namespace OpenSim.Region.PhysicsModule.ODE { float VAservo = 0.2f / (m_verticalAttractionTimescale * pTimestep); // get present body rotation - d.Quaternion rot = d.BodyGetQuaternion(Body); + SafeNativeMethods.Quaternion rot = SafeNativeMethods.BodyGetQuaternion(Body); Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W); // make a vector pointing up Vector3 verterr = Vector3.Zero; @@ -923,7 +923,7 @@ namespace OpenSim.Region.PhysicsModule.ODE if (!m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f)) { - if (!d.BodyIsEnabled (Body)) d.BodyEnable (Body); + if (!SafeNativeMethods.BodyIsEnabled (Body)) SafeNativeMethods.BodyEnable (Body); } else { @@ -935,14 +935,14 @@ namespace OpenSim.Region.PhysicsModule.ODE m_lastAngularVelocity -= m_lastAngularVelocity * decayamount; // Apply to the body - d.BodySetAngularVel (Body, m_lastAngularVelocity.X, m_lastAngularVelocity.Y, m_lastAngularVelocity.Z); + SafeNativeMethods.BodySetAngularVel (Body, m_lastAngularVelocity.X, m_lastAngularVelocity.Y, m_lastAngularVelocity.Z); } //end MoveAngular internal void LimitRotation(float timestep) { - d.Quaternion rot = d.BodyGetQuaternion(Body); + SafeNativeMethods.Quaternion rot = SafeNativeMethods.BodyGetQuaternion(Body); Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W); // rotq = rotation of object - d.Quaternion m_rot = new d.Quaternion(); + SafeNativeMethods.Quaternion m_rot = new SafeNativeMethods.Quaternion(); bool changed = false; m_rot.X = rotq.X; m_rot.Y = rotq.Y; @@ -975,7 +975,7 @@ namespace OpenSim.Region.PhysicsModule.ODE changed = true; } if (changed) - d.BodySetQuaternion(Body, ref m_rot); + SafeNativeMethods.BodySetQuaternion(Body, ref m_rot); } } } diff --git a/OpenSim/Region/PhysicsModules/Ode/ODEModule.cs b/OpenSim/Region/PhysicsModules/Ode/ODEModule.cs index 22fc84d85d..2cf7baa75e 100644 --- a/OpenSim/Region/PhysicsModules/Ode/ODEModule.cs +++ b/OpenSim/Region/PhysicsModules/Ode/ODEModule.cs @@ -63,7 +63,7 @@ namespace OpenSim.Region.PhysicsModule.ODE // Initializing ODE only when a scene is created allows alternative ODE plugins to co-habit (according to // http://opensimulator.org/mantis/view.php?id=2750). - d.InitODE(); + SafeNativeMethods.InitODE(); m_scene = new OdeScene(scene, m_config, Name, Version); } diff --git a/OpenSim/Region/PhysicsModules/Ode/ODEPrim.cs b/OpenSim/Region/PhysicsModules/Ode/ODEPrim.cs index 8934330a9f..b1c3b7c0c7 100644 --- a/OpenSim/Region/PhysicsModules/Ode/ODEPrim.cs +++ b/OpenSim/Region/PhysicsModules/Ode/ODEPrim.cs @@ -212,7 +212,7 @@ namespace OpenSim.Region.PhysicsModule.ODE public IntPtr Body = IntPtr.Zero; private Vector3 _target_velocity; - private d.Mass pMass; + private SafeNativeMethods.Mass pMass; private int m_eventsubscription; private CollisionEventUpdate CollisionEventsThisFrame = new CollisionEventUpdate(); @@ -356,13 +356,13 @@ namespace OpenSim.Region.PhysicsModule.ODE if (m_assetFailed) { - d.GeomSetCategoryBits(prim_geom, 0); - d.GeomSetCollideBits(prim_geom, (uint)BadMeshAssetCollideBits); + SafeNativeMethods.GeomSetCategoryBits(prim_geom, 0); + SafeNativeMethods.GeomSetCollideBits(prim_geom, (uint)BadMeshAssetCollideBits); } else { - d.GeomSetCategoryBits(prim_geom, (uint)m_collisionCategories); - d.GeomSetCollideBits(prim_geom, (uint)m_collisionFlags); + SafeNativeMethods.GeomSetCategoryBits(prim_geom, (uint)m_collisionCategories); + SafeNativeMethods.GeomSetCollideBits(prim_geom, (uint)m_collisionFlags); } _parent_scene.geom_name_map[prim_geom] = Name; @@ -386,7 +386,7 @@ namespace OpenSim.Region.PhysicsModule.ODE { if (IsPhysical && Body != IntPtr.Zero) { - d.BodyEnable(Body); + SafeNativeMethods.BodyEnable(Body); if (m_vehicle.Type != Vehicle.TYPE_NONE) m_vehicle.Enable(Body, _parent_scene); } @@ -401,7 +401,7 @@ namespace OpenSim.Region.PhysicsModule.ODE if (IsPhysical && Body != IntPtr.Zero) { - d.BodyDisable(Body); + SafeNativeMethods.BodyDisable(Body); } } @@ -415,22 +415,22 @@ namespace OpenSim.Region.PhysicsModule.ODE if (!childPrim) { // Sets the geom to a body - Body = d.BodyCreate(_parent_scene.world); + Body = SafeNativeMethods.BodyCreate(_parent_scene.world); setMass(); - d.BodySetPosition(Body, _position.X, _position.Y, _position.Z); - d.Quaternion myrot = new d.Quaternion(); + SafeNativeMethods.BodySetPosition(Body, _position.X, _position.Y, _position.Z); + SafeNativeMethods.Quaternion myrot = new SafeNativeMethods.Quaternion(); myrot.X = _orientation.X; myrot.Y = _orientation.Y; myrot.Z = _orientation.Z; myrot.W = _orientation.W; - d.BodySetQuaternion(Body, ref myrot); - d.GeomSetBody(prim_geom, Body); + SafeNativeMethods.BodySetQuaternion(Body, ref myrot); + SafeNativeMethods.GeomSetBody(prim_geom, Body); if (m_assetFailed) { - d.GeomSetCategoryBits(prim_geom, 0); - d.GeomSetCollideBits(prim_geom, (uint)BadMeshAssetCollideBits); + SafeNativeMethods.GeomSetCategoryBits(prim_geom, 0); + SafeNativeMethods.GeomSetCollideBits(prim_geom, (uint)BadMeshAssetCollideBits); } else { @@ -438,14 +438,14 @@ namespace OpenSim.Region.PhysicsModule.ODE m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); } - d.GeomSetCategoryBits(prim_geom, (uint)m_collisionCategories); - d.GeomSetCollideBits(prim_geom, (uint)m_collisionFlags); + SafeNativeMethods.GeomSetCategoryBits(prim_geom, (uint)m_collisionCategories); + SafeNativeMethods.GeomSetCollideBits(prim_geom, (uint)m_collisionFlags); - d.BodySetAutoDisableFlag(Body, true); - d.BodySetAutoDisableSteps(Body, body_autodisable_frames); + SafeNativeMethods.BodySetAutoDisableFlag(Body, true); + SafeNativeMethods.BodySetAutoDisableSteps(Body, body_autodisable_frames); // disconnect from world gravity so we can apply buoyancy - d.BodySetGravityMode (Body, false); + SafeNativeMethods.BodySetGravityMode (Body, false); m_interpenetrationcount = 0; m_collisionscore = 0; @@ -787,8 +787,8 @@ namespace OpenSim.Region.PhysicsModule.ODE //m_log.Info("[PHYSICS]: New Mass: " + newmass.ToString()); - d.MassSetBoxTotal(out pMass, newmass, _size.X, _size.Y, _size.Z); - d.BodySetMass(Body, ref pMass); + SafeNativeMethods.MassSetBoxTotal(out pMass, newmass, _size.X, _size.Y, _size.Z); + SafeNativeMethods.BodySetMass(Body, ref pMass); } } @@ -796,7 +796,7 @@ namespace OpenSim.Region.PhysicsModule.ODE { if (Body != (IntPtr)0) { - d.BodySetAngularVel(Body, x, y, z); + SafeNativeMethods.BodySetAngularVel(Body, x, y, z); } } @@ -818,16 +818,16 @@ namespace OpenSim.Region.PhysicsModule.ODE if (m_assetFailed) { - d.GeomSetCategoryBits(prim_geom, 0); - d.GeomSetCollideBits(prim_geom, 0); + SafeNativeMethods.GeomSetCategoryBits(prim_geom, 0); + SafeNativeMethods.GeomSetCollideBits(prim_geom, 0); } else { - d.GeomSetCategoryBits(prim_geom, (uint)m_collisionCategories); - d.GeomSetCollideBits(prim_geom, (uint)m_collisionFlags); + SafeNativeMethods.GeomSetCategoryBits(prim_geom, (uint)m_collisionCategories); + SafeNativeMethods.GeomSetCollideBits(prim_geom, (uint)m_collisionFlags); } - d.BodyDestroy(Body); + SafeNativeMethods.BodyDestroy(Body); lock (childrenPrim) { if (childrenPrim.Count > 0) @@ -851,14 +851,14 @@ namespace OpenSim.Region.PhysicsModule.ODE if (m_assetFailed) { - d.GeomSetCategoryBits(prim_geom, 0); - d.GeomSetCollideBits(prim_geom, 0); + SafeNativeMethods.GeomSetCategoryBits(prim_geom, 0); + SafeNativeMethods.GeomSetCollideBits(prim_geom, 0); } else { - d.GeomSetCategoryBits(prim_geom, (uint)m_collisionCategories); - d.GeomSetCollideBits(prim_geom, (uint)m_collisionFlags); + SafeNativeMethods.GeomSetCategoryBits(prim_geom, (uint)m_collisionCategories); + SafeNativeMethods.GeomSetCollideBits(prim_geom, (uint)m_collisionFlags); } Body = IntPtr.Zero; @@ -915,10 +915,10 @@ namespace OpenSim.Region.PhysicsModule.ODE } else { - _triMeshData = d.GeomTriMeshDataCreate(); + _triMeshData = SafeNativeMethods.GeomTriMeshDataCreate(); - d.GeomTriMeshDataBuildSimple(_triMeshData, vertices, vertexStride, vertexCount, indices, indexCount, triStride); - d.GeomTriMeshDataPreprocess(_triMeshData); + SafeNativeMethods.GeomTriMeshDataBuildSimple(_triMeshData, vertices, vertexStride, vertexCount, indices, indexCount, triStride); + SafeNativeMethods.GeomTriMeshDataPreprocess(_triMeshData); m_MeshToTriMeshMap[mesh] = _triMeshData; } } @@ -926,7 +926,7 @@ namespace OpenSim.Region.PhysicsModule.ODE // _parent_scene.waitForSpaceUnlock(m_targetSpace); try { - SetGeom(d.CreateTriMesh(m_targetSpace, _triMeshData, null, null, null)); + SetGeom(SafeNativeMethods.CreateTriMesh(m_targetSpace, _triMeshData, null, null, null)); } catch (AccessViolationException) { @@ -1032,7 +1032,7 @@ Console.WriteLine("ZProcessTaints for " + Name); { if (Amotor != IntPtr.Zero) { - d.JointDestroy(Amotor); + SafeNativeMethods.JointDestroy(Amotor); Amotor = IntPtr.Zero; } } @@ -1107,7 +1107,7 @@ Console.WriteLine("ZProcessTaints for " + Name); if (Body == IntPtr.Zero) { - Body = d.BodyCreate(_parent_scene.world); + Body = SafeNativeMethods.BodyCreate(_parent_scene.world); setMass(); } @@ -1123,21 +1123,21 @@ Console.WriteLine("ZProcessTaints for " + Name); foreach (OdePrim prm in childrenPrim) { - d.Mass m2; - d.MassSetZero(out m2); - d.MassSetBoxTotal(out m2, prm.CalculateMass(), prm._size.X, prm._size.Y, prm._size.Z); + SafeNativeMethods.Mass m2; + SafeNativeMethods.MassSetZero(out m2); + SafeNativeMethods.MassSetBoxTotal(out m2, prm.CalculateMass(), prm._size.X, prm._size.Y, prm._size.Z); - d.Quaternion quat = new d.Quaternion(); + SafeNativeMethods.Quaternion quat = new SafeNativeMethods.Quaternion(); quat.W = prm._orientation.W; quat.X = prm._orientation.X; quat.Y = prm._orientation.Y; quat.Z = prm._orientation.Z; - d.Matrix3 mat = new d.Matrix3(); - d.RfromQ(out mat, ref quat); - d.MassRotate(ref m2, ref mat); - d.MassTranslate(ref m2, Position.X - prm.Position.X, Position.Y - prm.Position.Y, Position.Z - prm.Position.Z); - d.MassAdd(ref pMass, ref m2); + SafeNativeMethods.Matrix3 mat = new SafeNativeMethods.Matrix3(); + SafeNativeMethods.RfromQ(out mat, ref quat); + SafeNativeMethods.MassRotate(ref m2, ref mat); + SafeNativeMethods.MassTranslate(ref m2, Position.X - prm.Position.X, Position.Y - prm.Position.Y, Position.Z - prm.Position.Z); + SafeNativeMethods.MassAdd(ref pMass, ref m2); } foreach (OdePrim prm in childrenPrim) @@ -1148,36 +1148,36 @@ Console.WriteLine("ZProcessTaints for " + Name); //Console.WriteLine(" GeomSetCategoryBits 1: " + prm.prim_geom + " - " + (int)prm.m_collisionCategories + " for " + Name); if (prm.m_assetFailed) { - d.GeomSetCategoryBits(prm.prim_geom, 0); - d.GeomSetCollideBits(prm.prim_geom, (uint)prm.BadMeshAssetCollideBits); + SafeNativeMethods.GeomSetCategoryBits(prm.prim_geom, 0); + SafeNativeMethods.GeomSetCollideBits(prm.prim_geom, (uint)prm.BadMeshAssetCollideBits); } else { - d.GeomSetCategoryBits(prm.prim_geom, (uint)prm.m_collisionCategories); - d.GeomSetCollideBits(prm.prim_geom, (uint)prm.m_collisionFlags); + SafeNativeMethods.GeomSetCategoryBits(prm.prim_geom, (uint)prm.m_collisionCategories); + SafeNativeMethods.GeomSetCollideBits(prm.prim_geom, (uint)prm.m_collisionFlags); } - d.Quaternion quat = new d.Quaternion(); + SafeNativeMethods.Quaternion quat = new SafeNativeMethods.Quaternion(); quat.W = prm._orientation.W; quat.X = prm._orientation.X; quat.Y = prm._orientation.Y; quat.Z = prm._orientation.Z; - d.Matrix3 mat = new d.Matrix3(); - d.RfromQ(out mat, ref quat); + SafeNativeMethods.Matrix3 mat = new SafeNativeMethods.Matrix3(); + SafeNativeMethods.RfromQ(out mat, ref quat); if (Body != IntPtr.Zero) { - d.GeomSetBody(prm.prim_geom, Body); + SafeNativeMethods.GeomSetBody(prm.prim_geom, Body); prm.childPrim = true; - d.GeomSetOffsetWorldPosition(prm.prim_geom, prm.Position.X , prm.Position.Y, prm.Position.Z); + SafeNativeMethods.GeomSetOffsetWorldPosition(prm.prim_geom, prm.Position.X , prm.Position.Y, prm.Position.Z); //d.GeomSetOffsetPosition(prim.prim_geom, // (Position.X - prm.Position.X) - pMass.c.X, // (Position.Y - prm.Position.Y) - pMass.c.Y, // (Position.Z - prm.Position.Z) - pMass.c.Z); - d.GeomSetOffsetWorldRotation(prm.prim_geom, ref mat); + SafeNativeMethods.GeomSetOffsetWorldRotation(prm.prim_geom, ref mat); //d.GeomSetOffsetRotation(prm.prim_geom, ref mat); - d.MassTranslate(ref pMass, -pMass.c.X, -pMass.c.Y, -pMass.c.Z); - d.BodySetMass(Body, ref pMass); + SafeNativeMethods.MassTranslate(ref pMass, -pMass.c.X, -pMass.c.Y, -pMass.c.Z); + SafeNativeMethods.BodySetMass(Body, ref pMass); } else { @@ -1197,37 +1197,37 @@ Console.WriteLine("ZProcessTaints for " + Name); if (m_assetFailed) { - d.GeomSetCategoryBits(prim_geom, 0); - d.GeomSetCollideBits(prim_geom, (uint)BadMeshAssetCollideBits); + SafeNativeMethods.GeomSetCategoryBits(prim_geom, 0); + SafeNativeMethods.GeomSetCollideBits(prim_geom, (uint)BadMeshAssetCollideBits); } else { //Console.WriteLine("GeomSetCategoryBits 2: " + prim_geom + " - " + (int)m_collisionCategories + " for " + Name); - d.GeomSetCategoryBits(prim_geom, (uint)m_collisionCategories); + SafeNativeMethods.GeomSetCategoryBits(prim_geom, (uint)m_collisionCategories); //Console.WriteLine(" Post GeomSetCategoryBits 2"); - d.GeomSetCollideBits(prim_geom, (uint)m_collisionFlags); + SafeNativeMethods.GeomSetCollideBits(prim_geom, (uint)m_collisionFlags); } - d.Quaternion quat2 = new d.Quaternion(); + SafeNativeMethods.Quaternion quat2 = new SafeNativeMethods.Quaternion(); quat2.W = _orientation.W; quat2.X = _orientation.X; quat2.Y = _orientation.Y; quat2.Z = _orientation.Z; - d.Matrix3 mat2 = new d.Matrix3(); - d.RfromQ(out mat2, ref quat2); - d.GeomSetBody(prim_geom, Body); - d.GeomSetOffsetWorldPosition(prim_geom, Position.X - pMass.c.X, Position.Y - pMass.c.Y, Position.Z - pMass.c.Z); + SafeNativeMethods.Matrix3 mat2 = new SafeNativeMethods.Matrix3(); + SafeNativeMethods.RfromQ(out mat2, ref quat2); + SafeNativeMethods.GeomSetBody(prim_geom, Body); + SafeNativeMethods.GeomSetOffsetWorldPosition(prim_geom, Position.X - pMass.c.X, Position.Y - pMass.c.Y, Position.Z - pMass.c.Z); //d.GeomSetOffsetPosition(prim.prim_geom, // (Position.X - prm.Position.X) - pMass.c.X, // (Position.Y - prm.Position.Y) - pMass.c.Y, // (Position.Z - prm.Position.Z) - pMass.c.Z); //d.GeomSetOffsetRotation(prim_geom, ref mat2); - d.MassTranslate(ref pMass, -pMass.c.X, -pMass.c.Y, -pMass.c.Z); - d.BodySetMass(Body, ref pMass); + SafeNativeMethods.MassTranslate(ref pMass, -pMass.c.X, -pMass.c.Y, -pMass.c.Z); + SafeNativeMethods.BodySetMass(Body, ref pMass); - d.BodySetAutoDisableFlag(Body, true); - d.BodySetAutoDisableSteps(Body, body_autodisable_frames); + SafeNativeMethods.BodySetAutoDisableFlag(Body, true); + SafeNativeMethods.BodySetAutoDisableSteps(Body, body_autodisable_frames); m_interpenetrationcount = 0; m_collisionscore = 0; @@ -1240,7 +1240,7 @@ Console.WriteLine("ZProcessTaints for " + Name); createAMotor(m_angularlock); } - d.BodySetPosition(Body, Position.X, Position.Y, Position.Z); + SafeNativeMethods.BodySetPosition(Body, Position.X, Position.Y, Position.Z); if (m_vehicle.Type != Vehicle.TYPE_NONE) m_vehicle.Enable(Body, _parent_scene); @@ -1370,13 +1370,13 @@ Console.WriteLine("ZProcessTaints for " + Name); if (m_assetFailed) { - d.GeomSetCategoryBits(prim_geom, 0); - d.GeomSetCollideBits(prim_geom, 0); + SafeNativeMethods.GeomSetCategoryBits(prim_geom, 0); + SafeNativeMethods.GeomSetCollideBits(prim_geom, 0); } else { - d.GeomSetCategoryBits(prim_geom, (uint)m_collisionCategories); - d.GeomSetCollideBits(prim_geom, (uint)m_collisionFlags); + SafeNativeMethods.GeomSetCategoryBits(prim_geom, (uint)m_collisionCategories); + SafeNativeMethods.GeomSetCollideBits(prim_geom, (uint)m_collisionFlags); } if (IsPhysical) @@ -1400,21 +1400,21 @@ Console.WriteLine("ZProcessTaints for " + Name); if (m_assetFailed) { - d.GeomSetCategoryBits(prim_geom, 0); - d.GeomSetCollideBits(prim_geom, (uint)BadMeshAssetCollideBits); + SafeNativeMethods.GeomSetCategoryBits(prim_geom, 0); + SafeNativeMethods.GeomSetCollideBits(prim_geom, (uint)BadMeshAssetCollideBits); } else { - d.GeomSetCategoryBits(prim_geom, (uint)m_collisionCategories); - d.GeomSetCollideBits(prim_geom, (uint)m_collisionFlags); + SafeNativeMethods.GeomSetCategoryBits(prim_geom, (uint)m_collisionCategories); + SafeNativeMethods.GeomSetCollideBits(prim_geom, (uint)m_collisionFlags); } if (IsPhysical) { if (Body != IntPtr.Zero) { - d.BodySetLinearVel(Body, 0f, 0f, 0f); - d.BodySetForce(Body, 0, 0, 0); + SafeNativeMethods.BodySetLinearVel(Body, 0f, 0f, 0f); + SafeNativeMethods.BodySetForce(Body, 0, 0, 0); enableBodySoft(); } } @@ -1463,7 +1463,7 @@ Console.WriteLine("CreateGeom:"); try { //Console.WriteLine(" CreateGeom 1"); - SetGeom(d.CreateSphere(m_targetSpace, _size.X / 2)); + SetGeom(SafeNativeMethods.CreateSphere(m_targetSpace, _size.X / 2)); m_expectedCollisionContacts = 3; } catch (AccessViolationException) @@ -1478,7 +1478,7 @@ Console.WriteLine("CreateGeom:"); try { //Console.WriteLine(" CreateGeom 2"); - SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z)); + SetGeom(SafeNativeMethods.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z)); m_expectedCollisionContacts = 4; } catch (AccessViolationException) @@ -1494,7 +1494,7 @@ Console.WriteLine("CreateGeom:"); try { //Console.WriteLine(" CreateGeom 3"); - SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z)); + SetGeom(SafeNativeMethods.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z)); m_expectedCollisionContacts = 4; } catch (AccessViolationException) @@ -1510,7 +1510,7 @@ Console.WriteLine("CreateGeom:"); try { //Console.WriteLine(" CreateGeom 4"); - SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z)); + SetGeom(SafeNativeMethods.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z)); m_expectedCollisionContacts = 4; } catch (AccessViolationException) @@ -1536,7 +1536,7 @@ Console.WriteLine("CreateGeom:"); { _parent_scene.geom_name_map.Remove(prim_geom); _parent_scene.actor_name_map.Remove(prim_geom); - d.GeomDestroy(prim_geom); + SafeNativeMethods.GeomDestroy(prim_geom); m_expectedCollisionContacts = 0; prim_geom = IntPtr.Zero; } @@ -1593,13 +1593,13 @@ Console.WriteLine("changeadd 1"); #endif CreateGeom(m_targetSpace, mesh); - d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); - d.Quaternion myrot = new d.Quaternion(); + SafeNativeMethods.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); + SafeNativeMethods.Quaternion myrot = new SafeNativeMethods.Quaternion(); myrot.X = _orientation.X; myrot.Y = _orientation.Y; myrot.Z = _orientation.Z; myrot.W = _orientation.W; - d.GeomSetQuaternion(prim_geom, ref myrot); + SafeNativeMethods.GeomSetQuaternion(prim_geom, ref myrot); if (IsPhysical && Body == IntPtr.Zero) enableBody(); @@ -1627,14 +1627,14 @@ Console.WriteLine("changeadd 1"); { if (m_linkJoint != IntPtr.Zero) { - d.JointDestroy(m_linkJoint); + SafeNativeMethods.JointDestroy(m_linkJoint); m_linkJoint = IntPtr.Zero; } } if (Body != IntPtr.Zero) { - d.BodySetPosition(Body, _position.X, _position.Y, _position.Z); + SafeNativeMethods.BodySetPosition(Body, _position.X, _position.Y, _position.Z); if (_parent != null) { @@ -1643,12 +1643,12 @@ Console.WriteLine("changeadd 1"); { // KF: Fixed Joints were removed? Anyway - this Console.WriteLine does not show up, so routine is not used?? Console.WriteLine(" JointCreateFixed"); - m_linkJoint = d.JointCreateFixed(_parent_scene.world, _linkJointGroup); - d.JointAttach(m_linkJoint, Body, odParent.Body); - d.JointSetFixed(m_linkJoint); + m_linkJoint = SafeNativeMethods.JointCreateFixed(_parent_scene.world, _linkJointGroup); + SafeNativeMethods.JointAttach(m_linkJoint, Body, odParent.Body); + SafeNativeMethods.JointSetFixed(m_linkJoint); } } - d.BodyEnable(Body); + SafeNativeMethods.BodyEnable(Body); if (m_vehicle.Type != Vehicle.TYPE_NONE) { m_vehicle.Enable(Body, _parent_scene); @@ -1674,10 +1674,10 @@ Console.WriteLine(" JointCreateFixed"); // _parent_scene.waitForSpaceUnlock(m_targetSpace); - d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); + SafeNativeMethods.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); // _parent_scene.waitForSpaceUnlock(m_targetSpace); - d.SpaceAdd(m_targetSpace, prim_geom); + SafeNativeMethods.SpaceAdd(m_targetSpace, prim_geom); changeSelectedStatus(); @@ -1704,7 +1704,7 @@ Console.WriteLine(" JointCreateFixed"); else { //Console.WriteLine("Move " + Name); - if (!d.BodyIsEnabled (Body)) d.BodyEnable (Body); // KF add 161009 + if (!SafeNativeMethods.BodyIsEnabled (Body)) SafeNativeMethods.BodyEnable (Body); // KF add 161009 float m_mass = CalculateMass(); @@ -1746,9 +1746,9 @@ Console.WriteLine(" JointCreateFixed"); //PidStatus = true; // PhysicsVector vec = new PhysicsVector(); - d.Vector3 vel = d.BodyGetLinearVel(Body); + SafeNativeMethods.Vector3 vel = SafeNativeMethods.BodyGetLinearVel(Body); - d.Vector3 pos = d.BodyGetPosition(Body); + SafeNativeMethods.Vector3 pos = SafeNativeMethods.BodyGetPosition(Body); _target_velocity = new Vector3( (m_PIDTarget.X - pos.X) * ((PID_G - m_PIDTau) * timestep), @@ -1770,9 +1770,9 @@ Console.WriteLine(" JointCreateFixed"); //fx = (_target_velocity.X - vel.X) * (PID_D) + (_zeroPosition.X - pos.X) * (PID_P * 2); //fy = (_target_velocity.Y - vel.Y) * (PID_D) + (_zeroPosition.Y - pos.Y) * (PID_P * 2); //fz = fz + (_target_velocity.Z - vel.Z) * (PID_D) + (_zeroPosition.Z - pos.Z) * PID_P; - d.BodySetPosition(Body, m_PIDTarget.X, m_PIDTarget.Y, m_PIDTarget.Z); - d.BodySetLinearVel(Body, 0, 0, 0); - d.BodyAddForce(Body, 0, 0, fz); + SafeNativeMethods.BodySetPosition(Body, m_PIDTarget.X, m_PIDTarget.Y, m_PIDTarget.Z); + SafeNativeMethods.BodySetLinearVel(Body, 0, 0, 0); + SafeNativeMethods.BodyAddForce(Body, 0, 0, fz); return; } else @@ -1813,8 +1813,8 @@ Console.WriteLine(" JointCreateFixed"); } // Where are we, and where are we headed? - d.Vector3 pos = d.BodyGetPosition(Body); - d.Vector3 vel = d.BodyGetLinearVel(Body); + SafeNativeMethods.Vector3 pos = SafeNativeMethods.BodyGetPosition(Body); + SafeNativeMethods.Vector3 vel = SafeNativeMethods.BodyGetLinearVel(Body); // Non-Vehicles have a limited set of Hover options. // determine what our target height really is based on HoverType @@ -1856,9 +1856,9 @@ Console.WriteLine(" JointCreateFixed"); // Avatar to Avatar collisions // Prim to avatar collisions - d.BodySetPosition(Body, pos.X, pos.Y, m_targetHoverHeight); - d.BodySetLinearVel(Body, vel.X, vel.Y, 0); - d.BodyAddForce(Body, 0, 0, fz); + SafeNativeMethods.BodySetPosition(Body, pos.X, pos.Y, m_targetHoverHeight); + SafeNativeMethods.BodySetLinearVel(Body, vel.X, vel.Y, 0); + SafeNativeMethods.BodyAddForce(Body, 0, 0, fz); return; } else @@ -1884,13 +1884,13 @@ Console.WriteLine(" JointCreateFixed"); //m_taintdisable = true; //base.RaiseOutOfBounds(Position); //d.BodySetLinearVel(Body, fx, fy, 0f); - if (!d.BodyIsEnabled(Body)) + if (!SafeNativeMethods.BodyIsEnabled(Body)) { // A physical body at rest on a surface will auto-disable after a while, // this appears to re-enable it incase the surface it is upon vanishes, // and the body should fall again. - d.BodySetLinearVel(Body, 0f, 0f, 0f); - d.BodySetForce(Body, 0, 0, 0); + SafeNativeMethods.BodySetLinearVel(Body, 0f, 0f, 0f); + SafeNativeMethods.BodySetForce(Body, 0, 0, 0); enableBodySoft(); } @@ -1906,7 +1906,7 @@ Console.WriteLine(" JointCreateFixed"); fy = nmax; if (fy < nmin) fy = nmin; - d.BodyAddForce(Body, fx, fy, fz); + SafeNativeMethods.BodyAddForce(Body, fx, fy, fz); //Console.WriteLine("AddForce " + fx + "," + fy + "," + fz); } } @@ -1922,7 +1922,7 @@ Console.WriteLine(" JointCreateFixed"); private void rotate() { - d.Quaternion myrot = new d.Quaternion(); + SafeNativeMethods.Quaternion myrot = new SafeNativeMethods.Quaternion(); myrot.X = _orientation.X; myrot.Y = _orientation.Y; myrot.Z = _orientation.Z; @@ -1930,7 +1930,7 @@ Console.WriteLine(" JointCreateFixed"); if (Body != IntPtr.Zero) { // KF: If this is a root prim do BodySet - d.BodySetQuaternion(Body, ref myrot); + SafeNativeMethods.BodySetQuaternion(Body, ref myrot); if (IsPhysical) { // create or remove locks @@ -1940,7 +1940,7 @@ Console.WriteLine(" JointCreateFixed"); else { // daughter prim, do Geom set - d.GeomSetQuaternion(prim_geom, ref myrot); + SafeNativeMethods.GeomSetQuaternion(prim_geom, ref myrot); } resetCollisionAccounting(); @@ -1962,7 +1962,7 @@ Console.WriteLine(" JointCreateFixed"); m_disabled = true; if (Body != IntPtr.Zero) { - d.BodyDisable(Body); + SafeNativeMethods.BodyDisable(Body); Body = IntPtr.Zero; } @@ -2051,10 +2051,10 @@ Console.WriteLine(" JointCreateFixed"); } } - if (d.SpaceQuery(m_targetSpace, prim_geom)) + if (SafeNativeMethods.SpaceQuery(m_targetSpace, prim_geom)) { // _parent_scene.waitForSpaceUnlock(m_targetSpace); - d.SpaceRemove(m_targetSpace, prim_geom); + SafeNativeMethods.SpaceRemove(m_targetSpace, prim_geom); } RemoveGeom(); @@ -2084,13 +2084,13 @@ Console.WriteLine(" JointCreateFixed"); } CreateGeom(m_targetSpace, mesh); - d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); - d.Quaternion myrot = new d.Quaternion(); + SafeNativeMethods.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); + SafeNativeMethods.Quaternion myrot = new SafeNativeMethods.Quaternion(); myrot.X = _orientation.X; myrot.Y = _orientation.Y; myrot.Z = _orientation.Z; myrot.W = _orientation.W; - d.GeomSetQuaternion(prim_geom, ref myrot); + SafeNativeMethods.GeomSetQuaternion(prim_geom, ref myrot); //d.GeomBoxSetLengths(prim_geom, _size.X, _size.Y, _size.Z); if (IsPhysical && Body == IntPtr.Zero && !childPrim) @@ -2098,7 +2098,7 @@ Console.WriteLine(" JointCreateFixed"); // Re creates body on size. // EnableBody also does setMass() enableBody(); - d.BodyEnable(Body); + SafeNativeMethods.BodyEnable(Body); } changeSelectedStatus(); @@ -2133,10 +2133,10 @@ Console.WriteLine(" JointCreateFixed"); } if (m_assetFailed) - d.GeomSetCollideBits(prim_geom, (uint)BadMeshAssetCollideBits); + SafeNativeMethods.GeomSetCollideBits(prim_geom, (uint)BadMeshAssetCollideBits); else - d.GeomSetCollideBits(prim_geom, (uint)m_collisionFlags); + SafeNativeMethods.GeomSetCollideBits(prim_geom, (uint)m_collisionFlags); } /// /// Change prim in response to a shape taint. @@ -2190,14 +2190,14 @@ Console.WriteLine(" JointCreateFixed"); } CreateGeom(m_targetSpace, mesh); - d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); - d.Quaternion myrot = new d.Quaternion(); + SafeNativeMethods.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); + SafeNativeMethods.Quaternion myrot = new SafeNativeMethods.Quaternion(); //myrot.W = _orientation.w; myrot.W = _orientation.W; myrot.X = _orientation.X; myrot.Y = _orientation.Y; myrot.Z = _orientation.Z; - d.GeomSetQuaternion(prim_geom, ref myrot); + SafeNativeMethods.GeomSetQuaternion(prim_geom, ref myrot); //d.GeomBoxSetLengths(prim_geom, _size.X, _size.Y, _size.Z); if (IsPhysical && Body == IntPtr.Zero) @@ -2207,7 +2207,7 @@ Console.WriteLine(" JointCreateFixed"); enableBody(); if (Body != IntPtr.Zero) { - d.BodyEnable(Body); + SafeNativeMethods.BodyEnable(Body); } } @@ -2264,8 +2264,8 @@ Console.WriteLine(" JointCreateFixed"); m_taintforce = false; return; } - d.BodyEnable(Body); - d.BodyAddForce(Body, iforce.X, iforce.Y, iforce.Z); + SafeNativeMethods.BodyEnable(Body); + SafeNativeMethods.BodyAddForce(Body, iforce.X, iforce.Y, iforce.Z); } m_forcelist.Clear(); } @@ -2286,7 +2286,7 @@ Console.WriteLine(" JointCreateFixed"); { if (IsPhysical && Body != IntPtr.Zero) { - d.BodySetTorque(Body, m_taintTorque.X, m_taintTorque.Y, m_taintTorque.Z); + SafeNativeMethods.BodySetTorque(Body, m_taintTorque.X, m_taintTorque.Y, m_taintTorque.Z); } } @@ -2310,8 +2310,8 @@ Console.WriteLine(" JointCreateFixed"); { iforce = iforce + (m_angularforcelist[i] * 100); } - d.BodyEnable(Body); - d.BodyAddTorque(Body, iforce.X, iforce.Y, iforce.Z); + SafeNativeMethods.BodyEnable(Body); + SafeNativeMethods.BodyAddTorque(Body, iforce.X, iforce.Y, iforce.Z); } m_angularforcelist.Clear(); @@ -2339,7 +2339,7 @@ Console.WriteLine(" JointCreateFixed"); { if (Body != IntPtr.Zero) { - d.BodySetLinearVel(Body, m_taintVelocity.X, m_taintVelocity.Y, m_taintVelocity.Z); + SafeNativeMethods.BodySetLinearVel(Body, m_taintVelocity.X, m_taintVelocity.Y, m_taintVelocity.Z); } } @@ -2665,7 +2665,7 @@ Console.WriteLine(" JointCreateFixed"); } */ - d.AllocateODEDataForThread(0U); + SafeNativeMethods.AllocateODEDataForThread(0U); _position.X = Util.Clip(_position.X, 0.5f, _parent_scene.WorldExtents.X - 0.5f); _position.Y = Util.Clip(_position.Y, 0.5f, _parent_scene.WorldExtents.Y - 0.5f); @@ -2680,8 +2680,8 @@ Console.WriteLine(" JointCreateFixed"); if (Body != IntPtr.Zero) { - d.BodySetLinearVel(Body, 0, 0, 0); // stop it - d.BodySetPosition(Body, _position.X, _position.Y, _position.Z); + SafeNativeMethods.BodySetLinearVel(Body, 0, 0, 0); // stop it + SafeNativeMethods.BodySetPosition(Body, _position.X, _position.Y, _position.Z); } if(m_vehicle != null && m_vehicle.Type != Vehicle.TYPE_NONE) @@ -2728,11 +2728,11 @@ Console.WriteLine(" JointCreateFixed"); float m_minvelocity = 0; if (Body != IntPtr.Zero) // FIXME -> or if it is a joint { - d.Vector3 vec = d.BodyGetPosition(Body); - d.Quaternion ori = d.BodyGetQuaternion(Body); - d.Vector3 vel = d.BodyGetLinearVel(Body); - d.Vector3 rotvel = d.BodyGetAngularVel(Body); - d.Vector3 torque = d.BodyGetTorque(Body); + SafeNativeMethods.Vector3 vec = SafeNativeMethods.BodyGetPosition(Body); + SafeNativeMethods.Quaternion ori = SafeNativeMethods.BodyGetQuaternion(Body); + SafeNativeMethods.Vector3 vel = SafeNativeMethods.BodyGetLinearVel(Body); + SafeNativeMethods.Vector3 rotvel = SafeNativeMethods.BodyGetAngularVel(Body); + SafeNativeMethods.Vector3 torque = SafeNativeMethods.BodyGetTorque(Body); _torque = new Vector3(torque.X, torque.Y, torque.Z); Vector3 l_position = Vector3.Zero; Quaternion l_orientation = Quaternion.Identity; @@ -2812,11 +2812,11 @@ Console.WriteLine(" JointCreateFixed"); else Util.Clamp(l_position.Y, _parent_scene.WorldExtents.Y + 0.1f, _parent_scene.WorldExtents.Y + 2f); - d.BodySetPosition(Body, l_position.X, l_position.Y, l_position.Z); + SafeNativeMethods.BodySetPosition(Body, l_position.X, l_position.Y, l_position.Z); // stop it - d.BodySetAngularVel(Body, 0, 0, 0); - d.BodySetLinearVel(Body, 0, 0, 0); + SafeNativeMethods.BodySetAngularVel(Body, 0, 0, 0); + SafeNativeMethods.BodySetLinearVel(Body, 0, 0, 0); disableBodySoft(); _position = l_position; @@ -3009,7 +3009,7 @@ Console.WriteLine(" JointCreateFixed"); if (Amotor != IntPtr.Zero) { - d.JointDestroy(Amotor); + SafeNativeMethods.JointDestroy(Amotor); Amotor = IntPtr.Zero; } @@ -3039,19 +3039,19 @@ Console.WriteLine(" JointCreateFixed"); if(axisnum == 0) return; // stop it - d.BodySetTorque(Body, 0, 0, 0); - d.BodySetAngularVel(Body, 0, 0, 0); + SafeNativeMethods.BodySetTorque(Body, 0, 0, 0); + SafeNativeMethods.BodySetAngularVel(Body, 0, 0, 0); - Amotor = d.JointCreateAMotor(_parent_scene.world, IntPtr.Zero); - d.JointAttach(Amotor, Body, IntPtr.Zero); + Amotor = SafeNativeMethods.JointCreateAMotor(_parent_scene.world, IntPtr.Zero); + SafeNativeMethods.JointAttach(Amotor, Body, IntPtr.Zero); - d.JointSetAMotorMode(Amotor, 0); + SafeNativeMethods.JointSetAMotorMode(Amotor, 0); - d.JointSetAMotorNumAxes(Amotor, axisnum); + SafeNativeMethods.JointSetAMotorNumAxes(Amotor, axisnum); // get current orientation to lock - d.Quaternion dcur = d.BodyGetQuaternion(Body); + SafeNativeMethods.Quaternion dcur = SafeNativeMethods.BodyGetQuaternion(Body); Quaternion curr; // crap convertion between identical things curr.X = dcur.X; curr.Y = dcur.Y; @@ -3064,17 +3064,17 @@ Console.WriteLine(" JointCreateFixed"); if (axisX) { ax = (new Vector3(1, 0, 0)) * curr; // rotate world X to current local X - d.JointSetAMotorAxis(Amotor, 0, 0, ax.X, ax.Y, ax.Z); - d.JointSetAMotorAngle(Amotor, 0, 0); - d.JointSetAMotorParam(Amotor, (int)d.JointParam.LoStop, 0f); - d.JointSetAMotorParam(Amotor, (int)d.JointParam.HiStop, 0f); - d.JointSetAMotorParam(Amotor, (int)d.JointParam.Vel, 0); - d.JointSetAMotorParam(Amotor, (int)d.JointParam.FudgeFactor, 0.0001f); - d.JointSetAMotorParam(Amotor, (int)d.JointParam.Bounce, 0f); - d.JointSetAMotorParam(Amotor, (int)d.JointParam.CFM, 0f); - d.JointSetAMotorParam(Amotor, (int)d.JointParam.FMax, 5e8f); - d.JointSetAMotorParam(Amotor, (int)d.JointParam.StopCFM, 0f); - d.JointSetAMotorParam(Amotor, (int)d.JointParam.StopERP, 0.8f); + SafeNativeMethods.JointSetAMotorAxis(Amotor, 0, 0, ax.X, ax.Y, ax.Z); + SafeNativeMethods.JointSetAMotorAngle(Amotor, 0, 0); + SafeNativeMethods.JointSetAMotorParam(Amotor, (int)SafeNativeMethods.JointParam.LoStop, 0f); + SafeNativeMethods.JointSetAMotorParam(Amotor, (int)SafeNativeMethods.JointParam.HiStop, 0f); + SafeNativeMethods.JointSetAMotorParam(Amotor, (int)SafeNativeMethods.JointParam.Vel, 0); + SafeNativeMethods.JointSetAMotorParam(Amotor, (int)SafeNativeMethods.JointParam.FudgeFactor, 0.0001f); + SafeNativeMethods.JointSetAMotorParam(Amotor, (int)SafeNativeMethods.JointParam.Bounce, 0f); + SafeNativeMethods.JointSetAMotorParam(Amotor, (int)SafeNativeMethods.JointParam.CFM, 0f); + SafeNativeMethods.JointSetAMotorParam(Amotor, (int)SafeNativeMethods.JointParam.FMax, 5e8f); + SafeNativeMethods.JointSetAMotorParam(Amotor, (int)SafeNativeMethods.JointParam.StopCFM, 0f); + SafeNativeMethods.JointSetAMotorParam(Amotor, (int)SafeNativeMethods.JointParam.StopERP, 0.8f); i++; j = 256; // move to next axis set } @@ -3082,17 +3082,17 @@ Console.WriteLine(" JointCreateFixed"); if (axisY) { ax = (new Vector3(0, 1, 0)) * curr; - d.JointSetAMotorAxis(Amotor, i, 0, ax.X, ax.Y, ax.Z); - d.JointSetAMotorAngle(Amotor, i, 0); - d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.LoStop, 0f); - d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.HiStop, 0f); - d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.Vel, 0); - d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.FudgeFactor, 0.0001f); - d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.Bounce, 0f); - d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.CFM, 0f); - d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.FMax, 5e8f); - d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.StopCFM, 0f); - d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.StopERP, 0.8f); + SafeNativeMethods.JointSetAMotorAxis(Amotor, i, 0, ax.X, ax.Y, ax.Z); + SafeNativeMethods.JointSetAMotorAngle(Amotor, i, 0); + SafeNativeMethods.JointSetAMotorParam(Amotor, j + (int)SafeNativeMethods.JointParam.LoStop, 0f); + SafeNativeMethods.JointSetAMotorParam(Amotor, j + (int)SafeNativeMethods.JointParam.HiStop, 0f); + SafeNativeMethods.JointSetAMotorParam(Amotor, j + (int)SafeNativeMethods.JointParam.Vel, 0); + SafeNativeMethods.JointSetAMotorParam(Amotor, j + (int)SafeNativeMethods.JointParam.FudgeFactor, 0.0001f); + SafeNativeMethods.JointSetAMotorParam(Amotor, j + (int)SafeNativeMethods.JointParam.Bounce, 0f); + SafeNativeMethods.JointSetAMotorParam(Amotor, j + (int)SafeNativeMethods.JointParam.CFM, 0f); + SafeNativeMethods.JointSetAMotorParam(Amotor, j + (int)SafeNativeMethods.JointParam.FMax, 5e8f); + SafeNativeMethods.JointSetAMotorParam(Amotor, j + (int)SafeNativeMethods.JointParam.StopCFM, 0f); + SafeNativeMethods.JointSetAMotorParam(Amotor, j + (int)SafeNativeMethods.JointParam.StopERP, 0.8f); i++; j += 256; } @@ -3100,17 +3100,17 @@ Console.WriteLine(" JointCreateFixed"); if (axisZ) { ax = (new Vector3(0, 0, 1)) * curr; - d.JointSetAMotorAxis(Amotor, i, 0, ax.X, ax.Y, ax.Z); - d.JointSetAMotorAngle(Amotor, i, 0); - d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.LoStop, 0f); - d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.HiStop, 0f); - d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.Vel, 0); - d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.FudgeFactor, 0.0001f); - d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.Bounce, 0f); - d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.CFM, 0f); - d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.FMax, 5e8f); - d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.StopCFM, 0f); - d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.StopERP, 0.8f); + SafeNativeMethods.JointSetAMotorAxis(Amotor, i, 0, ax.X, ax.Y, ax.Z); + SafeNativeMethods.JointSetAMotorAngle(Amotor, i, 0); + SafeNativeMethods.JointSetAMotorParam(Amotor, j + (int)SafeNativeMethods.JointParam.LoStop, 0f); + SafeNativeMethods.JointSetAMotorParam(Amotor, j + (int)SafeNativeMethods.JointParam.HiStop, 0f); + SafeNativeMethods.JointSetAMotorParam(Amotor, j + (int)SafeNativeMethods.JointParam.Vel, 0); + SafeNativeMethods.JointSetAMotorParam(Amotor, j + (int)SafeNativeMethods.JointParam.FudgeFactor, 0.0001f); + SafeNativeMethods.JointSetAMotorParam(Amotor, j + (int)SafeNativeMethods.JointParam.Bounce, 0f); + SafeNativeMethods.JointSetAMotorParam(Amotor, j + (int)SafeNativeMethods.JointParam.CFM, 0f); + SafeNativeMethods.JointSetAMotorParam(Amotor, j + (int)SafeNativeMethods.JointParam.FMax, 5e8f); + SafeNativeMethods.JointSetAMotorParam(Amotor, j + (int)SafeNativeMethods.JointParam.StopCFM, 0f); + SafeNativeMethods.JointSetAMotorParam(Amotor, j + (int)SafeNativeMethods.JointParam.StopERP, 0.8f); } } diff --git a/OpenSim/Region/PhysicsModules/Ode/ODERayCastRequestManager.cs b/OpenSim/Region/PhysicsModules/Ode/ODERayCastRequestManager.cs index 78dd7de6f4..c731c6c86e 100644 --- a/OpenSim/Region/PhysicsModules/Ode/ODERayCastRequestManager.cs +++ b/OpenSim/Region/PhysicsModules/Ode/ODERayCastRequestManager.cs @@ -61,12 +61,12 @@ namespace OpenSim.Region.PhysicsModule.ODE /// /// ODE contact array to be filled by the collision testing /// - d.ContactGeom[] contacts = new d.ContactGeom[5]; + SafeNativeMethods.ContactGeom[] contacts = new SafeNativeMethods.ContactGeom[5]; /// /// ODE near callback delegate /// - private d.NearCallback nearCallback; + private SafeNativeMethods.NearCallback nearCallback; private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private List m_contactResults = new List(); @@ -179,14 +179,14 @@ namespace OpenSim.Region.PhysicsModule.ODE len = 100f; // Create the ray - IntPtr ray = d.CreateRay(m_scene.space, len); - d.GeomRaySet(ray, req.Origin.X, req.Origin.Y, req.Origin.Z, req.Normal.X, req.Normal.Y, req.Normal.Z); + IntPtr ray = SafeNativeMethods.CreateRay(m_scene.space, len); + SafeNativeMethods.GeomRaySet(ray, req.Origin.X, req.Origin.Y, req.Origin.Z, req.Normal.X, req.Normal.Y, req.Normal.Z); // Collide test - d.SpaceCollide2(m_scene.space, ray, IntPtr.Zero, nearCallback); + SafeNativeMethods.SpaceCollide2(m_scene.space, ray, IntPtr.Zero, nearCallback); // Remove Ray - d.GeomDestroy(ray); + SafeNativeMethods.GeomDestroy(ray); // Define default results bool hitYN = false; @@ -230,14 +230,14 @@ namespace OpenSim.Region.PhysicsModule.ODE len = 100f; // Create the ray - IntPtr ray = d.CreateRay(m_scene.space, len); - d.GeomRaySet(ray, req.Origin.X, req.Origin.Y, req.Origin.Z, req.Normal.X, req.Normal.Y, req.Normal.Z); + IntPtr ray = SafeNativeMethods.CreateRay(m_scene.space, len); + SafeNativeMethods.GeomRaySet(ray, req.Origin.X, req.Origin.Y, req.Origin.Z, req.Normal.X, req.Normal.Y, req.Normal.Z); // Collide test - d.SpaceCollide2(m_scene.space, ray, IntPtr.Zero, nearCallback); + SafeNativeMethods.SpaceCollide2(m_scene.space, ray, IntPtr.Zero, nearCallback); // Remove Ray - d.GeomDestroy(ray); + SafeNativeMethods.GeomDestroy(ray); // Find closest contact and object. lock (m_contactResults) @@ -258,7 +258,7 @@ namespace OpenSim.Region.PhysicsModule.ODE // return; // Raytest against AABBs of spaces first, then dig into the spaces it hits for actual geoms. - if (d.GeomIsSpace(g1) || d.GeomIsSpace(g2)) + if (SafeNativeMethods.GeomIsSpace(g1) || SafeNativeMethods.GeomIsSpace(g2)) { if (g1 == IntPtr.Zero || g2 == IntPtr.Zero) return; @@ -269,7 +269,7 @@ namespace OpenSim.Region.PhysicsModule.ODE // contact points in the space try { - d.SpaceCollide2(g1, g2, IntPtr.Zero, nearCallback); + SafeNativeMethods.SpaceCollide2(g1, g2, IntPtr.Zero, nearCallback); } catch (AccessViolationException) { @@ -296,7 +296,7 @@ namespace OpenSim.Region.PhysicsModule.ODE lock (contacts) { - count = d.Collide(g1, g2, contacts.GetLength(0), contacts, d.ContactGeom.unmanagedSizeOf); + count = SafeNativeMethods.Collide(g1, g2, contacts.GetLength(0), contacts, SafeNativeMethods.ContactGeom.unmanagedSizeOf); } } catch (SEHException) diff --git a/OpenSim/Region/PhysicsModules/Ode/OdeScene.cs b/OpenSim/Region/PhysicsModules/Ode/OdeScene.cs index d15568e4ff..e760fa258f 100644 --- a/OpenSim/Region/PhysicsModules/Ode/OdeScene.cs +++ b/OpenSim/Region/PhysicsModules/Ode/OdeScene.cs @@ -336,9 +336,7 @@ namespace OpenSim.Region.PhysicsModule.ODE private bool m_filterCollisions = true; - private d.NearCallback nearCallback; - public d.TriCallback triCallback; - public d.TriArrayCallback triArrayCallback; + private SafeNativeMethods.NearCallback nearCallback; /// /// Avatars in the physics scene. @@ -368,7 +366,7 @@ namespace OpenSim.Region.PhysicsModule.ODE /// /// Keep record of contacts in the physics loop so that we can remove duplicates. /// - private readonly List _perloopContact = new List(); + private readonly List _perloopContact = new List(); /// /// A dictionary of actors that should receive collision events. @@ -409,7 +407,7 @@ namespace OpenSim.Region.PhysicsModule.ODE private bool m_NINJA_physics_joints_enabled = false; //private Dictionary jointpart_name_map = new Dictionary(); private readonly Dictionary> joints_connecting_actor = new Dictionary>(); - private d.ContactGeom[] contacts; + private SafeNativeMethods.ContactGeom[] contacts; /// /// Lock only briefly. accessed by external code (to request new joints) and by OdeScene.Simulate() to move those joints into pending/active @@ -437,12 +435,12 @@ namespace OpenSim.Region.PhysicsModule.ODE private readonly DoubleDictionary RegionTerrain = new DoubleDictionary(); private readonly Dictionary TerrainHeightFieldHeights = new Dictionary(); - private d.Contact contact; - private d.Contact TerrainContact; - private d.Contact AvatarMovementprimContact; - private d.Contact AvatarMovementTerrainContact; - private d.Contact WaterContact; - private d.Contact[,] m_materialContacts; + private SafeNativeMethods.Contact contact; + private SafeNativeMethods.Contact TerrainContact; + private SafeNativeMethods.Contact AvatarMovementprimContact; + private SafeNativeMethods.Contact AvatarMovementTerrainContact; + private SafeNativeMethods.Contact WaterContact; + private SafeNativeMethods.Contact[,] m_materialContacts; private int m_physicsiterations = 10; private const float m_SkipFramesAtms = 0.40f; // Drop frames gracefully at a 400 ms lag @@ -480,8 +478,8 @@ namespace OpenSim.Region.PhysicsModule.ODE private bool avplanted = false; private bool av_av_collisions_off = false; - public d.Vector3 xyz = new d.Vector3(128.1640f, 128.3079f, 25.7600f); - public d.Vector3 hpr = new d.Vector3(125.5000f, -17.0000f, 0.0000f); + internal SafeNativeMethods.Vector3 xyz = new SafeNativeMethods.Vector3(128.1640f, 128.3079f, 25.7600f); + internal SafeNativeMethods.Vector3 hpr = new SafeNativeMethods.Vector3(125.5000f, -17.0000f, 0.0000f); private volatile int m_global_contactcount = 0; @@ -544,12 +542,11 @@ namespace OpenSim.Region.PhysicsModule.ODE m_rayCastManager = new ODERayCastRequestManager(this); // Create the world and the first space - world = d.WorldCreate(); - space = d.HashSpaceCreate(IntPtr.Zero); + world = SafeNativeMethods.WorldCreate(); + space = SafeNativeMethods.HashSpaceCreate(IntPtr.Zero); + contactgroup = SafeNativeMethods.JointGroupCreate(0); - contactgroup = d.JointGroupCreate(0); - - d.WorldSetAutoDisableFlag(world, false); + SafeNativeMethods.WorldSetAutoDisableFlag(world, false); } // Initialize from configs @@ -651,7 +648,7 @@ namespace OpenSim.Region.PhysicsModule.ODE } } - contacts = new d.ContactGeom[contactsPerCollision]; + contacts = new SafeNativeMethods.ContactGeom[contactsPerCollision]; spacesPerMeterX = 1.0f / metersInSpace; spacesPerMeterY = 1.0f / metersInSpace; @@ -680,7 +677,7 @@ namespace OpenSim.Region.PhysicsModule.ODE // Centeral contact friction and bounce // ckrinke 11/10/08 Enabling soft_erp but not soft_cfm until I figure out why // an avatar falls through in Z but not in X or Y when walking on a prim. - contact.surface.mode |= d.ContactFlags.SoftERP; + contact.surface.mode |= SafeNativeMethods.ContactFlags.SoftERP; contact.surface.mu = nmAvatarObjectContactFriction; contact.surface.bounce = nmAvatarObjectContactBounce; contact.surface.soft_cfm = 0.010f; @@ -689,12 +686,12 @@ namespace OpenSim.Region.PhysicsModule.ODE // Terrain contact friction and Bounce // This is the *non* moving version. Use this when an avatar // isn't moving to keep it in place better - TerrainContact.surface.mode |= d.ContactFlags.SoftERP; + TerrainContact.surface.mode |= SafeNativeMethods.ContactFlags.SoftERP; TerrainContact.surface.mu = nmTerrainContactFriction; TerrainContact.surface.bounce = nmTerrainContactBounce; TerrainContact.surface.soft_erp = nmTerrainContactERP; - WaterContact.surface.mode |= (d.ContactFlags.SoftERP | d.ContactFlags.SoftCFM); + WaterContact.surface.mode |= (SafeNativeMethods.ContactFlags.SoftERP | SafeNativeMethods.ContactFlags.SoftCFM); WaterContact.surface.mu = 0f; // No friction WaterContact.surface.bounce = 0.0f; // No bounce WaterContact.surface.soft_cfm = 0.010f; @@ -709,7 +706,7 @@ namespace OpenSim.Region.PhysicsModule.ODE // Terrain contact friction bounce and various error correcting calculations // Use this when an avatar is in contact with the terrain and moving. - AvatarMovementTerrainContact.surface.mode |= d.ContactFlags.SoftERP; + AvatarMovementTerrainContact.surface.mode |= SafeNativeMethods.ContactFlags.SoftERP; AvatarMovementTerrainContact.surface.mu = mTerrainContactFriction; AvatarMovementTerrainContact.surface.bounce = mTerrainContactBounce; AvatarMovementTerrainContact.surface.soft_erp = mTerrainContactERP; @@ -731,38 +728,38 @@ namespace OpenSim.Region.PhysicsModule.ODE Rubber = 6 */ - m_materialContacts = new d.Contact[7,2]; + m_materialContacts = new SafeNativeMethods.Contact[7,2]; - m_materialContacts[(int)Material.Stone, 0] = new d.Contact(); - m_materialContacts[(int)Material.Stone, 0].surface.mode |= d.ContactFlags.SoftERP; + m_materialContacts[(int)Material.Stone, 0] = new SafeNativeMethods.Contact(); + m_materialContacts[(int)Material.Stone, 0].surface.mode |= SafeNativeMethods.ContactFlags.SoftERP; m_materialContacts[(int)Material.Stone, 0].surface.mu = nmAvatarObjectContactFriction; m_materialContacts[(int)Material.Stone, 0].surface.bounce = nmAvatarObjectContactBounce; m_materialContacts[(int)Material.Stone, 0].surface.soft_cfm = 0.010f; m_materialContacts[(int)Material.Stone, 0].surface.soft_erp = 0.010f; - m_materialContacts[(int)Material.Stone, 1] = new d.Contact(); - m_materialContacts[(int)Material.Stone, 1].surface.mode |= d.ContactFlags.SoftERP; + m_materialContacts[(int)Material.Stone, 1] = new SafeNativeMethods.Contact(); + m_materialContacts[(int)Material.Stone, 1].surface.mode |= SafeNativeMethods.ContactFlags.SoftERP; m_materialContacts[(int)Material.Stone, 1].surface.mu = mAvatarObjectContactFriction; m_materialContacts[(int)Material.Stone, 1].surface.bounce = mAvatarObjectContactBounce; m_materialContacts[(int)Material.Stone, 1].surface.soft_cfm = 0.010f; m_materialContacts[(int)Material.Stone, 1].surface.soft_erp = 0.010f; - m_materialContacts[(int)Material.Metal, 0] = new d.Contact(); - m_materialContacts[(int)Material.Metal, 0].surface.mode |= d.ContactFlags.SoftERP; + m_materialContacts[(int)Material.Metal, 0] = new SafeNativeMethods.Contact(); + m_materialContacts[(int)Material.Metal, 0].surface.mode |= SafeNativeMethods.ContactFlags.SoftERP; m_materialContacts[(int)Material.Metal, 0].surface.mu = nmAvatarObjectContactFriction; m_materialContacts[(int)Material.Metal, 0].surface.bounce = nmAvatarObjectContactBounce; m_materialContacts[(int)Material.Metal, 0].surface.soft_cfm = 0.010f; m_materialContacts[(int)Material.Metal, 0].surface.soft_erp = 0.010f; - m_materialContacts[(int)Material.Metal, 1] = new d.Contact(); - m_materialContacts[(int)Material.Metal, 1].surface.mode |= d.ContactFlags.SoftERP; + m_materialContacts[(int)Material.Metal, 1] = new SafeNativeMethods.Contact(); + m_materialContacts[(int)Material.Metal, 1].surface.mode |= SafeNativeMethods.ContactFlags.SoftERP; m_materialContacts[(int)Material.Metal, 1].surface.mu = mAvatarObjectContactFriction; m_materialContacts[(int)Material.Metal, 1].surface.bounce = mAvatarObjectContactBounce; m_materialContacts[(int)Material.Metal, 1].surface.soft_cfm = 0.010f; m_materialContacts[(int)Material.Metal, 1].surface.soft_erp = 0.010f; - m_materialContacts[(int)Material.Glass, 0] = new d.Contact(); - m_materialContacts[(int)Material.Glass, 0].surface.mode |= d.ContactFlags.SoftERP; + m_materialContacts[(int)Material.Glass, 0] = new SafeNativeMethods.Contact(); + m_materialContacts[(int)Material.Glass, 0].surface.mode |= SafeNativeMethods.ContactFlags.SoftERP; m_materialContacts[(int)Material.Glass, 0].surface.mu = 1f; m_materialContacts[(int)Material.Glass, 0].surface.bounce = 0.5f; m_materialContacts[(int)Material.Glass, 0].surface.soft_cfm = 0.010f; @@ -775,83 +772,83 @@ namespace OpenSim.Region.PhysicsModule.ODE private float mAvatarObjectContactFriction = 75f; private float mAvatarObjectContactBounce = 0.1f; */ - m_materialContacts[(int)Material.Glass, 1] = new d.Contact(); - m_materialContacts[(int)Material.Glass, 1].surface.mode |= d.ContactFlags.SoftERP; + m_materialContacts[(int)Material.Glass, 1] = new SafeNativeMethods.Contact(); + m_materialContacts[(int)Material.Glass, 1].surface.mode |= SafeNativeMethods.ContactFlags.SoftERP; m_materialContacts[(int)Material.Glass, 1].surface.mu = 1f; m_materialContacts[(int)Material.Glass, 1].surface.bounce = 0.5f; m_materialContacts[(int)Material.Glass, 1].surface.soft_cfm = 0.010f; m_materialContacts[(int)Material.Glass, 1].surface.soft_erp = 0.010f; - m_materialContacts[(int)Material.Wood, 0] = new d.Contact(); - m_materialContacts[(int)Material.Wood, 0].surface.mode |= d.ContactFlags.SoftERP; + m_materialContacts[(int)Material.Wood, 0] = new SafeNativeMethods.Contact(); + m_materialContacts[(int)Material.Wood, 0].surface.mode |= SafeNativeMethods.ContactFlags.SoftERP; m_materialContacts[(int)Material.Wood, 0].surface.mu = nmAvatarObjectContactFriction; m_materialContacts[(int)Material.Wood, 0].surface.bounce = nmAvatarObjectContactBounce; m_materialContacts[(int)Material.Wood, 0].surface.soft_cfm = 0.010f; m_materialContacts[(int)Material.Wood, 0].surface.soft_erp = 0.010f; - m_materialContacts[(int)Material.Wood, 1] = new d.Contact(); - m_materialContacts[(int)Material.Wood, 1].surface.mode |= d.ContactFlags.SoftERP; + m_materialContacts[(int)Material.Wood, 1] = new SafeNativeMethods.Contact(); + m_materialContacts[(int)Material.Wood, 1].surface.mode |= SafeNativeMethods.ContactFlags.SoftERP; m_materialContacts[(int)Material.Wood, 1].surface.mu = mAvatarObjectContactFriction; m_materialContacts[(int)Material.Wood, 1].surface.bounce = mAvatarObjectContactBounce; m_materialContacts[(int)Material.Wood, 1].surface.soft_cfm = 0.010f; m_materialContacts[(int)Material.Wood, 1].surface.soft_erp = 0.010f; - m_materialContacts[(int)Material.Flesh, 0] = new d.Contact(); - m_materialContacts[(int)Material.Flesh, 0].surface.mode |= d.ContactFlags.SoftERP; + m_materialContacts[(int)Material.Flesh, 0] = new SafeNativeMethods.Contact(); + m_materialContacts[(int)Material.Flesh, 0].surface.mode |= SafeNativeMethods.ContactFlags.SoftERP; m_materialContacts[(int)Material.Flesh, 0].surface.mu = nmAvatarObjectContactFriction; m_materialContacts[(int)Material.Flesh, 0].surface.bounce = nmAvatarObjectContactBounce; m_materialContacts[(int)Material.Flesh, 0].surface.soft_cfm = 0.010f; m_materialContacts[(int)Material.Flesh, 0].surface.soft_erp = 0.010f; - m_materialContacts[(int)Material.Flesh, 1] = new d.Contact(); - m_materialContacts[(int)Material.Flesh, 1].surface.mode |= d.ContactFlags.SoftERP; + m_materialContacts[(int)Material.Flesh, 1] = new SafeNativeMethods.Contact(); + m_materialContacts[(int)Material.Flesh, 1].surface.mode |= SafeNativeMethods.ContactFlags.SoftERP; m_materialContacts[(int)Material.Flesh, 1].surface.mu = mAvatarObjectContactFriction; m_materialContacts[(int)Material.Flesh, 1].surface.bounce = mAvatarObjectContactBounce; m_materialContacts[(int)Material.Flesh, 1].surface.soft_cfm = 0.010f; m_materialContacts[(int)Material.Flesh, 1].surface.soft_erp = 0.010f; - m_materialContacts[(int)Material.Plastic, 0] = new d.Contact(); - m_materialContacts[(int)Material.Plastic, 0].surface.mode |= d.ContactFlags.SoftERP; + m_materialContacts[(int)Material.Plastic, 0] = new SafeNativeMethods.Contact(); + m_materialContacts[(int)Material.Plastic, 0].surface.mode |= SafeNativeMethods.ContactFlags.SoftERP; m_materialContacts[(int)Material.Plastic, 0].surface.mu = nmAvatarObjectContactFriction; m_materialContacts[(int)Material.Plastic, 0].surface.bounce = nmAvatarObjectContactBounce; m_materialContacts[(int)Material.Plastic, 0].surface.soft_cfm = 0.010f; m_materialContacts[(int)Material.Plastic, 0].surface.soft_erp = 0.010f; - m_materialContacts[(int)Material.Plastic, 1] = new d.Contact(); - m_materialContacts[(int)Material.Plastic, 1].surface.mode |= d.ContactFlags.SoftERP; + m_materialContacts[(int)Material.Plastic, 1] = new SafeNativeMethods.Contact(); + m_materialContacts[(int)Material.Plastic, 1].surface.mode |= SafeNativeMethods.ContactFlags.SoftERP; m_materialContacts[(int)Material.Plastic, 1].surface.mu = mAvatarObjectContactFriction; m_materialContacts[(int)Material.Plastic, 1].surface.bounce = mAvatarObjectContactBounce; m_materialContacts[(int)Material.Plastic, 1].surface.soft_cfm = 0.010f; m_materialContacts[(int)Material.Plastic, 1].surface.soft_erp = 0.010f; - m_materialContacts[(int)Material.Rubber, 0] = new d.Contact(); - m_materialContacts[(int)Material.Rubber, 0].surface.mode |= d.ContactFlags.SoftERP; + m_materialContacts[(int)Material.Rubber, 0] = new SafeNativeMethods.Contact(); + m_materialContacts[(int)Material.Rubber, 0].surface.mode |= SafeNativeMethods.ContactFlags.SoftERP; m_materialContacts[(int)Material.Rubber, 0].surface.mu = nmAvatarObjectContactFriction; m_materialContacts[(int)Material.Rubber, 0].surface.bounce = nmAvatarObjectContactBounce; m_materialContacts[(int)Material.Rubber, 0].surface.soft_cfm = 0.010f; m_materialContacts[(int)Material.Rubber, 0].surface.soft_erp = 0.010f; - m_materialContacts[(int)Material.Rubber, 1] = new d.Contact(); - m_materialContacts[(int)Material.Rubber, 1].surface.mode |= d.ContactFlags.SoftERP; + m_materialContacts[(int)Material.Rubber, 1] = new SafeNativeMethods.Contact(); + m_materialContacts[(int)Material.Rubber, 1].surface.mode |= SafeNativeMethods.ContactFlags.SoftERP; m_materialContacts[(int)Material.Rubber, 1].surface.mu = mAvatarObjectContactFriction; m_materialContacts[(int)Material.Rubber, 1].surface.bounce = mAvatarObjectContactBounce; m_materialContacts[(int)Material.Rubber, 1].surface.soft_cfm = 0.010f; m_materialContacts[(int)Material.Rubber, 1].surface.soft_erp = 0.010f; - d.HashSpaceSetLevels(space, HashspaceLow, HashspaceHigh); + SafeNativeMethods.HashSpaceSetLevels(space, HashspaceLow, HashspaceHigh); // Set the gravity,, don't disable things automatically (we set it explicitly on some things) - d.WorldSetGravity(world, gravityx, gravityy, gravityz); - d.WorldSetContactSurfaceLayer(world, contactsurfacelayer); + SafeNativeMethods.WorldSetGravity(world, gravityx, gravityy, gravityz); + SafeNativeMethods.WorldSetContactSurfaceLayer(world, contactsurfacelayer); - d.WorldSetLinearDamping(world, 256f); - d.WorldSetAngularDamping(world, 256f); - d.WorldSetAngularDampingThreshold(world, 256f); - d.WorldSetLinearDampingThreshold(world, 256f); - d.WorldSetMaxAngularSpeed(world, 256f); + SafeNativeMethods.WorldSetLinearDamping(world, 256f); + SafeNativeMethods.WorldSetAngularDamping(world, 256f); + SafeNativeMethods.WorldSetAngularDampingThreshold(world, 256f); + SafeNativeMethods.WorldSetLinearDampingThreshold(world, 256f); + SafeNativeMethods.WorldSetMaxAngularSpeed(world, 256f); - d.WorldSetQuickStepNumIterations(world, m_physicsiterations); + SafeNativeMethods.WorldSetQuickStepNumIterations(world, m_physicsiterations); //d.WorldSetContactMaxCorrectingVel(world, 1000.0f); for (int i = 0; i < staticPrimspace.GetLength(0); i++) @@ -877,7 +874,7 @@ namespace OpenSim.Region.PhysicsModule.ODE /// /// private int CollideGeoms( - IntPtr geom1, IntPtr geom2, int maxContacts, d.ContactGeom[] contactsArray, int contactGeomSize) + IntPtr geom1, IntPtr geom2, int maxContacts, SafeNativeMethods.ContactGeom[] contactsArray, int contactGeomSize) { int count; @@ -887,7 +884,7 @@ namespace OpenSim.Region.PhysicsModule.ODE if (CollectStats) m_nativeCollisionStartTick = Util.EnvironmentTickCount(); - count = d.Collide(geom1, geom2, maxContacts, contactsArray, contactGeomSize); + count = SafeNativeMethods.Collide(geom1, geom2, maxContacts, contactsArray, contactGeomSize); } // We do this outside the lock so that any waiting threads aren't held up, though the effect is probably @@ -913,7 +910,7 @@ namespace OpenSim.Region.PhysicsModule.ODE m_nativeCollisionStartTick = Util.EnvironmentTickCount(); } - d.SpaceCollide2(space1, space2, data, nearCallback); + SafeNativeMethods.SpaceCollide2(space1, space2, data, nearCallback); if (CollectStats && m_inCollisionTiming) { @@ -944,7 +941,7 @@ namespace OpenSim.Region.PhysicsModule.ODE // Test if we're colliding a geom with a space. // If so we have to drill down into the space recursively - if (d.GeomIsSpace(g1) || d.GeomIsSpace(g2)) + if (SafeNativeMethods.GeomIsSpace(g1) || SafeNativeMethods.GeomIsSpace(g2)) { if (g1 == IntPtr.Zero || g2 == IntPtr.Zero) return; @@ -973,8 +970,8 @@ namespace OpenSim.Region.PhysicsModule.ODE if (g1 == IntPtr.Zero || g2 == IntPtr.Zero) return; - IntPtr b1 = d.GeomGetBody(g1); - IntPtr b2 = d.GeomGetBody(g2); + IntPtr b1 = SafeNativeMethods.GeomGetBody(g1); + IntPtr b2 = SafeNativeMethods.GeomGetBody(g2); // d.GeomClassID id = d.GeomGetClass(g1); @@ -1001,10 +998,10 @@ namespace OpenSim.Region.PhysicsModule.ODE if (g1 == g2) return; // Can't collide with yourself - if (b1 != IntPtr.Zero && b2 != IntPtr.Zero && d.AreConnectedExcluding(b1, b2, d.JointType.Contact)) + if (b1 != IntPtr.Zero && b2 != IntPtr.Zero && SafeNativeMethods.AreConnectedExcluding(b1, b2, SafeNativeMethods.JointType.Contact)) return; - count = CollideGeoms(g1, g2, contacts.Length, contacts, d.ContactGeom.unmanagedSizeOf); + count = CollideGeoms(g1, g2, contacts.Length, contacts, SafeNativeMethods.ContactGeom.unmanagedSizeOf); // All code after this is only relevant if we have any collisions if (count <= 0) @@ -1052,7 +1049,7 @@ namespace OpenSim.Region.PhysicsModule.ODE for (int i = 0; i < count; i++) { - d.ContactGeom curContact = contacts[i]; + SafeNativeMethods.ContactGeom curContact = contacts[i]; if (curContact.depth > maxDepthContact.PenetrationDepth) { @@ -1129,7 +1126,7 @@ namespace OpenSim.Region.PhysicsModule.ODE curContact.depth = 0.00000003f; p2.Velocity = p2.Velocity + new Vector3(0f, 0f, 0.5f); curContact.pos = - new d.Vector3(curContact.pos.X + (p1.Size.X/2), + new SafeNativeMethods.Vector3(curContact.pos.X + (p1.Size.X/2), curContact.pos.Y + (p1.Size.Y/2), curContact.pos.Z + (p1.Size.Z/2)); character.SetPidStatus(true); @@ -1146,7 +1143,7 @@ namespace OpenSim.Region.PhysicsModule.ODE curContact.depth = 0.00000003f; p1.Velocity = p1.Velocity + new Vector3(0f, 0f, 0.5f); curContact.pos = - new d.Vector3(curContact.pos.X + (p1.Size.X/2), + new SafeNativeMethods.Vector3(curContact.pos.X + (p1.Size.X/2), curContact.pos.Y + (p1.Size.Y/2), curContact.pos.Z + (p1.Size.Z/2)); character.SetPidStatus(true); @@ -1198,7 +1195,7 @@ namespace OpenSim.Region.PhysicsModule.ODE if (m_global_contactcount < maxContactsbeforedeath) { - joint = d.JointCreateContact(world, contactgroup, ref AvatarMovementTerrainContact); + joint = SafeNativeMethods.JointCreateContact(world, contactgroup, ref AvatarMovementTerrainContact); m_global_contactcount++; } } @@ -1212,7 +1209,7 @@ namespace OpenSim.Region.PhysicsModule.ODE if (m_global_contactcount < maxContactsbeforedeath) { - joint = d.JointCreateContact(world, contactgroup, ref TerrainContact); + joint = SafeNativeMethods.JointCreateContact(world, contactgroup, ref TerrainContact); m_global_contactcount++; } } @@ -1247,7 +1244,7 @@ namespace OpenSim.Region.PhysicsModule.ODE if (m_global_contactcount < maxContactsbeforedeath) { - joint = d.JointCreateContact(world, contactgroup, ref m_materialContacts[material, movintYN]); + joint = SafeNativeMethods.JointCreateContact(world, contactgroup, ref m_materialContacts[material, movintYN]); m_global_contactcount++; } } @@ -1273,7 +1270,7 @@ namespace OpenSim.Region.PhysicsModule.ODE if (m_global_contactcount < maxContactsbeforedeath) { - joint = d.JointCreateContact(world, contactgroup, ref m_materialContacts[material, movintYN]); + joint = SafeNativeMethods.JointCreateContact(world, contactgroup, ref m_materialContacts[material, movintYN]); m_global_contactcount++; } } @@ -1307,7 +1304,7 @@ namespace OpenSim.Region.PhysicsModule.ODE if (m_global_contactcount < maxContactsbeforedeath) { - joint = d.JointCreateContact(world, contactgroup, ref WaterContact); + joint = SafeNativeMethods.JointCreateContact(world, contactgroup, ref WaterContact); m_global_contactcount++; } //m_log.Info("[PHYSICS]: Prim Water Contact" + contact.depth); @@ -1324,7 +1321,7 @@ namespace OpenSim.Region.PhysicsModule.ODE if (m_global_contactcount < maxContactsbeforedeath) { - joint = d.JointCreateContact(world, contactgroup, ref AvatarMovementprimContact); + joint = SafeNativeMethods.JointCreateContact(world, contactgroup, ref AvatarMovementprimContact); m_global_contactcount++; } } @@ -1335,7 +1332,7 @@ namespace OpenSim.Region.PhysicsModule.ODE if (m_global_contactcount < maxContactsbeforedeath) { - joint = d.JointCreateContact(world, contactgroup, ref contact); + joint = SafeNativeMethods.JointCreateContact(world, contactgroup, ref contact); m_global_contactcount++; } } @@ -1356,7 +1353,7 @@ namespace OpenSim.Region.PhysicsModule.ODE if (m_global_contactcount < maxContactsbeforedeath) { - joint = d.JointCreateContact(world, contactgroup, ref m_materialContacts[material, 0]); + joint = SafeNativeMethods.JointCreateContact(world, contactgroup, ref m_materialContacts[material, 0]); m_global_contactcount++; } } @@ -1364,7 +1361,7 @@ namespace OpenSim.Region.PhysicsModule.ODE if (m_global_contactcount < maxContactsbeforedeath && joint != IntPtr.Zero) // stack collide! { - d.JointAttach(joint, b1, b2); + SafeNativeMethods.JointAttach(joint, b1, b2); m_global_contactcount++; } } @@ -1384,7 +1381,7 @@ namespace OpenSim.Region.PhysicsModule.ODE } } - private bool checkDupe(d.ContactGeom contactGeom, int atype) + private bool checkDupe(SafeNativeMethods.ContactGeom contactGeom, int atype) { if (!m_filterCollisions) return false; @@ -1393,7 +1390,7 @@ namespace OpenSim.Region.PhysicsModule.ODE ActorTypes at = (ActorTypes)atype; - foreach (d.ContactGeom contact in _perloopContact) + foreach (SafeNativeMethods.ContactGeom contact in _perloopContact) { //if ((contact.g1 == contactGeom.g1 && contact.g2 == contactGeom.g2)) //{ @@ -1580,7 +1577,7 @@ namespace OpenSim.Region.PhysicsModule.ODE List removeprims = null; foreach (OdePrim chr in _activeprims) { - if (chr.Body != IntPtr.Zero && d.BodyIsEnabled(chr.Body) && (!chr.m_disabled)) + if (chr.Body != IntPtr.Zero && SafeNativeMethods.BodyIsEnabled(chr.Body) && (!chr.m_disabled)) { try { @@ -1706,7 +1703,7 @@ namespace OpenSim.Region.PhysicsModule.ODE public override PhysicsActor AddAvatar(string avName, Vector3 position, Vector3 velocity, Vector3 size, bool isFlying) { - d.AllocateODEDataForThread(0); + SafeNativeMethods.AllocateODEDataForThread(0); OdeCharacter newAv = new OdeCharacter( @@ -1729,7 +1726,7 @@ namespace OpenSim.Region.PhysicsModule.ODE lock (OdeLock) { - d.AllocateODEDataForThread(0); + SafeNativeMethods.AllocateODEDataForThread(0); ((OdeCharacter) actor).Destroy(); } @@ -1786,7 +1783,7 @@ namespace OpenSim.Region.PhysicsModule.ODE OdePrim newPrim; lock (OdeLock) { - d.AllocateODEDataForThread(0); + SafeNativeMethods.AllocateODEDataForThread(0); newPrim = new OdePrim(name, this, pos, siz, rot, pbs, isphysical); lock (_prims) @@ -1950,7 +1947,7 @@ namespace OpenSim.Region.PhysicsModule.ODE DoJointDeactivated(joint); if (joint.jointID != IntPtr.Zero) { - d.JointDestroy(joint.jointID); + SafeNativeMethods.JointDestroy(joint.jointID); joint.jointID = IntPtr.Zero; //DoJointErrorMessage(joint, "successfully destroyed joint " + jointName); } @@ -2115,7 +2112,7 @@ namespace OpenSim.Region.PhysicsModule.ODE public override Vector3 GetJointAnchor(PhysicsJoint joint) { Debug.Assert(joint.IsInPhysicsEngine); - d.Vector3 pos = new d.Vector3(); + SafeNativeMethods.Vector3 pos = new SafeNativeMethods.Vector3(); if (!(joint is OdePhysicsJoint)) { @@ -2127,10 +2124,10 @@ namespace OpenSim.Region.PhysicsModule.ODE switch (odeJoint.Type) { case PhysicsJointType.Ball: - d.JointGetBallAnchor(odeJoint.jointID, out pos); + SafeNativeMethods.JointGetBallAnchor(odeJoint.jointID, out pos); break; case PhysicsJointType.Hinge: - d.JointGetHingeAnchor(odeJoint.jointID, out pos); + SafeNativeMethods.JointGetHingeAnchor(odeJoint.jointID, out pos); break; } } @@ -2151,7 +2148,7 @@ namespace OpenSim.Region.PhysicsModule.ODE public override Vector3 GetJointAxis(PhysicsJoint joint) { Debug.Assert(joint.IsInPhysicsEngine); - d.Vector3 axis = new d.Vector3(); + SafeNativeMethods.Vector3 axis = new SafeNativeMethods.Vector3(); if (!(joint is OdePhysicsJoint)) { @@ -2166,7 +2163,7 @@ namespace OpenSim.Region.PhysicsModule.ODE DoJointErrorMessage(joint, "warning - axis requested for ball joint: " + joint.ObjectNameInScene); break; case PhysicsJointType.Hinge: - d.JointGetHingeAxis(odeJoint.jointID, out axis); + SafeNativeMethods.JointGetHingeAxis(odeJoint.jointID, out axis); break; } } @@ -2299,12 +2296,12 @@ namespace OpenSim.Region.PhysicsModule.ODE //{ //int adfadf = 0; //} - if (d.SpaceQuery(currentspace, geom) && currentspace != IntPtr.Zero) + if (SafeNativeMethods.SpaceQuery(currentspace, geom) && currentspace != IntPtr.Zero) { - if (d.GeomIsSpace(currentspace)) + if (SafeNativeMethods.GeomIsSpace(currentspace)) { // waitForSpaceUnlock(currentspace); - d.SpaceRemove(currentspace, geom); + SafeNativeMethods.SpaceRemove(currentspace, geom); } else { @@ -2314,13 +2311,13 @@ namespace OpenSim.Region.PhysicsModule.ODE } else { - IntPtr sGeomIsIn = d.GeomGetSpace(geom); + IntPtr sGeomIsIn = SafeNativeMethods.GeomGetSpace(geom); if (sGeomIsIn != IntPtr.Zero) { - if (d.GeomIsSpace(currentspace)) + if (SafeNativeMethods.GeomIsSpace(currentspace)) { // waitForSpaceUnlock(sGeomIsIn); - d.SpaceRemove(sGeomIsIn, geom); + SafeNativeMethods.SpaceRemove(sGeomIsIn, geom); } else { @@ -2331,13 +2328,13 @@ namespace OpenSim.Region.PhysicsModule.ODE } //If there are no more geometries in the sub-space, we don't need it in the main space anymore - if (d.SpaceGetNumGeoms(currentspace) == 0) + if (SafeNativeMethods.SpaceGetNumGeoms(currentspace) == 0) { if (currentspace != IntPtr.Zero) { - if (d.GeomIsSpace(currentspace)) + if (SafeNativeMethods.GeomIsSpace(currentspace)) { - d.SpaceRemove(space, currentspace); + SafeNativeMethods.SpaceRemove(space, currentspace); // free up memory used by the space. resetSpaceArrayItemToZero(currentspace); @@ -2355,12 +2352,12 @@ namespace OpenSim.Region.PhysicsModule.ODE // this is a physical object that got disabled. ;.; if (currentspace != IntPtr.Zero && geom != IntPtr.Zero) { - if (d.SpaceQuery(currentspace, geom)) + if (SafeNativeMethods.SpaceQuery(currentspace, geom)) { - if (d.GeomIsSpace(currentspace)) + if (SafeNativeMethods.GeomIsSpace(currentspace)) { // waitForSpaceUnlock(currentspace); - d.SpaceRemove(currentspace, geom); + SafeNativeMethods.SpaceRemove(currentspace, geom); } else { @@ -2370,13 +2367,13 @@ namespace OpenSim.Region.PhysicsModule.ODE } else { - IntPtr sGeomIsIn = d.GeomGetSpace(geom); + IntPtr sGeomIsIn = SafeNativeMethods.GeomGetSpace(geom); if (sGeomIsIn != IntPtr.Zero) { - if (d.GeomIsSpace(sGeomIsIn)) + if (SafeNativeMethods.GeomIsSpace(sGeomIsIn)) { // waitForSpaceUnlock(sGeomIsIn); - d.SpaceRemove(sGeomIsIn, geom); + SafeNativeMethods.SpaceRemove(sGeomIsIn, geom); } else { @@ -2397,7 +2394,7 @@ namespace OpenSim.Region.PhysicsModule.ODE if (newspace == IntPtr.Zero) { newspace = createprimspace(iprimspaceArrItem[0], iprimspaceArrItem[1]); - d.HashSpaceSetLevels(newspace, HashspaceLow, HashspaceHigh); + SafeNativeMethods.HashSpaceSetLevels(newspace, HashspaceLow, HashspaceHigh); } return newspace; @@ -2412,11 +2409,11 @@ namespace OpenSim.Region.PhysicsModule.ODE internal IntPtr createprimspace(int iprimspaceArrItemX, int iprimspaceArrItemY) { // creating a new space for prim and inserting it into main space. - staticPrimspace[iprimspaceArrItemX, iprimspaceArrItemY] = d.HashSpaceCreate(IntPtr.Zero); - d.GeomSetCategoryBits(staticPrimspace[iprimspaceArrItemX, iprimspaceArrItemY], (int)CollisionCategories.Space); + staticPrimspace[iprimspaceArrItemX, iprimspaceArrItemY] = SafeNativeMethods.HashSpaceCreate(IntPtr.Zero); + SafeNativeMethods.GeomSetCategoryBits(staticPrimspace[iprimspaceArrItemX, iprimspaceArrItemY], (int)CollisionCategories.Space); // waitForSpaceUnlock(space); - d.SpaceSetSublevel(space, 1); - d.SpaceAdd(space, staticPrimspace[iprimspaceArrItemX, iprimspaceArrItemY]); + SafeNativeMethods.SpaceSetSublevel(space, 1); + SafeNativeMethods.SpaceAdd(space, staticPrimspace[iprimspaceArrItemX, iprimspaceArrItemY]); return staticPrimspace[iprimspaceArrItemX, iprimspaceArrItemY]; } @@ -2636,7 +2633,7 @@ namespace OpenSim.Region.PhysicsModule.ODE m_log.InfoFormat("[Ode] start processing pending actor operations"); int tstart = Util.EnvironmentTickCount(); - d.AllocateODEDataForThread(0); + SafeNativeMethods.AllocateODEDataForThread(0); lock (_taintedPrims) { @@ -2719,7 +2716,7 @@ namespace OpenSim.Region.PhysicsModule.ODE lock (OdeLock) { - d.AllocateODEDataForThread(~0U); + SafeNativeMethods.AllocateODEDataForThread(~0U); while (step_time > HalfOdeStep) { @@ -2871,12 +2868,12 @@ namespace OpenSim.Region.PhysicsModule.ODE } lock(SimulationLock) - d.WorldQuickStep(world, ODE_STEPSIZE); + SafeNativeMethods.WorldQuickStep(world, ODE_STEPSIZE); if (CollectStats) m_stats[ODENativeStepFrameMsStatName] += Util.EnvironmentTickCountSubtract(tempTick); - d.JointGroupEmpty(contactgroup); + SafeNativeMethods.JointGroupEmpty(contactgroup); } catch (Exception e) { @@ -2924,7 +2921,7 @@ namespace OpenSim.Region.PhysicsModule.ODE foreach (OdePrim prim in _activeprims) { - if (prim.IsPhysical && (d.BodyIsEnabled(prim.Body) || !prim._zeroFlag)) + if (prim.IsPhysical && (SafeNativeMethods.BodyIsEnabled(prim.Body) || !prim._zeroFlag)) { prim.UpdatePositionAndVelocity(); @@ -2954,7 +2951,7 @@ namespace OpenSim.Region.PhysicsModule.ODE fwriter.Close(); } - d.WorldExportDIF(world, fname, physics_logging_append_existing_logfile, prefix); + SafeNativeMethods.WorldExportDIF(world, fname, physics_logging_append_existing_logfile, prefix); } latertickcount = Util.EnvironmentTickCountSubtract(tickCountFrameRun); @@ -3069,11 +3066,11 @@ namespace OpenSim.Region.PhysicsModule.ODE { IntPtr odeJoint; //DoJointErrorMessage(joint, "ODE creating ball joint "); - odeJoint = d.JointCreateBall(world, IntPtr.Zero); + odeJoint = SafeNativeMethods.JointCreateBall(world, IntPtr.Zero); //DoJointErrorMessage(joint, "ODE attaching ball joint: " + odeJoint + " with b1:" + jointBodies[0] + " b2:" + jointBodies[1]); - d.JointAttach(odeJoint, jointBodies[0], jointBodies[1]); + SafeNativeMethods.JointAttach(odeJoint, jointBodies[0], jointBodies[1]); //DoJointErrorMessage(joint, "ODE setting ball anchor: " + odeJoint + " to vec:" + joint.Position); - d.JointSetBallAnchor(odeJoint, + SafeNativeMethods.JointSetBallAnchor(odeJoint, joint.Position.X, joint.Position.Y, joint.Position.Z); @@ -3097,11 +3094,11 @@ namespace OpenSim.Region.PhysicsModule.ODE { IntPtr odeJoint; //DoJointErrorMessage(joint, "ODE creating hinge joint "); - odeJoint = d.JointCreateHinge(world, IntPtr.Zero); + odeJoint = SafeNativeMethods.JointCreateHinge(world, IntPtr.Zero); //DoJointErrorMessage(joint, "ODE attaching hinge joint: " + odeJoint + " with b1:" + jointBodies[0] + " b2:" + jointBodies[1]); - d.JointAttach(odeJoint, jointBodies[0], jointBodies[1]); + SafeNativeMethods.JointAttach(odeJoint, jointBodies[0], jointBodies[1]); //DoJointErrorMessage(joint, "ODE setting hinge anchor: " + odeJoint + " to vec:" + joint.Position); - d.JointSetHingeAnchor(odeJoint, + SafeNativeMethods.JointSetHingeAnchor(odeJoint, joint.Position.X, joint.Position.Y, joint.Position.Z); @@ -3137,7 +3134,7 @@ namespace OpenSim.Region.PhysicsModule.ODE Vector3 jointAxis = Vector3.Transform(Vector3.UnitX, proxyFrame); //m_log.Debug("PHY: making axis: hinge joint axis is " + jointAxis); //DoJointErrorMessage(joint, "ODE setting hinge axis: " + odeJoint + " to vec:" + jointAxis); - d.JointSetHingeAxis(odeJoint, + SafeNativeMethods.JointSetHingeAxis(odeJoint, jointAxis.X, jointAxis.Y, jointAxis.Z); @@ -3299,7 +3296,7 @@ namespace OpenSim.Region.PhysicsModule.ODE lock (OdeLock) { - d.AllocateODEDataForThread(~0U); + SafeNativeMethods.AllocateODEDataForThread(~0U); IntPtr GroundGeom = IntPtr.Zero; if (RegionTerrain.TryGetValue(pOffset, out GroundGeom)) @@ -3311,29 +3308,29 @@ namespace OpenSim.Region.PhysicsModule.ODE { TerrainHeightFieldHeights.Remove(GroundGeom); } - d.SpaceRemove(space, GroundGeom); - d.GeomDestroy(GroundGeom); + SafeNativeMethods.SpaceRemove(space, GroundGeom); + SafeNativeMethods.GeomDestroy(GroundGeom); } } - IntPtr HeightmapData = d.GeomHeightfieldDataCreate(); - d.GeomHeightfieldDataBuildSingle(HeightmapData, _heightmap, 0, + IntPtr HeightmapData = SafeNativeMethods.GeomHeightfieldDataCreate(); + SafeNativeMethods.GeomHeightfieldDataBuildSingle(HeightmapData, _heightmap, 0, heightmapWidth, heightmapHeight, (int)heightmapWidthSamples, (int)heightmapHeightSamples, scale, offset, thickness, wrap); - d.GeomHeightfieldDataSetBounds(HeightmapData, hfmin - 1, hfmax + 1); - GroundGeom = d.CreateHeightfield(space, HeightmapData, 1); + SafeNativeMethods.GeomHeightfieldDataSetBounds(HeightmapData, hfmin - 1, hfmax + 1); + GroundGeom = SafeNativeMethods.CreateHeightfield(space, HeightmapData, 1); if (GroundGeom != IntPtr.Zero) { - d.GeomSetCategoryBits(GroundGeom, (int)(CollisionCategories.Land)); - d.GeomSetCollideBits(GroundGeom, (int)(CollisionCategories.Space)); + SafeNativeMethods.GeomSetCategoryBits(GroundGeom, (int)(CollisionCategories.Land)); + SafeNativeMethods.GeomSetCollideBits(GroundGeom, (int)(CollisionCategories.Space)); } geom_name_map[GroundGeom] = "Terrain"; - d.Matrix3 R = new d.Matrix3(); + SafeNativeMethods.Matrix3 R = new SafeNativeMethods.Matrix3(); Quaternion q1 = Quaternion.CreateFromAxisAngle(new Vector3(1, 0, 0), 1.5707f); Quaternion q2 = Quaternion.CreateFromAxisAngle(new Vector3(0, 1, 0), 1.5707f); @@ -3343,9 +3340,9 @@ namespace OpenSim.Region.PhysicsModule.ODE float angle; q1.GetAxisAngle(out v3, out angle); - d.RFromAxisAndAngle(out R, v3.X, v3.Y, v3.Z, angle); - d.GeomSetRotation(GroundGeom, ref R); - d.GeomSetPosition(GroundGeom, pOffset.X + regionsizeX * 0.5f, pOffset.Y + regionsizeY * 0.5f, 0.0f); + SafeNativeMethods.RFromAxisAndAngle(out R, v3.X, v3.Y, v3.Z, angle); + SafeNativeMethods.GeomSetRotation(GroundGeom, ref R); + SafeNativeMethods.GeomSetPosition(GroundGeom, pOffset.X + regionsizeX * 0.5f, pOffset.Y + regionsizeY * 0.5f, 0.0f); IntPtr testGround = IntPtr.Zero; if (RegionTerrain.TryGetValue(pOffset, out testGround)) { @@ -3384,7 +3381,7 @@ namespace OpenSim.Region.PhysicsModule.ODE _worldInitialized = false; - d.AllocateODEDataForThread(~0U); + SafeNativeMethods.AllocateODEDataForThread(~0U); if (m_rayCastManager != null) { @@ -3412,13 +3409,13 @@ namespace OpenSim.Region.PhysicsModule.ODE { if (TerrainHeightFieldHeights.ContainsKey(GroundGeom)) TerrainHeightFieldHeights.Remove(GroundGeom); - d.GeomDestroy(GroundGeom); + SafeNativeMethods.GeomDestroy(GroundGeom); } } try { - d.WorldDestroy(world); + SafeNativeMethods.WorldDestroy(world); world = IntPtr.Zero; } catch (AccessViolationException e) diff --git a/OpenSim/Region/PhysicsModules/SharedBase/PhysicsActor.cs b/OpenSim/Region/PhysicsModules/SharedBase/PhysicsActor.cs index 33f033759b..2fa98b579e 100644 --- a/OpenSim/Region/PhysicsModules/SharedBase/PhysicsActor.cs +++ b/OpenSim/Region/PhysicsModules/SharedBase/PhysicsActor.cs @@ -256,6 +256,7 @@ namespace OpenSim.Region.PhysicsModules.SharedBase /// public string SOPName; + public virtual void CrossingStart() { } public abstract void CrossingFailure(); public abstract void link(PhysicsActor obj); @@ -462,6 +463,23 @@ namespace OpenSim.Region.PhysicsModules.SharedBase public abstract bool SubscribedEvents(); public virtual void AddCollisionEvent(uint CollidedWith, ContactPoint contact) { } + public virtual void AddVDTCCollisionEvent(uint CollidedWith, ContactPoint contact) { } + + public virtual PhysicsInertiaData GetInertiaData() + { + PhysicsInertiaData data = new PhysicsInertiaData(); + data.TotalMass = this.Mass; + data.CenterOfMass = CenterOfMass - Position; + data.Inertia = Vector3.Zero; + data.InertiaRotation = Vector4.Zero; + return data; + } + + public virtual void SetInertiaData(PhysicsInertiaData inertia) + { + } + + public virtual float SimulationSuspended { get; set; } // Warning in a parent part it returns itself, not null public virtual PhysicsActor ParentActor { get { return this; } } diff --git a/OpenSim/Region/PhysicsModules/ubOde/ODEApi.cs b/OpenSim/Region/PhysicsModules/ubOde/ODEApi.cs index 35adf11ff1..42ad39165b 100644 --- a/OpenSim/Region/PhysicsModules/ubOde/ODEApi.cs +++ b/OpenSim/Region/PhysicsModules/ubOde/ODEApi.cs @@ -44,7 +44,7 @@ using System; using System.Runtime.InteropServices; using System.Security; using OMV = OpenMetaverse; -namespace OdeAPI +namespace OpenSim.Region.PhysicsModule.ubOde { //#if dDOUBLE // don't see much use in double precision with time steps of 20ms and 10 iterations used on opensim @@ -54,18 +54,19 @@ namespace OdeAPI using dReal = System.Single; //#endif - public static class d + [SuppressUnmanagedCodeSecurityAttribute] + internal static class SafeNativeMethods { - public static dReal Infinity = dReal.MaxValue; - public static int NTotalBodies = 0; - public static int NTotalGeoms = 0; + internal static dReal Infinity = dReal.MaxValue; + internal static int NTotalBodies = 0; + internal static int NTotalGeoms = 0; - public const uint CONTACTS_UNIMPORTANT = 0x80000000; + internal const uint CONTACTS_UNIMPORTANT = 0x80000000; #region Flags and Enumerations [Flags] - public enum AllocateODEDataFlags : uint + internal enum AllocateODEDataFlags : uint { BasicData = 0, CollisionData = 0x00000001, @@ -73,13 +74,13 @@ namespace OdeAPI } [Flags] - public enum IniteODEFlags : uint + internal enum IniteODEFlags : uint { dInitFlagManualThreadCleanup = 0x00000001 } [Flags] - public enum ContactFlags : int + internal enum ContactFlags : int { Mu2 = 0x001, FDir1 = 0x002, @@ -97,7 +98,7 @@ namespace OdeAPI Approx1 = 0x3000 } - public enum GeomClassID : int + internal enum GeomClassID : int { SphereClass, BoxClass, @@ -121,7 +122,7 @@ namespace OdeAPI MaxUserClasses = 5 } - public enum JointType : int + internal enum JointType : int { None, Ball, @@ -137,7 +138,7 @@ namespace OdeAPI Plane2D } - public enum JointParam : int + internal enum JointParam : int { LoStop, HiStop, @@ -174,7 +175,7 @@ namespace OdeAPI SuspensionCFM3 } - public enum dSweepAndPruneAxis : int + internal enum dSweepAndPruneAxis : int { XYZ = ((0)|(1<<2)|(2<<4)), XZY = ((0)|(2<<2)|(1<<4)), @@ -189,126 +190,126 @@ namespace OdeAPI #region Callbacks [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate int AABBTestFn(IntPtr o1, IntPtr o2, ref AABB aabb); + internal delegate int AABBTestFn(IntPtr o1, IntPtr o2, ref AABB aabb); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate int ColliderFn(IntPtr o1, IntPtr o2, int flags, out ContactGeom contact, int skip); + internal delegate int ColliderFn(IntPtr o1, IntPtr o2, int flags, out ContactGeom contact, int skip); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate void GetAABBFn(IntPtr geom, out AABB aabb); + internal delegate void GetAABBFn(IntPtr geom, out AABB aabb); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate ColliderFn GetColliderFnFn(int num); + internal delegate ColliderFn GetColliderFnFn(int num); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate void GeomDtorFn(IntPtr o); + internal delegate void GeomDtorFn(IntPtr o); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate dReal HeightfieldGetHeight(IntPtr p_user_data, int x, int z); + internal delegate dReal HeightfieldGetHeight(IntPtr p_user_data, int x, int z); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate dReal OSTerrainGetHeight(IntPtr p_user_data, int x, int z); + internal delegate dReal OSTerrainGetHeight(IntPtr p_user_data, int x, int z); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate void NearCallback(IntPtr data, IntPtr geom1, IntPtr geom2); + internal delegate void NearCallback(IntPtr data, IntPtr geom1, IntPtr geom2); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate int TriCallback(IntPtr trimesh, IntPtr refObject, int triangleIndex); + internal delegate int TriCallback(IntPtr trimesh, IntPtr refObject, int triangleIndex); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate int TriArrayCallback(IntPtr trimesh, IntPtr refObject, int[] triangleIndex, int triCount); + internal delegate int TriArrayCallback(IntPtr trimesh, IntPtr refObject, int[] triangleIndex, int triCount); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate int TriRayCallback(IntPtr trimesh, IntPtr ray, int triangleIndex, dReal u, dReal v); + internal delegate int TriRayCallback(IntPtr trimesh, IntPtr ray, int triangleIndex, dReal u, dReal v); #endregion #region Structs [StructLayout(LayoutKind.Sequential)] - public struct AABB + internal struct AABB { - public dReal MinX, MaxX; - public dReal MinY, MaxY; - public dReal MinZ, MaxZ; + internal dReal MinX, MaxX; + internal dReal MinY, MaxY; + internal dReal MinZ, MaxZ; } [StructLayout(LayoutKind.Sequential)] - public struct Contact + internal struct Contact { - public SurfaceParameters surface; - public ContactGeom geom; - public Vector3 fdir1; - public static readonly int unmanagedSizeOf = Marshal.SizeOf(typeof(Contact)); + internal SurfaceParameters surface; + internal ContactGeom geom; + internal Vector3 fdir1; + internal static readonly int unmanagedSizeOf = Marshal.SizeOf(typeof(Contact)); } [StructLayout(LayoutKind.Sequential)] - public struct ContactGeom + internal struct ContactGeom { - public Vector3 pos; - public Vector3 normal; - public dReal depth; - public IntPtr g1; - public IntPtr g2; - public int side1; - public int side2; - public static readonly int unmanagedSizeOf = Marshal.SizeOf(typeof(ContactGeom)); + internal Vector3 pos; + internal Vector3 normal; + internal dReal depth; + internal IntPtr g1; + internal IntPtr g2; + internal int side1; + internal int side2; + internal static readonly int unmanagedSizeOf = Marshal.SizeOf(typeof(ContactGeom)); } [StructLayout(LayoutKind.Sequential)] - public struct GeomClass + internal struct GeomClass { - public int bytes; - public GetColliderFnFn collider; - public GetAABBFn aabb; - public AABBTestFn aabb_test; - public GeomDtorFn dtor; + internal int bytes; + internal GetColliderFnFn collider; + internal GetAABBFn aabb; + internal AABBTestFn aabb_test; + internal GeomDtorFn dtor; } [StructLayout(LayoutKind.Sequential)] - public struct JointFeedback + internal struct JointFeedback { - public Vector3 f1; - public Vector3 t1; - public Vector3 f2; - public Vector3 t2; + internal Vector3 f1; + internal Vector3 t1; + internal Vector3 f2; + internal Vector3 t2; } [StructLayout(LayoutKind.Sequential)] - public struct Mass + internal struct Mass { - public dReal mass; - public Vector4 c; - public Matrix3 I; + internal dReal mass; + internal Vector4 c; + internal Matrix3 I; } [StructLayout(LayoutKind.Sequential)] - public struct Matrix3 + internal struct Matrix3 { - public Matrix3(dReal m00, dReal m10, dReal m20, dReal m01, dReal m11, dReal m21, dReal m02, dReal m12, dReal m22) + internal Matrix3(dReal m00, dReal m10, dReal m20, dReal m01, dReal m11, dReal m21, dReal m02, dReal m12, dReal m22) { M00 = m00; M10 = m10; M20 = m20; _m30 = 0.0f; M01 = m01; M11 = m11; M21 = m21; _m31 = 0.0f; M02 = m02; M12 = m12; M22 = m22; _m32 = 0.0f; } - public dReal M00, M10, M20; + internal dReal M00, M10, M20; private dReal _m30; - public dReal M01, M11, M21; + internal dReal M01, M11, M21; private dReal _m31; - public dReal M02, M12, M22; + internal dReal M02, M12, M22; private dReal _m32; } [StructLayout(LayoutKind.Sequential)] - public struct Matrix4 + internal struct Matrix4 { - public Matrix4(dReal m00, dReal m10, dReal m20, dReal m30, + internal Matrix4(dReal m00, dReal m10, dReal m20, dReal m30, dReal m01, dReal m11, dReal m21, dReal m31, dReal m02, dReal m12, dReal m22, dReal m32, dReal m03, dReal m13, dReal m23, dReal m33) @@ -318,312 +319,312 @@ namespace OdeAPI M02 = m02; M12 = m12; M22 = m22; M32 = m32; M03 = m03; M13 = m13; M23 = m23; M33 = m33; } - public dReal M00, M10, M20, M30; - public dReal M01, M11, M21, M31; - public dReal M02, M12, M22, M32; - public dReal M03, M13, M23, M33; + internal dReal M00, M10, M20, M30; + internal dReal M01, M11, M21, M31; + internal dReal M02, M12, M22, M32; + internal dReal M03, M13, M23, M33; } [StructLayout(LayoutKind.Sequential)] - public struct Quaternion + internal struct Quaternion { - public dReal W, X, Y, Z; + internal dReal W, X, Y, Z; } [StructLayout(LayoutKind.Sequential)] - public struct SurfaceParameters + internal struct SurfaceParameters { - public ContactFlags mode; - public dReal mu; - public dReal mu2; - public dReal bounce; - public dReal bounce_vel; - public dReal soft_erp; - public dReal soft_cfm; - public dReal motion1; - public dReal motion2; - public dReal motionN; - public dReal slip1; - public dReal slip2; + internal ContactFlags mode; + internal dReal mu; + internal dReal mu2; + internal dReal bounce; + internal dReal bounce_vel; + internal dReal soft_erp; + internal dReal soft_cfm; + internal dReal motion1; + internal dReal motion2; + internal dReal motionN; + internal dReal slip1; + internal dReal slip2; } [StructLayout(LayoutKind.Sequential)] - public struct Vector3 + internal struct Vector3 { - public Vector3(dReal x, dReal y, dReal z) + internal Vector3(dReal x, dReal y, dReal z) { X = x; Y = y; Z = z; _w = 0.0f; } - public dReal X, Y, Z; + internal dReal X, Y, Z; private dReal _w; } [StructLayout(LayoutKind.Sequential)] - public struct Vector4 + internal struct Vector4 { - public Vector4(dReal x, dReal y, dReal z, dReal w) + internal Vector4(dReal x, dReal y, dReal z, dReal w) { X = x; Y = y; Z = z; W = w; } - public dReal X, Y, Z, W; + internal dReal X, Y, Z, W; } #endregion [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dAllocateODEDataForThread"), SuppressUnmanagedCodeSecurity] - public static extern int AllocateODEDataForThread(uint ODEInitFlags); + internal static extern int AllocateODEDataForThread(uint ODEInitFlags); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dAreConnected"), SuppressUnmanagedCodeSecurity] - public static extern bool AreConnected(IntPtr b1, IntPtr b2); + internal static extern bool AreConnected(IntPtr b1, IntPtr b2); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dAreConnectedExcluding"), SuppressUnmanagedCodeSecurity] - public static extern bool AreConnectedExcluding(IntPtr b1, IntPtr b2, JointType joint_type); + internal static extern bool AreConnectedExcluding(IntPtr b1, IntPtr b2, JointType joint_type); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyAddForce"), SuppressUnmanagedCodeSecurity] - public static extern void BodyAddForce(IntPtr body, dReal fx, dReal fy, dReal fz); + internal static extern void BodyAddForce(IntPtr body, dReal fx, dReal fy, dReal fz); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyAddForceAtPos"), SuppressUnmanagedCodeSecurity] - public static extern void BodyAddForceAtPos(IntPtr body, dReal fx, dReal fy, dReal fz, dReal px, dReal py, dReal pz); + internal static extern void BodyAddForceAtPos(IntPtr body, dReal fx, dReal fy, dReal fz, dReal px, dReal py, dReal pz); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyAddForceAtRelPos"), SuppressUnmanagedCodeSecurity] - public static extern void BodyAddForceAtRelPos(IntPtr body, dReal fx, dReal fy, dReal fz, dReal px, dReal py, dReal pz); + internal static extern void BodyAddForceAtRelPos(IntPtr body, dReal fx, dReal fy, dReal fz, dReal px, dReal py, dReal pz); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyAddRelForce"), SuppressUnmanagedCodeSecurity] - public static extern void BodyAddRelForce(IntPtr body, dReal fx, dReal fy, dReal fz); + internal static extern void BodyAddRelForce(IntPtr body, dReal fx, dReal fy, dReal fz); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyAddRelForceAtPos"), SuppressUnmanagedCodeSecurity] - public static extern void BodyAddRelForceAtPos(IntPtr body, dReal fx, dReal fy, dReal fz, dReal px, dReal py, dReal pz); + internal static extern void BodyAddRelForceAtPos(IntPtr body, dReal fx, dReal fy, dReal fz, dReal px, dReal py, dReal pz); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyAddRelForceAtRelPos"), SuppressUnmanagedCodeSecurity] - public static extern void BodyAddRelForceAtRelPos(IntPtr body, dReal fx, dReal fy, dReal fz, dReal px, dReal py, dReal pz); + internal static extern void BodyAddRelForceAtRelPos(IntPtr body, dReal fx, dReal fy, dReal fz, dReal px, dReal py, dReal pz); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyAddRelTorque"), SuppressUnmanagedCodeSecurity] - public static extern void BodyAddRelTorque(IntPtr body, dReal fx, dReal fy, dReal fz); + internal static extern void BodyAddRelTorque(IntPtr body, dReal fx, dReal fy, dReal fz); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyAddTorque"), SuppressUnmanagedCodeSecurity] - public static extern void BodyAddTorque(IntPtr body, dReal fx, dReal fy, dReal fz); + internal static extern void BodyAddTorque(IntPtr body, dReal fx, dReal fy, dReal fz); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyCopyPosition"), SuppressUnmanagedCodeSecurity] - public static extern void BodyCopyPosition(IntPtr body, out Vector3 pos); + internal static extern void BodyCopyPosition(IntPtr body, out Vector3 pos); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyCopyPosition"), SuppressUnmanagedCodeSecurity] - public static extern void BodyCopyPosition(IntPtr body, out dReal X); + internal static extern void BodyCopyPosition(IntPtr body, out dReal X); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyCopyQuaternion"), SuppressUnmanagedCodeSecurity] - public static extern void BodyCopyQuaternion(IntPtr body, out Quaternion quat); + internal static extern void BodyCopyQuaternion(IntPtr body, out Quaternion quat); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyCopyQuaternion"), SuppressUnmanagedCodeSecurity] - public static extern void BodyCopyQuaternion(IntPtr body, out dReal X); + internal static extern void BodyCopyQuaternion(IntPtr body, out dReal X); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyCopyRotation"), SuppressUnmanagedCodeSecurity] - public static extern void BodyCopyRotation(IntPtr body, out Matrix3 R); + internal static extern void BodyCopyRotation(IntPtr body, out Matrix3 R); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyCopyRotation"), SuppressUnmanagedCodeSecurity] - public static extern void BodyCopyRotation(IntPtr body, out dReal M00); + internal static extern void BodyCopyRotation(IntPtr body, out dReal M00); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyCreate"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr BodyiCreate(IntPtr world); - public static IntPtr BodyCreate(IntPtr world) + internal static extern IntPtr BodyiCreate(IntPtr world); + internal static IntPtr BodyCreate(IntPtr world) { NTotalBodies++; return BodyiCreate(world); } [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyDestroy"), SuppressUnmanagedCodeSecurity] - public static extern void BodyiDestroy(IntPtr body); - public static void BodyDestroy(IntPtr body) + internal static extern void BodyiDestroy(IntPtr body); + internal static void BodyDestroy(IntPtr body) { NTotalBodies--; BodyiDestroy(body); } [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyDisable"), SuppressUnmanagedCodeSecurity] - public static extern void BodyDisable(IntPtr body); + internal static extern void BodyDisable(IntPtr body); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyEnable"), SuppressUnmanagedCodeSecurity] - public static extern void BodyEnable(IntPtr body); + internal static extern void BodyEnable(IntPtr body); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetAutoDisableAngularThreshold"), SuppressUnmanagedCodeSecurity] - public static extern dReal BodyGetAutoDisableAngularThreshold(IntPtr body); + internal static extern dReal BodyGetAutoDisableAngularThreshold(IntPtr body); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetAutoDisableFlag"), SuppressUnmanagedCodeSecurity] - public static extern bool BodyGetAutoDisableFlag(IntPtr body); + internal static extern bool BodyGetAutoDisableFlag(IntPtr body); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetAutoDisableDefaults"), SuppressUnmanagedCodeSecurity] - public static extern void BodyGetAutoDisableDefaults(IntPtr body); + internal static extern void BodyGetAutoDisableDefaults(IntPtr body); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetAutoDisableLinearThreshold"), SuppressUnmanagedCodeSecurity] - public static extern dReal BodyGetAutoDisableLinearThreshold(IntPtr body); + internal static extern dReal BodyGetAutoDisableLinearThreshold(IntPtr body); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetAutoDisableSteps"), SuppressUnmanagedCodeSecurity] - public static extern int BodyGetAutoDisableSteps(IntPtr body); + internal static extern int BodyGetAutoDisableSteps(IntPtr body); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetAutoDisableTime"), SuppressUnmanagedCodeSecurity] - public static extern dReal BodyGetAutoDisableTime(IntPtr body); + internal static extern dReal BodyGetAutoDisableTime(IntPtr body); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetAngularVel"), SuppressUnmanagedCodeSecurity] - public extern unsafe static Vector3* BodyGetAngularVelUnsafe(IntPtr body); - public static Vector3 BodyGetAngularVel(IntPtr body) + internal extern unsafe static Vector3* BodyGetAngularVelUnsafe(IntPtr body); + internal static Vector3 BodyGetAngularVel(IntPtr body) { unsafe { return *(BodyGetAngularVelUnsafe(body)); } } [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetData"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr BodyGetData(IntPtr body); + internal static extern IntPtr BodyGetData(IntPtr body); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetFiniteRotationMode"), SuppressUnmanagedCodeSecurity] - public static extern int BodyGetFiniteRotationMode(IntPtr body); + internal static extern int BodyGetFiniteRotationMode(IntPtr body); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetFiniteRotationAxis"), SuppressUnmanagedCodeSecurity] - public static extern void BodyGetFiniteRotationAxis(IntPtr body, out Vector3 result); + internal static extern void BodyGetFiniteRotationAxis(IntPtr body, out Vector3 result); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetForce"), SuppressUnmanagedCodeSecurity] - public extern unsafe static Vector3* BodyGetForceUnsafe(IntPtr body); - public static Vector3 BodyGetForce(IntPtr body) + internal extern unsafe static Vector3* BodyGetForceUnsafe(IntPtr body); + internal static Vector3 BodyGetForce(IntPtr body) { unsafe { return *(BodyGetForceUnsafe(body)); } } [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetGravityMode"), SuppressUnmanagedCodeSecurity] - public static extern bool BodyGetGravityMode(IntPtr body); + internal static extern bool BodyGetGravityMode(IntPtr body); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetGyroscopicMode"), SuppressUnmanagedCodeSecurity] - public static extern int BodyGetGyroscopicMode(IntPtr body); + internal static extern int BodyGetGyroscopicMode(IntPtr body); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetJoint"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr BodyGetJoint(IntPtr body, int index); + internal static extern IntPtr BodyGetJoint(IntPtr body, int index); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetLinearVel"), SuppressUnmanagedCodeSecurity] - public extern unsafe static Vector3* BodyGetLinearVelUnsafe(IntPtr body); - public static Vector3 BodyGetLinearVel(IntPtr body) + internal extern unsafe static Vector3* BodyGetLinearVelUnsafe(IntPtr body); + internal static Vector3 BodyGetLinearVel(IntPtr body) { unsafe { return *(BodyGetLinearVelUnsafe(body)); } } [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetMass"), SuppressUnmanagedCodeSecurity] - public static extern void BodyGetMass(IntPtr body, out Mass mass); + internal static extern void BodyGetMass(IntPtr body, out Mass mass); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetNumJoints"), SuppressUnmanagedCodeSecurity] - public static extern int BodyGetNumJoints(IntPtr body); + internal static extern int BodyGetNumJoints(IntPtr body); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetPointVel"), SuppressUnmanagedCodeSecurity] - public static extern void BodyGetPointVel(IntPtr body, dReal px, dReal py, dReal pz, out Vector3 result); + internal static extern void BodyGetPointVel(IntPtr body, dReal px, dReal py, dReal pz, out Vector3 result); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetPosition"), SuppressUnmanagedCodeSecurity] - public extern unsafe static Vector3* BodyGetPositionUnsafe(IntPtr body); - public static Vector3 BodyGetPosition(IntPtr body) + internal extern unsafe static Vector3* BodyGetPositionUnsafe(IntPtr body); + internal static Vector3 BodyGetPosition(IntPtr body) { unsafe { return *(BodyGetPositionUnsafe(body)); } } [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetPosRelPoint"), SuppressUnmanagedCodeSecurity] - public static extern void BodyGetPosRelPoint(IntPtr body, dReal px, dReal py, dReal pz, out Vector3 result); + internal static extern void BodyGetPosRelPoint(IntPtr body, dReal px, dReal py, dReal pz, out Vector3 result); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetQuaternion"), SuppressUnmanagedCodeSecurity] - public extern unsafe static Quaternion* BodyGetQuaternionUnsafe(IntPtr body); - public static Quaternion BodyGetQuaternion(IntPtr body) + internal extern unsafe static Quaternion* BodyGetQuaternionUnsafe(IntPtr body); + internal static Quaternion BodyGetQuaternion(IntPtr body) { unsafe { return *(BodyGetQuaternionUnsafe(body)); } } [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetRelPointPos"), SuppressUnmanagedCodeSecurity] - public static extern void BodyGetRelPointPos(IntPtr body, dReal px, dReal py, dReal pz, out Vector3 result); + internal static extern void BodyGetRelPointPos(IntPtr body, dReal px, dReal py, dReal pz, out Vector3 result); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetRelPointVel"), SuppressUnmanagedCodeSecurity] - public static extern void BodyGetRelPointVel(IntPtr body, dReal px, dReal py, dReal pz, out Vector3 result); + internal static extern void BodyGetRelPointVel(IntPtr body, dReal px, dReal py, dReal pz, out Vector3 result); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetRotation"), SuppressUnmanagedCodeSecurity] - public extern unsafe static Matrix3* BodyGetRotationUnsafe(IntPtr body); - public static Matrix3 BodyGetRotation(IntPtr body) + internal extern unsafe static Matrix3* BodyGetRotationUnsafe(IntPtr body); + internal static Matrix3 BodyGetRotation(IntPtr body) { unsafe { return *(BodyGetRotationUnsafe(body)); } } [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetTorque"), SuppressUnmanagedCodeSecurity] - public extern unsafe static Vector3* BodyGetTorqueUnsafe(IntPtr body); - public static Vector3 BodyGetTorque(IntPtr body) + internal extern unsafe static Vector3* BodyGetTorqueUnsafe(IntPtr body); + internal static Vector3 BodyGetTorque(IntPtr body) { unsafe { return *(BodyGetTorqueUnsafe(body)); } } [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetWorld"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr BodyGetWorld(IntPtr body); + internal static extern IntPtr BodyGetWorld(IntPtr body); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetFirstGeom"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr BodyGetFirstGeom(IntPtr body); + internal static extern IntPtr BodyGetFirstGeom(IntPtr body); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetNextGeom"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr dBodyGetNextGeom(IntPtr Geom); + internal static extern IntPtr dBodyGetNextGeom(IntPtr Geom); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyIsEnabled"), SuppressUnmanagedCodeSecurity] - public static extern bool BodyIsEnabled(IntPtr body); + internal static extern bool BodyIsEnabled(IntPtr body); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetAngularVel"), SuppressUnmanagedCodeSecurity] - public static extern void BodySetAngularVel(IntPtr body, dReal x, dReal y, dReal z); + internal static extern void BodySetAngularVel(IntPtr body, dReal x, dReal y, dReal z); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetAutoDisableAngularThreshold"), SuppressUnmanagedCodeSecurity] - public static extern void BodySetAutoDisableAngularThreshold(IntPtr body, dReal angular_threshold); + internal static extern void BodySetAutoDisableAngularThreshold(IntPtr body, dReal angular_threshold); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetAutoDisableDefaults"), SuppressUnmanagedCodeSecurity] - public static extern void BodySetAutoDisableDefaults(IntPtr body); + internal static extern void BodySetAutoDisableDefaults(IntPtr body); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetAutoDisableFlag"), SuppressUnmanagedCodeSecurity] - public static extern void BodySetAutoDisableFlag(IntPtr body, bool do_auto_disable); + internal static extern void BodySetAutoDisableFlag(IntPtr body, bool do_auto_disable); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetAutoDisableLinearThreshold"), SuppressUnmanagedCodeSecurity] - public static extern void BodySetAutoDisableLinearThreshold(IntPtr body, dReal linear_threshold); + internal static extern void BodySetAutoDisableLinearThreshold(IntPtr body, dReal linear_threshold); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetAutoDisableSteps"), SuppressUnmanagedCodeSecurity] - public static extern void BodySetAutoDisableSteps(IntPtr body, int steps); + internal static extern void BodySetAutoDisableSteps(IntPtr body, int steps); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetAutoDisableTime"), SuppressUnmanagedCodeSecurity] - public static extern void BodySetAutoDisableTime(IntPtr body, dReal time); + internal static extern void BodySetAutoDisableTime(IntPtr body, dReal time); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetData"), SuppressUnmanagedCodeSecurity] - public static extern void BodySetData(IntPtr body, IntPtr data); + internal static extern void BodySetData(IntPtr body, IntPtr data); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetFiniteRotationMode"), SuppressUnmanagedCodeSecurity] - public static extern void BodySetFiniteRotationMode(IntPtr body, int mode); + internal static extern void BodySetFiniteRotationMode(IntPtr body, int mode); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetFiniteRotationAxis"), SuppressUnmanagedCodeSecurity] - public static extern void BodySetFiniteRotationAxis(IntPtr body, dReal x, dReal y, dReal z); + internal static extern void BodySetFiniteRotationAxis(IntPtr body, dReal x, dReal y, dReal z); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetLinearDamping"), SuppressUnmanagedCodeSecurity] - public static extern void BodySetLinearDamping(IntPtr body, dReal scale); + internal static extern void BodySetLinearDamping(IntPtr body, dReal scale); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetAngularDamping"), SuppressUnmanagedCodeSecurity] - public static extern void BodySetAngularDamping(IntPtr body, dReal scale); + internal static extern void BodySetAngularDamping(IntPtr body, dReal scale); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetLinearDamping"), SuppressUnmanagedCodeSecurity] - public static extern dReal BodyGetLinearDamping(IntPtr body); + internal static extern dReal BodyGetLinearDamping(IntPtr body); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetAngularDamping"), SuppressUnmanagedCodeSecurity] - public static extern dReal BodyGetAngularDamping(IntPtr body); + internal static extern dReal BodyGetAngularDamping(IntPtr body); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetAngularDamping"), SuppressUnmanagedCodeSecurity] - public static extern void BodySetDamping(IntPtr body, dReal linear_scale, dReal angular_scale); + internal static extern void BodySetDamping(IntPtr body, dReal linear_scale, dReal angular_scale); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetAngularDampingThreshold"), SuppressUnmanagedCodeSecurity] - public static extern void BodySetAngularDampingThreshold(IntPtr body, dReal threshold); + internal static extern void BodySetAngularDampingThreshold(IntPtr body, dReal threshold); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetLinearDampingThreshold"), SuppressUnmanagedCodeSecurity] - public static extern void BodySetLinearDampingThreshold(IntPtr body, dReal threshold); + internal static extern void BodySetLinearDampingThreshold(IntPtr body, dReal threshold); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetLinearDampingThreshold"), SuppressUnmanagedCodeSecurity] - public static extern dReal BodyGetLinearDampingThreshold(IntPtr body); + internal static extern dReal BodyGetLinearDampingThreshold(IntPtr body); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyGetAngularDampingThreshold"), SuppressUnmanagedCodeSecurity] - public static extern dReal BodyGetAngularDampingThreshold(IntPtr body); + internal static extern dReal BodyGetAngularDampingThreshold(IntPtr body); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetForce"), SuppressUnmanagedCodeSecurity] - public static extern void BodySetForce(IntPtr body, dReal x, dReal y, dReal z); + internal static extern void BodySetForce(IntPtr body, dReal x, dReal y, dReal z); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetGravityMode"), SuppressUnmanagedCodeSecurity] - public static extern void BodySetGravityMode(IntPtr body, bool mode); + internal static extern void BodySetGravityMode(IntPtr body, bool mode); /// /// Sets the Gyroscopic term status on the body specified. @@ -631,112 +632,112 @@ namespace OdeAPI /// Pointer to body /// NonZero enabled, Zero disabled [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetGyroscopicMode"), SuppressUnmanagedCodeSecurity] - public static extern void dBodySetGyroscopicMode(IntPtr body, int enabled); + internal static extern void dBodySetGyroscopicMode(IntPtr body, int enabled); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetLinearVel"), SuppressUnmanagedCodeSecurity] - public static extern void BodySetLinearVel(IntPtr body, dReal x, dReal y, dReal z); + internal static extern void BodySetLinearVel(IntPtr body, dReal x, dReal y, dReal z); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetMass"), SuppressUnmanagedCodeSecurity] - public static extern void BodySetMass(IntPtr body, ref Mass mass); + internal static extern void BodySetMass(IntPtr body, ref Mass mass); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetPosition"), SuppressUnmanagedCodeSecurity] - public static extern void BodySetPosition(IntPtr body, dReal x, dReal y, dReal z); + internal static extern void BodySetPosition(IntPtr body, dReal x, dReal y, dReal z); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetQuaternion"), SuppressUnmanagedCodeSecurity] - public static extern void BodySetQuaternion(IntPtr body, ref Quaternion q); + internal static extern void BodySetQuaternion(IntPtr body, ref Quaternion q); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetQuaternion"), SuppressUnmanagedCodeSecurity] - public static extern void BodySetQuaternion(IntPtr body, ref dReal w); + internal static extern void BodySetQuaternion(IntPtr body, ref dReal w); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetRotation"), SuppressUnmanagedCodeSecurity] - public static extern void BodySetRotation(IntPtr body, ref Matrix3 R); + internal static extern void BodySetRotation(IntPtr body, ref Matrix3 R); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetRotation"), SuppressUnmanagedCodeSecurity] - public static extern void BodySetRotation(IntPtr body, ref dReal M00); + internal static extern void BodySetRotation(IntPtr body, ref dReal M00); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodySetTorque"), SuppressUnmanagedCodeSecurity] - public static extern void BodySetTorque(IntPtr body, dReal x, dReal y, dReal z); + internal static extern void BodySetTorque(IntPtr body, dReal x, dReal y, dReal z); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyVectorFromWorld"), SuppressUnmanagedCodeSecurity] - public static extern void BodyVectorFromWorld(IntPtr body, dReal px, dReal py, dReal pz, out Vector3 result); + internal static extern void BodyVectorFromWorld(IntPtr body, dReal px, dReal py, dReal pz, out Vector3 result); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBodyVectorToWorld"), SuppressUnmanagedCodeSecurity] - public static extern void BodyVectorToWorld(IntPtr body, dReal px, dReal py, dReal pz, out Vector3 result); + internal static extern void BodyVectorToWorld(IntPtr body, dReal px, dReal py, dReal pz, out Vector3 result); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBoxBox"), SuppressUnmanagedCodeSecurity] - public static extern void BoxBox(ref Vector3 p1, ref Matrix3 R1, + internal static extern void BoxBox(ref Vector3 p1, ref Matrix3 R1, ref Vector3 side1, ref Vector3 p2, ref Matrix3 R2, ref Vector3 side2, ref Vector3 normal, out dReal depth, out int return_code, int maxc, out ContactGeom contact, int skip); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dBoxTouchesBox"), SuppressUnmanagedCodeSecurity] - public static extern void BoxTouchesBox(ref Vector3 _p1, ref Matrix3 R1, + internal static extern void BoxTouchesBox(ref Vector3 _p1, ref Matrix3 R1, ref Vector3 side1, ref Vector3 _p2, ref Matrix3 R2, ref Vector3 side2); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCleanupODEAllDataForThread"), SuppressUnmanagedCodeSecurity] - public static extern void CleanupODEAllDataForThread(); + internal static extern void CleanupODEAllDataForThread(); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dClosestLineSegmentPoints"), SuppressUnmanagedCodeSecurity] - public static extern void ClosestLineSegmentPoints(ref Vector3 a1, ref Vector3 a2, + internal static extern void ClosestLineSegmentPoints(ref Vector3 a1, ref Vector3 a2, ref Vector3 b1, ref Vector3 b2, ref Vector3 cp1, ref Vector3 cp2); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCloseODE"), SuppressUnmanagedCodeSecurity] - public static extern void CloseODE(); + internal static extern void CloseODE(); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCollide"), SuppressUnmanagedCodeSecurity] - public static extern int Collide(IntPtr o1, IntPtr o2, int flags, [In, Out] ContactGeom[] contact, int skip); + internal static extern int Collide(IntPtr o1, IntPtr o2, int flags, [In, Out] ContactGeom[] contact, int skip); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCollide"), SuppressUnmanagedCodeSecurity] - public static extern int CollidePtr(IntPtr o1, IntPtr o2, int flags, IntPtr contactgeomarray, int skip); + internal static extern int CollidePtr(IntPtr o1, IntPtr o2, int flags, IntPtr contactgeomarray, int skip); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dConnectingJoint"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr ConnectingJoint(IntPtr j1, IntPtr j2); + internal static extern IntPtr ConnectingJoint(IntPtr j1, IntPtr j2); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateBox"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr CreateiBox(IntPtr space, dReal lx, dReal ly, dReal lz); - public static IntPtr CreateBox(IntPtr space, dReal lx, dReal ly, dReal lz) + internal static extern IntPtr CreateiBox(IntPtr space, dReal lx, dReal ly, dReal lz); + internal static IntPtr CreateBox(IntPtr space, dReal lx, dReal ly, dReal lz) { NTotalGeoms++; return CreateiBox(space, lx, ly, lz); } [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateCapsule"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr CreateiCapsule(IntPtr space, dReal radius, dReal length); - public static IntPtr CreateCapsule(IntPtr space, dReal radius, dReal length) + internal static extern IntPtr CreateiCapsule(IntPtr space, dReal radius, dReal length); + internal static IntPtr CreateCapsule(IntPtr space, dReal radius, dReal length) { NTotalGeoms++; return CreateiCapsule(space, radius, length); } [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateConvex"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr CreateiConvex(IntPtr space, dReal[] planes, int planeCount, dReal[] points, int pointCount, int[] polygons); - public static IntPtr CreateConvex(IntPtr space, dReal[] planes, int planeCount, dReal[] points, int pointCount, int[] polygons) + internal static extern IntPtr CreateiConvex(IntPtr space, dReal[] planes, int planeCount, dReal[] points, int pointCount, int[] polygons); + internal static IntPtr CreateConvex(IntPtr space, dReal[] planes, int planeCount, dReal[] points, int pointCount, int[] polygons) { NTotalGeoms++; return CreateiConvex(space, planes, planeCount, points, pointCount, polygons); } [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateCylinder"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr CreateiCylinder(IntPtr space, dReal radius, dReal length); - public static IntPtr CreateCylinder(IntPtr space, dReal radius, dReal length) + internal static extern IntPtr CreateiCylinder(IntPtr space, dReal radius, dReal length); + internal static IntPtr CreateCylinder(IntPtr space, dReal radius, dReal length) { NTotalGeoms++; return CreateiCylinder(space, radius, length); } [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateHeightfield"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr CreateiHeightfield(IntPtr space, IntPtr data, int bPlaceable); - public static IntPtr CreateHeightfield(IntPtr space, IntPtr data, int bPlaceable) + internal static extern IntPtr CreateiHeightfield(IntPtr space, IntPtr data, int bPlaceable); + internal static IntPtr CreateHeightfield(IntPtr space, IntPtr data, int bPlaceable) { NTotalGeoms++; return CreateiHeightfield(space, data, bPlaceable); } [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateOSTerrain"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr CreateiOSTerrain(IntPtr space, IntPtr data, int bPlaceable); - public static IntPtr CreateOSTerrain(IntPtr space, IntPtr data, int bPlaceable) + internal static extern IntPtr CreateiOSTerrain(IntPtr space, IntPtr data, int bPlaceable); + internal static IntPtr CreateOSTerrain(IntPtr space, IntPtr data, int bPlaceable) { NTotalGeoms++; return CreateiOSTerrain(space, data, bPlaceable); @@ -747,127 +748,127 @@ namespace OdeAPI [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateGeom"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr CreateiGeom(int classnum); - public static IntPtr CreateGeom(int classnum) + internal static extern IntPtr CreateiGeom(int classnum); + internal static IntPtr CreateGeom(int classnum) { NTotalGeoms++; return CreateiGeom(classnum); } [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateGeomClass"), SuppressUnmanagedCodeSecurity] - public static extern int CreateGeomClass(ref GeomClass classptr); + internal static extern int CreateGeomClass(ref GeomClass classptr); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateGeomTransform"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr CreateGeomTransform(IntPtr space); + internal static extern IntPtr CreateGeomTransform(IntPtr space); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreatePlane"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr CreateiPlane(IntPtr space, dReal a, dReal b, dReal c, dReal d); - public static IntPtr CreatePlane(IntPtr space, dReal a, dReal b, dReal c, dReal d) + internal static extern IntPtr CreateiPlane(IntPtr space, dReal a, dReal b, dReal c, dReal d); + internal static IntPtr CreatePlane(IntPtr space, dReal a, dReal b, dReal c, dReal d) { NTotalGeoms++; return CreateiPlane(space, a, b, c, d); } [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateRay"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr CreateiRay(IntPtr space, dReal length); - public static IntPtr CreateRay(IntPtr space, dReal length) + internal static extern IntPtr CreateiRay(IntPtr space, dReal length); + internal static IntPtr CreateRay(IntPtr space, dReal length) { NTotalGeoms++; return CreateiRay(space, length); } [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateSphere"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr CreateiSphere(IntPtr space, dReal radius); - public static IntPtr CreateSphere(IntPtr space, dReal radius) + internal static extern IntPtr CreateiSphere(IntPtr space, dReal radius); + internal static IntPtr CreateSphere(IntPtr space, dReal radius) { NTotalGeoms++; return CreateiSphere(space, radius); } [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dCreateTriMesh"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr CreateiTriMesh(IntPtr space, IntPtr data, + internal static extern IntPtr CreateiTriMesh(IntPtr space, IntPtr data, TriCallback callback, TriArrayCallback arrayCallback, TriRayCallback rayCallback); - public static IntPtr CreateTriMesh(IntPtr space, IntPtr data, + internal static IntPtr CreateTriMesh(IntPtr space, IntPtr data, TriCallback callback, TriArrayCallback arrayCallback, TriRayCallback rayCallback) { NTotalGeoms++; return CreateiTriMesh(space, data, callback, arrayCallback, rayCallback); } [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dDot"), SuppressUnmanagedCodeSecurity] - public static extern dReal Dot(ref dReal X0, ref dReal X1, int n); + internal static extern dReal Dot(ref dReal X0, ref dReal X1, int n); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dDQfromW"), SuppressUnmanagedCodeSecurity] - public static extern void DQfromW(dReal[] dq, ref Vector3 w, ref Quaternion q); + internal static extern void DQfromW(dReal[] dq, ref Vector3 w, ref Quaternion q); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dFactorCholesky"), SuppressUnmanagedCodeSecurity] - public static extern int FactorCholesky(ref dReal A00, int n); + internal static extern int FactorCholesky(ref dReal A00, int n); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dFactorLDLT"), SuppressUnmanagedCodeSecurity] - public static extern void FactorLDLT(ref dReal A, out dReal d, int n, int nskip); + internal static extern void FactorLDLT(ref dReal A, out dReal d, int n, int nskip); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomBoxGetLengths"), SuppressUnmanagedCodeSecurity] - public static extern void GeomBoxGetLengths(IntPtr geom, out Vector3 len); + internal static extern void GeomBoxGetLengths(IntPtr geom, out Vector3 len); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomBoxGetLengths"), SuppressUnmanagedCodeSecurity] - public static extern void GeomBoxGetLengths(IntPtr geom, out dReal x); + internal static extern void GeomBoxGetLengths(IntPtr geom, out dReal x); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomBoxPointDepth"), SuppressUnmanagedCodeSecurity] - public static extern dReal GeomBoxPointDepth(IntPtr geom, dReal x, dReal y, dReal z); + internal static extern dReal GeomBoxPointDepth(IntPtr geom, dReal x, dReal y, dReal z); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomBoxSetLengths"), SuppressUnmanagedCodeSecurity] - public static extern void GeomBoxSetLengths(IntPtr geom, dReal x, dReal y, dReal z); + internal static extern void GeomBoxSetLengths(IntPtr geom, dReal x, dReal y, dReal z); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomCapsuleGetParams"), SuppressUnmanagedCodeSecurity] - public static extern void GeomCapsuleGetParams(IntPtr geom, out dReal radius, out dReal length); + internal static extern void GeomCapsuleGetParams(IntPtr geom, out dReal radius, out dReal length); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomCapsulePointDepth"), SuppressUnmanagedCodeSecurity] - public static extern dReal GeomCapsulePointDepth(IntPtr geom, dReal x, dReal y, dReal z); + internal static extern dReal GeomCapsulePointDepth(IntPtr geom, dReal x, dReal y, dReal z); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomCapsuleSetParams"), SuppressUnmanagedCodeSecurity] - public static extern void GeomCapsuleSetParams(IntPtr geom, dReal radius, dReal length); + internal static extern void GeomCapsuleSetParams(IntPtr geom, dReal radius, dReal length); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomClearOffset"), SuppressUnmanagedCodeSecurity] - public static extern void GeomClearOffset(IntPtr geom); + internal static extern void GeomClearOffset(IntPtr geom); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomCopyOffsetPosition"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr GeomCopyOffsetPosition(IntPtr geom, ref Vector3 pos); + internal static extern IntPtr GeomCopyOffsetPosition(IntPtr geom, ref Vector3 pos); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomCopyOffsetPosition"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr GeomCopyOffsetPosition(IntPtr geom, ref dReal X); + internal static extern IntPtr GeomCopyOffsetPosition(IntPtr geom, ref dReal X); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetOffsetQuaternion"), SuppressUnmanagedCodeSecurity] - public static extern void GeomCopyOffsetQuaternion(IntPtr geom, ref Quaternion Q); + internal static extern void GeomCopyOffsetQuaternion(IntPtr geom, ref Quaternion Q); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetOffsetQuaternion"), SuppressUnmanagedCodeSecurity] - public static extern void GeomCopyOffsetQuaternion(IntPtr geom, ref dReal X); + internal static extern void GeomCopyOffsetQuaternion(IntPtr geom, ref dReal X); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomCopyOffsetRotation"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr GeomCopyOffsetRotation(IntPtr geom, ref Matrix3 R); + internal static extern IntPtr GeomCopyOffsetRotation(IntPtr geom, ref Matrix3 R); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomCopyOffsetRotation"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr GeomCopyOffsetRotation(IntPtr geom, ref dReal M00); + internal static extern IntPtr GeomCopyOffsetRotation(IntPtr geom, ref dReal M00); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomCopyPosition"), SuppressUnmanagedCodeSecurity] - public static extern void GeomCopyPosition(IntPtr geom, out Vector3 pos); + internal static extern void GeomCopyPosition(IntPtr geom, out Vector3 pos); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomCopyPosition"), SuppressUnmanagedCodeSecurity] - public static extern void GeomCopyPosition(IntPtr geom, out dReal X); + internal static extern void GeomCopyPosition(IntPtr geom, out dReal X); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomCopyRotation"), SuppressUnmanagedCodeSecurity] - public static extern void GeomCopyRotation(IntPtr geom, out Matrix3 R); + internal static extern void GeomCopyRotation(IntPtr geom, out Matrix3 R); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomCopyRotation"), SuppressUnmanagedCodeSecurity] - public static extern void GeomCopyRotation(IntPtr geom, out dReal M00); + internal static extern void GeomCopyRotation(IntPtr geom, out dReal M00); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomCylinderGetParams"), SuppressUnmanagedCodeSecurity] - public static extern void GeomCylinderGetParams(IntPtr geom, out dReal radius, out dReal length); + internal static extern void GeomCylinderGetParams(IntPtr geom, out dReal radius, out dReal length); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomCylinderSetParams"), SuppressUnmanagedCodeSecurity] - public static extern void GeomCylinderSetParams(IntPtr geom, dReal radius, dReal length); + internal static extern void GeomCylinderSetParams(IntPtr geom, dReal radius, dReal length); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomDestroy"), SuppressUnmanagedCodeSecurity] - public static extern void GeomiDestroy(IntPtr geom); - public static void GeomDestroy(IntPtr geom) + internal static extern void GeomiDestroy(IntPtr geom); + internal static void GeomDestroy(IntPtr geom) { NTotalGeoms--; GeomiDestroy(geom); @@ -875,64 +876,64 @@ namespace OdeAPI [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomDisable"), SuppressUnmanagedCodeSecurity] - public static extern void GeomDisable(IntPtr geom); + internal static extern void GeomDisable(IntPtr geom); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomEnable"), SuppressUnmanagedCodeSecurity] - public static extern void GeomEnable(IntPtr geom); + internal static extern void GeomEnable(IntPtr geom); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetAABB"), SuppressUnmanagedCodeSecurity] - public static extern void GeomGetAABB(IntPtr geom, out AABB aabb); + internal static extern void GeomGetAABB(IntPtr geom, out AABB aabb); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetAABB"), SuppressUnmanagedCodeSecurity] - public static extern void GeomGetAABB(IntPtr geom, out dReal minX); + internal static extern void GeomGetAABB(IntPtr geom, out dReal minX); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetBody"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr GeomGetBody(IntPtr geom); + internal static extern IntPtr GeomGetBody(IntPtr geom); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetCategoryBits"), SuppressUnmanagedCodeSecurity] - public static extern uint GeomGetCategoryBits(IntPtr geom); + internal static extern uint GeomGetCategoryBits(IntPtr geom); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetClassData"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr GeomGetClassData(IntPtr geom); + internal static extern IntPtr GeomGetClassData(IntPtr geom); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetCollideBits"), SuppressUnmanagedCodeSecurity] - public static extern uint GeomGetCollideBits(IntPtr geom); + internal static extern uint GeomGetCollideBits(IntPtr geom); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetClass"), SuppressUnmanagedCodeSecurity] - public static extern GeomClassID GeomGetClass(IntPtr geom); + internal static extern GeomClassID GeomGetClass(IntPtr geom); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetData"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr GeomGetData(IntPtr geom); + internal static extern IntPtr GeomGetData(IntPtr geom); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetOffsetPosition"), SuppressUnmanagedCodeSecurity] - public extern unsafe static Vector3* GeomGetOffsetPositionUnsafe(IntPtr geom); - public static Vector3 GeomGetOffsetPosition(IntPtr geom) + internal extern unsafe static Vector3* GeomGetOffsetPositionUnsafe(IntPtr geom); + internal static Vector3 GeomGetOffsetPosition(IntPtr geom) { unsafe { return *(GeomGetOffsetPositionUnsafe(geom)); } } [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetOffsetRotation"), SuppressUnmanagedCodeSecurity] - public extern unsafe static Matrix3* GeomGetOffsetRotationUnsafe(IntPtr geom); - public static Matrix3 GeomGetOffsetRotation(IntPtr geom) + internal extern unsafe static Matrix3* GeomGetOffsetRotationUnsafe(IntPtr geom); + internal static Matrix3 GeomGetOffsetRotation(IntPtr geom) { unsafe { return *(GeomGetOffsetRotationUnsafe(geom)); } } [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetPosition"), SuppressUnmanagedCodeSecurity] - public extern unsafe static Vector3* GeomGetPositionUnsafe(IntPtr geom); - public static Vector3 GeomGetPosition(IntPtr geom) + internal extern unsafe static Vector3* GeomGetPositionUnsafe(IntPtr geom); + internal static Vector3 GeomGetPosition(IntPtr geom) { unsafe { return *(GeomGetPositionUnsafe(geom)); } } - public static OMV.Vector3 GeomGetPositionOMV(IntPtr geom) + internal static OMV.Vector3 GeomGetPositionOMV(IntPtr geom) { Vector3 vtmp = GeomGetPosition(geom); return new OMV.Vector3(vtmp.X, vtmp.Y, vtmp.Z); } [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetQuaternion"), SuppressUnmanagedCodeSecurity] - public static extern void GeomCopyQuaternion(IntPtr geom, out Quaternion q); - public static OMV.Quaternion GeomGetQuaternionOMV(IntPtr geom) + internal static extern void GeomCopyQuaternion(IntPtr geom, out Quaternion q); + internal static OMV.Quaternion GeomGetQuaternionOMV(IntPtr geom) { Quaternion qtmp; GeomCopyQuaternion(geom, out qtmp); @@ -940,393 +941,393 @@ namespace OdeAPI } [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetQuaternion"), SuppressUnmanagedCodeSecurity] - public static extern void GeomCopyQuaternion(IntPtr geom, out dReal X); + internal static extern void GeomCopyQuaternion(IntPtr geom, out dReal X); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetRotation"), SuppressUnmanagedCodeSecurity] - public extern unsafe static Matrix3* GeomGetRotationUnsafe(IntPtr geom); - public static Matrix3 GeomGetRotation(IntPtr geom) + internal extern unsafe static Matrix3* GeomGetRotationUnsafe(IntPtr geom); + internal static Matrix3 GeomGetRotation(IntPtr geom) { unsafe { return *(GeomGetRotationUnsafe(geom)); } } [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetSpace"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr GeomGetSpace(IntPtr geom); + internal static extern IntPtr GeomGetSpace(IntPtr geom); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomHeightfieldDataBuildByte"), SuppressUnmanagedCodeSecurity] - public static extern void GeomHeightfieldDataBuildByte(IntPtr d, byte[] pHeightData, int bCopyHeightData, + internal static extern void GeomHeightfieldDataBuildByte(IntPtr d, byte[] pHeightData, int bCopyHeightData, dReal width, dReal depth, int widthSamples, int depthSamples, dReal scale, dReal offset, dReal thickness, int bWrap); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomHeightfieldDataBuildByte"), SuppressUnmanagedCodeSecurity] - public static extern void GeomHeightfieldDataBuildByte(IntPtr d, IntPtr pHeightData, int bCopyHeightData, + internal static extern void GeomHeightfieldDataBuildByte(IntPtr d, IntPtr pHeightData, int bCopyHeightData, dReal width, dReal depth, int widthSamples, int depthSamples, dReal scale, dReal offset, dReal thickness, int bWrap); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomHeightfieldDataBuildCallback"), SuppressUnmanagedCodeSecurity] - public static extern void GeomHeightfieldDataBuildCallback(IntPtr d, IntPtr pUserData, HeightfieldGetHeight pCallback, + internal static extern void GeomHeightfieldDataBuildCallback(IntPtr d, IntPtr pUserData, HeightfieldGetHeight pCallback, dReal width, dReal depth, int widthSamples, int depthSamples, dReal scale, dReal offset, dReal thickness, int bWrap); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomHeightfieldDataBuildShort"), SuppressUnmanagedCodeSecurity] - public static extern void GeomHeightfieldDataBuildShort(IntPtr d, ushort[] pHeightData, int bCopyHeightData, + internal static extern void GeomHeightfieldDataBuildShort(IntPtr d, ushort[] pHeightData, int bCopyHeightData, dReal width, dReal depth, int widthSamples, int depthSamples, dReal scale, dReal offset, dReal thickness, int bWrap); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomHeightfieldDataBuildShort"), SuppressUnmanagedCodeSecurity] - public static extern void GeomHeightfieldDataBuildShort(IntPtr d, short[] pHeightData, int bCopyHeightData, + internal static extern void GeomHeightfieldDataBuildShort(IntPtr d, short[] pHeightData, int bCopyHeightData, dReal width, dReal depth, int widthSamples, int depthSamples, dReal scale, dReal offset, dReal thickness, int bWrap); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomHeightfieldDataBuildShort"), SuppressUnmanagedCodeSecurity] - public static extern void GeomHeightfieldDataBuildShort(IntPtr d, IntPtr pHeightData, int bCopyHeightData, + internal static extern void GeomHeightfieldDataBuildShort(IntPtr d, IntPtr pHeightData, int bCopyHeightData, dReal width, dReal depth, int widthSamples, int depthSamples, dReal scale, dReal offset, dReal thickness, int bWrap); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomHeightfieldDataBuildSingle"), SuppressUnmanagedCodeSecurity] - public static extern void GeomHeightfieldDataBuildSingle(IntPtr d, float[] pHeightData, int bCopyHeightData, + internal static extern void GeomHeightfieldDataBuildSingle(IntPtr d, float[] pHeightData, int bCopyHeightData, dReal width, dReal depth, int widthSamples, int depthSamples, dReal scale, dReal offset, dReal thickness, int bWrap); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomHeightfieldDataBuildSingle"), SuppressUnmanagedCodeSecurity] - public static extern void GeomHeightfieldDataBuildSingle(IntPtr d, IntPtr pHeightData, int bCopyHeightData, + internal static extern void GeomHeightfieldDataBuildSingle(IntPtr d, IntPtr pHeightData, int bCopyHeightData, dReal width, dReal depth, int widthSamples, int depthSamples, dReal scale, dReal offset, dReal thickness, int bWrap); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomHeightfieldDataBuildDouble"), SuppressUnmanagedCodeSecurity] - public static extern void GeomHeightfieldDataBuildDouble(IntPtr d, double[] pHeightData, int bCopyHeightData, + internal static extern void GeomHeightfieldDataBuildDouble(IntPtr d, double[] pHeightData, int bCopyHeightData, dReal width, dReal depth, int widthSamples, int depthSamples, dReal scale, dReal offset, dReal thickness, int bWrap); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomHeightfieldDataBuildDouble"), SuppressUnmanagedCodeSecurity] - public static extern void GeomHeightfieldDataBuildDouble(IntPtr d, IntPtr pHeightData, int bCopyHeightData, + internal static extern void GeomHeightfieldDataBuildDouble(IntPtr d, IntPtr pHeightData, int bCopyHeightData, dReal width, dReal depth, int widthSamples, int depthSamples, dReal scale, dReal offset, dReal thickness, int bWrap); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomHeightfieldDataCreate"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr GeomHeightfieldDataCreate(); + internal static extern IntPtr GeomHeightfieldDataCreate(); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomHeightfieldDataDestroy"), SuppressUnmanagedCodeSecurity] - public static extern void GeomHeightfieldDataDestroy(IntPtr d); + internal static extern void GeomHeightfieldDataDestroy(IntPtr d); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomHeightfieldDataSetBounds"), SuppressUnmanagedCodeSecurity] - public static extern void GeomHeightfieldDataSetBounds(IntPtr d, dReal minHeight, dReal maxHeight); + internal static extern void GeomHeightfieldDataSetBounds(IntPtr d, dReal minHeight, dReal maxHeight); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomHeightfieldGetHeightfieldData"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr GeomHeightfieldGetHeightfieldData(IntPtr g); + internal static extern IntPtr GeomHeightfieldGetHeightfieldData(IntPtr g); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomHeightfieldSetHeightfieldData"), SuppressUnmanagedCodeSecurity] - public static extern void GeomHeightfieldSetHeightfieldData(IntPtr g, IntPtr d); + internal static extern void GeomHeightfieldSetHeightfieldData(IntPtr g, IntPtr d); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomUbitTerrainDataBuild"), SuppressUnmanagedCodeSecurity] - public static extern void GeomOSTerrainDataBuild(IntPtr d, float[] pHeightData, int bCopyHeightData, + internal static extern void GeomOSTerrainDataBuild(IntPtr d, float[] pHeightData, int bCopyHeightData, dReal sampleSize, int widthSamples, int depthSamples, dReal offset, dReal thickness, int bWrap); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomOSTerrainDataBuild"), SuppressUnmanagedCodeSecurity] - public static extern void GeomOSTerrainDataBuild(IntPtr d, IntPtr pHeightData, int bCopyHeightData, + internal static extern void GeomOSTerrainDataBuild(IntPtr d, IntPtr pHeightData, int bCopyHeightData, dReal sampleSize, int widthSamples, int depthSamples, dReal thickness, int bWrap); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomOSTerrainDataCreate"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr GeomOSTerrainDataCreate(); + internal static extern IntPtr GeomOSTerrainDataCreate(); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomOSTerrainDataDestroy"), SuppressUnmanagedCodeSecurity] - public static extern void GeomOSTerrainDataDestroy(IntPtr d); + internal static extern void GeomOSTerrainDataDestroy(IntPtr d); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomOSTerrainDataSetBounds"), SuppressUnmanagedCodeSecurity] - public static extern void GeomOSTerrainDataSetBounds(IntPtr d, dReal minHeight, dReal maxHeight); + internal static extern void GeomOSTerrainDataSetBounds(IntPtr d, dReal minHeight, dReal maxHeight); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomOSTerrainGetHeightfieldData"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr GeomOSTerrainGetHeightfieldData(IntPtr g); + internal static extern IntPtr GeomOSTerrainGetHeightfieldData(IntPtr g); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomOSTerrainSetHeightfieldData"), SuppressUnmanagedCodeSecurity] - public static extern void GeomOSTerrainSetHeightfieldData(IntPtr g, IntPtr d); + internal static extern void GeomOSTerrainSetHeightfieldData(IntPtr g, IntPtr d); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomIsEnabled"), SuppressUnmanagedCodeSecurity] - public static extern bool GeomIsEnabled(IntPtr geom); + internal static extern bool GeomIsEnabled(IntPtr geom); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomIsOffset"), SuppressUnmanagedCodeSecurity] - public static extern bool GeomIsOffset(IntPtr geom); + internal static extern bool GeomIsOffset(IntPtr geom); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomIsSpace"), SuppressUnmanagedCodeSecurity] - public static extern bool GeomIsSpace(IntPtr geom); + internal static extern bool GeomIsSpace(IntPtr geom); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomPlaneGetParams"), SuppressUnmanagedCodeSecurity] - public static extern void GeomPlaneGetParams(IntPtr geom, ref Vector4 result); + internal static extern void GeomPlaneGetParams(IntPtr geom, ref Vector4 result); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomPlaneGetParams"), SuppressUnmanagedCodeSecurity] - public static extern void GeomPlaneGetParams(IntPtr geom, ref dReal A); + internal static extern void GeomPlaneGetParams(IntPtr geom, ref dReal A); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomPlanePointDepth"), SuppressUnmanagedCodeSecurity] - public static extern dReal GeomPlanePointDepth(IntPtr geom, dReal x, dReal y, dReal z); + internal static extern dReal GeomPlanePointDepth(IntPtr geom, dReal x, dReal y, dReal z); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomPlaneSetParams"), SuppressUnmanagedCodeSecurity] - public static extern void GeomPlaneSetParams(IntPtr plane, dReal a, dReal b, dReal c, dReal d); + internal static extern void GeomPlaneSetParams(IntPtr plane, dReal a, dReal b, dReal c, dReal d); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomRayGet"), SuppressUnmanagedCodeSecurity] - public static extern void GeomRayGet(IntPtr ray, ref Vector3 start, ref Vector3 dir); + internal static extern void GeomRayGet(IntPtr ray, ref Vector3 start, ref Vector3 dir); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomRayGet"), SuppressUnmanagedCodeSecurity] - public static extern void GeomRayGet(IntPtr ray, ref dReal startX, ref dReal dirX); + internal static extern void GeomRayGet(IntPtr ray, ref dReal startX, ref dReal dirX); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomRayGetClosestHit"), SuppressUnmanagedCodeSecurity] - public static extern int GeomRayGetClosestHit(IntPtr ray); + internal static extern int GeomRayGetClosestHit(IntPtr ray); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomRayGetLength"), SuppressUnmanagedCodeSecurity] - public static extern dReal GeomRayGetLength(IntPtr ray); + internal static extern dReal GeomRayGetLength(IntPtr ray); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomRayGetParams"), SuppressUnmanagedCodeSecurity] - public static extern dReal GeomRayGetParams(IntPtr g, out int firstContact, out int backfaceCull); + internal static extern dReal GeomRayGetParams(IntPtr g, out int firstContact, out int backfaceCull); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomRaySet"), SuppressUnmanagedCodeSecurity] - public static extern void GeomRaySet(IntPtr ray, dReal px, dReal py, dReal pz, dReal dx, dReal dy, dReal dz); + internal static extern void GeomRaySet(IntPtr ray, dReal px, dReal py, dReal pz, dReal dx, dReal dy, dReal dz); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomRaySetClosestHit"), SuppressUnmanagedCodeSecurity] - public static extern void GeomRaySetClosestHit(IntPtr ray, int closestHit); + internal static extern void GeomRaySetClosestHit(IntPtr ray, int closestHit); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomRaySetLength"), SuppressUnmanagedCodeSecurity] - public static extern void GeomRaySetLength(IntPtr ray, dReal length); + internal static extern void GeomRaySetLength(IntPtr ray, dReal length); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomRaySetParams"), SuppressUnmanagedCodeSecurity] - public static extern void GeomRaySetParams(IntPtr ray, int firstContact, int backfaceCull); + internal static extern void GeomRaySetParams(IntPtr ray, int firstContact, int backfaceCull); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetBody"), SuppressUnmanagedCodeSecurity] - public static extern void GeomSetBody(IntPtr geom, IntPtr body); + internal static extern void GeomSetBody(IntPtr geom, IntPtr body); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetCategoryBits"), SuppressUnmanagedCodeSecurity] - public static extern void GeomSetCategoryBits(IntPtr geom, uint bits); + internal static extern void GeomSetCategoryBits(IntPtr geom, uint bits); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetCollideBits"), SuppressUnmanagedCodeSecurity] - public static extern void GeomSetCollideBits(IntPtr geom, uint bits); + internal static extern void GeomSetCollideBits(IntPtr geom, uint bits); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetConvex"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr GeomSetConvex(IntPtr geom, dReal[] planes, int planeCount, dReal[] points, int pointCount, int[] polygons); + internal static extern IntPtr GeomSetConvex(IntPtr geom, dReal[] planes, int planeCount, dReal[] points, int pointCount, int[] polygons); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetData"), SuppressUnmanagedCodeSecurity] - public static extern void GeomSetData(IntPtr geom, IntPtr data); + internal static extern void GeomSetData(IntPtr geom, IntPtr data); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetOffsetPosition"), SuppressUnmanagedCodeSecurity] - public static extern void GeomSetOffsetPosition(IntPtr geom, dReal x, dReal y, dReal z); + internal static extern void GeomSetOffsetPosition(IntPtr geom, dReal x, dReal y, dReal z); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetOffsetQuaternion"), SuppressUnmanagedCodeSecurity] - public static extern void GeomSetOffsetQuaternion(IntPtr geom, ref Quaternion Q); + internal static extern void GeomSetOffsetQuaternion(IntPtr geom, ref Quaternion Q); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetOffsetQuaternion"), SuppressUnmanagedCodeSecurity] - public static extern void GeomSetOffsetQuaternion(IntPtr geom, ref dReal X); + internal static extern void GeomSetOffsetQuaternion(IntPtr geom, ref dReal X); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetOffsetRotation"), SuppressUnmanagedCodeSecurity] - public static extern void GeomSetOffsetRotation(IntPtr geom, ref Matrix3 R); + internal static extern void GeomSetOffsetRotation(IntPtr geom, ref Matrix3 R); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetOffsetRotation"), SuppressUnmanagedCodeSecurity] - public static extern void GeomSetOffsetRotation(IntPtr geom, ref dReal M00); + internal static extern void GeomSetOffsetRotation(IntPtr geom, ref dReal M00); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetOffsetWorldPosition"), SuppressUnmanagedCodeSecurity] - public static extern void GeomSetOffsetWorldPosition(IntPtr geom, dReal x, dReal y, dReal z); + internal static extern void GeomSetOffsetWorldPosition(IntPtr geom, dReal x, dReal y, dReal z); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetOffsetWorldQuaternion"), SuppressUnmanagedCodeSecurity] - public static extern void GeomSetOffsetWorldQuaternion(IntPtr geom, ref Quaternion Q); + internal static extern void GeomSetOffsetWorldQuaternion(IntPtr geom, ref Quaternion Q); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetOffsetWorldQuaternion"), SuppressUnmanagedCodeSecurity] - public static extern void GeomSetOffsetWorldQuaternion(IntPtr geom, ref dReal X); + internal static extern void GeomSetOffsetWorldQuaternion(IntPtr geom, ref dReal X); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetOffsetWorldRotation"), SuppressUnmanagedCodeSecurity] - public static extern void GeomSetOffsetWorldRotation(IntPtr geom, ref Matrix3 R); + internal static extern void GeomSetOffsetWorldRotation(IntPtr geom, ref Matrix3 R); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetOffsetWorldRotation"), SuppressUnmanagedCodeSecurity] - public static extern void GeomSetOffsetWorldRotation(IntPtr geom, ref dReal M00); + internal static extern void GeomSetOffsetWorldRotation(IntPtr geom, ref dReal M00); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetPosition"), SuppressUnmanagedCodeSecurity] - public static extern void GeomSetPosition(IntPtr geom, dReal x, dReal y, dReal z); + internal static extern void GeomSetPosition(IntPtr geom, dReal x, dReal y, dReal z); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetQuaternion"), SuppressUnmanagedCodeSecurity] - public static extern void GeomSetQuaternion(IntPtr geom, ref Quaternion quat); + internal static extern void GeomSetQuaternion(IntPtr geom, ref Quaternion quat); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetQuaternion"), SuppressUnmanagedCodeSecurity] - public static extern void GeomSetQuaternion(IntPtr geom, ref dReal w); + internal static extern void GeomSetQuaternion(IntPtr geom, ref dReal w); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetRotation"), SuppressUnmanagedCodeSecurity] - public static extern void GeomSetRotation(IntPtr geom, ref Matrix3 R); + internal static extern void GeomSetRotation(IntPtr geom, ref Matrix3 R); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSetRotation"), SuppressUnmanagedCodeSecurity] - public static extern void GeomSetRotation(IntPtr geom, ref dReal M00); + internal static extern void GeomSetRotation(IntPtr geom, ref dReal M00); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSphereGetRadius"), SuppressUnmanagedCodeSecurity] - public static extern dReal GeomSphereGetRadius(IntPtr geom); + internal static extern dReal GeomSphereGetRadius(IntPtr geom); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSpherePointDepth"), SuppressUnmanagedCodeSecurity] - public static extern dReal GeomSpherePointDepth(IntPtr geom, dReal x, dReal y, dReal z); + internal static extern dReal GeomSpherePointDepth(IntPtr geom, dReal x, dReal y, dReal z); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomSphereSetRadius"), SuppressUnmanagedCodeSecurity] - public static extern void GeomSphereSetRadius(IntPtr geom, dReal radius); + internal static extern void GeomSphereSetRadius(IntPtr geom, dReal radius); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTransformGetCleanup"), SuppressUnmanagedCodeSecurity] - public static extern int GeomTransformGetCleanup(IntPtr geom); + internal static extern int GeomTransformGetCleanup(IntPtr geom); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTransformGetGeom"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr GeomTransformGetGeom(IntPtr geom); + internal static extern IntPtr GeomTransformGetGeom(IntPtr geom); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTransformGetInfo"), SuppressUnmanagedCodeSecurity] - public static extern int GeomTransformGetInfo(IntPtr geom); + internal static extern int GeomTransformGetInfo(IntPtr geom); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTransformSetCleanup"), SuppressUnmanagedCodeSecurity] - public static extern void GeomTransformSetCleanup(IntPtr geom, int mode); + internal static extern void GeomTransformSetCleanup(IntPtr geom, int mode); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTransformSetGeom"), SuppressUnmanagedCodeSecurity] - public static extern void GeomTransformSetGeom(IntPtr geom, IntPtr obj); + internal static extern void GeomTransformSetGeom(IntPtr geom, IntPtr obj); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTransformSetInfo"), SuppressUnmanagedCodeSecurity] - public static extern void GeomTransformSetInfo(IntPtr geom, int info); + internal static extern void GeomTransformSetInfo(IntPtr geom, int info); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshDataBuildDouble"), SuppressUnmanagedCodeSecurity] - public static extern void GeomTriMeshDataBuildDouble(IntPtr d, + internal static extern void GeomTriMeshDataBuildDouble(IntPtr d, double[] vertices, int vertexStride, int vertexCount, int[] indices, int indexCount, int triStride); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshDataBuildDouble"), SuppressUnmanagedCodeSecurity] - public static extern void GeomTriMeshDataBuildDouble(IntPtr d, + internal static extern void GeomTriMeshDataBuildDouble(IntPtr d, IntPtr vertices, int vertexStride, int vertexCount, IntPtr indices, int indexCount, int triStride); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshDataBuildDouble1"), SuppressUnmanagedCodeSecurity] - public static extern void GeomTriMeshDataBuildDouble1(IntPtr d, + internal static extern void GeomTriMeshDataBuildDouble1(IntPtr d, double[] vertices, int vertexStride, int vertexCount, int[] indices, int indexCount, int triStride, double[] normals); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshDataBuildDouble1"), SuppressUnmanagedCodeSecurity] - public static extern void GeomTriMeshDataBuildDouble(IntPtr d, + internal static extern void GeomTriMeshDataBuildDouble(IntPtr d, IntPtr vertices, int vertexStride, int vertexCount, IntPtr indices, int indexCount, int triStride, IntPtr normals); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshDataBuildSimple"), SuppressUnmanagedCodeSecurity] - public static extern void GeomTriMeshDataBuildSingle(IntPtr d, + internal static extern void GeomTriMeshDataBuildSingle(IntPtr d, dReal[] vertices, int vertexStride, int vertexCount, int[] indices, int indexCount, int triStride); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshDataBuildSimple"), SuppressUnmanagedCodeSecurity] - public static extern void GeomTriMeshDataBuildSingle(IntPtr d, + internal static extern void GeomTriMeshDataBuildSingle(IntPtr d, IntPtr vertices, int vertexStride, int vertexCount, IntPtr indices, int indexCount, int triStride); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshDataBuildSimple1"), SuppressUnmanagedCodeSecurity] - public static extern void GeomTriMeshDataBuildSingle1(IntPtr d, + internal static extern void GeomTriMeshDataBuildSingle1(IntPtr d, dReal[] vertices, int vertexStride, int vertexCount, int[] indices, int indexCount, int triStride, dReal[] normals); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshDataBuildSimple1"), SuppressUnmanagedCodeSecurity] - public static extern void GeomTriMeshDataBuildSingle1(IntPtr d, + internal static extern void GeomTriMeshDataBuildSingle1(IntPtr d, IntPtr vertices, int vertexStride, int vertexCount, IntPtr indices, int indexCount, int triStride, IntPtr normals); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshDataBuildSingle"), SuppressUnmanagedCodeSecurity] - public static extern void GeomTriMeshDataBuildSimple(IntPtr d, + internal static extern void GeomTriMeshDataBuildSimple(IntPtr d, float[] vertices, int vertexStride, int vertexCount, int[] indices, int indexCount, int triStride); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshDataBuildSingle"), SuppressUnmanagedCodeSecurity] - public static extern void GeomTriMeshDataBuildSimple(IntPtr d, + internal static extern void GeomTriMeshDataBuildSimple(IntPtr d, IntPtr vertices, int vertexStride, int vertexCount, IntPtr indices, int indexCount, int triStride); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshDataBuildSingle1"), SuppressUnmanagedCodeSecurity] - public static extern void GeomTriMeshDataBuildSimple1(IntPtr d, + internal static extern void GeomTriMeshDataBuildSimple1(IntPtr d, float[] vertices, int vertexStride, int vertexCount, int[] indices, int indexCount, int triStride, float[] normals); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshDataBuildSingle1"), SuppressUnmanagedCodeSecurity] - public static extern void GeomTriMeshDataBuildSimple1(IntPtr d, + internal static extern void GeomTriMeshDataBuildSimple1(IntPtr d, IntPtr vertices, int vertexStride, int vertexCount, IntPtr indices, int indexCount, int triStride, IntPtr normals); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshClearTCCache"), SuppressUnmanagedCodeSecurity] - public static extern void GeomTriMeshClearTCCache(IntPtr g); + internal static extern void GeomTriMeshClearTCCache(IntPtr g); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshDataCreate"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr GeomTriMeshDataCreate(); + internal static extern IntPtr GeomTriMeshDataCreate(); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshDataDestroy"), SuppressUnmanagedCodeSecurity] - public static extern void GeomTriMeshDataDestroy(IntPtr d); + internal static extern void GeomTriMeshDataDestroy(IntPtr d); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshDataGet"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr GeomTriMeshDataGet(IntPtr d, int data_id); + internal static extern IntPtr GeomTriMeshDataGet(IntPtr d, int data_id); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshDataPreprocess"), SuppressUnmanagedCodeSecurity] - public static extern void GeomTriMeshDataPreprocess(IntPtr d); + internal static extern void GeomTriMeshDataPreprocess(IntPtr d); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshDataSet"), SuppressUnmanagedCodeSecurity] - public static extern void GeomTriMeshDataSet(IntPtr d, int data_id, IntPtr in_data); + internal static extern void GeomTriMeshDataSet(IntPtr d, int data_id, IntPtr in_data); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshDataUpdate"), SuppressUnmanagedCodeSecurity] - public static extern void GeomTriMeshDataUpdate(IntPtr d); + internal static extern void GeomTriMeshDataUpdate(IntPtr d); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshEnableTC"), SuppressUnmanagedCodeSecurity] - public static extern void GeomTriMeshEnableTC(IntPtr g, int geomClass, bool enable); + internal static extern void GeomTriMeshEnableTC(IntPtr g, int geomClass, bool enable); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshGetArrayCallback"), SuppressUnmanagedCodeSecurity] - public static extern TriArrayCallback GeomTriMeshGetArrayCallback(IntPtr g); + internal static extern TriArrayCallback GeomTriMeshGetArrayCallback(IntPtr g); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshGetCallback"), SuppressUnmanagedCodeSecurity] - public static extern TriCallback GeomTriMeshGetCallback(IntPtr g); + internal static extern TriCallback GeomTriMeshGetCallback(IntPtr g); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshGetData"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr GeomTriMeshGetData(IntPtr g); + internal static extern IntPtr GeomTriMeshGetData(IntPtr g); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshGetLastTransform"), SuppressUnmanagedCodeSecurity] - public extern unsafe static Matrix4* GeomTriMeshGetLastTransformUnsafe(IntPtr geom); - public static Matrix4 GeomTriMeshGetLastTransform(IntPtr geom) + internal extern unsafe static Matrix4* GeomTriMeshGetLastTransformUnsafe(IntPtr geom); + internal static Matrix4 GeomTriMeshGetLastTransform(IntPtr geom) { unsafe { return *(GeomTriMeshGetLastTransformUnsafe(geom)); } } [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshGetPoint"), SuppressUnmanagedCodeSecurity] - public extern static void GeomTriMeshGetPoint(IntPtr g, int index, dReal u, dReal v, ref Vector3 outVec); + internal extern static void GeomTriMeshGetPoint(IntPtr g, int index, dReal u, dReal v, ref Vector3 outVec); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshGetRayCallback"), SuppressUnmanagedCodeSecurity] - public static extern TriRayCallback GeomTriMeshGetRayCallback(IntPtr g); + internal static extern TriRayCallback GeomTriMeshGetRayCallback(IntPtr g); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshGetTriangle"), SuppressUnmanagedCodeSecurity] - public extern static void GeomTriMeshGetTriangle(IntPtr g, int index, ref Vector3 v0, ref Vector3 v1, ref Vector3 v2); + internal extern static void GeomTriMeshGetTriangle(IntPtr g, int index, ref Vector3 v0, ref Vector3 v1, ref Vector3 v2); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshGetTriangleCount"), SuppressUnmanagedCodeSecurity] - public extern static int GeomTriMeshGetTriangleCount(IntPtr g); + internal extern static int GeomTriMeshGetTriangleCount(IntPtr g); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshGetTriMeshDataID"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr GeomTriMeshGetTriMeshDataID(IntPtr g); + internal static extern IntPtr GeomTriMeshGetTriMeshDataID(IntPtr g); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshIsTCEnabled"), SuppressUnmanagedCodeSecurity] - public static extern bool GeomTriMeshIsTCEnabled(IntPtr g, int geomClass); + internal static extern bool GeomTriMeshIsTCEnabled(IntPtr g, int geomClass); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshSetArrayCallback"), SuppressUnmanagedCodeSecurity] - public static extern void GeomTriMeshSetArrayCallback(IntPtr g, TriArrayCallback arrayCallback); + internal static extern void GeomTriMeshSetArrayCallback(IntPtr g, TriArrayCallback arrayCallback); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshSetCallback"), SuppressUnmanagedCodeSecurity] - public static extern void GeomTriMeshSetCallback(IntPtr g, TriCallback callback); + internal static extern void GeomTriMeshSetCallback(IntPtr g, TriCallback callback); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshSetData"), SuppressUnmanagedCodeSecurity] - public static extern void GeomTriMeshSetData(IntPtr g, IntPtr data); + internal static extern void GeomTriMeshSetData(IntPtr g, IntPtr data); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshSetLastTransform"), SuppressUnmanagedCodeSecurity] - public static extern void GeomTriMeshSetLastTransform(IntPtr g, ref Matrix4 last_trans); + internal static extern void GeomTriMeshSetLastTransform(IntPtr g, ref Matrix4 last_trans); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshSetLastTransform"), SuppressUnmanagedCodeSecurity] - public static extern void GeomTriMeshSetLastTransform(IntPtr g, ref dReal M00); + internal static extern void GeomTriMeshSetLastTransform(IntPtr g, ref dReal M00); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomTriMeshSetRayCallback"), SuppressUnmanagedCodeSecurity] - public static extern void GeomTriMeshSetRayCallback(IntPtr g, TriRayCallback callback); + internal static extern void GeomTriMeshSetRayCallback(IntPtr g, TriRayCallback callback); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGetConfiguration"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr iGetConfiguration(); + internal static extern IntPtr iGetConfiguration(); - public static string GetConfiguration() + internal static string GetConfiguration() { IntPtr ptr = iGetConfiguration(); string s = Marshal.PtrToStringAnsi(ptr); @@ -1334,691 +1335,688 @@ namespace OdeAPI } [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dHashSpaceCreate"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr HashSpaceCreate(IntPtr space); + internal static extern IntPtr HashSpaceCreate(IntPtr space); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dHashSpaceGetLevels"), SuppressUnmanagedCodeSecurity] - public static extern void HashSpaceGetLevels(IntPtr space, out int minlevel, out int maxlevel); + internal static extern void HashSpaceGetLevels(IntPtr space, out int minlevel, out int maxlevel); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dHashSpaceSetLevels"), SuppressUnmanagedCodeSecurity] - public static extern void HashSpaceSetLevels(IntPtr space, int minlevel, int maxlevel); + internal static extern void HashSpaceSetLevels(IntPtr space, int minlevel, int maxlevel); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dInfiniteAABB"), SuppressUnmanagedCodeSecurity] - public static extern void InfiniteAABB(IntPtr geom, out AABB aabb); + internal static extern void InfiniteAABB(IntPtr geom, out AABB aabb); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dInitODE"), SuppressUnmanagedCodeSecurity] - public static extern void InitODE(); + internal static extern void InitODE(); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dInitODE2"), SuppressUnmanagedCodeSecurity] - public static extern int InitODE2(uint ODEInitFlags); + internal static extern int InitODE2(uint ODEInitFlags); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dIsPositiveDefinite"), SuppressUnmanagedCodeSecurity] - public static extern int IsPositiveDefinite(ref dReal A, int n); + internal static extern int IsPositiveDefinite(ref dReal A, int n); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dInvertPDMatrix"), SuppressUnmanagedCodeSecurity] - public static extern int InvertPDMatrix(ref dReal A, out dReal Ainv, int n); + internal static extern int InvertPDMatrix(ref dReal A, out dReal Ainv, int n); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointAddAMotorTorques"), SuppressUnmanagedCodeSecurity] - public static extern void JointAddAMotorTorques(IntPtr joint, dReal torque1, dReal torque2, dReal torque3); + internal static extern void JointAddAMotorTorques(IntPtr joint, dReal torque1, dReal torque2, dReal torque3); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointAddHingeTorque"), SuppressUnmanagedCodeSecurity] - public static extern void JointAddHingeTorque(IntPtr joint, dReal torque); + internal static extern void JointAddHingeTorque(IntPtr joint, dReal torque); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointAddHinge2Torque"), SuppressUnmanagedCodeSecurity] - public static extern void JointAddHinge2Torques(IntPtr joint, dReal torque1, dReal torque2); + internal static extern void JointAddHinge2Torques(IntPtr joint, dReal torque1, dReal torque2); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointAddPRTorque"), SuppressUnmanagedCodeSecurity] - public static extern void JointAddPRTorque(IntPtr joint, dReal torque); + internal static extern void JointAddPRTorque(IntPtr joint, dReal torque); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointAddUniversalTorque"), SuppressUnmanagedCodeSecurity] - public static extern void JointAddUniversalTorques(IntPtr joint, dReal torque1, dReal torque2); + internal static extern void JointAddUniversalTorques(IntPtr joint, dReal torque1, dReal torque2); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointAddSliderForce"), SuppressUnmanagedCodeSecurity] - public static extern void JointAddSliderForce(IntPtr joint, dReal force); + internal static extern void JointAddSliderForce(IntPtr joint, dReal force); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointAttach"), SuppressUnmanagedCodeSecurity] - public static extern void JointAttach(IntPtr joint, IntPtr body1, IntPtr body2); + internal static extern void JointAttach(IntPtr joint, IntPtr body1, IntPtr body2); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointCreateAMotor"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr JointCreateAMotor(IntPtr world, IntPtr group); + internal static extern IntPtr JointCreateAMotor(IntPtr world, IntPtr group); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointCreateBall"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr JointCreateBall(IntPtr world, IntPtr group); + internal static extern IntPtr JointCreateBall(IntPtr world, IntPtr group); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointCreateContact"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr JointCreateContact(IntPtr world, IntPtr group, ref Contact contact); + internal static extern IntPtr JointCreateContact(IntPtr world, IntPtr group, ref Contact contact); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointCreateContact"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr JointCreateContactPtr(IntPtr world, IntPtr group, IntPtr contact); + internal static extern IntPtr JointCreateContactPtr(IntPtr world, IntPtr group, IntPtr contact); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointCreateFixed"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr JointCreateFixed(IntPtr world, IntPtr group); + internal static extern IntPtr JointCreateFixed(IntPtr world, IntPtr group); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointCreateHinge"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr JointCreateHinge(IntPtr world, IntPtr group); + internal static extern IntPtr JointCreateHinge(IntPtr world, IntPtr group); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointCreateHinge2"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr JointCreateHinge2(IntPtr world, IntPtr group); + internal static extern IntPtr JointCreateHinge2(IntPtr world, IntPtr group); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointCreateLMotor"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr JointCreateLMotor(IntPtr world, IntPtr group); + internal static extern IntPtr JointCreateLMotor(IntPtr world, IntPtr group); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointCreateNull"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr JointCreateNull(IntPtr world, IntPtr group); + internal static extern IntPtr JointCreateNull(IntPtr world, IntPtr group); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointCreatePR"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr JointCreatePR(IntPtr world, IntPtr group); + internal static extern IntPtr JointCreatePR(IntPtr world, IntPtr group); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointCreatePlane2D"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr JointCreatePlane2D(IntPtr world, IntPtr group); + internal static extern IntPtr JointCreatePlane2D(IntPtr world, IntPtr group); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointCreateSlider"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr JointCreateSlider(IntPtr world, IntPtr group); + internal static extern IntPtr JointCreateSlider(IntPtr world, IntPtr group); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointCreateUniversal"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr JointCreateUniversal(IntPtr world, IntPtr group); + internal static extern IntPtr JointCreateUniversal(IntPtr world, IntPtr group); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointDestroy"), SuppressUnmanagedCodeSecurity] - public static extern void JointDestroy(IntPtr j); + internal static extern void JointDestroy(IntPtr j); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetAMotorAngle"), SuppressUnmanagedCodeSecurity] - public static extern dReal JointGetAMotorAngle(IntPtr j, int anum); + internal static extern dReal JointGetAMotorAngle(IntPtr j, int anum); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetAMotorAngleRate"), SuppressUnmanagedCodeSecurity] - public static extern dReal JointGetAMotorAngleRate(IntPtr j, int anum); + internal static extern dReal JointGetAMotorAngleRate(IntPtr j, int anum); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetAMotorAxis"), SuppressUnmanagedCodeSecurity] - public static extern void JointGetAMotorAxis(IntPtr j, int anum, out Vector3 result); + internal static extern void JointGetAMotorAxis(IntPtr j, int anum, out Vector3 result); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetAMotorAxisRel"), SuppressUnmanagedCodeSecurity] - public static extern int JointGetAMotorAxisRel(IntPtr j, int anum); + internal static extern int JointGetAMotorAxisRel(IntPtr j, int anum); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetAMotorMode"), SuppressUnmanagedCodeSecurity] - public static extern int JointGetAMotorMode(IntPtr j); + internal static extern int JointGetAMotorMode(IntPtr j); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetAMotorNumAxes"), SuppressUnmanagedCodeSecurity] - public static extern int JointGetAMotorNumAxes(IntPtr j); + internal static extern int JointGetAMotorNumAxes(IntPtr j); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetAMotorParam"), SuppressUnmanagedCodeSecurity] - public static extern dReal JointGetAMotorParam(IntPtr j, int parameter); + internal static extern dReal JointGetAMotorParam(IntPtr j, int parameter); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetBallAnchor"), SuppressUnmanagedCodeSecurity] - public static extern void JointGetBallAnchor(IntPtr j, out Vector3 result); + internal static extern void JointGetBallAnchor(IntPtr j, out Vector3 result); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetBallAnchor2"), SuppressUnmanagedCodeSecurity] - public static extern void JointGetBallAnchor2(IntPtr j, out Vector3 result); + internal static extern void JointGetBallAnchor2(IntPtr j, out Vector3 result); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetBody"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr JointGetBody(IntPtr j); + internal static extern IntPtr JointGetBody(IntPtr j); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetData"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr JointGetData(IntPtr j); + internal static extern IntPtr JointGetData(IntPtr j); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetFeedback"), SuppressUnmanagedCodeSecurity] - public extern unsafe static JointFeedback* JointGetFeedbackUnsafe(IntPtr j); - public static JointFeedback JointGetFeedback(IntPtr j) + internal extern unsafe static JointFeedback* JointGetFeedbackUnsafe(IntPtr j); + internal static JointFeedback JointGetFeedback(IntPtr j) { unsafe { return *(JointGetFeedbackUnsafe(j)); } } [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetHingeAnchor"), SuppressUnmanagedCodeSecurity] - public static extern void JointGetHingeAnchor(IntPtr j, out Vector3 result); + internal static extern void JointGetHingeAnchor(IntPtr j, out Vector3 result); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetHingeAngle"), SuppressUnmanagedCodeSecurity] - public static extern dReal JointGetHingeAngle(IntPtr j); + internal static extern dReal JointGetHingeAngle(IntPtr j); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetHingeAngleRate"), SuppressUnmanagedCodeSecurity] - public static extern dReal JointGetHingeAngleRate(IntPtr j); + internal static extern dReal JointGetHingeAngleRate(IntPtr j); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetHingeAxis"), SuppressUnmanagedCodeSecurity] - public static extern void JointGetHingeAxis(IntPtr j, out Vector3 result); + internal static extern void JointGetHingeAxis(IntPtr j, out Vector3 result); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetHingeParam"), SuppressUnmanagedCodeSecurity] - public static extern dReal JointGetHingeParam(IntPtr j, int parameter); + internal static extern dReal JointGetHingeParam(IntPtr j, int parameter); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetHinge2Angle1"), SuppressUnmanagedCodeSecurity] - public static extern dReal JointGetHinge2Angle1(IntPtr j); + internal static extern dReal JointGetHinge2Angle1(IntPtr j); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetHinge2Angle1Rate"), SuppressUnmanagedCodeSecurity] - public static extern dReal JointGetHinge2Angle1Rate(IntPtr j); + internal static extern dReal JointGetHinge2Angle1Rate(IntPtr j); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetHinge2Angle2Rate"), SuppressUnmanagedCodeSecurity] - public static extern dReal JointGetHinge2Angle2Rate(IntPtr j); + internal static extern dReal JointGetHinge2Angle2Rate(IntPtr j); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetHingeAnchor2"), SuppressUnmanagedCodeSecurity] - public static extern void JointGetHingeAnchor2(IntPtr j, out Vector3 result); + internal static extern void JointGetHingeAnchor2(IntPtr j, out Vector3 result); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetHinge2Anchor"), SuppressUnmanagedCodeSecurity] - public static extern void JointGetHinge2Anchor(IntPtr j, out Vector3 result); + internal static extern void JointGetHinge2Anchor(IntPtr j, out Vector3 result); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetHinge2Anchor2"), SuppressUnmanagedCodeSecurity] - public static extern void JointGetHinge2Anchor2(IntPtr j, out Vector3 result); + internal static extern void JointGetHinge2Anchor2(IntPtr j, out Vector3 result); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetHinge2Axis1"), SuppressUnmanagedCodeSecurity] - public static extern void JointGetHinge2Axis1(IntPtr j, out Vector3 result); + internal static extern void JointGetHinge2Axis1(IntPtr j, out Vector3 result); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetHinge2Axis2"), SuppressUnmanagedCodeSecurity] - public static extern void JointGetHinge2Axis2(IntPtr j, out Vector3 result); + internal static extern void JointGetHinge2Axis2(IntPtr j, out Vector3 result); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetHinge2Param"), SuppressUnmanagedCodeSecurity] - public static extern dReal JointGetHinge2Param(IntPtr j, int parameter); + internal static extern dReal JointGetHinge2Param(IntPtr j, int parameter); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetLMotorAxis"), SuppressUnmanagedCodeSecurity] - public static extern void JointGetLMotorAxis(IntPtr j, int anum, out Vector3 result); + internal static extern void JointGetLMotorAxis(IntPtr j, int anum, out Vector3 result); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetLMotorNumAxes"), SuppressUnmanagedCodeSecurity] - public static extern int JointGetLMotorNumAxes(IntPtr j); + internal static extern int JointGetLMotorNumAxes(IntPtr j); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetLMotorParam"), SuppressUnmanagedCodeSecurity] - public static extern dReal JointGetLMotorParam(IntPtr j, int parameter); + internal static extern dReal JointGetLMotorParam(IntPtr j, int parameter); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetPRAnchor"), SuppressUnmanagedCodeSecurity] - public static extern void JointGetPRAnchor(IntPtr j, out Vector3 result); + internal static extern void JointGetPRAnchor(IntPtr j, out Vector3 result); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetPRAxis1"), SuppressUnmanagedCodeSecurity] - public static extern void JointGetPRAxis1(IntPtr j, out Vector3 result); + internal static extern void JointGetPRAxis1(IntPtr j, out Vector3 result); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetPRAxis2"), SuppressUnmanagedCodeSecurity] - public static extern void JointGetPRAxis2(IntPtr j, out Vector3 result); + internal static extern void JointGetPRAxis2(IntPtr j, out Vector3 result); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetPRParam"), SuppressUnmanagedCodeSecurity] - public static extern dReal JointGetPRParam(IntPtr j, int parameter); + internal static extern dReal JointGetPRParam(IntPtr j, int parameter); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetPRPosition"), SuppressUnmanagedCodeSecurity] - public static extern dReal JointGetPRPosition(IntPtr j); + internal static extern dReal JointGetPRPosition(IntPtr j); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetPRPositionRate"), SuppressUnmanagedCodeSecurity] - public static extern dReal JointGetPRPositionRate(IntPtr j); + internal static extern dReal JointGetPRPositionRate(IntPtr j); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetSliderAxis"), SuppressUnmanagedCodeSecurity] - public static extern void JointGetSliderAxis(IntPtr j, out Vector3 result); + internal static extern void JointGetSliderAxis(IntPtr j, out Vector3 result); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetSliderParam"), SuppressUnmanagedCodeSecurity] - public static extern dReal JointGetSliderParam(IntPtr j, int parameter); + internal static extern dReal JointGetSliderParam(IntPtr j, int parameter); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetSliderPosition"), SuppressUnmanagedCodeSecurity] - public static extern dReal JointGetSliderPosition(IntPtr j); + internal static extern dReal JointGetSliderPosition(IntPtr j); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetSliderPositionRate"), SuppressUnmanagedCodeSecurity] - public static extern dReal JointGetSliderPositionRate(IntPtr j); + internal static extern dReal JointGetSliderPositionRate(IntPtr j); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetType"), SuppressUnmanagedCodeSecurity] - public static extern JointType JointGetType(IntPtr j); + internal static extern JointType JointGetType(IntPtr j); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetUniversalAnchor"), SuppressUnmanagedCodeSecurity] - public static extern void JointGetUniversalAnchor(IntPtr j, out Vector3 result); + internal static extern void JointGetUniversalAnchor(IntPtr j, out Vector3 result); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetUniversalAnchor2"), SuppressUnmanagedCodeSecurity] - public static extern void JointGetUniversalAnchor2(IntPtr j, out Vector3 result); + internal static extern void JointGetUniversalAnchor2(IntPtr j, out Vector3 result); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetUniversalAngle1"), SuppressUnmanagedCodeSecurity] - public static extern dReal JointGetUniversalAngle1(IntPtr j); + internal static extern dReal JointGetUniversalAngle1(IntPtr j); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetUniversalAngle1Rate"), SuppressUnmanagedCodeSecurity] - public static extern dReal JointGetUniversalAngle1Rate(IntPtr j); + internal static extern dReal JointGetUniversalAngle1Rate(IntPtr j); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetUniversalAngle2"), SuppressUnmanagedCodeSecurity] - public static extern dReal JointGetUniversalAngle2(IntPtr j); + internal static extern dReal JointGetUniversalAngle2(IntPtr j); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetUniversalAngle2Rate"), SuppressUnmanagedCodeSecurity] - public static extern dReal JointGetUniversalAngle2Rate(IntPtr j); + internal static extern dReal JointGetUniversalAngle2Rate(IntPtr j); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetUniversalAngles"), SuppressUnmanagedCodeSecurity] - public static extern void JointGetUniversalAngles(IntPtr j, out dReal angle1, out dReal angle2); + internal static extern void JointGetUniversalAngles(IntPtr j, out dReal angle1, out dReal angle2); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetUniversalAxis1"), SuppressUnmanagedCodeSecurity] - public static extern void JointGetUniversalAxis1(IntPtr j, out Vector3 result); + internal static extern void JointGetUniversalAxis1(IntPtr j, out Vector3 result); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetUniversalAxis2"), SuppressUnmanagedCodeSecurity] - public static extern void JointGetUniversalAxis2(IntPtr j, out Vector3 result); + internal static extern void JointGetUniversalAxis2(IntPtr j, out Vector3 result); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGetUniversalParam"), SuppressUnmanagedCodeSecurity] - public static extern dReal JointGetUniversalParam(IntPtr j, int parameter); + internal static extern dReal JointGetUniversalParam(IntPtr j, int parameter); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGroupCreate"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr JointGroupCreate(int max_size); + internal static extern IntPtr JointGroupCreate(int max_size); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGroupDestroy"), SuppressUnmanagedCodeSecurity] - public static extern void JointGroupDestroy(IntPtr group); + internal static extern void JointGroupDestroy(IntPtr group); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointGroupEmpty"), SuppressUnmanagedCodeSecurity] - public static extern void JointGroupEmpty(IntPtr group); + internal static extern void JointGroupEmpty(IntPtr group); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetAMotorAngle"), SuppressUnmanagedCodeSecurity] - public static extern void JointSetAMotorAngle(IntPtr j, int anum, dReal angle); + internal static extern void JointSetAMotorAngle(IntPtr j, int anum, dReal angle); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetAMotorAxis"), SuppressUnmanagedCodeSecurity] - public static extern void JointSetAMotorAxis(IntPtr j, int anum, int rel, dReal x, dReal y, dReal z); + internal static extern void JointSetAMotorAxis(IntPtr j, int anum, int rel, dReal x, dReal y, dReal z); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetAMotorMode"), SuppressUnmanagedCodeSecurity] - public static extern void JointSetAMotorMode(IntPtr j, int mode); + internal static extern void JointSetAMotorMode(IntPtr j, int mode); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetAMotorNumAxes"), SuppressUnmanagedCodeSecurity] - public static extern void JointSetAMotorNumAxes(IntPtr group, int num); + internal static extern void JointSetAMotorNumAxes(IntPtr group, int num); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetAMotorParam"), SuppressUnmanagedCodeSecurity] - public static extern void JointSetAMotorParam(IntPtr group, int parameter, dReal value); + internal static extern void JointSetAMotorParam(IntPtr group, int parameter, dReal value); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetBallAnchor"), SuppressUnmanagedCodeSecurity] - public static extern void JointSetBallAnchor(IntPtr j, dReal x, dReal y, dReal z); + internal static extern void JointSetBallAnchor(IntPtr j, dReal x, dReal y, dReal z); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetBallAnchor2"), SuppressUnmanagedCodeSecurity] - public static extern void JointSetBallAnchor2(IntPtr j, dReal x, dReal y, dReal z); + internal static extern void JointSetBallAnchor2(IntPtr j, dReal x, dReal y, dReal z); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetData"), SuppressUnmanagedCodeSecurity] - public static extern void JointSetData(IntPtr j, IntPtr data); + internal static extern void JointSetData(IntPtr j, IntPtr data); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetFeedback"), SuppressUnmanagedCodeSecurity] - public static extern void JointSetFeedback(IntPtr j, out JointFeedback feedback); + internal static extern void JointSetFeedback(IntPtr j, out JointFeedback feedback); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetFixed"), SuppressUnmanagedCodeSecurity] - public static extern void JointSetFixed(IntPtr j); + internal static extern void JointSetFixed(IntPtr j); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetHingeAnchor"), SuppressUnmanagedCodeSecurity] - public static extern void JointSetHingeAnchor(IntPtr j, dReal x, dReal y, dReal z); + internal static extern void JointSetHingeAnchor(IntPtr j, dReal x, dReal y, dReal z); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetHingeAnchorDelta"), SuppressUnmanagedCodeSecurity] - public static extern void JointSetHingeAnchorDelta(IntPtr j, dReal x, dReal y, dReal z, dReal ax, dReal ay, dReal az); + internal static extern void JointSetHingeAnchorDelta(IntPtr j, dReal x, dReal y, dReal z, dReal ax, dReal ay, dReal az); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetHingeAxis"), SuppressUnmanagedCodeSecurity] - public static extern void JointSetHingeAxis(IntPtr j, dReal x, dReal y, dReal z); + internal static extern void JointSetHingeAxis(IntPtr j, dReal x, dReal y, dReal z); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetHingeParam"), SuppressUnmanagedCodeSecurity] - public static extern void JointSetHingeParam(IntPtr j, int parameter, dReal value); + internal static extern void JointSetHingeParam(IntPtr j, int parameter, dReal value); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetHinge2Anchor"), SuppressUnmanagedCodeSecurity] - public static extern void JointSetHinge2Anchor(IntPtr j, dReal x, dReal y, dReal z); + internal static extern void JointSetHinge2Anchor(IntPtr j, dReal x, dReal y, dReal z); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetHinge2Axis1"), SuppressUnmanagedCodeSecurity] - public static extern void JointSetHinge2Axis1(IntPtr j, dReal x, dReal y, dReal z); + internal static extern void JointSetHinge2Axis1(IntPtr j, dReal x, dReal y, dReal z); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetHinge2Axis2"), SuppressUnmanagedCodeSecurity] - public static extern void JointSetHinge2Axis2(IntPtr j, dReal x, dReal y, dReal z); + internal static extern void JointSetHinge2Axis2(IntPtr j, dReal x, dReal y, dReal z); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetHinge2Param"), SuppressUnmanagedCodeSecurity] - public static extern void JointSetHinge2Param(IntPtr j, int parameter, dReal value); + internal static extern void JointSetHinge2Param(IntPtr j, int parameter, dReal value); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetLMotorAxis"), SuppressUnmanagedCodeSecurity] - public static extern void JointSetLMotorAxis(IntPtr j, int anum, int rel, dReal x, dReal y, dReal z); + internal static extern void JointSetLMotorAxis(IntPtr j, int anum, int rel, dReal x, dReal y, dReal z); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetLMotorNumAxes"), SuppressUnmanagedCodeSecurity] - public static extern void JointSetLMotorNumAxes(IntPtr j, int num); + internal static extern void JointSetLMotorNumAxes(IntPtr j, int num); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetLMotorParam"), SuppressUnmanagedCodeSecurity] - public static extern void JointSetLMotorParam(IntPtr j, int parameter, dReal value); + internal static extern void JointSetLMotorParam(IntPtr j, int parameter, dReal value); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetPlane2DAngleParam"), SuppressUnmanagedCodeSecurity] - public static extern void JointSetPlane2DAngleParam(IntPtr j, int parameter, dReal value); + internal static extern void JointSetPlane2DAngleParam(IntPtr j, int parameter, dReal value); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetPlane2DXParam"), SuppressUnmanagedCodeSecurity] - public static extern void JointSetPlane2DXParam(IntPtr j, int parameter, dReal value); + internal static extern void JointSetPlane2DXParam(IntPtr j, int parameter, dReal value); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetPlane2DYParam"), SuppressUnmanagedCodeSecurity] - public static extern void JointSetPlane2DYParam(IntPtr j, int parameter, dReal value); + internal static extern void JointSetPlane2DYParam(IntPtr j, int parameter, dReal value); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetPRAnchor"), SuppressUnmanagedCodeSecurity] - public static extern void JointSetPRAnchor(IntPtr j, dReal x, dReal y, dReal z); + internal static extern void JointSetPRAnchor(IntPtr j, dReal x, dReal y, dReal z); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetPRAxis1"), SuppressUnmanagedCodeSecurity] - public static extern void JointSetPRAxis1(IntPtr j, dReal x, dReal y, dReal z); + internal static extern void JointSetPRAxis1(IntPtr j, dReal x, dReal y, dReal z); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetPRAxis2"), SuppressUnmanagedCodeSecurity] - public static extern void JointSetPRAxis2(IntPtr j, dReal x, dReal y, dReal z); + internal static extern void JointSetPRAxis2(IntPtr j, dReal x, dReal y, dReal z); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetPRParam"), SuppressUnmanagedCodeSecurity] - public static extern void JointSetPRParam(IntPtr j, int parameter, dReal value); + internal static extern void JointSetPRParam(IntPtr j, int parameter, dReal value); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetSliderAxis"), SuppressUnmanagedCodeSecurity] - public static extern void JointSetSliderAxis(IntPtr j, dReal x, dReal y, dReal z); + internal static extern void JointSetSliderAxis(IntPtr j, dReal x, dReal y, dReal z); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetSliderAxisDelta"), SuppressUnmanagedCodeSecurity] - public static extern void JointSetSliderAxisDelta(IntPtr j, dReal x, dReal y, dReal z, dReal ax, dReal ay, dReal az); + internal static extern void JointSetSliderAxisDelta(IntPtr j, dReal x, dReal y, dReal z, dReal ax, dReal ay, dReal az); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetSliderParam"), SuppressUnmanagedCodeSecurity] - public static extern void JointSetSliderParam(IntPtr j, int parameter, dReal value); + internal static extern void JointSetSliderParam(IntPtr j, int parameter, dReal value); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetUniversalAnchor"), SuppressUnmanagedCodeSecurity] - public static extern void JointSetUniversalAnchor(IntPtr j, dReal x, dReal y, dReal z); + internal static extern void JointSetUniversalAnchor(IntPtr j, dReal x, dReal y, dReal z); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetUniversalAxis1"), SuppressUnmanagedCodeSecurity] - public static extern void JointSetUniversalAxis1(IntPtr j, dReal x, dReal y, dReal z); + internal static extern void JointSetUniversalAxis1(IntPtr j, dReal x, dReal y, dReal z); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetUniversalAxis2"), SuppressUnmanagedCodeSecurity] - public static extern void JointSetUniversalAxis2(IntPtr j, dReal x, dReal y, dReal z); + internal static extern void JointSetUniversalAxis2(IntPtr j, dReal x, dReal y, dReal z); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dJointSetUniversalParam"), SuppressUnmanagedCodeSecurity] - public static extern void JointSetUniversalParam(IntPtr j, int parameter, dReal value); + internal static extern void JointSetUniversalParam(IntPtr j, int parameter, dReal value); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dLDLTAddTL"), SuppressUnmanagedCodeSecurity] - public static extern void LDLTAddTL(ref dReal L, ref dReal d, ref dReal a, int n, int nskip); + internal static extern void LDLTAddTL(ref dReal L, ref dReal d, ref dReal a, int n, int nskip); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMassAdd"), SuppressUnmanagedCodeSecurity] - public static extern void MassAdd(ref Mass a, ref Mass b); + internal static extern void MassAdd(ref Mass a, ref Mass b); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMassAdjust"), SuppressUnmanagedCodeSecurity] - public static extern void MassAdjust(ref Mass m, dReal newmass); + internal static extern void MassAdjust(ref Mass m, dReal newmass); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMassCheck"), SuppressUnmanagedCodeSecurity] - public static extern bool MassCheck(ref Mass m); + internal static extern bool MassCheck(ref Mass m); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMassRotate"), SuppressUnmanagedCodeSecurity] - public static extern void MassRotate(ref Mass mass, ref Matrix3 R); + internal static extern void MassRotate(ref Mass mass, ref Matrix3 R); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMassRotate"), SuppressUnmanagedCodeSecurity] - public static extern void MassRotate(ref Mass mass, ref dReal M00); + internal static extern void MassRotate(ref Mass mass, ref dReal M00); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMassSetBox"), SuppressUnmanagedCodeSecurity] - public static extern void MassSetBox(out Mass mass, dReal density, dReal lx, dReal ly, dReal lz); + internal static extern void MassSetBox(out Mass mass, dReal density, dReal lx, dReal ly, dReal lz); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMassSetBoxTotal"), SuppressUnmanagedCodeSecurity] - public static extern void MassSetBoxTotal(out Mass mass, dReal total_mass, dReal lx, dReal ly, dReal lz); + internal static extern void MassSetBoxTotal(out Mass mass, dReal total_mass, dReal lx, dReal ly, dReal lz); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMassSetCapsule"), SuppressUnmanagedCodeSecurity] - public static extern void MassSetCapsule(out Mass mass, dReal density, int direction, dReal radius, dReal length); + internal static extern void MassSetCapsule(out Mass mass, dReal density, int direction, dReal radius, dReal length); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMassSetCapsuleTotal"), SuppressUnmanagedCodeSecurity] - public static extern void MassSetCapsuleTotal(out Mass mass, dReal total_mass, int direction, dReal radius, dReal length); + internal static extern void MassSetCapsuleTotal(out Mass mass, dReal total_mass, int direction, dReal radius, dReal length); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMassSetCylinder"), SuppressUnmanagedCodeSecurity] - public static extern void MassSetCylinder(out Mass mass, dReal density, int direction, dReal radius, dReal length); + internal static extern void MassSetCylinder(out Mass mass, dReal density, int direction, dReal radius, dReal length); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMassSetCylinderTotal"), SuppressUnmanagedCodeSecurity] - public static extern void MassSetCylinderTotal(out Mass mass, dReal total_mass, int direction, dReal radius, dReal length); + internal static extern void MassSetCylinderTotal(out Mass mass, dReal total_mass, int direction, dReal radius, dReal length); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMassSetParameters"), SuppressUnmanagedCodeSecurity] - public static extern void MassSetParameters(out Mass mass, dReal themass, + internal static extern void MassSetParameters(out Mass mass, dReal themass, dReal cgx, dReal cgy, dReal cgz, dReal i11, dReal i22, dReal i33, dReal i12, dReal i13, dReal i23); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMassSetSphere"), SuppressUnmanagedCodeSecurity] - public static extern void MassSetSphere(out Mass mass, dReal density, dReal radius); + internal static extern void MassSetSphere(out Mass mass, dReal density, dReal radius); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMassSetSphereTotal"), SuppressUnmanagedCodeSecurity] - public static extern void dMassSetSphereTotal(out Mass mass, dReal total_mass, dReal radius); + internal static extern void dMassSetSphereTotal(out Mass mass, dReal total_mass, dReal radius); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMassSetTrimesh"), SuppressUnmanagedCodeSecurity] - public static extern void MassSetTrimesh(out Mass mass, dReal density, IntPtr g); + internal static extern void MassSetTrimesh(out Mass mass, dReal density, IntPtr g); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMassSetZero"), SuppressUnmanagedCodeSecurity] - public static extern void MassSetZero(out Mass mass); + internal static extern void MassSetZero(out Mass mass); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMassTranslate"), SuppressUnmanagedCodeSecurity] - public static extern void MassTranslate(ref Mass mass, dReal x, dReal y, dReal z); + internal static extern void MassTranslate(ref Mass mass, dReal x, dReal y, dReal z); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMultiply0"), SuppressUnmanagedCodeSecurity] - public static extern void Multiply0(out dReal A00, ref dReal B00, ref dReal C00, int p, int q, int r); + internal static extern void Multiply0(out dReal A00, ref dReal B00, ref dReal C00, int p, int q, int r); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMultiply0"), SuppressUnmanagedCodeSecurity] private static extern void MultiplyiM3V3(out Vector3 vout, ref Matrix3 matrix, ref Vector3 vect,int p, int q, int r); - public static void MultiplyM3V3(out Vector3 outvector, ref Matrix3 matrix, ref Vector3 invector) + internal static void MultiplyM3V3(out Vector3 outvector, ref Matrix3 matrix, ref Vector3 invector) { MultiplyiM3V3(out outvector, ref matrix, ref invector, 3, 3, 1); } [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMultiply1"), SuppressUnmanagedCodeSecurity] - public static extern void Multiply1(out dReal A00, ref dReal B00, ref dReal C00, int p, int q, int r); + internal static extern void Multiply1(out dReal A00, ref dReal B00, ref dReal C00, int p, int q, int r); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dMultiply2"), SuppressUnmanagedCodeSecurity] - public static extern void Multiply2(out dReal A00, ref dReal B00, ref dReal C00, int p, int q, int r); + internal static extern void Multiply2(out dReal A00, ref dReal B00, ref dReal C00, int p, int q, int r); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dQFromAxisAndAngle"), SuppressUnmanagedCodeSecurity] - public static extern void QFromAxisAndAngle(out Quaternion q, dReal ax, dReal ay, dReal az, dReal angle); + internal static extern void QFromAxisAndAngle(out Quaternion q, dReal ax, dReal ay, dReal az, dReal angle); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dQfromR"), SuppressUnmanagedCodeSecurity] - public static extern void QfromR(out Quaternion q, ref Matrix3 R); + internal static extern void QfromR(out Quaternion q, ref Matrix3 R); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dQMultiply0"), SuppressUnmanagedCodeSecurity] - public static extern void QMultiply0(out Quaternion qa, ref Quaternion qb, ref Quaternion qc); + internal static extern void QMultiply0(out Quaternion qa, ref Quaternion qb, ref Quaternion qc); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dQMultiply1"), SuppressUnmanagedCodeSecurity] - public static extern void QMultiply1(out Quaternion qa, ref Quaternion qb, ref Quaternion qc); + internal static extern void QMultiply1(out Quaternion qa, ref Quaternion qb, ref Quaternion qc); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dQMultiply2"), SuppressUnmanagedCodeSecurity] - public static extern void QMultiply2(out Quaternion qa, ref Quaternion qb, ref Quaternion qc); + internal static extern void QMultiply2(out Quaternion qa, ref Quaternion qb, ref Quaternion qc); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dQMultiply3"), SuppressUnmanagedCodeSecurity] - public static extern void QMultiply3(out Quaternion qa, ref Quaternion qb, ref Quaternion qc); + internal static extern void QMultiply3(out Quaternion qa, ref Quaternion qb, ref Quaternion qc); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dQSetIdentity"), SuppressUnmanagedCodeSecurity] - public static extern void QSetIdentity(out Quaternion q); + internal static extern void QSetIdentity(out Quaternion q); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dQuadTreeSpaceCreate"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr QuadTreeSpaceCreate(IntPtr space, ref Vector3 center, ref Vector3 extents, int depth); + internal static extern IntPtr QuadTreeSpaceCreate(IntPtr space, ref Vector3 center, ref Vector3 extents, int depth); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dQuadTreeSpaceCreate"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr QuadTreeSpaceCreate(IntPtr space, ref dReal centerX, ref dReal extentsX, int depth); + internal static extern IntPtr QuadTreeSpaceCreate(IntPtr space, ref dReal centerX, ref dReal extentsX, int depth); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dRandReal"), SuppressUnmanagedCodeSecurity] - public static extern dReal RandReal(); + internal static extern dReal RandReal(); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dRFrom2Axes"), SuppressUnmanagedCodeSecurity] - public static extern void RFrom2Axes(out Matrix3 R, dReal ax, dReal ay, dReal az, dReal bx, dReal by, dReal bz); + internal static extern void RFrom2Axes(out Matrix3 R, dReal ax, dReal ay, dReal az, dReal bx, dReal by, dReal bz); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dRFromAxisAndAngle"), SuppressUnmanagedCodeSecurity] - public static extern void RFromAxisAndAngle(out Matrix3 R, dReal x, dReal y, dReal z, dReal angle); + internal static extern void RFromAxisAndAngle(out Matrix3 R, dReal x, dReal y, dReal z, dReal angle); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dRFromEulerAngles"), SuppressUnmanagedCodeSecurity] - public static extern void RFromEulerAngles(out Matrix3 R, dReal phi, dReal theta, dReal psi); + internal static extern void RFromEulerAngles(out Matrix3 R, dReal phi, dReal theta, dReal psi); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dRfromQ"), SuppressUnmanagedCodeSecurity] - public static extern void RfromQ(out Matrix3 R, ref Quaternion q); + internal static extern void RfromQ(out Matrix3 R, ref Quaternion q); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dRFromZAxis"), SuppressUnmanagedCodeSecurity] - public static extern void RFromZAxis(out Matrix3 R, dReal ax, dReal ay, dReal az); + internal static extern void RFromZAxis(out Matrix3 R, dReal ax, dReal ay, dReal az); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dRSetIdentity"), SuppressUnmanagedCodeSecurity] - public static extern void RSetIdentity(out Matrix3 R); + internal static extern void RSetIdentity(out Matrix3 R); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSetValue"), SuppressUnmanagedCodeSecurity] - public static extern void SetValue(out dReal a, int n); + internal static extern void SetValue(out dReal a, int n); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSetZero"), SuppressUnmanagedCodeSecurity] - public static extern void SetZero(out dReal a, int n); + internal static extern void SetZero(out dReal a, int n); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSimpleSpaceCreate"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr SimpleSpaceCreate(IntPtr space); + internal static extern IntPtr SimpleSpaceCreate(IntPtr space); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSolveCholesky"), SuppressUnmanagedCodeSecurity] - public static extern void SolveCholesky(ref dReal L, out dReal b, int n); + internal static extern void SolveCholesky(ref dReal L, out dReal b, int n); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSolveL1"), SuppressUnmanagedCodeSecurity] - public static extern void SolveL1(ref dReal L, out dReal b, int n, int nskip); + internal static extern void SolveL1(ref dReal L, out dReal b, int n, int nskip); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSolveL1T"), SuppressUnmanagedCodeSecurity] - public static extern void SolveL1T(ref dReal L, out dReal b, int n, int nskip); + internal static extern void SolveL1T(ref dReal L, out dReal b, int n, int nskip); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSolveLDLT"), SuppressUnmanagedCodeSecurity] - public static extern void SolveLDLT(ref dReal L, ref dReal d, out dReal b, int n, int nskip); + internal static extern void SolveLDLT(ref dReal L, ref dReal d, out dReal b, int n, int nskip); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSpaceAdd"), SuppressUnmanagedCodeSecurity] - public static extern void SpaceAdd(IntPtr space, IntPtr geom); + internal static extern void SpaceAdd(IntPtr space, IntPtr geom); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSpaceLockQuery"), SuppressUnmanagedCodeSecurity] - public static extern bool SpaceLockQuery(IntPtr space); + internal static extern bool SpaceLockQuery(IntPtr space); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSpaceClean"), SuppressUnmanagedCodeSecurity] - public static extern void SpaceClean(IntPtr space); + internal static extern void SpaceClean(IntPtr space); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSpaceCollide"), SuppressUnmanagedCodeSecurity] - public static extern void SpaceCollide(IntPtr space, IntPtr data, NearCallback callback); + internal static extern void SpaceCollide(IntPtr space, IntPtr data, NearCallback callback); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSpaceCollide2"), SuppressUnmanagedCodeSecurity] - public static extern void SpaceCollide2(IntPtr space1, IntPtr space2, IntPtr data, NearCallback callback); + internal static extern void SpaceCollide2(IntPtr space1, IntPtr space2, IntPtr data, NearCallback callback); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSpaceDestroy"), SuppressUnmanagedCodeSecurity] - public static extern void SpaceDestroy(IntPtr space); + internal static extern void SpaceDestroy(IntPtr space); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSpaceGetCleanup"), SuppressUnmanagedCodeSecurity] - public static extern bool SpaceGetCleanup(IntPtr space); + internal static extern bool SpaceGetCleanup(IntPtr space); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSpaceGetNumGeoms"), SuppressUnmanagedCodeSecurity] - public static extern int SpaceGetNumGeoms(IntPtr space); + internal static extern int SpaceGetNumGeoms(IntPtr space); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSpaceGetGeom"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr SpaceGetGeom(IntPtr space, int i); + internal static extern IntPtr SpaceGetGeom(IntPtr space, int i); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSpaceGetSublevel"), SuppressUnmanagedCodeSecurity] - public static extern int SpaceGetSublevel(IntPtr space); + internal static extern int SpaceGetSublevel(IntPtr space); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSpaceQuery"), SuppressUnmanagedCodeSecurity] - public static extern bool SpaceQuery(IntPtr space, IntPtr geom); + internal static extern bool SpaceQuery(IntPtr space, IntPtr geom); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSpaceRemove"), SuppressUnmanagedCodeSecurity] - public static extern void SpaceRemove(IntPtr space, IntPtr geom); + internal static extern void SpaceRemove(IntPtr space, IntPtr geom); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSpaceSetCleanup"), SuppressUnmanagedCodeSecurity] - public static extern void SpaceSetCleanup(IntPtr space, bool mode); + internal static extern void SpaceSetCleanup(IntPtr space, bool mode); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSpaceSetSublevel"), SuppressUnmanagedCodeSecurity] - public static extern void SpaceSetSublevel(IntPtr space, int sublevel); + internal static extern void SpaceSetSublevel(IntPtr space, int sublevel); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dSweepAndPruneSpaceCreate"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr SweepAndPruneSpaceCreate(IntPtr space, int AxisOrder); + internal static extern IntPtr SweepAndPruneSpaceCreate(IntPtr space, int AxisOrder); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dVectorScale"), SuppressUnmanagedCodeSecurity] - public static extern void VectorScale(out dReal a, ref dReal d, int n); + internal static extern void VectorScale(out dReal a, ref dReal d, int n); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldCreate"), SuppressUnmanagedCodeSecurity] - public static extern IntPtr WorldCreate(); + internal static extern IntPtr WorldCreate(); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldDestroy"), SuppressUnmanagedCodeSecurity] - public static extern void WorldDestroy(IntPtr world); + internal static extern void WorldDestroy(IntPtr world); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetAutoDisableAverageSamplesCount"), SuppressUnmanagedCodeSecurity] - public static extern int WorldGetAutoDisableAverageSamplesCount(IntPtr world); + internal static extern int WorldGetAutoDisableAverageSamplesCount(IntPtr world); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetAutoDisableAngularThreshold"), SuppressUnmanagedCodeSecurity] - public static extern dReal WorldGetAutoDisableAngularThreshold(IntPtr world); + internal static extern dReal WorldGetAutoDisableAngularThreshold(IntPtr world); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetAutoDisableFlag"), SuppressUnmanagedCodeSecurity] - public static extern bool WorldGetAutoDisableFlag(IntPtr world); + internal static extern bool WorldGetAutoDisableFlag(IntPtr world); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetAutoDisableLinearThreshold"), SuppressUnmanagedCodeSecurity] - public static extern dReal WorldGetAutoDisableLinearThreshold(IntPtr world); + internal static extern dReal WorldGetAutoDisableLinearThreshold(IntPtr world); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetAutoDisableSteps"), SuppressUnmanagedCodeSecurity] - public static extern int WorldGetAutoDisableSteps(IntPtr world); + internal static extern int WorldGetAutoDisableSteps(IntPtr world); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetAutoDisableTime"), SuppressUnmanagedCodeSecurity] - public static extern dReal WorldGetAutoDisableTime(IntPtr world); + internal static extern dReal WorldGetAutoDisableTime(IntPtr world); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetAutoEnableDepthSF1"), SuppressUnmanagedCodeSecurity] - public static extern int WorldGetAutoEnableDepthSF1(IntPtr world); + internal static extern int WorldGetAutoEnableDepthSF1(IntPtr world); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetCFM"), SuppressUnmanagedCodeSecurity] - public static extern dReal WorldGetCFM(IntPtr world); + internal static extern dReal WorldGetCFM(IntPtr world); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetERP"), SuppressUnmanagedCodeSecurity] - public static extern dReal WorldGetERP(IntPtr world); + internal static extern dReal WorldGetERP(IntPtr world); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetGravity"), SuppressUnmanagedCodeSecurity] - public static extern void WorldGetGravity(IntPtr world, out Vector3 gravity); + internal static extern void WorldGetGravity(IntPtr world, out Vector3 gravity); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetGravity"), SuppressUnmanagedCodeSecurity] - public static extern void WorldGetGravity(IntPtr world, out dReal X); + internal static extern void WorldGetGravity(IntPtr world, out dReal X); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetContactMaxCorrectingVel"), SuppressUnmanagedCodeSecurity] - public static extern dReal WorldGetContactMaxCorrectingVel(IntPtr world); + internal static extern dReal WorldGetContactMaxCorrectingVel(IntPtr world); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetContactSurfaceLayer"), SuppressUnmanagedCodeSecurity] - public static extern dReal WorldGetContactSurfaceLayer(IntPtr world); + internal static extern dReal WorldGetContactSurfaceLayer(IntPtr world); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetAngularDamping"), SuppressUnmanagedCodeSecurity] - public static extern dReal WorldGetAngularDamping(IntPtr world); + internal static extern dReal WorldGetAngularDamping(IntPtr world); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetAngularDampingThreshold"), SuppressUnmanagedCodeSecurity] - public static extern dReal WorldGetAngularDampingThreshold(IntPtr world); + internal static extern dReal WorldGetAngularDampingThreshold(IntPtr world); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetLinearDamping"), SuppressUnmanagedCodeSecurity] - public static extern dReal WorldGetLinearDamping(IntPtr world); + internal static extern dReal WorldGetLinearDamping(IntPtr world); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetLinearDampingThreshold"), SuppressUnmanagedCodeSecurity] - public static extern dReal WorldGetLinearDampingThreshold(IntPtr world); + internal static extern dReal WorldGetLinearDampingThreshold(IntPtr world); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetQuickStepNumIterations"), SuppressUnmanagedCodeSecurity] - public static extern int WorldGetQuickStepNumIterations(IntPtr world); + internal static extern int WorldGetQuickStepNumIterations(IntPtr world); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetQuickStepW"), SuppressUnmanagedCodeSecurity] - public static extern dReal WorldGetQuickStepW(IntPtr world); + internal static extern dReal WorldGetQuickStepW(IntPtr world); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldGetMaxAngularSpeed"), SuppressUnmanagedCodeSecurity] - public static extern dReal WorldGetMaxAngularSpeed(IntPtr world); + internal static extern dReal WorldGetMaxAngularSpeed(IntPtr world); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldImpulseToForce"), SuppressUnmanagedCodeSecurity] - public static extern void WorldImpulseToForce(IntPtr world, dReal stepsize, dReal ix, dReal iy, dReal iz, out Vector3 force); + internal static extern void WorldImpulseToForce(IntPtr world, dReal stepsize, dReal ix, dReal iy, dReal iz, out Vector3 force); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldImpulseToForce"), SuppressUnmanagedCodeSecurity] - public static extern void WorldImpulseToForce(IntPtr world, dReal stepsize, dReal ix, dReal iy, dReal iz, out dReal forceX); + internal static extern void WorldImpulseToForce(IntPtr world, dReal stepsize, dReal ix, dReal iy, dReal iz, out dReal forceX); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldQuickStep"), SuppressUnmanagedCodeSecurity] - public static extern void WorldQuickStep(IntPtr world, dReal stepsize); + internal static extern void WorldQuickStep(IntPtr world, dReal stepsize); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetAngularDamping"), SuppressUnmanagedCodeSecurity] - public static extern void WorldSetAngularDamping(IntPtr world, dReal scale); + internal static extern void WorldSetAngularDamping(IntPtr world, dReal scale); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetAngularDampingThreshold"), SuppressUnmanagedCodeSecurity] - public static extern void WorldSetAngularDampingThreshold(IntPtr world, dReal threshold); + internal static extern void WorldSetAngularDampingThreshold(IntPtr world, dReal threshold); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetAutoDisableAngularThreshold"), SuppressUnmanagedCodeSecurity] - public static extern void WorldSetAutoDisableAngularThreshold(IntPtr world, dReal angular_threshold); + internal static extern void WorldSetAutoDisableAngularThreshold(IntPtr world, dReal angular_threshold); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetAutoDisableAverageSamplesCount"), SuppressUnmanagedCodeSecurity] - public static extern void WorldSetAutoDisableAverageSamplesCount(IntPtr world, int average_samples_count); + internal static extern void WorldSetAutoDisableAverageSamplesCount(IntPtr world, int average_samples_count); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetAutoDisableFlag"), SuppressUnmanagedCodeSecurity] - public static extern void WorldSetAutoDisableFlag(IntPtr world, bool do_auto_disable); + internal static extern void WorldSetAutoDisableFlag(IntPtr world, bool do_auto_disable); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetAutoDisableLinearThreshold"), SuppressUnmanagedCodeSecurity] - public static extern void WorldSetAutoDisableLinearThreshold(IntPtr world, dReal linear_threshold); + internal static extern void WorldSetAutoDisableLinearThreshold(IntPtr world, dReal linear_threshold); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetAutoDisableSteps"), SuppressUnmanagedCodeSecurity] - public static extern void WorldSetAutoDisableSteps(IntPtr world, int steps); + internal static extern void WorldSetAutoDisableSteps(IntPtr world, int steps); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetAutoDisableTime"), SuppressUnmanagedCodeSecurity] - public static extern void WorldSetAutoDisableTime(IntPtr world, dReal time); + internal static extern void WorldSetAutoDisableTime(IntPtr world, dReal time); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetAutoEnableDepthSF1"), SuppressUnmanagedCodeSecurity] - public static extern void WorldSetAutoEnableDepthSF1(IntPtr world, int autoEnableDepth); + internal static extern void WorldSetAutoEnableDepthSF1(IntPtr world, int autoEnableDepth); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetCFM"), SuppressUnmanagedCodeSecurity] - public static extern void WorldSetCFM(IntPtr world, dReal cfm); + internal static extern void WorldSetCFM(IntPtr world, dReal cfm); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetContactMaxCorrectingVel"), SuppressUnmanagedCodeSecurity] - public static extern void WorldSetContactMaxCorrectingVel(IntPtr world, dReal vel); + internal static extern void WorldSetContactMaxCorrectingVel(IntPtr world, dReal vel); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetContactSurfaceLayer"), SuppressUnmanagedCodeSecurity] - public static extern void WorldSetContactSurfaceLayer(IntPtr world, dReal depth); + internal static extern void WorldSetContactSurfaceLayer(IntPtr world, dReal depth); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetDamping"), SuppressUnmanagedCodeSecurity] - public static extern void WorldSetDamping(IntPtr world, dReal linear_scale, dReal angular_scale); + internal static extern void WorldSetDamping(IntPtr world, dReal linear_scale, dReal angular_scale); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetERP"), SuppressUnmanagedCodeSecurity] - public static extern void WorldSetERP(IntPtr world, dReal erp); + internal static extern void WorldSetERP(IntPtr world, dReal erp); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetGravity"), SuppressUnmanagedCodeSecurity] - public static extern void WorldSetGravity(IntPtr world, dReal x, dReal y, dReal z); + internal static extern void WorldSetGravity(IntPtr world, dReal x, dReal y, dReal z); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetLinearDamping"), SuppressUnmanagedCodeSecurity] - public static extern void WorldSetLinearDamping(IntPtr world, dReal scale); + internal static extern void WorldSetLinearDamping(IntPtr world, dReal scale); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetLinearDampingThreshold"), SuppressUnmanagedCodeSecurity] - public static extern void WorldSetLinearDampingThreshold(IntPtr world, dReal threshold); + internal static extern void WorldSetLinearDampingThreshold(IntPtr world, dReal threshold); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetQuickStepNumIterations"), SuppressUnmanagedCodeSecurity] - public static extern void WorldSetQuickStepNumIterations(IntPtr world, int num); + internal static extern void WorldSetQuickStepNumIterations(IntPtr world, int num); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetQuickStepW"), SuppressUnmanagedCodeSecurity] - public static extern void WorldSetQuickStepW(IntPtr world, dReal over_relaxation); + internal static extern void WorldSetQuickStepW(IntPtr world, dReal over_relaxation); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldSetMaxAngularSpeed"), SuppressUnmanagedCodeSecurity] - public static extern void WorldSetMaxAngularSpeed(IntPtr world, dReal max_speed); + internal static extern void WorldSetMaxAngularSpeed(IntPtr world, dReal max_speed); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldStep"), SuppressUnmanagedCodeSecurity] - public static extern void WorldStep(IntPtr world, dReal stepsize); + internal static extern void WorldStep(IntPtr world, dReal stepsize); [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldStepFast1"), SuppressUnmanagedCodeSecurity] - public static extern void WorldStepFast1(IntPtr world, dReal stepsize, int maxiterations); - - [DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dWorldExportDIF"), SuppressUnmanagedCodeSecurity] - public static extern void WorldExportDIF(IntPtr world, string filename, bool append, string prefix); + internal static extern void WorldStepFast1(IntPtr world, dReal stepsize, int maxiterations); } } diff --git a/OpenSim/Region/PhysicsModules/ubOde/ODECharacter.cs b/OpenSim/Region/PhysicsModules/ubOde/ODECharacter.cs index 9cef3d5496..60cc5497da 100644 --- a/OpenSim/Region/PhysicsModules/ubOde/ODECharacter.cs +++ b/OpenSim/Region/PhysicsModules/ubOde/ODECharacter.cs @@ -32,7 +32,6 @@ using System; using System.Collections.Generic; using System.Reflection; using OpenMetaverse; -using OdeAPI; using OpenSim.Framework; using OpenSim.Region.PhysicsModules.SharedBase; using log4net; @@ -43,7 +42,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde /// Various properties that ODE uses for AMotors but isn't exposed in ODE.NET so we must define them ourselves. /// - public enum dParam : int + public enum dParam:int { LowStop = 0, HiStop = 1, @@ -68,7 +67,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde StopCFM3 = 8 + 512 } - public class OdeCharacter : PhysicsActor + public class OdeCharacter:PhysicsActor { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -103,7 +102,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde public float walkDivisor = 1.3f; public float runDivisor = 0.8f; - private bool flying = false; + private bool m_flying = false; private bool m_iscolliding = false; private bool m_iscollidingGround = false; private bool m_iscollidingObj = false; @@ -122,7 +121,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde private bool m_freemove = false; -// private string m_name = String.Empty; + // private string m_name = String.Empty; // other filter control int m_colliderfilter = 0; int m_colliderGroundfilter = 0; @@ -138,13 +137,13 @@ namespace OpenSim.Region.PhysicsModule.ubOde ); // we do land collisions not ode | CollisionCategories.Land); public IntPtr Body = IntPtr.Zero; - private ODEScene _parent_scene; + private ODEScene m_parent_scene; private IntPtr capsule = IntPtr.Zero; public IntPtr collider = IntPtr.Zero; public IntPtr Amotor = IntPtr.Zero; - public d.Mass ShellMass; + internal SafeNativeMethods.Mass ShellMass; public int m_eventsubscription = 0; private int m_cureventsubscription = 0; @@ -165,35 +164,33 @@ namespace OpenSim.Region.PhysicsModule.ubOde private float m_targetHoverHeight; - public OdeCharacter(uint localID, String avName, ODEScene parent_scene, Vector3 pos, Vector3 pSize, float pfeetOffset, float density, float walk_divisor, float rundivisor) + public OdeCharacter(uint localID,String avName,ODEScene parent_scene,Vector3 pos,Vector3 pSize,float pfeetOffset,float density,float walk_divisor,float rundivisor) { m_uuid = UUID.Random(); m_localID = localID; + m_parent_scene = parent_scene; timeStep = parent_scene.ODE_STEPSIZE; invtimeStep = 1 / timeStep; - if (pos.IsFinite()) + if(pos.IsFinite()) { - if (pos.Z > 99999f) + if(pos.Z > 99999f) { - pos.Z = parent_scene.GetTerrainHeightAtXY(127, 127) + 5; + pos.Z = parent_scene.GetTerrainHeightAtXY(127,127) + 5; } - if (pos.Z < -100f) // shouldn't this be 0 ? + if(pos.Z < -100f) // shouldn't this be 0 ? { - pos.Z = parent_scene.GetTerrainHeightAtXY(127, 127) + 5; + pos.Z = parent_scene.GetTerrainHeightAtXY(127,127) + 5; } _position = pos; } else { - _position = new Vector3(((float)_parent_scene.WorldExtents.X * 0.5f), ((float)_parent_scene.WorldExtents.Y * 0.5f), parent_scene.GetTerrainHeightAtXY(128f, 128f) + 10f); + _position = new Vector3(((float)m_parent_scene.WorldExtents.X * 0.5f),((float)m_parent_scene.WorldExtents.Y * 0.5f),parent_scene.GetTerrainHeightAtXY(128f,128f) + 10f); m_log.Warn("[PHYSICS]: Got NaN Position on Character Create"); } - _parent_scene = parent_scene; - - m_size.X = pSize.X; m_size.Y = pSize.Y; m_size.Z = pSize.Z; @@ -213,12 +210,13 @@ namespace OpenSim.Region.PhysicsModule.ubOde // force lower density for testing m_density = 3.0f; - mu = parent_scene.AvatarFriction; + mu = m_parent_scene.AvatarFriction; walkDivisor = walk_divisor; runDivisor = rundivisor; - m_mass = m_density * m_size.X * m_size.Y * m_size.Z; ; // sure we have a default + m_mass = m_density * m_size.X * m_size.Y * m_size.Z; + ; // sure we have a default PID_D = basePID_D * m_mass * invtimeStep; PID_P = basePID_P * m_mass * invtimeStep; @@ -227,13 +225,19 @@ namespace OpenSim.Region.PhysicsModule.ubOde Name = avName; - AddChange(changes.Add, null); + AddChange(changes.Add,null); } public override int PhysicsActorType { - get { return (int)ActorTypes.Agent; } - set { return; } + get + { + return (int)ActorTypes.Agent; + } + set + { + return; + } } public override void getContactData(ref ContactData cdata) @@ -243,68 +247,116 @@ namespace OpenSim.Region.PhysicsModule.ubOde cdata.softcolide = false; } - public override bool Building { get; set; } + public override bool Building + { + get; set; + } /// /// If this is set, the avatar will move faster /// public override bool SetAlwaysRun { - get { return m_alwaysRun; } - set { m_alwaysRun = value; } + get + { + return m_alwaysRun; + } + set + { + m_alwaysRun = value; + } } public override uint LocalID { - get { return m_localID; } - set { m_localID = value; } + get + { + return m_localID; + } + set + { + m_localID = value; + } } public override PhysicsActor ParentActor { - get { return (PhysicsActor)this; } + get + { + return (PhysicsActor)this; + } } public override bool Grabbed { - set { return; } + set + { + return; + } } public override bool Selected { - set { return; } + set + { + return; + } } public override float Buoyancy { - get { return m_buoyancy; } - set { m_buoyancy = value; } + get + { + return m_buoyancy; + } + set + { + m_buoyancy = value; + } } public override bool FloatOnWater { - set { return; } + set + { + return; + } } public override bool IsPhysical { - get { return m_isPhysical; } - set { return; } + get + { + return m_isPhysical; + } + set + { + return; + } } public override bool ThrottleUpdates { - get { return false; } - set { return; } + get + { + return false; + } + set + { + return; + } } public override bool Flying { - get { return flying; } + get + { + return m_flying; + } set { - flying = value; -// m_log.DebugFormat("[PHYSICS]: Set OdeCharacter Flying to {0}", flying); + m_flying = value; + // m_log.DebugFormat("[PHYSICS]: Set OdeCharacter Flying to {0}", flying); } } @@ -314,23 +366,26 @@ namespace OpenSim.Region.PhysicsModule.ubOde /// public override bool IsColliding { - get { return (m_iscolliding || m_iscollidingGround); } + get + { + return (m_iscolliding || m_iscollidingGround); + } set { - if (value) + if(value) { m_colliderfilter += 3; - if (m_colliderfilter > 3) + if(m_colliderfilter > 3) m_colliderfilter = 3; } else { m_colliderfilter--; - if (m_colliderfilter < 0) + if(m_colliderfilter < 0) m_colliderfilter = 0; } - if (m_colliderfilter == 0) + if(m_colliderfilter == 0) m_iscolliding = false; else { @@ -346,28 +401,31 @@ namespace OpenSim.Region.PhysicsModule.ubOde /// public override bool CollidingGround { - get { return m_iscollidingGround; } + get + { + return m_iscollidingGround; + } set { -/* we now control this - if (value) - { - m_colliderGroundfilter += 2; - if (m_colliderGroundfilter > 2) - m_colliderGroundfilter = 2; - } - else - { - m_colliderGroundfilter--; - if (m_colliderGroundfilter < 0) - m_colliderGroundfilter = 0; - } + /* we now control this + if (value) + { + m_colliderGroundfilter += 2; + if (m_colliderGroundfilter > 2) + m_colliderGroundfilter = 2; + } + else + { + m_colliderGroundfilter--; + if (m_colliderGroundfilter < 0) + m_colliderGroundfilter = 0; + } - if (m_colliderGroundfilter == 0) - m_iscollidingGround = false; - else - m_iscollidingGround = true; - */ + if (m_colliderGroundfilter == 0) + m_iscollidingGround = false; + else + m_iscollidingGround = true; + */ } } @@ -377,31 +435,34 @@ namespace OpenSim.Region.PhysicsModule.ubOde /// public override bool CollidingObj { - get { return m_iscollidingObj; } + get + { + return m_iscollidingObj; + } set { // Ubit filter this also - if (value) + if(value) { m_colliderObjectfilter += 2; - if (m_colliderObjectfilter > 2) + if(m_colliderObjectfilter > 2) m_colliderObjectfilter = 2; } else { m_colliderObjectfilter--; - if (m_colliderObjectfilter < 0) + if(m_colliderObjectfilter < 0) m_colliderObjectfilter = 0; } - if (m_colliderObjectfilter == 0) + if(m_colliderObjectfilter == 0) m_iscollidingObj = false; else m_iscollidingObj = true; -// m_iscollidingObj = value; + // m_iscollidingObj = value; - if (m_iscollidingObj) + if(m_iscollidingObj) m_pidControllerActive = false; else m_pidControllerActive = true; @@ -420,7 +481,10 @@ namespace OpenSim.Region.PhysicsModule.ubOde public override bool Stopped { - get { return _zeroFlag; } + get + { + return _zeroFlag; + } } /// @@ -430,20 +494,23 @@ namespace OpenSim.Region.PhysicsModule.ubOde /// public override Vector3 Position { - get { return _position; } + get + { + return _position; + } set { - if (value.IsFinite()) + if(value.IsFinite()) { - if (value.Z > 9999999f) + if(value.Z > 9999999f) { - value.Z = _parent_scene.GetTerrainHeightAtXY(127, 127) + 5; + value.Z = m_parent_scene.GetTerrainHeightAtXY(127,127) + 5; } - if (value.Z < -100f) + if(value.Z < -100f) { - value.Z = _parent_scene.GetTerrainHeightAtXY(127, 127) + 5; + value.Z = m_parent_scene.GetTerrainHeightAtXY(127,127) + 5; } - AddChange(changes.Position, value); + AddChange(changes.Position,value); } else { @@ -454,8 +521,14 @@ namespace OpenSim.Region.PhysicsModule.ubOde public override Vector3 RotationalVelocity { - get { return m_rotationalVelocity; } - set { m_rotationalVelocity = value; } + get + { + return m_rotationalVelocity; + } + set + { + m_rotationalVelocity = value; + } } /// @@ -470,7 +543,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde } set { - if (value.IsFinite()) + if(value.IsFinite()) { if(value.X <0.01f) value.X = 0.01f; @@ -479,7 +552,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde if(value.Z <0.01f) value.Z = 0.01f; - AddChange(changes.Size, value); + AddChange(changes.Size,value); } else { @@ -488,21 +561,21 @@ namespace OpenSim.Region.PhysicsModule.ubOde } } - public override void setAvatarSize(Vector3 size, float feetOffset) + public override void setAvatarSize(Vector3 size,float feetOffset) { - if (size.IsFinite()) + if(size.IsFinite()) { - if (size.X < 0.01f) + if(size.X < 0.01f) size.X = 0.01f; - if (size.Y < 0.01f) + if(size.Y < 0.01f) size.Y = 0.01f; - if (size.Z < 0.01f) + if(size.Z < 0.01f) size.Z = 0.01f; strAvatarSize st = new strAvatarSize(); st.size = size; st.offset = feetOffset; - AddChange(changes.AvatarSize, st); + AddChange(changes.AvatarSize,st); } else { @@ -547,32 +620,44 @@ namespace OpenSim.Region.PhysicsModule.ubOde public override Vector3 Force { - get { return _target_velocity; } - set { return; } + get + { + return _target_velocity; + } + set + { + return; + } } public override int VehicleType { - get { return 0; } - set { return; } + get + { + return 0; + } + set + { + return; + } } - public override void VehicleFloatParam(int param, float value) + public override void VehicleFloatParam(int param,float value) { } - public override void VehicleVectorParam(int param, Vector3 value) + public override void VehicleVectorParam(int param,Vector3 value) { } - public override void VehicleRotationParam(int param, Quaternion rotation) + public override void VehicleRotationParam(int param,Quaternion rotation) { } - public override void VehicleFlags(int param, bool remove) + public override void VehicleFlags(int param,bool remove) { } @@ -602,7 +687,10 @@ namespace OpenSim.Region.PhysicsModule.ubOde public override PrimitiveBaseShape Shape { - set { return; } + set + { + return; + } } public override Vector3 rootVelocity @@ -621,9 +709,9 @@ namespace OpenSim.Region.PhysicsModule.ubOde } set { - if (value.IsFinite()) + if(value.IsFinite()) { - AddChange(changes.Velocity, value); + AddChange(changes.Velocity,value); } else { @@ -640,9 +728,9 @@ namespace OpenSim.Region.PhysicsModule.ubOde } set { - if (value.IsFinite()) + if(value.IsFinite()) { - AddChange(changes.TargetVelocity, value); + AddChange(changes.TargetVelocity,value); } else { @@ -653,38 +741,62 @@ namespace OpenSim.Region.PhysicsModule.ubOde public override Vector3 Torque { - get { return Vector3.Zero; } - set { return; } + get + { + return Vector3.Zero; + } + set + { + return; + } } public override float CollisionScore { - get { return 0f; } - set { } + get + { + return 0f; + } + set + { + } } public override bool Kinematic { - get { return false; } - set { } + get + { + return false; + } + set + { + } } public override Quaternion Orientation { - get { return m_orientation; } + get + { + return m_orientation; + } set { -// fakeori = value; -// givefakeori++; + // fakeori = value; + // givefakeori++; value.Normalize(); - AddChange(changes.Orientation, value); + AddChange(changes.Orientation,value); } } public override Vector3 Acceleration { - get { return _acceleration; } - set { } + get + { + return _acceleration; + } + set + { + } } public void SetAcceleration(Vector3 accel) @@ -698,17 +810,17 @@ namespace OpenSim.Region.PhysicsModule.ubOde /// The PID controller takes this target velocity and tries to make it a reality /// /// - public override void AddForce(Vector3 force, bool pushforce) + public override void AddForce(Vector3 force,bool pushforce) { - if (force.IsFinite()) + if(force.IsFinite()) { - if (pushforce) + if(pushforce) { - AddChange(changes.Force, force * m_density / (_parent_scene.ODE_STEPSIZE * 28f)); + AddChange(changes.Force,force * m_density / (m_parent_scene.ODE_STEPSIZE * 28f)); } else { - AddChange(changes.TargetVelocity, force); + AddChange(changes.TargetVelocity,force); } } else @@ -718,19 +830,19 @@ namespace OpenSim.Region.PhysicsModule.ubOde //m_lastUpdateSent = false; } - public override void AddAngularForce(Vector3 force, bool pushforce) + public override void AddAngularForce(Vector3 force,bool pushforce) { } public override void SetMomentum(Vector3 momentum) { - if (momentum.IsFinite()) - AddChange(changes.Momentum, momentum); + if(momentum.IsFinite()) + AddChange(changes.Momentum,momentum); } - private void AvatarGeomAndBodyCreation(float npositionX, float npositionY, float npositionZ) + private void AvatarGeomAndBodyCreation(float npositionX,float npositionY,float npositionZ) { // sizes one day should came from visual parameters float sx = m_size.X; @@ -741,7 +853,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde boneOff = bot + 0.3f; float feetsz = sz * 0.45f; - if (feetsz > 0.6f) + if(feetsz > 0.6f) feetsz = 0.6f; feetOff = bot + feetsz; @@ -751,31 +863,30 @@ namespace OpenSim.Region.PhysicsModule.ubOde AvaAvaSizeYsq = 0.5f * sy; AvaAvaSizeYsq *= AvaAvaSizeYsq; - _parent_scene.waitForSpaceUnlock(_parent_scene.CharsSpace); + m_parent_scene.waitForSpaceUnlock(m_parent_scene.CharsSpace); - collider = d.HashSpaceCreate(_parent_scene.CharsSpace); - d.HashSpaceSetLevels(collider, -4, 3); - d.SpaceSetSublevel(collider, 3); - d.SpaceSetCleanup(collider, false); - d.GeomSetCategoryBits(collider, (uint)m_collisionCategories); - d.GeomSetCollideBits(collider, (uint)m_collisionFlags); + collider = SafeNativeMethods.SimpleSpaceCreate(m_parent_scene.CharsSpace); + SafeNativeMethods.SpaceSetSublevel(collider,3); + SafeNativeMethods.SpaceSetCleanup(collider,false); + SafeNativeMethods.GeomSetCategoryBits(collider,(uint)m_collisionCategories); + SafeNativeMethods.GeomSetCollideBits(collider,(uint)m_collisionFlags); float r = m_size.X; - if (m_size.Y > r) + if(m_size.Y > r) r = m_size.Y; float l = m_size.Z - r; r *= 0.5f; - capsule = d.CreateCapsule(collider, r, l); + capsule = SafeNativeMethods.CreateCapsule(collider,r,l); m_mass = m_density * m_size.X * m_size.Y * m_size.Z; // update mass - d.MassSetBoxTotal(out ShellMass, m_mass, m_size.X, m_size.Y, m_size.Z); + SafeNativeMethods.MassSetBoxTotal(out ShellMass,m_mass,m_size.X,m_size.Y,m_size.Z); - PID_D = basePID_D * m_mass / _parent_scene.ODE_STEPSIZE; - PID_P = basePID_P * m_mass / _parent_scene.ODE_STEPSIZE; + PID_D = basePID_D * m_mass / m_parent_scene.ODE_STEPSIZE; + PID_P = basePID_P * m_mass / m_parent_scene.ODE_STEPSIZE; - Body = d.BodyCreate(_parent_scene.world); + Body = SafeNativeMethods.BodyCreate(m_parent_scene.world); _zeroFlag = false; m_pidControllerActive = true; @@ -783,53 +894,53 @@ namespace OpenSim.Region.PhysicsModule.ubOde _velocity = Vector3.Zero; - d.BodySetAutoDisableFlag(Body, false); - d.BodySetPosition(Body, npositionX, npositionY, npositionZ); + SafeNativeMethods.BodySetAutoDisableFlag(Body,false); + SafeNativeMethods.BodySetPosition(Body,npositionX,npositionY,npositionZ); _position.X = npositionX; _position.Y = npositionY; _position.Z = npositionZ; - d.BodySetMass(Body, ref ShellMass); - d.GeomSetBody(capsule, Body); + SafeNativeMethods.BodySetMass(Body,ref ShellMass); + SafeNativeMethods.GeomSetBody(capsule,Body); // The purpose of the AMotor here is to keep the avatar's physical // surrogate from rotating while moving - Amotor = d.JointCreateAMotor(_parent_scene.world, IntPtr.Zero); - d.JointAttach(Amotor, Body, IntPtr.Zero); + Amotor = SafeNativeMethods.JointCreateAMotor(m_parent_scene.world,IntPtr.Zero); + SafeNativeMethods.JointAttach(Amotor,Body,IntPtr.Zero); - d.JointSetAMotorMode(Amotor, 0); - d.JointSetAMotorNumAxes(Amotor, 3); - d.JointSetAMotorAxis(Amotor, 0, 0, 1, 0, 0); - d.JointSetAMotorAxis(Amotor, 1, 0, 0, 1, 0); - d.JointSetAMotorAxis(Amotor, 2, 0, 0, 0, 1); + SafeNativeMethods.JointSetAMotorMode(Amotor,0); + SafeNativeMethods.JointSetAMotorNumAxes(Amotor,3); + SafeNativeMethods.JointSetAMotorAxis(Amotor,0,0,1,0,0); + SafeNativeMethods.JointSetAMotorAxis(Amotor,1,0,0,1,0); + SafeNativeMethods.JointSetAMotorAxis(Amotor,2,0,0,0,1); - d.JointSetAMotorAngle(Amotor, 0, 0); - d.JointSetAMotorAngle(Amotor, 1, 0); - d.JointSetAMotorAngle(Amotor, 2, 0); + SafeNativeMethods.JointSetAMotorAngle(Amotor,0,0); + SafeNativeMethods.JointSetAMotorAngle(Amotor,1,0); + SafeNativeMethods.JointSetAMotorAngle(Amotor,2,0); - d.JointSetAMotorParam(Amotor, (int)dParam.StopCFM, 0f); // make it HARD - d.JointSetAMotorParam(Amotor, (int)dParam.StopCFM2, 0f); - d.JointSetAMotorParam(Amotor, (int)dParam.StopCFM3, 0f); - d.JointSetAMotorParam(Amotor, (int)dParam.StopERP, 0.8f); - d.JointSetAMotorParam(Amotor, (int)dParam.StopERP2, 0.8f); - d.JointSetAMotorParam(Amotor, (int)dParam.StopERP3, 0.8f); + SafeNativeMethods.JointSetAMotorParam(Amotor,(int)dParam.StopCFM,0f); // make it HARD + SafeNativeMethods.JointSetAMotorParam(Amotor,(int)dParam.StopCFM2,0f); + SafeNativeMethods.JointSetAMotorParam(Amotor,(int)dParam.StopCFM3,0f); + SafeNativeMethods.JointSetAMotorParam(Amotor,(int)dParam.StopERP,0.8f); + SafeNativeMethods.JointSetAMotorParam(Amotor,(int)dParam.StopERP2,0.8f); + SafeNativeMethods.JointSetAMotorParam(Amotor,(int)dParam.StopERP3,0.8f); // These lowstops and high stops are effectively (no wiggle room) - d.JointSetAMotorParam(Amotor, (int)dParam.LowStop, -1e-5f); - d.JointSetAMotorParam(Amotor, (int)dParam.HiStop, 1e-5f); - d.JointSetAMotorParam(Amotor, (int)dParam.LoStop2, -1e-5f); - d.JointSetAMotorParam(Amotor, (int)dParam.HiStop2, 1e-5f); - d.JointSetAMotorParam(Amotor, (int)dParam.LoStop3, -1e-5f); - d.JointSetAMotorParam(Amotor, (int)dParam.HiStop3, 1e-5f); + SafeNativeMethods.JointSetAMotorParam(Amotor,(int)dParam.LowStop,-1e-5f); + SafeNativeMethods.JointSetAMotorParam(Amotor,(int)dParam.HiStop,1e-5f); + SafeNativeMethods.JointSetAMotorParam(Amotor,(int)dParam.LoStop2,-1e-5f); + SafeNativeMethods.JointSetAMotorParam(Amotor,(int)dParam.HiStop2,1e-5f); + SafeNativeMethods.JointSetAMotorParam(Amotor,(int)dParam.LoStop3,-1e-5f); + SafeNativeMethods.JointSetAMotorParam(Amotor,(int)dParam.HiStop3,1e-5f); - d.JointSetAMotorParam(Amotor, (int)d.JointParam.Vel, 0); - d.JointSetAMotorParam(Amotor, (int)d.JointParam.Vel2, 0); - d.JointSetAMotorParam(Amotor, (int)d.JointParam.Vel3, 0); + SafeNativeMethods.JointSetAMotorParam(Amotor,(int)SafeNativeMethods.JointParam.Vel,0); + SafeNativeMethods.JointSetAMotorParam(Amotor,(int)SafeNativeMethods.JointParam.Vel2,0); + SafeNativeMethods.JointSetAMotorParam(Amotor,(int)SafeNativeMethods.JointParam.Vel3,0); - d.JointSetAMotorParam(Amotor, (int)dParam.FMax, 5e8f); - d.JointSetAMotorParam(Amotor, (int)dParam.FMax2, 5e8f); - d.JointSetAMotorParam(Amotor, (int)dParam.FMax3, 5e8f); + SafeNativeMethods.JointSetAMotorParam(Amotor,(int)dParam.FMax,5e8f); + SafeNativeMethods.JointSetAMotorParam(Amotor,(int)dParam.FMax2,5e8f); + SafeNativeMethods.JointSetAMotorParam(Amotor,(int)dParam.FMax3,5e8f); } /// @@ -838,38 +949,38 @@ namespace OpenSim.Region.PhysicsModule.ubOde private void AvatarGeomAndBodyDestroy() { // Kill the Amotor - if (Amotor != IntPtr.Zero) + if(Amotor != IntPtr.Zero) { - d.JointDestroy(Amotor); + SafeNativeMethods.JointDestroy(Amotor); Amotor = IntPtr.Zero; } - if (Body != IntPtr.Zero) + if(Body != IntPtr.Zero) { //kill the body - d.BodyDestroy(Body); + SafeNativeMethods.BodyDestroy(Body); Body = IntPtr.Zero; } //kill the Geoms - if (capsule != IntPtr.Zero) + if(capsule != IntPtr.Zero) { - _parent_scene.actor_name_map.Remove(capsule); - _parent_scene.waitForSpaceUnlock(collider); - d.GeomDestroy(capsule); + m_parent_scene.actor_name_map.Remove(capsule); + m_parent_scene.waitForSpaceUnlock(collider); + SafeNativeMethods.GeomDestroy(capsule); capsule = IntPtr.Zero; } - if (collider != IntPtr.Zero) + if(collider != IntPtr.Zero) { - d.SpaceDestroy(collider); + SafeNativeMethods.SpaceDestroy(collider); collider = IntPtr.Zero; } } //in place 2D rotation around Z assuming rot is normalised and is a rotation around Z - public void RotateXYonZ(ref float x, ref float y, ref Quaternion rot) + public void RotateXYonZ(ref float x,ref float y,ref Quaternion rot) { float sin = 2.0f * rot.Z * rot.W; float cos = rot.W * rot.W - rot.Z * rot.Z; @@ -878,22 +989,22 @@ namespace OpenSim.Region.PhysicsModule.ubOde x = tx * cos - y * sin; y = tx * sin + y * cos; } - public void RotateXYonZ(ref float x, ref float y, ref float sin, ref float cos) + public void RotateXYonZ(ref float x,ref float y,ref float sin,ref float cos) { float tx = x; x = tx * cos - y * sin; y = tx * sin + y * cos; } - public void invRotateXYonZ(ref float x, ref float y, ref float sin, ref float cos) + public void invRotateXYonZ(ref float x,ref float y,ref float sin,ref float cos) { float tx = x; x = tx * cos + y * sin; y = -tx * sin + y * cos; } - public void invRotateXYonZ(ref float x, ref float y, ref Quaternion rot) + public void invRotateXYonZ(ref float x,ref float y,ref Quaternion rot) { - float sin = - 2.0f * rot.Z * rot.W; + float sin = -2.0f * rot.Z * rot.W; float cos = rot.W * rot.W - rot.Z * rot.Z; float tx = x; @@ -901,13 +1012,13 @@ namespace OpenSim.Region.PhysicsModule.ubOde y = tx * sin + y * cos; } - public bool Collide(IntPtr me, IntPtr other, bool reverse, ref d.ContactGeom contact, - ref d.ContactGeom altContact , ref bool useAltcontact, ref bool feetcollision) + internal bool Collide(IntPtr me,IntPtr other,bool reverse,ref SafeNativeMethods.ContactGeom contact, + ref SafeNativeMethods.ContactGeom altContact,ref bool useAltcontact,ref bool feetcollision) { feetcollision = false; useAltcontact = false; - if (me == capsule) + if(me == capsule) { Vector3 offset; @@ -917,25 +1028,25 @@ namespace OpenSim.Region.PhysicsModule.ubOde offset.X = contact.pos.X - _position.X; offset.Y = contact.pos.Y - _position.Y; - d.GeomClassID gtype = d.GeomGetClass(other); - if (gtype == d.GeomClassID.CapsuleClass) + SafeNativeMethods.GeomClassID gtype = SafeNativeMethods.GeomGetClass(other); + if(gtype == SafeNativeMethods.GeomClassID.CapsuleClass) { Vector3 roff = offset * Quaternion.Inverse(m_orientation2D); float r = roff.X *roff.X / AvaAvaSizeXsq; r += (roff.Y * roff.Y) / AvaAvaSizeYsq; - if (r > 1.0f) + if(r > 1.0f) return false; float dp = 1.0f -(float)Math.Sqrt((double)r); - if (dp > 0.05f) + if(dp > 0.05f) dp = 0.05f; contact.depth = dp; - if (offset.Z < 0) + if(offset.Z < 0) { feetcollision = true; - if (h < boneOff) + if(h < boneOff) { m_collideNormal.X = contact.normal.X; m_collideNormal.Y = contact.normal.Y; @@ -945,18 +1056,19 @@ namespace OpenSim.Region.PhysicsModule.ubOde } return true; } -/* - d.AABB aabb; - d.GeomGetAABB(other,out aabb); - float othertop = aabb.MaxZ - _position.Z; -*/ -// if (offset.Z > 0 || othertop > -feetOff || contact.normal.Z > 0.35f) - if (offset.Z > 0 || contact.normal.Z > 0.35f) + + if(gtype == SafeNativeMethods.GeomClassID.SphereClass && SafeNativeMethods.GeomGetBody(other) != IntPtr.Zero) { - if (offset.Z <= 0) + if(SafeNativeMethods.GeomSphereGetRadius(other) < 0.5) + return true; + } + + if(offset.Z > 0 || contact.normal.Z > 0.35f) + { + if(offset.Z <= 0) { feetcollision = true; - if (h < boneOff) + if(h < boneOff) { m_collideNormal.X = contact.normal.X; m_collideNormal.Y = contact.normal.Y; @@ -967,6 +1079,18 @@ namespace OpenSim.Region.PhysicsModule.ubOde return true; } + if(m_flying) + return true; + + feetcollision = true; + if(h < boneOff) + { + m_collideNormal.X = contact.normal.X; + m_collideNormal.Y = contact.normal.Y; + m_collideNormal.Z = contact.normal.Z; + IsColliding = true; + } + altContact = contact; useAltcontact = true; @@ -974,10 +1098,23 @@ namespace OpenSim.Region.PhysicsModule.ubOde offset.Normalize(); - if (contact.depth > 0.1f) - contact.depth = 0.1f; + float tdp = contact.depth; + float t = offset.X; + t = Math.Abs(t); + if(t > 1e-6) + { + tdp /= t; + tdp *= contact.normal.X; + } + else + tdp *= 10; - if (reverse) + if(tdp > 0.25f) + tdp = 0.25f; + + altContact.depth = tdp; + + if(reverse) { altContact.normal.X = offset.X; altContact.normal.Y = offset.Y; @@ -989,15 +1126,6 @@ namespace OpenSim.Region.PhysicsModule.ubOde altContact.normal.Y = -offset.Y; altContact.normal.Z = -offset.Z; } - - feetcollision = true; - if (h < boneOff) - { - m_collideNormal.X = contact.normal.X; - m_collideNormal.Y = contact.normal.Y; - m_collideNormal.Z = contact.normal.Z; - IsColliding = true; - } return true; } return false; @@ -1010,28 +1138,28 @@ namespace OpenSim.Region.PhysicsModule.ubOde /// public void Move(List defects) { - if (Body == IntPtr.Zero) + if(Body == IntPtr.Zero) return; - d.Vector3 dtmp = d.BodyGetPosition(Body); - Vector3 localpos = new Vector3(dtmp.X, dtmp.Y, dtmp.Z); + SafeNativeMethods.Vector3 dtmp = SafeNativeMethods.BodyGetPosition(Body); + Vector3 localpos = new Vector3(dtmp.X,dtmp.Y,dtmp.Z); // the Amotor still lets avatar rotation to drift during colisions // so force it back to identity - d.Quaternion qtmp; + SafeNativeMethods.Quaternion qtmp; qtmp.W = m_orientation2D.W; qtmp.X = m_orientation2D.X; qtmp.Y = m_orientation2D.Y; qtmp.Z = m_orientation2D.Z; - d.BodySetQuaternion(Body, ref qtmp); + SafeNativeMethods.BodySetQuaternion(Body,ref qtmp); - if (m_pidControllerActive == false) + if(m_pidControllerActive == false) { _zeroPosition = localpos; } - if (!localpos.IsFinite()) + if(!localpos.IsFinite()) { m_log.Warn("[PHYSICS]: Avatar Position is non-finite!"); defects.Add(this); @@ -1044,44 +1172,44 @@ namespace OpenSim.Region.PhysicsModule.ubOde // check outbounds forcing to be in world bool fixbody = false; - if (localpos.X < 0.0f) + if(localpos.X < 0.0f) { fixbody = true; localpos.X = 0.1f; } - else if (localpos.X > _parent_scene.WorldExtents.X - 0.1f) + else if(localpos.X > m_parent_scene.WorldExtents.X - 0.1f) { fixbody = true; - localpos.X = _parent_scene.WorldExtents.X - 0.1f; + localpos.X = m_parent_scene.WorldExtents.X - 0.1f; } - if (localpos.Y < 0.0f) + if(localpos.Y < 0.0f) { fixbody = true; localpos.Y = 0.1f; } - else if (localpos.Y > _parent_scene.WorldExtents.Y - 0.1) + else if(localpos.Y > m_parent_scene.WorldExtents.Y - 0.1) { fixbody = true; - localpos.Y = _parent_scene.WorldExtents.Y - 0.1f; + localpos.Y = m_parent_scene.WorldExtents.Y - 0.1f; } - if (fixbody) + if(fixbody) { m_freemove = false; - d.BodySetPosition(Body, localpos.X, localpos.Y, localpos.Z); + SafeNativeMethods.BodySetPosition(Body,localpos.X,localpos.Y,localpos.Z); } float breakfactor; Vector3 vec = Vector3.Zero; - dtmp = d.BodyGetLinearVel(Body); - Vector3 vel = new Vector3(dtmp.X, dtmp.Y, dtmp.Z); + dtmp = SafeNativeMethods.BodyGetLinearVel(Body); + Vector3 vel = new Vector3(dtmp.X,dtmp.Y,dtmp.Z); float velLengthSquared = vel.LengthSquared(); Vector3 ctz = _target_velocity; float movementdivisor = 1f; //Ubit change divisions into multiplications below - if (!m_alwaysRun) + if(!m_alwaysRun) movementdivisor = 1 / walkDivisor; else movementdivisor = 1 / runDivisor; @@ -1092,25 +1220,25 @@ namespace OpenSim.Region.PhysicsModule.ubOde //****************************************** // colide with land - d.AABB aabb; -// d.GeomGetAABB(feetbox, out aabb); - d.GeomGetAABB(capsule, out aabb); + SafeNativeMethods.AABB aabb; + // d.GeomGetAABB(feetbox, out aabb); + SafeNativeMethods.GeomGetAABB(capsule,out aabb); float chrminZ = aabb.MinZ; // move up a bit Vector3 posch = localpos; float ftmp; - if (flying) + if(m_flying) { ftmp = timeStep; posch.X += vel.X * ftmp; posch.Y += vel.Y * ftmp; } - float terrainheight = _parent_scene.GetTerrainHeightAtXY(posch.X, posch.Y); - if (chrminZ < terrainheight) + float terrainheight = m_parent_scene.GetTerrainHeightAtXY(posch.X,posch.Y); + if(chrminZ < terrainheight) { - if (ctz.Z < 0) + if(ctz.Z < 0) ctz.Z = 0; if(!m_haveLastFallVel) @@ -1119,12 +1247,12 @@ namespace OpenSim.Region.PhysicsModule.ubOde m_haveLastFallVel = true; } - Vector3 n = _parent_scene.GetTerrainNormalAtXY(posch.X, posch.Y); + Vector3 n = m_parent_scene.GetTerrainNormalAtXY(posch.X,posch.Y); float depth = terrainheight - chrminZ; vec.Z = depth * PID_P * 50; - if (!flying) + if(!m_flying) { vec.Z += -vel.Z * PID_D; if(n.Z < 0.4f) @@ -1140,19 +1268,19 @@ namespace OpenSim.Region.PhysicsModule.ubOde n.X = 0f; n.Y = 0f; n.Z = 1.0f; - } + } } } - if (depth < 0.2f) + if(depth < 0.2f) { m_colliderGroundfilter++; - if (m_colliderGroundfilter > 2) + if(m_colliderGroundfilter > 2) { m_iscolliding = true; m_colliderfilter = 2; - if (m_colliderGroundfilter > 10) + if(m_colliderGroundfilter > 10) { m_colliderGroundfilter = 10; m_freemove = false; @@ -1172,19 +1300,19 @@ namespace OpenSim.Region.PhysicsModule.ubOde contact.SurfaceNormal.X = -n.X; contact.SurfaceNormal.Y = -n.Y; contact.SurfaceNormal.Z = -n.Z; - contact.RelativeSpeed = Vector3.Dot(m_lastFallVel, n); + contact.RelativeSpeed = Vector3.Dot(m_lastFallVel,n); contact.CharacterFeet = true; - AddCollisionEvent(0, contact); + AddCollisionEvent(0,contact); m_lastFallVel = vel; -// vec.Z *= 0.5f; + // vec.Z *= 0.5f; } } else { m_colliderGroundfilter -= 5; - if (m_colliderGroundfilter <= 0) + if(m_colliderGroundfilter <= 0) { m_colliderGroundfilter = 0; m_iscollidingGround = false; @@ -1195,7 +1323,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde { m_haveLastFallVel = false; m_colliderGroundfilter -= 5; - if (m_colliderGroundfilter <= 0) + if(m_colliderGroundfilter <= 0) { m_colliderGroundfilter = 0; m_iscollidingGround = false; @@ -1204,32 +1332,32 @@ namespace OpenSim.Region.PhysicsModule.ubOde bool hoverPIDActive = false; - if (m_useHoverPID && m_PIDHoverTau != 0 && m_PIDHoverHeight != 0) + if(m_useHoverPID && m_PIDHoverTau != 0 && m_PIDHoverHeight != 0) { hoverPIDActive = true; - switch (m_PIDHoverType) + switch(m_PIDHoverType) { case PIDHoverType.Ground: m_targetHoverHeight = terrainheight + m_PIDHoverHeight; break; case PIDHoverType.GroundAndWater: - float waterHeight = _parent_scene.GetWaterLevel(); - if (terrainheight > waterHeight) + float waterHeight = m_parent_scene.GetWaterLevel(); + if(terrainheight > waterHeight) m_targetHoverHeight = terrainheight + m_PIDHoverHeight; else m_targetHoverHeight = waterHeight + m_PIDHoverHeight; break; } // end switch (m_PIDHoverType) - // don't go underground - if (m_targetHoverHeight > terrainheight + 0.5f * (aabb.MaxZ - aabb.MinZ)) + // don't go underground + if(m_targetHoverHeight > terrainheight + 0.5f * (aabb.MaxZ - aabb.MinZ)) { float fz = (m_targetHoverHeight - localpos.Z); // if error is zero, use position control; otherwise, velocity control - if (Math.Abs(fz) < 0.01f) + if(Math.Abs(fz) < 0.01f) { ctz.Z = 0; } @@ -1239,9 +1367,9 @@ namespace OpenSim.Region.PhysicsModule.ubOde fz /= m_PIDHoverTau; float tmp = Math.Abs(fz); - if (tmp > 50) + if(tmp > 50) fz = 50 * Math.Sign(fz); - else if (tmp < 0.1) + else if(tmp < 0.1) fz = 0.1f * Math.Sign(fz); ctz.Z = fz; @@ -1250,43 +1378,43 @@ namespace OpenSim.Region.PhysicsModule.ubOde } //****************************************** - if (!m_iscolliding) + if(!m_iscolliding) m_collideNormal.Z = 0; bool tviszero = (ctz.X == 0.0f && ctz.Y == 0.0f && ctz.Z == 0.0f); - if (!tviszero) + if(!tviszero) { m_freemove = false; // movement relative to surface if moving on it // dont disturbe vertical movement, ie jumps - if (m_iscolliding && !flying && ctz.Z == 0 && m_collideNormal.Z > 0.2f && m_collideNormal.Z < 0.94f) + if(m_iscolliding && !m_flying && ctz.Z == 0 && m_collideNormal.Z > 0.2f && m_collideNormal.Z < 0.94f) { float p = ctz.X * m_collideNormal.X + ctz.Y * m_collideNormal.Y; ctz.X *= (float)Math.Sqrt(1 - m_collideNormal.X * m_collideNormal.X); ctz.Y *= (float)Math.Sqrt(1 - m_collideNormal.Y * m_collideNormal.Y); ctz.Z -= p; - if (ctz.Z < 0) + if(ctz.Z < 0) ctz.Z *= 2; } } - if (!m_freemove) + if(!m_freemove) { // if velocity is zero, use position control; otherwise, velocity control - if (tviszero && m_iscolliding && !flying) + if(tviszero && m_iscolliding && !m_flying) { // keep track of where we stopped. No more slippin' & slidin' - if (!_zeroFlag) + if(!_zeroFlag) { _zeroFlag = true; _zeroPosition = localpos; } - if (m_pidControllerActive) + if(m_pidControllerActive) { // We only want to deactivate the PID Controller if we think we want to have our surrogate // react to the physics scene by moving it's position. @@ -1299,12 +1427,12 @@ namespace OpenSim.Region.PhysicsModule.ubOde vec.Z += -vel.Z * PID_D + (_zeroPosition.Z - localpos.Z) * PID_P; else vec.Z += (-vel.Z * PID_D + (_zeroPosition.Z - localpos.Z) * PID_P) * 0.2f; -/* - if (flying) - { - vec.Z += -vel.Z * PID_D + (_zeroPosition.Z - localpos.Z) * PID_P; - } -*/ + /* + if (flying) + { + vec.Z += -vel.Z * PID_D + (_zeroPosition.Z - localpos.Z) * PID_P; + } + */ } //PidStatus = true; } @@ -1313,12 +1441,12 @@ namespace OpenSim.Region.PhysicsModule.ubOde m_pidControllerActive = true; _zeroFlag = false; - if (m_iscolliding) + if(m_iscolliding) { - if (!flying) + if(!m_flying) { // we are on a surface - if (ctz.Z > 0f) + if(ctz.Z > 0f) { // moving up or JUMPING vec.Z += (ctz.Z - vel.Z) * PID_D * 2f; @@ -1328,9 +1456,9 @@ namespace OpenSim.Region.PhysicsModule.ubOde else { // we are moving down on a surface - if (ctz.Z == 0) + if(ctz.Z == 0) { - if (vel.Z > 0) + if(vel.Z > 0) vec.Z -= vel.Z * PID_D * 2f; vec.X += (ctz.X - vel.X) * (PID_D); vec.Y += (ctz.Y - vel.Y) * (PID_D); @@ -1338,15 +1466,15 @@ namespace OpenSim.Region.PhysicsModule.ubOde // intencionally going down else { - if (ctz.Z < vel.Z) + if(ctz.Z < vel.Z) vec.Z += (ctz.Z - vel.Z) * PID_D; else { } - if (Math.Abs(ctz.X) > Math.Abs(vel.X)) + if(Math.Abs(ctz.X) > Math.Abs(vel.X)) vec.X += (ctz.X - vel.X) * (PID_D); - if (Math.Abs(ctz.Y) > Math.Abs(vel.Y)) + if(Math.Abs(ctz.Y) > Math.Abs(vel.Y)) vec.Y += (ctz.Y - vel.Y) * (PID_D); } } @@ -1363,7 +1491,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde } else // ie not colliding { - if (flying || hoverPIDActive) //(!m_iscolliding && flying) + if(m_flying || hoverPIDActive) //(!m_iscolliding && flying) { // we're in mid air suspended vec.X += (ctz.X - vel.X) * (PID_D); @@ -1380,13 +1508,13 @@ namespace OpenSim.Region.PhysicsModule.ubOde vec.X += (ctz.X - vel.X) * PID_D * 0.833f; vec.Y += (ctz.Y - vel.Y) * PID_D * 0.833f; // hack for breaking on fall - if (ctz.Z == -9999f) - vec.Z += -vel.Z * PID_D - _parent_scene.gravityz * m_mass; + if(ctz.Z == -9999f) + vec.Z += -vel.Z * PID_D - m_parent_scene.gravityz * m_mass; } } } - if (velLengthSquared > 2500.0f) // 50m/s apply breaks + if(velLengthSquared > 2500.0f) // 50m/s apply breaks { breakfactor = 0.16f * m_mass; vec.X -= breakfactor * vel.X; @@ -1399,33 +1527,33 @@ namespace OpenSim.Region.PhysicsModule.ubOde breakfactor = m_mass; vec.X -= breakfactor * vel.X; vec.Y -= breakfactor * vel.Y; - if (flying) + if(m_flying) vec.Z -= 0.5f * breakfactor * vel.Z; else vec.Z -= .16f* m_mass * vel.Z; } - if (flying || hoverPIDActive) + if(m_flying || hoverPIDActive) { - vec.Z -= _parent_scene.gravityz * m_mass; + vec.Z -= m_parent_scene.gravityz * m_mass; if(!hoverPIDActive) { //Added for auto fly height. Kitto Flora float target_altitude = terrainheight + MinimumGroundFlightOffset; - if (localpos.Z < target_altitude) + if(localpos.Z < target_altitude) { - vec.Z += (target_altitude - localpos.Z) * PID_P * 5.0f; + vec.Z += (target_altitude - localpos.Z) * PID_P * 5.0f; } // end add Kitto Flora } } - if (vec.IsFinite()) + if(vec.IsFinite()) { - if (vec.X != 0 || vec.Y !=0 || vec.Z !=0) - d.BodyAddForce(Body, vec.X, vec.Y, vec.Z); + if(vec.X != 0 || vec.Y !=0 || vec.Z !=0) + SafeNativeMethods.BodyAddForce(Body,vec.X,vec.Y,vec.Z); } else { @@ -1442,7 +1570,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde // _position = localpos; _position = localpos; - if (_zeroFlag) + if(_zeroFlag) { _velocity = Vector3.Zero; _acceleration = Vector3.Zero; @@ -1450,12 +1578,12 @@ namespace OpenSim.Region.PhysicsModule.ubOde } else { - Vector3 a =_velocity; // previus velocity - SetSmooth(ref _velocity, ref vel, 2); + Vector3 a = _velocity; // previus velocity + SetSmooth(ref _velocity,ref vel,2); a = (_velocity - a) * invtimeStep; - SetSmooth(ref _acceleration, ref a, 2); + SetSmooth(ref _acceleration,ref a,2); - dtmp = d.BodyGetAngularVel(Body); + dtmp = SafeNativeMethods.BodyGetAngularVel(Body); m_rotationalVelocity.X = 0f; m_rotationalVelocity.Y = 0f; m_rotationalVelocity.Z = dtmp.Z; @@ -1463,30 +1591,30 @@ namespace OpenSim.Region.PhysicsModule.ubOde } } - public void round(ref Vector3 v, int digits) + public void round(ref Vector3 v,int digits) { - v.X = (float)Math.Round(v.X, digits); - v.Y = (float)Math.Round(v.Y, digits); - v.Z = (float)Math.Round(v.Z, digits); - } + v.X = (float)Math.Round(v.X,digits); + v.Y = (float)Math.Round(v.Y,digits); + v.Z = (float)Math.Round(v.Z,digits); + } - public void SetSmooth(ref Vector3 dst, ref Vector3 value) + public void SetSmooth(ref Vector3 dst,ref Vector3 value) { dst.X = 0.1f * dst.X + 0.9f * value.X; dst.Y = 0.1f * dst.Y + 0.9f * value.Y; dst.Z = 0.1f * dst.Z + 0.9f * value.Z; } - public void SetSmooth(ref Vector3 dst, ref Vector3 value, int rounddigits) + public void SetSmooth(ref Vector3 dst,ref Vector3 value,int rounddigits) { dst.X = 0.4f * dst.X + 0.6f * value.X; - dst.X = (float)Math.Round(dst.X, rounddigits); + dst.X = (float)Math.Round(dst.X,rounddigits); dst.Y = 0.4f * dst.Y + 0.6f * value.Y; - dst.Y = (float)Math.Round(dst.Y, rounddigits); + dst.Y = (float)Math.Round(dst.Y,rounddigits); dst.Z = 0.4f * dst.Z + 0.6f * value.Z; - dst.Z = (float)Math.Round(dst.Z, rounddigits); + dst.Z = (float)Math.Round(dst.Z,rounddigits); } @@ -1501,8 +1629,8 @@ namespace OpenSim.Region.PhysicsModule.ubOde { return; -// if (Body == IntPtr.Zero) -// return; + // if (Body == IntPtr.Zero) + // return; } @@ -1511,16 +1639,38 @@ namespace OpenSim.Region.PhysicsModule.ubOde /// public void Destroy() { - AddChange(changes.Remove, null); + AddChange(changes.Remove,null); } public override void CrossingFailure() { } - public override Vector3 PIDTarget { set { return; } } - public override bool PIDActive {get {return m_pidControllerActive;} set { return; } } - public override float PIDTau { set { return; } } + public override Vector3 PIDTarget + { + set + { + return; + } + } + public override bool PIDActive + { + get + { + return m_pidControllerActive; + } + set + { + return; + } + } + public override float PIDTau + { + set + { + return; + } + } public override float PIDHoverHeight { @@ -1533,11 +1683,11 @@ namespace OpenSim.Region.PhysicsModule.ubOde { get { - return m_useHoverPID; + return m_useHoverPID; } set { - AddChange(changes.PIDHoverActive, value); + AddChange(changes.PIDHoverActive,value); } } @@ -1553,26 +1703,50 @@ namespace OpenSim.Region.PhysicsModule.ubOde { set { - float tmp =0; - if (value > 0) + float tmp = 0; + if(value > 0) { float mint = (0.05f > timeStep ? 0.05f : timeStep); - if (value < mint) + if(value < mint) tmp = mint; else tmp = value; } - AddChange(changes.PIDHoverTau, tmp); + AddChange(changes.PIDHoverTau,tmp); } } - public override Quaternion APIDTarget { set { return; } } + public override Quaternion APIDTarget + { + set + { + return; + } + } - public override bool APIDActive { set { return; } } + public override bool APIDActive + { + set + { + return; + } + } - public override float APIDStrength { set { return; } } + public override float APIDStrength + { + set + { + return; + } + } - public override float APIDDamping { set { return; } } + public override float APIDDamping + { + set + { + return; + } + } public override void SubscribeEvents(int ms) { @@ -1585,39 +1759,39 @@ namespace OpenSim.Region.PhysicsModule.ubOde public override void UnSubscribeEvents() { m_eventsubscription = 0; - _parent_scene.RemoveCollisionEventReporting(this); + m_parent_scene.RemoveCollisionEventReporting(this); lock(CollisionEventsThisFrame) CollisionEventsThisFrame.Clear(); } - public override void AddCollisionEvent(uint CollidedWith, ContactPoint contact) + public override void AddCollisionEvent(uint CollidedWith,ContactPoint contact) { lock(CollisionEventsThisFrame) - CollisionEventsThisFrame.AddCollider(CollidedWith, contact); - _parent_scene.AddCollisionEventReporting(this); + CollisionEventsThisFrame.AddCollider(CollidedWith,contact); + m_parent_scene.AddCollisionEventReporting(this); } public void SendCollisions(int timestep) { - if (m_cureventsubscription < 50000) + if(m_cureventsubscription < 50000) m_cureventsubscription += timestep; - if (m_cureventsubscription < m_eventsubscription) + if(m_cureventsubscription < m_eventsubscription) return; lock(CollisionEventsThisFrame) { int ncolisions = CollisionEventsThisFrame.m_objCollisionList.Count; - if (!SentEmptyCollisionsEvent || ncolisions > 0) + if(!SentEmptyCollisionsEvent || ncolisions > 0) { base.SendCollisionUpdate(CollisionEventsThisFrame); m_cureventsubscription = 0; - if (ncolisions == 0) + if(ncolisions == 0) { SentEmptyCollisionsEvent = true; - // _parent_scene.RemoveCollisionEventReporting(this); + // _parent_scene.RemoveCollisionEventReporting(this); } else { @@ -1630,29 +1804,29 @@ namespace OpenSim.Region.PhysicsModule.ubOde public override bool SubscribedEvents() { - if (m_eventsubscription > 0) + if(m_eventsubscription > 0) return true; return false; } private void changePhysicsStatus(bool NewStatus) { - if (NewStatus != m_isPhysical) + if(NewStatus != m_isPhysical) { - if (NewStatus) + if(NewStatus) { AvatarGeomAndBodyDestroy(); - AvatarGeomAndBodyCreation(_position.X, _position.Y, _position.Z); + AvatarGeomAndBodyCreation(_position.X,_position.Y,_position.Z); - _parent_scene.actor_name_map[collider] = (PhysicsActor)this; - _parent_scene.actor_name_map[capsule] = (PhysicsActor)this; - _parent_scene.AddCharacter(this); + m_parent_scene.actor_name_map[collider] = (PhysicsActor)this; + m_parent_scene.actor_name_map[capsule] = (PhysicsActor)this; + m_parent_scene.AddCharacter(this); } else { - _parent_scene.RemoveCollisionEventReporting(this); - _parent_scene.RemoveCharacter(this); + m_parent_scene.RemoveCollisionEventReporting(this); + m_parent_scene.RemoveCharacter(this); // destroy avatar capsule and related ODE data AvatarGeomAndBodyDestroy(); } @@ -1683,24 +1857,24 @@ namespace OpenSim.Region.PhysicsModule.ubOde private void changeSize(Vector3 pSize) { - if (pSize.IsFinite()) + if(pSize.IsFinite()) { // for now only look to Z changes since viewers also don't change X and Y - if (pSize.Z != m_size.Z) + if(pSize.Z != m_size.Z) { AvatarGeomAndBodyDestroy(); float oldsz = m_size.Z; m_size = pSize; - AvatarGeomAndBodyCreation(_position.X, _position.Y, + AvatarGeomAndBodyCreation(_position.X,_position.Y, _position.Z + (m_size.Z - oldsz) * 0.5f); -// Velocity = Vector3.Zero; + // Velocity = Vector3.Zero; m_targetVelocity = Vector3.Zero; - _parent_scene.actor_name_map[collider] = (PhysicsActor)this; - _parent_scene.actor_name_map[capsule] = (PhysicsActor)this; + m_parent_scene.actor_name_map[collider] = (PhysicsActor)this; + m_parent_scene.actor_name_map[capsule] = (PhysicsActor)this; } m_freemove = false; m_pidControllerActive = true; @@ -1711,18 +1885,18 @@ namespace OpenSim.Region.PhysicsModule.ubOde } } - private void changePosition( Vector3 newPos) - { - if (Body != IntPtr.Zero) - d.BodySetPosition(Body, newPos.X, newPos.Y, newPos.Z); - _position = newPos; - m_freemove = false; - m_pidControllerActive = true; - } + private void changePosition(Vector3 newPos) + { + if(Body != IntPtr.Zero) + SafeNativeMethods.BodySetPosition(Body,newPos.X,newPos.Y,newPos.Z); + _position = newPos; + m_freemove = false; + m_pidControllerActive = true; + } private void changeOrientation(Quaternion newOri) { - if (m_orientation != newOri) + if(m_orientation != newOri) { m_orientation = newOri; // keep a copy for core use // but only use rotations around Z @@ -1731,7 +1905,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde m_orientation2D.Z = newOri.Z; float t = m_orientation2D.W * m_orientation2D.W + m_orientation2D.Z * m_orientation2D.Z; - if (t > 0) + if(t > 0) { t = 1.0f / (float)Math.Sqrt(t); m_orientation2D.W *= t; @@ -1745,12 +1919,12 @@ namespace OpenSim.Region.PhysicsModule.ubOde m_orientation2D.Y = 0f; m_orientation2D.X = 0f; - d.Quaternion myrot = new d.Quaternion(); + SafeNativeMethods.Quaternion myrot = new SafeNativeMethods.Quaternion(); myrot.X = m_orientation2D.X; myrot.Y = m_orientation2D.Y; myrot.Z = m_orientation2D.Z; myrot.W = m_orientation2D.W; - d.BodySetQuaternion(Body, ref myrot); + SafeNativeMethods.BodySetQuaternion(Body,ref myrot); } } @@ -1759,8 +1933,8 @@ namespace OpenSim.Region.PhysicsModule.ubOde _velocity = newVel; setFreeMove(); - if (Body != IntPtr.Zero) - d.BodySetLinearVel(Body, newVel.X, newVel.Y, newVel.Z); + if(Body != IntPtr.Zero) + SafeNativeMethods.BodySetLinearVel(Body,newVel.X,newVel.Y,newVel.Z); } private void changeTargetVelocity(Vector3 newVel) @@ -1827,10 +2001,10 @@ namespace OpenSim.Region.PhysicsModule.ubOde { setFreeMove(); - if (Body != IntPtr.Zero) + if(Body != IntPtr.Zero) { - if (newForce.X != 0f || newForce.Y != 0f || newForce.Z != 0) - d.BodyAddForce(Body, newForce.X, newForce.Y, newForce.Z); + if(newForce.X != 0f || newForce.Y != 0f || newForce.Z != 0) + SafeNativeMethods.BodyAddForce(Body,newForce.X,newForce.Y,newForce.Z); } } @@ -1840,15 +2014,15 @@ namespace OpenSim.Region.PhysicsModule.ubOde _velocity = newmomentum; setFreeMove(); - if (Body != IntPtr.Zero) - d.BodySetLinearVel(Body, newmomentum.X, newmomentum.Y, newmomentum.Z); + if(Body != IntPtr.Zero) + SafeNativeMethods.BodySetLinearVel(Body,newmomentum.X,newmomentum.Y,newmomentum.Z); } private void changePIDHoverHeight(float val) { - m_PIDHoverHeight = val; - if (val == 0) - m_useHoverPID = false; + m_PIDHoverHeight = val; + if(val == 0) + m_useHoverPID = false; } private void changePIDHoverType(PIDHoverType type) @@ -1870,15 +2044,15 @@ namespace OpenSim.Region.PhysicsModule.ubOde { } - public bool DoAChange(changes what, object arg) + public bool DoAChange(changes what,object arg) { - if (collider == IntPtr.Zero && what != changes.Add && what != changes.Remove) + if(collider == IntPtr.Zero && what != changes.Add && what != changes.Remove) { return false; } // nasty switch - switch (what) + switch(what) { case changes.Add: changeAdd(); @@ -1966,35 +2140,35 @@ namespace OpenSim.Region.PhysicsModule.ubOde changePIDHoverActive((bool)arg); break; -/* not in use for now - case changes.Shape: - changeShape((PrimitiveBaseShape)arg); - break; + /* not in use for now + case changes.Shape: + changeShape((PrimitiveBaseShape)arg); + break; - case changes.CollidesWater: - changeFloatOnWater((bool)arg); - break; + case changes.CollidesWater: + changeFloatOnWater((bool)arg); + break; - case changes.VolumeDtc: - changeVolumedetetion((bool)arg); - break; + case changes.VolumeDtc: + changeVolumedetetion((bool)arg); + break; - case changes.Physical: - changePhysicsStatus((bool)arg); - break; + case changes.Physical: + changePhysicsStatus((bool)arg); + break; - case changes.Selected: - changeSelectedStatus((bool)arg); - break; + case changes.Selected: + changeSelectedStatus((bool)arg); + break; - case changes.disabled: - changeDisable((bool)arg); - break; + case changes.disabled: + changeDisable((bool)arg); + break; - case changes.building: - changeBuilding((bool)arg); - break; -*/ + case changes.building: + changeBuilding((bool)arg); + break; + */ case changes.Null: donullchange(); break; @@ -2006,9 +2180,9 @@ namespace OpenSim.Region.PhysicsModule.ubOde return false; } - public void AddChange(changes what, object arg) + public void AddChange(changes what,object arg) { - _parent_scene.AddChange((PhysicsActor)this, what, arg); + m_parent_scene.AddChange((PhysicsActor)this,what,arg); } private struct strAvatarSize diff --git a/OpenSim/Region/PhysicsModules/ubOde/ODEDynamics.cs b/OpenSim/Region/PhysicsModules/ubOde/ODEDynamics.cs index 63bef7cdc6..23b119213e 100644 --- a/OpenSim/Region/PhysicsModules/ubOde/ODEDynamics.cs +++ b/OpenSim/Region/PhysicsModules/ubOde/ODEDynamics.cs @@ -41,13 +41,7 @@ // Extensive change Ubit 2012 using System; -using System.Collections.Generic; -using System.Reflection; -using System.Runtime.InteropServices; -using log4net; using OpenMetaverse; -using OdeAPI; -using OpenSim.Framework; using OpenSim.Region.PhysicsModules.SharedBase; namespace OpenSim.Region.PhysicsModule.ubOde @@ -243,6 +237,8 @@ namespace OpenSim.Region.PhysicsModule.ubOde internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue) { float len; + if(float.IsNaN(pValue) || float.IsInfinity(pValue)) + return; switch (pParam) { @@ -340,9 +336,10 @@ namespace OpenSim.Region.PhysicsModule.ubOde m_amEfect = 1.0f ; // turn it on m_amDecay = 1.0f - 1.0f / m_angularMotorDecayTimescale; - if (rootPrim.Body != IntPtr.Zero && !d.BodyIsEnabled(rootPrim.Body) + if (rootPrim.Body != IntPtr.Zero && !SafeNativeMethods.BodyIsEnabled(rootPrim.Body) && !rootPrim.m_isSelected && !rootPrim.m_disabled) - d.BodyEnable(rootPrim.Body); + SafeNativeMethods.BodyEnable(rootPrim.Body); + break; case Vehicle.LINEAR_FRICTION_TIMESCALE: if (pValue < m_timestep) pValue = m_timestep; @@ -358,9 +355,9 @@ namespace OpenSim.Region.PhysicsModule.ubOde m_lmEfect = 1.0f; // turn it on m_ffactor = 0.0f; - if (rootPrim.Body != IntPtr.Zero && !d.BodyIsEnabled(rootPrim.Body) + if (rootPrim.Body != IntPtr.Zero && !SafeNativeMethods.BodyIsEnabled(rootPrim.Body) && !rootPrim.m_isSelected && !rootPrim.m_disabled) - d.BodyEnable(rootPrim.Body); + SafeNativeMethods.BodyEnable(rootPrim.Body); break; case Vehicle.LINEAR_MOTOR_OFFSET: m_linearMotorOffset = new Vector3(pValue, pValue, pValue); @@ -374,6 +371,8 @@ namespace OpenSim.Region.PhysicsModule.ubOde internal void ProcessVectorVehicleParam(Vehicle pParam, Vector3 pValue) { float len; + if(!pValue.IsFinite()) + return; switch (pParam) { @@ -394,9 +393,9 @@ namespace OpenSim.Region.PhysicsModule.ubOde m_amEfect = 1.0f; // turn it on m_amDecay = 1.0f - 1.0f / m_angularMotorDecayTimescale; - if (rootPrim.Body != IntPtr.Zero && !d.BodyIsEnabled(rootPrim.Body) + if (rootPrim.Body != IntPtr.Zero && !SafeNativeMethods.BodyIsEnabled(rootPrim.Body) && !rootPrim.m_isSelected && !rootPrim.m_disabled) - d.BodyEnable(rootPrim.Body); + SafeNativeMethods.BodyEnable(rootPrim.Body); break; case Vehicle.LINEAR_FRICTION_TIMESCALE: if (pValue.X < m_timestep) pValue.X = m_timestep; @@ -414,9 +413,9 @@ namespace OpenSim.Region.PhysicsModule.ubOde m_lmDecay = 1.0f - 1.0f / m_linearMotorDecayTimescale; m_ffactor = 0.0f; - if (rootPrim.Body != IntPtr.Zero && !d.BodyIsEnabled(rootPrim.Body) + if (rootPrim.Body != IntPtr.Zero && !SafeNativeMethods.BodyIsEnabled(rootPrim.Body) && !rootPrim.m_isSelected && !rootPrim.m_disabled) - d.BodyEnable(rootPrim.Body); + SafeNativeMethods.BodyEnable(rootPrim.Body); break; case Vehicle.LINEAR_MOTOR_OFFSET: m_linearMotorOffset = new Vector3(pValue.X, pValue.Y, pValue.Z); @@ -767,30 +766,30 @@ namespace OpenSim.Region.PhysicsModule.ubOde { IntPtr Body = rootPrim.Body; - d.Mass dmass; - d.BodyGetMass(Body, out dmass); + SafeNativeMethods.Mass dmass; + SafeNativeMethods.BodyGetMass(Body, out dmass); - d.Quaternion rot = d.BodyGetQuaternion(Body); + SafeNativeMethods.Quaternion rot = SafeNativeMethods.BodyGetQuaternion(Body); Quaternion objrotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W); // rotq = rotation of object Quaternion rotq = objrotq; // rotq = rotation of object rotq *= m_referenceFrame; // rotq is now rotation in vehicle reference frame Quaternion irotq = Quaternion.Inverse(rotq); - d.Vector3 dvtmp; + SafeNativeMethods.Vector3 dvtmp; Vector3 tmpV; Vector3 curVel; // velocity in world Vector3 curAngVel; // angular velocity in world Vector3 force = Vector3.Zero; // actually linear aceleration until mult by mass in world frame Vector3 torque = Vector3.Zero;// actually angular aceleration until mult by Inertia in vehicle frame - d.Vector3 dtorque = new d.Vector3(); + SafeNativeMethods.Vector3 dtorque = new SafeNativeMethods.Vector3(); - dvtmp = d.BodyGetLinearVel(Body); + dvtmp = SafeNativeMethods.BodyGetLinearVel(Body); curVel.X = dvtmp.X; curVel.Y = dvtmp.Y; curVel.Z = dvtmp.Z; Vector3 curLocalVel = curVel * irotq; // current velocity in local - dvtmp = d.BodyGetAngularVel(Body); + dvtmp = SafeNativeMethods.BodyGetAngularVel(Body); curAngVel.X = dvtmp.X; curAngVel.Y = dvtmp.Y; curAngVel.Z = dvtmp.Z; @@ -834,7 +833,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde { // have offset, do it now tmpV *= dmass.mass; - d.BodyAddForceAtRelPos(Body, tmpV.X, tmpV.Y, tmpV.Z, m_linearMotorOffset.X, m_linearMotorOffset.Y, m_linearMotorOffset.Z); + SafeNativeMethods.BodyAddForceAtRelPos(Body, tmpV.X, tmpV.Y, tmpV.Z, m_linearMotorOffset.X, m_linearMotorOffset.Y, m_linearMotorOffset.Z); } else { @@ -857,7 +856,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde if (m_VhoverTimescale < 300 && rootPrim.prim_geom != IntPtr.Zero) { // d.Vector3 pos = d.BodyGetPosition(Body); - d.Vector3 pos = d.GeomGetPosition(rootPrim.prim_geom); + SafeNativeMethods.Vector3 pos = SafeNativeMethods.GeomGetPosition(rootPrim.prim_geom); pos.Z -= 0.21f; // minor offset that seems to be always there in sl float t = _pParentScene.GetTerrainHeightAtXY(pos.X, pos.Y); @@ -1176,7 +1175,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde if (force.X != 0 || force.Y != 0 || force.Z != 0) { - d.BodyAddForce(Body, force.X, force.Y, force.Z); + SafeNativeMethods.BodyAddForce(Body, force.X, force.Y, force.Z); } if (torque.X != 0 || torque.Y != 0 || torque.Z != 0) @@ -1186,15 +1185,15 @@ namespace OpenSim.Region.PhysicsModule.ubOde dtorque.Y = torque.Y; dtorque.Z = torque.Z; - d.MultiplyM3V3(out dvtmp, ref dmass.I, ref dtorque); - d.BodyAddRelTorque(Body, dvtmp.X, dvtmp.Y, dvtmp.Z); // add torque in object frame + SafeNativeMethods.MultiplyM3V3(out dvtmp, ref dmass.I, ref dtorque); + SafeNativeMethods.BodyAddRelTorque(Body, dvtmp.X, dvtmp.Y, dvtmp.Z); // add torque in object frame } torque = rootPrim.m_torque; torque += rootPrim.m_angularForceacc; rootPrim.m_angularForceacc = Vector3.Zero; if (torque.X != 0 || torque.Y != 0 || torque.Z != 0) - d.BodyAddTorque(Body,torque.X, torque.Y, torque.Z); + SafeNativeMethods.BodyAddTorque(Body,torque.X, torque.Y, torque.Z); } } } diff --git a/OpenSim/Region/PhysicsModules/ubOde/ODEMeshWorker.cs b/OpenSim/Region/PhysicsModules/ubOde/ODEMeshWorker.cs index 923e2ff8ba..bdfbe3d5b7 100644 --- a/OpenSim/Region/PhysicsModules/ubOde/ODEMeshWorker.cs +++ b/OpenSim/Region/PhysicsModules/ubOde/ODEMeshWorker.cs @@ -3,15 +3,10 @@ */ using System; +using System.Collections.Concurrent; using System.Threading; -using System.Collections.Generic; -using System.IO; -using System.Reflection; -using System.Runtime.InteropServices; -using System.Text; using OpenSim.Framework; using OpenSim.Region.PhysicsModules.SharedBase; -using OdeAPI; using log4net; using Nini.Config; using OpenMetaverse; @@ -62,6 +57,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde public byte shapetype; public bool hasOBB; public bool hasMeshVolume; + public bool isTooSmall; public MeshState meshState; public UUID? assetID; public meshWorkerCmnds comand; @@ -69,18 +65,16 @@ namespace OpenSim.Region.PhysicsModule.ubOde public class ODEMeshWorker { - private ILog m_log; private ODEScene m_scene; private IMesher m_mesher; public bool meshSculptedPrim = true; - public bool forceSimplePrimMeshing = false; public float meshSculptLOD = 32; public float MeshSculptphysicalLOD = 32; + public float MinSizeToMeshmerize = 0.1f; - - private OpenSim.Framework.BlockingQueue createqueue = new OpenSim.Framework.BlockingQueue(); + private BlockingCollection workQueue = new BlockingCollection(); private bool m_running; private Thread m_thread; @@ -93,9 +87,9 @@ namespace OpenSim.Region.PhysicsModule.ubOde if (pConfig != null) { - forceSimplePrimMeshing = pConfig.GetBoolean("force_simple_prim_meshing", forceSimplePrimMeshing); meshSculptedPrim = pConfig.GetBoolean("mesh_sculpted_prim", meshSculptedPrim); meshSculptLOD = pConfig.GetFloat("mesh_lod", meshSculptLOD); + MinSizeToMeshmerize = pConfig.GetFloat("mesh_min_size", MinSizeToMeshmerize); MeshSculptphysicalLOD = pConfig.GetFloat("mesh_physical_lod", MeshSculptphysicalLOD); } m_running = true; @@ -107,10 +101,11 @@ namespace OpenSim.Region.PhysicsModule.ubOde private void DoWork() { m_mesher.ExpireFileCache(); + ODEPhysRepData nextRep; while(m_running) { - ODEPhysRepData nextRep = createqueue.Dequeue(); + workQueue.TryTake(out nextRep, -1); if(!m_running) return; if (nextRep == null) @@ -139,7 +134,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde try { m_thread.Abort(); - createqueue.Clear(); + // workQueue.Dispose(); } catch { @@ -196,7 +191,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde repData.meshState = MeshState.loadingAsset; repData.comand = meshWorkerCmnds.getmesh; - createqueue.Enqueue(repData); + workQueue.Add(repData); } } @@ -242,7 +237,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde if (needsMeshing(repData)) // no need for pbs now? { repData.comand = meshWorkerCmnds.changefull; - createqueue.Enqueue(repData); + workQueue.Add(repData); } } else @@ -288,6 +283,16 @@ namespace OpenSim.Region.PhysicsModule.ubOde { PrimitiveBaseShape pbs = repData.pbs; // check sculpts or meshs + + Vector3 scale = pbs.Scale; + if(scale.X <= MinSizeToMeshmerize && + scale.Y <= MinSizeToMeshmerize && + scale.Z <= MinSizeToMeshmerize) + { + repData.isTooSmall = true; + return false; + } + if (pbs.SculptEntry) { if (meshSculptedPrim) @@ -299,9 +304,6 @@ namespace OpenSim.Region.PhysicsModule.ubOde return false; } - if (forceSimplePrimMeshing) - return true; - // convex shapes have no holes ushort profilehollow = pbs.ProfileHollow; if(repData.shapetype == 2) @@ -425,17 +427,8 @@ namespace OpenSim.Region.PhysicsModule.ubOde Vector3 size = repData.size; int clod = (int)LevelOfDetail.High; - bool convex; byte shapetype = repData.shapetype; - if (shapetype == 0) - convex = false; - else - { - convex = true; - // sculpts pseudo convex - if (pbs.SculptEntry && pbs.SculptType != (byte)SculptType.Mesh) - clod = (int)LevelOfDetail.Low; - } + bool convex = shapetype == 2; mesh = m_mesher.GetMesh(actor.Name, pbs, size, clod, true, convex); @@ -563,10 +556,16 @@ namespace OpenSim.Region.PhysicsModule.ubOde private void CalculateBasicPrimVolume(ODEPhysRepData repData) { - PrimitiveBaseShape _pbs = repData.pbs; Vector3 _size = repData.size; float volume = _size.X * _size.Y * _size.Z; // default + if(repData.isTooSmall) + { + repData.volume = volume; + return; + } + + PrimitiveBaseShape _pbs = repData.pbs; float tmp; float hollowAmount = (float)_pbs.ProfileHollow * 2.0e-5f; @@ -936,7 +935,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde repData.actor.Name, asset.ID.ToString()); } else - m_log.WarnFormat("[PHYSICS]: asset provider returned null asset fo mesh of prim {0}.", + m_log.WarnFormat("[PHYSICS]: asset provider returned null asset for mesh of prim {0}.", repData.actor.Name); } } diff --git a/OpenSim/Region/PhysicsModules/ubOde/ODEModule.cs b/OpenSim/Region/PhysicsModules/ubOde/ODEModule.cs index 4cb17369b6..90560fde2e 100644 --- a/OpenSim/Region/PhysicsModules/ubOde/ODEModule.cs +++ b/OpenSim/Region/PhysicsModules/ubOde/ODEModule.cs @@ -4,7 +4,6 @@ using System.Reflection; using log4net; using Nini.Config; using Mono.Addins; -using OdeAPI; using OpenSim.Framework; using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Interfaces; @@ -53,9 +52,9 @@ namespace OpenSim.Region.PhysicsModule.ubOde if (Util.IsWindows()) Util.LoadArchSpecificWindowsDll("ode.dll"); - d.InitODE(); + SafeNativeMethods.InitODE(); - string ode_config = d.GetConfiguration(); + string ode_config = SafeNativeMethods.GetConfiguration(); if (ode_config != null && ode_config != "") { m_log.InfoFormat("[ubODE] ode library configuration: {0}", ode_config); diff --git a/OpenSim/Region/PhysicsModules/ubOde/ODEPrim.cs b/OpenSim/Region/PhysicsModules/ubOde/ODEPrim.cs index 45ef273bf2..4e1852295c 100644 --- a/OpenSim/Region/PhysicsModules/ubOde/ODEPrim.cs +++ b/OpenSim/Region/PhysicsModules/ubOde/ODEPrim.cs @@ -44,11 +44,8 @@ using System; using System.Collections.Generic; using System.Reflection; -using System.Runtime.InteropServices; -using System.Threading; using log4net; using OpenMetaverse; -using OdeAPI; using OpenSim.Framework; using OpenSim.Region.PhysicsModules.SharedBase; @@ -85,7 +82,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde private Vector3 m_lastposition; private Vector3 m_rotationalVelocity; private Vector3 _size; - private Vector3 _acceleration; + private Vector3 m_acceleration; private IntPtr Amotor; internal Vector3 m_force; @@ -109,8 +106,8 @@ namespace OpenSim.Region.PhysicsModule.ubOde private float m_waterHeight; private float m_buoyancy; //KF: m_buoyancy should be set by llSetBuoyancy() for non-vehicle. - private int body_autodisable_frames; - public int bodydisablecontrol = 0; + private int m_body_autodisable_frames; + public int m_bodydisablecontrol = 0; private float m_gravmod = 1.0f; // Default we're a Geometry @@ -165,6 +162,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde private float m_density; private byte m_shapetype; + private byte m_fakeShapetype; public bool _zeroFlag; private bool m_lastUpdateSent; @@ -181,19 +179,22 @@ namespace OpenSim.Region.PhysicsModule.ubOde private float m_physCost; private float m_streamCost; - public d.Mass primdMass; // prim inertia information on it's own referencial + internal SafeNativeMethods.Mass primdMass; // prim inertia information on it's own referencial + private PhysicsInertiaData m_InertiaOverride; float primMass; // prim own mass float primVolume; // prim own volume; - float _mass; // object mass acording to case + float m_mass; // object mass acording to case public int givefakepos; private Vector3 fakepos; public int givefakeori; private Quaternion fakeori; + private PhysicsInertiaData m_fakeInertiaOverride; private int m_eventsubscription; private int m_cureventsubscription; - private CollisionEventUpdate CollisionEventsThisFrame = null; + private CollisionEventUpdate CollisionEvents = null; + private CollisionEventUpdate CollisionVDTCEvents = null; private bool SentEmptyCollisionsEvent; public volatile bool childPrim; @@ -417,7 +418,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde { if (value.IsFinite()) { - _parent_scene.m_meshWorker.ChangeActorPhysRep(this, _pbs, value, m_shapetype); + _parent_scene.m_meshWorker.ChangeActorPhysRep(this, _pbs, value, m_fakeShapetype); } else { @@ -465,24 +466,121 @@ namespace OpenSim.Region.PhysicsModule.ubOde } } + public override PhysicsInertiaData GetInertiaData() + { + PhysicsInertiaData inertia; + if(childPrim) + { + if(_parent != null) + return _parent.GetInertiaData(); + else + { + inertia = new PhysicsInertiaData(); + inertia.TotalMass = -1; + return inertia; + } + } + + inertia = new PhysicsInertiaData(); + + // double buffering + if(m_fakeInertiaOverride != null) + { + SafeNativeMethods.Mass objdmass = new SafeNativeMethods.Mass(); + objdmass.I.M00 = m_fakeInertiaOverride.Inertia.X; + objdmass.I.M11 = m_fakeInertiaOverride.Inertia.Y; + objdmass.I.M22 = m_fakeInertiaOverride.Inertia.Z; + + objdmass.mass = m_fakeInertiaOverride.TotalMass; + + if(Math.Abs(m_fakeInertiaOverride.InertiaRotation.W) < 0.999) + { + SafeNativeMethods.Matrix3 inertiarotmat = new SafeNativeMethods.Matrix3(); + SafeNativeMethods.Quaternion inertiarot = new SafeNativeMethods.Quaternion(); + + inertiarot.X = m_fakeInertiaOverride.InertiaRotation.X; + inertiarot.Y = m_fakeInertiaOverride.InertiaRotation.Y; + inertiarot.Z = m_fakeInertiaOverride.InertiaRotation.Z; + inertiarot.W = m_fakeInertiaOverride.InertiaRotation.W; + SafeNativeMethods.RfromQ(out inertiarotmat, ref inertiarot); + SafeNativeMethods.MassRotate(ref objdmass, ref inertiarotmat); + } + + inertia.TotalMass = m_fakeInertiaOverride.TotalMass; + inertia.CenterOfMass = m_fakeInertiaOverride.CenterOfMass; + inertia.Inertia.X = objdmass.I.M00; + inertia.Inertia.Y = objdmass.I.M11; + inertia.Inertia.Z = objdmass.I.M22; + inertia.InertiaRotation.X = objdmass.I.M01; + inertia.InertiaRotation.Y = objdmass.I.M02; + inertia.InertiaRotation.Z = objdmass.I.M12; + return inertia; + } + + inertia.TotalMass = m_mass; + + if(Body == IntPtr.Zero || prim_geom == IntPtr.Zero) + { + inertia.CenterOfMass = Vector3.Zero; + inertia.Inertia = Vector3.Zero; + inertia.InertiaRotation = Vector4.Zero; + return inertia; + } + + SafeNativeMethods.Vector3 dtmp; + SafeNativeMethods.Mass m = new SafeNativeMethods.Mass(); + lock(_parent_scene.OdeLock) + { + SafeNativeMethods.AllocateODEDataForThread(0); + dtmp = SafeNativeMethods.GeomGetOffsetPosition(prim_geom); + SafeNativeMethods.BodyGetMass(Body, out m); + } + + Vector3 cm = new Vector3(-dtmp.X, -dtmp.Y, -dtmp.Z); + inertia.CenterOfMass = cm; + inertia.Inertia = new Vector3(m.I.M00, m.I.M11, m.I.M22); + inertia.InertiaRotation = new Vector4(m.I.M01, m.I.M02 , m.I.M12, 0); + + return inertia; + } + + public override void SetInertiaData(PhysicsInertiaData inertia) + { + if(childPrim) + { + if(_parent != null) + _parent.SetInertiaData(inertia); + return; + } + + if(inertia.TotalMass > 0) + m_fakeInertiaOverride = new PhysicsInertiaData(inertia); + else + m_fakeInertiaOverride = null; + + if (inertia.TotalMass > _parent_scene.maximumMassObject) + inertia.TotalMass = _parent_scene.maximumMassObject; + AddChange(changes.SetInertia,(object)m_fakeInertiaOverride); + } + public override Vector3 CenterOfMass { get { lock (_parent_scene.OdeLock) { - d.AllocateODEDataForThread(0); + SafeNativeMethods.AllocateODEDataForThread(0); - d.Vector3 dtmp; + SafeNativeMethods.Vector3 dtmp; if (!childPrim && Body != IntPtr.Zero) { - dtmp = d.BodyGetPosition(Body); + dtmp = SafeNativeMethods.BodyGetPosition(Body); return new Vector3(dtmp.X, dtmp.Y, dtmp.Z); } else if (prim_geom != IntPtr.Zero) { - d.Quaternion dq; - d.GeomCopyQuaternion(prim_geom, out dq); + SafeNativeMethods.Quaternion dq; + SafeNativeMethods.GeomCopyQuaternion(prim_geom, out dq); Quaternion q; q.X = dq.X; q.Y = dq.Y; @@ -490,7 +588,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde q.W = dq.W; Vector3 Ptot = m_OBBOffset * q; - dtmp = d.GeomGetPosition(prim_geom); + dtmp = SafeNativeMethods.GeomGetPosition(prim_geom); Ptot.X += dtmp.X; Ptot.Y += dtmp.Y; Ptot.Z += dtmp.Z; @@ -530,7 +628,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde set { // AddChange(changes.Shape, value); - _parent_scene.m_meshWorker.ChangeActorPhysRep(this, value, _size, m_shapetype); + _parent_scene.m_meshWorker.ChangeActorPhysRep(this, value, _size, m_fakeShapetype); } } @@ -538,11 +636,11 @@ namespace OpenSim.Region.PhysicsModule.ubOde { get { - return m_shapetype; + return m_fakeShapetype; } set { - m_shapetype = value; + m_fakeShapetype = value; _parent_scene.m_meshWorker.ChangeActorPhysRep(this, _pbs, _size, value); } } @@ -569,7 +667,10 @@ namespace OpenSim.Region.PhysicsModule.ubOde { if (value.IsFinite()) { - AddChange(changes.Velocity, value); + if(m_outbounds) + _velocity = value; + else + AddChange(changes.Velocity, value); } else { @@ -642,8 +743,12 @@ namespace OpenSim.Region.PhysicsModule.ubOde public override Vector3 Acceleration { - get { return _acceleration; } - set { } + get { return m_acceleration; } + set + { + if(m_outbounds) + m_acceleration = value; + } } public override Vector3 RotationalVelocity @@ -663,7 +768,10 @@ namespace OpenSim.Region.PhysicsModule.ubOde { if (value.IsFinite()) { - AddChange(changes.AngVelocity, value); + if(m_outbounds) + m_rotationalVelocity = value; + else + AddChange(changes.AngVelocity, value); } else { @@ -837,7 +945,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde } public void SetAcceleration(Vector3 accel) { - _acceleration = accel; + m_acceleration = accel; } public override void AddForce(Vector3 force, bool pushforce) @@ -873,31 +981,69 @@ namespace OpenSim.Region.PhysicsModule.ubOde public override void CrossingFailure() { - if (m_outbounds) + lock(_parent_scene.OdeLock) { - _position.X = Util.Clip(_position.X, 0.5f, _parent_scene.WorldExtents.X - 0.5f); - _position.Y = Util.Clip(_position.Y, 0.5f, _parent_scene.WorldExtents.Y - 0.5f); - _position.Z = Util.Clip(_position.Z + 0.2f, -100f, 50000f); + if (m_outbounds) + { + _position.X = Util.Clip(_position.X, 0.5f, _parent_scene.WorldExtents.X - 0.5f); + _position.Y = Util.Clip(_position.Y, 0.5f, _parent_scene.WorldExtents.Y - 0.5f); + _position.Z = Util.Clip(_position.Z + 0.2f, -100f, 50000f); + + m_lastposition = _position; + _velocity.X = 0; + _velocity.Y = 0; + _velocity.Z = 0; + + SafeNativeMethods.AllocateODEDataForThread(0); + + m_lastVelocity = _velocity; + if (m_vehicle != null && m_vehicle.Type != Vehicle.TYPE_NONE) + m_vehicle.Stop(); + + if(Body != IntPtr.Zero) + SafeNativeMethods.BodySetLinearVel(Body, 0, 0, 0); // stop it + if (prim_geom != IntPtr.Zero) + SafeNativeMethods.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); + + m_outbounds = false; + changeDisable(false); + base.RequestPhysicsterseUpdate(); + } + } + } + + public override void CrossingStart() + { + lock(_parent_scene.OdeLock) + { + if (m_outbounds || childPrim) + return; + + m_outbounds = true; m_lastposition = _position; - _velocity.X = 0; - _velocity.Y = 0; - _velocity.Z = 0; - - d.AllocateODEDataForThread(0); - - m_lastVelocity = _velocity; - if (m_vehicle != null && m_vehicle.Type != Vehicle.TYPE_NONE) - m_vehicle.Stop(); + m_lastorientation = _orientation; + SafeNativeMethods.AllocateODEDataForThread(0); if(Body != IntPtr.Zero) - d.BodySetLinearVel(Body, 0, 0, 0); // stop it - if (prim_geom != IntPtr.Zero) - d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); + { + SafeNativeMethods.Vector3 dtmp = SafeNativeMethods.BodyGetAngularVel(Body); + m_rotationalVelocity.X = dtmp.X; + m_rotationalVelocity.Y = dtmp.Y; + m_rotationalVelocity.Z = dtmp.Z; - m_outbounds = false; - changeDisable(false); - base.RequestPhysicsterseUpdate(); + dtmp = SafeNativeMethods.BodyGetLinearVel(Body); + _velocity.X = dtmp.X; + _velocity.Y = dtmp.Y; + _velocity.Z = dtmp.Z; + + SafeNativeMethods.BodySetLinearVel(Body, 0, 0, 0); // stop it + SafeNativeMethods.BodySetAngularVel(Body, 0, 0, 0); + } + if(prim_geom != IntPtr.Zero) + SafeNativeMethods.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); + disableBodySoft(); // stop collisions + UnSubscribeEvents(); } } @@ -922,8 +1068,8 @@ namespace OpenSim.Region.PhysicsModule.ubOde { float old = m_density; m_density = value / 100f; - if(m_density != old) - UpdatePrimBodyData(); + // if(m_density != old) + // UpdatePrimBodyData(); } } public override float GravModifier @@ -989,17 +1135,24 @@ namespace OpenSim.Region.PhysicsModule.ubOde { m_eventsubscription = ms; m_cureventsubscription = 0; - if (CollisionEventsThisFrame == null) - CollisionEventsThisFrame = new CollisionEventUpdate(); + if (CollisionEvents == null) + CollisionEvents = new CollisionEventUpdate(); + if (CollisionVDTCEvents == null) + CollisionVDTCEvents = new CollisionEventUpdate(); SentEmptyCollisionsEvent = false; } public override void UnSubscribeEvents() { - if (CollisionEventsThisFrame != null) + if (CollisionVDTCEvents != null) { - CollisionEventsThisFrame.Clear(); - CollisionEventsThisFrame = null; + CollisionVDTCEvents.Clear(); + CollisionVDTCEvents = null; + } + if (CollisionEvents != null) + { + CollisionEvents.Clear(); + CollisionEvents = null; } m_eventsubscription = 0; _parent_scene.RemoveCollisionEventReporting(this); @@ -1007,29 +1160,58 @@ namespace OpenSim.Region.PhysicsModule.ubOde public override void AddCollisionEvent(uint CollidedWith, ContactPoint contact) { - if (CollisionEventsThisFrame == null) - CollisionEventsThisFrame = new CollisionEventUpdate(); + if (CollisionEvents == null) + CollisionEvents = new CollisionEventUpdate(); - CollisionEventsThisFrame.AddCollider(CollidedWith, contact); + CollisionEvents.AddCollider(CollidedWith, contact); + _parent_scene.AddCollisionEventReporting(this); + } + + public override void AddVDTCCollisionEvent(uint CollidedWith, ContactPoint contact) + { + if (CollisionVDTCEvents == null) + CollisionVDTCEvents = new CollisionEventUpdate(); + + CollisionVDTCEvents.AddCollider(CollidedWith, contact); _parent_scene.AddCollisionEventReporting(this); } internal void SleeperAddCollisionEvents() { - if (CollisionEventsThisFrame == null) - return; - if(CollisionEventsThisFrame.m_objCollisionList.Count == 0) - return; - foreach(KeyValuePair kvp in CollisionEventsThisFrame.m_objCollisionList) + if(CollisionEvents != null && CollisionEvents.m_objCollisionList.Count != 0) { - OdePrim other = _parent_scene.getPrim(kvp.Key); - if(other == null) - continue; - ContactPoint cp = kvp.Value; - cp.SurfaceNormal = - cp.SurfaceNormal; - cp.RelativeSpeed = -cp.RelativeSpeed; - other.AddCollisionEvent(ParentActor.LocalID,cp); + foreach(KeyValuePair kvp in CollisionEvents.m_objCollisionList) + { + if(kvp.Key == 0) + continue; + OdePrim other = _parent_scene.getPrim(kvp.Key); + if(other == null) + continue; + ContactPoint cp = kvp.Value; + cp.SurfaceNormal = - cp.SurfaceNormal; + cp.RelativeSpeed = -cp.RelativeSpeed; + other.AddCollisionEvent(ParentActor.LocalID,cp); + } } + if(CollisionVDTCEvents != null && CollisionVDTCEvents.m_objCollisionList.Count != 0) + { + foreach(KeyValuePair kvp in CollisionVDTCEvents.m_objCollisionList) + { + OdePrim other = _parent_scene.getPrim(kvp.Key); + if(other == null) + continue; + ContactPoint cp = kvp.Value; + cp.SurfaceNormal = - cp.SurfaceNormal; + cp.RelativeSpeed = -cp.RelativeSpeed; + other.AddCollisionEvent(ParentActor.LocalID,cp); + } + } + } + + internal void clearSleeperCollisions() + { + if(CollisionVDTCEvents != null && CollisionVDTCEvents.Count >0 ) + CollisionVDTCEvents.Clear(); } public void SendCollisions(int timestep) @@ -1037,17 +1219,18 @@ namespace OpenSim.Region.PhysicsModule.ubOde if (m_cureventsubscription < 50000) m_cureventsubscription += timestep; - if (CollisionEventsThisFrame == null) - return; - - int ncolisions = CollisionEventsThisFrame.m_objCollisionList.Count; if (m_cureventsubscription < m_eventsubscription) return; + if (CollisionEvents == null) + return; + + int ncolisions = CollisionEvents.m_objCollisionList.Count; + if (!SentEmptyCollisionsEvent || ncolisions > 0) { - base.SendCollisionUpdate(CollisionEventsThisFrame); + base.SendCollisionUpdate(CollisionEvents); m_cureventsubscription = 0; if (ncolisions == 0) @@ -1055,10 +1238,10 @@ namespace OpenSim.Region.PhysicsModule.ubOde SentEmptyCollisionsEvent = true; // _parent_scene.RemoveCollisionEventReporting(this); } - else if(Body == IntPtr.Zero || d.BodyIsEnabled(Body)) + else if(Body == IntPtr.Zero || (SafeNativeMethods.BodyIsEnabled(Body) && m_bodydisablecontrol >= 0 )) { SentEmptyCollisionsEvent = false; - CollisionEventsThisFrame.Clear(); + CollisionEvents.Clear(); } } } @@ -1093,7 +1276,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde m_invTimeStep = 1f / m_timeStep; m_density = parent_scene.geomDefaultDensity; - body_autodisable_frames = parent_scene.bodyFramesAutoDisable; + m_body_autodisable_frames = parent_scene.bodyFramesAutoDisable; prim_geom = IntPtr.Zero; collide_geom = IntPtr.Zero; @@ -1145,7 +1328,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde _triMeshData = IntPtr.Zero; - m_shapetype = _shapeType; + m_fakeShapetype = _shapeType; m_lastdoneSelected = false; m_isSelected = false; @@ -1162,7 +1345,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde AddChange(changes.Add, null); // get basic mass parameters - ODEPhysRepData repData = _parent_scene.m_meshWorker.NewActorPhysRep(this, _pbs, _size, m_shapetype); + ODEPhysRepData repData = _parent_scene.m_meshWorker.NewActorPhysRep(this, _pbs, _size, _shapeType); primVolume = repData.volume; m_OBB = repData.OBB; @@ -1264,16 +1447,16 @@ namespace OpenSim.Region.PhysicsModule.ubOde { if (prm.m_NoColide) { - d.GeomSetCategoryBits(prm.prim_geom, 0); + SafeNativeMethods.GeomSetCategoryBits(prm.prim_geom, 0); if (m_isphysical) - d.GeomSetCollideBits(prm.prim_geom, (int)CollisionCategories.Land); + SafeNativeMethods.GeomSetCollideBits(prm.prim_geom, (int)CollisionCategories.Land); else - d.GeomSetCollideBits(prm.prim_geom, 0); + SafeNativeMethods.GeomSetCollideBits(prm.prim_geom, 0); } else { - d.GeomSetCategoryBits(prm.prim_geom, (uint)prm.m_collisionCategories); - d.GeomSetCollideBits(prm.prim_geom, (uint)prm.m_collisionFlags); + SafeNativeMethods.GeomSetCategoryBits(prm.prim_geom, (uint)prm.m_collisionCategories); + SafeNativeMethods.GeomSetCollideBits(prm.prim_geom, (uint)prm.m_collisionFlags); } } } @@ -1281,22 +1464,22 @@ namespace OpenSim.Region.PhysicsModule.ubOde if (m_NoColide) { - d.GeomSetCategoryBits(prim_geom, 0); - d.GeomSetCollideBits(prim_geom, (uint)CollisionCategories.Land); + SafeNativeMethods.GeomSetCategoryBits(prim_geom, 0); + SafeNativeMethods.GeomSetCollideBits(prim_geom, (uint)CollisionCategories.Land); if (collide_geom != prim_geom && collide_geom != IntPtr.Zero) { - d.GeomSetCategoryBits(collide_geom, 0); - d.GeomSetCollideBits(collide_geom, (uint)CollisionCategories.Land); + SafeNativeMethods.GeomSetCategoryBits(collide_geom, 0); + SafeNativeMethods.GeomSetCollideBits(collide_geom, (uint)CollisionCategories.Land); } } else { - d.GeomSetCategoryBits(prim_geom, (uint)m_collisionCategories); - d.GeomSetCollideBits(prim_geom, (uint)m_collisionFlags); + SafeNativeMethods.GeomSetCategoryBits(prim_geom, (uint)m_collisionCategories); + SafeNativeMethods.GeomSetCollideBits(prim_geom, (uint)m_collisionFlags); if (collide_geom != prim_geom && collide_geom != IntPtr.Zero) { - d.GeomSetCategoryBits(collide_geom, (uint)m_collisionCategories); - d.GeomSetCollideBits(collide_geom, (uint)m_collisionFlags); + SafeNativeMethods.GeomSetCategoryBits(collide_geom, (uint)m_collisionCategories); + SafeNativeMethods.GeomSetCollideBits(collide_geom, (uint)m_collisionFlags); } } } @@ -1309,7 +1492,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde if (Amotor != IntPtr.Zero) { - d.JointDestroy(Amotor); + SafeNativeMethods.JointDestroy(Amotor); Amotor = IntPtr.Zero; } @@ -1336,19 +1519,19 @@ namespace OpenSim.Region.PhysicsModule.ubOde if(axisnum == 0) return; // stop it - d.BodySetTorque(Body, 0, 0, 0); - d.BodySetAngularVel(Body, 0, 0, 0); + SafeNativeMethods.BodySetTorque(Body, 0, 0, 0); + SafeNativeMethods.BodySetAngularVel(Body, 0, 0, 0); - Amotor = d.JointCreateAMotor(_parent_scene.world, IntPtr.Zero); - d.JointAttach(Amotor, Body, IntPtr.Zero); + Amotor = SafeNativeMethods.JointCreateAMotor(_parent_scene.world, IntPtr.Zero); + SafeNativeMethods.JointAttach(Amotor, Body, IntPtr.Zero); - d.JointSetAMotorMode(Amotor, 0); + SafeNativeMethods.JointSetAMotorMode(Amotor, 0); - d.JointSetAMotorNumAxes(Amotor, axisnum); + SafeNativeMethods.JointSetAMotorNumAxes(Amotor, axisnum); // get current orientation to lock - d.Quaternion dcur = d.BodyGetQuaternion(Body); + SafeNativeMethods.Quaternion dcur = SafeNativeMethods.BodyGetQuaternion(Body); Quaternion curr; // crap convertion between identical things curr.X = dcur.X; curr.Y = dcur.Y; @@ -1361,17 +1544,17 @@ namespace OpenSim.Region.PhysicsModule.ubOde if (axisX) { ax = (new Vector3(1, 0, 0)) * curr; // rotate world X to current local X - d.JointSetAMotorAxis(Amotor, 0, 0, ax.X, ax.Y, ax.Z); - d.JointSetAMotorAngle(Amotor, 0, 0); - d.JointSetAMotorParam(Amotor, (int)d.JointParam.LoStop, 0f); - d.JointSetAMotorParam(Amotor, (int)d.JointParam.HiStop, 0f); - d.JointSetAMotorParam(Amotor, (int)d.JointParam.Vel, 0); - d.JointSetAMotorParam(Amotor, (int)d.JointParam.FudgeFactor, 0.0001f); - d.JointSetAMotorParam(Amotor, (int)d.JointParam.Bounce, 0f); - d.JointSetAMotorParam(Amotor, (int)d.JointParam.CFM, 0f); - d.JointSetAMotorParam(Amotor, (int)d.JointParam.FMax, 5e8f); - d.JointSetAMotorParam(Amotor, (int)d.JointParam.StopCFM, 0f); - d.JointSetAMotorParam(Amotor, (int)d.JointParam.StopERP, 0.8f); + SafeNativeMethods.JointSetAMotorAxis(Amotor, 0, 0, ax.X, ax.Y, ax.Z); + SafeNativeMethods.JointSetAMotorAngle(Amotor, 0, 0); + SafeNativeMethods.JointSetAMotorParam(Amotor, (int)SafeNativeMethods.JointParam.LoStop, 0f); + SafeNativeMethods.JointSetAMotorParam(Amotor, (int)SafeNativeMethods.JointParam.HiStop, 0f); + SafeNativeMethods.JointSetAMotorParam(Amotor, (int)SafeNativeMethods.JointParam.Vel, 0); + SafeNativeMethods.JointSetAMotorParam(Amotor, (int)SafeNativeMethods.JointParam.FudgeFactor, 0.0001f); + SafeNativeMethods.JointSetAMotorParam(Amotor, (int)SafeNativeMethods.JointParam.Bounce, 0f); + SafeNativeMethods.JointSetAMotorParam(Amotor, (int)SafeNativeMethods.JointParam.CFM, 0f); + SafeNativeMethods.JointSetAMotorParam(Amotor, (int)SafeNativeMethods.JointParam.FMax, 5e8f); + SafeNativeMethods.JointSetAMotorParam(Amotor, (int)SafeNativeMethods.JointParam.StopCFM, 0f); + SafeNativeMethods.JointSetAMotorParam(Amotor, (int)SafeNativeMethods.JointParam.StopERP, 0.8f); i++; j = 256; // move to next axis set } @@ -1379,17 +1562,17 @@ namespace OpenSim.Region.PhysicsModule.ubOde if (axisY) { ax = (new Vector3(0, 1, 0)) * curr; - d.JointSetAMotorAxis(Amotor, i, 0, ax.X, ax.Y, ax.Z); - d.JointSetAMotorAngle(Amotor, i, 0); - d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.LoStop, 0f); - d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.HiStop, 0f); - d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.Vel, 0); - d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.FudgeFactor, 0.0001f); - d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.Bounce, 0f); - d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.CFM, 0f); - d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.FMax, 5e8f); - d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.StopCFM, 0f); - d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.StopERP, 0.8f); + SafeNativeMethods.JointSetAMotorAxis(Amotor, i, 0, ax.X, ax.Y, ax.Z); + SafeNativeMethods.JointSetAMotorAngle(Amotor, i, 0); + SafeNativeMethods.JointSetAMotorParam(Amotor, j + (int)SafeNativeMethods.JointParam.LoStop, 0f); + SafeNativeMethods.JointSetAMotorParam(Amotor, j + (int)SafeNativeMethods.JointParam.HiStop, 0f); + SafeNativeMethods.JointSetAMotorParam(Amotor, j + (int)SafeNativeMethods.JointParam.Vel, 0); + SafeNativeMethods.JointSetAMotorParam(Amotor, j + (int)SafeNativeMethods.JointParam.FudgeFactor, 0.0001f); + SafeNativeMethods.JointSetAMotorParam(Amotor, j + (int)SafeNativeMethods.JointParam.Bounce, 0f); + SafeNativeMethods.JointSetAMotorParam(Amotor, j + (int)SafeNativeMethods.JointParam.CFM, 0f); + SafeNativeMethods.JointSetAMotorParam(Amotor, j + (int)SafeNativeMethods.JointParam.FMax, 5e8f); + SafeNativeMethods.JointSetAMotorParam(Amotor, j + (int)SafeNativeMethods.JointParam.StopCFM, 0f); + SafeNativeMethods.JointSetAMotorParam(Amotor, j + (int)SafeNativeMethods.JointParam.StopERP, 0.8f); i++; j += 256; } @@ -1397,17 +1580,17 @@ namespace OpenSim.Region.PhysicsModule.ubOde if (axisZ) { ax = (new Vector3(0, 0, 1)) * curr; - d.JointSetAMotorAxis(Amotor, i, 0, ax.X, ax.Y, ax.Z); - d.JointSetAMotorAngle(Amotor, i, 0); - d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.LoStop, 0f); - d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.HiStop, 0f); - d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.Vel, 0); - d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.FudgeFactor, 0.0001f); - d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.Bounce, 0f); - d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.CFM, 0f); - d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.FMax, 5e8f); - d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.StopCFM, 0f); - d.JointSetAMotorParam(Amotor, j + (int)d.JointParam.StopERP, 0.8f); + SafeNativeMethods.JointSetAMotorAxis(Amotor, i, 0, ax.X, ax.Y, ax.Z); + SafeNativeMethods.JointSetAMotorAngle(Amotor, i, 0); + SafeNativeMethods.JointSetAMotorParam(Amotor, j + (int)SafeNativeMethods.JointParam.LoStop, 0f); + SafeNativeMethods.JointSetAMotorParam(Amotor, j + (int)SafeNativeMethods.JointParam.HiStop, 0f); + SafeNativeMethods.JointSetAMotorParam(Amotor, j + (int)SafeNativeMethods.JointParam.Vel, 0); + SafeNativeMethods.JointSetAMotorParam(Amotor, j + (int)SafeNativeMethods.JointParam.FudgeFactor, 0.0001f); + SafeNativeMethods.JointSetAMotorParam(Amotor, j + (int)SafeNativeMethods.JointParam.Bounce, 0f); + SafeNativeMethods.JointSetAMotorParam(Amotor, j + (int)SafeNativeMethods.JointParam.CFM, 0f); + SafeNativeMethods.JointSetAMotorParam(Amotor, j + (int)SafeNativeMethods.JointParam.FMax, 5e8f); + SafeNativeMethods.JointSetAMotorParam(Amotor, j + (int)SafeNativeMethods.JointParam.StopCFM, 0f); + SafeNativeMethods.JointSetAMotorParam(Amotor, j + (int)SafeNativeMethods.JointParam.StopERP, 0.8f); } } @@ -1421,21 +1604,21 @@ namespace OpenSim.Region.PhysicsModule.ubOde if (m_NoColide) { - d.GeomSetCategoryBits(prim_geom, 0); + SafeNativeMethods.GeomSetCategoryBits(prim_geom, 0); if (m_isphysical) { - d.GeomSetCollideBits(prim_geom, (uint)CollisionCategories.Land); + SafeNativeMethods.GeomSetCollideBits(prim_geom, (uint)CollisionCategories.Land); } else { - d.GeomSetCollideBits(prim_geom, 0); - d.GeomDisable(prim_geom); + SafeNativeMethods.GeomSetCollideBits(prim_geom, 0); + SafeNativeMethods.GeomDisable(prim_geom); } } else { - d.GeomSetCategoryBits(prim_geom, (uint)m_collisionCategories); - d.GeomSetCollideBits(prim_geom, (uint)m_collisionFlags); + SafeNativeMethods.GeomSetCategoryBits(prim_geom, (uint)m_collisionCategories); + SafeNativeMethods.GeomSetCollideBits(prim_geom, (uint)m_collisionFlags); } UpdatePrimBodyData(); @@ -1503,12 +1686,12 @@ namespace OpenSim.Region.PhysicsModule.ubOde try { - _triMeshData = d.GeomTriMeshDataCreate(); + _triMeshData = SafeNativeMethods.GeomTriMeshDataCreate(); - d.GeomTriMeshDataBuildSimple(_triMeshData, vertices, vertexStride, vertexCount, indices, indexCount, triStride); - d.GeomTriMeshDataPreprocess(_triMeshData); + SafeNativeMethods.GeomTriMeshDataBuildSimple(_triMeshData, vertices, vertexStride, vertexCount, indices, indexCount, triStride); + SafeNativeMethods.GeomTriMeshDataPreprocess(_triMeshData); - geo = d.CreateTriMesh(m_targetSpace, _triMeshData, null, null, null); + geo = SafeNativeMethods.CreateTriMesh(m_targetSpace, _triMeshData, null, null, null); } catch (Exception e) @@ -1518,7 +1701,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde { try { - d.GeomTriMeshDataDestroy(_triMeshData); + SafeNativeMethods.GeomTriMeshDataDestroy(_triMeshData); } catch { @@ -1547,7 +1730,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde return true; } - private void CreateGeom() + private void CreateGeom(bool OverrideToBox) { bool hasMesh = false; @@ -1556,7 +1739,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde if ((m_meshState & MeshState.MeshNoColide) != 0) m_NoColide = true; - else if(m_mesh != null) + else if(!OverrideToBox && m_mesh != null) { if (GetMeshGeom()) hasMesh = true; @@ -1574,7 +1757,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde { // it's a sphere try { - geo = d.CreateSphere(m_targetSpace, _size.X * 0.5f); + geo = SafeNativeMethods.CreateSphere(m_targetSpace, _size.X * 0.5f); } catch (Exception e) { @@ -1586,7 +1769,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde {// do it as a box try { - geo = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z); + geo = SafeNativeMethods.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z); } catch (Exception e) { @@ -1608,10 +1791,10 @@ namespace OpenSim.Region.PhysicsModule.ubOde try { - d.GeomDestroy(prim_geom); + SafeNativeMethods.GeomDestroy(prim_geom); if (_triMeshData != IntPtr.Zero) { - d.GeomTriMeshDataDestroy(_triMeshData); + SafeNativeMethods.GeomTriMeshDataDestroy(_triMeshData); _triMeshData = IntPtr.Zero; } } @@ -1646,7 +1829,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde // should only be called for non physical prims unless they are becoming non physical private void SetInStaticSpace(OdePrim prim) { - IntPtr targetSpace = _parent_scene.MoveGeomToStaticSpace(prim.prim_geom, prim._position, prim.m_targetSpace); + IntPtr targetSpace = _parent_scene.MoveGeomToStaticSpace(prim.prim_geom, prim.m_targetSpace); prim.m_targetSpace = targetSpace; collide_geom = IntPtr.Zero; } @@ -1662,8 +1845,8 @@ namespace OpenSim.Region.PhysicsModule.ubOde ApplyCollisionCatFlags(); _zeroFlag = true; - d.BodyEnable(Body); - + SafeNativeMethods.BodySetAutoDisableSteps(Body, m_body_autodisable_frames); + SafeNativeMethods.BodyEnable(Body); } } resetCollisionAccounting(); @@ -1682,7 +1865,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde m_collisionCategories = 0; m_collisionFlags = 0; ApplyCollisionCatFlags(); - d.BodyDisable(Body); + SafeNativeMethods.BodyDisable(Body); } } } @@ -1710,38 +1893,41 @@ namespace OpenSim.Region.PhysicsModule.ubOde m_log.Warn("[PHYSICS]: MakeBody called having a body"); } - if (d.GeomGetBody(prim_geom) != IntPtr.Zero) + if (SafeNativeMethods.GeomGetBody(prim_geom) != IntPtr.Zero) { - d.GeomSetBody(prim_geom, IntPtr.Zero); + SafeNativeMethods.GeomSetBody(prim_geom, IntPtr.Zero); m_log.Warn("[PHYSICS]: MakeBody root geom already had a body"); } - d.Matrix3 mymat = new d.Matrix3(); - d.Quaternion myrot = new d.Quaternion(); - d.Mass objdmass = new d.Mass { }; + bool noInertiaOverride = (m_InertiaOverride == null); - Body = d.BodyCreate(_parent_scene.world); + Body = SafeNativeMethods.BodyCreate(_parent_scene.world); - objdmass = primdMass; + SafeNativeMethods.Matrix3 mymat = new SafeNativeMethods.Matrix3(); + SafeNativeMethods.Quaternion myrot = new SafeNativeMethods.Quaternion(); + SafeNativeMethods.Mass objdmass = new SafeNativeMethods.Mass { }; - // rotate inertia myrot.X = _orientation.X; myrot.Y = _orientation.Y; myrot.Z = _orientation.Z; myrot.W = _orientation.W; - - d.RfromQ(out mymat, ref myrot); - d.MassRotate(ref objdmass, ref mymat); + SafeNativeMethods.RfromQ(out mymat, ref myrot); // set the body rotation - d.BodySetRotation(Body, ref mymat); + SafeNativeMethods.BodySetRotation(Body, ref mymat); + if(noInertiaOverride) + { + objdmass = primdMass; + SafeNativeMethods.MassRotate(ref objdmass, ref mymat); + } + // recompute full object inertia if needed if (childrenPrim.Count > 0) { - d.Matrix3 mat = new d.Matrix3(); - d.Quaternion quat = new d.Quaternion(); - d.Mass tmpdmass = new d.Mass { }; + SafeNativeMethods.Matrix3 mat = new SafeNativeMethods.Matrix3(); + SafeNativeMethods.Quaternion quat = new SafeNativeMethods.Quaternion(); + SafeNativeMethods.Mass tmpdmass = new SafeNativeMethods.Mass { }; Vector3 rcm; rcm.X = _position.X; @@ -1758,75 +1944,119 @@ namespace OpenSim.Region.PhysicsModule.ubOde continue; } - tmpdmass = prm.primdMass; - - // apply prim current rotation to inertia quat.X = prm._orientation.X; quat.Y = prm._orientation.Y; quat.Z = prm._orientation.Z; quat.W = prm._orientation.W; - d.RfromQ(out mat, ref quat); - d.MassRotate(ref tmpdmass, ref mat); + SafeNativeMethods.RfromQ(out mat, ref quat); - Vector3 ppos = prm._position; - ppos.X -= rcm.X; - ppos.Y -= rcm.Y; - ppos.Z -= rcm.Z; - // refer inertia to root prim center of mass position - d.MassTranslate(ref tmpdmass, - ppos.X, - ppos.Y, - ppos.Z); - - d.MassAdd(ref objdmass, ref tmpdmass); // add to total object inertia // fix prim colision cats - if (d.GeomGetBody(prm.prim_geom) != IntPtr.Zero) + if (SafeNativeMethods.GeomGetBody(prm.prim_geom) != IntPtr.Zero) { - d.GeomSetBody(prm.prim_geom, IntPtr.Zero); + SafeNativeMethods.GeomSetBody(prm.prim_geom, IntPtr.Zero); m_log.Warn("[PHYSICS]: MakeBody child geom already had a body"); } - d.GeomClearOffset(prm.prim_geom); - d.GeomSetBody(prm.prim_geom, Body); + SafeNativeMethods.GeomClearOffset(prm.prim_geom); + SafeNativeMethods.GeomSetBody(prm.prim_geom, Body); prm.Body = Body; - d.GeomSetOffsetWorldRotation(prm.prim_geom, ref mat); // set relative rotation + SafeNativeMethods.GeomSetOffsetWorldRotation(prm.prim_geom, ref mat); // set relative rotation + + if(noInertiaOverride) + { + tmpdmass = prm.primdMass; + + SafeNativeMethods.MassRotate(ref tmpdmass, ref mat); + Vector3 ppos = prm._position; + ppos.X -= rcm.X; + ppos.Y -= rcm.Y; + ppos.Z -= rcm.Z; + // refer inertia to root prim center of mass position + SafeNativeMethods.MassTranslate(ref tmpdmass, + ppos.X, + ppos.Y, + ppos.Z); + + SafeNativeMethods.MassAdd(ref objdmass, ref tmpdmass); // add to total object inertia + } } } } - d.GeomClearOffset(prim_geom); // make sure we don't have a hidden offset + SafeNativeMethods.GeomClearOffset(prim_geom); // make sure we don't have a hidden offset // associate root geom with body - d.GeomSetBody(prim_geom, Body); + SafeNativeMethods.GeomSetBody(prim_geom, Body); - d.BodySetPosition(Body, _position.X + objdmass.c.X, _position.Y + objdmass.c.Y, _position.Z + objdmass.c.Z); - d.GeomSetOffsetWorldPosition(prim_geom, _position.X, _position.Y, _position.Z); + if(noInertiaOverride) + SafeNativeMethods.BodySetPosition(Body, _position.X + objdmass.c.X, _position.Y + objdmass.c.Y, _position.Z + objdmass.c.Z); + else + { + Vector3 ncm = m_InertiaOverride.CenterOfMass * _orientation; + SafeNativeMethods.BodySetPosition(Body, + _position.X + ncm.X, + _position.Y + ncm.Y, + _position.Z + ncm.Z); + } - d.MassTranslate(ref objdmass, -objdmass.c.X, -objdmass.c.Y, -objdmass.c.Z); // ode wants inertia at center of body - myrot.X = -myrot.X; - myrot.Y = -myrot.Y; - myrot.Z = -myrot.Z; + SafeNativeMethods.GeomSetOffsetWorldPosition(prim_geom, _position.X, _position.Y, _position.Z); - d.RfromQ(out mymat, ref myrot); - d.MassRotate(ref objdmass, ref mymat); + if(noInertiaOverride) + { + SafeNativeMethods.MassTranslate(ref objdmass, -objdmass.c.X, -objdmass.c.Y, -objdmass.c.Z); // ode wants inertia at center of body + myrot.X = -myrot.X; + myrot.Y = -myrot.Y; + myrot.Z = -myrot.Z; - d.BodySetMass(Body, ref objdmass); - _mass = objdmass.mass; + SafeNativeMethods.RfromQ(out mymat, ref myrot); + SafeNativeMethods.MassRotate(ref objdmass, ref mymat); + + SafeNativeMethods.BodySetMass(Body, ref objdmass); + m_mass = objdmass.mass; + } + else + { + objdmass.c.X = 0; + objdmass.c.Y = 0; + objdmass.c.Z = 0; + + objdmass.I.M00 = m_InertiaOverride.Inertia.X; + objdmass.I.M11 = m_InertiaOverride.Inertia.Y; + objdmass.I.M22 = m_InertiaOverride.Inertia.Z; + + objdmass.mass = m_InertiaOverride.TotalMass; + + if(Math.Abs(m_InertiaOverride.InertiaRotation.W) < 0.999) + { + SafeNativeMethods.Matrix3 inertiarotmat = new SafeNativeMethods.Matrix3(); + SafeNativeMethods.Quaternion inertiarot = new SafeNativeMethods.Quaternion(); + + inertiarot.X = m_InertiaOverride.InertiaRotation.X; + inertiarot.Y = m_InertiaOverride.InertiaRotation.Y; + inertiarot.Z = m_InertiaOverride.InertiaRotation.Z; + inertiarot.W = m_InertiaOverride.InertiaRotation.W; + SafeNativeMethods.RfromQ(out inertiarotmat, ref inertiarot); + SafeNativeMethods.MassRotate(ref objdmass, ref inertiarotmat); + } + SafeNativeMethods.BodySetMass(Body, ref objdmass); + + m_mass = objdmass.mass; + } // disconnect from world gravity so we can apply buoyancy - d.BodySetGravityMode(Body, false); + SafeNativeMethods.BodySetGravityMode(Body, false); - d.BodySetAutoDisableFlag(Body, true); - d.BodySetAutoDisableSteps(Body, body_autodisable_frames); - d.BodySetAutoDisableAngularThreshold(Body, 0.05f); - d.BodySetAutoDisableLinearThreshold(Body, 0.05f); - d.BodySetDamping(Body, .004f, .001f); + SafeNativeMethods.BodySetAutoDisableFlag(Body, true); + SafeNativeMethods.BodySetAutoDisableSteps(Body, m_body_autodisable_frames); + SafeNativeMethods.BodySetAutoDisableAngularThreshold(Body, 0.05f); + SafeNativeMethods.BodySetAutoDisableLinearThreshold(Body, 0.05f); + SafeNativeMethods.BodySetDamping(Body, .004f, .001f); if (m_targetSpace != IntPtr.Zero) { _parent_scene.waitForSpaceUnlock(m_targetSpace); - if (d.SpaceQuery(m_targetSpace, prim_geom)) - d.SpaceRemove(m_targetSpace, prim_geom); + if (SafeNativeMethods.SpaceQuery(m_targetSpace, prim_geom)) + SafeNativeMethods.SpaceRemove(m_targetSpace, prim_geom); } if (childrenPrim.Count == 0) @@ -1836,21 +2066,23 @@ namespace OpenSim.Region.PhysicsModule.ubOde } else { - m_targetSpace = d.HashSpaceCreate(_parent_scene.ActiveSpace); - d.HashSpaceSetLevels(m_targetSpace, -2, 8); - d.SpaceSetSublevel(m_targetSpace, 3); - d.SpaceSetCleanup(m_targetSpace, false); + m_targetSpace = SafeNativeMethods.SimpleSpaceCreate(_parent_scene.ActiveSpace); + SafeNativeMethods.SpaceSetSublevel(m_targetSpace, 3); + SafeNativeMethods.SpaceSetCleanup(m_targetSpace, false); - d.GeomSetCategoryBits(m_targetSpace, (uint)(CollisionCategories.Space | + SafeNativeMethods.GeomSetCategoryBits(m_targetSpace, (uint)(CollisionCategories.Space | CollisionCategories.Geom | CollisionCategories.Phantom | CollisionCategories.VolumeDtc )); - d.GeomSetCollideBits(m_targetSpace, 0); + SafeNativeMethods.GeomSetCollideBits(m_targetSpace, 0); collide_geom = m_targetSpace; } - d.SpaceAdd(m_targetSpace, prim_geom); + if (SafeNativeMethods.SpaceQuery(m_targetSpace, prim_geom)) + m_log.Debug("[PRIM]: parent already in target space"); + else + SafeNativeMethods.SpaceAdd(m_targetSpace, prim_geom); if (m_delaySelect) { @@ -1869,22 +2101,27 @@ namespace OpenSim.Region.PhysicsModule.ubOde { foreach (OdePrim prm in childrenPrim) { - if (prm.prim_geom == IntPtr.Zero) + IntPtr prmgeom = prm.prim_geom; + if (prmgeom == IntPtr.Zero) continue; Vector3 ppos = prm._position; - d.GeomSetOffsetWorldPosition(prm.prim_geom, ppos.X, ppos.Y, ppos.Z); // set relative position + SafeNativeMethods.GeomSetOffsetWorldPosition(prm.prim_geom, ppos.X, ppos.Y, ppos.Z); // set relative position - if (prm.m_targetSpace != m_targetSpace) + IntPtr prmspace = prm.m_targetSpace; + if (prmspace != m_targetSpace) { - if (prm.m_targetSpace != IntPtr.Zero) + if (prmspace != IntPtr.Zero) { - _parent_scene.waitForSpaceUnlock(prm.m_targetSpace); - if (d.SpaceQuery(prm.m_targetSpace, prm.prim_geom)) - d.SpaceRemove(prm.m_targetSpace, prm.prim_geom); + _parent_scene.waitForSpaceUnlock(prmspace); + if (SafeNativeMethods.SpaceQuery(prmspace, prmgeom)) + SafeNativeMethods.SpaceRemove(prmspace, prmgeom); } prm.m_targetSpace = m_targetSpace; - d.SpaceAdd(m_targetSpace, prm.prim_geom); + if (SafeNativeMethods.SpaceQuery(m_targetSpace, prmgeom)) + m_log.Debug("[PRIM]: child already in target space"); + else + SafeNativeMethods.SpaceAdd(m_targetSpace, prmgeom); } prm.m_collisionscore = 0; @@ -1904,15 +2141,16 @@ namespace OpenSim.Region.PhysicsModule.ubOde if (m_isSelected || m_disabled) { - d.BodyDisable(Body); + SafeNativeMethods.BodyDisable(Body); _zeroFlag = true; } else { - d.BodySetAngularVel(Body, m_rotationalVelocity.X, m_rotationalVelocity.Y, m_rotationalVelocity.Z); - d.BodySetLinearVel(Body, _velocity.X, _velocity.Y, _velocity.Z); + SafeNativeMethods.BodySetAngularVel(Body, m_rotationalVelocity.X, m_rotationalVelocity.Y, m_rotationalVelocity.Z); + SafeNativeMethods.BodySetLinearVel(Body, _velocity.X, _velocity.Y, _velocity.Z); + _zeroFlag = false; - bodydisablecontrol = 0; + m_bodydisablecontrol = 0; } _parent_scene.addActiveGroups(this); } @@ -1942,16 +2180,16 @@ namespace OpenSim.Region.PhysicsModule.ubOde { if (m_NoColide) { - d.GeomSetCategoryBits(prim_geom, 0); - d.GeomSetCollideBits(prim_geom, 0); + SafeNativeMethods.GeomSetCategoryBits(prim_geom, 0); + SafeNativeMethods.GeomSetCollideBits(prim_geom, 0); } else { - d.GeomSetCategoryBits(prim_geom, (uint)m_collisionCategories); - d.GeomSetCollideBits(prim_geom, (uint)m_collisionFlags); + SafeNativeMethods.GeomSetCategoryBits(prim_geom, (uint)m_collisionCategories); + SafeNativeMethods.GeomSetCollideBits(prim_geom, (uint)m_collisionFlags); } UpdateDataFromGeom(); - d.GeomSetBody(prim_geom, IntPtr.Zero); + SafeNativeMethods.GeomSetBody(prim_geom, IntPtr.Zero); SetInStaticSpace(this); } @@ -1978,62 +2216,62 @@ namespace OpenSim.Region.PhysicsModule.ubOde { if (prm.m_NoColide) { - d.GeomSetCategoryBits(prm.prim_geom, 0); - d.GeomSetCollideBits(prm.prim_geom, 0); + SafeNativeMethods.GeomSetCategoryBits(prm.prim_geom, 0); + SafeNativeMethods.GeomSetCollideBits(prm.prim_geom, 0); } else { - d.GeomSetCategoryBits(prm.prim_geom, (uint)prm.m_collisionCategories); - d.GeomSetCollideBits(prm.prim_geom, (uint)prm.m_collisionFlags); + SafeNativeMethods.GeomSetCategoryBits(prm.prim_geom, (uint)prm.m_collisionCategories); + SafeNativeMethods.GeomSetCollideBits(prm.prim_geom, (uint)prm.m_collisionFlags); } prm.UpdateDataFromGeom(); SetInStaticSpace(prm); } prm.Body = IntPtr.Zero; - prm._mass = prm.primMass; + prm.m_mass = prm.primMass; prm.m_collisionscore = 0; } } if (Amotor != IntPtr.Zero) { - d.JointDestroy(Amotor); + SafeNativeMethods.JointDestroy(Amotor); Amotor = IntPtr.Zero; } _parent_scene.remActiveGroup(this); - d.BodyDestroy(Body); + SafeNativeMethods.BodyDestroy(Body); } Body = IntPtr.Zero; } - _mass = primMass; + m_mass = primMass; m_collisionscore = 0; } private void FixInertia(Vector3 NewPos,Quaternion newrot) { - d.Matrix3 mat = new d.Matrix3(); - d.Quaternion quat = new d.Quaternion(); + SafeNativeMethods.Matrix3 mat = new SafeNativeMethods.Matrix3(); + SafeNativeMethods.Quaternion quat = new SafeNativeMethods.Quaternion(); - d.Mass tmpdmass = new d.Mass { }; - d.Mass objdmass = new d.Mass { }; + SafeNativeMethods.Mass tmpdmass = new SafeNativeMethods.Mass { }; + SafeNativeMethods.Mass objdmass = new SafeNativeMethods.Mass { }; - d.BodyGetMass(Body, out tmpdmass); + SafeNativeMethods.BodyGetMass(Body, out tmpdmass); objdmass = tmpdmass; - d.Vector3 dobjpos; - d.Vector3 thispos; + SafeNativeMethods.Vector3 dobjpos; + SafeNativeMethods.Vector3 thispos; // get current object position and rotation - dobjpos = d.BodyGetPosition(Body); + dobjpos = SafeNativeMethods.BodyGetPosition(Body); // get prim own inertia in its local frame tmpdmass = primdMass; // transform to object frame - mat = d.GeomGetOffsetRotation(prim_geom); - d.MassRotate(ref tmpdmass, ref mat); + mat = SafeNativeMethods.GeomGetOffsetRotation(prim_geom); + SafeNativeMethods.MassRotate(ref tmpdmass, ref mat); - thispos = d.GeomGetOffsetPosition(prim_geom); - d.MassTranslate(ref tmpdmass, + thispos = SafeNativeMethods.GeomGetOffsetPosition(prim_geom); + SafeNativeMethods.MassTranslate(ref tmpdmass, thispos.X, thispos.Y, thispos.Z); @@ -2046,66 +2284,66 @@ namespace OpenSim.Region.PhysicsModule.ubOde // update to new position and orientation _position = NewPos; - d.GeomSetOffsetWorldPosition(prim_geom, NewPos.X, NewPos.Y, NewPos.Z); + SafeNativeMethods.GeomSetOffsetWorldPosition(prim_geom, NewPos.X, NewPos.Y, NewPos.Z); _orientation = newrot; quat.X = newrot.X; quat.Y = newrot.Y; quat.Z = newrot.Z; quat.W = newrot.W; - d.GeomSetOffsetWorldQuaternion(prim_geom, ref quat); + SafeNativeMethods.GeomSetOffsetWorldQuaternion(prim_geom, ref quat); - mat = d.GeomGetOffsetRotation(prim_geom); - d.MassRotate(ref tmpdmass, ref mat); + mat = SafeNativeMethods.GeomGetOffsetRotation(prim_geom); + SafeNativeMethods.MassRotate(ref tmpdmass, ref mat); - thispos = d.GeomGetOffsetPosition(prim_geom); - d.MassTranslate(ref tmpdmass, + thispos = SafeNativeMethods.GeomGetOffsetPosition(prim_geom); + SafeNativeMethods.MassTranslate(ref tmpdmass, thispos.X, thispos.Y, thispos.Z); - d.MassAdd(ref objdmass, ref tmpdmass); + SafeNativeMethods.MassAdd(ref objdmass, ref tmpdmass); // fix all positions - IntPtr g = d.BodyGetFirstGeom(Body); + IntPtr g = SafeNativeMethods.BodyGetFirstGeom(Body); while (g != IntPtr.Zero) { - thispos = d.GeomGetOffsetPosition(g); + thispos = SafeNativeMethods.GeomGetOffsetPosition(g); thispos.X -= objdmass.c.X; thispos.Y -= objdmass.c.Y; thispos.Z -= objdmass.c.Z; - d.GeomSetOffsetPosition(g, thispos.X, thispos.Y, thispos.Z); - g = d.dBodyGetNextGeom(g); + SafeNativeMethods.GeomSetOffsetPosition(g, thispos.X, thispos.Y, thispos.Z); + g = SafeNativeMethods.dBodyGetNextGeom(g); } - d.BodyVectorToWorld(Body,objdmass.c.X, objdmass.c.Y, objdmass.c.Z,out thispos); + SafeNativeMethods.BodyVectorToWorld(Body,objdmass.c.X, objdmass.c.Y, objdmass.c.Z,out thispos); - d.BodySetPosition(Body, dobjpos.X + thispos.X, dobjpos.Y + thispos.Y, dobjpos.Z + thispos.Z); - d.MassTranslate(ref objdmass, -objdmass.c.X, -objdmass.c.Y, -objdmass.c.Z); // ode wants inertia at center of body - d.BodySetMass(Body, ref objdmass); - _mass = objdmass.mass; + SafeNativeMethods.BodySetPosition(Body, dobjpos.X + thispos.X, dobjpos.Y + thispos.Y, dobjpos.Z + thispos.Z); + SafeNativeMethods.MassTranslate(ref objdmass, -objdmass.c.X, -objdmass.c.Y, -objdmass.c.Z); // ode wants inertia at center of body + SafeNativeMethods.BodySetMass(Body, ref objdmass); + m_mass = objdmass.mass; } private void FixInertia(Vector3 NewPos) { - d.Matrix3 primmat = new d.Matrix3(); - d.Mass tmpdmass = new d.Mass { }; - d.Mass objdmass = new d.Mass { }; - d.Mass primmass = new d.Mass { }; + SafeNativeMethods.Matrix3 primmat = new SafeNativeMethods.Matrix3(); + SafeNativeMethods.Mass tmpdmass = new SafeNativeMethods.Mass { }; + SafeNativeMethods.Mass objdmass = new SafeNativeMethods.Mass { }; + SafeNativeMethods.Mass primmass = new SafeNativeMethods.Mass { }; - d.Vector3 dobjpos; - d.Vector3 thispos; + SafeNativeMethods.Vector3 dobjpos; + SafeNativeMethods.Vector3 thispos; - d.BodyGetMass(Body, out objdmass); + SafeNativeMethods.BodyGetMass(Body, out objdmass); // get prim own inertia in its local frame primmass = primdMass; // transform to object frame - primmat = d.GeomGetOffsetRotation(prim_geom); - d.MassRotate(ref primmass, ref primmat); + primmat = SafeNativeMethods.GeomGetOffsetRotation(prim_geom); + SafeNativeMethods.MassRotate(ref primmass, ref primmat); tmpdmass = primmass; - thispos = d.GeomGetOffsetPosition(prim_geom); - d.MassTranslate(ref tmpdmass, + thispos = SafeNativeMethods.GeomGetOffsetPosition(prim_geom); + SafeNativeMethods.MassTranslate(ref tmpdmass, thispos.X, thispos.Y, thispos.Z); @@ -2115,58 +2353,58 @@ namespace OpenSim.Region.PhysicsModule.ubOde // update to new position _position = NewPos; - d.GeomSetOffsetWorldPosition(prim_geom, NewPos.X, NewPos.Y, NewPos.Z); + SafeNativeMethods.GeomSetOffsetWorldPosition(prim_geom, NewPos.X, NewPos.Y, NewPos.Z); - thispos = d.GeomGetOffsetPosition(prim_geom); - d.MassTranslate(ref primmass, + thispos = SafeNativeMethods.GeomGetOffsetPosition(prim_geom); + SafeNativeMethods.MassTranslate(ref primmass, thispos.X, thispos.Y, thispos.Z); - d.MassAdd(ref objdmass, ref primmass); + SafeNativeMethods.MassAdd(ref objdmass, ref primmass); // fix all positions - IntPtr g = d.BodyGetFirstGeom(Body); + IntPtr g = SafeNativeMethods.BodyGetFirstGeom(Body); while (g != IntPtr.Zero) { - thispos = d.GeomGetOffsetPosition(g); + thispos = SafeNativeMethods.GeomGetOffsetPosition(g); thispos.X -= objdmass.c.X; thispos.Y -= objdmass.c.Y; thispos.Z -= objdmass.c.Z; - d.GeomSetOffsetPosition(g, thispos.X, thispos.Y, thispos.Z); - g = d.dBodyGetNextGeom(g); + SafeNativeMethods.GeomSetOffsetPosition(g, thispos.X, thispos.Y, thispos.Z); + g = SafeNativeMethods.dBodyGetNextGeom(g); } - d.BodyVectorToWorld(Body, objdmass.c.X, objdmass.c.Y, objdmass.c.Z, out thispos); + SafeNativeMethods.BodyVectorToWorld(Body, objdmass.c.X, objdmass.c.Y, objdmass.c.Z, out thispos); // get current object position and rotation - dobjpos = d.BodyGetPosition(Body); + dobjpos = SafeNativeMethods.BodyGetPosition(Body); - d.BodySetPosition(Body, dobjpos.X + thispos.X, dobjpos.Y + thispos.Y, dobjpos.Z + thispos.Z); - d.MassTranslate(ref objdmass, -objdmass.c.X, -objdmass.c.Y, -objdmass.c.Z); // ode wants inertia at center of body - d.BodySetMass(Body, ref objdmass); - _mass = objdmass.mass; + SafeNativeMethods.BodySetPosition(Body, dobjpos.X + thispos.X, dobjpos.Y + thispos.Y, dobjpos.Z + thispos.Z); + SafeNativeMethods.MassTranslate(ref objdmass, -objdmass.c.X, -objdmass.c.Y, -objdmass.c.Z); // ode wants inertia at center of body + SafeNativeMethods.BodySetMass(Body, ref objdmass); + m_mass = objdmass.mass; } private void FixInertia(Quaternion newrot) { - d.Matrix3 mat = new d.Matrix3(); - d.Quaternion quat = new d.Quaternion(); + SafeNativeMethods.Matrix3 mat = new SafeNativeMethods.Matrix3(); + SafeNativeMethods.Quaternion quat = new SafeNativeMethods.Quaternion(); - d.Mass tmpdmass = new d.Mass { }; - d.Mass objdmass = new d.Mass { }; - d.Vector3 dobjpos; - d.Vector3 thispos; + SafeNativeMethods.Mass tmpdmass = new SafeNativeMethods.Mass { }; + SafeNativeMethods.Mass objdmass = new SafeNativeMethods.Mass { }; + SafeNativeMethods.Vector3 dobjpos; + SafeNativeMethods.Vector3 thispos; - d.BodyGetMass(Body, out objdmass); + SafeNativeMethods.BodyGetMass(Body, out objdmass); // get prim own inertia in its local frame tmpdmass = primdMass; - mat = d.GeomGetOffsetRotation(prim_geom); - d.MassRotate(ref tmpdmass, ref mat); + mat = SafeNativeMethods.GeomGetOffsetRotation(prim_geom); + SafeNativeMethods.MassRotate(ref tmpdmass, ref mat); // transform to object frame - thispos = d.GeomGetOffsetPosition(prim_geom); - d.MassTranslate(ref tmpdmass, + thispos = SafeNativeMethods.GeomGetOffsetPosition(prim_geom); + SafeNativeMethods.MassTranslate(ref tmpdmass, thispos.X, thispos.Y, thispos.Z); @@ -2180,38 +2418,38 @@ namespace OpenSim.Region.PhysicsModule.ubOde quat.Y = newrot.Y; quat.Z = newrot.Z; quat.W = newrot.W; - d.GeomSetOffsetWorldQuaternion(prim_geom, ref quat); + SafeNativeMethods.GeomSetOffsetWorldQuaternion(prim_geom, ref quat); tmpdmass = primdMass; - mat = d.GeomGetOffsetRotation(prim_geom); - d.MassRotate(ref tmpdmass, ref mat); - d.MassTranslate(ref tmpdmass, + mat = SafeNativeMethods.GeomGetOffsetRotation(prim_geom); + SafeNativeMethods.MassRotate(ref tmpdmass, ref mat); + SafeNativeMethods.MassTranslate(ref tmpdmass, thispos.X, thispos.Y, thispos.Z); - d.MassAdd(ref objdmass, ref tmpdmass); + SafeNativeMethods.MassAdd(ref objdmass, ref tmpdmass); // fix all positions - IntPtr g = d.BodyGetFirstGeom(Body); + IntPtr g = SafeNativeMethods.BodyGetFirstGeom(Body); while (g != IntPtr.Zero) { - thispos = d.GeomGetOffsetPosition(g); + thispos = SafeNativeMethods.GeomGetOffsetPosition(g); thispos.X -= objdmass.c.X; thispos.Y -= objdmass.c.Y; thispos.Z -= objdmass.c.Z; - d.GeomSetOffsetPosition(g, thispos.X, thispos.Y, thispos.Z); - g = d.dBodyGetNextGeom(g); + SafeNativeMethods.GeomSetOffsetPosition(g, thispos.X, thispos.Y, thispos.Z); + g = SafeNativeMethods.dBodyGetNextGeom(g); } - d.BodyVectorToWorld(Body, objdmass.c.X, objdmass.c.Y, objdmass.c.Z, out thispos); + SafeNativeMethods.BodyVectorToWorld(Body, objdmass.c.X, objdmass.c.Y, objdmass.c.Z, out thispos); // get current object position and rotation - dobjpos = d.BodyGetPosition(Body); + dobjpos = SafeNativeMethods.BodyGetPosition(Body); - d.BodySetPosition(Body, dobjpos.X + thispos.X, dobjpos.Y + thispos.Y, dobjpos.Z + thispos.Z); - d.MassTranslate(ref objdmass, -objdmass.c.X, -objdmass.c.Y, -objdmass.c.Z); // ode wants inertia at center of body - d.BodySetMass(Body, ref objdmass); - _mass = objdmass.mass; + SafeNativeMethods.BodySetPosition(Body, dobjpos.X + thispos.X, dobjpos.Y + thispos.Y, dobjpos.Z + thispos.Z); + SafeNativeMethods.MassTranslate(ref objdmass, -objdmass.c.X, -objdmass.c.Y, -objdmass.c.Z); // ode wants inertia at center of body + SafeNativeMethods.BodySetMass(Body, ref objdmass); + m_mass = objdmass.mass; } @@ -2226,11 +2464,11 @@ namespace OpenSim.Region.PhysicsModule.ubOde if (primMass > _parent_scene.maximumMassObject) primMass = _parent_scene.maximumMassObject; - _mass = primMass; // just in case + m_mass = primMass; // just in case - d.MassSetBoxTotal(out primdMass, primMass, 2.0f * m_OBB.X, 2.0f * m_OBB.Y, 2.0f * m_OBB.Z); + SafeNativeMethods.MassSetBoxTotal(out primdMass, primMass, 2.0f * m_OBB.X, 2.0f * m_OBB.Y, 2.0f * m_OBB.Z); - d.MassTranslate(ref primdMass, + SafeNativeMethods.MassTranslate(ref primdMass, m_OBBOffset.X, m_OBBOffset.Y, m_OBBOffset.Z); @@ -2285,7 +2523,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde if (prm.Body != IntPtr.Zero) { if (prm.prim_geom != IntPtr.Zero) - d.GeomSetBody(prm.prim_geom, IntPtr.Zero); + SafeNativeMethods.GeomSetBody(prm.prim_geom, IntPtr.Zero); if (prm.Body != prim.Body) prm.DestroyBody(); // don't loose bodies around prm.Body = IntPtr.Zero; @@ -2302,7 +2540,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde if (prim.Body != IntPtr.Zero) { if (prim.prim_geom != IntPtr.Zero) - d.GeomSetBody(prim.prim_geom, IntPtr.Zero); + SafeNativeMethods.GeomSetBody(prim.prim_geom, IntPtr.Zero); prim.DestroyBody(); // don't loose bodies around prim.Body = IntPtr.Zero; } @@ -2327,8 +2565,8 @@ namespace OpenSim.Region.PhysicsModule.ubOde { if (prim_geom != IntPtr.Zero) { - d.Quaternion qtmp; - d.GeomCopyQuaternion(prim_geom, out qtmp); + SafeNativeMethods.Quaternion qtmp; + SafeNativeMethods.GeomCopyQuaternion(prim_geom, out qtmp); _orientation.X = qtmp.X; _orientation.Y = qtmp.Y; _orientation.Z = qtmp.Z; @@ -2342,7 +2580,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde */ _orientation.Normalize(); - d.Vector3 lpos = d.GeomGetPosition(prim_geom); + SafeNativeMethods.Vector3 lpos = SafeNativeMethods.GeomGetPosition(prim_geom); _position.X = lpos.X; _position.Y = lpos.Y; _position.Z = lpos.Z; @@ -2471,7 +2709,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde { if (Amotor != IntPtr.Zero) { - d.JointDestroy(Amotor); + SafeNativeMethods.JointDestroy(Amotor); Amotor = IntPtr.Zero; } } @@ -2516,7 +2754,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde m_angularForceacc = Vector3.Zero; // m_torque = Vector3.Zero; _velocity = Vector3.Zero; - _acceleration = Vector3.Zero; + m_acceleration = Vector3.Zero; m_rotationalVelocity = Vector3.Zero; _target_velocity = Vector3.Zero; if (m_vehicle != null && m_vehicle.Type != Vehicle.TYPE_NONE) @@ -2528,10 +2766,10 @@ namespace OpenSim.Region.PhysicsModule.ubOde if (Body != IntPtr.Zero) { - d.BodySetForce(Body, 0f, 0f, 0f); - d.BodySetTorque(Body, 0f, 0f, 0f); - d.BodySetLinearVel(Body, 0f, 0f, 0f); - d.BodySetAngularVel(Body, 0f, 0f, 0f); + SafeNativeMethods.BodySetForce(Body, 0f, 0f, 0f); + SafeNativeMethods.BodySetTorque(Body, 0f, 0f, 0f); + SafeNativeMethods.BodySetLinearVel(Body, 0f, 0f, 0f); + SafeNativeMethods.BodySetAngularVel(Body, 0f, 0f, 0f); } } @@ -2593,7 +2831,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde if (newval) { if (!childPrim && Body != IntPtr.Zero) - d.BodyDisable(Body); + SafeNativeMethods.BodyDisable(Body); if (m_delaySelect || m_isphysical) { @@ -2612,13 +2850,13 @@ namespace OpenSim.Region.PhysicsModule.ubOde if (prm.m_NoColide) { - d.GeomSetCategoryBits(prm.prim_geom, 0); - d.GeomSetCollideBits(prm.prim_geom, 0); + SafeNativeMethods.GeomSetCategoryBits(prm.prim_geom, 0); + SafeNativeMethods.GeomSetCollideBits(prm.prim_geom, 0); } else { - d.GeomSetCategoryBits(prm.prim_geom, (uint)m_collisionCategories); - d.GeomSetCollideBits(prm.prim_geom, (uint)m_collisionFlags); + SafeNativeMethods.GeomSetCategoryBits(prm.prim_geom, (uint)m_collisionCategories); + SafeNativeMethods.GeomSetCollideBits(prm.prim_geom, (uint)m_collisionFlags); } } prm.m_delaySelect = false; @@ -2632,23 +2870,23 @@ namespace OpenSim.Region.PhysicsModule.ubOde { if (m_NoColide) { - d.GeomSetCategoryBits(prim_geom, 0); - d.GeomSetCollideBits(prim_geom, 0); + SafeNativeMethods.GeomSetCategoryBits(prim_geom, 0); + SafeNativeMethods.GeomSetCollideBits(prim_geom, 0); if (collide_geom != prim_geom && collide_geom != IntPtr.Zero) { - d.GeomSetCategoryBits(collide_geom, 0); - d.GeomSetCollideBits(collide_geom, 0); + SafeNativeMethods.GeomSetCategoryBits(collide_geom, 0); + SafeNativeMethods.GeomSetCollideBits(collide_geom, 0); } } else { - d.GeomSetCategoryBits(prim_geom, (uint)m_collisionCategories); - d.GeomSetCollideBits(prim_geom, (uint)m_collisionFlags); + SafeNativeMethods.GeomSetCategoryBits(prim_geom, (uint)m_collisionCategories); + SafeNativeMethods.GeomSetCollideBits(prim_geom, (uint)m_collisionFlags); if (collide_geom != prim_geom && collide_geom != IntPtr.Zero) { - d.GeomSetCategoryBits(collide_geom, (uint)m_collisionCategories); - d.GeomSetCollideBits(collide_geom, (uint)m_collisionFlags); + SafeNativeMethods.GeomSetCategoryBits(collide_geom, (uint)m_collisionCategories); + SafeNativeMethods.GeomSetCollideBits(collide_geom, (uint)m_collisionFlags); } } } @@ -2667,7 +2905,8 @@ namespace OpenSim.Region.PhysicsModule.ubOde if (Body != IntPtr.Zero && !m_disabled) { _zeroFlag = true; - d.BodyEnable(Body); + SafeNativeMethods.BodySetAutoDisableSteps(Body, m_body_autodisable_frames); + SafeNativeMethods.BodyEnable(Body); } } // else if (_parent != null) @@ -2697,10 +2936,11 @@ namespace OpenSim.Region.PhysicsModule.ubOde else if (m_forcePosOrRotation && _position != newPos && Body != IntPtr.Zero) { FixInertia(newPos); - if (!d.BodyIsEnabled(Body)) + if (!SafeNativeMethods.BodyIsEnabled(Body)) { _zeroFlag = true; - d.BodyEnable(Body); + SafeNativeMethods.BodySetAutoDisableSteps(Body, m_body_autodisable_frames); + SafeNativeMethods.BodyEnable(Body); } } } @@ -2708,13 +2948,14 @@ namespace OpenSim.Region.PhysicsModule.ubOde { if (_position != newPos) { - d.GeomSetPosition(prim_geom, newPos.X, newPos.Y, newPos.Z); + SafeNativeMethods.GeomSetPosition(prim_geom, newPos.X, newPos.Y, newPos.Z); _position = newPos; } - if (Body != IntPtr.Zero && !d.BodyIsEnabled(Body)) + if (Body != IntPtr.Zero && !SafeNativeMethods.BodyIsEnabled(Body)) { _zeroFlag = true; - d.BodyEnable(Body); + SafeNativeMethods.BodySetAutoDisableSteps(Body, m_body_autodisable_frames); + SafeNativeMethods.BodyEnable(Body); } } } @@ -2724,10 +2965,10 @@ namespace OpenSim.Region.PhysicsModule.ubOde { if (newPos != _position) { - d.GeomSetPosition(prim_geom, newPos.X, newPos.Y, newPos.Z); + SafeNativeMethods.GeomSetPosition(prim_geom, newPos.X, newPos.Y, newPos.Z); _position = newPos; - m_targetSpace = _parent_scene.MoveGeomToStaticSpace(prim_geom, _position, m_targetSpace); + m_targetSpace = _parent_scene.MoveGeomToStaticSpace(prim_geom, m_targetSpace); } } } @@ -2762,20 +3003,25 @@ namespace OpenSim.Region.PhysicsModule.ubOde { if (newOri != _orientation) { - d.Quaternion myrot = new d.Quaternion(); + SafeNativeMethods.Quaternion myrot = new SafeNativeMethods.Quaternion(); myrot.X = newOri.X; myrot.Y = newOri.Y; myrot.Z = newOri.Z; myrot.W = newOri.W; - d.GeomSetQuaternion(prim_geom, ref myrot); + SafeNativeMethods.GeomSetQuaternion(prim_geom, ref myrot); _orientation = newOri; - if (Body != IntPtr.Zero && m_angularlocks != 0) - createAMotor(m_angularlocks); + + if (Body != IntPtr.Zero) + { + if(m_angularlocks != 0) + createAMotor(m_angularlocks); + } } - if (Body != IntPtr.Zero && !d.BodyIsEnabled(Body)) + if (Body != IntPtr.Zero && !SafeNativeMethods.BodyIsEnabled(Body)) { _zeroFlag = true; - d.BodyEnable(Body); + SafeNativeMethods.BodySetAutoDisableSteps(Body, m_body_autodisable_frames); + SafeNativeMethods.BodyEnable(Body); } } } @@ -2785,12 +3031,12 @@ namespace OpenSim.Region.PhysicsModule.ubOde { if (newOri != _orientation) { - d.Quaternion myrot = new d.Quaternion(); + SafeNativeMethods.Quaternion myrot = new SafeNativeMethods.Quaternion(); myrot.X = newOri.X; myrot.Y = newOri.Y; myrot.Z = newOri.Z; myrot.W = newOri.W; - d.GeomSetQuaternion(prim_geom, ref myrot); + SafeNativeMethods.GeomSetQuaternion(prim_geom, ref myrot); _orientation = newOri; } } @@ -2815,25 +3061,26 @@ namespace OpenSim.Region.PhysicsModule.ubOde { if (newOri != _orientation) { - d.Quaternion myrot = new d.Quaternion(); + SafeNativeMethods.Quaternion myrot = new SafeNativeMethods.Quaternion(); myrot.X = newOri.X; myrot.Y = newOri.Y; myrot.Z = newOri.Z; myrot.W = newOri.W; - d.GeomSetQuaternion(prim_geom, ref myrot); + SafeNativeMethods.GeomSetQuaternion(prim_geom, ref myrot); _orientation = newOri; if (Body != IntPtr.Zero && m_angularlocks != 0) createAMotor(m_angularlocks); } if (_position != newPos) { - d.GeomSetPosition(prim_geom, newPos.X, newPos.Y, newPos.Z); + SafeNativeMethods.GeomSetPosition(prim_geom, newPos.X, newPos.Y, newPos.Z); _position = newPos; } - if (Body != IntPtr.Zero && !d.BodyIsEnabled(Body)) + if (Body != IntPtr.Zero && !SafeNativeMethods.BodyIsEnabled(Body)) { _zeroFlag = true; - d.BodyEnable(Body); + SafeNativeMethods.BodySetAutoDisableSteps(Body, m_body_autodisable_frames); + SafeNativeMethods.BodyEnable(Body); } } } @@ -2846,21 +3093,21 @@ namespace OpenSim.Region.PhysicsModule.ubOde { if (newOri != _orientation) { - d.Quaternion myrot = new d.Quaternion(); + SafeNativeMethods.Quaternion myrot = new SafeNativeMethods.Quaternion(); myrot.X = newOri.X; myrot.Y = newOri.Y; myrot.Z = newOri.Z; myrot.W = newOri.W; - d.GeomSetQuaternion(prim_geom, ref myrot); + SafeNativeMethods.GeomSetQuaternion(prim_geom, ref myrot); _orientation = newOri; } if (newPos != _position) { - d.GeomSetPosition(prim_geom, newPos.X, newPos.Y, newPos.Z); + SafeNativeMethods.GeomSetPosition(prim_geom, newPos.X, newPos.Y, newPos.Z); _position = newPos; - m_targetSpace = _parent_scene.MoveGeomToStaticSpace(prim_geom, _position, m_targetSpace); + m_targetSpace = _parent_scene.MoveGeomToStaticSpace(prim_geom, m_targetSpace); } } } @@ -2925,7 +3172,6 @@ namespace OpenSim.Region.PhysicsModule.ubOde { _size = repData.size; //?? _pbs = repData.pbs; - m_shapetype = repData.shapetype; m_mesh = repData.mesh; @@ -2938,17 +3184,17 @@ namespace OpenSim.Region.PhysicsModule.ubOde primVolume = repData.volume; - CreateGeom(); + CreateGeom(repData.isTooSmall); if (prim_geom != IntPtr.Zero) { - d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); - d.Quaternion myrot = new d.Quaternion(); + SafeNativeMethods.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); + SafeNativeMethods.Quaternion myrot = new SafeNativeMethods.Quaternion(); myrot.X = _orientation.X; myrot.Y = _orientation.Y; myrot.Z = _orientation.Z; myrot.W = _orientation.W; - d.GeomSetQuaternion(prim_geom, ref myrot); + SafeNativeMethods.GeomSetQuaternion(prim_geom, ref myrot); } if (!m_isphysical) @@ -2964,9 +3210,11 @@ namespace OpenSim.Region.PhysicsModule.ubOde { repData.size = _size; repData.pbs = _pbs; - repData.shapetype = m_shapetype; + repData.shapetype = m_fakeShapetype; _parent_scene.m_meshWorker.RequestMesh(repData); } + else + m_shapetype = repData.shapetype; } private void changePhysRepData(ODEPhysRepData repData) @@ -3000,7 +3248,6 @@ namespace OpenSim.Region.PhysicsModule.ubOde _size = repData.size; _pbs = repData.pbs; - m_shapetype = repData.shapetype; m_mesh = repData.mesh; @@ -3013,17 +3260,17 @@ namespace OpenSim.Region.PhysicsModule.ubOde primVolume = repData.volume; - CreateGeom(); + CreateGeom(repData.isTooSmall); if (prim_geom != IntPtr.Zero) { - d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); - d.Quaternion myrot = new d.Quaternion(); + SafeNativeMethods.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); + SafeNativeMethods.Quaternion myrot = new SafeNativeMethods.Quaternion(); myrot.X = _orientation.X; myrot.Y = _orientation.Y; myrot.Z = _orientation.Z; myrot.W = _orientation.W; - d.GeomSetQuaternion(prim_geom, ref myrot); + SafeNativeMethods.GeomSetQuaternion(prim_geom, ref myrot); } if (m_isphysical) @@ -3051,9 +3298,11 @@ namespace OpenSim.Region.PhysicsModule.ubOde { repData.size = _size; repData.pbs = _pbs; - repData.shapetype = m_shapetype; + repData.shapetype = m_fakeShapetype; _parent_scene.m_meshWorker.RequestMesh(repData); } + else + m_shapetype = repData.shapetype; } private void changeFloatOnWater(bool newval) @@ -3066,15 +3315,17 @@ namespace OpenSim.Region.PhysicsModule.ubOde private void changeSetTorque(Vector3 newtorque) { - if (!m_isSelected) + if (!m_isSelected && !m_outbounds) { if (m_isphysical && Body != IntPtr.Zero) { if (m_disabled) enableBodySoft(); - else if (!d.BodyIsEnabled(Body)) - d.BodyEnable(Body); - + else if (!SafeNativeMethods.BodyIsEnabled(Body)) + { + SafeNativeMethods.BodySetAutoDisableSteps(Body, m_body_autodisable_frames); + SafeNativeMethods.BodyEnable(Body); + } } m_torque = newtorque; } @@ -3083,14 +3334,17 @@ namespace OpenSim.Region.PhysicsModule.ubOde private void changeForce(Vector3 force) { m_force = force; - if (Body != IntPtr.Zero && !d.BodyIsEnabled(Body)) - d.BodyEnable(Body); + if (!m_isSelected && !m_outbounds && Body != IntPtr.Zero && !SafeNativeMethods.BodyIsEnabled(Body)) + { + SafeNativeMethods.BodySetAutoDisableSteps(Body, m_body_autodisable_frames); + SafeNativeMethods.BodyEnable(Body); + } } private void changeAddForce(Vector3 theforce) { m_forceacc += theforce; - if (!m_isSelected) + if (!m_isSelected && !m_outbounds) { lock (this) { @@ -3099,8 +3353,11 @@ namespace OpenSim.Region.PhysicsModule.ubOde { if (m_disabled) enableBodySoft(); - else if (!d.BodyIsEnabled(Body)) - d.BodyEnable(Body); + else if (!SafeNativeMethods.BodyIsEnabled(Body)) + { + SafeNativeMethods.BodySetAutoDisableSteps(Body, m_body_autodisable_frames); + SafeNativeMethods.BodyEnable(Body); + } } } m_collisionscore = 0; @@ -3111,7 +3368,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde private void changeAddAngularImpulse(Vector3 aimpulse) { m_angularForceacc += aimpulse * m_invTimeStep; - if (!m_isSelected) + if (!m_isSelected && !m_outbounds) { lock (this) { @@ -3119,8 +3376,11 @@ namespace OpenSim.Region.PhysicsModule.ubOde { if (m_disabled) enableBodySoft(); - else if (!d.BodyIsEnabled(Body)) - d.BodyEnable(Body); + else if (!SafeNativeMethods.BodyIsEnabled(Body)) + { + SafeNativeMethods.BodySetAutoDisableSteps(Body, m_body_autodisable_frames); + SafeNativeMethods.BodyEnable(Body); + } } } m_collisionscore = 0; @@ -3136,16 +3396,18 @@ namespace OpenSim.Region.PhysicsModule.ubOde newVel *= len; } - if (!m_isSelected) + if (!m_isSelected && !m_outbounds) { if (Body != IntPtr.Zero) { if (m_disabled) enableBodySoft(); - else if (!d.BodyIsEnabled(Body)) - d.BodyEnable(Body); - - d.BodySetLinearVel(Body, newVel.X, newVel.Y, newVel.Z); + else if (!SafeNativeMethods.BodyIsEnabled(Body)) + { + SafeNativeMethods.BodySetAutoDisableSteps(Body, m_body_autodisable_frames); + SafeNativeMethods.BodyEnable(Body); + } + SafeNativeMethods.BodySetLinearVel(Body, newVel.X, newVel.Y, newVel.Z); } //resetCollisionAccounting(); } @@ -3161,17 +3423,18 @@ namespace OpenSim.Region.PhysicsModule.ubOde newAngVel *= len; } - if (!m_isSelected) + if (!m_isSelected && !m_outbounds) { if (Body != IntPtr.Zero) { if (m_disabled) enableBodySoft(); - else if (!d.BodyIsEnabled(Body)) - d.BodyEnable(Body); - - - d.BodySetAngularVel(Body, newAngVel.X, newAngVel.Y, newAngVel.Z); + else if (!SafeNativeMethods.BodyIsEnabled(Body)) + { + SafeNativeMethods.BodySetAutoDisableSteps(Body, m_body_autodisable_frames); + SafeNativeMethods.BodyEnable(Body); + } + SafeNativeMethods.BodySetAngularVel(Body, newAngVel.X, newAngVel.Y, newAngVel.Z); } //resetCollisionAccounting(); } @@ -3306,6 +3569,15 @@ namespace OpenSim.Region.PhysicsModule.ubOde m_useHoverPID = active; } + private void changeInertia(PhysicsInertiaData inertia) + { + m_InertiaOverride = inertia; + + if (Body != IntPtr.Zero) + DestroyBody(); + MakeBody(); + } + #endregion public void Move() @@ -3313,27 +3585,28 @@ namespace OpenSim.Region.PhysicsModule.ubOde if (!childPrim && m_isphysical && Body != IntPtr.Zero && !m_disabled && !m_isSelected && !m_building && !m_outbounds) { - if (!d.BodyIsEnabled(Body)) + if (!SafeNativeMethods.BodyIsEnabled(Body)) { // let vehicles sleep if (m_vehicle != null && m_vehicle.Type != Vehicle.TYPE_NONE) return; - if (++bodydisablecontrol < 50) + if (++m_bodydisablecontrol < 50) return; // clear residuals - d.BodySetAngularVel(Body,0f,0f,0f); - d.BodySetLinearVel(Body,0f,0f,0f); + SafeNativeMethods.BodySetAngularVel(Body,0f,0f,0f); + SafeNativeMethods.BodySetLinearVel(Body,0f,0f,0f); _zeroFlag = true; - d.BodyEnable(Body); - bodydisablecontrol = -4; + SafeNativeMethods.BodySetAutoDisableSteps(Body, 1); + SafeNativeMethods.BodyEnable(Body); + m_bodydisablecontrol = -3; } - if(bodydisablecontrol < 0) - bodydisablecontrol ++; + if(m_bodydisablecontrol < 0) + m_bodydisablecontrol++; - d.Vector3 lpos = d.GeomGetPosition(prim_geom); // root position that is seem by rest of simulator + SafeNativeMethods.Vector3 lpos = SafeNativeMethods.GeomGetPosition(prim_geom); // root position that is seem by rest of simulator if (m_vehicle != null && m_vehicle.Type != Vehicle.TYPE_NONE) { @@ -3346,7 +3619,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde float fy = 0; float fz = 0; - float m_mass = _mass; + float mass = m_mass; if (m_usePID && m_PIDTau > 0) { @@ -3360,8 +3633,8 @@ namespace OpenSim.Region.PhysicsModule.ubOde if (_target_velocity.ApproxEquals(Vector3.Zero, 0.02f)) { - d.BodySetPosition(Body, m_PIDTarget.X, m_PIDTarget.Y, m_PIDTarget.Z); - d.BodySetLinearVel(Body, 0, 0, 0); + SafeNativeMethods.BodySetPosition(Body, m_PIDTarget.X, m_PIDTarget.Y, m_PIDTarget.Z); + SafeNativeMethods.BodySetLinearVel(Body, 0, 0, 0); return; } else @@ -3384,7 +3657,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde _target_velocity *= tmp; } - d.Vector3 vel = d.BodyGetLinearVel(Body); + SafeNativeMethods.Vector3 vel = SafeNativeMethods.BodyGetLinearVel(Body); fx = (_target_velocity.X - vel.X) * m_invTimeStep; fy = (_target_velocity.Y - vel.Y) * m_invTimeStep; fz = (_target_velocity.Z - vel.Z) * m_invTimeStep; @@ -3420,15 +3693,15 @@ namespace OpenSim.Region.PhysicsModule.ubOde if (m_targetHoverHeight > m_groundHeight || m_isVolumeDetect) { - d.Vector3 vel = d.BodyGetLinearVel(Body); + SafeNativeMethods.Vector3 vel = SafeNativeMethods.BodyGetLinearVel(Body); fz = (m_targetHoverHeight - lpos.Z); // if error is zero, use position control; otherwise, velocity control if (Math.Abs(fz) < 0.01f) { - d.BodySetPosition(Body, lpos.X, lpos.Y, m_targetHoverHeight); - d.BodySetLinearVel(Body, vel.X, vel.Y, 0); + SafeNativeMethods.BodySetPosition(Body, lpos.X, lpos.Y, m_targetHoverHeight); + SafeNativeMethods.BodySetLinearVel(Body, vel.X, vel.Y, 0); } else { @@ -3453,9 +3726,9 @@ namespace OpenSim.Region.PhysicsModule.ubOde fz = _parent_scene.gravityz * b; } - fx *= m_mass; - fy *= m_mass; - fz *= m_mass; + fx *= mass; + fy *= mass; + fz *= mass; // constant force fx += m_force.X; @@ -3471,7 +3744,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde //m_log.Info("[OBJPID]: X:" + fx.ToString() + " Y:" + fy.ToString() + " Z:" + fz.ToString()); if (fx != 0 || fy != 0 || fz != 0) { - d.BodyAddForce(Body, fx, fy, fz); + SafeNativeMethods.BodyAddForce(Body, fx, fy, fz); //Console.WriteLine("AddForce " + fx + "," + fy + "," + fz); } @@ -3482,7 +3755,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde m_angularForceacc = Vector3.Zero; if (trq.X != 0 || trq.Y != 0 || trq.Z != 0) { - d.BodyAddTorque(Body, trq.X, trq.Y, trq.Z); + SafeNativeMethods.BodyAddTorque(Body, trq.X, trq.Y, trq.Z); } } else @@ -3496,18 +3769,17 @@ namespace OpenSim.Region.PhysicsModule.ubOde public void UpdatePositionAndVelocity(int frame) { - if (_parent == null && !m_disabled && !m_building && !m_outbounds && Body != IntPtr.Zero) + if (_parent == null && !m_isSelected && !m_disabled && !m_building && !m_outbounds && Body != IntPtr.Zero) { - bool bodyenabled = d.BodyIsEnabled(Body); - - if(bodydisablecontrol < 0) + if(m_bodydisablecontrol < 0) return; + bool bodyenabled = SafeNativeMethods.BodyIsEnabled(Body); if (bodyenabled || !_zeroFlag) { bool lastZeroFlag = _zeroFlag; - d.Vector3 lpos = d.GeomGetPosition(prim_geom); + SafeNativeMethods.Vector3 lpos = SafeNativeMethods.GeomGetPosition(prim_geom); // check outside region if (lpos.Z < -100 || lpos.Z > 100000f) @@ -3515,9 +3787,9 @@ namespace OpenSim.Region.PhysicsModule.ubOde m_outbounds = true; lpos.Z = Util.Clip(lpos.Z, -100f, 100000f); - _acceleration.X = 0; - _acceleration.Y = 0; - _acceleration.Z = 0; + m_acceleration.X = 0; + m_acceleration.Y = 0; + m_acceleration.Z = 0; _velocity.X = 0; _velocity.Y = 0; @@ -3526,9 +3798,9 @@ namespace OpenSim.Region.PhysicsModule.ubOde m_rotationalVelocity.Y = 0; m_rotationalVelocity.Z = 0; - d.BodySetLinearVel(Body, 0, 0, 0); // stop it - d.BodySetAngularVel(Body, 0, 0, 0); // stop it - d.BodySetPosition(Body, lpos.X, lpos.Y, lpos.Z); // put it somewhere + SafeNativeMethods.BodySetLinearVel(Body, 0, 0, 0); // stop it + SafeNativeMethods.BodySetAngularVel(Body, 0, 0, 0); // stop it + SafeNativeMethods.BodySetPosition(Body, lpos.X, lpos.Y, lpos.Z); // put it somewhere m_lastposition = _position; m_lastorientation = _orientation; @@ -3568,19 +3840,19 @@ namespace OpenSim.Region.PhysicsModule.ubOde m_lastposition = _position; m_lastorientation = _orientation; - d.Vector3 dtmp = d.BodyGetAngularVel(Body); + SafeNativeMethods.Vector3 dtmp = SafeNativeMethods.BodyGetAngularVel(Body); m_rotationalVelocity.X = dtmp.X; m_rotationalVelocity.Y = dtmp.Y; m_rotationalVelocity.Z = dtmp.Z; - dtmp = d.BodyGetLinearVel(Body); + dtmp = SafeNativeMethods.BodyGetLinearVel(Body); _velocity.X = dtmp.X; _velocity.Y = dtmp.Y; _velocity.Z = dtmp.Z; - d.BodySetLinearVel(Body, 0, 0, 0); // stop it - d.BodySetAngularVel(Body, 0, 0, 0); - d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); + SafeNativeMethods.BodySetLinearVel(Body, 0, 0, 0); // stop it + SafeNativeMethods.BodySetAngularVel(Body, 0, 0, 0); + SafeNativeMethods.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); disableBodySoft(); // stop collisions UnSubscribeEvents(); @@ -3588,8 +3860,8 @@ namespace OpenSim.Region.PhysicsModule.ubOde return; } - d.Quaternion ori; - d.GeomCopyQuaternion(prim_geom, out ori); + SafeNativeMethods.Quaternion ori; + SafeNativeMethods.GeomCopyQuaternion(prim_geom, out ori); // decide if moving // use positions since this are integrated quantities @@ -3640,19 +3912,19 @@ namespace OpenSim.Region.PhysicsModule.ubOde _orientation.W = ori.W; } - // update velocities and aceleration + // update velocities and acceleration if (_zeroFlag || lastZeroFlag) { // disable interpolators _velocity = Vector3.Zero; - _acceleration = Vector3.Zero; - m_rotationalVelocity = Vector3.Zero; + m_acceleration = Vector3.Zero; + m_rotationalVelocity = Vector3.Zero; } else { - d.Vector3 vel = d.BodyGetLinearVel(Body); + SafeNativeMethods.Vector3 vel = SafeNativeMethods.BodyGetLinearVel(Body); - _acceleration = _velocity; + m_acceleration = _velocity; if ((Math.Abs(vel.X) < 0.005f) && (Math.Abs(vel.Y) < 0.005f) && @@ -3660,28 +3932,28 @@ namespace OpenSim.Region.PhysicsModule.ubOde { _velocity = Vector3.Zero; float t = -m_invTimeStep; - _acceleration = _acceleration * t; + m_acceleration = m_acceleration * t; } else { _velocity.X = vel.X; _velocity.Y = vel.Y; _velocity.Z = vel.Z; - _acceleration = (_velocity - _acceleration) * m_invTimeStep; + m_acceleration = (_velocity - m_acceleration) * m_invTimeStep; } - if ((Math.Abs(_acceleration.X) < 0.01f) && - (Math.Abs(_acceleration.Y) < 0.01f) && - (Math.Abs(_acceleration.Z) < 0.01f)) + if ((Math.Abs(m_acceleration.X) < 0.01f) && + (Math.Abs(m_acceleration.Y) < 0.01f) && + (Math.Abs(m_acceleration.Z) < 0.01f)) { - _acceleration = Vector3.Zero; + m_acceleration = Vector3.Zero; } - vel = d.BodyGetAngularVel(Body); + vel = SafeNativeMethods.BodyGetAngularVel(Body); if ((Math.Abs(vel.X) < 0.0001) && - (Math.Abs(vel.Y) < 0.0001) && - (Math.Abs(vel.Z) < 0.0001) - ) + (Math.Abs(vel.Y) < 0.0001) && + (Math.Abs(vel.Z) < 0.0001) + ) { m_rotationalVelocity = Vector3.Zero; } @@ -3723,7 +3995,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde return true; } - internal static void DMassSubPartFromObj(ref d.Mass part, ref d.Mass theobj) + internal static void DMassSubPartFromObj(ref SafeNativeMethods.Mass part, ref SafeNativeMethods.Mass theobj) { // assumes object center of mass is zero float smass = part.mass; @@ -3941,6 +4213,10 @@ namespace OpenSim.Region.PhysicsModule.ubOde changePIDHoverActive((bool)arg); break; + case changes.SetInertia: + changeInertia((PhysicsInertiaData) arg); + break; + case changes.Null: donullchange(); break; @@ -3957,7 +4233,6 @@ namespace OpenSim.Region.PhysicsModule.ubOde _parent_scene.AddChange((PhysicsActor) this, what, arg); } - private struct strVehicleBoolParam { public int param; diff --git a/OpenSim/Region/PhysicsModules/ubOde/ODERayCastRequestManager.cs b/OpenSim/Region/PhysicsModules/ubOde/ODERayCastRequestManager.cs index f671722e4c..2e3a197621 100644 --- a/OpenSim/Region/PhysicsModules/ubOde/ODERayCastRequestManager.cs +++ b/OpenSim/Region/PhysicsModules/ubOde/ODERayCastRequestManager.cs @@ -29,10 +29,8 @@ using System; using System.Collections.Generic; using System.Reflection; using System.Runtime.InteropServices; -using System.Text; using OpenSim.Framework; using OpenSim.Region.PhysicsModules.SharedBase; -using OdeAPI; using log4net; using OpenMetaverse; @@ -67,7 +65,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde /// /// ODE near callback delegate /// - private d.NearCallback nearCallback; + private SafeNativeMethods.NearCallback nearCallback; private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private List m_contactResults = new List(); private RayFilterFlags CurrentRayFilter; @@ -77,14 +75,14 @@ namespace OpenSim.Region.PhysicsModule.ubOde { m_scene = pScene; nearCallback = near; - ray = d.CreateRay(IntPtr.Zero, 1.0f); - d.GeomSetCategoryBits(ray, 0); - Box = d.CreateBox(IntPtr.Zero, 1.0f, 1.0f, 1.0f); - d.GeomSetCategoryBits(Box, 0); - Sphere = d.CreateSphere(IntPtr.Zero,1.0f); - d.GeomSetCategoryBits(Sphere, 0); - Plane = d.CreatePlane(IntPtr.Zero, 0f,0f,1f,1f); - d.GeomSetCategoryBits(Sphere, 0); + ray = SafeNativeMethods.CreateRay(IntPtr.Zero, 1.0f); + SafeNativeMethods.GeomSetCategoryBits(ray, 0); + Box = SafeNativeMethods.CreateBox(IntPtr.Zero, 1.0f, 1.0f, 1.0f); + SafeNativeMethods.GeomSetCategoryBits(Box, 0); + Sphere = SafeNativeMethods.CreateSphere(IntPtr.Zero,1.0f); + SafeNativeMethods.GeomSetCategoryBits(Sphere, 0); + Plane = SafeNativeMethods.CreatePlane(IntPtr.Zero, 0f,0f,1f,1f); + SafeNativeMethods.GeomSetCategoryBits(Sphere, 0); } public void QueueRequest(ODERayRequest req) @@ -152,29 +150,29 @@ namespace OpenSim.Region.PhysicsModule.ubOde { if (CollisionContactGeomsPerTest > 80) CollisionContactGeomsPerTest = 80; - d.GeomBoxSetLengths(Box, req.Normal.X, req.Normal.Y, req.Normal.Z); - d.GeomSetPosition(Box, req.Origin.X, req.Origin.Y, req.Origin.Z); - d.Quaternion qtmp; + SafeNativeMethods.GeomBoxSetLengths(Box, req.Normal.X, req.Normal.Y, req.Normal.Z); + SafeNativeMethods.GeomSetPosition(Box, req.Origin.X, req.Origin.Y, req.Origin.Z); + SafeNativeMethods.Quaternion qtmp; qtmp.X = req.orientation.X; qtmp.Y = req.orientation.Y; qtmp.Z = req.orientation.Z; qtmp.W = req.orientation.W; - d.GeomSetQuaternion(Box, ref qtmp); + SafeNativeMethods.GeomSetQuaternion(Box, ref qtmp); } else if (req.callbackMethod is ProbeSphereCallback) { if (CollisionContactGeomsPerTest > 80) CollisionContactGeomsPerTest = 80; - d.GeomSphereSetRadius(Sphere, req.length); - d.GeomSetPosition(Sphere, req.Origin.X, req.Origin.Y, req.Origin.Z); + SafeNativeMethods.GeomSphereSetRadius(Sphere, req.length); + SafeNativeMethods.GeomSetPosition(Sphere, req.Origin.X, req.Origin.Y, req.Origin.Z); } else if (req.callbackMethod is ProbePlaneCallback) { if (CollisionContactGeomsPerTest > 80) CollisionContactGeomsPerTest = 80; - d.GeomPlaneSetParams(Plane, req.Normal.X, req.Normal.Y, req.Normal.Z, req.length); + SafeNativeMethods.GeomPlaneSetParams(Plane, req.Normal.X, req.Normal.Y, req.Normal.Z, req.length); } else @@ -182,24 +180,24 @@ namespace OpenSim.Region.PhysicsModule.ubOde if (CollisionContactGeomsPerTest > 25) CollisionContactGeomsPerTest = 25; - d.GeomRaySetLength(ray, req.length); - d.GeomRaySet(ray, req.Origin.X, req.Origin.Y, req.Origin.Z, req.Normal.X, req.Normal.Y, req.Normal.Z); - d.GeomRaySetParams(ray, 0, backfacecull); + SafeNativeMethods.GeomRaySetLength(ray, req.length); + SafeNativeMethods.GeomRaySet(ray, req.Origin.X, req.Origin.Y, req.Origin.Z, req.Normal.X, req.Normal.Y, req.Normal.Z); + SafeNativeMethods.GeomRaySetParams(ray, 0, backfacecull); if (req.callbackMethod is RaycastCallback) { // if we only want one get only one per Collision pair saving memory CurrentRayFilter |= RayFilterFlags.ClosestHit; - d.GeomRaySetClosestHit(ray, 1); + SafeNativeMethods.GeomRaySetClosestHit(ray, 1); } else - d.GeomRaySetClosestHit(ray, closestHit); + SafeNativeMethods.GeomRaySetClosestHit(ray, closestHit); } if ((CurrentRayFilter & RayFilterFlags.ContactsUnImportant) != 0) unchecked { - CollisionContactGeomsPerTest |= (int)d.CONTACTS_UNIMPORTANT; + CollisionContactGeomsPerTest |= (int)SafeNativeMethods.CONTACTS_UNIMPORTANT; } if (geom == IntPtr.Zero) @@ -224,27 +222,27 @@ namespace OpenSim.Region.PhysicsModule.ubOde if (req.callbackMethod is ProbeBoxCallback) { catflags |= CollisionCategories.Space; - d.GeomSetCollideBits(Box, (uint)catflags); - d.GeomSetCategoryBits(Box, (uint)catflags); + SafeNativeMethods.GeomSetCollideBits(Box, (uint)catflags); + SafeNativeMethods.GeomSetCategoryBits(Box, (uint)catflags); doProbe(req, Box); } else if (req.callbackMethod is ProbeSphereCallback) { catflags |= CollisionCategories.Space; - d.GeomSetCollideBits(Sphere, (uint)catflags); - d.GeomSetCategoryBits(Sphere, (uint)catflags); + SafeNativeMethods.GeomSetCollideBits(Sphere, (uint)catflags); + SafeNativeMethods.GeomSetCategoryBits(Sphere, (uint)catflags); doProbe(req, Sphere); } else if (req.callbackMethod is ProbePlaneCallback) { catflags |= CollisionCategories.Space; - d.GeomSetCollideBits(Plane, (uint)catflags); - d.GeomSetCategoryBits(Plane, (uint)catflags); + SafeNativeMethods.GeomSetCollideBits(Plane, (uint)catflags); + SafeNativeMethods.GeomSetCategoryBits(Plane, (uint)catflags); doPlane(req,IntPtr.Zero); } else { - d.GeomSetCollideBits(ray, (uint)catflags); + SafeNativeMethods.GeomSetCollideBits(ray, (uint)catflags); doSpaceRay(req); } } @@ -255,12 +253,12 @@ namespace OpenSim.Region.PhysicsModule.ubOde if (req.callbackMethod is ProbePlaneCallback) { - d.GeomSetCollideBits(Plane, (uint)CollisionCategories.All); + SafeNativeMethods.GeomSetCollideBits(Plane, (uint)CollisionCategories.All); doPlane(req,geom); } else { - d.GeomSetCollideBits(ray, (uint)CollisionCategories.All); + SafeNativeMethods.GeomSetCollideBits(ray, (uint)CollisionCategories.All); doGeomRay(req,geom); } } @@ -307,11 +305,11 @@ namespace OpenSim.Region.PhysicsModule.ubOde // Collide tests if ((CurrentRayFilter & FilterActiveSpace) != 0) { - d.SpaceCollide2(ray, m_scene.ActiveSpace, IntPtr.Zero, nearCallback); - d.SpaceCollide2(ray, m_scene.CharsSpace, IntPtr.Zero, nearCallback); + SafeNativeMethods.SpaceCollide2(ray, m_scene.ActiveSpace, IntPtr.Zero, nearCallback); + SafeNativeMethods.SpaceCollide2(ray, m_scene.CharsSpace, IntPtr.Zero, nearCallback); } if ((CurrentRayFilter & FilterStaticSpace) != 0 && (m_contactResults.Count < CurrentMaxCount)) - d.SpaceCollide2(ray, m_scene.StaticSpace, IntPtr.Zero, nearCallback); + SafeNativeMethods.SpaceCollide2(ray, m_scene.StaticSpace, IntPtr.Zero, nearCallback); if ((CurrentRayFilter & RayFilterFlags.land) != 0 && (m_contactResults.Count < CurrentMaxCount)) { // current ode land to ray collisions is very bad @@ -324,11 +322,11 @@ namespace OpenSim.Region.PhysicsModule.ubOde { float tmp2 = req.length * req.length - tmp + 2500; tmp2 = (float)Math.Sqrt(tmp2); - d.GeomRaySetLength(ray, tmp2); + SafeNativeMethods.GeomRaySetLength(ray, tmp2); } } - d.SpaceCollide2(ray, m_scene.GroundSpace, IntPtr.Zero, nearCallback); + SafeNativeMethods.SpaceCollide2(ray, m_scene.GroundSpace, IntPtr.Zero, nearCallback); } if (req.callbackMethod is RaycastCallback) @@ -377,13 +375,13 @@ namespace OpenSim.Region.PhysicsModule.ubOde // Collide tests if ((CurrentRayFilter & FilterActiveSpace) != 0) { - d.SpaceCollide2(probe, m_scene.ActiveSpace, IntPtr.Zero, nearCallback); - d.SpaceCollide2(probe, m_scene.CharsSpace, IntPtr.Zero, nearCallback); + SafeNativeMethods.SpaceCollide2(probe, m_scene.ActiveSpace, IntPtr.Zero, nearCallback); + SafeNativeMethods.SpaceCollide2(probe, m_scene.CharsSpace, IntPtr.Zero, nearCallback); } if ((CurrentRayFilter & FilterStaticSpace) != 0 && (m_contactResults.Count < CurrentMaxCount)) - d.SpaceCollide2(probe, m_scene.StaticSpace, IntPtr.Zero, nearCallback); + SafeNativeMethods.SpaceCollide2(probe, m_scene.StaticSpace, IntPtr.Zero, nearCallback); if ((CurrentRayFilter & RayFilterFlags.land) != 0 && (m_contactResults.Count < CurrentMaxCount)) - d.SpaceCollide2(probe, m_scene.GroundSpace, IntPtr.Zero, nearCallback); + SafeNativeMethods.SpaceCollide2(probe, m_scene.GroundSpace, IntPtr.Zero, nearCallback); List cresult = new List(m_contactResults.Count); lock (m_PendingRequests) @@ -404,17 +402,17 @@ namespace OpenSim.Region.PhysicsModule.ubOde { if ((CurrentRayFilter & FilterActiveSpace) != 0) { - d.SpaceCollide2(Plane, m_scene.ActiveSpace, IntPtr.Zero, nearCallback); - d.SpaceCollide2(Plane, m_scene.CharsSpace, IntPtr.Zero, nearCallback); + SafeNativeMethods.SpaceCollide2(Plane, m_scene.ActiveSpace, IntPtr.Zero, nearCallback); + SafeNativeMethods.SpaceCollide2(Plane, m_scene.CharsSpace, IntPtr.Zero, nearCallback); } if ((CurrentRayFilter & FilterStaticSpace) != 0 && (m_contactResults.Count < CurrentMaxCount)) - d.SpaceCollide2(Plane, m_scene.StaticSpace, IntPtr.Zero, nearCallback); + SafeNativeMethods.SpaceCollide2(Plane, m_scene.StaticSpace, IntPtr.Zero, nearCallback); if ((CurrentRayFilter & RayFilterFlags.land) != 0 && (m_contactResults.Count < CurrentMaxCount)) - d.SpaceCollide2(Plane, m_scene.GroundSpace, IntPtr.Zero, nearCallback); + SafeNativeMethods.SpaceCollide2(Plane, m_scene.GroundSpace, IntPtr.Zero, nearCallback); } else { - d.SpaceCollide2(Plane, geom, IntPtr.Zero, nearCallback); + SafeNativeMethods.SpaceCollide2(Plane, geom, IntPtr.Zero, nearCallback); } List cresult = new List(m_contactResults.Count); @@ -434,7 +432,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde private void doGeomRay(ODERayRequest req, IntPtr geom) { // Collide test - d.SpaceCollide2(ray, geom, IntPtr.Zero, nearCallback); // still do this to have full AABB pre test + SafeNativeMethods.SpaceCollide2(ray, geom, IntPtr.Zero, nearCallback); // still do this to have full AABB pre test if (req.callbackMethod is RaycastCallback) { @@ -478,14 +476,14 @@ namespace OpenSim.Region.PhysicsModule.ubOde } } - private bool GetCurContactGeom(int index, ref d.ContactGeom newcontactgeom) + private bool GetCurContactGeom(int index, ref SafeNativeMethods.ContactGeom newcontactgeom) { IntPtr ContactgeomsArray = m_scene.ContactgeomsArray; if (ContactgeomsArray == IntPtr.Zero || index >= CollisionContactGeomsPerTest) return false; - IntPtr contactptr = new IntPtr(ContactgeomsArray.ToInt64() + (Int64)(index * d.ContactGeom.unmanagedSizeOf)); - newcontactgeom = (d.ContactGeom)Marshal.PtrToStructure(contactptr, typeof(d.ContactGeom)); + IntPtr contactptr = new IntPtr(ContactgeomsArray.ToInt64() + (Int64)(index * SafeNativeMethods.ContactGeom.unmanagedSizeOf)); + newcontactgeom = (SafeNativeMethods.ContactGeom)Marshal.PtrToStructure(contactptr, typeof(SafeNativeMethods.ContactGeom)); return true; } @@ -498,11 +496,11 @@ namespace OpenSim.Region.PhysicsModule.ubOde if (m_contactResults.Count >= CurrentMaxCount) return; - if (d.GeomIsSpace(g2)) + if (SafeNativeMethods.GeomIsSpace(g2)) { try { - d.SpaceCollide2(g1, g2, IntPtr.Zero, nearCallback); + SafeNativeMethods.SpaceCollide2(g1, g2, IntPtr.Zero, nearCallback); } catch (Exception e) { @@ -514,7 +512,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde int count = 0; try { - count = d.CollidePtr(g1, g2, CollisionContactGeomsPerTest, m_scene.ContactgeomsArray, d.ContactGeom.unmanagedSizeOf); + count = SafeNativeMethods.CollidePtr(g1, g2, CollisionContactGeomsPerTest, m_scene.ContactgeomsArray, SafeNativeMethods.ContactGeom.unmanagedSizeOf); } catch (Exception e) { @@ -586,7 +584,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde break; } - d.ContactGeom curcontact = new d.ContactGeom(); + SafeNativeMethods.ContactGeom curcontact = new SafeNativeMethods.ContactGeom(); // closestHit for now only works for meshs, so must do it for others if ((CurrentRayFilter & RayFilterFlags.ClosestHit) == 0) @@ -654,22 +652,22 @@ namespace OpenSim.Region.PhysicsModule.ubOde m_scene = null; if (ray != IntPtr.Zero) { - d.GeomDestroy(ray); + SafeNativeMethods.GeomDestroy(ray); ray = IntPtr.Zero; } if (Box != IntPtr.Zero) { - d.GeomDestroy(Box); + SafeNativeMethods.GeomDestroy(Box); Box = IntPtr.Zero; } if (Sphere != IntPtr.Zero) { - d.GeomDestroy(Sphere); + SafeNativeMethods.GeomDestroy(Sphere); Sphere = IntPtr.Zero; } if (Plane != IntPtr.Zero) { - d.GeomDestroy(Plane); + SafeNativeMethods.GeomDestroy(Plane); Plane = IntPtr.Zero; } } diff --git a/OpenSim/Region/PhysicsModules/ubOde/ODEScene.cs b/OpenSim/Region/PhysicsModules/ubOde/ODEScene.cs index bed66ccad3..fe11505a8d 100644 --- a/OpenSim/Region/PhysicsModules/ubOde/ODEScene.cs +++ b/OpenSim/Region/PhysicsModules/ubOde/ODEScene.cs @@ -34,15 +34,10 @@ using System.Linq; using System.Reflection; using System.Runtime.InteropServices; using System.Threading; -using System.IO; -using System.Diagnostics; using log4net; using Nini.Config; -using Mono.Addins; -using OdeAPI; using OpenSim.Framework; using OpenSim.Region.Framework.Scenes; -using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.PhysicsModules.SharedBase; using OpenMetaverse; @@ -155,6 +150,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde VehicleRotationParam, VehicleFlags, SetVehicle, + SetInertia, Null //keep this last used do dim the methods array. does nothing but pulsing the prim } @@ -178,14 +174,15 @@ namespace OpenSim.Region.PhysicsModule.ubOde // const d.ContactFlags comumContactFlags = d.ContactFlags.SoftERP | d.ContactFlags.SoftCFM |d.ContactFlags.Approx1 | d.ContactFlags.Bounce; - const d.ContactFlags comumContactFlags = d.ContactFlags.Bounce | d.ContactFlags.Approx1 | d.ContactFlags.Slip1 | d.ContactFlags.Slip2; +// const d.ContactFlags comumContactFlags = d.ContactFlags.Bounce | d.ContactFlags.Approx1 | d.ContactFlags.Slip1 | d.ContactFlags.Slip2; + const SafeNativeMethods.ContactFlags comumContactFlags = SafeNativeMethods.ContactFlags.Bounce | SafeNativeMethods.ContactFlags.Approx1; const float comumContactERP = 0.75f; const float comumContactCFM = 0.0001f; const float comumContactSLIP = 0f; - float frictionMovementMult = 0.8f; +// float frictionMovementMult = 0.2f; - float TerrainBounce = 0.1f; + float TerrainBounce = 0.001f; float TerrainFriction = 0.3f; public float AvatarFriction = 0;// 0.9f * 0.5f; @@ -199,11 +196,10 @@ namespace OpenSim.Region.PhysicsModule.ubOde public float ODE_STEPSIZE = 0.020f; public float HalfOdeStep = 0.01f; public int odetimestepMS = 20; // rounded - private float metersInSpace = 25.6f; private float m_timeDilation = 1.0f; - private DateTime m_lastframe; - private DateTime m_lastMeshExpire; + private double m_lastframe; + private double m_lastMeshExpire; public float gravityx = 0f; public float gravityy = 0f; @@ -227,7 +223,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde public int bodyFramesAutoDisable = 5; - private d.NearCallback nearCallback; + private SafeNativeMethods.NearCallback nearCallback; private Dictionary _prims = new Dictionary(); private HashSet _characters = new HashSet(); @@ -250,7 +246,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde private int contactsPerCollision = 80; internal IntPtr ContactgeomsArray = IntPtr.Zero; private IntPtr GlobalContactsArray = IntPtr.Zero; - private d.Contact SharedTmpcontact = new d.Contact(); + private SafeNativeMethods.Contact SharedTmpcontact = new SafeNativeMethods.Contact(); const int maxContactsbeforedeath = 6000; private volatile int m_global_contactcount = 0; @@ -282,16 +278,6 @@ namespace OpenSim.Region.PhysicsModule.ubOde public IntPtr StaticSpace; // space for the static things around public IntPtr GroundSpace; // space for ground - // some speedup variables - private int spaceGridMaxX; - private int spaceGridMaxY; - private float spacesPerMeterX; - private float spacesPerMeterY; - - // split static geometry collision into a grid as before - private IntPtr[,] staticPrimspace; - private IntPtr[] staticPrimspaceOffRegion; - public Object OdeLock; public static Object SimulationLock; @@ -365,7 +351,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde /// private void Initialization() { - d.AllocateODEDataForThread(~0U); + SafeNativeMethods.AllocateODEDataForThread(~0U); SimulationLock = new Object(); @@ -383,14 +369,24 @@ namespace OpenSim.Region.PhysicsModule.ubOde // Create the world and the first space try { - world = d.WorldCreate(); - TopSpace = d.HashSpaceCreate(IntPtr.Zero); - - // now the major subspaces - ActiveSpace = d.HashSpaceCreate(TopSpace); - CharsSpace = d.HashSpaceCreate(TopSpace); - StaticSpace = d.HashSpaceCreate(TopSpace); - GroundSpace = d.HashSpaceCreate(TopSpace); + world = SafeNativeMethods.WorldCreate(); + TopSpace = SafeNativeMethods.SimpleSpaceCreate(IntPtr.Zero); + ActiveSpace = SafeNativeMethods.SimpleSpaceCreate(TopSpace); + CharsSpace = SafeNativeMethods.SimpleSpaceCreate(TopSpace); + GroundSpace = SafeNativeMethods.SimpleSpaceCreate(TopSpace); + float sx = WorldExtents.X + 16; + float sy = WorldExtents.Y + 16; + SafeNativeMethods.Vector3 ex =new SafeNativeMethods.Vector3(sx, sy, 0); + SafeNativeMethods.Vector3 px =new SafeNativeMethods.Vector3(sx * 0.5f, sx * 0.5f, 0); + if(sx < sy) + sx = sy; + sx = (float)Math.Log(sx) * 1.442695f + 0.5f; + int dp = (int)sx - 2; + if(dp > 8) + dp = 8; + else if(dp < 4) + dp = 4; + StaticSpace = SafeNativeMethods.QuadTreeSpaceCreate(TopSpace, ref px, ref ex, dp); } catch { @@ -398,54 +394,48 @@ namespace OpenSim.Region.PhysicsModule.ubOde // i did! } - d.HashSpaceSetLevels(TopSpace, -5, 12); - d.HashSpaceSetLevels(ActiveSpace, -5, 10); - d.HashSpaceSetLevels(CharsSpace, -4, 3); - d.HashSpaceSetLevels(StaticSpace, -5, 12); - d.HashSpaceSetLevels(GroundSpace, 0, 8); - // demote to second level - d.SpaceSetSublevel(ActiveSpace, 1); - d.SpaceSetSublevel(CharsSpace, 1); - d.SpaceSetSublevel(StaticSpace, 1); - d.SpaceSetSublevel(GroundSpace, 1); + SafeNativeMethods.SpaceSetSublevel(ActiveSpace, 1); + SafeNativeMethods.SpaceSetSublevel(CharsSpace, 1); + SafeNativeMethods.SpaceSetSublevel(StaticSpace, 1); + SafeNativeMethods.SpaceSetSublevel(GroundSpace, 1); - d.GeomSetCategoryBits(ActiveSpace, (uint)(CollisionCategories.Space | + SafeNativeMethods.GeomSetCategoryBits(ActiveSpace, (uint)(CollisionCategories.Space | CollisionCategories.Geom | CollisionCategories.Character | CollisionCategories.Phantom | CollisionCategories.VolumeDtc )); - d.GeomSetCollideBits(ActiveSpace, (uint)(CollisionCategories.Space | + SafeNativeMethods.GeomSetCollideBits(ActiveSpace, (uint)(CollisionCategories.Space | CollisionCategories.Geom | CollisionCategories.Character | CollisionCategories.Phantom | CollisionCategories.VolumeDtc )); - d.GeomSetCategoryBits(CharsSpace, (uint)(CollisionCategories.Space | + SafeNativeMethods.GeomSetCategoryBits(CharsSpace, (uint)(CollisionCategories.Space | CollisionCategories.Geom | CollisionCategories.Character | CollisionCategories.Phantom | CollisionCategories.VolumeDtc )); - d.GeomSetCollideBits(CharsSpace, 0); + SafeNativeMethods.GeomSetCollideBits(CharsSpace, 0); - d.GeomSetCategoryBits(StaticSpace, (uint)(CollisionCategories.Space | + SafeNativeMethods.GeomSetCategoryBits(StaticSpace, (uint)(CollisionCategories.Space | CollisionCategories.Geom | // CollisionCategories.Land | // CollisionCategories.Water | CollisionCategories.Phantom | CollisionCategories.VolumeDtc )); - d.GeomSetCollideBits(StaticSpace, 0); + SafeNativeMethods.GeomSetCollideBits(StaticSpace, 0); - d.GeomSetCategoryBits(GroundSpace, (uint)(CollisionCategories.Land)); - d.GeomSetCollideBits(GroundSpace, 0); + SafeNativeMethods.GeomSetCategoryBits(GroundSpace, (uint)(CollisionCategories.Land)); + SafeNativeMethods.GeomSetCollideBits(GroundSpace, 0); - contactgroup = d.JointGroupCreate(maxContactsbeforedeath + 1); + contactgroup = SafeNativeMethods.JointGroupCreate(maxContactsbeforedeath + 1); //contactgroup - d.WorldSetAutoDisableFlag(world, false); + SafeNativeMethods.WorldSetAutoDisableFlag(world, false); } @@ -467,8 +457,6 @@ namespace OpenSim.Region.PhysicsModule.ubOde gravityy = physicsconfig.GetFloat("world_gravityy", gravityy); gravityz = physicsconfig.GetFloat("world_gravityz", gravityz); - metersInSpace = physicsconfig.GetFloat("meters_in_small_space", metersInSpace); - // contactsurfacelayer = physicsconfig.GetFloat("world_contact_surface_layer", contactsurfacelayer); ODE_STEPSIZE = physicsconfig.GetFloat("world_stepsize", ODE_STEPSIZE); @@ -480,7 +468,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde contactsPerCollision = physicsconfig.GetInt("contacts_per_collision", contactsPerCollision); geomDefaultDensity = physicsconfig.GetFloat("geometry_default_density", geomDefaultDensity); - bodyFramesAutoDisable = physicsconfig.GetInt("body_frames_auto_disable", bodyFramesAutoDisable); +// bodyFramesAutoDisable = physicsconfig.GetInt("body_frames_auto_disable", bodyFramesAutoDisable); physics_logging = physicsconfig.GetBoolean("physics_logging", false); physics_logging_interval = physicsconfig.GetInt("physics_logging_interval", 0); @@ -497,27 +485,27 @@ namespace OpenSim.Region.PhysicsModule.ubOde maximumAngularVelocity = 0.49f * heartbeat *(float)Math.PI; maxAngVelocitySQ = maximumAngularVelocity * maximumAngularVelocity; - d.WorldSetCFM(world, comumContactCFM); - d.WorldSetERP(world, comumContactERP); + SafeNativeMethods.WorldSetCFM(world, comumContactCFM); + SafeNativeMethods.WorldSetERP(world, comumContactERP); - d.WorldSetGravity(world, gravityx, gravityy, gravityz); + SafeNativeMethods.WorldSetGravity(world, gravityx, gravityy, gravityz); - d.WorldSetLinearDamping(world, 0.002f); - d.WorldSetAngularDamping(world, 0.002f); - d.WorldSetAngularDampingThreshold(world, 0f); - d.WorldSetLinearDampingThreshold(world, 0f); - d.WorldSetMaxAngularSpeed(world, maximumAngularVelocity); + SafeNativeMethods.WorldSetLinearDamping(world, 0.001f); + SafeNativeMethods.WorldSetAngularDamping(world, 0.002f); + SafeNativeMethods.WorldSetAngularDampingThreshold(world, 0f); + SafeNativeMethods.WorldSetLinearDampingThreshold(world, 0f); + SafeNativeMethods.WorldSetMaxAngularSpeed(world, maximumAngularVelocity); - d.WorldSetQuickStepNumIterations(world, m_physicsiterations); + SafeNativeMethods.WorldSetQuickStepNumIterations(world, m_physicsiterations); - d.WorldSetContactSurfaceLayer(world, contactsurfacelayer); - d.WorldSetContactMaxCorrectingVel(world, 60.0f); + SafeNativeMethods.WorldSetContactSurfaceLayer(world, contactsurfacelayer); + SafeNativeMethods.WorldSetContactMaxCorrectingVel(world, 60.0f); HalfOdeStep = ODE_STEPSIZE * 0.5f; odetimestepMS = (int)(1000.0f * ODE_STEPSIZE + 0.5f); - ContactgeomsArray = Marshal.AllocHGlobal(contactsPerCollision * d.ContactGeom.unmanagedSizeOf); - GlobalContactsArray = Marshal.AllocHGlobal((maxContactsbeforedeath + 100) * d.Contact.unmanagedSizeOf); + ContactgeomsArray = Marshal.AllocHGlobal(contactsPerCollision * SafeNativeMethods.ContactGeom.unmanagedSizeOf); + GlobalContactsArray = Marshal.AllocHGlobal((maxContactsbeforedeath + 100) * SafeNativeMethods.Contact.unmanagedSizeOf); SharedTmpcontact.geom.g1 = IntPtr.Zero; SharedTmpcontact.geom.g2 = IntPtr.Zero; @@ -528,6 +516,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde SharedTmpcontact.surface.mode = comumContactFlags; SharedTmpcontact.surface.mu = 0; SharedTmpcontact.surface.bounce = 0; + SharedTmpcontact.surface.bounce_vel = 1.5f; SharedTmpcontact.surface.soft_cfm = comumContactCFM; SharedTmpcontact.surface.soft_erp = comumContactERP; SharedTmpcontact.surface.slip1 = comumContactSLIP; @@ -557,78 +546,9 @@ namespace OpenSim.Region.PhysicsModule.ubOde m_materialContactsData[(int)Material.light].mu = 0.0f; m_materialContactsData[(int)Material.light].bounce = 0.0f; - - spacesPerMeterX = 1.0f / metersInSpace; - spacesPerMeterY = spacesPerMeterX; - spaceGridMaxX = (int)(WorldExtents.X * spacesPerMeterX); - spaceGridMaxY = (int)(WorldExtents.Y * spacesPerMeterY); - - if (spaceGridMaxX > 24) - { - spaceGridMaxX = 24; - spacesPerMeterX = spaceGridMaxX / WorldExtents.X; - } - - if (spaceGridMaxY > 24) - { - spaceGridMaxY = 24; - spacesPerMeterY = spaceGridMaxY / WorldExtents.Y; - } - - staticPrimspace = new IntPtr[spaceGridMaxX, spaceGridMaxY]; - - // create all spaces now - int i, j; - IntPtr newspace; - - for (i = 0; i < spaceGridMaxX; i++) - for (j = 0; j < spaceGridMaxY; j++) - { - newspace = d.HashSpaceCreate(StaticSpace); - d.GeomSetCategoryBits(newspace, (int)CollisionCategories.Space); - waitForSpaceUnlock(newspace); - d.SpaceSetSublevel(newspace, 2); - d.HashSpaceSetLevels(newspace, -2, 8); - d.GeomSetCategoryBits(newspace, (uint)(CollisionCategories.Space | - CollisionCategories.Geom | - CollisionCategories.Land | - CollisionCategories.Water | - CollisionCategories.Phantom | - CollisionCategories.VolumeDtc - )); - d.GeomSetCollideBits(newspace, 0); - - staticPrimspace[i, j] = newspace; - } - - // let this now be index limit - spaceGridMaxX--; - spaceGridMaxY--; - - // create 4 off world spaces (x<0,x>max,y<0,y>max) - staticPrimspaceOffRegion = new IntPtr[4]; - - for (i = 0; i < 4; i++) - { - newspace = d.HashSpaceCreate(StaticSpace); - d.GeomSetCategoryBits(newspace, (int)CollisionCategories.Space); - waitForSpaceUnlock(newspace); - d.SpaceSetSublevel(newspace, 2); - d.HashSpaceSetLevels(newspace, -2, 8); - d.GeomSetCategoryBits(newspace, (uint)(CollisionCategories.Space | - CollisionCategories.Geom | - CollisionCategories.Land | - CollisionCategories.Water | - CollisionCategories.Phantom | - CollisionCategories.VolumeDtc - )); - d.GeomSetCollideBits(newspace, 0); - - staticPrimspaceOffRegion[i] = newspace; - } - - m_lastframe = DateTime.UtcNow; + m_lastframe = Util.GetTimeStamp(); m_lastMeshExpire = m_lastframe; + step_time = -1; } internal void waitForSpaceUnlock(IntPtr space) @@ -640,7 +560,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde #region Collision Detection // sets a global contact for a joint for contactgeom , and base contact description) - private IntPtr CreateContacJoint(ref d.ContactGeom contactGeom,bool smooth) + private IntPtr CreateContacJoint(ref SafeNativeMethods.ContactGeom contactGeom,bool smooth) { if (m_global_contactcount >= maxContactsbeforedeath) return IntPtr.Zero; @@ -653,18 +573,18 @@ namespace OpenSim.Region.PhysicsModule.ubOde SharedTmpcontact.geom.pos = contactGeom.pos; SharedTmpcontact.geom.normal = contactGeom.normal; - IntPtr contact = new IntPtr(GlobalContactsArray.ToInt64() + (Int64)(m_global_contactcount * d.Contact.unmanagedSizeOf)); + IntPtr contact = new IntPtr(GlobalContactsArray.ToInt64() + (Int64)(m_global_contactcount * SafeNativeMethods.Contact.unmanagedSizeOf)); Marshal.StructureToPtr(SharedTmpcontact, contact, true); - return d.JointCreateContactPtr(world, contactgroup, contact); + return SafeNativeMethods.JointCreateContactPtr(world, contactgroup, contact); } - private bool GetCurContactGeom(int index, ref d.ContactGeom newcontactgeom) + private bool GetCurContactGeom(int index, ref SafeNativeMethods.ContactGeom newcontactgeom) { if (ContactgeomsArray == IntPtr.Zero || index >= contactsPerCollision) return false; - IntPtr contactptr = new IntPtr(ContactgeomsArray.ToInt64() + (Int64)(index * d.ContactGeom.unmanagedSizeOf)); - newcontactgeom = (d.ContactGeom)Marshal.PtrToStructure(contactptr, typeof(d.ContactGeom)); + IntPtr contactptr = new IntPtr(ContactgeomsArray.ToInt64() + (Int64)(index * SafeNativeMethods.ContactGeom.unmanagedSizeOf)); + newcontactgeom = (SafeNativeMethods.ContactGeom)Marshal.PtrToStructure(contactptr, typeof(SafeNativeMethods.ContactGeom)); return true; } @@ -689,14 +609,14 @@ namespace OpenSim.Region.PhysicsModule.ubOde if (g1 == IntPtr.Zero || g2 == IntPtr.Zero) return; - if (d.GeomIsSpace(g1) || d.GeomIsSpace(g2)) + if (SafeNativeMethods.GeomIsSpace(g1) || SafeNativeMethods.GeomIsSpace(g2)) { // We'll be calling near recursivly if one // of them is a space to find all of the // contact points in the space try { - d.SpaceCollide2(g1, g2, IntPtr.Zero, nearCallback); + SafeNativeMethods.SpaceCollide2(g1, g2, IntPtr.Zero, nearCallback); } catch (AccessViolationException) { @@ -711,8 +631,8 @@ namespace OpenSim.Region.PhysicsModule.ubOde // get geom bodies to check if we already a joint contact // guess this shouldn't happen now - IntPtr b1 = d.GeomGetBody(g1); - IntPtr b2 = d.GeomGetBody(g2); + IntPtr b1 = SafeNativeMethods.GeomGetBody(g1); + IntPtr b2 = SafeNativeMethods.GeomGetBody(g2); // d.GeomClassID id = d.GeomGetClass(g1); @@ -726,8 +646,8 @@ namespace OpenSim.Region.PhysicsModule.ubOde if (g1 == g2) return; // Can't collide with yourself - if (b1 != IntPtr.Zero && b2 != IntPtr.Zero && d.AreConnectedExcluding(b1, b2, d.JointType.Contact)) - return; +// if (b1 != IntPtr.Zero && b2 != IntPtr.Zero && d.AreConnectedExcluding(b1, b2, d.JointType.Contact)) +// return; /* // debug PhysicsActor dp2; @@ -754,19 +674,18 @@ namespace OpenSim.Region.PhysicsModule.ubOde // */ - - if (d.GeomGetCategoryBits(g1) == (uint)CollisionCategories.VolumeDtc || - d.GeomGetCategoryBits(g2) == (uint)CollisionCategories.VolumeDtc) + if (SafeNativeMethods.GeomGetCategoryBits(g1) == (uint)CollisionCategories.VolumeDtc || + SafeNativeMethods.GeomGetCategoryBits(g2) == (uint)CollisionCategories.VolumeDtc) { int cflags; unchecked { - cflags = (int)(1 | d.CONTACTS_UNIMPORTANT); + cflags = (int)(1 | SafeNativeMethods.CONTACTS_UNIMPORTANT); } - count = d.CollidePtr(g1, g2, cflags, ContactgeomsArray, d.ContactGeom.unmanagedSizeOf); + count = SafeNativeMethods.CollidePtr(g1, g2, cflags, ContactgeomsArray, SafeNativeMethods.ContactGeom.unmanagedSizeOf); } else - count = d.CollidePtr(g1, g2, (contactsPerCollision & 0xffff), ContactgeomsArray, d.ContactGeom.unmanagedSizeOf); + count = SafeNativeMethods.CollidePtr(g1, g2, (contactsPerCollision & 0xffff), ContactgeomsArray, SafeNativeMethods.ContactGeom.unmanagedSizeOf); } catch (SEHException) { @@ -802,7 +721,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde // get first contact - d.ContactGeom curContact = new d.ContactGeom(); + SafeNativeMethods.ContactGeom curContact = new SafeNativeMethods.ContactGeom(); if (!GetCurContactGeom(0, ref curContact)) return; @@ -863,9 +782,9 @@ namespace OpenSim.Region.PhysicsModule.ubOde break; case (int)ActorTypes.Prim: - Vector3 relV = p1.rootVelocity - p2.rootVelocity; - float relVlenSQ = relV.LengthSquared(); - if (relVlenSQ > 0.0001f) +// Vector3 relV = p1.rootVelocity - p2.rootVelocity; +// float relVlenSQ = relV.LengthSquared(); +// if (relVlenSQ > 0.0001f) { p1.CollidingObj = true; p2.CollidingObj = true; @@ -875,11 +794,11 @@ namespace OpenSim.Region.PhysicsModule.ubOde bounce = contactdata1.bounce * contactdata2.bounce; mu = (float)Math.Sqrt(contactdata1.mu * contactdata2.mu); - if (relVlenSQ > 0.01f) - mu *= frictionMovementMult; +// if (relVlenSQ > 0.01f) +// mu *= frictionMovementMult; - if(d.GeomGetClass(g2) == d.GeomClassID.TriMeshClass && - d.GeomGetClass(g1) == d.GeomClassID.TriMeshClass) + if(SafeNativeMethods.GeomGetClass(g2) == SafeNativeMethods.GeomClassID.TriMeshClass && + SafeNativeMethods.GeomGetClass(g1) == SafeNativeMethods.GeomClassID.TriMeshClass) smoothMesh = true; break; @@ -888,12 +807,12 @@ namespace OpenSim.Region.PhysicsModule.ubOde bounce = contactdata1.bounce * TerrainBounce; mu = (float)Math.Sqrt(contactdata1.mu * TerrainFriction); - Vector3 v1 = p1.rootVelocity; - if (Math.Abs(v1.X) > 0.1f || Math.Abs(v1.Y) > 0.1f) - mu *= frictionMovementMult; +// Vector3 v1 = p1.rootVelocity; +// if (Math.Abs(v1.X) > 0.1f || Math.Abs(v1.Y) > 0.1f) +// mu *= frictionMovementMult; p1.CollidingGround = true; - if(d.GeomGetClass(g1) == d.GeomClassID.TriMeshClass) + if(SafeNativeMethods.GeomGetClass(g1) == SafeNativeMethods.GeomClassID.TriMeshClass) smoothMesh = true; break; @@ -915,11 +834,11 @@ namespace OpenSim.Region.PhysicsModule.ubOde // if (curContact.side1 > 0) // should be 2 ? // IgnoreNegSides = true; - Vector3 v2 = p2.rootVelocity; - if (Math.Abs(v2.X) > 0.1f || Math.Abs(v2.Y) > 0.1f) - mu *= frictionMovementMult; +// Vector3 v2 = p2.rootVelocity; +// if (Math.Abs(v2.X) > 0.1f || Math.Abs(v2.Y) > 0.1f) +// mu *= frictionMovementMult; - if(d.GeomGetClass(g2) == d.GeomClassID.TriMeshClass) + if(SafeNativeMethods.GeomGetClass(g2) == SafeNativeMethods.GeomClassID.TriMeshClass) smoothMesh = true; } else @@ -949,9 +868,9 @@ namespace OpenSim.Region.PhysicsModule.ubOde SharedTmpcontact.surface.mu = mu; SharedTmpcontact.surface.bounce = bounce; - d.ContactGeom altContact = new d.ContactGeom(); - bool useAltcontact = false; - bool noskip = true; + SafeNativeMethods.ContactGeom altContact = new SafeNativeMethods.ContactGeom(); + bool useAltcontact; + bool noskip; if(dop1ava || dop2ava) smoothMesh = false; @@ -998,11 +917,10 @@ namespace OpenSim.Region.PhysicsModule.ubOde Joint = CreateContacJoint(ref altContact,smoothMesh); else Joint = CreateContacJoint(ref curContact,smoothMesh); - if (Joint == IntPtr.Zero) break; - d.JointAttach(Joint, b1, b2); + SafeNativeMethods.JointAttach(Joint, b1, b2); ncontacts++; @@ -1082,9 +1000,12 @@ namespace OpenSim.Region.PhysicsModule.ubOde case ActorTypes.Prim: if (p2events) { - AddCollisionEventReporting(p2); + //AddCollisionEventReporting(p2); p2.AddCollisionEvent(p1.ParentActor.LocalID, contact); } + else if(p1.IsVolumeDtc) + p2.AddVDTCCollisionEvent(p1.ParentActor.LocalID, contact); + obj2LocalID = p2.ParentActor.LocalID; break; @@ -1098,9 +1019,16 @@ namespace OpenSim.Region.PhysicsModule.ubOde { contact.SurfaceNormal = -contact.SurfaceNormal; contact.RelativeSpeed = -contact.RelativeSpeed; - AddCollisionEventReporting(p1); + //AddCollisionEventReporting(p1); p1.AddCollisionEvent(obj2LocalID, contact); } + else if(p2.IsVolumeDtc) + { + contact.SurfaceNormal = -contact.SurfaceNormal; + contact.RelativeSpeed = -contact.RelativeSpeed; + //AddCollisionEventReporting(p1); + p1.AddVDTCCollisionEvent(obj2LocalID, contact); + } break; } case ActorTypes.Ground: @@ -1109,7 +1037,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde { if (p2events && !p2.IsVolumeDtc) { - AddCollisionEventReporting(p2); + //AddCollisionEventReporting(p2); p2.AddCollisionEvent(0, contact); } break; @@ -1140,12 +1068,12 @@ namespace OpenSim.Region.PhysicsModule.ubOde continue; // do colisions with static space - d.SpaceCollide2(chr.collider, StaticSpace, IntPtr.Zero, nearCallback); + SafeNativeMethods.SpaceCollide2(chr.collider, StaticSpace, IntPtr.Zero, nearCallback); // no coll with gnd } // chars with chars - d.SpaceCollide(CharsSpace, IntPtr.Zero, nearCallback); + SafeNativeMethods.SpaceCollide(CharsSpace, IntPtr.Zero, nearCallback); } catch (AccessViolationException) @@ -1161,19 +1089,22 @@ namespace OpenSim.Region.PhysicsModule.ubOde { aprim.CollisionScore = 0; aprim.IsColliding = false; + if(!aprim.m_outbounds && SafeNativeMethods.BodyIsEnabled(aprim.Body)) + aprim.clearSleeperCollisions(); } } + lock (_activegroups) { try { foreach (OdePrim aprim in _activegroups) { - if(!aprim.m_outbounds && d.BodyIsEnabled(aprim.Body) && + if(!aprim.m_outbounds && SafeNativeMethods.BodyIsEnabled(aprim.Body) && aprim.collide_geom != IntPtr.Zero) { - d.SpaceCollide2(StaticSpace, aprim.collide_geom, IntPtr.Zero, nearCallback); - d.SpaceCollide2(GroundSpace, aprim.collide_geom, IntPtr.Zero, nearCallback); + SafeNativeMethods.SpaceCollide2(StaticSpace, aprim.collide_geom, IntPtr.Zero, nearCallback); + SafeNativeMethods.SpaceCollide2(GroundSpace, aprim.collide_geom, IntPtr.Zero, nearCallback); } } } @@ -1186,7 +1117,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde // colide active amoung them try { - d.SpaceCollide(ActiveSpace, IntPtr.Zero, nearCallback); + SafeNativeMethods.SpaceCollide(ActiveSpace, IntPtr.Zero, nearCallback); } catch (Exception e) { @@ -1196,7 +1127,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde // and with chars try { - d.SpaceCollide2(CharsSpace,ActiveSpace, IntPtr.Zero, nearCallback); + SafeNativeMethods.SpaceCollide2(CharsSpace,ActiveSpace, IntPtr.Zero, nearCallback); } catch (Exception e) { @@ -1291,9 +1222,12 @@ namespace OpenSim.Region.PhysicsModule.ubOde public override void RemoveAvatar(PhysicsActor actor) { //m_log.Debug("[PHYSICS]:ODELOCK"); + if (world == IntPtr.Zero) + return; + lock (OdeLock) { - d.AllocateODEDataForThread(0); + SafeNativeMethods.AllocateODEDataForThread(0); ((OdeCharacter) actor).Destroy(); } } @@ -1445,39 +1379,35 @@ namespace OpenSim.Region.PhysicsModule.ubOde /// /// Called when a static prim moves or becomes static - /// Places the prim in a space one the static sub-spaces grid + /// Places the prim in a space one the static space /// /// the pointer to the geom that moved - /// the position that the geom moved to /// a pointer to the space it was in before it was moved. /// a pointer to the new space it's in - public IntPtr MoveGeomToStaticSpace(IntPtr geom, Vector3 pos, IntPtr currentspace) + public IntPtr MoveGeomToStaticSpace(IntPtr geom, IntPtr currentspace) { - // moves a prim into another static sub-space or from another space into a static sub-space + // moves a prim into static sub-space // Called ODEPrim so // it's already in locked space. if (geom == IntPtr.Zero) // shouldn't happen return IntPtr.Zero; - - // get the static sub-space for current position - IntPtr newspace = calculateSpaceForGeom(pos); - - if (newspace == currentspace) // if we are there all done - return newspace; + + if (StaticSpace == currentspace) // if we are there all done + return StaticSpace; // else remove it from its current space - if (currentspace != IntPtr.Zero && d.SpaceQuery(currentspace, geom)) + if (currentspace != IntPtr.Zero && SafeNativeMethods.SpaceQuery(currentspace, geom)) { - if (d.GeomIsSpace(currentspace)) + if (SafeNativeMethods.GeomIsSpace(currentspace)) { waitForSpaceUnlock(currentspace); - d.SpaceRemove(currentspace, geom); + SafeNativeMethods.SpaceRemove(currentspace, geom); - if (d.SpaceGetSublevel(currentspace) > 2 && d.SpaceGetNumGeoms(currentspace) == 0) + if (SafeNativeMethods.SpaceGetSublevel(currentspace) > 2 && SafeNativeMethods.SpaceGetNumGeoms(currentspace) == 0) { - d.SpaceDestroy(currentspace); + SafeNativeMethods.SpaceDestroy(currentspace); } } else @@ -1486,59 +1416,33 @@ namespace OpenSim.Region.PhysicsModule.ubOde " Geom:" + geom); } } - else // odd currentspace is null or doesn't contain the geom? lets try the geom ideia of current space + else { - currentspace = d.GeomGetSpace(geom); + currentspace = SafeNativeMethods.GeomGetSpace(geom); if (currentspace != IntPtr.Zero) { - if (d.GeomIsSpace(currentspace)) + if (SafeNativeMethods.GeomIsSpace(currentspace)) { waitForSpaceUnlock(currentspace); - d.SpaceRemove(currentspace, geom); + SafeNativeMethods.SpaceRemove(currentspace, geom); - if (d.SpaceGetSublevel(currentspace) > 2 && d.SpaceGetNumGeoms(currentspace) == 0) + if (SafeNativeMethods.SpaceGetSublevel(currentspace) > 2 && SafeNativeMethods.SpaceGetNumGeoms(currentspace) == 0) { - d.SpaceDestroy(currentspace); + SafeNativeMethods.SpaceDestroy(currentspace); } - } } } // put the geom in the newspace - waitForSpaceUnlock(newspace); - d.SpaceAdd(newspace, geom); + waitForSpaceUnlock(StaticSpace); + if(SafeNativeMethods.SpaceQuery(StaticSpace, geom)) + m_log.Info("[Physics]: 'MoveGeomToStaticSpace' geom already in static space:" + geom); + else + SafeNativeMethods.SpaceAdd(StaticSpace, geom); - // let caller know this newspace - return newspace; + return StaticSpace; } - - /// - /// Calculates the space the prim should be in by its position - /// - /// - /// a pointer to the space. This could be a new space or reused space. - public IntPtr calculateSpaceForGeom(Vector3 pos) - { - int x, y; - - if (pos.X < 0) - return staticPrimspaceOffRegion[0]; - - if (pos.Y < 0) - return staticPrimspaceOffRegion[2]; - - x = (int)(pos.X * spacesPerMeterX); - if (x > spaceGridMaxX) - return staticPrimspaceOffRegion[1]; - - y = (int)(pos.Y * spacesPerMeterY); - if (y > spaceGridMaxY) - return staticPrimspaceOffRegion[3]; - - return staticPrimspace[x, y]; - } - #endregion @@ -1577,7 +1481,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde return; } - d.AllocateODEDataForThread(~0U); + SafeNativeMethods.AllocateODEDataForThread(~0U); ODEchangeitem item; @@ -1611,6 +1515,8 @@ namespace OpenSim.Region.PhysicsModule.ubOde } m_log.InfoFormat("[ubOde] {0} prim actors loaded",_prims.Count); } + m_lastframe = Util.GetTimeStamp() + 0.5; + step_time = -0.5f; } /// @@ -1624,13 +1530,15 @@ namespace OpenSim.Region.PhysicsModule.ubOde /// public override float Simulate(float reqTimeStep) { - DateTime now = DateTime.UtcNow; - TimeSpan timedif = now - m_lastframe; - float timeStep = (float)timedif.TotalSeconds; + if (world == IntPtr.Zero) + return 0; + + double now = Util.GetTimeStamp(); + double timeStep = now - m_lastframe; m_lastframe = now; // acumulate time so we can reduce error - step_time += timeStep; + step_time += (float)timeStep; if (step_time < HalfOdeStep) return 0; @@ -1657,13 +1565,23 @@ namespace OpenSim.Region.PhysicsModule.ubOde // d.WorldSetQuickStepNumIterations(world, curphysiteractions); - int loopstartMS = Util.EnvironmentTickCount(); - int looptimeMS = 0; - int changestimeMS = 0; - int maxChangestime = (int)(reqTimeStep * 500f); // half the time - int maxLoopTime = (int)(reqTimeStep * 1200f); // 1.2 the time + double loopstartMS = Util.GetTimeStampMS(); + double looptimeMS = 0; + double changestimeMS = 0; + double maxChangestime = (int)(reqTimeStep * 500f); // half the time + double maxLoopTime = (int)(reqTimeStep * 1200f); // 1.2 the time - d.AllocateODEDataForThread(~0U); +/* + double collisionTime = 0; + double qstepTIme = 0; + double tmpTime = 0; + double changestot = 0; + double collisonRepo = 0; + double updatesTime = 0; + double moveTime = 0; + double rayTime = 0; +*/ + SafeNativeMethods.AllocateODEDataForThread(~0U); if (ChangesQueue.Count > 0) { @@ -1684,7 +1602,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde item.actor.Name, item.what.ToString()); } } - changestimeMS = Util.EnvironmentTickCountSubtract(loopstartMS); + changestimeMS = Util.GetTimeStampMS() - loopstartMS; if (changestimeMS > maxChangestime) break; } @@ -1699,6 +1617,8 @@ namespace OpenSim.Region.PhysicsModule.ubOde m_global_contactcount = 0; +// tmpTime = Util.GetTimeStampMS(); + // Move characters lock (_characters) { @@ -1726,12 +1646,26 @@ namespace OpenSim.Region.PhysicsModule.ubOde aprim.Move(); } } +// moveTime += Util.GetTimeStampMS() - tmpTime; +// tmpTime = Util.GetTimeStampMS(); m_rayCastManager.ProcessQueuedRequests(); +// rayTime += Util.GetTimeStampMS() - tmpTime; +// tmpTime = Util.GetTimeStampMS(); collision_optimized(); - List sleepers = new List(); +// collisionTime += Util.GetTimeStampMS() - tmpTime; +// tmpTime = Util.GetTimeStampMS(); + lock(_collisionEventPrimRemove) + { + foreach (PhysicsActor obj in _collisionEventPrimRemove) + _collisionEventPrim.Remove(obj); + + _collisionEventPrimRemove.Clear(); + } + + List sleepers = new List(); foreach (PhysicsActor obj in _collisionEventPrim) { if (obj == null) @@ -1751,7 +1685,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde pobj.SendCollisions((int)(odetimestepMS)); if(pobj.Body != IntPtr.Zero && !pobj.m_isSelected && !pobj.m_disabled && !pobj.m_building && - !d.BodyIsEnabled(pobj.Body)) + !SafeNativeMethods.BodyIsEnabled(pobj.Body)) sleepers.Add(pobj); } break; @@ -1761,18 +1695,14 @@ namespace OpenSim.Region.PhysicsModule.ubOde foreach(OdePrim prm in sleepers) prm.SleeperAddCollisionEvents(); sleepers.Clear(); +// collisonRepo += Util.GetTimeStampMS() - tmpTime; - lock(_collisionEventPrimRemove) - { - foreach (PhysicsActor obj in _collisionEventPrimRemove) - _collisionEventPrim.Remove(obj); - - _collisionEventPrimRemove.Clear(); - } - + // do a ode simulation step - d.WorldQuickStep(world, ODE_STEPSIZE); - d.JointGroupEmpty(contactgroup); +// tmpTime = Util.GetTimeStampMS(); + SafeNativeMethods.WorldQuickStep(world, ODE_STEPSIZE); + SafeNativeMethods.JointGroupEmpty(contactgroup); +// qstepTIme += Util.GetTimeStampMS() - tmpTime; // update managed ideia of physical data and do updates to core /* @@ -1790,7 +1720,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde } } */ - +// tmpTime = Util.GetTimeStampMS(); lock (_activegroups) { { @@ -1803,6 +1733,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde } } } +// updatesTime += Util.GetTimeStampMS() - tmpTime; } catch (Exception e) { @@ -1810,10 +1741,12 @@ namespace OpenSim.Region.PhysicsModule.ubOde // ode.dunlock(world); } + step_time -= ODE_STEPSIZE; nodeframes++; - looptimeMS = Util.EnvironmentTickCountSubtract(loopstartMS); + looptimeMS = Util.GetTimeStampMS() - loopstartMS; + if (looptimeMS > maxLoopTime) break; } @@ -1830,17 +1763,9 @@ namespace OpenSim.Region.PhysicsModule.ubOde _badCharacter.Clear(); } } - - timedif = now - m_lastMeshExpire; - - if (timedif.Seconds > 10) - { - mesher.ExpireReleaseMeshs(); - m_lastMeshExpire = now; - } - -// information block for in debug breakpoint only /* +// information block for in debug breakpoint only + int ntopactivegeoms = d.SpaceGetNumGeoms(ActiveSpace); int ntopstaticgeoms = d.SpaceGetNumGeoms(StaticSpace); int ngroundgeoms = d.SpaceGetNumGeoms(GroundSpace); @@ -1882,25 +1807,23 @@ namespace OpenSim.Region.PhysicsModule.ubOde int nbodies = d.NTotalBodies; int ngeoms = d.NTotalGeoms; */ - // Finished with all sim stepping. If requested, dump world state to file for debugging. - // TODO: This call to the export function is already inside lock (OdeLock) - but is an extra lock needed? - // TODO: This overwrites all dump files in-place. Should this be a growing logfile, or separate snapshots? - if (physics_logging && (physics_logging_interval > 0) && (framecount % physics_logging_interval == 0)) + +/* + looptimeMS /= nodeframes; + collisionTime /= nodeframes; + qstepTIme /= nodeframes; + changestot /= nodeframes; + collisonRepo /= nodeframes; + updatesTime /= nodeframes; + moveTime /= nodeframes; + rayTime /= nodeframes; + + if(looptimeMS > .05) { - string fname = "state-" + world.ToString() + ".DIF"; // give each physics world a separate filename - string prefix = "world" + world.ToString(); // prefix for variable names in exported .DIF file - if (physics_logging_append_existing_logfile) - { - string header = "-------------- START OF PHYSICS FRAME " + framecount.ToString() + " --------------"; - TextWriter fwriter = File.AppendText(fname); - fwriter.WriteLine(header); - fwriter.Close(); - } - d.WorldExportDIF(world, fname, physics_logging_append_existing_logfile, prefix); } - +*/ fps = (float)nodeframes * ODE_STEPSIZE / reqTimeStep; if(step_time < HalfOdeStep) @@ -1910,7 +1833,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde // if we lag too much skip frames m_timeDilation = 0.0f; step_time = 0; - m_lastframe = DateTime.UtcNow; // skip also the time lost + m_lastframe = Util.GetTimeStamp(); // skip also the time lost } else { @@ -1918,6 +1841,14 @@ namespace OpenSim.Region.PhysicsModule.ubOde if (m_timeDilation > 1) m_timeDilation = 1; } + + if (m_timeDilation == 1 && now - m_lastMeshExpire > 30) + { + mesher.ExpireReleaseMeshs(); + m_lastMeshExpire = now; + } + + } return fps; @@ -2239,8 +2170,8 @@ namespace OpenSim.Region.PhysicsModule.ubOde yy += regionsizeX; val = heightMap[yy + xx]; - if (val < 0.0f) - val = 0.0f; // no neg terrain as in chode + if (val < -100.0f) + val = -100.0f; _heightmap[xt + y] = val; if (hfmin > val) @@ -2253,35 +2184,35 @@ namespace OpenSim.Region.PhysicsModule.ubOde lock (OdeLock) { - d.AllocateODEDataForThread(~0U); + SafeNativeMethods.AllocateODEDataForThread(~0U); if (TerrainGeom != IntPtr.Zero) { actor_name_map.Remove(TerrainGeom); - d.GeomDestroy(TerrainGeom); + SafeNativeMethods.GeomDestroy(TerrainGeom); } if (TerrainHeightFieldHeightsHandler.IsAllocated) TerrainHeightFieldHeightsHandler.Free(); - IntPtr HeightmapData = d.GeomHeightfieldDataCreate(); + IntPtr HeightmapData = SafeNativeMethods.GeomHeightfieldDataCreate(); TerrainHeightFieldHeightsHandler = GCHandle.Alloc(_heightmap, GCHandleType.Pinned); - d.GeomHeightfieldDataBuildSingle(HeightmapData, TerrainHeightFieldHeightsHandler.AddrOfPinnedObject(), 0, + SafeNativeMethods.GeomHeightfieldDataBuildSingle(HeightmapData, TerrainHeightFieldHeightsHandler.AddrOfPinnedObject(), 0, heightmapHeight, heightmapWidth , (int)heightmapHeightSamples, (int)heightmapWidthSamples, scale, offset, thickness, wrap); - d.GeomHeightfieldDataSetBounds(HeightmapData, hfmin - 1, hfmax + 1); + SafeNativeMethods.GeomHeightfieldDataSetBounds(HeightmapData, hfmin - 1, hfmax + 1); - TerrainGeom = d.CreateHeightfield(GroundSpace, HeightmapData, 1); + TerrainGeom = SafeNativeMethods.CreateHeightfield(GroundSpace, HeightmapData, 1); if (TerrainGeom != IntPtr.Zero) { - d.GeomSetCategoryBits(TerrainGeom, (uint)(CollisionCategories.Land)); - d.GeomSetCollideBits(TerrainGeom, 0); + SafeNativeMethods.GeomSetCategoryBits(TerrainGeom, (uint)(CollisionCategories.Land)); + SafeNativeMethods.GeomSetCollideBits(TerrainGeom, 0); PhysicsActor pa = new NullPhysicsActor(); pa.Name = "Terrain"; @@ -2290,14 +2221,14 @@ namespace OpenSim.Region.PhysicsModule.ubOde // geom_name_map[GroundGeom] = "Terrain"; - d.Quaternion q = new d.Quaternion(); + SafeNativeMethods.Quaternion q = new SafeNativeMethods.Quaternion(); q.X = 0.5f; q.Y = 0.5f; q.Z = 0.5f; q.W = 0.5f; - d.GeomSetQuaternion(TerrainGeom, ref q); - d.GeomSetPosition(TerrainGeom, m_regionWidth * 0.5f, m_regionHeight * 0.5f, 0.0f); + SafeNativeMethods.GeomSetQuaternion(TerrainGeom, ref q); + SafeNativeMethods.GeomSetPosition(TerrainGeom, m_regionWidth * 0.5f, m_regionHeight * 0.5f, 0.0f); TerrainHeightFieldHeight = _heightmap; } else @@ -2329,8 +2260,8 @@ namespace OpenSim.Region.PhysicsModule.ubOde float val; - uint maxXX = regionsizeX - 1; - uint maxYY = regionsizeY - 1; + uint maxXX = regionsizeX + 1; + uint maxYY = regionsizeY + 1; // adding one margin all around so things don't fall in edges uint xx; @@ -2348,8 +2279,8 @@ namespace OpenSim.Region.PhysicsModule.ubOde xx++; val = heightMap[yy + xx]; - if (val < 0.0f) - val = 0.0f; // no neg terrain as in chode + if (val < -100.0f) + val = -100.0f; _heightmap[yt + x] = val; if (hfmin > val) @@ -2365,7 +2296,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde if (TerrainGeom != IntPtr.Zero) { actor_name_map.Remove(TerrainGeom); - d.GeomDestroy(TerrainGeom); + SafeNativeMethods.GeomDestroy(TerrainGeom); } if (TerrainHeightFieldHeightsHandler.IsAllocated) @@ -2373,7 +2304,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde TerrainHeightFieldHeight = null; - IntPtr HeightmapData = d.GeomOSTerrainDataCreate(); + IntPtr HeightmapData = SafeNativeMethods.GeomOSTerrainDataCreate(); const int wrap = 0; float thickness = hfmin; @@ -2382,16 +2313,16 @@ namespace OpenSim.Region.PhysicsModule.ubOde TerrainHeightFieldHeightsHandler = GCHandle.Alloc(_heightmap, GCHandleType.Pinned); - d.GeomOSTerrainDataBuild(HeightmapData, TerrainHeightFieldHeightsHandler.AddrOfPinnedObject(), 0, 1.0f, + SafeNativeMethods.GeomOSTerrainDataBuild(HeightmapData, TerrainHeightFieldHeightsHandler.AddrOfPinnedObject(), 0, 1.0f, (int)heightmapWidthSamples, (int)heightmapHeightSamples, thickness, wrap); // d.GeomOSTerrainDataSetBounds(HeightmapData, hfmin - 1, hfmax + 1); - TerrainGeom = d.CreateOSTerrain(GroundSpace, HeightmapData, 1); + TerrainGeom = SafeNativeMethods.CreateOSTerrain(GroundSpace, HeightmapData, 1); if (TerrainGeom != IntPtr.Zero) { - d.GeomSetCategoryBits(TerrainGeom, (uint)(CollisionCategories.Land)); - d.GeomSetCollideBits(TerrainGeom, 0); + SafeNativeMethods.GeomSetCategoryBits(TerrainGeom, (uint)(CollisionCategories.Land)); + SafeNativeMethods.GeomSetCollideBits(TerrainGeom, 0); PhysicsActor pa = new NullPhysicsActor(); pa.Name = "Terrain"; @@ -2400,7 +2331,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde // geom_name_map[GroundGeom] = "Terrain"; - d.GeomSetPosition(TerrainGeom, m_regionWidth * 0.5f, m_regionHeight * 0.5f, 0.0f); + SafeNativeMethods.GeomSetPosition(TerrainGeom, m_regionWidth * 0.5f, m_regionHeight * 0.5f, 0.0f); TerrainHeightFieldHeight = _heightmap; } else @@ -2430,7 +2361,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde if (world == IntPtr.Zero) return; - d.AllocateODEDataForThread(~0U); + SafeNativeMethods.AllocateODEDataForThread(~0U); if (m_meshWorker != null) m_meshWorker.Stop(); @@ -2464,7 +2395,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde ch.DoAChange(changes.Remove, null); if (TerrainGeom != IntPtr.Zero) - d.GeomDestroy(TerrainGeom); + SafeNativeMethods.GeomDestroy(TerrainGeom); TerrainGeom = IntPtr.Zero; if (TerrainHeightFieldHeightsHandler.IsAllocated) @@ -2483,7 +2414,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde GlobalContactsArray = IntPtr.Zero; } - d.WorldDestroy(world); + SafeNativeMethods.WorldDestroy(world); world = IntPtr.Zero; //d.CloseODE(); } diff --git a/OpenSim/Region/PhysicsModules/ubOde/ODESitAvatar.cs b/OpenSim/Region/PhysicsModules/ubOde/ODESitAvatar.cs index 214205ddc5..f882e6ccf2 100644 --- a/OpenSim/Region/PhysicsModules/ubOde/ODESitAvatar.cs +++ b/OpenSim/Region/PhysicsModules/ubOde/ODESitAvatar.cs @@ -27,13 +27,7 @@ // Ubit Umarov 2012 using System; using System.Collections.Generic; -using System.Reflection; -using System.Runtime.InteropServices; -using System.Text; -using OpenSim.Framework; using OpenSim.Region.PhysicsModules.SharedBase; -using OdeAPI; -using log4net; using OpenMetaverse; namespace OpenSim.Region.PhysicsModule.ubOde @@ -78,8 +72,8 @@ namespace OpenSim.Region.PhysicsModule.ubOde IntPtr geom = ((OdePrim)actor).prim_geom; - Vector3 geopos = d.GeomGetPositionOMV(geom); - Quaternion geomOri = d.GeomGetQuaternionOMV(geom); + Vector3 geopos = SafeNativeMethods.GeomGetPositionOMV(geom); + Quaternion geomOri = SafeNativeMethods.GeomGetQuaternionOMV(geom); // Vector3 geopos = actor.Position; // Quaternion geomOri = actor.Orientation; @@ -123,11 +117,11 @@ namespace OpenSim.Region.PhysicsModule.ubOde offset = rayResults[0].Pos - geopos; - d.GeomClassID geoclass = d.GeomGetClass(geom); + SafeNativeMethods.GeomClassID geoclass = SafeNativeMethods.GeomGetClass(geom); - if (geoclass == d.GeomClassID.SphereClass) + if (geoclass == SafeNativeMethods.GeomClassID.SphereClass) { - float r = d.GeomSphereGetRadius(geom); + float r = SafeNativeMethods.GeomSphereGetRadius(geom); offset.Normalize(); offset *= r; diff --git a/OpenSim/Region/PhysicsModules/ubOdeMeshing/Meshmerizer.cs b/OpenSim/Region/PhysicsModules/ubOdeMeshing/Meshmerizer.cs index 0117800b96..6a4ef1e684 100644 --- a/OpenSim/Region/PhysicsModules/ubOdeMeshing/Meshmerizer.cs +++ b/OpenSim/Region/PhysicsModules/ubOdeMeshing/Meshmerizer.cs @@ -36,15 +36,13 @@ using OpenSim.Region.PhysicsModules.ConvexDecompositionDotNet; using OpenMetaverse; using OpenMetaverse.StructuredData; using System.Drawing; -using System.Drawing.Imaging; +using System.Threading; using System.IO.Compression; using PrimMesher; using log4net; using Nini.Config; using System.Reflection; using System.IO; -using System.Runtime.Serialization; -using System.Runtime.Serialization.Formatters.Binary; using Mono.Addins; @@ -58,22 +56,22 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing // Setting baseDir to a path will enable the dumping of raw files // raw files can be imported by blender so a visual inspection of the results can be done + private static string cacheControlFilename = "cntr"; private bool m_Enabled = false; public static object diskLock = new object(); public bool doMeshFileCache = true; - + public bool doCacheExpire = true; public string cachePath = "MeshCache"; public TimeSpan CacheExpire; - public bool doCacheExpire = true; // const string baseDir = "rawFiles"; private const string baseDir = null; //"rawFiles"; - private bool useMeshiesPhysicsMesh = false; - - private float minSizeForComplexMesh = 0.2f; // prims with all dimensions smaller than this will have a bounding box mesh + private bool useMeshiesPhysicsMesh = true; + private bool doConvexPrims = true; + private bool doConvexSculpts = true; private Dictionary m_uniqueMeshes = new Dictionary(); private Dictionary m_uniqueReleasedMeshes = new Dictionary(); @@ -103,40 +101,31 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing if (mesh_config != null) { useMeshiesPhysicsMesh = mesh_config.GetBoolean("UseMeshiesPhysicsMesh", useMeshiesPhysicsMesh); - if (useMeshiesPhysicsMesh) - { - doMeshFileCache = mesh_config.GetBoolean("MeshFileCache", doMeshFileCache); - cachePath = mesh_config.GetString("MeshFileCachePath", cachePath); - fcache = mesh_config.GetFloat("MeshFileCacheExpireHours", fcache); - doCacheExpire = mesh_config.GetBoolean("MeshFileCacheDoExpire", doCacheExpire); - } - else - { - doMeshFileCache = false; - doCacheExpire = false; - } + doConvexPrims = mesh_config.GetBoolean("ConvexPrims",doConvexPrims); + doConvexSculpts = mesh_config.GetBoolean("ConvexSculpts",doConvexPrims); + doMeshFileCache = mesh_config.GetBoolean("MeshFileCache", doMeshFileCache); + cachePath = mesh_config.GetString("MeshFileCachePath", cachePath); + fcache = mesh_config.GetFloat("MeshFileCacheExpireHours", fcache); + doCacheExpire = mesh_config.GetBoolean("MeshFileCacheDoExpire", doCacheExpire); m_Enabled = true; } CacheExpire = TimeSpan.FromHours(fcache); - lock (diskLock) + if(String.IsNullOrEmpty(cachePath)) + doMeshFileCache = false; + + if(doMeshFileCache) { - if(doMeshFileCache && cachePath != "") + if(!checkCache()) { - try - { - if (!Directory.Exists(cachePath)) - Directory.CreateDirectory(cachePath); - } - catch - { - doMeshFileCache = false; - doCacheExpire = false; - } + doMeshFileCache = false; + doCacheExpire = false; } } + else + doCacheExpire = false; } } @@ -168,87 +157,6 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing #endregion - /// - /// creates a simple box mesh of the specified size. This mesh is of very low vertex count and may - /// be useful as a backup proxy when level of detail is not needed or when more complex meshes fail - /// for some reason - /// - /// - /// - /// - /// - /// - /// - /// - private static Mesh CreateSimpleBoxMesh(float minX, float maxX, float minY, float maxY, float minZ, float maxZ) - { - Mesh box = new Mesh(true); - List vertices = new List(); - // bottom - - vertices.Add(new Vertex(minX, maxY, minZ)); - vertices.Add(new Vertex(maxX, maxY, minZ)); - vertices.Add(new Vertex(maxX, minY, minZ)); - vertices.Add(new Vertex(minX, minY, minZ)); - - box.Add(new Triangle(vertices[0], vertices[1], vertices[2])); - box.Add(new Triangle(vertices[0], vertices[2], vertices[3])); - - // top - - vertices.Add(new Vertex(maxX, maxY, maxZ)); - vertices.Add(new Vertex(minX, maxY, maxZ)); - vertices.Add(new Vertex(minX, minY, maxZ)); - vertices.Add(new Vertex(maxX, minY, maxZ)); - - box.Add(new Triangle(vertices[4], vertices[5], vertices[6])); - box.Add(new Triangle(vertices[4], vertices[6], vertices[7])); - - // sides - - box.Add(new Triangle(vertices[5], vertices[0], vertices[3])); - box.Add(new Triangle(vertices[5], vertices[3], vertices[6])); - - box.Add(new Triangle(vertices[1], vertices[0], vertices[5])); - box.Add(new Triangle(vertices[1], vertices[5], vertices[4])); - - box.Add(new Triangle(vertices[7], vertices[1], vertices[4])); - box.Add(new Triangle(vertices[7], vertices[2], vertices[1])); - - box.Add(new Triangle(vertices[3], vertices[2], vertices[7])); - box.Add(new Triangle(vertices[3], vertices[7], vertices[6])); - - return box; - } - - /// - /// Creates a simple bounding box mesh for a complex input mesh - /// - /// - /// - private static Mesh CreateBoundingBoxMesh(Mesh meshIn) - { - float minX = float.MaxValue; - float maxX = float.MinValue; - float minY = float.MaxValue; - float maxY = float.MinValue; - float minZ = float.MaxValue; - float maxZ = float.MinValue; - - foreach (Vector3 v in meshIn.getVertexList()) - { - if (v.X < minX) minX = v.X; - if (v.Y < minY) minY = v.Y; - if (v.Z < minZ) minZ = v.Z; - - if (v.X > maxX) maxX = v.X; - if (v.Y > maxY) maxY = v.Y; - if (v.Z > maxZ) maxZ = v.Z; - } - - return CreateSimpleBoxMesh(minX, maxX, minY, maxY, minZ, maxZ); - } - private void ReportPrimError(string message, string primName, PrimMesh primMesh) { m_log.Error(message); @@ -265,7 +173,7 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing /// private void AddSubMesh(OSDMap subMeshData, List coords, List faces) { - // Console.WriteLine("subMeshMap for {0} - {1}", primName, Util.GetFormattedXml((OSD)subMeshMap)); + // Console.WriteLine("subMeshMap for {0} - {1}", primName, Util.GetFormattedXml((OSD)subMeshMap)); // As per http://wiki.secondlife.com/wiki/Mesh/Mesh_Asset_Format, some Mesh Level // of Detail Blocks (maps) contain just a NoGeometry key to signal there is no @@ -330,33 +238,83 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing List coords; List faces; + bool needsConvexProcessing = convex; if (primShape.SculptEntry) { - if (((OpenMetaverse.SculptType)primShape.SculptType) == SculptType.Mesh) + if (((SculptType)primShape.SculptType) == SculptType.Mesh) { if (!useMeshiesPhysicsMesh) return null; - - if (!GenerateCoordsAndFacesFromPrimMeshData(primName, primShape, out coords, out faces, convex)) + try + { + if (!GenerateCoordsAndFacesFromPrimMeshData(primName, primShape, out coords, out faces, convex)) + return null; + needsConvexProcessing = false; + } + catch + { + m_log.ErrorFormat("[MESH]: fail to process mesh asset for prim {0}", primName); return null; + } } else { - if (!GenerateCoordsAndFacesFromPrimSculptData(primName, primShape, lod, out coords, out faces)) + try + { + if (!GenerateCoordsAndFacesFromPrimSculptData(primName, primShape, lod, out coords, out faces)) + return null; + needsConvexProcessing &= doConvexSculpts; + } + catch + { + m_log.ErrorFormat("[MESH]: fail to process sculpt map for prim {0}", primName); return null; + } } } else { - if (!GenerateCoordsAndFacesFromPrimShapeData(primName, primShape, lod, convex, out coords, out faces)) + try + { + if (!GenerateCoordsAndFacesFromPrimShapeData(primName, primShape, lod, convex, out coords, out faces)) + return null; + needsConvexProcessing &= doConvexPrims; + } + catch + { + m_log.ErrorFormat("[MESH]: fail to process shape parameters for prim {0}", primName); return null; + } } - int numCoords = coords.Count; int numFaces = faces.Count; + if(numCoords < 3 || (!needsConvexProcessing && numFaces < 1)) + { + m_log.ErrorFormat("[MESH]: invalid degenerated mesh for prim {0} ignored", primName); + return null; + } + + if(needsConvexProcessing) + { + List convexcoords; + List convexfaces; + if(CreateBoundingHull(coords, out convexcoords, out convexfaces) && convexcoords != null && convexfaces != null) + { + coords.Clear(); + coords = convexcoords; + numCoords = coords.Count; + + faces.Clear(); + faces = convexfaces; + numFaces = faces.Count; + } + else + m_log.ErrorFormat("[ubMESH]: failed to create convex for {0} using normal mesh", primName); + } + Mesh mesh = new Mesh(true); // Add the corresponding triangles to the mesh for (int i = 0; i < numFaces; i++) @@ -371,10 +329,10 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing faces.Clear(); if(mesh.numberVertices() < 3 || mesh.numberTriangles() < 1) - { - m_log.ErrorFormat("[MESH]: invalid degenerated mesh for prim " + primName + " ignored"); + { + m_log.ErrorFormat("[MESH]: invalid degenerated mesh for prim {0} ignored", primName); return null; - } + } primShape.SculptData = Utils.EmptyBytes; @@ -405,7 +363,7 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing faces = new List(); OSD meshOsd = null; - if (primShape.SculptData.Length <= 0) + if (primShape.SculptData == null || primShape.SculptData.Length <= 0) { // m_log.InfoFormat("[MESH]: asset data for {0} is zero length", primName); return false; @@ -428,6 +386,7 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing catch (Exception e) { m_log.Error("[MESH]: Exception deserializing mesh asset header:" + e.ToString()); + return false; } start = data.Position; @@ -625,45 +584,7 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing vs.Clear(); continue; } - /* - if (!HullUtils.ComputeHull(vs, ref hullr, 0, 0.0f)) - { - vs.Clear(); - continue; - } - nverts = hullr.Vertices.Count; - nindexs = hullr.Indices.Count; - - if (nindexs % 3 != 0) - { - vs.Clear(); - continue; - } - - for (i = 0; i < nverts; i++) - { - c.X = hullr.Vertices[i].x; - c.Y = hullr.Vertices[i].y; - c.Z = hullr.Vertices[i].z; - coords.Add(c); - } - - for (i = 0; i < nindexs; i += 3) - { - t1 = hullr.Indices[i]; - if (t1 > nverts) - break; - t2 = hullr.Indices[i + 1]; - if (t2 > nverts) - break; - t3 = hullr.Indices[i + 2]; - if (t3 > nverts) - break; - f = new Face(vertsoffset + t1, vertsoffset + t2, vertsoffset + t3); - faces.Add(f); - } - */ List indices; if (!HullUtils.ComputeHull(vs, out indices)) { @@ -769,38 +690,7 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing vs.Clear(); return true; } -/* - if (!HullUtils.ComputeHull(vs, ref hullr, 0, 0.0f)) - return false; - nverts = hullr.Vertices.Count; - nindexs = hullr.Indices.Count; - - if (nindexs % 3 != 0) - return false; - - for (i = 0; i < nverts; i++) - { - c.X = hullr.Vertices[i].x; - c.Y = hullr.Vertices[i].y; - c.Z = hullr.Vertices[i].z; - coords.Add(c); - } - for (i = 0; i < nindexs; i += 3) - { - t1 = hullr.Indices[i]; - if (t1 > nverts) - break; - t2 = hullr.Indices[i + 1]; - if (t2 > nverts) - break; - t3 = hullr.Indices[i + 2]; - if (t3 > nverts) - break; - f = new Face(t1, t2, t3); - faces.Add(f); - } -*/ List indices; if (!HullUtils.ComputeHull(vs, out indices)) return false; @@ -1413,7 +1303,7 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing } } - public void FileNames(AMeshKey key, out string dir,out string fullFileName) + public void FileNames(AMeshKey key, out string dir, out string fullFileName) { string id = key.ToString(); string init = id.Substring(0, 1); @@ -1516,7 +1406,7 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing { File.Delete(filename); } - catch (IOException e) + catch (IOException) { m_log.ErrorFormat( "[MESH CACHE]: Failed to delete file {0}",filename); @@ -1530,7 +1420,7 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing if (!doCacheExpire) return; - string controlfile = System.IO.Path.Combine(cachePath, "cntr"); + string controlfile = System.IO.Path.Combine(cachePath, cacheControlFilename); lock (diskLock) { @@ -1583,5 +1473,151 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing catch { } } } + + public bool checkCache() + { + string controlfile = System.IO.Path.Combine(cachePath, cacheControlFilename); + lock (diskLock) + { + try + { + if (!Directory.Exists(cachePath)) + { + Directory.CreateDirectory(cachePath); + Thread.Sleep(100); + FileStream fs = File.Create(controlfile, 4096, FileOptions.WriteThrough); + fs.Close(); + return true; + } + } + catch + { + doMeshFileCache = false; + doCacheExpire = false; + return false; + } + finally {} + + if (File.Exists(controlfile)) + return true; + + try + { + Directory.Delete(cachePath, true); + while(Directory.Exists(cachePath)) + Thread.Sleep(100); + } + catch(Exception e) + { + m_log.Error("[MESH CACHE]: failed to delete old version of the cache: " + e.Message); + doMeshFileCache = false; + doCacheExpire = false; + return false; + } + finally {} + try + { + Directory.CreateDirectory(cachePath); + while(!Directory.Exists(cachePath)) + Thread.Sleep(100); + } + catch(Exception e) + { + m_log.Error("[MESH CACHE]: failed to create new cache folder: " + e.Message); + doMeshFileCache = false; + doCacheExpire = false; + return false; + } + finally {} + + try + { + FileStream fs = File.Create(controlfile, 4096, FileOptions.WriteThrough); + fs.Close(); + } + catch(Exception e) + { + m_log.Error("[MESH CACHE]: failed to create new control file: " + e.Message); + doMeshFileCache = false; + doCacheExpire = false; + return false; + } + finally {} + + return true; + } + } + + public bool CreateBoundingHull(List inputVertices, out List convexcoords, out List newfaces) + { + convexcoords = null; + newfaces = null; + HullDesc desc = new HullDesc(); + HullResult result = new HullResult(); + + int nInputVerts = inputVertices.Count; + int i; + + List vs = new List(nInputVerts); + float3 f3; + + //useless copy + for(i = 0 ; i < nInputVerts; i++) + { + f3 = new float3(inputVertices[i].X, inputVertices[i].Y, inputVertices[i].Z); + vs.Add(f3); + } + + desc.Vertices = vs; + desc.Flags = HullFlag.QF_TRIANGLES; + desc.MaxVertices = 256; + + try + { + HullError ret = HullUtils.CreateConvexHull(desc, ref result); + if (ret != HullError.QE_OK) + return false; + int nverts = result.OutputVertices.Count; + int nindx = result.Indices.Count; + if(nverts < 3 || nindx< 3) + return false; + if(nindx % 3 != 0) + return false; + + convexcoords = new List(nverts); + Coord c; + vs = result.OutputVertices; + + for(i = 0 ; i < nverts; i++) + { + c = new Coord(vs[i].x, vs[i].y, vs[i].z); + convexcoords.Add(c); + } + + newfaces = new List(nindx / 3); + List indxs = result.Indices; + int k, l, m; + Face f; + for(i = 0 ; i < nindx;) + { + k = indxs[i++]; + l = indxs[i++]; + m = indxs[i++]; + if(k > nInputVerts) + continue; + if(l > nInputVerts) + continue; + if(m > nInputVerts) + continue; + f = new Face(k,l,m); + newfaces.Add(f); + } + } + catch + { + return false; + } + return true; + } } } diff --git a/OpenSim/Region/PhysicsModules/ubOdeMeshing/PrimMesher.cs b/OpenSim/Region/PhysicsModules/ubOdeMeshing/PrimMesher.cs index 10facf2713..e93175f081 100644 --- a/OpenSim/Region/PhysicsModules/ubOdeMeshing/PrimMesher.cs +++ b/OpenSim/Region/PhysicsModules/ubOdeMeshing/PrimMesher.cs @@ -755,8 +755,8 @@ namespace PrimMesher if (hollowAngles.angles[0].angle - angles.angles[i].angle < angles.angles[i].angle - hollowAngles.angles[maxJ].angle + 0.000001f) { newFace.v1 = 0; - newFace.v2 = numTotalVerts - maxJ - 1; - newFace.v3 = numTotalVerts - 1; + newFace.v2 = numTotalVerts - 1; + newFace.v3 = numTotalVerts - maxJ - 1; faces.Add(newFace); } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs index 6a39bb95e0..5eb3c5cd3d 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs @@ -51,7 +51,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api private static Thread cmdHandlerThread; private static int cmdHandlerThreadCycleSleepms; - + private static int numInstances; /// /// Lock for reading/writing static components of AsyncCommandManager. /// @@ -172,18 +172,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (!m_XmlRequest.ContainsKey(m_ScriptEngine)) m_XmlRequest[m_ScriptEngine] = new XmlRequest(this); - StartThread(); - } - } - - private static void StartThread() - { - if (cmdHandlerThread == null) - { - // Start the thread that will be doing the work - cmdHandlerThread - = WorkManager.StartThread( + numInstances++; + if (cmdHandlerThread == null) + { + cmdHandlerThread = WorkManager.StartThread( CmdHandlerThreadLoop, "AsyncLSLCmdHandlerThread", ThreadPriority.Normal, true, true); + } } } @@ -194,25 +188,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api cmdHandlerThreadCycleSleepms = 100; } +/* ~AsyncCommandManager() { // Shut down thread -// try -// { -// if (cmdHandlerThread != null) -// { -// if (cmdHandlerThread.IsAlive == true) -// { -// cmdHandlerThread.Abort(); -// //cmdHandlerThread.Join(); -// } -// } -// } -// catch -// { -// } - } + try + { + lock (staticLock) + { + numInstances--; + if(numInstances > 0) + return; + if (cmdHandlerThread != null) + { + if (cmdHandlerThread.IsAlive == true) + { + cmdHandlerThread.Abort(); + //cmdHandlerThread.Join(); + cmdHandlerThread = null; + } + } + } + } + catch + { + } + } +*/ /// /// Main loop for the manager thread /// @@ -223,11 +226,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api try { Thread.Sleep(cmdHandlerThreadCycleSleepms); - + Watchdog.UpdateThread(); DoOneCmdHandlerPass(); - Watchdog.UpdateThread(); } + catch ( System.Threading.ThreadAbortException) { } catch (Exception e) { m_log.Error("[ASYNC COMMAND MANAGER]: Exception in command handler pass: ", e); @@ -240,24 +243,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api lock (staticLock) { // Check HttpRequests - m_HttpRequest[m_ScriptEngines[0]].CheckHttpRequests(); + try { m_HttpRequest[m_ScriptEngines[0]].CheckHttpRequests(); } catch {} // Check XMLRPCRequests - m_XmlRequest[m_ScriptEngines[0]].CheckXMLRPCRequests(); + try { m_XmlRequest[m_ScriptEngines[0]].CheckXMLRPCRequests(); } catch {} foreach (IScriptEngine s in m_ScriptEngines) { // Check Listeners - m_Listener[s].CheckListeners(); + try { m_Listener[s].CheckListeners(); } catch {} + // Check timers - m_Timer[s].CheckTimerEvents(); + try { m_Timer[s].CheckTimerEvents(); } catch {} // Check Sensors - m_SensorRepeat[s].CheckSenseRepeaterEvents(); + try { m_SensorRepeat[s].CheckSenseRepeaterEvents(); } catch {} // Check dataserver - m_Dataserver[s].ExpireRequests(); + try { m_Dataserver[s].ExpireRequests(); } catch {} } } } @@ -280,22 +284,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // Remove from: Timers m_Timer[engine].UnSetTimerEvents(localID, itemID); - // Remove from: HttpRequest - IHttpRequestModule iHttpReq = engine.World.RequestModuleInterface(); - if (iHttpReq != null) - iHttpReq.StopHttpRequest(localID, itemID); - - IWorldComm comms = engine.World.RequestModuleInterface(); - if (comms != null) - comms.DeleteListener(itemID); - - IXMLRPC xmlrpc = engine.World.RequestModuleInterface(); - if (xmlrpc != null) + if(engine.World != null) { - xmlrpc.DeleteChannels(itemID); - xmlrpc.CancelSRDRequests(itemID); - } + // Remove from: HttpRequest + IHttpRequestModule iHttpReq = engine.World.RequestModuleInterface(); + if (iHttpReq != null) + iHttpReq.StopHttpRequest(localID, itemID); + IWorldComm comms = engine.World.RequestModuleInterface(); + if (comms != null) + comms.DeleteListener(itemID); + + IXMLRPC xmlrpc = engine.World.RequestModuleInterface(); + if (xmlrpc != null) + { + xmlrpc.DeleteChannels(itemID); + xmlrpc.CancelSRDRequests(itemID); + } + } // Remove Sensors m_SensorRepeat[engine].UnSetSenseRepeaterEvents(localID, itemID); } @@ -387,8 +393,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } } - - public static Object[] GetSerializationData(IScriptEngine engine, UUID itemID) { List data = new List(); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 62654eed1f..68804a18c1 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -28,6 +28,7 @@ using System; using System.Collections; using System.Collections.Generic; +using System.Collections.Specialized; using System.Diagnostics; using System.Drawing; using System.Drawing.Imaging; @@ -40,7 +41,7 @@ using Nini.Config; using log4net; using OpenMetaverse; using OpenMetaverse.Assets; -using OpenMetaverse.StructuredData; +using OpenMetaverse.StructuredData; // LitJson is hidden on this using OpenMetaverse.Packets; using OpenMetaverse.Rendering; using OpenSim; @@ -123,6 +124,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api protected bool m_debuggerSafe = false; protected IUrlModule m_UrlModule = null; + protected IMaterialsModule m_materialsModule = null; + protected Dictionary m_userInfoCache = new Dictionary(); protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp. protected int m_sleepMsOnSetTexture = 200; @@ -305,6 +308,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_ScriptEngine.World.RequestModuleInterface(); m_UrlModule = m_ScriptEngine.World.RequestModuleInterface(); m_SoundModule = m_ScriptEngine.World.RequestModuleInterface(); + m_materialsModule = m_ScriptEngine.World.RequestModuleInterface(); AsyncCommands = new AsyncCommandManager(m_ScriptEngine); } @@ -439,8 +443,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api protected virtual void ScriptSleep(int delay) { - delay = (int)((float)delay * m_ScriptDelayFactor); - if (delay == 0) + delay = (int)(delay * m_ScriptDelayFactor); + if (delay < 10) return; Sleep(delay); @@ -449,12 +453,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api protected virtual void Sleep(int delay) { if (m_item == null) // Some unit tests don't set this - { Thread.Sleep(delay); - return; - } - - m_ScriptEngine.SleepScript(m_item.ItemID, delay); + else + m_ScriptEngine.SleepScript(m_item.ItemID, delay); } /// @@ -494,12 +495,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { UUID item; - m_host.AddScriptLPS(1); - - if ((item = GetScriptByName(name)) != UUID.Zero) - m_ScriptEngine.ResetScript(item); - else + if ((item = GetScriptByName(name)) == UUID.Zero) + { + m_host.AddScriptLPS(1); Error("llResetOtherScript", "Can't find script '" + name + "'"); + return; + } + if(item == m_item.ItemID) + llResetScript(); + else + { + m_host.AddScriptLPS(1); + m_ScriptEngine.ResetScript(item); + } } public LSL_Integer llGetScriptState(string name) @@ -1396,7 +1404,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return detectedParams.Name; } - public LSL_String llDetectedKey(int number) + public LSL_Key llDetectedKey(int number) { m_host.AddScriptLPS(1); DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, number); @@ -1405,7 +1413,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return detectedParams.Key.ToString(); } - public LSL_String llDetectedOwner(int number) + public LSL_Key llDetectedOwner(int number) { m_host.AddScriptLPS(1); DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, number); @@ -1925,8 +1933,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return; Primitive.TextureEntry tex = part.Shape.Textures; + int nsides = GetNumberOfSides(part); Color4 texcolor; - if (face >= 0 && face < GetNumberOfSides(part)) + + if (face >= 0 && face < nsides) { texcolor = tex.CreateFace((uint)face).RGBA; texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f); @@ -1937,8 +1947,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return; } else if (face == ScriptBaseClass.ALL_SIDES) - { - for (uint i = 0; i < GetNumberOfSides(part); i++) + { + for (uint i = 0; i < nsides; i++) { if (tex.FaceTextures[i] != null) { @@ -2055,7 +2065,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (style == (int)ScriptBaseClass.PRIM_TEXGEN_PLANAR) textype = MappingType.Planar; - if (face >= 0 && face < GetNumberOfSides(part)) + int nsides = GetNumberOfSides(part); + + if (face >= 0 && face < nsides) { tex.CreateFace((uint) face); tex.FaceTextures[face].TexMapType = textype; @@ -2064,7 +2076,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } else if (face == ScriptBaseClass.ALL_SIDES) { - for (uint i = 0; i < GetNumberOfSides(part); i++) + for (uint i = 0; i < nsides; i++) { if (tex.FaceTextures[i] != null) { @@ -2083,7 +2095,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return; Primitive.TextureEntry tex = part.Shape.Textures; - if (face >= 0 && face < GetNumberOfSides(part)) + int nsides = GetNumberOfSides(part); + + if (face >= 0 && face < nsides) { tex.CreateFace((uint) face); tex.FaceTextures[face].Glow = glow; @@ -2092,7 +2106,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } else if (face == ScriptBaseClass.ALL_SIDES) { - for (uint i = 0; i < GetNumberOfSides(part); i++) + for (uint i = 0; i < nsides; i++) { if (tex.FaceTextures[i] != null) { @@ -2131,8 +2145,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api break; } + int nsides = GetNumberOfSides(part); + Primitive.TextureEntry tex = part.Shape.Textures; - if (face >= 0 && face < GetNumberOfSides(part)) + if (face >= 0 && face < nsides) { tex.CreateFace((uint) face); tex.FaceTextures[face].Shiny = sval; @@ -2142,7 +2158,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } else if (face == ScriptBaseClass.ALL_SIDES) { - for (uint i = 0; i < GetNumberOfSides(part); i++) + for (uint i = 0; i < nsides; i++) { if (tex.FaceTextures[i] != null) { @@ -2162,8 +2178,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) return; + int nsides = GetNumberOfSides(part); Primitive.TextureEntry tex = part.Shape.Textures; - if (face >= 0 && face < GetNumberOfSides(part)) + if (face >= 0 && face < nsides) { tex.CreateFace((uint) face); tex.FaceTextures[face].Fullbright = bright; @@ -2172,7 +2189,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } else if (face == ScriptBaseClass.ALL_SIDES) { - for (uint i = 0; i < GetNumberOfSides(part); i++) + for (uint i = 0; i < nsides; i++) { if (tex.FaceTextures[i] != null) { @@ -2195,15 +2212,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api protected LSL_Float GetAlpha(SceneObjectPart part, int face) { Primitive.TextureEntry tex = part.Shape.Textures; + int nsides = GetNumberOfSides(part); if (face == ScriptBaseClass.ALL_SIDES) { int i; double sum = 0.0; - for (i = 0 ; i < GetNumberOfSides(part); i++) + for (i = 0 ; i < nsides; i++) sum += (double)tex.GetFace((uint)i).RGBA.A; return sum; } - if (face >= 0 && face < GetNumberOfSides(part)) + if (face >= 0 && face < nsides) { return (double)tex.GetFace((uint)face).RGBA.A; } @@ -2239,8 +2257,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return; Primitive.TextureEntry tex = part.Shape.Textures; + int nsides = GetNumberOfSides(part); Color4 texcolor; - if (face >= 0 && face < GetNumberOfSides(part)) + + if (face >= 0 && face < nsides) { texcolor = tex.CreateFace((uint)face).RGBA; texcolor.A = Util.Clip((float)alpha, 0.0f, 1.0f); @@ -2250,7 +2270,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } else if (face == ScriptBaseClass.ALL_SIDES) { - for (int i = 0; i < GetNumberOfSides(part); i++) + for (int i = 0; i < nsides; i++) { if (tex.FaceTextures[i] != null) { @@ -2439,8 +2459,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } Primitive.TextureEntry tex = part.Shape.Textures; + int nsides = GetNumberOfSides(part); - if (face >= 0 && face < GetNumberOfSides(part)) + if (face >= 0 && face < nsides) { Primitive.TextureEntryFace texface = tex.CreateFace((uint)face); texface.TextureID = textureID; @@ -2450,7 +2471,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } else if (face == ScriptBaseClass.ALL_SIDES) { - for (uint i = 0; i < GetNumberOfSides(part); i++) + for (uint i = 0; i < nsides; i++) { if (tex.FaceTextures[i] != null) { @@ -2477,7 +2498,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return; Primitive.TextureEntry tex = part.Shape.Textures; - if (face >= 0 && face < GetNumberOfSides(part)) + int nsides = GetNumberOfSides(part); + + if (face >= 0 && face < nsides) { Primitive.TextureEntryFace texface = tex.CreateFace((uint)face); texface.RepeatU = (float)u; @@ -2488,7 +2511,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } if (face == ScriptBaseClass.ALL_SIDES) { - for (int i = 0; i < GetNumberOfSides(part); i++) + for (int i = 0; i < nsides; i++) { if (tex.FaceTextures[i] != null) { @@ -2516,7 +2539,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return; Primitive.TextureEntry tex = part.Shape.Textures; - if (face >= 0 && face < GetNumberOfSides(part)) + int nsides = GetNumberOfSides(part); + + if (face >= 0 && face < nsides) { Primitive.TextureEntryFace texface = tex.CreateFace((uint)face); texface.OffsetU = (float)u; @@ -2527,7 +2552,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } if (face == ScriptBaseClass.ALL_SIDES) { - for (int i = 0; i < GetNumberOfSides(part); i++) + for (int i = 0; i < nsides; i++) { if (tex.FaceTextures[i] != null) { @@ -2555,7 +2580,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return; Primitive.TextureEntry tex = part.Shape.Textures; - if (face >= 0 && face < GetNumberOfSides(part)) + int nsides = GetNumberOfSides(part); + + if (face >= 0 && face < nsides) { Primitive.TextureEntryFace texface = tex.CreateFace((uint)face); texface.Rotation = (float)rotation; @@ -2565,7 +2592,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } if (face == ScriptBaseClass.ALL_SIDES) { - for (int i = 0; i < GetNumberOfSides(part); i++) + for (int i = 0; i < nsides; i++) { if (tex.FaceTextures[i] != null) { @@ -2587,12 +2614,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api protected LSL_String GetTexture(SceneObjectPart part, int face) { Primitive.TextureEntry tex = part.Shape.Textures; + int nsides = GetNumberOfSides(part); + if (face == ScriptBaseClass.ALL_SIDES) { face = 0; } - if (face >= 0 && face < GetNumberOfSides(part)) + if (face >= 0 && face < nsides) { Primitive.TextureEntryFace texface; texface = tex.GetFace((uint)face); @@ -2725,9 +2754,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api /// if TRUE, will cap the distance to 10m. protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust) { - if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) + if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted || part.ParentGroup.inTransit) return; + LSL_Vector currentPos = GetPartLocalPos(part); LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos, adjust); @@ -3137,70 +3167,87 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); - // send the sound, once, to all clients in range - if (m_SoundModule != null) - { - m_SoundModule.SendSound( - m_host.UUID, - ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound, AssetType.Sound), - volume, false, 0, - 0, false, false); - } + if (m_SoundModule == null) + return; + + UUID soundID = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound, AssetType.Sound); + if(soundID == UUID.Zero) + return; + + // send the sound, once, to all clients in range + m_SoundModule.SendSound(m_host.UUID, soundID, volume, false, 0, false, false); } public void llLoopSound(string sound, double volume) { m_host.AddScriptLPS(1); - if (m_SoundModule != null) - { - m_SoundModule.LoopSound(m_host.UUID, ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound), - volume, 20, false,false); - } + + if (m_SoundModule == null) + return; + + UUID soundID = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound, AssetType.Sound); + if(soundID == UUID.Zero) + return; + + m_SoundModule.LoopSound(m_host.UUID, soundID, volume, false,false); } public void llLoopSoundMaster(string sound, double volume) { m_host.AddScriptLPS(1); - if (m_SoundModule != null) - { - m_SoundModule.LoopSound(m_host.UUID, ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound), - volume, 20, true, false); - } + + if (m_SoundModule == null) + return; + + UUID soundID = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound, AssetType.Sound); + if(soundID == UUID.Zero) + return; + + m_SoundModule.LoopSound(m_host.UUID, soundID, volume, true, false); } public void llLoopSoundSlave(string sound, double volume) { m_host.AddScriptLPS(1); - if (m_SoundModule != null) - { - m_SoundModule.LoopSound(m_host.UUID, ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound), - volume, 20, false, true); - } + + if (m_SoundModule == null) + return; + + UUID soundID = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound, AssetType.Sound); + if(soundID == UUID.Zero) + return; + + m_SoundModule.LoopSound(m_host.UUID, soundID, volume, false, true); } public void llPlaySoundSlave(string sound, double volume) { m_host.AddScriptLPS(1); + if (m_SoundModule == null) + return; + + UUID soundID = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound, AssetType.Sound); + if(soundID == UUID.Zero) + return; + // send the sound, once, to all clients in range - if (m_SoundModule != null) - { - m_SoundModule.SendSound(m_host.UUID, - ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound, AssetType.Sound), volume, false, 0, - 0, true, false); - } + m_SoundModule.SendSound(m_host.UUID, soundID, volume, false, 0, true, false); } public void llTriggerSound(string sound, double volume) { m_host.AddScriptLPS(1); + + if (m_SoundModule == null) + return; + + UUID soundID = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound, AssetType.Sound); + if(soundID == UUID.Zero) + return; + // send the sound, once, to all clients in rangeTrigger or play an attached sound in this part's inventory. - if (m_SoundModule != null) - { - m_SoundModule.SendSound(m_host.UUID, - ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound, AssetType.Sound), volume, true, 0, 0, - false, false); - } + m_SoundModule.SendSound(m_host.UUID, soundID, volume, true, 0, false, false); } public void llStopSound() @@ -3214,8 +3261,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void llPreloadSound(string sound) { m_host.AddScriptLPS(1); - if (m_SoundModule != null) - m_SoundModule.PreloadSound(m_host.UUID, ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound), 0); + + if (m_SoundModule == null) + return; + + UUID soundID = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound, AssetType.Sound); + if(soundID == UUID.Zero) + return; + + m_SoundModule.PreloadSound(m_host.UUID, soundID); ScriptSleep(m_sleepMsOnPreloadSound); } @@ -3525,32 +3579,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void doObjectRez(string inventory, LSL_Vector pos, LSL_Vector vel, LSL_Rotation rot, int param, bool atRoot) { m_host.AddScriptLPS(1); + if (Double.IsNaN(rot.x) || Double.IsNaN(rot.y) || Double.IsNaN(rot.z) || Double.IsNaN(rot.s)) + return; + + float dist = (float)llVecDist(llGetPos(), pos); + + if (dist > m_ScriptDistanceFactor * 10.0f) + return; + + TaskInventoryItem item = m_host.Inventory.GetInventoryItem(inventory); + + if (item == null) + { + Error("llRez(AtRoot/Object)", "Can't find object '" + inventory + "'"); + return; + } + + if (item.InvType != (int)InventoryType.Object) + { + Error("llRez(AtRoot/Object)", "Can't create requested object; object is missing from database"); + return; + } Util.FireAndForget(x => { - if (Double.IsNaN(rot.x) || Double.IsNaN(rot.y) || Double.IsNaN(rot.z) || Double.IsNaN(rot.s)) - return; - float dist = (float)llVecDist(llGetPos(), pos); - - if (dist > m_ScriptDistanceFactor * 10.0f) - return; - - TaskInventoryItem item = m_host.Inventory.GetInventoryItem(inventory); - - if (item == null) - { - Error("llRez(AtRoot/Object)", "Can't find object '" + inventory + "'"); - return; - } - - if (item.InvType != (int)InventoryType.Object) - { - Error("llRez(AtRoot/Object)", "Can't create requested object; object is missing from database"); - return; - } - - List new_groups = World.RezObject(m_host, item, pos, rot, vel, param, atRoot); + Quaternion wrot = rot; + wrot.Normalize(); + List new_groups = World.RezObject(m_host, item, pos, wrot, vel, param, atRoot); // If either of these are null, then there was an unknown error. if (new_groups == null) @@ -3587,9 +3643,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } } } - // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) - } - + } }, null, "LSL_Api.doObjectRez"); //ScriptSleep((int)((groupmass * velmag) / 10)); @@ -3847,7 +3901,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api Deprecated("llReleaseCamera", "Use llClearCameraParams instead"); } - public LSL_String llGetOwner() + public LSL_Key llGetOwner() { m_host.AddScriptLPS(1); @@ -3979,7 +4033,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } - public LSL_String llGetKey() + public LSL_Key llGetKey() { m_host.AddScriptLPS(1); return m_host.UUID.ToString(); @@ -4305,7 +4359,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api new DetectParams[0])); } - public LSL_String llGetPermissionsKey() + public LSL_Key llGetPermissionsKey() { m_host.AddScriptLPS(1); @@ -4556,7 +4610,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api parentPrim.ScheduleGroupForFullUpdate(); } - public LSL_String llGetLinkKey(int linknum) + public LSL_Key llGetLinkKey(int linknum) { m_host.AddScriptLPS(1); SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum); @@ -4818,7 +4872,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.PassTouches = false; } - public LSL_String llRequestAgentData(string id, int data) + public LSL_Key llRequestAgentData(string id, int data) { m_host.AddScriptLPS(1); @@ -4936,7 +4990,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return ""; } - public LSL_String llRequestInventoryData(string name) + public LSL_Key llRequestInventoryData(string name) { m_host.AddScriptLPS(1); @@ -5450,20 +5504,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); - return GetNumberOfSides(m_host); + return m_host.GetNumberOfSides(); } protected int GetNumberOfSides(SceneObjectPart part) { - int sides = part.GetNumberOfSides(); - - if (part.GetPrimType() == PrimType.SPHERE && part.Shape.ProfileHollow > 0) - { - // Make up for a bug where LSL shows 4 sides rather than 2 - sides += 2; - } - - return sides; + return part.GetNumberOfSides(); } @@ -5518,20 +5564,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); - if (Math.Abs(rot.s) > 1) // normalization needed - rot.Normalize(); + rot.Normalize(); double s = Math.Sqrt(1 - rot.s * rot.s); - if (s < 0.001) - { - return new LSL_Vector(1, 0, 0); - } - else - { - double invS = 1.0 / s; - if (rot.s < 0) invS = -invS; - return new LSL_Vector(rot.x * invS, rot.y * invS, rot.z * invS); - } + if (s < 1e-8) + return new LSL_Vector(0, 0, 0); + + double invS = 1.0 / s; + if (rot.s < 0) + invS = -invS; + return new LSL_Vector(rot.x * invS, rot.y * invS, rot.z * invS); } @@ -5540,8 +5582,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); - if (Math.Abs(rot.s) > 1) // normalization needed - rot.Normalize(); + rot.Normalize(); double angle = 2 * Math.Acos(rot.s); if (angle > Math.PI) @@ -5577,7 +5618,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return Math.Acos(2 * quotient - 1); } - public LSL_String llGetInventoryKey(string name) + public LSL_Key llGetInventoryKey(string name) { m_host.AddScriptLPS(1); @@ -5697,7 +5738,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return source.IndexOf(pattern); } - public LSL_String llGetOwnerKey(string id) + public LSL_Key llGetOwnerKey(string id) { m_host.AddScriptLPS(1); UUID key = new UUID(); @@ -5751,29 +5792,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); if (index < 0) - { index = src.Length + index; - } + if (index >= src.Length || index < 0) - { return 0; - } + + object item = src.Data[index]; // Vectors & Rotations always return zero in SL, but // keys don't always return zero, it seems to be a bit complex. - else if (src.Data[index] is LSL_Vector || - src.Data[index] is LSL_Rotation) - { + if (item is LSL_Vector || item is LSL_Rotation) return 0; - } + try { - - if (src.Data[index] is LSL_Integer) - return (LSL_Integer)src.Data[index]; - else if (src.Data[index] is LSL_Float) - return Convert.ToInt32(((LSL_Float)src.Data[index]).value); - return new LSL_Integer(src.Data[index].ToString()); + if (item is LSL_Integer) + return (LSL_Integer)item; + else if (item is LSL_Float) + return Convert.ToInt32(((LSL_Float)item).value);; + return new LSL_Integer(item.ToString()); } catch (FormatException) { @@ -5785,38 +5822,38 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); if (index < 0) - { index = src.Length + index; - } + if (index >= src.Length || index < 0) - { - return 0.0; - } + return 0; + + object item = src.Data[index]; // Vectors & Rotations always return zero in SL - else if (src.Data[index] is LSL_Vector || - src.Data[index] is LSL_Rotation) - { + if(item is LSL_Vector || item is LSL_Rotation) return 0; - } + // valid keys seem to get parsed as integers then converted to floats - else + if (item is LSL_Key) { UUID uuidt; - if (src.Data[index] is LSL_Key && UUID.TryParse(src.Data[index].ToString(), out uuidt)) - { - return Convert.ToDouble(new LSL_Integer(src.Data[index].ToString()).value); - } + string s = item.ToString(); + if(UUID.TryParse(s, out uuidt)) + return Convert.ToDouble(new LSL_Integer(s).value); +// we can't do this because a string is also a LSL_Key for now :( +// else +// return 0; } + try { - if (src.Data[index] is LSL_Integer) - return Convert.ToDouble(((LSL_Integer)src.Data[index]).value); - else if (src.Data[index] is LSL_Float) - return Convert.ToDouble(((LSL_Float)src.Data[index]).value); - else if (src.Data[index] is LSL_String) + if (item is LSL_Integer) + return Convert.ToDouble(((LSL_Integer)item).value); + else if (item is LSL_Float) + return Convert.ToDouble(((LSL_Float)item).value); + else if (item is LSL_String) { - string str = ((LSL_String) src.Data[index]).m_string; + string str = ((LSL_String)item).m_string; Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)"); if (m != Match.Empty) { @@ -5824,12 +5861,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api double d = 0.0; if (!Double.TryParse(str, out d)) return 0.0; - return d; } return 0.0; } - return Convert.ToDouble(src.Data[index]); + return Convert.ToDouble(item); } catch (FormatException) { @@ -5841,13 +5877,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); if (index < 0) - { index = src.Length + index; - } + if (index >= src.Length || index < 0) - { return String.Empty; - } + return src.Data[index].ToString(); } @@ -5855,14 +5889,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); if (index < 0) - { index = src.Length + index; - } if (index >= src.Length || index < 0) - { - return ""; - } + return String.Empty; + + object item = src.Data[index]; // SL spits out an empty string for types other than key & string // At the time of patching, LSL_Key is currently LSL_String, @@ -5871,31 +5903,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // as it's own struct // NOTE: 3rd case is needed because a NULL_KEY comes through as // type 'obj' and wrongly returns "" - else if (!(src.Data[index] is LSL_String || - src.Data[index] is LSL_Key || - src.Data[index].ToString() == "00000000-0000-0000-0000-000000000000")) + if (!(item is LSL_String || + item is LSL_Key || + item.ToString() == "00000000-0000-0000-0000-000000000000")) { - return ""; + return String.Empty; } - return src.Data[index].ToString(); + return item.ToString(); } public LSL_Vector llList2Vector(LSL_List src, int index) { m_host.AddScriptLPS(1); if (index < 0) - { index = src.Length + index; - } + if (index >= src.Length || index < 0) - { return new LSL_Vector(0, 0, 0); - } - if (src.Data[index].GetType() == typeof(LSL_Vector)) - { - return (LSL_Vector)src.Data[index]; - } + + object item = src.Data[index]; + + if (item.GetType() == typeof(LSL_Vector)) + return (LSL_Vector)item; // SL spits always out ZERO_VECTOR for anything other than // strings or vectors. Although keys always return ZERO_VECTOR, @@ -5903,28 +5933,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // a string, a key as string and a string that by coincidence // is a string, so we're going to leave that up to the // LSL_Vector constructor. - else if (!(src.Data[index] is LSL_String || - src.Data[index] is LSL_Vector)) - { - return new LSL_Vector(0, 0, 0); - } - else - { - return new LSL_Vector(src.Data[index].ToString()); - } + if(item is LSL_Vector) + return (LSL_Vector) item; + + if (item is LSL_String) + return new LSL_Vector(item.ToString()); + + return new LSL_Vector(0, 0, 0); } public LSL_Rotation llList2Rot(LSL_List src, int index) { m_host.AddScriptLPS(1); if (index < 0) - { index = src.Length + index; - } + if (index >= src.Length || index < 0) - { return new LSL_Rotation(0, 0, 0, 1); - } + + object item = src.Data[index]; // SL spits always out ZERO_ROTATION for anything other than // strings or vectors. Although keys always return ZERO_ROTATION, @@ -5932,19 +5959,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // a string, a key as string and a string that by coincidence // is a string, so we're going to leave that up to the // LSL_Rotation constructor. - else if (!(src.Data[index] is LSL_String || - src.Data[index] is LSL_Rotation)) - { - return new LSL_Rotation(0, 0, 0, 1); - } - else if (src.Data[index].GetType() == typeof(LSL_Rotation)) - { - return (LSL_Rotation)src.Data[index]; - } - else - { + + if (item.GetType() == typeof(LSL_Rotation)) + return (LSL_Rotation)item; + + if (item is LSL_String) return new LSL_Rotation(src.Data[index].ToString()); - } + + return new LSL_Rotation(0, 0, 0, 1); } public LSL_List llList2List(LSL_List src, int start, int end) @@ -6654,11 +6676,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api /// AGENT_LIST_PARCEL - all in the same parcel as the scripted object /// AGENT_LIST_PARCEL_OWNER - all in any parcel owned by the owner of the /// current parcel. + /// AGENT_LIST_EXCLUDENPC ignore NPCs (bit mask) /// public LSL_List llGetAgentList(LSL_Integer scope, LSL_List options) { m_host.AddScriptLPS(1); + // do our bit masks part + bool noNPC = (scope & ScriptBaseClass.AGENT_LIST_EXCLUDENPC) !=0; + + // remove bit masks part + scope &= ~ ScriptBaseClass.AGENT_LIST_EXCLUDENPC; + // the constants are 1, 2 and 4 so bits are being set, but you // get an error "INVALID_SCOPE" if it is anything but 1, 2 and 4 bool regionWide = scope == ScriptBaseClass.AGENT_LIST_REGION; @@ -6699,6 +6728,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api World.ForEachRootScenePresence( delegate (ScenePresence ssp) { + if(noNPC && ssp.IsNPC) + return; + // Gods are not listed in SL if (!ssp.IsDeleted && !ssp.IsViewerUIGod && !ssp.IsChildAgent) { @@ -6842,7 +6874,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (m_host.OwnerID == land.LandData.OwnerID) { Vector3 p = World.GetNearestAllowedPosition(presence, land); - presence.TeleportWithMomentum(p, null); + presence.TeleportOnEject(p); presence.ControllingClient.SendAlertMessage("You have been ejected from this land"); } } @@ -6861,28 +6893,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api UUID key = new UUID(); if (UUID.TryParse(id, out key)) { - ScenePresence presence = World.GetScenePresence(key); - if (presence != null) // object is an avatar + try { - if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID) - return 1; - } - else // object is not an avatar - { - SceneObjectPart obj = World.GetSceneObjectPart(key); - - if (obj != null) + ScenePresence presence = World.GetScenePresence(key); + if (presence != null) // object is an avatar { - if (m_host.OwnerID == World.LandChannel.GetLandObject(obj.AbsolutePosition).LandData.OwnerID) + if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID) return 1; } + else // object is not an avatar + { + SceneObjectPart obj = World.GetSceneObjectPart(key); + + if (obj != null && + m_host.OwnerID == World.LandChannel.GetLandObject(obj.AbsolutePosition).LandData.OwnerID) + return 1; + } } + catch { } } return 0; } - public LSL_String llGetLandOwnerAt(LSL_Vector pos) + public LSL_Key llGetLandOwnerAt(LSL_Vector pos) { m_host.AddScriptLPS(1); ILandObject land = World.LandChannel.GetLandObject((float)pos.x, (float)pos.y); @@ -7832,14 +7866,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } } - public LSL_String llAvatarOnSitTarget() + public LSL_Key llAvatarOnSitTarget() { m_host.AddScriptLPS(1); return m_host.SitTargetAvatar.ToString(); } // http://wiki.secondlife.com/wiki/LlAvatarOnLinkSitTarget - public LSL_String llAvatarOnLinkSitTarget(int linknum) + public LSL_Key llAvatarOnLinkSitTarget(int linknum) { m_host.AddScriptLPS(1); if(linknum == ScriptBaseClass.LINK_SET || @@ -7861,7 +7895,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api UUID key; ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition); - if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned, false)) + if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManagePasses, false)) { int expires = 0; if (hours != 0) @@ -8144,7 +8178,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api ScriptSleep(m_sleepMsOnOpenRemoteDataChannel); } - public LSL_String llSendRemoteData(string channel, string dest, int idata, string sdata) + public LSL_Key llSendRemoteData(string channel, string dest, int idata, string sdata) { m_host.AddScriptLPS(1); IXMLRPC xmlrpcMod = m_ScriptEngine.World.RequestModuleInterface(); @@ -8901,6 +8935,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api SceneObjectGroup parentgrp = part.ParentGroup; bool positionChanged = false; + bool materialChanged = false; LSL_Vector currentPosition = GetPartLocalPos(part); try @@ -10197,6 +10232,231 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api break; + case ScriptBaseClass.PRIM_ALPHA_MODE: + if (remain < 3) + return new LSL_List(); + + try + { + face = rules.GetLSLIntegerItem(idx++); + } + catch(InvalidCastException) + { + Error(originFunc, string.Format("Error running rule #{0} -> PRIM_ALPHA_MODE: arg #{1} - must be integer", rulesParsed, idx - idxStart - 1)); + return new LSL_List(); + } + + int materialAlphaMode; + try + { + materialAlphaMode = rules.GetLSLIntegerItem(idx++); + } + catch(InvalidCastException) + { + Error(originFunc, string.Format("Error running rule #{0} -> PRIM_ALPHA_MODE: arg #{1} - must be integer", rulesParsed, idx - idxStart - 1)); + return new LSL_List(); + } + + if(materialAlphaMode < 0 || materialAlphaMode > 3) + { + Error(originFunc, string.Format("Error running rule #{0} -> PRIM_ALPHA_MODE: arg #{1} - must be 0 to 3", rulesParsed, idx - idxStart - 1)); + return new LSL_List(); + } + + int materialMaskCutoff; + try + { + materialMaskCutoff = rules.GetLSLIntegerItem(idx++); + } + catch(InvalidCastException) + { + Error(originFunc, string.Format("Error running rule #{0} -> PRIM_ALPHA_MODE: arg #{1} - must be integer", rulesParsed, idx - idxStart - 1)); + return new LSL_List(); + } + + if(materialMaskCutoff < 0 || materialMaskCutoff > 255) + { + Error(originFunc, string.Format("Error running rule #{0} -> PRIM_ALPHA_MODE: arg #{1} - must be 0 to 255", rulesParsed, idx - idxStart - 1)); + return new LSL_List(); + } + + materialChanged |= SetMaterialAlphaMode(part, face, materialAlphaMode, materialMaskCutoff); + break; + + case ScriptBaseClass.PRIM_NORMAL: + if (remain < 5) + return new LSL_List(); + + try + { + face = rules.GetLSLIntegerItem(idx++); + } + catch(InvalidCastException) + { + Error(originFunc, string.Format("Error running rule #{0} -> PRIM_NORMAL: arg #{1} - must be integer", rulesParsed, idx - idxStart - 1)); + return new LSL_List(); + } + + string mapname = rules.Data[idx++].ToString(); + + UUID mapID = ScriptUtils.GetAssetIdFromItemName(m_host, mapname, (int)AssetType.Texture); + if (mapID == UUID.Zero) + { + if (!UUID.TryParse(mapname, out mapID)) + { + Error(originFunc, string.Format("Error running rule #{0} -> PRIM_NORMAL: arg #{1} - must be a UUID or a texture name on object inventory", rulesParsed, idx - idxStart - 1)); + return new LSL_List(); + } + } + + LSL_Vector mnrepeat; + try + { + mnrepeat = rules.GetVector3Item(idx++); + } + catch(InvalidCastException) + { + Error(originFunc, string.Format("Error running rule #{0} -> PRIM_NORMAL: arg #{1} - must be vector", rulesParsed, idx - idxStart - 1)); + return new LSL_List(); + } + + LSL_Vector mnoffset; + try + { + mnoffset = rules.GetVector3Item(idx++); + } + catch(InvalidCastException) + { + Error(originFunc, string.Format("Error running rule #{0} -> PRIM_NORMAL: arg #{1} - must be vector", rulesParsed, idx - idxStart - 1)); + return new LSL_List(); + } + + LSL_Float mnrot; + try + { + mnrot = rules.GetLSLFloatItem(idx++); + } + catch(InvalidCastException) + { + Error(originFunc, string.Format("Error running rule #{0} -> PRIM_NORMAL: arg #{1} - must be float", rulesParsed, idx - idxStart - 1)); + return new LSL_List(); + } + + float repeatX = (float)Util.Clamp(mnrepeat.x,-100.0, 100.0); + float repeatY = (float)Util.Clamp(mnrepeat.y,-100.0, 100.0); + float offsetX = (float)Util.Clamp(mnoffset.x, 0, 1.0); + float offsetY = (float)Util.Clamp(mnoffset.y, 0, 1.0); + + materialChanged |= SetMaterialNormalMap(part, face, mapID, repeatX, repeatY, offsetX, offsetY, (float)mnrot); + break; + + case ScriptBaseClass.PRIM_SPECULAR: + if (remain < 8) + return new LSL_List(); + + try + { + face = rules.GetLSLIntegerItem(idx++); + } + catch(InvalidCastException) + { + Error(originFunc, string.Format("Error running rule #{0} -> PRIM_SPECULAR: arg #{1} - must be integer", rulesParsed, idx - idxStart - 1)); + return new LSL_List(); + } + + string smapname = rules.Data[idx++].ToString(); + + UUID smapID = ScriptUtils.GetAssetIdFromItemName(m_host, smapname, (int)AssetType.Texture); + if (smapID == UUID.Zero) + { + if (!UUID.TryParse(smapname, out smapID)) + { + Error(originFunc, string.Format("Error running rule #{0} -> PRIM_SPECULAR: arg #{1} - must be a UUID or a texture name on object inventory", rulesParsed, idx - idxStart - 1)); + return new LSL_List(); + } + } + + LSL_Vector msrepeat; + try + { + msrepeat = rules.GetVector3Item(idx++); + } + catch(InvalidCastException) + { + Error(originFunc, string.Format("Error running rule #{0} -> PRIM_SPECULAR: arg #{1} - must be vector", rulesParsed, idx - idxStart - 1)); + return new LSL_List(); + } + + LSL_Vector msoffset; + try + { + msoffset = rules.GetVector3Item(idx++); + } + catch(InvalidCastException) + { + Error(originFunc, string.Format("Error running rule #{0} -> PRIM_SPECULAR: arg #{1} - must be vector", rulesParsed, idx - idxStart - 1)); + return new LSL_List(); + } + + LSL_Float msrot; + try + { + msrot = rules.GetLSLFloatItem(idx++); + } + catch(InvalidCastException) + { + Error(originFunc, string.Format("Error running rule #{0} -> PRIM_SPECULAR: arg #{1} - must be float", rulesParsed, idx - idxStart - 1)); + return new LSL_List(); + } + + LSL_Vector mscolor; + try + { + mscolor = rules.GetVector3Item(idx++); + } + catch(InvalidCastException) + { + Error(originFunc, string.Format("Error running rule #{0} -> PRIM_SPECULAR: arg #{1} - must be vector", rulesParsed, idx - idxStart - 1)); + return new LSL_List(); + } + + LSL_Integer msgloss; + try + { + msgloss = rules.GetLSLIntegerItem(idx++); + } + catch(InvalidCastException) + { + Error(originFunc, string.Format("Error running rule #{0} -> PRIM_SPECULAR: arg #{1} - must be integer", rulesParsed, idx - idxStart - 1)); + return new LSL_List(); + } + + LSL_Integer msenv; + try + { + msenv = rules.GetLSLIntegerItem(idx++); + } + catch(InvalidCastException) + { + Error(originFunc, string.Format("Error running rule #{0} -> PRIM_SPECULAR: arg #{1} - must be integer", rulesParsed, idx - idxStart - 1)); + return new LSL_List(); + } + + float srepeatX = (float)Util.Clamp(msrepeat.x, -100.0, 100.0); + float srepeatY = (float)Util.Clamp(msrepeat.y, -100.0, 100.0); + float soffsetX = (float)Util.Clamp(msoffset.x, -1.0, 1.0); + float soffsetY = (float)Util.Clamp(msoffset.y, -1.0, 1.0); + byte colorR = (byte)(255.0 * Util.Clamp(mscolor.x, 0, 1.0) + 0.5); + byte colorG = (byte)(255.0 * Util.Clamp(mscolor.y, 0, 1.0) + 0.5); + byte colorB = (byte)(255.0 * Util.Clamp(mscolor.z, 0, 1.0) + 0.5); + byte gloss = (byte)Util.Clamp((int)msgloss, 0, 255); + byte env = (byte)Util.Clamp((int)msenv, 0, 255); + + materialChanged |= SetMaterialSpecMap(part, face, smapID, srepeatX, srepeatY, soffsetX, soffsetY, + (float)msrot, colorR, colorG, colorB, gloss, env); + + break; + case ScriptBaseClass.PRIM_LINK_TARGET: if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless. return new LSL_List(); @@ -10233,11 +10493,194 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api part.ScheduleTerseUpdate(); } } + if(materialChanged) + { + if (part.ParentGroup != null && !part.ParentGroup.IsDeleted) + { + part.TriggerScriptChangedEvent(Changed.TEXTURE); + part.ScheduleFullUpdate(); + part.ParentGroup.HasGroupChanged = true; + } + } } return new LSL_List(); } + protected bool SetMaterialAlphaMode(SceneObjectPart part, int face, int materialAlphaMode, int materialMaskCutoff) + { + if(m_materialsModule == null) + return false; + + int nsides = part.GetNumberOfSides(); + + if(face == ScriptBaseClass.ALL_SIDES) + { + bool changed = false; + for(int i = 0; i < nsides; i++) + changed |= SetFaceMaterialAlphaMode(part, i, materialAlphaMode, materialMaskCutoff); + return changed; + } + + if( face >= 0 && face < nsides) + return SetFaceMaterialAlphaMode(part, face, materialAlphaMode, materialMaskCutoff); + + return false; + } + + protected bool SetFaceMaterialAlphaMode(SceneObjectPart part, int face, int materialAlphaMode, int materialMaskCutoff) + { + Primitive.TextureEntry tex = part.Shape.Textures; + Primitive.TextureEntryFace texface = tex.CreateFace((uint)face); + if(texface == null) + return false; + + FaceMaterial mat = null; + UUID oldid = texface.MaterialID; + + if(oldid != UUID.Zero) + mat = m_materialsModule.GetMaterialCopy(oldid); + + if(mat == null) + mat = new FaceMaterial(); + + mat.DiffuseAlphaMode = (byte)materialAlphaMode; + mat.AlphaMaskCutoff = (byte)materialMaskCutoff; + + UUID id = m_materialsModule.AddNewMaterial(mat); + if(oldid == id) + return false; + + texface.MaterialID = id; + part.Shape.TextureEntry = tex.GetBytes(); + m_materialsModule.RemoveMaterial(oldid); + return true; + } + + protected bool SetMaterialNormalMap(SceneObjectPart part, int face, UUID mapID, float repeatX, float repeatY, + float offsetX, float offsetY, float rot) + { + if(m_materialsModule == null) + return false; + + int nsides = part.GetNumberOfSides(); + + if(face == ScriptBaseClass.ALL_SIDES) + { + bool changed = false; + for(int i = 0; i < nsides; i++) + changed |= SetFaceMaterialNormalMap(part, i, mapID, repeatX, repeatY, offsetX, offsetY, rot); + return changed; + } + + if( face >= 0 && face < nsides) + return SetFaceMaterialNormalMap(part, face, mapID, repeatX, repeatY, offsetX, offsetY, rot); + + return false; + } + + protected bool SetFaceMaterialNormalMap(SceneObjectPart part, int face, UUID mapID, float repeatX, float repeatY, + float offsetX, float offsetY, float rot) + + { + Primitive.TextureEntry tex = part.Shape.Textures; + Primitive.TextureEntryFace texface = tex.CreateFace((uint)face); + if(texface == null) + return false; + + FaceMaterial mat = null; + UUID oldid = texface.MaterialID; + + if(oldid != UUID.Zero) + mat = m_materialsModule.GetMaterialCopy(oldid); + + if(mat == null) + mat = new FaceMaterial(); + + mat.NormalMapID = mapID; + mat.NormalOffsetX = offsetX; + mat.NormalOffsetY = offsetY; + mat.NormalRepeatX = repeatX; + mat.NormalRepeatY = repeatY; + mat.NormalRotation = rot; + + UUID id = m_materialsModule.AddNewMaterial(mat); + if(oldid == id) + return false; + + texface.MaterialID = id; + part.Shape.TextureEntry = tex.GetBytes(); + m_materialsModule.RemoveMaterial(oldid); + return true; + } + + protected bool SetMaterialSpecMap(SceneObjectPart part, int face, UUID mapID, float repeatX, float repeatY, + float offsetX, float offsetY, float rot, + byte colorR, byte colorG, byte colorB, + byte gloss, byte env) + { + if(m_materialsModule == null) + return false; + + int nsides = part.GetNumberOfSides(); + + if(face == ScriptBaseClass.ALL_SIDES) + { + bool changed = false; + for(int i = 0; i < nsides; i++) + changed |= SetFaceMaterialSpecMap(part, i, mapID, repeatX, repeatY, offsetX, offsetY, rot, + colorR, colorG, colorB, gloss, env); + return changed; + } + + if( face >= 0 && face < nsides) + return SetFaceMaterialSpecMap(part, face, mapID, repeatX, repeatY, offsetX, offsetY, rot, + colorR, colorG, colorB, gloss, env); + + return false; + } + + protected bool SetFaceMaterialSpecMap(SceneObjectPart part, int face, UUID mapID, float repeatX, float repeatY, + float offsetX, float offsetY, float rot, + byte colorR, byte colorG, byte colorB, + byte gloss, byte env) + { + Primitive.TextureEntry tex = part.Shape.Textures; + Primitive.TextureEntryFace texface = tex.CreateFace((uint)face); + if(texface == null) + return false; + + FaceMaterial mat = null; + UUID oldid = texface.MaterialID; + + if(oldid != UUID.Zero) + mat = m_materialsModule.GetMaterialCopy(oldid); + + if(mat == null) + mat = new FaceMaterial(); + + mat.SpecularMapID = mapID; + mat.SpecularOffsetX = offsetX; + mat.SpecularOffsetY = offsetY; + mat.SpecularRepeatX = repeatX; + mat.SpecularRepeatY = repeatY; + mat.SpecularRotation = rot; + mat.SpecularLightColorR = colorR; + mat.SpecularLightColorG = colorG; + mat.SpecularLightColorB = colorB; + mat.SpecularLightExponent = gloss; + mat.EnvironmentIntensity = env; + + UUID id = m_materialsModule.AddNewMaterial(mat); + if(oldid == id) + return false; + + texface.MaterialID = id; + part.Shape.TextureEntry = tex.GetBytes(); + m_materialsModule.RemoveMaterial(oldid); + return true; + } + protected LSL_List SetAgentParams(ScenePresence sp, LSL_List rules, string originFunc, ref uint rulesParsed) { int idx = 0; @@ -10589,7 +11032,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.Description = desc!=null?desc:String.Empty; } - public LSL_String llGetCreator() + public LSL_Key llGetCreator() { m_host.AddScriptLPS(1); return m_host.CreatorID.ToString(); @@ -10849,6 +11292,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_List GetPrimParams(SceneObjectPart part, LSL_List rules, ref LSL_List res) { int idx = 0; + int face; + Primitive.TextureEntry tex; + int nsides = GetNumberOfSides(part); + while (idx < rules.Length) { int code = (int)rules.GetLSLIntegerItem(idx++); @@ -10989,11 +11436,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (remain < 1) return new LSL_List(); - int face = (int)rules.GetLSLIntegerItem(idx++); - Primitive.TextureEntry tex = part.Shape.Textures; + face = (int)rules.GetLSLIntegerItem(idx++); + tex = part.Shape.Textures; + if (face == ScriptBaseClass.ALL_SIDES) { - for (face = 0; face < GetNumberOfSides(part); face++) + for (face = 0; face < nsides; face++) { Primitive.TextureEntryFace texface = tex.GetFace((uint)face); @@ -11009,7 +11457,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } else { - if (face >= 0 && face < GetNumberOfSides(part)) + if (face >= 0 && face < nsides) { Primitive.TextureEntryFace texface = tex.GetFace((uint)face); @@ -11030,12 +11478,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return new LSL_List(); face = (int)rules.GetLSLIntegerItem(idx++); - tex = part.Shape.Textures; Color4 texcolor; + if (face == ScriptBaseClass.ALL_SIDES) { - for (face = 0; face < GetNumberOfSides(part); face++) + for (face = 0; face < nsides; face++) { texcolor = tex.GetFace((uint)face).RGBA; res.Add(new LSL_Vector(texcolor.R, @@ -11055,16 +11503,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api break; case (int)ScriptBaseClass.PRIM_BUMP_SHINY: + { if (remain < 1) return new LSL_List(); face = (int)rules.GetLSLIntegerItem(idx++); - tex = part.Shape.Textures; int shiny; if (face == ScriptBaseClass.ALL_SIDES) { - for (face = 0; face < GetNumberOfSides(part); face++) + for (face = 0; face < nsides; face++) { Shininess shinyness = tex.GetFace((uint)face).Shiny; if (shinyness == Shininess.High) @@ -11110,8 +11558,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump)); } break; - + } case (int)ScriptBaseClass.PRIM_FULLBRIGHT: + { if (remain < 1) return new LSL_List(); @@ -11121,7 +11570,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api int fullbright; if (face == ScriptBaseClass.ALL_SIDES) { - for (face = 0; face < GetNumberOfSides(part); face++) + for (face = 0; face < nsides; face++) { if (tex.GetFace((uint)face).Fullbright == true) { @@ -11147,7 +11596,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api res.Add(new LSL_Integer(fullbright)); } break; - + } case (int)ScriptBaseClass.PRIM_FLEXIBLE: PrimitiveBaseShape shape = part.Shape; @@ -11175,7 +11624,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api tex = part.Shape.Textures; if (face == ScriptBaseClass.ALL_SIDES) { - for (face = 0; face < GetNumberOfSides(part); face++) + for (face = 0; face < nsides; face++) { if (tex.GetFace((uint)face).TexMapType == MappingType.Planar) { @@ -11225,7 +11674,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api float primglow; if (face == ScriptBaseClass.ALL_SIDES) { - for (face = 0; face < GetNumberOfSides(part); face++) + for (face = 0; face < nsides; face++) { primglow = tex.GetFace((uint)face).Glow; res.Add(new LSL_Float(primglow)); @@ -11309,6 +11758,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } break; + case (int)ScriptBaseClass.PRIM_NORMAL: + case (int)ScriptBaseClass.PRIM_SPECULAR: + case (int)ScriptBaseClass.PRIM_ALPHA_MODE: + if (remain < 1) + return new LSL_List(); + + face = (int)rules.GetLSLIntegerItem(idx++); + tex = part.Shape.Textures; + if (face == ScriptBaseClass.ALL_SIDES) + { + for (face = 0; face < nsides; face++) + { + Primitive.TextureEntryFace texface = tex.GetFace((uint)face); + getLSLFaceMaterial(ref res, code, part, texface); + } + } + else + { + if (face >= 0 && face < nsides) + { + Primitive.TextureEntryFace texface = tex.GetFace((uint)face); + getLSLFaceMaterial(ref res, code, part, texface); + } + } + break; + case (int)ScriptBaseClass.PRIM_LINK_TARGET: // TODO: Should be issuing a runtime script warning in this case. @@ -11322,6 +11797,84 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return new LSL_List(); } + private string GetMaterialTextureUUIDbyRights(UUID origID, SceneObjectPart part) + { + if(World.Permissions.CanEditObject(m_host.ParentGroup.UUID, m_host.ParentGroup.RootPart.OwnerID)) + return origID.ToString(); + + lock(part.TaskInventory) + { + foreach(KeyValuePair inv in part.TaskInventory) + { + if(inv.Value.InvType == (int)InventoryType.Texture && inv.Value.AssetID == origID) + return origID.ToString(); + } + } + + return UUID.Zero.ToString(); + } + + private void getLSLFaceMaterial(ref LSL_List res, int code, SceneObjectPart part, Primitive.TextureEntryFace texface) + { + UUID matID = UUID.Zero; + if(m_materialsModule != null) + matID = texface.MaterialID; + + if(matID != UUID.Zero) + { + FaceMaterial mat = m_materialsModule.GetMaterial(matID); + if(mat != null) + { + if(code == ScriptBaseClass.PRIM_NORMAL) + { + res.Add(new LSL_String(GetMaterialTextureUUIDbyRights(mat.NormalMapID, part))); + res.Add(new LSL_Vector(mat.NormalRepeatX, mat.NormalRepeatY, 0)); + res.Add(new LSL_Vector(mat.NormalOffsetX, mat.NormalOffsetY, 0)); + res.Add(new LSL_Float(mat.NormalRotation)); + } + else if(code == ScriptBaseClass.PRIM_SPECULAR) + { + const float colorScale = 1.0f / 255f; + res.Add(new LSL_String(GetMaterialTextureUUIDbyRights(mat.SpecularMapID, part))); + res.Add(new LSL_Vector(mat.SpecularRepeatX, mat.SpecularRepeatY, 0)); + res.Add(new LSL_Vector(mat.SpecularOffsetX, mat.SpecularOffsetY, 0)); + res.Add(new LSL_Float(mat.SpecularRotation)); + res.Add(new LSL_Vector(mat.SpecularLightColorR * colorScale, + mat.SpecularLightColorG * colorScale, + mat.SpecularLightColorB * colorScale)); + res.Add(new LSL_Integer(mat.SpecularLightExponent)); + res.Add(new LSL_Integer(mat.EnvironmentIntensity)); + } + else if(code == ScriptBaseClass.PRIM_ALPHA_MODE) + { + res.Add(new LSL_Integer(mat.DiffuseAlphaMode)); + res.Add(new LSL_Integer(mat.AlphaMaskCutoff)); + } + return; + } + } + + // material not found + if(code == (int)ScriptBaseClass.PRIM_NORMAL || code == (int)ScriptBaseClass.PRIM_SPECULAR) + { + res.Add(new LSL_String(UUID.Zero.ToString())); + res.Add(new LSL_Vector(1.0, 1.0, 0)); + res.Add(new LSL_Vector(0, 0, 0)); + res.Add(new LSL_Float(0)); + + if(code == (int)ScriptBaseClass.PRIM_SPECULAR) + { + res.Add(new LSL_Vector(1.0, 1.0, 1.0)); + res.Add(new LSL_Integer(51)); + res.Add(new LSL_Integer(0)); + } + } + else if(code == (int)ScriptBaseClass.PRIM_ALPHA_MODE) + { + res.Add(new LSL_Integer(1)); + res.Add(new LSL_Integer(0)); + } + } public LSL_List llGetPrimMediaParams(int face, LSL_List rules) { @@ -12186,7 +12739,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } } - public LSL_String llGetInventoryCreator(string itemName) + public LSL_Key llGetInventoryCreator(string itemName) { m_host.AddScriptLPS(1); @@ -12212,7 +12765,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // wComm.DeliverMessage(ChatTypeEnum.Owner, 0, m_host.Name, m_host.UUID, msg); } - public LSL_String llRequestSecureURL() + public LSL_Key llRequestSecureURL() { m_host.AddScriptLPS(1); if (m_UrlModule != null) @@ -12220,7 +12773,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return UUID.Zero.ToString(); } - public LSL_String llRequestSimulatorData(string simulator, int data) + public LSL_Key llRequestSimulatorData(string simulator, int data) { IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_item.ItemID, "OSSL"); @@ -12329,7 +12882,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } } - public LSL_String llRequestURL() + public LSL_Key llRequestURL() { m_host.AddScriptLPS(1); @@ -12502,7 +13055,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api for (int i = 0; i < commandList.Data.Length; i++) { - ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; + int cmd; + if(commandList.Data[i] is LSL_Integer) + cmd = (LSL_Integer)commandList.Data[i]; + else + cmd = (int)commandList.Data[i]; + + ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)cmd; + switch (command) { case ParcelMediaCommandEnum.Agent: @@ -12699,14 +13259,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (sp.currentParcelUUID == landData.GlobalID) { sp.ControllingClient.SendParcelMediaCommand(0x4, // TODO what is this? - (ParcelMediaCommandEnum)commandToSend, time); + commandToSend.Value, time); } }); } else if (!presence.IsChildAgent) { presence.ControllingClient.SendParcelMediaCommand(0x4, // TODO what is this? - (ParcelMediaCommandEnum)commandToSend, time); + commandToSend.Value, time); } } ScriptSleep(m_sleepMsOnParcelMediaCommandList); @@ -12955,7 +13515,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); UUID key; ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition); - if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageAllowed, false)) + if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManagePasses, false)) { if (UUID.TryParse(avatar, out key)) { @@ -13275,7 +13835,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return Convert.ToBase64String(data1); } - public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) + public LSL_Key llHTTPRequest(string url, LSL_List parameters, string body) { // Partial implementation: support for parameter flags needed // see http://wiki.secondlife.com/wiki/LlHTTPRequest @@ -13288,6 +13848,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api List param = new List(); bool ok; Int32 flag; + int nCustomHeaders = 0; for (int i = 0; i < parameters.Data.Length; i += 2) { @@ -13314,6 +13875,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api //Second Life documentation for llHTTPRequest. for (int count = 1; count <= 8; ++count) { + if(nCustomHeaders >= 8) + { + Error("llHTTPRequest", "Max number of custom headers is 8, excess ignored"); + break; + } + //Enough parameters remaining for (another) header? if (parameters.Data.Length - i < 2) { @@ -13328,15 +13895,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api param.Add(parameters.Data[i].ToString()); param.Add(parameters.Data[i+1].ToString()); + nCustomHeaders++; //Have we reached the end of the list of headers? //End is marked by a string with a single digit. - if (i+2 >= parameters.Data.Length || - Char.IsDigit(parameters.Data[i].ToString()[0])) + if (i + 2 >= parameters.Data.Length || + Char.IsDigit(parameters.Data[i + 2].ToString()[0])) { break; } - i += 2; } } @@ -14124,7 +14691,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api }); } - public LSL_String llGetNumberOfNotecardLines(string name) + public LSL_Key llGetNumberOfNotecardLines(string name) { m_host.AddScriptLPS(1); @@ -14175,7 +14742,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return tid.ToString(); } - public LSL_String llGetNotecardLine(string name, int line) + public LSL_Key llGetNotecardLine(string name, int line) { m_host.AddScriptLPS(1); @@ -14219,7 +14786,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return; } - string data = Encoding.UTF8.GetString(a.Data); + //string data = Encoding.UTF8.GetString(a.Data); //m_log.Debug(data); NotecardCache.Cache(id, a.Data); AsyncCommands.DataserverPlugin.DataserverReply( @@ -14302,7 +14869,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return Name2Username(llKey2Name(id)); } - public LSL_String llRequestUsername(string id) + public LSL_Key llRequestUsername(string id) { UUID rq = UUID.Random(); @@ -14318,7 +14885,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return llKey2Name(id); } - public LSL_String llRequestDisplayName(string id) + public LSL_Key llRequestDisplayName(string id) { UUID rq = UUID.Random(); @@ -15900,7 +16467,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api new DetectParams[0])); } - public LSL_String llTransferLindenDollars(string destination, int amount) + public LSL_Key llTransferLindenDollars(string destination, int amount) { UUID txn = UUID.Random(); @@ -16576,92 +17143,158 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return String.Empty; } - public LSL_String llJsonGetValue(LSL_String json, LSL_List specifiers) - { - OSD o = OSDParser.DeserializeJson(json); - OSD specVal = JsonGetSpecific(o, specifiers, 0); - - return specVal.AsString(); - } - public LSL_List llJson2List(LSL_String json) { + if(String.IsNullOrEmpty(json)) + return new LSL_List(); + if(json == "[]") + return new LSL_List(); + if(json == "{}") + return new LSL_List(); + char first = ((string)json)[0]; + + if(first != '[' && first !='{') + { + // we already have a single element + LSL_List l = new LSL_List(); + l.Add(json); + return l; + } + + LitJson.JsonData jsdata; try { - OSD o = OSDParser.DeserializeJson(json); - return (LSL_List)ParseJsonNode(o); + jsdata = LitJson.JsonMapper.ToObject(json); } - catch (Exception) + catch (Exception e) { - return new LSL_List(ScriptBaseClass.JSON_INVALID); + string m = e.Message; // debug point + return json; + } + try + { + return JsonParseTop(jsdata); + } + catch (Exception e) + { + string m = e.Message; // debug point + return (LSL_String)ScriptBaseClass.JSON_INVALID; } } - private object ParseJsonNode(OSD node) + private LSL_List JsonParseTop(LitJson.JsonData elem) { - if (node.Type == OSDType.Integer) - return new LSL_Integer(node.AsInteger()); - if (node.Type == OSDType.Boolean) - return new LSL_Integer(node.AsBoolean() ? 1 : 0); - if (node.Type == OSDType.Real) - return new LSL_Float(node.AsReal()); - if (node.Type == OSDType.UUID || node.Type == OSDType.String) - return new LSL_String(node.AsString()); - if (node.Type == OSDType.Array) + LSL_List retl = new LSL_List(); + if(elem == null) + retl.Add((LSL_String)ScriptBaseClass.JSON_NULL); + + LitJson.JsonType elemType = elem.GetJsonType(); + switch (elemType) { - LSL_List resp = new LSL_List(); - OSDArray ar = node as OSDArray; - foreach (OSD o in ar) - resp.Add(ParseJsonNode(o)); - return resp; + case LitJson.JsonType.Int: + retl.Add(new LSL_Integer((int)elem)); + return retl; + case LitJson.JsonType.Boolean: + retl.Add((LSL_String)((bool)elem ? ScriptBaseClass.JSON_TRUE : ScriptBaseClass.JSON_FALSE)); + return retl; + case LitJson.JsonType.Double: + retl.Add(new LSL_Float((double)elem)); + return retl; + case LitJson.JsonType.None: + retl.Add((LSL_String)ScriptBaseClass.JSON_NULL); + return retl; + case LitJson.JsonType.String: + retl.Add(new LSL_String((string)elem)); + return retl; + case LitJson.JsonType.Array: + foreach (LitJson.JsonData subelem in elem) + retl.Add(JsonParseTopNodes(subelem)); + return retl; + case LitJson.JsonType.Object: + IDictionaryEnumerator e = ((IOrderedDictionary)elem).GetEnumerator(); + while (e.MoveNext()) + { + retl.Add(new LSL_String((string)e.Key)); + retl.Add(JsonParseTopNodes((LitJson.JsonData)e.Value)); + } + return retl; + default: + throw new Exception(ScriptBaseClass.JSON_INVALID); } - if (node.Type == OSDType.Map) + } + + private object JsonParseTopNodes(LitJson.JsonData elem) + { + if(elem == null) + return ((LSL_String)ScriptBaseClass.JSON_NULL); + + LitJson.JsonType elemType = elem.GetJsonType(); + switch (elemType) { - LSL_List resp = new LSL_List(); - OSDMap ar = node as OSDMap; - foreach (KeyValuePair o in ar) - { - resp.Add(new LSL_String(o.Key)); - resp.Add(ParseJsonNode(o.Value)); - } - return resp; + case LitJson.JsonType.Int: + return (new LSL_Integer((int)elem)); + case LitJson.JsonType.Boolean: + return ((bool)elem ? (LSL_String)ScriptBaseClass.JSON_TRUE : (LSL_String)ScriptBaseClass.JSON_FALSE); + case LitJson.JsonType.Double: + return (new LSL_Float((double)elem)); + case LitJson.JsonType.None: + return ((LSL_String)ScriptBaseClass.JSON_NULL); + case LitJson.JsonType.String: + return (new LSL_String((string)elem)); + case LitJson.JsonType.Array: + case LitJson.JsonType.Object: + string s = LitJson.JsonMapper.ToJson(elem); + return (LSL_String)s; + default: + throw new Exception(ScriptBaseClass.JSON_INVALID); } - throw new Exception(ScriptBaseClass.JSON_INVALID); } public LSL_String llList2Json(LSL_String type, LSL_List values) { try { + StringBuilder sb = new StringBuilder(); if (type == ScriptBaseClass.JSON_ARRAY) { - OSDArray array = new OSDArray(); + sb.Append("["); + int i= 0; foreach (object o in values.Data) { - array.Add(ListToJson(o)); + sb.Append(ListToJson(o)); + if((i++) < values.Data.Length - 1) + sb.Append(","); } - return OSDParser.SerializeJsonString(array); + sb.Append("]"); + return (LSL_String)sb.ToString();; } else if (type == ScriptBaseClass.JSON_OBJECT) { - OSDMap map = new OSDMap(); + sb.Append("{"); for (int i = 0; i < values.Data.Length; i += 2) { if (!(values.Data[i] is LSL_String)) return ScriptBaseClass.JSON_INVALID; - map.Add(((LSL_String)values.Data[i]).m_string, ListToJson(values.Data[i + 1])); + string key = ((LSL_String)values.Data[i]).m_string; + key = EscapeForJSON(key, true); + sb.Append(key); + sb.Append(":"); + sb.Append(ListToJson(values.Data[i+1])); + if(i < values.Data.Length - 2) + sb.Append(","); } - return OSDParser.SerializeJsonString(map); + sb.Append("}"); + return (LSL_String)sb.ToString(); } return ScriptBaseClass.JSON_INVALID; } - catch (Exception ex) + catch { - return ex.Message; + return ScriptBaseClass.JSON_INVALID; } } - private OSD ListToJson(object o) + private string ListToJson(object o) { if (o is LSL_Float || o is double) { @@ -16671,7 +17304,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api else float_val = ((LSL_Float)o).value; - return OSD.FromReal(float_val); + if(double.IsInfinity(float_val)) + return "\"Inf\""; + if(double.IsNaN(float_val)) + return "\"NaN\""; + + return ((LSL_Float)float_val).ToString(); } if (o is LSL_Integer || o is int) { @@ -16680,17 +17318,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api i = ((int)o); else i = ((LSL_Integer)o).value; - - if (i == 0) - return OSD.FromBoolean(false); - else if (i == 1) - return OSD.FromBoolean(true); - return OSD.FromInteger(i); + return i.ToString(); } if (o is LSL_Rotation) - return OSD.FromString(((LSL_Rotation)o).ToString()); + { + StringBuilder sb = new StringBuilder(128); + sb.Append("\""); + LSL_Rotation r = (LSL_Rotation)o; + sb.Append(r.ToString()); + sb.Append("\""); + return sb.ToString(); + } if (o is LSL_Vector) - return OSD.FromString(((LSL_Vector)o).ToString()); + { + StringBuilder sb = new StringBuilder(128); + sb.Append("\""); + LSL_Vector v = (LSL_Vector)o; + sb.Append(v.ToString()); + sb.Append("\""); + return sb.ToString(); + } if (o is LSL_String || o is string) { string str; @@ -16699,137 +17346,579 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api else str = ((LSL_String)o).m_string; - if (str == ScriptBaseClass.JSON_NULL) - return new OSD(); - return OSD.FromString(str); + if(str == ScriptBaseClass.JSON_TRUE || str == "true") + return "true"; + if(str == ScriptBaseClass.JSON_FALSE ||str == "false") + return "false"; + if(str == ScriptBaseClass.JSON_NULL || str == "null") + return "null"; + str.Trim(); + if (str[0] == '{') + return str; + if (str[0] == '[') + return str; + return EscapeForJSON(str, true); } - throw new Exception(ScriptBaseClass.JSON_INVALID); + throw new IndexOutOfRangeException(); } - private OSD JsonGetSpecific(OSD o, LSL_List specifiers, int i) + private string EscapeForJSON(string s, bool AddOuter) { - object spec = specifiers.Data[i]; - OSD nextVal = null; - if (o is OSDArray) + int i; + char c; + String t; + int len = s.Length; + + StringBuilder sb = new StringBuilder(len + 64); + if(AddOuter) + sb.Append("\""); + + for (i = 0; i < len; i++) { - if (spec is LSL_Integer) - nextVal = ((OSDArray)o)[((LSL_Integer)spec).value]; + c = s[i]; + switch (c) + { + case '\\': + case '"': + case '/': + sb.Append('\\'); + sb.Append(c); + break; + case '\b': + sb.Append("\\b"); + break; + case '\t': + sb.Append("\\t"); + break; + case '\n': + sb.Append("\\n"); + break; + case '\f': + sb.Append("\\f"); + break; + case '\r': + sb.Append("\\r"); + break; + default: + if (c < ' ') + { + t = "000" + String.Format("{0:X}", c); + sb.Append("\\u" + t.Substring(t.Length - 4)); + } + else + { + sb.Append(c); + } + break; + } } - if (o is OSDMap) - { - if (spec is LSL_String) - nextVal = ((OSDMap)o)[((LSL_String)spec).m_string]; - } - if (nextVal != null) - { - if (specifiers.Data.Length - 1 > i) - return JsonGetSpecific(nextVal, specifiers, i + 1); - } - return nextVal; + if(AddOuter) + sb.Append("\""); + return sb.ToString(); } public LSL_String llJsonSetValue(LSL_String json, LSL_List specifiers, LSL_String value) { + bool noSpecifiers = specifiers.Length == 0; + LitJson.JsonData workData; try { - OSD o = OSDParser.DeserializeJson(json); - JsonSetSpecific(o, specifiers, 0, value); - return OSDParser.SerializeJsonString(o); + if(noSpecifiers) + specifiers.Add(new LSL_Integer(0)); + + if(!String.IsNullOrEmpty(json)) + workData = LitJson.JsonMapper.ToObject(json); + else + { + workData = new LitJson.JsonData(); + workData.SetJsonType(LitJson.JsonType.Array); + } } - catch (Exception) + catch (Exception e) { + string m = e.Message; // debug point + return ScriptBaseClass.JSON_INVALID; + } + try + { + LitJson.JsonData replace = JsonSetSpecific(workData, specifiers, 0, value); + if(replace != null) + workData = replace; + } + catch (Exception e) + { + string m = e.Message; // debug point + return ScriptBaseClass.JSON_INVALID; + } + + try + { + string r = LitJson.JsonMapper.ToJson(workData); + if(noSpecifiers) + r = r.Substring(1,r.Length -2); // strip leading and trailing brakets + return r; + } + catch (Exception e) + { + string m = e.Message; // debug point } return ScriptBaseClass.JSON_INVALID; } - private void JsonSetSpecific(OSD o, LSL_List specifiers, int i, LSL_String val) + private LitJson.JsonData JsonSetSpecific(LitJson.JsonData elem, LSL_List specifiers, int level, LSL_String val) { - object spec = specifiers.Data[i]; - // 20131224 not used object specNext = i+1 == specifiers.Data.Length ? null : specifiers.Data[i+1]; - OSD nextVal = null; - if (o is OSDArray) + object spec = specifiers.Data[level]; + if(spec is LSL_String) + spec = ((LSL_String)spec).m_string; + else if (spec is LSL_Integer) + spec = ((LSL_Integer)spec).value; + + if(!(spec is string || spec is int)) + throw new IndexOutOfRangeException(); + + int speclen = specifiers.Data.Length - 1; + + bool hasvalue = false; + LitJson.JsonData value = null; + + LitJson.JsonType elemType = elem.GetJsonType(); + if (elemType == LitJson.JsonType.Array) + { + if (spec is int) + { + int v = (int)spec; + int c = elem.Count; + if(v < 0 || (v != 0 && v > c)) + throw new IndexOutOfRangeException(); + if(v == c) + elem.Add(JsonBuildRestOfSpec(specifiers, level + 1, val)); + else + { + hasvalue = true; + value = elem[v]; + } + } + else if (spec is string) + { + if((string)spec == ScriptBaseClass.JSON_APPEND) + elem.Add(JsonBuildRestOfSpec(specifiers, level + 1, val)); + else if(elem.Count < 2) + { + // our initial guess of array was wrong + LitJson.JsonData newdata = new LitJson.JsonData(); + newdata.SetJsonType(LitJson.JsonType.Object); + IOrderedDictionary no = newdata as IOrderedDictionary; + no.Add((string)spec,JsonBuildRestOfSpec(specifiers, level + 1, val)); + return newdata; + } + } + } + else if (elemType == LitJson.JsonType.Object) + { + if (spec is string) + { + IOrderedDictionary e = elem as IOrderedDictionary; + string key = (string)spec; + if(e.Contains(key)) + { + hasvalue = true; + value = (LitJson.JsonData)e[key]; + } + else + e.Add(key, JsonBuildRestOfSpec(specifiers, level + 1, val)); + } + else if(spec is int && (int)spec == 0) + { + //we are replacing a object by a array + LitJson.JsonData newData = new LitJson.JsonData(); + newData.SetJsonType(LitJson.JsonType.Array); + newData.Add(JsonBuildRestOfSpec(specifiers, level + 1, val)); + return newData; + } + } + else + { + LitJson.JsonData newData = JsonBuildRestOfSpec(specifiers, level, val); + return newData; + } + + if (hasvalue) + { + if (level < speclen) + { + LitJson.JsonData replace = JsonSetSpecific(value, specifiers, level + 1, val); + if(replace != null) + { + if(elemType == LitJson.JsonType.Array) + { + if(spec is int) + elem[(int)spec] = replace; + else if( spec is string) + { + LitJson.JsonData newdata = new LitJson.JsonData(); + newdata.SetJsonType(LitJson.JsonType.Object); + IOrderedDictionary no = newdata as IOrderedDictionary; + no.Add((string)spec, replace); + return newdata; + } + } + else if(elemType == LitJson.JsonType.Object) + { + if(spec is string) + elem[(string)spec] = replace; + else if(spec is int && (int)spec == 0) + { + LitJson.JsonData newdata = new LitJson.JsonData(); + newdata.SetJsonType(LitJson.JsonType.Array); + newdata.Add(replace); + return newdata; + } + } + } + return null; + } + else if(speclen == level) + { + if(val == ScriptBaseClass.JSON_DELETE) + { + if(elemType == LitJson.JsonType.Array) + { + if(spec is int) + { + IList el = elem as IList; + el.RemoveAt((int)spec); + } + } + else if(elemType == LitJson.JsonType.Object) + { + if(spec is string) + { + IOrderedDictionary eo = elem as IOrderedDictionary; + eo.Remove((string) spec); + } + } + return null; + } + + LitJson.JsonData newval = null; + float num; + if(val == null || val == ScriptBaseClass.JSON_NULL || val == "null") + newval = null; + else if(val == ScriptBaseClass.JSON_TRUE || val == "true") + newval = new LitJson.JsonData(true); + else if(val == ScriptBaseClass.JSON_FALSE || val == "false") + newval = new LitJson.JsonData(false); + else if(float.TryParse(val, out num)) + { + // assuming we are at en.us already + if(num - (int)num == 0.0f && !val.Contains(".")) + newval = new LitJson.JsonData((int)num); + else + { + num = (float)Math.Round(num,6); + newval = new LitJson.JsonData((double)num); + } + } + else + { + string str = val.m_string; + newval = new LitJson.JsonData(str); + } + + if(elemType == LitJson.JsonType.Array) + { + if(spec is int) + elem[(int)spec] = newval; + else if( spec is string) + { + LitJson.JsonData newdata = new LitJson.JsonData(); + newdata.SetJsonType(LitJson.JsonType.Object); + IOrderedDictionary no = newdata as IOrderedDictionary; + no.Add((string)spec,newval); + return newdata; + } + } + else if(elemType == LitJson.JsonType.Object) + { + if(spec is string) + elem[(string)spec] = newval; + else if(spec is int && (int)spec == 0) + { + LitJson.JsonData newdata = new LitJson.JsonData(); + newdata.SetJsonType(LitJson.JsonType.Array); + newdata.Add(newval); + return newdata; + } + } + } + } + if(val == ScriptBaseClass.JSON_DELETE) + throw new IndexOutOfRangeException(); + return null; + } + + private LitJson.JsonData JsonBuildRestOfSpec(LSL_List specifiers, int level, LSL_String val) + { + object spec = level >= specifiers.Data.Length ? null : specifiers.Data[level]; + // 20131224 not used object specNext = i+1 >= specifiers.Data.Length ? null : specifiers.Data[i+1]; + + float num; + if (spec == null) + { + if(val == null || val == ScriptBaseClass.JSON_NULL || val == "null") + return null; + if(val == ScriptBaseClass.JSON_DELETE) + throw new IndexOutOfRangeException(); + if(val == ScriptBaseClass.JSON_TRUE || val == "true") + return new LitJson.JsonData(true); + if(val == ScriptBaseClass.JSON_FALSE || val == "false") + return new LitJson.JsonData(false); + if(val == null || val == ScriptBaseClass.JSON_NULL || val == "null") + return null; + if(float.TryParse(val, out num)) + { + // assuming we are at en.us already + if(num - (int)num == 0.0f && !val.Contains(".")) + return new LitJson.JsonData((int)num); + else + { + num = (float)Math.Round(num,6); + return new LitJson.JsonData(num); + } + } + else + { + string str = val.m_string; + return new LitJson.JsonData(str); + } + throw new IndexOutOfRangeException(); + } + + if(spec is LSL_String) + spec = ((LSL_String)spec).m_string; + else if (spec is LSL_Integer) + spec = ((LSL_Integer)spec).value; + + if (spec is int || + (spec is string && ((string)spec) == ScriptBaseClass.JSON_APPEND) ) + { + if(spec is int && (int)spec != 0) + throw new IndexOutOfRangeException(); + LitJson.JsonData newdata = new LitJson.JsonData(); + newdata.SetJsonType(LitJson.JsonType.Array); + newdata.Add(JsonBuildRestOfSpec(specifiers, level + 1, val)); + return newdata; + } + else if (spec is string) + { + LitJson.JsonData newdata = new LitJson.JsonData(); + newdata.SetJsonType(LitJson.JsonType.Object); + IOrderedDictionary no = newdata as IOrderedDictionary; + no.Add((string)spec,JsonBuildRestOfSpec(specifiers, level + 1, val)); + return newdata; + } + throw new IndexOutOfRangeException(); + } + + private bool JsonFind(LitJson.JsonData elem, LSL_List specifiers, int level, out LitJson.JsonData value) + { + value = null; + if(elem == null) + return false; + + object spec; + spec = specifiers.Data[level]; + + bool haveVal = false; + LitJson.JsonData next = null; + + if (elem.GetJsonType() == LitJson.JsonType.Array) { - OSDArray array = ((OSDArray)o); if (spec is LSL_Integer) { - int v = ((LSL_Integer)spec).value; - if (v >= array.Count) - array.Add(JsonBuildRestOfSpec(specifiers, i + 1, val)); - else - nextVal = ((OSDArray)o)[v]; + int indx = (LSL_Integer)spec; + if(indx >= 0 && indx < elem.Count) + { + haveVal = true; + next = (LitJson.JsonData)elem[indx]; + } } - else if (spec is LSL_String && ((LSL_String)spec) == ScriptBaseClass.JSON_APPEND) - array.Add(JsonBuildRestOfSpec(specifiers, i + 1, val)); } - if (o is OSDMap) + else if (elem.GetJsonType() == LitJson.JsonType.Object) { if (spec is LSL_String) { - OSDMap map = ((OSDMap)o); - if (map.ContainsKey(((LSL_String)spec).m_string)) - nextVal = map[((LSL_String)spec).m_string]; - else - map.Add(((LSL_String)spec).m_string, JsonBuildRestOfSpec(specifiers, i + 1, val)); + IOrderedDictionary e = elem as IOrderedDictionary; + string key = (LSL_String)spec; + if(e.Contains(key)) + { + haveVal = true; + next = (LitJson.JsonData)e[key]; + } } } - if (nextVal != null) + + if (haveVal) { - if (specifiers.Data.Length - 1 > i) + if(level == specifiers.Data.Length - 1) { - JsonSetSpecific(nextVal, specifiers, i + 1, val); - return; + value = next; + return true; } + + level++; + if(next == null) + return false; + + LitJson.JsonType nextType = next.GetJsonType(); + if(nextType != LitJson.JsonType.Object && nextType != LitJson.JsonType.Array) + return false; + + return JsonFind(next, specifiers, level, out value); } + return false; } - private OSD JsonBuildRestOfSpec(LSL_List specifiers, int i, LSL_String val) + public LSL_String llJsonGetValue(LSL_String json, LSL_List specifiers) { - object spec = i >= specifiers.Data.Length ? null : specifiers.Data[i]; - // 20131224 not used object specNext = i+1 >= specifiers.Data.Length ? null : specifiers.Data[i+1]; + if(String.IsNullOrWhiteSpace(json)) + return ScriptBaseClass.JSON_INVALID; - if (spec == null) - return OSD.FromString(val); + if(specifiers.Length > 0 && (json == "{}" || json == "[]")) + return ScriptBaseClass.JSON_INVALID; - if (spec is LSL_Integer || - (spec is LSL_String && ((LSL_String)spec) == ScriptBaseClass.JSON_APPEND)) + char first = ((string)json)[0]; + if((first != '[' && first !='{')) { - OSDArray array = new OSDArray(); - array.Add(JsonBuildRestOfSpec(specifiers, i + 1, val)); - return array; + if(specifiers.Length > 0) + return ScriptBaseClass.JSON_INVALID; + json = "[" + json + "]"; // could handle single element case.. but easier like this + specifiers.Add((LSL_Integer)0); } - else if (spec is LSL_String) + + LitJson.JsonData jsonData; + try { - OSDMap map = new OSDMap(); - map.Add((LSL_String)spec, JsonBuildRestOfSpec(specifiers, i + 1, val)); - return map; + jsonData = LitJson.JsonMapper.ToObject(json); + } + catch (Exception e) + { + string m = e.Message; // debug point + return ScriptBaseClass.JSON_INVALID; + } + + LitJson.JsonData elem = null; + if(specifiers.Length == 0) + elem = jsonData; + else + { + if(!JsonFind(jsonData, specifiers, 0, out elem)) + return ScriptBaseClass.JSON_INVALID; + } + return JsonElementToString(elem); + } + + private LSL_String JsonElementToString(LitJson.JsonData elem) + { + if(elem == null) + return ScriptBaseClass.JSON_NULL; + + LitJson.JsonType elemType = elem.GetJsonType(); + switch(elemType) + { + case LitJson.JsonType.Array: + return new LSL_String(LitJson.JsonMapper.ToJson(elem)); + case LitJson.JsonType.Boolean: + return new LSL_String((bool)elem ? ScriptBaseClass.JSON_TRUE : ScriptBaseClass.JSON_FALSE); + case LitJson.JsonType.Double: + double d= (double)elem; + string sd = String.Format(Culture.FormatProvider, "{0:0.0#####}",d); + return new LSL_String(sd); + case LitJson.JsonType.Int: + int i = (int)elem; + return new LSL_String(i.ToString()); + case LitJson.JsonType.Long: + long l = (long)elem; + return new LSL_String(l.ToString()); + case LitJson.JsonType.Object: + return new LSL_String(LitJson.JsonMapper.ToJson(elem)); + case LitJson.JsonType.String: + string s = (string)elem; + return new LSL_String(s); + case LitJson.JsonType.None: + return ScriptBaseClass.JSON_NULL; + default: + return ScriptBaseClass.JSON_INVALID; } - return new OSD(); } public LSL_String llJsonValueType(LSL_String json, LSL_List specifiers) { - OSD o = OSDParser.DeserializeJson(json); - OSD specVal = JsonGetSpecific(o, specifiers, 0); - if (specVal == null) + if(String.IsNullOrWhiteSpace(json)) return ScriptBaseClass.JSON_INVALID; - switch (specVal.Type) + + if(specifiers.Length > 0 && (json == "{}" || json == "[]")) + return ScriptBaseClass.JSON_INVALID; + + char first = ((string)json)[0]; + if((first != '[' && first !='{')) { - case OSDType.Array: - return ScriptBaseClass.JSON_ARRAY; - case OSDType.Boolean: - return specVal.AsBoolean() ? ScriptBaseClass.JSON_TRUE : ScriptBaseClass.JSON_FALSE; - case OSDType.Integer: - case OSDType.Real: - return ScriptBaseClass.JSON_NUMBER; - case OSDType.Map: - return ScriptBaseClass.JSON_OBJECT; - case OSDType.String: - case OSDType.UUID: - return ScriptBaseClass.JSON_STRING; - case OSDType.Unknown: - return ScriptBaseClass.JSON_NULL; + if(specifiers.Length > 0) + return ScriptBaseClass.JSON_INVALID; + json = "[" + json + "]"; // could handle single element case.. but easier like this + specifiers.Add((LSL_Integer)0); + } + + LitJson.JsonData jsonData; + try + { + jsonData = LitJson.JsonMapper.ToObject(json); + } + catch (Exception e) + { + string m = e.Message; // debug point + return ScriptBaseClass.JSON_INVALID; + } + + LitJson.JsonData elem = null; + if(specifiers.Length == 0) + elem = jsonData; + else + { + if(!JsonFind(jsonData, specifiers, 0, out elem)) + return ScriptBaseClass.JSON_INVALID; + } + + if(elem == null) + return ScriptBaseClass.JSON_NULL; + + LitJson.JsonType elemType = elem.GetJsonType(); + switch(elemType) + { + case LitJson.JsonType.Array: + return ScriptBaseClass.JSON_ARRAY; + case LitJson.JsonType.Boolean: + return (bool)elem ? ScriptBaseClass.JSON_TRUE : ScriptBaseClass.JSON_FALSE; + case LitJson.JsonType.Double: + case LitJson.JsonType.Int: + case LitJson.JsonType.Long: + return ScriptBaseClass.JSON_NUMBER; + case LitJson.JsonType.Object: + return ScriptBaseClass.JSON_OBJECT; + case LitJson.JsonType.String: + string s = (string)elem; + if(s == ScriptBaseClass.JSON_NULL) + return ScriptBaseClass.JSON_NULL; + if(s == ScriptBaseClass.JSON_TRUE) + return ScriptBaseClass.JSON_TRUE; + if(s == ScriptBaseClass.JSON_FALSE) + return ScriptBaseClass.JSON_FALSE; + return ScriptBaseClass.JSON_STRING; + case LitJson.JsonType.None: + return ScriptBaseClass.JSON_NULL; + default: + return ScriptBaseClass.JSON_INVALID; } - return ScriptBaseClass.JSON_INVALID; } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs index 238fefbe75..1979012b8b 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs @@ -61,6 +61,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api internal SceneObjectPart m_host; internal bool m_LSFunctionsEnabled = false; internal IScriptModuleComms m_comms = null; + internal IConfig m_osslconfig; public void Initialize( IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item) @@ -68,7 +69,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_ScriptEngine = scriptEngine; m_host = host; - if (m_ScriptEngine.Config.GetBoolean("AllowLightShareFunctions", false)) + m_osslconfig = m_ScriptEngine.ConfigSource.Configs["OSSL"]; + if(m_osslconfig == null) + m_osslconfig = m_ScriptEngine.Config; + + if (m_osslconfig.GetBoolean("AllowLightShareFunctions", false)) m_LSFunctionsEnabled = true; m_comms = m_ScriptEngine.World.RequestModuleInterface(); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs index 692bec075e..b73a1418f4 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs @@ -64,6 +64,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api internal TaskInventoryItem m_item; internal bool m_MODFunctionsEnabled = false; internal IScriptModuleComms m_comms = null; + internal IConfig m_osslconfig; public void Initialize( IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item) @@ -72,7 +73,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host = host; m_item = item; - if (m_ScriptEngine.Config.GetBoolean("AllowMODFunctions", false)) + + m_osslconfig = m_ScriptEngine.ConfigSource.Configs["OSSL"]; + if(m_osslconfig == null) + m_osslconfig = m_ScriptEngine.Config; + + if (m_osslconfig.GetBoolean("AllowMODFunctions", false)) m_MODFunctionsEnabled = true; m_comms = m_ScriptEngine.World.RequestModuleInterface(); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 4c3f7eeec5..62729b3393 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -144,6 +144,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api internal bool m_debuggerSafe = false; internal Dictionary m_FunctionPerms = new Dictionary(); protected IUrlModule m_UrlModule = null; + protected ISoundModule m_SoundModule = null; + internal IConfig m_osslconfig; public void Initialize( IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item) @@ -151,11 +153,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_ScriptEngine = scriptEngine; m_host = host; m_item = item; + + m_osslconfig = m_ScriptEngine.ConfigSource.Configs["OSSL"]; + if(m_osslconfig == null) + m_osslconfig = m_ScriptEngine.Config; + m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false); m_UrlModule = m_ScriptEngine.World.RequestModuleInterface(); + m_SoundModule = m_ScriptEngine.World.RequestModuleInterface(); - if (m_ScriptEngine.Config.GetBoolean("AllowOSFunctions", false)) + if (m_osslconfig.GetBoolean("AllowOSFunctions", false)) { m_OSFunctionsEnabled = true; // m_log.Warn("[OSSL] OSSL FUNCTIONS ENABLED"); @@ -166,7 +174,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_ScriptDistanceFactor = m_ScriptEngine.Config.GetFloat("ScriptDistanceLimitFactor", 1.0f); - string risk = m_ScriptEngine.Config.GetString("OSFunctionThreatLevel", "VeryLow"); + string risk = m_osslconfig.GetString("OSFunctionThreatLevel", "VeryLow"); switch (risk) { case "NoAccess": @@ -260,9 +268,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api wComm.DeliverMessage(ChatTypeEnum.Shout, ScriptBaseClass.DEBUG_CHANNEL, m_host.Name, m_host.UUID, message); } - // Returns of the function is allowed. Throws a script exception if not allowed. + // Returns if OSSL is enabled. Throws a script exception if OSSL is not allowed.. + // for safe funtions always active + public void CheckThreatLevel() + { + m_host.AddScriptLPS(1); + if (!m_OSFunctionsEnabled) + OSSLError("permission denied. All OS functions are disabled."); // throws + } + + // Returns if the function is allowed. Throws a script exception if not allowed. public void CheckThreatLevel(ThreatLevel level, string function) { + m_host.AddScriptLPS(1); if (!m_OSFunctionsEnabled) OSSLError(String.Format("{0} permission denied. All OS functions are disabled.", function)); // throws @@ -282,8 +300,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api FunctionPerms perms = new FunctionPerms(); m_FunctionPerms[function] = perms; - string ownerPerm = m_ScriptEngine.Config.GetString("Allow_" + function, ""); - string creatorPerm = m_ScriptEngine.Config.GetString("Creators_" + function, ""); + string ownerPerm = m_osslconfig.GetString("Allow_" + function, ""); + string creatorPerm = m_osslconfig.GetString("Creators_" + function, ""); if (ownerPerm == "" && creatorPerm == "") { // Default behavior @@ -444,7 +462,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } } - if (!m_FunctionPerms[function].AllowedCreators.Contains(m_item.CreatorID)) return( String.Format("{0} permission denied. Script creator is not in the list of users allowed to execute this function and prim owner also has no permission.", @@ -468,10 +485,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api protected void ScriptSleep(int delay) { - delay = (int)((float)delay * m_ScriptDelayFactor); - if (delay == 0) + delay = (int)(delay * m_ScriptDelayFactor); + if (delay < 10) return; - System.Threading.Thread.Sleep(delay); + if(m_item != null) + m_ScriptEngine.SleepScript(m_item.ItemID, delay); + else + Thread.Sleep(delay); } public LSL_Integer osSetTerrainHeight(int x, int y, double val) @@ -491,8 +511,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api private LSL_Integer SetTerrainHeight(int x, int y, double val) { - m_host.AddScriptLPS(1); - if (x > (World.RegionInfo.RegionSizeX - 1) || x < 0 || y > (World.RegionInfo.RegionSizeY - 1) || y < 0) OSSLError("osSetTerrainHeight: Coordinate out of bounds"); @@ -509,20 +527,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Float osGetTerrainHeight(int x, int y) { - CheckThreatLevel(ThreatLevel.None, "osGetTerrainHeight"); + CheckThreatLevel(); return GetTerrainHeight(x, y); } public LSL_Float osTerrainGetHeight(int x, int y) { - CheckThreatLevel(ThreatLevel.None, "osTerrainGetHeight"); + CheckThreatLevel(); OSSLDeprecated("osTerrainGetHeight", "osGetTerrainHeight"); return GetTerrainHeight(x, y); } private LSL_Float GetTerrainHeight(int x, int y) { - m_host.AddScriptLPS(1); if (x > (World.RegionInfo.RegionSizeX - 1) || x < 0 || y > (World.RegionInfo.RegionSizeY - 1) || y < 0) OSSLError("osGetTerrainHeight: Coordinate out of bounds"); @@ -532,7 +549,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void osTerrainFlush() { CheckThreatLevel(ThreatLevel.VeryLow, "osTerrainFlush"); - m_host.AddScriptLPS(1); ITerrainModule terrainModule = World.RequestModuleInterface(); if (terrainModule != null) terrainModule.TaintTerrain(); @@ -549,7 +565,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api CheckThreatLevel(ThreatLevel.High, "osRegionRestart"); IRestartModule restartModule = World.RequestModuleInterface(); - m_host.AddScriptLPS(1); if (World.Permissions.CanIssueEstateCommand(m_host.OwnerID, false) && (restartModule != null)) { if (seconds < 15) @@ -572,7 +587,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api CheckThreatLevel(ThreatLevel.High, "osRegionRestart"); IRestartModule restartModule = World.RequestModuleInterface(); - m_host.AddScriptLPS(1); if (World.Permissions.CanIssueEstateCommand(m_host.OwnerID, false) && (restartModule != null)) { if (seconds < 15) @@ -617,18 +631,41 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void osRegionNotice(string msg) { - // This implementation provides absolutely no security - // It's high griefing potential makes this classification - // necessary - // - CheckThreatLevel(ThreatLevel.VeryHigh, "osRegionNotice"); - - m_host.AddScriptLPS(1); + CheckThreatLevel(ThreatLevel.High, "osRegionNotice"); IDialogModule dm = World.RequestModuleInterface(); + if (dm == null) + return; - if (dm != null) - dm.SendGeneralAlert(msg); + if (!World.Permissions.CanIssueEstateCommand(m_host.OwnerID, false)) + return; + + dm.SendGeneralAlert(msg + "\n"); + } + + public void osRegionNotice(LSL_Key agentID, string msg) + { + CheckThreatLevel(ThreatLevel.High, "osRegionNotice"); + + if (!World.Permissions.CanIssueEstateCommand(m_host.OwnerID, false)) + return; + + IDialogModule dm = World.RequestModuleInterface(); + if (dm == null) + return; + + UUID avatarID; + if (!UUID.TryParse(agentID, out avatarID)) + return; + + ScenePresence sp = null; + if (!World.TryGetScenePresence(avatarID, out sp)) + return; + + if (sp == null || sp.IsChildAgent || sp.IsDeleted || sp.IsInTransit || sp.IsNPC) + return; + + dm.SendAlertToUser(sp.ControllingClient, msg + "\n", false); } public void osSetRot(UUID target, Quaternion rotation) @@ -638,7 +675,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // CheckThreatLevel(ThreatLevel.VeryHigh, "osSetRot"); - m_host.AddScriptLPS(1); if (World.Entities.ContainsKey(target)) { EntityBase entity; @@ -664,13 +700,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // CheckThreatLevel(ThreatLevel.VeryLow, "osSetDynamicTextureURL"); - m_host.AddScriptLPS(1); if (dynamicID == String.Empty) { IDynamicTextureManager textureManager = World.RequestModuleInterface(); UUID createdTexture = textureManager.AddDynamicTextureURL(World.RegionInfo.RegionID, m_host.UUID, contentType, url, - extraParams, timer); + extraParams); return createdTexture.ToString(); } else @@ -686,13 +721,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { CheckThreatLevel(ThreatLevel.VeryLow, "osSetDynamicTextureURLBlend"); - m_host.AddScriptLPS(1); if (dynamicID == String.Empty) { IDynamicTextureManager textureManager = World.RequestModuleInterface(); UUID createdTexture = textureManager.AddDynamicTextureURL(World.RegionInfo.RegionID, m_host.UUID, contentType, url, - extraParams, timer, true, (byte) alpha); + extraParams, true, (byte) alpha); return createdTexture.ToString(); } else @@ -708,13 +742,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { CheckThreatLevel(ThreatLevel.VeryLow, "osSetDynamicTextureURLBlendFace"); - m_host.AddScriptLPS(1); if (dynamicID == String.Empty) { IDynamicTextureManager textureManager = World.RequestModuleInterface(); UUID createdTexture = textureManager.AddDynamicTextureURL(World.RegionInfo.RegionID, m_host.UUID, contentType, url, - extraParams, timer, blend, disp, (byte) alpha, face); + extraParams, blend, disp, (byte) alpha, face); return createdTexture.ToString(); } else @@ -727,10 +760,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public string osSetDynamicTextureData(string dynamicID, string contentType, string data, string extraParams, int timer) + { + return osSetDynamicTextureDataFace(dynamicID, contentType, data, extraParams, timer, -1); + } + + public string osSetDynamicTextureDataFace(string dynamicID, string contentType, string data, string extraParams, + int timer, int face) { CheckThreatLevel(ThreatLevel.VeryLow, "osSetDynamicTextureData"); - m_host.AddScriptLPS(1); if (dynamicID == String.Empty) { IDynamicTextureManager textureManager = World.RequestModuleInterface(); @@ -742,7 +780,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } UUID createdTexture = textureManager.AddDynamicTextureData(World.RegionInfo.RegionID, m_host.UUID, contentType, data, - extraParams, timer); + extraParams, false, 3, 255, face); + return createdTexture.ToString(); } } @@ -759,7 +798,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { CheckThreatLevel(ThreatLevel.VeryLow, "osSetDynamicTextureDataBlend"); - m_host.AddScriptLPS(1); if (dynamicID == String.Empty) { IDynamicTextureManager textureManager = World.RequestModuleInterface(); @@ -771,7 +809,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } UUID createdTexture = textureManager.AddDynamicTextureData(World.RegionInfo.RegionID, m_host.UUID, contentType, data, - extraParams, timer, true, (byte) alpha); + extraParams, true, (byte) alpha); return createdTexture.ToString(); } } @@ -786,9 +824,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public string osSetDynamicTextureDataBlendFace(string dynamicID, string contentType, string data, string extraParams, bool blend, int disp, int timer, int alpha, int face) { - CheckThreatLevel(ThreatLevel.VeryLow, "osSetDynamicTextureDataBlendFace"); + CheckThreatLevel(ThreatLevel.VeryLow , "osSetDynamicTextureDataBlendFace"); - m_host.AddScriptLPS(1); if (dynamicID == String.Empty) { IDynamicTextureManager textureManager = World.RequestModuleInterface(); @@ -800,7 +837,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } UUID createdTexture = textureManager.AddDynamicTextureData(World.RegionInfo.RegionID, m_host.UUID, contentType, data, - extraParams, timer, blend, disp, (byte) alpha, face); + extraParams, blend, disp, (byte) alpha, face); return createdTexture.ToString(); } } @@ -816,8 +853,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { CheckThreatLevel(ThreatLevel.Severe, "osConsoleCommand"); - m_host.AddScriptLPS(1); - // For safety, we add another permission check here, and don't rely only on the standard OSSL permissions if (World.Permissions.CanRunConsoleCommand(m_host.OwnerID)) { @@ -832,11 +867,50 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { CheckThreatLevel(ThreatLevel.VeryLow, "osSetPrimFloatOnWater"); - m_host.AddScriptLPS(1); - m_host.ParentGroup.RootPart.SetFloatOnWater(floatYN); } + private bool checkAllowAgentTPbyLandOwner(UUID agentId, Vector3 pos) + { + UUID hostOwner = m_host.OwnerID; + + if(hostOwner == agentId) + return true; + + if (m_item.PermsGranter == agentId) + { + if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TELEPORT) != 0) + return true; + } + + ILandObject land = World.LandChannel.GetLandObject(pos); + if(land == null) + return true; + + LandData landdata = land.LandData; + if(landdata == null) + return true; + + if(landdata.OwnerID == hostOwner) + return true; + + EstateSettings es = World.RegionInfo.EstateSettings; + if(es != null && es.IsEstateManagerOrOwner(hostOwner)) + return true; + + if(!landdata.IsGroupOwned) + return false; + + UUID landGroup = landdata.GroupID; + if(landGroup == UUID.Zero) + return false; + + if(landGroup == m_host.GroupID) + return true; + + return false; + } + // Teleport functions public void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat) { @@ -844,41 +918,46 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // CheckThreatLevel(ThreatLevel.Severe, "osTeleportAgent"); - TeleportAgent(agent, regionName, position, lookat, false); + TeleportAgent(agent, regionName, position, lookat); } private void TeleportAgent(string agent, string regionName, - LSL_Types.Vector3 position, LSL_Types.Vector3 lookat, bool relaxRestrictions) + LSL_Types.Vector3 position, LSL_Types.Vector3 lookat) { - m_host.AddScriptLPS(1); - UUID agentId = new UUID(); + if(String.IsNullOrEmpty(regionName)) + regionName = World.RegionInfo.RegionName; + + UUID agentId; if (UUID.TryParse(agent, out agentId)) { ScenePresence presence = World.GetScenePresence(agentId); - if (presence != null) + if (presence == null || presence.IsDeleted || presence.IsInTransit) + return; + + Vector3 pos = presence.AbsolutePosition; + if(!checkAllowAgentTPbyLandOwner(agentId, pos)) { - // For osTeleportAgent, agent must be over owners land to avoid abuse - // For osTeleportOwner, this restriction isn't necessary - - // commented out because its redundant and uneeded please remove eventually. - // if (relaxRestrictions || - // m_host.OwnerID - // == World.LandChannel.GetLandObject( - // presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) - // { - - // We will launch the teleport on a new thread so that when the script threads are terminated - // before teleport in ScriptInstance.GetXMLState(), we don't end up aborting the one doing the teleporting. - Util.FireAndForget( - o => World.RequestTeleportLocation( - presence.ControllingClient, regionName, position, - lookat, (uint)TPFlags.ViaLocation), - null, "OSSL_Api.TeleportAgentByRegionCoords"); - - ScriptSleep(5000); - - // } + ScriptSleep(500); + return; + } + if(regionName == World.RegionInfo.RegionName) + { + // should be faster than going to threadpool + World.RequestTeleportLocation(presence.ControllingClient, regionName, position, + lookat, (uint)TPFlags.ViaLocation); + ScriptSleep(500); + } + else + { + // We will launch the teleport on a new thread so that when the script threads are terminated + // before teleport in ScriptInstance.GetXMLState(), we don't end up aborting the one doing the teleporting. + Util.FireAndForget( + o => World.RequestTeleportLocation( + presence.ControllingClient, regionName, position, + lookat, (uint)TPFlags.ViaLocation), + null, "OSSL_Api.TeleportAgentByRegionCoords"); + ScriptSleep(5000); } } } @@ -889,50 +968,58 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // CheckThreatLevel(ThreatLevel.Severe, "osTeleportAgent"); - TeleportAgent(agent, regionGridX, regionGridY, position, lookat, false); + TeleportAgent(agent, regionGridX, regionGridY, position, lookat); } private void TeleportAgent(string agent, int regionGridX, int regionGridY, - LSL_Types.Vector3 position, LSL_Types.Vector3 lookat, bool relaxRestrictions) + LSL_Types.Vector3 position, LSL_Types.Vector3 lookat) { ulong regionHandle = Util.RegionGridLocToHandle((uint)regionGridX, (uint)regionGridY); - m_host.AddScriptLPS(1); - UUID agentId = new UUID(); + UUID agentId; if (UUID.TryParse(agent, out agentId)) { ScenePresence presence = World.GetScenePresence(agentId); - if (presence != null) + if (presence == null || presence.IsDeleted || presence.IsInTransit) + return; + + Vector3 pos = presence.AbsolutePosition; + if(!checkAllowAgentTPbyLandOwner(agentId, pos)) { - // For osTeleportAgent, agent must be over owners land to avoid abuse - // For osTeleportOwner, this restriction isn't necessary - - // commented out because its redundant and uneeded please remove eventually. - // if (relaxRestrictions || - // m_host.OwnerID - // == World.LandChannel.GetLandObject( - // presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) - // { - - // We will launch the teleport on a new thread so that when the script threads are terminated - // before teleport in ScriptInstance.GetXMLState(), we don't end up aborting the one doing the teleporting. - Util.FireAndForget( - o => World.RequestTeleportLocation( - presence.ControllingClient, regionHandle, - position, lookat, (uint)TPFlags.ViaLocation), - null, "OSSL_Api.TeleportAgentByRegionName"); - - ScriptSleep(5000); - - // } - + ScriptSleep(500); + return; } + + Util.FireAndForget( + o => World.RequestTeleportLocation( + presence.ControllingClient, regionHandle, + position, lookat, (uint)TPFlags.ViaLocation), + null, "OSSL_Api.TeleportAgentByRegionName"); + + ScriptSleep(5000); } } public void osTeleportAgent(string agent, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat) { - osTeleportAgent(agent, World.RegionInfo.RegionName, position, lookat); + UUID agentId; + if (UUID.TryParse(agent, out agentId)) + { + ScenePresence presence = World.GetScenePresence(agentId); + if (presence == null || presence.IsDeleted || presence.IsInTransit) + return; + + Vector3 pos = presence.AbsolutePosition; + if(!checkAllowAgentTPbyLandOwner(agentId, pos)) + { + ScriptSleep(500); + return; + } + + World.RequestTeleportLocation(presence.ControllingClient, World.RegionInfo.RegionName, position, + lookat, (uint)TPFlags.ViaLocation); + ScriptSleep(500); + } } public void osTeleportOwner(string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat) @@ -940,19 +1027,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // Threat level None because this is what can already be done with the World Map in the viewer CheckThreatLevel(ThreatLevel.None, "osTeleportOwner"); - TeleportAgent(m_host.OwnerID.ToString(), regionName, position, lookat, true); - } - - public void osTeleportOwner(LSL_Types.Vector3 position, LSL_Types.Vector3 lookat) - { - osTeleportOwner(World.RegionInfo.RegionName, position, lookat); + TeleportAgent(m_host.OwnerID.ToString(), regionName, position, lookat); } public void osTeleportOwner(int regionGridX, int regionGridY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat) { CheckThreatLevel(ThreatLevel.None, "osTeleportOwner"); - TeleportAgent(m_host.OwnerID.ToString(), regionGridX, regionGridY, position, lookat, true); + TeleportAgent(m_host.OwnerID.ToString(), regionGridX, regionGridY, position, lookat); + } + + public void osTeleportOwner(LSL_Types.Vector3 position, LSL_Types.Vector3 lookat) + { + CheckThreatLevel(ThreatLevel.None, "osTeleportOwner"); + + osTeleportAgent(m_host.OwnerID.ToString(), position, lookat); } /// @@ -966,8 +1055,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { CheckThreatLevel(ThreatLevel.VeryHigh, "osForceOtherSit"); - m_host.AddScriptLPS(1); - ForceSit(avatar, m_host.UUID); } @@ -981,8 +1068,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { CheckThreatLevel(ThreatLevel.VeryHigh, "osForceOtherSit"); - m_host.AddScriptLPS(1); - UUID targetID = new UUID(target); ForceSit(avatar, targetID); @@ -1008,20 +1093,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api part.SitTargetPosition); } - // Functions that get information from the agent itself. - // - // osGetAgentIP - this is used to determine the IP address of - //the client. This is needed to help configure other in world - //resources based on the IP address of the clients connected. - //I think High is a good risk level for this, as it is an - //information leak. + // Get a list of all the avatars/agents in the region + public LSL_List osGetAgents() + { + // threat level is None as we could get this information with an + // in-world script as well, just not as efficient + CheckThreatLevel(ThreatLevel.None, "osGetAgents"); + + LSL_List result = new LSL_List(); + World.ForEachRootScenePresence(delegate(ScenePresence sp) + { + result.Add(new LSL_String(sp.Name)); + }); + return result; + } + public string osGetAgentIP(string agent) { - CheckThreatLevel(ThreatLevel.High, "osGetAgentIP"); + CheckThreatLevel(ThreatLevel.Severe, "osGetAgentIP"); + if(!(World.Permissions.IsGod(m_host.OwnerID))) // user god always needed + return ""; UUID avatarID = (UUID)agent; - m_host.AddScriptLPS(1); if (World.Entities.ContainsKey((UUID)agent) && World.Entities[avatarID] is ScenePresence) { ScenePresence target = (ScenePresence)World.Entities[avatarID]; @@ -1032,22 +1126,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return ""; } - // Get a list of all the avatars/agents in the region - public LSL_List osGetAgents() - { - // threat level is None as we could get this information with an - // in-world script as well, just not as efficient - CheckThreatLevel(ThreatLevel.None, "osGetAgents"); - m_host.AddScriptLPS(1); - - LSL_List result = new LSL_List(); - World.ForEachRootScenePresence(delegate(ScenePresence sp) - { - result.Add(new LSL_String(sp.Name)); - }); - return result; - } - // Adam's super super custom animation functions public void osAvatarPlayAnimation(string avatar, string animation) { @@ -1058,19 +1136,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api private void AvatarPlayAnimation(string avatar, string animation) { - m_host.AddScriptLPS(1); - UUID avatarID; if(!UUID.TryParse(avatar, out avatarID)) return; - if(!World.Entities.ContainsKey(avatarID)) - return; - - ScenePresence target = null; - if ((World.Entities[avatarID] is ScenePresence)) - target = (ScenePresence)World.Entities[avatarID]; - + ScenePresence target = World.GetScenePresence(avatarID); if (target == null) return; @@ -1106,8 +1176,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { UUID avatarID = (UUID)avatar; - m_host.AddScriptLPS(1); - // FIXME: What we really want to do here is factor out the similar code in llStopAnimation() to a common // method (though see that doesn't do the is animation check, which is probably a bug) and have both // these functions call that common code. However, this does mean navigating the brain-dead requirement @@ -1138,29 +1206,59 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } //Texture draw functions + + public string osDrawResetTransform(string drawList) + { + CheckThreatLevel(); + + drawList += "ResetTransf;"; + return drawList; + } + + public string osDrawRotationTransform(string drawList, LSL_Float x) + { + CheckThreatLevel(); + + drawList += "RotTransf " + x + ";"; + return drawList; + } + + public string osDrawScaleTransform(string drawList, LSL_Float x, LSL_Float y) + { + CheckThreatLevel(); + + drawList += "ScaleTransf " + x + "," + y + ";"; + return drawList; + } + + public string osDrawTranslationTransform(string drawList, LSL_Float x, LSL_Float y) + { + CheckThreatLevel(); + + drawList += "TransTransf " + x + "," + y + ";"; + return drawList; + } + public string osMovePen(string drawList, int x, int y) { - CheckThreatLevel(ThreatLevel.None, "osMovePen"); + CheckThreatLevel(); - m_host.AddScriptLPS(1); drawList += "MoveTo " + x + "," + y + ";"; return drawList; } public string osDrawLine(string drawList, int startX, int startY, int endX, int endY) { - CheckThreatLevel(ThreatLevel.None, "osDrawLine"); + CheckThreatLevel(); - m_host.AddScriptLPS(1); drawList += "MoveTo "+ startX+","+ startY +"; LineTo "+endX +","+endY +"; "; return drawList; } public string osDrawLine(string drawList, int endX, int endY) { - CheckThreatLevel(ThreatLevel.None, "osDrawLine"); + CheckThreatLevel(); - m_host.AddScriptLPS(1); drawList += "LineTo " + endX + "," + endY + "; "; return drawList; } @@ -1169,43 +1267,45 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { CheckThreatLevel(ThreatLevel.None, "osDrawText"); - m_host.AddScriptLPS(1); drawList += "Text " + text + "; "; return drawList; } public string osDrawEllipse(string drawList, int width, int height) { - CheckThreatLevel(ThreatLevel.None, "osDrawEllipse"); + CheckThreatLevel(); - m_host.AddScriptLPS(1); drawList += "Ellipse " + width + "," + height + "; "; return drawList; } + public string osDrawFilledEllipse(string drawList, int width, int height) + { + CheckThreatLevel(); + + drawList += "FillEllipse " + width + "," + height + "; "; + return drawList; + } + public string osDrawRectangle(string drawList, int width, int height) { - CheckThreatLevel(ThreatLevel.None, "osDrawRectangle"); + CheckThreatLevel(); - m_host.AddScriptLPS(1); drawList += "Rectangle " + width + "," + height + "; "; return drawList; } public string osDrawFilledRectangle(string drawList, int width, int height) { - CheckThreatLevel(ThreatLevel.None, "osDrawFilledRectangle"); + CheckThreatLevel(); - m_host.AddScriptLPS(1); drawList += "FillRectangle " + width + "," + height + "; "; return drawList; } public string osDrawFilledPolygon(string drawList, LSL_List x, LSL_List y) { - CheckThreatLevel(ThreatLevel.None, "osDrawFilledPolygon"); - - m_host.AddScriptLPS(1); + CheckThreatLevel(); if (x.Length != y.Length || x.Length < 3) { @@ -1222,9 +1322,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public string osDrawPolygon(string drawList, LSL_List x, LSL_List y) { - CheckThreatLevel(ThreatLevel.None, "osDrawPolygon"); - - m_host.AddScriptLPS(1); + CheckThreatLevel(); if (x.Length != y.Length || x.Length < 3) { @@ -1241,36 +1339,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public string osSetFontSize(string drawList, int fontSize) { - CheckThreatLevel(ThreatLevel.None, "osSetFontSize"); + CheckThreatLevel(); - m_host.AddScriptLPS(1); drawList += "FontSize "+ fontSize +"; "; return drawList; } public string osSetFontName(string drawList, string fontName) { - CheckThreatLevel(ThreatLevel.None, "osSetFontName"); + CheckThreatLevel(); - m_host.AddScriptLPS(1); drawList += "FontName "+ fontName +"; "; return drawList; } public string osSetPenSize(string drawList, int penSize) { - CheckThreatLevel(ThreatLevel.None, "osSetPenSize"); + CheckThreatLevel(); - m_host.AddScriptLPS(1); drawList += "PenSize " + penSize + "; "; return drawList; } public string osSetPenColor(string drawList, string color) { - CheckThreatLevel(ThreatLevel.None, "osSetPenColor"); + CheckThreatLevel(); - m_host.AddScriptLPS(1); drawList += "PenColor " + color + "; "; return drawList; } @@ -1278,36 +1372,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // Deprecated public string osSetPenColour(string drawList, string colour) { - CheckThreatLevel(ThreatLevel.None, "osSetPenColour"); + CheckThreatLevel(); OSSLDeprecated("osSetPenColour", "osSetPenColor"); - m_host.AddScriptLPS(1); drawList += "PenColour " + colour + "; "; return drawList; } public string osSetPenCap(string drawList, string direction, string type) { - CheckThreatLevel(ThreatLevel.None, "osSetPenCap"); + CheckThreatLevel(); - m_host.AddScriptLPS(1); drawList += "PenCap " + direction + "," + type + "; "; return drawList; } public string osDrawImage(string drawList, int width, int height, string imageUrl) { - CheckThreatLevel(ThreatLevel.None, "osDrawImage"); + CheckThreatLevel(); - m_host.AddScriptLPS(1); drawList +="Image " +width + "," + height+ ","+ imageUrl +"; " ; return drawList; } public LSL_Vector osGetDrawStringSize(string contentType, string text, string fontName, int fontSize) { - CheckThreatLevel(ThreatLevel.VeryLow, "osGetDrawStringSize"); - m_host.AddScriptLPS(1); + CheckThreatLevel(); LSL_Vector vec = new LSL_Vector(0,0,0); IDynamicTextureManager textureManager = World.RequestModuleInterface(); @@ -1330,7 +1420,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // should be removed // CheckThreatLevel(ThreatLevel.High, "osSetStateEvents"); - m_host.AddScriptLPS(1); m_host.SetScriptEvents(m_item.ItemID, events); } @@ -1339,8 +1428,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { CheckThreatLevel(ThreatLevel.High, "osSetRegionWaterHeight"); - m_host.AddScriptLPS(1); - World.EventManager.TriggerRequestChangeWaterHeight((float)height); } @@ -1354,8 +1441,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { CheckThreatLevel(ThreatLevel.High, "osSetRegionSunSettings"); - m_host.AddScriptLPS(1); - while (sunHour > 24.0) sunHour -= 24.0; @@ -1379,8 +1464,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { CheckThreatLevel(ThreatLevel.High, "osSetEstateSunSettings"); - m_host.AddScriptLPS(1); - while (sunHour > 24.0) sunHour -= 24.0; @@ -1401,9 +1484,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api /// public double osGetCurrentSunHour() { - CheckThreatLevel(ThreatLevel.None, "osGetCurrentSunHour"); - - m_host.AddScriptLPS(1); + CheckThreatLevel(); // Must adjust for the fact that Region Sun Settings are still LL offset double sunHour = World.RegionInfo.RegionSettings.SunPosition - 6; @@ -1427,14 +1508,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public double osGetSunParam(string param) { - CheckThreatLevel(ThreatLevel.None, "osGetSunParam"); + CheckThreatLevel(); return GetSunParam(param); } private double GetSunParam(string param) { - m_host.AddScriptLPS(1); - double value = 0.0; ISunModule module = World.RequestModuleInterface(); @@ -1461,8 +1540,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api private void SetSunParam(string param, double value) { - m_host.AddScriptLPS(1); - ISunModule module = World.RequestModuleInterface(); if (module != null) { @@ -1473,7 +1550,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public string osWindActiveModelPluginName() { CheckThreatLevel(ThreatLevel.None, "osWindActiveModelPluginName"); - m_host.AddScriptLPS(1); IWindModule module = World.RequestModuleInterface(); if (module != null) @@ -1487,7 +1563,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void osSetWindParam(string plugin, string param, LSL_Float value) { CheckThreatLevel(ThreatLevel.VeryLow, "osSetWindParam"); - m_host.AddScriptLPS(1); IWindModule module = World.RequestModuleInterface(); if (module != null) @@ -1503,7 +1578,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Float osGetWindParam(string plugin, string param) { CheckThreatLevel(ThreatLevel.VeryLow, "osGetWindParam"); - m_host.AddScriptLPS(1); IWindModule module = World.RequestModuleInterface(); if (module != null) @@ -1518,7 +1592,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void osParcelJoin(LSL_Vector pos1, LSL_Vector pos2) { CheckThreatLevel(ThreatLevel.High, "osParcelJoin"); - m_host.AddScriptLPS(1); int startx = (int)(pos1.x < pos2.x ? pos1.x : pos2.x); int starty = (int)(pos1.y < pos2.y ? pos1.y : pos2.y); @@ -1531,7 +1604,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void osParcelSubdivide(LSL_Vector pos1, LSL_Vector pos2) { CheckThreatLevel(ThreatLevel.High, "osParcelSubdivide"); - m_host.AddScriptLPS(1); int startx = (int)(pos1.x < pos2.x ? pos1.x : pos2.x); int starty = (int)(pos1.y < pos2.y ? pos1.y : pos2.y); @@ -1558,8 +1630,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api private void SetParcelDetails(LSL_Vector pos, LSL_List rules, string functionName) { - m_host.AddScriptLPS(1); - // Get a reference to the land data and make sure the owner of the script // can modify it @@ -1572,13 +1642,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (!World.Permissions.CanEditParcelProperties(m_host.OwnerID, startLandObject, GroupPowers.LandOptions, false)) { - OSSLShoutError("You do not have permission to modify the parcel"); + OSSLShoutError("script owner does not have permission to modify the parcel"); return; } // Create a new land data object we can modify LandData newLand = startLandObject.LandData.Copy(); UUID uuid; + EstateSettings es = World.RegionInfo.EstateSettings; + + bool changed = false; + bool changedSeeAvs = false; + bool changedoverlay = false; + bool changedneedupdate = false; // Process the rules, not sure what the impact would be of changing owner or group for (int idx = 0; idx < rules.Length;) @@ -1588,35 +1664,151 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api switch (code) { case ScriptBaseClass.PARCEL_DETAILS_NAME: - newLand.Name = arg; + if(newLand.Name != arg) + { + newLand.Name = arg; + changed = true; + } break; case ScriptBaseClass.PARCEL_DETAILS_DESC: - newLand.Description = arg; + if(newLand.Description != arg) + { + newLand.Description = arg; + changed = true; + } break; case ScriptBaseClass.PARCEL_DETAILS_OWNER: - CheckThreatLevel(ThreatLevel.VeryHigh, functionName); - if (UUID.TryParse(arg, out uuid)) - newLand.OwnerID = uuid; + if(es != null && !es.IsEstateManagerOrOwner(m_host.OwnerID)) + { + OSSLError("script owner does not have permission to modify the parcel owner"); + } + else + { + if (UUID.TryParse(arg, out uuid)) + { + if(newLand.OwnerID != uuid) + { + changed = true; + newLand.OwnerID = uuid; + newLand.GroupID = UUID.Zero; + } + } + } break; case ScriptBaseClass.PARCEL_DETAILS_GROUP: - CheckThreatLevel(ThreatLevel.VeryHigh, functionName); - if (UUID.TryParse(arg, out uuid)) - newLand.GroupID = uuid; + if(m_host.OwnerID == newLand.OwnerID || es == null || es.IsEstateManagerOrOwner(m_host.OwnerID)) + { + if (UUID.TryParse(arg, out uuid)) + { + if(newLand.GroupID != uuid) + { + if(uuid == UUID.Zero) + { + changed = true; + newLand.GroupID = uuid; + } + else + { + IGroupsModule groupsModule = m_ScriptEngine.World.RequestModuleInterface(); + GroupMembershipData member = null; + if (groupsModule != null) + member = groupsModule.GetMembershipData(uuid, newLand.OwnerID); + if (member == null) + OSSLError(string.Format("land owner is not member of the new group for parcel")); + else + { + changed = true; + newLand.GroupID = uuid; + } + } + } + } + } + else + { + OSSLError("script owner does not have permission to modify the parcel group"); + } break; case ScriptBaseClass.PARCEL_DETAILS_CLAIMDATE: - CheckThreatLevel(ThreatLevel.VeryHigh, functionName); - newLand.ClaimDate = Convert.ToInt32(arg); - if (newLand.ClaimDate == 0) - newLand.ClaimDate = Util.UnixTimeSinceEpoch(); + if(es != null && !es.IsEstateManagerOrOwner(m_host.OwnerID)) + { + OSSLError("script owner does not have permission to modify the parcel CLAIM DATE"); + } + else + { + int date = Convert.ToInt32(arg); + if (date == 0) + date = Util.UnixTimeSinceEpoch(); + if(newLand.ClaimDate != date) + { + changed = true; + newLand.ClaimDate = date; + } + } break; - } - } - World.LandChannel.UpdateLandObject(newLand.LocalID,newLand); + case ScriptBaseClass.PARCEL_DETAILS_SEE_AVATARS: + bool newavs = (Convert.ToInt32(arg) != 0); + if(newLand.SeeAVs != newavs) + { + changed = true; + changedSeeAvs = true; + changedoverlay = true; + changedneedupdate = true; + newLand.SeeAVs = newavs; + } + break; + + case ScriptBaseClass.PARCEL_DETAILS_ANY_AVATAR_SOUNDS: + bool newavsounds = (Convert.ToInt32(arg) != 0); + if(newLand.AnyAVSounds != newavsounds) + { + changed = true; + newLand.AnyAVSounds = newavsounds; + } + break; + + case ScriptBaseClass.PARCEL_DETAILS_GROUP_SOUNDS: + bool newgrpsounds = (Convert.ToInt32(arg) != 0); + if(newLand.GroupAVSounds != newgrpsounds) + { + changed = true; + newLand.GroupAVSounds = newgrpsounds; + } + break; + } + } + if(changed) + { + World.LandChannel.UpdateLandObject(newLand.LocalID, newLand); + + if(changedneedupdate) + { + UUID parcelID= newLand.GlobalID; + World.ForEachRootScenePresence(delegate (ScenePresence avatar) + { + if (avatar == null || avatar.IsDeleted || avatar.IsInTransit) + return; + + if(changedSeeAvs && avatar.currentParcelUUID == parcelID ) + avatar.currentParcelUUID = parcelID; // force parcel flags review + + if(avatar.ControllingClient == null) + return; + + // this will be needed for some things like damage etc +// if(avatar.currentParcelUUID == parcelID) +// startLandObject.SendLandUpdateToClient(avatar.ControllingClient); + + if(changedoverlay && !avatar.IsNPC) + World.LandChannel.SendParcelsOverlay(avatar.ControllingClient); + }); + } + } } public double osList2Double(LSL_Types.list src, int index) @@ -1626,9 +1818,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // is not allowed to contain any. // This really should be removed. // - CheckThreatLevel(ThreatLevel.None, "osList2Double"); + CheckThreatLevel(); - m_host.AddScriptLPS(1); if (index < 0) { index = src.Length + index; @@ -1646,8 +1837,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // CheckThreatLevel(ThreatLevel.VeryLow, "osSetParcelMediaURL"); - m_host.AddScriptLPS(1); - ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition); if (land.LandData.OwnerID != m_host.OwnerID) @@ -1662,8 +1851,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // CheckThreatLevel(ThreatLevel.VeryLow, "osSetParcelSIPAddress"); - m_host.AddScriptLPS(1); - ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition); if (land.LandData.OwnerID != m_host.OwnerID) @@ -1690,8 +1877,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // CheckThreatLevel(ThreatLevel.High, "osGetScriptEngineName"); - m_host.AddScriptLPS(1); - int scriptEngineNameIndex = 0; if (!String.IsNullOrEmpty(m_ScriptEngine.ScriptEngineName)) @@ -1716,7 +1901,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Integer osCheckODE() { - m_host.AddScriptLPS(1); + CheckThreatLevel(); + LSL_Integer ret = 0; // false if (m_ScriptEngine.World.PhysicsScene != null) { @@ -1739,6 +1925,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // about the physics engine, this function returns an empty string if // the user does not have permission to see it. This as opposed to // throwing an exception. + m_host.AddScriptLPS(1); string ret = String.Empty; if (String.IsNullOrEmpty(CheckThreatLevelTest(ThreatLevel.High, "osGetPhysicsEngineType"))) @@ -1757,10 +1944,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public string osGetPhysicsEngineName() { - // not doing security checks - // this whould limit the use of this + CheckThreatLevel(); - m_host.AddScriptLPS(1); string ret = "NoEngine"; if (m_ScriptEngine.World.PhysicsScene != null) { @@ -1771,6 +1956,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } return ret; } + public string osGetSimulatorVersion() { // High because it can be used to target attacks to known weaknesses @@ -1779,7 +1965,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // kiddie) // CheckThreatLevel(ThreatLevel.High,"osGetSimulatorVersion"); - m_host.AddScriptLPS(1); return m_ScriptEngine.World.GetSimulatorVersion(); } @@ -1825,8 +2010,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { CheckThreatLevel(ThreatLevel.None, "osParseJSONNew"); - m_host.AddScriptLPS(1); - try { OSD decoded = OSDParser.DeserializeJson(JSON); @@ -1843,8 +2026,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { CheckThreatLevel(ThreatLevel.None, "osParseJSON"); - m_host.AddScriptLPS(1); - Object decoded = osParseJSONNew(JSON); if ( decoded is Hashtable ) { @@ -1875,7 +2056,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void osMessageObject(LSL_Key objectUUID, string message) { CheckThreatLevel(ThreatLevel.Low, "osMessageObject"); - m_host.AddScriptLPS(1); UUID objUUID; if (!UUID.TryParse(objectUUID, out objUUID)) // prior to patching, a thrown exception regarding invalid GUID format would be shouted instead. @@ -1916,7 +2096,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // if this is restricted to objects rezzed by this host level can be reduced CheckThreatLevel(ThreatLevel.Low, "osDie"); - m_host.AddScriptLPS(1); UUID objUUID; if (!UUID.TryParse(objectUUID, out objUUID)) @@ -1966,7 +2145,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void osMakeNotecard(string notecardName, LSL_Types.list contents) { CheckThreatLevel(ThreatLevel.High, "osMakeNotecard"); - m_host.AddScriptLPS(1); StringBuilder notecardData = new StringBuilder(); @@ -2038,7 +2216,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.Inventory.AddInventoryItemExclusive(taskItem, false); else m_host.Inventory.AddInventoryItem(taskItem, false); - m_host.ParentGroup.AggregatePerms(); + m_host.ParentGroup.InvalidateDeepEffectivePerms(); return taskItem; } @@ -2152,7 +2330,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public string osGetNotecardLine(string name, int line) { CheckThreatLevel(ThreatLevel.VeryHigh, "osGetNotecardLine"); - m_host.AddScriptLPS(1); UUID assetID = CacheNotecard(name); @@ -2180,7 +2357,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public string osGetNotecard(string name) { CheckThreatLevel(ThreatLevel.VeryHigh, "osGetNotecard"); - m_host.AddScriptLPS(1); string text = LoadNotecard(name); @@ -2210,7 +2386,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public int osGetNumberOfNotecardLines(string name) { CheckThreatLevel(ThreatLevel.VeryHigh, "osGetNumberOfNotecardLines"); - m_host.AddScriptLPS(1); UUID assetID = CacheNotecard(name); @@ -2226,7 +2401,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public string osAvatarName2Key(string firstname, string lastname) { CheckThreatLevel(ThreatLevel.Low, "osAvatarName2Key"); - m_host.AddScriptLPS(1); IUserManagement userManager = World.RequestModuleInterface(); if (userManager == null) @@ -2278,7 +2452,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public string osKey2Name(string id) { CheckThreatLevel(ThreatLevel.Low, "osKey2Name"); - m_host.AddScriptLPS(1); UUID key = new UUID(); @@ -2388,7 +2561,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public string osGetGridNick() { CheckThreatLevel(ThreatLevel.Moderate, "osGetGridNick"); - m_host.AddScriptLPS(1); string nick = String.Empty; IConfigSource config = m_ScriptEngine.ConfigSource; @@ -2405,7 +2577,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public string osGetGridName() { CheckThreatLevel(ThreatLevel.Moderate, "osGetGridName"); - m_host.AddScriptLPS(1); string name = String.Empty; IConfigSource config = m_ScriptEngine.ConfigSource; @@ -2422,7 +2593,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public string osGetGridLoginURI() { CheckThreatLevel(ThreatLevel.Moderate, "osGetGridLoginURI"); - m_host.AddScriptLPS(1); string loginURI = String.Empty; IConfigSource config = m_ScriptEngine.ConfigSource; @@ -2439,7 +2609,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public string osGetGridHomeURI() { CheckThreatLevel(ThreatLevel.Moderate, "osGetGridHomeURI"); - m_host.AddScriptLPS(1); IConfigSource config = m_ScriptEngine.ConfigSource; string HomeURI = Util.GetConfigVarFromSections(config, "HomeURI", @@ -2461,7 +2630,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public string osGetGridGatekeeperURI() { CheckThreatLevel(ThreatLevel.Moderate, "osGetGridGatekeeperURI"); - m_host.AddScriptLPS(1); IConfigSource config = m_ScriptEngine.ConfigSource; string gatekeeperURI = Util.GetConfigVarFromSections(config, "GatekeeperURI", @@ -2480,7 +2648,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public string osGetGridCustom(string key) { CheckThreatLevel(ThreatLevel.Moderate, "osGetGridCustom"); - m_host.AddScriptLPS(1); string retval = String.Empty; IConfigSource config = m_ScriptEngine.ConfigSource; @@ -2497,7 +2664,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public string osGetAvatarHomeURI(string uuid) { CheckThreatLevel(ThreatLevel.Low, "osGetAvatarHomeURI"); - m_host.AddScriptLPS(1); IUserManagement userManager = m_ScriptEngine.World.RequestModuleInterface(); string returnValue = ""; @@ -2530,7 +2696,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_String osFormatString(string str, LSL_List strings) { CheckThreatLevel(ThreatLevel.VeryLow, "osFormatString"); - m_host.AddScriptLPS(1); return String.Format(str, strings.Data); } @@ -2538,7 +2703,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_List osMatchString(string src, string pattern, int start) { CheckThreatLevel(ThreatLevel.VeryLow, "osMatchString"); - m_host.AddScriptLPS(1); LSL_List result = new LSL_List(); @@ -2580,7 +2744,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_String osReplaceString(string src, string pattern, string replace, int count, int start) { CheckThreatLevel(ThreatLevel.VeryLow, "osReplaceString"); - m_host.AddScriptLPS(1); // Normalize indices (if negative). // After normlaization they may still be @@ -2605,7 +2768,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public string osLoadedCreationDate() { CheckThreatLevel(ThreatLevel.Low, "osLoadedCreationDate"); - m_host.AddScriptLPS(1); return World.RegionInfo.RegionSettings.LoadedCreationDate; } @@ -2613,7 +2775,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public string osLoadedCreationTime() { CheckThreatLevel(ThreatLevel.Low, "osLoadedCreationTime"); - m_host.AddScriptLPS(1); return World.RegionInfo.RegionSettings.LoadedCreationTime; } @@ -2621,7 +2782,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public string osLoadedCreationID() { CheckThreatLevel(ThreatLevel.Low, "osLoadedCreationID"); - m_host.AddScriptLPS(1); return World.RegionInfo.RegionSettings.LoadedCreationID; } @@ -2642,7 +2802,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_List osGetLinkPrimitiveParams(int linknumber, LSL_List rules) { CheckThreatLevel(ThreatLevel.High, "osGetLinkPrimitiveParams"); - m_host.AddScriptLPS(1); + InitLSL(); // One needs to cast m_LSL_Api because we're using functions not // on the ILSL_Api interface. @@ -2671,8 +2831,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { CheckThreatLevel(ThreatLevel.VeryLow, "osForceCreateLink"); - m_host.AddScriptLPS(1); - InitLSL(); ((LSL_Api)m_LSL_Api).CreateLink(target, parent); } @@ -2681,8 +2839,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { CheckThreatLevel(ThreatLevel.VeryLow, "osForceBreakLink"); - m_host.AddScriptLPS(1); - InitLSL(); ((LSL_Api)m_LSL_Api).BreakLink(linknum); } @@ -2691,16 +2847,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { CheckThreatLevel(ThreatLevel.VeryLow, "osForceBreakAllLinks"); - m_host.AddScriptLPS(1); - InitLSL(); ((LSL_Api)m_LSL_Api).BreakAllLinks(); } public LSL_Integer osIsNpc(LSL_Key npc) { - CheckThreatLevel(ThreatLevel.None, "osIsNpc"); - m_host.AddScriptLPS(1); + CheckThreatLevel(); INPCModule module = World.RequestModuleInterface(); if (module != null) @@ -2717,7 +2870,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard) { CheckThreatLevel(ThreatLevel.High, "osNpcCreate"); - m_host.AddScriptLPS(1); // have to get the npc module also here to set the default Not Owned INPCModule module = World.RequestModuleInterface(); @@ -2732,7 +2884,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options) { CheckThreatLevel(ThreatLevel.High, "osNpcCreate"); - m_host.AddScriptLPS(1); return NpcCreate( firstname, lastname, position, notecard, @@ -2875,7 +3026,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Key osNpcSaveAppearance(LSL_Key npc, string notecard) { CheckThreatLevel(ThreatLevel.High, "osNpcSaveAppearance"); - m_host.AddScriptLPS(1); INPCModule npcModule = World.RequestModuleInterface(); @@ -2897,7 +3047,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void osNpcLoadAppearance(LSL_Key npc, string notecard) { CheckThreatLevel(ThreatLevel.High, "osNpcLoadAppearance"); - m_host.AddScriptLPS(1); INPCModule npcModule = World.RequestModuleInterface(); @@ -2929,7 +3078,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Key osNpcGetOwner(LSL_Key npc) { CheckThreatLevel(ThreatLevel.None, "osNpcGetOwner"); - m_host.AddScriptLPS(1); INPCModule npcModule = World.RequestModuleInterface(); if (npcModule != null) @@ -2951,7 +3099,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Vector osNpcGetPos(LSL_Key npc) { CheckThreatLevel(ThreatLevel.High, "osNpcGetPos"); - m_host.AddScriptLPS(1); INPCModule npcModule = World.RequestModuleInterface(); if (npcModule != null) @@ -2975,7 +3122,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void osNpcMoveTo(LSL_Key npc, LSL_Vector pos) { CheckThreatLevel(ThreatLevel.High, "osNpcMoveTo"); - m_host.AddScriptLPS(1); INPCModule module = World.RequestModuleInterface(); if (module != null) @@ -2994,7 +3140,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void osNpcMoveToTarget(LSL_Key npc, LSL_Vector target, int options) { CheckThreatLevel(ThreatLevel.High, "osNpcMoveToTarget"); - m_host.AddScriptLPS(1); INPCModule module = World.RequestModuleInterface(); if (module != null) @@ -3019,7 +3164,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Rotation osNpcGetRot(LSL_Key npc) { CheckThreatLevel(ThreatLevel.High, "osNpcGetRot"); - m_host.AddScriptLPS(1); INPCModule npcModule = World.RequestModuleInterface(); if (npcModule != null) @@ -3043,7 +3187,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void osNpcSetRot(LSL_Key npc, LSL_Rotation rotation) { CheckThreatLevel(ThreatLevel.High, "osNpcSetRot"); - m_host.AddScriptLPS(1); INPCModule npcModule = World.RequestModuleInterface(); if (npcModule != null) @@ -3065,7 +3208,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void osNpcStopMoveToTarget(LSL_Key npc) { CheckThreatLevel(ThreatLevel.High, "osNpcStopMoveToTarget"); - m_host.AddScriptLPS(1); INPCModule module = World.RequestModuleInterface(); if (module != null) @@ -3082,7 +3224,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void osNpcSetProfileAbout(LSL_Key npc, string about) { CheckThreatLevel(ThreatLevel.Low, "osNpcSetProfileAbout"); - m_host.AddScriptLPS(1); INPCModule module = World.RequestModuleInterface(); if (module != null) @@ -3101,7 +3242,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void osNpcSetProfileImage(LSL_Key npc, string image) { CheckThreatLevel(ThreatLevel.Low, "osNpcSetProfileImage"); - m_host.AddScriptLPS(1); INPCModule module = World.RequestModuleInterface(); if (module != null) @@ -3135,7 +3275,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void osNpcSay(LSL_Key npc, int channel, string message) { CheckThreatLevel(ThreatLevel.High, "osNpcSay"); - m_host.AddScriptLPS(1); INPCModule module = World.RequestModuleInterface(); if (module != null) @@ -3152,7 +3291,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void osNpcShout(LSL_Key npc, int channel, string message) { CheckThreatLevel(ThreatLevel.High, "osNpcShout"); - m_host.AddScriptLPS(1); INPCModule module = World.RequestModuleInterface(); if (module != null) @@ -3169,7 +3307,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void osNpcSit(LSL_Key npc, LSL_Key target, int options) { CheckThreatLevel(ThreatLevel.High, "osNpcSit"); - m_host.AddScriptLPS(1); INPCModule module = World.RequestModuleInterface(); if (module != null) @@ -3186,7 +3323,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void osNpcStand(LSL_Key npc) { CheckThreatLevel(ThreatLevel.High, "osNpcStand"); - m_host.AddScriptLPS(1); INPCModule module = World.RequestModuleInterface(); if (module != null) @@ -3203,7 +3339,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void osNpcRemove(LSL_Key npc) { CheckThreatLevel(ThreatLevel.High, "osNpcRemove"); - m_host.AddScriptLPS(1); try { @@ -3224,7 +3359,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void osNpcPlayAnimation(LSL_Key npc, string animation) { CheckThreatLevel(ThreatLevel.High, "osNpcPlayAnimation"); - m_host.AddScriptLPS(1); INPCModule module = World.RequestModuleInterface(); if (module != null) @@ -3239,7 +3373,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void osNpcStopAnimation(LSL_Key npc, string animation) { CheckThreatLevel(ThreatLevel.High, "osNpcStopAnimation"); - m_host.AddScriptLPS(1); INPCModule module = World.RequestModuleInterface(); if (module != null) @@ -3254,7 +3387,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void osNpcWhisper(LSL_Key npc, int channel, string message) { CheckThreatLevel(ThreatLevel.High, "osNpcWhisper"); - m_host.AddScriptLPS(1); INPCModule module = World.RequestModuleInterface(); if (module != null) @@ -3271,7 +3403,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void osNpcTouch(LSL_Key npcLSL_Key, LSL_Key object_key, LSL_Integer link_num) { CheckThreatLevel(ThreatLevel.High, "osNpcTouch"); - m_host.AddScriptLPS(1); INPCModule module = World.RequestModuleInterface(); int linkNum = link_num.value; @@ -3316,7 +3447,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Key osOwnerSaveAppearance(string notecard) { CheckThreatLevel(ThreatLevel.High, "osOwnerSaveAppearance"); - m_host.AddScriptLPS(1); return SaveAppearanceToNotecard(m_host.OwnerID, notecard); } @@ -3324,7 +3454,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Key osAgentSaveAppearance(LSL_Key avatarId, string notecard) { CheckThreatLevel(ThreatLevel.VeryHigh, "osAgentSaveAppearance"); - m_host.AddScriptLPS(1); return SaveAppearanceToNotecard(avatarId, notecard); } @@ -3377,7 +3506,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_String osGetGender(LSL_Key rawAvatarId) { CheckThreatLevel(ThreatLevel.None, "osGetGender"); - m_host.AddScriptLPS(1); UUID avatarId; if (!UUID.TryParse(rawAvatarId, out avatarId)) @@ -3420,8 +3548,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api /// public LSL_Key osGetMapTexture() { - CheckThreatLevel(ThreatLevel.None, "osGetMapTexture"); - m_host.AddScriptLPS(1); + CheckThreatLevel(); return m_ScriptEngine.World.RegionInfo.RegionSettings.TerrainImageID.ToString(); } @@ -3434,7 +3561,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Key osGetRegionMapTexture(string regionName) { CheckThreatLevel(ThreatLevel.High, "osGetRegionMapTexture"); - m_host.AddScriptLPS(1); Scene scene = m_ScriptEngine.World; UUID key = UUID.Zero; @@ -3465,7 +3591,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_List osGetRegionStats() { CheckThreatLevel(ThreatLevel.Moderate, "osGetRegionStats"); - m_host.AddScriptLPS(1); + LSL_List ret = new LSL_List(); float[] stats = World.StatsReporter.LastReportedSimStats; @@ -3478,8 +3604,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Vector osGetRegionSize() { - CheckThreatLevel(ThreatLevel.None, "osGetRegionSize"); - m_host.AddScriptLPS(1); + CheckThreatLevel(); Scene scene = m_ScriptEngine.World; RegionInfo reg = World.RegionInfo; @@ -3491,7 +3616,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public int osGetSimulatorMemory() { CheckThreatLevel(ThreatLevel.Moderate, "osGetSimulatorMemory"); - m_host.AddScriptLPS(1); + long pws = System.Diagnostics.Process.GetCurrentProcess().WorkingSet64; if (pws > Int32.MaxValue) @@ -3502,10 +3627,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return (int)pws; } + public int osGetSimulatorMemoryKB() + { + CheckThreatLevel(ThreatLevel.Moderate, "osGetSimulatorMemoryKB"); + + long pws = System.Diagnostics.Process.GetCurrentProcess().WorkingSet64; + + if((pws & 0x3FFL) != 0) + pws += 0x400L; + pws >>= 10; + + if (pws > Int32.MaxValue) + return Int32.MaxValue; + + return (int)pws; + } + public void osSetSpeed(string UUID, LSL_Float SpeedModifier) { CheckThreatLevel(ThreatLevel.Moderate, "osSetSpeed"); - m_host.AddScriptLPS(1); + ScenePresence avatar = World.GetScenePresence(new UUID(UUID)); if (avatar != null) @@ -3515,7 +3656,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void osKickAvatar(string FirstName, string SurName, string alert) { CheckThreatLevel(ThreatLevel.Severe, "osKickAvatar"); - m_host.AddScriptLPS(1); World.ForEachRootScenePresence(delegate(ScenePresence sp) { @@ -3534,7 +3674,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Float osGetHealth(string avatar) { CheckThreatLevel(ThreatLevel.None, "osGetHealth"); - m_host.AddScriptLPS(1); LSL_Float health = new LSL_Float(-1); ScenePresence presence = World.GetScenePresence(new UUID(avatar)); @@ -3546,7 +3685,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void osCauseDamage(string avatar, double damage) { CheckThreatLevel(ThreatLevel.High, "osCauseDamage"); - m_host.AddScriptLPS(1); UUID avatarId = new UUID(avatar); Vector3 pos = m_host.GetWorldPosition(); @@ -3574,7 +3712,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void osCauseHealing(string avatar, double healing) { CheckThreatLevel(ThreatLevel.High, "osCauseHealing"); - m_host.AddScriptLPS(1); UUID avatarId = new UUID(avatar); ScenePresence presence = World.GetScenePresence(avatarId); @@ -3594,7 +3731,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void osSetHealth(string avatar, double health) { CheckThreatLevel(ThreatLevel.High, "osSetHealth"); - m_host.AddScriptLPS(1); UUID avatarId = new UUID(avatar); ScenePresence presence = World.GetScenePresence(avatarId); @@ -3613,7 +3749,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void osSetHealRate(string avatar, double healrate) { CheckThreatLevel(ThreatLevel.High, "osSetHealRate"); - m_host.AddScriptLPS(1); UUID avatarId = new UUID(avatar); ScenePresence presence = World.GetScenePresence(avatarId); @@ -3625,7 +3760,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Float osGetHealRate(string avatar) { CheckThreatLevel(ThreatLevel.None, "osGetHealRate"); - m_host.AddScriptLPS(1); LSL_Float rate = new LSL_Float(0); ScenePresence presence = World.GetScenePresence(new UUID(avatar)); @@ -3637,18 +3771,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_List osGetPrimitiveParams(LSL_Key prim, LSL_List rules) { CheckThreatLevel(ThreatLevel.High, "osGetPrimitiveParams"); - m_host.AddScriptLPS(1); - InitLSL(); + InitLSL(); return m_LSL_Api.GetPrimitiveParamsEx(prim, rules); } public void osSetPrimitiveParams(LSL_Key prim, LSL_List rules) { CheckThreatLevel(ThreatLevel.High, "osSetPrimitiveParams"); - m_host.AddScriptLPS(1); - InitLSL(); + InitLSL(); m_LSL_Api.SetPrimitiveParamsEx(prim, rules, "osSetPrimitiveParams"); } @@ -3657,8 +3789,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api /// public void osSetProjectionParams(bool projection, LSL_Key texture, double fov, double focus, double amb) { - CheckThreatLevel(ThreatLevel.High, "osSetProjectionParams"); - osSetProjectionParams(UUID.Zero.ToString(), projection, texture, fov, focus, amb); } @@ -3668,7 +3798,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void osSetProjectionParams(LSL_Key prim, bool projection, LSL_Key texture, double fov, double focus, double amb) { CheckThreatLevel(ThreatLevel.High, "osSetProjectionParams"); - m_host.AddScriptLPS(1); SceneObjectPart obj = null; if (prim == UUID.Zero.ToString()) @@ -3699,12 +3828,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_List osGetAvatarList() { CheckThreatLevel(ThreatLevel.None, "osGetAvatarList"); - m_host.AddScriptLPS(1); LSL_List result = new LSL_List(); World.ForEachRootScenePresence(delegate (ScenePresence avatar) { - if (avatar != null && avatar.UUID != m_host.OwnerID) + if (avatar != null && !avatar.IsDeleted && avatar.UUID != m_host.OwnerID ) + { + result.Add(new LSL_String(avatar.UUID.ToString())); + result.Add(new LSL_Vector(avatar.AbsolutePosition)); + result.Add(new LSL_String(avatar.Name)); + } + }); + + return result; + } + + public LSL_List osGetNPCList() + { + CheckThreatLevel(ThreatLevel.None, "osGetNPCList"); + + LSL_List result = new LSL_List(); + World.ForEachRootScenePresence(delegate (ScenePresence avatar) + { + // npcs are not childagents but that is now. + if (avatar != null && avatar.IsNPC && !avatar.IsDeleted && !avatar.IsChildAgent && !avatar.IsInTransit) { result.Add(new LSL_String(avatar.UUID.ToString())); result.Add(new LSL_Vector(avatar.AbsolutePosition)); @@ -3720,10 +3867,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api /// /// /// - public LSL_String osUnixTimeToTimestamp(long time) + public LSL_String osUnixTimeToTimestamp(LSL_Integer time) { CheckThreatLevel(ThreatLevel.VeryLow, "osUnixTimeToTimestamp"); - m_host.AddScriptLPS(1); long baseTicks = 621355968000000000; long tickResolution = 10000000; @@ -3740,7 +3886,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api /// Item description public LSL_String osGetInventoryDesc(string item) { - m_host.AddScriptLPS(1); + CheckThreatLevel(); lock (m_host.TaskInventory) { @@ -3764,7 +3910,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Integer osInviteToGroup(LSL_Key agentId) { CheckThreatLevel(ThreatLevel.VeryLow, "osInviteToGroup"); - m_host.AddScriptLPS(1); UUID agent = new UUID(agentId); @@ -3799,7 +3944,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Integer osEjectFromGroup(LSL_Key agentId) { CheckThreatLevel(ThreatLevel.VeryLow, "osEjectFromGroup"); - m_host.AddScriptLPS(1); UUID agent = new UUID(agentId); @@ -3835,7 +3979,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { CheckThreatLevel(ThreatLevel.High, "osSetTerrainTexture"); - m_host.AddScriptLPS(1); //Check to make sure that the script's owner is the estate manager/master //World.Permissions.GenericEstatePermission( if (World.Permissions.IsGod(m_host.OwnerID)) @@ -3865,7 +4008,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { CheckThreatLevel(ThreatLevel.High, "osSetTerrainTextureHeight"); - m_host.AddScriptLPS(1); //Check to make sure that the script's owner is the estate manager/master //World.Permissions.GenericEstatePermission( if (World.Permissions.IsGod(m_host.OwnerID)) @@ -3886,8 +4028,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { CheckThreatLevel(ThreatLevel.High, "osForceAttachToAvatar"); - m_host.AddScriptLPS(1); - InitLSL(); ((LSL_Api)m_LSL_Api).AttachToAvatar(attachmentPoint); } @@ -3896,8 +4036,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { CheckThreatLevel(ThreatLevel.High, "osForceAttachToAvatarFromInventory"); - m_host.AddScriptLPS(1); - ForceAttachToAvatarFromInventory(m_host.OwnerID, itemName, attachmentPoint); } @@ -3905,8 +4043,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { CheckThreatLevel(ThreatLevel.VeryHigh, "osForceAttachToOtherAvatarFromInventory"); - m_host.AddScriptLPS(1); - UUID avatarId; if (!UUID.TryParse(rawAvatarId, out avatarId)) @@ -3966,8 +4102,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { CheckThreatLevel(ThreatLevel.High, "osForceDetachFromAvatar"); - m_host.AddScriptLPS(1); - InitLSL(); ((LSL_Api)m_LSL_Api).DetachFromAvatar(); } @@ -3976,8 +4110,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { CheckThreatLevel(ThreatLevel.Moderate, "osGetNumberOfAttachments"); - m_host.AddScriptLPS(1); - UUID targetUUID; ScenePresence target; LSL_List resp = new LSL_List(); @@ -4011,7 +4143,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void osMessageAttachments(LSL_Key avatar, string message, LSL_List attachmentPoints, int options) { CheckThreatLevel(ThreatLevel.Moderate, "osMessageAttachments"); - m_host.AddScriptLPS(1); UUID targetUUID; if(!UUID.TryParse(avatar.ToString(), out targetUUID)) @@ -4120,8 +4251,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api /// 1 if thing is a valid UUID, 0 otherwise public LSL_Integer osIsUUID(string thing) { - CheckThreatLevel(ThreatLevel.None, "osIsUUID"); - m_host.AddScriptLPS(1); + CheckThreatLevel(); UUID test; return UUID.TryParse(thing, out test) ? 1 : 0; @@ -4135,8 +4265,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api /// public LSL_Float osMin(double a, double b) { - CheckThreatLevel(ThreatLevel.None, "osMin"); - m_host.AddScriptLPS(1); + CheckThreatLevel(); return Math.Min(a, b); } @@ -4149,8 +4278,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api /// public LSL_Float osMax(double a, double b) { - CheckThreatLevel(ThreatLevel.None, "osMax"); - m_host.AddScriptLPS(1); + CheckThreatLevel(); return Math.Max(a, b); } @@ -4158,7 +4286,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Key osGetRezzingObject() { CheckThreatLevel(ThreatLevel.None, "osGetRezzingObject"); - m_host.AddScriptLPS(1); + UUID rezID = m_host.ParentGroup.RezzerID; if(rezID == UUID.Zero || m_host.ParentGroup.Scene.GetScenePresence(rezID) != null) return new LSL_Key(UUID.Zero.ToString()); @@ -4183,7 +4311,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api /// boolean indicating whether an error was shouted. protected bool ShoutErrorOnLackingOwnerPerms(int perms, string errorPrefix) { - m_host.AddScriptLPS(1); bool fail = false; if (m_item.PermsGranter != m_host.OwnerID) { @@ -4234,7 +4361,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void osDropAttachment() { CheckThreatLevel(ThreatLevel.Moderate, "osDropAttachment"); - m_host.AddScriptLPS(1); DropAttachment(true); } @@ -4242,7 +4368,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void osForceDropAttachment() { CheckThreatLevel(ThreatLevel.High, "osForceDropAttachment"); - m_host.AddScriptLPS(1); DropAttachment(false); } @@ -4250,7 +4375,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void osDropAttachmentAt(LSL_Vector pos, LSL_Rotation rot) { CheckThreatLevel(ThreatLevel.Moderate, "osDropAttachmentAt"); - m_host.AddScriptLPS(1); DropAttachmentAt(true, pos, rot); } @@ -4258,7 +4382,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void osForceDropAttachmentAt(LSL_Vector pos, LSL_Rotation rot) { CheckThreatLevel(ThreatLevel.High, "osForceDropAttachmentAt"); - m_host.AddScriptLPS(1); DropAttachmentAt(false, pos, rot); } @@ -4266,7 +4389,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Integer osListenRegex(int channelID, string name, string ID, string msg, int regexBitfield) { CheckThreatLevel(ThreatLevel.Low, "osListenRegex"); - m_host.AddScriptLPS(1); + UUID keyID; UUID.TryParse(ID, out keyID); @@ -4314,7 +4437,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Integer osRegexIsMatch(string input, string pattern) { CheckThreatLevel(ThreatLevel.Low, "osRegexIsMatch"); - m_host.AddScriptLPS(1); + try { return Regex.IsMatch(input, pattern) ? 1 : 0; @@ -4329,7 +4452,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_String osRequestURL(LSL_List options) { CheckThreatLevel(ThreatLevel.Moderate, "osRequestSecureURL"); - m_host.AddScriptLPS(1); Hashtable opts = new Hashtable(); for (int i = 0 ; i < options.Length ; i++) @@ -4347,7 +4469,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_String osRequestSecureURL(LSL_List options) { CheckThreatLevel(ThreatLevel.Moderate, "osRequestSecureURL"); - m_host.AddScriptLPS(1); Hashtable opts = new Hashtable(); for (int i = 0 ; i < options.Length ; i++) @@ -4364,7 +4485,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void osCollisionSound(string impact_sound, double impact_volume) { - m_host.AddScriptLPS(1); + CheckThreatLevel(); if(impact_sound == "") { @@ -4396,7 +4517,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // still not very usefull, detector is lost on rez, restarts, etc public void osVolumeDetect(int detect) { - m_host.AddScriptLPS(1); + CheckThreatLevel(); if (m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted || m_host.ParentGroup.IsAttachment) return; @@ -4404,5 +4525,553 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.ScriptSetVolumeDetect(detect != 0); } + /// + /// Get inertial data + /// + /// + /// + /// + /// a LSL list with contents: + /// LSL_Float mass, the total mass of a linkset + /// LSL_Vector CenterOfMass, center mass relative to root prim + /// LSL_Vector Inertia, elements of diagonal of inertia Ixx,Iyy,Izz divided by total mass + /// LSL_Vector aux, elements of upper triagle of inertia Ixy (= Iyx), Ixz (= Izx), Iyz(= Izy) divided by total mass + /// + public LSL_List osGetInertiaData() + { + CheckThreatLevel(); + + LSL_List result = new LSL_List(); + float TotalMass; + Vector3 CenterOfMass; + Vector3 Inertia; + Vector4 aux; + + SceneObjectGroup sog = m_host.ParentGroup; + if(sog== null || sog.IsDeleted) + return result; + + sog.GetInertiaData(out TotalMass, out CenterOfMass, out Inertia, out aux ); + if(TotalMass > 0) + { + float t = 1.0f/TotalMass; + Inertia.X *= t; + Inertia.Y *= t; + Inertia.Z *= t; + + aux.X *= t; + aux.Y *= t; + aux.Z *= t; + } + + result.Add(new LSL_Float(TotalMass)); + result.Add(new LSL_Vector(CenterOfMass.X, CenterOfMass.Y, CenterOfMass.Z)); + result.Add(new LSL_Vector(Inertia.X, Inertia.Y, Inertia.Z)); + result.Add(new LSL_Vector(aux.X, aux.Y, aux.Z)); + return result; + } + + /// + /// set inertial data + /// replaces the automatic calculation of mass, center of mass and inertia + /// + /// + /// total mass of linkset + /// location of center of mass relative to root prim in local coords + /// moment of inertia relative to principal axis and center of mass,Ixx, Iyy, Izz divided by mass + /// rotation of the inertia, relative to local axis + /// + /// the inertia argument is is inertia divided by mass, so corresponds only to the geometric distribution of mass and both can be changed independently. + /// + + public void osSetInertia(LSL_Float mass, LSL_Vector centerOfMass, LSL_Vector principalInertiaScaled, LSL_Rotation lslrot) + { + CheckThreatLevel(); + + SceneObjectGroup sog = m_host.ParentGroup; + if(sog== null || sog.IsDeleted) + return; + + if(mass < 0 || principalInertiaScaled.x < 0 || principalInertiaScaled.y < 0 || principalInertiaScaled.z < 0) + return; + + // need more checks + + Vector3 CenterOfMass = new Vector3((float)centerOfMass.x,(float)centerOfMass.y,(float)centerOfMass.z); + Vector3 Inertia; + float m = (float)mass; + + Inertia.X = m * (float)principalInertiaScaled.x; + Inertia.Y = m * (float)principalInertiaScaled.y; + Inertia.Z = m * (float)principalInertiaScaled.z; + + Vector4 rot = new Vector4((float)lslrot.x, (float)lslrot.y, (float)lslrot.y, (float)lslrot.s); + rot.Normalize(); + + sog.SetInertiaData(m, CenterOfMass, Inertia, rot ); + } + + /// + /// set inertial data as a sphere + /// replaces the automatic calculation of mass, center of mass and inertia + /// + /// + /// total mass of linkset + /// size of the Box + /// location of center of mass relative to root prim in local coords + /// rotation of the box, and so inertia, relative to local axis + /// + /// + public void osSetInertiaAsBox(LSL_Float mass, LSL_Vector boxSize, LSL_Vector centerOfMass, LSL_Rotation lslrot) + { + CheckThreatLevel(); + + SceneObjectGroup sog = m_host.ParentGroup; + if(sog== null || sog.IsDeleted) + return; + + if(mass < 0) + return; + + // need more checks + + Vector3 CenterOfMass = new Vector3((float)centerOfMass.x,(float)centerOfMass.y,(float)centerOfMass.z); + Vector3 Inertia; + float lx = (float)boxSize.x; + float ly = (float)boxSize.y; + float lz = (float)boxSize.z; + float m = (float)mass; + float t = m / 12.0f; + + Inertia.X = t * (ly*ly + lz*lz); + Inertia.Y = t * (lx*lx + lz*lz); + Inertia.Z = t * (lx*lx + ly*ly); + + Vector4 rot = new Vector4((float)lslrot.x, (float)lslrot.y, (float)lslrot.z, (float)lslrot.s); + rot.Normalize(); + + sog.SetInertiaData(m, CenterOfMass, Inertia, rot ); + } + + /// + /// set inertial data as a sphere + /// replaces the automatic calculation of mass, center of mass and inertia + /// + /// + /// total mass of linkset + /// radius of the sphere + /// location of center of mass relative to root prim in local coords + /// + /// + public void osSetInertiaAsSphere(LSL_Float mass, LSL_Float radius, LSL_Vector centerOfMass) + { + CheckThreatLevel(); + + SceneObjectGroup sog = m_host.ParentGroup; + if(sog== null || sog.IsDeleted) + return; + + if(mass < 0) + return; + + // need more checks + + Vector3 CenterOfMass = new Vector3((float)centerOfMass.x,(float)centerOfMass.y,(float)centerOfMass.z); + Vector3 Inertia; + float r = (float)radius; + float m = (float)mass; + float t = 0.4f * m * r * r; + + Inertia.X = t; + Inertia.Y = t; + Inertia.Z = t; + + sog.SetInertiaData(m, CenterOfMass, Inertia, new Vector4(0f, 0f, 0f,1.0f)); + } + + /// + /// set inertial data as a cylinder + /// replaces the automatic calculation of mass, center of mass and inertia + /// + /// + /// total mass of linkset + /// radius of the cylinder + /// lenght of the cylinder + /// location of center of mass relative to root prim in local coords + /// rotation of the cylinder, and so inertia, relative to local axis + /// + /// cylinder axis aligned with Z axis. For other orientations provide the rotation. + /// + public void osSetInertiaAsCylinder(LSL_Float mass, LSL_Float radius, LSL_Float lenght, LSL_Vector centerOfMass, LSL_Rotation lslrot) + { + CheckThreatLevel(); + + SceneObjectGroup sog = m_host.ParentGroup; + if(sog== null || sog.IsDeleted) + return; + + if(mass < 0) + return; + + // need more checks + + Vector3 CenterOfMass = new Vector3((float)centerOfMass.x,(float)centerOfMass.y,(float)centerOfMass.z); + Vector3 Inertia; + float m = (float)mass; + float r = (float)radius; + r *= r; + Inertia.Z = 0.5f * m * r; + float t = (float)lenght; + t *= t; + t += 3.0f * r; + t *= 8.333333e-2f * m; + + Inertia.X = t; + Inertia.Y = t; + + Vector4 rot = new Vector4((float)lslrot.x, (float)lslrot.y, (float)lslrot.z, (float)lslrot.s); + rot.Normalize(); + + sog.SetInertiaData(m, CenterOfMass, Inertia, rot); + } + + /// + /// removes inertial data manual override + /// default automatic calculation is used again + /// + /// + public void osClearInertia() + { + CheckThreatLevel(); + + SceneObjectGroup sog = m_host.ParentGroup; + if(sog== null || sog.IsDeleted) + return; + + sog.SetInertiaData(-1, Vector3.Zero, Vector3.Zero, Vector4.Zero ); + } + + private bool checkAllowObjectTPbyLandOwner(Vector3 pos) + { + ILandObject land = World.LandChannel.GetLandObject(pos); + if(land == null) + return true; + + LandData landdata = land.LandData; + if(landdata == null) + return true; + + UUID hostOwner = m_host.OwnerID; + if(landdata.OwnerID == hostOwner) + return true; + + EstateSettings es = World.RegionInfo.EstateSettings; + if(es != null && es.IsEstateManagerOrOwner(hostOwner)) + return true; + + if(!landdata.IsGroupOwned) + return false; + + UUID landGroup = landdata.GroupID; + if(landGroup == UUID.Zero) + return false; + + if(landGroup == m_host.GroupID) + return true; + + return false; + } + + /// + /// teleports a object (full linkset) + /// + /// the id of the linkset to teleport + /// target position + /// a rotation to apply + /// several flags/param> + /// + /// only does teleport local to region + /// if object has scripts, owner must have rights to run scripts on target location + /// object owner must have rights to enter ojects on target location + /// target location parcel must have enought free prims capacity for the linkset prims + /// all avatars siting on the object must have access to target location + /// has a cool down time. retries before expire reset it + /// fail conditions are silent ignored + /// + public LSL_Integer osTeleportObject(LSL_Key objectUUID, LSL_Vector targetPos, LSL_Rotation rotation, LSL_Integer flags) + { + CheckThreatLevel(ThreatLevel.Severe, "osTeleportObject"); + + UUID objUUID; + if (!UUID.TryParse(objectUUID, out objUUID)) + { + OSSLShoutError("osTeleportObject() invalid object Key"); + return -1; + } + + SceneObjectGroup sog = World.GetSceneObjectGroup(objUUID); + if(sog== null || sog.IsDeleted || sog.inTransit) + return -1; + + if(sog.OwnerID != m_host.OwnerID) + { + Vector3 pos = sog.AbsolutePosition; + if(!checkAllowObjectTPbyLandOwner(pos)) + return -1; + } + + UUID myid = m_host.ParentGroup.UUID; + + return sog.TeleportObject(myid, targetPos, rotation, flags); + // a delay here may break vehicles + } + + public LSL_Integer osGetLinkNumber(LSL_String name) + { + CheckThreatLevel(); + + SceneObjectGroup sog = m_host.ParentGroup; + if(sog== null || sog.IsDeleted) + return -1; + return sog.GetLinkNumber(name); + } + + // rounds to the nearest number with provided number of decimal places + public LSL_Float osRound(LSL_Float value, LSL_Integer ndigits) + { + if(ndigits <= 0) + return Math.Round(value, MidpointRounding.AwayFromZero); + if(ndigits > 15) + ndigits = 15; + return Math.Round(value, ndigits, MidpointRounding.AwayFromZero); + } + + public LSL_Float osVecMagSquare(LSL_Vector a) + { + return LSL_Vector.MagSquare(a); + } + + public LSL_Float osVecDistSquare(LSL_Vector a, LSL_Vector b) + { + return LSL_Vector.MagSquare(a - b); + } + + // returns the angle between 2 vectors 0 to pi + public LSL_Float osAngleBetween(LSL_Vector a, LSL_Vector b) + { + double dot = LSL_Vector.Dot(a,b); + double mcross = LSL_Vector.Mag(LSL_Vector.Cross(a,b)); + return Math.Atan2(mcross, dot); + } + + +//******* link sound + public void osAdjustSoundVolume(LSL_Integer linknum, LSL_Float volume) + { + m_host.AddScriptLPS(1); + SceneObjectPart sop = GetSingleLinkPart(linknum); + if(sop == null) + return; + sop.AdjustSoundGain(volume); + ScriptSleep(100); + } + + public void osSetSoundRadius(LSL_Integer linknum, LSL_Float radius) + { + m_host.AddScriptLPS(1); + SceneObjectPart sop = GetSingleLinkPart(linknum); + if(sop == null) + return; + m_host.SoundRadius = radius; + } + + public void osPlaySound(LSL_Integer linknum, LSL_String sound, LSL_Float volume) + { + m_host.AddScriptLPS(1); + + if (m_SoundModule == null) + return; + + SceneObjectPart sop = GetSingleLinkPart(linknum); + if(sop == null) + return; + + UUID soundID = ScriptUtils.GetAssetIdFromKeyOrItemName(sop, sound, AssetType.Sound); + if(soundID == UUID.Zero) + return; + + // send the sound, once, to all clients in range + m_SoundModule.SendSound(sop.UUID, soundID, volume, false, 0, false, false); + } + + public void osLoopSound(LSL_Integer linknum, LSL_String sound, LSL_Float volume) + { + m_host.AddScriptLPS(1); + + if (m_SoundModule == null) + return; + + SceneObjectPart sop = GetSingleLinkPart(linknum); + if(sop == null) + return; + + UUID soundID = ScriptUtils.GetAssetIdFromKeyOrItemName(sop, sound, AssetType.Sound); + if(soundID == UUID.Zero) + return; + + m_SoundModule.LoopSound(sop.UUID, soundID, volume, false,false); + } + + public void osLoopSoundMaster(LSL_Integer linknum, LSL_String sound, LSL_Float volume) + { + m_host.AddScriptLPS(1); + + SceneObjectPart sop = GetSingleLinkPart(linknum); + if(sop == null) + return; + + UUID soundID = ScriptUtils.GetAssetIdFromKeyOrItemName(sop, sound, AssetType.Sound); + if(soundID == UUID.Zero) + return; + + m_SoundModule.LoopSound(sop.UUID, soundID, volume, true, false); + } + + public void osLoopSoundSlave(LSL_Integer linknum, LSL_String sound, LSL_Float volume) + { + m_host.AddScriptLPS(1); + + if (m_SoundModule == null) + return; + + SceneObjectPart sop = GetSingleLinkPart(linknum); + if(sop == null) + return; + + UUID soundID = ScriptUtils.GetAssetIdFromKeyOrItemName(sop, sound, AssetType.Sound); + if(soundID == UUID.Zero) + return; + + m_SoundModule.LoopSound(sop.UUID, soundID, volume, false, true); + } + + public void osPlaySoundSlave(LSL_Integer linknum, LSL_String sound, LSL_Float volume) + { + m_host.AddScriptLPS(1); + + if (m_SoundModule == null) + return; + + SceneObjectPart sop = GetSingleLinkPart(linknum); + if(sop == null) + return; + + UUID soundID = ScriptUtils.GetAssetIdFromKeyOrItemName(sop, sound, AssetType.Sound); + if(soundID == UUID.Zero) + return; + + // send the sound, once, to all clients in range + m_SoundModule.SendSound(sop.UUID, soundID, volume, false, 0, true, false); + } + + public void osTriggerSound(LSL_Integer linknum, LSL_String sound, LSL_Float volume) + { + m_host.AddScriptLPS(1); + + if (m_SoundModule == null) + return; + + SceneObjectPart sop = GetSingleLinkPart(linknum); + if(sop == null) + return; + + UUID soundID = ScriptUtils.GetAssetIdFromKeyOrItemName(sop, sound, AssetType.Sound); + if(soundID == UUID.Zero) + return; + + // send the sound, once, to all clients in rangeTrigger or play an attached sound in this part's inventory. + m_SoundModule.SendSound(sop.UUID, soundID, volume, true, 0, false, false); + } + + public void osTriggerSoundLimited(LSL_Integer linknum, LSL_String sound, LSL_Float volume, + LSL_Vector top_north_east, LSL_Vector bottom_south_west) + { + m_host.AddScriptLPS(1); + + if (m_SoundModule == null) + return; + + SceneObjectPart sop = GetSingleLinkPart(linknum); + if(sop == null) + return; + + UUID soundID = ScriptUtils.GetAssetIdFromKeyOrItemName(sop, sound, AssetType.Sound); + if(soundID == UUID.Zero) + return; + + m_SoundModule.TriggerSoundLimited(sop.UUID, soundID, volume, + bottom_south_west, top_north_east); + } + + public void osStopSound(LSL_Integer linknum) + { + m_host.AddScriptLPS(1); + + if (m_SoundModule == null) + return; + + SceneObjectPart sop = GetSingleLinkPart(linknum); + if(sop == null) + return; + + m_SoundModule.StopSound(sop.UUID); + } + + public void osPreloadSound(LSL_Integer linknum, LSL_String sound) + { + m_host.AddScriptLPS(1); + + if (m_SoundModule == null) + return; + + SceneObjectPart sop = GetSingleLinkPart(linknum); + if(sop == null) + return; + + UUID soundID = ScriptUtils.GetAssetIdFromKeyOrItemName(sop, sound, AssetType.Sound); + if(soundID == UUID.Zero) + return; + + m_SoundModule.PreloadSound(sop.UUID, soundID); + ScriptSleep(1000); + } + + // get only one part + private SceneObjectPart GetSingleLinkPart(int linkType) + { + if (m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted) + return null; + + switch (linkType) + { + case ScriptBaseClass.LINK_SET: + case ScriptBaseClass.LINK_ALL_OTHERS: + case ScriptBaseClass.LINK_ALL_CHILDREN: + return null; + + case 0: + case ScriptBaseClass.LINK_ROOT: + return m_host.ParentGroup.RootPart; + + case ScriptBaseClass.LINK_THIS: + return m_host; + + default: + if(linkType < 0) + return null; + + return m_host.ParentGroup.GetLinkNumPart(linkType); + } + } } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs index 1808c34507..2b37adce20 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs @@ -160,7 +160,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins ts.arc = arc; ts.host = host; - ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval); + ts.next = DateTime.UtcNow.AddSeconds(ts.interval); AddSenseRepeater(ts); } @@ -196,14 +196,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins public void CheckSenseRepeaterEvents() { // Go through all timers - foreach (SensorInfo ts in SenseRepeaters) + + List curSensors; + lock(SenseRepeatListLock) + curSensors = SenseRepeaters; + + DateTime now = DateTime.UtcNow; + foreach (SensorInfo ts in curSensors) { // Time has passed? - if (ts.next.ToUniversalTime() < DateTime.Now.ToUniversalTime()) + if (ts.next < now) { SensorSweep(ts); // set next interval - ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval); + ts.next = now.AddSeconds(ts.interval); } } } @@ -549,13 +555,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins return; toRegionPos = presence.AbsolutePosition; - dis = Util.GetDistanceTo(toRegionPos, fromRegionPos); + dis = Vector3.Distance(toRegionPos, fromRegionPos); if (presence.IsSatOnObject && presence.ParentPart != null && presence.ParentPart.ParentGroup != null && presence.ParentPart.ParentGroup.RootPart != null) { Vector3 rpos = presence.ParentPart.ParentGroup.RootPart.AbsolutePosition; - double dis2 = Util.GetDistanceTo(rpos, fromRegionPos); + double dis2 = Vector3.Distance(rpos, fromRegionPos); if (dis > dis2) dis = dis2; } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs index 17c977f927..4529d9ac89 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs @@ -122,7 +122,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces LSL_Rotation llGetCameraRot(); LSL_Vector llGetCenterOfMass(); LSL_Vector llGetColor(int face); - LSL_String llGetCreator(); + LSL_Key llGetCreator(); LSL_String llGetDate(); LSL_Float llGetEnergy(); LSL_String llGetEnv(LSL_String name); @@ -155,7 +155,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces LSL_Float llGetMassMKS(); LSL_Integer llGetMemoryLimit(); void llGetNextEmail(string address, string subject); - LSL_String llGetNotecardLine(string name, int line); + LSL_Key llGetNotecardLine(string name, int line); LSL_Key llGetNumberOfNotecardLines(string name); LSL_Integer llGetNumberOfPrims(); LSL_Integer llGetNumberOfSides(); @@ -211,23 +211,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces void llGiveInventory(string destination, string inventory); void llGiveInventoryList(string destination, string category, LSL_List inventory); LSL_Integer llGiveMoney(string destination, int amount); - LSL_String llTransferLindenDollars(string destination, int amount); + LSL_Key llTransferLindenDollars(string destination, int amount); void llGodLikeRezObject(string inventory, LSL_Vector pos); LSL_Float llGround(LSL_Vector offset); LSL_Vector llGroundContour(LSL_Vector offset); LSL_Vector llGroundNormal(LSL_Vector offset); void llGroundRepel(double height, int water, double tau); LSL_Vector llGroundSlope(LSL_Vector offset); - LSL_String llHTTPRequest(string url, LSL_List parameters, string body); + LSL_Key llHTTPRequest(string url, LSL_List parameters, string body); void llHTTPResponse(LSL_Key id, int status, string body); LSL_String llInsertString(string dst, int position, string src); void llInstantMessage(string user, string message); LSL_String llIntegerToBase64(int number); LSL_String llKey2Name(string id); LSL_String llGetUsername(string id); - LSL_String llRequestUsername(string id); + LSL_Key llRequestUsername(string id); LSL_String llGetDisplayName(string id); - LSL_String llRequestDisplayName(string id); + LSL_Key llRequestDisplayName(string id); void llLinkParticleSystem(int linknum, LSL_List rules); void llLinkSitTarget(LSL_Integer link, LSL_Vector offset, LSL_Rotation rot); LSL_String llList2CSV(LSL_List src); @@ -302,7 +302,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces LSL_Key llRequestAgentData(string id, int data); LSL_Key llRequestInventoryData(string name); void llRequestPermissions(string agent, int perm); - LSL_String llRequestSecureURL(); + LSL_Key llRequestSecureURL(); LSL_Key llRequestSimulatorData(string simulator, int data); LSL_Key llRequestURL(); void llResetLandBanList(); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs index bee060ad4c..9f35d7aee6 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs @@ -38,6 +38,7 @@ using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; + namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces { /// @@ -50,7 +51,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces /// public enum ThreatLevel { - // Not documented, presumably means permanently disabled ? NoAccess = -1, /// @@ -123,6 +123,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces string osSetDynamicTextureURLBlendFace(string dynamicID, string contentType, string url, string extraParams, bool blend, int disp, int timer, int alpha, int face); string osSetDynamicTextureData(string dynamicID, string contentType, string data, string extraParams, int timer); + string osSetDynamicTextureDataFace(string dynamicID, string contentType, string data, string extraParams, int timer, int face); string osSetDynamicTextureDataBlend(string dynamicID, string contentType, string data, string extraParams, int timer, int alpha); string osSetDynamicTextureDataBlendFace(string dynamicID, string contentType, string data, string extraParams, @@ -137,14 +138,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces int osRegionRestart(double seconds); int osRegionRestart(double seconds, string msg); void osRegionNotice(string msg); + void osRegionNotice(LSL_Key agentID, string msg); bool osConsoleCommand(string Command); void osSetParcelMediaURL(string url); void osSetPrimFloatOnWater(int floatYN); void osSetParcelSIPAddress(string SIPAddress); // Avatar Info Commands - string osGetAgentIP(string agent); LSL_List osGetAgents(); + string osGetAgentIP(string agent); // Teleport commands void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); @@ -222,10 +224,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces string osDrawLine(string drawList, int endX, int endY); string osDrawText(string drawList, string text); string osDrawEllipse(string drawList, int width, int height); + string osDrawFilledEllipse(string drawList, int width, int height); string osDrawRectangle(string drawList, int width, int height); string osDrawFilledRectangle(string drawList, int width, int height); string osDrawPolygon(string drawList, LSL_List x, LSL_List y); string osDrawFilledPolygon(string drawList, LSL_List x, LSL_List y); + string osDrawResetTransform(string drawList); + string osDrawRotationTransform(string drawList, LSL_Float x); + string osDrawScaleTransform(string drawList, LSL_Float x, LSL_Float y); + string osDrawTranslationTransform(string drawList, LSL_Float x, LSL_Float y); string osSetFontName(string drawList, string fontName); string osSetFontSize(string drawList, int fontSize); string osSetPenSize(string drawList, int penSize); @@ -373,6 +380,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces vector osGetRegionSize(); int osGetSimulatorMemory(); + int osGetSimulatorMemoryKB(); void osKickAvatar(string FirstName,string SurName,string alert); void osSetSpeed(string UUID, LSL_Float SpeedModifier); LSL_Float osGetHealth(string avatar); @@ -389,8 +397,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces void osSetProjectionParams(LSL_Key prim, bool projection, LSL_Key texture, double fov, double focus, double amb); LSL_List osGetAvatarList(); + LSL_List osGetNPCList(); - LSL_String osUnixTimeToTimestamp(long time); + LSL_String osUnixTimeToTimestamp(LSL_Integer time); LSL_String osGetInventoryDesc(string item); @@ -486,6 +495,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces LSL_String osRequestURL(LSL_List options); LSL_String osRequestSecureURL(LSL_List options); void osCollisionSound(string impact_sound, double impact_volume); + void osVolumeDetect(int detect); + + LSL_List osGetInertiaData(); + void osClearInertia(); + void osSetInertia(LSL_Float mass, vector centerOfMass, vector principalInertiaScaled, rotation rot); + void osSetInertiaAsBox(LSL_Float mass, vector boxSize, vector centerOfMass, rotation rot); + void osSetInertiaAsSphere(LSL_Float mass, LSL_Float radius, vector centerOfMass); + void osSetInertiaAsCylinder(LSL_Float mass, LSL_Float radius, LSL_Float lenght, vector centerOfMass,rotation lslrot); + + LSL_Integer osTeleportObject(LSL_Key objectUUID, vector targetPos, rotation targetrotation, LSL_Integer flags); + LSL_Integer osGetLinkNumber(LSL_String name); + + LSL_Float osRound(LSL_Float value, LSL_Integer digits); + + LSL_Float osVecMagSquare(vector a); + LSL_Float osVecDistSquare(vector a, vector b); + LSL_Float osAngleBetween(vector a, vector b); + + void osAdjustSoundVolume(LSL_Integer linknum, LSL_Float volume); + void osLoopSound(LSL_Integer linknum, LSL_String sound, LSL_Float volume); + void osLoopSoundMaster(LSL_Integer linknum, LSL_String sound, LSL_Float volume); + void osLoopSoundSlave(LSL_Integer linknum, LSL_String sound, LSL_Float volume); + void osPlaySound(LSL_Integer linknum, LSL_String sound, LSL_Float volume); + void osPlaySoundSlave(LSL_Integer linknum, LSL_String sound, LSL_Float volume); + void osPreloadSound(LSL_Integer linknum, LSL_String sound); + void osSetSoundRadius(LSL_Integer linknum, LSL_Float radius); + void osStopSound(LSL_Integer linknum); + void osTriggerSound(LSL_Integer linknum, LSL_String sound, LSL_Float volume); + void osTriggerSoundLimited(LSL_Integer linknum, LSL_String sound, LSL_Float volume, + vector top_north_east, vector bottom_south_west); } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs index 3a90c7704e..dedf75eba3 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs @@ -29,6 +29,7 @@ using System; using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; using LSLInteger = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; +using LSLString = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase { @@ -446,6 +447,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase // parameters + + public const int PRIM_ALPHA_MODE_NONE = 0; + public const int PRIM_ALPHA_MODE_BLEND = 1; + public const int PRIM_ALPHA_MODE_MASK = 2; + public const int PRIM_ALPHA_MODE_EMISSIVE = 3; + public const int PRIM_TEXGEN_DEFAULT = 0; public const int PRIM_TEXGEN_PLANAR = 1; @@ -659,6 +666,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase public const int AGENT_LIST_PARCEL = 1; public const int AGENT_LIST_PARCEL_OWNER = 2; public const int AGENT_LIST_REGION = 4; + public const int AGENT_LIST_EXCLUDENPC = 0x4000000; // our flag, not SL and it is a bit mask // Can not be public const? public static readonly vector ZERO_VECTOR = new vector(0.0, 0.0, 0.0); @@ -696,7 +704,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase public const int PARCEL_DETAILS_GROUP = 3; public const int PARCEL_DETAILS_AREA = 4; public const int PARCEL_DETAILS_ID = 5; - public const int PARCEL_DETAILS_SEE_AVATARS = 6; // not implemented + public const int PARCEL_DETAILS_SEE_AVATARS = 6; + public const int PARCEL_DETAILS_ANY_AVATAR_SOUNDS = 7; + public const int PARCEL_DETAILS_GROUP_SOUNDS = 8; //osSetParcelDetails public const int PARCEL_DETAILS_CLAIMDATE = 10; @@ -834,15 +844,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase public const int KFM_CMD_STOP = 1; public const int KFM_CMD_PAUSE = 2; - public const string JSON_ARRAY = "JSON_ARRAY"; - public const string JSON_OBJECT = "JSON_OBJECT"; - public const string JSON_INVALID = "JSON_INVALID"; - public const string JSON_NUMBER = "JSON_NUMBER"; - public const string JSON_STRING = "JSON_STRING"; - public const string JSON_TRUE = "JSON_TRUE"; - public const string JSON_FALSE = "JSON_FALSE"; - public const string JSON_NULL = "JSON_NULL"; - public const string JSON_APPEND = "JSON_APPEND"; + public const string JSON_INVALID = "\uFDD0"; + public const string JSON_OBJECT = "\uFDD1"; + public const string JSON_ARRAY = "\uFDD2"; + public const string JSON_NUMBER = "\uFDD3"; + public const string JSON_STRING = "\uFDD4"; + public const string JSON_NULL = "\uFDD5"; + public const string JSON_TRUE = "\uFDD6"; + public const string JSON_FALSE = "\uFDD7"; + public const string JSON_DELETE = "\uFDD8"; + public const string JSON_APPEND = "-1"; /// /// process name parameter as regex @@ -853,5 +864,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase /// process message parameter as regex /// public const int OS_LISTEN_REGEX_MESSAGE = 0x2; + + // for osTeleportObject + public const int OSTPOBJ_NONE = 0x0; + public const int OSTPOBJ_STOPATTARGET = 0x1; // stops at destination + public const int OSTPOBJ_STOPONFAIL = 0x2; // stops at jump point if tp fails + public const int OSTPOBJ_SETROT = 0x4; // the rotation is the final rotation, otherwise is a added rotation + } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs index c39248bcd2..0b474f431c 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs @@ -456,7 +456,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase return m_LSL_Functions.llGetColor(face); } - public LSL_String llGetCreator() + public LSL_Key llGetCreator() { return m_LSL_Functions.llGetCreator(); } @@ -611,7 +611,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase m_LSL_Functions.llGetNextEmail(address, subject); } - public LSL_String llGetNotecardLine(string name, int line) + public LSL_Key llGetNotecardLine(string name, int line) { return m_LSL_Functions.llGetNotecardLine(name, line); } @@ -891,7 +891,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase return m_LSL_Functions.llGiveMoney(destination, amount); } - public LSL_String llTransferLindenDollars(string destination, int amount) + public LSL_Key llTransferLindenDollars(string destination, int amount) { return m_LSL_Functions.llTransferLindenDollars(destination, amount); } @@ -926,7 +926,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase return m_LSL_Functions.llGroundSlope(offset); } - public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) + public LSL_Key llHTTPRequest(string url, LSL_List parameters, string body) { return m_LSL_Functions.llHTTPRequest(url, parameters, body); } @@ -961,7 +961,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase return m_LSL_Functions.llGetUsername(id); } - public LSL_String llRequestUsername(string id) + public LSL_Key llRequestUsername(string id) { return m_LSL_Functions.llRequestUsername(id); } @@ -971,7 +971,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase return m_LSL_Functions.llGetDisplayName(id); } - public LSL_String llRequestDisplayName(string id) + public LSL_Key llRequestDisplayName(string id) { return m_LSL_Functions.llRequestDisplayName(id); } @@ -1346,7 +1346,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase m_LSL_Functions.llRequestPermissions(agent, perm); } - public LSL_String llRequestSecureURL() + public LSL_Key llRequestSecureURL() { return m_LSL_Functions.llRequestSecureURL(); } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs index 6164734789..5c6d2331ca 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs @@ -153,6 +153,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase return m_OSSL_Functions.osSetDynamicTextureData(dynamicID, contentType, data, extraParams, timer); } + public string osSetDynamicTextureDataFace(string dynamicID, string contentType, string data, string extraParams, + int timer, int face) + { + return m_OSSL_Functions.osSetDynamicTextureDataFace(dynamicID, contentType, data, extraParams, timer, face); + } + public string osSetDynamicTextureURLBlend(string dynamicID, string contentType, string url, string extraParams, int timer, int alpha) { @@ -219,6 +225,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase m_OSSL_Functions.osRegionNotice(msg); } + public void osRegionNotice(LSL_Key agentID, string msg) + { + m_OSSL_Functions.osRegionNotice(agentID, msg); + } + public bool osConsoleCommand(string Command) { return m_OSSL_Functions.osConsoleCommand(Command); @@ -271,17 +282,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase m_OSSL_Functions.osTeleportOwner(position, lookat); } - // Avatar info functions - public string osGetAgentIP(string agent) - { - return m_OSSL_Functions.osGetAgentIP(agent); - } - public LSL_List osGetAgents() { return m_OSSL_Functions.osGetAgents(); } + public string osGetAgentIP(string agent) + { + return m_OSSL_Functions.osGetAgentIP(agent); + } + // Animation Functions public void osAvatarPlayAnimation(string avatar, string animation) @@ -355,6 +365,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase return m_OSSL_Functions.osDrawEllipse(drawList, width, height); } + public string osDrawFilledEllipse(string drawList, int width, int height) + { + return m_OSSL_Functions.osDrawFilledEllipse(drawList, width, height); + } + public string osDrawRectangle(string drawList, int width, int height) { return m_OSSL_Functions.osDrawRectangle(drawList, width, height); @@ -375,6 +390,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase return m_OSSL_Functions.osDrawFilledPolygon(drawList, x, y); } + public string osDrawResetTransform(string drawList) + { + return m_OSSL_Functions.osDrawResetTransform(drawList); + } + + public string osDrawRotationTransform(string drawList, LSL_Float x) + { + return m_OSSL_Functions.osDrawRotationTransform(drawList, x); + } + + public string osDrawScaleTransform(string drawList, LSL_Float x, LSL_Float y) + { + return m_OSSL_Functions.osDrawScaleTransform(drawList, x, y); + } + + public string osDrawTranslationTransform(string drawList, LSL_Float x, LSL_Float y) + { + return m_OSSL_Functions.osDrawTranslationTransform(drawList, x, y); + } + public string osSetFontSize(string drawList, int fontSize) { return m_OSSL_Functions.osSetFontSize(drawList, fontSize); @@ -399,6 +434,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase { return m_OSSL_Functions.osSetPenColor(drawList, color); } + // Deprecated public string osSetPenColour(string drawList, string colour) { @@ -927,7 +963,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase /// /// Returns the amount of memory in use by the Simulator Daemon. - /// Amount in bytes - if >= 4GB, returns 4GB. (LSL is not 64-bit aware) + /// Amount in bytes - if >= 2GB, returns 2GB. (LSL is not 64-bit aware) /// /// public LSL_Integer osGetSimulatorMemory() @@ -935,6 +971,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase return m_OSSL_Functions.osGetSimulatorMemory(); } + public LSL_Integer osGetSimulatorMemoryKB() + { + return m_OSSL_Functions.osGetSimulatorMemoryKB(); + } + public void osKickAvatar(string FirstName,string SurName,string alert) { m_OSSL_Functions.osKickAvatar(FirstName, SurName, alert); @@ -1010,7 +1051,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase return m_OSSL_Functions.osGetAvatarList(); } - public LSL_String osUnixTimeToTimestamp(long time) + public LSL_List osGetNPCList() + { + return m_OSSL_Functions.osGetNPCList(); + } + + public LSL_String osUnixTimeToTimestamp(LSL_Integer time) { return m_OSSL_Functions.osUnixTimeToTimestamp(time); } @@ -1114,5 +1160,122 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase { m_OSSL_Functions.osVolumeDetect(detect); } + + public LSL_List osGetInertiaData() + { + return m_OSSL_Functions.osGetInertiaData(); + } + + public void osSetInertia(LSL_Float mass, vector centerOfMass, vector principalInertiaScaled, rotation rot) + { + m_OSSL_Functions.osSetInertia(mass, centerOfMass, principalInertiaScaled, rot); + } + + public void osSetInertiaAsBox(LSL_Float mass, vector boxSize, vector centerOfMass, rotation rot) + { + m_OSSL_Functions.osSetInertiaAsBox(mass, boxSize, centerOfMass, rot); + } + + public void osSetInertiaAsSphere(LSL_Float mass, LSL_Float radius, vector centerOfMass) + { + m_OSSL_Functions.osSetInertiaAsSphere(mass, radius, centerOfMass); + } + + public void osSetInertiaAsCylinder(LSL_Float mass, LSL_Float radius, LSL_Float lenght, vector centerOfMass,rotation lslrot) + { + m_OSSL_Functions.osSetInertiaAsCylinder( mass, radius, lenght, centerOfMass, lslrot); + } + + public void osClearInertia() + { + m_OSSL_Functions.osClearInertia(); + } + + public LSL_Integer osTeleportObject(LSL_Key objectUUID, vector targetPos, rotation targetrotation, LSL_Integer flags) + { + return m_OSSL_Functions.osTeleportObject(objectUUID, targetPos, targetrotation, flags); + } + + public LSL_Integer osGetLinkNumber(LSL_String name) + { + return m_OSSL_Functions.osGetLinkNumber(name); + } + + public LSL_Float osRound(LSL_Float value, LSL_Integer digits) + { + return m_OSSL_Functions.osRound(value, digits); + } + + public LSL_Float osVecMagSquare(vector a) + { + return m_OSSL_Functions.osVecMagSquare(a); + } + + public LSL_Float osVecDistSquare(vector a, vector b) + { + return m_OSSL_Functions.osVecDistSquare(a, b); + } + + public LSL_Float osAngleBetween(vector a, vector b) + { + return m_OSSL_Functions.osAngleBetween(a, b); + } + + public void osAdjustSoundVolume(LSL_Integer linknum, LSL_Float volume) + { + m_OSSL_Functions.osAdjustSoundVolume(linknum, volume); + } + + public void osSetSoundRadius(LSL_Integer linknum, LSL_Float radius) + { + m_OSSL_Functions.osSetSoundRadius(linknum, radius); + } + + public void osPlaySound(LSL_Integer linknum, LSL_String sound, LSL_Float volume) + { + m_OSSL_Functions.osPlaySound(linknum, sound, volume); + } + + public void osLoopSound(LSL_Integer linknum, LSL_String sound, LSL_Float volume) + { + m_OSSL_Functions.osLoopSound(linknum, sound, volume); + } + + public void osLoopSoundMaster(LSL_Integer linknum, LSL_String sound, LSL_Float volume) + { + m_OSSL_Functions.osLoopSoundMaster(linknum, sound, volume); + } + + public void osLoopSoundSlave(LSL_Integer linknum, LSL_String sound, LSL_Float volume) + { + m_OSSL_Functions.osLoopSoundSlave(linknum, sound, volume); + } + + public void osPlaySoundSlave(LSL_Integer linknum, LSL_String sound, LSL_Float volume) + { + m_OSSL_Functions.osPlaySoundSlave(linknum, sound, volume); + } + + public void osTriggerSound(LSL_Integer linknum, LSL_String sound, LSL_Float volume) + { + m_OSSL_Functions.osTriggerSound(linknum, sound, volume); + } + + public void osTriggerSoundLimited(LSL_Integer linknum, LSL_String sound, LSL_Float volume, + vector top_north_east, vector bottom_south_west) + { + m_OSSL_Functions.osTriggerSoundLimited(linknum, sound, volume, + top_north_east, bottom_south_west); + } + + public void osStopSound(LSL_Integer linknum) + { + m_OSSL_Functions.osStopSound(linknum); + } + + public void osPreloadSound(LSL_Integer linknum, LSL_String sound) + { + m_OSSL_Functions.osPreloadSound(linknum, sound); + } } } diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs index f3b8e1d382..134595629a 100644 --- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs +++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs @@ -79,12 +79,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools private List m_warnings = new List(); - // private object m_syncy = new object(); - -// private static CSharpCodeProvider CScodeProvider = new CSharpCodeProvider(); -// private static VBCodeProvider VBcodeProvider = new VBCodeProvider(); - - // private static int instanceID = new Random().Next(0, int.MaxValue); // Unique number to use on our compiled files private static UInt64 scriptCompileCounter = 0; // And a counter public IScriptEngine m_scriptEngine; @@ -251,23 +245,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools } } - ////private ICodeCompiler icc = codeProvider.CreateCompiler(); - //public string CompileFromFile(string LSOFileName) - //{ - // switch (Path.GetExtension(LSOFileName).ToLower()) - // { - // case ".txt": - // case ".lsl": - // Common.ScriptEngineBase.Shared.SendToDebug("Source code is LSL, converting to CS"); - // return CompileFromLSLText(File.ReadAllText(LSOFileName)); - // case ".cs": - // Common.ScriptEngineBase.Shared.SendToDebug("Source code is CS"); - // return CompileFromCSText(File.ReadAllText(LSOFileName)); - // default: - // throw new Exception("Unknown script type."); - // } - //} - public string GetCompilerOutput(string assetID) { return Path.Combine(ScriptEnginesPath, Path.Combine( @@ -392,14 +369,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools { case enumCompileType.cs: compileScript = CreateCSCompilerScript( - compileScript, + source, m_scriptEngine.ScriptClassName, m_scriptEngine.ScriptBaseClassName, m_scriptEngine.ScriptBaseClassParameters); break; case enumCompileType.vb: compileScript = CreateVBCompilerScript( - compileScript, m_scriptEngine.ScriptClassName, m_scriptEngine.ScriptBaseClassName); + source, m_scriptEngine.ScriptClassName, m_scriptEngine.ScriptBaseClassName); break; } } @@ -572,14 +549,15 @@ namespace SecondLife parameters.TreatWarningsAsErrors = false; parameters.GenerateInMemory = false; +// parameters.TempFiles = new TempFileCollection(Path.Combine(ScriptEnginesPath, +// m_scriptEngine.World.RegionInfo.RegionID.ToString()), CompileWithDebugInformation); + CompilerResults results; CodeDomProvider provider; switch (lang) { case enumCompileType.vb: -// results = VBcodeProvider.CompileAssemblyFromSource( -// parameters, Script); provider = CodeDomProvider.CreateProvider("VisualBasic"); break; case enumCompileType.cs: @@ -594,56 +572,36 @@ namespace SecondLife if(provider == null) throw new Exception("Compiler failed to load "); + bool complete = false; + bool retried = false; - bool complete = false; - bool retried = false; - - do + do + { + results = provider.CompileAssemblyFromSource( + parameters, Script); + // Deal with an occasional segv in the compiler. + // Rarely, if ever, occurs twice in succession. + // Line # == 0 and no file name are indications that + // this is a native stack trace rather than a normal + // error log. + if (results.Errors.Count > 0) + { + if (!retried && string.IsNullOrEmpty(results.Errors[0].FileName) && + results.Errors[0].Line == 0) { -// lock (CScodeProvider) -// { -// results = CScodeProvider.CompileAssemblyFromSource( -// parameters, Script); -// } - - results = provider.CompileAssemblyFromSource( - parameters, Script); - // Deal with an occasional segv in the compiler. - // Rarely, if ever, occurs twice in succession. - // Line # == 0 and no file name are indications that - // this is a native stack trace rather than a normal - // error log. - if (results.Errors.Count > 0) - { - if (!retried && string.IsNullOrEmpty(results.Errors[0].FileName) && - results.Errors[0].Line == 0) - { - // System.Console.WriteLine("retrying failed compilation"); - retried = true; - } - else - { - complete = true; - } - } - else - { - complete = true; - } - } while (!complete); -// break; -// default: -// throw new Exception("Compiler is not able to recongnize " + -// "language type \"" + lang.ToString() + "\""); -// } - -// foreach (Type type in results.CompiledAssembly.GetTypes()) -// { -// foreach (MethodInfo method in type.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static)) -// { -// m_log.DebugFormat("[COMPILER]: {0}.{1}", type.FullName, method.Name); -// } -// } + // System.Console.WriteLine("retrying failed compilation"); + retried = true; + } + else + { + complete = true; + } + } + else + { + complete = true; + } + } while (!complete); // // WARNINGS AND ERRORS diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/lsl.lexer.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/lsl.lexer.cs index 66210b7670..8dc3faf6d7 100644 --- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/lsl.lexer.cs +++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/lsl.lexer.cs @@ -379,7 +379,7 @@ public override int yynum { get { return 96; }} public FLOAT_CONSTANT(Lexer yyl):base(yyl) {}} //%|LSLTokens public class yyLSLTokens : YyLexer { - public yyLSLTokens(ErrorHandler eh):base(eh) { arr = new int[] { + public yyLSLTokens(ErrorHandler eh):base(eh) { arr = new int[] { 101,4,6,52,0, 46,0,53,0,6, 102,4,16,117,0, @@ -387,2974 +387,4050 @@ public class yyLSLTokens : YyLexer { 0,115,0,99,0, 105,0,105,0,2, 0,103,5,27,7, -0,104,9,1,0, -3,192,0,105,5, -27,3,65,0,2, -1,3,66,0,2, -1,3,67,0,2, -1,3,68,0,2, -1,3,69,0,2, -1,3,70,0,2, -1,3,71,0,2, -1,3,72,0,2, -1,3,73,0,2, -1,3,74,0,2, -1,3,75,0,2, -1,3,76,0,2, -1,3,77,0,2, -1,3,78,0,2, -1,3,79,0,2, -1,3,80,0,2, -1,3,81,0,2, -1,3,82,0,2, -1,3,83,0,2, -1,3,84,0,2, -1,3,85,0,2, -1,3,86,0,2, -1,3,87,0,2, -1,3,88,0,2, -1,3,89,0,2, -1,3,90,0,2, -1,3,192,0,2, -1,7,1,106,9, -1,1,3,170,0, -107,5,27,3,109, -0,2,1,3,110, -0,2,1,3,111, -0,2,1,3,112, -0,2,1,3,113, -0,2,1,3,114, -0,2,1,3,115, -0,2,1,3,116, -0,2,1,3,117, -0,2,1,3,118, -0,2,1,3,119, -0,2,1,3,120, -0,2,1,3,121, -0,2,1,3,122, -0,2,1,3,170, -0,2,1,3,97, -0,2,1,3,98, -0,2,1,3,99, -0,2,1,3,100, -0,2,1,3,101, -0,2,1,3,102, -0,2,1,3,103, -0,2,1,3,104, -0,2,1,3,105, -0,2,1,3,106, -0,2,1,3,107, -0,2,1,3,108, -0,2,1,7,2, -108,9,1,2,3, -197,1,109,5,1, -3,197,1,2,1, -7,3,110,9,1, -3,3,176,2,111, -5,1,3,176,2, -2,1,7,4,112, -9,1,4,3,187, -1,113,5,1,3, -187,1,2,1,7, -5,114,9,1,5, -3,0,3,115,5, -1,3,0,3,2, -1,7,6,116,9, -1,6,3,3,9, -117,5,1,3,3, -9,2,1,7,7, -118,9,1,7,3, -136,4,119,5,1, -3,136,4,2,1, -7,8,120,9,1, -8,3,96,6,121, -5,11,3,96,6, -2,1,3,48,0, -2,1,3,49,0, -2,1,3,50,0, -2,1,3,51,0, -2,1,3,52,0, -2,1,3,53,0, -2,1,3,54,0, -2,1,3,55,0, -2,1,3,56,0, -2,1,3,57,0, -2,1,7,9,122, -9,1,9,3,238, -22,123,5,1,3, -238,22,2,1,7, -10,124,9,1,10, -3,178,0,125,5, -1,3,178,0,2, -1,7,11,126,9, -1,11,3,160,0, -127,5,2,3,160, -0,2,1,3,32, -0,2,1,7,12, -128,9,1,12,3, -40,32,129,5,1, -3,40,32,2,1, +27,104,9,1,27, +3,96,0,105,5, +2,3,94,0,2, +1,3,96,0,2, +1,7,26,106,9, +1,26,3,36,0, +107,5,1,3,36, +0,2,1,7,25, +108,9,1,25,3, +172,0,109,5,7, +3,60,0,2,1, +3,124,0,2,1, +3,62,0,2,1, +3,126,0,2,1, +3,61,0,2,1, +3,43,0,2,1, +3,172,0,2,1, +7,24,110,9,1, +24,3,35,0,111, +5,12,3,59,0, +2,1,3,33,0, +2,1,3,44,0, +2,1,3,92,0, +2,1,3,47,0, +2,1,3,35,0, +2,1,3,46,0, +2,1,3,42,0, +2,1,3,64,0, +2,1,3,38,0, +2,1,3,34,0, +2,1,3,37,0, +2,1,7,23,112, +9,1,23,3,187, +0,113,5,1,3, +187,0,2,1,7, +22,114,9,1,22, +3,171,0,115,5, +1,3,171,0,2, +1,7,21,116,9, +1,21,3,59,15, +117,5,4,3,93, +0,2,1,3,125, +0,2,1,3,41, +0,2,1,3,59, +15,2,1,7,20, +118,9,1,20,3, +58,15,119,5,4, +3,123,0,2,1, +3,58,15,2,1, +3,40,0,2,1, +3,91,0,2,1, +7,19,120,9,1, +19,3,173,0,121, +5,2,3,45,0, +2,1,3,173,0, +2,1,7,18,122, +9,1,18,3,63, +32,123,5,2,3, +63,32,2,1,3, +95,0,2,1,7, +17,124,9,1,17, +3,0,224,125,5, +1,3,0,224,2, +1,7,15,126,9, +1,15,3,0,6, +127,5,1,3,0, +6,2,1,7,14, +128,9,1,14,3, +1,0,129,5,5, +3,13,0,2,1, +3,10,0,2,1, +3,1,0,2,1, +3,9,0,2,1, +3,0,0,2,1, 7,13,130,9,1, 13,3,41,32,131, 5,1,3,41,32, -2,1,7,14,132, -9,1,14,3,1, -0,133,5,5,3, -0,0,2,1,3, -1,0,2,1,3, -13,0,2,1,3, -9,0,2,1,3, -10,0,2,1,7, -15,134,9,1,15, -3,0,6,135,5, -1,3,0,6,2, -1,7,17,136,9, -1,17,3,0,224, -137,5,1,3,0, -224,2,1,7,18, -138,9,1,18,3, -63,32,139,5,2, -3,63,32,2,1, -3,95,0,2,1, -7,19,140,9,1, -19,3,173,0,141, -5,2,3,45,0, -2,1,3,173,0, -2,1,7,20,142, -9,1,20,3,58, -15,143,5,4,3, -123,0,2,1,3, -91,0,2,1,3, -58,15,2,1,3, -40,0,2,1,7, -21,144,9,1,21, -3,59,15,145,5, -4,3,59,15,2, -1,3,125,0,2, -1,3,93,0,2, -1,3,41,0,2, -1,7,22,146,9, -1,22,3,171,0, -147,5,1,3,171, -0,2,1,7,23, -148,9,1,23,3, -187,0,149,5,1, -3,187,0,2,1, -7,24,150,9,1, -24,3,35,0,151, -5,12,3,37,0, -2,1,3,38,0, -2,1,3,42,0, -2,1,3,44,0, -2,1,3,46,0, -2,1,3,47,0, -2,1,3,92,0, -2,1,3,59,0, -2,1,3,64,0, -2,1,3,33,0, -2,1,3,34,0, -2,1,3,35,0, -2,1,7,25,152, -9,1,25,3,172, -0,153,5,7,3, -172,0,2,1,3, -124,0,2,1,3, -126,0,2,1,3, -60,0,2,1,3, -61,0,2,1,3, -62,0,2,1,3, -43,0,2,1,7, -26,154,9,1,26, -3,36,0,155,5, -1,3,36,0,2, -1,7,27,156,9, -1,27,3,96,0, -157,5,2,3,94, -0,2,1,3,96, +2,1,7,12,132, +9,1,12,3,40, +32,133,5,1,3, +40,32,2,1,7, +11,134,9,1,11, +3,160,0,135,5, +2,3,160,0,2, +1,3,32,0,2, +1,7,10,136,9, +1,10,3,178,0, +137,5,1,3,178, +0,2,1,7,9, +138,9,1,9,3, +238,22,139,5,1, +3,238,22,2,1, +7,8,140,9,1, +8,3,96,6,141, +5,11,3,50,0, +2,1,3,49,0, +2,1,3,57,0, +2,1,3,48,0, +2,1,3,56,0, +2,1,3,55,0, +2,1,3,54,0, +2,1,3,53,0, +2,1,3,52,0, +2,1,3,96,6, +2,1,3,51,0, +2,1,7,7,142, +9,1,7,3,136, +4,143,5,1,3, +136,4,2,1,7, +6,144,9,1,6, +3,3,9,145,5, +1,3,3,9,2, +1,7,5,146,9, +1,5,3,0,3, +147,5,1,3,0, +3,2,1,7,4, +148,9,1,4,3, +187,1,149,5,1, +3,187,1,2,1, +7,3,150,9,1, +3,3,176,2,151, +5,1,3,176,2, +2,1,7,2,152, +9,1,2,3,197, +1,153,5,1,3, +197,1,2,1,7, +1,154,9,1,1, +3,170,0,155,5, +27,3,97,0,2, +1,3,105,0,2, +1,3,113,0,2, +1,3,121,0,2, +1,3,102,0,2, +1,3,110,0,2, +1,3,118,0,2, +1,3,99,0,2, +1,3,107,0,2, +1,3,115,0,2, +1,3,104,0,2, +1,3,112,0,2, +1,3,120,0,2, +1,3,101,0,2, +1,3,109,0,2, +1,3,117,0,2, +1,3,98,0,2, +1,3,106,0,2, +1,3,114,0,2, +1,3,122,0,2, +1,3,103,0,2, +1,3,111,0,2, +1,3,119,0,2, +1,3,100,0,2, +1,3,108,0,2, +1,3,170,0,2, +1,3,116,0,2, +1,7,0,156,9, +1,0,3,192,0, +157,5,27,3,70, +0,2,1,3,78, +0,2,1,3,86, +0,2,1,3,67, +0,2,1,3,75, +0,2,1,3,83, +0,2,1,3,72, +0,2,1,3,80, +0,2,1,3,88, +0,2,1,3,69, +0,2,1,3,77, +0,2,1,3,85, +0,2,1,3,66, +0,2,1,3,74, +0,2,1,3,82, +0,2,1,3,90, +0,2,1,3,71, +0,2,1,3,79, +0,2,1,3,87, +0,2,1,3,68, +0,2,1,3,192, +0,2,1,3,76, +0,2,1,3,84, +0,2,1,3,65, +0,2,1,3,73, +0,2,1,3,81, +0,2,1,3,89, 0,2,1,7,27, 2,0,158,5,3, 159,4,14,67,0, 79,0,77,0,77, 0,69,0,78,0, 84,0,160,12,1, -1095,161,5,119,3, -1,0,162,12,1, -1096,163,5,0,164, +2176,161,5,119,3, +238,22,162,12,1, +2177,163,5,0,164, 11,1,1063,0,165, 4,0,1,-1,3, -9,0,162,3,10, -0,166,12,1,1297, -167,5,0,168,11, -1,1067,0,165,1, --1,3,13,0,162, -3,0,3,162,3, -0,6,162,3,32, -0,162,3,33,0, -162,3,34,0,162, -3,35,0,162,3, -36,0,162,3,37, -0,162,3,38,0, -162,3,40,0,162, -3,41,0,162,3, -42,0,169,12,1, -1436,170,5,1,3, -47,0,171,12,1, -1540,172,5,0,173, -11,1,1049,0,165, -1,-1,174,11,1, -1063,0,165,1,-1, -3,43,0,162,3, -44,0,162,3,45, -0,162,3,46,0, -162,3,47,0,162, -3,3,9,162,3, -49,0,162,3,50, -0,162,3,48,0, -162,3,52,0,162, -3,53,0,162,3, -51,0,162,3,55, -0,162,3,56,0, -162,3,54,0,162, -3,59,0,162,3, -57,0,162,3,61, -0,162,3,62,0, -162,3,60,0,162, -3,64,0,162,3, -65,0,162,3,66, -0,162,3,67,0, -162,3,68,0,162, -3,69,0,162,3, -70,0,162,3,71, -0,162,3,72,0, -162,3,73,0,162, +117,0,162,3,63, +32,162,3,37,0, +162,3,114,0,162, 3,74,0,162,3, -75,0,162,3,76, -0,162,3,77,0, -162,3,78,0,162, -3,79,0,162,3, -80,0,162,3,81, -0,162,3,82,0, -162,3,83,0,162, -3,84,0,162,3, -85,0,162,3,86, -0,162,3,87,0, -162,3,88,0,162, -3,89,0,162,3, -90,0,162,3,91, -0,162,3,92,0, -162,3,93,0,162, -3,94,0,162,3, -95,0,162,3,96, -0,162,3,238,22, -162,3,98,0,162, -3,99,0,162,3, -100,0,162,3,101, -0,162,3,97,0, -162,3,103,0,162, -3,104,0,162,3, -105,0,162,3,106, -0,162,3,102,0, +34,0,162,3,111, +0,162,3,71,0, 162,3,108,0,162, -3,109,0,162,3, -110,0,162,3,111, -0,162,3,112,0, -162,3,113,0,162, -3,114,0,162,3, -115,0,162,3,116, -0,162,3,117,0, -162,3,118,0,162, -3,119,0,162,3, -120,0,162,3,121, -0,162,3,122,0, -162,3,123,0,162, -3,124,0,162,3, -125,0,162,3,96, -6,162,3,107,0, -162,3,126,0,162, -3,58,15,162,3, -59,15,162,3,136, -4,162,3,160,0, -162,3,170,0,162, -3,171,0,162,3, -172,0,162,3,173, -0,162,3,178,0, -162,3,176,2,162, -3,187,0,162,3, -187,1,162,3,192, -0,162,3,41,32, -162,3,197,1,162, -3,0,224,162,3, -40,32,162,3,63, -32,162,0,165,1, +3,68,0,162,3, +105,0,162,3,65, +0,162,3,102,0, +162,3,62,0,162, +3,99,0,162,3, +59,0,162,3,96, +0,162,3,96,6, +162,3,173,0,162, +3,93,0,162,3, +53,0,162,3,13, +0,162,3,170,0, +162,3,90,0,162, +3,50,0,162,3, +10,0,166,12,1, +2576,167,5,0,168, +11,1,1067,0,165, +1,-1,3,87,0, +162,3,47,0,162, +3,100,0,162,3, +124,0,162,3,84, +0,162,3,44,0, +162,3,121,0,162, +3,81,0,162,3, +41,0,162,3,1, +0,162,3,59,15, +162,3,78,0,162, +3,38,0,162,3, +58,15,162,3,115, +0,162,3,75,0, +162,3,35,0,162, +3,192,0,162,3, +112,0,162,3,72, +0,162,3,32,0, +162,3,109,0,162, +3,69,0,162,3, +187,1,162,3,106, +0,162,3,66,0, +162,3,103,0,162, +3,77,0,162,3, +3,9,162,3,118, +0,162,3,60,0, +162,3,0,3,162, +3,197,1,162,3, +176,2,162,3,57, +0,162,3,70,0, +162,3,94,0,162, +3,54,0,162,3, +171,0,162,3,91, +0,162,3,51,0, +162,3,88,0,162, +3,48,0,162,3, +125,0,162,3,85, +0,162,3,56,0, +162,3,97,0,162, +3,122,0,162,3, +82,0,162,3,42, +0,169,12,1,2314, +170,5,1,3,47, +0,171,12,1,2329, +172,5,0,173,11, +1,1049,0,165,1, +-1,174,11,1,1063, +0,165,1,-1,3, +0,6,162,3,119, +0,162,3,79,0, +162,3,41,32,162, +3,116,0,162,3, +76,0,162,3,36, +0,162,3,113,0, +162,3,73,0,162, +3,33,0,162,3, +110,0,162,3,40, +32,162,3,0,224, +162,3,187,0,162, +3,107,0,162,3, +67,0,162,3,104, +0,162,3,64,0, +162,3,101,0,162, +3,61,0,162,3, +178,0,162,3,98, +0,162,3,45,0, +162,3,136,4,162, +3,95,0,162,3, +55,0,162,3,172, +0,162,3,92,0, +162,3,52,0,162, +3,89,0,162,3, +49,0,162,3,9, +0,162,3,126,0, +162,3,86,0,162, +3,46,0,162,3, +123,0,162,3,83, +0,162,3,43,0, +162,3,160,0,162, +3,120,0,162,3, +80,0,162,3,40, +0,162,0,165,1, -1,175,4,18,89, 0,89,0,73,0, 78,0,73,0,84, 0,73,0,65,0, 76,0,176,12,1, -1696,177,5,91,3, -9,0,178,12,1, -42571,179,5,0,180, -11,1,1072,0,165, -1,-1,3,10,0, -178,3,13,0,178, -3,32,0,178,3, -33,0,181,12,1, -45604,182,5,1,3, -61,0,183,12,1, -45719,184,5,0,185, -11,1,142,0,186, -4,36,69,0,88, -0,67,0,76,0, -65,0,77,0,65, -0,84,0,73,0, -79,0,78,0,95, -0,69,0,81,0, -85,0,65,0,76, -0,83,0,1,-1, -187,11,1,180,0, -188,4,22,69,0, -88,0,67,0,76, -0,65,0,77,0, -65,0,84,0,73, -0,79,0,78,0, -1,-1,3,34,0, -189,12,1,45845,190, -5,0,191,11,1, -963,0,165,1,-1, -3,37,0,192,12, -1,43795,193,5,1, -3,61,0,194,12, -1,43910,195,5,0, -196,11,1,40,0, -197,4,28,80,0, -69,0,82,0,67, -0,69,0,78,0, -84,0,95,0,69, -0,81,0,85,0, -65,0,76,0,83, -0,1,-1,198,11, -1,101,0,199,4, -14,80,0,69,0, -82,0,67,0,69, -0,78,0,84,0, -1,-1,3,38,0, -200,12,1,44036,201, -5,1,3,38,0, -202,12,1,44136,203, -5,0,204,11,1, -185,0,205,4,14, -65,0,77,0,80, -0,95,0,65,0, -77,0,80,0,1, --1,206,11,1,160, -0,207,4,6,65, -0,77,0,80,0, -1,-1,3,40,0, -208,12,1,43308,209, -5,0,210,11,1, -71,0,211,4,20, -76,0,69,0,70, -0,84,0,95,0, -80,0,65,0,82, -0,69,0,78,0, -1,-1,3,41,0, -212,12,1,43672,213, -5,0,214,11,1, -76,0,215,4,22, -82,0,73,0,71, -0,72,0,84,0, -95,0,80,0,65, -0,82,0,69,0, -78,0,1,-1,3, -42,0,216,12,1, -44277,217,5,1,3, -61,0,218,12,1, -44392,219,5,0,220, -11,1,28,0,221, -4,22,83,0,84, -0,65,0,82,0, -95,0,69,0,81, -0,85,0,65,0, -76,0,83,0,1, --1,222,11,1,91, -0,223,4,8,83, -0,84,0,65,0, -82,0,1,-1,3, -43,0,224,12,1, -47293,225,5,2,3, -61,0,226,12,1, -47408,227,5,0,228, -11,1,16,0,229, -4,22,80,0,76, -0,85,0,83,0, -95,0,69,0,81, -0,85,0,65,0, -76,0,83,0,1, --1,3,43,0,230, -12,1,47530,231,5, -0,232,11,1,2, -0,233,4,18,73, -0,78,0,67,0, -82,0,69,0,77, -0,69,0,78,0, -84,0,1,-1,234, -11,1,81,0,235, -4,8,80,0,76, -0,85,0,83,0, -1,-1,3,44,0, -236,12,1,44518,237, -5,0,238,11,1, -61,0,239,4,10, -67,0,79,0,77, -0,77,0,65,0, -1,-1,3,45,0, -240,12,1,42703,241, -5,2,3,45,0, -242,12,1,42790,243, -5,0,244,11,1, -10,0,245,4,18, -68,0,69,0,67, -0,82,0,69,0, -77,0,69,0,78, -0,84,0,1,-1, -3,61,0,246,12, -1,42938,247,5,0, -248,11,1,22,0, -249,4,24,77,0, -73,0,78,0,85, -0,83,0,95,0, -69,0,81,0,85, -0,65,0,76,0, -83,0,1,-1,250, -11,1,86,0,251, -4,10,77,0,73, -0,78,0,85,0, -83,0,1,-1,3, -46,0,252,12,1, -44639,253,5,14,3, -48,0,254,12,1, -42305,255,5,14,3, -48,0,254,3,49, -0,254,3,50,0, -254,3,51,0,254, -3,52,0,254,3, -53,0,254,3,54, -0,254,3,55,0, -254,3,56,0,254, -3,57,0,254,3, -101,0,256,12,1, -41768,257,5,12,3, -43,0,258,12,1, -42095,259,5,10,3, -48,0,260,12,1, -41830,261,5,12,3, -48,0,260,3,49, -0,260,3,50,0, -260,3,51,0,260, -3,52,0,260,3, -53,0,260,3,54, -0,260,3,55,0, -260,3,56,0,260, -3,57,0,260,3, -102,0,262,12,1, -41836,263,5,0,264, -11,1,904,0,265, -4,28,70,0,76, -0,79,0,65,0, -84,0,95,0,67, -0,79,0,78,0, -83,0,84,0,65, -0,78,0,84,0, -1,-1,3,70,0, -262,266,11,1,904, -0,265,1,-1,3, -49,0,260,3,50, -0,260,3,51,0, -260,3,52,0,260, -3,53,0,260,3, -54,0,260,3,55, -0,260,3,56,0, -260,3,57,0,260, -0,165,1,-1,3, -45,0,258,3,48, -0,260,3,49,0, -260,3,50,0,260, -3,51,0,260,3, -52,0,260,3,53, -0,260,3,54,0, -260,3,55,0,260, -3,56,0,260,3, -57,0,260,0,165, -1,-1,3,102,0, -262,3,69,0,256, -3,70,0,262,267, -11,1,904,0,265, -1,-1,3,49,0, -254,3,50,0,254, -3,51,0,254,3, -52,0,254,3,53, -0,254,3,54,0, -254,3,55,0,254, -3,56,0,254,3, -57,0,254,3,101, -0,256,3,102,0, -262,3,69,0,256, -3,70,0,262,268, -11,1,111,0,269, -4,12,80,0,69, -0,82,0,73,0, -79,0,68,0,1, --1,3,47,0,270, -12,1,44760,271,5, -3,3,47,0,272, -12,1,44984,273,5, -118,3,1,0,274, -12,1,44985,275,5, -118,3,1,0,274, -3,9,0,274,3, -13,0,274,3,0, -3,274,3,0,6, -274,3,32,0,274, -3,33,0,274,3, -34,0,274,3,35, -0,274,3,36,0, -274,3,37,0,274, -3,38,0,274,3, -40,0,274,3,41, -0,274,3,42,0, -274,3,43,0,274, -3,44,0,274,3, -45,0,274,3,46, -0,274,3,47,0, -274,3,3,9,274, -3,49,0,274,3, -50,0,274,3,48, -0,274,3,52,0, -274,3,53,0,274, -3,51,0,274,3, -55,0,274,3,56, -0,274,3,54,0, -274,3,59,0,274, -3,57,0,274,3, -61,0,274,3,62, -0,274,3,60,0, -274,3,64,0,274, -3,65,0,274,3, -66,0,274,3,67, -0,274,3,68,0, -274,3,69,0,274, -3,70,0,274,3, -71,0,274,3,72, -0,274,3,73,0, -274,3,74,0,274, -3,75,0,274,3, -76,0,274,3,77, -0,274,3,78,0, -274,3,79,0,274, -3,80,0,274,3, -81,0,274,3,82, -0,274,3,83,0, -274,3,84,0,274, -3,85,0,274,3, -86,0,274,3,87, -0,274,3,88,0, -274,3,89,0,274, -3,90,0,274,3, -91,0,274,3,92, -0,274,3,93,0, -274,3,94,0,274, -3,95,0,274,3, -96,0,274,3,238, -22,274,3,98,0, -274,3,99,0,274, -3,100,0,274,3, -101,0,274,3,97, -0,274,3,103,0, -274,3,104,0,274, -3,105,0,274,3, -106,0,274,3,102, -0,274,3,108,0, -274,3,109,0,274, -3,110,0,274,3, -111,0,274,3,112, -0,274,3,113,0, -274,3,114,0,274, -3,115,0,274,3, -116,0,274,3,117, -0,274,3,118,0, -274,3,119,0,274, -3,120,0,274,3, -121,0,274,3,122, -0,274,3,123,0, -274,3,124,0,274, -3,125,0,274,3, -96,6,274,3,107, -0,274,3,126,0, -274,3,58,15,274, -3,59,15,274,3, -136,4,274,3,160, -0,274,3,170,0, -274,3,171,0,274, -3,172,0,274,3, -173,0,274,3,178, -0,274,3,176,2, -274,3,187,0,274, -3,187,1,274,3, -192,0,274,3,41, -32,274,3,197,1, -274,3,0,224,274, -3,40,32,274,3, -63,32,274,276,11, -1,1076,0,165,1, --1,3,9,0,274, -3,13,0,274,3, -0,3,274,3,0, -6,274,3,32,0, -274,3,33,0,274, -3,34,0,274,3, -35,0,274,3,36, -0,274,3,37,0, -274,3,38,0,274, -3,40,0,274,3, -41,0,274,3,42, -0,274,3,43,0, -274,3,44,0,274, -3,45,0,274,3, -46,0,274,3,47, -0,274,3,3,9, -274,3,49,0,274, -3,50,0,274,3, -48,0,274,3,52, -0,274,3,53,0, -274,3,51,0,274, -3,55,0,274,3, -56,0,274,3,54, -0,274,3,59,0, -274,3,57,0,274, -3,61,0,274,3, -62,0,274,3,60, -0,274,3,64,0, -274,3,65,0,274, -3,66,0,274,3, -67,0,274,3,68, -0,274,3,69,0, -274,3,70,0,274, -3,71,0,274,3, -72,0,274,3,73, -0,274,3,74,0, -274,3,75,0,274, -3,76,0,274,3, -77,0,274,3,78, -0,274,3,79,0, -274,3,80,0,274, -3,81,0,274,3, -82,0,274,3,83, -0,274,3,84,0, -274,3,85,0,274, -3,86,0,274,3, -87,0,274,3,88, -0,274,3,89,0, -274,3,90,0,274, -3,91,0,274,3, -92,0,274,3,93, -0,274,3,94,0, -274,3,95,0,274, -3,96,0,274,3, -238,22,274,3,98, -0,274,3,99,0, -274,3,100,0,274, -3,101,0,274,3, -97,0,274,3,103, -0,274,3,104,0, -274,3,105,0,274, -3,106,0,274,3, -102,0,274,3,108, -0,274,3,109,0, -274,3,110,0,274, -3,111,0,274,3, -112,0,274,3,113, -0,274,3,114,0, -274,3,115,0,274, -3,116,0,274,3, -117,0,274,3,118, -0,274,3,119,0, -274,3,120,0,274, -3,121,0,274,3, -122,0,274,3,123, -0,274,3,124,0, -274,3,125,0,274, -3,96,6,274,3, -107,0,274,3,126, -0,274,3,58,15, -274,3,59,15,274, -3,136,4,274,3, -160,0,274,3,170, -0,274,3,171,0, -274,3,172,0,274, -3,173,0,274,3, -178,0,274,3,176, -2,274,3,187,0, -274,3,187,1,274, -3,192,0,274,3, -41,32,274,3,197, -1,274,3,0,224, -274,3,40,32,274, -3,63,32,274,277, -11,1,1076,0,165, -1,-1,3,61,0, -278,12,1,45235,279, -5,0,280,11,1, -34,0,281,4,24, -83,0,76,0,65, -0,83,0,72,0, -95,0,69,0,81, -0,85,0,65,0, -76,0,83,0,1, --1,3,42,0,282, -12,1,44861,283,5, -0,284,11,1,1037, -0,165,1,-1,285, -11,1,96,0,286, -4,10,83,0,76, -0,65,0,83,0, -72,0,1,-1,3, -48,0,287,12,1, -41358,288,5,13,3, -120,0,289,12,1, -41382,290,5,22,3, -102,0,291,12,1, -41383,292,5,22,3, -102,0,291,3,48, -0,291,3,49,0, -291,3,50,0,291, -3,51,0,291,3, -52,0,291,3,53, -0,291,3,54,0, -291,3,55,0,291, -3,56,0,291,3, -57,0,291,3,97, -0,291,3,98,0, -291,3,99,0,291, -3,100,0,291,3, -101,0,291,3,65, -0,291,3,66,0, -291,3,67,0,291, -3,68,0,291,3, -69,0,291,3,70, -0,291,293,11,1, -885,0,294,4,40, -72,0,69,0,88, -0,95,0,73,0, -78,0,84,0,69, -0,71,0,69,0, -82,0,95,0,67, -0,79,0,78,0, -83,0,84,0,65, -0,78,0,84,0, -1,-1,3,48,0, -291,3,49,0,291, -3,50,0,291,3, -51,0,291,3,52, -0,291,3,53,0, -291,3,54,0,291, -3,55,0,291,3, -56,0,291,3,57, -0,291,3,97,0, -291,3,98,0,291, -3,99,0,291,3, -100,0,291,3,101, -0,291,3,65,0, -291,3,66,0,291, -3,67,0,291,3, -68,0,291,3,69, -0,291,3,70,0, -291,0,165,1,-1, -3,48,0,295,12, -1,41660,296,5,11, -3,46,0,297,12, -1,41763,298,5,14, -3,48,0,254,3, -49,0,254,3,50, -0,254,3,51,0, -254,3,52,0,254, -3,53,0,254,3, -54,0,254,3,55, -0,254,3,56,0, -254,3,57,0,254, -3,101,0,256,3, -102,0,262,3,69, -0,256,3,70,0, -262,299,11,1,904, -0,265,1,-1,3, -48,0,295,3,49, -0,295,3,50,0, -295,3,51,0,295, -3,52,0,295,3, -53,0,295,3,54, -0,295,3,55,0, -295,3,56,0,295, -3,57,0,295,300, -11,1,879,0,301, -4,32,73,0,78, -0,84,0,69,0, -71,0,69,0,82, -0,95,0,67,0, -79,0,78,0,83, -0,84,0,65,0, +2777,177,5,91,3, +117,0,178,12,1, +8453,179,5,63,3, +97,0,180,12,1, +8489,181,5,63,3, +97,0,180,3,70, +0,180,3,105,0, +180,3,78,0,180, +3,51,0,180,3, +113,0,180,3,86, +0,180,3,121,0, +180,3,67,0,180, +3,102,0,180,3, +75,0,180,3,48, +0,180,3,110,0, +180,3,83,0,180, +3,56,0,180,3, +118,0,180,3,99, +0,180,3,72,0, +180,3,107,0,180, +3,80,0,180,3, +53,0,180,3,115, +0,180,3,88,0, +180,3,69,0,180, +3,104,0,180,3, +77,0,180,3,50, +0,180,3,112,0, +180,3,85,0,180, +3,120,0,180,3, +66,0,180,3,101, +0,180,3,74,0, +180,3,109,0,180, +3,82,0,180,3, +55,0,180,3,117, +0,180,3,90,0, +180,3,98,0,180, +3,71,0,180,3, +106,0,180,3,79, +0,180,3,52,0, +180,3,114,0,180, +3,87,0,180,3, +122,0,180,3,95, +0,180,3,68,0, +180,3,103,0,180, +3,76,0,180,3, +49,0,180,3,111, +0,180,3,84,0, +180,3,57,0,180, +3,119,0,180,3, +65,0,180,3,100, +0,180,3,73,0, +180,3,108,0,180, +3,81,0,180,3, +54,0,180,3,116, +0,180,3,89,0, +180,182,11,1,867, +0,183,4,10,73, +0,68,0,69,0, 78,0,84,0,1, --1,3,49,0,295, -3,50,0,295,3, -88,0,289,3,52, -0,295,3,53,0, -295,3,51,0,295, -3,55,0,295,3, -56,0,295,3,54, -0,295,3,46,0, -297,3,57,0,295, -302,11,1,879,0, -301,1,-1,3,49, -0,295,3,50,0, -295,3,51,0,295, -3,52,0,295,3, -53,0,295,3,54, -0,295,3,55,0, -295,3,56,0,295, -3,57,0,295,3, -59,0,303,12,1, -45362,304,5,0,305, -11,1,46,0,306, -4,18,83,0,69, -0,77,0,73,0, -67,0,79,0,76, -0,79,0,78,0, -1,-1,3,60,0, -307,12,1,46330,308, -5,2,3,60,0, -309,12,1,46444,310, -5,0,311,11,1, -197,0,312,4,20, -76,0,69,0,70, +-1,3,70,0,180, +3,105,0,180,3, +78,0,180,3,51, +0,180,3,113,0, +180,3,86,0,180, +3,121,0,180,3, +67,0,180,3,102, +0,180,3,75,0, +180,3,48,0,180, +3,110,0,180,3, +83,0,180,3,56, +0,180,3,118,0, +180,3,99,0,180, +3,72,0,180,3, +107,0,180,3,80, +0,180,3,53,0, +180,3,115,0,180, +3,88,0,180,3, +69,0,180,3,104, +0,180,3,77,0, +180,3,50,0,180, +3,112,0,180,3, +85,0,180,3,120, +0,180,3,66,0, +180,3,101,0,180, +3,74,0,180,3, +109,0,180,3,82, +0,180,3,55,0, +180,3,117,0,180, +3,90,0,180,3, +98,0,180,3,71, +0,180,3,106,0, +180,3,79,0,180, +3,52,0,180,3, +114,0,180,3,87, +0,180,3,122,0, +180,3,95,0,180, +3,68,0,180,3, +103,0,180,3,76, +0,180,3,49,0, +180,3,111,0,180, +3,84,0,180,3, +57,0,180,3,119, +0,180,3,65,0, +180,3,100,0,180, +3,73,0,180,3, +108,0,180,3,81, +0,180,3,54,0, +180,3,116,0,180, +3,89,0,180,184, +11,1,867,0,183, +1,-1,3,77,0, +178,3,37,0,185, +12,1,7119,186,5, +1,3,61,0,187, +12,1,7127,188,5, +0,189,11,1,40, +0,190,4,28,80, +0,69,0,82,0, +67,0,69,0,78, 0,84,0,95,0, -83,0,72,0,73, -0,70,0,84,0, -1,-1,3,61,0, -313,12,1,46565,314, -5,0,315,11,1, -148,0,316,4,22, -76,0,69,0,83, -0,83,0,95,0, 69,0,81,0,85, 0,65,0,76,0, -83,0,1,-1,317, -11,1,116,0,318, -4,20,76,0,69, -0,70,0,84,0, -95,0,65,0,78, -0,71,0,76,0, -69,0,1,-1,3, -61,0,319,12,1, -46691,320,5,1,3, -61,0,321,12,1, -46806,322,5,0,323, -11,1,136,0,324, -4,26,69,0,81, -0,85,0,65,0, -76,0,83,0,95, -0,69,0,81,0, -85,0,65,0,76, -0,83,0,1,-1, -325,11,1,66,0, -326,4,12,69,0, -81,0,85,0,65, -0,76,0,83,0, -1,-1,3,62,0, -327,12,1,46932,328, -5,2,3,61,0, -329,12,1,47047,330, -5,0,331,11,1, -154,0,332,4,28, -71,0,82,0,69, -0,65,0,84,0, -69,0,82,0,95, -0,69,0,81,0, -85,0,65,0,76, -0,83,0,1,-1, -3,62,0,333,12, -1,47168,334,5,0, -335,11,1,203,0, -336,4,22,82,0, -73,0,71,0,72, -0,84,0,95,0, -83,0,72,0,73, -0,70,0,84,0, -1,-1,337,11,1, -121,0,338,4,22, -82,0,73,0,71, -0,72,0,84,0, -95,0,65,0,78, -0,71,0,76,0, -69,0,1,-1,3, -64,0,339,12,1, -45483,340,5,0,341, -11,1,106,0,342, -4,4,65,0,84, -0,1,-1,3,65, -0,343,12,1,1697, -344,5,63,3,109, -0,345,12,1,1698, -346,5,63,3,109, -0,345,3,110,0, -345,3,111,0,345, -3,112,0,345,3, -113,0,345,3,114, -0,345,3,115,0, -345,3,116,0,345, -3,117,0,345,3, -118,0,345,3,119, -0,345,3,120,0, -345,3,121,0,345, -3,122,0,345,3, -48,0,345,3,49, -0,345,3,50,0, -345,3,51,0,345, -3,52,0,345,3, -53,0,345,3,54, -0,345,3,55,0, -345,3,56,0,345, -3,57,0,345,3, -65,0,345,3,66, -0,345,3,67,0, -345,3,68,0,345, -3,69,0,345,3, -70,0,345,3,71, -0,345,3,72,0, -345,3,73,0,345, -3,74,0,345,3, -75,0,345,3,76, -0,345,3,77,0, -345,3,78,0,345, -3,79,0,345,3, -80,0,345,3,81, -0,345,3,82,0, -345,3,83,0,345, -3,84,0,345,3, -85,0,345,3,86, -0,345,3,87,0, -345,3,88,0,345, -3,89,0,345,3, -90,0,345,3,95, -0,345,3,97,0, -345,3,98,0,345, -3,99,0,345,3, -100,0,345,3,101, -0,345,3,102,0, -345,3,103,0,345, -3,104,0,345,3, -105,0,345,3,106, -0,345,3,107,0, -345,3,108,0,345, -347,11,1,867,0, -348,4,10,73,0, -68,0,69,0,78, -0,84,0,1,-1, -3,110,0,345,3, -111,0,345,3,112, -0,345,3,113,0, -345,3,114,0,345, -3,115,0,345,3, -116,0,345,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,345,3, -98,0,345,3,99, -0,345,3,100,0, -345,3,101,0,345, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -345,3,106,0,345, -3,107,0,345,3, -108,0,345,349,11, -1,867,0,348,1, --1,3,66,0,343, -3,67,0,343,3, -68,0,343,3,69, -0,343,3,70,0, -343,3,71,0,343, -3,72,0,343,3, -73,0,343,3,74, -0,343,3,75,0, -343,3,76,0,343, -3,77,0,343,3, -78,0,343,3,79, -0,343,3,80,0, -343,3,81,0,343, -3,82,0,343,3, -83,0,343,3,84, -0,343,3,85,0, -343,3,86,0,343, -3,87,0,343,3, -88,0,343,3,89, -0,343,3,90,0, -343,3,91,0,350, -12,1,43186,351,5, -0,352,11,1,126, -0,353,4,24,76, -0,69,0,70,0, -84,0,95,0,66, -0,82,0,65,0, -67,0,75,0,69, -0,84,0,1,-1, -3,93,0,354,12, -1,43551,355,5,0, -356,11,1,131,0, -357,4,26,82,0, -73,0,71,0,72, -0,84,0,95,0, -66,0,82,0,65, -0,67,0,75,0, -69,0,84,0,1, --1,3,94,0,358, -12,1,47655,359,5, -0,360,11,1,170, -0,361,4,10,67, -0,65,0,82,0, -69,0,84,0,1, --1,3,95,0,343, -3,97,0,362,12, -1,22739,363,5,63, -3,109,0,345,3, -110,0,345,3,111, -0,345,3,112,0, -345,3,113,0,345, -3,114,0,345,3, -115,0,345,3,116, -0,364,12,1,22774, -365,5,63,3,109, -0,345,3,110,0, -345,3,111,0,345, -3,112,0,345,3, -113,0,345,3,114, -0,345,3,115,0, -345,3,116,0,366, -12,1,22809,367,5, -63,3,109,0,345, -3,110,0,345,3, -111,0,345,3,112, -0,345,3,113,0, -345,3,114,0,345, -3,115,0,345,3, -116,0,345,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,368,12, -1,22852,369,5,63, -3,109,0,345,3, -110,0,345,3,111, -0,345,3,112,0, -345,3,113,0,345, -3,114,0,345,3, -115,0,345,3,116, -0,345,3,117,0, -345,3,118,0,345, -3,119,0,345,3, -120,0,345,3,121, -0,345,3,122,0, -345,3,48,0,345, -3,49,0,345,3, -50,0,345,3,51, -0,345,3,52,0, -345,3,53,0,345, -3,54,0,345,3, -55,0,345,3,56, -0,345,3,57,0, -345,3,65,0,345, -3,66,0,345,3, -67,0,345,3,68, -0,345,3,69,0, -345,3,70,0,345, -3,71,0,345,3, -72,0,345,3,73, -0,345,3,74,0, -345,3,75,0,345, -3,76,0,345,3, -77,0,345,3,78, -0,345,3,79,0, -345,3,80,0,345, -3,81,0,345,3, -82,0,345,3,83, -0,345,3,84,0, -345,3,85,0,345, -3,86,0,345,3, -87,0,345,3,88, -0,345,3,89,0, -345,3,90,0,345, -3,95,0,345,3, -97,0,345,3,98, -0,345,3,99,0, -370,12,1,22897,371, -5,63,3,109,0, -345,3,110,0,345, -3,111,0,345,3, -112,0,345,3,113, -0,345,3,114,0, -345,3,115,0,345, -3,116,0,345,3, -117,0,345,3,118, -0,345,3,119,0, -345,3,120,0,345, -3,121,0,345,3, -122,0,345,3,48, -0,345,3,49,0, -345,3,50,0,345, -3,51,0,345,3, -52,0,345,3,53, -0,345,3,54,0, -345,3,55,0,345, -3,56,0,345,3, -57,0,345,3,65, -0,345,3,66,0, -345,3,67,0,345, -3,68,0,345,3, -69,0,345,3,70, -0,345,3,71,0, -345,3,72,0,345, -3,73,0,345,3, -74,0,345,3,75, -0,345,3,76,0, -345,3,77,0,345, -3,78,0,345,3, -79,0,345,3,80, -0,345,3,81,0, -345,3,82,0,345, -3,83,0,345,3, -84,0,345,3,85, -0,345,3,86,0, -345,3,87,0,345, -3,88,0,345,3, -89,0,345,3,90, -0,345,3,95,0, -345,3,97,0,345, -3,98,0,345,3, -99,0,345,3,100, -0,345,3,101,0, -345,3,102,0,345, -3,103,0,345,3, -104,0,372,12,1, -22947,373,5,63,3, -109,0,345,3,110, -0,345,3,111,0, -345,3,112,0,345, -3,113,0,345,3, -114,0,345,3,115, -0,345,3,116,0, -345,3,117,0,345, -3,118,0,345,3, -119,0,345,3,120, -0,345,3,121,0, -345,3,122,0,345, -3,48,0,345,3, -49,0,345,3,50, -0,345,3,51,0, -345,3,52,0,345, -3,53,0,345,3, -54,0,345,3,55, -0,345,3,56,0, -345,3,57,0,345, -3,65,0,345,3, -66,0,345,3,67, -0,345,3,68,0, -345,3,69,0,345, -3,70,0,345,3, -71,0,345,3,72, -0,345,3,73,0, -345,3,74,0,345, -3,75,0,345,3, -76,0,345,3,77, -0,345,3,78,0, -345,3,79,0,345, -3,80,0,345,3, -81,0,345,3,82, -0,345,3,83,0, -345,3,84,0,345, -3,85,0,345,3, -86,0,345,3,87, -0,345,3,88,0, -345,3,89,0,345, -3,90,0,345,3, -95,0,345,3,97, -0,345,3,98,0, -345,3,99,0,345, -3,100,0,345,3, -101,0,345,3,102, -0,345,3,103,0, -345,3,104,0,345, -3,105,0,345,3, -106,0,345,3,107, -0,345,3,108,0, -345,374,11,1,380, -0,375,4,24,65, -0,84,0,84,0, -65,0,67,0,72, +83,0,1,-1,191, +11,1,101,0,192, +4,14,80,0,69, +0,82,0,67,0, +69,0,78,0,84, +0,1,-1,3,114, +0,193,12,1,30702, +194,5,63,3,97, +0,180,3,70,0, +180,3,105,0,180, +3,78,0,180,3, +51,0,180,3,113, +0,180,3,86,0, +180,3,121,0,180, +3,67,0,180,3, +102,0,180,3,75, +0,180,3,48,0, +180,3,110,0,180, +3,83,0,180,3, +56,0,180,3,118, +0,180,3,99,0, +180,3,72,0,180, +3,107,0,180,3, +80,0,180,3,53, +0,180,3,115,0, +180,3,88,0,180, +3,69,0,180,3, +104,0,180,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,180,3,66, +0,180,3,101,0, +195,12,1,30782,196, +5,63,3,97,0, +180,3,70,0,180, +3,105,0,180,3, +78,0,180,3,51, +0,180,3,113,0, +180,3,86,0,180, +3,121,0,180,3, +67,0,180,3,102, +0,180,3,75,0, +180,3,48,0,180, +3,110,0,180,3, +83,0,180,3,56, +0,180,3,118,0, +180,3,99,0,180, +3,72,0,180,3, +107,0,180,3,80, +0,180,3,53,0, +180,3,115,0,180, +3,88,0,180,3, +69,0,180,3,104, +0,180,3,77,0, +180,3,50,0,180, +3,112,0,180,3, +85,0,180,3,120, +0,180,3,66,0, +180,3,101,0,180, +3,74,0,180,3, +109,0,197,12,1, +30863,198,5,63,3, +97,0,180,3,70, +0,180,3,105,0, +180,3,78,0,180, +3,51,0,180,3, +113,0,180,3,86, +0,180,3,121,0, +180,3,67,0,180, +3,102,0,180,3, +75,0,180,3,48, +0,180,3,110,0, +180,3,83,0,180, +3,56,0,180,3, +118,0,180,3,99, +0,180,3,72,0, +180,3,107,0,180, +3,80,0,180,3, +53,0,180,3,115, +0,180,3,88,0, +180,3,69,0,180, +3,104,0,180,3, +77,0,180,3,50, +0,180,3,112,0, +180,3,85,0,180, +3,120,0,180,3, +66,0,180,3,101, +0,180,3,74,0, +180,3,109,0,180, +3,82,0,180,3, +55,0,180,3,117, +0,180,3,90,0, +180,3,98,0,180, +3,71,0,180,3, +106,0,180,3,79, +0,180,3,52,0, +180,3,114,0,180, +3,87,0,180,3, +122,0,180,3,95, +0,180,3,68,0, +180,3,103,0,180, +3,76,0,180,3, +49,0,180,3,111, +0,199,12,1,30951, +200,5,63,3,97, +0,180,3,70,0, +180,3,105,0,180, +3,78,0,180,3, +51,0,180,3,113, +0,180,3,86,0, +180,3,121,0,180, +3,67,0,180,3, +102,0,180,3,75, +0,180,3,48,0, +180,3,110,0,180, +3,83,0,180,3, +56,0,180,3,118, +0,180,3,99,0, +180,3,72,0,180, +3,107,0,180,3, +80,0,180,3,53, +0,180,3,115,0, +180,3,88,0,180, +3,69,0,180,3, +104,0,180,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,180,3,66, +0,180,3,101,0, +180,3,74,0,180, +3,109,0,180,3, +82,0,180,3,55, +0,180,3,117,0, +180,3,90,0,180, +3,98,0,180,3, +71,0,180,3,106, +0,180,3,79,0, +180,3,52,0,180, +3,114,0,180,3, +87,0,180,3,122, +0,180,3,95,0, +180,3,68,0,180, +3,103,0,180,3, +76,0,180,3,49, +0,180,3,111,0, +180,3,84,0,180, +3,57,0,180,3, +119,0,180,3,65, +0,180,3,100,0, +180,3,73,0,180, +3,108,0,180,3, +81,0,180,3,54, +0,180,3,116,0, +201,12,1,31044,202, +5,63,3,97,0, +180,3,70,0,180, +3,105,0,180,3, +78,0,180,3,51, +0,180,3,113,0, +180,3,86,0,180, +3,121,0,180,3, +67,0,180,3,102, +0,180,3,75,0, +180,3,48,0,180, +3,110,0,180,3, +83,0,180,3,56, +0,180,3,118,0, +180,3,99,0,180, +3,72,0,180,3, +107,0,180,3,80, +0,180,3,53,0, +180,3,115,0,180, +3,88,0,180,3, +69,0,180,3,104, +0,180,3,77,0, +180,3,50,0,180, +3,112,0,180,3, +85,0,180,3,120, +0,180,3,66,0, +180,3,101,0,203, +12,1,31124,204,5, +63,3,97,0,180, +3,70,0,180,3, +105,0,180,3,78, +0,180,3,51,0, +180,3,113,0,180, +3,86,0,180,3, +121,0,180,3,67, +0,180,3,102,0, +180,3,75,0,180, +3,48,0,180,3, +110,0,180,3,83, +0,180,3,56,0, +180,3,118,0,180, +3,99,0,180,3, +72,0,180,3,107, +0,180,3,80,0, +180,3,53,0,180, +3,115,0,180,3, +88,0,180,3,69, +0,180,3,104,0, +180,3,77,0,180, +3,50,0,180,3, +112,0,180,3,85, +0,180,3,120,0, +180,3,66,0,180, +3,101,0,180,3, +74,0,180,3,109, +0,180,3,82,0, +180,3,55,0,180, +3,117,0,180,3, +90,0,180,3,98, +0,180,3,71,0, +180,3,106,0,180, +3,79,0,180,3, +52,0,180,3,114, +0,180,3,87,0, +180,3,122,0,180, +3,95,0,205,12, +1,31160,206,5,63, +3,97,0,180,3, +70,0,180,3,105, +0,180,3,78,0, +180,3,51,0,180, +3,113,0,180,3, +86,0,180,3,121, +0,180,3,67,0, +180,3,102,0,180, +3,75,0,180,3, +48,0,180,3,110, +0,180,3,83,0, +180,3,56,0,180, +3,118,0,180,3, +99,0,180,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,180,3,88, +0,180,3,69,0, +180,3,104,0,180, +3,77,0,180,3, +50,0,180,3,112, +0,180,3,85,0, +180,3,120,0,180, +3,66,0,180,3, +101,0,180,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +180,3,87,0,180, +3,122,0,180,3, +95,0,180,3,68, +0,180,3,103,0, +180,3,76,0,180, +3,49,0,180,3, +111,0,180,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,207,12,1, +31250,208,5,63,3, +97,0,209,12,1, +31317,210,5,63,3, +97,0,180,3,70, +0,180,3,105,0, +180,3,78,0,180, +3,51,0,180,3, +113,0,180,3,86, +0,180,3,121,0, +180,3,67,0,180, +3,102,0,180,3, +75,0,180,3,48, +0,180,3,110,0, +180,3,83,0,180, +3,56,0,180,3, +118,0,180,3,99, +0,180,3,72,0, +180,3,107,0,180, +3,80,0,180,3, +53,0,180,3,115, +0,180,3,88,0, +180,3,69,0,180, +3,104,0,180,3, +77,0,180,3,50, +0,180,3,112,0, +180,3,85,0,180, +3,120,0,180,3, +66,0,180,3,101, +0,180,3,74,0, +180,3,109,0,180, +3,82,0,180,3, +55,0,180,3,117, +0,180,3,90,0, +180,3,98,0,180, +3,71,0,180,3, +106,0,180,3,79, +0,180,3,52,0, +180,3,114,0,180, +3,87,0,180,3, +122,0,180,3,95, +0,180,3,68,0, +180,3,103,0,180, +3,76,0,180,3, +49,0,180,3,111, +0,180,3,84,0, +180,3,57,0,180, +3,119,0,180,3, +65,0,180,3,100, +0,180,3,73,0, +180,3,108,0,180, +3,81,0,180,3, +54,0,180,3,116, +0,211,12,1,31410, +212,5,63,3,97, +0,213,12,1,31477, +214,5,63,3,97, +0,180,3,70,0, +180,3,105,0,180, +3,78,0,180,3, +51,0,180,3,113, +0,180,3,86,0, +180,3,121,0,180, +3,67,0,180,3, +102,0,180,3,75, +0,180,3,48,0, +180,3,110,0,180, +3,83,0,180,3, +56,0,180,3,118, +0,180,3,99,0, +180,3,72,0,180, +3,107,0,180,3, +80,0,180,3,53, +0,180,3,115,0, +180,3,88,0,180, +3,69,0,180,3, +104,0,180,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,180,3,66, +0,180,3,101,0, +180,3,74,0,180, +3,109,0,180,3, +82,0,180,3,55, +0,180,3,117,0, +180,3,90,0,180, +3,98,0,180,3, +71,0,180,3,106, +0,180,3,79,0, +180,3,52,0,180, +3,114,0,180,3, +87,0,180,3,122, +0,180,3,95,0, +180,3,68,0,180, +3,103,0,180,3, +76,0,180,3,49, +0,180,3,111,0, +180,3,84,0,180, +3,57,0,180,3, +119,0,180,3,65, +0,180,3,100,0, +180,3,73,0,180, +3,108,0,180,3, +81,0,180,3,54, +0,180,3,116,0, +180,3,89,0,180, +215,11,1,705,0, +216,4,34,82,0, +69,0,77,0,79, +0,84,0,69,0, +95,0,68,0,65, +0,84,0,65,0, +95,0,69,0,86, +0,69,0,78,0, +84,0,1,-1,3, +70,0,180,3,105, +0,180,3,78,0, +180,3,51,0,180, +3,113,0,180,3, +86,0,180,3,121, +0,180,3,67,0, +180,3,102,0,180, +3,75,0,180,3, +48,0,180,3,110, +0,180,3,83,0, +180,3,56,0,180, +3,118,0,180,3, +99,0,180,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,180,3,88, +0,180,3,69,0, +180,3,104,0,180, +3,77,0,180,3, +50,0,180,3,112, +0,180,3,85,0, +180,3,120,0,180, +3,66,0,180,3, +101,0,180,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +180,3,87,0,180, +3,122,0,180,3, +95,0,180,3,68, +0,180,3,103,0, +180,3,76,0,180, +3,49,0,180,3, +111,0,180,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,180,3,73, +0,180,3,108,0, +180,3,81,0,180, +3,54,0,180,3, +116,0,180,3,89, +0,180,217,11,1, +867,0,183,1,-1, +3,89,0,180,218, +11,1,867,0,183, +1,-1,3,70,0, +180,3,105,0,180, +3,78,0,180,3, +51,0,180,3,113, +0,180,3,86,0, +180,3,121,0,180, +3,67,0,180,3, +102,0,180,3,75, +0,180,3,48,0, +180,3,110,0,180, +3,83,0,180,3, +56,0,180,3,118, +0,180,3,99,0, +180,3,72,0,180, +3,107,0,180,3, +80,0,180,3,53, +0,180,3,115,0, +180,3,88,0,180, +3,69,0,180,3, +104,0,180,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,180,3,66, +0,180,3,101,0, +180,3,74,0,180, +3,109,0,180,3, +82,0,180,3,55, +0,180,3,117,0, +180,3,90,0,180, +3,98,0,180,3, +71,0,180,3,106, +0,180,3,79,0, +180,3,52,0,180, +3,114,0,180,3, +87,0,180,3,122, +0,180,3,95,0, +180,3,68,0,180, +3,103,0,180,3, +76,0,180,3,49, +0,180,3,111,0, +180,3,84,0,180, +3,57,0,180,3, +119,0,180,3,65, +0,180,3,100,0, +180,3,73,0,180, +3,108,0,180,3, +81,0,180,3,54, +0,180,3,116,0, +180,3,89,0,180, +219,11,1,867,0, +183,1,-1,3,73, +0,180,3,108,0, +180,3,81,0,180, +3,54,0,180,3, +116,0,180,3,89, +0,180,220,11,1, +867,0,183,1,-1, +3,68,0,180,3, +103,0,180,3,76, +0,180,3,49,0, +180,3,111,0,180, +3,84,0,180,3, +57,0,180,3,119, +0,180,3,65,0, +180,3,100,0,180, +3,73,0,180,3, +108,0,180,3,81, +0,180,3,54,0, +180,3,116,0,180, +3,89,0,180,221, +11,1,867,0,183, +1,-1,3,74,0, +180,3,109,0,180, +3,82,0,180,3, +55,0,180,3,117, +0,180,3,90,0, +180,3,98,0,180, +3,71,0,180,3, +106,0,180,3,79, +0,180,3,52,0, +180,3,114,0,180, +3,87,0,180,3, +122,0,180,3,95, +0,180,3,68,0, +180,3,103,0,180, +3,76,0,180,3, +49,0,180,3,111, +0,180,3,84,0, +180,3,57,0,180, +3,119,0,180,3, +65,0,180,3,100, +0,180,3,73,0, +180,3,108,0,180, +3,81,0,180,3, +54,0,180,3,116, +0,180,3,89,0, +180,222,11,1,867, +0,183,1,-1,3, +89,0,180,223,11, +1,867,0,183,1, +-1,3,84,0,180, +3,57,0,180,3, +119,0,180,3,65, +0,180,3,100,0, +180,3,73,0,180, +3,108,0,180,3, +81,0,180,3,54, +0,180,3,116,0, +180,3,89,0,180, +224,11,1,867,0, +183,1,-1,3,82, +0,180,3,55,0, +180,3,117,0,180, +3,90,0,180,3, +98,0,180,3,71, +0,180,3,106,0, +180,3,79,0,180, +3,52,0,180,3, +114,0,180,3,87, +0,180,3,122,0, +180,3,95,0,180, +3,68,0,180,3, +103,0,180,3,76, +0,180,3,49,0, +180,3,111,0,180, +3,84,0,180,3, +57,0,180,3,119, +0,180,3,65,0, +180,3,100,0,180, +3,73,0,180,3, +108,0,180,3,81, +0,180,3,54,0, +180,3,116,0,225, +12,1,31955,226,5, +63,3,97,0,180, +3,70,0,180,3, +105,0,180,3,78, +0,180,3,51,0, +180,3,113,0,180, +3,86,0,180,3, +121,0,180,3,67, +0,180,3,102,0, +180,3,75,0,180, +3,48,0,180,3, +110,0,180,3,83, +0,180,3,56,0, +180,3,118,0,180, +3,99,0,180,3, +72,0,180,3,107, +0,180,3,80,0, +180,3,53,0,180, +3,115,0,180,3, +88,0,180,3,69, +0,180,3,104,0, +180,3,77,0,180, +3,50,0,180,3, +112,0,180,3,85, +0,180,3,120,0, +180,3,66,0,180, +3,101,0,180,3, +74,0,180,3,109, +0,180,3,82,0, +180,3,55,0,180, +3,117,0,227,12, +1,32037,228,5,63, +3,97,0,180,3, +70,0,180,3,105, +0,180,3,78,0, +180,3,51,0,180, +3,113,0,180,3, +86,0,180,3,121, +0,180,3,67,0, +180,3,102,0,180, +3,75,0,180,3, +48,0,180,3,110, +0,180,3,83,0, +180,3,56,0,180, +3,118,0,180,3, +99,0,180,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,180,3,88, +0,180,3,69,0, +180,3,104,0,180, +3,77,0,180,3, +50,0,180,3,112, +0,180,3,85,0, +180,3,120,0,180, +3,66,0,180,3, +101,0,180,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +229,12,1,32122,230, +5,63,3,97,0, +180,3,70,0,180, +3,105,0,180,3, +78,0,180,3,51, +0,180,3,113,0, +180,3,86,0,180, +3,121,0,180,3, +67,0,180,3,102, +0,180,3,75,0, +180,3,48,0,180, +3,110,0,231,12, +1,32194,232,5,63, +3,97,0,180,3, +70,0,180,3,105, +0,180,3,78,0, +180,3,51,0,180, +3,113,0,180,3, +86,0,180,3,121, +0,180,3,67,0, +180,3,102,0,180, +3,75,0,180,3, +48,0,180,3,110, +0,180,3,83,0, +180,3,56,0,180, +3,118,0,180,3, +99,0,180,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,180,3,88, +0,180,3,69,0, +180,3,104,0,180, +3,77,0,180,3, +50,0,180,3,112, +0,180,3,85,0, +180,3,120,0,180, +3,66,0,180,3, +101,0,180,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +180,3,87,0,180, +3,122,0,180,3, +95,0,180,3,68, +0,180,3,103,0, +180,3,76,0,180, +3,49,0,180,3, +111,0,180,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,180,3,73, +0,180,3,108,0, +180,3,81,0,180, +3,54,0,180,3, +116,0,180,3,89, +0,180,233,11,1, +273,0,234,4,12, +82,0,69,0,84, +0,85,0,82,0, +78,0,1,-1,3, +83,0,180,3,56, +0,180,3,118,0, +180,3,99,0,180, +3,72,0,180,3, +107,0,180,3,80, +0,180,3,53,0, +180,3,115,0,180, +3,88,0,180,3, +69,0,180,3,104, +0,180,3,77,0, +180,3,50,0,180, +3,112,0,180,3, +85,0,180,3,120, +0,180,3,66,0, +180,3,101,0,180, +3,74,0,180,3, +109,0,180,3,82, +0,180,3,55,0, +180,3,117,0,180, +3,90,0,180,3, +98,0,180,3,71, +0,180,3,106,0, +180,3,79,0,180, +3,52,0,180,3, +114,0,180,3,87, +0,180,3,122,0, +180,3,95,0,180, +3,68,0,180,3, +103,0,180,3,76, +0,180,3,49,0, +180,3,111,0,180, +3,84,0,180,3, +57,0,180,3,119, +0,180,3,65,0, +180,3,100,0,180, +3,73,0,180,3, +108,0,180,3,81, +0,180,3,54,0, +180,3,116,0,180, +3,89,0,180,235, +11,1,867,0,183, +1,-1,3,87,0, +180,3,122,0,180, +3,95,0,180,3, +68,0,180,3,103, +0,180,3,76,0, +180,3,49,0,180, +3,111,0,180,3, +84,0,180,3,57, +0,180,3,119,0, +180,3,65,0,180, +3,100,0,180,3, +73,0,180,3,108, +0,180,3,81,0, +180,3,54,0,180, +3,116,0,180,3, +89,0,180,236,11, +1,867,0,183,1, +-1,3,90,0,180, +3,98,0,180,3, +71,0,180,3,106, +0,180,3,79,0, +180,3,52,0,180, +3,114,0,180,3, +87,0,180,3,122, +0,180,3,95,0, +180,3,68,0,180, +3,103,0,180,3, +76,0,180,3,49, +0,180,3,111,0, +180,3,84,0,180, +3,57,0,180,3, +119,0,180,3,65, +0,180,3,100,0, +180,3,73,0,180, +3,108,0,180,3, +81,0,180,3,54, +0,180,3,116,0, +180,3,89,0,180, +237,11,1,867,0, +183,1,-1,3,89, +0,180,238,11,1, +867,0,183,1,-1, +3,74,0,180,3, +109,0,180,3,82, +0,180,3,55,0, +180,3,117,0,239, +12,1,32464,240,5, +63,3,97,0,180, +3,70,0,180,3, +105,0,180,3,78, +0,180,3,51,0, +180,3,113,0,180, +3,86,0,180,3, +121,0,180,3,67, +0,180,3,102,0, +180,3,75,0,180, +3,48,0,180,3, +110,0,241,12,1, +32536,242,5,63,3, +97,0,180,3,70, +0,180,3,105,0, +180,3,78,0,180, +3,51,0,180,3, +113,0,180,3,86, +0,180,3,121,0, +180,3,67,0,180, +3,102,0,180,3, +75,0,180,3,48, +0,180,3,110,0, +180,3,83,0,180, +3,56,0,180,3, +118,0,180,3,99, +0,180,3,72,0, +180,3,107,0,180, +3,80,0,180,3, +53,0,180,3,115, +0,180,3,88,0, +180,3,69,0,180, +3,104,0,180,3, +77,0,180,3,50, +0,180,3,112,0, +180,3,85,0,180, +3,120,0,180,3, +66,0,180,3,101, +0,180,3,74,0, +180,3,109,0,180, +3,82,0,180,3, +55,0,180,3,117, +0,180,3,90,0, +180,3,98,0,180, +3,71,0,180,3, +106,0,180,3,79, +0,180,3,52,0, +180,3,114,0,180, +3,87,0,180,3, +122,0,180,3,95, +0,243,12,1,32572, +244,5,63,3,97, +0,180,3,70,0, +180,3,105,0,180, +3,78,0,180,3, +51,0,180,3,113, +0,180,3,86,0, +180,3,121,0,180, +3,67,0,180,3, +102,0,180,3,75, +0,180,3,48,0, +180,3,110,0,180, +3,83,0,180,3, +56,0,180,3,118, +0,180,3,99,0, +180,3,72,0,180, +3,107,0,180,3, +80,0,180,3,53, +0,180,3,115,0, +180,3,88,0,180, +3,69,0,180,3, +104,0,180,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,180,3,66, +0,180,3,101,0, +180,3,74,0,180, +3,109,0,180,3, +82,0,180,3,55, +0,180,3,117,0, +180,3,90,0,180, +3,98,0,180,3, +71,0,180,3,106, +0,180,3,79,0, +180,3,52,0,180, +3,114,0,180,3, +87,0,180,3,122, +0,180,3,95,0, +180,3,68,0,180, +3,103,0,180,3, +76,0,180,3,49, +0,180,3,111,0, +180,3,84,0,180, +3,57,0,180,3, +119,0,180,3,65, +0,180,3,100,0, +180,3,73,0,180, +3,108,0,180,3, +81,0,180,3,54, +0,180,3,116,0, +245,12,1,32665,246, +5,63,3,97,0, +180,3,70,0,180, +3,105,0,247,12, +1,32733,248,5,63, +3,97,0,180,3, +70,0,180,3,105, +0,180,3,78,0, +180,3,51,0,180, +3,113,0,180,3, +86,0,180,3,121, +0,180,3,67,0, +180,3,102,0,180, +3,75,0,180,3, +48,0,180,3,110, +0,180,3,83,0, +180,3,56,0,180, +3,118,0,180,3, +99,0,180,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,180,3,88, +0,180,3,69,0, +180,3,104,0,180, +3,77,0,180,3, +50,0,180,3,112, +0,180,3,85,0, +180,3,120,0,180, +3,66,0,180,3, +101,0,180,3,74, +0,180,3,109,0, +249,12,1,32814,250, +5,63,3,97,0, +180,3,70,0,180, +3,105,0,180,3, +78,0,180,3,51, +0,180,3,113,0, +180,3,86,0,180, +3,121,0,180,3, +67,0,180,3,102, +0,180,3,75,0, +180,3,48,0,180, +3,110,0,180,3, +83,0,180,3,56, +0,180,3,118,0, +180,3,99,0,180, +3,72,0,180,3, +107,0,180,3,80, +0,180,3,53,0, +180,3,115,0,180, +3,88,0,180,3, +69,0,180,3,104, +0,180,3,77,0, +180,3,50,0,180, +3,112,0,180,3, +85,0,180,3,120, +0,180,3,66,0, +180,3,101,0,251, +12,1,32894,252,5, +63,3,97,0,180, +3,70,0,180,3, +105,0,180,3,78, +0,180,3,51,0, +180,3,113,0,180, +3,86,0,180,3, +121,0,180,3,67, +0,180,3,102,0, +180,3,75,0,180, +3,48,0,180,3, +110,0,180,3,83, +0,180,3,56,0, +180,3,118,0,180, +3,99,0,180,3, +72,0,180,3,107, +0,180,3,80,0, +180,3,53,0,180, +3,115,0,180,3, +88,0,180,3,69, +0,180,3,104,0, +180,3,77,0,180, +3,50,0,180,3, +112,0,180,3,85, +0,180,3,120,0, +180,3,66,0,180, +3,101,0,180,3, +74,0,180,3,109, +0,180,3,82,0, +180,3,55,0,180, +3,117,0,180,3, +90,0,180,3,98, +0,180,3,71,0, +180,3,106,0,180, +3,79,0,180,3, +52,0,180,3,114, +0,180,3,87,0, +180,3,122,0,180, +3,95,0,253,12, +1,32930,254,5,63, +3,97,0,180,3, +70,0,180,3,105, +0,180,3,78,0, +180,3,51,0,180, +3,113,0,180,3, +86,0,180,3,121, +0,180,3,67,0, +180,3,102,0,180, +3,75,0,180,3, +48,0,180,3,110, +0,180,3,83,0, +180,3,56,0,180, +3,118,0,180,3, +99,0,180,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,180,3,88, +0,180,3,69,0, +180,3,104,0,180, +3,77,0,180,3, +50,0,180,3,112, +0,255,12,1,33008, +256,5,63,3,97, +0,180,3,70,0, +180,3,105,0,180, +3,78,0,180,3, +51,0,180,3,113, +0,180,3,86,0, +180,3,121,0,180, +3,67,0,180,3, +102,0,180,3,75, +0,180,3,48,0, +180,3,110,0,180, +3,83,0,180,3, +56,0,180,3,118, +0,180,3,99,0, +180,3,72,0,180, +3,107,0,180,3, +80,0,180,3,53, +0,180,3,115,0, +180,3,88,0,180, +3,69,0,180,3, +104,0,180,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,180,3,66, +0,180,3,101,0, +257,12,1,33088,258, +5,63,3,97,0, +180,3,70,0,180, +3,105,0,180,3, +78,0,180,3,51, +0,180,3,113,0, +180,3,86,0,180, +3,121,0,180,3, +67,0,180,3,102, +0,180,3,75,0, +180,3,48,0,180, +3,110,0,180,3, +83,0,180,3,56, +0,180,3,118,0, +180,3,99,0,180, +3,72,0,180,3, +107,0,180,3,80, +0,180,3,53,0, +180,3,115,0,180, +3,88,0,180,3, +69,0,180,3,104, +0,180,3,77,0, +180,3,50,0,180, +3,112,0,180,3, +85,0,180,3,120, +0,180,3,66,0, +180,3,101,0,180, +3,74,0,180,3, +109,0,180,3,82, +0,180,3,55,0, +180,3,117,0,180, +3,90,0,180,3, +98,0,180,3,71, +0,180,3,106,0, +180,3,79,0,180, +3,52,0,180,3, +114,0,259,12,1, +33173,260,5,63,3, +97,0,180,3,70, +0,180,3,105,0, +180,3,78,0,180, +3,51,0,180,3, +113,0,180,3,86, +0,180,3,121,0, +180,3,67,0,180, +3,102,0,180,3, +75,0,180,3,48, +0,180,3,110,0, +180,3,83,0,180, +3,56,0,180,3, +118,0,180,3,99, +0,180,3,72,0, +180,3,107,0,180, +3,80,0,180,3, +53,0,180,3,115, +0,180,3,88,0, +180,3,69,0,180, +3,104,0,180,3, +77,0,180,3,50, +0,180,3,112,0, +180,3,85,0,180, +3,120,0,180,3, +66,0,180,3,101, +0,180,3,74,0, +180,3,109,0,261, +12,1,33254,262,5, +63,3,97,0,180, +3,70,0,180,3, +105,0,263,12,1, +33322,264,5,63,3, +97,0,180,3,70, +0,180,3,105,0, +180,3,78,0,180, +3,51,0,180,3, +113,0,180,3,86, +0,180,3,121,0, +180,3,67,0,180, +3,102,0,180,3, +75,0,180,3,48, +0,180,3,110,0, +180,3,83,0,180, +3,56,0,180,3, +118,0,180,3,99, +0,180,3,72,0, +180,3,107,0,180, +3,80,0,180,3, +53,0,180,3,115, +0,265,12,1,33398, +266,5,63,3,97, +0,180,3,70,0, +180,3,105,0,180, +3,78,0,180,3, +51,0,180,3,113, +0,180,3,86,0, +180,3,121,0,180, +3,67,0,180,3, +102,0,180,3,75, +0,180,3,48,0, +180,3,110,0,180, +3,83,0,180,3, +56,0,180,3,118, +0,180,3,99,0, +180,3,72,0,180, +3,107,0,180,3, +80,0,180,3,53, +0,180,3,115,0, +267,12,1,33474,268, +5,63,3,97,0, +180,3,70,0,180, +3,105,0,269,12, +1,33542,270,5,63, +3,97,0,180,3, +70,0,180,3,105, +0,180,3,78,0, +180,3,51,0,180, +3,113,0,180,3, +86,0,180,3,121, +0,180,3,67,0, +180,3,102,0,180, +3,75,0,180,3, +48,0,180,3,110, +0,180,3,83,0, +180,3,56,0,180, +3,118,0,180,3, +99,0,180,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,180,3,88, +0,180,3,69,0, +180,3,104,0,180, +3,77,0,180,3, +50,0,180,3,112, +0,180,3,85,0, +180,3,120,0,180, +3,66,0,180,3, +101,0,180,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +180,3,87,0,180, +3,122,0,180,3, +95,0,180,3,68, +0,180,3,103,0, +180,3,76,0,180, +3,49,0,180,3, +111,0,271,12,1, +33630,272,5,63,3, +97,0,180,3,70, +0,180,3,105,0, +180,3,78,0,180, +3,51,0,180,3, +113,0,180,3,86, +0,180,3,121,0, +180,3,67,0,180, +3,102,0,180,3, +75,0,180,3,48, +0,180,3,110,0, +273,12,1,33702,274, +5,63,3,97,0, +180,3,70,0,180, +3,105,0,180,3, +78,0,180,3,51, +0,180,3,113,0, +180,3,86,0,180, +3,121,0,180,3, +67,0,180,3,102, +0,180,3,75,0, +180,3,48,0,180, +3,110,0,180,3, +83,0,180,3,56, +0,180,3,118,0, +180,3,99,0,180, +3,72,0,180,3, +107,0,180,3,80, +0,180,3,53,0, +180,3,115,0,275, +12,1,33778,276,5, +63,3,97,0,180, +3,70,0,180,3, +105,0,180,3,78, +0,180,3,51,0, +180,3,113,0,180, +3,86,0,180,3, +121,0,180,3,67, +0,180,3,102,0, +180,3,75,0,180, +3,48,0,180,3, +110,0,180,3,83, +0,180,3,56,0, +180,3,118,0,180, +3,99,0,180,3, +72,0,180,3,107, +0,180,3,80,0, +180,3,53,0,180, +3,115,0,180,3, +88,0,180,3,69, +0,180,3,104,0, +180,3,77,0,180, +3,50,0,180,3, +112,0,180,3,85, +0,180,3,120,0, +180,3,66,0,180, +3,101,0,180,3, +74,0,180,3,109, +0,180,3,82,0, +180,3,55,0,180, +3,117,0,180,3, +90,0,180,3,98, +0,180,3,71,0, +180,3,106,0,180, +3,79,0,180,3, +52,0,180,3,114, +0,180,3,87,0, +180,3,122,0,180, +3,95,0,180,3, +68,0,180,3,103, +0,180,3,76,0, +180,3,49,0,180, +3,111,0,180,3, +84,0,180,3,57, +0,180,3,119,0, +180,3,65,0,180, +3,100,0,180,3, +73,0,180,3,108, +0,180,3,81,0, +180,3,54,0,180, +3,116,0,180,3, +89,0,180,277,11, +1,720,0,278,4, +52,82,0,85,0, +78,0,95,0,84, +0,73,0,77,0, +69,0,95,0,80, +0,69,0,82,0, +77,0,73,0,83, +0,83,0,73,0, +79,0,78,0,83, 0,95,0,69,0, 86,0,69,0,78, 0,84,0,1,-1, -3,105,0,345,3, -106,0,345,3,107, -0,345,3,108,0, -345,376,11,1,867, -0,348,1,-1,3, -100,0,345,3,101, -0,345,3,102,0, -345,3,103,0,345, -3,104,0,345,3, -105,0,345,3,106, -0,345,3,107,0, -345,3,108,0,345, -377,11,1,867,0, -348,1,-1,3,98, -0,345,3,99,0, -345,3,100,0,345, -3,101,0,345,3, -102,0,345,3,103, -0,345,3,104,0, -345,3,105,0,345, -3,106,0,345,3, -107,0,345,3,108, -0,345,378,11,1, -867,0,348,1,-1, -3,117,0,345,3, -118,0,345,3,119, -0,345,3,120,0, -345,3,121,0,345, -3,122,0,345,3, -48,0,345,3,49, -0,345,3,50,0, -345,3,51,0,345, -3,52,0,345,3, -53,0,345,3,54, -0,345,3,55,0, -345,3,56,0,345, -3,57,0,345,3, -65,0,345,3,66, -0,345,3,67,0, -345,3,68,0,345, -3,69,0,345,3, -70,0,345,3,71, -0,345,3,72,0, -345,3,73,0,345, -3,74,0,345,3, -75,0,345,3,76, -0,345,3,77,0, -345,3,78,0,345, -3,79,0,345,3, -80,0,345,3,81, -0,345,3,82,0, -345,3,83,0,345, -3,84,0,345,3, -85,0,345,3,86, -0,345,3,87,0, -345,3,88,0,345, -3,89,0,345,3, -90,0,345,3,95, -0,379,12,1,23340, -380,5,63,3,109, -0,345,3,110,0, -345,3,111,0,345, -3,112,0,345,3, -113,0,345,3,114, -0,381,12,1,23373, -382,5,63,3,109, -0,345,3,110,0, -345,3,111,0,383, -12,1,23403,384,5, -63,3,109,0,345, -3,110,0,345,3, -111,0,345,3,112, -0,345,3,113,0, -345,3,114,0,345, -3,115,0,345,3, -116,0,385,12,1, -23438,386,5,63,3, -109,0,345,3,110, -0,345,3,111,0, -345,3,112,0,345, -3,113,0,345,3, -114,0,345,3,115, -0,345,3,116,0, -345,3,117,0,345, -3,118,0,345,3, -119,0,345,3,120, -0,345,3,121,0, -345,3,122,0,345, -3,48,0,345,3, -49,0,345,3,50, -0,345,3,51,0, -345,3,52,0,345, -3,53,0,345,3, -54,0,345,3,55, -0,345,3,56,0, -345,3,57,0,345, -3,65,0,345,3, -66,0,345,3,67, -0,345,3,68,0, -345,3,69,0,345, -3,70,0,345,3, -71,0,345,3,72, -0,345,3,73,0, -345,3,74,0,345, -3,75,0,345,3, -76,0,345,3,77, -0,345,3,78,0, -345,3,79,0,345, -3,80,0,345,3, -81,0,345,3,82, -0,345,3,83,0, -345,3,84,0,345, -3,85,0,345,3, -86,0,345,3,87, -0,345,3,88,0, -345,3,89,0,345, -3,90,0,345,3, -95,0,387,12,1, -23524,388,5,63,3, -109,0,345,3,110, -0,345,3,111,0, -345,3,112,0,345, -3,113,0,345,3, -114,0,345,3,115, -0,345,3,116,0, -389,12,1,23559,390, -5,63,3,109,0, -345,3,110,0,345, -3,111,0,345,3, -112,0,345,3,113, -0,345,3,114,0, -345,3,115,0,345, -3,116,0,345,3, -117,0,345,3,118, -0,345,3,119,0, -345,3,120,0,345, -3,121,0,345,3, -122,0,345,3,48, -0,345,3,49,0, -345,3,50,0,345, -3,51,0,345,3, -52,0,345,3,53, -0,345,3,54,0, -345,3,55,0,345, -3,56,0,345,3, -57,0,345,3,65, -0,345,3,66,0, -345,3,67,0,345, -3,68,0,345,3, -69,0,345,3,70, -0,345,3,71,0, -345,3,72,0,345, -3,73,0,345,3, -74,0,345,3,75, -0,345,3,76,0, -345,3,77,0,345, -3,78,0,345,3, -79,0,345,3,80, -0,345,3,81,0, -345,3,82,0,345, -3,83,0,345,3, -84,0,345,3,85, -0,345,3,86,0, -345,3,87,0,345, -3,88,0,345,3, -89,0,345,3,90, -0,345,3,95,0, -345,3,97,0,391, -12,1,23602,392,5, -63,3,109,0,345, -3,110,0,345,3, -111,0,345,3,112, -0,345,3,113,0, -345,3,114,0,393, -12,1,23635,394,5, -63,3,109,0,345, -3,110,0,345,3, -111,0,345,3,112, -0,345,3,113,0, -345,3,114,0,345, -3,115,0,345,3, -116,0,345,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,345,3, -98,0,345,3,99, -0,345,3,100,0, -345,3,101,0,345, -3,102,0,345,3, -103,0,395,12,1, -23684,396,5,63,3, -109,0,345,3,110, -0,345,3,111,0, -345,3,112,0,345, -3,113,0,345,3, -114,0,345,3,115, -0,345,3,116,0, -345,3,117,0,345, -3,118,0,345,3, -119,0,345,3,120, -0,345,3,121,0, -345,3,122,0,345, -3,48,0,345,3, -49,0,345,3,50, -0,345,3,51,0, -345,3,52,0,345, -3,53,0,345,3, -54,0,345,3,55, -0,345,3,56,0, -345,3,57,0,345, -3,65,0,345,3, -66,0,345,3,67, -0,345,3,68,0, -345,3,69,0,345, -3,70,0,345,3, -71,0,345,3,72, -0,345,3,73,0, -345,3,74,0,345, -3,75,0,345,3, -76,0,345,3,77, -0,345,3,78,0, -345,3,79,0,345, -3,80,0,345,3, -81,0,345,3,82, -0,345,3,83,0, -345,3,84,0,345, -3,85,0,345,3, -86,0,345,3,87, -0,345,3,88,0, -345,3,89,0,345, -3,90,0,345,3, -95,0,345,3,97, -0,345,3,98,0, -345,3,99,0,345, -3,100,0,345,3, -101,0,397,12,1, -23731,398,5,63,3, -109,0,345,3,110, -0,345,3,111,0, -345,3,112,0,345, -3,113,0,345,3, -114,0,345,3,115, -0,345,3,116,0, -399,12,1,23766,400, -5,63,3,109,0, -345,3,110,0,345, -3,111,0,345,3, -112,0,345,3,113, -0,345,3,114,0, -345,3,115,0,345, -3,116,0,345,3, -117,0,345,3,118, -0,345,3,119,0, -345,3,120,0,345, -3,121,0,345,3, -122,0,345,3,48, -0,345,3,49,0, -345,3,50,0,345, -3,51,0,345,3, -52,0,345,3,53, -0,345,3,54,0, -345,3,55,0,345, -3,56,0,345,3, -57,0,345,3,65, -0,345,3,66,0, -345,3,67,0,345, -3,68,0,345,3, -69,0,345,3,70, -0,345,3,71,0, -345,3,72,0,345, -3,73,0,345,3, -74,0,345,3,75, -0,345,3,76,0, -345,3,77,0,345, -3,78,0,345,3, -79,0,345,3,80, -0,345,3,81,0, -345,3,82,0,345, -3,83,0,345,3, -84,0,345,3,85, -0,345,3,86,0, -345,3,87,0,345, -3,88,0,345,3, -89,0,345,3,90, -0,345,3,95,0, -345,3,97,0,345, -3,98,0,345,3, -99,0,345,3,100, -0,345,3,101,0, -345,3,102,0,345, -3,103,0,345,3, -104,0,345,3,105, -0,345,3,106,0, -345,3,107,0,345, -3,108,0,345,401, -11,1,350,0,402, -4,38,65,0,84, -0,95,0,82,0, -79,0,84,0,95, +3,88,0,180,3, +69,0,180,3,104, +0,180,3,77,0, +180,3,50,0,180, +3,112,0,180,3, +85,0,180,3,120, +0,180,3,66,0, +180,3,101,0,180, +3,74,0,180,3, +109,0,180,3,82, +0,180,3,55,0, +180,3,117,0,180, +3,90,0,180,3, +98,0,180,3,71, +0,180,3,106,0, +180,3,79,0,180, +3,52,0,180,3, +114,0,180,3,87, +0,180,3,122,0, +180,3,95,0,180, +3,68,0,180,3, +103,0,180,3,76, +0,180,3,49,0, +180,3,111,0,180, +3,84,0,180,3, +57,0,180,3,119, +0,180,3,65,0, +180,3,100,0,180, +3,73,0,180,3, +108,0,180,3,81, +0,180,3,54,0, +180,3,116,0,180, +3,89,0,180,279, +11,1,867,0,183, +1,-1,3,83,0, +180,3,56,0,180, +3,118,0,180,3, +99,0,180,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,180,3,88, +0,180,3,69,0, +180,3,104,0,180, +3,77,0,180,3, +50,0,180,3,112, +0,180,3,85,0, +180,3,120,0,180, +3,66,0,180,3, +101,0,180,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +180,3,87,0,180, +3,122,0,180,3, +95,0,180,3,68, +0,180,3,103,0, +180,3,76,0,180, +3,49,0,180,3, +111,0,180,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,180,3,73, +0,180,3,108,0, +180,3,81,0,180, +3,54,0,180,3, +116,0,180,3,89, +0,180,280,11,1, +867,0,183,1,-1, +3,84,0,180,3, +57,0,180,3,119, +0,180,3,65,0, +180,3,100,0,180, +3,73,0,180,3, +108,0,180,3,81, +0,180,3,54,0, +180,3,116,0,180, +3,89,0,180,281, +11,1,867,0,183, +1,-1,3,78,0, +180,3,51,0,180, +3,113,0,180,3, +86,0,180,3,121, +0,180,3,67,0, +180,3,102,0,180, +3,75,0,180,3, +48,0,180,3,110, +0,180,3,83,0, +180,3,56,0,180, +3,118,0,180,3, +99,0,180,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,180,3,88, +0,180,3,69,0, +180,3,104,0,180, +3,77,0,180,3, +50,0,180,3,112, +0,180,3,85,0, +180,3,120,0,180, +3,66,0,180,3, +101,0,180,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +180,3,87,0,180, +3,122,0,180,3, +95,0,180,3,68, +0,180,3,103,0, +180,3,76,0,180, +3,49,0,180,3, +111,0,180,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,180,3,73, +0,180,3,108,0, +180,3,81,0,180, +3,54,0,180,3, +116,0,180,3,89, +0,180,282,11,1, +867,0,183,1,-1, +3,88,0,180,3, +69,0,180,3,104, +0,180,3,77,0, +180,3,50,0,180, +3,112,0,180,3, +85,0,180,3,120, +0,180,3,66,0, +180,3,101,0,180, +3,74,0,180,3, +109,0,180,3,82, +0,180,3,55,0, +180,3,117,0,180, +3,90,0,180,3, +98,0,180,3,71, +0,180,3,106,0, +180,3,79,0,180, +3,52,0,180,3, +114,0,180,3,87, +0,180,3,122,0, +180,3,95,0,180, +3,68,0,180,3, +103,0,180,3,76, +0,180,3,49,0, +180,3,111,0,180, +3,84,0,180,3, +57,0,180,3,119, +0,180,3,65,0, +180,3,100,0,180, +3,73,0,180,3, +108,0,180,3,81, +0,180,3,54,0, +180,3,116,0,180, +3,89,0,180,283, +11,1,867,0,183, +1,-1,3,88,0, +180,3,69,0,180, +3,104,0,180,3, +77,0,180,3,50, +0,180,3,112,0, +180,3,85,0,180, +3,120,0,180,3, +66,0,180,3,101, +0,180,3,74,0, +180,3,109,0,180, +3,82,0,180,3, +55,0,180,3,117, +0,180,3,90,0, +180,3,98,0,180, +3,71,0,180,3, +106,0,180,3,79, +0,180,3,52,0, +180,3,114,0,180, +3,87,0,180,3, +122,0,180,3,95, +0,180,3,68,0, +180,3,103,0,180, +3,76,0,180,3, +49,0,180,3,111, +0,180,3,84,0, +180,3,57,0,180, +3,119,0,180,3, +65,0,180,3,100, +0,180,3,73,0, +180,3,108,0,180, +3,81,0,180,3, +54,0,180,3,116, +0,180,3,89,0, +180,284,11,1,867, +0,183,1,-1,3, +78,0,180,3,51, +0,180,3,113,0, +180,3,86,0,180, +3,121,0,180,3, +67,0,180,3,102, +0,180,3,75,0, +180,3,48,0,180, +3,110,0,180,3, +83,0,180,3,56, +0,180,3,118,0, +180,3,99,0,180, +3,72,0,180,3, +107,0,180,3,80, +0,180,3,53,0, +180,3,115,0,180, +3,88,0,180,3, +69,0,180,3,104, +0,180,3,77,0, +180,3,50,0,180, +3,112,0,180,3, +85,0,180,3,120, +0,180,3,66,0, +180,3,101,0,180, +3,74,0,180,3, +109,0,180,3,82, +0,180,3,55,0, +180,3,117,0,180, +3,90,0,180,3, +98,0,180,3,71, +0,180,3,106,0, +180,3,79,0,180, +3,52,0,180,3, +114,0,180,3,87, +0,180,3,122,0, +180,3,95,0,180, +3,68,0,180,3, +103,0,180,3,76, +0,180,3,49,0, +180,3,111,0,180, +3,84,0,180,3, +57,0,180,3,119, +0,180,3,65,0, +180,3,100,0,180, +3,73,0,180,3, +108,0,180,3,81, +0,180,3,54,0, +180,3,116,0,180, +3,89,0,180,285, +11,1,867,0,183, +1,-1,3,82,0, +180,3,55,0,180, +3,117,0,180,3, +90,0,180,3,98, +0,180,3,71,0, +180,3,106,0,180, +3,79,0,180,3, +52,0,180,3,114, +0,180,3,87,0, +180,3,122,0,180, +3,95,0,180,3, +68,0,180,3,103, +0,180,3,76,0, +180,3,49,0,180, +3,111,0,180,3, +84,0,180,3,57, +0,180,3,119,0, +180,3,65,0,180, +3,100,0,180,3, +73,0,180,3,108, +0,180,3,81,0, +180,3,54,0,180, +3,116,0,180,3, +89,0,180,286,11, +1,867,0,183,1, +-1,3,87,0,180, +3,122,0,180,3, +95,0,180,3,68, +0,180,3,103,0, +180,3,76,0,180, +3,49,0,180,3, +111,0,180,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,180,3,73, +0,180,3,108,0, +180,3,81,0,180, +3,54,0,180,3, +116,0,180,3,89, +0,180,287,11,1, +867,0,183,1,-1, +3,74,0,180,3, +109,0,180,3,82, +0,180,3,55,0, +180,3,117,0,180, +3,90,0,180,3, +98,0,180,3,71, +0,180,3,106,0, +180,3,79,0,180, +3,52,0,180,3, +114,0,180,3,87, +0,180,3,122,0, +180,3,95,0,180, +3,68,0,180,3, +103,0,180,3,76, +0,180,3,49,0, +180,3,111,0,180, +3,84,0,180,3, +57,0,180,3,119, +0,180,3,65,0, +180,3,100,0,180, +3,73,0,180,3, +108,0,180,3,81, +0,180,3,54,0, +180,3,116,0,180, +3,89,0,180,288, +11,1,867,0,183, +1,-1,3,85,0, +180,3,120,0,180, +3,66,0,180,3, +101,0,180,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +180,3,87,0,180, +3,122,0,180,3, +95,0,180,3,68, +0,180,3,103,0, +180,3,76,0,180, +3,49,0,180,3, +111,0,180,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,180,3,73, +0,180,3,108,0, +180,3,81,0,180, +3,54,0,180,3, +116,0,180,3,89, +0,180,289,11,1, +867,0,183,1,-1, +3,68,0,180,3, +103,0,180,3,76, +0,180,3,49,0, +180,3,111,0,180, +3,84,0,180,3, +57,0,180,3,119, +0,180,3,65,0, +180,3,100,0,180, +3,73,0,180,3, +108,0,180,3,81, +0,180,3,54,0, +180,3,116,0,180, +3,89,0,180,290, +11,1,867,0,183, +1,-1,3,74,0, +180,3,109,0,180, +3,82,0,180,3, +55,0,180,3,117, +0,180,3,90,0, +180,3,98,0,180, +3,71,0,180,3, +106,0,180,3,79, +0,180,3,52,0, +180,3,114,0,180, +3,87,0,180,3, +122,0,180,3,95, +0,180,3,68,0, +180,3,103,0,180, +3,76,0,180,3, +49,0,180,3,111, +0,180,3,84,0, +180,3,57,0,180, +3,119,0,180,3, +65,0,180,3,100, +0,180,3,73,0, +180,3,108,0,180, +3,81,0,180,3, +54,0,180,3,116, +0,180,3,89,0, +180,291,11,1,867, +0,183,1,-1,3, +82,0,180,3,55, +0,180,3,117,0, +180,3,90,0,180, +3,98,0,180,3, +71,0,180,3,106, +0,180,3,79,0, +180,3,52,0,180, +3,114,0,180,3, +87,0,180,3,122, +0,180,3,95,0, +180,3,68,0,180, +3,103,0,180,3, +76,0,180,3,49, +0,180,3,111,0, +180,3,84,0,180, +3,57,0,180,3, +119,0,180,3,65, +0,180,3,100,0, +180,3,73,0,180, +3,108,0,180,3, +81,0,180,3,54, +0,180,3,116,0, +180,3,89,0,180, +292,11,1,867,0, +183,1,-1,3,78, +0,180,3,51,0, +180,3,113,0,180, +3,86,0,180,3, +121,0,180,3,67, +0,180,3,102,0, +180,3,75,0,180, +3,48,0,180,3, +110,0,180,3,83, +0,180,3,56,0, +180,3,118,0,180, +3,99,0,180,3, +72,0,180,3,107, +0,180,3,80,0, +180,3,53,0,180, +3,115,0,180,3, +88,0,180,3,69, +0,180,3,104,0, +180,3,77,0,180, +3,50,0,180,3, +112,0,180,3,85, +0,180,3,120,0, +180,3,66,0,180, +3,101,0,180,3, +74,0,180,3,109, +0,180,3,82,0, +180,3,55,0,180, +3,117,0,180,3, +90,0,180,3,98, +0,180,3,71,0, +180,3,106,0,180, +3,79,0,180,3, +52,0,180,3,114, +0,180,3,87,0, +180,3,122,0,180, +3,95,0,180,3, +68,0,180,3,103, +0,180,3,76,0, +180,3,49,0,180, +3,111,0,180,3, +84,0,180,3,57, +0,180,3,119,0, +180,3,65,0,180, +3,100,0,180,3, +73,0,180,3,108, +0,180,3,81,0, +180,3,54,0,180, +3,116,0,180,3, +89,0,180,293,11, +1,867,0,183,1, +-1,3,89,0,180, +294,11,1,867,0, +183,1,-1,3,68, +0,180,3,103,0, +180,3,76,0,180, +3,49,0,180,3, +111,0,180,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,180,3,73, +0,180,3,108,0, +180,3,81,0,180, +3,54,0,180,3, +116,0,180,3,89, +0,180,295,11,1, +867,0,183,1,-1, +3,83,0,180,3, +56,0,180,3,118, +0,180,3,99,0, +180,3,72,0,180, +3,107,0,180,3, +80,0,180,3,53, +0,180,3,115,0, +180,3,88,0,180, +3,69,0,180,3, +104,0,180,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,180,3,66, +0,180,3,101,0, +180,3,74,0,180, +3,109,0,180,3, +82,0,180,3,55, +0,180,3,117,0, +180,3,90,0,180, +3,98,0,180,3, +71,0,180,3,106, +0,180,3,79,0, +180,3,52,0,180, +3,114,0,180,3, +87,0,180,3,122, +0,180,3,95,0, +180,3,68,0,180, +3,103,0,180,3, +76,0,180,3,49, +0,180,3,111,0, +180,3,84,0,180, +3,57,0,180,3, +119,0,180,3,65, +0,180,3,100,0, +180,3,73,0,180, +3,108,0,180,3, +81,0,180,3,54, +0,180,3,116,0, +180,3,89,0,180, +296,11,1,867,0, +183,1,-1,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +180,3,87,0,180, +3,122,0,180,3, +95,0,180,3,68, +0,180,3,103,0, +180,3,76,0,180, +3,49,0,180,3, +111,0,297,12,1, +34750,298,5,63,3, +97,0,180,3,70, +0,180,3,105,0, +180,3,78,0,180, +3,51,0,180,3, +113,0,180,3,86, +0,180,3,121,0, +180,3,67,0,180, +3,102,0,180,3, +75,0,180,3,48, +0,180,3,110,0, +180,3,83,0,180, +3,56,0,180,3, +118,0,180,3,99, +0,180,3,72,0, +180,3,107,0,180, +3,80,0,180,3, +53,0,180,3,115, +0,180,3,88,0, +180,3,69,0,180, +3,104,0,180,3, +77,0,180,3,50, +0,180,3,112,0, +180,3,85,0,180, +3,120,0,180,3, +66,0,180,3,101, +0,180,3,74,0, +180,3,109,0,180, +3,82,0,180,3, +55,0,180,3,117, +0,180,3,90,0, +180,3,98,0,180, +3,71,0,180,3, +106,0,180,3,79, +0,180,3,52,0, +180,3,114,0,180, +3,87,0,180,3, +122,0,180,3,95, +0,180,3,68,0, +180,3,103,0,180, +3,76,0,180,3, +49,0,180,3,111, +0,180,3,84,0, +180,3,57,0,180, +3,119,0,180,3, +65,0,180,3,100, +0,180,3,73,0, +180,3,108,0,180, +3,81,0,180,3, +54,0,180,3,116, +0,299,12,1,34843, +300,5,63,3,97, +0,301,12,1,34910, +302,5,63,3,97, +0,180,3,70,0, +180,3,105,0,180, +3,78,0,180,3, +51,0,180,3,113, +0,180,3,86,0, +180,3,121,0,180, +3,67,0,180,3, +102,0,180,3,75, +0,180,3,48,0, +180,3,110,0,180, +3,83,0,180,3, +56,0,180,3,118, +0,180,3,99,0, +180,3,72,0,180, +3,107,0,180,3, +80,0,180,3,53, +0,180,3,115,0, +180,3,88,0,180, +3,69,0,180,3, +104,0,180,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,180,3,66, +0,180,3,101,0, +180,3,74,0,180, +3,109,0,180,3, +82,0,180,3,55, +0,180,3,117,0, +180,3,90,0,180, +3,98,0,180,3, +71,0,180,3,106, +0,180,3,79,0, +180,3,52,0,180, +3,114,0,180,3, +87,0,180,3,122, +0,180,3,95,0, +180,3,68,0,180, +3,103,0,180,3, +76,0,180,3,49, +0,180,3,111,0, +180,3,84,0,180, +3,57,0,180,3, +119,0,180,3,65, +0,180,3,100,0, +180,3,73,0,180, +3,108,0,180,3, +81,0,180,3,54, +0,180,3,116,0, +303,12,1,35003,304, +5,63,3,97,0, +180,3,70,0,180, +3,105,0,305,12, +1,35071,306,5,63, +3,97,0,180,3, +70,0,180,3,105, +0,180,3,78,0, +180,3,51,0,180, +3,113,0,180,3, +86,0,180,3,121, +0,180,3,67,0, +180,3,102,0,180, +3,75,0,180,3, +48,0,180,3,110, +0,180,3,83,0, +180,3,56,0,180, +3,118,0,180,3, +99,0,180,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,180,3,88, +0,180,3,69,0, +180,3,104,0,180, +3,77,0,180,3, +50,0,180,3,112, +0,180,3,85,0, +180,3,120,0,180, +3,66,0,180,3, +101,0,180,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +180,3,87,0,180, +3,122,0,180,3, +95,0,180,3,68, +0,180,3,103,0, +180,3,76,0,180, +3,49,0,180,3, +111,0,307,12,1, +35159,308,5,63,3, +97,0,180,3,70, +0,180,3,105,0, +180,3,78,0,180, +3,51,0,180,3, +113,0,180,3,86, +0,180,3,121,0, +180,3,67,0,180, +3,102,0,180,3, +75,0,180,3,48, +0,180,3,110,0, +309,12,1,35231,310, +5,63,3,97,0, +180,3,70,0,180, +3,105,0,180,3, +78,0,180,3,51, +0,180,3,113,0, +180,3,86,0,180, +3,121,0,180,3, +67,0,180,3,102, +0,180,3,75,0, +180,3,48,0,180, +3,110,0,180,3, +83,0,180,3,56, +0,180,3,118,0, +180,3,99,0,180, +3,72,0,180,3, +107,0,180,3,80, +0,180,3,53,0, +180,3,115,0,180, +3,88,0,180,3, +69,0,180,3,104, +0,180,3,77,0, +180,3,50,0,180, +3,112,0,180,3, +85,0,180,3,120, +0,180,3,66,0, +180,3,101,0,180, +3,74,0,180,3, +109,0,180,3,82, +0,180,3,55,0, +180,3,117,0,180, +3,90,0,180,3, +98,0,180,3,71, +0,180,3,106,0, +180,3,79,0,180, +3,52,0,180,3, +114,0,180,3,87, +0,180,3,122,0, +180,3,95,0,180, +3,68,0,180,3, +103,0,180,3,76, +0,180,3,49,0, +180,3,111,0,180, +3,84,0,180,3, +57,0,180,3,119, +0,180,3,65,0, +180,3,100,0,180, +3,73,0,180,3, +108,0,180,3,81, +0,180,3,54,0, +180,3,116,0,180, +3,89,0,180,311, +11,1,330,0,312, +4,26,82,0,79, 0,84,0,65,0, -82,0,71,0,69, -0,84,0,95,0, -69,0,86,0,69, -0,78,0,84,0, -1,-1,3,117,0, -345,3,118,0,345, -3,119,0,345,3, -120,0,345,3,121, -0,345,3,122,0, -345,3,48,0,345, -3,49,0,345,3, -50,0,345,3,51, -0,345,3,52,0, -345,3,53,0,345, -3,54,0,345,3, -55,0,345,3,56, -0,345,3,57,0, -345,3,65,0,345, -3,66,0,345,3, -67,0,345,3,68, -0,345,3,69,0, -345,3,70,0,345, -3,71,0,345,3, -72,0,345,3,73, -0,345,3,74,0, -345,3,75,0,345, -3,76,0,345,3, -77,0,345,3,78, -0,345,3,79,0, -345,3,80,0,345, -3,81,0,345,3, -82,0,345,3,83, -0,345,3,84,0, -345,3,85,0,345, -3,86,0,345,3, -87,0,345,3,88, -0,345,3,89,0, -345,3,90,0,345, -3,95,0,345,3, -97,0,345,3,98, -0,345,3,99,0, -345,3,100,0,345, -3,101,0,345,3, -102,0,345,3,103, -0,345,3,104,0, -345,3,105,0,345, -3,106,0,345,3, -107,0,345,3,108, -0,345,403,11,1, -867,0,348,1,-1, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -345,3,106,0,345, -3,107,0,345,3, -108,0,345,404,11, -1,867,0,348,1, --1,3,104,0,345, -3,105,0,345,3, -106,0,345,3,107, -0,345,3,108,0, -345,405,11,1,867, -0,348,1,-1,3, -115,0,345,3,116, -0,345,3,117,0, -345,3,118,0,345, -3,119,0,345,3, -120,0,345,3,121, -0,345,3,122,0, -345,3,48,0,345, -3,49,0,345,3, -50,0,345,3,51, -0,345,3,52,0, -345,3,53,0,345, -3,54,0,345,3, -55,0,345,3,56, -0,345,3,57,0, -345,3,65,0,345, -3,66,0,345,3, -67,0,345,3,68, -0,345,3,69,0, -345,3,70,0,345, -3,71,0,345,3, -72,0,345,3,73, -0,345,3,74,0, -345,3,75,0,345, -3,76,0,345,3, -77,0,345,3,78, -0,345,3,79,0, -345,3,80,0,345, -3,81,0,345,3, -82,0,345,3,83, -0,345,3,84,0, -345,3,85,0,345, -3,86,0,345,3, -87,0,345,3,88, -0,345,3,89,0, -345,3,90,0,345, -3,95,0,345,3, -97,0,345,3,98, -0,345,3,99,0, -345,3,100,0,345, -3,101,0,345,3, -102,0,345,3,103, -0,345,3,104,0, -345,3,105,0,345, -3,106,0,345,3, -107,0,345,3,108, -0,345,406,11,1, -867,0,348,1,-1, -3,98,0,345,3, -99,0,345,3,100, -0,345,3,101,0, -345,3,102,0,345, -3,103,0,345,3, -104,0,345,3,105, -0,345,3,106,0, -345,3,107,0,345, -3,108,0,345,407, -11,1,867,0,348, -1,-1,3,117,0, -345,3,118,0,345, -3,119,0,345,3, -120,0,345,3,121, -0,345,3,122,0, -345,3,48,0,345, -3,49,0,345,3, -50,0,345,3,51, -0,345,3,52,0, -345,3,53,0,345, -3,54,0,345,3, -55,0,345,3,56, -0,345,3,57,0, -345,3,65,0,345, -3,66,0,345,3, -67,0,345,3,68, -0,345,3,69,0, -345,3,70,0,345, -3,71,0,345,3, -72,0,345,3,73, -0,345,3,74,0, -345,3,75,0,345, -3,76,0,345,3, -77,0,345,3,78, -0,345,3,79,0, -345,3,80,0,345, -3,81,0,345,3, -82,0,345,3,83, -0,345,3,84,0, -345,3,85,0,345, -3,86,0,345,3, -87,0,345,3,88, -0,345,3,89,0, -345,3,90,0,345, -3,95,0,345,3, -97,0,345,3,98, -0,345,3,99,0, -345,3,100,0,345, -3,101,0,345,3, -102,0,345,3,103, -0,345,3,104,0, -345,3,105,0,345, -3,106,0,345,3, -107,0,345,3,108, -0,345,408,11,1, -867,0,348,1,-1, -3,97,0,345,3, -98,0,345,3,99, -0,345,3,100,0, -345,3,101,0,345, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -345,3,106,0,345, -3,107,0,345,3, -108,0,345,409,11, -1,867,0,348,1, --1,3,117,0,345, -3,118,0,345,3, -119,0,345,3,120, -0,345,3,121,0, -345,3,122,0,345, -3,48,0,345,3, -49,0,345,3,50, -0,345,3,51,0, -345,3,52,0,345, -3,53,0,345,3, -54,0,345,3,55, -0,345,3,56,0, -345,3,57,0,345, -3,65,0,345,3, -66,0,345,3,67, -0,345,3,68,0, -345,3,69,0,345, -3,70,0,345,3, -71,0,345,3,72, -0,345,3,73,0, -345,3,74,0,345, -3,75,0,345,3, -76,0,345,3,77, -0,345,3,78,0, -345,3,79,0,345, -3,80,0,345,3, -81,0,345,3,82, -0,345,3,83,0, -345,3,84,0,345, -3,85,0,345,3, -86,0,345,3,87, -0,345,3,88,0, -345,3,89,0,345, -3,90,0,345,3, -95,0,345,3,97, -0,345,3,98,0, -345,3,99,0,345, -3,100,0,345,3, -101,0,345,3,102, -0,345,3,103,0, -345,3,104,0,345, -3,105,0,345,3, -106,0,345,3,107, -0,345,3,108,0, -345,410,11,1,867, -0,348,1,-1,3, -112,0,345,3,113, -0,345,3,114,0, -345,3,115,0,345, -3,116,0,345,3, -117,0,345,3,118, -0,345,3,119,0, -345,3,120,0,345, -3,121,0,345,3, -122,0,345,3,48, -0,345,3,49,0, -345,3,50,0,345, -3,51,0,345,3, -52,0,345,3,53, -0,345,3,54,0, -345,3,55,0,345, -3,56,0,345,3, -57,0,345,3,65, -0,345,3,66,0, -345,3,67,0,345, -3,68,0,345,3, -69,0,345,3,70, -0,345,3,71,0, -345,3,72,0,345, -3,73,0,345,3, -74,0,345,3,75, -0,345,3,76,0, -345,3,77,0,345, -3,78,0,345,3, -79,0,345,3,80, -0,345,3,81,0, -345,3,82,0,345, -3,83,0,345,3, -84,0,345,3,85, -0,345,3,86,0, -345,3,87,0,345, -3,88,0,345,3, -89,0,345,3,90, -0,345,3,95,0, -345,3,97,0,345, -3,98,0,345,3, -99,0,345,3,100, -0,345,3,101,0, -345,3,102,0,345, -3,103,0,345,3, -104,0,345,3,105, -0,345,3,106,0, -345,3,107,0,345, -3,108,0,345,411, -11,1,867,0,348, -1,-1,3,115,0, -345,3,116,0,412, -12,1,24575,413,5, -63,3,109,0,345, -3,110,0,345,3, -111,0,345,3,112, -0,345,3,113,0, -345,3,114,0,345, -3,115,0,345,3, -116,0,345,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,414,12, -1,24618,415,5,63, -3,109,0,345,3, -110,0,345,3,111, -0,345,3,112,0, -345,3,113,0,345, -3,114,0,416,12, -1,24651,417,5,63, -3,109,0,345,3, -110,0,345,3,111, -0,345,3,112,0, -345,3,113,0,345, -3,114,0,345,3, -115,0,345,3,116, -0,345,3,117,0, -345,3,118,0,345, -3,119,0,345,3, -120,0,345,3,121, -0,345,3,122,0, -345,3,48,0,345, -3,49,0,345,3, -50,0,345,3,51, -0,345,3,52,0, -345,3,53,0,345, -3,54,0,345,3, -55,0,345,3,56, -0,345,3,57,0, -345,3,65,0,345, -3,66,0,345,3, -67,0,345,3,68, -0,345,3,69,0, -345,3,70,0,345, -3,71,0,345,3, -72,0,345,3,73, -0,345,3,74,0, -345,3,75,0,345, -3,76,0,345,3, -77,0,345,3,78, -0,345,3,79,0, -345,3,80,0,345, -3,81,0,345,3, -82,0,345,3,83, -0,345,3,84,0, -345,3,85,0,345, -3,86,0,345,3, -87,0,345,3,88, -0,345,3,89,0, -345,3,90,0,345, -3,95,0,345,3, -97,0,345,3,98, -0,345,3,99,0, -345,3,100,0,345, -3,101,0,345,3, -102,0,345,3,103, -0,418,12,1,24700, -419,5,63,3,109, -0,345,3,110,0, -345,3,111,0,345, -3,112,0,345,3, -113,0,345,3,114, -0,345,3,115,0, -345,3,116,0,345, -3,117,0,345,3, -118,0,345,3,119, -0,345,3,120,0, -345,3,121,0,345, -3,122,0,345,3, -48,0,345,3,49, -0,345,3,50,0, -345,3,51,0,345, -3,52,0,345,3, -53,0,345,3,54, -0,345,3,55,0, -345,3,56,0,345, -3,57,0,345,3, -65,0,345,3,66, -0,345,3,67,0, -345,3,68,0,345, -3,69,0,345,3, -70,0,345,3,71, -0,345,3,72,0, -345,3,73,0,345, -3,74,0,345,3, -75,0,345,3,76, -0,345,3,77,0, -345,3,78,0,345, -3,79,0,345,3, -80,0,345,3,81, -0,345,3,82,0, -345,3,83,0,345, -3,84,0,345,3, -85,0,345,3,86, -0,345,3,87,0, -345,3,88,0,345, -3,89,0,345,3, -90,0,345,3,95, -0,345,3,97,0, -345,3,98,0,345, -3,99,0,345,3, -100,0,345,3,101, -0,420,12,1,24747, -421,5,63,3,109, -0,345,3,110,0, -345,3,111,0,345, -3,112,0,345,3, -113,0,345,3,114, -0,345,3,115,0, -345,3,116,0,422, -12,1,24782,423,5, -63,3,109,0,345, -3,110,0,345,3, -111,0,345,3,112, -0,345,3,113,0, -345,3,114,0,345, -3,115,0,345,3, -116,0,345,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,345,3, -98,0,345,3,99, -0,345,3,100,0, -345,3,101,0,345, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -345,3,106,0,345, -3,107,0,345,3, -108,0,345,424,11, -1,367,0,425,4, -30,65,0,84,0, -95,0,84,0,65, -0,82,0,71,0, -69,0,84,0,95, -0,69,0,86,0, -69,0,78,0,84, -0,1,-1,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,345,3, -98,0,345,3,99, -0,345,3,100,0, -345,3,101,0,345, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -345,3,106,0,345, -3,107,0,345,3, -108,0,345,426,11, -1,867,0,348,1, --1,3,102,0,345, -3,103,0,345,3, -104,0,345,3,105, -0,345,3,106,0, -345,3,107,0,345, -3,108,0,345,427, -11,1,867,0,348, -1,-1,3,104,0, -345,3,105,0,345, -3,106,0,345,3, -107,0,345,3,108, -0,345,428,11,1, -867,0,348,1,-1, -3,115,0,345,3, -116,0,345,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,345,3, -98,0,345,3,99, -0,345,3,100,0, -345,3,101,0,345, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -345,3,106,0,345, -3,107,0,345,3, -108,0,345,429,11, -1,867,0,348,1, --1,3,98,0,345, -3,99,0,345,3, -100,0,345,3,101, -0,345,3,102,0, -345,3,103,0,345, -3,104,0,345,3, -105,0,345,3,106, -0,345,3,107,0, -345,3,108,0,345, -430,11,1,867,0, -348,1,-1,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,345,3, -98,0,345,3,99, -0,345,3,100,0, -345,3,101,0,345, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -345,3,106,0,345, -3,107,0,345,3, -108,0,345,431,11, -1,867,0,348,1, --1,3,97,0,345, -3,98,0,345,3, -99,0,345,3,100, -0,345,3,101,0, -345,3,102,0,345, -3,103,0,345,3, -104,0,345,3,105, -0,345,3,106,0, -345,3,107,0,345, -3,108,0,345,432, -11,1,867,0,348, -1,-1,3,117,0, -345,3,118,0,345, -3,119,0,345,3, -120,0,345,3,121, -0,345,3,122,0, -345,3,48,0,345, -3,49,0,345,3, -50,0,345,3,51, -0,345,3,52,0, -345,3,53,0,345, -3,54,0,345,3, -55,0,345,3,56, -0,345,3,57,0, -345,3,65,0,345, -3,66,0,345,3, -67,0,345,3,68, -0,345,3,69,0, -345,3,70,0,345, -3,71,0,345,3, -72,0,345,3,73, -0,345,3,74,0, -345,3,75,0,345, -3,76,0,345,3, -77,0,345,3,78, -0,345,3,79,0, -345,3,80,0,345, -3,81,0,345,3, -82,0,345,3,83, -0,345,3,84,0, -345,3,85,0,345, -3,86,0,345,3, -87,0,345,3,88, -0,345,3,89,0, -345,3,90,0,345, -3,95,0,345,3, -97,0,345,3,98, -0,345,3,99,0, -345,3,100,0,345, -3,101,0,345,3, -102,0,345,3,103, -0,345,3,104,0, -345,3,105,0,345, -3,106,0,345,3, -107,0,345,3,108, -0,345,433,11,1, -867,0,348,1,-1, -3,98,0,343,3, -99,0,434,12,1, -25501,435,5,63,3, -109,0,345,3,110, -0,345,3,111,0, -436,12,1,25531,437, -5,63,3,109,0, -345,3,110,0,438, -12,1,25560,439,5, -63,3,109,0,345, -3,110,0,345,3, -111,0,345,3,112, -0,345,3,113,0, -345,3,114,0,345, -3,115,0,345,3, -116,0,440,12,1, -25595,441,5,63,3, -109,0,345,3,110, -0,345,3,111,0, -345,3,112,0,345, -3,113,0,345,3, -114,0,442,12,1, -25628,443,5,63,3, -109,0,345,3,110, -0,345,3,111,0, -444,12,1,25658,445, -5,63,3,109,0, -345,3,110,0,345, -3,111,0,345,3, -112,0,345,3,113, -0,345,3,114,0, -345,3,115,0,345, -3,116,0,345,3, -117,0,345,3,118, -0,345,3,119,0, -345,3,120,0,345, -3,121,0,345,3, -122,0,345,3,48, -0,345,3,49,0, -345,3,50,0,345, -3,51,0,345,3, -52,0,345,3,53, -0,345,3,54,0, -345,3,55,0,345, -3,56,0,345,3, -57,0,345,3,65, -0,345,3,66,0, -345,3,67,0,345, -3,68,0,345,3, -69,0,345,3,70, -0,345,3,71,0, -345,3,72,0,345, -3,73,0,345,3, -74,0,345,3,75, -0,345,3,76,0, -345,3,77,0,345, -3,78,0,345,3, -79,0,345,3,80, -0,345,3,81,0, -345,3,82,0,345, -3,83,0,345,3, -84,0,345,3,85, -0,345,3,86,0, -345,3,87,0,345, -3,88,0,345,3, -89,0,345,3,90, -0,345,3,95,0, -345,3,97,0,345, -3,98,0,345,3, -99,0,345,3,100, -0,345,3,101,0, -345,3,102,0,345, -3,103,0,345,3, -104,0,345,3,105, -0,345,3,106,0, -345,3,107,0,345, -3,108,0,446,12, -1,25712,447,5,63, -3,109,0,345,3, -110,0,345,3,111, -0,345,3,112,0, -345,3,113,0,345, -3,114,0,345,3, -115,0,345,3,116, -0,345,3,117,0, -345,3,118,0,345, -3,119,0,345,3, -120,0,345,3,121, -0,345,3,122,0, -345,3,48,0,345, -3,49,0,345,3, -50,0,345,3,51, -0,345,3,52,0, -345,3,53,0,345, -3,54,0,345,3, -55,0,345,3,56, -0,345,3,57,0, -345,3,65,0,345, -3,66,0,345,3, -67,0,345,3,68, -0,345,3,69,0, -345,3,70,0,345, -3,71,0,345,3, -72,0,345,3,73, -0,345,3,74,0, -345,3,75,0,345, -3,76,0,345,3, -77,0,345,3,78, -0,345,3,79,0, -345,3,80,0,345, -3,81,0,345,3, -82,0,345,3,83, -0,345,3,84,0, -345,3,85,0,345, -3,86,0,345,3, -87,0,345,3,88, -0,345,3,89,0, -345,3,90,0,345, -3,95,0,345,3, -97,0,345,3,98, -0,345,3,99,0, -345,3,100,0,345, -3,101,0,345,3, -102,0,345,3,103, -0,345,3,104,0, -345,3,105,0,345, -3,106,0,345,3, -107,0,345,3,108, -0,345,448,11,1, -450,0,449,4,26, -67,0,79,0,78, -0,84,0,82,0, -79,0,76,0,95, -0,69,0,86,0, -69,0,78,0,84, -0,1,-1,450,11, -1,867,0,348,1, --1,3,112,0,345, -3,113,0,345,3, -114,0,345,3,115, -0,345,3,116,0, -345,3,117,0,345, -3,118,0,345,3, -119,0,345,3,120, -0,345,3,121,0, -345,3,122,0,345, -3,48,0,345,3, -49,0,345,3,50, -0,345,3,51,0, -345,3,52,0,345, -3,53,0,345,3, -54,0,345,3,55, -0,345,3,56,0, -345,3,57,0,345, -3,65,0,345,3, -66,0,345,3,67, -0,345,3,68,0, -345,3,69,0,345, -3,70,0,345,3, -71,0,345,3,72, -0,345,3,73,0, -345,3,74,0,345, -3,75,0,345,3, -76,0,345,3,77, -0,345,3,78,0, -345,3,79,0,345, -3,80,0,345,3, -81,0,345,3,82, -0,345,3,83,0, -345,3,84,0,345, -3,85,0,345,3, -86,0,345,3,87, -0,345,3,88,0, -345,3,89,0,345, -3,90,0,345,3, -95,0,345,3,97, -0,345,3,98,0, -345,3,99,0,345, -3,100,0,345,3, -101,0,345,3,102, -0,345,3,103,0, -345,3,104,0,345, -3,105,0,345,3, -106,0,345,3,107, -0,345,3,108,0, -345,451,11,1,867, -0,348,1,-1,3, -115,0,345,3,116, -0,345,3,117,0, -345,3,118,0,345, -3,119,0,345,3, -120,0,345,3,121, -0,345,3,122,0, -345,3,48,0,345, -3,49,0,345,3, -50,0,345,3,51, -0,345,3,52,0, -345,3,53,0,345, -3,54,0,345,3, -55,0,345,3,56, -0,345,3,57,0, -345,3,65,0,345, -3,66,0,345,3, -67,0,345,3,68, -0,345,3,69,0, -345,3,70,0,345, -3,71,0,345,3, -72,0,345,3,73, -0,345,3,74,0, -345,3,75,0,345, -3,76,0,345,3, -77,0,345,3,78, -0,345,3,79,0, -345,3,80,0,345, -3,81,0,345,3, -82,0,345,3,83, -0,345,3,84,0, -345,3,85,0,345, -3,86,0,345,3, -87,0,345,3,88, -0,345,3,89,0, -345,3,90,0,345, -3,95,0,345,3, -97,0,345,3,98, -0,345,3,99,0, -345,3,100,0,345, -3,101,0,345,3, -102,0,345,3,103, -0,345,3,104,0, -345,3,105,0,345, -3,106,0,345,3, -107,0,345,3,108, -0,345,452,11,1, -867,0,348,1,-1, -3,117,0,345,3, -118,0,345,3,119, -0,345,3,120,0, -345,3,121,0,345, -3,122,0,345,3, -48,0,345,3,49, -0,345,3,50,0, -345,3,51,0,345, -3,52,0,345,3, -53,0,345,3,54, -0,345,3,55,0, -345,3,56,0,345, -3,57,0,345,3, -65,0,345,3,66, -0,345,3,67,0, -345,3,68,0,345, -3,69,0,345,3, -70,0,345,3,71, -0,345,3,72,0, -345,3,73,0,345, -3,74,0,345,3, -75,0,345,3,76, -0,345,3,77,0, -345,3,78,0,345, -3,79,0,345,3, -80,0,345,3,81, -0,345,3,82,0, -345,3,83,0,345, -3,84,0,345,3, -85,0,345,3,86, -0,345,3,87,0, -345,3,88,0,345, -3,89,0,345,3, -90,0,345,3,95, -0,345,3,97,0, -345,3,98,0,345, -3,99,0,345,3, -100,0,345,3,101, -0,345,3,102,0, -345,3,103,0,345, -3,104,0,345,3, -105,0,345,3,106, -0,345,3,107,0, -345,3,108,0,345, -453,11,1,867,0, -348,1,-1,3,111, -0,345,3,112,0, -345,3,113,0,345, -3,114,0,345,3, -115,0,345,3,116, -0,345,3,117,0, -345,3,118,0,345, -3,119,0,345,3, -120,0,345,3,121, -0,345,3,122,0, -345,3,48,0,345, -3,49,0,345,3, -50,0,345,3,51, -0,345,3,52,0, -345,3,53,0,345, -3,54,0,345,3, -55,0,345,3,56, -0,345,3,57,0, -345,3,65,0,345, -3,66,0,345,3, -67,0,345,3,68, -0,345,3,69,0, -345,3,70,0,345, -3,71,0,345,3, -72,0,345,3,73, -0,345,3,74,0, -345,3,75,0,345, -3,76,0,345,3, -77,0,345,3,78, -0,345,3,79,0, -345,3,80,0,345, -3,81,0,345,3, -82,0,345,3,83, -0,345,3,84,0, -345,3,85,0,345, -3,86,0,345,3, -87,0,345,3,88, -0,345,3,89,0, -345,3,90,0,345, -3,95,0,345,3, -97,0,345,3,98, -0,345,3,99,0, -345,3,100,0,345, -3,101,0,345,3, -102,0,345,3,103, -0,345,3,104,0, -345,3,105,0,345, -3,106,0,345,3, -107,0,345,3,108, -0,454,12,1,26185, -455,5,63,3,109, -0,345,3,110,0, -345,3,111,0,345, -3,112,0,345,3, -113,0,345,3,114, -0,345,3,115,0, -345,3,116,0,345, -3,117,0,345,3, -118,0,345,3,119, -0,345,3,120,0, -345,3,121,0,345, -3,122,0,345,3, -48,0,345,3,49, -0,345,3,50,0, -345,3,51,0,345, -3,52,0,345,3, -53,0,345,3,54, -0,345,3,55,0, -345,3,56,0,345, -3,57,0,345,3, -65,0,345,3,66, -0,345,3,67,0, -345,3,68,0,345, -3,69,0,345,3, -70,0,345,3,71, -0,345,3,72,0, -345,3,73,0,345, -3,74,0,345,3, -75,0,345,3,76, -0,345,3,77,0, -345,3,78,0,345, -3,79,0,345,3, -80,0,345,3,81, -0,345,3,82,0, -345,3,83,0,345, -3,84,0,345,3, -85,0,345,3,86, -0,345,3,87,0, -345,3,88,0,345, -3,89,0,345,3, -90,0,345,3,95, -0,345,3,97,0, -345,3,98,0,345, -3,99,0,345,3, -100,0,345,3,101, -0,345,3,102,0, -345,3,103,0,345, -3,104,0,345,3, -105,0,345,3,106, -0,345,3,107,0, -345,3,108,0,456, -12,1,26239,457,5, -63,3,109,0,345, -3,110,0,345,3, -111,0,345,3,112, -0,345,3,113,0, -345,3,114,0,345, -3,115,0,345,3, -116,0,345,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,345,3, -98,0,345,3,99, -0,345,3,100,0, -345,3,101,0,345, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -458,12,1,26290,459, -5,63,3,109,0, -345,3,110,0,345, -3,111,0,345,3, -112,0,345,3,113, -0,345,3,114,0, -345,3,115,0,460, -12,1,26324,461,5, -63,3,109,0,345, -3,110,0,345,3, -111,0,345,3,112, -0,345,3,113,0, -345,3,114,0,345, -3,115,0,345,3, -116,0,345,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,345,3, -98,0,345,3,99, -0,345,3,100,0, -345,3,101,0,345, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -462,12,1,26375,463, -5,63,3,109,0, -345,3,110,0,345, -3,111,0,464,12, -1,26405,465,5,63, -3,109,0,345,3, -110,0,466,12,1, -26434,467,5,63,3, -109,0,345,3,110, -0,345,3,111,0, -345,3,112,0,345, -3,113,0,345,3, -114,0,345,3,115, -0,345,3,116,0, -345,3,117,0,345, -3,118,0,345,3, -119,0,345,3,120, -0,345,3,121,0, -345,3,122,0,345, -3,48,0,345,3, -49,0,345,3,50, -0,345,3,51,0, -345,3,52,0,345, -3,53,0,345,3, -54,0,345,3,55, -0,345,3,56,0, -345,3,57,0,345, -3,65,0,345,3, -66,0,345,3,67, -0,345,3,68,0, -345,3,69,0,345, -3,70,0,345,3, -71,0,345,3,72, -0,345,3,73,0, -345,3,74,0,345, -3,75,0,345,3, -76,0,345,3,77, -0,345,3,78,0, -345,3,79,0,345, -3,80,0,345,3, -81,0,345,3,82, -0,345,3,83,0, -345,3,84,0,345, -3,85,0,345,3, -86,0,345,3,87, -0,345,3,88,0, -345,3,89,0,345, -3,90,0,345,3, -95,0,468,12,1, -26520,469,5,63,3, -109,0,345,3,110, -0,345,3,111,0, -345,3,112,0,345, -3,113,0,345,3, -114,0,345,3,115, -0,470,12,1,26554, -471,5,63,3,109, -0,345,3,110,0, -345,3,111,0,345, -3,112,0,345,3, -113,0,345,3,114, -0,345,3,115,0, -345,3,116,0,472, -12,1,26589,473,5, -63,3,109,0,345, -3,110,0,345,3, -111,0,345,3,112, -0,345,3,113,0, -345,3,114,0,345, -3,115,0,345,3, -116,0,345,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,474,12, -1,26632,475,5,63, -3,109,0,345,3, -110,0,345,3,111, -0,345,3,112,0, -345,3,113,0,345, -3,114,0,476,12, -1,26665,477,5,63, -3,109,0,345,3, -110,0,345,3,111, -0,345,3,112,0, -345,3,113,0,345, -3,114,0,345,3, -115,0,345,3,116, -0,478,12,1,26700, -479,5,63,3,109, -0,345,3,110,0, -345,3,111,0,345, -3,112,0,345,3, -113,0,345,3,114, -0,345,3,115,0, -345,3,116,0,345, -3,117,0,345,3, -118,0,345,3,119, -0,345,3,120,0, -345,3,121,0,345, -3,122,0,345,3, -48,0,345,3,49, -0,345,3,50,0, -345,3,51,0,345, -3,52,0,345,3, -53,0,345,3,54, -0,345,3,55,0, -345,3,56,0,345, -3,57,0,345,3, -65,0,345,3,66, -0,345,3,67,0, -345,3,68,0,345, -3,69,0,345,3, -70,0,345,3,71, -0,345,3,72,0, -345,3,73,0,345, -3,74,0,345,3, -75,0,345,3,76, -0,345,3,77,0, -345,3,78,0,345, -3,79,0,345,3, -80,0,345,3,81, -0,345,3,82,0, -345,3,83,0,345, -3,84,0,345,3, -85,0,345,3,86, -0,345,3,87,0, -345,3,88,0,345, -3,89,0,345,3, -90,0,345,3,95, -0,345,3,97,0, -345,3,98,0,345, -3,99,0,345,3, -100,0,345,3,101, -0,345,3,102,0, -345,3,103,0,345, -3,104,0,345,3, -105,0,345,3,106, -0,345,3,107,0, -345,3,108,0,345, -480,11,1,431,0, -481,4,42,67,0, +84,0,73,0,79, +0,78,0,95,0, +84,0,89,0,80, +0,69,0,1,-1, +3,83,0,180,3, +56,0,180,3,118, +0,180,3,99,0, +180,3,72,0,180, +3,107,0,180,3, +80,0,180,3,53, +0,180,3,115,0, +180,3,88,0,180, +3,69,0,180,3, +104,0,180,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,180,3,66, +0,180,3,101,0, +180,3,74,0,180, +3,109,0,180,3, +82,0,180,3,55, +0,180,3,117,0, +180,3,90,0,180, +3,98,0,180,3, +71,0,180,3,106, +0,180,3,79,0, +180,3,52,0,180, +3,114,0,180,3, +87,0,180,3,122, +0,180,3,95,0, +180,3,68,0,180, +3,103,0,180,3, +76,0,180,3,49, +0,180,3,111,0, +180,3,84,0,180, +3,57,0,180,3, +119,0,180,3,65, +0,180,3,100,0, +180,3,73,0,180, +3,108,0,180,3, +81,0,180,3,54, +0,180,3,116,0, +180,3,89,0,180, +313,11,1,867,0, +183,1,-1,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,180,3,73, +0,180,3,108,0, +180,3,81,0,180, +3,54,0,180,3, +116,0,180,3,89, +0,180,314,11,1, +867,0,183,1,-1, +3,78,0,180,3, +51,0,180,3,113, +0,180,3,86,0, +180,3,121,0,180, +3,67,0,180,3, +102,0,180,3,75, +0,180,3,48,0, +180,3,110,0,180, +3,83,0,180,3, +56,0,180,3,118, +0,180,3,99,0, +180,3,72,0,180, +3,107,0,180,3, +80,0,180,3,53, +0,180,3,115,0, +180,3,88,0,180, +3,69,0,180,3, +104,0,180,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,180,3,66, +0,180,3,101,0, +180,3,74,0,180, +3,109,0,180,3, +82,0,180,3,55, +0,180,3,117,0, +180,3,90,0,180, +3,98,0,180,3, +71,0,180,3,106, +0,180,3,79,0, +180,3,52,0,180, +3,114,0,180,3, +87,0,180,3,122, +0,180,3,95,0, +180,3,68,0,180, +3,103,0,180,3, +76,0,180,3,49, +0,180,3,111,0, +180,3,84,0,180, +3,57,0,180,3, +119,0,180,3,65, +0,180,3,100,0, +180,3,73,0,180, +3,108,0,180,3, +81,0,180,3,54, +0,180,3,116,0, +180,3,89,0,180, +315,11,1,867,0, +183,1,-1,3,89, +0,180,316,11,1, +867,0,183,1,-1, +3,70,0,180,3, +105,0,180,3,78, +0,180,3,51,0, +180,3,113,0,180, +3,86,0,180,3, +121,0,180,3,67, +0,180,3,102,0, +180,3,75,0,180, +3,48,0,180,3, +110,0,180,3,83, +0,180,3,56,0, +180,3,118,0,180, +3,99,0,180,3, +72,0,180,3,107, +0,180,3,80,0, +180,3,53,0,180, +3,115,0,180,3, +88,0,180,3,69, +0,180,3,104,0, +180,3,77,0,180, +3,50,0,180,3, +112,0,180,3,85, +0,180,3,120,0, +180,3,66,0,180, +3,101,0,180,3, +74,0,180,3,109, +0,180,3,82,0, +180,3,55,0,180, +3,117,0,180,3, +90,0,180,3,98, +0,180,3,71,0, +180,3,106,0,180, +3,79,0,180,3, +52,0,180,3,114, +0,180,3,87,0, +180,3,122,0,180, +3,95,0,180,3, +68,0,180,3,103, +0,180,3,76,0, +180,3,49,0,180, +3,111,0,180,3, +84,0,180,3,57, +0,180,3,119,0, +180,3,65,0,180, +3,100,0,180,3, +73,0,180,3,108, +0,180,3,81,0, +180,3,54,0,180, +3,116,0,180,3, +89,0,180,317,11, +1,867,0,183,1, +-1,3,89,0,180, +318,11,1,867,0, +183,1,-1,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,180,3,73, +0,180,3,108,0, +180,3,81,0,180, +3,54,0,180,3, +116,0,180,3,89, +0,180,319,11,1, +867,0,183,1,-1, +3,74,0,178,3, +34,0,320,12,1, +6998,321,5,0,322, +11,1,963,0,165, +1,-1,3,111,0, +323,12,1,35625,324, +5,63,3,97,0, +180,3,70,0,180, +3,105,0,180,3, +78,0,180,3,51, +0,180,3,113,0, +180,3,86,0,180, +3,121,0,180,3, +67,0,180,3,102, +0,180,3,75,0, +180,3,48,0,180, +3,110,0,325,12, +1,35697,326,5,63, +3,97,0,180,3, +70,0,180,3,105, +0,180,3,78,0, +180,3,51,0,180, +3,113,0,180,3, +86,0,180,3,121, +0,180,3,67,0, +180,3,102,0,180, +3,75,0,180,3, +48,0,180,3,110, +0,180,3,83,0, +180,3,56,0,180, +3,118,0,180,3, +99,0,180,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,180,3,88, +0,180,3,69,0, +180,3,104,0,180, +3,77,0,180,3, +50,0,180,3,112, +0,180,3,85,0, +180,3,120,0,180, +3,66,0,180,3, +101,0,180,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +180,3,87,0,180, +3,122,0,180,3, +95,0,327,12,1, +35733,328,5,63,3, +97,0,180,3,70, +0,180,3,105,0, +180,3,78,0,180, +3,51,0,180,3, +113,0,180,3,86, +0,180,3,121,0, +180,3,67,0,180, +3,102,0,180,3, +75,0,180,3,48, +0,180,3,110,0, +180,3,83,0,180, +3,56,0,180,3, +118,0,180,3,99, +0,180,3,72,0, +180,3,107,0,180, +3,80,0,180,3, +53,0,180,3,115, +0,180,3,88,0, +180,3,69,0,180, +3,104,0,180,3, +77,0,180,3,50, +0,180,3,112,0, +180,3,85,0,180, +3,120,0,180,3, +66,0,180,3,101, +0,180,3,74,0, +180,3,109,0,180, +3,82,0,180,3, +55,0,180,3,117, +0,180,3,90,0, +180,3,98,0,180, +3,71,0,180,3, +106,0,180,3,79, +0,180,3,52,0, +180,3,114,0,329, +12,1,35818,330,5, +63,3,97,0,180, +3,70,0,180,3, +105,0,180,3,78, +0,180,3,51,0, +180,3,113,0,180, +3,86,0,180,3, +121,0,180,3,67, +0,180,3,102,0, +180,3,75,0,180, +3,48,0,180,3, +110,0,180,3,83, +0,180,3,56,0, +180,3,118,0,180, +3,99,0,180,3, +72,0,180,3,107, +0,180,3,80,0, +180,3,53,0,180, +3,115,0,180,3, +88,0,180,3,69, +0,180,3,104,0, +180,3,77,0,180, +3,50,0,180,3, +112,0,180,3,85, +0,180,3,120,0, +180,3,66,0,180, +3,101,0,331,12, +1,35898,332,5,63, +3,97,0,180,3, +70,0,180,3,105, +0,180,3,78,0, +180,3,51,0,180, +3,113,0,180,3, +86,0,180,3,121, +0,180,3,67,0, +180,3,102,0,180, +3,75,0,180,3, +48,0,180,3,110, +0,180,3,83,0, +180,3,56,0,180, +3,118,0,180,3, +99,0,180,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,180,3,88, +0,180,3,69,0, +180,3,104,0,180, +3,77,0,180,3, +50,0,180,3,112, +0,180,3,85,0, +180,3,120,0,180, +3,66,0,180,3, +101,0,180,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +180,3,87,0,180, +3,122,0,333,12, +1,35984,334,5,63, +3,97,0,180,3, +70,0,180,3,105, +0,180,3,78,0, +180,3,51,0,180, +3,113,0,180,3, +86,0,180,3,121, +0,180,3,67,0, +180,3,102,0,180, +3,75,0,180,3, +48,0,180,3,110, +0,180,3,83,0, +180,3,56,0,180, +3,118,0,180,3, +99,0,180,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,180,3,88, +0,180,3,69,0, +180,3,104,0,180, +3,77,0,180,3, +50,0,180,3,112, +0,180,3,85,0, +180,3,120,0,180, +3,66,0,180,3, +101,0,180,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +180,3,87,0,180, +3,122,0,180,3, +95,0,180,3,68, +0,180,3,103,0, +180,3,76,0,180, +3,49,0,180,3, +111,0,180,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,180,3,73, +0,180,3,108,0, +180,3,81,0,180, +3,54,0,180,3, +116,0,180,3,89, +0,180,335,11,1, +695,0,336,4,24, +79,0,78,0,95, +0,82,0,69,0, +90,0,95,0,69, +0,86,0,69,0, +78,0,84,0,1, +-1,3,95,0,180, +3,68,0,180,3, +103,0,180,3,76, +0,180,3,49,0, +180,3,111,0,180, +3,84,0,180,3, +57,0,180,3,119, +0,180,3,65,0, +180,3,100,0,180, +3,73,0,180,3, +108,0,180,3,81, +0,180,3,54,0, +180,3,116,0,180, +3,89,0,180,337, +11,1,867,0,183, +1,-1,3,74,0, +180,3,109,0,180, +3,82,0,180,3, +55,0,180,3,117, +0,180,3,90,0, +180,3,98,0,180, +3,71,0,180,3, +106,0,180,3,79, +0,180,3,52,0, +180,3,114,0,180, +3,87,0,180,3, +122,0,180,3,95, +0,180,3,68,0, +180,3,103,0,180, +3,76,0,180,3, +49,0,180,3,111, +0,180,3,84,0, +180,3,57,0,180, +3,119,0,180,3, +65,0,180,3,100, +0,180,3,73,0, +180,3,108,0,180, +3,81,0,180,3, +54,0,180,3,116, +0,180,3,89,0, +180,338,11,1,867, +0,183,1,-1,3, +87,0,180,3,122, +0,180,3,95,0, +180,3,68,0,180, +3,103,0,180,3, +76,0,180,3,49, +0,180,3,111,0, +180,3,84,0,180, +3,57,0,180,3, +119,0,180,3,65, +0,180,3,100,0, +180,3,73,0,180, +3,108,0,180,3, +81,0,180,3,54, +0,180,3,116,0, +180,3,89,0,180, +339,11,1,867,0, +183,1,-1,3,68, +0,180,3,103,0, +180,3,76,0,180, +3,49,0,180,3, +111,0,180,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,180,3,73, +0,180,3,108,0, +180,3,81,0,180, +3,54,0,180,3, +116,0,180,3,89, +0,180,340,11,1, +867,0,183,1,-1, +3,83,0,180,3, +56,0,180,3,118, +0,180,3,99,0, +180,3,72,0,180, +3,107,0,180,3, +80,0,180,3,53, +0,180,3,115,0, +180,3,88,0,180, +3,69,0,180,3, +104,0,180,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,180,3,66, +0,180,3,101,0, +180,3,74,0,180, +3,109,0,180,3, +82,0,180,3,55, +0,180,3,117,0, +180,3,90,0,180, +3,98,0,341,12, +1,36308,342,5,63, +3,97,0,180,3, +70,0,180,3,105, +0,180,3,78,0, +180,3,51,0,180, +3,113,0,180,3, +86,0,180,3,121, +0,180,3,67,0, +180,3,102,0,180, +3,75,0,180,3, +48,0,180,3,110, +0,180,3,83,0, +180,3,56,0,180, +3,118,0,180,3, +99,0,180,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,180,3,88, +0,180,3,69,0, +180,3,104,0,180, +3,77,0,180,3, +50,0,180,3,112, +0,180,3,85,0, +180,3,120,0,180, +3,66,0,180,3, +101,0,180,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,343,12, +1,36392,344,5,63, +3,97,0,180,3, +70,0,180,3,105, +0,180,3,78,0, +180,3,51,0,180, +3,113,0,180,3, +86,0,180,3,121, +0,180,3,67,0, +180,3,102,0,180, +3,75,0,180,3, +48,0,180,3,110, +0,180,3,83,0, +180,3,56,0,180, +3,118,0,180,3, +99,0,180,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,180,3,88, +0,180,3,69,0, +180,3,104,0,180, +3,77,0,180,3, +50,0,180,3,112, +0,180,3,85,0, +180,3,120,0,180, +3,66,0,180,3, +101,0,345,12,1, +36472,346,5,63,3, +97,0,180,3,70, +0,180,3,105,0, +180,3,78,0,180, +3,51,0,180,3, +113,0,180,3,86, +0,180,3,121,0, +180,3,67,0,180, +3,102,0,180,3, +75,0,180,3,48, +0,180,3,110,0, +180,3,83,0,180, +3,56,0,180,3, +118,0,180,3,99, +0,347,12,1,36546, +348,5,63,3,97, +0,180,3,70,0, +180,3,105,0,180, +3,78,0,180,3, +51,0,180,3,113, +0,180,3,86,0, +180,3,121,0,180, +3,67,0,180,3, +102,0,180,3,75, +0,180,3,48,0, +180,3,110,0,180, +3,83,0,180,3, +56,0,180,3,118, +0,180,3,99,0, +180,3,72,0,180, +3,107,0,180,3, +80,0,180,3,53, +0,180,3,115,0, +180,3,88,0,180, +3,69,0,180,3, +104,0,180,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,180,3,66, +0,180,3,101,0, +180,3,74,0,180, +3,109,0,180,3, +82,0,180,3,55, +0,180,3,117,0, +180,3,90,0,180, +3,98,0,180,3, +71,0,180,3,106, +0,180,3,79,0, +180,3,52,0,180, +3,114,0,180,3, +87,0,180,3,122, +0,180,3,95,0, +180,3,68,0,180, +3,103,0,180,3, +76,0,180,3,49, +0,180,3,111,0, +180,3,84,0,180, +3,57,0,180,3, +119,0,180,3,65, +0,180,3,100,0, +180,3,73,0,180, +3,108,0,180,3, +81,0,180,3,54, +0,180,3,116,0, +349,12,1,36639,350, +5,63,3,97,0, +180,3,70,0,180, +3,105,0,180,3, +78,0,180,3,51, +0,180,3,113,0, +180,3,86,0,180, +3,121,0,180,3, +67,0,180,3,102, +0,180,3,75,0, +180,3,48,0,180, +3,110,0,180,3, +83,0,180,3,56, +0,180,3,118,0, +180,3,99,0,180, +3,72,0,180,3, +107,0,180,3,80, +0,180,3,53,0, +180,3,115,0,180, +3,88,0,180,3, +69,0,180,3,104, +0,180,3,77,0, +180,3,50,0,180, +3,112,0,180,3, +85,0,180,3,120, +0,180,3,66,0, +180,3,101,0,180, +3,74,0,180,3, +109,0,180,3,82, +0,180,3,55,0, +180,3,117,0,180, +3,90,0,180,3, +98,0,180,3,71, +0,180,3,106,0, +180,3,79,0,180, +3,52,0,180,3, +114,0,180,3,87, +0,180,3,122,0, +180,3,95,0,351, +12,1,36675,352,5, +63,3,97,0,180, +3,70,0,180,3, +105,0,180,3,78, +0,180,3,51,0, +180,3,113,0,180, +3,86,0,180,3, +121,0,180,3,67, +0,180,3,102,0, +180,3,75,0,180, +3,48,0,180,3, +110,0,180,3,83, +0,180,3,56,0, +180,3,118,0,180, +3,99,0,180,3, +72,0,180,3,107, +0,180,3,80,0, +180,3,53,0,180, +3,115,0,180,3, +88,0,180,3,69, +0,180,3,104,0, +180,3,77,0,180, +3,50,0,180,3, +112,0,180,3,85, +0,180,3,120,0, +180,3,66,0,180, +3,101,0,180,3, +74,0,180,3,109, +0,180,3,82,0, +180,3,55,0,180, +3,117,0,180,3, +90,0,180,3,98, +0,180,3,71,0, +180,3,106,0,180, +3,79,0,180,3, +52,0,180,3,114, +0,353,12,1,36760, +354,5,63,3,97, +0,180,3,70,0, +180,3,105,0,180, +3,78,0,180,3, +51,0,180,3,113, +0,180,3,86,0, +180,3,121,0,180, +3,67,0,180,3, +102,0,180,3,75, +0,180,3,48,0, +180,3,110,0,180, +3,83,0,180,3, +56,0,180,3,118, +0,180,3,99,0, +180,3,72,0,180, +3,107,0,180,3, +80,0,180,3,53, +0,180,3,115,0, +180,3,88,0,180, +3,69,0,180,3, +104,0,180,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,180,3,66, +0,180,3,101,0, +355,12,1,36840,356, +5,63,3,97,0, +180,3,70,0,180, +3,105,0,180,3, +78,0,180,3,51, +0,180,3,113,0, +180,3,86,0,180, +3,121,0,180,3, +67,0,180,3,102, +0,180,3,75,0, +180,3,48,0,180, +3,110,0,180,3, +83,0,180,3,56, +0,180,3,118,0, +180,3,99,0,180, +3,72,0,180,3, +107,0,180,3,80, +0,180,3,53,0, +180,3,115,0,180, +3,88,0,180,3, +69,0,180,3,104, +0,180,3,77,0, +180,3,50,0,180, +3,112,0,180,3, +85,0,180,3,120, +0,180,3,66,0, +180,3,101,0,180, +3,74,0,180,3, +109,0,180,3,82, +0,180,3,55,0, +180,3,117,0,180, +3,90,0,180,3, +98,0,180,3,71, +0,180,3,106,0, +180,3,79,0,180, +3,52,0,180,3, +114,0,180,3,87, +0,180,3,122,0, +357,12,1,36926,358, +5,63,3,97,0, +180,3,70,0,180, +3,105,0,180,3, +78,0,180,3,51, +0,180,3,113,0, +180,3,86,0,180, +3,121,0,180,3, +67,0,180,3,102, +0,180,3,75,0, +180,3,48,0,180, +3,110,0,180,3, +83,0,180,3,56, +0,180,3,118,0, +180,3,99,0,180, +3,72,0,180,3, +107,0,180,3,80, +0,180,3,53,0, +180,3,115,0,180, +3,88,0,180,3, +69,0,180,3,104, +0,180,3,77,0, +180,3,50,0,180, +3,112,0,180,3, +85,0,180,3,120, +0,180,3,66,0, +180,3,101,0,180, +3,74,0,180,3, +109,0,180,3,82, +0,180,3,55,0, +180,3,117,0,180, +3,90,0,180,3, +98,0,180,3,71, +0,180,3,106,0, +180,3,79,0,180, +3,52,0,180,3, +114,0,180,3,87, +0,180,3,122,0, +180,3,95,0,180, +3,68,0,180,3, +103,0,180,3,76, +0,180,3,49,0, +180,3,111,0,180, +3,84,0,180,3, +57,0,180,3,119, +0,180,3,65,0, +180,3,100,0,180, +3,73,0,180,3, +108,0,180,3,81, +0,180,3,54,0, +180,3,116,0,180, +3,89,0,180,359, +11,1,681,0,360, +4,32,79,0,66, +0,74,0,69,0, +67,0,84,0,95, +0,82,0,69,0, +90,0,95,0,69, +0,86,0,69,0, +78,0,84,0,1, +-1,3,95,0,180, +3,68,0,180,3, +103,0,180,3,76, +0,180,3,49,0, +180,3,111,0,180, +3,84,0,180,3, +57,0,180,3,119, +0,180,3,65,0, +180,3,100,0,180, +3,73,0,180,3, +108,0,180,3,81, +0,180,3,54,0, +180,3,116,0,180, +3,89,0,180,361, +11,1,867,0,183, +1,-1,3,74,0, +180,3,109,0,180, +3,82,0,180,3, +55,0,180,3,117, +0,180,3,90,0, +180,3,98,0,180, +3,71,0,180,3, +106,0,180,3,79, +0,180,3,52,0, +180,3,114,0,180, +3,87,0,180,3, +122,0,180,3,95, +0,180,3,68,0, +180,3,103,0,180, +3,76,0,180,3, +49,0,180,3,111, +0,180,3,84,0, +180,3,57,0,180, +3,119,0,180,3, +65,0,180,3,100, +0,180,3,73,0, +180,3,108,0,180, +3,81,0,180,3, +54,0,180,3,116, +0,180,3,89,0, +180,362,11,1,867, +0,183,1,-1,3, +87,0,180,3,122, +0,180,3,95,0, +180,3,68,0,180, +3,103,0,180,3, +76,0,180,3,49, +0,180,3,111,0, +180,3,84,0,180, +3,57,0,180,3, +119,0,180,3,65, +0,180,3,100,0, +180,3,73,0,180, +3,108,0,180,3, +81,0,180,3,54, +0,180,3,116,0, +180,3,89,0,180, +363,11,1,867,0, +183,1,-1,3,68, +0,180,3,103,0, +180,3,76,0,180, +3,49,0,180,3, +111,0,180,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,180,3,73, +0,180,3,108,0, +180,3,81,0,180, +3,54,0,180,3, +116,0,180,3,89, +0,180,364,11,1, +867,0,183,1,-1, +3,89,0,180,365, +11,1,867,0,183, +1,-1,3,72,0, +180,3,107,0,180, +3,80,0,180,3, +53,0,180,3,115, +0,180,3,88,0, +180,3,69,0,180, +3,104,0,180,3, +77,0,180,3,50, +0,180,3,112,0, +180,3,85,0,180, +3,120,0,180,3, +66,0,180,3,101, +0,180,3,74,0, +180,3,109,0,180, +3,82,0,180,3, +55,0,180,3,117, +0,180,3,90,0, +180,3,98,0,180, +3,71,0,180,3, +106,0,180,3,79, +0,180,3,52,0, +180,3,114,0,180, +3,87,0,180,3, +122,0,180,3,95, +0,180,3,68,0, +180,3,103,0,180, +3,76,0,180,3, +49,0,180,3,111, +0,180,3,84,0, +180,3,57,0,180, +3,119,0,180,3, +65,0,180,3,100, +0,180,3,73,0, +180,3,108,0,180, +3,81,0,180,3, +54,0,180,3,116, +0,180,3,89,0, +180,366,11,1,867, +0,183,1,-1,3, +74,0,180,3,109, +0,180,3,82,0, +180,3,55,0,180, +3,117,0,180,3, +90,0,180,3,98, +0,180,3,71,0, +180,3,106,0,180, +3,79,0,180,3, +52,0,180,3,114, +0,180,3,87,0, +180,3,122,0,180, +3,95,0,180,3, +68,0,180,3,103, +0,180,3,76,0, +180,3,49,0,180, +3,111,0,180,3, +84,0,180,3,57, +0,180,3,119,0, +180,3,65,0,180, +3,100,0,180,3, +73,0,180,3,108, +0,180,3,81,0, +180,3,54,0,180, +3,116,0,180,3, +89,0,180,367,11, +1,867,0,183,1, +-1,3,79,0,180, +3,52,0,180,3, +114,0,180,3,87, +0,180,3,122,0, +180,3,95,0,180, +3,68,0,180,3, +103,0,180,3,76, +0,180,3,49,0, +180,3,111,0,180, +3,84,0,180,3, +57,0,180,3,119, +0,180,3,65,0, +180,3,100,0,180, +3,73,0,180,3, +108,0,180,3,81, +0,180,3,54,0, +180,3,116,0,180, +3,89,0,180,368, +11,1,867,0,183, +1,-1,3,71,0, +180,3,106,0,180, +3,79,0,180,3, +52,0,180,3,114, +0,180,3,87,0, +180,3,122,0,180, +3,95,0,180,3, +68,0,180,3,103, +0,180,3,76,0, +180,3,49,0,180, +3,111,0,180,3, +84,0,180,3,57, +0,180,3,119,0, +180,3,65,0,180, +3,100,0,180,3, +73,0,180,3,108, +0,180,3,81,0, +180,3,54,0,180, +3,116,0,180,3, +89,0,180,369,11, +1,867,0,183,1, +-1,3,71,0,178, +3,108,0,370,12, +1,40068,371,5,63, +3,97,0,372,12, +1,40135,373,5,63, +3,97,0,180,3, +70,0,180,3,105, +0,180,3,78,0, +180,3,51,0,180, +3,113,0,180,3, +86,0,180,3,121, +0,180,3,67,0, +180,3,102,0,180, +3,75,0,180,3, +48,0,180,3,110, +0,374,12,1,40207, +375,5,63,3,97, +0,180,3,70,0, +180,3,105,0,180, +3,78,0,180,3, +51,0,180,3,113, +0,180,3,86,0, +180,3,121,0,180, +3,67,0,180,3, +102,0,180,3,75, +0,180,3,48,0, +180,3,110,0,180, +3,83,0,180,3, +56,0,180,3,118, +0,180,3,99,0, +180,3,72,0,180, +3,107,0,180,3, +80,0,180,3,53, +0,180,3,115,0, +180,3,88,0,180, +3,69,0,180,3, +104,0,180,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,180,3,66, +0,180,3,101,0, +180,3,74,0,180, +3,109,0,180,3, +82,0,180,3,55, +0,180,3,117,0, +180,3,90,0,180, +3,98,0,180,3, +71,0,180,3,106, +0,180,3,79,0, +180,3,52,0,180, +3,114,0,180,3, +87,0,180,3,122, +0,180,3,95,0, +180,3,68,0,180, +3,103,0,180,3, +76,0,180,3,49, +0,180,3,111,0, +180,3,84,0,180, +3,57,0,180,3, +119,0,180,3,65, +0,180,3,100,0, +376,12,1,40297,377, +5,63,3,97,0, +180,3,70,0,180, +3,105,0,180,3, +78,0,180,3,51, +0,180,3,113,0, +180,3,86,0,180, +3,121,0,180,3, +67,0,180,3,102, +0,180,3,75,0, +180,3,48,0,180, +3,110,0,180,3, +83,0,180,3,56, +0,180,3,118,0, +180,3,99,0,180, +3,72,0,180,3, +107,0,180,3,80, +0,180,3,53,0, +180,3,115,0,180, +3,88,0,180,3, +69,0,180,3,104, +0,180,3,77,0, +180,3,50,0,180, +3,112,0,180,3, +85,0,180,3,120, +0,180,3,66,0, +180,3,101,0,180, +3,74,0,180,3, +109,0,180,3,82, +0,180,3,55,0, +180,3,117,0,180, +3,90,0,180,3, +98,0,180,3,71, +0,180,3,106,0, +180,3,79,0,180, +3,52,0,180,3, +114,0,180,3,87, +0,180,3,122,0, +180,3,95,0,378, +12,1,40333,379,5, +63,3,97,0,180, +3,70,0,180,3, +105,0,180,3,78, +0,180,3,51,0, +180,3,113,0,180, +3,86,0,180,3, +121,0,180,3,67, +0,180,3,102,0, +180,3,75,0,180, +3,48,0,180,3, +110,0,180,3,83, +0,180,3,56,0, +180,3,118,0,180, +3,99,0,380,12, +1,40407,381,5,63, +3,97,0,180,3, +70,0,180,3,105, +0,180,3,78,0, +180,3,51,0,180, +3,113,0,180,3, +86,0,180,3,121, +0,180,3,67,0, +180,3,102,0,180, +3,75,0,180,3, +48,0,180,3,110, +0,180,3,83,0, +180,3,56,0,180, +3,118,0,180,3, +99,0,180,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,180,3,88, +0,180,3,69,0, +180,3,104,0,180, +3,77,0,180,3, +50,0,180,3,112, +0,180,3,85,0, +180,3,120,0,180, +3,66,0,180,3, +101,0,180,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +180,3,87,0,180, +3,122,0,180,3, +95,0,180,3,68, +0,180,3,103,0, +180,3,76,0,180, +3,49,0,180,3, +111,0,382,12,1, +40495,383,5,63,3, +97,0,180,3,70, +0,180,3,105,0, +180,3,78,0,180, +3,51,0,180,3, +113,0,180,3,86, +0,180,3,121,0, +180,3,67,0,180, +3,102,0,180,3, +75,0,180,3,48, +0,180,3,110,0, +180,3,83,0,180, +3,56,0,180,3, +118,0,180,3,99, +0,180,3,72,0, +180,3,107,0,180, +3,80,0,180,3, +53,0,180,3,115, +0,180,3,88,0, +180,3,69,0,180, +3,104,0,180,3, +77,0,180,3,50, +0,180,3,112,0, +180,3,85,0,180, +3,120,0,180,3, +66,0,180,3,101, +0,180,3,74,0, +180,3,109,0,180, +3,82,0,180,3, +55,0,180,3,117, +0,180,3,90,0, +180,3,98,0,180, +3,71,0,180,3, +106,0,180,3,79, +0,180,3,52,0, +180,3,114,0,180, +3,87,0,180,3, +122,0,180,3,95, +0,180,3,68,0, +180,3,103,0,180, +3,76,0,180,3, +49,0,180,3,111, +0,180,3,84,0, +180,3,57,0,180, +3,119,0,180,3, +65,0,180,3,100, +0,180,3,73,0, +180,3,108,0,384, +12,1,40586,385,5, +63,3,97,0,180, +3,70,0,180,3, +105,0,180,3,78, +0,180,3,51,0, +180,3,113,0,180, +3,86,0,180,3, +121,0,180,3,67, +0,180,3,102,0, +180,3,75,0,180, +3,48,0,180,3, +110,0,180,3,83, +0,180,3,56,0, +180,3,118,0,180, +3,99,0,180,3, +72,0,180,3,107, +0,180,3,80,0, +180,3,53,0,180, +3,115,0,180,3, +88,0,180,3,69, +0,180,3,104,0, +180,3,77,0,180, +3,50,0,180,3, +112,0,180,3,85, +0,180,3,120,0, +180,3,66,0,180, +3,101,0,180,3, +74,0,180,3,109, +0,180,3,82,0, +180,3,55,0,180, +3,117,0,180,3, +90,0,180,3,98, +0,180,3,71,0, +180,3,106,0,180, +3,79,0,180,3, +52,0,180,3,114, +0,180,3,87,0, +180,3,122,0,180, +3,95,0,180,3, +68,0,180,3,103, +0,180,3,76,0, +180,3,49,0,180, +3,111,0,180,3, +84,0,180,3,57, +0,180,3,119,0, +180,3,65,0,180, +3,100,0,180,3, +73,0,180,3,108, +0,386,12,1,40677, +387,5,63,3,97, +0,180,3,70,0, +180,3,105,0,388, +12,1,40745,389,5, +63,3,97,0,180, +3,70,0,180,3, +105,0,180,3,78, +0,180,3,51,0, +180,3,113,0,180, +3,86,0,180,3, +121,0,180,3,67, +0,180,3,102,0, +180,3,75,0,180, +3,48,0,180,3, +110,0,180,3,83, +0,180,3,56,0, +180,3,118,0,180, +3,99,0,180,3, +72,0,180,3,107, +0,180,3,80,0, +180,3,53,0,180, +3,115,0,390,12, +1,40821,391,5,63, +3,97,0,180,3, +70,0,180,3,105, +0,392,12,1,40889, +393,5,63,3,97, +0,180,3,70,0, +180,3,105,0,180, +3,78,0,180,3, +51,0,180,3,113, +0,180,3,86,0, +180,3,121,0,180, +3,67,0,180,3, +102,0,180,3,75, +0,180,3,48,0, +180,3,110,0,180, +3,83,0,180,3, +56,0,180,3,118, +0,180,3,99,0, +180,3,72,0,180, +3,107,0,180,3, +80,0,180,3,53, +0,180,3,115,0, +180,3,88,0,180, +3,69,0,180,3, +104,0,180,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,180,3,66, +0,180,3,101,0, +180,3,74,0,180, +3,109,0,180,3, +82,0,180,3,55, +0,180,3,117,0, +180,3,90,0,180, +3,98,0,180,3, +71,0,180,3,106, +0,180,3,79,0, +180,3,52,0,180, +3,114,0,180,3, +87,0,180,3,122, +0,180,3,95,0, +180,3,68,0,180, +3,103,0,180,3, +76,0,180,3,49, +0,180,3,111,0, +394,12,1,40977,395, +5,63,3,97,0, +180,3,70,0,180, +3,105,0,180,3, +78,0,180,3,51, +0,180,3,113,0, +180,3,86,0,180, +3,121,0,180,3, +67,0,180,3,102, +0,180,3,75,0, +180,3,48,0,180, +3,110,0,396,12, +1,41049,397,5,63, +3,97,0,180,3, +70,0,180,3,105, +0,180,3,78,0, +180,3,51,0,180, +3,113,0,180,3, +86,0,180,3,121, +0,180,3,67,0, +180,3,102,0,180, +3,75,0,180,3, +48,0,180,3,110, +0,180,3,83,0, +180,3,56,0,180, +3,118,0,180,3, +99,0,180,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,180,3,88, +0,180,3,69,0, +180,3,104,0,180, +3,77,0,180,3, +50,0,180,3,112, +0,180,3,85,0, +180,3,120,0,180, +3,66,0,180,3, +101,0,180,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +180,3,87,0,180, +3,122,0,180,3, +95,0,398,12,1, +41085,399,5,63,3, +97,0,180,3,70, +0,180,3,105,0, +180,3,78,0,180, +3,51,0,180,3, +113,0,180,3,86, +0,180,3,121,0, +180,3,67,0,180, +3,102,0,180,3, +75,0,180,3,48, +0,180,3,110,0, +180,3,83,0,180, +3,56,0,180,3, +118,0,180,3,99, +0,180,3,72,0, +180,3,107,0,180, +3,80,0,180,3, +53,0,180,3,115, +0,400,12,1,41161, +401,5,63,3,97, +0,180,3,70,0, +180,3,105,0,180, +3,78,0,180,3, +51,0,180,3,113, +0,180,3,86,0, +180,3,121,0,180, +3,67,0,180,3, +102,0,180,3,75, +0,180,3,48,0, +180,3,110,0,180, +3,83,0,180,3, +56,0,180,3,118, +0,180,3,99,0, +180,3,72,0,180, +3,107,0,180,3, +80,0,180,3,53, +0,180,3,115,0, +180,3,88,0,180, +3,69,0,180,3, +104,0,180,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,180,3,66, +0,180,3,101,0, +180,3,74,0,180, +3,109,0,180,3, +82,0,180,3,55, +0,180,3,117,0, +180,3,90,0,180, +3,98,0,180,3, +71,0,180,3,106, +0,180,3,79,0, +180,3,52,0,180, +3,114,0,180,3, +87,0,180,3,122, +0,180,3,95,0, +180,3,68,0,180, +3,103,0,180,3, +76,0,180,3,49, +0,180,3,111,0, +180,3,84,0,180, +3,57,0,180,3, +119,0,180,3,65, +0,180,3,100,0, +180,3,73,0,180, +3,108,0,180,3, +81,0,180,3,54, +0,180,3,116,0, +402,12,1,41254,403, +5,63,3,97,0, +404,12,1,41321,405, +5,63,3,97,0, +180,3,70,0,180, +3,105,0,180,3, +78,0,180,3,51, +0,180,3,113,0, +180,3,86,0,180, +3,121,0,180,3, +67,0,180,3,102, +0,180,3,75,0, +180,3,48,0,180, +3,110,0,180,3, +83,0,180,3,56, +0,180,3,118,0, +180,3,99,0,180, +3,72,0,180,3, +107,0,180,3,80, +0,180,3,53,0, +180,3,115,0,180, +3,88,0,180,3, +69,0,180,3,104, +0,180,3,77,0, +180,3,50,0,180, +3,112,0,180,3, +85,0,180,3,120, +0,180,3,66,0, +180,3,101,0,180, +3,74,0,180,3, +109,0,180,3,82, +0,180,3,55,0, +180,3,117,0,180, +3,90,0,180,3, +98,0,180,3,71, +0,180,3,106,0, +180,3,79,0,180, +3,52,0,180,3, +114,0,406,12,1, +41406,407,5,63,3, +97,0,180,3,70, +0,180,3,105,0, +180,3,78,0,180, +3,51,0,180,3, +113,0,180,3,86, +0,180,3,121,0, +180,3,67,0,180, +3,102,0,180,3, +75,0,180,3,48, +0,180,3,110,0, +180,3,83,0,180, +3,56,0,180,3, +118,0,180,3,99, +0,180,3,72,0, +180,3,107,0,180, +3,80,0,180,3, +53,0,180,3,115, +0,180,3,88,0, +180,3,69,0,180, +3,104,0,180,3, +77,0,180,3,50, +0,180,3,112,0, +180,3,85,0,180, +3,120,0,180,3, +66,0,180,3,101, +0,180,3,74,0, +180,3,109,0,180, +3,82,0,180,3, +55,0,180,3,117, +0,180,3,90,0, +180,3,98,0,180, +3,71,0,180,3, +106,0,180,3,79, +0,180,3,52,0, +180,3,114,0,180, +3,87,0,180,3, +122,0,180,3,95, +0,180,3,68,0, +180,3,103,0,180, +3,76,0,180,3, +49,0,180,3,111, +0,180,3,84,0, +180,3,57,0,180, +3,119,0,180,3, +65,0,180,3,100, +0,180,3,73,0, +180,3,108,0,180, +3,81,0,180,3, +54,0,180,3,116, +0,408,12,1,41499, +409,5,63,3,97, +0,180,3,70,0, +180,3,105,0,180, +3,78,0,180,3, +51,0,180,3,113, +0,180,3,86,0, +180,3,121,0,180, +3,67,0,180,3, +102,0,180,3,75, +0,180,3,48,0, +180,3,110,0,180, +3,83,0,180,3, +56,0,180,3,118, +0,180,3,99,0, +180,3,72,0,180, +3,107,0,180,3, +80,0,180,3,53, +0,180,3,115,0, +180,3,88,0,180, +3,69,0,180,3, +104,0,180,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,180,3,66, +0,180,3,101,0, +180,3,74,0,180, +3,109,0,180,3, +82,0,180,3,55, +0,180,3,117,0, +180,3,90,0,180, +3,98,0,180,3, +71,0,180,3,106, +0,180,3,79,0, +180,3,52,0,180, +3,114,0,180,3, +87,0,180,3,122, +0,180,3,95,0, +180,3,68,0,180, +3,103,0,180,3, +76,0,180,3,49, +0,180,3,111,0, +180,3,84,0,180, +3,57,0,180,3, +119,0,180,3,65, +0,180,3,100,0, +180,3,73,0,180, +3,108,0,180,3, +81,0,180,3,54, +0,180,3,116,0, +180,3,89,0,180, +410,11,1,541,0, +411,4,52,76,0, +65,0,78,0,68, +0,95,0,67,0, 79,0,76,0,76, 0,73,0,83,0, 73,0,79,0,78, @@ -3363,296 +4439,3588 @@ public class yyLSLTokens : YyLexer { 0,84,0,95,0, 69,0,86,0,69, 0,78,0,84,0, -1,-1,3,117,0, -345,3,118,0,345, -3,119,0,345,3, -120,0,345,3,121, -0,345,3,122,0, -345,3,48,0,345, -3,49,0,345,3, -50,0,345,3,51, -0,345,3,52,0, -345,3,53,0,345, -3,54,0,345,3, -55,0,345,3,56, -0,345,3,57,0, -345,3,65,0,345, -3,66,0,345,3, -67,0,345,3,68, -0,345,3,69,0, -345,3,70,0,345, -3,71,0,345,3, -72,0,345,3,73, -0,345,3,74,0, -345,3,75,0,345, -3,76,0,345,3, -77,0,345,3,78, -0,345,3,79,0, -345,3,80,0,345, -3,81,0,345,3, -82,0,345,3,83, -0,345,3,84,0, -345,3,85,0,345, -3,86,0,345,3, -87,0,345,3,88, -0,345,3,89,0, -345,3,90,0,345, -3,95,0,345,3, -97,0,345,3,98, -0,345,3,99,0, -345,3,100,0,345, -3,101,0,345,3, -102,0,345,3,103, -0,345,3,104,0, -345,3,105,0,345, -3,106,0,345,3, -107,0,345,3,108, -0,345,482,11,1, -867,0,348,1,-1, -3,115,0,345,3, -116,0,345,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,345,3, -98,0,345,3,99, -0,345,3,100,0, -345,3,101,0,345, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -345,3,106,0,345, -3,107,0,345,3, -108,0,345,483,11, -1,867,0,348,1, --1,3,98,0,345, -3,99,0,345,3, -100,0,345,3,101, -0,345,3,102,0, -345,3,103,0,345, -3,104,0,345,3, -105,0,345,3,106, -0,345,3,107,0, -345,3,108,0,345, +1,-1,3,89,0, +180,412,11,1,867, +0,183,1,-1,3, +87,0,180,3,122, +0,180,3,95,0, +180,3,68,0,180, +3,103,0,180,3, +76,0,180,3,49, +0,180,3,111,0, +180,3,84,0,180, +3,57,0,180,3, +119,0,180,3,65, +0,180,3,100,0, +180,3,73,0,180, +3,108,0,180,3, +81,0,180,3,54, +0,180,3,116,0, +180,3,89,0,180, +413,11,1,867,0, +183,1,-1,3,70, +0,180,3,105,0, +180,3,78,0,180, +3,51,0,180,3, +113,0,180,3,86, +0,180,3,121,0, +180,3,67,0,180, +3,102,0,180,3, +75,0,180,3,48, +0,180,3,110,0, +180,3,83,0,180, +3,56,0,180,3, +118,0,180,3,99, +0,180,3,72,0, +180,3,107,0,180, +3,80,0,180,3, +53,0,180,3,115, +0,180,3,88,0, +180,3,69,0,180, +3,104,0,180,3, +77,0,180,3,50, +0,180,3,112,0, +180,3,85,0,180, +3,120,0,180,3, +66,0,180,3,101, +0,180,3,74,0, +180,3,109,0,180, +3,82,0,180,3, +55,0,180,3,117, +0,180,3,90,0, +180,3,98,0,180, +3,71,0,180,3, +106,0,180,3,79, +0,180,3,52,0, +180,3,114,0,180, +3,87,0,180,3, +122,0,180,3,95, +0,180,3,68,0, +180,3,103,0,180, +3,76,0,180,3, +49,0,180,3,111, +0,180,3,84,0, +180,3,57,0,180, +3,119,0,180,3, +65,0,180,3,100, +0,180,3,73,0, +180,3,108,0,180, +3,81,0,180,3, +54,0,180,3,116, +0,180,3,89,0, +180,414,11,1,867, +0,183,1,-1,3, +89,0,180,415,11, +1,867,0,183,1, +-1,3,88,0,180, +3,69,0,180,3, +104,0,180,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,180,3,66, +0,180,3,101,0, +416,12,1,41765,417, +5,63,3,97,0, +180,3,70,0,180, +3,105,0,180,3, +78,0,180,3,51, +0,180,3,113,0, +180,3,86,0,180, +3,121,0,180,3, +67,0,180,3,102, +0,180,3,75,0, +180,3,48,0,180, +3,110,0,418,12, +1,41837,419,5,63, +3,97,0,180,3, +70,0,180,3,105, +0,180,3,78,0, +180,3,51,0,180, +3,113,0,180,3, +86,0,180,3,121, +0,180,3,67,0, +180,3,102,0,180, +3,75,0,180,3, +48,0,180,3,110, +0,180,3,83,0, +180,3,56,0,180, +3,118,0,180,3, +99,0,180,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,180,3,88, +0,180,3,69,0, +180,3,104,0,180, +3,77,0,180,3, +50,0,180,3,112, +0,180,3,85,0, +180,3,120,0,180, +3,66,0,180,3, +101,0,180,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +180,3,87,0,180, +3,122,0,180,3, +95,0,180,3,68, +0,180,3,103,0, +180,3,76,0,180, +3,49,0,180,3, +111,0,180,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,420,12,1, +41927,421,5,63,3, +97,0,180,3,70, +0,180,3,105,0, +180,3,78,0,180, +3,51,0,180,3, +113,0,180,3,86, +0,180,3,121,0, +180,3,67,0,180, +3,102,0,180,3, +75,0,180,3,48, +0,180,3,110,0, +180,3,83,0,180, +3,56,0,180,3, +118,0,180,3,99, +0,180,3,72,0, +180,3,107,0,180, +3,80,0,180,3, +53,0,180,3,115, +0,180,3,88,0, +180,3,69,0,180, +3,104,0,180,3, +77,0,180,3,50, +0,180,3,112,0, +180,3,85,0,180, +3,120,0,180,3, +66,0,180,3,101, +0,180,3,74,0, +180,3,109,0,180, +3,82,0,180,3, +55,0,180,3,117, +0,180,3,90,0, +180,3,98,0,180, +3,71,0,180,3, +106,0,180,3,79, +0,180,3,52,0, +180,3,114,0,180, +3,87,0,180,3, +122,0,180,3,95, +0,180,3,68,0, +180,3,103,0,180, +3,76,0,180,3, +49,0,180,3,111, +0,180,3,84,0, +180,3,57,0,180, +3,119,0,180,3, +65,0,180,3,100, +0,180,3,73,0, +180,3,108,0,180, +3,81,0,180,3, +54,0,180,3,116, +0,180,3,89,0, +180,422,11,1,519, +0,423,4,48,76, +0,65,0,78,0, +68,0,95,0,67, +0,79,0,76,0, +76,0,73,0,83, +0,73,0,79,0, +78,0,95,0,69, +0,78,0,68,0, +95,0,69,0,86, +0,69,0,78,0, +84,0,1,-1,3, +73,0,180,3,108, +0,180,3,81,0, +180,3,54,0,180, +3,116,0,180,3, +89,0,180,424,11, +1,867,0,183,1, +-1,3,83,0,180, +3,56,0,180,3, +118,0,180,3,99, +0,180,3,72,0, +180,3,107,0,180, +3,80,0,180,3, +53,0,180,3,115, +0,180,3,88,0, +180,3,69,0,180, +3,104,0,180,3, +77,0,180,3,50, +0,180,3,112,0, +180,3,85,0,180, +3,120,0,180,3, +66,0,180,3,101, +0,180,3,74,0, +180,3,109,0,180, +3,82,0,180,3, +55,0,180,3,117, +0,180,3,90,0, +180,3,98,0,180, +3,71,0,180,3, +106,0,180,3,79, +0,180,3,52,0, +180,3,114,0,180, +3,87,0,180,3, +122,0,180,3,95, +0,180,3,68,0, +180,3,103,0,180, +3,76,0,180,3, +49,0,180,3,111, +0,180,3,84,0, +180,3,57,0,180, +3,119,0,180,3, +65,0,180,3,100, +0,180,3,73,0, +180,3,108,0,180, +3,81,0,180,3, +54,0,180,3,116, +0,180,3,89,0, +180,425,11,1,867, +0,183,1,-1,3, +74,0,180,3,109, +0,180,3,82,0, +180,3,55,0,180, +3,117,0,180,3, +90,0,180,3,98, +0,180,3,71,0, +180,3,106,0,180, +3,79,0,180,3, +52,0,180,3,114, +0,180,3,87,0, +180,3,122,0,180, +3,95,0,180,3, +68,0,180,3,103, +0,180,3,76,0, +180,3,49,0,180, +3,111,0,180,3, +84,0,180,3,57, +0,180,3,119,0, +180,3,65,0,180, +3,100,0,180,3, +73,0,180,3,108, +0,180,3,81,0, +180,3,54,0,180, +3,116,0,180,3, +89,0,180,426,11, +1,867,0,183,1, +-1,3,68,0,180, +3,103,0,180,3, +76,0,180,3,49, +0,180,3,111,0, +180,3,84,0,180, +3,57,0,180,3, +119,0,180,3,65, +0,180,3,100,0, +180,3,73,0,180, +3,108,0,180,3, +81,0,180,3,54, +0,180,3,116,0, +180,3,89,0,180, +427,11,1,501,0, +428,4,40,76,0, +65,0,78,0,68, +0,95,0,67,0, +79,0,76,0,76, +0,73,0,83,0, +73,0,79,0,78, +0,95,0,69,0, +86,0,69,0,78, +0,84,0,1,-1, +3,83,0,180,3, +56,0,180,3,118, +0,180,3,99,0, +180,3,72,0,180, +3,107,0,180,3, +80,0,180,3,53, +0,180,3,115,0, +180,3,88,0,180, +3,69,0,180,3, +104,0,180,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,180,3,66, +0,180,3,101,0, +180,3,74,0,180, +3,109,0,180,3, +82,0,180,3,55, +0,180,3,117,0, +180,3,90,0,180, +3,98,0,180,3, +71,0,180,3,106, +0,180,3,79,0, +180,3,52,0,180, +3,114,0,180,3, +87,0,180,3,122, +0,180,3,95,0, +180,3,68,0,180, +3,103,0,180,3, +76,0,180,3,49, +0,180,3,111,0, +180,3,84,0,180, +3,57,0,180,3, +119,0,180,3,65, +0,180,3,100,0, +180,3,73,0,180, +3,108,0,180,3, +81,0,180,3,54, +0,180,3,116,0, +180,3,89,0,180, +429,11,1,867,0, +183,1,-1,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,180,3,73, +0,180,3,108,0, +180,3,81,0,180, +3,54,0,180,3, +116,0,180,3,89, +0,180,430,11,1, +867,0,183,1,-1, +3,78,0,180,3, +51,0,180,3,113, +0,180,3,86,0, +180,3,121,0,180, +3,67,0,180,3, +102,0,180,3,75, +0,180,3,48,0, +180,3,110,0,180, +3,83,0,180,3, +56,0,180,3,118, +0,180,3,99,0, +180,3,72,0,180, +3,107,0,180,3, +80,0,180,3,53, +0,180,3,115,0, +180,3,88,0,180, +3,69,0,180,3, +104,0,180,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,180,3,66, +0,180,3,101,0, +180,3,74,0,180, +3,109,0,180,3, +82,0,180,3,55, +0,180,3,117,0, +180,3,90,0,180, +3,98,0,180,3, +71,0,180,3,106, +0,180,3,79,0, +180,3,52,0,180, +3,114,0,180,3, +87,0,180,3,122, +0,180,3,95,0, +180,3,68,0,180, +3,103,0,180,3, +76,0,180,3,49, +0,180,3,111,0, +180,3,84,0,180, +3,57,0,180,3, +119,0,180,3,65, +0,180,3,100,0, +180,3,73,0,180, +3,108,0,180,3, +81,0,180,3,54, +0,180,3,116,0, +180,3,89,0,180, +431,11,1,867,0, +183,1,-1,3,88, +0,180,3,69,0, +180,3,104,0,180, +3,77,0,180,3, +50,0,180,3,112, +0,180,3,85,0, +180,3,120,0,180, +3,66,0,180,3, +101,0,180,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +180,3,87,0,180, +3,122,0,180,3, +95,0,180,3,68, +0,180,3,103,0, +180,3,76,0,180, +3,49,0,180,3, +111,0,180,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,180,3,73, +0,180,3,108,0, +180,3,81,0,180, +3,54,0,180,3, +116,0,180,3,89, +0,180,432,11,1, +867,0,183,1,-1, +3,78,0,180,3, +51,0,180,3,113, +0,180,3,86,0, +180,3,121,0,180, +3,67,0,180,3, +102,0,180,3,75, +0,180,3,48,0, +180,3,110,0,180, +3,83,0,180,3, +56,0,180,3,118, +0,180,3,99,0, +180,3,72,0,180, +3,107,0,180,3, +80,0,180,3,53, +0,180,3,115,0, +180,3,88,0,180, +3,69,0,180,3, +104,0,180,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,180,3,66, +0,180,3,101,0, +180,3,74,0,180, +3,109,0,180,3, +82,0,180,3,55, +0,180,3,117,0, +180,3,90,0,180, +3,98,0,180,3, +71,0,180,3,106, +0,180,3,79,0, +180,3,52,0,180, +3,114,0,180,3, +87,0,180,3,122, +0,180,3,95,0, +180,3,68,0,180, +3,103,0,180,3, +76,0,180,3,49, +0,180,3,111,0, +180,3,84,0,180, +3,57,0,180,3, +119,0,180,3,65, +0,180,3,100,0, +180,3,73,0,180, +3,108,0,180,3, +81,0,180,3,54, +0,180,3,116,0, +180,3,89,0,180, +433,11,1,867,0, +183,1,-1,3,81, +0,180,3,54,0, +180,3,116,0,180, +3,89,0,180,434, +11,1,867,0,183, +1,-1,3,81,0, +180,3,54,0,180, +3,116,0,180,3, +89,0,180,435,11, +1,867,0,183,1, +-1,3,84,0,180, +3,57,0,180,3, +119,0,180,3,65, +0,180,3,100,0, +180,3,73,0,180, +3,108,0,180,3, +81,0,180,3,54, +0,180,3,116,0, +180,3,89,0,180, +436,11,1,867,0, +183,1,-1,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,180,3,88, +0,180,3,69,0, +180,3,104,0,180, +3,77,0,180,3, +50,0,180,3,112, +0,180,3,85,0, +180,3,120,0,180, +3,66,0,180,3, +101,0,180,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +180,3,87,0,180, +3,122,0,180,3, +95,0,180,3,68, +0,180,3,103,0, +180,3,76,0,180, +3,49,0,180,3, +111,0,180,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,180,3,73, +0,180,3,108,0, +180,3,81,0,180, +3,54,0,180,3, +116,0,180,3,89, +0,180,437,11,1, +867,0,183,1,-1, +3,68,0,180,3, +103,0,180,3,76, +0,180,3,49,0, +180,3,111,0,180, +3,84,0,180,3, +57,0,180,3,119, +0,180,3,65,0, +180,3,100,0,180, +3,73,0,180,3, +108,0,180,3,81, +0,180,3,54,0, +180,3,116,0,180, +3,89,0,180,438, +11,1,867,0,183, +1,-1,3,73,0, +180,3,108,0,180, +3,81,0,180,3, +54,0,180,3,116, +0,180,3,89,0, +180,439,11,1,867, +0,183,1,-1,3, +83,0,180,3,56, +0,180,3,118,0, +180,3,99,0,180, +3,72,0,180,3, +107,0,180,3,80, +0,180,3,53,0, +180,3,115,0,180, +3,88,0,180,3, +69,0,180,3,104, +0,180,3,77,0, +180,3,50,0,180, +3,112,0,180,3, +85,0,180,3,120, +0,180,3,66,0, +180,3,101,0,180, +3,74,0,180,3, +109,0,180,3,82, +0,180,3,55,0, +180,3,117,0,180, +3,90,0,180,3, +98,0,180,3,71, +0,180,3,106,0, +180,3,79,0,180, +3,52,0,180,3, +114,0,180,3,87, +0,180,3,122,0, +180,3,95,0,180, +3,68,0,180,3, +103,0,180,3,76, +0,180,3,49,0, +180,3,111,0,180, +3,84,0,180,3, +57,0,180,3,119, +0,180,3,65,0, +180,3,100,0,180, +3,73,0,180,3, +108,0,180,3,81, +0,180,3,54,0, +180,3,116,0,180, +3,89,0,180,440, +11,1,867,0,183, +1,-1,3,70,0, +180,3,105,0,441, +12,1,42776,442,5, +63,3,97,0,180, +3,70,0,180,3, +105,0,180,3,78, +0,180,3,51,0, +180,3,113,0,180, +3,86,0,180,3, +121,0,180,3,67, +0,180,3,102,0, +180,3,75,0,180, +3,48,0,180,3, +110,0,443,12,1, +42848,444,5,63,3, +97,0,180,3,70, +0,180,3,105,0, +180,3,78,0,180, +3,51,0,180,3, +113,0,180,3,86, +0,180,3,121,0, +180,3,67,0,180, +3,102,0,180,3, +75,0,180,3,48, +0,180,3,110,0, +180,3,83,0,180, +3,56,0,180,3, +118,0,180,3,99, +0,180,3,72,0, +180,3,107,0,445, +12,1,42923,446,5, +63,3,97,0,180, +3,70,0,180,3, +105,0,180,3,78, +0,180,3,51,0, +180,3,113,0,180, +3,86,0,180,3, +121,0,180,3,67, +0,180,3,102,0, +180,3,75,0,180, +3,48,0,180,3, +110,0,180,3,83, +0,180,3,56,0, +180,3,118,0,180, +3,99,0,180,3, +72,0,180,3,107, +0,180,3,80,0, +180,3,53,0,180, +3,115,0,180,3, +88,0,180,3,69, +0,180,3,104,0, +180,3,77,0,180, +3,50,0,180,3, +112,0,180,3,85, +0,180,3,120,0, +180,3,66,0,180, +3,101,0,180,3, +74,0,180,3,109, +0,180,3,82,0, +180,3,55,0,180, +3,117,0,180,3, +90,0,180,3,98, +0,180,3,71,0, +180,3,106,0,180, +3,79,0,180,3, +52,0,180,3,114, +0,180,3,87,0, +180,3,122,0,180, +3,95,0,447,12, +1,42959,448,5,63, +3,97,0,180,3, +70,0,180,3,105, +0,180,3,78,0, +180,3,51,0,180, +3,113,0,180,3, +86,0,180,3,121, +0,180,3,67,0, +180,3,102,0,180, +3,75,0,180,3, +48,0,180,3,110, +0,180,3,83,0, +180,3,56,0,180, +3,118,0,180,3, +99,0,180,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,180,3,88, +0,180,3,69,0, +180,3,104,0,180, +3,77,0,180,3, +50,0,180,3,112, +0,180,3,85,0, +180,3,120,0,180, +3,66,0,180,3, +101,0,180,3,74, +0,180,3,109,0, +449,12,1,43040,450, +5,63,3,97,0, +180,3,70,0,180, +3,105,0,180,3, +78,0,180,3,51, +0,180,3,113,0, +180,3,86,0,180, +3,121,0,180,3, +67,0,180,3,102, +0,180,3,75,0, +180,3,48,0,180, +3,110,0,180,3, +83,0,180,3,56, +0,180,3,118,0, +180,3,99,0,180, +3,72,0,180,3, +107,0,180,3,80, +0,180,3,53,0, +180,3,115,0,180, +3,88,0,180,3, +69,0,180,3,104, +0,180,3,77,0, +180,3,50,0,180, +3,112,0,180,3, +85,0,180,3,120, +0,180,3,66,0, +180,3,101,0,451, +12,1,43120,452,5, +63,3,97,0,180, +3,70,0,180,3, +105,0,180,3,78, +0,180,3,51,0, +180,3,113,0,180, +3,86,0,180,3, +121,0,180,3,67, +0,180,3,102,0, +180,3,75,0,180, +3,48,0,180,3, +110,0,180,3,83, +0,180,3,56,0, +180,3,118,0,180, +3,99,0,180,3, +72,0,180,3,107, +0,180,3,80,0, +180,3,53,0,180, +3,115,0,453,12, +1,43196,454,5,63, +3,97,0,180,3, +70,0,180,3,105, +0,180,3,78,0, +180,3,51,0,180, +3,113,0,180,3, +86,0,180,3,121, +0,180,3,67,0, +180,3,102,0,180, +3,75,0,180,3, +48,0,180,3,110, +0,180,3,83,0, +180,3,56,0,180, +3,118,0,180,3, +99,0,180,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,455,12,1, +43272,456,5,63,3, +97,0,457,12,1, +43339,458,5,63,3, +97,0,180,3,70, +0,180,3,105,0, +180,3,78,0,180, +3,51,0,180,3, +113,0,180,3,86, +0,180,3,121,0, +180,3,67,0,180, +3,102,0,180,3, +75,0,180,3,48, +0,180,3,110,0, +180,3,83,0,180, +3,56,0,180,3, +118,0,180,3,99, +0,180,3,72,0, +180,3,107,0,180, +3,80,0,180,3, +53,0,180,3,115, +0,180,3,88,0, +180,3,69,0,180, +3,104,0,180,3, +77,0,180,3,50, +0,180,3,112,0, +180,3,85,0,180, +3,120,0,180,3, +66,0,180,3,101, +0,180,3,74,0, +180,3,109,0,180, +3,82,0,180,3, +55,0,180,3,117, +0,180,3,90,0, +180,3,98,0,180, +3,71,0,180,3, +106,0,180,3,79, +0,180,3,52,0, +180,3,114,0,180, +3,87,0,180,3, +122,0,180,3,95, +0,180,3,68,0, +180,3,103,0,459, +12,1,43426,460,5, +63,3,97,0,180, +3,70,0,180,3, +105,0,180,3,78, +0,180,3,51,0, +180,3,113,0,180, +3,86,0,180,3, +121,0,180,3,67, +0,180,3,102,0, +180,3,75,0,180, +3,48,0,180,3, +110,0,180,3,83, +0,180,3,56,0, +180,3,118,0,180, +3,99,0,180,3, +72,0,180,3,107, +0,180,3,80,0, +180,3,53,0,180, +3,115,0,180,3, +88,0,180,3,69, +0,180,3,104,0, +180,3,77,0,180, +3,50,0,180,3, +112,0,180,3,85, +0,180,3,120,0, +180,3,66,0,180, +3,101,0,461,12, +1,43506,462,5,63, +3,97,0,180,3, +70,0,180,3,105, +0,180,3,78,0, +180,3,51,0,180, +3,113,0,180,3, +86,0,180,3,121, +0,180,3,67,0, +180,3,102,0,180, +3,75,0,180,3, +48,0,180,3,110, +0,180,3,83,0, +180,3,56,0,180, +3,118,0,180,3, +99,0,180,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,180,3,88, +0,180,3,69,0, +180,3,104,0,180, +3,77,0,180,3, +50,0,180,3,112, +0,180,3,85,0, +180,3,120,0,180, +3,66,0,180,3, +101,0,180,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +180,3,87,0,180, +3,122,0,180,3, +95,0,180,3,68, +0,180,3,103,0, +180,3,76,0,180, +3,49,0,180,3, +111,0,180,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,180,3,73, +0,180,3,108,0, +180,3,81,0,180, +3,54,0,180,3, +116,0,180,3,89, +0,180,463,11,1, +565,0,464,4,36, +76,0,73,0,78, +0,75,0,95,0, +77,0,69,0,83, +0,83,0,65,0, +71,0,69,0,95, +0,69,0,86,0, +69,0,78,0,84, +0,1,-1,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +180,3,87,0,180, +3,122,0,180,3, +95,0,180,3,68, +0,180,3,103,0, +180,3,76,0,180, +3,49,0,180,3, +111,0,180,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,180,3,73, +0,180,3,108,0, +180,3,81,0,180, +3,54,0,180,3, +116,0,180,3,89, +0,180,465,11,1, +867,0,183,1,-1, +3,76,0,180,3, +49,0,180,3,111, +0,180,3,84,0, +180,3,57,0,180, +3,119,0,180,3, +65,0,180,3,100, +0,180,3,73,0, +180,3,108,0,180, +3,81,0,180,3, +54,0,180,3,116, +0,180,3,89,0, +180,466,11,1,867, +0,183,1,-1,3, +70,0,180,3,105, +0,180,3,78,0, +180,3,51,0,180, +3,113,0,180,3, +86,0,180,3,121, +0,180,3,67,0, +180,3,102,0,180, +3,75,0,180,3, +48,0,180,3,110, +0,180,3,83,0, +180,3,56,0,180, +3,118,0,180,3, +99,0,180,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,180,3,88, +0,180,3,69,0, +180,3,104,0,180, +3,77,0,180,3, +50,0,180,3,112, +0,180,3,85,0, +180,3,120,0,180, +3,66,0,180,3, +101,0,180,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +180,3,87,0,180, +3,122,0,180,3, +95,0,180,3,68, +0,180,3,103,0, +180,3,76,0,180, +3,49,0,180,3, +111,0,180,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,180,3,73, +0,180,3,108,0, +180,3,81,0,180, +3,54,0,180,3, +116,0,180,3,89, +0,180,467,11,1, +867,0,183,1,-1, +3,88,0,180,3, +69,0,180,3,104, +0,180,3,77,0, +180,3,50,0,180, +3,112,0,180,3, +85,0,180,3,120, +0,180,3,66,0, +180,3,101,0,180, +3,74,0,180,3, +109,0,180,3,82, +0,180,3,55,0, +180,3,117,0,180, +3,90,0,180,3, +98,0,180,3,71, +0,180,3,106,0, +180,3,79,0,180, +3,52,0,180,3, +114,0,180,3,87, +0,180,3,122,0, +180,3,95,0,180, +3,68,0,180,3, +103,0,180,3,76, +0,180,3,49,0, +180,3,111,0,180, +3,84,0,180,3, +57,0,180,3,119, +0,180,3,65,0, +180,3,100,0,180, +3,73,0,180,3, +108,0,180,3,81, +0,180,3,54,0, +180,3,116,0,180, +3,89,0,180,468, +11,1,867,0,183, +1,-1,3,88,0, +180,3,69,0,180, +3,104,0,180,3, +77,0,180,3,50, +0,180,3,112,0, +180,3,85,0,180, +3,120,0,180,3, +66,0,180,3,101, +0,180,3,74,0, +180,3,109,0,180, +3,82,0,180,3, +55,0,180,3,117, +0,180,3,90,0, +180,3,98,0,180, +3,71,0,180,3, +106,0,180,3,79, +0,180,3,52,0, +180,3,114,0,180, +3,87,0,180,3, +122,0,180,3,95, +0,180,3,68,0, +180,3,103,0,180, +3,76,0,180,3, +49,0,180,3,111, +0,180,3,84,0, +180,3,57,0,180, +3,119,0,180,3, +65,0,180,3,100, +0,180,3,73,0, +180,3,108,0,180, +3,81,0,180,3, +54,0,180,3,116, +0,180,3,89,0, +180,469,11,1,867, +0,183,1,-1,3, +74,0,180,3,109, +0,180,3,82,0, +180,3,55,0,180, +3,117,0,180,3, +90,0,180,3,98, +0,180,3,71,0, +180,3,106,0,180, +3,79,0,180,3, +52,0,180,3,114, +0,180,3,87,0, +180,3,122,0,180, +3,95,0,180,3, +68,0,180,3,103, +0,180,3,76,0, +180,3,49,0,180, +3,111,0,180,3, +84,0,180,3,57, +0,180,3,119,0, +180,3,65,0,180, +3,100,0,180,3, +73,0,180,3,108, +0,180,3,81,0, +180,3,54,0,180, +3,116,0,180,3, +89,0,180,470,11, +1,867,0,183,1, +-1,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +180,3,87,0,180, +3,122,0,180,3, +95,0,180,3,68, +0,180,3,103,0, +180,3,76,0,180, +3,49,0,180,3, +111,0,180,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,180,3,73, +0,180,3,108,0, +180,3,81,0,180, +3,54,0,180,3, +116,0,180,3,89, +0,180,471,11,1, +867,0,183,1,-1, +3,68,0,180,3, +103,0,180,3,76, +0,180,3,49,0, +180,3,111,0,180, +3,84,0,180,3, +57,0,180,3,119, +0,180,3,65,0, +180,3,100,0,180, +3,73,0,180,3, +108,0,180,3,81, +0,180,3,54,0, +180,3,116,0,180, +3,89,0,180,472, +11,1,867,0,183, +1,-1,3,80,0, +180,3,53,0,180, +3,115,0,180,3, +88,0,180,3,69, +0,180,3,104,0, +180,3,77,0,180, +3,50,0,180,3, +112,0,180,3,85, +0,180,3,120,0, +180,3,66,0,180, +3,101,0,180,3, +74,0,180,3,109, +0,180,3,82,0, +180,3,55,0,180, +3,117,0,180,3, +90,0,180,3,98, +0,180,3,71,0, +180,3,106,0,180, +3,79,0,180,3, +52,0,180,3,114, +0,180,3,87,0, +180,3,122,0,180, +3,95,0,180,3, +68,0,180,3,103, +0,180,3,76,0, +180,3,49,0,180, +3,111,0,180,3, +84,0,180,3,57, +0,180,3,119,0, +180,3,65,0,180, +3,100,0,180,3, +73,0,180,3,108, +0,180,3,81,0, +180,3,54,0,180, +3,116,0,180,3, +89,0,180,473,11, +1,867,0,183,1, +-1,3,83,0,180, +3,56,0,180,3, +118,0,180,3,99, +0,180,3,72,0, +180,3,107,0,180, +3,80,0,180,3, +53,0,180,3,115, +0,474,12,1,44052, +475,5,63,3,97, +0,180,3,70,0, +180,3,105,0,180, +3,78,0,180,3, +51,0,180,3,113, +0,180,3,86,0, +180,3,121,0,180, +3,67,0,180,3, +102,0,180,3,75, +0,180,3,48,0, +180,3,110,0,180, +3,83,0,180,3, +56,0,180,3,118, +0,180,3,99,0, +180,3,72,0,180, +3,107,0,180,3, +80,0,180,3,53, +0,180,3,115,0, +180,3,88,0,180, +3,69,0,180,3, +104,0,180,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,180,3,66, +0,180,3,101,0, +180,3,74,0,180, +3,109,0,180,3, +82,0,180,3,55, +0,180,3,117,0, +180,3,90,0,180, +3,98,0,180,3, +71,0,180,3,106, +0,180,3,79,0, +180,3,52,0,180, +3,114,0,180,3, +87,0,180,3,122, +0,180,3,95,0, +180,3,68,0,180, +3,103,0,180,3, +76,0,180,3,49, +0,180,3,111,0, +180,3,84,0,180, +3,57,0,180,3, +119,0,180,3,65, +0,180,3,100,0, +180,3,73,0,180, +3,108,0,180,3, +81,0,180,3,54, +0,180,3,116,0, +476,12,1,44145,477, +5,63,3,97,0, +180,3,70,0,180, +3,105,0,180,3, +78,0,180,3,51, +0,180,3,113,0, +180,3,86,0,180, +3,121,0,180,3, +67,0,180,3,102, +0,180,3,75,0, +180,3,48,0,180, +3,110,0,180,3, +83,0,180,3,56, +0,180,3,118,0, +180,3,99,0,180, +3,72,0,180,3, +107,0,180,3,80, +0,180,3,53,0, +180,3,115,0,180, +3,88,0,180,3, +69,0,180,3,104, +0,180,3,77,0, +180,3,50,0,180, +3,112,0,180,3, +85,0,180,3,120, +0,180,3,66,0, +180,3,101,0,478, +12,1,44225,479,5, +63,3,97,0,180, +3,70,0,180,3, +105,0,180,3,78, +0,180,3,51,0, +180,3,113,0,180, +3,86,0,180,3, +121,0,180,3,67, +0,180,3,102,0, +180,3,75,0,180, +3,48,0,180,3, +110,0,480,12,1, +44297,481,5,63,3, +97,0,180,3,70, +0,180,3,105,0, +180,3,78,0,180, +3,51,0,180,3, +113,0,180,3,86, +0,180,3,121,0, +180,3,67,0,180, +3,102,0,180,3, +75,0,180,3,48, +0,180,3,110,0, +180,3,83,0,180, +3,56,0,180,3, +118,0,180,3,99, +0,180,3,72,0, +180,3,107,0,180, +3,80,0,180,3, +53,0,180,3,115, +0,180,3,88,0, +180,3,69,0,180, +3,104,0,180,3, +77,0,180,3,50, +0,180,3,112,0, +180,3,85,0,180, +3,120,0,180,3, +66,0,180,3,101, +0,180,3,74,0, +180,3,109,0,180, +3,82,0,180,3, +55,0,180,3,117, +0,180,3,90,0, +180,3,98,0,180, +3,71,0,180,3, +106,0,180,3,79, +0,180,3,52,0, +180,3,114,0,180, +3,87,0,180,3, +122,0,180,3,95, +0,180,3,68,0, +180,3,103,0,180, +3,76,0,180,3, +49,0,180,3,111, +0,180,3,84,0, +180,3,57,0,180, +3,119,0,180,3, +65,0,180,3,100, +0,180,3,73,0, +180,3,108,0,180, +3,81,0,180,3, +54,0,180,3,116, +0,180,3,89,0, +180,482,11,1,581, +0,483,4,24,76, +0,73,0,83,0, +84,0,69,0,78, +0,95,0,69,0, +86,0,69,0,78, +0,84,0,1,-1, +3,83,0,180,3, +56,0,180,3,118, +0,180,3,99,0, +180,3,72,0,180, +3,107,0,180,3, +80,0,180,3,53, +0,180,3,115,0, +180,3,88,0,180, +3,69,0,180,3, +104,0,180,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,180,3,66, +0,180,3,101,0, +180,3,74,0,180, +3,109,0,180,3, +82,0,180,3,55, +0,180,3,117,0, +180,3,90,0,180, +3,98,0,180,3, +71,0,180,3,106, +0,180,3,79,0, +180,3,52,0,180, +3,114,0,180,3, +87,0,180,3,122, +0,180,3,95,0, +180,3,68,0,180, +3,103,0,180,3, +76,0,180,3,49, +0,180,3,111,0, +180,3,84,0,180, +3,57,0,180,3, +119,0,180,3,65, +0,180,3,100,0, +180,3,73,0,180, +3,108,0,180,3, +81,0,180,3,54, +0,180,3,116,0, +180,3,89,0,180, 484,11,1,867,0, -348,1,-1,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,345,3, -98,0,345,3,99, -0,345,3,100,0, -345,3,101,0,345, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -345,3,106,0,345, -3,107,0,345,3, -108,0,345,485,11, -1,867,0,348,1, --1,3,116,0,345, -3,117,0,345,3, -118,0,345,3,119, -0,345,3,120,0, -345,3,121,0,345, -3,122,0,345,3, -48,0,345,3,49, -0,345,3,50,0, -345,3,51,0,345, -3,52,0,345,3, -53,0,345,3,54, -0,345,3,55,0, -345,3,56,0,345, -3,57,0,345,3, -65,0,345,3,66, -0,345,3,67,0, -345,3,68,0,345, -3,69,0,345,3, -70,0,345,3,71, -0,345,3,72,0, -345,3,73,0,345, -3,74,0,345,3, -75,0,345,3,76, -0,345,3,77,0, -345,3,78,0,345, -3,79,0,345,3, -80,0,345,3,81, -0,345,3,82,0, -345,3,83,0,345, -3,84,0,345,3, -85,0,345,3,86, -0,345,3,87,0, -345,3,88,0,345, -3,89,0,345,3, -90,0,345,3,95, -0,345,3,97,0, -345,3,98,0,345, -3,99,0,345,3, -100,0,345,3,101, -0,486,12,1,27167, -487,5,63,3,109, -0,345,3,110,0, -488,12,1,27196,489, -5,63,3,109,0, -345,3,110,0,345, -3,111,0,345,3, -112,0,345,3,113, -0,345,3,114,0, -345,3,115,0,345, -3,116,0,345,3, -117,0,345,3,118, -0,345,3,119,0, -345,3,120,0,345, -3,121,0,345,3, -122,0,345,3,48, -0,345,3,49,0, -345,3,50,0,345, -3,51,0,345,3, -52,0,345,3,53, -0,345,3,54,0, -345,3,55,0,345, -3,56,0,345,3, -57,0,345,3,65, -0,345,3,66,0, -345,3,67,0,345, -3,68,0,345,3, -69,0,345,3,70, -0,345,3,71,0, -345,3,72,0,345, -3,73,0,345,3, -74,0,345,3,75, -0,345,3,76,0, -345,3,77,0,345, -3,78,0,345,3, -79,0,345,3,80, -0,345,3,81,0, -345,3,82,0,345, -3,83,0,345,3, -84,0,345,3,85, -0,345,3,86,0, -345,3,87,0,345, -3,88,0,345,3, -89,0,345,3,90, -0,345,3,95,0, -345,3,97,0,345, -3,98,0,345,3, -99,0,345,3,100, -0,490,12,1,27242, -491,5,63,3,109, -0,345,3,110,0, -345,3,111,0,345, -3,112,0,345,3, -113,0,345,3,114, -0,345,3,115,0, -345,3,116,0,345, -3,117,0,345,3, -118,0,345,3,119, -0,345,3,120,0, -345,3,121,0,345, -3,122,0,345,3, -48,0,345,3,49, -0,345,3,50,0, -345,3,51,0,345, -3,52,0,345,3, -53,0,345,3,54, -0,345,3,55,0, -345,3,56,0,345, -3,57,0,345,3, -65,0,345,3,66, -0,345,3,67,0, -345,3,68,0,345, -3,69,0,345,3, -70,0,345,3,71, -0,345,3,72,0, -345,3,73,0,345, -3,74,0,345,3, -75,0,345,3,76, -0,345,3,77,0, -345,3,78,0,345, -3,79,0,345,3, -80,0,345,3,81, -0,345,3,82,0, -345,3,83,0,345, -3,84,0,345,3, -85,0,345,3,86, -0,345,3,87,0, -345,3,88,0,345, -3,89,0,345,3, -90,0,345,3,95, -0,345,3,97,0, -345,3,98,0,345, -3,99,0,345,3, -100,0,345,3,101, -0,345,3,102,0, -345,3,103,0,345, -3,104,0,345,3, -105,0,345,3,106, -0,345,3,107,0, -345,3,108,0,345, -492,11,1,414,0, -493,4,38,67,0, +183,1,-1,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +180,3,87,0,180, +3,122,0,180,3, +95,0,180,3,68, +0,180,3,103,0, +180,3,76,0,180, +3,49,0,180,3, +111,0,180,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,180,3,73, +0,180,3,108,0, +180,3,81,0,180, +3,54,0,180,3, +116,0,180,3,89, +0,180,485,11,1, +342,0,486,4,18, +76,0,73,0,83, +0,84,0,95,0, +84,0,89,0,80, +0,69,0,1,-1, +3,89,0,180,487, +11,1,867,0,183, +1,-1,3,88,0, +180,3,69,0,180, +3,104,0,180,3, +77,0,180,3,50, +0,180,3,112,0, +180,3,85,0,180, +3,120,0,180,3, +66,0,180,3,101, +0,180,3,74,0, +180,3,109,0,180, +3,82,0,180,3, +55,0,180,3,117, +0,180,3,90,0, +180,3,98,0,180, +3,71,0,180,3, +106,0,180,3,79, +0,180,3,52,0, +180,3,114,0,180, +3,87,0,180,3, +122,0,180,3,95, +0,180,3,68,0, +180,3,103,0,180, +3,76,0,180,3, +49,0,180,3,111, +0,180,3,84,0, +180,3,57,0,180, +3,119,0,180,3, +65,0,180,3,100, +0,180,3,73,0, +180,3,108,0,180, +3,81,0,180,3, +54,0,180,3,116, +0,180,3,89,0, +180,488,11,1,867, +0,183,1,-1,3, +78,0,180,3,51, +0,180,3,113,0, +180,3,86,0,180, +3,121,0,180,3, +67,0,180,3,102, +0,180,3,75,0, +180,3,48,0,180, +3,110,0,180,3, +83,0,180,3,56, +0,180,3,118,0, +180,3,99,0,180, +3,72,0,180,3, +107,0,180,3,80, +0,180,3,53,0, +180,3,115,0,180, +3,88,0,180,3, +69,0,180,3,104, +0,180,3,77,0, +180,3,50,0,180, +3,112,0,180,3, +85,0,180,3,120, +0,180,3,66,0, +180,3,101,0,180, +3,74,0,180,3, +109,0,180,3,82, +0,180,3,55,0, +180,3,117,0,180, +3,90,0,180,3, +98,0,180,3,71, +0,180,3,106,0, +180,3,79,0,180, +3,52,0,180,3, +114,0,180,3,87, +0,180,3,122,0, +180,3,95,0,180, +3,68,0,180,3, +103,0,180,3,76, +0,180,3,49,0, +180,3,111,0,180, +3,84,0,180,3, +57,0,180,3,119, +0,180,3,65,0, +180,3,100,0,180, +3,73,0,180,3, +108,0,180,3,81, +0,180,3,54,0, +180,3,116,0,180, +3,89,0,180,489, +11,1,867,0,183, +1,-1,3,68,0, +178,3,105,0,490, +12,1,12205,491,5, +63,3,97,0,180, +3,70,0,180,3, +105,0,180,3,78, +0,180,3,51,0, +180,3,113,0,180, +3,86,0,180,3, +121,0,180,3,67, +0,180,3,102,0, +492,12,1,12276,493, +5,63,3,97,0, +180,3,70,0,180, +3,105,0,180,3, +78,0,180,3,51, +0,180,3,113,0, +180,3,86,0,180, +3,121,0,180,3, +67,0,180,3,102, +0,180,3,75,0, +180,3,48,0,180, +3,110,0,180,3, +83,0,180,3,56, +0,180,3,118,0, +180,3,99,0,180, +3,72,0,180,3, +107,0,180,3,80, +0,180,3,53,0, +180,3,115,0,180, +3,88,0,180,3, +69,0,180,3,104, +0,180,3,77,0, +180,3,50,0,180, +3,112,0,180,3, +85,0,180,3,120, +0,180,3,66,0, +180,3,101,0,180, +3,74,0,180,3, +109,0,180,3,82, +0,180,3,55,0, +180,3,117,0,180, +3,90,0,180,3, +98,0,180,3,71, +0,180,3,106,0, +180,3,79,0,180, +3,52,0,180,3, +114,0,180,3,87, +0,180,3,122,0, +180,3,95,0,180, +3,68,0,180,3, +103,0,180,3,76, +0,180,3,49,0, +180,3,111,0,180, +3,84,0,180,3, +57,0,180,3,119, +0,180,3,65,0, +180,3,100,0,180, +3,73,0,180,3, +108,0,180,3,81, +0,180,3,54,0, +180,3,116,0,180, +3,89,0,180,494, +11,1,209,0,495, +4,4,73,0,70, +0,1,-1,3,75, +0,180,3,48,0, +180,3,110,0,496, +12,1,12397,497,5, +63,3,97,0,180, +3,70,0,180,3, +105,0,180,3,78, +0,180,3,51,0, +180,3,113,0,180, +3,86,0,180,3, +121,0,180,3,67, +0,180,3,102,0, +180,3,75,0,180, +3,48,0,180,3, +110,0,180,3,83, +0,180,3,56,0, +180,3,118,0,180, +3,99,0,180,3, +72,0,180,3,107, +0,180,3,80,0, +180,3,53,0,180, +3,115,0,180,3, +88,0,180,3,69, +0,180,3,104,0, +180,3,77,0,180, +3,50,0,180,3, +112,0,180,3,85, +0,180,3,120,0, +180,3,66,0,180, +3,101,0,180,3, +74,0,180,3,109, +0,180,3,82,0, +180,3,55,0,180, +3,117,0,180,3, +90,0,180,3,98, +0,180,3,71,0, +180,3,106,0,180, +3,79,0,180,3, +52,0,180,3,114, +0,180,3,87,0, +180,3,122,0,180, +3,95,0,180,3, +68,0,180,3,103, +0,180,3,76,0, +180,3,49,0,180, +3,111,0,180,3, +84,0,180,3,57, +0,180,3,119,0, +180,3,65,0,180, +3,100,0,180,3, +73,0,180,3,108, +0,180,3,81,0, +180,3,54,0,180, +3,116,0,498,12, +1,12490,499,5,63, +3,97,0,180,3, +70,0,180,3,105, +0,180,3,78,0, +180,3,51,0,180, +3,113,0,180,3, +86,0,180,3,121, +0,180,3,67,0, +180,3,102,0,180, +3,75,0,180,3, +48,0,180,3,110, +0,180,3,83,0, +180,3,56,0,180, +3,118,0,180,3, +99,0,180,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,180,3,88, +0,180,3,69,0, +180,3,104,0,180, +3,77,0,180,3, +50,0,180,3,112, +0,180,3,85,0, +180,3,120,0,180, +3,66,0,180,3, +101,0,500,12,1, +12570,501,5,63,3, +97,0,180,3,70, +0,180,3,105,0, +180,3,78,0,180, +3,51,0,180,3, +113,0,180,3,86, +0,180,3,121,0, +180,3,67,0,180, +3,102,0,180,3, +75,0,180,3,48, +0,180,3,110,0, +180,3,83,0,180, +3,56,0,180,3, +118,0,180,3,99, +0,180,3,72,0, +180,3,107,0,180, +3,80,0,180,3, +53,0,180,3,115, +0,180,3,88,0, +180,3,69,0,180, +3,104,0,180,3, +77,0,180,3,50, +0,180,3,112,0, +180,3,85,0,180, +3,120,0,180,3, +66,0,180,3,101, +0,180,3,74,0, +180,3,109,0,180, +3,82,0,180,3, +55,0,180,3,117, +0,180,3,90,0, +180,3,98,0,180, +3,71,0,180,3, +106,0,180,3,79, +0,180,3,52,0, +180,3,114,0,180, +3,87,0,180,3, +122,0,180,3,95, +0,180,3,68,0, +180,3,103,0,502, +12,1,12657,503,5, +63,3,97,0,180, +3,70,0,180,3, +105,0,180,3,78, +0,180,3,51,0, +180,3,113,0,180, +3,86,0,180,3, +121,0,180,3,67, +0,180,3,102,0, +180,3,75,0,180, +3,48,0,180,3, +110,0,180,3,83, +0,180,3,56,0, +180,3,118,0,180, +3,99,0,180,3, +72,0,180,3,107, +0,180,3,80,0, +180,3,53,0,180, +3,115,0,180,3, +88,0,180,3,69, +0,180,3,104,0, +180,3,77,0,180, +3,50,0,180,3, +112,0,180,3,85, +0,180,3,120,0, +180,3,66,0,180, +3,101,0,504,12, +1,12737,505,5,63, +3,97,0,180,3, +70,0,180,3,105, +0,180,3,78,0, +180,3,51,0,180, +3,113,0,180,3, +86,0,180,3,121, +0,180,3,67,0, +180,3,102,0,180, +3,75,0,180,3, +48,0,180,3,110, +0,180,3,83,0, +180,3,56,0,180, +3,118,0,180,3, +99,0,180,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,180,3,88, +0,180,3,69,0, +180,3,104,0,180, +3,77,0,180,3, +50,0,180,3,112, +0,180,3,85,0, +180,3,120,0,180, +3,66,0,180,3, +101,0,180,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +506,12,1,12822,507, +5,63,3,97,0, +180,3,70,0,180, +3,105,0,180,3, +78,0,180,3,51, +0,180,3,113,0, +180,3,86,0,180, +3,121,0,180,3, +67,0,180,3,102, +0,180,3,75,0, +180,3,48,0,180, +3,110,0,180,3, +83,0,180,3,56, +0,180,3,118,0, +180,3,99,0,180, +3,72,0,180,3, +107,0,180,3,80, +0,180,3,53,0, +180,3,115,0,180, +3,88,0,180,3, +69,0,180,3,104, +0,180,3,77,0, +180,3,50,0,180, +3,112,0,180,3, +85,0,180,3,120, +0,180,3,66,0, +180,3,101,0,180, +3,74,0,180,3, +109,0,180,3,82, +0,180,3,55,0, +180,3,117,0,180, +3,90,0,180,3, +98,0,180,3,71, +0,180,3,106,0, +180,3,79,0,180, +3,52,0,180,3, +114,0,180,3,87, +0,180,3,122,0, +180,3,95,0,180, +3,68,0,180,3, +103,0,180,3,76, +0,180,3,49,0, +180,3,111,0,180, +3,84,0,180,3, +57,0,180,3,119, +0,180,3,65,0, +180,3,100,0,180, +3,73,0,180,3, +108,0,180,3,81, +0,180,3,54,0, +180,3,116,0,180, +3,89,0,180,508, +11,1,283,0,509, +4,24,73,0,78, +0,84,0,69,0, +71,0,69,0,82, +0,95,0,84,0, +89,0,80,0,69, +0,1,-1,3,87, +0,180,3,122,0, +180,3,95,0,180, +3,68,0,180,3, +103,0,180,3,76, +0,180,3,49,0, +180,3,111,0,180, +3,84,0,180,3, +57,0,180,3,119, +0,180,3,65,0, +180,3,100,0,180, +3,73,0,180,3, +108,0,180,3,81, +0,180,3,54,0, +180,3,116,0,180, +3,89,0,180,510, +11,1,867,0,183, +1,-1,3,74,0, +180,3,109,0,180, +3,82,0,180,3, +55,0,180,3,117, +0,180,3,90,0, +180,3,98,0,180, +3,71,0,180,3, +106,0,180,3,79, +0,180,3,52,0, +180,3,114,0,180, +3,87,0,180,3, +122,0,180,3,95, +0,180,3,68,0, +180,3,103,0,180, +3,76,0,180,3, +49,0,180,3,111, +0,180,3,84,0, +180,3,57,0,180, +3,119,0,180,3, +65,0,180,3,100, +0,180,3,73,0, +180,3,108,0,180, +3,81,0,180,3, +54,0,180,3,116, +0,180,3,89,0, +180,511,11,1,867, +0,183,1,-1,3, +76,0,180,3,49, +0,180,3,111,0, +180,3,84,0,180, +3,57,0,180,3, +119,0,180,3,65, +0,180,3,100,0, +180,3,73,0,180, +3,108,0,180,3, +81,0,180,3,54, +0,180,3,116,0, +180,3,89,0,180, +512,11,1,867,0, +183,1,-1,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +180,3,87,0,180, +3,122,0,180,3, +95,0,180,3,68, +0,180,3,103,0, +180,3,76,0,180, +3,49,0,180,3, +111,0,180,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,180,3,73, +0,180,3,108,0, +180,3,81,0,180, +3,54,0,180,3, +116,0,180,3,89, +0,180,513,11,1, +867,0,183,1,-1, +3,89,0,180,514, +11,1,867,0,183, +1,-1,3,83,0, +180,3,56,0,180, +3,118,0,180,3, +99,0,180,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,180,3,88, +0,180,3,69,0, +180,3,104,0,180, +3,77,0,180,3, +50,0,180,3,112, +0,180,3,85,0, +180,3,120,0,180, +3,66,0,180,3, +101,0,180,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +180,3,87,0,180, +3,122,0,180,3, +95,0,180,3,68, +0,180,3,103,0, +180,3,76,0,180, +3,49,0,180,3, +111,0,180,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,180,3,73, +0,180,3,108,0, +180,3,81,0,180, +3,54,0,180,3, +116,0,180,3,89, +0,180,515,11,1, +867,0,183,1,-1, +3,65,0,178,3, +102,0,516,12,1, +13168,517,5,63,3, +97,0,180,3,70, +0,180,3,105,0, +180,3,78,0,180, +3,51,0,180,3, +113,0,180,3,86, +0,180,3,121,0, +180,3,67,0,180, +3,102,0,180,3, +75,0,180,3,48, +0,180,3,110,0, +180,3,83,0,180, +3,56,0,180,3, +118,0,180,3,99, +0,180,3,72,0, +180,3,107,0,180, +3,80,0,180,3, +53,0,180,3,115, +0,180,3,88,0, +180,3,69,0,180, +3,104,0,180,3, +77,0,180,3,50, +0,180,3,112,0, +180,3,85,0,180, +3,120,0,180,3, +66,0,180,3,101, +0,180,3,74,0, +180,3,109,0,180, +3,82,0,180,3, +55,0,180,3,117, +0,180,3,90,0, +180,3,98,0,180, +3,71,0,180,3, +106,0,180,3,79, +0,180,3,52,0, +180,3,114,0,180, +3,87,0,180,3, +122,0,180,3,95, +0,180,3,68,0, +180,3,103,0,180, +3,76,0,180,3, +49,0,180,3,111, +0,518,12,1,13256, +519,5,63,3,97, +0,180,3,70,0, +180,3,105,0,180, +3,78,0,180,3, +51,0,180,3,113, +0,180,3,86,0, +180,3,121,0,180, +3,67,0,180,3, +102,0,180,3,75, +0,180,3,48,0, +180,3,110,0,180, +3,83,0,180,3, +56,0,180,3,118, +0,180,3,99,0, +180,3,72,0,180, +3,107,0,180,3, +80,0,180,3,53, +0,180,3,115,0, +180,3,88,0,180, +3,69,0,180,3, +104,0,180,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,180,3,66, +0,180,3,101,0, +180,3,74,0,180, +3,109,0,180,3, +82,0,180,3,55, +0,180,3,117,0, +180,3,90,0,180, +3,98,0,180,3, +71,0,180,3,106, +0,180,3,79,0, +180,3,52,0,180, +3,114,0,520,12, +1,13341,521,5,63, +3,97,0,180,3, +70,0,180,3,105, +0,180,3,78,0, +180,3,51,0,180, +3,113,0,180,3, +86,0,180,3,121, +0,180,3,67,0, +180,3,102,0,180, +3,75,0,180,3, +48,0,180,3,110, +0,180,3,83,0, +180,3,56,0,180, +3,118,0,180,3, +99,0,180,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,180,3,88, +0,180,3,69,0, +180,3,104,0,180, +3,77,0,180,3, +50,0,180,3,112, +0,180,3,85,0, +180,3,120,0,180, +3,66,0,180,3, +101,0,180,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +180,3,87,0,180, +3,122,0,180,3, +95,0,180,3,68, +0,180,3,103,0, +180,3,76,0,180, +3,49,0,180,3, +111,0,180,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,180,3,73, +0,180,3,108,0, +180,3,81,0,180, +3,54,0,180,3, +116,0,180,3,89, +0,180,522,11,1, +238,0,523,4,6, +70,0,79,0,82, +0,1,-1,3,87, +0,180,3,122,0, +180,3,95,0,180, +3,68,0,180,3, +103,0,180,3,76, +0,180,3,49,0, +180,3,111,0,180, +3,84,0,180,3, +57,0,180,3,119, +0,180,3,65,0, +180,3,100,0,180, +3,73,0,180,3, +108,0,180,3,81, +0,180,3,54,0, +180,3,116,0,180, +3,89,0,180,524, +11,1,867,0,183, +1,-1,3,84,0, +180,3,57,0,180, +3,119,0,180,3, +65,0,180,3,100, +0,180,3,73,0, +180,3,108,0,525, +12,1,13499,526,5, +63,3,97,0,180, +3,70,0,180,3, +105,0,180,3,78, +0,180,3,51,0, +180,3,113,0,180, +3,86,0,180,3, +121,0,180,3,67, +0,180,3,102,0, +180,3,75,0,180, +3,48,0,180,3, +110,0,180,3,83, +0,180,3,56,0, +180,3,118,0,180, +3,99,0,180,3, +72,0,180,3,107, +0,180,3,80,0, +180,3,53,0,180, +3,115,0,180,3, +88,0,180,3,69, +0,180,3,104,0, +180,3,77,0,180, +3,50,0,180,3, +112,0,180,3,85, +0,180,3,120,0, +180,3,66,0,180, +3,101,0,180,3, +74,0,180,3,109, +0,180,3,82,0, +180,3,55,0,180, +3,117,0,180,3, +90,0,180,3,98, +0,180,3,71,0, +180,3,106,0,180, +3,79,0,180,3, +52,0,180,3,114, +0,180,3,87,0, +180,3,122,0,180, +3,95,0,180,3, +68,0,180,3,103, +0,180,3,76,0, +180,3,49,0,180, +3,111,0,527,12, +1,13587,528,5,63, +3,97,0,529,12, +1,13654,530,5,63, +3,97,0,180,3, +70,0,180,3,105, +0,180,3,78,0, +180,3,51,0,180, +3,113,0,180,3, +86,0,180,3,121, +0,180,3,67,0, +180,3,102,0,180, +3,75,0,180,3, +48,0,180,3,110, +0,180,3,83,0, +180,3,56,0,180, +3,118,0,180,3, +99,0,180,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,180,3,88, +0,180,3,69,0, +180,3,104,0,180, +3,77,0,180,3, +50,0,180,3,112, +0,180,3,85,0, +180,3,120,0,180, +3,66,0,180,3, +101,0,180,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +180,3,87,0,180, +3,122,0,180,3, +95,0,180,3,68, +0,180,3,103,0, +180,3,76,0,180, +3,49,0,180,3, +111,0,180,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,180,3,73, +0,180,3,108,0, +180,3,81,0,180, +3,54,0,180,3, +116,0,531,12,1, +13747,532,5,63,3, +97,0,180,3,70, +0,180,3,105,0, +180,3,78,0,180, +3,51,0,180,3, +113,0,180,3,86, +0,180,3,121,0, +180,3,67,0,180, +3,102,0,180,3, +75,0,180,3,48, +0,180,3,110,0, +180,3,83,0,180, +3,56,0,180,3, +118,0,180,3,99, +0,180,3,72,0, +180,3,107,0,180, +3,80,0,180,3, +53,0,180,3,115, +0,180,3,88,0, +180,3,69,0,180, +3,104,0,180,3, +77,0,180,3,50, +0,180,3,112,0, +180,3,85,0,180, +3,120,0,180,3, +66,0,180,3,101, +0,180,3,74,0, +180,3,109,0,180, +3,82,0,180,3, +55,0,180,3,117, +0,180,3,90,0, +180,3,98,0,180, +3,71,0,180,3, +106,0,180,3,79, +0,180,3,52,0, +180,3,114,0,180, +3,87,0,180,3, +122,0,180,3,95, +0,180,3,68,0, +180,3,103,0,180, +3,76,0,180,3, +49,0,180,3,111, +0,180,3,84,0, +180,3,57,0,180, +3,119,0,180,3, +65,0,180,3,100, +0,180,3,73,0, +180,3,108,0,180, +3,81,0,180,3, +54,0,180,3,116, +0,180,3,89,0, +180,533,11,1,294, +0,534,4,20,70, +0,76,0,79,0, +65,0,84,0,95, +0,84,0,89,0, +80,0,69,0,1, +-1,3,89,0,180, +535,11,1,867,0, +183,1,-1,3,70, +0,180,3,105,0, +180,3,78,0,180, +3,51,0,180,3, +113,0,180,3,86, +0,180,3,121,0, +180,3,67,0,180, +3,102,0,180,3, +75,0,180,3,48, +0,180,3,110,0, +180,3,83,0,180, +3,56,0,180,3, +118,0,180,3,99, +0,180,3,72,0, +180,3,107,0,180, +3,80,0,180,3, +53,0,180,3,115, +0,180,3,88,0, +180,3,69,0,180, +3,104,0,180,3, +77,0,180,3,50, +0,180,3,112,0, +180,3,85,0,180, +3,120,0,180,3, +66,0,180,3,101, +0,180,3,74,0, +180,3,109,0,180, +3,82,0,180,3, +55,0,180,3,117, +0,180,3,90,0, +180,3,98,0,180, +3,71,0,180,3, +106,0,180,3,79, +0,180,3,52,0, +180,3,114,0,180, +3,87,0,180,3, +122,0,180,3,95, +0,180,3,68,0, +180,3,103,0,180, +3,76,0,180,3, +49,0,180,3,111, +0,180,3,84,0, +180,3,57,0,180, +3,119,0,180,3, +65,0,180,3,100, +0,180,3,73,0, +180,3,108,0,180, +3,81,0,180,3, +54,0,180,3,116, +0,180,3,89,0, +180,536,11,1,867, +0,183,1,-1,3, +84,0,180,3,57, +0,180,3,119,0, +180,3,65,0,180, +3,100,0,180,3, +73,0,180,3,108, +0,180,3,81,0, +180,3,54,0,180, +3,116,0,180,3, +89,0,180,537,11, +1,867,0,183,1, +-1,3,81,0,180, +3,54,0,180,3, +116,0,180,3,89, +0,180,538,11,1, +867,0,183,1,-1, +3,62,0,539,12, +1,3503,540,5,2, +3,61,0,541,12, +1,3631,542,5,0, +543,11,1,154,0, +544,4,28,71,0, +82,0,69,0,65, +0,84,0,69,0, +82,0,95,0,69, +0,81,0,85,0, +65,0,76,0,83, +0,1,-1,3,62, +0,545,12,1,3509, +546,5,0,547,11, +1,203,0,548,4, +22,82,0,73,0, +71,0,72,0,84, +0,95,0,83,0, +72,0,73,0,70, +0,84,0,1,-1, +549,11,1,121,0, +550,4,22,82,0, +73,0,71,0,72, +0,84,0,95,0, +65,0,78,0,71, +0,76,0,69,0, +1,-1,3,99,0, +551,12,1,18331,552, +5,63,3,97,0, +180,3,70,0,180, +3,105,0,180,3, +78,0,180,3,51, +0,180,3,113,0, +180,3,86,0,180, +3,121,0,180,3, +67,0,180,3,102, +0,180,3,75,0, +180,3,48,0,180, +3,110,0,180,3, +83,0,180,3,56, +0,180,3,118,0, +180,3,99,0,180, +3,72,0,180,3, +107,0,180,3,80, +0,180,3,53,0, +180,3,115,0,180, +3,88,0,180,3, +69,0,180,3,104, +0,553,12,1,18408, +554,5,63,3,97, +0,555,12,1,18475, +556,5,63,3,97, +0,180,3,70,0, +180,3,105,0,180, +3,78,0,180,3, +51,0,180,3,113, +0,180,3,86,0, +180,3,121,0,180, +3,67,0,180,3, +102,0,180,3,75, +0,180,3,48,0, +180,3,110,0,557, +12,1,18547,558,5, +63,3,97,0,180, +3,70,0,180,3, +105,0,180,3,78, +0,180,3,51,0, +180,3,113,0,180, +3,86,0,180,3, +121,0,180,3,67, +0,180,3,102,0, +180,3,75,0,180, +3,48,0,180,3, +110,0,180,3,83, +0,180,3,56,0, +180,3,118,0,180, +3,99,0,180,3, +72,0,180,3,107, +0,180,3,80,0, +180,3,53,0,180, +3,115,0,180,3, +88,0,180,3,69, +0,180,3,104,0, +180,3,77,0,180, +3,50,0,180,3, +112,0,180,3,85, +0,180,3,120,0, +180,3,66,0,180, +3,101,0,180,3, +74,0,180,3,109, +0,180,3,82,0, +180,3,55,0,180, +3,117,0,180,3, +90,0,180,3,98, +0,180,3,71,0, +180,3,106,0,180, +3,79,0,180,3, +52,0,180,3,114, +0,180,3,87,0, +180,3,122,0,180, +3,95,0,180,3, +68,0,180,3,103, +0,559,12,1,18634, +560,5,63,3,97, +0,180,3,70,0, +180,3,105,0,180, +3,78,0,180,3, +51,0,180,3,113, +0,180,3,86,0, +180,3,121,0,180, +3,67,0,180,3, +102,0,180,3,75, +0,180,3,48,0, +180,3,110,0,180, +3,83,0,180,3, +56,0,180,3,118, +0,180,3,99,0, +180,3,72,0,180, +3,107,0,180,3, +80,0,180,3,53, +0,180,3,115,0, +180,3,88,0,180, +3,69,0,180,3, +104,0,180,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,180,3,66, +0,180,3,101,0, +561,12,1,18714,562, +5,63,3,97,0, +180,3,70,0,180, +3,105,0,180,3, +78,0,180,3,51, +0,180,3,113,0, +180,3,86,0,180, +3,121,0,180,3, +67,0,180,3,102, +0,180,3,75,0, +180,3,48,0,180, +3,110,0,180,3, +83,0,180,3,56, +0,180,3,118,0, +180,3,99,0,180, +3,72,0,180,3, +107,0,180,3,80, +0,180,3,53,0, +180,3,115,0,180, +3,88,0,180,3, +69,0,180,3,104, +0,180,3,77,0, +180,3,50,0,180, +3,112,0,180,3, +85,0,180,3,120, +0,180,3,66,0, +180,3,101,0,180, +3,74,0,180,3, +109,0,180,3,82, +0,180,3,55,0, +180,3,117,0,180, +3,90,0,180,3, +98,0,180,3,71, +0,180,3,106,0, +180,3,79,0,180, +3,52,0,180,3, +114,0,180,3,87, +0,180,3,122,0, +180,3,95,0,180, +3,68,0,180,3, +103,0,180,3,76, +0,180,3,49,0, +180,3,111,0,180, +3,84,0,180,3, +57,0,180,3,119, +0,180,3,65,0, +180,3,100,0,563, +12,1,18804,564,5, +63,3,97,0,180, +3,70,0,180,3, +105,0,180,3,78, +0,180,3,51,0, +180,3,113,0,180, +3,86,0,180,3, +121,0,180,3,67, +0,180,3,102,0, +180,3,75,0,180, +3,48,0,180,3, +110,0,180,3,83, +0,180,3,56,0, +180,3,118,0,180, +3,99,0,180,3, +72,0,180,3,107, +0,180,3,80,0, +180,3,53,0,180, +3,115,0,180,3, +88,0,180,3,69, +0,180,3,104,0, +180,3,77,0,180, +3,50,0,180,3, +112,0,180,3,85, +0,180,3,120,0, +180,3,66,0,180, +3,101,0,180,3, +74,0,180,3,109, +0,180,3,82,0, +180,3,55,0,180, +3,117,0,180,3, +90,0,180,3,98, +0,180,3,71,0, +180,3,106,0,180, +3,79,0,180,3, +52,0,180,3,114, +0,180,3,87,0, +180,3,122,0,180, +3,95,0,180,3, +68,0,180,3,103, +0,180,3,76,0, +180,3,49,0,180, +3,111,0,180,3, +84,0,180,3,57, +0,180,3,119,0, +180,3,65,0,180, +3,100,0,180,3, +73,0,180,3,108, +0,180,3,81,0, +180,3,54,0,180, +3,116,0,180,3, +89,0,180,565,11, +1,390,0,566,4, +26,67,0,72,0, +65,0,78,0,71, +0,69,0,68,0, +95,0,69,0,86, +0,69,0,78,0, +84,0,1,-1,3, +73,0,180,3,108, +0,180,3,81,0, +180,3,54,0,180, +3,116,0,180,3, +89,0,180,567,11, +1,867,0,183,1, +-1,3,74,0,180, +3,109,0,180,3, +82,0,180,3,55, +0,180,3,117,0, +180,3,90,0,180, +3,98,0,180,3, +71,0,180,3,106, +0,180,3,79,0, +180,3,52,0,180, +3,114,0,180,3, +87,0,180,3,122, +0,180,3,95,0, +180,3,68,0,180, +3,103,0,180,3, +76,0,180,3,49, +0,180,3,111,0, +180,3,84,0,180, +3,57,0,180,3, +119,0,180,3,65, +0,180,3,100,0, +180,3,73,0,180, +3,108,0,180,3, +81,0,180,3,54, +0,180,3,116,0, +180,3,89,0,180, +568,11,1,867,0, +183,1,-1,3,76, +0,180,3,49,0, +180,3,111,0,180, +3,84,0,180,3, +57,0,180,3,119, +0,180,3,65,0, +180,3,100,0,180, +3,73,0,180,3, +108,0,180,3,81, +0,180,3,54,0, +180,3,116,0,180, +3,89,0,180,569, +11,1,867,0,183, +1,-1,3,83,0, +180,3,56,0,180, +3,118,0,180,3, +99,0,180,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,180,3,88, +0,180,3,69,0, +180,3,104,0,180, +3,77,0,180,3, +50,0,180,3,112, +0,180,3,85,0, +180,3,120,0,180, +3,66,0,180,3, +101,0,180,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +180,3,87,0,180, +3,122,0,180,3, +95,0,180,3,68, +0,180,3,103,0, +180,3,76,0,180, +3,49,0,180,3, +111,0,180,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,180,3,73, +0,180,3,108,0, +180,3,81,0,180, +3,54,0,180,3, +116,0,180,3,89, +0,180,570,11,1, +867,0,183,1,-1, +3,70,0,180,3, +105,0,180,3,78, +0,180,3,51,0, +180,3,113,0,180, +3,86,0,180,3, +121,0,180,3,67, +0,180,3,102,0, +180,3,75,0,180, +3,48,0,180,3, +110,0,180,3,83, +0,180,3,56,0, +180,3,118,0,180, +3,99,0,180,3, +72,0,180,3,107, +0,180,3,80,0, +180,3,53,0,180, +3,115,0,180,3, +88,0,180,3,69, +0,180,3,104,0, +180,3,77,0,180, +3,50,0,180,3, +112,0,180,3,85, +0,180,3,120,0, +180,3,66,0,180, +3,101,0,180,3, +74,0,180,3,109, +0,180,3,82,0, +180,3,55,0,180, +3,117,0,180,3, +90,0,180,3,98, +0,180,3,71,0, +180,3,106,0,180, +3,79,0,180,3, +52,0,180,3,114, +0,180,3,87,0, +180,3,122,0,180, +3,95,0,180,3, +68,0,180,3,103, +0,180,3,76,0, +180,3,49,0,180, +3,111,0,180,3, +84,0,180,3,57, +0,180,3,119,0, +180,3,65,0,180, +3,100,0,180,3, +73,0,180,3,108, +0,180,3,81,0, +180,3,54,0,180, +3,116,0,180,3, +89,0,180,571,11, +1,867,0,183,1, +-1,3,77,0,180, +3,50,0,180,3, +112,0,180,3,85, +0,180,3,120,0, +180,3,66,0,180, +3,101,0,180,3, +74,0,180,3,109, +0,180,3,82,0, +180,3,55,0,180, +3,117,0,180,3, +90,0,180,3,98, +0,180,3,71,0, +180,3,106,0,180, +3,79,0,180,3, +52,0,180,3,114, +0,180,3,87,0, +180,3,122,0,180, +3,95,0,180,3, +68,0,180,3,103, +0,180,3,76,0, +180,3,49,0,180, +3,111,0,572,12, +1,19139,573,5,63, +3,97,0,180,3, +70,0,180,3,105, +0,180,3,78,0, +180,3,51,0,180, +3,113,0,180,3, +86,0,180,3,121, +0,180,3,67,0, +180,3,102,0,180, +3,75,0,180,3, +48,0,180,3,110, +0,574,12,1,19211, +575,5,63,3,97, +0,180,3,70,0, +180,3,105,0,180, +3,78,0,180,3, +51,0,180,3,113, +0,180,3,86,0, +180,3,121,0,180, +3,67,0,180,3, +102,0,180,3,75, +0,180,3,48,0, +180,3,110,0,180, +3,83,0,180,3, +56,0,180,3,118, +0,180,3,99,0, +180,3,72,0,180, +3,107,0,180,3, +80,0,180,3,53, +0,180,3,115,0, +180,3,88,0,180, +3,69,0,180,3, +104,0,180,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,180,3,66, +0,180,3,101,0, +180,3,74,0,180, +3,109,0,180,3, +82,0,180,3,55, +0,180,3,117,0, +180,3,90,0,180, +3,98,0,180,3, +71,0,180,3,106, +0,180,3,79,0, +180,3,52,0,180, +3,114,0,180,3, +87,0,180,3,122, +0,180,3,95,0, +180,3,68,0,180, +3,103,0,180,3, +76,0,180,3,49, +0,180,3,111,0, +180,3,84,0,180, +3,57,0,180,3, +119,0,180,3,65, +0,180,3,100,0, +180,3,73,0,180, +3,108,0,180,3, +81,0,180,3,54, +0,180,3,116,0, +576,12,1,19304,577, +5,63,3,97,0, +180,3,70,0,180, +3,105,0,180,3, +78,0,180,3,51, +0,180,3,113,0, +180,3,86,0,180, +3,121,0,180,3, +67,0,180,3,102, +0,180,3,75,0, +180,3,48,0,180, +3,110,0,180,3, +83,0,180,3,56, +0,180,3,118,0, +180,3,99,0,180, +3,72,0,180,3, +107,0,180,3,80, +0,180,3,53,0, +180,3,115,0,180, +3,88,0,180,3, +69,0,180,3,104, +0,180,3,77,0, +180,3,50,0,180, +3,112,0,180,3, +85,0,180,3,120, +0,180,3,66,0, +180,3,101,0,180, +3,74,0,180,3, +109,0,180,3,82, +0,180,3,55,0, +180,3,117,0,180, +3,90,0,180,3, +98,0,180,3,71, +0,180,3,106,0, +180,3,79,0,180, +3,52,0,180,3, +114,0,578,12,1, +19389,579,5,63,3, +97,0,180,3,70, +0,180,3,105,0, +180,3,78,0,180, +3,51,0,180,3, +113,0,180,3,86, +0,180,3,121,0, +180,3,67,0,180, +3,102,0,180,3, +75,0,180,3,48, +0,180,3,110,0, +180,3,83,0,180, +3,56,0,180,3, +118,0,180,3,99, +0,180,3,72,0, +180,3,107,0,180, +3,80,0,180,3, +53,0,180,3,115, +0,180,3,88,0, +180,3,69,0,180, +3,104,0,180,3, +77,0,180,3,50, +0,180,3,112,0, +180,3,85,0,180, +3,120,0,180,3, +66,0,180,3,101, +0,180,3,74,0, +180,3,109,0,180, +3,82,0,180,3, +55,0,180,3,117, +0,180,3,90,0, +180,3,98,0,180, +3,71,0,180,3, +106,0,180,3,79, +0,180,3,52,0, +180,3,114,0,180, +3,87,0,180,3, +122,0,180,3,95, +0,180,3,68,0, +180,3,103,0,180, +3,76,0,180,3, +49,0,180,3,111, +0,580,12,1,19477, +581,5,63,3,97, +0,180,3,70,0, +180,3,105,0,180, +3,78,0,180,3, +51,0,180,3,113, +0,180,3,86,0, +180,3,121,0,180, +3,67,0,180,3, +102,0,180,3,75, +0,180,3,48,0, +180,3,110,0,180, +3,83,0,180,3, +56,0,180,3,118, +0,180,3,99,0, +180,3,72,0,180, +3,107,0,180,3, +80,0,180,3,53, +0,180,3,115,0, +180,3,88,0,180, +3,69,0,180,3, +104,0,180,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,180,3,66, +0,180,3,101,0, +180,3,74,0,180, +3,109,0,180,3, +82,0,180,3,55, +0,180,3,117,0, +180,3,90,0,180, +3,98,0,180,3, +71,0,180,3,106, +0,180,3,79,0, +180,3,52,0,180, +3,114,0,180,3, +87,0,180,3,122, +0,180,3,95,0, +180,3,68,0,180, +3,103,0,180,3, +76,0,180,3,49, +0,180,3,111,0, +180,3,84,0,180, +3,57,0,180,3, +119,0,180,3,65, +0,180,3,100,0, +180,3,73,0,180, +3,108,0,582,12, +1,19568,583,5,63, +3,97,0,180,3, +70,0,180,3,105, +0,180,3,78,0, +180,3,51,0,180, +3,113,0,180,3, +86,0,180,3,121, +0,180,3,67,0, +180,3,102,0,180, +3,75,0,180,3, +48,0,180,3,110, +0,180,3,83,0, +180,3,56,0,180, +3,118,0,180,3, +99,0,180,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,180,3,88, +0,180,3,69,0, +180,3,104,0,180, +3,77,0,180,3, +50,0,180,3,112, +0,180,3,85,0, +180,3,120,0,180, +3,66,0,180,3, +101,0,180,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +180,3,87,0,180, +3,122,0,180,3, +95,0,180,3,68, +0,180,3,103,0, +180,3,76,0,180, +3,49,0,180,3, +111,0,180,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,180,3,73, +0,180,3,108,0, +180,3,81,0,180, +3,54,0,180,3, +116,0,180,3,89, +0,180,584,11,1, +450,0,585,4,26, +67,0,79,0,78, +0,84,0,82,0, +79,0,76,0,95, +0,69,0,86,0, +69,0,78,0,84, +0,1,-1,3,81, +0,180,3,54,0, +180,3,116,0,180, +3,89,0,180,586, +11,1,867,0,183, +1,-1,3,84,0, +180,3,57,0,180, +3,119,0,180,3, +65,0,180,3,100, +0,180,3,73,0, +180,3,108,0,180, +3,81,0,180,3, +54,0,180,3,116, +0,180,3,89,0, +180,587,11,1,867, +0,183,1,-1,3, +87,0,180,3,122, +0,180,3,95,0, +180,3,68,0,180, +3,103,0,180,3, +76,0,180,3,49, +0,180,3,111,0, +180,3,84,0,180, +3,57,0,180,3, +119,0,180,3,65, +0,180,3,100,0, +180,3,73,0,180, +3,108,0,180,3, +81,0,180,3,54, +0,180,3,116,0, +180,3,89,0,180, +588,11,1,867,0, +183,1,-1,3,89, +0,180,589,11,1, +867,0,183,1,-1, +3,83,0,180,3, +56,0,180,3,118, +0,180,3,99,0, +180,3,72,0,180, +3,107,0,180,3, +80,0,180,3,53, +0,180,3,115,0, +180,3,88,0,180, +3,69,0,180,3, +104,0,180,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,180,3,66, +0,180,3,101,0, +180,3,74,0,180, +3,109,0,180,3, +82,0,180,3,55, +0,180,3,117,0, +180,3,90,0,180, +3,98,0,180,3, +71,0,180,3,106, +0,180,3,79,0, +180,3,52,0,180, +3,114,0,180,3, +87,0,180,3,122, +0,180,3,95,0, +180,3,68,0,180, +3,103,0,180,3, +76,0,180,3,49, +0,180,3,111,0, +180,3,84,0,180, +3,57,0,180,3, +119,0,180,3,65, +0,180,3,100,0, +180,3,73,0,180, +3,108,0,590,12, +1,19830,591,5,63, +3,97,0,180,3, +70,0,180,3,105, +0,180,3,78,0, +180,3,51,0,180, +3,113,0,180,3, +86,0,180,3,121, +0,180,3,67,0, +180,3,102,0,180, +3,75,0,180,3, +48,0,180,3,110, +0,180,3,83,0, +180,3,56,0,180, +3,118,0,180,3, +99,0,180,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,180,3,88, +0,180,3,69,0, +180,3,104,0,180, +3,77,0,180,3, +50,0,180,3,112, +0,180,3,85,0, +180,3,120,0,180, +3,66,0,180,3, +101,0,180,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +180,3,87,0,180, +3,122,0,180,3, +95,0,180,3,68, +0,180,3,103,0, +180,3,76,0,180, +3,49,0,180,3, +111,0,180,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,180,3,73, +0,180,3,108,0, +592,12,1,19921,593, +5,63,3,97,0, +180,3,70,0,180, +3,105,0,594,12, +1,19989,595,5,63, +3,97,0,180,3, +70,0,180,3,105, +0,180,3,78,0, +180,3,51,0,180, +3,113,0,180,3, +86,0,180,3,121, +0,180,3,67,0, +180,3,102,0,180, +3,75,0,180,3, +48,0,180,3,110, +0,180,3,83,0, +180,3,56,0,180, +3,118,0,180,3, +99,0,180,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,596,12,1, +20065,597,5,63,3, +97,0,180,3,70, +0,180,3,105,0, +598,12,1,20133,599, +5,63,3,97,0, +180,3,70,0,180, +3,105,0,180,3, +78,0,180,3,51, +0,180,3,113,0, +180,3,86,0,180, +3,121,0,180,3, +67,0,180,3,102, +0,180,3,75,0, +180,3,48,0,180, +3,110,0,180,3, +83,0,180,3,56, +0,180,3,118,0, +180,3,99,0,180, +3,72,0,180,3, +107,0,180,3,80, +0,180,3,53,0, +180,3,115,0,180, +3,88,0,180,3, +69,0,180,3,104, +0,180,3,77,0, +180,3,50,0,180, +3,112,0,180,3, +85,0,180,3,120, +0,180,3,66,0, +180,3,101,0,180, +3,74,0,180,3, +109,0,180,3,82, +0,180,3,55,0, +180,3,117,0,180, +3,90,0,180,3, +98,0,180,3,71, +0,180,3,106,0, +180,3,79,0,180, +3,52,0,180,3, +114,0,180,3,87, +0,180,3,122,0, +180,3,95,0,180, +3,68,0,180,3, +103,0,180,3,76, +0,180,3,49,0, +180,3,111,0,600, +12,1,20221,601,5, +63,3,97,0,180, +3,70,0,180,3, +105,0,180,3,78, +0,180,3,51,0, +180,3,113,0,180, +3,86,0,180,3, +121,0,180,3,67, +0,180,3,102,0, +180,3,75,0,180, +3,48,0,180,3, +110,0,602,12,1, +20293,603,5,63,3, +97,0,180,3,70, +0,180,3,105,0, +180,3,78,0,180, +3,51,0,180,3, +113,0,180,3,86, +0,180,3,121,0, +180,3,67,0,180, +3,102,0,180,3, +75,0,180,3,48, +0,180,3,110,0, +180,3,83,0,180, +3,56,0,180,3, +118,0,180,3,99, +0,180,3,72,0, +180,3,107,0,180, +3,80,0,180,3, +53,0,180,3,115, +0,180,3,88,0, +180,3,69,0,180, +3,104,0,180,3, +77,0,180,3,50, +0,180,3,112,0, +180,3,85,0,180, +3,120,0,180,3, +66,0,180,3,101, +0,180,3,74,0, +180,3,109,0,180, +3,82,0,180,3, +55,0,180,3,117, +0,180,3,90,0, +180,3,98,0,180, +3,71,0,180,3, +106,0,180,3,79, +0,180,3,52,0, +180,3,114,0,180, +3,87,0,180,3, +122,0,180,3,95, +0,604,12,1,20329, +605,5,63,3,97, +0,180,3,70,0, +180,3,105,0,180, +3,78,0,180,3, +51,0,180,3,113, +0,180,3,86,0, +180,3,121,0,180, +3,67,0,180,3, +102,0,180,3,75, +0,180,3,48,0, +180,3,110,0,180, +3,83,0,180,3, +56,0,180,3,118, +0,180,3,99,0, +180,3,72,0,180, +3,107,0,180,3, +80,0,180,3,53, +0,180,3,115,0, +606,12,1,20405,607, +5,63,3,97,0, +180,3,70,0,180, +3,105,0,180,3, +78,0,180,3,51, +0,180,3,113,0, +180,3,86,0,180, +3,121,0,180,3, +67,0,180,3,102, +0,180,3,75,0, +180,3,48,0,180, +3,110,0,180,3, +83,0,180,3,56, +0,180,3,118,0, +180,3,99,0,180, +3,72,0,180,3, +107,0,180,3,80, +0,180,3,53,0, +180,3,115,0,180, +3,88,0,180,3, +69,0,180,3,104, +0,180,3,77,0, +180,3,50,0,180, +3,112,0,180,3, +85,0,180,3,120, +0,180,3,66,0, +180,3,101,0,180, +3,74,0,180,3, +109,0,180,3,82, +0,180,3,55,0, +180,3,117,0,180, +3,90,0,180,3, +98,0,180,3,71, +0,180,3,106,0, +180,3,79,0,180, +3,52,0,180,3, +114,0,180,3,87, +0,180,3,122,0, +180,3,95,0,180, +3,68,0,180,3, +103,0,180,3,76, +0,180,3,49,0, +180,3,111,0,180, +3,84,0,180,3, +57,0,180,3,119, +0,180,3,65,0, +180,3,100,0,180, +3,73,0,180,3, +108,0,180,3,81, +0,180,3,54,0, +180,3,116,0,608, +12,1,20498,609,5, +63,3,97,0,610, +12,1,20565,611,5, +63,3,97,0,180, +3,70,0,180,3, +105,0,180,3,78, +0,180,3,51,0, +180,3,113,0,180, +3,86,0,180,3, +121,0,180,3,67, +0,180,3,102,0, +180,3,75,0,180, +3,48,0,180,3, +110,0,180,3,83, +0,180,3,56,0, +180,3,118,0,180, +3,99,0,180,3, +72,0,180,3,107, +0,180,3,80,0, +180,3,53,0,180, +3,115,0,180,3, +88,0,180,3,69, +0,180,3,104,0, +180,3,77,0,180, +3,50,0,180,3, +112,0,180,3,85, +0,180,3,120,0, +180,3,66,0,180, +3,101,0,180,3, +74,0,180,3,109, +0,180,3,82,0, +180,3,55,0,180, +3,117,0,180,3, +90,0,180,3,98, +0,180,3,71,0, +180,3,106,0,180, +3,79,0,180,3, +52,0,180,3,114, +0,612,12,1,20650, +613,5,63,3,97, +0,180,3,70,0, +180,3,105,0,180, +3,78,0,180,3, +51,0,180,3,113, +0,180,3,86,0, +180,3,121,0,180, +3,67,0,180,3, +102,0,180,3,75, +0,180,3,48,0, +180,3,110,0,180, +3,83,0,180,3, +56,0,180,3,118, +0,180,3,99,0, +180,3,72,0,180, +3,107,0,180,3, +80,0,180,3,53, +0,180,3,115,0, +180,3,88,0,180, +3,69,0,180,3, +104,0,180,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,180,3,66, +0,180,3,101,0, +180,3,74,0,180, +3,109,0,180,3, +82,0,180,3,55, +0,180,3,117,0, +180,3,90,0,180, +3,98,0,180,3, +71,0,180,3,106, +0,180,3,79,0, +180,3,52,0,180, +3,114,0,180,3, +87,0,180,3,122, +0,180,3,95,0, +180,3,68,0,180, +3,103,0,180,3, +76,0,180,3,49, +0,180,3,111,0, +180,3,84,0,180, +3,57,0,180,3, +119,0,180,3,65, +0,180,3,100,0, +180,3,73,0,180, +3,108,0,180,3, +81,0,180,3,54, +0,180,3,116,0, +614,12,1,20743,615, +5,63,3,97,0, +180,3,70,0,180, +3,105,0,180,3, +78,0,180,3,51, +0,180,3,113,0, +180,3,86,0,180, +3,121,0,180,3, +67,0,180,3,102, +0,180,3,75,0, +180,3,48,0,180, +3,110,0,180,3, +83,0,180,3,56, +0,180,3,118,0, +180,3,99,0,180, +3,72,0,180,3, +107,0,180,3,80, +0,180,3,53,0, +180,3,115,0,180, +3,88,0,180,3, +69,0,180,3,104, +0,180,3,77,0, +180,3,50,0,180, +3,112,0,180,3, +85,0,180,3,120, +0,180,3,66,0, +180,3,101,0,180, +3,74,0,180,3, +109,0,180,3,82, +0,180,3,55,0, +180,3,117,0,180, +3,90,0,180,3, +98,0,180,3,71, +0,180,3,106,0, +180,3,79,0,180, +3,52,0,180,3, +114,0,180,3,87, +0,180,3,122,0, +180,3,95,0,180, +3,68,0,180,3, +103,0,180,3,76, +0,180,3,49,0, +180,3,111,0,180, +3,84,0,180,3, +57,0,180,3,119, +0,180,3,65,0, +180,3,100,0,180, +3,73,0,180,3, +108,0,180,3,81, +0,180,3,54,0, +180,3,116,0,180, +3,89,0,180,616, +11,1,431,0,617, +4,42,67,0,79, +0,76,0,76,0, +73,0,83,0,73, +0,79,0,78,0, +95,0,83,0,84, +0,65,0,82,0, +84,0,95,0,69, +0,86,0,69,0, +78,0,84,0,1, +-1,3,89,0,180, +618,11,1,867,0, +183,1,-1,3,87, +0,180,3,122,0, +180,3,95,0,180, +3,68,0,180,3, +103,0,180,3,76, +0,180,3,49,0, +180,3,111,0,180, +3,84,0,180,3, +57,0,180,3,119, +0,180,3,65,0, +180,3,100,0,180, +3,73,0,180,3, +108,0,180,3,81, +0,180,3,54,0, +180,3,116,0,180, +3,89,0,180,619, +11,1,867,0,183, +1,-1,3,70,0, +180,3,105,0,180, +3,78,0,180,3, +51,0,180,3,113, +0,180,3,86,0, +180,3,121,0,180, +3,67,0,180,3, +102,0,180,3,75, +0,180,3,48,0, +180,3,110,0,180, +3,83,0,180,3, +56,0,180,3,118, +0,180,3,99,0, +180,3,72,0,180, +3,107,0,180,3, +80,0,180,3,53, +0,180,3,115,0, +180,3,88,0,180, +3,69,0,180,3, +104,0,180,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,180,3,66, +0,180,3,101,0, +180,3,74,0,180, +3,109,0,180,3, +82,0,180,3,55, +0,180,3,117,0, +180,3,90,0,180, +3,98,0,180,3, +71,0,180,3,106, +0,180,3,79,0, +180,3,52,0,180, +3,114,0,180,3, +87,0,180,3,122, +0,180,3,95,0, +180,3,68,0,180, +3,103,0,180,3, +76,0,180,3,49, +0,180,3,111,0, +180,3,84,0,180, +3,57,0,180,3, +119,0,180,3,65, +0,180,3,100,0, +180,3,73,0,180, +3,108,0,180,3, +81,0,180,3,54, +0,180,3,116,0, +180,3,89,0,180, +620,11,1,867,0, +183,1,-1,3,89, +0,180,621,11,1, +867,0,183,1,-1, +3,88,0,180,3, +69,0,180,3,104, +0,180,3,77,0, +180,3,50,0,180, +3,112,0,180,3, +85,0,180,3,120, +0,180,3,66,0, +180,3,101,0,622, +12,1,21009,623,5, +63,3,97,0,180, +3,70,0,180,3, +105,0,180,3,78, +0,180,3,51,0, +180,3,113,0,180, +3,86,0,180,3, +121,0,180,3,67, +0,180,3,102,0, +180,3,75,0,180, +3,48,0,180,3, +110,0,624,12,1, +21081,625,5,63,3, +97,0,180,3,70, +0,180,3,105,0, +180,3,78,0,180, +3,51,0,180,3, +113,0,180,3,86, +0,180,3,121,0, +180,3,67,0,180, +3,102,0,180,3, +75,0,180,3,48, +0,180,3,110,0, +180,3,83,0,180, +3,56,0,180,3, +118,0,180,3,99, +0,180,3,72,0, +180,3,107,0,180, +3,80,0,180,3, +53,0,180,3,115, +0,180,3,88,0, +180,3,69,0,180, +3,104,0,180,3, +77,0,180,3,50, +0,180,3,112,0, +180,3,85,0,180, +3,120,0,180,3, +66,0,180,3,101, +0,180,3,74,0, +180,3,109,0,180, +3,82,0,180,3, +55,0,180,3,117, +0,180,3,90,0, +180,3,98,0,180, +3,71,0,180,3, +106,0,180,3,79, +0,180,3,52,0, +180,3,114,0,180, +3,87,0,180,3, +122,0,180,3,95, +0,180,3,68,0, +180,3,103,0,180, +3,76,0,180,3, +49,0,180,3,111, +0,180,3,84,0, +180,3,57,0,180, +3,119,0,180,3, +65,0,180,3,100, +0,626,12,1,21171, +627,5,63,3,97, +0,180,3,70,0, +180,3,105,0,180, +3,78,0,180,3, +51,0,180,3,113, +0,180,3,86,0, +180,3,121,0,180, +3,67,0,180,3, +102,0,180,3,75, +0,180,3,48,0, +180,3,110,0,180, +3,83,0,180,3, +56,0,180,3,118, +0,180,3,99,0, +180,3,72,0,180, +3,107,0,180,3, +80,0,180,3,53, +0,180,3,115,0, +180,3,88,0,180, +3,69,0,180,3, +104,0,180,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,180,3,66, +0,180,3,101,0, +180,3,74,0,180, +3,109,0,180,3, +82,0,180,3,55, +0,180,3,117,0, +180,3,90,0,180, +3,98,0,180,3, +71,0,180,3,106, +0,180,3,79,0, +180,3,52,0,180, +3,114,0,180,3, +87,0,180,3,122, +0,180,3,95,0, +180,3,68,0,180, +3,103,0,180,3, +76,0,180,3,49, +0,180,3,111,0, +180,3,84,0,180, +3,57,0,180,3, +119,0,180,3,65, +0,180,3,100,0, +180,3,73,0,180, +3,108,0,180,3, +81,0,180,3,54, +0,180,3,116,0, +180,3,89,0,180, +628,11,1,414,0, +629,4,38,67,0, 79,0,76,0,76, 0,73,0,83,0, 73,0,79,0,78, @@ -3660,83 +8028,95 @@ public class yyLSLTokens : YyLexer { 78,0,68,0,95, 0,69,0,86,0, 69,0,78,0,84, -0,1,-1,3,101, -0,345,3,102,0, -345,3,103,0,345, -3,104,0,345,3, -105,0,345,3,106, -0,345,3,107,0, -345,3,108,0,345, -494,11,1,867,0, -348,1,-1,3,111, -0,345,3,112,0, -345,3,113,0,345, -3,114,0,345,3, -115,0,345,3,116, -0,345,3,117,0, -345,3,118,0,345, -3,119,0,345,3, -120,0,345,3,121, -0,345,3,122,0, -345,3,48,0,345, -3,49,0,345,3, -50,0,345,3,51, -0,345,3,52,0, -345,3,53,0,345, -3,54,0,345,3, -55,0,345,3,56, -0,345,3,57,0, -345,3,65,0,345, -3,66,0,345,3, -67,0,345,3,68, -0,345,3,69,0, -345,3,70,0,345, -3,71,0,345,3, -72,0,345,3,73, -0,345,3,74,0, -345,3,75,0,345, -3,76,0,345,3, -77,0,345,3,78, -0,345,3,79,0, -345,3,80,0,345, -3,81,0,345,3, -82,0,345,3,83, -0,345,3,84,0, -345,3,85,0,345, -3,86,0,345,3, -87,0,345,3,88, -0,345,3,89,0, -345,3,90,0,345, -3,95,0,345,3, -97,0,345,3,98, -0,345,3,99,0, -345,3,100,0,345, -3,101,0,345,3, -102,0,345,3,103, -0,345,3,104,0, -345,3,105,0,345, -3,106,0,345,3, -107,0,345,3,108, -0,345,495,11,1, -867,0,348,1,-1, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -345,3,106,0,345, -3,107,0,345,3, -108,0,345,496,11, -1,867,0,348,1, --1,3,97,0,345, -3,98,0,345,3, -99,0,345,3,100, -0,345,3,101,0, -345,3,102,0,345, -3,103,0,345,3, -104,0,345,3,105, -0,345,3,106,0, -345,3,107,0,345, -3,108,0,345,497, -11,1,401,0,498, +0,1,-1,3,73, +0,180,3,108,0, +180,3,81,0,180, +3,54,0,180,3, +116,0,180,3,89, +0,180,630,11,1, +867,0,183,1,-1, +3,83,0,180,3, +56,0,180,3,118, +0,180,3,99,0, +180,3,72,0,180, +3,107,0,180,3, +80,0,180,3,53, +0,180,3,115,0, +180,3,88,0,180, +3,69,0,180,3, +104,0,180,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,180,3,66, +0,180,3,101,0, +180,3,74,0,180, +3,109,0,180,3, +82,0,180,3,55, +0,180,3,117,0, +180,3,90,0,180, +3,98,0,180,3, +71,0,180,3,106, +0,180,3,79,0, +180,3,52,0,180, +3,114,0,180,3, +87,0,180,3,122, +0,180,3,95,0, +180,3,68,0,180, +3,103,0,180,3, +76,0,180,3,49, +0,180,3,111,0, +180,3,84,0,180, +3,57,0,180,3, +119,0,180,3,65, +0,180,3,100,0, +180,3,73,0,180, +3,108,0,180,3, +81,0,180,3,54, +0,180,3,116,0, +180,3,89,0,180, +631,11,1,867,0, +183,1,-1,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +180,3,87,0,180, +3,122,0,180,3, +95,0,180,3,68, +0,180,3,103,0, +180,3,76,0,180, +3,49,0,180,3, +111,0,180,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,180,3,73, +0,180,3,108,0, +180,3,81,0,180, +3,54,0,180,3, +116,0,180,3,89, +0,180,632,11,1, +867,0,183,1,-1, +3,68,0,180,3, +103,0,180,3,76, +0,180,3,49,0, +180,3,111,0,180, +3,84,0,180,3, +57,0,180,3,119, +0,180,3,65,0, +180,3,100,0,180, +3,73,0,180,3, +108,0,180,3,81, +0,180,3,54,0, +180,3,116,0,180, +3,89,0,180,633, +11,1,401,0,634, 4,30,67,0,79, 0,76,0,76,0, 73,0,83,0,73, @@ -3744,7519 +8124,8895 @@ public class yyLSLTokens : YyLexer { 95,0,69,0,86, 0,69,0,78,0, 84,0,1,-1,3, -111,0,345,3,112, -0,345,3,113,0, -345,3,114,0,345, -3,115,0,345,3, -116,0,345,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,345,3, -98,0,345,3,99, -0,345,3,100,0, -345,3,101,0,345, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -345,3,106,0,345, -3,107,0,345,3, -108,0,345,499,11, -1,867,0,348,1, --1,3,112,0,345, -3,113,0,345,3, -114,0,345,3,115, -0,345,3,116,0, -345,3,117,0,345, -3,118,0,345,3, -119,0,345,3,120, -0,345,3,121,0, -345,3,122,0,345, -3,48,0,345,3, -49,0,345,3,50, -0,345,3,51,0, -345,3,52,0,345, -3,53,0,345,3, -54,0,345,3,55, -0,345,3,56,0, -345,3,57,0,345, -3,65,0,345,3, -66,0,345,3,67, -0,345,3,68,0, -345,3,69,0,345, -3,70,0,345,3, -71,0,345,3,72, -0,345,3,73,0, -345,3,74,0,345, -3,75,0,345,3, -76,0,345,3,77, -0,345,3,78,0, -345,3,79,0,345, -3,80,0,345,3, -81,0,345,3,82, -0,345,3,83,0, -345,3,84,0,345, -3,85,0,345,3, -86,0,345,3,87, -0,345,3,88,0, -345,3,89,0,345, -3,90,0,345,3, -95,0,345,3,97, -0,345,3,98,0, -345,3,99,0,345, -3,100,0,345,3, -101,0,345,3,102, -0,345,3,103,0, -345,3,104,0,345, -3,105,0,345,3, -106,0,345,3,107, -0,345,3,108,0, -345,500,11,1,867, -0,348,1,-1,3, -106,0,345,3,107, -0,345,3,108,0, -345,501,11,1,867, -0,348,1,-1,3, -116,0,345,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,345,3, -98,0,345,3,99, -0,345,3,100,0, -345,3,101,0,345, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -345,3,106,0,345, -3,107,0,345,3, -108,0,345,502,11, -1,867,0,348,1, --1,3,106,0,345, -3,107,0,345,3, -108,0,345,503,11, -1,867,0,348,1, --1,504,11,1,867, -0,348,1,-1,505, -11,1,867,0,348, -1,-1,3,112,0, -345,3,113,0,345, -3,114,0,345,3, -115,0,345,3,116, -0,345,3,117,0, -345,3,118,0,345, -3,119,0,345,3, -120,0,345,3,121, -0,345,3,122,0, -345,3,48,0,345, -3,49,0,345,3, -50,0,345,3,51, -0,345,3,52,0, -345,3,53,0,345, -3,54,0,345,3, -55,0,345,3,56, -0,345,3,57,0, -345,3,65,0,345, -3,66,0,345,3, -67,0,345,3,68, -0,345,3,69,0, -345,3,70,0,345, -3,71,0,345,3, -72,0,345,3,73, -0,345,3,74,0, -345,3,75,0,345, -3,76,0,345,3, -77,0,345,3,78, -0,345,3,79,0, -345,3,80,0,345, -3,81,0,345,3, -82,0,345,3,83, -0,345,3,84,0, -345,3,85,0,345, -3,86,0,345,3, -87,0,345,3,88, -0,345,3,89,0, -345,3,90,0,345, -3,95,0,345,3, -97,0,345,3,98, -0,345,3,99,0, -345,3,100,0,345, -3,101,0,345,3, -102,0,345,3,103, -0,345,3,104,0, -506,12,1,28191,507, -5,63,3,109,0, -345,3,110,0,345, -3,111,0,345,3, -112,0,345,3,113, -0,345,3,114,0, -345,3,115,0,345, -3,116,0,345,3, -117,0,345,3,118, -0,345,3,119,0, -345,3,120,0,345, -3,121,0,345,3, -122,0,345,3,48, -0,345,3,49,0, -345,3,50,0,345, -3,51,0,345,3, -52,0,345,3,53, -0,345,3,54,0, -345,3,55,0,345, -3,56,0,345,3, -57,0,345,3,65, -0,345,3,66,0, -345,3,67,0,345, -3,68,0,345,3, -69,0,345,3,70, -0,345,3,71,0, -345,3,72,0,345, -3,73,0,345,3, -74,0,345,3,75, -0,345,3,76,0, -345,3,77,0,345, -3,78,0,345,3, -79,0,345,3,80, -0,345,3,81,0, -345,3,82,0,345, -3,83,0,345,3, -84,0,345,3,85, -0,345,3,86,0, -345,3,87,0,345, -3,88,0,345,3, -89,0,345,3,90, -0,345,3,95,0, -345,3,97,0,508, -12,1,28234,509,5, -63,3,109,0,345, -3,110,0,510,12, -1,28263,511,5,63, -3,109,0,345,3, -110,0,345,3,111, -0,345,3,112,0, -345,3,113,0,345, -3,114,0,345,3, -115,0,345,3,116, -0,345,3,117,0, -345,3,118,0,345, -3,119,0,345,3, -120,0,345,3,121, -0,345,3,122,0, -345,3,48,0,345, -3,49,0,345,3, -50,0,345,3,51, -0,345,3,52,0, -345,3,53,0,345, -3,54,0,345,3, -55,0,345,3,56, -0,345,3,57,0, -345,3,65,0,345, -3,66,0,345,3, -67,0,345,3,68, -0,345,3,69,0, -345,3,70,0,345, -3,71,0,345,3, -72,0,345,3,73, -0,345,3,74,0, -345,3,75,0,345, -3,76,0,345,3, -77,0,345,3,78, -0,345,3,79,0, -345,3,80,0,345, -3,81,0,345,3, -82,0,345,3,83, -0,345,3,84,0, -345,3,85,0,345, -3,86,0,345,3, -87,0,345,3,88, -0,345,3,89,0, -345,3,90,0,345, -3,95,0,345,3, -97,0,345,3,98, -0,345,3,99,0, -345,3,100,0,345, -3,101,0,345,3, -102,0,345,3,103, -0,512,12,1,28312, -513,5,63,3,109, -0,345,3,110,0, -345,3,111,0,345, -3,112,0,345,3, -113,0,345,3,114, -0,345,3,115,0, -345,3,116,0,345, -3,117,0,345,3, -118,0,345,3,119, -0,345,3,120,0, -345,3,121,0,345, -3,122,0,345,3, -48,0,345,3,49, -0,345,3,50,0, -345,3,51,0,345, -3,52,0,345,3, -53,0,345,3,54, -0,345,3,55,0, -345,3,56,0,345, -3,57,0,345,3, -65,0,345,3,66, -0,345,3,67,0, -345,3,68,0,345, -3,69,0,345,3, -70,0,345,3,71, -0,345,3,72,0, -345,3,73,0,345, -3,74,0,345,3, -75,0,345,3,76, -0,345,3,77,0, -345,3,78,0,345, -3,79,0,345,3, -80,0,345,3,81, -0,345,3,82,0, -345,3,83,0,345, -3,84,0,345,3, -85,0,345,3,86, -0,345,3,87,0, -345,3,88,0,345, -3,89,0,345,3, -90,0,345,3,95, -0,345,3,97,0, -345,3,98,0,345, -3,99,0,345,3, -100,0,345,3,101, -0,514,12,1,28359, -515,5,63,3,109, -0,345,3,110,0, -345,3,111,0,345, -3,112,0,345,3, -113,0,345,3,114, -0,345,3,115,0, -345,3,116,0,345, -3,117,0,345,3, -118,0,345,3,119, -0,345,3,120,0, -345,3,121,0,345, -3,122,0,345,3, -48,0,345,3,49, -0,345,3,50,0, -345,3,51,0,345, -3,52,0,345,3, -53,0,345,3,54, -0,345,3,55,0, -345,3,56,0,345, -3,57,0,345,3, -65,0,345,3,66, -0,345,3,67,0, -345,3,68,0,345, -3,69,0,345,3, -70,0,345,3,71, -0,345,3,72,0, -345,3,73,0,345, -3,74,0,345,3, -75,0,345,3,76, -0,345,3,77,0, -345,3,78,0,345, -3,79,0,345,3, -80,0,345,3,81, -0,345,3,82,0, -345,3,83,0,345, -3,84,0,345,3, -85,0,345,3,86, -0,345,3,87,0, -345,3,88,0,345, -3,89,0,345,3, -90,0,345,3,95, -0,345,3,97,0, -345,3,98,0,345, -3,99,0,345,3, -100,0,516,12,1, -28405,517,5,63,3, -109,0,345,3,110, -0,345,3,111,0, -345,3,112,0,345, -3,113,0,345,3, -114,0,345,3,115, -0,345,3,116,0, -345,3,117,0,345, -3,118,0,345,3, -119,0,345,3,120, -0,345,3,121,0, -345,3,122,0,345, -3,48,0,345,3, -49,0,345,3,50, -0,345,3,51,0, -345,3,52,0,345, -3,53,0,345,3, -54,0,345,3,55, -0,345,3,56,0, -345,3,57,0,345, -3,65,0,345,3, -66,0,345,3,67, -0,345,3,68,0, -345,3,69,0,345, -3,70,0,345,3, -71,0,345,3,72, -0,345,3,73,0, -345,3,74,0,345, -3,75,0,345,3, -76,0,345,3,77, -0,345,3,78,0, -345,3,79,0,345, -3,80,0,345,3, -81,0,345,3,82, -0,345,3,83,0, -345,3,84,0,345, -3,85,0,345,3, -86,0,345,3,87, -0,345,3,88,0, -345,3,89,0,345, -3,90,0,345,3, -95,0,345,3,97, -0,345,3,98,0, -345,3,99,0,345, -3,100,0,345,3, -101,0,345,3,102, -0,345,3,103,0, -345,3,104,0,345, -3,105,0,345,3, -106,0,345,3,107, -0,345,3,108,0, -345,518,11,1,390, -0,519,4,26,67, -0,72,0,65,0, -78,0,71,0,69, -0,68,0,95,0, -69,0,86,0,69, -0,78,0,84,0, -1,-1,3,101,0, -345,3,102,0,345, -3,103,0,345,3, -104,0,345,3,105, -0,345,3,106,0, -345,3,107,0,345, -3,108,0,345,520, -11,1,867,0,348, -1,-1,3,102,0, -345,3,103,0,345, -3,104,0,345,3, -105,0,345,3,106, -0,345,3,107,0, -345,3,108,0,345, -521,11,1,867,0, -348,1,-1,3,104, -0,345,3,105,0, -345,3,106,0,345, -3,107,0,345,3, -108,0,345,522,11, -1,867,0,348,1, --1,3,111,0,345, -3,112,0,345,3, -113,0,345,3,114, -0,345,3,115,0, -345,3,116,0,345, -3,117,0,345,3, -118,0,345,3,119, -0,345,3,120,0, -345,3,121,0,345, -3,122,0,345,3, -48,0,345,3,49, -0,345,3,50,0, -345,3,51,0,345, -3,52,0,345,3, -53,0,345,3,54, -0,345,3,55,0, -345,3,56,0,345, -3,57,0,345,3, -65,0,345,3,66, -0,345,3,67,0, -345,3,68,0,345, -3,69,0,345,3, -70,0,345,3,71, -0,345,3,72,0, -345,3,73,0,345, -3,74,0,345,3, -75,0,345,3,76, -0,345,3,77,0, -345,3,78,0,345, -3,79,0,345,3, -80,0,345,3,81, -0,345,3,82,0, -345,3,83,0,345, -3,84,0,345,3, -85,0,345,3,86, -0,345,3,87,0, -345,3,88,0,345, -3,89,0,345,3, -90,0,345,3,95, -0,345,3,97,0, -345,3,98,0,345, -3,99,0,345,3, -100,0,345,3,101, -0,345,3,102,0, -345,3,103,0,345, -3,104,0,345,3, -105,0,345,3,106, -0,345,3,107,0, -345,3,108,0,345, -523,11,1,867,0, -348,1,-1,3,98, -0,345,3,99,0, -345,3,100,0,345, -3,101,0,345,3, -102,0,345,3,103, -0,345,3,104,0, -345,3,105,0,345, -3,106,0,345,3, -107,0,345,3,108, -0,345,524,11,1, -867,0,348,1,-1, -3,105,0,345,3, -106,0,345,3,107, -0,345,3,108,0, -345,525,11,1,867, -0,348,1,-1,3, -100,0,526,12,1, -28982,527,5,63,3, -109,0,345,3,110, -0,345,3,111,0, -528,12,1,29012,529, -5,63,3,109,0, -345,3,110,0,345, -3,111,0,345,3, -112,0,345,3,113, -0,345,3,114,0, -345,3,115,0,345, -3,116,0,345,3, -117,0,345,3,118, -0,345,3,119,0, -345,3,120,0,345, -3,121,0,345,3, -122,0,345,3,48, -0,345,3,49,0, -345,3,50,0,345, -3,51,0,345,3, -52,0,345,3,53, -0,345,3,54,0, -345,3,55,0,345, -3,56,0,345,3, -57,0,345,3,65, -0,345,3,66,0, -345,3,67,0,345, -3,68,0,345,3, -69,0,345,3,70, -0,345,3,71,0, -345,3,72,0,345, -3,73,0,345,3, -74,0,345,3,75, -0,345,3,76,0, -345,3,77,0,345, -3,78,0,345,3, -79,0,345,3,80, -0,345,3,81,0, -345,3,82,0,345, -3,83,0,345,3, -84,0,345,3,85, -0,345,3,86,0, -345,3,87,0,345, -3,88,0,345,3, -89,0,345,3,90, -0,345,3,95,0, -345,3,97,0,345, -3,98,0,345,3, -99,0,345,3,100, -0,345,3,101,0, -345,3,102,0,345, -3,103,0,345,3, -104,0,345,3,105, -0,345,3,106,0, -345,3,107,0,345, -3,108,0,345,530, -11,1,223,0,531, -4,4,68,0,79, -0,1,-1,3,112, -0,345,3,113,0, -345,3,114,0,345, -3,115,0,345,3, -116,0,345,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,532,12, -1,29145,533,5,63, -3,109,0,345,3, -110,0,345,3,111, -0,345,3,112,0, -345,3,113,0,345, -3,114,0,345,3, -115,0,345,3,116, -0,534,12,1,29180, -535,5,63,3,109, -0,345,3,110,0, -345,3,111,0,345, -3,112,0,345,3, -113,0,345,3,114, -0,345,3,115,0, -345,3,116,0,345, -3,117,0,345,3, -118,0,345,3,119, -0,345,3,120,0, -345,3,121,0,345, -3,122,0,345,3, -48,0,345,3,49, -0,345,3,50,0, -345,3,51,0,345, -3,52,0,345,3, -53,0,345,3,54, -0,345,3,55,0, -345,3,56,0,345, -3,57,0,345,3, -65,0,345,3,66, -0,345,3,67,0, -345,3,68,0,345, -3,69,0,345,3, -70,0,345,3,71, -0,345,3,72,0, -345,3,73,0,345, -3,74,0,345,3, -75,0,345,3,76, -0,345,3,77,0, -345,3,78,0,345, -3,79,0,345,3, -80,0,345,3,81, -0,345,3,82,0, -345,3,83,0,345, -3,84,0,345,3, -85,0,345,3,86, -0,345,3,87,0, -345,3,88,0,345, -3,89,0,345,3, -90,0,345,3,95, -0,345,3,97,0, -536,12,1,29223,537, -5,63,3,109,0, -345,3,110,0,345, -3,111,0,345,3, -112,0,345,3,113, -0,345,3,114,0, -345,3,115,0,538, -12,1,29257,539,5, -63,3,109,0,345, -3,110,0,345,3, -111,0,345,3,112, -0,345,3,113,0, -345,3,114,0,345, -3,115,0,345,3, -116,0,345,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,345,3, -98,0,345,3,99, -0,345,3,100,0, -345,3,101,0,540, -12,1,29304,541,5, -63,3,109,0,345, -3,110,0,345,3, -111,0,345,3,112, -0,345,3,113,0, -345,3,114,0,542, -12,1,29337,543,5, -63,3,109,0,345, -3,110,0,345,3, -111,0,345,3,112, -0,345,3,113,0, -345,3,114,0,345, -3,115,0,345,3, -116,0,345,3,117, -0,345,3,118,0, -544,12,1,29374,545, -5,63,3,109,0, -345,3,110,0,345, -3,111,0,345,3, -112,0,345,3,113, -0,345,3,114,0, -345,3,115,0,345, -3,116,0,345,3, -117,0,345,3,118, -0,345,3,119,0, -345,3,120,0,345, -3,121,0,345,3, -122,0,345,3,48, -0,345,3,49,0, -345,3,50,0,345, -3,51,0,345,3, -52,0,345,3,53, -0,345,3,54,0, -345,3,55,0,345, -3,56,0,345,3, -57,0,345,3,65, -0,345,3,66,0, -345,3,67,0,345, -3,68,0,345,3, -69,0,345,3,70, -0,345,3,71,0, -345,3,72,0,345, -3,73,0,345,3, -74,0,345,3,75, -0,345,3,76,0, -345,3,77,0,345, -3,78,0,345,3, -79,0,345,3,80, -0,345,3,81,0, -345,3,82,0,345, -3,83,0,345,3, -84,0,345,3,85, -0,345,3,86,0, -345,3,87,0,345, -3,88,0,345,3, -89,0,345,3,90, -0,345,3,95,0, -345,3,97,0,345, -3,98,0,345,3, -99,0,345,3,100, -0,345,3,101,0, -546,12,1,29421,547, -5,63,3,109,0, -345,3,110,0,345, -3,111,0,345,3, -112,0,345,3,113, -0,345,3,114,0, -548,12,1,29454,549, -5,63,3,109,0, -345,3,110,0,345, -3,111,0,345,3, -112,0,345,3,113, -0,345,3,114,0, -345,3,115,0,345, -3,116,0,345,3, -117,0,345,3,118, -0,345,3,119,0, -345,3,120,0,345, -3,121,0,345,3, -122,0,345,3,48, -0,345,3,49,0, -345,3,50,0,345, -3,51,0,345,3, -52,0,345,3,53, -0,345,3,54,0, -345,3,55,0,345, -3,56,0,345,3, -57,0,345,3,65, -0,345,3,66,0, -345,3,67,0,345, -3,68,0,345,3, -69,0,345,3,70, -0,345,3,71,0, -345,3,72,0,345, -3,73,0,345,3, -74,0,345,3,75, -0,345,3,76,0, -345,3,77,0,345, -3,78,0,345,3, -79,0,345,3,80, -0,345,3,81,0, -345,3,82,0,345, -3,83,0,345,3, -84,0,345,3,85, -0,345,3,86,0, -345,3,87,0,345, -3,88,0,345,3, -89,0,345,3,90, -0,345,3,95,0, -345,3,97,0,345, -3,98,0,345,3, -99,0,345,3,100, -0,345,3,101,0, -345,3,102,0,345, -3,103,0,345,3, -104,0,345,3,105, -0,345,3,106,0, -345,3,107,0,345, -3,108,0,345,550, -11,1,461,0,551, -4,32,68,0,65, +83,0,180,3,56, +0,180,3,118,0, +180,3,99,0,180, +3,72,0,180,3, +107,0,180,3,80, +0,180,3,53,0, +180,3,115,0,180, +3,88,0,180,3, +69,0,180,3,104, +0,180,3,77,0, +180,3,50,0,180, +3,112,0,180,3, +85,0,180,3,120, +0,180,3,66,0, +180,3,101,0,180, +3,74,0,180,3, +109,0,180,3,82, +0,180,3,55,0, +180,3,117,0,180, +3,90,0,180,3, +98,0,180,3,71, +0,180,3,106,0, +180,3,79,0,180, +3,52,0,180,3, +114,0,180,3,87, +0,180,3,122,0, +180,3,95,0,180, +3,68,0,180,3, +103,0,180,3,76, +0,180,3,49,0, +180,3,111,0,180, +3,84,0,180,3, +57,0,180,3,119, +0,180,3,65,0, +180,3,100,0,180, +3,73,0,180,3, +108,0,180,3,81, +0,180,3,54,0, +180,3,116,0,180, +3,89,0,180,635, +11,1,867,0,183, +1,-1,3,84,0, +180,3,57,0,180, +3,119,0,180,3, +65,0,180,3,100, +0,180,3,73,0, +180,3,108,0,180, +3,81,0,180,3, +54,0,180,3,116, +0,180,3,89,0, +180,636,11,1,867, +0,183,1,-1,3, +78,0,180,3,51, +0,180,3,113,0, +180,3,86,0,180, +3,121,0,180,3, +67,0,180,3,102, +0,180,3,75,0, +180,3,48,0,180, +3,110,0,180,3, +83,0,180,3,56, +0,180,3,118,0, +180,3,99,0,180, +3,72,0,180,3, +107,0,180,3,80, +0,180,3,53,0, +180,3,115,0,180, +3,88,0,180,3, +69,0,180,3,104, +0,180,3,77,0, +180,3,50,0,180, +3,112,0,180,3, +85,0,180,3,120, +0,180,3,66,0, +180,3,101,0,180, +3,74,0,180,3, +109,0,180,3,82, +0,180,3,55,0, +180,3,117,0,180, +3,90,0,180,3, +98,0,180,3,71, +0,180,3,106,0, +180,3,79,0,180, +3,52,0,180,3, +114,0,180,3,87, +0,180,3,122,0, +180,3,95,0,180, +3,68,0,180,3, +103,0,180,3,76, +0,180,3,49,0, +180,3,111,0,180, +3,84,0,180,3, +57,0,180,3,119, +0,180,3,65,0, +180,3,100,0,180, +3,73,0,180,3, +108,0,180,3,81, +0,180,3,54,0, +180,3,116,0,180, +3,89,0,180,637, +11,1,867,0,183, +1,-1,3,88,0, +180,3,69,0,180, +3,104,0,180,3, +77,0,180,3,50, +0,180,3,112,0, +180,3,85,0,180, +3,120,0,180,3, +66,0,180,3,101, +0,180,3,74,0, +180,3,109,0,180, +3,82,0,180,3, +55,0,180,3,117, +0,180,3,90,0, +180,3,98,0,180, +3,71,0,180,3, +106,0,180,3,79, +0,180,3,52,0, +180,3,114,0,180, +3,87,0,180,3, +122,0,180,3,95, +0,180,3,68,0, +180,3,103,0,180, +3,76,0,180,3, +49,0,180,3,111, +0,180,3,84,0, +180,3,57,0,180, +3,119,0,180,3, +65,0,180,3,100, +0,180,3,73,0, +180,3,108,0,180, +3,81,0,180,3, +54,0,180,3,116, +0,180,3,89,0, +180,638,11,1,867, +0,183,1,-1,3, +78,0,180,3,51, +0,180,3,113,0, +180,3,86,0,180, +3,121,0,180,3, +67,0,180,3,102, +0,180,3,75,0, +180,3,48,0,180, +3,110,0,180,3, +83,0,180,3,56, +0,180,3,118,0, +180,3,99,0,180, +3,72,0,180,3, +107,0,180,3,80, +0,180,3,53,0, +180,3,115,0,180, +3,88,0,180,3, +69,0,180,3,104, +0,180,3,77,0, +180,3,50,0,180, +3,112,0,180,3, +85,0,180,3,120, +0,180,3,66,0, +180,3,101,0,180, +3,74,0,180,3, +109,0,180,3,82, +0,180,3,55,0, +180,3,117,0,180, +3,90,0,180,3, +98,0,180,3,71, +0,180,3,106,0, +180,3,79,0,180, +3,52,0,180,3, +114,0,180,3,87, +0,180,3,122,0, +180,3,95,0,180, +3,68,0,180,3, +103,0,180,3,76, +0,180,3,49,0, +180,3,111,0,180, +3,84,0,180,3, +57,0,180,3,119, +0,180,3,65,0, +180,3,100,0,180, +3,73,0,180,3, +108,0,180,3,81, +0,180,3,54,0, +180,3,116,0,180, +3,89,0,180,639, +11,1,867,0,183, +1,-1,3,81,0, +180,3,54,0,180, +3,116,0,180,3, +89,0,180,640,11, +1,867,0,183,1, +-1,3,81,0,180, +3,54,0,180,3, +116,0,180,3,89, +0,180,641,11,1, +867,0,183,1,-1, +3,84,0,180,3, +57,0,180,3,119, +0,180,3,65,0, +180,3,100,0,180, +3,73,0,180,3, +108,0,180,3,81, +0,180,3,54,0, +180,3,116,0,180, +3,89,0,180,642, +11,1,867,0,183, +1,-1,3,59,0, +643,12,1,4588,644, +5,0,645,11,1, +46,0,646,4,18, +83,0,69,0,77, +0,73,0,67,0, +79,0,76,0,79, +0,78,0,1,-1, +3,56,0,647,12, +1,8827,648,5,11, +3,50,0,647,3, +49,0,647,3,57, +0,647,3,48,0, +647,3,56,0,647, +3,55,0,647,3, +46,0,649,12,1, +8844,650,5,14,3, +48,0,651,12,1, +5724,652,5,14,3, +48,0,651,3,70, +0,653,12,1,5795, +654,5,0,655,11, +1,904,0,656,4, +28,70,0,76,0, +79,0,65,0,84, +0,95,0,67,0, +79,0,78,0,83, 0,84,0,65,0, -83,0,69,0,82, -0,86,0,69,0, -82,0,95,0,69, +78,0,84,0,1, +-1,3,55,0,651, +3,51,0,651,3, +69,0,657,12,1, +5924,658,5,12,3, +50,0,659,12,1, +5983,660,5,12,3, +50,0,659,3,49, +0,659,3,57,0, +659,3,48,0,659, +3,56,0,659,3, +102,0,653,3,55, +0,659,3,70,0, +653,3,54,0,659, +3,53,0,659,3, +52,0,659,3,51, +0,659,661,11,1, +904,0,656,1,-1, +3,49,0,659,3, +57,0,659,3,48, +0,659,3,56,0, +659,3,55,0,659, +3,54,0,659,3, +45,0,662,12,1, +5933,663,5,10,3, +50,0,659,3,49, +0,659,3,57,0, +659,3,48,0,659, +3,56,0,659,3, +55,0,659,3,54, +0,659,3,53,0, +659,3,52,0,659, +3,51,0,659,0, +165,1,-1,3,53, +0,659,3,52,0, +659,3,43,0,662, +3,51,0,659,0, +165,1,-1,3,54, +0,651,3,102,0, +653,3,50,0,651, +3,57,0,651,3, +53,0,651,3,101, +0,657,3,49,0, +651,3,56,0,651, +3,52,0,651,664, +11,1,904,0,656, +1,-1,3,70,0, +653,3,55,0,651, +3,51,0,651,3, +69,0,657,3,54, +0,651,3,102,0, +653,3,50,0,651, +3,57,0,651,3, +53,0,651,3,101, +0,657,3,49,0, +651,3,56,0,651, +3,52,0,651,665, +11,1,904,0,656, +1,-1,3,54,0, +647,3,53,0,647, +3,52,0,647,3, +51,0,647,666,11, +1,879,0,667,4, +32,73,0,78,0, +84,0,69,0,71, +0,69,0,82,0, +95,0,67,0,79, +0,78,0,83,0, +84,0,65,0,78, +0,84,0,1,-1, +3,93,0,668,12, +1,7362,669,5,0, +670,11,1,131,0, +671,4,26,82,0, +73,0,71,0,72, +0,84,0,95,0, +66,0,82,0,65, +0,67,0,75,0, +69,0,84,0,1, +-1,3,53,0,647, +3,13,0,672,12, +1,8696,673,5,0, +674,11,1,1072,0, +165,1,-1,3,90, +0,178,3,50,0, +647,3,10,0,672, +3,87,0,178,3, +47,0,675,12,1, +5072,676,5,3,3, +61,0,677,12,1, +5080,678,5,0,679, +11,1,34,0,680, +4,24,83,0,76, +0,65,0,83,0, +72,0,95,0,69, +0,81,0,85,0, +65,0,76,0,83, +0,1,-1,3,47, +0,681,12,1,5207, +682,5,118,3,238, +22,683,12,1,5208, +684,5,118,3,238, +22,683,3,117,0, +683,3,63,32,683, +3,37,0,683,3, +114,0,683,3,74, +0,683,3,34,0, +683,3,111,0,683, +3,71,0,683,3, +108,0,683,3,68, +0,683,3,105,0, +683,3,65,0,683, +3,102,0,683,3, +62,0,683,3,99, +0,683,3,59,0, +683,3,96,0,683, +3,96,6,683,3, +173,0,683,3,93, +0,683,3,53,0, +683,3,13,0,683, +3,170,0,683,3, +90,0,683,3,50, +0,683,3,87,0, +683,3,47,0,683, +3,100,0,683,3, +124,0,683,3,84, +0,683,3,44,0, +683,3,121,0,683, +3,81,0,683,3, +41,0,683,3,1, +0,683,3,59,15, +683,3,78,0,683, +3,38,0,683,3, +58,15,683,3,115, +0,683,3,75,0, +683,3,35,0,683, +3,192,0,683,3, +112,0,683,3,72, +0,683,3,32,0, +683,3,109,0,683, +3,69,0,683,3, +187,1,683,3,106, +0,683,3,66,0, +683,3,103,0,683, +3,77,0,683,3, +3,9,683,3,118, +0,683,3,60,0, +683,3,0,3,683, +3,197,1,683,3, +176,2,683,3,57, +0,683,3,70,0, +683,3,94,0,683, +3,54,0,683,3, +171,0,683,3,91, +0,683,3,51,0, +683,3,88,0,683, +3,48,0,683,3, +125,0,683,3,85, +0,683,3,56,0, +683,3,97,0,683, +3,122,0,683,3, +82,0,683,3,42, +0,683,3,0,6, +683,3,119,0,683, +3,79,0,683,3, +41,32,683,3,116, +0,683,3,76,0, +683,3,36,0,683, +3,113,0,683,3, +73,0,683,3,33, +0,683,3,110,0, +683,3,40,32,683, +3,0,224,683,3, +187,0,683,3,107, +0,683,3,67,0, +683,3,104,0,683, +3,64,0,683,3, +101,0,683,3,61, +0,683,3,178,0, +683,3,98,0,683, +3,45,0,683,3, +136,4,683,3,95, +0,683,3,55,0, +683,3,172,0,683, +3,92,0,683,3, +52,0,683,3,89, +0,683,3,49,0, +683,3,9,0,683, +3,126,0,683,3, +86,0,683,3,46, +0,683,3,123,0, +683,3,83,0,683, +3,43,0,683,3, +160,0,683,3,120, +0,683,3,80,0, +683,3,40,0,683, +685,11,1,1076,0, +165,1,-1,3,117, +0,683,3,63,32, +683,3,37,0,683, +3,114,0,683,3, +74,0,683,3,34, +0,683,3,111,0, +683,3,71,0,683, +3,108,0,683,3, +68,0,683,3,105, +0,683,3,65,0, +683,3,102,0,683, +3,62,0,683,3, +99,0,683,3,59, +0,683,3,96,0, +683,3,96,6,683, +3,173,0,683,3, +93,0,683,3,53, +0,683,3,13,0, +683,3,170,0,683, +3,90,0,683,3, +50,0,683,3,87, +0,683,3,47,0, +683,3,100,0,683, +3,124,0,683,3, +84,0,683,3,44, +0,683,3,121,0, +683,3,81,0,683, +3,41,0,683,3, +1,0,683,3,59, +15,683,3,78,0, +683,3,38,0,683, +3,58,15,683,3, +115,0,683,3,75, +0,683,3,35,0, +683,3,192,0,683, +3,112,0,683,3, +72,0,683,3,32, +0,683,3,109,0, +683,3,69,0,683, +3,187,1,683,3, +106,0,683,3,66, +0,683,3,103,0, +683,3,77,0,683, +3,3,9,683,3, +118,0,683,3,60, +0,683,3,0,3, +683,3,197,1,683, +3,176,2,683,3, +57,0,683,3,70, +0,683,3,94,0, +683,3,54,0,683, +3,171,0,683,3, +91,0,683,3,51, +0,683,3,88,0, +683,3,48,0,683, +3,125,0,683,3, +85,0,683,3,56, +0,683,3,97,0, +683,3,122,0,683, +3,82,0,683,3, +42,0,683,3,0, +6,683,3,119,0, +683,3,79,0,683, +3,41,32,683,3, +116,0,683,3,76, +0,683,3,36,0, +683,3,113,0,683, +3,73,0,683,3, +33,0,683,3,110, +0,683,3,40,32, +683,3,0,224,683, +3,187,0,683,3, +107,0,683,3,67, +0,683,3,104,0, +683,3,64,0,683, +3,101,0,683,3, +61,0,683,3,178, +0,683,3,98,0, +683,3,45,0,683, +3,136,4,683,3, +95,0,683,3,55, +0,683,3,172,0, +683,3,92,0,683, +3,52,0,683,3, +89,0,683,3,49, +0,683,3,9,0, +683,3,126,0,683, +3,86,0,683,3, +46,0,683,3,123, +0,683,3,83,0, +683,3,43,0,683, +3,160,0,683,3, +120,0,683,3,80, +0,683,3,40,0, +683,686,11,1,1076, +0,165,1,-1,3, +42,0,687,12,1, +5450,688,5,0,689, +11,1,1037,0,165, +1,-1,690,11,1, +96,0,691,4,10, +83,0,76,0,65, +0,83,0,72,0, +1,-1,3,124,0, +692,12,1,3262,693, +5,1,3,124,0, +694,12,1,3267,695, +5,0,696,11,1, +191,0,697,4,26, +83,0,84,0,82, +0,79,0,75,0, +69,0,95,0,83, +0,84,0,82,0, +79,0,75,0,69, +0,1,-1,698,11, +1,165,0,699,4, +12,83,0,84,0, +82,0,79,0,75, +0,69,0,1,-1, +3,84,0,178,3, +44,0,700,12,1, +4950,701,5,0,702, +11,1,61,0,703, +4,10,67,0,79, +0,77,0,77,0, +65,0,1,-1,3, +121,0,178,3,81, +0,178,3,41,0, +704,12,1,7604,705, +5,0,706,11,1, +76,0,707,4,22, +82,0,73,0,71, +0,72,0,84,0, +95,0,80,0,65, +0,82,0,69,0, +78,0,1,-1,3, +118,0,708,12,1, +17610,709,5,63,3, +97,0,180,3,70, +0,180,3,105,0, +180,3,78,0,180, +3,51,0,180,3, +113,0,180,3,86, +0,180,3,121,0, +180,3,67,0,180, +3,102,0,180,3, +75,0,180,3,48, +0,180,3,110,0, +180,3,83,0,180, +3,56,0,180,3, +118,0,180,3,99, +0,180,3,72,0, +180,3,107,0,180, +3,80,0,180,3, +53,0,180,3,115, +0,180,3,88,0, +180,3,69,0,180, +3,104,0,180,3, +77,0,180,3,50, +0,180,3,112,0, +180,3,85,0,180, +3,120,0,180,3, +66,0,180,3,101, +0,710,12,1,17690, +711,5,63,3,97, +0,180,3,70,0, +180,3,105,0,180, +3,78,0,180,3, +51,0,180,3,113, +0,180,3,86,0, +180,3,121,0,180, +3,67,0,180,3, +102,0,180,3,75, +0,180,3,48,0, +180,3,110,0,180, +3,83,0,180,3, +56,0,180,3,118, +0,180,3,99,0, +712,12,1,17764,713, +5,63,3,97,0, +180,3,70,0,180, +3,105,0,180,3, +78,0,180,3,51, +0,180,3,113,0, +180,3,86,0,180, +3,121,0,180,3, +67,0,180,3,102, +0,180,3,75,0, +180,3,48,0,180, +3,110,0,180,3, +83,0,180,3,56, +0,180,3,118,0, +180,3,99,0,180, +3,72,0,180,3, +107,0,180,3,80, +0,180,3,53,0, +180,3,115,0,180, +3,88,0,180,3, +69,0,180,3,104, +0,180,3,77,0, +180,3,50,0,180, +3,112,0,180,3, +85,0,180,3,120, +0,180,3,66,0, +180,3,101,0,180, +3,74,0,180,3, +109,0,180,3,82, +0,180,3,55,0, +180,3,117,0,180, +3,90,0,180,3, +98,0,180,3,71, +0,180,3,106,0, +180,3,79,0,180, +3,52,0,180,3, +114,0,180,3,87, +0,180,3,122,0, +180,3,95,0,180, +3,68,0,180,3, +103,0,180,3,76, +0,180,3,49,0, +180,3,111,0,180, +3,84,0,180,3, +57,0,180,3,119, +0,180,3,65,0, +180,3,100,0,180, +3,73,0,180,3, +108,0,180,3,81, +0,180,3,54,0, +180,3,116,0,714, +12,1,17857,715,5, +63,3,97,0,180, +3,70,0,180,3, +105,0,180,3,78, +0,180,3,51,0, +180,3,113,0,180, +3,86,0,180,3, +121,0,180,3,67, +0,180,3,102,0, +180,3,75,0,180, +3,48,0,180,3, +110,0,180,3,83, +0,180,3,56,0, +180,3,118,0,180, +3,99,0,180,3, +72,0,180,3,107, +0,180,3,80,0, +180,3,53,0,180, +3,115,0,180,3, +88,0,180,3,69, +0,180,3,104,0, +180,3,77,0,180, +3,50,0,180,3, +112,0,180,3,85, +0,180,3,120,0, +180,3,66,0,180, +3,101,0,180,3, +74,0,180,3,109, +0,180,3,82,0, +180,3,55,0,180, +3,117,0,180,3, +90,0,180,3,98, +0,180,3,71,0, +180,3,106,0,180, +3,79,0,180,3, +52,0,180,3,114, +0,180,3,87,0, +180,3,122,0,180, +3,95,0,180,3, +68,0,180,3,103, +0,180,3,76,0, +180,3,49,0,180, +3,111,0,716,12, +1,17945,717,5,63, +3,97,0,180,3, +70,0,180,3,105, +0,180,3,78,0, +180,3,51,0,180, +3,113,0,180,3, +86,0,180,3,121, +0,180,3,67,0, +180,3,102,0,180, +3,75,0,180,3, +48,0,180,3,110, +0,180,3,83,0, +180,3,56,0,180, +3,118,0,180,3, +99,0,180,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,180,3,88, +0,180,3,69,0, +180,3,104,0,180, +3,77,0,180,3, +50,0,180,3,112, +0,180,3,85,0, +180,3,120,0,180, +3,66,0,180,3, +101,0,180,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +718,12,1,18030,719, +5,63,3,97,0, +180,3,70,0,180, +3,105,0,180,3, +78,0,180,3,51, +0,180,3,113,0, +180,3,86,0,180, +3,121,0,180,3, +67,0,180,3,102, +0,180,3,75,0, +180,3,48,0,180, +3,110,0,180,3, +83,0,180,3,56, +0,180,3,118,0, +180,3,99,0,180, +3,72,0,180,3, +107,0,180,3,80, +0,180,3,53,0, +180,3,115,0,180, +3,88,0,180,3, +69,0,180,3,104, +0,180,3,77,0, +180,3,50,0,180, +3,112,0,180,3, +85,0,180,3,120, +0,180,3,66,0, +180,3,101,0,180, +3,74,0,180,3, +109,0,180,3,82, +0,180,3,55,0, +180,3,117,0,180, +3,90,0,180,3, +98,0,180,3,71, +0,180,3,106,0, +180,3,79,0,180, +3,52,0,180,3, +114,0,180,3,87, +0,180,3,122,0, +180,3,95,0,180, +3,68,0,180,3, +103,0,180,3,76, +0,180,3,49,0, +180,3,111,0,180, +3,84,0,180,3, +57,0,180,3,119, +0,180,3,65,0, +180,3,100,0,180, +3,73,0,180,3, +108,0,180,3,81, +0,180,3,54,0, +180,3,116,0,180, +3,89,0,180,720, +11,1,320,0,721, +4,22,86,0,69, +0,67,0,84,0, +79,0,82,0,95, +0,84,0,89,0, +80,0,69,0,1, +-1,3,87,0,180, +3,122,0,180,3, +95,0,180,3,68, +0,180,3,103,0, +180,3,76,0,180, +3,49,0,180,3, +111,0,180,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,180,3,73, +0,180,3,108,0, +180,3,81,0,180, +3,54,0,180,3, +116,0,180,3,89, +0,180,722,11,1, +867,0,183,1,-1, +3,84,0,180,3, +57,0,180,3,119, +0,180,3,65,0, +180,3,100,0,180, +3,73,0,180,3, +108,0,180,3,81, +0,180,3,54,0, +180,3,116,0,180, +3,89,0,180,723, +11,1,867,0,183, +1,-1,3,89,0, +180,724,11,1,867, +0,183,1,-1,3, +72,0,180,3,107, +0,180,3,80,0, +180,3,53,0,180, +3,115,0,180,3, +88,0,180,3,69, +0,180,3,104,0, +180,3,77,0,180, +3,50,0,180,3, +112,0,180,3,85, +0,180,3,120,0, +180,3,66,0,180, +3,101,0,180,3, +74,0,180,3,109, +0,180,3,82,0, +180,3,55,0,180, +3,117,0,180,3, +90,0,180,3,98, +0,180,3,71,0, +180,3,106,0,180, +3,79,0,180,3, +52,0,180,3,114, +0,180,3,87,0, +180,3,122,0,180, +3,95,0,180,3, +68,0,180,3,103, +0,180,3,76,0, +180,3,49,0,180, +3,111,0,180,3, +84,0,180,3,57, +0,180,3,119,0, +180,3,65,0,180, +3,100,0,180,3, +73,0,180,3,108, +0,180,3,81,0, +180,3,54,0,180, +3,116,0,180,3, +89,0,180,725,11, +1,867,0,183,1, +-1,3,74,0,180, +3,109,0,180,3, +82,0,180,3,55, +0,180,3,117,0, +180,3,90,0,180, +3,98,0,180,3, +71,0,180,3,106, +0,180,3,79,0, +180,3,52,0,180, +3,114,0,180,3, +87,0,180,3,122, +0,180,3,95,0, +180,3,68,0,180, +3,103,0,180,3, +76,0,180,3,49, +0,180,3,111,0, +180,3,84,0,180, +3,57,0,180,3, +119,0,180,3,65, +0,180,3,100,0, +180,3,73,0,180, +3,108,0,180,3, +81,0,180,3,54, +0,180,3,116,0, +180,3,89,0,180, +726,11,1,867,0, +183,1,-1,3,78, +0,178,3,38,0, +727,12,1,6757,728, +5,1,3,38,0, +729,12,1,6777,730, +5,0,731,11,1, +185,0,732,4,14, +65,0,77,0,80, +0,95,0,65,0, +77,0,80,0,1, +-1,733,11,1,160, +0,734,4,6,65, +0,77,0,80,0, +1,-1,3,115,0, +735,12,1,22173,736, +5,63,3,97,0, +180,3,70,0,180, +3,105,0,180,3, +78,0,180,3,51, +0,180,3,113,0, +180,3,86,0,180, +3,121,0,180,3, +67,0,180,3,102, +0,180,3,75,0, +180,3,48,0,180, +3,110,0,180,3, +83,0,180,3,56, +0,180,3,118,0, +180,3,99,0,180, +3,72,0,180,3, +107,0,180,3,80, +0,180,3,53,0, +180,3,115,0,180, +3,88,0,180,3, +69,0,180,3,104, +0,180,3,77,0, +180,3,50,0,180, +3,112,0,180,3, +85,0,180,3,120, +0,180,3,66,0, +180,3,101,0,737, +12,1,22253,738,5, +63,3,97,0,180, +3,70,0,180,3, +105,0,180,3,78, +0,180,3,51,0, +180,3,113,0,180, +3,86,0,180,3, +121,0,180,3,67, +0,180,3,102,0, +180,3,75,0,180, +3,48,0,180,3, +110,0,739,12,1, +22325,740,5,63,3, +97,0,180,3,70, +0,180,3,105,0, +180,3,78,0,180, +3,51,0,180,3, +113,0,180,3,86, +0,180,3,121,0, +180,3,67,0,180, +3,102,0,180,3, +75,0,180,3,48, +0,180,3,110,0, +180,3,83,0,180, +3,56,0,180,3, +118,0,180,3,99, +0,180,3,72,0, +180,3,107,0,180, +3,80,0,180,3, +53,0,180,3,115, +0,741,12,1,22401, +742,5,63,3,97, +0,180,3,70,0, +180,3,105,0,180, +3,78,0,180,3, +51,0,180,3,113, +0,180,3,86,0, +180,3,121,0,180, +3,67,0,180,3, +102,0,180,3,75, +0,180,3,48,0, +180,3,110,0,180, +3,83,0,180,3, +56,0,180,3,118, +0,180,3,99,0, +180,3,72,0,180, +3,107,0,180,3, +80,0,180,3,53, +0,180,3,115,0, +180,3,88,0,180, +3,69,0,180,3, +104,0,180,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,180,3,66, +0,180,3,101,0, +180,3,74,0,180, +3,109,0,180,3, +82,0,180,3,55, +0,180,3,117,0, +180,3,90,0,180, +3,98,0,180,3, +71,0,180,3,106, +0,180,3,79,0, +180,3,52,0,180, +3,114,0,180,3, +87,0,180,3,122, +0,180,3,95,0, +180,3,68,0,180, +3,103,0,180,3, +76,0,180,3,49, +0,180,3,111,0, +743,12,1,22489,744, +5,63,3,97,0, +180,3,70,0,180, +3,105,0,180,3, +78,0,180,3,51, +0,180,3,113,0, +180,3,86,0,180, +3,121,0,180,3, +67,0,180,3,102, +0,180,3,75,0, +180,3,48,0,180, +3,110,0,180,3, +83,0,180,3,56, +0,180,3,118,0, +180,3,99,0,180, +3,72,0,180,3, +107,0,180,3,80, +0,180,3,53,0, +180,3,115,0,180, +3,88,0,180,3, +69,0,180,3,104, +0,180,3,77,0, +180,3,50,0,180, +3,112,0,180,3, +85,0,180,3,120, +0,180,3,66,0, +180,3,101,0,180, +3,74,0,180,3, +109,0,180,3,82, +0,180,3,55,0, +180,3,117,0,180, +3,90,0,180,3, +98,0,180,3,71, +0,180,3,106,0, +180,3,79,0,180, +3,52,0,180,3, +114,0,745,12,1, +22574,746,5,63,3, +97,0,180,3,70, +0,180,3,105,0, +180,3,78,0,180, +3,51,0,180,3, +113,0,180,3,86, +0,180,3,121,0, +180,3,67,0,180, +3,102,0,180,3, +75,0,180,3,48, +0,180,3,110,0, +180,3,83,0,180, +3,56,0,180,3, +118,0,180,3,99, +0,180,3,72,0, +180,3,107,0,180, +3,80,0,180,3, +53,0,180,3,115, +0,180,3,88,0, +180,3,69,0,180, +3,104,0,180,3, +77,0,180,3,50, +0,180,3,112,0, +180,3,85,0,180, +3,120,0,180,3, +66,0,180,3,101, +0,180,3,74,0, +180,3,109,0,180, +3,82,0,180,3, +55,0,180,3,117, +0,180,3,90,0, +180,3,98,0,180, +3,71,0,180,3, +106,0,180,3,79, +0,180,3,52,0, +180,3,114,0,180, +3,87,0,180,3, +122,0,180,3,95, +0,180,3,68,0, +180,3,103,0,180, +3,76,0,180,3, +49,0,180,3,111, +0,180,3,84,0, +180,3,57,0,180, +3,119,0,180,3, +65,0,180,3,100, +0,180,3,73,0, +180,3,108,0,180, +3,81,0,180,3, +54,0,180,3,116, +0,180,3,89,0, +180,747,11,1,744, +0,748,4,24,83, +0,69,0,78,0, +83,0,79,0,82, +0,95,0,69,0, +86,0,69,0,78, +0,84,0,1,-1, +3,87,0,180,3, +122,0,180,3,95, +0,180,3,68,0, +180,3,103,0,180, +3,76,0,180,3, +49,0,180,3,111, +0,180,3,84,0, +180,3,57,0,180, +3,119,0,180,3, +65,0,180,3,100, +0,180,3,73,0, +180,3,108,0,180, +3,81,0,180,3, +54,0,180,3,116, +0,180,3,89,0, +180,749,11,1,867, +0,183,1,-1,3, +84,0,180,3,57, +0,180,3,119,0, +180,3,65,0,180, +3,100,0,180,3, +73,0,180,3,108, +0,180,3,81,0, +180,3,54,0,180, +3,116,0,180,3, +89,0,180,750,11, +1,867,0,183,1, +-1,3,88,0,180, +3,69,0,180,3, +104,0,180,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,180,3,66, +0,180,3,101,0, +180,3,74,0,180, +3,109,0,180,3, +82,0,180,3,55, +0,180,3,117,0, +180,3,90,0,180, +3,98,0,180,3, +71,0,180,3,106, +0,180,3,79,0, +180,3,52,0,180, +3,114,0,180,3, +87,0,180,3,122, +0,180,3,95,0, +180,3,68,0,180, +3,103,0,180,3, +76,0,180,3,49, +0,180,3,111,0, +180,3,84,0,180, +3,57,0,180,3, +119,0,180,3,65, +0,180,3,100,0, +180,3,73,0,180, +3,108,0,180,3, +81,0,180,3,54, +0,180,3,116,0, +180,3,89,0,180, +751,11,1,867,0, +183,1,-1,3,83, +0,180,3,56,0, +180,3,118,0,180, +3,99,0,180,3, +72,0,180,3,107, +0,180,3,80,0, +180,3,53,0,180, +3,115,0,180,3, +88,0,180,3,69, +0,180,3,104,0, +180,3,77,0,180, +3,50,0,180,3, +112,0,180,3,85, +0,180,3,120,0, +180,3,66,0,180, +3,101,0,180,3, +74,0,180,3,109, +0,180,3,82,0, +180,3,55,0,180, +3,117,0,180,3, +90,0,180,3,98, +0,180,3,71,0, +180,3,106,0,180, +3,79,0,180,3, +52,0,180,3,114, +0,180,3,87,0, +180,3,122,0,180, +3,95,0,180,3, +68,0,180,3,103, +0,180,3,76,0, +180,3,49,0,180, +3,111,0,180,3, +84,0,180,3,57, +0,180,3,119,0, +180,3,65,0,180, +3,100,0,180,3, +73,0,180,3,108, +0,180,3,81,0, +180,3,54,0,180, +3,116,0,180,3, +89,0,180,752,11, +1,867,0,183,1, +-1,3,74,0,180, +3,109,0,180,3, +82,0,180,3,55, +0,180,3,117,0, +180,3,90,0,180, +3,98,0,180,3, +71,0,180,3,106, +0,180,3,79,0, +180,3,52,0,180, +3,114,0,180,3, +87,0,180,3,122, +0,180,3,95,0, +180,3,68,0,180, +3,103,0,180,3, +76,0,180,3,49, +0,180,3,111,0, +180,3,84,0,180, +3,57,0,180,3, +119,0,180,3,65, +0,180,3,100,0, +180,3,73,0,180, +3,108,0,180,3, +81,0,180,3,54, +0,180,3,116,0, +753,12,1,22866,754, +5,63,3,97,0, +755,12,1,22933,756, +5,63,3,97,0, +180,3,70,0,180, +3,105,0,180,3, +78,0,180,3,51, +0,180,3,113,0, +180,3,86,0,180, +3,121,0,180,3, +67,0,180,3,102, +0,180,3,75,0, +180,3,48,0,180, +3,110,0,180,3, +83,0,180,3,56, +0,180,3,118,0, +180,3,99,0,180, +3,72,0,180,3, +107,0,180,3,80, +0,180,3,53,0, +180,3,115,0,180, +3,88,0,180,3, +69,0,180,3,104, +0,180,3,77,0, +180,3,50,0,180, +3,112,0,180,3, +85,0,180,3,120, +0,180,3,66,0, +180,3,101,0,180, +3,74,0,180,3, +109,0,180,3,82, +0,180,3,55,0, +180,3,117,0,180, +3,90,0,180,3, +98,0,180,3,71, +0,180,3,106,0, +180,3,79,0,180, +3,52,0,180,3, +114,0,180,3,87, +0,180,3,122,0, +180,3,95,0,180, +3,68,0,180,3, +103,0,180,3,76, +0,180,3,49,0, +180,3,111,0,180, +3,84,0,180,3, +57,0,180,3,119, +0,180,3,65,0, +180,3,100,0,180, +3,73,0,180,3, +108,0,180,3,81, +0,180,3,54,0, +180,3,116,0,757, +12,1,23026,758,5, +63,3,97,0,180, +3,70,0,180,3, +105,0,180,3,78, +0,180,3,51,0, +180,3,113,0,180, +3,86,0,180,3, +121,0,180,3,67, +0,180,3,102,0, +180,3,75,0,180, +3,48,0,180,3, +110,0,180,3,83, +0,180,3,56,0, +180,3,118,0,180, +3,99,0,180,3, +72,0,180,3,107, +0,180,3,80,0, +180,3,53,0,180, +3,115,0,180,3, +88,0,180,3,69, +0,180,3,104,0, +180,3,77,0,180, +3,50,0,180,3, +112,0,180,3,85, +0,180,3,120,0, +180,3,66,0,180, +3,101,0,759,12, +1,23106,760,5,63, +3,97,0,180,3, +70,0,180,3,105, +0,180,3,78,0, +180,3,51,0,180, +3,113,0,180,3, +86,0,180,3,121, +0,180,3,67,0, +180,3,102,0,180, +3,75,0,180,3, +48,0,180,3,110, +0,180,3,83,0, +180,3,56,0,180, +3,118,0,180,3, +99,0,180,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,180,3,88, +0,180,3,69,0, +180,3,104,0,180, +3,77,0,180,3, +50,0,180,3,112, +0,180,3,85,0, +180,3,120,0,180, +3,66,0,180,3, +101,0,180,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +180,3,87,0,180, +3,122,0,180,3, +95,0,761,12,1, +23142,762,5,63,3, +97,0,180,3,70, +0,180,3,105,0, +180,3,78,0,180, +3,51,0,180,3, +113,0,180,3,86, +0,180,3,121,0, +180,3,67,0,180, +3,102,0,180,3, +75,0,180,3,48, +0,180,3,110,0, +180,3,83,0,180, +3,56,0,180,3, +118,0,180,3,99, +0,180,3,72,0, +180,3,107,0,180, +3,80,0,180,3, +53,0,180,3,115, +0,180,3,88,0, +180,3,69,0,180, +3,104,0,180,3, +77,0,180,3,50, +0,180,3,112,0, +180,3,85,0,180, +3,120,0,180,3, +66,0,180,3,101, +0,763,12,1,23222, +764,5,63,3,97, +0,180,3,70,0, +180,3,105,0,180, +3,78,0,180,3, +51,0,180,3,113, +0,180,3,86,0, +180,3,121,0,180, +3,67,0,180,3, +102,0,180,3,75, +0,180,3,48,0, +180,3,110,0,765, +12,1,23294,766,5, +63,3,97,0,180, +3,70,0,180,3, +105,0,180,3,78, +0,180,3,51,0, +180,3,113,0,180, +3,86,0,180,3, +121,0,180,3,67, +0,180,3,102,0, +180,3,75,0,180, +3,48,0,180,3, +110,0,180,3,83, +0,180,3,56,0, +180,3,118,0,180, +3,99,0,180,3, +72,0,180,3,107, +0,180,3,80,0, +180,3,53,0,180, +3,115,0,180,3, +88,0,180,3,69, +0,180,3,104,0, +180,3,77,0,180, +3,50,0,180,3, +112,0,180,3,85, +0,180,3,120,0, +180,3,66,0,180, +3,101,0,180,3, +74,0,180,3,109, +0,180,3,82,0, +180,3,55,0,180, +3,117,0,180,3, +90,0,180,3,98, +0,180,3,71,0, +180,3,106,0,180, +3,79,0,180,3, +52,0,180,3,114, +0,180,3,87,0, +180,3,122,0,180, +3,95,0,180,3, +68,0,180,3,103, +0,180,3,76,0, +180,3,49,0,180, +3,111,0,180,3, +84,0,180,3,57, +0,180,3,119,0, +180,3,65,0,180, +3,100,0,180,3, +73,0,180,3,108, +0,180,3,81,0, +180,3,54,0,180, +3,116,0,767,12, +1,23387,768,5,63, +3,97,0,180,3, +70,0,180,3,105, +0,180,3,78,0, +180,3,51,0,180, +3,113,0,180,3, +86,0,180,3,121, +0,180,3,67,0, +180,3,102,0,180, +3,75,0,180,3, +48,0,180,3,110, +0,180,3,83,0, +180,3,56,0,180, +3,118,0,180,3, +99,0,180,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,180,3,88, +0,180,3,69,0, +180,3,104,0,180, +3,77,0,180,3, +50,0,180,3,112, +0,180,3,85,0, +180,3,120,0,180, +3,66,0,180,3, +101,0,180,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +769,12,1,23472,770, +5,63,3,97,0, +180,3,70,0,180, +3,105,0,180,3, +78,0,180,3,51, +0,180,3,113,0, +180,3,86,0,180, +3,121,0,771,12, +1,23542,772,5,63, +3,97,0,180,3, +70,0,180,3,105, +0,180,3,78,0, +180,3,51,0,180, +3,113,0,180,3, +86,0,180,3,121, +0,180,3,67,0, +180,3,102,0,180, +3,75,0,180,3, +48,0,180,3,110, +0,180,3,83,0, +180,3,56,0,180, +3,118,0,180,3, +99,0,180,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,180,3,88, +0,180,3,69,0, +180,3,104,0,180, +3,77,0,180,3, +50,0,180,3,112, +0,180,3,85,0, +180,3,120,0,180, +3,66,0,180,3, +101,0,180,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +180,3,87,0,180, +3,122,0,180,3, +95,0,180,3,68, +0,180,3,103,0, +180,3,76,0,180, +3,49,0,180,3, +111,0,180,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,180,3,73, +0,180,3,108,0, +180,3,81,0,180, +3,54,0,180,3, +116,0,180,3,89, +0,180,773,11,1, +754,0,774,4,34, +83,0,84,0,65, +0,84,0,69,0, +95,0,69,0,78, +0,84,0,82,0, +89,0,95,0,69, 0,86,0,69,0, 78,0,84,0,1, --1,3,115,0,345, -3,116,0,345,3, -117,0,345,3,118, -0,345,3,119,0, -345,3,120,0,345, -3,121,0,345,3, -122,0,345,3,48, -0,345,3,49,0, -345,3,50,0,345, -3,51,0,345,3, -52,0,345,3,53, -0,345,3,54,0, -345,3,55,0,345, -3,56,0,345,3, -57,0,345,3,65, -0,345,3,66,0, -345,3,67,0,345, -3,68,0,345,3, -69,0,345,3,70, -0,345,3,71,0, -345,3,72,0,345, -3,73,0,345,3, -74,0,345,3,75, -0,345,3,76,0, -345,3,77,0,345, -3,78,0,345,3, -79,0,345,3,80, -0,345,3,81,0, -345,3,82,0,345, -3,83,0,345,3, -84,0,345,3,85, -0,345,3,86,0, -345,3,87,0,345, -3,88,0,345,3, -89,0,345,3,90, -0,345,3,95,0, -345,3,97,0,345, -3,98,0,345,3, -99,0,345,3,100, -0,345,3,101,0, -345,3,102,0,345, -3,103,0,345,3, -104,0,345,3,105, -0,345,3,106,0, -345,3,107,0,345, -3,108,0,345,552, -11,1,867,0,348, -1,-1,3,102,0, -345,3,103,0,345, -3,104,0,345,3, -105,0,345,3,106, -0,345,3,107,0, -345,3,108,0,345, -553,11,1,867,0, -348,1,-1,3,119, -0,345,3,120,0, -345,3,121,0,345, -3,122,0,345,3, -48,0,345,3,49, -0,345,3,50,0, -345,3,51,0,345, -3,52,0,345,3, -53,0,345,3,54, -0,345,3,55,0, -345,3,56,0,345, -3,57,0,345,3, -65,0,345,3,66, -0,345,3,67,0, -345,3,68,0,345, -3,69,0,345,3, -70,0,345,3,71, -0,345,3,72,0, -345,3,73,0,345, -3,74,0,345,3, -75,0,345,3,76, -0,345,3,77,0, -345,3,78,0,345, -3,79,0,345,3, -80,0,345,3,81, -0,345,3,82,0, -345,3,83,0,345, -3,84,0,345,3, -85,0,345,3,86, -0,345,3,87,0, -345,3,88,0,345, -3,89,0,345,3, -90,0,345,3,95, -0,345,3,97,0, -345,3,98,0,345, -3,99,0,345,3, -100,0,345,3,101, -0,345,3,102,0, -345,3,103,0,345, -3,104,0,345,3, -105,0,345,3,106, -0,345,3,107,0, -345,3,108,0,345, -554,11,1,867,0, -348,1,-1,3,115, -0,345,3,116,0, -345,3,117,0,345, -3,118,0,345,3, -119,0,345,3,120, -0,345,3,121,0, -345,3,122,0,345, -3,48,0,345,3, -49,0,345,3,50, -0,345,3,51,0, -345,3,52,0,345, -3,53,0,345,3, -54,0,345,3,55, -0,345,3,56,0, -345,3,57,0,345, -3,65,0,345,3, -66,0,345,3,67, -0,345,3,68,0, -345,3,69,0,345, -3,70,0,345,3, -71,0,345,3,72, -0,345,3,73,0, -345,3,74,0,345, -3,75,0,345,3, -76,0,345,3,77, -0,345,3,78,0, -345,3,79,0,345, -3,80,0,345,3, -81,0,345,3,82, -0,345,3,83,0, -345,3,84,0,345, -3,85,0,345,3, -86,0,345,3,87, -0,345,3,88,0, -345,3,89,0,345, -3,90,0,345,3, -95,0,345,3,97, -0,345,3,98,0, -345,3,99,0,345, -3,100,0,345,3, -101,0,345,3,102, -0,345,3,103,0, -345,3,104,0,345, -3,105,0,345,3, -106,0,345,3,107, -0,345,3,108,0, -345,555,11,1,867, -0,348,1,-1,3, -102,0,345,3,103, -0,345,3,104,0, -345,3,105,0,345, -3,106,0,345,3, -107,0,345,3,108, -0,345,556,11,1, -867,0,348,1,-1, -3,116,0,345,3, -117,0,345,3,118, -0,345,3,119,0, -345,3,120,0,345, -3,121,0,345,3, -122,0,345,3,48, -0,345,3,49,0, -345,3,50,0,345, -3,51,0,345,3, -52,0,345,3,53, -0,345,3,54,0, -345,3,55,0,345, -3,56,0,345,3, -57,0,345,3,65, -0,345,3,66,0, -345,3,67,0,345, -3,68,0,345,3, -69,0,345,3,70, -0,345,3,71,0, -345,3,72,0,345, -3,73,0,345,3, -74,0,345,3,75, -0,345,3,76,0, -345,3,77,0,345, -3,78,0,345,3, -79,0,345,3,80, -0,345,3,81,0, -345,3,82,0,345, -3,83,0,345,3, -84,0,345,3,85, -0,345,3,86,0, -345,3,87,0,345, -3,88,0,345,3, -89,0,345,3,90, -0,345,3,95,0, -345,3,97,0,345, -3,98,0,345,3, -99,0,345,3,100, -0,345,3,101,0, -345,3,102,0,345, -3,103,0,345,3, -104,0,345,3,105, -0,345,3,106,0, -345,3,107,0,345, -3,108,0,345,557, -11,1,867,0,348, -1,-1,3,98,0, -345,3,99,0,345, -3,100,0,345,3, -101,0,345,3,102, -0,345,3,103,0, -345,3,104,0,345, -3,105,0,345,3, -106,0,345,3,107, -0,345,3,108,0, -345,558,11,1,867, -0,348,1,-1,3, -117,0,345,3,118, -0,345,3,119,0, -345,3,120,0,345, -3,121,0,345,3, -122,0,345,3,48, -0,345,3,49,0, -345,3,50,0,345, -3,51,0,345,3, -52,0,345,3,53, -0,345,3,54,0, -345,3,55,0,345, -3,56,0,345,3, -57,0,345,3,65, -0,345,3,66,0, -345,3,67,0,345, -3,68,0,345,3, -69,0,345,3,70, -0,345,3,71,0, -345,3,72,0,345, -3,73,0,345,3, -74,0,345,3,75, -0,345,3,76,0, -345,3,77,0,345, -3,78,0,345,3, -79,0,345,3,80, -0,345,3,81,0, -345,3,82,0,345, -3,83,0,345,3, -84,0,345,3,85, -0,345,3,86,0, -345,3,87,0,345, -3,88,0,345,3, -89,0,345,3,90, -0,345,3,95,0, -345,3,97,0,345, -3,98,0,345,3, -99,0,345,3,100, -0,345,3,101,0, -345,3,102,0,345, -3,103,0,345,3, -104,0,345,3,105, -0,345,3,106,0, -345,3,107,0,345, -3,108,0,345,559, -11,1,867,0,348, -1,-1,3,98,0, -345,3,99,0,345, -3,100,0,345,3, -101,0,560,12,1, -30229,561,5,63,3, -109,0,345,3,110, -0,345,3,111,0, -345,3,112,0,345, -3,113,0,345,3, -114,0,345,3,115, -0,345,3,116,0, -345,3,117,0,345, -3,118,0,345,3, -119,0,345,3,120, -0,345,3,121,0, -345,3,122,0,345, -3,48,0,345,3, -49,0,345,3,50, -0,345,3,51,0, -345,3,52,0,345, -3,53,0,345,3, -54,0,345,3,55, -0,345,3,56,0, -345,3,57,0,345, -3,65,0,345,3, -66,0,345,3,67, -0,345,3,68,0, -345,3,69,0,345, -3,70,0,345,3, -71,0,345,3,72, -0,345,3,73,0, -345,3,74,0,345, -3,75,0,345,3, -76,0,345,3,77, -0,345,3,78,0, -345,3,79,0,345, -3,80,0,345,3, -81,0,345,3,82, -0,345,3,83,0, -345,3,84,0,345, -3,85,0,345,3, -86,0,345,3,87, -0,345,3,88,0, -345,3,89,0,345, -3,90,0,345,3, -95,0,345,3,97, -0,345,3,98,0, -345,3,99,0,345, -3,100,0,345,3, -101,0,345,3,102, -0,562,12,1,30277, -563,5,63,3,109, -0,345,3,110,0, -345,3,111,0,345, -3,112,0,345,3, -113,0,345,3,114, -0,345,3,115,0, -345,3,116,0,345, -3,117,0,345,3, -118,0,345,3,119, -0,345,3,120,0, -345,3,121,0,345, -3,122,0,345,3, -48,0,345,3,49, -0,345,3,50,0, -345,3,51,0,345, -3,52,0,345,3, -53,0,345,3,54, -0,345,3,55,0, -345,3,56,0,345, -3,57,0,345,3, -65,0,345,3,66, -0,345,3,67,0, -345,3,68,0,345, -3,69,0,345,3, -70,0,345,3,71, -0,345,3,72,0, -345,3,73,0,345, -3,74,0,345,3, -75,0,345,3,76, -0,345,3,77,0, -345,3,78,0,345, -3,79,0,345,3, -80,0,345,3,81, -0,345,3,82,0, -345,3,83,0,345, -3,84,0,345,3, -85,0,345,3,86, -0,345,3,87,0, -345,3,88,0,345, -3,89,0,345,3, -90,0,345,3,95, -0,345,3,97,0, -564,12,1,30320,565, -5,63,3,109,0, -345,3,110,0,345, -3,111,0,345,3, -112,0,345,3,113, -0,345,3,114,0, -345,3,115,0,345, -3,116,0,345,3, -117,0,566,12,1, -30356,567,5,63,3, -109,0,345,3,110, -0,345,3,111,0, -345,3,112,0,345, -3,113,0,345,3, -114,0,345,3,115, -0,345,3,116,0, -345,3,117,0,345, -3,118,0,345,3, -119,0,345,3,120, -0,345,3,121,0, -345,3,122,0,345, -3,48,0,345,3, -49,0,345,3,50, -0,345,3,51,0, -345,3,52,0,345, -3,53,0,345,3, -54,0,345,3,55, -0,345,3,56,0, -345,3,57,0,345, -3,65,0,345,3, -66,0,345,3,67, -0,345,3,68,0, -345,3,69,0,345, -3,70,0,345,3, -71,0,345,3,72, -0,345,3,73,0, -345,3,74,0,345, -3,75,0,345,3, -76,0,345,3,77, -0,345,3,78,0, -345,3,79,0,345, -3,80,0,345,3, -81,0,345,3,82, -0,345,3,83,0, -345,3,84,0,345, -3,85,0,345,3, -86,0,345,3,87, -0,345,3,88,0, -345,3,89,0,345, -3,90,0,345,3, -95,0,345,3,97, -0,345,3,98,0, -345,3,99,0,345, -3,100,0,345,3, -101,0,345,3,102, -0,345,3,103,0, -345,3,104,0,345, -3,105,0,345,3, -106,0,345,3,107, -0,345,3,108,0, -568,12,1,30410,569, -5,63,3,109,0, -345,3,110,0,345, -3,111,0,345,3, -112,0,345,3,113, -0,345,3,114,0, -345,3,115,0,345, -3,116,0,570,12, -1,30445,571,5,63, -3,109,0,345,3, -110,0,345,3,111, -0,345,3,112,0, -345,3,113,0,345, -3,114,0,345,3, -115,0,345,3,116, -0,345,3,117,0, -345,3,118,0,345, -3,119,0,345,3, -120,0,345,3,121, -0,345,3,122,0, -345,3,48,0,345, -3,49,0,345,3, -50,0,345,3,51, -0,345,3,52,0, -345,3,53,0,345, -3,54,0,345,3, -55,0,345,3,56, -0,345,3,57,0, -345,3,65,0,345, -3,66,0,345,3, -67,0,345,3,68, -0,345,3,69,0, -345,3,70,0,345, -3,71,0,345,3, -72,0,345,3,73, -0,345,3,74,0, -345,3,75,0,345, -3,76,0,345,3, -77,0,345,3,78, -0,345,3,79,0, -345,3,80,0,345, -3,81,0,345,3, -82,0,345,3,83, -0,345,3,84,0, -345,3,85,0,345, -3,86,0,345,3, -87,0,345,3,88, -0,345,3,89,0, -345,3,90,0,345, -3,95,0,345,3, -97,0,345,3,98, -0,345,3,99,0, -345,3,100,0,345, -3,101,0,345,3, -102,0,345,3,103, -0,345,3,104,0, -345,3,105,0,345, -3,106,0,345,3, -107,0,345,3,108, -0,345,572,11,1, -245,0,573,4,26, -68,0,69,0,70, -0,65,0,85,0, -76,0,84,0,95, -0,83,0,84,0, +-1,3,67,0,180, +3,102,0,180,3, +75,0,180,3,48, +0,180,3,110,0, +180,3,83,0,180, +3,56,0,180,3, +118,0,180,3,99, +0,180,3,72,0, +180,3,107,0,180, +3,80,0,180,3, +53,0,180,3,115, +0,180,3,88,0, +180,3,69,0,180, +3,104,0,180,3, +77,0,180,3,50, +0,180,3,112,0, +180,3,85,0,180, +3,120,0,180,3, +66,0,180,3,101, +0,180,3,74,0, +180,3,109,0,180, +3,82,0,180,3, +55,0,180,3,117, +0,180,3,90,0, +180,3,98,0,180, +3,71,0,180,3, +106,0,180,3,79, +0,180,3,52,0, +180,3,114,0,180, +3,87,0,180,3, +122,0,180,3,95, +0,180,3,68,0, +180,3,103,0,180, +3,76,0,180,3, +49,0,180,3,111, +0,180,3,84,0, +180,3,57,0,180, +3,119,0,180,3, +65,0,180,3,100, +0,180,3,73,0, +180,3,108,0,180, +3,81,0,180,3, +54,0,180,3,116, +0,180,3,89,0, +180,775,11,1,867, +0,183,1,-1,3, +87,0,180,3,122, +0,180,3,95,0, +180,3,68,0,180, +3,103,0,180,3, +76,0,180,3,49, +0,180,3,111,0, +180,3,84,0,180, +3,57,0,180,3, +119,0,180,3,65, +0,180,3,100,0, +180,3,73,0,180, +3,108,0,180,3, +81,0,180,3,54, +0,180,3,116,0, +180,3,89,0,180, +776,11,1,867,0, +183,1,-1,3,89, +0,180,777,11,1, +867,0,183,1,-1, +3,83,0,180,3, +56,0,180,3,118, +0,180,3,99,0, +180,3,72,0,180, +3,107,0,180,3, +80,0,180,3,53, +0,180,3,115,0, +180,3,88,0,180, +3,69,0,180,3, +104,0,180,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,778,12,1, +23781,779,5,63,3, +97,0,180,3,70, +0,180,3,105,0, +780,12,1,23849,781, +5,63,3,97,0, +180,3,70,0,180, +3,105,0,180,3, +78,0,180,3,51, +0,180,3,113,0, +180,3,86,0,180, +3,121,0,180,3, +67,0,180,3,102, +0,180,3,75,0, +180,3,48,0,180, +3,110,0,180,3, +83,0,180,3,56, +0,180,3,118,0, +180,3,99,0,180, +3,72,0,180,3, +107,0,180,3,80, +0,180,3,53,0, +180,3,115,0,180, +3,88,0,180,3, +69,0,180,3,104, +0,180,3,77,0, +180,3,50,0,180, +3,112,0,180,3, +85,0,180,3,120, +0,180,3,66,0, +180,3,101,0,180, +3,74,0,180,3, +109,0,180,3,82, +0,180,3,55,0, +180,3,117,0,180, +3,90,0,180,3, +98,0,180,3,71, +0,180,3,106,0, +180,3,79,0,180, +3,52,0,180,3, +114,0,180,3,87, +0,180,3,122,0, +180,3,95,0,180, +3,68,0,180,3, +103,0,180,3,76, +0,180,3,49,0, +180,3,111,0,180, +3,84,0,180,3, +57,0,180,3,119, +0,180,3,65,0, +180,3,100,0,180, +3,73,0,180,3, +108,0,180,3,81, +0,180,3,54,0, +180,3,116,0,782, +12,1,23942,783,5, +63,3,97,0,180, +3,70,0,180,3, +105,0,180,3,78, +0,180,3,51,0, +180,3,113,0,180, +3,86,0,180,3, +121,0,180,3,67, +0,180,3,102,0, +180,3,75,0,180, +3,48,0,180,3, +110,0,180,3,83, +0,180,3,56,0, +180,3,118,0,180, +3,99,0,180,3, +72,0,180,3,107, +0,180,3,80,0, +180,3,53,0,180, +3,115,0,180,3, +88,0,180,3,69, +0,180,3,104,0, +180,3,77,0,180, +3,50,0,180,3, +112,0,180,3,85, +0,180,3,120,0, +180,3,66,0,180, +3,101,0,180,3, +74,0,180,3,109, +0,180,3,82,0, +180,3,55,0,180, +3,117,0,180,3, +90,0,180,3,98, +0,180,3,71,0, +180,3,106,0,180, +3,79,0,180,3, +52,0,180,3,114, +0,180,3,87,0, +180,3,122,0,180, +3,95,0,180,3, +68,0,180,3,103, +0,180,3,76,0, +180,3,49,0,180, +3,111,0,180,3, +84,0,180,3,57, +0,180,3,119,0, +180,3,65,0,180, +3,100,0,180,3, +73,0,180,3,108, +0,180,3,81,0, +180,3,54,0,180, +3,116,0,180,3, +89,0,180,784,11, +1,769,0,785,4, +32,83,0,84,0, 65,0,84,0,69, -0,1,-1,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,345,3, -98,0,345,3,99, -0,345,3,100,0, -345,3,101,0,345, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -345,3,106,0,345, -3,107,0,345,3, -108,0,345,574,11, -1,867,0,348,1, --1,575,11,1,867, -0,348,1,-1,3, -118,0,345,3,119, -0,345,3,120,0, -345,3,121,0,345, -3,122,0,345,3, -48,0,345,3,49, -0,345,3,50,0, -345,3,51,0,345, -3,52,0,345,3, -53,0,345,3,54, -0,345,3,55,0, -345,3,56,0,345, -3,57,0,345,3, -65,0,345,3,66, -0,345,3,67,0, -345,3,68,0,345, -3,69,0,345,3, -70,0,345,3,71, -0,345,3,72,0, -345,3,73,0,345, -3,74,0,345,3, -75,0,345,3,76, -0,345,3,77,0, -345,3,78,0,345, -3,79,0,345,3, -80,0,345,3,81, -0,345,3,82,0, -345,3,83,0,345, -3,84,0,345,3, -85,0,345,3,86, -0,345,3,87,0, -345,3,88,0,345, -3,89,0,345,3, -90,0,345,3,95, -0,345,3,97,0, -345,3,98,0,345, -3,99,0,345,3, -100,0,345,3,101, -0,345,3,102,0, -345,3,103,0,345, -3,104,0,345,3, -105,0,345,3,106, -0,345,3,107,0, -345,3,108,0,345, -576,11,1,867,0, -348,1,-1,3,98, -0,345,3,99,0, -345,3,100,0,345, -3,101,0,345,3, -102,0,345,3,103, -0,345,3,104,0, -345,3,105,0,345, -3,106,0,345,3, -107,0,345,3,108, -0,345,577,11,1, -867,0,348,1,-1, -3,103,0,345,3, -104,0,345,3,105, -0,345,3,106,0, -345,3,107,0,345, -3,108,0,345,578, -11,1,867,0,348, -1,-1,3,102,0, -345,3,103,0,345, -3,104,0,345,3, -105,0,345,3,106, -0,345,3,107,0, -345,3,108,0,345, -579,11,1,867,0, -348,1,-1,3,101, -0,580,12,1,31023, -581,5,63,3,109, -0,582,12,1,31051, -583,5,63,3,109, -0,345,3,110,0, -345,3,111,0,345, -3,112,0,345,3, -113,0,345,3,114, -0,345,3,115,0, -345,3,116,0,345, -3,117,0,345,3, -118,0,345,3,119, -0,345,3,120,0, -345,3,121,0,345, -3,122,0,345,3, -48,0,345,3,49, -0,345,3,50,0, -345,3,51,0,345, -3,52,0,345,3, -53,0,345,3,54, -0,345,3,55,0, -345,3,56,0,345, -3,57,0,345,3, -65,0,345,3,66, -0,345,3,67,0, -345,3,68,0,345, -3,69,0,345,3, -70,0,345,3,71, -0,345,3,72,0, -345,3,73,0,345, -3,74,0,345,3, -75,0,345,3,76, -0,345,3,77,0, -345,3,78,0,345, -3,79,0,345,3, -80,0,345,3,81, -0,345,3,82,0, -345,3,83,0,345, -3,84,0,345,3, -85,0,345,3,86, -0,345,3,87,0, -345,3,88,0,345, -3,89,0,345,3, -90,0,345,3,95, -0,345,3,97,0, -584,12,1,31094,585, -5,63,3,109,0, -345,3,110,0,345, -3,111,0,345,3, -112,0,345,3,113, -0,345,3,114,0, -345,3,115,0,345, -3,116,0,345,3, -117,0,345,3,118, -0,345,3,119,0, -345,3,120,0,345, -3,121,0,345,3, -122,0,345,3,48, -0,345,3,49,0, -345,3,50,0,345, -3,51,0,345,3, -52,0,345,3,53, -0,345,3,54,0, -345,3,55,0,345, -3,56,0,345,3, -57,0,345,3,65, -0,345,3,66,0, -345,3,67,0,345, -3,68,0,345,3, -69,0,345,3,70, -0,345,3,71,0, -345,3,72,0,345, -3,73,0,345,3, -74,0,345,3,75, -0,345,3,76,0, -345,3,77,0,345, -3,78,0,345,3, -79,0,345,3,80, -0,345,3,81,0, -345,3,82,0,345, -3,83,0,345,3, -84,0,345,3,85, -0,345,3,86,0, -345,3,87,0,345, -3,88,0,345,3, -89,0,345,3,90, -0,345,3,95,0, -345,3,97,0,345, -3,98,0,345,3, -99,0,345,3,100, -0,345,3,101,0, -345,3,102,0,345, -3,103,0,345,3, -104,0,345,3,105, -0,586,12,1,31145, -587,5,63,3,109, -0,345,3,110,0, -345,3,111,0,345, -3,112,0,345,3, -113,0,345,3,114, -0,345,3,115,0, -345,3,116,0,345, -3,117,0,345,3, -118,0,345,3,119, -0,345,3,120,0, -345,3,121,0,345, -3,122,0,345,3, -48,0,345,3,49, -0,345,3,50,0, -345,3,51,0,345, -3,52,0,345,3, -53,0,345,3,54, -0,345,3,55,0, -345,3,56,0,345, -3,57,0,345,3, -65,0,345,3,66, -0,345,3,67,0, -345,3,68,0,345, -3,69,0,345,3, -70,0,345,3,71, -0,345,3,72,0, -345,3,73,0,345, -3,74,0,345,3, -75,0,345,3,76, -0,345,3,77,0, -345,3,78,0,345, -3,79,0,345,3, -80,0,345,3,81, -0,345,3,82,0, -345,3,83,0,345, -3,84,0,345,3, -85,0,345,3,86, -0,345,3,87,0, -345,3,88,0,345, -3,89,0,345,3, -90,0,345,3,95, -0,345,3,97,0, -345,3,98,0,345, -3,99,0,345,3, -100,0,345,3,101, -0,345,3,102,0, -345,3,103,0,345, -3,104,0,345,3, -105,0,345,3,106, -0,345,3,107,0, -345,3,108,0,588, -12,1,31199,589,5, -63,3,109,0,345, -3,110,0,345,3, -111,0,345,3,112, -0,345,3,113,0, -345,3,114,0,345, -3,115,0,345,3, -116,0,345,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,345,3, -98,0,345,3,99, -0,345,3,100,0, -345,3,101,0,345, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -345,3,106,0,345, -3,107,0,345,3, -108,0,345,590,11, -1,475,0,591,4, -22,69,0,77,0, -65,0,73,0,76, +0,95,0,69,0, +88,0,73,0,84, 0,95,0,69,0, 86,0,69,0,78, 0,84,0,1,-1, -592,11,1,867,0, -348,1,-1,3,106, -0,345,3,107,0, -345,3,108,0,345, -593,11,1,867,0, -348,1,-1,3,98, -0,345,3,99,0, -345,3,100,0,345, -3,101,0,345,3, -102,0,345,3,103, -0,345,3,104,0, -345,3,105,0,345, -3,106,0,345,3, -107,0,345,3,108, -0,345,594,11,1, -867,0,348,1,-1, -3,110,0,345,3, -111,0,345,3,112, -0,345,3,113,0, -345,3,114,0,345, -3,115,0,345,3, -116,0,345,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,345,3, -98,0,345,3,99, -0,345,3,100,0, -345,3,101,0,345, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -345,3,106,0,345, -3,107,0,345,3, -108,0,595,12,1, -31557,596,5,63,3, -109,0,345,3,110, -0,345,3,111,0, -345,3,112,0,345, -3,113,0,345,3, -114,0,345,3,115, -0,597,12,1,31591, -598,5,63,3,109, -0,345,3,110,0, -345,3,111,0,345, -3,112,0,345,3, -113,0,345,3,114, -0,345,3,115,0, -345,3,116,0,345, -3,117,0,345,3, -118,0,345,3,119, -0,345,3,120,0, -345,3,121,0,345, -3,122,0,345,3, -48,0,345,3,49, -0,345,3,50,0, -345,3,51,0,345, -3,52,0,345,3, -53,0,345,3,54, -0,345,3,55,0, -345,3,56,0,345, -3,57,0,345,3, -65,0,345,3,66, -0,345,3,67,0, -345,3,68,0,345, -3,69,0,345,3, -70,0,345,3,71, -0,345,3,72,0, -345,3,73,0,345, -3,74,0,345,3, -75,0,345,3,76, -0,345,3,77,0, -345,3,78,0,345, -3,79,0,345,3, -80,0,345,3,81, -0,345,3,82,0, -345,3,83,0,345, -3,84,0,345,3, -85,0,345,3,86, -0,345,3,87,0, -345,3,88,0,345, -3,89,0,345,3, -90,0,345,3,95, -0,345,3,97,0, -345,3,98,0,345, -3,99,0,345,3, -100,0,345,3,101, -0,599,12,1,31638, -600,5,63,3,109, -0,345,3,110,0, -345,3,111,0,345, -3,112,0,345,3, -113,0,345,3,114, -0,345,3,115,0, -345,3,116,0,345, -3,117,0,345,3, -118,0,345,3,119, -0,345,3,120,0, -345,3,121,0,345, -3,122,0,345,3, -48,0,345,3,49, -0,345,3,50,0, -345,3,51,0,345, -3,52,0,345,3, -53,0,345,3,54, -0,345,3,55,0, -345,3,56,0,345, -3,57,0,345,3, -65,0,345,3,66, -0,345,3,67,0, -345,3,68,0,345, -3,69,0,345,3, -70,0,345,3,71, -0,345,3,72,0, -345,3,73,0,345, -3,74,0,345,3, -75,0,345,3,76, -0,345,3,77,0, -345,3,78,0,345, -3,79,0,345,3, -80,0,345,3,81, -0,345,3,82,0, -345,3,83,0,345, -3,84,0,345,3, -85,0,345,3,86, -0,345,3,87,0, -345,3,88,0,345, -3,89,0,345,3, -90,0,345,3,95, -0,345,3,97,0, -345,3,98,0,345, -3,99,0,345,3, -100,0,345,3,101, -0,345,3,102,0, -345,3,103,0,345, -3,104,0,345,3, -105,0,345,3,106, -0,345,3,107,0, -345,3,108,0,345, -601,11,1,215,0, -602,4,8,69,0, -76,0,83,0,69, -0,1,-1,3,102, -0,345,3,103,0, -345,3,104,0,345, -3,105,0,345,3, -106,0,345,3,107, -0,345,3,108,0, -345,603,11,1,867, -0,348,1,-1,3, -116,0,345,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,345,3, -98,0,345,3,99, -0,345,3,100,0, -345,3,101,0,345, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -345,3,106,0,345, -3,107,0,345,3, -108,0,345,604,11, -1,867,0,348,1, --1,605,11,1,867, -0,348,1,-1,3, -102,0,606,12,1, -31984,607,5,63,3, -109,0,345,3,110, -0,345,3,111,0, -608,12,1,32014,609, -5,63,3,109,0, -345,3,110,0,345, -3,111,0,345,3, -112,0,345,3,113, -0,345,3,114,0, -610,12,1,32047,611, -5,63,3,109,0, -345,3,110,0,345, -3,111,0,345,3, -112,0,345,3,113, -0,345,3,114,0, -345,3,115,0,345, -3,116,0,345,3, -117,0,345,3,118, -0,345,3,119,0, -345,3,120,0,345, -3,121,0,345,3, -122,0,345,3,48, -0,345,3,49,0, -345,3,50,0,345, -3,51,0,345,3, -52,0,345,3,53, -0,345,3,54,0, -345,3,55,0,345, -3,56,0,345,3, -57,0,345,3,65, -0,345,3,66,0, -345,3,67,0,345, -3,68,0,345,3, -69,0,345,3,70, -0,345,3,71,0, -345,3,72,0,345, -3,73,0,345,3, -74,0,345,3,75, -0,345,3,76,0, -345,3,77,0,345, -3,78,0,345,3, -79,0,345,3,80, -0,345,3,81,0, -345,3,82,0,345, -3,83,0,345,3, -84,0,345,3,85, -0,345,3,86,0, -345,3,87,0,345, -3,88,0,345,3, -89,0,345,3,90, -0,345,3,95,0, -345,3,97,0,345, -3,98,0,345,3, -99,0,345,3,100, -0,345,3,101,0, -345,3,102,0,345, -3,103,0,345,3, -104,0,345,3,105, -0,345,3,106,0, -345,3,107,0,345, -3,108,0,345,612, -11,1,238,0,613, -4,6,70,0,79, -0,82,0,1,-1, -3,115,0,345,3, -116,0,345,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,345,3, -98,0,345,3,99, -0,345,3,100,0, -345,3,101,0,345, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -345,3,106,0,345, -3,107,0,345,3, -108,0,345,614,11, -1,867,0,348,1, --1,3,112,0,345, -3,113,0,345,3, -114,0,345,3,115, -0,345,3,116,0, -345,3,117,0,345, -3,118,0,345,3, -119,0,345,3,120, -0,345,3,121,0, -345,3,122,0,345, -3,48,0,345,3, -49,0,345,3,50, -0,345,3,51,0, -345,3,52,0,345, -3,53,0,345,3, -54,0,345,3,55, -0,345,3,56,0, -345,3,57,0,345, -3,65,0,345,3, -66,0,345,3,67, -0,345,3,68,0, -345,3,69,0,345, -3,70,0,345,3, -71,0,345,3,72, -0,345,3,73,0, -345,3,74,0,345, -3,75,0,345,3, -76,0,345,3,77, -0,345,3,78,0, -345,3,79,0,345, -3,80,0,345,3, -81,0,345,3,82, -0,345,3,83,0, -345,3,84,0,345, -3,85,0,345,3, -86,0,345,3,87, -0,345,3,88,0, -345,3,89,0,345, -3,90,0,345,3, -95,0,345,3,97, -0,345,3,98,0, -345,3,99,0,345, -3,100,0,345,3, -101,0,345,3,102, -0,345,3,103,0, -345,3,104,0,345, -3,105,0,345,3, -106,0,345,3,107, -0,345,3,108,0, -615,12,1,32278,616, -5,63,3,109,0, -345,3,110,0,345, -3,111,0,617,12, -1,32308,618,5,63, -3,109,0,345,3, -110,0,345,3,111, -0,345,3,112,0, -345,3,113,0,345, -3,114,0,345,3, -115,0,345,3,116, -0,345,3,117,0, -345,3,118,0,345, -3,119,0,345,3, -120,0,345,3,121, -0,345,3,122,0, -345,3,48,0,345, -3,49,0,345,3, -50,0,345,3,51, -0,345,3,52,0, -345,3,53,0,345, -3,54,0,345,3, -55,0,345,3,56, -0,345,3,57,0, -345,3,65,0,345, -3,66,0,345,3, -67,0,345,3,68, -0,345,3,69,0, -345,3,70,0,345, -3,71,0,345,3, -72,0,345,3,73, -0,345,3,74,0, -345,3,75,0,345, -3,76,0,345,3, -77,0,345,3,78, -0,345,3,79,0, -345,3,80,0,345, -3,81,0,345,3, -82,0,345,3,83, -0,345,3,84,0, -345,3,85,0,345, -3,86,0,345,3, -87,0,345,3,88, -0,345,3,89,0, -345,3,90,0,345, -3,95,0,345,3, -97,0,619,12,1, -32351,620,5,63,3, -109,0,345,3,110, -0,345,3,111,0, -345,3,112,0,345, -3,113,0,345,3, -114,0,345,3,115, -0,345,3,116,0, -621,12,1,32386,622, -5,63,3,109,0, -345,3,110,0,345, -3,111,0,345,3, -112,0,345,3,113, -0,345,3,114,0, -345,3,115,0,345, -3,116,0,345,3, -117,0,345,3,118, -0,345,3,119,0, -345,3,120,0,345, -3,121,0,345,3, -122,0,345,3,48, -0,345,3,49,0, -345,3,50,0,345, -3,51,0,345,3, -52,0,345,3,53, -0,345,3,54,0, -345,3,55,0,345, -3,56,0,345,3, -57,0,345,3,65, -0,345,3,66,0, -345,3,67,0,345, -3,68,0,345,3, -69,0,345,3,70, -0,345,3,71,0, -345,3,72,0,345, -3,73,0,345,3, -74,0,345,3,75, -0,345,3,76,0, -345,3,77,0,345, -3,78,0,345,3, -79,0,345,3,80, -0,345,3,81,0, -345,3,82,0,345, -3,83,0,345,3, -84,0,345,3,85, -0,345,3,86,0, -345,3,87,0,345, -3,88,0,345,3, -89,0,345,3,90, -0,345,3,95,0, -345,3,97,0,345, -3,98,0,345,3, -99,0,345,3,100, -0,345,3,101,0, -345,3,102,0,345, -3,103,0,345,3, -104,0,345,3,105, -0,345,3,106,0, -345,3,107,0,345, -3,108,0,345,623, -11,1,294,0,624, -4,20,70,0,76, -0,79,0,65,0, -84,0,95,0,84, -0,89,0,80,0, -69,0,1,-1,3, -117,0,345,3,118, -0,345,3,119,0, -345,3,120,0,345, -3,121,0,345,3, -122,0,345,3,48, -0,345,3,49,0, -345,3,50,0,345, -3,51,0,345,3, -52,0,345,3,53, -0,345,3,54,0, -345,3,55,0,345, -3,56,0,345,3, -57,0,345,3,65, -0,345,3,66,0, -345,3,67,0,345, -3,68,0,345,3, -69,0,345,3,70, -0,345,3,71,0, -345,3,72,0,345, -3,73,0,345,3, -74,0,345,3,75, -0,345,3,76,0, -345,3,77,0,345, -3,78,0,345,3, -79,0,345,3,80, -0,345,3,81,0, -345,3,82,0,345, -3,83,0,345,3, -84,0,345,3,85, -0,345,3,86,0, -345,3,87,0,345, -3,88,0,345,3, -89,0,345,3,90, -0,345,3,95,0, -345,3,97,0,345, -3,98,0,345,3, -99,0,345,3,100, -0,345,3,101,0, -345,3,102,0,345, -3,103,0,345,3, -104,0,345,3,105, -0,345,3,106,0, -345,3,107,0,345, -3,108,0,345,625, -11,1,867,0,348, -1,-1,3,98,0, -345,3,99,0,345, -3,100,0,345,3, -101,0,345,3,102, -0,345,3,103,0, -345,3,104,0,345, -3,105,0,345,3, -106,0,345,3,107, -0,345,3,108,0, -345,626,11,1,867, -0,348,1,-1,3, -112,0,345,3,113, -0,345,3,114,0, -345,3,115,0,345, -3,116,0,345,3, -117,0,345,3,118, -0,345,3,119,0, -345,3,120,0,345, -3,121,0,345,3, -122,0,345,3,48, -0,345,3,49,0, -345,3,50,0,345, -3,51,0,345,3, -52,0,345,3,53, -0,345,3,54,0, -345,3,55,0,345, -3,56,0,345,3, -57,0,345,3,65, -0,345,3,66,0, -345,3,67,0,345, -3,68,0,345,3, -69,0,345,3,70, -0,345,3,71,0, -345,3,72,0,345, -3,73,0,345,3, -74,0,345,3,75, -0,345,3,76,0, -345,3,77,0,345, -3,78,0,345,3, -79,0,345,3,80, -0,345,3,81,0, -345,3,82,0,345, -3,83,0,345,3, -84,0,345,3,85, -0,345,3,86,0, -345,3,87,0,345, -3,88,0,345,3, -89,0,345,3,90, -0,345,3,95,0, -345,3,97,0,345, -3,98,0,345,3, -99,0,345,3,100, -0,345,3,101,0, -345,3,102,0,345, -3,103,0,345,3, -104,0,345,3,105, -0,345,3,106,0, -345,3,107,0,345, -3,108,0,345,627, -11,1,867,0,348, -1,-1,628,11,1, -867,0,348,1,-1, -3,103,0,343,3, -104,0,629,12,1, -32826,630,5,63,3, -109,0,345,3,110, -0,345,3,111,0, -345,3,112,0,345, -3,113,0,345,3, -114,0,345,3,115, -0,345,3,116,0, -631,12,1,32861,632, -5,63,3,109,0, -345,3,110,0,345, -3,111,0,345,3, -112,0,345,3,113, -0,345,3,114,0, -345,3,115,0,345, -3,116,0,633,12, -1,32896,634,5,63, -3,109,0,345,3, -110,0,345,3,111, -0,345,3,112,0, -635,12,1,32927,636, -5,63,3,109,0, -345,3,110,0,345, -3,111,0,345,3, -112,0,345,3,113, -0,345,3,114,0, -345,3,115,0,345, -3,116,0,345,3, -117,0,345,3,118, -0,345,3,119,0, -345,3,120,0,345, -3,121,0,345,3, -122,0,345,3,48, -0,345,3,49,0, -345,3,50,0,345, -3,51,0,345,3, -52,0,345,3,53, -0,345,3,54,0, -345,3,55,0,345, -3,56,0,345,3, -57,0,345,3,65, -0,345,3,66,0, -345,3,67,0,345, -3,68,0,345,3, -69,0,345,3,70, -0,345,3,71,0, -345,3,72,0,345, -3,73,0,345,3, -74,0,345,3,75, -0,345,3,76,0, -345,3,77,0,345, -3,78,0,345,3, -79,0,345,3,80, -0,345,3,81,0, -345,3,82,0,345, -3,83,0,345,3, -84,0,345,3,85, -0,345,3,86,0, -345,3,87,0,345, -3,88,0,345,3, -89,0,345,3,90, -0,345,3,95,0, -637,12,1,33013,638, -5,63,3,109,0, -345,3,110,0,345, -3,111,0,345,3, -112,0,345,3,113, -0,345,3,114,0, -639,12,1,33046,640, -5,63,3,109,0, -345,3,110,0,345, -3,111,0,345,3, -112,0,345,3,113, -0,345,3,114,0, -345,3,115,0,345, -3,116,0,345,3, -117,0,345,3,118, -0,345,3,119,0, -345,3,120,0,345, -3,121,0,345,3, -122,0,345,3,48, -0,345,3,49,0, -345,3,50,0,345, -3,51,0,345,3, -52,0,345,3,53, -0,345,3,54,0, -345,3,55,0,345, -3,56,0,345,3, -57,0,345,3,65, -0,345,3,66,0, -345,3,67,0,345, -3,68,0,345,3, -69,0,345,3,70, -0,345,3,71,0, -345,3,72,0,345, -3,73,0,345,3, -74,0,345,3,75, -0,345,3,76,0, -345,3,77,0,345, -3,78,0,345,3, -79,0,345,3,80, -0,345,3,81,0, -345,3,82,0,345, -3,83,0,345,3, -84,0,345,3,85, -0,345,3,86,0, -345,3,87,0,345, -3,88,0,345,3, -89,0,345,3,90, -0,345,3,95,0, -345,3,97,0,345, -3,98,0,345,3, -99,0,345,3,100, -0,345,3,101,0, -641,12,1,33093,642, -5,63,3,109,0, -345,3,110,0,345, -3,111,0,345,3, -112,0,345,3,113, -0,643,12,1,33125, -644,5,63,3,109, -0,345,3,110,0, -345,3,111,0,345, -3,112,0,345,3, -113,0,345,3,114, -0,345,3,115,0, -345,3,116,0,345, -3,117,0,645,12, -1,33161,646,5,63, -3,109,0,345,3, -110,0,345,3,111, -0,345,3,112,0, -345,3,113,0,345, -3,114,0,345,3, -115,0,345,3,116, -0,345,3,117,0, -345,3,118,0,345, -3,119,0,345,3, -120,0,345,3,121, -0,345,3,122,0, -345,3,48,0,345, -3,49,0,345,3, -50,0,345,3,51, -0,345,3,52,0, -345,3,53,0,345, -3,54,0,345,3, -55,0,345,3,56, -0,345,3,57,0, -345,3,65,0,345, -3,66,0,345,3, -67,0,345,3,68, -0,345,3,69,0, -345,3,70,0,345, -3,71,0,345,3, -72,0,345,3,73, -0,345,3,74,0, -345,3,75,0,345, -3,76,0,345,3, -77,0,345,3,78, -0,345,3,79,0, -345,3,80,0,345, -3,81,0,345,3, -82,0,345,3,83, -0,345,3,84,0, -345,3,85,0,345, -3,86,0,345,3, -87,0,345,3,88, -0,345,3,89,0, -345,3,90,0,345, -3,95,0,345,3, -97,0,345,3,98, -0,345,3,99,0, -345,3,100,0,345, -3,101,0,647,12, -1,33208,648,5,63, -3,109,0,345,3, -110,0,345,3,111, -0,345,3,112,0, -345,3,113,0,345, -3,114,0,345,3, -115,0,649,12,1, -33242,650,5,63,3, -109,0,345,3,110, -0,345,3,111,0, -345,3,112,0,345, -3,113,0,345,3, -114,0,345,3,115, -0,345,3,116,0, -651,12,1,33277,652, -5,63,3,109,0, -345,3,110,0,345, -3,111,0,345,3, -112,0,345,3,113, -0,345,3,114,0, -345,3,115,0,345, -3,116,0,345,3, -117,0,345,3,118, -0,345,3,119,0, -345,3,120,0,345, -3,121,0,345,3, -122,0,345,3,48, -0,345,3,49,0, -345,3,50,0,345, -3,51,0,345,3, -52,0,345,3,53, -0,345,3,54,0, -345,3,55,0,345, -3,56,0,345,3, -57,0,345,3,65, -0,345,3,66,0, -345,3,67,0,345, -3,68,0,345,3, -69,0,345,3,70, -0,345,3,71,0, -345,3,72,0,345, -3,73,0,345,3, -74,0,345,3,75, -0,345,3,76,0, -345,3,77,0,345, -3,78,0,345,3, -79,0,345,3,80, -0,345,3,81,0, -345,3,82,0,345, -3,83,0,345,3, -84,0,345,3,85, -0,345,3,86,0, -345,3,87,0,345, -3,88,0,345,3, -89,0,345,3,90, -0,345,3,95,0, -345,3,97,0,345, -3,98,0,345,3, -99,0,345,3,100, -0,345,3,101,0, -345,3,102,0,345, -3,103,0,345,3, -104,0,345,3,105, -0,345,3,106,0, -345,3,107,0,345, -3,108,0,345,653, -11,1,829,0,654, -4,36,72,0,84, -0,84,0,80,0, -95,0,82,0,69, -0,81,0,85,0, -69,0,83,0,84, -0,95,0,69,0, -86,0,69,0,78, -0,84,0,1,-1, -3,117,0,345,3, -118,0,345,3,119, -0,345,3,120,0, -345,3,121,0,345, -3,122,0,345,3, -48,0,345,3,49, -0,345,3,50,0, -345,3,51,0,345, -3,52,0,345,3, -53,0,345,3,54, -0,345,3,55,0, -345,3,56,0,345, -3,57,0,345,3, -65,0,345,3,66, -0,345,3,67,0, -345,3,68,0,345, -3,69,0,345,3, -70,0,345,3,71, -0,345,3,72,0, -345,3,73,0,345, -3,74,0,345,3, -75,0,345,3,76, -0,345,3,77,0, -345,3,78,0,345, -3,79,0,345,3, -80,0,345,3,81, -0,345,3,82,0, -345,3,83,0,345, -3,84,0,345,3, -85,0,345,3,86, -0,345,3,87,0, -345,3,88,0,345, -3,89,0,345,3, -90,0,345,3,95, -0,345,3,97,0, -345,3,98,0,345, -3,99,0,345,3, -100,0,345,3,101, -0,345,3,102,0, -345,3,103,0,345, -3,104,0,345,3, -105,0,345,3,106, -0,345,3,107,0, -345,3,108,0,345, -655,11,1,867,0, -348,1,-1,3,116, -0,345,3,117,0, -345,3,118,0,345, -3,119,0,345,3, -120,0,345,3,121, -0,345,3,122,0, -345,3,48,0,345, -3,49,0,345,3, -50,0,345,3,51, -0,345,3,52,0, -345,3,53,0,345, -3,54,0,345,3, -55,0,345,3,56, -0,345,3,57,0, -345,3,65,0,345, -3,66,0,345,3, -67,0,345,3,68, -0,345,3,69,0, -345,3,70,0,345, -3,71,0,345,3, -72,0,345,3,73, -0,345,3,74,0, -345,3,75,0,345, -3,76,0,345,3, -77,0,345,3,78, -0,345,3,79,0, -345,3,80,0,345, -3,81,0,345,3, -82,0,345,3,83, -0,345,3,84,0, -345,3,85,0,345, -3,86,0,345,3, -87,0,345,3,88, -0,345,3,89,0, -345,3,90,0,345, -3,95,0,345,3, -97,0,345,3,98, -0,345,3,99,0, -345,3,100,0,345, -3,101,0,345,3, -102,0,345,3,103, -0,345,3,104,0, -345,3,105,0,345, -3,106,0,345,3, -107,0,345,3,108, -0,345,656,11,1, -867,0,348,1,-1, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -345,3,106,0,345, -3,107,0,345,3, -108,0,345,657,11, -1,867,0,348,1, --1,3,118,0,345, -3,119,0,345,3, -120,0,345,3,121, -0,345,3,122,0, -345,3,48,0,345, -3,49,0,345,3, -50,0,345,3,51, -0,345,3,52,0, -345,3,53,0,345, -3,54,0,345,3, -55,0,345,3,56, -0,345,3,57,0, -345,3,65,0,345, -3,66,0,345,3, -67,0,345,3,68, -0,345,3,69,0, -345,3,70,0,345, -3,71,0,345,3, -72,0,345,3,73, -0,345,3,74,0, -345,3,75,0,345, -3,76,0,345,3, -77,0,345,3,78, -0,345,3,79,0, -345,3,80,0,345, -3,81,0,345,3, -82,0,345,3,83, -0,345,3,84,0, -345,3,85,0,345, -3,86,0,345,3, -87,0,345,3,88, -0,345,3,89,0, -345,3,90,0,345, -3,95,0,345,3, -97,0,345,3,98, -0,345,3,99,0, -345,3,100,0,345, -3,101,0,345,3, -102,0,345,3,103, -0,345,3,104,0, -345,3,105,0,345, -3,106,0,345,3, -107,0,345,3,108, -0,345,658,11,1, -867,0,348,1,-1, -3,114,0,345,3, -115,0,659,12,1, -33727,660,5,63,3, -109,0,345,3,110, -0,345,3,111,0, -345,3,112,0,661, -12,1,33758,662,5, -63,3,109,0,345, -3,110,0,345,3, -111,0,663,12,1, -33788,664,5,63,3, -109,0,345,3,110, -0,665,12,1,33817, -666,5,63,3,109, -0,345,3,110,0, -345,3,111,0,345, -3,112,0,345,3, -113,0,345,3,114, -0,345,3,115,0, -667,12,1,33851,668, -5,63,3,109,0, -345,3,110,0,345, -3,111,0,345,3, -112,0,345,3,113, -0,345,3,114,0, -345,3,115,0,345, -3,116,0,345,3, -117,0,345,3,118, -0,345,3,119,0, -345,3,120,0,345, -3,121,0,345,3, -122,0,345,3,48, -0,345,3,49,0, -345,3,50,0,345, -3,51,0,345,3, -52,0,345,3,53, -0,345,3,54,0, -345,3,55,0,345, -3,56,0,345,3, -57,0,345,3,65, -0,345,3,66,0, -345,3,67,0,345, -3,68,0,345,3, -69,0,345,3,70, -0,345,3,71,0, -345,3,72,0,345, -3,73,0,345,3, -74,0,345,3,75, -0,345,3,76,0, -345,3,77,0,345, -3,78,0,345,3, -79,0,345,3,80, -0,345,3,81,0, -345,3,82,0,345, -3,83,0,345,3, -84,0,345,3,85, -0,345,3,86,0, -345,3,87,0,345, -3,88,0,345,3, -89,0,345,3,90, -0,345,3,95,0, -345,3,97,0,345, -3,98,0,345,3, -99,0,345,3,100, -0,345,3,101,0, -669,12,1,33898,670, -5,63,3,109,0, -345,3,110,0,345, -3,111,0,345,3, -112,0,345,3,113, -0,345,3,114,0, -345,3,115,0,345, -3,116,0,345,3, -117,0,345,3,118, -0,345,3,119,0, -345,3,120,0,345, -3,121,0,345,3, -122,0,345,3,48, -0,345,3,49,0, -345,3,50,0,345, -3,51,0,345,3, -52,0,345,3,53, -0,345,3,54,0, -345,3,55,0,345, -3,56,0,345,3, -57,0,345,3,65, -0,345,3,66,0, -345,3,67,0,345, -3,68,0,345,3, -69,0,345,3,70, -0,345,3,71,0, -345,3,72,0,345, -3,73,0,345,3, -74,0,345,3,75, -0,345,3,76,0, -345,3,77,0,345, -3,78,0,345,3, -79,0,345,3,80, -0,345,3,81,0, -345,3,82,0,345, -3,83,0,345,3, -84,0,345,3,85, -0,345,3,86,0, -345,3,87,0,345, -3,88,0,345,3, -89,0,345,3,90, -0,345,3,95,0, -345,3,97,0,345, -3,98,0,345,3, -99,0,345,3,100, -0,345,3,101,0, -345,3,102,0,345, -3,103,0,345,3, -104,0,345,3,105, -0,345,3,106,0, -345,3,107,0,345, -3,108,0,345,671, -11,1,484,0,672, -4,38,72,0,84, -0,84,0,80,0, -95,0,82,0,69, -0,83,0,80,0, -79,0,78,0,83, -0,69,0,95,0, -69,0,86,0,69, -0,78,0,84,0, -1,-1,3,102,0, -345,3,103,0,345, -3,104,0,345,3, -105,0,345,3,106, -0,345,3,107,0, -345,3,108,0,345, -673,11,1,867,0, -348,1,-1,3,116, -0,345,3,117,0, -345,3,118,0,345, -3,119,0,345,3, -120,0,345,3,121, -0,345,3,122,0, -345,3,48,0,345, -3,49,0,345,3, -50,0,345,3,51, -0,345,3,52,0, -345,3,53,0,345, -3,54,0,345,3, -55,0,345,3,56, -0,345,3,57,0, -345,3,65,0,345, -3,66,0,345,3, -67,0,345,3,68, -0,345,3,69,0, -345,3,70,0,345, -3,71,0,345,3, -72,0,345,3,73, -0,345,3,74,0, -345,3,75,0,345, -3,76,0,345,3, -77,0,345,3,78, -0,345,3,79,0, -345,3,80,0,345, -3,81,0,345,3, -82,0,345,3,83, -0,345,3,84,0, -345,3,85,0,345, -3,86,0,345,3, -87,0,345,3,88, -0,345,3,89,0, -345,3,90,0,345, -3,95,0,345,3, -97,0,345,3,98, -0,345,3,99,0, -345,3,100,0,345, -3,101,0,345,3, -102,0,345,3,103, -0,345,3,104,0, -345,3,105,0,345, -3,106,0,345,3, -107,0,345,3,108, -0,345,674,11,1, -867,0,348,1,-1, -3,111,0,345,3, -112,0,345,3,113, -0,345,3,114,0, -345,3,115,0,345, -3,116,0,345,3, -117,0,345,3,118, -0,345,3,119,0, -345,3,120,0,345, -3,121,0,345,3, -122,0,345,3,48, -0,345,3,49,0, -345,3,50,0,345, -3,51,0,345,3, -52,0,345,3,53, -0,345,3,54,0, -345,3,55,0,345, -3,56,0,345,3, -57,0,345,3,65, -0,345,3,66,0, -345,3,67,0,345, -3,68,0,345,3, -69,0,345,3,70, -0,345,3,71,0, -345,3,72,0,345, -3,73,0,345,3, -74,0,345,3,75, -0,345,3,76,0, -345,3,77,0,345, -3,78,0,345,3, -79,0,345,3,80, -0,345,3,81,0, -345,3,82,0,345, -3,83,0,345,3, -84,0,345,3,85, -0,345,3,86,0, -345,3,87,0,345, -3,88,0,345,3, -89,0,345,3,90, -0,345,3,95,0, -345,3,97,0,345, -3,98,0,345,3, -99,0,345,3,100, -0,345,3,101,0, -345,3,102,0,345, -3,103,0,345,3, -104,0,345,3,105, -0,345,3,106,0, -345,3,107,0,345, -3,108,0,345,675, -11,1,867,0,348, -1,-1,3,112,0, -345,3,113,0,345, -3,114,0,345,3, -115,0,345,3,116, -0,345,3,117,0, -345,3,118,0,345, -3,119,0,345,3, -120,0,345,3,121, -0,345,3,122,0, -345,3,48,0,345, -3,49,0,345,3, -50,0,345,3,51, -0,345,3,52,0, -345,3,53,0,345, -3,54,0,345,3, -55,0,345,3,56, -0,345,3,57,0, -345,3,65,0,345, -3,66,0,345,3, -67,0,345,3,68, -0,345,3,69,0, -345,3,70,0,345, -3,71,0,345,3, -72,0,345,3,73, -0,345,3,74,0, -345,3,75,0,345, -3,76,0,345,3, -77,0,345,3,78, -0,345,3,79,0, -345,3,80,0,345, -3,81,0,345,3, -82,0,345,3,83, -0,345,3,84,0, -345,3,85,0,345, -3,86,0,345,3, -87,0,345,3,88, -0,345,3,89,0, -345,3,90,0,345, -3,95,0,345,3, -97,0,345,3,98, -0,345,3,99,0, -345,3,100,0,345, -3,101,0,345,3, -102,0,345,3,103, -0,345,3,104,0, -345,3,105,0,345, -3,106,0,345,3, -107,0,345,3,108, -0,345,676,11,1, -867,0,348,1,-1, -3,113,0,345,3, -114,0,345,3,115, -0,345,3,116,0, -345,3,117,0,345, -3,118,0,345,3, -119,0,345,3,120, -0,345,3,121,0, -345,3,122,0,345, -3,48,0,345,3, -49,0,345,3,50, -0,345,3,51,0, -345,3,52,0,345, -3,53,0,345,3, -54,0,345,3,55, -0,345,3,56,0, -345,3,57,0,345, -3,65,0,345,3, -66,0,345,3,67, -0,345,3,68,0, -345,3,69,0,345, -3,70,0,345,3, -71,0,345,3,72, -0,345,3,73,0, -345,3,74,0,345, -3,75,0,345,3, -76,0,345,3,77, -0,345,3,78,0, -345,3,79,0,345, -3,80,0,345,3, -81,0,345,3,82, -0,345,3,83,0, -345,3,84,0,345, -3,85,0,345,3, -86,0,345,3,87, -0,345,3,88,0, -345,3,89,0,345, -3,90,0,345,3, -95,0,345,3,97, -0,345,3,98,0, -345,3,99,0,345, -3,100,0,345,3, -101,0,345,3,102, -0,345,3,103,0, -345,3,104,0,345, -3,105,0,345,3, -106,0,345,3,107, -0,345,3,108,0, -345,677,11,1,867, -0,348,1,-1,3, -116,0,345,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,345,3, -98,0,345,3,99, -0,345,3,100,0, -345,3,101,0,345, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -345,3,106,0,345, -3,107,0,345,3, -108,0,345,678,11, -1,867,0,348,1, --1,3,102,0,345, -3,103,0,345,3, -104,0,345,3,105, -0,345,3,106,0, -345,3,107,0,345, -3,108,0,345,679, -11,1,867,0,348, -1,-1,3,115,0, -345,3,116,0,345, -3,117,0,345,3, -118,0,345,3,119, -0,345,3,120,0, -345,3,121,0,345, -3,122,0,345,3, -48,0,345,3,49, -0,345,3,50,0, -345,3,51,0,345, -3,52,0,345,3, -53,0,345,3,54, -0,345,3,55,0, -345,3,56,0,345, -3,57,0,345,3, -65,0,345,3,66, -0,345,3,67,0, -345,3,68,0,345, -3,69,0,345,3, -70,0,345,3,71, -0,345,3,72,0, -345,3,73,0,345, -3,74,0,345,3, -75,0,345,3,76, -0,345,3,77,0, -345,3,78,0,345, -3,79,0,345,3, -80,0,345,3,81, -0,345,3,82,0, -345,3,83,0,345, -3,84,0,345,3, -85,0,345,3,86, -0,345,3,87,0, -345,3,88,0,345, -3,89,0,345,3, -90,0,345,3,95, -0,345,3,97,0, -345,3,98,0,345, -3,99,0,345,3, -100,0,345,3,101, -0,345,3,102,0, -345,3,103,0,345, -3,104,0,345,3, -105,0,345,3,106, -0,345,3,107,0, -345,3,108,0,345, -680,11,1,867,0, -348,1,-1,3,97, -0,345,3,98,0, -345,3,99,0,345, -3,100,0,345,3, -101,0,345,3,102, -0,345,3,103,0, -345,3,104,0,345, -3,105,0,345,3, -106,0,345,3,107, -0,345,3,108,0, -345,681,11,1,867, -0,348,1,-1,3, -113,0,345,3,114, -0,345,3,115,0, -345,3,116,0,345, -3,117,0,345,3, -118,0,345,3,119, -0,345,3,120,0, -345,3,121,0,345, -3,122,0,345,3, -48,0,345,3,49, -0,345,3,50,0, -345,3,51,0,345, -3,52,0,345,3, -53,0,345,3,54, -0,345,3,55,0, -345,3,56,0,345, -3,57,0,345,3, -65,0,345,3,66, -0,345,3,67,0, -345,3,68,0,345, -3,69,0,345,3, -70,0,345,3,71, -0,345,3,72,0, -345,3,73,0,345, -3,74,0,345,3, -75,0,345,3,76, -0,345,3,77,0, -345,3,78,0,345, -3,79,0,345,3, -80,0,345,3,81, -0,345,3,82,0, -345,3,83,0,345, -3,84,0,345,3, -85,0,345,3,86, -0,345,3,87,0, -345,3,88,0,345, -3,89,0,345,3, -90,0,345,3,95, -0,345,3,97,0, -345,3,98,0,345, -3,99,0,345,3, -100,0,345,3,101, -0,345,3,102,0, -345,3,103,0,345, -3,104,0,345,3, -105,0,345,3,106, -0,345,3,107,0, -345,3,108,0,345, -682,11,1,867,0, -348,1,-1,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,345,3, -98,0,345,3,99, -0,345,3,100,0, -345,3,101,0,345, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -345,3,106,0,345, -3,107,0,345,3, -108,0,345,683,11, -1,867,0,348,1, --1,3,117,0,345, -3,118,0,345,3, -119,0,345,3,120, -0,345,3,121,0, -345,3,122,0,345, -3,48,0,345,3, -49,0,345,3,50, -0,345,3,51,0, -345,3,52,0,345, -3,53,0,345,3, -54,0,345,3,55, -0,345,3,56,0, -345,3,57,0,345, -3,65,0,345,3, -66,0,345,3,67, -0,345,3,68,0, -345,3,69,0,345, -3,70,0,345,3, -71,0,345,3,72, -0,345,3,73,0, -345,3,74,0,345, -3,75,0,345,3, -76,0,345,3,77, -0,345,3,78,0, -345,3,79,0,345, -3,80,0,345,3, -81,0,345,3,82, -0,345,3,83,0, -345,3,84,0,345, -3,85,0,345,3, -86,0,345,3,87, -0,345,3,88,0, -345,3,89,0,345, -3,90,0,345,3, -95,0,345,3,97, -0,345,3,98,0, -345,3,99,0,345, -3,100,0,345,3, -101,0,345,3,102, -0,345,3,103,0, -345,3,104,0,345, -3,105,0,345,3, -106,0,345,3,107, -0,345,3,108,0, -345,684,11,1,867, -0,348,1,-1,3, -105,0,685,12,1, -34987,686,5,63,3, -109,0,345,3,110, -0,687,12,1,35016, -688,5,63,3,109, -0,345,3,110,0, -345,3,111,0,345, -3,112,0,345,3, -113,0,345,3,114, -0,345,3,115,0, -345,3,116,0,689, -12,1,35051,690,5, -63,3,109,0,345, -3,110,0,345,3, -111,0,345,3,112, -0,345,3,113,0, -345,3,114,0,345, -3,115,0,345,3, -116,0,345,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,345,3, -98,0,345,3,99, -0,345,3,100,0, -345,3,101,0,691, -12,1,35098,692,5, -63,3,109,0,345, -3,110,0,345,3, -111,0,345,3,112, -0,345,3,113,0, -345,3,114,0,345, -3,115,0,345,3, -116,0,345,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,345,3, -98,0,345,3,99, -0,345,3,100,0, -345,3,101,0,345, -3,102,0,345,3, -103,0,693,12,1, -35147,694,5,63,3, -109,0,345,3,110, -0,345,3,111,0, -345,3,112,0,345, -3,113,0,345,3, -114,0,345,3,115, -0,345,3,116,0, -345,3,117,0,345, -3,118,0,345,3, -119,0,345,3,120, -0,345,3,121,0, -345,3,122,0,345, -3,48,0,345,3, -49,0,345,3,50, -0,345,3,51,0, -345,3,52,0,345, -3,53,0,345,3, -54,0,345,3,55, -0,345,3,56,0, -345,3,57,0,345, -3,65,0,345,3, -66,0,345,3,67, -0,345,3,68,0, -345,3,69,0,345, -3,70,0,345,3, -71,0,345,3,72, -0,345,3,73,0, -345,3,74,0,345, -3,75,0,345,3, -76,0,345,3,77, -0,345,3,78,0, -345,3,79,0,345, -3,80,0,345,3, -81,0,345,3,82, -0,345,3,83,0, -345,3,84,0,345, -3,85,0,345,3, -86,0,345,3,87, -0,345,3,88,0, -345,3,89,0,345, -3,90,0,345,3, -95,0,345,3,97, -0,345,3,98,0, -345,3,99,0,345, -3,100,0,345,3, -101,0,695,12,1, -35194,696,5,63,3, -109,0,345,3,110, -0,345,3,111,0, -345,3,112,0,345, -3,113,0,345,3, -114,0,697,12,1, -35227,698,5,63,3, -109,0,345,3,110, -0,345,3,111,0, -345,3,112,0,345, -3,113,0,345,3, -114,0,345,3,115, -0,345,3,116,0, -345,3,117,0,345, -3,118,0,345,3, -119,0,345,3,120, -0,345,3,121,0, -345,3,122,0,345, -3,48,0,345,3, -49,0,345,3,50, -0,345,3,51,0, -345,3,52,0,345, -3,53,0,345,3, -54,0,345,3,55, -0,345,3,56,0, -345,3,57,0,345, -3,65,0,345,3, -66,0,345,3,67, -0,345,3,68,0, -345,3,69,0,345, -3,70,0,345,3, -71,0,345,3,72, -0,345,3,73,0, -345,3,74,0,345, -3,75,0,345,3, -76,0,345,3,77, -0,345,3,78,0, -345,3,79,0,345, -3,80,0,345,3, -81,0,345,3,82, -0,345,3,83,0, -345,3,84,0,345, -3,85,0,345,3, -86,0,345,3,87, -0,345,3,88,0, -345,3,89,0,345, -3,90,0,345,3, -95,0,345,3,97, -0,345,3,98,0, -345,3,99,0,345, -3,100,0,345,3, -101,0,345,3,102, -0,345,3,103,0, -345,3,104,0,345, -3,105,0,345,3, -106,0,345,3,107, -0,345,3,108,0, -345,699,11,1,283, -0,700,4,24,73, -0,78,0,84,0, -69,0,71,0,69, -0,82,0,95,0, +3,89,0,180,786, +11,1,867,0,183, +1,-1,3,78,0, +180,3,51,0,180, +3,113,0,180,3, +86,0,180,3,121, +0,180,3,67,0, +180,3,102,0,180, +3,75,0,180,3, +48,0,180,3,110, +0,180,3,83,0, +180,3,56,0,180, +3,118,0,180,3, +99,0,180,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,180,3,88, +0,180,3,69,0, +180,3,104,0,180, +3,77,0,180,3, +50,0,180,3,112, +0,180,3,85,0, +180,3,120,0,180, +3,66,0,180,3, +101,0,180,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +180,3,87,0,180, +3,122,0,180,3, +95,0,180,3,68, +0,180,3,103,0, +180,3,76,0,180, +3,49,0,180,3, +111,0,180,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,180,3,73, +0,180,3,108,0, +180,3,81,0,180, +3,54,0,180,3, +116,0,180,3,89, +0,180,787,11,1, +867,0,183,1,-1, +3,66,0,180,3, +101,0,180,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +180,3,87,0,180, +3,122,0,180,3, +95,0,180,3,68, +0,180,3,103,0, +180,3,76,0,180, +3,49,0,180,3, +111,0,180,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,180,3,73, +0,180,3,108,0, +180,3,81,0,180, +3,54,0,180,3, +116,0,180,3,89, +0,180,788,11,1, +867,0,183,1,-1, +3,74,0,180,3, +109,0,180,3,82, +0,180,3,55,0, +180,3,117,0,180, +3,90,0,180,3, +98,0,180,3,71, +0,180,3,106,0, +180,3,79,0,180, +3,52,0,180,3, +114,0,180,3,87, +0,180,3,122,0, +180,3,95,0,180, +3,68,0,180,3, +103,0,180,3,76, +0,180,3,49,0, +180,3,111,0,180, +3,84,0,180,3, +57,0,180,3,119, +0,180,3,65,0, +180,3,100,0,180, +3,73,0,180,3, +108,0,180,3,81, +0,180,3,54,0, +180,3,116,0,180, +3,89,0,180,789, +11,1,867,0,183, +1,-1,3,68,0, +180,3,103,0,180, +3,76,0,180,3, +49,0,180,3,111, +0,180,3,84,0, +180,3,57,0,180, +3,119,0,180,3, +65,0,180,3,100, +0,180,3,73,0, +180,3,108,0,180, +3,81,0,180,3, +54,0,180,3,116, +0,180,3,89,0, +180,790,11,1,256, +0,791,4,10,83, +0,84,0,65,0, +84,0,69,0,1, +-1,3,74,0,180, +3,109,0,180,3, +82,0,180,3,55, +0,180,3,117,0, +180,3,90,0,180, +3,98,0,180,3, +71,0,180,3,106, +0,180,3,79,0, +180,3,52,0,180, +3,114,0,180,3, +87,0,180,3,122, +0,180,3,95,0, +180,3,68,0,180, +3,103,0,180,3, +76,0,180,3,49, +0,180,3,111,0, +180,3,84,0,180, +3,57,0,180,3, +119,0,180,3,65, +0,180,3,100,0, +180,3,73,0,180, +3,108,0,180,3, +81,0,180,3,54, +0,180,3,116,0, +180,3,89,0,180, +792,11,1,867,0, +183,1,-1,3,89, +0,180,793,11,1, +867,0,183,1,-1, +3,70,0,180,3, +105,0,180,3,78, +0,180,3,51,0, +180,3,113,0,180, +3,86,0,180,3, +121,0,180,3,67, +0,180,3,102,0, +180,3,75,0,180, +3,48,0,180,3, +110,0,180,3,83, +0,180,3,56,0, +180,3,118,0,180, +3,99,0,180,3, +72,0,180,3,107, +0,180,3,80,0, +180,3,53,0,180, +3,115,0,180,3, +88,0,180,3,69, +0,180,3,104,0, +180,3,77,0,180, +3,50,0,180,3, +112,0,180,3,85, +0,180,3,120,0, +180,3,66,0,180, +3,101,0,180,3, +74,0,180,3,109, +0,180,3,82,0, +180,3,55,0,180, +3,117,0,180,3, +90,0,180,3,98, +0,180,3,71,0, +180,3,106,0,180, +3,79,0,180,3, +52,0,180,3,114, +0,794,12,1,24391, +795,5,63,3,97, +0,180,3,70,0, +180,3,105,0,796, +12,1,24459,797,5, +63,3,97,0,180, +3,70,0,180,3, +105,0,180,3,78, +0,180,3,51,0, +180,3,113,0,180, +3,86,0,180,3, +121,0,180,3,67, +0,180,3,102,0, +180,3,75,0,180, +3,48,0,180,3, +110,0,798,12,1, +24531,799,5,63,3, +97,0,180,3,70, +0,180,3,105,0, +180,3,78,0,180, +3,51,0,180,3, +113,0,180,3,86, +0,180,3,121,0, +180,3,67,0,180, +3,102,0,180,3, +75,0,180,3,48, +0,180,3,110,0, +180,3,83,0,180, +3,56,0,180,3, +118,0,180,3,99, +0,180,3,72,0, +180,3,107,0,180, +3,80,0,180,3, +53,0,180,3,115, +0,180,3,88,0, +180,3,69,0,180, +3,104,0,180,3, +77,0,180,3,50, +0,180,3,112,0, +180,3,85,0,180, +3,120,0,180,3, +66,0,180,3,101, +0,180,3,74,0, +180,3,109,0,180, +3,82,0,180,3, +55,0,180,3,117, +0,180,3,90,0, +180,3,98,0,180, +3,71,0,180,3, +106,0,180,3,79, +0,180,3,52,0, +180,3,114,0,180, +3,87,0,180,3, +122,0,180,3,95, +0,180,3,68,0, +180,3,103,0,800, +12,1,24618,801,5, +63,3,97,0,180, +3,70,0,180,3, +105,0,180,3,78, +0,180,3,51,0, +180,3,113,0,180, +3,86,0,180,3, +121,0,180,3,67, +0,180,3,102,0, +180,3,75,0,180, +3,48,0,180,3, +110,0,180,3,83, +0,180,3,56,0, +180,3,118,0,180, +3,99,0,180,3, +72,0,180,3,107, +0,180,3,80,0, +180,3,53,0,180, +3,115,0,180,3, +88,0,180,3,69, +0,180,3,104,0, +180,3,77,0,180, +3,50,0,180,3, +112,0,180,3,85, +0,180,3,120,0, +180,3,66,0,180, +3,101,0,180,3, +74,0,180,3,109, +0,180,3,82,0, +180,3,55,0,180, +3,117,0,180,3, +90,0,180,3,98, +0,180,3,71,0, +180,3,106,0,180, +3,79,0,180,3, +52,0,180,3,114, +0,180,3,87,0, +180,3,122,0,180, +3,95,0,180,3, +68,0,180,3,103, +0,180,3,76,0, +180,3,49,0,180, +3,111,0,180,3, +84,0,180,3,57, +0,180,3,119,0, +180,3,65,0,180, +3,100,0,180,3, +73,0,180,3,108, +0,180,3,81,0, +180,3,54,0,180, +3,116,0,180,3, +89,0,180,802,11, +1,303,0,803,4, +22,83,0,84,0, +82,0,73,0,78, +0,71,0,95,0, 84,0,89,0,80, 0,69,0,1,-1, -3,115,0,345,3, -116,0,345,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,345,3, -98,0,345,3,99, -0,345,3,100,0, -345,3,101,0,345, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -345,3,106,0,345, -3,107,0,345,3, -108,0,345,701,11, -1,867,0,348,1, --1,3,102,0,345, -3,103,0,345,3, -104,0,345,3,105, -0,345,3,106,0, -345,3,107,0,345, -3,108,0,345,702, -11,1,867,0,348, -1,-1,3,104,0, -345,3,105,0,345, -3,106,0,345,3, -107,0,345,3,108, -0,345,703,11,1, -867,0,348,1,-1, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -345,3,106,0,345, -3,107,0,345,3, -108,0,345,704,11, -1,867,0,348,1, --1,3,117,0,345, -3,118,0,345,3, -119,0,345,3,120, -0,345,3,121,0, -345,3,122,0,345, -3,48,0,345,3, -49,0,345,3,50, -0,345,3,51,0, -345,3,52,0,345, -3,53,0,345,3, -54,0,345,3,55, -0,345,3,56,0, -345,3,57,0,345, -3,65,0,345,3, -66,0,345,3,67, -0,345,3,68,0, -345,3,69,0,345, -3,70,0,345,3, -71,0,345,3,72, -0,345,3,73,0, -345,3,74,0,345, -3,75,0,345,3, -76,0,345,3,77, -0,345,3,78,0, -345,3,79,0,345, -3,80,0,345,3, -81,0,345,3,82, -0,345,3,83,0, -345,3,84,0,345, -3,85,0,345,3, -86,0,345,3,87, -0,345,3,88,0, -345,3,89,0,345, -3,90,0,345,3, -95,0,345,3,97, -0,345,3,98,0, -345,3,99,0,345, -3,100,0,345,3, -101,0,345,3,102, -0,345,3,103,0, -345,3,104,0,345, -3,105,0,345,3, -106,0,345,3,107, -0,345,3,108,0, -345,705,11,1,867, -0,348,1,-1,3, -111,0,345,3,112, -0,345,3,113,0, -345,3,114,0,345, -3,115,0,345,3, -116,0,345,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,345,3, -98,0,345,3,99, -0,345,3,100,0, -345,3,101,0,345, -3,102,0,706,12, -1,35755,707,5,63, -3,109,0,345,3, -110,0,345,3,111, -0,345,3,112,0, -345,3,113,0,345, -3,114,0,345,3, -115,0,345,3,116, -0,345,3,117,0, -345,3,118,0,345, -3,119,0,345,3, -120,0,345,3,121, -0,345,3,122,0, -345,3,48,0,345, -3,49,0,345,3, -50,0,345,3,51, -0,345,3,52,0, -345,3,53,0,345, -3,54,0,345,3, -55,0,345,3,56, -0,345,3,57,0, -345,3,65,0,345, -3,66,0,345,3, -67,0,345,3,68, -0,345,3,69,0, -345,3,70,0,345, -3,71,0,345,3, -72,0,345,3,73, -0,345,3,74,0, -345,3,75,0,345, -3,76,0,345,3, -77,0,345,3,78, -0,345,3,79,0, -345,3,80,0,345, -3,81,0,345,3, -82,0,345,3,83, -0,345,3,84,0, -345,3,85,0,345, -3,86,0,345,3, -87,0,345,3,88, -0,345,3,89,0, -345,3,90,0,345, -3,95,0,345,3, -97,0,345,3,98, -0,345,3,99,0, -345,3,100,0,345, -3,101,0,345,3, -102,0,345,3,103, -0,345,3,104,0, -345,3,105,0,345, -3,106,0,345,3, -107,0,345,3,108, -0,345,708,11,1, -209,0,709,4,4, -73,0,70,0,1, --1,3,103,0,345, -3,104,0,345,3, -105,0,345,3,106, -0,345,3,107,0, -345,3,108,0,345, -710,11,1,867,0, -348,1,-1,3,106, -0,711,12,1,35948, -712,5,63,3,109, -0,345,3,110,0, -345,3,111,0,345, -3,112,0,345,3, -113,0,345,3,114, -0,345,3,115,0, -345,3,116,0,345, -3,117,0,713,12, -1,35984,714,5,63, -3,109,0,715,12, -1,36012,716,5,63, -3,109,0,345,3, -110,0,345,3,111, -0,345,3,112,0, -717,12,1,36043,718, -5,63,3,109,0, -345,3,110,0,345, -3,111,0,345,3, -112,0,345,3,113, -0,345,3,114,0, -345,3,115,0,345, -3,116,0,345,3, -117,0,345,3,118, -0,345,3,119,0, -345,3,120,0,345, -3,121,0,345,3, -122,0,345,3,48, -0,345,3,49,0, -345,3,50,0,345, -3,51,0,345,3, -52,0,345,3,53, -0,345,3,54,0, -345,3,55,0,345, -3,56,0,345,3, -57,0,345,3,65, -0,345,3,66,0, -345,3,67,0,345, -3,68,0,345,3, -69,0,345,3,70, -0,345,3,71,0, -345,3,72,0,345, -3,73,0,345,3, -74,0,345,3,75, -0,345,3,76,0, -345,3,77,0,345, -3,78,0,345,3, -79,0,345,3,80, -0,345,3,81,0, -345,3,82,0,345, -3,83,0,345,3, -84,0,345,3,85, -0,345,3,86,0, -345,3,87,0,345, -3,88,0,345,3, -89,0,345,3,90, -0,345,3,95,0, -345,3,97,0,345, -3,98,0,345,3, -99,0,345,3,100, -0,345,3,101,0, -345,3,102,0,345, -3,103,0,345,3, -104,0,345,3,105, -0,345,3,106,0, -345,3,107,0,345, -3,108,0,345,719, -11,1,265,0,720, -4,8,74,0,85, -0,77,0,80,0, -1,-1,3,113,0, -345,3,114,0,345, -3,115,0,345,3, -116,0,345,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,345,3, -98,0,345,3,99, -0,345,3,100,0, -345,3,101,0,345, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -345,3,106,0,345, -3,107,0,345,3, -108,0,345,721,11, -1,867,0,348,1, --1,3,110,0,345, -3,111,0,345,3, -112,0,345,3,113, -0,345,3,114,0, -345,3,115,0,345, -3,116,0,345,3, -117,0,345,3,118, -0,345,3,119,0, -345,3,120,0,345, -3,121,0,345,3, -122,0,345,3,48, -0,345,3,49,0, -345,3,50,0,345, -3,51,0,345,3, -52,0,345,3,53, -0,345,3,54,0, -345,3,55,0,345, -3,56,0,345,3, -57,0,345,3,65, -0,345,3,66,0, -345,3,67,0,345, -3,68,0,345,3, -69,0,345,3,70, -0,345,3,71,0, -345,3,72,0,345, -3,73,0,345,3, -74,0,345,3,75, -0,345,3,76,0, -345,3,77,0,345, -3,78,0,345,3, -79,0,345,3,80, -0,345,3,81,0, -345,3,82,0,345, -3,83,0,345,3, -84,0,345,3,85, -0,345,3,86,0, -345,3,87,0,345, -3,88,0,345,3, -89,0,345,3,90, -0,345,3,95,0, -345,3,97,0,345, -3,98,0,345,3, -99,0,345,3,100, -0,345,3,101,0, -345,3,102,0,345, -3,103,0,345,3, -104,0,345,3,105, -0,345,3,106,0, -345,3,107,0,345, -3,108,0,345,722, -11,1,867,0,348, -1,-1,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,345,3, -98,0,345,3,99, -0,345,3,100,0, -345,3,101,0,345, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -345,3,106,0,345, -3,107,0,345,3, -108,0,345,723,11, -1,867,0,348,1, --1,3,107,0,724, -12,1,36429,725,5, -63,3,109,0,345, -3,110,0,345,3, -111,0,345,3,112, -0,345,3,113,0, -345,3,114,0,345, -3,115,0,345,3, -116,0,345,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,345,3, -98,0,345,3,99, -0,345,3,100,0, -345,3,101,0,726, -12,1,36476,727,5, -63,3,109,0,345, -3,110,0,345,3, -111,0,345,3,112, -0,345,3,113,0, -345,3,114,0,345, -3,115,0,345,3, -116,0,345,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,728,12,1, -36516,729,5,63,3, -109,0,345,3,110, -0,345,3,111,0, -345,3,112,0,345, -3,113,0,345,3, -114,0,345,3,115, -0,345,3,116,0, -345,3,117,0,345, -3,118,0,345,3, -119,0,345,3,120, -0,345,3,121,0, -345,3,122,0,345, -3,48,0,345,3, -49,0,345,3,50, -0,345,3,51,0, -345,3,52,0,345, -3,53,0,345,3, -54,0,345,3,55, -0,345,3,56,0, -345,3,57,0,345, -3,65,0,345,3, -66,0,345,3,67, -0,345,3,68,0, -345,3,69,0,345, -3,70,0,345,3, -71,0,345,3,72, -0,345,3,73,0, -345,3,74,0,345, -3,75,0,345,3, -76,0,345,3,77, -0,345,3,78,0, -345,3,79,0,345, -3,80,0,345,3, -81,0,345,3,82, -0,345,3,83,0, -345,3,84,0,345, -3,85,0,345,3, -86,0,345,3,87, -0,345,3,88,0, -345,3,89,0,345, -3,90,0,345,3, -95,0,345,3,97, -0,345,3,98,0, -345,3,99,0,345, -3,100,0,345,3, -101,0,345,3,102, -0,345,3,103,0, -345,3,104,0,345, -3,105,0,345,3, -106,0,345,3,107, -0,345,3,108,0, -345,730,11,1,313, -0,731,4,16,75, -0,69,0,89,0, -95,0,84,0,89, -0,80,0,69,0, -1,-1,3,122,0, -345,3,48,0,345, -3,49,0,345,3, -50,0,345,3,51, -0,345,3,52,0, -345,3,53,0,345, -3,54,0,345,3, -55,0,345,3,56, -0,345,3,57,0, -345,3,65,0,345, -3,66,0,345,3, -67,0,345,3,68, -0,345,3,69,0, -345,3,70,0,345, -3,71,0,345,3, -72,0,345,3,73, -0,345,3,74,0, -345,3,75,0,345, -3,76,0,345,3, -77,0,345,3,78, -0,345,3,79,0, -345,3,80,0,345, -3,81,0,345,3, -82,0,345,3,83, -0,345,3,84,0, -345,3,85,0,345, -3,86,0,345,3, -87,0,345,3,88, -0,345,3,89,0, -345,3,90,0,345, -3,95,0,345,3, -97,0,345,3,98, -0,345,3,99,0, -345,3,100,0,345, -3,101,0,345,3, -102,0,345,3,103, -0,345,3,104,0, -345,3,105,0,345, -3,106,0,345,3, -107,0,345,3,108, -0,345,732,11,1, -867,0,348,1,-1, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -345,3,106,0,345, -3,107,0,345,3, -108,0,345,733,11, -1,867,0,348,1, --1,3,108,0,734, -12,1,36790,735,5, -63,3,109,0,345, -3,110,0,345,3, -111,0,345,3,112, -0,345,3,113,0, -345,3,114,0,345, -3,115,0,345,3, -116,0,345,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,736,12, -1,36833,737,5,63, -3,109,0,345,3, -110,0,738,12,1, -36862,739,5,63,3, -109,0,345,3,110, -0,345,3,111,0, -345,3,112,0,345, -3,113,0,345,3, -114,0,345,3,115, -0,345,3,116,0, -345,3,117,0,345, -3,118,0,345,3, -119,0,345,3,120, -0,345,3,121,0, -345,3,122,0,345, -3,48,0,345,3, -49,0,345,3,50, -0,345,3,51,0, -345,3,52,0,345, -3,53,0,345,3, -54,0,345,3,55, -0,345,3,56,0, -345,3,57,0,345, -3,65,0,345,3, -66,0,345,3,67, -0,345,3,68,0, -345,3,69,0,345, -3,70,0,345,3, -71,0,345,3,72, -0,345,3,73,0, -345,3,74,0,345, -3,75,0,345,3, -76,0,345,3,77, -0,345,3,78,0, -345,3,79,0,345, -3,80,0,345,3, -81,0,345,3,82, -0,345,3,83,0, -345,3,84,0,345, -3,85,0,345,3, -86,0,345,3,87, -0,345,3,88,0, -345,3,89,0,345, -3,90,0,345,3, -95,0,345,3,97, -0,345,3,98,0, -345,3,99,0,345, -3,100,0,740,12, -1,36908,741,5,63, -3,109,0,345,3, -110,0,345,3,111, -0,345,3,112,0, -345,3,113,0,345, -3,114,0,345,3, -115,0,345,3,116, -0,345,3,117,0, -345,3,118,0,345, -3,119,0,345,3, -120,0,345,3,121, -0,345,3,122,0, -345,3,48,0,345, -3,49,0,345,3, -50,0,345,3,51, -0,345,3,52,0, -345,3,53,0,345, -3,54,0,345,3, -55,0,345,3,56, -0,345,3,57,0, -345,3,65,0,345, -3,66,0,345,3, -67,0,345,3,68, -0,345,3,69,0, -345,3,70,0,345, -3,71,0,345,3, -72,0,345,3,73, -0,345,3,74,0, -345,3,75,0,345, -3,76,0,345,3, -77,0,345,3,78, -0,345,3,79,0, -345,3,80,0,345, -3,81,0,345,3, -82,0,345,3,83, -0,345,3,84,0, -345,3,85,0,345, -3,86,0,345,3, -87,0,345,3,88, -0,345,3,89,0, -345,3,90,0,345, -3,95,0,742,12, -1,36994,743,5,63, -3,109,0,345,3, -110,0,345,3,111, -0,345,3,112,0, -345,3,113,0,345, -3,114,0,345,3, -115,0,345,3,116, -0,345,3,117,0, -345,3,118,0,345, -3,119,0,345,3, -120,0,345,3,121, -0,345,3,122,0, -345,3,48,0,345, -3,49,0,345,3, -50,0,345,3,51, -0,345,3,52,0, -345,3,53,0,345, -3,54,0,345,3, -55,0,345,3,56, -0,345,3,57,0, -345,3,65,0,345, -3,66,0,345,3, -67,0,345,3,68, -0,345,3,69,0, -345,3,70,0,345, -3,71,0,345,3, -72,0,345,3,73, -0,345,3,74,0, -345,3,75,0,345, -3,76,0,345,3, -77,0,345,3,78, -0,345,3,79,0, -345,3,80,0,345, -3,81,0,345,3, -82,0,345,3,83, -0,345,3,84,0, -345,3,85,0,345, -3,86,0,345,3, -87,0,345,3,88, -0,345,3,89,0, -345,3,90,0,345, -3,95,0,345,3, -97,0,345,3,98, -0,345,3,99,0, -744,12,1,37039,745, -5,63,3,109,0, -345,3,110,0,345, -3,111,0,746,12, -1,37069,747,5,63, -3,109,0,345,3, -110,0,345,3,111, -0,345,3,112,0, -345,3,113,0,345, -3,114,0,345,3, -115,0,345,3,116, -0,345,3,117,0, -345,3,118,0,345, -3,119,0,345,3, -120,0,345,3,121, -0,345,3,122,0, -345,3,48,0,345, -3,49,0,345,3, -50,0,345,3,51, -0,345,3,52,0, -345,3,53,0,345, -3,54,0,345,3, -55,0,345,3,56, -0,345,3,57,0, -345,3,65,0,345, -3,66,0,345,3, -67,0,345,3,68, -0,345,3,69,0, -345,3,70,0,345, -3,71,0,345,3, -72,0,345,3,73, -0,345,3,74,0, -345,3,75,0,345, -3,76,0,345,3, -77,0,345,3,78, -0,345,3,79,0, -345,3,80,0,345, -3,81,0,345,3, -82,0,345,3,83, -0,345,3,84,0, -345,3,85,0,345, -3,86,0,345,3, -87,0,345,3,88, -0,345,3,89,0, -345,3,90,0,345, -3,95,0,345,3, -97,0,345,3,98, -0,345,3,99,0, -345,3,100,0,345, -3,101,0,345,3, -102,0,345,3,103, -0,345,3,104,0, -345,3,105,0,345, -3,106,0,345,3, -107,0,345,3,108, -0,748,12,1,37123, -749,5,63,3,109, -0,345,3,110,0, -345,3,111,0,345, -3,112,0,345,3, -113,0,345,3,114, -0,345,3,115,0, -345,3,116,0,345, -3,117,0,345,3, -118,0,345,3,119, -0,345,3,120,0, -345,3,121,0,345, -3,122,0,345,3, -48,0,345,3,49, -0,345,3,50,0, -345,3,51,0,345, -3,52,0,345,3, -53,0,345,3,54, -0,345,3,55,0, -345,3,56,0,345, -3,57,0,345,3, -65,0,345,3,66, -0,345,3,67,0, -345,3,68,0,345, -3,69,0,345,3, -70,0,345,3,71, -0,345,3,72,0, -345,3,73,0,345, -3,74,0,345,3, -75,0,345,3,76, -0,345,3,77,0, -345,3,78,0,345, -3,79,0,345,3, -80,0,345,3,81, -0,345,3,82,0, -345,3,83,0,345, -3,84,0,345,3, -85,0,345,3,86, -0,345,3,87,0, -345,3,88,0,345, -3,89,0,345,3, -90,0,345,3,95, -0,345,3,97,0, -345,3,98,0,345, -3,99,0,345,3, -100,0,345,3,101, -0,345,3,102,0, -345,3,103,0,345, -3,104,0,345,3, -105,0,345,3,106, -0,345,3,107,0, -345,3,108,0,750, -12,1,37177,751,5, -63,3,109,0,345, -3,110,0,345,3, -111,0,345,3,112, -0,345,3,113,0, -345,3,114,0,345, -3,115,0,345,3, -116,0,345,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,345,3, -98,0,345,3,99, -0,345,3,100,0, -345,3,101,0,345, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -752,12,1,37228,753, -5,63,3,109,0, -345,3,110,0,345, -3,111,0,345,3, -112,0,345,3,113, -0,345,3,114,0, -345,3,115,0,754, -12,1,37262,755,5, -63,3,109,0,345, -3,110,0,345,3, -111,0,345,3,112, -0,345,3,113,0, -345,3,114,0,345, -3,115,0,345,3, -116,0,345,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,345,3, -98,0,345,3,99, -0,345,3,100,0, -345,3,101,0,345, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -756,12,1,37313,757, -5,63,3,109,0, -345,3,110,0,345, -3,111,0,758,12, -1,37343,759,5,63, -3,109,0,345,3, -110,0,760,12,1, -37372,761,5,63,3, -109,0,345,3,110, -0,345,3,111,0, -345,3,112,0,345, -3,113,0,345,3, -114,0,345,3,115, -0,345,3,116,0, -345,3,117,0,345, -3,118,0,345,3, -119,0,345,3,120, -0,345,3,121,0, -345,3,122,0,345, -3,48,0,345,3, -49,0,345,3,50, -0,345,3,51,0, -345,3,52,0,345, -3,53,0,345,3, -54,0,345,3,55, -0,345,3,56,0, -345,3,57,0,345, -3,65,0,345,3, -66,0,345,3,67, -0,345,3,68,0, -345,3,69,0,345, -3,70,0,345,3, -71,0,345,3,72, -0,345,3,73,0, -345,3,74,0,345, -3,75,0,345,3, -76,0,345,3,77, -0,345,3,78,0, -345,3,79,0,345, -3,80,0,345,3, -81,0,345,3,82, -0,345,3,83,0, -345,3,84,0,345, -3,85,0,345,3, -86,0,345,3,87, -0,345,3,88,0, -345,3,89,0,345, -3,90,0,345,3, -95,0,762,12,1, -37458,763,5,63,3, -109,0,345,3,110, -0,345,3,111,0, -345,3,112,0,345, -3,113,0,345,3, -114,0,345,3,115, -0,764,12,1,37492, -765,5,63,3,109, -0,345,3,110,0, -345,3,111,0,345, -3,112,0,345,3, -113,0,345,3,114, -0,345,3,115,0, -345,3,116,0,766, -12,1,37527,767,5, -63,3,109,0,345, -3,110,0,345,3, -111,0,345,3,112, -0,345,3,113,0, -345,3,114,0,345, -3,115,0,345,3, -116,0,345,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,768,12, -1,37570,769,5,63, -3,109,0,345,3, -110,0,345,3,111, -0,345,3,112,0, -345,3,113,0,345, -3,114,0,770,12, -1,37603,771,5,63, -3,109,0,345,3, -110,0,345,3,111, -0,345,3,112,0, -345,3,113,0,345, -3,114,0,345,3, -115,0,345,3,116, -0,772,12,1,37638, -773,5,63,3,109, -0,345,3,110,0, -345,3,111,0,345, -3,112,0,345,3, -113,0,345,3,114, -0,345,3,115,0, -345,3,116,0,345, -3,117,0,345,3, -118,0,345,3,119, -0,345,3,120,0, -345,3,121,0,345, -3,122,0,345,3, -48,0,345,3,49, -0,345,3,50,0, -345,3,51,0,345, -3,52,0,345,3, -53,0,345,3,54, -0,345,3,55,0, -345,3,56,0,345, -3,57,0,345,3, -65,0,345,3,66, -0,345,3,67,0, -345,3,68,0,345, -3,69,0,345,3, -70,0,345,3,71, -0,345,3,72,0, -345,3,73,0,345, -3,74,0,345,3, -75,0,345,3,76, -0,345,3,77,0, -345,3,78,0,345, -3,79,0,345,3, -80,0,345,3,81, -0,345,3,82,0, -345,3,83,0,345, -3,84,0,345,3, -85,0,345,3,86, -0,345,3,87,0, -345,3,88,0,345, -3,89,0,345,3, -90,0,345,3,95, -0,345,3,97,0, -345,3,98,0,345, -3,99,0,345,3, -100,0,345,3,101, -0,345,3,102,0, -345,3,103,0,345, -3,104,0,345,3, -105,0,345,3,106, -0,345,3,107,0, -345,3,108,0,345, -774,11,1,541,0, -775,4,52,76,0, -65,0,78,0,68, -0,95,0,67,0, -79,0,76,0,76, -0,73,0,83,0, -73,0,79,0,78, +3,76,0,180,3, +49,0,180,3,111, +0,180,3,84,0, +180,3,57,0,180, +3,119,0,180,3, +65,0,180,3,100, +0,180,3,73,0, +180,3,108,0,180, +3,81,0,180,3, +54,0,180,3,116, +0,180,3,89,0, +180,804,11,1,867, +0,183,1,-1,3, +83,0,180,3,56, +0,180,3,118,0, +180,3,99,0,180, +3,72,0,180,3, +107,0,180,3,80, +0,180,3,53,0, +180,3,115,0,180, +3,88,0,180,3, +69,0,180,3,104, +0,180,3,77,0, +180,3,50,0,180, +3,112,0,180,3, +85,0,180,3,120, +0,180,3,66,0, +180,3,101,0,180, +3,74,0,180,3, +109,0,180,3,82, +0,180,3,55,0, +180,3,117,0,180, +3,90,0,180,3, +98,0,180,3,71, +0,180,3,106,0, +180,3,79,0,180, +3,52,0,180,3, +114,0,180,3,87, +0,180,3,122,0, +180,3,95,0,180, +3,68,0,180,3, +103,0,180,3,76, +0,180,3,49,0, +180,3,111,0,180, +3,84,0,180,3, +57,0,180,3,119, +0,180,3,65,0, +180,3,100,0,180, +3,73,0,180,3, +108,0,180,3,81, +0,180,3,54,0, +180,3,116,0,180, +3,89,0,180,805, +11,1,867,0,183, +1,-1,3,78,0, +180,3,51,0,180, +3,113,0,180,3, +86,0,180,3,121, +0,180,3,67,0, +180,3,102,0,180, +3,75,0,180,3, +48,0,180,3,110, +0,180,3,83,0, +180,3,56,0,180, +3,118,0,180,3, +99,0,180,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,180,3,88, +0,180,3,69,0, +180,3,104,0,180, +3,77,0,180,3, +50,0,180,3,112, +0,180,3,85,0, +180,3,120,0,180, +3,66,0,180,3, +101,0,180,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +180,3,87,0,180, +3,122,0,180,3, +95,0,180,3,68, +0,180,3,103,0, +180,3,76,0,180, +3,49,0,180,3, +111,0,180,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,180,3,73, +0,180,3,108,0, +180,3,81,0,180, +3,54,0,180,3, +116,0,180,3,89, +0,180,806,11,1, +867,0,183,1,-1, +3,87,0,180,3, +122,0,180,3,95, +0,180,3,68,0, +180,3,103,0,180, +3,76,0,180,3, +49,0,180,3,111, +0,180,3,84,0, +180,3,57,0,180, +3,119,0,180,3, +65,0,180,3,100, +0,180,3,73,0, +180,3,108,0,180, +3,81,0,180,3, +54,0,180,3,116, +0,180,3,89,0, +180,807,11,1,867, +0,183,1,-1,3, +89,0,180,808,11, +1,867,0,183,1, +-1,3,75,0,178, +3,112,0,178,3, +72,0,178,3,32, +0,672,3,109,0, +809,12,1,28058,810, +5,63,3,97,0, +180,3,70,0,180, +3,105,0,180,3, +78,0,180,3,51, +0,180,3,113,0, +180,3,86,0,180, +3,121,0,180,3, +67,0,180,3,102, +0,180,3,75,0, +180,3,48,0,180, +3,110,0,180,3, +83,0,180,3,56, +0,180,3,118,0, +180,3,99,0,180, +3,72,0,180,3, +107,0,180,3,80, +0,180,3,53,0, +180,3,115,0,180, +3,88,0,180,3, +69,0,180,3,104, +0,180,3,77,0, +180,3,50,0,180, +3,112,0,180,3, +85,0,180,3,120, +0,180,3,66,0, +180,3,101,0,180, +3,74,0,180,3, +109,0,180,3,82, +0,180,3,55,0, +180,3,117,0,180, +3,90,0,180,3, +98,0,180,3,71, +0,180,3,106,0, +180,3,79,0,180, +3,52,0,180,3, +114,0,180,3,87, +0,180,3,122,0, +180,3,95,0,180, +3,68,0,180,3, +103,0,180,3,76, +0,180,3,49,0, +180,3,111,0,811, +12,1,28146,812,5, +63,3,97,0,180, +3,70,0,180,3, +105,0,180,3,78, +0,180,3,51,0, +180,3,113,0,180, +3,86,0,180,3, +121,0,180,3,67, +0,180,3,102,0, +180,3,75,0,180, +3,48,0,180,3, +110,0,813,12,1, +28218,814,5,63,3, +97,0,180,3,70, +0,180,3,105,0, +180,3,78,0,180, +3,51,0,180,3, +113,0,180,3,86, +0,180,3,121,0, +180,3,67,0,180, +3,102,0,180,3, +75,0,180,3,48, +0,180,3,110,0, +180,3,83,0,180, +3,56,0,180,3, +118,0,180,3,99, +0,180,3,72,0, +180,3,107,0,180, +3,80,0,180,3, +53,0,180,3,115, +0,180,3,88,0, +180,3,69,0,180, +3,104,0,180,3, +77,0,180,3,50, +0,180,3,112,0, +180,3,85,0,180, +3,120,0,180,3, +66,0,180,3,101, +0,815,12,1,28298, +816,5,63,3,97, +0,180,3,70,0, +180,3,105,0,180, +3,78,0,180,3, +51,0,180,3,113, +0,180,3,86,0, +180,3,121,0,817, +12,1,28368,818,5, +63,3,97,0,180, +3,70,0,180,3, +105,0,180,3,78, +0,180,3,51,0, +180,3,113,0,180, +3,86,0,180,3, +121,0,180,3,67, +0,180,3,102,0, +180,3,75,0,180, +3,48,0,180,3, +110,0,180,3,83, +0,180,3,56,0, +180,3,118,0,180, +3,99,0,180,3, +72,0,180,3,107, +0,180,3,80,0, +180,3,53,0,180, +3,115,0,180,3, +88,0,180,3,69, +0,180,3,104,0, +180,3,77,0,180, +3,50,0,180,3, +112,0,180,3,85, +0,180,3,120,0, +180,3,66,0,180, +3,101,0,180,3, +74,0,180,3,109, +0,180,3,82,0, +180,3,55,0,180, +3,117,0,180,3, +90,0,180,3,98, +0,180,3,71,0, +180,3,106,0,180, +3,79,0,180,3, +52,0,180,3,114, +0,180,3,87,0, +180,3,122,0,180, +3,95,0,180,3, +68,0,180,3,103, +0,180,3,76,0, +180,3,49,0,180, +3,111,0,180,3, +84,0,180,3,57, +0,180,3,119,0, +180,3,65,0,180, +3,100,0,180,3, +73,0,180,3,108, +0,180,3,81,0, +180,3,54,0,180, +3,116,0,180,3, +89,0,180,819,11, +1,591,0,820,4, +22,77,0,79,0, +78,0,69,0,89, +0,95,0,69,0, +86,0,69,0,78, +0,84,0,1,-1, +3,67,0,180,3, +102,0,180,3,75, +0,180,3,48,0, +180,3,110,0,180, +3,83,0,180,3, +56,0,180,3,118, +0,180,3,99,0, +180,3,72,0,180, +3,107,0,180,3, +80,0,180,3,53, +0,180,3,115,0, +180,3,88,0,180, +3,69,0,180,3, +104,0,180,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,180,3,66, +0,180,3,101,0, +180,3,74,0,180, +3,109,0,180,3, +82,0,180,3,55, +0,180,3,117,0, +180,3,90,0,180, +3,98,0,180,3, +71,0,180,3,106, +0,180,3,79,0, +180,3,52,0,180, +3,114,0,180,3, +87,0,180,3,122, +0,180,3,95,0, +180,3,68,0,180, +3,103,0,180,3, +76,0,180,3,49, +0,180,3,111,0, +180,3,84,0,180, +3,57,0,180,3, +119,0,180,3,65, +0,180,3,100,0, +180,3,73,0,180, +3,108,0,180,3, +81,0,180,3,54, +0,180,3,116,0, +180,3,89,0,180, +821,11,1,867,0, +183,1,-1,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +180,3,87,0,180, +3,122,0,180,3, +95,0,180,3,68, +0,180,3,103,0, +180,3,76,0,180, +3,49,0,180,3, +111,0,180,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,180,3,73, +0,180,3,108,0, +180,3,81,0,180, +3,54,0,180,3, +116,0,180,3,89, +0,180,822,11,1, +867,0,183,1,-1, +3,83,0,180,3, +56,0,180,3,118, +0,823,12,1,28579, +824,5,63,3,97, +0,180,3,70,0, +180,3,105,0,825, +12,1,28647,826,5, +63,3,97,0,180, +3,70,0,180,3, +105,0,180,3,78, +0,180,3,51,0, +180,3,113,0,180, +3,86,0,180,3, +121,0,180,3,67, +0,180,3,102,0, +180,3,75,0,180, +3,48,0,180,3, +110,0,827,12,1, +28719,828,5,63,3, +97,0,180,3,70, +0,180,3,105,0, +180,3,78,0,180, +3,51,0,180,3, +113,0,180,3,86, +0,180,3,121,0, +180,3,67,0,180, +3,102,0,180,3, +75,0,180,3,48, +0,180,3,110,0, +180,3,83,0,180, +3,56,0,180,3, +118,0,180,3,99, +0,180,3,72,0, +180,3,107,0,180, +3,80,0,180,3, +53,0,180,3,115, +0,180,3,88,0, +180,3,69,0,180, +3,104,0,180,3, +77,0,180,3,50, +0,180,3,112,0, +180,3,85,0,180, +3,120,0,180,3, +66,0,180,3,101, +0,180,3,74,0, +180,3,109,0,180, +3,82,0,180,3, +55,0,180,3,117, +0,180,3,90,0, +180,3,98,0,180, +3,71,0,180,3, +106,0,180,3,79, +0,180,3,52,0, +180,3,114,0,180, +3,87,0,180,3, +122,0,180,3,95, +0,180,3,68,0, +180,3,103,0,829, +12,1,28806,830,5, +63,3,97,0,180, +3,70,0,180,3, +105,0,180,3,78, +0,180,3,51,0, +180,3,113,0,180, +3,86,0,180,3, +121,0,180,3,67, +0,180,3,102,0, +180,3,75,0,180, +3,48,0,180,3, +110,0,180,3,83, +0,180,3,56,0, +180,3,118,0,180, +3,99,0,180,3, +72,0,180,3,107, +0,180,3,80,0, +180,3,53,0,180, +3,115,0,180,3, +88,0,180,3,69, +0,180,3,104,0, +180,3,77,0,180, +3,50,0,180,3, +112,0,180,3,85, +0,180,3,120,0, +180,3,66,0,180, +3,101,0,180,3, +74,0,180,3,109, +0,180,3,82,0, +180,3,55,0,180, +3,117,0,180,3, +90,0,180,3,98, +0,180,3,71,0, +180,3,106,0,180, +3,79,0,180,3, +52,0,180,3,114, +0,180,3,87,0, +180,3,122,0,180, +3,95,0,831,12, +1,28842,832,5,63, +3,97,0,180,3, +70,0,180,3,105, +0,180,3,78,0, +180,3,51,0,180, +3,113,0,180,3, +86,0,180,3,121, +0,180,3,67,0, +180,3,102,0,180, +3,75,0,180,3, +48,0,180,3,110, +0,180,3,83,0, +180,3,56,0,180, +3,118,0,180,3, +99,0,180,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,833,12,1, +28918,834,5,63,3, +97,0,180,3,70, +0,180,3,105,0, +180,3,78,0,180, +3,51,0,180,3, +113,0,180,3,86, +0,180,3,121,0, +180,3,67,0,180, +3,102,0,180,3, +75,0,180,3,48, +0,180,3,110,0, +180,3,83,0,180, +3,56,0,180,3, +118,0,180,3,99, +0,180,3,72,0, +180,3,107,0,180, +3,80,0,180,3, +53,0,180,3,115, +0,180,3,88,0, +180,3,69,0,180, +3,104,0,180,3, +77,0,180,3,50, +0,180,3,112,0, +180,3,85,0,180, +3,120,0,180,3, +66,0,180,3,101, +0,180,3,74,0, +180,3,109,0,180, +3,82,0,180,3, +55,0,180,3,117, +0,180,3,90,0, +180,3,98,0,180, +3,71,0,180,3, +106,0,180,3,79, +0,180,3,52,0, +180,3,114,0,180, +3,87,0,180,3, +122,0,180,3,95, +0,180,3,68,0, +180,3,103,0,180, +3,76,0,180,3, +49,0,180,3,111, +0,180,3,84,0, +180,3,57,0,180, +3,119,0,180,3, +65,0,180,3,100, +0,180,3,73,0, +180,3,108,0,180, +3,81,0,180,3, +54,0,180,3,116, +0,835,12,1,29011, +836,5,63,3,97, +0,837,12,1,29078, +838,5,63,3,97, +0,180,3,70,0, +180,3,105,0,180, +3,78,0,180,3, +51,0,180,3,113, +0,180,3,86,0, +180,3,121,0,180, +3,67,0,180,3, +102,0,180,3,75, +0,180,3,48,0, +180,3,110,0,180, +3,83,0,180,3, +56,0,180,3,118, +0,180,3,99,0, +180,3,72,0,180, +3,107,0,180,3, +80,0,180,3,53, +0,180,3,115,0, +180,3,88,0,180, +3,69,0,180,3, +104,0,180,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,180,3,66, +0,180,3,101,0, +180,3,74,0,180, +3,109,0,180,3, +82,0,180,3,55, +0,180,3,117,0, +180,3,90,0,180, +3,98,0,180,3, +71,0,180,3,106, +0,180,3,79,0, +180,3,52,0,180, +3,114,0,839,12, +1,29163,840,5,63, +3,97,0,180,3, +70,0,180,3,105, +0,180,3,78,0, +180,3,51,0,180, +3,113,0,180,3, +86,0,180,3,121, +0,180,3,67,0, +180,3,102,0,180, +3,75,0,180,3, +48,0,180,3,110, +0,180,3,83,0, +180,3,56,0,180, +3,118,0,180,3, +99,0,180,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,180,3,88, +0,180,3,69,0, +180,3,104,0,180, +3,77,0,180,3, +50,0,180,3,112, +0,180,3,85,0, +180,3,120,0,180, +3,66,0,180,3, +101,0,180,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +180,3,87,0,180, +3,122,0,180,3, +95,0,180,3,68, +0,180,3,103,0, +180,3,76,0,180, +3,49,0,180,3, +111,0,180,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,180,3,73, +0,180,3,108,0, +180,3,81,0,180, +3,54,0,180,3, +116,0,841,12,1, +29256,842,5,63,3, +97,0,180,3,70, +0,180,3,105,0, +180,3,78,0,180, +3,51,0,180,3, +113,0,180,3,86, +0,180,3,121,0, +180,3,67,0,180, +3,102,0,180,3, +75,0,180,3,48, +0,180,3,110,0, +180,3,83,0,180, +3,56,0,180,3, +118,0,180,3,99, +0,180,3,72,0, +180,3,107,0,180, +3,80,0,180,3, +53,0,180,3,115, +0,180,3,88,0, +180,3,69,0,180, +3,104,0,180,3, +77,0,180,3,50, +0,180,3,112,0, +180,3,85,0,180, +3,120,0,180,3, +66,0,180,3,101, +0,180,3,74,0, +180,3,109,0,180, +3,82,0,180,3, +55,0,180,3,117, +0,180,3,90,0, +180,3,98,0,180, +3,71,0,180,3, +106,0,180,3,79, +0,180,3,52,0, +180,3,114,0,180, +3,87,0,180,3, +122,0,180,3,95, +0,180,3,68,0, +180,3,103,0,180, +3,76,0,180,3, +49,0,180,3,111, +0,180,3,84,0, +180,3,57,0,180, +3,119,0,180,3, +65,0,180,3,100, +0,180,3,73,0, +180,3,108,0,180, +3,81,0,180,3, +54,0,180,3,116, +0,180,3,89,0, +180,843,11,1,614, +0,844,4,36,77, +0,79,0,86,0, +73,0,78,0,71, 0,95,0,83,0, 84,0,65,0,82, 0,84,0,95,0, 69,0,86,0,69, 0,78,0,84,0, -1,-1,3,117,0, -345,3,118,0,345, -3,119,0,345,3, -120,0,345,3,121, -0,345,3,122,0, -345,3,48,0,345, -3,49,0,345,3, -50,0,345,3,51, -0,345,3,52,0, -345,3,53,0,345, -3,54,0,345,3, -55,0,345,3,56, -0,345,3,57,0, -345,3,65,0,345, -3,66,0,345,3, -67,0,345,3,68, -0,345,3,69,0, -345,3,70,0,345, -3,71,0,345,3, -72,0,345,3,73, -0,345,3,74,0, -345,3,75,0,345, -3,76,0,345,3, -77,0,345,3,78, -0,345,3,79,0, -345,3,80,0,345, -3,81,0,345,3, -82,0,345,3,83, -0,345,3,84,0, -345,3,85,0,345, -3,86,0,345,3, -87,0,345,3,88, -0,345,3,89,0, -345,3,90,0,345, -3,95,0,345,3, -97,0,345,3,98, -0,345,3,99,0, -345,3,100,0,345, -3,101,0,345,3, -102,0,345,3,103, -0,345,3,104,0, -345,3,105,0,345, -3,106,0,345,3, -107,0,345,3,108, -0,345,776,11,1, -867,0,348,1,-1, -3,115,0,345,3, -116,0,345,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,345,3, -98,0,345,3,99, -0,345,3,100,0, -345,3,101,0,345, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -345,3,106,0,345, -3,107,0,345,3, -108,0,345,777,11, -1,867,0,348,1, --1,3,98,0,345, -3,99,0,345,3, -100,0,345,3,101, -0,345,3,102,0, -345,3,103,0,345, -3,104,0,345,3, -105,0,345,3,106, -0,345,3,107,0, -345,3,108,0,345, -778,11,1,867,0, -348,1,-1,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,345,3, -98,0,345,3,99, -0,345,3,100,0, -345,3,101,0,345, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -345,3,106,0,345, -3,107,0,345,3, -108,0,345,779,11, -1,867,0,348,1, --1,3,116,0,345, -3,117,0,345,3, -118,0,345,3,119, -0,345,3,120,0, -345,3,121,0,345, -3,122,0,345,3, -48,0,345,3,49, -0,345,3,50,0, -345,3,51,0,345, -3,52,0,345,3, -53,0,345,3,54, -0,345,3,55,0, -345,3,56,0,345, -3,57,0,345,3, -65,0,345,3,66, -0,345,3,67,0, -345,3,68,0,345, -3,69,0,345,3, -70,0,345,3,71, -0,345,3,72,0, -345,3,73,0,345, -3,74,0,345,3, -75,0,345,3,76, -0,345,3,77,0, -345,3,78,0,345, -3,79,0,345,3, -80,0,345,3,81, -0,345,3,82,0, -345,3,83,0,345, -3,84,0,345,3, -85,0,345,3,86, -0,345,3,87,0, -345,3,88,0,345, -3,89,0,345,3, -90,0,345,3,95, -0,345,3,97,0, -345,3,98,0,345, -3,99,0,345,3, -100,0,345,3,101, -0,780,12,1,38105, -781,5,63,3,109, -0,345,3,110,0, -782,12,1,38134,783, -5,63,3,109,0, -345,3,110,0,345, -3,111,0,345,3, -112,0,345,3,113, -0,345,3,114,0, -345,3,115,0,345, -3,116,0,345,3, -117,0,345,3,118, -0,345,3,119,0, -345,3,120,0,345, -3,121,0,345,3, -122,0,345,3,48, -0,345,3,49,0, -345,3,50,0,345, -3,51,0,345,3, -52,0,345,3,53, -0,345,3,54,0, -345,3,55,0,345, -3,56,0,345,3, -57,0,345,3,65, -0,345,3,66,0, -345,3,67,0,345, -3,68,0,345,3, -69,0,345,3,70, -0,345,3,71,0, -345,3,72,0,345, -3,73,0,345,3, -74,0,345,3,75, -0,345,3,76,0, -345,3,77,0,345, -3,78,0,345,3, -79,0,345,3,80, -0,345,3,81,0, -345,3,82,0,345, -3,83,0,345,3, -84,0,345,3,85, -0,345,3,86,0, -345,3,87,0,345, -3,88,0,345,3, -89,0,345,3,90, -0,345,3,95,0, -345,3,97,0,345, -3,98,0,345,3, -99,0,345,3,100, -0,784,12,1,38180, -785,5,63,3,109, -0,345,3,110,0, -345,3,111,0,345, -3,112,0,345,3, -113,0,345,3,114, -0,345,3,115,0, -345,3,116,0,345, -3,117,0,345,3, -118,0,345,3,119, -0,345,3,120,0, -345,3,121,0,345, -3,122,0,345,3, -48,0,345,3,49, -0,345,3,50,0, -345,3,51,0,345, -3,52,0,345,3, -53,0,345,3,54, -0,345,3,55,0, -345,3,56,0,345, -3,57,0,345,3, -65,0,345,3,66, -0,345,3,67,0, -345,3,68,0,345, -3,69,0,345,3, -70,0,345,3,71, -0,345,3,72,0, -345,3,73,0,345, -3,74,0,345,3, -75,0,345,3,76, -0,345,3,77,0, -345,3,78,0,345, -3,79,0,345,3, -80,0,345,3,81, -0,345,3,82,0, -345,3,83,0,345, -3,84,0,345,3, -85,0,345,3,86, -0,345,3,87,0, -345,3,88,0,345, -3,89,0,345,3, -90,0,345,3,95, -0,345,3,97,0, -345,3,98,0,345, -3,99,0,345,3, -100,0,345,3,101, -0,345,3,102,0, -345,3,103,0,345, -3,104,0,345,3, -105,0,345,3,106, -0,345,3,107,0, -345,3,108,0,345, -786,11,1,519,0, -787,4,48,76,0, -65,0,78,0,68, -0,95,0,67,0, -79,0,76,0,76, -0,73,0,83,0, -73,0,79,0,78, +1,-1,3,89,0, +180,845,11,1,867, +0,183,1,-1,3, +87,0,180,3,122, +0,180,3,95,0, +180,3,68,0,180, +3,103,0,180,3, +76,0,180,3,49, +0,180,3,111,0, +180,3,84,0,180, +3,57,0,180,3, +119,0,180,3,65, +0,180,3,100,0, +180,3,73,0,180, +3,108,0,180,3, +81,0,180,3,54, +0,180,3,116,0, +180,3,89,0,180, +846,11,1,867,0, +183,1,-1,3,70, +0,180,3,105,0, +180,3,78,0,180, +3,51,0,180,3, +113,0,180,3,86, +0,180,3,121,0, +180,3,67,0,180, +3,102,0,180,3, +75,0,180,3,48, +0,180,3,110,0, +180,3,83,0,180, +3,56,0,180,3, +118,0,180,3,99, +0,180,3,72,0, +180,3,107,0,180, +3,80,0,180,3, +53,0,180,3,115, +0,180,3,88,0, +180,3,69,0,180, +3,104,0,180,3, +77,0,180,3,50, +0,180,3,112,0, +180,3,85,0,180, +3,120,0,180,3, +66,0,180,3,101, +0,180,3,74,0, +180,3,109,0,180, +3,82,0,180,3, +55,0,180,3,117, +0,180,3,90,0, +180,3,98,0,180, +3,71,0,180,3, +106,0,180,3,79, +0,180,3,52,0, +180,3,114,0,180, +3,87,0,180,3, +122,0,180,3,95, +0,180,3,68,0, +180,3,103,0,180, +3,76,0,180,3, +49,0,180,3,111, +0,180,3,84,0, +180,3,57,0,180, +3,119,0,180,3, +65,0,180,3,100, +0,180,3,73,0, +180,3,108,0,180, +3,81,0,180,3, +54,0,180,3,116, +0,180,3,89,0, +180,847,11,1,867, +0,183,1,-1,3, +89,0,180,848,11, +1,867,0,183,1, +-1,3,88,0,180, +3,69,0,180,3, +104,0,180,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,180,3,66, +0,180,3,101,0, +849,12,1,29522,850, +5,63,3,97,0, +180,3,70,0,180, +3,105,0,180,3, +78,0,180,3,51, +0,180,3,113,0, +180,3,86,0,180, +3,121,0,180,3, +67,0,180,3,102, +0,180,3,75,0, +180,3,48,0,180, +3,110,0,851,12, +1,29594,852,5,63, +3,97,0,180,3, +70,0,180,3,105, +0,180,3,78,0, +180,3,51,0,180, +3,113,0,180,3, +86,0,180,3,121, +0,180,3,67,0, +180,3,102,0,180, +3,75,0,180,3, +48,0,180,3,110, +0,180,3,83,0, +180,3,56,0,180, +3,118,0,180,3, +99,0,180,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,180,3,88, +0,180,3,69,0, +180,3,104,0,180, +3,77,0,180,3, +50,0,180,3,112, +0,180,3,85,0, +180,3,120,0,180, +3,66,0,180,3, +101,0,180,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +180,3,87,0,180, +3,122,0,180,3, +95,0,180,3,68, +0,180,3,103,0, +180,3,76,0,180, +3,49,0,180,3, +111,0,180,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,853,12,1, +29684,854,5,63,3, +97,0,180,3,70, +0,180,3,105,0, +180,3,78,0,180, +3,51,0,180,3, +113,0,180,3,86, +0,180,3,121,0, +180,3,67,0,180, +3,102,0,180,3, +75,0,180,3,48, +0,180,3,110,0, +180,3,83,0,180, +3,56,0,180,3, +118,0,180,3,99, +0,180,3,72,0, +180,3,107,0,180, +3,80,0,180,3, +53,0,180,3,115, +0,180,3,88,0, +180,3,69,0,180, +3,104,0,180,3, +77,0,180,3,50, +0,180,3,112,0, +180,3,85,0,180, +3,120,0,180,3, +66,0,180,3,101, +0,180,3,74,0, +180,3,109,0,180, +3,82,0,180,3, +55,0,180,3,117, +0,180,3,90,0, +180,3,98,0,180, +3,71,0,180,3, +106,0,180,3,79, +0,180,3,52,0, +180,3,114,0,180, +3,87,0,180,3, +122,0,180,3,95, +0,180,3,68,0, +180,3,103,0,180, +3,76,0,180,3, +49,0,180,3,111, +0,180,3,84,0, +180,3,57,0,180, +3,119,0,180,3, +65,0,180,3,100, +0,180,3,73,0, +180,3,108,0,180, +3,81,0,180,3, +54,0,180,3,116, +0,180,3,89,0, +180,855,11,1,600, +0,856,4,32,77, +0,79,0,86,0, +73,0,78,0,71, 0,95,0,69,0, 78,0,68,0,95, 0,69,0,86,0, 69,0,78,0,84, -0,1,-1,3,101, -0,345,3,102,0, -345,3,103,0,345, -3,104,0,345,3, -105,0,345,3,106, -0,345,3,107,0, -345,3,108,0,345, -788,11,1,867,0, -348,1,-1,3,111, -0,345,3,112,0, -345,3,113,0,345, -3,114,0,345,3, -115,0,345,3,116, -0,345,3,117,0, -345,3,118,0,345, -3,119,0,345,3, -120,0,345,3,121, -0,345,3,122,0, -345,3,48,0,345, -3,49,0,345,3, -50,0,345,3,51, -0,345,3,52,0, -345,3,53,0,345, -3,54,0,345,3, -55,0,345,3,56, -0,345,3,57,0, -345,3,65,0,345, -3,66,0,345,3, -67,0,345,3,68, -0,345,3,69,0, -345,3,70,0,345, -3,71,0,345,3, -72,0,345,3,73, -0,345,3,74,0, -345,3,75,0,345, -3,76,0,345,3, -77,0,345,3,78, -0,345,3,79,0, -345,3,80,0,345, -3,81,0,345,3, -82,0,345,3,83, -0,345,3,84,0, -345,3,85,0,345, -3,86,0,345,3, -87,0,345,3,88, -0,345,3,89,0, -345,3,90,0,345, -3,95,0,345,3, -97,0,345,3,98, -0,345,3,99,0, -345,3,100,0,345, -3,101,0,345,3, -102,0,345,3,103, -0,345,3,104,0, -345,3,105,0,345, -3,106,0,345,3, -107,0,345,3,108, -0,345,789,11,1, -867,0,348,1,-1, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -345,3,106,0,345, -3,107,0,345,3, -108,0,345,790,11, -1,867,0,348,1, --1,3,97,0,345, -3,98,0,345,3, -99,0,345,3,100, -0,345,3,101,0, -345,3,102,0,345, -3,103,0,345,3, -104,0,345,3,105, -0,345,3,106,0, -345,3,107,0,345, -3,108,0,345,791, -11,1,501,0,792, -4,40,76,0,65, -0,78,0,68,0, -95,0,67,0,79, -0,76,0,76,0, -73,0,83,0,73, -0,79,0,78,0, +0,1,-1,3,73, +0,180,3,108,0, +180,3,81,0,180, +3,54,0,180,3, +116,0,180,3,89, +0,180,857,11,1, +867,0,183,1,-1, +3,83,0,180,3, +56,0,180,3,118, +0,180,3,99,0, +180,3,72,0,180, +3,107,0,180,3, +80,0,180,3,53, +0,180,3,115,0, +180,3,88,0,180, +3,69,0,180,3, +104,0,180,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,180,3,66, +0,180,3,101,0, +180,3,74,0,180, +3,109,0,180,3, +82,0,180,3,55, +0,180,3,117,0, +180,3,90,0,180, +3,98,0,180,3, +71,0,180,3,106, +0,180,3,79,0, +180,3,52,0,180, +3,114,0,180,3, +87,0,180,3,122, +0,180,3,95,0, +180,3,68,0,180, +3,103,0,180,3, +76,0,180,3,49, +0,180,3,111,0, +180,3,84,0,180, +3,57,0,180,3, +119,0,180,3,65, +0,180,3,100,0, +180,3,73,0,180, +3,108,0,180,3, +81,0,180,3,54, +0,180,3,116,0, +180,3,89,0,180, +858,11,1,867,0, +183,1,-1,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +180,3,87,0,180, +3,122,0,180,3, +95,0,180,3,68, +0,180,3,103,0, +180,3,76,0,180, +3,49,0,180,3, +111,0,180,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,180,3,73, +0,180,3,108,0, +180,3,81,0,180, +3,54,0,180,3, +116,0,180,3,89, +0,180,859,11,1, +867,0,183,1,-1, +3,68,0,180,3, +103,0,180,3,76, +0,180,3,49,0, +180,3,111,0,180, +3,84,0,180,3, +57,0,180,3,119, +0,180,3,65,0, +180,3,100,0,180, +3,73,0,180,3, +108,0,180,3,81, +0,180,3,54,0, +180,3,116,0,180, +3,89,0,180,860, +11,1,867,0,183, +1,-1,3,76,0, +180,3,49,0,180, +3,111,0,180,3, +84,0,180,3,57, +0,180,3,119,0, +180,3,65,0,180, +3,100,0,180,3, +73,0,180,3,108, +0,180,3,81,0, +180,3,54,0,180, +3,116,0,180,3, +89,0,180,861,11, +1,867,0,183,1, +-1,3,83,0,180, +3,56,0,180,3, +118,0,180,3,99, +0,180,3,72,0, +180,3,107,0,180, +3,80,0,180,3, +53,0,180,3,115, +0,180,3,88,0, +180,3,69,0,180, +3,104,0,180,3, +77,0,180,3,50, +0,180,3,112,0, +180,3,85,0,180, +3,120,0,180,3, +66,0,180,3,101, +0,180,3,74,0, +180,3,109,0,180, +3,82,0,180,3, +55,0,180,3,117, +0,180,3,90,0, +180,3,98,0,180, +3,71,0,180,3, +106,0,180,3,79, +0,180,3,52,0, +180,3,114,0,180, +3,87,0,180,3, +122,0,180,3,95, +0,180,3,68,0, +180,3,103,0,180, +3,76,0,180,3, +49,0,180,3,111, +0,180,3,84,0, +180,3,57,0,180, +3,119,0,180,3, +65,0,180,3,100, +0,180,3,73,0, +180,3,108,0,180, +3,81,0,180,3, +54,0,180,3,116, +0,180,3,89,0, +180,862,11,1,867, +0,183,1,-1,3, +78,0,180,3,51, +0,180,3,113,0, +180,3,86,0,180, +3,121,0,180,3, +67,0,180,3,102, +0,180,3,75,0, +180,3,48,0,180, +3,110,0,180,3, +83,0,180,3,56, +0,180,3,118,0, +180,3,99,0,180, +3,72,0,180,3, +107,0,180,3,80, +0,180,3,53,0, +180,3,115,0,180, +3,88,0,180,3, +69,0,180,3,104, +0,180,3,77,0, +180,3,50,0,180, +3,112,0,180,3, +85,0,180,3,120, +0,180,3,66,0, +180,3,101,0,180, +3,74,0,180,3, +109,0,180,3,82, +0,180,3,55,0, +180,3,117,0,180, +3,90,0,180,3, +98,0,180,3,71, +0,180,3,106,0, +180,3,79,0,180, +3,52,0,180,3, +114,0,180,3,87, +0,180,3,122,0, +180,3,95,0,180, +3,68,0,180,3, +103,0,180,3,76, +0,180,3,49,0, +180,3,111,0,180, +3,84,0,180,3, +57,0,180,3,119, +0,180,3,65,0, +180,3,100,0,180, +3,73,0,180,3, +108,0,180,3,81, +0,180,3,54,0, +180,3,116,0,180, +3,89,0,180,863, +11,1,867,0,183, +1,-1,3,99,0, +180,3,72,0,180, +3,107,0,180,3, +80,0,180,3,53, +0,180,3,115,0, +180,3,88,0,180, +3,69,0,180,3, +104,0,180,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,180,3,66, +0,180,3,101,0, +180,3,74,0,180, +3,109,0,180,3, +82,0,180,3,55, +0,180,3,117,0, +180,3,90,0,180, +3,98,0,180,3, +71,0,180,3,106, +0,180,3,79,0, +180,3,52,0,180, +3,114,0,180,3, +87,0,180,3,122, +0,180,3,95,0, +180,3,68,0,180, +3,103,0,180,3, +76,0,180,3,49, +0,180,3,111,0, +180,3,84,0,180, +3,57,0,180,3, +119,0,180,3,65, +0,180,3,100,0, +180,3,73,0,180, +3,108,0,180,3, +81,0,180,3,54, +0,180,3,116,0, +180,3,89,0,180, +864,11,1,867,0, +183,1,-1,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,180,3,73, +0,180,3,108,0, +180,3,81,0,180, +3,54,0,180,3, +116,0,180,3,89, +0,180,865,11,1, +867,0,183,1,-1, +3,69,0,178,3, +106,0,866,12,1, +30221,867,5,63,3, +97,0,180,3,70, +0,180,3,105,0, +180,3,78,0,180, +3,51,0,180,3, +113,0,180,3,86, +0,180,3,121,0, +180,3,67,0,180, +3,102,0,180,3, +75,0,180,3,48, +0,180,3,110,0, +180,3,83,0,180, +3,56,0,180,3, +118,0,180,3,99, +0,180,3,72,0, +180,3,107,0,180, +3,80,0,180,3, +53,0,180,3,115, +0,180,3,88,0, +180,3,69,0,180, +3,104,0,180,3, +77,0,180,3,50, +0,180,3,112,0, +180,3,85,0,180, +3,120,0,180,3, +66,0,180,3,101, +0,180,3,74,0, +180,3,109,0,180, +3,82,0,180,3, +55,0,180,3,117, +0,868,12,1,30303, +869,5,63,3,97, +0,180,3,70,0, +180,3,105,0,180, +3,78,0,180,3, +51,0,180,3,113, +0,180,3,86,0, +180,3,121,0,180, +3,67,0,180,3, +102,0,180,3,75, +0,180,3,48,0, +180,3,110,0,180, +3,83,0,180,3, +56,0,180,3,118, +0,180,3,99,0, +180,3,72,0,180, +3,107,0,180,3, +80,0,180,3,53, +0,180,3,115,0, +180,3,88,0,180, +3,69,0,180,3, +104,0,180,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,180,3,66, +0,180,3,101,0, +180,3,74,0,180, +3,109,0,870,12, +1,30384,871,5,63, +3,97,0,180,3, +70,0,180,3,105, +0,180,3,78,0, +180,3,51,0,180, +3,113,0,180,3, +86,0,180,3,121, +0,180,3,67,0, +180,3,102,0,180, +3,75,0,180,3, +48,0,180,3,110, +0,180,3,83,0, +180,3,56,0,180, +3,118,0,180,3, +99,0,180,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,180,3,88, +0,180,3,69,0, +180,3,104,0,180, +3,77,0,180,3, +50,0,180,3,112, +0,872,12,1,30462, +873,5,63,3,97, +0,180,3,70,0, +180,3,105,0,180, +3,78,0,180,3, +51,0,180,3,113, +0,180,3,86,0, +180,3,121,0,180, +3,67,0,180,3, +102,0,180,3,75, +0,180,3,48,0, +180,3,110,0,180, +3,83,0,180,3, +56,0,180,3,118, +0,180,3,99,0, +180,3,72,0,180, +3,107,0,180,3, +80,0,180,3,53, +0,180,3,115,0, +180,3,88,0,180, +3,69,0,180,3, +104,0,180,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,180,3,66, +0,180,3,101,0, +180,3,74,0,180, +3,109,0,180,3, +82,0,180,3,55, +0,180,3,117,0, +180,3,90,0,180, +3,98,0,180,3, +71,0,180,3,106, +0,180,3,79,0, +180,3,52,0,180, +3,114,0,180,3, +87,0,180,3,122, +0,180,3,95,0, +180,3,68,0,180, +3,103,0,180,3, +76,0,180,3,49, +0,180,3,111,0, +180,3,84,0,180, +3,57,0,180,3, +119,0,180,3,65, +0,180,3,100,0, +180,3,73,0,180, +3,108,0,180,3, +81,0,180,3,54, +0,180,3,116,0, +180,3,89,0,180, +874,11,1,265,0, +875,4,8,74,0, +85,0,77,0,80, +0,1,-1,3,85, +0,180,3,120,0, +180,3,66,0,180, +3,101,0,180,3, +74,0,180,3,109, +0,180,3,82,0, +180,3,55,0,180, +3,117,0,180,3, +90,0,180,3,98, +0,180,3,71,0, +180,3,106,0,180, +3,79,0,180,3, +52,0,180,3,114, +0,180,3,87,0, +180,3,122,0,180, +3,95,0,180,3, +68,0,180,3,103, +0,180,3,76,0, +180,3,49,0,180, +3,111,0,180,3, +84,0,180,3,57, +0,180,3,119,0, +180,3,65,0,180, +3,100,0,180,3, +73,0,180,3,108, +0,180,3,81,0, +180,3,54,0,180, +3,116,0,180,3, +89,0,180,876,11, +1,867,0,183,1, +-1,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +180,3,87,0,180, +3,122,0,180,3, +95,0,180,3,68, +0,180,3,103,0, +180,3,76,0,180, +3,49,0,180,3, +111,0,180,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,180,3,73, +0,180,3,108,0, +180,3,81,0,180, +3,54,0,180,3, +116,0,180,3,89, +0,180,877,11,1, +867,0,183,1,-1, +3,90,0,180,3, +98,0,180,3,71, +0,180,3,106,0, +180,3,79,0,180, +3,52,0,180,3, +114,0,180,3,87, +0,180,3,122,0, +180,3,95,0,180, +3,68,0,180,3, +103,0,180,3,76, +0,180,3,49,0, +180,3,111,0,180, +3,84,0,180,3, +57,0,180,3,119, +0,180,3,65,0, +180,3,100,0,180, +3,73,0,180,3, +108,0,180,3,81, +0,180,3,54,0, +180,3,116,0,180, +3,89,0,180,878, +11,1,867,0,183, +1,-1,3,66,0, +178,3,103,0,178, +3,100,0,879,12, +1,38027,880,5,63, +3,97,0,881,12, +1,38094,882,5,63, +3,97,0,180,3, +70,0,180,3,105, +0,180,3,78,0, +180,3,51,0,180, +3,113,0,180,3, +86,0,180,3,121, +0,180,3,67,0, +180,3,102,0,180, +3,75,0,180,3, +48,0,180,3,110, +0,180,3,83,0, +180,3,56,0,180, +3,118,0,180,3, +99,0,180,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,180,3,88, +0,180,3,69,0, +180,3,104,0,180, +3,77,0,180,3, +50,0,180,3,112, +0,180,3,85,0, +180,3,120,0,180, +3,66,0,180,3, +101,0,180,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +180,3,87,0,180, +3,122,0,180,3, +95,0,180,3,68, +0,180,3,103,0, +180,3,76,0,180, +3,49,0,180,3, +111,0,180,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,180,3,73, +0,180,3,108,0, +180,3,81,0,180, +3,54,0,180,3, +116,0,883,12,1, +38187,884,5,63,3, +97,0,885,12,1, +38254,886,5,63,3, +97,0,180,3,70, +0,180,3,105,0, +180,3,78,0,180, +3,51,0,180,3, +113,0,180,3,86, +0,180,3,121,0, +180,3,67,0,180, +3,102,0,180,3, +75,0,180,3,48, +0,180,3,110,0, +180,3,83,0,180, +3,56,0,180,3, +118,0,180,3,99, +0,180,3,72,0, +180,3,107,0,180, +3,80,0,180,3, +53,0,180,3,115, +0,887,12,1,38330, +888,5,63,3,97, +0,180,3,70,0, +180,3,105,0,180, +3,78,0,180,3, +51,0,180,3,113, +0,180,3,86,0, +180,3,121,0,180, +3,67,0,180,3, +102,0,180,3,75, +0,180,3,48,0, +180,3,110,0,180, +3,83,0,180,3, +56,0,180,3,118, +0,180,3,99,0, +180,3,72,0,180, +3,107,0,180,3, +80,0,180,3,53, +0,180,3,115,0, +180,3,88,0,180, +3,69,0,180,3, +104,0,180,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,180,3,66, +0,180,3,101,0, +889,12,1,38410,890, +5,63,3,97,0, +180,3,70,0,180, +3,105,0,180,3, +78,0,180,3,51, +0,180,3,113,0, +180,3,86,0,180, +3,121,0,180,3, +67,0,180,3,102, +0,180,3,75,0, +180,3,48,0,180, +3,110,0,180,3, +83,0,180,3,56, +0,180,3,118,0, +180,3,99,0,180, +3,72,0,180,3, +107,0,180,3,80, +0,180,3,53,0, +180,3,115,0,180, +3,88,0,180,3, +69,0,180,3,104, +0,180,3,77,0, +180,3,50,0,180, +3,112,0,180,3, +85,0,180,3,120, +0,180,3,66,0, +180,3,101,0,180, +3,74,0,180,3, +109,0,180,3,82, +0,180,3,55,0, +180,3,117,0,180, +3,90,0,180,3, +98,0,180,3,71, +0,180,3,106,0, +180,3,79,0,180, +3,52,0,180,3, +114,0,891,12,1, +38495,892,5,63,3, +97,0,180,3,70, +0,180,3,105,0, +180,3,78,0,180, +3,51,0,180,3, +113,0,180,3,86, +0,180,3,121,0, +180,3,67,0,180, +3,102,0,180,3, +75,0,180,3,48, +0,180,3,110,0, +180,3,83,0,180, +3,56,0,180,3, +118,0,893,12,1, +38568,894,5,63,3, +97,0,180,3,70, +0,180,3,105,0, +180,3,78,0,180, +3,51,0,180,3, +113,0,180,3,86, +0,180,3,121,0, +180,3,67,0,180, +3,102,0,180,3, +75,0,180,3,48, +0,180,3,110,0, +180,3,83,0,180, +3,56,0,180,3, +118,0,180,3,99, +0,180,3,72,0, +180,3,107,0,180, +3,80,0,180,3, +53,0,180,3,115, +0,180,3,88,0, +180,3,69,0,180, +3,104,0,180,3, +77,0,180,3,50, +0,180,3,112,0, +180,3,85,0,180, +3,120,0,180,3, +66,0,180,3,101, +0,895,12,1,38648, +896,5,63,3,97, +0,180,3,70,0, +180,3,105,0,180, +3,78,0,180,3, +51,0,180,3,113, +0,180,3,86,0, +180,3,121,0,180, +3,67,0,180,3, +102,0,180,3,75, +0,180,3,48,0, +180,3,110,0,180, +3,83,0,180,3, +56,0,180,3,118, +0,180,3,99,0, +180,3,72,0,180, +3,107,0,180,3, +80,0,180,3,53, +0,180,3,115,0, +180,3,88,0,180, +3,69,0,180,3, +104,0,180,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,180,3,66, +0,180,3,101,0, +180,3,74,0,180, +3,109,0,180,3, +82,0,180,3,55, +0,180,3,117,0, +180,3,90,0,180, +3,98,0,180,3, +71,0,180,3,106, +0,180,3,79,0, +180,3,52,0,180, +3,114,0,897,12, +1,38733,898,5,63, +3,97,0,180,3, +70,0,180,3,105, +0,180,3,78,0, +180,3,51,0,180, +3,113,0,180,3, +86,0,180,3,121, +0,180,3,67,0, +180,3,102,0,180, +3,75,0,180,3, +48,0,180,3,110, +0,180,3,83,0, +180,3,56,0,180, +3,118,0,180,3, +99,0,180,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,180,3,88, +0,180,3,69,0, +180,3,104,0,180, +3,77,0,180,3, +50,0,180,3,112, +0,180,3,85,0, +180,3,120,0,180, +3,66,0,180,3, +101,0,180,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +180,3,87,0,180, +3,122,0,180,3, +95,0,180,3,68, +0,180,3,103,0, +180,3,76,0,180, +3,49,0,180,3, +111,0,180,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,180,3,73, +0,180,3,108,0, +180,3,81,0,180, +3,54,0,180,3, +116,0,180,3,89, +0,180,899,11,1, +461,0,900,4,32, +68,0,65,0,84, +0,65,0,83,0, +69,0,82,0,86, +0,69,0,82,0, 95,0,69,0,86, 0,69,0,78,0, 84,0,1,-1,3, -111,0,345,3,112, -0,345,3,113,0, -345,3,114,0,345, -3,115,0,345,3, -116,0,345,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,345,3, -98,0,345,3,99, -0,345,3,100,0, -345,3,101,0,345, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -345,3,106,0,345, -3,107,0,345,3, -108,0,345,793,11, -1,867,0,348,1, --1,3,112,0,345, -3,113,0,345,3, -114,0,345,3,115, -0,345,3,116,0, -345,3,117,0,345, -3,118,0,345,3, -119,0,345,3,120, -0,345,3,121,0, -345,3,122,0,345, -3,48,0,345,3, -49,0,345,3,50, -0,345,3,51,0, -345,3,52,0,345, -3,53,0,345,3, -54,0,345,3,55, -0,345,3,56,0, -345,3,57,0,345, -3,65,0,345,3, -66,0,345,3,67, -0,345,3,68,0, -345,3,69,0,345, -3,70,0,345,3, -71,0,345,3,72, -0,345,3,73,0, -345,3,74,0,345, -3,75,0,345,3, -76,0,345,3,77, -0,345,3,78,0, -345,3,79,0,345, -3,80,0,345,3, -81,0,345,3,82, -0,345,3,83,0, -345,3,84,0,345, -3,85,0,345,3, -86,0,345,3,87, -0,345,3,88,0, -345,3,89,0,345, -3,90,0,345,3, -95,0,345,3,97, -0,345,3,98,0, -345,3,99,0,345, -3,100,0,345,3, -101,0,345,3,102, -0,345,3,103,0, -345,3,104,0,345, -3,105,0,345,3, -106,0,345,3,107, -0,345,3,108,0, -345,794,11,1,867, -0,348,1,-1,3, -106,0,345,3,107, -0,345,3,108,0, -345,795,11,1,867, -0,348,1,-1,3, -116,0,345,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,345,3, -98,0,345,3,99, -0,345,3,100,0, -345,3,101,0,345, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -345,3,106,0,345, -3,107,0,345,3, -108,0,345,796,11, -1,867,0,348,1, --1,3,106,0,345, -3,107,0,345,3, -108,0,345,797,11, -1,867,0,348,1, --1,798,11,1,867, -0,348,1,-1,799, -11,1,867,0,348, -1,-1,3,112,0, -345,3,113,0,345, -3,114,0,345,3, -115,0,345,3,116, -0,345,3,117,0, -345,3,118,0,345, -3,119,0,345,3, -120,0,345,3,121, -0,345,3,122,0, -345,3,48,0,345, -3,49,0,345,3, -50,0,345,3,51, -0,345,3,52,0, -345,3,53,0,345, -3,54,0,345,3, -55,0,345,3,56, -0,345,3,57,0, -345,3,65,0,345, -3,66,0,345,3, -67,0,345,3,68, -0,345,3,69,0, -345,3,70,0,345, -3,71,0,345,3, -72,0,345,3,73, -0,345,3,74,0, -345,3,75,0,345, -3,76,0,345,3, -77,0,345,3,78, -0,345,3,79,0, -345,3,80,0,345, -3,81,0,345,3, -82,0,345,3,83, -0,345,3,84,0, -345,3,85,0,345, -3,86,0,345,3, -87,0,345,3,88, -0,345,3,89,0, -345,3,90,0,345, -3,95,0,345,3, -97,0,345,3,98, -0,345,3,99,0, -345,3,100,0,345, -3,101,0,345,3, -102,0,345,3,103, -0,345,3,104,0, -345,3,105,0,345, -3,106,0,345,3, -107,0,345,3,108, -0,345,800,11,1, -867,0,348,1,-1, -3,100,0,345,3, -101,0,345,3,102, -0,345,3,103,0, -345,3,104,0,345, -3,105,0,345,3, -106,0,345,3,107, -0,345,3,108,0, -345,801,11,1,867, -0,348,1,-1,3, -97,0,345,3,98, -0,345,3,99,0, -345,3,100,0,345, -3,101,0,345,3, -102,0,345,3,103, -0,345,3,104,0, -345,3,105,0,345, -3,106,0,345,3, -107,0,345,3,108, -0,345,802,11,1, -867,0,348,1,-1, -3,101,0,345,3, -102,0,345,3,103, -0,345,3,104,0, -345,3,105,0,345, -3,106,0,345,3, -107,0,345,3,108, -0,345,803,11,1, -867,0,348,1,-1, -3,111,0,345,3, -112,0,345,3,113, -0,345,3,114,0, -345,3,115,0,345, -3,116,0,345,3, -117,0,345,3,118, -0,345,3,119,0, -345,3,120,0,345, -3,121,0,345,3, -122,0,345,3,48, -0,345,3,49,0, -345,3,50,0,345, -3,51,0,345,3, -52,0,345,3,53, -0,345,3,54,0, -345,3,55,0,345, -3,56,0,345,3, -57,0,345,3,65, -0,345,3,66,0, -345,3,67,0,345, -3,68,0,345,3, -69,0,345,3,70, -0,345,3,71,0, -345,3,72,0,345, -3,73,0,345,3, -74,0,345,3,75, -0,345,3,76,0, -345,3,77,0,345, -3,78,0,345,3, -79,0,345,3,80, -0,345,3,81,0, -345,3,82,0,345, -3,83,0,345,3, -84,0,345,3,85, -0,345,3,86,0, -345,3,87,0,345, -3,88,0,345,3, -89,0,345,3,90, -0,345,3,95,0, -345,3,97,0,345, -3,98,0,345,3, -99,0,345,3,100, -0,345,3,101,0, -345,3,102,0,345, -3,103,0,345,3, -104,0,345,3,105, -0,345,3,106,0, -345,3,107,0,345, -3,108,0,345,804, -11,1,867,0,348, -1,-1,3,98,0, -345,3,99,0,345, -3,100,0,345,3, -101,0,345,3,102, -0,345,3,103,0, -345,3,104,0,345, -3,105,0,805,12, -1,39481,806,5,63, -3,109,0,345,3, -110,0,807,12,1, -39510,808,5,63,3, -109,0,345,3,110, -0,345,3,111,0, -345,3,112,0,345, -3,113,0,345,3, -114,0,345,3,115, -0,345,3,116,0, -345,3,117,0,345, -3,118,0,345,3, -119,0,345,3,120, -0,345,3,121,0, -345,3,122,0,345, -3,48,0,345,3, -49,0,345,3,50, -0,345,3,51,0, -345,3,52,0,345, -3,53,0,345,3, -54,0,345,3,55, -0,345,3,56,0, -345,3,57,0,345, -3,65,0,345,3, -66,0,345,3,67, -0,345,3,68,0, -345,3,69,0,345, -3,70,0,345,3, -71,0,345,3,72, -0,345,3,73,0, -345,3,74,0,345, -3,75,0,345,3, -76,0,345,3,77, -0,345,3,78,0, -345,3,79,0,345, -3,80,0,345,3, -81,0,345,3,82, -0,345,3,83,0, -345,3,84,0,345, -3,85,0,345,3, -86,0,345,3,87, -0,345,3,88,0, -345,3,89,0,345, -3,90,0,345,3, -95,0,345,3,97, -0,345,3,98,0, -345,3,99,0,345, -3,100,0,345,3, -101,0,345,3,102, -0,345,3,103,0, -345,3,104,0,345, -3,105,0,345,3, -106,0,345,3,107, -0,809,12,1,39563, -810,5,63,3,109, -0,345,3,110,0, -345,3,111,0,345, -3,112,0,345,3, -113,0,345,3,114, -0,345,3,115,0, -345,3,116,0,345, -3,117,0,345,3, -118,0,345,3,119, -0,345,3,120,0, -345,3,121,0,345, -3,122,0,345,3, -48,0,345,3,49, -0,345,3,50,0, -345,3,51,0,345, -3,52,0,345,3, -53,0,345,3,54, -0,345,3,55,0, -345,3,56,0,345, -3,57,0,345,3, -65,0,345,3,66, -0,345,3,67,0, -345,3,68,0,345, -3,69,0,345,3, -70,0,345,3,71, -0,345,3,72,0, -345,3,73,0,345, -3,74,0,345,3, -75,0,345,3,76, -0,345,3,77,0, -345,3,78,0,345, -3,79,0,345,3, -80,0,345,3,81, -0,345,3,82,0, -345,3,83,0,345, -3,84,0,345,3, -85,0,345,3,86, -0,345,3,87,0, -345,3,88,0,345, -3,89,0,345,3, -90,0,345,3,95, -0,811,12,1,39649, -812,5,63,3,109, -0,813,12,1,39677, -814,5,63,3,109, -0,345,3,110,0, -345,3,111,0,345, -3,112,0,345,3, -113,0,345,3,114, -0,345,3,115,0, -345,3,116,0,345, -3,117,0,345,3, -118,0,345,3,119, -0,345,3,120,0, -345,3,121,0,345, -3,122,0,345,3, -48,0,345,3,49, -0,345,3,50,0, -345,3,51,0,345, -3,52,0,345,3, -53,0,345,3,54, -0,345,3,55,0, -345,3,56,0,345, -3,57,0,345,3, -65,0,345,3,66, -0,345,3,67,0, -345,3,68,0,345, -3,69,0,345,3, -70,0,345,3,71, -0,345,3,72,0, -345,3,73,0,345, -3,74,0,345,3, -75,0,345,3,76, -0,345,3,77,0, -345,3,78,0,345, -3,79,0,345,3, -80,0,345,3,81, -0,345,3,82,0, -345,3,83,0,345, -3,84,0,345,3, -85,0,345,3,86, -0,345,3,87,0, -345,3,88,0,345, -3,89,0,345,3, -90,0,345,3,95, -0,345,3,97,0, -345,3,98,0,345, -3,99,0,345,3, -100,0,345,3,101, -0,815,12,1,39724, -816,5,63,3,109, -0,345,3,110,0, -345,3,111,0,345, -3,112,0,345,3, -113,0,345,3,114, -0,345,3,115,0, -817,12,1,39758,818, -5,63,3,109,0, -345,3,110,0,345, -3,111,0,345,3, -112,0,345,3,113, -0,345,3,114,0, -345,3,115,0,819, -12,1,39792,820,5, -63,3,109,0,345, -3,110,0,345,3, -111,0,345,3,112, -0,345,3,113,0, -345,3,114,0,345, -3,115,0,345,3, -116,0,345,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,821,12, -1,39835,822,5,63, -3,109,0,345,3, -110,0,345,3,111, -0,345,3,112,0, -345,3,113,0,345, -3,114,0,345,3, -115,0,345,3,116, -0,345,3,117,0, -345,3,118,0,345, -3,119,0,345,3, -120,0,345,3,121, -0,345,3,122,0, -345,3,48,0,345, -3,49,0,345,3, -50,0,345,3,51, -0,345,3,52,0, -345,3,53,0,345, -3,54,0,345,3, -55,0,345,3,56, -0,345,3,57,0, -345,3,65,0,345, -3,66,0,345,3, -67,0,345,3,68, -0,345,3,69,0, -345,3,70,0,345, -3,71,0,345,3, -72,0,345,3,73, -0,345,3,74,0, -345,3,75,0,345, -3,76,0,345,3, -77,0,345,3,78, -0,345,3,79,0, -345,3,80,0,345, -3,81,0,345,3, -82,0,345,3,83, -0,345,3,84,0, -345,3,85,0,345, -3,86,0,345,3, -87,0,345,3,88, -0,345,3,89,0, -345,3,90,0,345, -3,95,0,345,3, -97,0,345,3,98, -0,345,3,99,0, -345,3,100,0,345, -3,101,0,345,3, -102,0,345,3,103, -0,823,12,1,39884, -824,5,63,3,109, -0,345,3,110,0, -345,3,111,0,345, -3,112,0,345,3, -113,0,345,3,114, -0,345,3,115,0, -345,3,116,0,345, -3,117,0,345,3, -118,0,345,3,119, -0,345,3,120,0, -345,3,121,0,345, -3,122,0,345,3, -48,0,345,3,49, -0,345,3,50,0, -345,3,51,0,345, -3,52,0,345,3, -53,0,345,3,54, -0,345,3,55,0, -345,3,56,0,345, -3,57,0,345,3, -65,0,345,3,66, -0,345,3,67,0, -345,3,68,0,345, -3,69,0,345,3, -70,0,345,3,71, -0,345,3,72,0, -345,3,73,0,345, -3,74,0,345,3, -75,0,345,3,76, -0,345,3,77,0, -345,3,78,0,345, -3,79,0,345,3, -80,0,345,3,81, -0,345,3,82,0, -345,3,83,0,345, -3,84,0,345,3, -85,0,345,3,86, -0,345,3,87,0, -345,3,88,0,345, -3,89,0,345,3, -90,0,345,3,95, -0,345,3,97,0, -345,3,98,0,345, -3,99,0,345,3, -100,0,345,3,101, -0,825,12,1,39931, -826,5,63,3,109, -0,345,3,110,0, -345,3,111,0,345, -3,112,0,345,3, -113,0,345,3,114, -0,345,3,115,0, -345,3,116,0,345, -3,117,0,345,3, -118,0,345,3,119, -0,345,3,120,0, -345,3,121,0,345, -3,122,0,345,3, -48,0,345,3,49, -0,345,3,50,0, -345,3,51,0,345, -3,52,0,345,3, -53,0,345,3,54, -0,345,3,55,0, -345,3,56,0,345, -3,57,0,345,3, -65,0,345,3,66, -0,345,3,67,0, -345,3,68,0,345, -3,69,0,345,3, -70,0,345,3,71, -0,345,3,72,0, -345,3,73,0,345, -3,74,0,345,3, -75,0,345,3,76, -0,345,3,77,0, -345,3,78,0,345, -3,79,0,345,3, -80,0,345,3,81, -0,345,3,82,0, -345,3,83,0,345, -3,84,0,345,3, -85,0,345,3,86, -0,345,3,87,0, -345,3,88,0,345, -3,89,0,345,3, -90,0,345,3,95, -0,345,3,97,0, -345,3,98,0,345, -3,99,0,345,3, -100,0,345,3,101, -0,345,3,102,0, -345,3,103,0,345, -3,104,0,345,3, -105,0,345,3,106, -0,345,3,107,0, -345,3,108,0,345, -827,11,1,565,0, -828,4,36,76,0, -73,0,78,0,75, -0,95,0,77,0, -69,0,83,0,83, -0,65,0,71,0, -69,0,95,0,69, +87,0,180,3,122, +0,180,3,95,0, +180,3,68,0,180, +3,103,0,180,3, +76,0,180,3,49, +0,180,3,111,0, +180,3,84,0,180, +3,57,0,180,3, +119,0,180,3,65, +0,180,3,100,0, +180,3,73,0,180, +3,108,0,180,3, +81,0,180,3,54, +0,180,3,116,0, +180,3,89,0,180, +901,11,1,867,0, +183,1,-1,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +180,3,87,0,180, +3,122,0,180,3, +95,0,180,3,68, +0,180,3,103,0, +180,3,76,0,180, +3,49,0,180,3, +111,0,180,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,180,3,73, +0,180,3,108,0, +180,3,81,0,180, +3,54,0,180,3, +116,0,180,3,89, +0,180,902,11,1, +867,0,183,1,-1, +3,99,0,180,3, +72,0,180,3,107, +0,180,3,80,0, +180,3,53,0,180, +3,115,0,180,3, +88,0,180,3,69, +0,180,3,104,0, +180,3,77,0,180, +3,50,0,180,3, +112,0,180,3,85, +0,180,3,120,0, +180,3,66,0,180, +3,101,0,180,3, +74,0,180,3,109, +0,180,3,82,0, +180,3,55,0,180, +3,117,0,180,3, +90,0,180,3,98, +0,180,3,71,0, +180,3,106,0,180, +3,79,0,180,3, +52,0,180,3,114, +0,180,3,87,0, +180,3,122,0,180, +3,95,0,180,3, +68,0,180,3,103, +0,180,3,76,0, +180,3,49,0,180, +3,111,0,180,3, +84,0,180,3,57, +0,180,3,119,0, +180,3,65,0,180, +3,100,0,180,3, +73,0,180,3,108, +0,180,3,81,0, +180,3,54,0,180, +3,116,0,180,3, +89,0,180,903,11, +1,867,0,183,1, +-1,3,87,0,180, +3,122,0,180,3, +95,0,180,3,68, +0,180,3,103,0, +180,3,76,0,180, +3,49,0,180,3, +111,0,180,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,180,3,73, +0,180,3,108,0, +180,3,81,0,180, +3,54,0,180,3, +116,0,180,3,89, +0,180,904,11,1, +867,0,183,1,-1, +3,74,0,180,3, +109,0,180,3,82, +0,180,3,55,0, +180,3,117,0,180, +3,90,0,180,3, +98,0,180,3,71, +0,180,3,106,0, +180,3,79,0,180, +3,52,0,180,3, +114,0,180,3,87, +0,180,3,122,0, +180,3,95,0,180, +3,68,0,180,3, +103,0,180,3,76, +0,180,3,49,0, +180,3,111,0,180, +3,84,0,180,3, +57,0,180,3,119, +0,180,3,65,0, +180,3,100,0,180, +3,73,0,180,3, +108,0,180,3,81, +0,180,3,54,0, +180,3,116,0,180, +3,89,0,180,905, +11,1,867,0,183, +1,-1,3,88,0, +180,3,69,0,180, +3,104,0,180,3, +77,0,180,3,50, +0,180,3,112,0, +180,3,85,0,180, +3,120,0,180,3, +66,0,180,3,101, +0,180,3,74,0, +180,3,109,0,180, +3,82,0,180,3, +55,0,180,3,117, +0,180,3,90,0, +180,3,98,0,180, +3,71,0,180,3, +106,0,180,3,79, +0,180,3,52,0, +180,3,114,0,180, +3,87,0,180,3, +122,0,180,3,95, +0,180,3,68,0, +180,3,103,0,180, +3,76,0,180,3, +49,0,180,3,111, +0,180,3,84,0, +180,3,57,0,180, +3,119,0,180,3, +65,0,180,3,100, +0,180,3,73,0, +180,3,108,0,180, +3,81,0,180,3, +54,0,180,3,116, +0,180,3,89,0, +180,906,11,1,867, +0,183,1,-1,3, +70,0,180,3,105, +0,180,3,78,0, +180,3,51,0,180, +3,113,0,180,3, +86,0,180,3,121, +0,180,3,67,0, +180,3,102,0,180, +3,75,0,180,3, +48,0,180,3,110, +0,180,3,83,0, +180,3,56,0,180, +3,118,0,180,3, +99,0,180,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,180,3,88, +0,180,3,69,0, +180,3,104,0,180, +3,77,0,180,3, +50,0,180,3,112, +0,180,3,85,0, +180,3,120,0,180, +3,66,0,180,3, +101,0,180,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +180,3,87,0,180, +3,122,0,180,3, +95,0,180,3,68, +0,180,3,103,0, +180,3,76,0,180, +3,49,0,180,3, +111,0,180,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,180,3,73, +0,180,3,108,0, +180,3,81,0,180, +3,54,0,180,3, +116,0,180,3,89, +0,180,907,11,1, +867,0,183,1,-1, +3,89,0,180,908, +11,1,867,0,183, +1,-1,3,70,0, +180,3,105,0,180, +3,78,0,180,3, +51,0,180,3,113, +0,180,3,86,0, +180,3,121,0,180, +3,67,0,180,3, +102,0,180,3,75, +0,180,3,48,0, +180,3,110,0,180, +3,83,0,180,3, +56,0,180,3,118, +0,180,3,99,0, +180,3,72,0,180, +3,107,0,180,3, +80,0,180,3,53, +0,180,3,115,0, +180,3,88,0,180, +3,69,0,180,3, +104,0,180,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,180,3,66, +0,180,3,101,0, +909,12,1,39187,910, +5,63,3,97,0, +180,3,70,0,180, +3,105,0,180,3, +78,0,180,3,51, +0,180,3,113,0, +180,3,86,0,180, +3,121,0,180,3, +67,0,180,3,102, +0,911,12,1,39258, +912,5,63,3,97, +0,913,12,1,39325, +914,5,63,3,97, +0,180,3,70,0, +180,3,105,0,180, +3,78,0,180,3, +51,0,180,3,113, +0,180,3,86,0, +180,3,121,0,180, +3,67,0,180,3, +102,0,180,3,75, +0,180,3,48,0, +180,3,110,0,180, +3,83,0,180,3, +56,0,180,3,118, +0,180,3,99,0, +180,3,72,0,180, +3,107,0,180,3, +80,0,180,3,53, +0,180,3,115,0, +180,3,88,0,180, +3,69,0,180,3, +104,0,180,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,180,3,66, +0,180,3,101,0, +180,3,74,0,180, +3,109,0,180,3, +82,0,180,3,55, +0,180,3,117,0, +915,12,1,39407,916, +5,63,3,97,0, +180,3,70,0,180, +3,105,0,180,3, +78,0,180,3,51, +0,180,3,113,0, +180,3,86,0,180, +3,121,0,180,3, +67,0,180,3,102, +0,180,3,75,0, +180,3,48,0,180, +3,110,0,180,3, +83,0,180,3,56, +0,180,3,118,0, +180,3,99,0,180, +3,72,0,180,3, +107,0,180,3,80, +0,180,3,53,0, +180,3,115,0,180, +3,88,0,180,3, +69,0,180,3,104, +0,180,3,77,0, +180,3,50,0,180, +3,112,0,180,3, +85,0,180,3,120, +0,180,3,66,0, +180,3,101,0,180, +3,74,0,180,3, +109,0,180,3,82, +0,180,3,55,0, +180,3,117,0,180, +3,90,0,180,3, +98,0,180,3,71, +0,180,3,106,0, +180,3,79,0,180, +3,52,0,180,3, +114,0,180,3,87, +0,180,3,122,0, +180,3,95,0,180, +3,68,0,180,3, +103,0,180,3,76, +0,180,3,49,0, +180,3,111,0,180, +3,84,0,180,3, +57,0,180,3,119, +0,180,3,65,0, +180,3,100,0,180, +3,73,0,180,3, +108,0,917,12,1, +39498,918,5,63,3, +97,0,180,3,70, +0,180,3,105,0, +180,3,78,0,180, +3,51,0,180,3, +113,0,180,3,86, +0,180,3,121,0, +180,3,67,0,180, +3,102,0,180,3, +75,0,180,3,48, +0,180,3,110,0, +180,3,83,0,180, +3,56,0,180,3, +118,0,180,3,99, +0,180,3,72,0, +180,3,107,0,180, +3,80,0,180,3, +53,0,180,3,115, +0,180,3,88,0, +180,3,69,0,180, +3,104,0,180,3, +77,0,180,3,50, +0,180,3,112,0, +180,3,85,0,180, +3,120,0,180,3, +66,0,180,3,101, +0,180,3,74,0, +180,3,109,0,180, +3,82,0,180,3, +55,0,180,3,117, +0,180,3,90,0, +180,3,98,0,180, +3,71,0,180,3, +106,0,180,3,79, +0,180,3,52,0, +180,3,114,0,180, +3,87,0,180,3, +122,0,180,3,95, +0,180,3,68,0, +180,3,103,0,180, +3,76,0,180,3, +49,0,180,3,111, +0,180,3,84,0, +180,3,57,0,180, +3,119,0,180,3, +65,0,180,3,100, +0,180,3,73,0, +180,3,108,0,180, +3,81,0,180,3, +54,0,180,3,116, +0,919,12,1,39591, +920,5,63,3,97, +0,180,3,70,0, +180,3,105,0,180, +3,78,0,180,3, +51,0,180,3,113, +0,180,3,86,0, +180,3,121,0,180, +3,67,0,180,3, +102,0,180,3,75, +0,180,3,48,0, +180,3,110,0,180, +3,83,0,180,3, +56,0,180,3,118, +0,180,3,99,0, +180,3,72,0,180, +3,107,0,180,3, +80,0,180,3,53, +0,180,3,115,0, +180,3,88,0,180, +3,69,0,180,3, +104,0,180,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,180,3,66, +0,180,3,101,0, +180,3,74,0,180, +3,109,0,180,3, +82,0,180,3,55, +0,180,3,117,0, +180,3,90,0,180, +3,98,0,180,3, +71,0,180,3,106, +0,180,3,79,0, +180,3,52,0,180, +3,114,0,180,3, +87,0,180,3,122, +0,180,3,95,0, +180,3,68,0,180, +3,103,0,180,3, +76,0,180,3,49, +0,180,3,111,0, +180,3,84,0,180, +3,57,0,180,3, +119,0,180,3,65, +0,180,3,100,0, +180,3,73,0,180, +3,108,0,180,3, +81,0,180,3,54, +0,180,3,116,0, +180,3,89,0,180, +921,11,1,245,0, +922,4,26,68,0, +69,0,70,0,65, +0,85,0,76,0, +84,0,95,0,83, +0,84,0,65,0, +84,0,69,0,1, +-1,3,89,0,180, +923,11,1,867,0, +183,1,-1,3,81, +0,180,3,54,0, +180,3,116,0,180, +3,89,0,180,924, +11,1,867,0,183, +1,-1,3,90,0, +180,3,98,0,180, +3,71,0,180,3, +106,0,180,3,79, +0,180,3,52,0, +180,3,114,0,180, +3,87,0,180,3, +122,0,180,3,95, +0,180,3,68,0, +180,3,103,0,180, +3,76,0,180,3, +49,0,180,3,111, +0,180,3,84,0, +180,3,57,0,180, +3,119,0,180,3, +65,0,180,3,100, +0,180,3,73,0, +180,3,108,0,180, +3,81,0,180,3, +54,0,180,3,116, +0,180,3,89,0, +180,925,11,1,867, +0,183,1,-1,3, +70,0,180,3,105, +0,180,3,78,0, +180,3,51,0,180, +3,113,0,180,3, +86,0,180,3,121, +0,180,3,67,0, +180,3,102,0,180, +3,75,0,180,3, +48,0,180,3,110, +0,180,3,83,0, +180,3,56,0,180, +3,118,0,180,3, +99,0,180,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,180,3,88, +0,180,3,69,0, +180,3,104,0,180, +3,77,0,180,3, +50,0,180,3,112, +0,180,3,85,0, +180,3,120,0,180, +3,66,0,180,3, +101,0,180,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +180,3,87,0,180, +3,122,0,180,3, +95,0,180,3,68, +0,180,3,103,0, +180,3,76,0,180, +3,49,0,180,3, +111,0,180,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,180,3,73, +0,180,3,108,0, +180,3,81,0,180, +3,54,0,180,3, +116,0,180,3,89, +0,180,926,11,1, +867,0,183,1,-1, +3,75,0,180,3, +48,0,180,3,110, +0,180,3,83,0, +180,3,56,0,180, +3,118,0,180,3, +99,0,180,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,180,3,88, +0,180,3,69,0, +180,3,104,0,180, +3,77,0,180,3, +50,0,180,3,112, +0,180,3,85,0, +180,3,120,0,180, +3,66,0,180,3, +101,0,180,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +180,3,87,0,180, +3,122,0,180,3, +95,0,180,3,68, +0,180,3,103,0, +180,3,76,0,180, +3,49,0,180,3, +111,0,180,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,180,3,73, +0,180,3,108,0, +180,3,81,0,180, +3,54,0,180,3, +116,0,180,3,89, +0,180,927,11,1, +867,0,183,1,-1, +3,74,0,180,3, +109,0,180,3,82, +0,180,3,55,0, +180,3,117,0,180, +3,90,0,180,3, +98,0,180,3,71, +0,180,3,106,0, +180,3,79,0,180, +3,52,0,180,3, +114,0,180,3,87, +0,180,3,122,0, +180,3,95,0,180, +3,68,0,180,3, +103,0,180,3,76, +0,180,3,49,0, +180,3,111,0,928, +12,1,39915,929,5, +63,3,97,0,180, +3,70,0,180,3, +105,0,180,3,78, +0,180,3,51,0, +180,3,113,0,180, +3,86,0,180,3, +121,0,180,3,67, +0,180,3,102,0, +180,3,75,0,180, +3,48,0,180,3, +110,0,180,3,83, +0,180,3,56,0, +180,3,118,0,180, +3,99,0,180,3, +72,0,180,3,107, +0,180,3,80,0, +180,3,53,0,180, +3,115,0,180,3, +88,0,180,3,69, +0,180,3,104,0, +180,3,77,0,180, +3,50,0,180,3, +112,0,180,3,85, +0,180,3,120,0, +180,3,66,0,180, +3,101,0,180,3, +74,0,180,3,109, +0,180,3,82,0, +180,3,55,0,180, +3,117,0,180,3, +90,0,180,3,98, +0,180,3,71,0, +180,3,106,0,180, +3,79,0,180,3, +52,0,180,3,114, +0,180,3,87,0, +180,3,122,0,180, +3,95,0,180,3, +68,0,180,3,103, +0,180,3,76,0, +180,3,49,0,180, +3,111,0,180,3, +84,0,180,3,57, +0,180,3,119,0, +180,3,65,0,180, +3,100,0,180,3, +73,0,180,3,108, +0,180,3,81,0, +180,3,54,0,180, +3,116,0,180,3, +89,0,180,930,11, +1,223,0,931,4, +4,68,0,79,0, +1,-1,3,84,0, +180,3,57,0,180, +3,119,0,180,3, +65,0,180,3,100, +0,180,3,73,0, +180,3,108,0,180, +3,81,0,180,3, +54,0,180,3,116, +0,180,3,89,0, +180,932,11,1,867, +0,183,1,-1,3, +60,0,933,12,1, +2901,934,5,2,3, +61,0,935,12,1, +3029,936,5,0,937, +11,1,148,0,938, +4,22,76,0,69, +0,83,0,83,0, +95,0,69,0,81, +0,85,0,65,0, +76,0,83,0,1, +-1,3,60,0,939, +12,1,2905,940,5, +0,941,11,1,197, +0,942,4,20,76, +0,69,0,70,0, +84,0,95,0,83, +0,72,0,73,0, +70,0,84,0,1, +-1,943,11,1,116, +0,944,4,20,76, +0,69,0,70,0, +84,0,95,0,65, +0,78,0,71,0, +76,0,69,0,1, +-1,3,97,0,945, +12,1,9444,946,5, +63,3,97,0,180, +3,70,0,180,3, +105,0,180,3,78, +0,180,3,51,0, +180,3,113,0,180, +3,86,0,180,3, +121,0,180,3,67, +0,180,3,102,0, +180,3,75,0,180, +3,48,0,180,3, +110,0,180,3,83, +0,180,3,56,0, +180,3,118,0,180, +3,99,0,180,3, +72,0,180,3,107, +0,180,3,80,0, +180,3,53,0,180, +3,115,0,180,3, +88,0,180,3,69, +0,180,3,104,0, +180,3,77,0,180, +3,50,0,180,3, +112,0,180,3,85, +0,180,3,120,0, +180,3,66,0,180, +3,101,0,180,3, +74,0,180,3,109, +0,180,3,82,0, +180,3,55,0,180, +3,117,0,180,3, +90,0,180,3,98, +0,180,3,71,0, +180,3,106,0,180, +3,79,0,180,3, +52,0,180,3,114, +0,180,3,87,0, +180,3,122,0,180, +3,95,0,180,3, +68,0,180,3,103, +0,180,3,76,0, +180,3,49,0,180, +3,111,0,180,3, +84,0,180,3,57, +0,180,3,119,0, +180,3,65,0,180, +3,100,0,180,3, +73,0,180,3,108, +0,180,3,81,0, +180,3,54,0,180, +3,116,0,947,12, +1,9537,948,5,63, +3,97,0,180,3, +70,0,180,3,105, +0,180,3,78,0, +180,3,51,0,180, +3,113,0,180,3, +86,0,180,3,121, +0,180,3,67,0, +180,3,102,0,180, +3,75,0,180,3, +48,0,180,3,110, +0,180,3,83,0, +180,3,56,0,180, +3,118,0,180,3, +99,0,180,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,180,3,88, +0,180,3,69,0, +180,3,104,0,180, +3,77,0,180,3, +50,0,180,3,112, +0,180,3,85,0, +180,3,120,0,180, +3,66,0,180,3, +101,0,180,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +180,3,87,0,180, +3,122,0,180,3, +95,0,949,12,1, +9573,950,5,63,3, +97,0,180,3,70, +0,180,3,105,0, +180,3,78,0,180, +3,51,0,180,3, +113,0,180,3,86, +0,180,3,121,0, +180,3,67,0,180, +3,102,0,180,3, +75,0,180,3,48, +0,180,3,110,0, +180,3,83,0,180, +3,56,0,180,3, +118,0,180,3,99, +0,180,3,72,0, +180,3,107,0,180, +3,80,0,180,3, +53,0,180,3,115, +0,180,3,88,0, +180,3,69,0,180, +3,104,0,180,3, +77,0,180,3,50, +0,180,3,112,0, +180,3,85,0,180, +3,120,0,180,3, +66,0,180,3,101, +0,180,3,74,0, +180,3,109,0,180, +3,82,0,180,3, +55,0,180,3,117, +0,180,3,90,0, +180,3,98,0,180, +3,71,0,180,3, +106,0,180,3,79, +0,180,3,52,0, +180,3,114,0,951, +12,1,9658,952,5, +63,3,97,0,180, +3,70,0,180,3, +105,0,180,3,78, +0,180,3,51,0, +180,3,113,0,180, +3,86,0,180,3, +121,0,180,3,67, +0,180,3,102,0, +180,3,75,0,180, +3,48,0,180,3, +110,0,180,3,83, +0,180,3,56,0, +180,3,118,0,180, +3,99,0,180,3, +72,0,180,3,107, +0,180,3,80,0, +180,3,53,0,180, +3,115,0,180,3, +88,0,180,3,69, +0,180,3,104,0, +180,3,77,0,180, +3,50,0,180,3, +112,0,180,3,85, +0,180,3,120,0, +180,3,66,0,180, +3,101,0,180,3, +74,0,180,3,109, +0,180,3,82,0, +180,3,55,0,180, +3,117,0,180,3, +90,0,180,3,98, +0,180,3,71,0, +180,3,106,0,180, +3,79,0,180,3, +52,0,180,3,114, +0,180,3,87,0, +180,3,122,0,180, +3,95,0,180,3, +68,0,180,3,103, +0,180,3,76,0, +180,3,49,0,180, +3,111,0,953,12, +1,9746,954,5,63, +3,97,0,180,3, +70,0,180,3,105, +0,180,3,78,0, +180,3,51,0,180, +3,113,0,180,3, +86,0,180,3,121, +0,180,3,67,0, +180,3,102,0,180, +3,75,0,180,3, +48,0,180,3,110, +0,180,3,83,0, +180,3,56,0,180, +3,118,0,180,3, +99,0,180,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,180,3,88, +0,180,3,69,0, +180,3,104,0,180, +3,77,0,180,3, +50,0,180,3,112, +0,180,3,85,0, +180,3,120,0,180, +3,66,0,180,3, +101,0,180,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +180,3,87,0,180, +3,122,0,180,3, +95,0,180,3,68, +0,180,3,103,0, +180,3,76,0,180, +3,49,0,180,3, +111,0,180,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,180,3,73, +0,180,3,108,0, +180,3,81,0,180, +3,54,0,180,3, +116,0,955,12,1, +9839,956,5,63,3, +97,0,180,3,70, +0,180,3,105,0, +180,3,78,0,180, +3,51,0,180,3, +113,0,180,3,86, +0,180,3,121,0, +180,3,67,0,180, +3,102,0,180,3, +75,0,180,3,48, +0,180,3,110,0, +180,3,83,0,180, +3,56,0,180,3, +118,0,180,3,99, +0,180,3,72,0, +180,3,107,0,180, +3,80,0,180,3, +53,0,180,3,115, +0,180,3,88,0, +180,3,69,0,180, +3,104,0,180,3, +77,0,180,3,50, +0,180,3,112,0, +180,3,85,0,180, +3,120,0,180,3, +66,0,180,3,101, +0,180,3,74,0, +180,3,109,0,180, +3,82,0,180,3, +55,0,180,3,117, +0,180,3,90,0, +180,3,98,0,180, +3,71,0,180,3, +106,0,180,3,79, +0,180,3,52,0, +180,3,114,0,180, +3,87,0,180,3, +122,0,180,3,95, +0,957,12,1,9875, +958,5,63,3,97, +0,180,3,70,0, +180,3,105,0,180, +3,78,0,180,3, +51,0,180,3,113, +0,180,3,86,0, +180,3,121,0,180, +3,67,0,180,3, +102,0,180,3,75, +0,180,3,48,0, +180,3,110,0,180, +3,83,0,180,3, +56,0,180,3,118, +0,180,3,99,0, +180,3,72,0,180, +3,107,0,180,3, +80,0,180,3,53, +0,180,3,115,0, +180,3,88,0,180, +3,69,0,180,3, +104,0,180,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,180,3,66, +0,180,3,101,0, +180,3,74,0,180, +3,109,0,180,3, +82,0,180,3,55, +0,180,3,117,0, +180,3,90,0,180, +3,98,0,180,3, +71,0,180,3,106, +0,180,3,79,0, +180,3,52,0,180, +3,114,0,180,3, +87,0,180,3,122, +0,180,3,95,0, +180,3,68,0,180, +3,103,0,180,3, +76,0,180,3,49, +0,180,3,111,0, +180,3,84,0,180, +3,57,0,180,3, +119,0,180,3,65, +0,180,3,100,0, +180,3,73,0,180, +3,108,0,180,3, +81,0,180,3,54, +0,180,3,116,0, +959,12,1,9968,960, +5,63,3,97,0, +961,12,1,10035,962, +5,63,3,97,0, +180,3,70,0,180, +3,105,0,180,3, +78,0,180,3,51, +0,180,3,113,0, +180,3,86,0,180, +3,121,0,180,3, +67,0,180,3,102, +0,180,3,75,0, +180,3,48,0,180, +3,110,0,180,3, +83,0,180,3,56, +0,180,3,118,0, +180,3,99,0,180, +3,72,0,180,3, +107,0,180,3,80, +0,180,3,53,0, +180,3,115,0,180, +3,88,0,180,3, +69,0,180,3,104, +0,180,3,77,0, +180,3,50,0,180, +3,112,0,180,3, +85,0,180,3,120, +0,180,3,66,0, +180,3,101,0,180, +3,74,0,180,3, +109,0,180,3,82, +0,180,3,55,0, +180,3,117,0,180, +3,90,0,180,3, +98,0,180,3,71, +0,180,3,106,0, +180,3,79,0,180, +3,52,0,180,3, +114,0,963,12,1, +10120,964,5,63,3, +97,0,180,3,70, +0,180,3,105,0, +180,3,78,0,180, +3,51,0,180,3, +113,0,180,3,86, +0,180,3,121,0, +180,3,67,0,180, +3,102,0,180,3, +75,0,180,3,48, +0,180,3,110,0, +180,3,83,0,180, +3,56,0,180,3, +118,0,180,3,99, +0,180,3,72,0, +180,3,107,0,180, +3,80,0,180,3, +53,0,180,3,115, +0,180,3,88,0, +180,3,69,0,180, +3,104,0,180,3, +77,0,180,3,50, +0,180,3,112,0, +180,3,85,0,180, +3,120,0,180,3, +66,0,180,3,101, +0,180,3,74,0, +180,3,109,0,180, +3,82,0,180,3, +55,0,180,3,117, +0,180,3,90,0, +180,3,98,0,180, +3,71,0,180,3, +106,0,180,3,79, +0,180,3,52,0, +180,3,114,0,180, +3,87,0,180,3, +122,0,180,3,95, +0,180,3,68,0, +180,3,103,0,965, +12,1,10207,966,5, +63,3,97,0,180, +3,70,0,180,3, +105,0,180,3,78, +0,180,3,51,0, +180,3,113,0,180, +3,86,0,180,3, +121,0,180,3,67, +0,180,3,102,0, +180,3,75,0,180, +3,48,0,180,3, +110,0,180,3,83, +0,180,3,56,0, +180,3,118,0,180, +3,99,0,180,3, +72,0,180,3,107, +0,180,3,80,0, +180,3,53,0,180, +3,115,0,180,3, +88,0,180,3,69, +0,180,3,104,0, +180,3,77,0,180, +3,50,0,180,3, +112,0,180,3,85, +0,180,3,120,0, +180,3,66,0,180, +3,101,0,967,12, +1,10287,968,5,63, +3,97,0,180,3, +70,0,180,3,105, +0,180,3,78,0, +180,3,51,0,180, +3,113,0,180,3, +86,0,180,3,121, +0,180,3,67,0, +180,3,102,0,180, +3,75,0,180,3, +48,0,180,3,110, +0,180,3,83,0, +180,3,56,0,180, +3,118,0,180,3, +99,0,180,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,180,3,88, +0,180,3,69,0, +180,3,104,0,180, +3,77,0,180,3, +50,0,180,3,112, +0,180,3,85,0, +180,3,120,0,180, +3,66,0,180,3, +101,0,180,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +180,3,87,0,180, +3,122,0,180,3, +95,0,180,3,68, +0,180,3,103,0, +180,3,76,0,180, +3,49,0,180,3, +111,0,180,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,180,3,73, +0,180,3,108,0, +180,3,81,0,180, +3,54,0,180,3, +116,0,969,12,1, +10380,970,5,63,3, +97,0,180,3,70, +0,180,3,105,0, +180,3,78,0,180, +3,51,0,180,3, +113,0,180,3,86, +0,180,3,121,0, +180,3,67,0,180, +3,102,0,180,3, +75,0,180,3,48, +0,180,3,110,0, +180,3,83,0,180, +3,56,0,180,3, +118,0,180,3,99, +0,180,3,72,0, +180,3,107,0,180, +3,80,0,180,3, +53,0,180,3,115, +0,180,3,88,0, +180,3,69,0,180, +3,104,0,180,3, +77,0,180,3,50, +0,180,3,112,0, +180,3,85,0,180, +3,120,0,180,3, +66,0,180,3,101, +0,180,3,74,0, +180,3,109,0,180, +3,82,0,180,3, +55,0,180,3,117, +0,180,3,90,0, +180,3,98,0,180, +3,71,0,180,3, +106,0,180,3,79, +0,180,3,52,0, +180,3,114,0,180, +3,87,0,180,3, +122,0,180,3,95, +0,180,3,68,0, +180,3,103,0,180, +3,76,0,180,3, +49,0,180,3,111, +0,180,3,84,0, +180,3,57,0,180, +3,119,0,180,3, +65,0,180,3,100, +0,180,3,73,0, +180,3,108,0,180, +3,81,0,180,3, +54,0,180,3,116, +0,180,3,89,0, +180,971,11,1,350, +0,972,4,38,65, +0,84,0,95,0, +82,0,79,0,84, +0,95,0,84,0, +65,0,82,0,71, +0,69,0,84,0, +95,0,69,0,86, +0,69,0,78,0, +84,0,1,-1,3, +89,0,180,973,11, +1,867,0,183,1, +-1,3,74,0,180, +3,109,0,180,3, +82,0,180,3,55, +0,180,3,117,0, +180,3,90,0,180, +3,98,0,180,3, +71,0,180,3,106, +0,180,3,79,0, +180,3,52,0,180, +3,114,0,180,3, +87,0,180,3,122, +0,180,3,95,0, +180,3,68,0,180, +3,103,0,180,3, +76,0,180,3,49, +0,180,3,111,0, +180,3,84,0,180, +3,57,0,180,3, +119,0,180,3,65, +0,180,3,100,0, +180,3,73,0,180, +3,108,0,180,3, +81,0,180,3,54, +0,180,3,116,0, +180,3,89,0,180, +974,11,1,867,0, +183,1,-1,3,76, +0,180,3,49,0, +180,3,111,0,180, +3,84,0,180,3, +57,0,180,3,119, +0,180,3,65,0, +180,3,100,0,180, +3,73,0,180,3, +108,0,180,3,81, +0,180,3,54,0, +180,3,116,0,180, +3,89,0,180,975, +11,1,867,0,183, +1,-1,3,87,0, +180,3,122,0,180, +3,95,0,180,3, +68,0,180,3,103, +0,180,3,76,0, +180,3,49,0,180, +3,111,0,180,3, +84,0,180,3,57, +0,180,3,119,0, +180,3,65,0,180, +3,100,0,180,3, +73,0,180,3,108, +0,180,3,81,0, +180,3,54,0,180, +3,116,0,180,3, +89,0,180,976,11, +1,867,0,183,1, +-1,3,70,0,180, +3,105,0,180,3, +78,0,180,3,51, +0,180,3,113,0, +180,3,86,0,180, +3,121,0,180,3, +67,0,180,3,102, +0,180,3,75,0, +180,3,48,0,180, +3,110,0,180,3, +83,0,180,3,56, +0,180,3,118,0, +180,3,99,0,180, +3,72,0,180,3, +107,0,180,3,80, +0,180,3,53,0, +180,3,115,0,180, +3,88,0,180,3, +69,0,180,3,104, +0,180,3,77,0, +180,3,50,0,180, +3,112,0,180,3, +85,0,180,3,120, +0,180,3,66,0, +180,3,101,0,180, +3,74,0,180,3, +109,0,180,3,82, +0,180,3,55,0, +180,3,117,0,180, +3,90,0,180,3, +98,0,180,3,71, +0,180,3,106,0, +180,3,79,0,180, +3,52,0,180,3, +114,0,180,3,87, +0,180,3,122,0, +180,3,95,0,180, +3,68,0,180,3, +103,0,180,3,76, +0,180,3,49,0, +180,3,111,0,180, +3,84,0,180,3, +57,0,180,3,119, +0,180,3,65,0, +180,3,100,0,180, +3,73,0,180,3, +108,0,180,3,81, +0,180,3,54,0, +180,3,116,0,180, +3,89,0,180,977, +11,1,867,0,183, +1,-1,3,89,0, +180,978,11,1,867, +0,183,1,-1,3, +68,0,180,3,103, +0,180,3,76,0, +180,3,49,0,180, +3,111,0,180,3, +84,0,180,3,57, +0,180,3,119,0, +180,3,65,0,180, +3,100,0,180,3, +73,0,180,3,108, +0,180,3,81,0, +180,3,54,0,180, +3,116,0,180,3, +89,0,180,979,11, +1,867,0,183,1, +-1,3,89,0,180, +980,11,1,867,0, +183,1,-1,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,180,3,73, +0,180,3,108,0, +180,3,81,0,180, +3,54,0,180,3, +116,0,180,3,89, +0,180,981,11,1, +867,0,183,1,-1, +3,87,0,180,3, +122,0,180,3,95, +0,180,3,68,0, +180,3,103,0,180, +3,76,0,180,3, +49,0,180,3,111, +0,180,3,84,0, +180,3,57,0,180, +3,119,0,180,3, +65,0,180,3,100, +0,180,3,73,0, +180,3,108,0,180, +3,81,0,180,3, +54,0,180,3,116, +0,982,12,1,10866, +983,5,63,3,97, +0,984,12,1,10933, +985,5,63,3,97, +0,180,3,70,0, +180,3,105,0,180, +3,78,0,180,3, +51,0,180,3,113, +0,180,3,86,0, +180,3,121,0,180, +3,67,0,180,3, +102,0,180,3,75, +0,180,3,48,0, +180,3,110,0,180, +3,83,0,180,3, +56,0,180,3,118, +0,180,3,99,0, +180,3,72,0,180, +3,107,0,180,3, +80,0,180,3,53, +0,180,3,115,0, +180,3,88,0,180, +3,69,0,180,3, +104,0,180,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,180,3,66, +0,180,3,101,0, +180,3,74,0,180, +3,109,0,180,3, +82,0,180,3,55, +0,180,3,117,0, +180,3,90,0,180, +3,98,0,180,3, +71,0,180,3,106, +0,180,3,79,0, +180,3,52,0,180, +3,114,0,986,12, +1,11018,987,5,63, +3,97,0,180,3, +70,0,180,3,105, +0,180,3,78,0, +180,3,51,0,180, +3,113,0,180,3, +86,0,180,3,121, +0,180,3,67,0, +180,3,102,0,180, +3,75,0,180,3, +48,0,180,3,110, +0,180,3,83,0, +180,3,56,0,180, +3,118,0,180,3, +99,0,180,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,180,3,88, +0,180,3,69,0, +180,3,104,0,180, +3,77,0,180,3, +50,0,180,3,112, +0,180,3,85,0, +180,3,120,0,180, +3,66,0,180,3, +101,0,180,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +180,3,87,0,180, +3,122,0,180,3, +95,0,180,3,68, +0,180,3,103,0, +988,12,1,11105,989, +5,63,3,97,0, +180,3,70,0,180, +3,105,0,180,3, +78,0,180,3,51, +0,180,3,113,0, +180,3,86,0,180, +3,121,0,180,3, +67,0,180,3,102, +0,180,3,75,0, +180,3,48,0,180, +3,110,0,180,3, +83,0,180,3,56, +0,180,3,118,0, +180,3,99,0,180, +3,72,0,180,3, +107,0,180,3,80, +0,180,3,53,0, +180,3,115,0,180, +3,88,0,180,3, +69,0,180,3,104, +0,180,3,77,0, +180,3,50,0,180, +3,112,0,180,3, +85,0,180,3,120, +0,180,3,66,0, +180,3,101,0,990, +12,1,11185,991,5, +63,3,97,0,180, +3,70,0,180,3, +105,0,180,3,78, +0,180,3,51,0, +180,3,113,0,180, +3,86,0,180,3, +121,0,180,3,67, +0,180,3,102,0, +180,3,75,0,180, +3,48,0,180,3, +110,0,180,3,83, +0,180,3,56,0, +180,3,118,0,180, +3,99,0,180,3, +72,0,180,3,107, +0,180,3,80,0, +180,3,53,0,180, +3,115,0,180,3, +88,0,180,3,69, +0,180,3,104,0, +180,3,77,0,180, +3,50,0,180,3, +112,0,180,3,85, +0,180,3,120,0, +180,3,66,0,180, +3,101,0,180,3, +74,0,180,3,109, +0,180,3,82,0, +180,3,55,0,180, +3,117,0,180,3, +90,0,180,3,98, +0,180,3,71,0, +180,3,106,0,180, +3,79,0,180,3, +52,0,180,3,114, +0,180,3,87,0, +180,3,122,0,180, +3,95,0,180,3, +68,0,180,3,103, +0,180,3,76,0, +180,3,49,0,180, +3,111,0,180,3, +84,0,180,3,57, +0,180,3,119,0, +180,3,65,0,180, +3,100,0,180,3, +73,0,180,3,108, +0,180,3,81,0, +180,3,54,0,180, +3,116,0,992,12, +1,11278,993,5,63, +3,97,0,180,3, +70,0,180,3,105, +0,180,3,78,0, +180,3,51,0,180, +3,113,0,180,3, +86,0,180,3,121, +0,180,3,67,0, +180,3,102,0,180, +3,75,0,180,3, +48,0,180,3,110, +0,180,3,83,0, +180,3,56,0,180, +3,118,0,180,3, +99,0,180,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,180,3,88, +0,180,3,69,0, +180,3,104,0,180, +3,77,0,180,3, +50,0,180,3,112, +0,180,3,85,0, +180,3,120,0,180, +3,66,0,180,3, +101,0,180,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +180,3,87,0,180, +3,122,0,180,3, +95,0,180,3,68, +0,180,3,103,0, +180,3,76,0,180, +3,49,0,180,3, +111,0,180,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,180,3,73, +0,180,3,108,0, +180,3,81,0,180, +3,54,0,180,3, +116,0,180,3,89, +0,180,994,11,1, +367,0,995,4,30, +65,0,84,0,95, +0,84,0,65,0, +82,0,71,0,69, +0,84,0,95,0, +69,0,86,0,69, +0,78,0,84,0, +1,-1,3,89,0, +180,996,11,1,867, +0,183,1,-1,3, +74,0,180,3,109, +0,180,3,82,0, +180,3,55,0,180, +3,117,0,180,3, +90,0,180,3,98, +0,180,3,71,0, +180,3,106,0,180, +3,79,0,180,3, +52,0,180,3,114, +0,180,3,87,0, +180,3,122,0,180, +3,95,0,180,3, +68,0,180,3,103, +0,180,3,76,0, +180,3,49,0,180, +3,111,0,180,3, +84,0,180,3,57, +0,180,3,119,0, +180,3,65,0,180, +3,100,0,180,3, +73,0,180,3,108, +0,180,3,81,0, +180,3,54,0,180, +3,116,0,180,3, +89,0,180,997,11, +1,867,0,183,1, +-1,3,76,0,180, +3,49,0,180,3, +111,0,180,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,180,3,73, +0,180,3,108,0, +180,3,81,0,180, +3,54,0,180,3, +116,0,180,3,89, +0,180,998,11,1, +867,0,183,1,-1, +3,87,0,180,3, +122,0,180,3,95, +0,180,3,68,0, +180,3,103,0,180, +3,76,0,180,3, +49,0,180,3,111, +0,180,3,84,0, +180,3,57,0,180, +3,119,0,180,3, +65,0,180,3,100, +0,180,3,73,0, +180,3,108,0,180, +3,81,0,180,3, +54,0,180,3,116, +0,180,3,89,0, +180,999,11,1,867, +0,183,1,-1,3, +70,0,180,3,105, +0,180,3,78,0, +180,3,51,0,180, +3,113,0,180,3, +86,0,180,3,121, +0,180,3,67,0, +180,3,102,0,180, +3,75,0,180,3, +48,0,180,3,110, +0,180,3,83,0, +180,3,56,0,180, +3,118,0,180,3, +99,0,180,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,180,3,88, +0,180,3,69,0, +180,3,104,0,180, +3,77,0,180,3, +50,0,180,3,112, +0,180,3,85,0, +180,3,120,0,180, +3,66,0,180,3, +101,0,180,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +180,3,87,0,180, +3,122,0,180,3, +95,0,180,3,68, +0,180,3,103,0, +180,3,76,0,180, +3,49,0,180,3, +111,0,180,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,180,3,73, +0,180,3,108,0, +180,3,81,0,180, +3,54,0,180,3, +116,0,180,3,89, +0,180,1000,11,1, +867,0,183,1,-1, +3,89,0,180,1001, +11,1,867,0,183, +1,-1,3,68,0, +180,3,103,0,180, +3,76,0,180,3, +49,0,180,3,111, +0,180,3,84,0, +180,3,57,0,180, +3,119,0,180,3, +65,0,180,3,100, +0,180,3,73,0, +180,3,108,0,180, +3,81,0,180,3, +54,0,180,3,116, +0,1002,12,1,11670, +1003,5,63,3,97, +0,1004,12,1,11737, +1005,5,63,3,97, +0,180,3,70,0, +180,3,105,0,180, +3,78,0,180,3, +51,0,180,3,113, +0,180,3,86,0, +180,3,121,0,180, +3,67,0,180,3, +102,0,180,3,75, +0,180,3,48,0, +180,3,110,0,180, +3,83,0,180,3, +56,0,180,3,118, +0,180,3,99,0, +1006,12,1,11811,1007, +5,63,3,97,0, +180,3,70,0,180, +3,105,0,180,3, +78,0,180,3,51, +0,180,3,113,0, +180,3,86,0,180, +3,121,0,180,3, +67,0,180,3,102, +0,180,3,75,0, +180,3,48,0,180, +3,110,0,180,3, +83,0,180,3,56, +0,180,3,118,0, +180,3,99,0,180, +3,72,0,180,3, +107,0,180,3,80, +0,180,3,53,0, +180,3,115,0,180, +3,88,0,180,3, +69,0,180,3,104, +0,1008,12,1,11888, +1009,5,63,3,97, +0,180,3,70,0, +180,3,105,0,180, +3,78,0,180,3, +51,0,180,3,113, +0,180,3,86,0, +180,3,121,0,180, +3,67,0,180,3, +102,0,180,3,75, +0,180,3,48,0, +180,3,110,0,180, +3,83,0,180,3, +56,0,180,3,118, +0,180,3,99,0, +180,3,72,0,180, +3,107,0,180,3, +80,0,180,3,53, +0,180,3,115,0, +180,3,88,0,180, +3,69,0,180,3, +104,0,180,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,180,3,66, +0,180,3,101,0, +180,3,74,0,180, +3,109,0,180,3, +82,0,180,3,55, +0,180,3,117,0, +180,3,90,0,180, +3,98,0,180,3, +71,0,180,3,106, +0,180,3,79,0, +180,3,52,0,180, +3,114,0,180,3, +87,0,180,3,122, +0,180,3,95,0, +180,3,68,0,180, +3,103,0,180,3, +76,0,180,3,49, +0,180,3,111,0, +180,3,84,0,180, +3,57,0,180,3, +119,0,180,3,65, +0,180,3,100,0, +180,3,73,0,180, +3,108,0,180,3, +81,0,180,3,54, +0,180,3,116,0, +180,3,89,0,180, +1010,11,1,380,0, +1011,4,24,65,0, +84,0,84,0,65, +0,67,0,72,0, +95,0,69,0,86, +0,69,0,78,0, +84,0,1,-1,3, +77,0,180,3,50, +0,180,3,112,0, +180,3,85,0,180, +3,120,0,180,3, +66,0,180,3,101, +0,180,3,74,0, +180,3,109,0,180, +3,82,0,180,3, +55,0,180,3,117, +0,180,3,90,0, +180,3,98,0,180, +3,71,0,180,3, +106,0,180,3,79, +0,180,3,52,0, +180,3,114,0,180, +3,87,0,180,3, +122,0,180,3,95, +0,180,3,68,0, +180,3,103,0,180, +3,76,0,180,3, +49,0,180,3,111, +0,180,3,84,0, +180,3,57,0,180, +3,119,0,180,3, +65,0,180,3,100, +0,180,3,73,0, +180,3,108,0,180, +3,81,0,180,3, +54,0,180,3,116, +0,180,3,89,0, +180,1012,11,1,867, +0,183,1,-1,3, +72,0,180,3,107, +0,180,3,80,0, +180,3,53,0,180, +3,115,0,180,3, +88,0,180,3,69, +0,180,3,104,0, +180,3,77,0,180, +3,50,0,180,3, +112,0,180,3,85, +0,180,3,120,0, +180,3,66,0,180, +3,101,0,180,3, +74,0,180,3,109, +0,180,3,82,0, +180,3,55,0,180, +3,117,0,180,3, +90,0,180,3,98, +0,180,3,71,0, +180,3,106,0,180, +3,79,0,180,3, +52,0,180,3,114, +0,180,3,87,0, +180,3,122,0,180, +3,95,0,180,3, +68,0,180,3,103, +0,180,3,76,0, +180,3,49,0,180, +3,111,0,180,3, +84,0,180,3,57, +0,180,3,119,0, +180,3,65,0,180, +3,100,0,180,3, +73,0,180,3,108, +0,180,3,81,0, +180,3,54,0,180, +3,116,0,180,3, +89,0,180,1013,11, +1,867,0,183,1, +-1,3,70,0,180, +3,105,0,180,3, +78,0,180,3,51, +0,180,3,113,0, +180,3,86,0,180, +3,121,0,180,3, +67,0,180,3,102, +0,180,3,75,0, +180,3,48,0,180, +3,110,0,180,3, +83,0,180,3,56, +0,180,3,118,0, +180,3,99,0,180, +3,72,0,180,3, +107,0,180,3,80, +0,180,3,53,0, +180,3,115,0,180, +3,88,0,180,3, +69,0,180,3,104, +0,180,3,77,0, +180,3,50,0,180, +3,112,0,180,3, +85,0,180,3,120, +0,180,3,66,0, +180,3,101,0,180, +3,74,0,180,3, +109,0,180,3,82, +0,180,3,55,0, +180,3,117,0,180, +3,90,0,180,3, +98,0,180,3,71, +0,180,3,106,0, +180,3,79,0,180, +3,52,0,180,3, +114,0,180,3,87, +0,180,3,122,0, +180,3,95,0,180, +3,68,0,180,3, +103,0,180,3,76, +0,180,3,49,0, +180,3,111,0,180, +3,84,0,180,3, +57,0,180,3,119, +0,180,3,65,0, +180,3,100,0,180, +3,73,0,180,3, +108,0,180,3,81, +0,180,3,54,0, +180,3,116,0,180, +3,89,0,180,1014, +11,1,867,0,183, +1,-1,3,89,0, +180,1015,11,1,867, +0,183,1,-1,3, +89,0,180,1016,11, +1,867,0,183,1, +-1,3,57,0,647, +3,94,0,1017,12, +1,2778,1018,5,0, +1019,11,1,170,0, +1020,4,10,67,0, +65,0,82,0,69, +0,84,0,1,-1, +3,54,0,647,3, +91,0,1021,12,1, +7969,1022,5,0,1023, +11,1,126,0,1024, +4,24,76,0,69, +0,70,0,84,0, +95,0,66,0,82, +0,65,0,67,0, +75,0,69,0,84, +0,1,-1,3,51, +0,647,3,88,0, +178,3,48,0,1025, +12,1,9070,1026,5, +13,3,48,0,647, +3,88,0,1027,12, +1,9149,1028,5,22, +3,48,0,1029,12, +1,9199,1030,5,22, +3,48,0,1029,3, +70,0,1029,3,55, +0,1029,3,66,0, +1029,3,51,0,1029, +3,99,0,1029,3, +65,0,1029,3,69, +0,1029,3,54,0, +1029,3,102,0,1029, +3,50,0,1029,3, +98,0,1029,3,57, +0,1029,3,68,0, +1029,3,53,0,1029, +3,101,0,1029,3, +49,0,1029,3,97, +0,1029,3,56,0, +1029,3,67,0,1029, +3,52,0,1029,3, +100,0,1029,1031,11, +1,885,0,1032,4, +40,72,0,69,0, +88,0,95,0,73, +0,78,0,84,0, +69,0,71,0,69, +0,82,0,95,0, +67,0,79,0,78, +0,83,0,84,0, +65,0,78,0,84, +0,1,-1,3,70, +0,1029,3,55,0, +1029,3,66,0,1029, +3,51,0,1029,3, +99,0,1029,3,65, +0,1029,3,69,0, +1029,3,54,0,1029, +3,102,0,1029,3, +50,0,1029,3,98, +0,1029,3,57,0, +1029,3,68,0,1029, +3,53,0,1029,3, +101,0,1029,3,49, +0,1029,3,97,0, +1029,3,56,0,1029, +3,67,0,1029,3, +52,0,1029,3,100, +0,1029,0,165,1, +-1,3,55,0,647, +3,51,0,647,3, +54,0,647,3,50, +0,647,3,120,0, +1027,3,57,0,647, +3,46,0,649,3, +53,0,647,3,49, +0,647,3,56,0, +647,3,52,0,647, +1033,11,1,879,0, +667,1,-1,3,125, +0,1034,12,1,7483, +1035,5,0,1036,11, +1,56,0,1037,4, +22,82,0,73,0, +71,0,72,0,84, +0,95,0,66,0, +82,0,65,0,67, +0,69,0,1,-1, +3,85,0,178,3, +45,0,1038,12,1, +8090,1039,5,2,3, +61,0,1040,12,1, +8098,1041,5,0,1042, +11,1,22,0,1043, +4,24,77,0,73, +0,78,0,85,0, +83,0,95,0,69, +0,81,0,85,0, +65,0,76,0,83, +0,1,-1,3,45, +0,1044,12,1,8243, +1045,5,0,1046,11, +1,10,0,1047,4, +18,68,0,69,0, +67,0,82,0,69, +0,77,0,69,0, +78,0,84,0,1, +-1,1048,11,1,86, +0,1049,4,10,77, +0,73,0,78,0, +85,0,83,0,1, +-1,3,122,0,178, +3,82,0,178,3, +42,0,1050,12,1, +6395,1051,5,1,3, +61,0,1052,12,1, +6403,1053,5,0,1054, +11,1,28,0,1055, +4,22,83,0,84, +0,65,0,82,0, +95,0,69,0,81, +0,85,0,65,0, +76,0,83,0,1, +-1,1056,11,1,91, +0,1057,4,8,83, +0,84,0,65,0, +82,0,1,-1,3, +119,0,1058,12,1, +37426,1059,5,63,3, +97,0,180,3,70, +0,180,3,105,0, +180,3,78,0,180, +3,51,0,180,3, +113,0,180,3,86, +0,180,3,121,0, +180,3,67,0,180, +3,102,0,180,3, +75,0,180,3,48, +0,180,3,110,0, +180,3,83,0,180, +3,56,0,180,3, +118,0,180,3,99, +0,180,3,72,0, +180,3,107,0,180, +3,80,0,180,3, +53,0,180,3,115, +0,180,3,88,0, +180,3,69,0,180, +3,104,0,1060,12, +1,37503,1061,5,63, +3,97,0,180,3, +70,0,180,3,105, +0,1062,12,1,37571, +1063,5,63,3,97, +0,180,3,70,0, +180,3,105,0,180, +3,78,0,180,3, +51,0,180,3,113, +0,180,3,86,0, +180,3,121,0,180, +3,67,0,180,3, +102,0,180,3,75, +0,180,3,48,0, +180,3,110,0,180, +3,83,0,180,3, +56,0,180,3,118, +0,180,3,99,0, +180,3,72,0,180, +3,107,0,180,3, +80,0,180,3,53, +0,180,3,115,0, +180,3,88,0,180, +3,69,0,180,3, +104,0,180,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,180,3,66, +0,180,3,101,0, +180,3,74,0,180, +3,109,0,180,3, +82,0,180,3,55, +0,180,3,117,0, +180,3,90,0,180, +3,98,0,180,3, +71,0,180,3,106, +0,180,3,79,0, +180,3,52,0,180, +3,114,0,180,3, +87,0,180,3,122, +0,180,3,95,0, +180,3,68,0,180, +3,103,0,180,3, +76,0,180,3,49, +0,180,3,111,0, +180,3,84,0,180, +3,57,0,180,3, +119,0,180,3,65, +0,180,3,100,0, +180,3,73,0,180, +3,108,0,1064,12, +1,37662,1065,5,63, +3,97,0,180,3, +70,0,180,3,105, +0,180,3,78,0, +180,3,51,0,180, +3,113,0,180,3, +86,0,180,3,121, +0,180,3,67,0, +180,3,102,0,180, +3,75,0,180,3, +48,0,180,3,110, +0,180,3,83,0, +180,3,56,0,180, +3,118,0,180,3, +99,0,180,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,180,3,88, +0,180,3,69,0, +180,3,104,0,180, +3,77,0,180,3, +50,0,180,3,112, +0,180,3,85,0, +180,3,120,0,180, +3,66,0,180,3, +101,0,1066,12,1, +37742,1067,5,63,3, +97,0,180,3,70, +0,180,3,105,0, +180,3,78,0,180, +3,51,0,180,3, +113,0,180,3,86, +0,180,3,121,0, +180,3,67,0,180, +3,102,0,180,3, +75,0,180,3,48, +0,180,3,110,0, +180,3,83,0,180, +3,56,0,180,3, +118,0,180,3,99, +0,180,3,72,0, +180,3,107,0,180, +3,80,0,180,3, +53,0,180,3,115, +0,180,3,88,0, +180,3,69,0,180, +3,104,0,180,3, +77,0,180,3,50, +0,180,3,112,0, +180,3,85,0,180, +3,120,0,180,3, +66,0,180,3,101, +0,180,3,74,0, +180,3,109,0,180, +3,82,0,180,3, +55,0,180,3,117, +0,180,3,90,0, +180,3,98,0,180, +3,71,0,180,3, +106,0,180,3,79, +0,180,3,52,0, +180,3,114,0,180, +3,87,0,180,3, +122,0,180,3,95, +0,180,3,68,0, +180,3,103,0,180, +3,76,0,180,3, +49,0,180,3,111, +0,180,3,84,0, +180,3,57,0,180, +3,119,0,180,3, +65,0,180,3,100, +0,180,3,73,0, +180,3,108,0,180, +3,81,0,180,3, +54,0,180,3,116, +0,180,3,89,0, +180,1068,11,1,229, +0,1069,4,10,87, +0,72,0,73,0, +76,0,69,0,1, +-1,3,74,0,180, +3,109,0,180,3, +82,0,180,3,55, +0,180,3,117,0, +180,3,90,0,180, +3,98,0,180,3, +71,0,180,3,106, +0,180,3,79,0, +180,3,52,0,180, +3,114,0,180,3, +87,0,180,3,122, +0,180,3,95,0, +180,3,68,0,180, +3,103,0,180,3, +76,0,180,3,49, +0,180,3,111,0, +180,3,84,0,180, +3,57,0,180,3, +119,0,180,3,65, +0,180,3,100,0, +180,3,73,0,180, +3,108,0,180,3, +81,0,180,3,54, +0,180,3,116,0, +180,3,89,0,180, +1070,11,1,867,0, +183,1,-1,3,81, +0,180,3,54,0, +180,3,116,0,180, +3,89,0,180,1071, +11,1,867,0,183, +1,-1,3,78,0, +180,3,51,0,180, +3,113,0,180,3, +86,0,180,3,121, +0,180,3,67,0, +180,3,102,0,180, +3,75,0,180,3, +48,0,180,3,110, +0,180,3,83,0, +180,3,56,0,180, +3,118,0,180,3, +99,0,180,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,180,3,88, +0,180,3,69,0, +180,3,104,0,180, +3,77,0,180,3, +50,0,180,3,112, +0,180,3,85,0, +180,3,120,0,180, +3,66,0,180,3, +101,0,180,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +180,3,87,0,180, +3,122,0,180,3, +95,0,180,3,68, +0,180,3,103,0, +180,3,76,0,180, +3,49,0,180,3, +111,0,180,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,180,3,73, +0,180,3,108,0, +180,3,81,0,180, +3,54,0,180,3, +116,0,180,3,89, +0,180,1072,11,1, +867,0,183,1,-1, +3,77,0,180,3, +50,0,180,3,112, +0,180,3,85,0, +180,3,120,0,180, +3,66,0,180,3, +101,0,180,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +180,3,87,0,180, +3,122,0,180,3, +95,0,180,3,68, +0,180,3,103,0, +180,3,76,0,180, +3,49,0,180,3, +111,0,180,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,180,3,73, +0,180,3,108,0, +180,3,81,0,180, +3,54,0,180,3, +116,0,180,3,89, +0,180,1073,11,1, +867,0,183,1,-1, +3,79,0,178,3, +116,0,1074,12,1, +44630,1075,5,63,3, +97,0,180,3,70, +0,180,3,105,0, +1076,12,1,44698,1077, +5,63,3,97,0, +180,3,70,0,180, +3,105,0,180,3, +78,0,180,3,51, +0,180,3,113,0, +180,3,86,0,180, +3,121,0,180,3, +67,0,180,3,102, +0,180,3,75,0, +180,3,48,0,180, +3,110,0,180,3, +83,0,180,3,56, +0,180,3,118,0, +180,3,99,0,180, +3,72,0,180,3, +107,0,180,3,80, +0,180,3,53,0, +180,3,115,0,180, +3,88,0,180,3, +69,0,180,3,104, +0,180,3,77,0, +180,3,50,0,180, +3,112,0,180,3, +85,0,180,3,120, +0,180,3,66,0, +180,3,101,0,180, +3,74,0,180,3, +109,0,1078,12,1, +44779,1079,5,63,3, +97,0,180,3,70, +0,180,3,105,0, +180,3,78,0,180, +3,51,0,180,3, +113,0,180,3,86, +0,180,3,121,0, +180,3,67,0,180, +3,102,0,180,3, +75,0,180,3,48, +0,180,3,110,0, +180,3,83,0,180, +3,56,0,180,3, +118,0,180,3,99, +0,180,3,72,0, +180,3,107,0,180, +3,80,0,180,3, +53,0,180,3,115, +0,180,3,88,0, +180,3,69,0,180, +3,104,0,180,3, +77,0,180,3,50, +0,180,3,112,0, +180,3,85,0,180, +3,120,0,180,3, +66,0,180,3,101, +0,1080,12,1,44859, +1081,5,63,3,97, +0,180,3,70,0, +180,3,105,0,180, +3,78,0,180,3, +51,0,180,3,113, +0,180,3,86,0, +180,3,121,0,180, +3,67,0,180,3, +102,0,180,3,75, +0,180,3,48,0, +180,3,110,0,180, +3,83,0,180,3, +56,0,180,3,118, +0,180,3,99,0, +180,3,72,0,180, +3,107,0,180,3, +80,0,180,3,53, +0,180,3,115,0, +180,3,88,0,180, +3,69,0,180,3, +104,0,180,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,180,3,66, +0,180,3,101,0, +180,3,74,0,180, +3,109,0,180,3, +82,0,180,3,55, +0,180,3,117,0, +180,3,90,0,180, +3,98,0,180,3, +71,0,180,3,106, +0,180,3,79,0, +180,3,52,0,180, +3,114,0,1082,12, +1,44944,1083,5,63, +3,97,0,180,3, +70,0,180,3,105, +0,180,3,78,0, +180,3,51,0,180, +3,113,0,180,3, +86,0,180,3,121, +0,180,3,67,0, +180,3,102,0,180, +3,75,0,180,3, +48,0,180,3,110, +0,180,3,83,0, +180,3,56,0,180, +3,118,0,180,3, +99,0,180,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,180,3,88, +0,180,3,69,0, +180,3,104,0,180, +3,77,0,180,3, +50,0,180,3,112, +0,180,3,85,0, +180,3,120,0,180, +3,66,0,180,3, +101,0,180,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +180,3,87,0,180, +3,122,0,180,3, +95,0,180,3,68, +0,180,3,103,0, +180,3,76,0,180, +3,49,0,180,3, +111,0,180,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,180,3,73, +0,180,3,108,0, +180,3,81,0,180, +3,54,0,180,3, +116,0,180,3,89, +0,180,1084,11,1, +783,0,1085,4,22, +84,0,73,0,77, +0,69,0,82,0, +95,0,69,0,86, +0,69,0,78,0, +84,0,1,-1,3, +87,0,180,3,122, +0,180,3,95,0, +180,3,68,0,180, +3,103,0,180,3, +76,0,180,3,49, +0,180,3,111,0, +180,3,84,0,180, +3,57,0,180,3, +119,0,180,3,65, +0,180,3,100,0, +180,3,73,0,180, +3,108,0,180,3, +81,0,180,3,54, +0,180,3,116,0, +180,3,89,0,180, +1086,11,1,867,0, +183,1,-1,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +180,3,87,0,180, +3,122,0,180,3, +95,0,180,3,68, +0,180,3,103,0, +180,3,76,0,180, +3,49,0,180,3, +111,0,180,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,180,3,73, +0,180,3,108,0, +180,3,81,0,180, +3,54,0,180,3, +116,0,180,3,89, +0,180,1087,11,1, +867,0,183,1,-1, +3,82,0,180,3, +55,0,180,3,117, +0,180,3,90,0, +180,3,98,0,180, +3,71,0,180,3, +106,0,180,3,79, +0,180,3,52,0, +180,3,114,0,180, +3,87,0,180,3, +122,0,180,3,95, +0,180,3,68,0, +180,3,103,0,180, +3,76,0,180,3, +49,0,180,3,111, +0,180,3,84,0, +180,3,57,0,180, +3,119,0,180,3, +65,0,180,3,100, +0,180,3,73,0, +180,3,108,0,180, +3,81,0,180,3, +54,0,180,3,116, +0,180,3,89,0, +180,1088,11,1,867, +0,183,1,-1,3, +78,0,180,3,51, +0,180,3,113,0, +180,3,86,0,180, +3,121,0,180,3, +67,0,180,3,102, +0,180,3,75,0, +180,3,48,0,180, +3,110,0,180,3, +83,0,180,3,56, +0,180,3,118,0, +180,3,99,0,180, +3,72,0,180,3, +107,0,180,3,80, +0,180,3,53,0, +180,3,115,0,180, +3,88,0,180,3, +69,0,180,3,104, +0,180,3,77,0, +180,3,50,0,180, +3,112,0,180,3, +85,0,180,3,120, +0,180,3,66,0, +180,3,101,0,180, +3,74,0,180,3, +109,0,180,3,82, +0,180,3,55,0, +180,3,117,0,180, +3,90,0,180,3, +98,0,180,3,71, +0,180,3,106,0, +180,3,79,0,180, +3,52,0,180,3, +114,0,1089,12,1, +45195,1090,5,63,3, +97,0,1091,12,1, +45262,1092,5,63,3, +97,0,180,3,70, +0,180,3,105,0, +180,3,78,0,180, +3,51,0,180,3, +113,0,180,3,86, +0,180,3,121,0, +180,3,67,0,180, +3,102,0,180,3, +75,0,180,3,48, +0,180,3,110,0, +1093,12,1,45334,1094, +5,63,3,97,0, +180,3,70,0,180, +3,105,0,180,3, +78,0,180,3,51, +0,180,3,113,0, +180,3,86,0,180, +3,121,0,180,3, +67,0,180,3,102, +0,180,3,75,0, +180,3,48,0,180, +3,110,0,180,3, +83,0,180,3,56, +0,180,3,118,0, +180,3,99,0,180, +3,72,0,180,3, +107,0,180,3,80, +0,180,3,53,0, +180,3,115,0,1095, +12,1,45410,1096,5, +63,3,97,0,1097, +12,1,45477,1098,5, +63,3,97,0,180, +3,70,0,180,3, +105,0,180,3,78, +0,180,3,51,0, +180,3,113,0,180, +3,86,0,180,3, +121,0,180,3,67, +0,180,3,102,0, +180,3,75,0,180, +3,48,0,180,3, +110,0,180,3,83, +0,180,3,56,0, +180,3,118,0,180, +3,99,0,1099,12, +1,45551,1100,5,63, +3,97,0,180,3, +70,0,180,3,105, +0,180,3,78,0, +180,3,51,0,180, +3,113,0,180,3, +86,0,180,3,121, +0,180,3,67,0, +180,3,102,0,180, +3,75,0,180,3, +48,0,180,3,110, +0,180,3,83,0, +180,3,56,0,180, +3,118,0,180,3, +99,0,180,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,180,3,88, +0,180,3,69,0, +180,3,104,0,180, +3,77,0,180,3, +50,0,180,3,112, +0,180,3,85,0, +180,3,120,0,180, +3,66,0,180,3, +101,0,180,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +180,3,87,0,180, +3,122,0,180,3, +95,0,180,3,68, +0,180,3,103,0, +180,3,76,0,180, +3,49,0,180,3, +111,0,180,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,180,3,73, +0,180,3,108,0, +180,3,81,0,180, +3,54,0,180,3, +116,0,1101,12,1, +45644,1102,5,63,3, +97,0,180,3,70, +0,180,3,105,0, +1103,12,1,45712,1104, +5,63,3,97,0, +180,3,70,0,180, +3,105,0,180,3, +78,0,180,3,51, +0,180,3,113,0, +180,3,86,0,180, +3,121,0,180,3, +67,0,180,3,102, +0,180,3,75,0, +180,3,48,0,180, +3,110,0,180,3, +83,0,180,3,56, +0,180,3,118,0, +180,3,99,0,180, +3,72,0,180,3, +107,0,180,3,80, +0,180,3,53,0, +180,3,115,0,180, +3,88,0,180,3, +69,0,180,3,104, +0,180,3,77,0, +180,3,50,0,180, +3,112,0,180,3, +85,0,180,3,120, +0,180,3,66,0, +180,3,101,0,180, +3,74,0,180,3, +109,0,180,3,82, +0,180,3,55,0, +180,3,117,0,180, +3,90,0,180,3, +98,0,180,3,71, +0,180,3,106,0, +180,3,79,0,180, +3,52,0,180,3, +114,0,180,3,87, +0,180,3,122,0, +180,3,95,0,180, +3,68,0,180,3, +103,0,180,3,76, +0,180,3,49,0, +180,3,111,0,1105, +12,1,45800,1106,5, +63,3,97,0,180, +3,70,0,180,3, +105,0,180,3,78, +0,180,3,51,0, +180,3,113,0,180, +3,86,0,180,3, +121,0,180,3,67, +0,180,3,102,0, +180,3,75,0,180, +3,48,0,180,3, +110,0,1107,12,1, +45872,1108,5,63,3, +97,0,180,3,70, +0,180,3,105,0, +180,3,78,0,180, +3,51,0,180,3, +113,0,180,3,86, +0,180,3,121,0, +180,3,67,0,180, +3,102,0,180,3, +75,0,180,3,48, +0,180,3,110,0, +180,3,83,0,180, +3,56,0,180,3, +118,0,180,3,99, +0,180,3,72,0, +180,3,107,0,180, +3,80,0,180,3, +53,0,180,3,115, +0,180,3,88,0, +180,3,69,0,180, +3,104,0,180,3, +77,0,180,3,50, +0,180,3,112,0, +180,3,85,0,180, +3,120,0,180,3, +66,0,180,3,101, +0,180,3,74,0, +180,3,109,0,180, +3,82,0,180,3, +55,0,180,3,117, +0,180,3,90,0, +180,3,98,0,180, +3,71,0,180,3, +106,0,180,3,79, +0,180,3,52,0, +180,3,114,0,180, +3,87,0,180,3, +122,0,180,3,95, +0,1109,12,1,45908, +1110,5,63,3,97, +0,180,3,70,0, +180,3,105,0,180, +3,78,0,180,3, +51,0,180,3,113, +0,180,3,86,0, +180,3,121,0,180, +3,67,0,180,3, +102,0,180,3,75, +0,180,3,48,0, +180,3,110,0,180, +3,83,0,180,3, +56,0,180,3,118, +0,180,3,99,0, +180,3,72,0,180, +3,107,0,180,3, +80,0,180,3,53, +0,180,3,115,0, +180,3,88,0,180, +3,69,0,180,3, +104,0,180,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,180,3,66, +0,180,3,101,0, +180,3,74,0,180, +3,109,0,180,3, +82,0,180,3,55, +0,180,3,117,0, +180,3,90,0,180, +3,98,0,180,3, +71,0,180,3,106, +0,180,3,79,0, +180,3,52,0,180, +3,114,0,1111,12, +1,45993,1112,5,63, +3,97,0,180,3, +70,0,180,3,105, +0,180,3,78,0, +180,3,51,0,180, +3,113,0,180,3, +86,0,180,3,121, +0,180,3,67,0, +180,3,102,0,180, +3,75,0,180,3, +48,0,180,3,110, +0,180,3,83,0, +180,3,56,0,180, +3,118,0,180,3, +99,0,180,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,180,3,88, +0,180,3,69,0, +180,3,104,0,180, +3,77,0,180,3, +50,0,180,3,112, +0,180,3,85,0, +180,3,120,0,180, +3,66,0,180,3, +101,0,1113,12,1, +46073,1114,5,63,3, +97,0,180,3,70, +0,180,3,105,0, +180,3,78,0,180, +3,51,0,180,3, +113,0,180,3,86, +0,180,3,121,0, +180,3,67,0,180, +3,102,0,180,3, +75,0,180,3,48, +0,180,3,110,0, +180,3,83,0,180, +3,56,0,180,3, +118,0,180,3,99, +0,180,3,72,0, +180,3,107,0,180, +3,80,0,180,3, +53,0,180,3,115, +0,1115,12,1,46149, +1116,5,63,3,97, +0,180,3,70,0, +180,3,105,0,180, +3,78,0,180,3, +51,0,180,3,113, +0,180,3,86,0, +180,3,121,0,180, +3,67,0,180,3, +102,0,180,3,75, +0,180,3,48,0, +180,3,110,0,180, +3,83,0,180,3, +56,0,180,3,118, +0,180,3,99,0, +180,3,72,0,180, +3,107,0,180,3, +80,0,180,3,53, +0,180,3,115,0, +180,3,88,0,180, +3,69,0,180,3, +104,0,180,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,180,3,66, +0,180,3,101,0, +180,3,74,0,180, +3,109,0,180,3, +82,0,180,3,55, +0,180,3,117,0, +1117,12,1,46231,1118, +5,63,3,97,0, +180,3,70,0,180, +3,105,0,180,3, +78,0,180,3,51, +0,180,3,113,0, +180,3,86,0,180, +3,121,0,180,3, +67,0,180,3,102, +0,180,3,75,0, +180,3,48,0,180, +3,110,0,180,3, +83,0,180,3,56, +0,180,3,118,0, +180,3,99,0,180, +3,72,0,180,3, +107,0,180,3,80, +0,180,3,53,0, +180,3,115,0,180, +3,88,0,180,3, +69,0,180,3,104, +0,180,3,77,0, +180,3,50,0,180, +3,112,0,180,3, +85,0,180,3,120, +0,180,3,66,0, +180,3,101,0,180, +3,74,0,180,3, +109,0,180,3,82, +0,180,3,55,0, +180,3,117,0,180, +3,90,0,180,3, +98,0,180,3,71, +0,180,3,106,0, +180,3,79,0,180, +3,52,0,180,3, +114,0,180,3,87, +0,180,3,122,0, +180,3,95,0,180, +3,68,0,180,3, +103,0,180,3,76, +0,180,3,49,0, +180,3,111,0,180, +3,84,0,180,3, +57,0,180,3,119, +0,180,3,65,0, +180,3,100,0,180, +3,73,0,180,3, +108,0,1119,12,1, +46322,1120,5,63,3, +97,0,180,3,70, +0,180,3,105,0, +180,3,78,0,180, +3,51,0,180,3, +113,0,180,3,86, +0,180,3,121,0, +180,3,67,0,180, +3,102,0,180,3, +75,0,180,3,48, +0,180,3,110,0, +180,3,83,0,180, +3,56,0,180,3, +118,0,180,3,99, +0,180,3,72,0, +180,3,107,0,180, +3,80,0,180,3, +53,0,180,3,115, +0,180,3,88,0, +180,3,69,0,180, +3,104,0,180,3, +77,0,180,3,50, +0,180,3,112,0, +180,3,85,0,180, +3,120,0,180,3, +66,0,180,3,101, +0,180,3,74,0, +180,3,109,0,180, +3,82,0,180,3, +55,0,180,3,117, +0,180,3,90,0, +180,3,98,0,180, +3,71,0,180,3, +106,0,180,3,79, +0,180,3,52,0, +180,3,114,0,180, +3,87,0,180,3, +122,0,180,3,95, +0,180,3,68,0, +180,3,103,0,180, +3,76,0,180,3, +49,0,180,3,111, +0,180,3,84,0, +180,3,57,0,180, +3,119,0,180,3, +65,0,180,3,100, +0,180,3,73,0, +180,3,108,0,180, +3,81,0,180,3, +54,0,180,3,116, +0,1121,12,1,46415, +1122,5,63,3,97, +0,180,3,70,0, +180,3,105,0,180, +3,78,0,180,3, +51,0,180,3,113, +0,180,3,86,0, +180,3,121,0,180, +3,67,0,180,3, +102,0,180,3,75, +0,180,3,48,0, +180,3,110,0,180, +3,83,0,180,3, +56,0,180,3,118, +0,180,3,99,0, +180,3,72,0,180, +3,107,0,180,3, +80,0,180,3,53, +0,180,3,115,0, +180,3,88,0,180, +3,69,0,180,3, +104,0,180,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,180,3,66, +0,180,3,101,0, +180,3,74,0,180, +3,109,0,180,3, +82,0,180,3,55, +0,180,3,117,0, +180,3,90,0,180, +3,98,0,180,3, +71,0,180,3,106, +0,180,3,79,0, +180,3,52,0,180, +3,114,0,180,3, +87,0,180,3,122, +0,180,3,95,0, +180,3,68,0,180, +3,103,0,180,3, +76,0,180,3,49, +0,180,3,111,0, +180,3,84,0,180, +3,57,0,180,3, +119,0,180,3,65, +0,180,3,100,0, +180,3,73,0,180, +3,108,0,180,3, +81,0,180,3,54, +0,180,3,116,0, +180,3,89,0,180, +1123,11,1,845,0, +1124,4,48,84,0, +82,0,65,0,78, +0,83,0,65,0, +67,0,84,0,73, +0,79,0,78,0, +95,0,82,0,69, +0,83,0,85,0, +76,0,84,0,95, +0,69,0,86,0, +69,0,78,0,84, +0,1,-1,3,89, +0,180,1125,11,1, +867,0,183,1,-1, +3,81,0,180,3, +54,0,180,3,116, +0,180,3,89,0, +180,1126,11,1,867, +0,183,1,-1,3, +90,0,180,3,98, +0,180,3,71,0, +180,3,106,0,180, +3,79,0,180,3, +52,0,180,3,114, +0,180,3,87,0, +180,3,122,0,180, +3,95,0,180,3, +68,0,180,3,103, +0,180,3,76,0, +180,3,49,0,180, +3,111,0,180,3, +84,0,180,3,57, +0,180,3,119,0, +180,3,65,0,180, +3,100,0,180,3, +73,0,180,3,108, +0,180,3,81,0, +180,3,54,0,180, +3,116,0,180,3, +89,0,180,1127,11, +1,867,0,183,1, +-1,3,88,0,180, +3,69,0,180,3, +104,0,180,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,180,3,66, +0,180,3,101,0, +180,3,74,0,180, +3,109,0,180,3, +82,0,180,3,55, +0,180,3,117,0, +180,3,90,0,180, +3,98,0,180,3, +71,0,180,3,106, +0,180,3,79,0, +180,3,52,0,180, +3,114,0,180,3, +87,0,180,3,122, +0,180,3,95,0, +180,3,68,0,180, +3,103,0,180,3, +76,0,180,3,49, +0,180,3,111,0, +180,3,84,0,180, +3,57,0,180,3, +119,0,180,3,65, +0,180,3,100,0, +180,3,73,0,180, +3,108,0,180,3, +81,0,180,3,54, +0,180,3,116,0, +180,3,89,0,180, +1128,11,1,867,0, +183,1,-1,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +180,3,87,0,180, +3,122,0,180,3, +95,0,180,3,68, +0,180,3,103,0, +180,3,76,0,180, +3,49,0,180,3, +111,0,180,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,180,3,73, +0,180,3,108,0, +180,3,81,0,180, +3,54,0,180,3, +116,0,180,3,89, +0,180,1129,11,1, +867,0,183,1,-1, +3,87,0,180,3, +122,0,180,3,95, +0,180,3,68,0, +180,3,103,0,180, +3,76,0,180,3, +49,0,180,3,111, +0,180,3,84,0, +180,3,57,0,180, +3,119,0,180,3, +65,0,180,3,100, +0,180,3,73,0, +180,3,108,0,180, +3,81,0,180,3, +54,0,180,3,116, +0,180,3,89,0, +180,1130,11,1,867, +0,183,1,-1,3, +68,0,180,3,103, +0,180,3,76,0, +180,3,49,0,180, +3,111,0,180,3, +84,0,180,3,57, +0,180,3,119,0, +180,3,65,0,180, +3,100,0,180,3, +73,0,180,3,108, +0,180,3,81,0, +180,3,54,0,180, +3,116,0,180,3, +89,0,180,1131,11, +1,867,0,183,1, +-1,3,83,0,180, +3,56,0,180,3, +118,0,180,3,99, +0,180,3,72,0, +180,3,107,0,180, +3,80,0,180,3, +53,0,180,3,115, +0,180,3,88,0, +180,3,69,0,180, +3,104,0,180,3, +77,0,180,3,50, +0,180,3,112,0, +180,3,85,0,180, +3,120,0,180,3, +66,0,180,3,101, +0,180,3,74,0, +180,3,109,0,180, +3,82,0,180,3, +55,0,180,3,117, +0,180,3,90,0, +180,3,98,0,180, +3,71,0,180,3, +106,0,180,3,79, +0,180,3,52,0, +180,3,114,0,180, +3,87,0,180,3, +122,0,180,3,95, +0,180,3,68,0, +180,3,103,0,180, +3,76,0,180,3, +49,0,180,3,111, +0,180,3,84,0, +180,3,57,0,180, +3,119,0,180,3, +65,0,180,3,100, +0,180,3,73,0, +180,3,108,0,180, +3,81,0,180,3, +54,0,180,3,116, +0,180,3,89,0, +180,1132,11,1,867, +0,183,1,-1,3, +84,0,180,3,57, +0,180,3,119,0, +180,3,65,0,180, +3,100,0,180,3, +73,0,180,3,108, +0,180,3,81,0, +180,3,54,0,180, +3,116,0,180,3, +89,0,180,1133,11, +1,867,0,183,1, +-1,3,78,0,180, +3,51,0,180,3, +113,0,180,3,86, +0,180,3,121,0, +180,3,67,0,180, +3,102,0,180,3, +75,0,180,3,48, +0,180,3,110,0, +180,3,83,0,180, +3,56,0,180,3, +118,0,180,3,99, +0,180,3,72,0, +180,3,107,0,180, +3,80,0,180,3, +53,0,180,3,115, +0,180,3,88,0, +180,3,69,0,180, +3,104,0,180,3, +77,0,180,3,50, +0,180,3,112,0, +180,3,85,0,180, +3,120,0,180,3, +66,0,180,3,101, +0,180,3,74,0, +180,3,109,0,180, +3,82,0,180,3, +55,0,180,3,117, +0,180,3,90,0, +180,3,98,0,180, +3,71,0,180,3, +106,0,180,3,79, +0,180,3,52,0, +180,3,114,0,180, +3,87,0,180,3, +122,0,180,3,95, +0,180,3,68,0, +180,3,103,0,180, +3,76,0,180,3, +49,0,180,3,111, +0,180,3,84,0, +180,3,57,0,180, +3,119,0,180,3, +65,0,180,3,100, +0,180,3,73,0, +180,3,108,0,180, +3,81,0,180,3, +54,0,180,3,116, +0,180,3,89,0, +180,1134,11,1,867, +0,183,1,-1,3, +89,0,180,1135,11, +1,867,0,183,1, +-1,3,72,0,180, +3,107,0,180,3, +80,0,180,3,53, +0,180,3,115,0, +180,3,88,0,180, +3,69,0,180,3, +104,0,180,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,180,3,66, +0,180,3,101,0, +180,3,74,0,180, +3,109,0,180,3, +82,0,180,3,55, +0,180,3,117,0, +180,3,90,0,180, +3,98,0,180,3, +71,0,180,3,106, +0,180,3,79,0, +180,3,52,0,180, +3,114,0,180,3, +87,0,180,3,122, +0,180,3,95,0, +180,3,68,0,180, +3,103,0,180,3, +76,0,180,3,49, +0,180,3,111,0, +180,3,84,0,180, +3,57,0,180,3, +119,0,180,3,65, +0,180,3,100,0, +180,3,73,0,180, +3,108,0,180,3, +81,0,180,3,54, +0,180,3,116,0, +180,3,89,0,180, +1136,11,1,867,0, +183,1,-1,3,70, +0,180,3,105,0, +180,3,78,0,180, +3,51,0,180,3, +113,0,180,3,86, +0,180,3,121,0, +180,3,67,0,180, +3,102,0,180,3, +75,0,180,3,48, +0,180,3,110,0, +180,3,83,0,180, +3,56,0,180,3, +118,0,180,3,99, +0,180,3,72,0, +180,3,107,0,180, +3,80,0,180,3, +53,0,180,3,115, +0,180,3,88,0, +180,3,69,0,180, +3,104,0,180,3, +77,0,180,3,50, +0,180,3,112,0, +180,3,85,0,180, +3,120,0,180,3, +66,0,180,3,101, +0,180,3,74,0, +180,3,109,0,180, +3,82,0,180,3, +55,0,180,3,117, +0,180,3,90,0, +180,3,98,0,180, +3,71,0,180,3, +106,0,180,3,79, +0,180,3,52,0, +180,3,114,0,180, +3,87,0,180,3, +122,0,180,3,95, +0,180,3,68,0, +180,3,103,0,180, +3,76,0,180,3, +49,0,180,3,111, +0,180,3,84,0, +180,3,57,0,180, +3,119,0,180,3, +65,0,180,3,100, +0,180,3,73,0, +180,3,108,0,180, +3,81,0,180,3, +54,0,180,3,116, +0,180,3,89,0, +180,1137,11,1,867, +0,183,1,-1,3, +88,0,180,3,69, +0,180,3,104,0, +180,3,77,0,180, +3,50,0,180,3, +112,0,180,3,85, +0,180,3,120,0, +180,3,66,0,180, +3,101,0,180,3, +74,0,180,3,109, +0,180,3,82,0, +180,3,55,0,180, +3,117,0,180,3, +90,0,180,3,98, +0,180,3,71,0, +180,3,106,0,180, +3,79,0,180,3, +52,0,180,3,114, +0,180,3,87,0, +180,3,122,0,180, +3,95,0,180,3, +68,0,180,3,103, +0,180,3,76,0, +180,3,49,0,180, +3,111,0,180,3, +84,0,180,3,57, +0,180,3,119,0, +180,3,65,0,180, +3,100,0,180,3, +73,0,180,3,108, +0,180,3,81,0, +180,3,54,0,180, +3,116,0,180,3, +89,0,180,1138,11, +1,867,0,183,1, +-1,3,83,0,180, +3,56,0,180,3, +118,0,180,3,99, +0,180,3,72,0, +180,3,107,0,180, +3,80,0,180,3, +53,0,180,3,115, +0,180,3,88,0, +180,3,69,0,180, +3,104,0,180,3, +77,0,180,3,50, +0,180,3,112,0, +180,3,85,0,180, +3,120,0,180,3, +66,0,180,3,101, +0,180,3,74,0, +180,3,109,0,180, +3,82,0,180,3, +55,0,180,3,117, +0,180,3,90,0, +180,3,98,0,180, +3,71,0,180,3, +106,0,180,3,79, +0,180,3,52,0, +180,3,114,0,180, +3,87,0,180,3, +122,0,180,3,95, +0,180,3,68,0, +180,3,103,0,180, +3,76,0,180,3, +49,0,180,3,111, +0,180,3,84,0, +180,3,57,0,180, +3,119,0,180,3, +65,0,180,3,100, +0,180,3,73,0, +180,3,108,0,180, +3,81,0,180,3, +54,0,180,3,116, +0,180,3,89,0, +180,1139,11,1,867, +0,183,1,-1,3, +70,0,180,3,105, +0,180,3,78,0, +180,3,51,0,180, +3,113,0,180,3, +86,0,180,3,121, +0,180,3,67,0, +180,3,102,0,180, +3,75,0,180,3, +48,0,180,3,110, +0,180,3,83,0, +180,3,56,0,180, +3,118,0,180,3, +99,0,180,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,180,3,88, +0,180,3,69,0, +180,3,104,0,180, +3,77,0,180,3, +50,0,180,3,112, +0,180,3,85,0, +180,3,120,0,180, +3,66,0,180,3, +101,0,180,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +180,3,87,0,180, +3,122,0,180,3, +95,0,180,3,68, +0,180,3,103,0, +180,3,76,0,180, +3,49,0,180,3, +111,0,180,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,180,3,73, +0,180,3,108,0, +180,3,81,0,180, +3,54,0,180,3, +116,0,180,3,89, +0,180,1140,11,1, +867,0,183,1,-1, +3,87,0,180,3, +122,0,180,3,95, +0,180,3,68,0, +180,3,103,0,180, +3,76,0,180,3, +49,0,180,3,111, +0,1141,12,1,47238, +1142,5,63,3,97, +0,180,3,70,0, +180,3,105,0,180, +3,78,0,180,3, +51,0,180,3,113, +0,180,3,86,0, +180,3,121,0,180, +3,67,0,180,3, +102,0,180,3,75, +0,180,3,48,0, +180,3,110,0,180, +3,83,0,180,3, +56,0,180,3,118, +0,180,3,99,0, +180,3,72,0,180, +3,107,0,180,3, +80,0,180,3,53, +0,180,3,115,0, +180,3,88,0,180, +3,69,0,180,3, +104,0,180,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,180,3,66, +0,180,3,101,0, +180,3,74,0,180, +3,109,0,180,3, +82,0,180,3,55, +0,180,3,117,0, +1143,12,1,47320,1144, +5,63,3,97,0, +180,3,70,0,180, +3,105,0,180,3, +78,0,180,3,51, +0,180,3,113,0, +180,3,86,0,180, +3,121,0,180,3, +67,0,180,3,102, +0,180,3,75,0, +180,3,48,0,180, +3,110,0,180,3, +83,0,180,3,56, +0,180,3,118,0, +180,3,99,0,1145, +12,1,47394,1146,5, +63,3,97,0,180, +3,70,0,180,3, +105,0,180,3,78, +0,180,3,51,0, +180,3,113,0,180, +3,86,0,180,3, +121,0,180,3,67, +0,180,3,102,0, +180,3,75,0,180, +3,48,0,180,3, +110,0,180,3,83, +0,180,3,56,0, +180,3,118,0,180, +3,99,0,180,3, +72,0,180,3,107, +0,180,3,80,0, +180,3,53,0,180, +3,115,0,180,3, +88,0,180,3,69, +0,180,3,104,0, +1147,12,1,47471,1148, +5,63,3,97,0, +180,3,70,0,180, +3,105,0,180,3, +78,0,180,3,51, +0,180,3,113,0, +180,3,86,0,180, +3,121,0,180,3, +67,0,180,3,102, +0,180,3,75,0, +180,3,48,0,180, +3,110,0,180,3, +83,0,180,3,56, +0,180,3,118,0, +180,3,99,0,180, +3,72,0,180,3, +107,0,180,3,80, +0,180,3,53,0, +180,3,115,0,180, +3,88,0,180,3, +69,0,180,3,104, +0,180,3,77,0, +180,3,50,0,180, +3,112,0,180,3, +85,0,180,3,120, +0,180,3,66,0, +180,3,101,0,180, +3,74,0,180,3, +109,0,180,3,82, +0,180,3,55,0, +180,3,117,0,180, +3,90,0,180,3, +98,0,180,3,71, +0,180,3,106,0, +180,3,79,0,180, +3,52,0,180,3, +114,0,180,3,87, +0,180,3,122,0, +180,3,95,0,1149, +12,1,47507,1150,5, +63,3,97,0,180, +3,70,0,180,3, +105,0,180,3,78, +0,180,3,51,0, +180,3,113,0,180, +3,86,0,180,3, +121,0,180,3,67, +0,180,3,102,0, +180,3,75,0,180, +3,48,0,180,3, +110,0,180,3,83, +0,180,3,56,0, +180,3,118,0,180, +3,99,0,180,3, +72,0,180,3,107, +0,180,3,80,0, +180,3,53,0,180, +3,115,0,1151,12, +1,47583,1152,5,63, +3,97,0,180,3, +70,0,180,3,105, +0,180,3,78,0, +180,3,51,0,180, +3,113,0,180,3, +86,0,180,3,121, +0,180,3,67,0, +180,3,102,0,180, +3,75,0,180,3, +48,0,180,3,110, +0,180,3,83,0, +180,3,56,0,180, +3,118,0,180,3, +99,0,180,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,180,3,88, +0,180,3,69,0, +180,3,104,0,180, +3,77,0,180,3, +50,0,180,3,112, +0,180,3,85,0, +180,3,120,0,180, +3,66,0,180,3, +101,0,180,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +180,3,87,0,180, +3,122,0,180,3, +95,0,180,3,68, +0,180,3,103,0, +180,3,76,0,180, +3,49,0,180,3, +111,0,180,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,180,3,73, +0,180,3,108,0, +180,3,81,0,180, +3,54,0,180,3, +116,0,1153,12,1, +47676,1154,5,63,3, +97,0,1155,12,1, +47743,1156,5,63,3, +97,0,180,3,70, +0,180,3,105,0, +180,3,78,0,180, +3,51,0,180,3, +113,0,180,3,86, +0,180,3,121,0, +180,3,67,0,180, +3,102,0,180,3, +75,0,180,3,48, +0,180,3,110,0, +180,3,83,0,180, +3,56,0,180,3, +118,0,180,3,99, +0,180,3,72,0, +180,3,107,0,180, +3,80,0,180,3, +53,0,180,3,115, +0,180,3,88,0, +180,3,69,0,180, +3,104,0,180,3, +77,0,180,3,50, +0,180,3,112,0, +180,3,85,0,180, +3,120,0,180,3, +66,0,180,3,101, +0,180,3,74,0, +180,3,109,0,180, +3,82,0,180,3, +55,0,180,3,117, +0,180,3,90,0, +180,3,98,0,180, +3,71,0,180,3, +106,0,180,3,79, +0,180,3,52,0, +180,3,114,0,1157, +12,1,47828,1158,5, +63,3,97,0,180, +3,70,0,180,3, +105,0,180,3,78, +0,180,3,51,0, +180,3,113,0,180, +3,86,0,180,3, +121,0,180,3,67, +0,180,3,102,0, +180,3,75,0,180, +3,48,0,180,3, +110,0,180,3,83, +0,180,3,56,0, +180,3,118,0,180, +3,99,0,180,3, +72,0,180,3,107, +0,180,3,80,0, +180,3,53,0,180, +3,115,0,180,3, +88,0,180,3,69, +0,180,3,104,0, +180,3,77,0,180, +3,50,0,180,3, +112,0,180,3,85, +0,180,3,120,0, +180,3,66,0,180, +3,101,0,180,3, +74,0,180,3,109, +0,180,3,82,0, +180,3,55,0,180, +3,117,0,180,3, +90,0,180,3,98, +0,180,3,71,0, +180,3,106,0,180, +3,79,0,180,3, +52,0,180,3,114, +0,180,3,87,0, +180,3,122,0,180, +3,95,0,180,3, +68,0,180,3,103, +0,180,3,76,0, +180,3,49,0,180, +3,111,0,180,3, +84,0,180,3,57, +0,180,3,119,0, +180,3,65,0,180, +3,100,0,180,3, +73,0,180,3,108, +0,180,3,81,0, +180,3,54,0,180, +3,116,0,1159,12, +1,47921,1160,5,63, +3,97,0,180,3, +70,0,180,3,105, +0,180,3,78,0, +180,3,51,0,180, +3,113,0,180,3, +86,0,180,3,121, +0,180,3,67,0, +180,3,102,0,180, +3,75,0,180,3, +48,0,180,3,110, +0,180,3,83,0, +180,3,56,0,180, +3,118,0,180,3, +99,0,180,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,180,3,88, +0,180,3,69,0, +180,3,104,0,180, +3,77,0,180,3, +50,0,180,3,112, +0,180,3,85,0, +180,3,120,0,180, +3,66,0,180,3, +101,0,180,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +180,3,87,0,180, +3,122,0,180,3, +95,0,180,3,68, +0,180,3,103,0, +180,3,76,0,180, +3,49,0,180,3, +111,0,180,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,180,3,73, +0,180,3,108,0, +180,3,81,0,180, +3,54,0,180,3, +116,0,180,3,89, +0,180,1161,11,1, +801,0,1162,4,34, +84,0,79,0,85, +0,67,0,72,0, +95,0,83,0,84, +0,65,0,82,0, +84,0,95,0,69, 0,86,0,69,0, 78,0,84,0,1, --1,3,102,0,345, -3,103,0,345,3, -104,0,345,3,105, -0,345,3,106,0, -345,3,107,0,345, -3,108,0,345,829, -11,1,867,0,348, -1,-1,3,104,0, -345,3,105,0,345, -3,106,0,345,3, -107,0,345,3,108, -0,345,830,11,1, -867,0,348,1,-1, -3,98,0,345,3, -99,0,345,3,100, -0,345,3,101,0, -345,3,102,0,345, -3,103,0,345,3, -104,0,345,3,105, -0,345,3,106,0, -345,3,107,0,345, -3,108,0,345,831, -11,1,867,0,348, -1,-1,3,116,0, -345,3,117,0,345, -3,118,0,345,3, -119,0,345,3,120, -0,345,3,121,0, -345,3,122,0,345, -3,48,0,345,3, -49,0,345,3,50, -0,345,3,51,0, -345,3,52,0,345, -3,53,0,345,3, -54,0,345,3,55, -0,345,3,56,0, -345,3,57,0,345, -3,65,0,345,3, -66,0,345,3,67, -0,345,3,68,0, -345,3,69,0,345, -3,70,0,345,3, -71,0,345,3,72, -0,345,3,73,0, -345,3,74,0,345, -3,75,0,345,3, -76,0,345,3,77, -0,345,3,78,0, -345,3,79,0,345, -3,80,0,345,3, -81,0,345,3,82, -0,345,3,83,0, -345,3,84,0,345, -3,85,0,345,3, -86,0,345,3,87, -0,345,3,88,0, -345,3,89,0,345, -3,90,0,345,3, -95,0,345,3,97, -0,345,3,98,0, -345,3,99,0,345, -3,100,0,345,3, -101,0,345,3,102, -0,345,3,103,0, -345,3,104,0,345, -3,105,0,345,3, -106,0,345,3,107, -0,345,3,108,0, -345,832,11,1,867, -0,348,1,-1,3, -116,0,345,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,345,3, -98,0,345,3,99, -0,345,3,100,0, -345,3,101,0,345, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -345,3,106,0,345, -3,107,0,345,3, -108,0,345,833,11, -1,867,0,348,1, --1,3,102,0,345, -3,103,0,345,3, -104,0,345,3,105, -0,345,3,106,0, -345,3,107,0,345, -3,108,0,345,834, -11,1,867,0,348, -1,-1,3,110,0, -345,3,111,0,345, -3,112,0,345,3, -113,0,345,3,114, -0,345,3,115,0, -345,3,116,0,345, -3,117,0,345,3, -118,0,345,3,119, -0,345,3,120,0, -345,3,121,0,345, -3,122,0,345,3, -48,0,345,3,49, -0,345,3,50,0, -345,3,51,0,345, -3,52,0,345,3, -53,0,345,3,54, -0,345,3,55,0, -345,3,56,0,345, -3,57,0,345,3, -65,0,345,3,66, -0,345,3,67,0, -345,3,68,0,345, -3,69,0,345,3, -70,0,345,3,71, -0,345,3,72,0, -345,3,73,0,345, -3,74,0,345,3, -75,0,345,3,76, -0,345,3,77,0, -345,3,78,0,345, -3,79,0,345,3, -80,0,345,3,81, -0,345,3,82,0, -345,3,83,0,345, -3,84,0,345,3, -85,0,345,3,86, -0,345,3,87,0, -345,3,88,0,345, -3,89,0,345,3, -90,0,345,3,95, -0,345,3,97,0, -345,3,98,0,345, -3,99,0,345,3, -100,0,345,3,101, -0,345,3,102,0, -345,3,103,0,345, -3,104,0,345,3, -105,0,345,3,106, -0,345,3,107,0, -345,3,108,0,345, -835,11,1,867,0, -348,1,-1,3,97, -0,345,3,98,0, -345,3,99,0,345, -3,100,0,345,3, -101,0,345,3,102, -0,345,3,103,0, -345,3,104,0,345, -3,105,0,345,3, -106,0,345,3,107, -0,345,3,108,0, -345,836,11,1,867, -0,348,1,-1,3, -108,0,345,837,11, -1,867,0,348,1, --1,3,111,0,345, -3,112,0,345,3, -113,0,345,3,114, -0,345,3,115,0, -838,12,1,40715,839, -5,63,3,109,0, -345,3,110,0,345, -3,111,0,345,3, -112,0,345,3,113, -0,345,3,114,0, -345,3,115,0,345, -3,116,0,840,12, -1,40750,841,5,63, -3,109,0,345,3, -110,0,345,3,111, -0,345,3,112,0, -345,3,113,0,345, -3,114,0,345,3, -115,0,345,3,116, -0,345,3,117,0, -345,3,118,0,345, -3,119,0,345,3, -120,0,345,3,121, -0,345,3,122,0, -345,3,48,0,345, -3,49,0,345,3, -50,0,345,3,51, -0,345,3,52,0, -345,3,53,0,345, -3,54,0,345,3, -55,0,345,3,56, -0,345,3,57,0, -345,3,65,0,345, -3,66,0,345,3, -67,0,345,3,68, -0,345,3,69,0, -345,3,70,0,345, -3,71,0,345,3, -72,0,345,3,73, -0,345,3,74,0, -345,3,75,0,345, -3,76,0,345,3, -77,0,345,3,78, -0,345,3,79,0, -345,3,80,0,345, -3,81,0,345,3, -82,0,345,3,83, -0,345,3,84,0, -345,3,85,0,345, -3,86,0,345,3, -87,0,345,3,88, -0,345,3,89,0, -345,3,90,0,345, -3,95,0,345,3, -97,0,345,3,98, -0,345,3,99,0, -345,3,100,0,345, -3,101,0,842,12, -1,40797,843,5,63, -3,109,0,345,3, -110,0,844,12,1, -40826,845,5,63,3, -109,0,345,3,110, -0,345,3,111,0, -345,3,112,0,345, -3,113,0,345,3, -114,0,345,3,115, -0,345,3,116,0, -345,3,117,0,345, -3,118,0,345,3, -119,0,345,3,120, -0,345,3,121,0, -345,3,122,0,345, -3,48,0,345,3, -49,0,345,3,50, -0,345,3,51,0, -345,3,52,0,345, -3,53,0,345,3, -54,0,345,3,55, -0,345,3,56,0, -345,3,57,0,345, -3,65,0,345,3, -66,0,345,3,67, -0,345,3,68,0, -345,3,69,0,345, -3,70,0,345,3, -71,0,345,3,72, -0,345,3,73,0, -345,3,74,0,345, -3,75,0,345,3, -76,0,345,3,77, -0,345,3,78,0, -345,3,79,0,345, -3,80,0,345,3, -81,0,345,3,82, -0,345,3,83,0, -345,3,84,0,345, -3,85,0,345,3, -86,0,345,3,87, -0,345,3,88,0, -345,3,89,0,345, -3,90,0,345,3, -95,0,345,3,97, -0,345,3,98,0, -345,3,99,0,345, -3,100,0,345,3, -101,0,345,3,102, -0,345,3,103,0, -345,3,104,0,345, -3,105,0,345,3, -106,0,345,3,107, -0,345,3,108,0, -345,846,11,1,581, -0,847,4,24,76, -0,73,0,83,0, -84,0,69,0,78, +-1,3,89,0,180, +1163,11,1,867,0, +183,1,-1,3,87, +0,180,3,122,0, +180,3,95,0,180, +3,68,0,180,3, +103,0,180,3,76, +0,180,3,49,0, +180,3,111,0,180, +3,84,0,180,3, +57,0,180,3,119, +0,180,3,65,0, +180,3,100,0,180, +3,73,0,180,3, +108,0,180,3,81, +0,180,3,54,0, +180,3,116,0,180, +3,89,0,180,1164, +11,1,867,0,183, +1,-1,3,70,0, +180,3,105,0,180, +3,78,0,180,3, +51,0,180,3,113, +0,180,3,86,0, +180,3,121,0,180, +3,67,0,180,3, +102,0,180,3,75, +0,180,3,48,0, +180,3,110,0,180, +3,83,0,180,3, +56,0,180,3,118, +0,180,3,99,0, +180,3,72,0,180, +3,107,0,180,3, +80,0,180,3,53, +0,180,3,115,0, +180,3,88,0,180, +3,69,0,180,3, +104,0,180,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,180,3,66, +0,180,3,101,0, +180,3,74,0,180, +3,109,0,180,3, +82,0,180,3,55, +0,180,3,117,0, +180,3,90,0,180, +3,98,0,180,3, +71,0,180,3,106, +0,180,3,79,0, +180,3,52,0,180, +3,114,0,180,3, +87,0,180,3,122, +0,180,3,95,0, +180,3,68,0,180, +3,103,0,180,3, +76,0,180,3,49, +0,180,3,111,0, +180,3,84,0,180, +3,57,0,180,3, +119,0,180,3,65, +0,180,3,100,0, +180,3,73,0,180, +3,108,0,180,3, +81,0,180,3,54, +0,180,3,116,0, +180,3,89,0,180, +1165,11,1,867,0, +183,1,-1,3,89, +0,180,1166,11,1, +867,0,183,1,-1, +3,88,0,180,3, +69,0,180,3,104, +0,180,3,77,0, +180,3,50,0,180, +3,112,0,180,3, +85,0,180,3,120, +0,180,3,66,0, +180,3,101,0,1167, +12,1,48187,1168,5, +63,3,97,0,180, +3,70,0,180,3, +105,0,180,3,78, +0,180,3,51,0, +180,3,113,0,180, +3,86,0,180,3, +121,0,180,3,67, +0,180,3,102,0, +180,3,75,0,180, +3,48,0,180,3, +110,0,1169,12,1, +48259,1170,5,63,3, +97,0,180,3,70, +0,180,3,105,0, +180,3,78,0,180, +3,51,0,180,3, +113,0,180,3,86, +0,180,3,121,0, +180,3,67,0,180, +3,102,0,180,3, +75,0,180,3,48, +0,180,3,110,0, +180,3,83,0,180, +3,56,0,180,3, +118,0,180,3,99, +0,180,3,72,0, +180,3,107,0,180, +3,80,0,180,3, +53,0,180,3,115, +0,180,3,88,0, +180,3,69,0,180, +3,104,0,180,3, +77,0,180,3,50, +0,180,3,112,0, +180,3,85,0,180, +3,120,0,180,3, +66,0,180,3,101, +0,180,3,74,0, +180,3,109,0,180, +3,82,0,180,3, +55,0,180,3,117, +0,180,3,90,0, +180,3,98,0,180, +3,71,0,180,3, +106,0,180,3,79, +0,180,3,52,0, +180,3,114,0,180, +3,87,0,180,3, +122,0,180,3,95, +0,180,3,68,0, +180,3,103,0,180, +3,76,0,180,3, +49,0,180,3,111, +0,180,3,84,0, +180,3,57,0,180, +3,119,0,180,3, +65,0,180,3,100, +0,1171,12,1,48349, +1172,5,63,3,97, +0,180,3,70,0, +180,3,105,0,180, +3,78,0,180,3, +51,0,180,3,113, +0,180,3,86,0, +180,3,121,0,180, +3,67,0,180,3, +102,0,180,3,75, +0,180,3,48,0, +180,3,110,0,180, +3,83,0,180,3, +56,0,180,3,118, +0,180,3,99,0, +180,3,72,0,180, +3,107,0,180,3, +80,0,180,3,53, +0,180,3,115,0, +180,3,88,0,180, +3,69,0,180,3, +104,0,180,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,180,3,66, +0,180,3,101,0, +180,3,74,0,180, +3,109,0,180,3, +82,0,180,3,55, +0,180,3,117,0, +180,3,90,0,180, +3,98,0,180,3, +71,0,180,3,106, +0,180,3,79,0, +180,3,52,0,180, +3,114,0,180,3, +87,0,180,3,122, +0,180,3,95,0, +180,3,68,0,180, +3,103,0,180,3, +76,0,180,3,49, +0,180,3,111,0, +180,3,84,0,180, +3,57,0,180,3, +119,0,180,3,65, +0,180,3,100,0, +180,3,73,0,180, +3,108,0,180,3, +81,0,180,3,54, +0,180,3,116,0, +180,3,89,0,180, +1173,11,1,816,0, +1174,4,30,84,0, +79,0,85,0,67, +0,72,0,95,0, +69,0,78,0,68, 0,95,0,69,0, 86,0,69,0,78, 0,84,0,1,-1, -3,111,0,345,3, -112,0,345,3,113, -0,345,3,114,0, -345,3,115,0,345, -3,116,0,345,3, -117,0,345,3,118, -0,345,3,119,0, -345,3,120,0,345, -3,121,0,345,3, -122,0,345,3,48, -0,345,3,49,0, -345,3,50,0,345, -3,51,0,345,3, -52,0,345,3,53, -0,345,3,54,0, -345,3,55,0,345, -3,56,0,345,3, -57,0,345,3,65, -0,345,3,66,0, -345,3,67,0,345, -3,68,0,345,3, -69,0,345,3,70, -0,345,3,71,0, -345,3,72,0,345, -3,73,0,345,3, -74,0,345,3,75, -0,345,3,76,0, -345,3,77,0,345, -3,78,0,345,3, -79,0,345,3,80, -0,345,3,81,0, -345,3,82,0,345, -3,83,0,345,3, -84,0,345,3,85, -0,345,3,86,0, -345,3,87,0,345, -3,88,0,345,3, -89,0,345,3,90, -0,345,3,95,0, -345,3,97,0,345, -3,98,0,345,3, -99,0,345,3,100, -0,345,3,101,0, -345,3,102,0,345, -3,103,0,345,3, -104,0,345,3,105, -0,345,3,106,0, -345,3,107,0,345, -3,108,0,345,848, -11,1,867,0,348, -1,-1,3,102,0, -345,3,103,0,345, -3,104,0,345,3, -105,0,345,3,106, -0,345,3,107,0, -345,3,108,0,345, -849,11,1,342,0, -850,4,18,76,0, -73,0,83,0,84, -0,95,0,84,0, -89,0,80,0,69, -0,1,-1,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,345,3, -98,0,345,3,99, -0,345,3,100,0, -345,3,101,0,345, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -345,3,106,0,345, -3,107,0,345,3, -108,0,345,851,11, -1,867,0,348,1, --1,3,116,0,345, -3,117,0,345,3, -118,0,345,3,119, -0,345,3,120,0, -345,3,121,0,345, -3,122,0,345,3, -48,0,345,3,49, -0,345,3,50,0, -345,3,51,0,345, -3,52,0,345,3, -53,0,345,3,54, -0,345,3,55,0, -345,3,56,0,345, -3,57,0,345,3, -65,0,345,3,66, -0,345,3,67,0, -345,3,68,0,345, -3,69,0,345,3, -70,0,345,3,71, -0,345,3,72,0, -345,3,73,0,345, -3,74,0,345,3, -75,0,345,3,76, -0,345,3,77,0, -345,3,78,0,345, -3,79,0,345,3, -80,0,345,3,81, -0,345,3,82,0, -345,3,83,0,345, -3,84,0,345,3, -85,0,345,3,86, -0,345,3,87,0, -345,3,88,0,345, -3,89,0,345,3, -90,0,345,3,95, -0,345,3,97,0, -345,3,98,0,345, -3,99,0,345,3, -100,0,345,3,101, -0,345,3,102,0, -345,3,103,0,345, -3,104,0,345,3, -105,0,345,3,106, -0,345,3,107,0, -345,3,108,0,345, -852,11,1,867,0, -348,1,-1,3,106, -0,345,3,107,0, -345,3,108,0,345, -853,11,1,867,0, -348,1,-1,3,109, -0,854,12,1,1964, -855,5,63,3,109, -0,345,3,110,0, -345,3,111,0,856, -12,1,1994,857,5, -63,3,109,0,345, -3,110,0,858,12, -1,2023,859,5,63, -3,109,0,345,3, -110,0,345,3,111, -0,345,3,112,0, -345,3,113,0,345, -3,114,0,345,3, -115,0,345,3,116, -0,345,3,117,0, -345,3,118,0,345, -3,119,0,345,3, -120,0,345,3,121, -0,345,3,122,0, -345,3,48,0,345, -3,49,0,345,3, -50,0,345,3,51, -0,345,3,52,0, -345,3,53,0,345, -3,54,0,345,3, -55,0,345,3,56, -0,345,3,57,0, -345,3,65,0,345, -3,66,0,345,3, -67,0,345,3,68, -0,345,3,69,0, -345,3,70,0,345, -3,71,0,345,3, -72,0,345,3,73, -0,345,3,74,0, -345,3,75,0,345, -3,76,0,345,3, -77,0,345,3,78, -0,345,3,79,0, -345,3,80,0,345, -3,81,0,345,3, -82,0,345,3,83, -0,345,3,84,0, -345,3,85,0,345, -3,86,0,345,3, -87,0,345,3,88, -0,345,3,89,0, -345,3,90,0,345, -3,95,0,345,3, -97,0,345,3,98, -0,345,3,99,0, -345,3,100,0,345, -3,101,0,860,12, -1,2070,861,5,63, -3,109,0,345,3, -110,0,345,3,111, -0,345,3,112,0, -345,3,113,0,345, -3,114,0,345,3, -115,0,345,3,116, -0,345,3,117,0, -345,3,118,0,345, -3,119,0,345,3, -120,0,345,3,121, -0,862,12,1,2110, -863,5,63,3,109, -0,345,3,110,0, -345,3,111,0,345, -3,112,0,345,3, -113,0,345,3,114, -0,345,3,115,0, -345,3,116,0,345, -3,117,0,345,3, -118,0,345,3,119, -0,345,3,120,0, -345,3,121,0,345, -3,122,0,345,3, -48,0,345,3,49, -0,345,3,50,0, -345,3,51,0,345, -3,52,0,345,3, -53,0,345,3,54, -0,345,3,55,0, -345,3,56,0,345, -3,57,0,345,3, -65,0,345,3,66, -0,345,3,67,0, -345,3,68,0,345, -3,69,0,345,3, -70,0,345,3,71, -0,345,3,72,0, -345,3,73,0,345, -3,74,0,345,3, -75,0,345,3,76, -0,345,3,77,0, -345,3,78,0,345, -3,79,0,345,3, -80,0,345,3,81, -0,345,3,82,0, -345,3,83,0,345, -3,84,0,345,3, -85,0,345,3,86, -0,345,3,87,0, -345,3,88,0,345, -3,89,0,345,3, -90,0,345,3,95, -0,345,3,97,0, -345,3,98,0,345, -3,99,0,345,3, -100,0,345,3,101, -0,345,3,102,0, -345,3,103,0,345, -3,104,0,345,3, -105,0,345,3,106, -0,345,3,107,0, -345,3,108,0,345, -864,11,1,591,0, -865,4,22,77,0, -79,0,78,0,69, -0,89,0,95,0, -69,0,86,0,69, -0,78,0,84,0, -1,-1,3,122,0, -345,3,48,0,345, -3,49,0,345,3, -50,0,345,3,51, -0,345,3,52,0, -345,3,53,0,345, -3,54,0,345,3, -55,0,345,3,56, -0,345,3,57,0, -345,3,65,0,345, -3,66,0,345,3, -67,0,345,3,68, -0,345,3,69,0, -345,3,70,0,345, -3,71,0,345,3, -72,0,345,3,73, -0,345,3,74,0, -345,3,75,0,345, -3,76,0,345,3, -77,0,345,3,78, -0,345,3,79,0, -345,3,80,0,345, -3,81,0,345,3, -82,0,345,3,83, -0,345,3,84,0, -345,3,85,0,345, -3,86,0,345,3, -87,0,345,3,88, -0,345,3,89,0, -345,3,90,0,345, -3,95,0,345,3, -97,0,345,3,98, -0,345,3,99,0, -345,3,100,0,345, -3,101,0,345,3, -102,0,345,3,103, -0,345,3,104,0, -345,3,105,0,345, -3,106,0,345,3, -107,0,345,3,108, -0,345,866,11,1, -867,0,348,1,-1, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -345,3,106,0,345, -3,107,0,345,3, -108,0,345,867,11, -1,867,0,348,1, --1,3,111,0,345, -3,112,0,345,3, -113,0,345,3,114, -0,345,3,115,0, -345,3,116,0,345, -3,117,0,345,3, -118,0,868,12,1, -2391,869,5,63,3, -109,0,345,3,110, -0,345,3,111,0, -345,3,112,0,345, -3,113,0,345,3, -114,0,345,3,115, -0,345,3,116,0, -345,3,117,0,345, -3,118,0,345,3, -119,0,345,3,120, -0,345,3,121,0, -345,3,122,0,345, -3,48,0,345,3, -49,0,345,3,50, -0,345,3,51,0, -345,3,52,0,345, -3,53,0,345,3, -54,0,345,3,55, -0,345,3,56,0, -345,3,57,0,345, -3,65,0,345,3, -66,0,345,3,67, -0,345,3,68,0, -345,3,69,0,345, -3,70,0,345,3, -71,0,345,3,72, -0,345,3,73,0, -345,3,74,0,345, -3,75,0,345,3, -76,0,345,3,77, -0,345,3,78,0, -345,3,79,0,345, -3,80,0,345,3, -81,0,345,3,82, -0,345,3,83,0, -345,3,84,0,345, -3,85,0,345,3, -86,0,345,3,87, -0,345,3,88,0, -345,3,89,0,345, -3,90,0,345,3, -95,0,345,3,97, -0,345,3,98,0, -345,3,99,0,345, -3,100,0,345,3, -101,0,345,3,102, -0,345,3,103,0, -345,3,104,0,345, -3,105,0,870,12, -1,2442,871,5,63, -3,109,0,345,3, -110,0,872,12,1, -2471,873,5,63,3, -109,0,345,3,110, -0,345,3,111,0, -345,3,112,0,345, -3,113,0,345,3, -114,0,345,3,115, -0,345,3,116,0, -345,3,117,0,345, -3,118,0,345,3, -119,0,345,3,120, -0,345,3,121,0, -345,3,122,0,345, -3,48,0,345,3, -49,0,345,3,50, -0,345,3,51,0, -345,3,52,0,345, -3,53,0,345,3, -54,0,345,3,55, -0,345,3,56,0, -345,3,57,0,345, -3,65,0,345,3, -66,0,345,3,67, -0,345,3,68,0, -345,3,69,0,345, -3,70,0,345,3, -71,0,345,3,72, -0,345,3,73,0, -345,3,74,0,345, -3,75,0,345,3, -76,0,345,3,77, -0,345,3,78,0, -345,3,79,0,345, -3,80,0,345,3, -81,0,345,3,82, -0,345,3,83,0, -345,3,84,0,345, -3,85,0,345,3, -86,0,345,3,87, -0,345,3,88,0, -345,3,89,0,345, -3,90,0,345,3, -95,0,345,3,97, -0,345,3,98,0, -345,3,99,0,345, -3,100,0,345,3, -101,0,345,3,102, -0,345,3,103,0, -874,12,1,2520,875, -5,63,3,109,0, -345,3,110,0,345, -3,111,0,345,3, -112,0,345,3,113, -0,345,3,114,0, -345,3,115,0,345, -3,116,0,345,3, -117,0,345,3,118, -0,345,3,119,0, -345,3,120,0,345, -3,121,0,345,3, -122,0,345,3,48, -0,345,3,49,0, -345,3,50,0,345, -3,51,0,345,3, -52,0,345,3,53, -0,345,3,54,0, -345,3,55,0,345, -3,56,0,345,3, -57,0,345,3,65, -0,345,3,66,0, -345,3,67,0,345, -3,68,0,345,3, -69,0,345,3,70, -0,345,3,71,0, -345,3,72,0,345, -3,73,0,345,3, -74,0,345,3,75, -0,345,3,76,0, -345,3,77,0,345, -3,78,0,345,3, -79,0,345,3,80, -0,345,3,81,0, -345,3,82,0,345, -3,83,0,345,3, -84,0,345,3,85, -0,345,3,86,0, -345,3,87,0,345, -3,88,0,345,3, -89,0,345,3,90, -0,345,3,95,0, -876,12,1,2606,877, -5,63,3,109,0, -345,3,110,0,345, -3,111,0,345,3, -112,0,345,3,113, -0,345,3,114,0, -345,3,115,0,878, -12,1,2640,879,5, -63,3,109,0,345, -3,110,0,345,3, -111,0,345,3,112, -0,345,3,113,0, -345,3,114,0,345, -3,115,0,345,3, -116,0,880,12,1, -2675,881,5,63,3, -109,0,345,3,110, -0,345,3,111,0, -345,3,112,0,345, -3,113,0,345,3, -114,0,345,3,115, -0,345,3,116,0, -345,3,117,0,345, -3,118,0,345,3, -119,0,345,3,120, -0,345,3,121,0, -345,3,122,0,345, -3,48,0,345,3, -49,0,345,3,50, -0,345,3,51,0, -345,3,52,0,345, -3,53,0,345,3, -54,0,345,3,55, -0,345,3,56,0, -345,3,57,0,345, -3,65,0,345,3, -66,0,345,3,67, -0,345,3,68,0, -345,3,69,0,345, -3,70,0,345,3, -71,0,345,3,72, -0,345,3,73,0, -345,3,74,0,345, -3,75,0,345,3, -76,0,345,3,77, -0,345,3,78,0, -345,3,79,0,345, -3,80,0,345,3, -81,0,345,3,82, -0,345,3,83,0, -345,3,84,0,345, -3,85,0,345,3, -86,0,345,3,87, -0,345,3,88,0, -345,3,89,0,345, -3,90,0,345,3, -95,0,345,3,97, -0,882,12,1,2718, -883,5,63,3,109, -0,345,3,110,0, -345,3,111,0,345, -3,112,0,345,3, -113,0,345,3,114, -0,884,12,1,2751, -885,5,63,3,109, -0,345,3,110,0, -345,3,111,0,345, -3,112,0,345,3, -113,0,345,3,114, -0,345,3,115,0, -345,3,116,0,886, -12,1,2786,887,5, -63,3,109,0,345, -3,110,0,345,3, -111,0,345,3,112, -0,345,3,113,0, -345,3,114,0,345, -3,115,0,345,3, -116,0,345,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,345,3, -98,0,345,3,99, -0,345,3,100,0, -345,3,101,0,345, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -345,3,106,0,345, -3,107,0,345,3, -108,0,345,888,11, -1,614,0,889,4, -36,77,0,79,0, -86,0,73,0,78, -0,71,0,95,0, -83,0,84,0,65, -0,82,0,84,0, -95,0,69,0,86, +3,73,0,180,3, +108,0,180,3,81, +0,180,3,54,0, +180,3,116,0,180, +3,89,0,180,1175, +11,1,867,0,183, +1,-1,3,83,0, +180,3,56,0,180, +3,118,0,180,3, +99,0,180,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,180,3,88, +0,180,3,69,0, +180,3,104,0,180, +3,77,0,180,3, +50,0,180,3,112, +0,180,3,85,0, +180,3,120,0,180, +3,66,0,180,3, +101,0,180,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +180,3,87,0,180, +3,122,0,180,3, +95,0,180,3,68, +0,180,3,103,0, +180,3,76,0,180, +3,49,0,180,3, +111,0,180,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,180,3,73, +0,180,3,108,0, +180,3,81,0,180, +3,54,0,180,3, +116,0,180,3,89, +0,180,1176,11,1, +867,0,183,1,-1, +3,74,0,180,3, +109,0,180,3,82, +0,180,3,55,0, +180,3,117,0,180, +3,90,0,180,3, +98,0,180,3,71, +0,180,3,106,0, +180,3,79,0,180, +3,52,0,180,3, +114,0,180,3,87, +0,180,3,122,0, +180,3,95,0,180, +3,68,0,180,3, +103,0,180,3,76, +0,180,3,49,0, +180,3,111,0,180, +3,84,0,180,3, +57,0,180,3,119, +0,180,3,65,0, +180,3,100,0,180, +3,73,0,180,3, +108,0,180,3,81, +0,180,3,54,0, +180,3,116,0,180, +3,89,0,180,1177, +11,1,867,0,183, +1,-1,3,68,0, +180,3,103,0,180, +3,76,0,180,3, +49,0,180,3,111, +0,180,3,84,0, +180,3,57,0,180, +3,119,0,180,3, +65,0,180,3,100, +0,180,3,73,0, +180,3,108,0,180, +3,81,0,180,3, +54,0,180,3,116, +0,180,3,89,0, +180,1178,11,1,792, +0,1179,4,22,84, +0,79,0,85,0, +67,0,72,0,95, +0,69,0,86,0, +69,0,78,0,84, +0,1,-1,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,180,3,66, +0,180,3,101,0, +180,3,74,0,180, +3,109,0,180,3, +82,0,180,3,55, +0,180,3,117,0, +180,3,90,0,180, +3,98,0,180,3, +71,0,180,3,106, +0,180,3,79,0, +180,3,52,0,180, +3,114,0,180,3, +87,0,180,3,122, +0,180,3,95,0, +180,3,68,0,180, +3,103,0,180,3, +76,0,180,3,49, +0,180,3,111,0, +180,3,84,0,180, +3,57,0,180,3, +119,0,180,3,65, +0,180,3,100,0, +180,3,73,0,180, +3,108,0,180,3, +81,0,180,3,54, +0,180,3,116,0, +180,3,89,0,180, +1180,11,1,867,0, +183,1,-1,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,180,3,88, +0,180,3,69,0, +180,3,104,0,180, +3,77,0,180,3, +50,0,180,3,112, +0,180,3,85,0, +180,3,120,0,180, +3,66,0,180,3, +101,0,180,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +180,3,87,0,180, +3,122,0,180,3, +95,0,180,3,68, +0,180,3,103,0, +180,3,76,0,180, +3,49,0,180,3, +111,0,180,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,180,3,73, +0,180,3,108,0, +180,3,81,0,180, +3,54,0,180,3, +116,0,180,3,89, +0,180,1181,11,1, +867,0,183,1,-1, +3,90,0,180,3, +98,0,180,3,71, +0,180,3,106,0, +180,3,79,0,180, +3,52,0,180,3, +114,0,180,3,87, +0,180,3,122,0, +180,3,95,0,180, +3,68,0,180,3, +103,0,180,3,76, +0,180,3,49,0, +180,3,111,0,180, +3,84,0,180,3, +57,0,180,3,119, +0,180,3,65,0, +180,3,100,0,180, +3,73,0,180,3, +108,0,180,3,81, +0,180,3,54,0, +180,3,116,0,180, +3,89,0,180,1182, +11,1,867,0,183, +1,-1,3,84,0, +180,3,57,0,180, +3,119,0,180,3, +65,0,180,3,100, +0,180,3,73,0, +180,3,108,0,180, +3,81,0,180,3, +54,0,180,3,116, +0,180,3,89,0, +180,1183,11,1,867, +0,183,1,-1,3, +76,0,178,3,113, +0,178,3,73,0, +178,3,33,0,1184, +12,1,4709,1185,5, +1,3,61,0,1186, +12,1,4717,1187,5, +0,1188,11,1,142, +0,1189,4,36,69, +0,88,0,67,0, +76,0,65,0,77, +0,65,0,84,0, +73,0,79,0,78, +0,95,0,69,0, +81,0,85,0,65, +0,76,0,83,0, +1,-1,1190,11,1, +180,0,1191,4,22, +69,0,88,0,67, +0,76,0,65,0, +77,0,65,0,84, +0,73,0,79,0, +78,0,1,-1,3, +110,0,1192,12,1, +14009,1193,5,63,3, +97,0,180,3,70, +0,180,3,105,0, +180,3,78,0,180, +3,51,0,180,3, +113,0,180,3,86, +0,180,3,121,0, +180,3,67,0,180, +3,102,0,180,3, +75,0,180,3,48, +0,180,3,110,0, +180,3,83,0,180, +3,56,0,180,3, +118,0,180,3,99, +0,180,3,72,0, +180,3,107,0,180, +3,80,0,180,3, +53,0,180,3,115, +0,180,3,88,0, +180,3,69,0,180, +3,104,0,180,3, +77,0,180,3,50, +0,180,3,112,0, +180,3,85,0,180, +3,120,0,180,3, +66,0,180,3,101, +0,180,3,74,0, +180,3,109,0,180, +3,82,0,180,3, +55,0,180,3,117, +0,180,3,90,0, +180,3,98,0,180, +3,71,0,180,3, +106,0,180,3,79, +0,180,3,52,0, +180,3,114,0,180, +3,87,0,180,3, +122,0,180,3,95, +0,180,3,68,0, +180,3,103,0,180, +3,76,0,180,3, +49,0,180,3,111, +0,1194,12,1,14097, +1195,5,63,3,97, +0,180,3,70,0, +180,3,105,0,180, +3,78,0,180,3, +51,0,180,3,113, +0,180,3,86,0, +180,3,121,0,180, +3,67,0,180,3, +102,0,180,3,75, +0,180,3,48,0, +180,3,110,0,180, +3,83,0,180,3, +56,0,180,3,118, +0,180,3,99,0, +180,3,72,0,180, +3,107,0,180,3, +80,0,180,3,53, +0,180,3,115,0, +180,3,88,0,180, +3,69,0,180,3, +104,0,180,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,180,3,66, +0,180,3,101,0, +180,3,74,0,180, +3,109,0,180,3, +82,0,180,3,55, +0,180,3,117,0, +180,3,90,0,180, +3,98,0,180,3, +71,0,180,3,106, +0,180,3,79,0, +180,3,52,0,180, +3,114,0,180,3, +87,0,180,3,122, +0,180,3,95,0, +1196,12,1,14133,1197, +5,63,3,97,0, +180,3,70,0,180, +3,105,0,180,3, +78,0,180,3,51, +0,180,3,113,0, +180,3,86,0,180, +3,121,0,180,3, +67,0,180,3,102, +0,180,3,75,0, +180,3,48,0,180, +3,110,0,180,3, +83,0,180,3,56, +0,180,3,118,0, +180,3,99,0,180, +3,72,0,180,3, +107,0,180,3,80, +0,180,3,53,0, +180,3,115,0,1198, +12,1,14209,1199,5, +63,3,97,0,180, +3,70,0,180,3, +105,0,180,3,78, +0,180,3,51,0, +180,3,113,0,180, +3,86,0,180,3, +121,0,180,3,67, +0,180,3,102,0, +180,3,75,0,180, +3,48,0,180,3, +110,0,180,3,83, +0,180,3,56,0, +180,3,118,0,180, +3,99,0,180,3, +72,0,180,3,107, +0,180,3,80,0, +180,3,53,0,180, +3,115,0,180,3, +88,0,180,3,69, +0,180,3,104,0, +180,3,77,0,180, +3,50,0,180,3, +112,0,180,3,85, +0,180,3,120,0, +180,3,66,0,180, +3,101,0,1200,12, +1,14289,1201,5,63, +3,97,0,180,3, +70,0,180,3,105, +0,180,3,78,0, +180,3,51,0,180, +3,113,0,180,3, +86,0,180,3,121, +0,180,3,67,0, +180,3,102,0,180, +3,75,0,180,3, +48,0,180,3,110, +0,1202,12,1,14361, +1203,5,63,3,97, +0,180,3,70,0, +180,3,105,0,180, +3,78,0,180,3, +51,0,180,3,113, +0,180,3,86,0, +180,3,121,0,180, +3,67,0,180,3, +102,0,180,3,75, +0,180,3,48,0, +180,3,110,0,180, +3,83,0,180,3, +56,0,180,3,118, +0,180,3,99,0, +180,3,72,0,180, +3,107,0,180,3, +80,0,180,3,53, +0,180,3,115,0, +1204,12,1,14437,1205, +5,63,3,97,0, +180,3,70,0,180, +3,105,0,180,3, +78,0,180,3,51, +0,180,3,113,0, +180,3,86,0,180, +3,121,0,180,3, +67,0,180,3,102, +0,180,3,75,0, +180,3,48,0,180, +3,110,0,180,3, +83,0,180,3,56, +0,180,3,118,0, +180,3,99,0,180, +3,72,0,180,3, +107,0,180,3,80, +0,180,3,53,0, +180,3,115,0,180, +3,88,0,180,3, +69,0,180,3,104, +0,180,3,77,0, +180,3,50,0,180, +3,112,0,180,3, +85,0,180,3,120, +0,180,3,66,0, +180,3,101,0,180, +3,74,0,180,3, +109,0,180,3,82, +0,180,3,55,0, +180,3,117,0,180, +3,90,0,180,3, +98,0,180,3,71, +0,180,3,106,0, +180,3,79,0,180, +3,52,0,180,3, +114,0,180,3,87, +0,180,3,122,0, +180,3,95,0,180, +3,68,0,180,3, +103,0,180,3,76, +0,180,3,49,0, +180,3,111,0,1206, +12,1,14525,1207,5, +63,3,97,0,180, +3,70,0,180,3, +105,0,180,3,78, +0,180,3,51,0, +180,3,113,0,180, +3,86,0,180,3, +121,0,180,3,67, +0,180,3,102,0, +180,3,75,0,180, +3,48,0,180,3, +110,0,180,3,83, +0,180,3,56,0, +180,3,118,0,180, +3,99,0,180,3, +72,0,180,3,107, +0,180,3,80,0, +180,3,53,0,180, +3,115,0,180,3, +88,0,180,3,69, +0,180,3,104,0, +180,3,77,0,180, +3,50,0,180,3, +112,0,180,3,85, +0,180,3,120,0, +180,3,66,0,180, +3,101,0,180,3, +74,0,180,3,109, +0,180,3,82,0, +180,3,55,0,180, +3,117,0,180,3, +90,0,180,3,98, +0,180,3,71,0, +180,3,106,0,180, +3,79,0,180,3, +52,0,180,3,114, +0,1208,12,1,14610, +1209,5,63,3,97, +0,180,3,70,0, +180,3,105,0,180, +3,78,0,180,3, +51,0,180,3,113, +0,180,3,86,0, +180,3,121,0,180, +3,67,0,180,3, +102,0,180,3,75, +0,180,3,48,0, +180,3,110,0,180, +3,83,0,180,3, +56,0,180,3,118, +0,180,3,99,0, +180,3,72,0,180, +3,107,0,180,3, +80,0,180,3,53, +0,180,3,115,0, +180,3,88,0,180, +3,69,0,180,3, +104,0,180,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,180,3,66, +0,180,3,101,0, +180,3,74,0,180, +3,109,0,180,3, +82,0,180,3,55, +0,180,3,117,0, +180,3,90,0,180, +3,98,0,180,3, +71,0,180,3,106, +0,180,3,79,0, +180,3,52,0,180, +3,114,0,180,3, +87,0,180,3,122, +0,180,3,95,0, +180,3,68,0,180, +3,103,0,180,3, +76,0,180,3,49, +0,180,3,111,0, +180,3,84,0,180, +3,57,0,180,3, +119,0,180,3,65, +0,180,3,100,0, +180,3,73,0,180, +3,108,0,180,3, +81,0,180,3,54, +0,180,3,116,0, +180,3,89,0,180, +1210,11,1,630,0, +1211,4,30,78,0, +79,0,95,0,83, 0,69,0,78,0, -84,0,1,-1,3, -117,0,345,3,118, -0,345,3,119,0, -345,3,120,0,345, -3,121,0,345,3, -122,0,345,3,48, -0,345,3,49,0, -345,3,50,0,345, -3,51,0,345,3, -52,0,345,3,53, -0,345,3,54,0, -345,3,55,0,345, -3,56,0,345,3, -57,0,345,3,65, -0,345,3,66,0, -345,3,67,0,345, -3,68,0,345,3, -69,0,345,3,70, -0,345,3,71,0, -345,3,72,0,345, -3,73,0,345,3, -74,0,345,3,75, -0,345,3,76,0, -345,3,77,0,345, -3,78,0,345,3, -79,0,345,3,80, -0,345,3,81,0, -345,3,82,0,345, -3,83,0,345,3, -84,0,345,3,85, -0,345,3,86,0, -345,3,87,0,345, -3,88,0,345,3, -89,0,345,3,90, -0,345,3,95,0, -345,3,97,0,345, -3,98,0,345,3, -99,0,345,3,100, -0,345,3,101,0, -345,3,102,0,345, -3,103,0,345,3, -104,0,345,3,105, -0,345,3,106,0, -345,3,107,0,345, -3,108,0,345,890, -11,1,867,0,348, -1,-1,3,115,0, -345,3,116,0,345, -3,117,0,345,3, -118,0,345,3,119, -0,345,3,120,0, -345,3,121,0,345, -3,122,0,345,3, -48,0,345,3,49, -0,345,3,50,0, -345,3,51,0,345, -3,52,0,345,3, -53,0,345,3,54, -0,345,3,55,0, -345,3,56,0,345, -3,57,0,345,3, -65,0,345,3,66, -0,345,3,67,0, -345,3,68,0,345, -3,69,0,345,3, -70,0,345,3,71, -0,345,3,72,0, -345,3,73,0,345, -3,74,0,345,3, -75,0,345,3,76, -0,345,3,77,0, -345,3,78,0,345, -3,79,0,345,3, -80,0,345,3,81, -0,345,3,82,0, -345,3,83,0,345, -3,84,0,345,3, -85,0,345,3,86, -0,345,3,87,0, -345,3,88,0,345, -3,89,0,345,3, -90,0,345,3,95, -0,345,3,97,0, -345,3,98,0,345, -3,99,0,345,3, -100,0,345,3,101, -0,345,3,102,0, -345,3,103,0,345, -3,104,0,345,3, -105,0,345,3,106, -0,345,3,107,0, -345,3,108,0,345, -891,11,1,867,0, -348,1,-1,3,98, -0,345,3,99,0, -345,3,100,0,345, -3,101,0,345,3, -102,0,345,3,103, -0,345,3,104,0, -345,3,105,0,345, -3,106,0,345,3, -107,0,345,3,108, -0,345,892,11,1, -867,0,348,1,-1, -3,117,0,345,3, -118,0,345,3,119, -0,345,3,120,0, -345,3,121,0,345, -3,122,0,345,3, -48,0,345,3,49, -0,345,3,50,0, -345,3,51,0,345, -3,52,0,345,3, -53,0,345,3,54, -0,345,3,55,0, -345,3,56,0,345, -3,57,0,345,3, -65,0,345,3,66, -0,345,3,67,0, -345,3,68,0,345, -3,69,0,345,3, -70,0,345,3,71, -0,345,3,72,0, -345,3,73,0,345, -3,74,0,345,3, -75,0,345,3,76, -0,345,3,77,0, -345,3,78,0,345, -3,79,0,345,3, -80,0,345,3,81, -0,345,3,82,0, -345,3,83,0,345, -3,84,0,345,3, -85,0,345,3,86, -0,345,3,87,0, -345,3,88,0,345, -3,89,0,345,3, -90,0,345,3,95, -0,345,3,97,0, -345,3,98,0,345, -3,99,0,345,3, -100,0,345,3,101, -0,345,3,102,0, -345,3,103,0,345, -3,104,0,345,3, -105,0,345,3,106, -0,345,3,107,0, -345,3,108,0,345, -893,11,1,867,0, -348,1,-1,3,116, -0,345,3,117,0, -345,3,118,0,345, -3,119,0,345,3, -120,0,345,3,121, -0,345,3,122,0, -345,3,48,0,345, -3,49,0,345,3, -50,0,345,3,51, -0,345,3,52,0, -345,3,53,0,345, -3,54,0,345,3, -55,0,345,3,56, -0,345,3,57,0, -345,3,65,0,345, -3,66,0,345,3, -67,0,345,3,68, -0,345,3,69,0, -345,3,70,0,345, -3,71,0,345,3, -72,0,345,3,73, -0,345,3,74,0, -345,3,75,0,345, -3,76,0,345,3, -77,0,345,3,78, -0,345,3,79,0, -345,3,80,0,345, -3,81,0,345,3, -82,0,345,3,83, -0,345,3,84,0, -345,3,85,0,345, -3,86,0,345,3, -87,0,345,3,88, -0,345,3,89,0, -345,3,90,0,345, -3,95,0,345,3, -97,0,345,3,98, -0,345,3,99,0, -345,3,100,0,345, -3,101,0,894,12, -1,3253,895,5,63, -3,109,0,345,3, -110,0,896,12,1, -3282,897,5,63,3, -109,0,345,3,110, -0,345,3,111,0, -345,3,112,0,345, -3,113,0,345,3, -114,0,345,3,115, -0,345,3,116,0, -345,3,117,0,345, -3,118,0,345,3, -119,0,345,3,120, -0,345,3,121,0, -345,3,122,0,345, -3,48,0,345,3, -49,0,345,3,50, -0,345,3,51,0, -345,3,52,0,345, -3,53,0,345,3, -54,0,345,3,55, -0,345,3,56,0, -345,3,57,0,345, -3,65,0,345,3, -66,0,345,3,67, -0,345,3,68,0, -345,3,69,0,345, -3,70,0,345,3, -71,0,345,3,72, -0,345,3,73,0, -345,3,74,0,345, -3,75,0,345,3, -76,0,345,3,77, -0,345,3,78,0, -345,3,79,0,345, -3,80,0,345,3, -81,0,345,3,82, -0,345,3,83,0, -345,3,84,0,345, -3,85,0,345,3, -86,0,345,3,87, -0,345,3,88,0, -345,3,89,0,345, -3,90,0,345,3, -95,0,345,3,97, -0,345,3,98,0, -345,3,99,0,345, -3,100,0,898,12, -1,3328,899,5,63, -3,109,0,345,3, -110,0,345,3,111, -0,345,3,112,0, -345,3,113,0,345, -3,114,0,345,3, -115,0,345,3,116, -0,345,3,117,0, -345,3,118,0,345, -3,119,0,345,3, -120,0,345,3,121, -0,345,3,122,0, -345,3,48,0,345, -3,49,0,345,3, -50,0,345,3,51, -0,345,3,52,0, -345,3,53,0,345, -3,54,0,345,3, -55,0,345,3,56, -0,345,3,57,0, -345,3,65,0,345, -3,66,0,345,3, -67,0,345,3,68, -0,345,3,69,0, -345,3,70,0,345, -3,71,0,345,3, -72,0,345,3,73, -0,345,3,74,0, -345,3,75,0,345, -3,76,0,345,3, -77,0,345,3,78, -0,345,3,79,0, -345,3,80,0,345, -3,81,0,345,3, -82,0,345,3,83, -0,345,3,84,0, -345,3,85,0,345, -3,86,0,345,3, -87,0,345,3,88, -0,345,3,89,0, -345,3,90,0,345, -3,95,0,345,3, -97,0,345,3,98, -0,345,3,99,0, -345,3,100,0,345, -3,101,0,345,3, -102,0,345,3,103, -0,345,3,104,0, -345,3,105,0,345, -3,106,0,345,3, -107,0,345,3,108, -0,345,900,11,1, -600,0,901,4,32, -77,0,79,0,86, -0,73,0,78,0, -71,0,95,0,69, -0,78,0,68,0, -95,0,69,0,86, -0,69,0,78,0, -84,0,1,-1,3, -101,0,345,3,102, -0,345,3,103,0, -345,3,104,0,345, -3,105,0,345,3, -106,0,345,3,107, -0,345,3,108,0, -345,902,11,1,867, -0,348,1,-1,3, -111,0,345,3,112, -0,345,3,113,0, -345,3,114,0,345, -3,115,0,345,3, -116,0,345,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,345,3, -98,0,345,3,99, -0,345,3,100,0, -345,3,101,0,345, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -345,3,106,0,345, -3,107,0,345,3, -108,0,345,903,11, -1,867,0,348,1, --1,3,102,0,345, -3,103,0,345,3, -104,0,345,3,105, -0,345,3,106,0, -345,3,107,0,345, -3,108,0,345,904, -11,1,867,0,348, -1,-1,3,97,0, -345,3,98,0,345, -3,99,0,345,3, -100,0,345,3,101, -0,345,3,102,0, -345,3,103,0,345, -3,104,0,345,3, -105,0,345,3,106, -0,345,3,107,0, -345,3,108,0,345, -905,11,1,867,0, -348,1,-1,3,104, -0,345,3,105,0, -345,3,106,0,345, -3,107,0,345,3, -108,0,345,906,11, -1,867,0,348,1, --1,3,111,0,345, -3,112,0,345,3, -113,0,345,3,114, -0,345,3,115,0, -345,3,116,0,345, -3,117,0,345,3, -118,0,345,3,119, -0,345,3,120,0, -345,3,121,0,345, -3,122,0,345,3, -48,0,345,3,49, -0,345,3,50,0, -345,3,51,0,345, -3,52,0,345,3, -53,0,345,3,54, -0,345,3,55,0, -345,3,56,0,345, -3,57,0,345,3, -65,0,345,3,66, -0,345,3,67,0, -345,3,68,0,345, -3,69,0,345,3, -70,0,345,3,71, -0,345,3,72,0, -345,3,73,0,345, -3,74,0,345,3, -75,0,345,3,76, -0,345,3,77,0, -345,3,78,0,345, -3,79,0,345,3, -80,0,345,3,81, -0,345,3,82,0, -345,3,83,0,345, -3,84,0,345,3, -85,0,345,3,86, -0,345,3,87,0, -345,3,88,0,345, -3,89,0,345,3, -90,0,345,3,95, -0,345,3,97,0, -345,3,98,0,345, -3,99,0,345,3, -100,0,345,3,101, -0,345,3,102,0, -345,3,103,0,345, -3,104,0,345,3, -105,0,345,3,106, -0,345,3,107,0, -345,3,108,0,345, -907,11,1,867,0, -348,1,-1,3,106, -0,345,3,107,0, -345,3,108,0,345, -908,11,1,867,0, -348,1,-1,3,119, -0,345,3,120,0, -345,3,121,0,345, -3,122,0,345,3, -48,0,345,3,49, -0,345,3,50,0, -345,3,51,0,345, -3,52,0,345,3, -53,0,345,3,54, -0,345,3,55,0, -345,3,56,0,345, -3,57,0,345,3, -65,0,345,3,66, -0,345,3,67,0, -345,3,68,0,345, -3,69,0,345,3, -70,0,345,3,71, -0,345,3,72,0, -345,3,73,0,345, -3,74,0,345,3, -75,0,345,3,76, -0,345,3,77,0, -345,3,78,0,345, -3,79,0,345,3, -80,0,345,3,81, -0,345,3,82,0, -345,3,83,0,345, -3,84,0,345,3, -85,0,345,3,86, -0,345,3,87,0, -345,3,88,0,345, -3,89,0,345,3, -90,0,345,3,95, -0,345,3,97,0, -345,3,98,0,345, -3,99,0,345,3, -100,0,345,3,101, -0,345,3,102,0, -345,3,103,0,345, -3,104,0,345,3, -105,0,345,3,106, -0,345,3,107,0, -345,3,108,0,345, -909,11,1,867,0, -348,1,-1,3,112, -0,345,3,113,0, -345,3,114,0,345, -3,115,0,345,3, -116,0,345,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,345,3, -98,0,345,3,99, -0,345,3,100,0, -345,3,101,0,345, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -345,3,106,0,345, -3,107,0,345,3, -108,0,345,910,11, -1,867,0,348,1, --1,3,110,0,911, -12,1,4125,912,5, -63,3,109,0,345, -3,110,0,345,3, -111,0,913,12,1, -4155,914,5,63,3, -109,0,345,3,110, -0,345,3,111,0, -345,3,112,0,345, -3,113,0,345,3, -114,0,345,3,115, -0,345,3,116,0, -915,12,1,4190,916, -5,63,3,109,0, -345,3,110,0,345, -3,111,0,345,3, -112,0,345,3,113, -0,345,3,114,0, -345,3,115,0,345, -3,116,0,345,3, -117,0,345,3,118, -0,345,3,119,0, -345,3,120,0,345, -3,121,0,345,3, -122,0,345,3,48, -0,345,3,49,0, -345,3,50,0,345, -3,51,0,345,3, -52,0,345,3,53, -0,345,3,54,0, -345,3,55,0,345, -3,56,0,345,3, -57,0,345,3,65, -0,345,3,66,0, -345,3,67,0,345, -3,68,0,345,3, -69,0,345,3,70, -0,345,3,71,0, -345,3,72,0,345, -3,73,0,345,3, -74,0,345,3,75, -0,345,3,76,0, -345,3,77,0,345, -3,78,0,345,3, -79,0,345,3,80, -0,345,3,81,0, -345,3,82,0,345, -3,83,0,345,3, -84,0,345,3,85, -0,345,3,86,0, -345,3,87,0,345, -3,88,0,345,3, -89,0,345,3,90, -0,345,3,95,0, -917,12,1,4276,918, -5,63,3,109,0, -345,3,110,0,345, -3,111,0,345,3, -112,0,345,3,113, -0,345,3,114,0, -345,3,115,0,345, -3,116,0,345,3, -117,0,345,3,118, -0,345,3,119,0, -345,3,120,0,345, -3,121,0,345,3, -122,0,345,3,48, -0,345,3,49,0, -345,3,50,0,345, -3,51,0,345,3, -52,0,345,3,53, -0,345,3,54,0, -345,3,55,0,345, -3,56,0,345,3, -57,0,345,3,65, -0,345,3,66,0, -345,3,67,0,345, -3,68,0,345,3, -69,0,345,3,70, -0,345,3,71,0, -345,3,72,0,345, -3,73,0,345,3, -74,0,345,3,75, -0,345,3,76,0, -345,3,77,0,345, -3,78,0,345,3, -79,0,345,3,80, -0,345,3,81,0, -345,3,82,0,345, -3,83,0,345,3, -84,0,345,3,85, -0,345,3,86,0, -345,3,87,0,345, -3,88,0,345,3, -89,0,345,3,90, -0,345,3,95,0, -345,3,97,0,919, -12,1,4319,920,5, -63,3,109,0,345, -3,110,0,345,3, -111,0,345,3,112, -0,345,3,113,0, -345,3,114,0,345, -3,115,0,345,3, -116,0,921,12,1, -4354,922,5,63,3, -109,0,345,3,110, -0,345,3,111,0, -345,3,112,0,345, -3,113,0,345,3, -114,0,345,3,115, -0,345,3,116,0, -345,3,117,0,345, -3,118,0,345,3, -119,0,345,3,120, -0,345,3,121,0, -345,3,122,0,345, -3,48,0,345,3, -49,0,345,3,50, -0,345,3,51,0, -345,3,52,0,345, -3,53,0,345,3, -54,0,345,3,55, -0,345,3,56,0, -345,3,57,0,345, -3,65,0,345,3, -66,0,345,3,67, -0,345,3,68,0, -345,3,69,0,345, -3,70,0,345,3, -71,0,345,3,72, -0,345,3,73,0, -345,3,74,0,345, -3,75,0,345,3, -76,0,345,3,77, -0,345,3,78,0, -345,3,79,0,345, -3,80,0,345,3, -81,0,345,3,82, -0,345,3,83,0, -345,3,84,0,345, -3,85,0,345,3, -86,0,345,3,87, -0,345,3,88,0, -345,3,89,0,345, -3,90,0,345,3, -95,0,923,12,1, -4440,924,5,63,3, -109,0,345,3,110, -0,345,3,111,0, -345,3,112,0,345, -3,113,0,345,3, -114,0,925,12,1, -4473,926,5,63,3, -109,0,345,3,110, -0,345,3,111,0, -927,12,1,4503,928, -5,63,3,109,0, -345,3,110,0,345, -3,111,0,345,3, -112,0,345,3,113, -0,345,3,114,0, -345,3,115,0,345, -3,116,0,929,12, -1,4538,930,5,63, -3,109,0,345,3, -110,0,345,3,111, -0,345,3,112,0, -345,3,113,0,345, -3,114,0,345,3, -115,0,345,3,116, -0,345,3,117,0, -345,3,118,0,345, -3,119,0,345,3, -120,0,345,3,121, -0,345,3,122,0, -345,3,48,0,345, -3,49,0,345,3, -50,0,345,3,51, -0,345,3,52,0, -345,3,53,0,345, -3,54,0,345,3, -55,0,345,3,56, -0,345,3,57,0, -345,3,65,0,345, -3,66,0,345,3, -67,0,345,3,68, -0,345,3,69,0, -345,3,70,0,345, -3,71,0,345,3, -72,0,345,3,73, -0,345,3,74,0, -345,3,75,0,345, -3,76,0,345,3, -77,0,345,3,78, -0,345,3,79,0, -345,3,80,0,345, -3,81,0,345,3, -82,0,345,3,83, -0,345,3,84,0, -345,3,85,0,345, -3,86,0,345,3, -87,0,345,3,88, -0,345,3,89,0, -345,3,90,0,345, -3,95,0,931,12, -1,4624,932,5,63, -3,109,0,345,3, -110,0,345,3,111, -0,345,3,112,0, -345,3,113,0,345, -3,114,0,345,3, -115,0,345,3,116, -0,933,12,1,4659, -934,5,63,3,109, -0,345,3,110,0, -345,3,111,0,345, -3,112,0,345,3, -113,0,345,3,114, -0,345,3,115,0, -345,3,116,0,345, -3,117,0,345,3, -118,0,345,3,119, -0,345,3,120,0, -345,3,121,0,345, -3,122,0,345,3, -48,0,345,3,49, -0,345,3,50,0, -345,3,51,0,345, -3,52,0,345,3, -53,0,345,3,54, -0,345,3,55,0, -345,3,56,0,345, -3,57,0,345,3, -65,0,345,3,66, -0,345,3,67,0, -345,3,68,0,345, -3,69,0,345,3, -70,0,345,3,71, -0,345,3,72,0, -345,3,73,0,345, -3,74,0,345,3, -75,0,345,3,76, -0,345,3,77,0, -345,3,78,0,345, -3,79,0,345,3, -80,0,345,3,81, -0,345,3,82,0, -345,3,83,0,345, -3,84,0,345,3, -85,0,345,3,86, -0,345,3,87,0, -345,3,88,0,345, -3,89,0,345,3, -90,0,345,3,95, -0,345,3,97,0, -935,12,1,4702,936, -5,63,3,109,0, -345,3,110,0,345, -3,111,0,345,3, -112,0,345,3,113, -0,345,3,114,0, -937,12,1,4735,938, -5,63,3,109,0, -345,3,110,0,345, -3,111,0,345,3, -112,0,345,3,113, -0,345,3,114,0, -345,3,115,0,345, -3,116,0,345,3, -117,0,345,3,118, -0,345,3,119,0, -345,3,120,0,345, -3,121,0,345,3, -122,0,345,3,48, -0,345,3,49,0, -345,3,50,0,345, -3,51,0,345,3, -52,0,345,3,53, -0,345,3,54,0, -345,3,55,0,345, -3,56,0,345,3, -57,0,345,3,65, -0,345,3,66,0, -345,3,67,0,345, -3,68,0,345,3, -69,0,345,3,70, -0,345,3,71,0, -345,3,72,0,345, -3,73,0,345,3, -74,0,345,3,75, -0,345,3,76,0, -345,3,77,0,345, -3,78,0,345,3, -79,0,345,3,80, -0,345,3,81,0, -345,3,82,0,345, -3,83,0,345,3, -84,0,345,3,85, -0,345,3,86,0, -345,3,87,0,345, -3,88,0,345,3, -89,0,345,3,90, -0,345,3,95,0, -345,3,97,0,345, -3,98,0,345,3, -99,0,345,3,100, -0,345,3,101,0, -345,3,102,0,345, -3,103,0,939,12, -1,4784,940,5,63, -3,109,0,345,3, -110,0,345,3,111, -0,345,3,112,0, -345,3,113,0,345, -3,114,0,345,3, -115,0,345,3,116, -0,345,3,117,0, -345,3,118,0,345, -3,119,0,345,3, -120,0,345,3,121, -0,345,3,122,0, -345,3,48,0,345, -3,49,0,345,3, -50,0,345,3,51, -0,345,3,52,0, -345,3,53,0,345, -3,54,0,345,3, -55,0,345,3,56, -0,345,3,57,0, -345,3,65,0,345, -3,66,0,345,3, -67,0,345,3,68, -0,345,3,69,0, -345,3,70,0,345, -3,71,0,345,3, -72,0,345,3,73, -0,345,3,74,0, -345,3,75,0,345, -3,76,0,345,3, -77,0,345,3,78, -0,345,3,79,0, -345,3,80,0,345, -3,81,0,345,3, -82,0,345,3,83, -0,345,3,84,0, -345,3,85,0,345, -3,86,0,345,3, -87,0,345,3,88, -0,345,3,89,0, -345,3,90,0,345, -3,95,0,345,3, -97,0,345,3,98, -0,345,3,99,0, -345,3,100,0,345, -3,101,0,941,12, -1,4831,942,5,63, -3,109,0,345,3, -110,0,345,3,111, -0,345,3,112,0, -345,3,113,0,345, -3,114,0,345,3, -115,0,345,3,116, -0,943,12,1,4866, -944,5,63,3,109, -0,345,3,110,0, -345,3,111,0,345, -3,112,0,345,3, -113,0,345,3,114, -0,345,3,115,0, -345,3,116,0,345, -3,117,0,345,3, -118,0,345,3,119, -0,345,3,120,0, -345,3,121,0,345, -3,122,0,345,3, -48,0,345,3,49, -0,345,3,50,0, -345,3,51,0,345, -3,52,0,345,3, -53,0,345,3,54, -0,345,3,55,0, -345,3,56,0,345, -3,57,0,345,3, -65,0,345,3,66, -0,345,3,67,0, -345,3,68,0,345, -3,69,0,345,3, -70,0,345,3,71, -0,345,3,72,0, -345,3,73,0,345, -3,74,0,345,3, -75,0,345,3,76, -0,345,3,77,0, -345,3,78,0,345, -3,79,0,345,3, -80,0,345,3,81, -0,345,3,82,0, -345,3,83,0,345, -3,84,0,345,3, -85,0,345,3,86, -0,345,3,87,0, -345,3,88,0,345, -3,89,0,345,3, -90,0,345,3,95, -0,345,3,97,0, -345,3,98,0,345, -3,99,0,345,3, -100,0,345,3,101, -0,345,3,102,0, -345,3,103,0,345, -3,104,0,345,3, -105,0,345,3,106, -0,345,3,107,0, -345,3,108,0,345, -945,11,1,643,0, -946,4,46,78,0, +83,0,79,0,82, +0,95,0,69,0, +86,0,69,0,78, +0,84,0,1,-1, +3,87,0,180,3, +122,0,180,3,95, +0,180,3,68,0, +180,3,103,0,180, +3,76,0,180,3, +49,0,180,3,111, +0,180,3,84,0, +180,3,57,0,180, +3,119,0,180,3, +65,0,180,3,100, +0,180,3,73,0, +180,3,108,0,180, +3,81,0,180,3, +54,0,180,3,116, +0,180,3,89,0, +180,1212,11,1,867, +0,183,1,-1,3, +84,0,180,3,57, +0,180,3,119,0, +180,3,65,0,180, +3,100,0,180,3, +73,0,180,3,108, +0,180,3,81,0, +180,3,54,0,180, +3,116,0,180,3, +89,0,180,1213,11, +1,867,0,183,1, +-1,3,88,0,180, +3,69,0,180,3, +104,0,180,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,180,3,66, +0,180,3,101,0, +180,3,74,0,180, +3,109,0,180,3, +82,0,180,3,55, +0,180,3,117,0, +180,3,90,0,180, +3,98,0,180,3, +71,0,180,3,106, +0,180,3,79,0, +180,3,52,0,180, +3,114,0,180,3, +87,0,180,3,122, +0,180,3,95,0, +180,3,68,0,180, +3,103,0,180,3, +76,0,180,3,49, +0,180,3,111,0, +180,3,84,0,180, +3,57,0,180,3, +119,0,180,3,65, +0,180,3,100,0, +180,3,73,0,180, +3,108,0,180,3, +81,0,180,3,54, +0,180,3,116,0, +180,3,89,0,180, +1214,11,1,867,0, +183,1,-1,3,83, +0,180,3,56,0, +180,3,118,0,180, +3,99,0,180,3, +72,0,180,3,107, +0,180,3,80,0, +180,3,53,0,180, +3,115,0,180,3, +88,0,180,3,69, +0,180,3,104,0, +180,3,77,0,180, +3,50,0,180,3, +112,0,180,3,85, +0,180,3,120,0, +180,3,66,0,180, +3,101,0,180,3, +74,0,180,3,109, +0,180,3,82,0, +180,3,55,0,180, +3,117,0,180,3, +90,0,180,3,98, +0,180,3,71,0, +180,3,106,0,180, +3,79,0,180,3, +52,0,180,3,114, +0,180,3,87,0, +180,3,122,0,180, +3,95,0,180,3, +68,0,180,3,103, +0,180,3,76,0, +180,3,49,0,180, +3,111,0,180,3, +84,0,180,3,57, +0,180,3,119,0, +180,3,65,0,180, +3,100,0,180,3, +73,0,180,3,108, +0,180,3,81,0, +180,3,54,0,180, +3,116,0,180,3, +89,0,180,1215,11, +1,867,0,183,1, +-1,3,74,0,180, +3,109,0,180,3, +82,0,180,3,55, +0,180,3,117,0, +180,3,90,0,180, +3,98,0,180,3, +71,0,180,3,106, +0,180,3,79,0, +180,3,52,0,180, +3,114,0,180,3, +87,0,180,3,122, +0,180,3,95,0, +180,3,68,0,180, +3,103,0,180,3, +76,0,180,3,49, +0,180,3,111,0, +180,3,84,0,180, +3,57,0,180,3, +119,0,180,3,65, +0,180,3,100,0, +180,3,73,0,180, +3,108,0,180,3, +81,0,180,3,54, +0,180,3,116,0, +180,3,89,0,180, +1216,11,1,867,0, +183,1,-1,3,88, +0,180,3,69,0, +180,3,104,0,180, +3,77,0,180,3, +50,0,180,3,112, +0,180,3,85,0, +180,3,120,0,180, +3,66,0,180,3, +101,0,180,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +180,3,87,0,180, +3,122,0,180,3, +95,0,180,3,68, +0,180,3,103,0, +180,3,76,0,180, +3,49,0,180,3, +111,0,180,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,180,3,73, +0,180,3,108,0, +180,3,81,0,180, +3,54,0,180,3, +116,0,180,3,89, +0,180,1217,11,1, +867,0,183,1,-1, +3,68,0,180,3, +103,0,180,3,76, +0,180,3,49,0, +180,3,111,0,180, +3,84,0,180,3, +57,0,180,3,119, +0,180,3,65,0, +180,3,100,0,180, +3,73,0,180,3, +108,0,180,3,81, +0,180,3,54,0, +180,3,116,0,1218, +12,1,15030,1219,5, +63,3,97,0,180, +3,70,0,180,3, +105,0,180,3,78, +0,180,3,51,0, +180,3,113,0,180, +3,86,0,180,3, +121,0,180,3,67, +0,180,3,102,0, +180,3,75,0,180, +3,48,0,180,3, +110,0,180,3,83, +0,180,3,56,0, +180,3,118,0,180, +3,99,0,180,3, +72,0,180,3,107, +0,180,3,80,0, +180,3,53,0,180, +3,115,0,180,3, +88,0,180,3,69, +0,180,3,104,0, +180,3,77,0,180, +3,50,0,180,3, +112,0,180,3,85, +0,180,3,120,0, +180,3,66,0,180, +3,101,0,180,3, +74,0,180,3,109, +0,180,3,82,0, +180,3,55,0,180, +3,117,0,180,3, +90,0,180,3,98, +0,180,3,71,0, +180,3,106,0,180, +3,79,0,180,3, +52,0,180,3,114, +0,180,3,87,0, +180,3,122,0,180, +3,95,0,1220,12, +1,15066,1221,5,63, +3,97,0,1222,12, +1,15133,1223,5,63, +3,97,0,180,3, +70,0,180,3,105, +0,180,3,78,0, +180,3,51,0,180, +3,113,0,180,3, +86,0,180,3,121, +0,180,3,67,0, +180,3,102,0,180, +3,75,0,180,3, +48,0,180,3,110, +0,180,3,83,0, +180,3,56,0,180, +3,118,0,180,3, +99,0,180,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,180,3,88, +0,180,3,69,0, +180,3,104,0,180, +3,77,0,180,3, +50,0,180,3,112, +0,180,3,85,0, +180,3,120,0,180, +3,66,0,180,3, +101,0,180,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +180,3,87,0,180, +3,122,0,180,3, +95,0,180,3,68, +0,180,3,103,0, +180,3,76,0,180, +3,49,0,180,3, +111,0,180,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,180,3,73, +0,180,3,108,0, +180,3,81,0,180, +3,54,0,180,3, +116,0,1224,12,1, +15226,1225,5,63,3, +97,0,180,3,70, +0,180,3,105,0, +180,3,78,0,180, +3,51,0,180,3, +113,0,180,3,86, +0,180,3,121,0, +180,3,67,0,180, +3,102,0,180,3, +75,0,180,3,48, +0,180,3,110,0, +180,3,83,0,180, +3,56,0,180,3, +118,0,180,3,99, +0,180,3,72,0, +180,3,107,0,180, +3,80,0,180,3, +53,0,180,3,115, +0,180,3,88,0, +180,3,69,0,180, +3,104,0,180,3, +77,0,180,3,50, +0,180,3,112,0, +180,3,85,0,180, +3,120,0,180,3, +66,0,180,3,101, +0,180,3,74,0, +180,3,109,0,180, +3,82,0,180,3, +55,0,180,3,117, +0,180,3,90,0, +180,3,98,0,180, +3,71,0,180,3, +106,0,180,3,79, +0,180,3,52,0, +180,3,114,0,180, +3,87,0,180,3, +122,0,180,3,95, +0,1226,12,1,15262, +1227,5,63,3,97, +0,180,3,70,0, +180,3,105,0,180, +3,78,0,180,3, +51,0,180,3,113, +0,180,3,86,0, +180,3,121,0,180, +3,67,0,180,3, +102,0,180,3,75, +0,180,3,48,0, +180,3,110,0,180, +3,83,0,180,3, +56,0,180,3,118, +0,180,3,99,0, +180,3,72,0,180, +3,107,0,180,3, +80,0,180,3,53, +0,180,3,115,0, +180,3,88,0,180, +3,69,0,180,3, +104,0,180,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,180,3,66, +0,180,3,101,0, +180,3,74,0,180, +3,109,0,180,3, +82,0,180,3,55, +0,180,3,117,0, +180,3,90,0,180, +3,98,0,180,3, +71,0,180,3,106, +0,180,3,79,0, +180,3,52,0,180, +3,114,0,1228,12, +1,15347,1229,5,63, +3,97,0,180,3, +70,0,180,3,105, +0,180,3,78,0, +180,3,51,0,180, +3,113,0,180,3, +86,0,180,3,121, +0,180,3,67,0, +180,3,102,0,180, +3,75,0,180,3, +48,0,180,3,110, +0,180,3,83,0, +180,3,56,0,180, +3,118,0,180,3, +99,0,180,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,180,3,88, +0,180,3,69,0, +180,3,104,0,180, +3,77,0,180,3, +50,0,180,3,112, +0,180,3,85,0, +180,3,120,0,180, +3,66,0,180,3, +101,0,180,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +180,3,87,0,180, +3,122,0,180,3, +95,0,180,3,68, +0,180,3,103,0, +180,3,76,0,180, +3,49,0,180,3, +111,0,1230,12,1, +15435,1231,5,63,3, +97,0,180,3,70, +0,180,3,105,0, +180,3,78,0,180, +3,51,0,180,3, +113,0,180,3,86, +0,180,3,121,0, +180,3,67,0,180, +3,102,0,180,3, +75,0,180,3,48, +0,180,3,110,0, +180,3,83,0,180, +3,56,0,180,3, +118,0,180,3,99, +0,180,3,72,0, +180,3,107,0,180, +3,80,0,180,3, +53,0,180,3,115, +0,180,3,88,0, +180,3,69,0,180, +3,104,0,180,3, +77,0,180,3,50, +0,180,3,112,0, +180,3,85,0,180, +3,120,0,180,3, +66,0,180,3,101, +0,180,3,74,0, +180,3,109,0,180, +3,82,0,180,3, +55,0,180,3,117, +0,180,3,90,0, +180,3,98,0,180, +3,71,0,180,3, +106,0,180,3,79, +0,180,3,52,0, +180,3,114,0,180, +3,87,0,180,3, +122,0,180,3,95, +0,180,3,68,0, +180,3,103,0,180, +3,76,0,180,3, +49,0,180,3,111, +0,180,3,84,0, +180,3,57,0,180, +3,119,0,180,3, +65,0,180,3,100, +0,180,3,73,0, +180,3,108,0,180, +3,81,0,180,3, +54,0,180,3,116, +0,1232,12,1,15528, +1233,5,63,3,97, +0,180,3,70,0, +180,3,105,0,180, +3,78,0,180,3, +51,0,180,3,113, +0,180,3,86,0, +180,3,121,0,180, +3,67,0,180,3, +102,0,180,3,75, +0,180,3,48,0, +180,3,110,0,180, +3,83,0,180,3, +56,0,180,3,118, +0,180,3,99,0, +180,3,72,0,180, +3,107,0,180,3, +80,0,180,3,53, +0,180,3,115,0, +180,3,88,0,180, +3,69,0,180,3, +104,0,180,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,180,3,66, +0,180,3,101,0, +180,3,74,0,180, +3,109,0,180,3, +82,0,180,3,55, +0,180,3,117,0, +180,3,90,0,180, +3,98,0,180,3, +71,0,180,3,106, +0,180,3,79,0, +180,3,52,0,180, +3,114,0,180,3, +87,0,180,3,122, +0,180,3,95,0, +1234,12,1,15564,1235, +5,63,3,97,0, +180,3,70,0,180, +3,105,0,180,3, +78,0,180,3,51, +0,180,3,113,0, +180,3,86,0,180, +3,121,0,180,3, +67,0,180,3,102, +0,180,3,75,0, +180,3,48,0,180, +3,110,0,180,3, +83,0,180,3,56, +0,180,3,118,0, +180,3,99,0,180, +3,72,0,180,3, +107,0,180,3,80, +0,180,3,53,0, +180,3,115,0,180, +3,88,0,180,3, +69,0,180,3,104, +0,180,3,77,0, +180,3,50,0,180, +3,112,0,180,3, +85,0,180,3,120, +0,180,3,66,0, +180,3,101,0,180, +3,74,0,180,3, +109,0,180,3,82, +0,180,3,55,0, +180,3,117,0,180, +3,90,0,180,3, +98,0,180,3,71, +0,180,3,106,0, +180,3,79,0,180, +3,52,0,180,3, +114,0,180,3,87, +0,180,3,122,0, +180,3,95,0,180, +3,68,0,180,3, +103,0,180,3,76, +0,180,3,49,0, +180,3,111,0,180, +3,84,0,180,3, +57,0,180,3,119, +0,180,3,65,0, +180,3,100,0,180, +3,73,0,180,3, +108,0,180,3,81, +0,180,3,54,0, +180,3,116,0,1236, +12,1,15657,1237,5, +63,3,97,0,1238, +12,1,15724,1239,5, +63,3,97,0,180, +3,70,0,180,3, +105,0,180,3,78, +0,180,3,51,0, +180,3,113,0,180, +3,86,0,180,3, +121,0,180,3,67, +0,180,3,102,0, +180,3,75,0,180, +3,48,0,180,3, +110,0,180,3,83, +0,180,3,56,0, +180,3,118,0,180, +3,99,0,180,3, +72,0,180,3,107, +0,180,3,80,0, +180,3,53,0,180, +3,115,0,180,3, +88,0,180,3,69, +0,180,3,104,0, +180,3,77,0,180, +3,50,0,180,3, +112,0,180,3,85, +0,180,3,120,0, +180,3,66,0,180, +3,101,0,180,3, +74,0,180,3,109, +0,180,3,82,0, +180,3,55,0,180, +3,117,0,180,3, +90,0,180,3,98, +0,180,3,71,0, +180,3,106,0,180, +3,79,0,180,3, +52,0,180,3,114, +0,1240,12,1,15809, +1241,5,63,3,97, +0,180,3,70,0, +180,3,105,0,180, +3,78,0,180,3, +51,0,180,3,113, +0,180,3,86,0, +180,3,121,0,180, +3,67,0,180,3, +102,0,180,3,75, +0,180,3,48,0, +180,3,110,0,180, +3,83,0,180,3, +56,0,180,3,118, +0,180,3,99,0, +180,3,72,0,180, +3,107,0,180,3, +80,0,180,3,53, +0,180,3,115,0, +180,3,88,0,180, +3,69,0,180,3, +104,0,180,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,180,3,66, +0,180,3,101,0, +180,3,74,0,180, +3,109,0,180,3, +82,0,180,3,55, +0,180,3,117,0, +180,3,90,0,180, +3,98,0,180,3, +71,0,180,3,106, +0,180,3,79,0, +180,3,52,0,180, +3,114,0,180,3, +87,0,180,3,122, +0,180,3,95,0, +180,3,68,0,180, +3,103,0,1242,12, +1,15896,1243,5,63, +3,97,0,180,3, +70,0,180,3,105, +0,180,3,78,0, +180,3,51,0,180, +3,113,0,180,3, +86,0,180,3,121, +0,180,3,67,0, +180,3,102,0,180, +3,75,0,180,3, +48,0,180,3,110, +0,180,3,83,0, +180,3,56,0,180, +3,118,0,180,3, +99,0,180,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,180,3,88, +0,180,3,69,0, +180,3,104,0,180, +3,77,0,180,3, +50,0,180,3,112, +0,180,3,85,0, +180,3,120,0,180, +3,66,0,180,3, +101,0,1244,12,1, +15976,1245,5,63,3, +97,0,180,3,70, +0,180,3,105,0, +180,3,78,0,180, +3,51,0,180,3, +113,0,180,3,86, +0,180,3,121,0, +180,3,67,0,180, +3,102,0,180,3, +75,0,180,3,48, +0,180,3,110,0, +180,3,83,0,180, +3,56,0,180,3, +118,0,180,3,99, +0,180,3,72,0, +180,3,107,0,180, +3,80,0,180,3, +53,0,180,3,115, +0,180,3,88,0, +180,3,69,0,180, +3,104,0,180,3, +77,0,180,3,50, +0,180,3,112,0, +180,3,85,0,180, +3,120,0,180,3, +66,0,180,3,101, +0,180,3,74,0, +180,3,109,0,180, +3,82,0,180,3, +55,0,180,3,117, +0,180,3,90,0, +180,3,98,0,180, +3,71,0,180,3, +106,0,180,3,79, +0,180,3,52,0, +180,3,114,0,180, +3,87,0,180,3, +122,0,180,3,95, +0,180,3,68,0, +180,3,103,0,180, +3,76,0,180,3, +49,0,180,3,111, +0,180,3,84,0, +180,3,57,0,180, +3,119,0,180,3, +65,0,180,3,100, +0,180,3,73,0, +180,3,108,0,180, +3,81,0,180,3, +54,0,180,3,116, +0,1246,12,1,16069, +1247,5,63,3,97, +0,180,3,70,0, +180,3,105,0,180, +3,78,0,180,3, +51,0,180,3,113, +0,180,3,86,0, +180,3,121,0,180, +3,67,0,180,3, +102,0,180,3,75, +0,180,3,48,0, +180,3,110,0,180, +3,83,0,180,3, +56,0,180,3,118, +0,180,3,99,0, +180,3,72,0,180, +3,107,0,180,3, +80,0,180,3,53, +0,180,3,115,0, +180,3,88,0,180, +3,69,0,180,3, +104,0,180,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,180,3,66, +0,180,3,101,0, +180,3,74,0,180, +3,109,0,180,3, +82,0,180,3,55, +0,180,3,117,0, +180,3,90,0,180, +3,98,0,180,3, +71,0,180,3,106, +0,180,3,79,0, +180,3,52,0,180, +3,114,0,180,3, +87,0,180,3,122, +0,180,3,95,0, +180,3,68,0,180, +3,103,0,180,3, +76,0,180,3,49, +0,180,3,111,0, +180,3,84,0,180, +3,57,0,180,3, +119,0,180,3,65, +0,180,3,100,0, +180,3,73,0,180, +3,108,0,180,3, +81,0,180,3,54, +0,180,3,116,0, +180,3,89,0,180, +1248,11,1,643,0, +1249,4,46,78,0, 79,0,84,0,95, 0,65,0,84,0, 95,0,82,0,79, @@ -11266,8473 +17022,2717 @@ public class yyLSLTokens : YyLexer { 84,0,95,0,69, 0,86,0,69,0, 78,0,84,0,1, --1,3,117,0,345, -3,118,0,345,3, -119,0,345,3,120, -0,345,3,121,0, -345,3,122,0,345, -3,48,0,345,3, -49,0,345,3,50, -0,345,3,51,0, -345,3,52,0,345, -3,53,0,345,3, -54,0,345,3,55, -0,345,3,56,0, -345,3,57,0,345, -3,65,0,345,3, -66,0,345,3,67, -0,345,3,68,0, -345,3,69,0,345, -3,70,0,345,3, -71,0,345,3,72, -0,345,3,73,0, -345,3,74,0,345, -3,75,0,345,3, -76,0,345,3,77, -0,345,3,78,0, -345,3,79,0,345, -3,80,0,345,3, -81,0,345,3,82, -0,345,3,83,0, -345,3,84,0,345, -3,85,0,345,3, -86,0,345,3,87, -0,345,3,88,0, -345,3,89,0,345, -3,90,0,345,3, -95,0,345,3,97, -0,345,3,98,0, -345,3,99,0,345, -3,100,0,345,3, -101,0,345,3,102, -0,345,3,103,0, -345,3,104,0,345, -3,105,0,345,3, -106,0,345,3,107, -0,345,3,108,0, -345,947,11,1,867, -0,348,1,-1,3, -102,0,345,3,103, -0,345,3,104,0, -345,3,105,0,345, -3,106,0,345,3, -107,0,345,3,108, -0,345,948,11,1, -867,0,348,1,-1, -3,104,0,345,3, -105,0,345,3,106, -0,345,3,107,0, -345,3,108,0,345, -949,11,1,867,0, -348,1,-1,3,115, -0,345,3,116,0, -345,3,117,0,345, -3,118,0,345,3, -119,0,345,3,120, -0,345,3,121,0, -345,3,122,0,345, -3,48,0,345,3, -49,0,345,3,50, -0,345,3,51,0, -345,3,52,0,345, -3,53,0,345,3, -54,0,345,3,55, -0,345,3,56,0, -345,3,57,0,345, -3,65,0,345,3, -66,0,345,3,67, -0,345,3,68,0, -345,3,69,0,345, -3,70,0,345,3, -71,0,345,3,72, -0,345,3,73,0, -345,3,74,0,345, -3,75,0,345,3, -76,0,345,3,77, -0,345,3,78,0, -345,3,79,0,345, -3,80,0,345,3, -81,0,345,3,82, -0,345,3,83,0, -345,3,84,0,345, -3,85,0,345,3, -86,0,345,3,87, -0,345,3,88,0, -345,3,89,0,345, -3,90,0,345,3, -95,0,345,3,97, -0,345,3,98,0, -345,3,99,0,345, -3,100,0,345,3, -101,0,345,3,102, -0,345,3,103,0, -345,3,104,0,345, -3,105,0,345,3, -106,0,345,3,107, -0,345,3,108,0, -345,950,11,1,867, -0,348,1,-1,3, -98,0,345,3,99, -0,345,3,100,0, -345,3,101,0,345, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -345,3,106,0,345, -3,107,0,345,3, -108,0,345,951,11, -1,867,0,348,1, --1,3,117,0,345, -3,118,0,345,3, -119,0,345,3,120, -0,345,3,121,0, -345,3,122,0,345, -3,48,0,345,3, -49,0,345,3,50, -0,345,3,51,0, -345,3,52,0,345, -3,53,0,345,3, -54,0,345,3,55, -0,345,3,56,0, -345,3,57,0,345, -3,65,0,345,3, -66,0,345,3,67, -0,345,3,68,0, -345,3,69,0,345, -3,70,0,345,3, -71,0,345,3,72, -0,345,3,73,0, -345,3,74,0,345, -3,75,0,345,3, -76,0,345,3,77, -0,345,3,78,0, -345,3,79,0,345, -3,80,0,345,3, -81,0,345,3,82, -0,345,3,83,0, -345,3,84,0,345, -3,85,0,345,3, -86,0,345,3,87, -0,345,3,88,0, -345,3,89,0,345, -3,90,0,345,3, -95,0,345,3,97, -0,345,3,98,0, -345,3,99,0,345, -3,100,0,345,3, -101,0,345,3,102, -0,345,3,103,0, -345,3,104,0,345, -3,105,0,345,3, -106,0,345,3,107, -0,345,3,108,0, -345,952,11,1,867, -0,348,1,-1,3, -97,0,345,3,98, -0,345,3,99,0, -345,3,100,0,345, -3,101,0,345,3, -102,0,345,3,103, -0,345,3,104,0, -345,3,105,0,345, -3,106,0,345,3, -107,0,345,3,108, -0,345,953,11,1, -867,0,348,1,-1, -3,117,0,345,3, -118,0,345,3,119, -0,345,3,120,0, -345,3,121,0,345, -3,122,0,345,3, -48,0,345,3,49, -0,345,3,50,0, -345,3,51,0,345, -3,52,0,345,3, -53,0,345,3,54, -0,345,3,55,0, -345,3,56,0,345, -3,57,0,345,3, -65,0,345,3,66, -0,345,3,67,0, -345,3,68,0,345, -3,69,0,345,3, -70,0,345,3,71, -0,345,3,72,0, -345,3,73,0,345, -3,74,0,345,3, -75,0,345,3,76, -0,345,3,77,0, -345,3,78,0,345, -3,79,0,345,3, -80,0,345,3,81, -0,345,3,82,0, -345,3,83,0,345, -3,84,0,345,3, -85,0,345,3,86, -0,345,3,87,0, -345,3,88,0,345, -3,89,0,345,3, -90,0,345,3,95, -0,345,3,97,0, -345,3,98,0,345, -3,99,0,345,3, -100,0,345,3,101, -0,345,3,102,0, -345,3,103,0,345, -3,104,0,345,3, -105,0,345,3,106, -0,345,3,107,0, -345,3,108,0,345, -954,11,1,867,0, -348,1,-1,3,112, -0,345,3,113,0, -345,3,114,0,345, -3,115,0,345,3, -116,0,345,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,345,3, -98,0,345,3,99, -0,345,3,100,0, -345,3,101,0,345, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -345,3,106,0,345, -3,107,0,345,3, -108,0,345,955,11, -1,867,0,348,1, --1,3,115,0,345, -3,116,0,956,12, -1,5675,957,5,63, -3,109,0,345,3, -110,0,345,3,111, -0,345,3,112,0, -345,3,113,0,345, -3,114,0,345,3, -115,0,345,3,116, -0,345,3,117,0, -345,3,118,0,345, -3,119,0,345,3, -120,0,345,3,121, -0,345,3,122,0, -345,3,48,0,345, -3,49,0,345,3, -50,0,345,3,51, -0,345,3,52,0, -345,3,53,0,345, -3,54,0,345,3, -55,0,345,3,56, -0,345,3,57,0, -345,3,65,0,345, -3,66,0,345,3, -67,0,345,3,68, -0,345,3,69,0, -345,3,70,0,345, -3,71,0,345,3, -72,0,345,3,73, -0,345,3,74,0, -345,3,75,0,345, -3,76,0,345,3, -77,0,345,3,78, -0,345,3,79,0, -345,3,80,0,345, -3,81,0,345,3, -82,0,345,3,83, -0,345,3,84,0, -345,3,85,0,345, -3,86,0,345,3, -87,0,345,3,88, -0,345,3,89,0, -345,3,90,0,345, -3,95,0,345,3, -97,0,958,12,1, -5718,959,5,63,3, -109,0,345,3,110, -0,345,3,111,0, -345,3,112,0,345, -3,113,0,345,3, -114,0,960,12,1, -5751,961,5,63,3, -109,0,345,3,110, -0,345,3,111,0, -345,3,112,0,345, -3,113,0,345,3, -114,0,345,3,115, -0,345,3,116,0, -345,3,117,0,345, -3,118,0,345,3, -119,0,345,3,120, -0,345,3,121,0, -345,3,122,0,345, -3,48,0,345,3, -49,0,345,3,50, -0,345,3,51,0, -345,3,52,0,345, -3,53,0,345,3, -54,0,345,3,55, -0,345,3,56,0, -345,3,57,0,345, -3,65,0,345,3, -66,0,345,3,67, -0,345,3,68,0, -345,3,69,0,345, -3,70,0,345,3, -71,0,345,3,72, -0,345,3,73,0, -345,3,74,0,345, -3,75,0,345,3, -76,0,345,3,77, -0,345,3,78,0, -345,3,79,0,345, -3,80,0,345,3, -81,0,345,3,82, -0,345,3,83,0, -345,3,84,0,345, -3,85,0,345,3, -86,0,345,3,87, -0,345,3,88,0, -345,3,89,0,345, -3,90,0,345,3, -95,0,345,3,97, -0,345,3,98,0, -345,3,99,0,345, -3,100,0,345,3, -101,0,345,3,102, -0,345,3,103,0, -962,12,1,5800,963, -5,63,3,109,0, -345,3,110,0,345, -3,111,0,345,3, -112,0,345,3,113, -0,345,3,114,0, -345,3,115,0,345, -3,116,0,345,3, -117,0,345,3,118, -0,345,3,119,0, -345,3,120,0,345, -3,121,0,345,3, -122,0,345,3,48, -0,345,3,49,0, -345,3,50,0,345, -3,51,0,345,3, -52,0,345,3,53, -0,345,3,54,0, -345,3,55,0,345, -3,56,0,345,3, -57,0,345,3,65, -0,345,3,66,0, -345,3,67,0,345, -3,68,0,345,3, -69,0,345,3,70, -0,345,3,71,0, -345,3,72,0,345, -3,73,0,345,3, -74,0,345,3,75, -0,345,3,76,0, -345,3,77,0,345, -3,78,0,345,3, -79,0,345,3,80, -0,345,3,81,0, -345,3,82,0,345, -3,83,0,345,3, -84,0,345,3,85, -0,345,3,86,0, -345,3,87,0,345, -3,88,0,345,3, -89,0,345,3,90, -0,345,3,95,0, -345,3,97,0,345, -3,98,0,345,3, -99,0,345,3,100, -0,345,3,101,0, -964,12,1,5847,965, -5,63,3,109,0, -345,3,110,0,345, -3,111,0,345,3, -112,0,345,3,113, -0,345,3,114,0, -345,3,115,0,345, -3,116,0,966,12, -1,5882,967,5,63, -3,109,0,345,3, -110,0,345,3,111, -0,345,3,112,0, -345,3,113,0,345, -3,114,0,345,3, -115,0,345,3,116, -0,345,3,117,0, -345,3,118,0,345, -3,119,0,345,3, -120,0,345,3,121, -0,345,3,122,0, -345,3,48,0,345, -3,49,0,345,3, -50,0,345,3,51, -0,345,3,52,0, -345,3,53,0,345, -3,54,0,345,3, -55,0,345,3,56, -0,345,3,57,0, -345,3,65,0,345, -3,66,0,345,3, -67,0,345,3,68, -0,345,3,69,0, -345,3,70,0,345, -3,71,0,345,3, -72,0,345,3,73, -0,345,3,74,0, -345,3,75,0,345, -3,76,0,345,3, -77,0,345,3,78, -0,345,3,79,0, -345,3,80,0,345, -3,81,0,345,3, -82,0,345,3,83, -0,345,3,84,0, -345,3,85,0,345, -3,86,0,345,3, -87,0,345,3,88, -0,345,3,89,0, -345,3,90,0,345, -3,95,0,345,3, -97,0,345,3,98, -0,345,3,99,0, -345,3,100,0,345, -3,101,0,345,3, -102,0,345,3,103, -0,345,3,104,0, -345,3,105,0,345, -3,106,0,345,3, -107,0,345,3,108, -0,345,968,11,1, -664,0,969,4,38, -78,0,79,0,84, -0,95,0,65,0, -84,0,95,0,84, -0,65,0,82,0, -71,0,69,0,84, -0,95,0,69,0, -86,0,69,0,78, -0,84,0,1,-1, -3,117,0,345,3, -118,0,345,3,119, -0,345,3,120,0, -345,3,121,0,345, -3,122,0,345,3, -48,0,345,3,49, -0,345,3,50,0, -345,3,51,0,345, -3,52,0,345,3, -53,0,345,3,54, -0,345,3,55,0, -345,3,56,0,345, -3,57,0,345,3, -65,0,345,3,66, -0,345,3,67,0, -345,3,68,0,345, -3,69,0,345,3, -70,0,345,3,71, -0,345,3,72,0, -345,3,73,0,345, -3,74,0,345,3, -75,0,345,3,76, -0,345,3,77,0, -345,3,78,0,345, -3,79,0,345,3, -80,0,345,3,81, -0,345,3,82,0, -345,3,83,0,345, -3,84,0,345,3, -85,0,345,3,86, -0,345,3,87,0, -345,3,88,0,345, -3,89,0,345,3, -90,0,345,3,95, -0,345,3,97,0, -345,3,98,0,345, -3,99,0,345,3, -100,0,345,3,101, -0,345,3,102,0, -345,3,103,0,345, -3,104,0,345,3, -105,0,345,3,106, -0,345,3,107,0, -345,3,108,0,345, -970,11,1,867,0, -348,1,-1,3,102, -0,345,3,103,0, -345,3,104,0,345, -3,105,0,345,3, -106,0,345,3,107, -0,345,3,108,0, -345,971,11,1,867, -0,348,1,-1,3, -104,0,345,3,105, -0,345,3,106,0, -345,3,107,0,345, -3,108,0,345,972, -11,1,867,0,348, -1,-1,3,115,0, -345,3,116,0,345, -3,117,0,345,3, -118,0,345,3,119, -0,345,3,120,0, -345,3,121,0,345, -3,122,0,345,3, -48,0,345,3,49, -0,345,3,50,0, -345,3,51,0,345, -3,52,0,345,3, -53,0,345,3,54, -0,345,3,55,0, -345,3,56,0,345, -3,57,0,345,3, -65,0,345,3,66, -0,345,3,67,0, -345,3,68,0,345, -3,69,0,345,3, -70,0,345,3,71, -0,345,3,72,0, -345,3,73,0,345, -3,74,0,345,3, -75,0,345,3,76, -0,345,3,77,0, -345,3,78,0,345, -3,79,0,345,3, -80,0,345,3,81, -0,345,3,82,0, -345,3,83,0,345, -3,84,0,345,3, -85,0,345,3,86, -0,345,3,87,0, -345,3,88,0,345, -3,89,0,345,3, -90,0,345,3,95, -0,345,3,97,0, -345,3,98,0,345, -3,99,0,345,3, -100,0,345,3,101, -0,345,3,102,0, -345,3,103,0,345, -3,104,0,345,3, -105,0,345,3,106, -0,345,3,107,0, -345,3,108,0,345, -973,11,1,867,0, -348,1,-1,3,98, -0,345,3,99,0, -345,3,100,0,345, -3,101,0,345,3, -102,0,345,3,103, -0,345,3,104,0, -345,3,105,0,345, -3,106,0,345,3, -107,0,345,3,108, -0,345,974,11,1, -867,0,348,1,-1, -3,117,0,345,3, -118,0,345,3,119, -0,345,3,120,0, -345,3,121,0,345, -3,122,0,345,3, -48,0,345,3,49, -0,345,3,50,0, -345,3,51,0,345, -3,52,0,345,3, -53,0,345,3,54, -0,345,3,55,0, -345,3,56,0,345, -3,57,0,345,3, -65,0,345,3,66, -0,345,3,67,0, -345,3,68,0,345, -3,69,0,345,3, -70,0,345,3,71, -0,345,3,72,0, -345,3,73,0,345, -3,74,0,345,3, -75,0,345,3,76, -0,345,3,77,0, -345,3,78,0,345, -3,79,0,345,3, -80,0,345,3,81, -0,345,3,82,0, -345,3,83,0,345, -3,84,0,345,3, -85,0,345,3,86, -0,345,3,87,0, -345,3,88,0,345, -3,89,0,345,3, -90,0,345,3,95, -0,345,3,97,0, -345,3,98,0,345, -3,99,0,345,3, -100,0,345,3,101, -0,345,3,102,0, -345,3,103,0,345, -3,104,0,345,3, -105,0,345,3,106, -0,345,3,107,0, -345,3,108,0,345, -975,11,1,867,0, -348,1,-1,3,97, -0,345,3,98,0, -345,3,99,0,345, -3,100,0,345,3, -101,0,345,3,102, -0,345,3,103,0, -345,3,104,0,345, -3,105,0,345,3, -106,0,345,3,107, -0,345,3,108,0, -345,976,11,1,867, -0,348,1,-1,3, -117,0,345,3,118, -0,345,3,119,0, -345,3,120,0,345, -3,121,0,345,3, -122,0,345,3,48, -0,345,3,49,0, -345,3,50,0,345, -3,51,0,345,3, -52,0,345,3,53, -0,345,3,54,0, -345,3,55,0,345, -3,56,0,345,3, -57,0,345,3,65, -0,345,3,66,0, -345,3,67,0,345, -3,68,0,345,3, -69,0,345,3,70, -0,345,3,71,0, -345,3,72,0,345, -3,73,0,345,3, -74,0,345,3,75, -0,345,3,76,0, -345,3,77,0,345, -3,78,0,345,3, -79,0,345,3,80, -0,345,3,81,0, -345,3,82,0,345, -3,83,0,345,3, -84,0,345,3,85, -0,345,3,86,0, -345,3,87,0,345, -3,88,0,345,3, -89,0,345,3,90, -0,345,3,95,0, -345,3,97,0,345, -3,98,0,345,3, -99,0,345,3,100, -0,345,3,101,0, -345,3,102,0,345, -3,103,0,345,3, -104,0,345,3,105, -0,345,3,106,0, -345,3,107,0,345, -3,108,0,345,977, -11,1,867,0,348, -1,-1,3,98,0, -345,3,99,0,345, -3,100,0,345,3, -101,0,345,3,102, -0,345,3,103,0, -345,3,104,0,345, -3,105,0,345,3, -106,0,345,3,107, -0,345,3,108,0, -345,978,11,1,867, -0,348,1,-1,3, -97,0,345,3,98, -0,345,3,99,0, -345,3,100,0,345, -3,101,0,345,3, -102,0,345,3,103, -0,345,3,104,0, -345,3,105,0,345, -3,106,0,345,3, -107,0,345,3,108, -0,345,979,11,1, -867,0,348,1,-1, -3,117,0,345,3, -118,0,345,3,119, -0,345,3,120,0, -345,3,121,0,345, -3,122,0,345,3, -48,0,345,3,49, -0,345,3,50,0, -345,3,51,0,345, -3,52,0,345,3, -53,0,345,3,54, -0,345,3,55,0, -345,3,56,0,345, -3,57,0,345,3, -65,0,345,3,66, -0,345,3,67,0, -345,3,68,0,345, -3,69,0,345,3, -70,0,345,3,71, -0,345,3,72,0, -345,3,73,0,345, -3,74,0,345,3, -75,0,345,3,76, -0,345,3,77,0, -345,3,78,0,345, -3,79,0,345,3, -80,0,345,3,81, -0,345,3,82,0, -345,3,83,0,345, -3,84,0,345,3, -85,0,345,3,86, -0,345,3,87,0, -345,3,88,0,345, -3,89,0,345,3, -90,0,345,3,95, -0,980,12,1,6761, -981,5,63,3,109, -0,345,3,110,0, -345,3,111,0,345, -3,112,0,345,3, -113,0,345,3,114, -0,345,3,115,0, -982,12,1,6795,983, -5,63,3,109,0, -345,3,110,0,345, -3,111,0,345,3, -112,0,345,3,113, -0,345,3,114,0, -345,3,115,0,345, -3,116,0,345,3, -117,0,345,3,118, -0,345,3,119,0, -345,3,120,0,345, -3,121,0,345,3, -122,0,345,3,48, -0,345,3,49,0, -345,3,50,0,345, -3,51,0,345,3, -52,0,345,3,53, -0,345,3,54,0, -345,3,55,0,345, -3,56,0,345,3, -57,0,345,3,65, -0,345,3,66,0, -345,3,67,0,345, -3,68,0,345,3, -69,0,345,3,70, -0,345,3,71,0, -345,3,72,0,345, -3,73,0,345,3, -74,0,345,3,75, -0,345,3,76,0, -345,3,77,0,345, -3,78,0,345,3, -79,0,345,3,80, -0,345,3,81,0, -345,3,82,0,345, -3,83,0,345,3, -84,0,345,3,85, -0,345,3,86,0, -345,3,87,0,345, -3,88,0,345,3, -89,0,345,3,90, -0,345,3,95,0, -345,3,97,0,345, -3,98,0,345,3, -99,0,345,3,100, -0,345,3,101,0, -984,12,1,6842,985, -5,63,3,109,0, -345,3,110,0,986, -12,1,6871,987,5, -63,3,109,0,345, -3,110,0,345,3, -111,0,345,3,112, -0,345,3,113,0, -345,3,114,0,345, -3,115,0,988,12, -1,6905,989,5,63, -3,109,0,345,3, -110,0,345,3,111, -0,990,12,1,6935, -991,5,63,3,109, -0,345,3,110,0, -345,3,111,0,345, -3,112,0,345,3, -113,0,345,3,114, -0,992,12,1,6968, -993,5,63,3,109, -0,345,3,110,0, -345,3,111,0,345, -3,112,0,345,3, -113,0,345,3,114, -0,345,3,115,0, -345,3,116,0,345, -3,117,0,345,3, -118,0,345,3,119, -0,345,3,120,0, -345,3,121,0,345, -3,122,0,345,3, -48,0,345,3,49, -0,345,3,50,0, -345,3,51,0,345, -3,52,0,345,3, -53,0,345,3,54, -0,345,3,55,0, -345,3,56,0,345, -3,57,0,345,3, -65,0,345,3,66, -0,345,3,67,0, -345,3,68,0,345, -3,69,0,345,3, -70,0,345,3,71, -0,345,3,72,0, -345,3,73,0,345, -3,74,0,345,3, -75,0,345,3,76, -0,345,3,77,0, -345,3,78,0,345, -3,79,0,345,3, -80,0,345,3,81, -0,345,3,82,0, -345,3,83,0,345, -3,84,0,345,3, -85,0,345,3,86, -0,345,3,87,0, -345,3,88,0,345, -3,89,0,345,3, -90,0,345,3,95, -0,345,3,97,0, -345,3,98,0,345, -3,99,0,345,3, -100,0,345,3,101, -0,345,3,102,0, -345,3,103,0,345, -3,104,0,345,3, -105,0,345,3,106, -0,345,3,107,0, -345,3,108,0,345, -994,11,1,630,0, -995,4,30,78,0, -79,0,95,0,83, -0,69,0,78,0, -83,0,79,0,82, -0,95,0,69,0, -86,0,69,0,78, -0,84,0,1,-1, -3,115,0,345,3, -116,0,345,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,345,3, -98,0,345,3,99, -0,345,3,100,0, -345,3,101,0,345, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -345,3,106,0,345, -3,107,0,345,3, -108,0,345,996,11, -1,867,0,348,1, --1,3,112,0,345, -3,113,0,345,3, -114,0,345,3,115, -0,345,3,116,0, -345,3,117,0,345, -3,118,0,345,3, -119,0,345,3,120, -0,345,3,121,0, -345,3,122,0,345, -3,48,0,345,3, -49,0,345,3,50, -0,345,3,51,0, -345,3,52,0,345, -3,53,0,345,3, -54,0,345,3,55, -0,345,3,56,0, -345,3,57,0,345, -3,65,0,345,3, -66,0,345,3,67, -0,345,3,68,0, -345,3,69,0,345, -3,70,0,345,3, -71,0,345,3,72, -0,345,3,73,0, -345,3,74,0,345, -3,75,0,345,3, -76,0,345,3,77, -0,345,3,78,0, -345,3,79,0,345, -3,80,0,345,3, -81,0,345,3,82, -0,345,3,83,0, -345,3,84,0,345, -3,85,0,345,3, -86,0,345,3,87, -0,345,3,88,0, -345,3,89,0,345, -3,90,0,345,3, -95,0,345,3,97, -0,345,3,98,0, -345,3,99,0,345, -3,100,0,345,3, -101,0,345,3,102, -0,345,3,103,0, -345,3,104,0,345, -3,105,0,345,3, -106,0,345,3,107, -0,345,3,108,0, -345,997,11,1,867, -0,348,1,-1,3, -116,0,345,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,345,3, -98,0,345,3,99, -0,345,3,100,0, -345,3,101,0,345, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -345,3,106,0,345, -3,107,0,345,3, -108,0,345,998,11, -1,867,0,348,1, --1,3,111,0,345, -3,112,0,345,3, -113,0,345,3,114, -0,345,3,115,0, -345,3,116,0,345, -3,117,0,345,3, -118,0,345,3,119, -0,345,3,120,0, -345,3,121,0,345, -3,122,0,345,3, -48,0,345,3,49, -0,345,3,50,0, -345,3,51,0,345, -3,52,0,345,3, -53,0,345,3,54, -0,345,3,55,0, -345,3,56,0,345, -3,57,0,345,3, -65,0,345,3,66, -0,345,3,67,0, -345,3,68,0,345, -3,69,0,345,3, -70,0,345,3,71, -0,345,3,72,0, -345,3,73,0,345, -3,74,0,345,3, -75,0,345,3,76, -0,345,3,77,0, -345,3,78,0,345, -3,79,0,345,3, -80,0,345,3,81, -0,345,3,82,0, -345,3,83,0,345, -3,84,0,345,3, -85,0,345,3,86, -0,345,3,87,0, -345,3,88,0,345, -3,89,0,345,3, -90,0,345,3,95, -0,345,3,97,0, -345,3,98,0,345, -3,99,0,345,3, -100,0,345,3,101, -0,345,3,102,0, -345,3,103,0,345, -3,104,0,345,3, -105,0,345,3,106, -0,345,3,107,0, -345,3,108,0,345, -999,11,1,867,0, -348,1,-1,3,102, -0,345,3,103,0, -345,3,104,0,345, -3,105,0,345,3, -106,0,345,3,107, -0,345,3,108,0, -345,1000,11,1,867, -0,348,1,-1,3, -116,0,345,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,345,3, -98,0,345,3,99, -0,345,3,100,0, -345,3,101,0,345, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -345,3,106,0,345, -3,107,0,345,3, -108,0,345,1001,11, -1,867,0,348,1, --1,3,97,0,345, -3,98,0,345,3, -99,0,345,3,100, -0,345,3,101,0, -345,3,102,0,345, -3,103,0,345,3, -104,0,345,3,105, -0,345,3,106,0, -345,3,107,0,345, -3,108,0,345,1002, -11,1,867,0,348, -1,-1,3,112,0, -345,3,113,0,345, -3,114,0,345,3, -115,0,345,3,116, -0,345,3,117,0, -345,3,118,0,345, -3,119,0,345,3, -120,0,345,3,121, -0,345,3,122,0, -345,3,48,0,345, -3,49,0,345,3, -50,0,345,3,51, -0,345,3,52,0, -345,3,53,0,345, -3,54,0,345,3, -55,0,345,3,56, -0,345,3,57,0, -345,3,65,0,345, -3,66,0,345,3, -67,0,345,3,68, -0,345,3,69,0, -345,3,70,0,345, -3,71,0,345,3, -72,0,345,3,73, -0,345,3,74,0, -345,3,75,0,345, -3,76,0,345,3, -77,0,345,3,78, -0,345,3,79,0, -345,3,80,0,345, -3,81,0,345,3, -82,0,345,3,83, -0,345,3,84,0, -345,3,85,0,345, -3,86,0,345,3, -87,0,345,3,88, -0,345,3,89,0, -345,3,90,0,345, -3,95,0,345,3, -97,0,345,3,98, -0,345,3,99,0, -345,3,100,0,345, -3,101,0,345,3, -102,0,345,3,103, -0,345,3,104,0, -345,3,105,0,345, -3,106,0,345,3, -107,0,345,3,108, -0,345,1003,11,1, -867,0,348,1,-1, -3,111,0,1004,12, -1,7726,1005,5,63, -3,109,0,345,3, -110,0,1006,12,1, -7755,1007,5,63,3, -109,0,345,3,110, -0,345,3,111,0, -345,3,112,0,345, -3,113,0,345,3, -114,0,345,3,115, -0,345,3,116,0, -345,3,117,0,345, -3,118,0,345,3, -119,0,345,3,120, -0,345,3,121,0, -345,3,122,0,345, -3,48,0,345,3, -49,0,345,3,50, -0,345,3,51,0, -345,3,52,0,345, -3,53,0,345,3, -54,0,345,3,55, -0,345,3,56,0, -345,3,57,0,345, -3,65,0,345,3, -66,0,345,3,67, -0,345,3,68,0, -345,3,69,0,345, -3,70,0,345,3, -71,0,345,3,72, -0,345,3,73,0, -345,3,74,0,345, -3,75,0,345,3, -76,0,345,3,77, -0,345,3,78,0, -345,3,79,0,345, -3,80,0,345,3, -81,0,345,3,82, -0,345,3,83,0, -345,3,84,0,345, -3,85,0,345,3, -86,0,345,3,87, -0,345,3,88,0, -345,3,89,0,345, -3,90,0,345,3, -95,0,1008,12,1, -7841,1009,5,63,3, -109,0,345,3,110, -0,345,3,111,0, -345,3,112,0,345, -3,113,0,345,3, -114,0,1010,12,1, -7874,1011,5,63,3, -109,0,345,3,110, -0,345,3,111,0, -345,3,112,0,345, -3,113,0,345,3, -114,0,345,3,115, -0,345,3,116,0, -345,3,117,0,345, -3,118,0,345,3, -119,0,345,3,120, -0,345,3,121,0, -345,3,122,0,345, -3,48,0,345,3, -49,0,345,3,50, -0,345,3,51,0, -345,3,52,0,345, -3,53,0,345,3, -54,0,345,3,55, -0,345,3,56,0, -345,3,57,0,345, -3,65,0,345,3, -66,0,345,3,67, -0,345,3,68,0, -345,3,69,0,345, -3,70,0,345,3, -71,0,345,3,72, -0,345,3,73,0, -345,3,74,0,345, -3,75,0,345,3, -76,0,345,3,77, -0,345,3,78,0, -345,3,79,0,345, -3,80,0,345,3, -81,0,345,3,82, -0,345,3,83,0, -345,3,84,0,345, -3,85,0,345,3, -86,0,345,3,87, -0,345,3,88,0, -345,3,89,0,345, -3,90,0,345,3, -95,0,345,3,97, -0,345,3,98,0, -345,3,99,0,345, -3,100,0,345,3, -101,0,1012,12,1, -7921,1013,5,63,3, -109,0,345,3,110, -0,345,3,111,0, -345,3,112,0,345, -3,113,0,345,3, -114,0,345,3,115, -0,345,3,116,0, -345,3,117,0,345, -3,118,0,345,3, -119,0,345,3,120, -0,345,3,121,0, -345,3,122,0,1014, -12,1,7962,1015,5, -63,3,109,0,345, -3,110,0,345,3, -111,0,345,3,112, -0,345,3,113,0, -345,3,114,0,345, -3,115,0,345,3, -116,0,345,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,345,3, -98,0,345,3,99, -0,345,3,100,0, -345,3,101,0,345, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -345,3,106,0,345, -3,107,0,345,3, -108,0,345,1016,11, -1,695,0,1017,4, -24,79,0,78,0, -95,0,82,0,69, -0,90,0,95,0, -69,0,86,0,69, -0,78,0,84,0, -1,-1,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,345,3, -98,0,345,3,99, -0,345,3,100,0, -345,3,101,0,345, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -345,3,106,0,345, -3,107,0,345,3, -108,0,345,1018,11, -1,867,0,348,1, --1,3,102,0,345, -3,103,0,345,3, -104,0,345,3,105, -0,345,3,106,0, -345,3,107,0,345, -3,108,0,345,1019, -11,1,867,0,348, -1,-1,3,115,0, -345,3,116,0,345, -3,117,0,345,3, -118,0,345,3,119, -0,345,3,120,0, -345,3,121,0,345, -3,122,0,345,3, -48,0,345,3,49, -0,345,3,50,0, -345,3,51,0,345, -3,52,0,345,3, -53,0,345,3,54, -0,345,3,55,0, -345,3,56,0,345, -3,57,0,345,3, -65,0,345,3,66, -0,345,3,67,0, -345,3,68,0,345, -3,69,0,345,3, -70,0,345,3,71, -0,345,3,72,0, -345,3,73,0,345, -3,74,0,345,3, -75,0,345,3,76, -0,345,3,77,0, -345,3,78,0,345, -3,79,0,345,3, -80,0,345,3,81, -0,345,3,82,0, -345,3,83,0,345, -3,84,0,345,3, -85,0,345,3,86, -0,345,3,87,0, -345,3,88,0,345, -3,89,0,345,3, -90,0,345,3,95, -0,345,3,97,0, -345,3,98,0,345, -3,99,0,345,3, -100,0,345,3,101, -0,345,3,102,0, -345,3,103,0,345, -3,104,0,345,3, -105,0,345,3,106, -0,345,3,107,0, -345,3,108,0,345, -1020,11,1,867,0, -348,1,-1,3,97, -0,345,3,98,0, -345,3,99,0,345, -3,100,0,345,3, -101,0,345,3,102, -0,345,3,103,0, -345,3,104,0,345, -3,105,0,345,3, -106,0,345,3,107, -0,345,3,108,0, -345,1021,11,1,867, -0,348,1,-1,3, -111,0,345,3,112, -0,345,3,113,0, -345,3,114,0,345, -3,115,0,345,3, -116,0,345,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,345,3, -98,0,1022,12,1, -8370,1023,5,63,3, -109,0,345,3,110, -0,345,3,111,0, -345,3,112,0,345, -3,113,0,345,3, -114,0,345,3,115, -0,345,3,116,0, -345,3,117,0,345, -3,118,0,345,3, -119,0,345,3,120, -0,345,3,121,0, -345,3,122,0,345, -3,48,0,345,3, -49,0,345,3,50, -0,345,3,51,0, -345,3,52,0,345, -3,53,0,345,3, -54,0,345,3,55, -0,345,3,56,0, -345,3,57,0,345, -3,65,0,345,3, -66,0,345,3,67, -0,345,3,68,0, -345,3,69,0,345, -3,70,0,345,3, -71,0,345,3,72, -0,345,3,73,0, -345,3,74,0,345, -3,75,0,345,3, -76,0,345,3,77, -0,345,3,78,0, -345,3,79,0,345, -3,80,0,345,3, -81,0,345,3,82, -0,345,3,83,0, -345,3,84,0,345, -3,85,0,345,3, -86,0,345,3,87, -0,345,3,88,0, -345,3,89,0,345, -3,90,0,345,3, -95,0,345,3,97, -0,345,3,98,0, -345,3,99,0,345, -3,100,0,345,3, -101,0,345,3,102, -0,345,3,103,0, -345,3,104,0,345, -3,105,0,345,3, -106,0,1024,12,1, -8422,1025,5,63,3, -109,0,345,3,110, -0,345,3,111,0, -345,3,112,0,345, -3,113,0,345,3, -114,0,345,3,115, -0,345,3,116,0, -345,3,117,0,345, -3,118,0,345,3, -119,0,345,3,120, -0,345,3,121,0, -345,3,122,0,345, -3,48,0,345,3, -49,0,345,3,50, -0,345,3,51,0, -345,3,52,0,345, -3,53,0,345,3, -54,0,345,3,55, -0,345,3,56,0, -345,3,57,0,345, -3,65,0,345,3, -66,0,345,3,67, -0,345,3,68,0, -345,3,69,0,345, -3,70,0,345,3, -71,0,345,3,72, -0,345,3,73,0, -345,3,74,0,345, -3,75,0,345,3, -76,0,345,3,77, -0,345,3,78,0, -345,3,79,0,345, -3,80,0,345,3, -81,0,345,3,82, -0,345,3,83,0, -345,3,84,0,345, -3,85,0,345,3, -86,0,345,3,87, -0,345,3,88,0, -345,3,89,0,345, -3,90,0,345,3, -95,0,345,3,97, -0,345,3,98,0, -345,3,99,0,345, -3,100,0,345,3, -101,0,1026,12,1, -8469,1027,5,63,3, -109,0,345,3,110, -0,345,3,111,0, -345,3,112,0,345, -3,113,0,345,3, -114,0,345,3,115, -0,345,3,116,0, -345,3,117,0,345, -3,118,0,345,3, -119,0,345,3,120, -0,345,3,121,0, -345,3,122,0,345, -3,48,0,345,3, -49,0,345,3,50, -0,345,3,51,0, -345,3,52,0,345, -3,53,0,345,3, -54,0,345,3,55, -0,345,3,56,0, -345,3,57,0,345, -3,65,0,345,3, -66,0,345,3,67, -0,345,3,68,0, -345,3,69,0,345, -3,70,0,345,3, -71,0,345,3,72, -0,345,3,73,0, -345,3,74,0,345, -3,75,0,345,3, -76,0,345,3,77, -0,345,3,78,0, -345,3,79,0,345, -3,80,0,345,3, -81,0,345,3,82, -0,345,3,83,0, -345,3,84,0,345, -3,85,0,345,3, -86,0,345,3,87, -0,345,3,88,0, -345,3,89,0,345, -3,90,0,345,3, -95,0,345,3,97, -0,345,3,98,0, -345,3,99,0,1028, -12,1,8514,1029,5, -63,3,109,0,345, -3,110,0,345,3, -111,0,345,3,112, -0,345,3,113,0, -345,3,114,0,345, -3,115,0,345,3, -116,0,1030,12,1, -8549,1031,5,63,3, -109,0,345,3,110, -0,345,3,111,0, -345,3,112,0,345, -3,113,0,345,3, -114,0,345,3,115, -0,345,3,116,0, -345,3,117,0,345, -3,118,0,345,3, -119,0,345,3,120, -0,345,3,121,0, -345,3,122,0,345, -3,48,0,345,3, -49,0,345,3,50, -0,345,3,51,0, -345,3,52,0,345, -3,53,0,345,3, -54,0,345,3,55, -0,345,3,56,0, -345,3,57,0,345, -3,65,0,345,3, -66,0,345,3,67, -0,345,3,68,0, -345,3,69,0,345, -3,70,0,345,3, -71,0,345,3,72, -0,345,3,73,0, -345,3,74,0,345, -3,75,0,345,3, -76,0,345,3,77, -0,345,3,78,0, -345,3,79,0,345, -3,80,0,345,3, -81,0,345,3,82, -0,345,3,83,0, -345,3,84,0,345, -3,85,0,345,3, -86,0,345,3,87, -0,345,3,88,0, -345,3,89,0,345, -3,90,0,345,3, -95,0,1032,12,1, -8635,1033,5,63,3, -109,0,345,3,110, -0,345,3,111,0, -345,3,112,0,345, -3,113,0,345,3, -114,0,1034,12,1, -8668,1035,5,63,3, -109,0,345,3,110, -0,345,3,111,0, -345,3,112,0,345, -3,113,0,345,3, -114,0,345,3,115, -0,345,3,116,0, -345,3,117,0,345, -3,118,0,345,3, -119,0,345,3,120, -0,345,3,121,0, -345,3,122,0,345, -3,48,0,345,3, -49,0,345,3,50, -0,345,3,51,0, -345,3,52,0,345, -3,53,0,345,3, -54,0,345,3,55, -0,345,3,56,0, -345,3,57,0,345, -3,65,0,345,3, -66,0,345,3,67, -0,345,3,68,0, -345,3,69,0,345, -3,70,0,345,3, -71,0,345,3,72, -0,345,3,73,0, -345,3,74,0,345, -3,75,0,345,3, -76,0,345,3,77, -0,345,3,78,0, -345,3,79,0,345, -3,80,0,345,3, -81,0,345,3,82, -0,345,3,83,0, -345,3,84,0,345, -3,85,0,345,3, -86,0,345,3,87, -0,345,3,88,0, -345,3,89,0,345, -3,90,0,345,3, -95,0,345,3,97, -0,345,3,98,0, -345,3,99,0,345, -3,100,0,345,3, -101,0,1036,12,1, -8715,1037,5,63,3, -109,0,345,3,110, -0,345,3,111,0, -345,3,112,0,345, -3,113,0,345,3, -114,0,345,3,115, -0,345,3,116,0, -345,3,117,0,345, -3,118,0,345,3, -119,0,345,3,120, -0,345,3,121,0, -345,3,122,0,1038, -12,1,8756,1039,5, -63,3,109,0,345, -3,110,0,345,3, -111,0,345,3,112, -0,345,3,113,0, -345,3,114,0,345, -3,115,0,345,3, -116,0,345,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,345,3, -98,0,345,3,99, -0,345,3,100,0, -345,3,101,0,345, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -345,3,106,0,345, -3,107,0,345,3, -108,0,345,1040,11, -1,681,0,1041,4, -32,79,0,66,0, -74,0,69,0,67, +-1,3,89,0,180, +1250,11,1,867,0, +183,1,-1,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +180,3,87,0,180, +3,122,0,180,3, +95,0,180,3,68, +0,180,3,103,0, +180,3,76,0,180, +3,49,0,180,3, +111,0,180,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,180,3,73, +0,180,3,108,0, +180,3,81,0,180, +3,54,0,180,3, +116,0,180,3,89, +0,180,1251,11,1, +867,0,183,1,-1, +3,76,0,180,3, +49,0,180,3,111, +0,180,3,84,0, +180,3,57,0,180, +3,119,0,180,3, +65,0,180,3,100, +0,180,3,73,0, +180,3,108,0,180, +3,81,0,180,3, +54,0,180,3,116, +0,180,3,89,0, +180,1252,11,1,867, +0,183,1,-1,3, +87,0,180,3,122, +0,180,3,95,0, +180,3,68,0,180, +3,103,0,180,3, +76,0,180,3,49, +0,180,3,111,0, +180,3,84,0,180, +3,57,0,180,3, +119,0,180,3,65, +0,180,3,100,0, +180,3,73,0,180, +3,108,0,180,3, +81,0,180,3,54, +0,180,3,116,0, +180,3,89,0,180, +1253,11,1,867,0, +183,1,-1,3,70, +0,180,3,105,0, +180,3,78,0,180, +3,51,0,180,3, +113,0,180,3,86, +0,180,3,121,0, +180,3,67,0,180, +3,102,0,180,3, +75,0,180,3,48, +0,180,3,110,0, +180,3,83,0,180, +3,56,0,180,3, +118,0,180,3,99, +0,180,3,72,0, +180,3,107,0,180, +3,80,0,180,3, +53,0,180,3,115, +0,180,3,88,0, +180,3,69,0,180, +3,104,0,180,3, +77,0,180,3,50, +0,180,3,112,0, +180,3,85,0,180, +3,120,0,180,3, +66,0,180,3,101, +0,180,3,74,0, +180,3,109,0,180, +3,82,0,180,3, +55,0,180,3,117, +0,180,3,90,0, +180,3,98,0,180, +3,71,0,180,3, +106,0,180,3,79, +0,180,3,52,0, +180,3,114,0,180, +3,87,0,180,3, +122,0,180,3,95, +0,180,3,68,0, +180,3,103,0,180, +3,76,0,180,3, +49,0,180,3,111, +0,180,3,84,0, +180,3,57,0,180, +3,119,0,180,3, +65,0,180,3,100, +0,180,3,73,0, +180,3,108,0,180, +3,81,0,180,3, +54,0,180,3,116, +0,180,3,89,0, +180,1254,11,1,867, +0,183,1,-1,3, +89,0,180,1255,11, +1,867,0,183,1, +-1,3,68,0,180, +3,103,0,180,3, +76,0,180,3,49, +0,180,3,111,0, +180,3,84,0,180, +3,57,0,180,3, +119,0,180,3,65, +0,180,3,100,0, +180,3,73,0,180, +3,108,0,180,3, +81,0,180,3,54, +0,180,3,116,0, +180,3,89,0,180, +1256,11,1,867,0, +183,1,-1,3,89, +0,180,1257,11,1, +867,0,183,1,-1, +3,84,0,180,3, +57,0,180,3,119, +0,180,3,65,0, +180,3,100,0,180, +3,73,0,180,3, +108,0,180,3,81, +0,180,3,54,0, +180,3,116,0,180, +3,89,0,180,1258, +11,1,867,0,183, +1,-1,3,87,0, +180,3,122,0,180, +3,95,0,180,3, +68,0,180,3,103, +0,180,3,76,0, +180,3,49,0,180, +3,111,0,180,3, +84,0,180,3,57, +0,180,3,119,0, +180,3,65,0,180, +3,100,0,180,3, +73,0,180,3,108, +0,180,3,81,0, +180,3,54,0,180, +3,116,0,1259,12, +1,16555,1260,5,63, +3,97,0,1261,12, +1,16622,1262,5,63, +3,97,0,180,3, +70,0,180,3,105, +0,180,3,78,0, +180,3,51,0,180, +3,113,0,180,3, +86,0,180,3,121, +0,180,3,67,0, +180,3,102,0,180, +3,75,0,180,3, +48,0,180,3,110, +0,180,3,83,0, +180,3,56,0,180, +3,118,0,180,3, +99,0,180,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,180,3,88, +0,180,3,69,0, +180,3,104,0,180, +3,77,0,180,3, +50,0,180,3,112, +0,180,3,85,0, +180,3,120,0,180, +3,66,0,180,3, +101,0,180,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +1263,12,1,16707,1264, +5,63,3,97,0, +180,3,70,0,180, +3,105,0,180,3, +78,0,180,3,51, +0,180,3,113,0, +180,3,86,0,180, +3,121,0,180,3, +67,0,180,3,102, +0,180,3,75,0, +180,3,48,0,180, +3,110,0,180,3, +83,0,180,3,56, +0,180,3,118,0, +180,3,99,0,180, +3,72,0,180,3, +107,0,180,3,80, +0,180,3,53,0, +180,3,115,0,180, +3,88,0,180,3, +69,0,180,3,104, +0,180,3,77,0, +180,3,50,0,180, +3,112,0,180,3, +85,0,180,3,120, +0,180,3,66,0, +180,3,101,0,180, +3,74,0,180,3, +109,0,180,3,82, +0,180,3,55,0, +180,3,117,0,180, +3,90,0,180,3, +98,0,180,3,71, +0,180,3,106,0, +180,3,79,0,180, +3,52,0,180,3, +114,0,180,3,87, +0,180,3,122,0, +180,3,95,0,180, +3,68,0,180,3, +103,0,1265,12,1, +16794,1266,5,63,3, +97,0,180,3,70, +0,180,3,105,0, +180,3,78,0,180, +3,51,0,180,3, +113,0,180,3,86, +0,180,3,121,0, +180,3,67,0,180, +3,102,0,180,3, +75,0,180,3,48, +0,180,3,110,0, +180,3,83,0,180, +3,56,0,180,3, +118,0,180,3,99, +0,180,3,72,0, +180,3,107,0,180, +3,80,0,180,3, +53,0,180,3,115, +0,180,3,88,0, +180,3,69,0,180, +3,104,0,180,3, +77,0,180,3,50, +0,180,3,112,0, +180,3,85,0,180, +3,120,0,180,3, +66,0,180,3,101, +0,1267,12,1,16874, +1268,5,63,3,97, +0,180,3,70,0, +180,3,105,0,180, +3,78,0,180,3, +51,0,180,3,113, +0,180,3,86,0, +180,3,121,0,180, +3,67,0,180,3, +102,0,180,3,75, +0,180,3,48,0, +180,3,110,0,180, +3,83,0,180,3, +56,0,180,3,118, +0,180,3,99,0, +180,3,72,0,180, +3,107,0,180,3, +80,0,180,3,53, +0,180,3,115,0, +180,3,88,0,180, +3,69,0,180,3, +104,0,180,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,180,3,66, +0,180,3,101,0, +180,3,74,0,180, +3,109,0,180,3, +82,0,180,3,55, +0,180,3,117,0, +180,3,90,0,180, +3,98,0,180,3, +71,0,180,3,106, +0,180,3,79,0, +180,3,52,0,180, +3,114,0,180,3, +87,0,180,3,122, +0,180,3,95,0, +180,3,68,0,180, +3,103,0,180,3, +76,0,180,3,49, +0,180,3,111,0, +180,3,84,0,180, +3,57,0,180,3, +119,0,180,3,65, +0,180,3,100,0, +180,3,73,0,180, +3,108,0,180,3, +81,0,180,3,54, +0,180,3,116,0, +1269,12,1,16967,1270, +5,63,3,97,0, +180,3,70,0,180, +3,105,0,180,3, +78,0,180,3,51, +0,180,3,113,0, +180,3,86,0,180, +3,121,0,180,3, +67,0,180,3,102, +0,180,3,75,0, +180,3,48,0,180, +3,110,0,180,3, +83,0,180,3,56, +0,180,3,118,0, +180,3,99,0,180, +3,72,0,180,3, +107,0,180,3,80, +0,180,3,53,0, +180,3,115,0,180, +3,88,0,180,3, +69,0,180,3,104, +0,180,3,77,0, +180,3,50,0,180, +3,112,0,180,3, +85,0,180,3,120, +0,180,3,66,0, +180,3,101,0,180, +3,74,0,180,3, +109,0,180,3,82, +0,180,3,55,0, +180,3,117,0,180, +3,90,0,180,3, +98,0,180,3,71, +0,180,3,106,0, +180,3,79,0,180, +3,52,0,180,3, +114,0,180,3,87, +0,180,3,122,0, +180,3,95,0,180, +3,68,0,180,3, +103,0,180,3,76, +0,180,3,49,0, +180,3,111,0,180, +3,84,0,180,3, +57,0,180,3,119, +0,180,3,65,0, +180,3,100,0,180, +3,73,0,180,3, +108,0,180,3,81, +0,180,3,54,0, +180,3,116,0,180, +3,89,0,180,1271, +11,1,664,0,1272, +4,38,78,0,79, 0,84,0,95,0, -82,0,69,0,90, -0,95,0,69,0, -86,0,69,0,78, -0,84,0,1,-1, -3,48,0,345,3, -49,0,345,3,50, -0,345,3,51,0, -345,3,52,0,345, -3,53,0,345,3, -54,0,345,3,55, -0,345,3,56,0, -345,3,57,0,345, -3,65,0,345,3, -66,0,345,3,67, -0,345,3,68,0, -345,3,69,0,345, -3,70,0,345,3, -71,0,345,3,72, -0,345,3,73,0, -345,3,74,0,345, -3,75,0,345,3, -76,0,345,3,77, -0,345,3,78,0, -345,3,79,0,345, -3,80,0,345,3, -81,0,345,3,82, -0,345,3,83,0, -345,3,84,0,345, -3,85,0,345,3, -86,0,345,3,87, -0,345,3,88,0, -345,3,89,0,345, -3,90,0,345,3, -95,0,345,3,97, -0,345,3,98,0, -345,3,99,0,345, -3,100,0,345,3, -101,0,345,3,102, -0,345,3,103,0, -345,3,104,0,345, -3,105,0,345,3, -106,0,345,3,107, -0,345,3,108,0, -345,1042,11,1,867, -0,348,1,-1,3, -102,0,345,3,103, -0,345,3,104,0, -345,3,105,0,345, -3,106,0,345,3, -107,0,345,3,108, -0,345,1043,11,1, -867,0,348,1,-1, -3,115,0,345,3, -116,0,345,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,345,3, -98,0,345,3,99, -0,345,3,100,0, -345,3,101,0,345, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -345,3,106,0,345, -3,107,0,345,3, -108,0,345,1044,11, -1,867,0,348,1, --1,3,97,0,345, -3,98,0,345,3, -99,0,345,3,100, -0,345,3,101,0, -345,3,102,0,345, -3,103,0,345,3, -104,0,345,3,105, -0,345,3,106,0, -345,3,107,0,345, -3,108,0,345,1045, -11,1,867,0,348, -1,-1,3,117,0, -345,3,118,0,345, -3,119,0,345,3, -120,0,345,3,121, -0,345,3,122,0, -345,3,48,0,345, -3,49,0,345,3, -50,0,345,3,51, -0,345,3,52,0, -345,3,53,0,345, -3,54,0,345,3, -55,0,345,3,56, -0,345,3,57,0, -345,3,65,0,345, -3,66,0,345,3, -67,0,345,3,68, -0,345,3,69,0, -345,3,70,0,345, -3,71,0,345,3, -72,0,345,3,73, -0,345,3,74,0, -345,3,75,0,345, -3,76,0,345,3, -77,0,345,3,78, -0,345,3,79,0, -345,3,80,0,345, -3,81,0,345,3, -82,0,345,3,83, -0,345,3,84,0, -345,3,85,0,345, -3,86,0,345,3, -87,0,345,3,88, -0,345,3,89,0, -345,3,90,0,345, -3,95,0,345,3, -97,0,345,3,98, -0,345,3,99,0, -345,3,100,0,345, -3,101,0,345,3, -102,0,345,3,103, -0,345,3,104,0, -345,3,105,0,345, -3,106,0,345,3, -107,0,345,3,108, -0,345,1046,11,1, -867,0,348,1,-1, -3,100,0,345,3, -101,0,345,3,102, -0,345,3,103,0, -345,3,104,0,345, -3,105,0,345,3, -106,0,345,3,107, -0,345,3,108,0, -345,1047,11,1,867, -0,348,1,-1,3, -102,0,345,3,103, -0,345,3,104,0, -345,3,105,0,345, -3,106,0,345,3, -107,0,345,3,108, -0,345,1048,11,1, -867,0,348,1,-1, -3,107,0,345,3, -108,0,345,1049,11, -1,867,0,348,1, --1,3,99,0,345, -3,100,0,345,3, -101,0,345,3,102, -0,345,3,103,0, -345,3,104,0,345, -3,105,0,345,3, -106,0,345,3,107, -0,345,3,108,0, -345,1050,11,1,867, -0,348,1,-1,3, -112,0,343,3,113, -0,343,3,114,0, -1051,12,1,9529,1052, -5,63,3,109,0, -345,3,110,0,345, -3,111,0,1053,12, -1,9559,1054,5,63, -3,109,0,345,3, -110,0,345,3,111, -0,345,3,112,0, -345,3,113,0,345, -3,114,0,345,3, -115,0,345,3,116, -0,1055,12,1,9594, -1056,5,63,3,109, -0,345,3,110,0, -345,3,111,0,345, -3,112,0,345,3, -113,0,345,3,114, -0,345,3,115,0, -345,3,116,0,345, -3,117,0,345,3, -118,0,345,3,119, -0,345,3,120,0, -345,3,121,0,345, -3,122,0,345,3, -48,0,345,3,49, -0,345,3,50,0, -345,3,51,0,345, -3,52,0,345,3, -53,0,345,3,54, -0,345,3,55,0, -345,3,56,0,345, -3,57,0,345,3, -65,0,345,3,66, -0,345,3,67,0, -345,3,68,0,345, -3,69,0,345,3, -70,0,345,3,71, -0,345,3,72,0, -345,3,73,0,345, -3,74,0,345,3, -75,0,345,3,76, -0,345,3,77,0, -345,3,78,0,345, -3,79,0,345,3, -80,0,345,3,81, -0,345,3,82,0, -345,3,83,0,345, -3,84,0,345,3, -85,0,345,3,86, -0,345,3,87,0, -345,3,88,0,345, -3,89,0,345,3, -90,0,345,3,95, -0,345,3,97,0, -1057,12,1,9637,1058, -5,63,3,109,0, -345,3,110,0,345, -3,111,0,345,3, -112,0,345,3,113, -0,345,3,114,0, -345,3,115,0,345, -3,116,0,1059,12, -1,9672,1060,5,63, -3,109,0,345,3, -110,0,345,3,111, -0,345,3,112,0, -345,3,113,0,345, -3,114,0,345,3, -115,0,345,3,116, -0,345,3,117,0, -345,3,118,0,345, -3,119,0,345,3, -120,0,345,3,121, -0,345,3,122,0, -345,3,48,0,345, -3,49,0,345,3, -50,0,345,3,51, -0,345,3,52,0, -345,3,53,0,345, -3,54,0,345,3, -55,0,345,3,56, -0,345,3,57,0, -345,3,65,0,345, -3,66,0,345,3, -67,0,345,3,68, -0,345,3,69,0, -345,3,70,0,345, -3,71,0,345,3, -72,0,345,3,73, -0,345,3,74,0, -345,3,75,0,345, -3,76,0,345,3, -77,0,345,3,78, -0,345,3,79,0, -345,3,80,0,345, -3,81,0,345,3, -82,0,345,3,83, -0,345,3,84,0, -345,3,85,0,345, -3,86,0,345,3, -87,0,345,3,88, -0,345,3,89,0, -345,3,90,0,345, -3,95,0,345,3, -97,0,345,3,98, -0,345,3,99,0, -345,3,100,0,345, -3,101,0,345,3, -102,0,345,3,103, -0,345,3,104,0, -345,3,105,0,1061, -12,1,9723,1062,5, -63,3,109,0,345, -3,110,0,345,3, -111,0,1063,12,1, -9753,1064,5,63,3, -109,0,345,3,110, -0,1065,12,1,9782, -1066,5,63,3,109, -0,345,3,110,0, -345,3,111,0,345, -3,112,0,345,3, -113,0,345,3,114, -0,345,3,115,0, -345,3,116,0,345, -3,117,0,345,3, -118,0,345,3,119, -0,345,3,120,0, -345,3,121,0,345, -3,122,0,345,3, -48,0,345,3,49, -0,345,3,50,0, -345,3,51,0,345, -3,52,0,345,3, -53,0,345,3,54, -0,345,3,55,0, -345,3,56,0,345, -3,57,0,345,3, -65,0,345,3,66, -0,345,3,67,0, -345,3,68,0,345, -3,69,0,345,3, -70,0,345,3,71, -0,345,3,72,0, -345,3,73,0,345, -3,74,0,345,3, -75,0,345,3,76, -0,345,3,77,0, -345,3,78,0,345, -3,79,0,345,3, -80,0,345,3,81, -0,345,3,82,0, -345,3,83,0,345, -3,84,0,345,3, -85,0,345,3,86, -0,345,3,87,0, -345,3,88,0,345, -3,89,0,345,3, -90,0,345,3,95, -0,345,3,97,0, -345,3,98,0,345, -3,99,0,345,3, -100,0,345,3,101, -0,345,3,102,0, -345,3,103,0,345, -3,104,0,345,3, -105,0,345,3,106, -0,345,3,107,0, -345,3,108,0,345, -1067,11,1,330,0, -1068,4,26,82,0, -79,0,84,0,65, -0,84,0,73,0, -79,0,78,0,95, -0,84,0,89,0, -80,0,69,0,1, --1,3,111,0,345, -3,112,0,345,3, -113,0,345,3,114, -0,345,3,115,0, -345,3,116,0,345, -3,117,0,345,3, -118,0,345,3,119, -0,345,3,120,0, -345,3,121,0,345, -3,122,0,345,3, -48,0,345,3,49, -0,345,3,50,0, -345,3,51,0,345, -3,52,0,345,3, -53,0,345,3,54, -0,345,3,55,0, -345,3,56,0,345, -3,57,0,345,3, -65,0,345,3,66, -0,345,3,67,0, -345,3,68,0,345, -3,69,0,345,3, -70,0,345,3,71, -0,345,3,72,0, -345,3,73,0,345, -3,74,0,345,3, -75,0,345,3,76, -0,345,3,77,0, -345,3,78,0,345, -3,79,0,345,3, -80,0,345,3,81, -0,345,3,82,0, -345,3,83,0,345, -3,84,0,345,3, -85,0,345,3,86, -0,345,3,87,0, -345,3,88,0,345, -3,89,0,345,3, -90,0,345,3,95, -0,345,3,97,0, -345,3,98,0,345, -3,99,0,345,3, -100,0,345,3,101, -0,345,3,102,0, -345,3,103,0,345, -3,104,0,345,3, -105,0,345,3,106, -0,345,3,107,0, -345,3,108,0,345, -1069,11,1,867,0, -348,1,-1,3,112, -0,345,3,113,0, -345,3,114,0,345, -3,115,0,345,3, -116,0,345,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,345,3, -98,0,345,3,99, -0,345,3,100,0, -345,3,101,0,345, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -345,3,106,0,345, -3,107,0,345,3, -108,0,345,1070,11, -1,867,0,348,1, --1,3,106,0,345, -3,107,0,345,3, -108,0,345,1071,11, -1,867,0,348,1, --1,3,117,0,345, -3,118,0,345,3, -119,0,345,3,120, -0,345,3,121,0, -345,3,122,0,345, -3,48,0,345,3, -49,0,345,3,50, -0,345,3,51,0, -345,3,52,0,345, -3,53,0,345,3, -54,0,345,3,55, -0,345,3,56,0, -345,3,57,0,345, -3,65,0,345,3, -66,0,345,3,67, -0,345,3,68,0, -345,3,69,0,345, -3,70,0,345,3, -71,0,345,3,72, -0,345,3,73,0, -345,3,74,0,345, -3,75,0,345,3, -76,0,345,3,77, -0,345,3,78,0, -345,3,79,0,345, -3,80,0,345,3, -81,0,345,3,82, -0,345,3,83,0, -345,3,84,0,345, -3,85,0,345,3, -86,0,345,3,87, -0,345,3,88,0, -345,3,89,0,345, -3,90,0,345,3, -95,0,345,3,97, -0,345,3,98,0, -345,3,99,0,345, -3,100,0,345,3, -101,0,345,3,102, -0,345,3,103,0, -345,3,104,0,345, -3,105,0,345,3, -106,0,345,3,107, -0,345,3,108,0, -345,1072,11,1,867, -0,348,1,-1,3, -98,0,345,3,99, -0,345,3,100,0, -345,3,101,0,345, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -345,3,106,0,345, -3,107,0,345,3, -108,0,345,1073,11, -1,867,0,348,1, --1,3,117,0,345, -3,118,0,345,3, -119,0,345,3,120, -0,345,3,121,0, -345,3,122,0,345, -3,48,0,345,3, -49,0,345,3,50, -0,345,3,51,0, -345,3,52,0,345, -3,53,0,345,3, -54,0,345,3,55, -0,345,3,56,0, -345,3,57,0,345, -3,65,0,345,3, -66,0,345,3,67, -0,345,3,68,0, -345,3,69,0,345, -3,70,0,345,3, -71,0,345,3,72, -0,345,3,73,0, -345,3,74,0,345, -3,75,0,345,3, -76,0,345,3,77, -0,345,3,78,0, -345,3,79,0,345, -3,80,0,345,3, -81,0,345,3,82, -0,345,3,83,0, -345,3,84,0,345, -3,85,0,345,3, -86,0,345,3,87, -0,345,3,88,0, -345,3,89,0,345, -3,90,0,345,3, -95,0,345,3,97, -0,345,3,98,0, -345,3,99,0,345, -3,100,0,345,3, -101,0,345,3,102, -0,345,3,103,0, -345,3,104,0,345, -3,105,0,345,3, -106,0,345,3,107, -0,345,3,108,0, -345,1074,11,1,867, -0,348,1,-1,3, -112,0,345,3,113, -0,345,3,114,0, -345,3,115,0,345, -3,116,0,345,3, -117,0,1075,12,1, -10405,1076,5,63,3, -109,0,345,3,110, -0,1077,12,1,10434, -1078,5,63,3,109, -0,345,3,110,0, -345,3,111,0,345, -3,112,0,345,3, -113,0,345,3,114, -0,345,3,115,0, -345,3,116,0,345, -3,117,0,345,3, -118,0,345,3,119, -0,345,3,120,0, -345,3,121,0,345, -3,122,0,345,3, -48,0,345,3,49, -0,345,3,50,0, -345,3,51,0,345, -3,52,0,345,3, -53,0,345,3,54, -0,345,3,55,0, -345,3,56,0,345, -3,57,0,345,3, -65,0,345,3,66, -0,345,3,67,0, -345,3,68,0,345, -3,69,0,345,3, -70,0,345,3,71, -0,345,3,72,0, -345,3,73,0,345, -3,74,0,345,3, -75,0,345,3,76, -0,345,3,77,0, -345,3,78,0,345, -3,79,0,345,3, -80,0,345,3,81, -0,345,3,82,0, -345,3,83,0,345, -3,84,0,345,3, -85,0,345,3,86, -0,345,3,87,0, -345,3,88,0,345, -3,89,0,345,3, -90,0,345,3,95, -0,1079,12,1,10520, -1080,5,63,3,109, -0,345,3,110,0, -345,3,111,0,345, -3,112,0,345,3, -113,0,345,3,114, -0,345,3,115,0, -345,3,116,0,1081, -12,1,10555,1082,5, -63,3,109,0,345, -3,110,0,345,3, -111,0,345,3,112, -0,345,3,113,0, -345,3,114,0,345, -3,115,0,345,3, -116,0,345,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,345,3, -98,0,345,3,99, -0,345,3,100,0, -345,3,101,0,345, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -1083,12,1,10606,1084, -5,63,3,109,0, -1085,12,1,10634,1086, -5,63,3,109,0, -345,3,110,0,345, -3,111,0,345,3, -112,0,345,3,113, -0,345,3,114,0, -345,3,115,0,345, -3,116,0,345,3, -117,0,345,3,118, -0,345,3,119,0, -345,3,120,0,345, -3,121,0,345,3, -122,0,345,3,48, -0,345,3,49,0, -345,3,50,0,345, -3,51,0,345,3, -52,0,345,3,53, -0,345,3,54,0, -345,3,55,0,345, -3,56,0,345,3, -57,0,345,3,65, -0,345,3,66,0, -345,3,67,0,345, -3,68,0,345,3, -69,0,345,3,70, -0,345,3,71,0, -345,3,72,0,345, -3,73,0,345,3, -74,0,345,3,75, -0,345,3,76,0, -345,3,77,0,345, -3,78,0,345,3, -79,0,345,3,80, -0,345,3,81,0, -345,3,82,0,345, -3,83,0,345,3, -84,0,345,3,85, -0,345,3,86,0, -345,3,87,0,345, -3,88,0,345,3, -89,0,345,3,90, -0,345,3,95,0, -345,3,97,0,345, -3,98,0,345,3, -99,0,345,3,100, -0,345,3,101,0, -1087,12,1,10681,1088, -5,63,3,109,0, -345,3,110,0,345, -3,111,0,345,3, -112,0,345,3,113, -0,345,3,114,0, -345,3,115,0,345, -3,116,0,345,3, -117,0,345,3,118, -0,345,3,119,0, -345,3,120,0,345, -3,121,0,345,3, -122,0,345,3,48, -0,345,3,49,0, -345,3,50,0,345, -3,51,0,345,3, -52,0,345,3,53, -0,345,3,54,0, -345,3,55,0,345, -3,56,0,345,3, -57,0,345,3,65, -0,345,3,66,0, -345,3,67,0,345, -3,68,0,345,3, -69,0,345,3,70, -0,345,3,71,0, -345,3,72,0,345, -3,73,0,345,3, -74,0,345,3,75, -0,345,3,76,0, -345,3,77,0,345, -3,78,0,345,3, -79,0,345,3,80, -0,345,3,81,0, -345,3,82,0,345, -3,83,0,345,3, -84,0,345,3,85, -0,345,3,86,0, -345,3,87,0,345, -3,88,0,345,3, -89,0,345,3,90, -0,345,3,95,0, -1089,12,1,10767,1090, -5,63,3,109,0, -345,3,110,0,345, -3,111,0,345,3, -112,0,1091,12,1, -10798,1092,5,63,3, -109,0,345,3,110, -0,345,3,111,0, -345,3,112,0,345, -3,113,0,345,3, -114,0,345,3,115, -0,345,3,116,0, -345,3,117,0,345, -3,118,0,345,3, -119,0,345,3,120, -0,345,3,121,0, -345,3,122,0,345, -3,48,0,345,3, -49,0,345,3,50, -0,345,3,51,0, -345,3,52,0,345, -3,53,0,345,3, -54,0,345,3,55, -0,345,3,56,0, -345,3,57,0,345, -3,65,0,345,3, -66,0,345,3,67, -0,345,3,68,0, -345,3,69,0,345, -3,70,0,345,3, -71,0,345,3,72, -0,345,3,73,0, -345,3,74,0,345, -3,75,0,345,3, -76,0,345,3,77, -0,345,3,78,0, -345,3,79,0,345, -3,80,0,345,3, -81,0,345,3,82, -0,345,3,83,0, -345,3,84,0,345, -3,85,0,345,3, -86,0,345,3,87, -0,345,3,88,0, -345,3,89,0,345, -3,90,0,345,3, -95,0,345,3,97, -0,345,3,98,0, -345,3,99,0,345, -3,100,0,345,3, -101,0,1093,12,1, -10845,1094,5,63,3, -109,0,345,3,110, -0,345,3,111,0, -345,3,112,0,345, -3,113,0,345,3, -114,0,1095,12,1, -10878,1096,5,63,3, -109,0,1097,12,1, -10906,1098,5,63,3, -109,0,345,3,110, -0,345,3,111,0, -345,3,112,0,345, -3,113,0,345,3, -114,0,345,3,115, -0,345,3,116,0, -345,3,117,0,345, -3,118,0,345,3, -119,0,345,3,120, -0,345,3,121,0, -345,3,122,0,345, -3,48,0,345,3, -49,0,345,3,50, -0,345,3,51,0, -345,3,52,0,345, -3,53,0,345,3, -54,0,345,3,55, -0,345,3,56,0, -345,3,57,0,345, -3,65,0,345,3, -66,0,345,3,67, -0,345,3,68,0, -345,3,69,0,345, -3,70,0,345,3, -71,0,345,3,72, -0,345,3,73,0, -345,3,74,0,345, -3,75,0,345,3, -76,0,345,3,77, -0,345,3,78,0, -345,3,79,0,345, -3,80,0,345,3, -81,0,345,3,82, -0,345,3,83,0, -345,3,84,0,345, -3,85,0,345,3, -86,0,345,3,87, -0,345,3,88,0, -345,3,89,0,345, -3,90,0,345,3, -95,0,345,3,97, -0,345,3,98,0, -345,3,99,0,345, -3,100,0,345,3, -101,0,345,3,102, -0,345,3,103,0, -345,3,104,0,345, -3,105,0,1099,12, -1,10957,1100,5,63, -3,109,0,345,3, -110,0,345,3,111, -0,345,3,112,0, -345,3,113,0,345, -3,114,0,345,3, -115,0,1101,12,1, -10991,1102,5,63,3, -109,0,345,3,110, -0,345,3,111,0, -345,3,112,0,345, -3,113,0,345,3, -114,0,345,3,115, -0,1103,12,1,11025, -1104,5,63,3,109, -0,345,3,110,0, -345,3,111,0,345, -3,112,0,345,3, -113,0,345,3,114, -0,345,3,115,0, -345,3,116,0,345, -3,117,0,345,3, -118,0,345,3,119, -0,345,3,120,0, -345,3,121,0,345, -3,122,0,345,3, -48,0,345,3,49, -0,345,3,50,0, -345,3,51,0,345, -3,52,0,345,3, -53,0,345,3,54, -0,345,3,55,0, -345,3,56,0,345, -3,57,0,345,3, -65,0,345,3,66, -0,345,3,67,0, -345,3,68,0,345, -3,69,0,345,3, -70,0,345,3,71, -0,345,3,72,0, -345,3,73,0,345, -3,74,0,345,3, -75,0,345,3,76, -0,345,3,77,0, -345,3,78,0,345, -3,79,0,345,3, -80,0,345,3,81, -0,345,3,82,0, -345,3,83,0,345, -3,84,0,345,3, -85,0,345,3,86, -0,345,3,87,0, -345,3,88,0,345, -3,89,0,345,3, -90,0,345,3,95, -0,345,3,97,0, -345,3,98,0,345, -3,99,0,345,3, -100,0,345,3,101, -0,345,3,102,0, -345,3,103,0,345, -3,104,0,345,3, -105,0,1105,12,1, -11076,1106,5,63,3, -109,0,345,3,110, -0,345,3,111,0, -1107,12,1,11106,1108, -5,63,3,109,0, -345,3,110,0,1109, -12,1,11135,1110,5, -63,3,109,0,345, -3,110,0,345,3, -111,0,345,3,112, -0,345,3,113,0, -345,3,114,0,345, -3,115,0,1111,12, -1,11169,1112,5,63, -3,109,0,345,3, -110,0,345,3,111, -0,345,3,112,0, -345,3,113,0,345, -3,114,0,345,3, -115,0,345,3,116, -0,345,3,117,0, -345,3,118,0,345, -3,119,0,345,3, -120,0,345,3,121, -0,345,3,122,0, -345,3,48,0,345, -3,49,0,345,3, -50,0,345,3,51, -0,345,3,52,0, -345,3,53,0,345, -3,54,0,345,3, -55,0,345,3,56, -0,345,3,57,0, -345,3,65,0,345, -3,66,0,345,3, -67,0,345,3,68, -0,345,3,69,0, -345,3,70,0,345, -3,71,0,345,3, -72,0,345,3,73, -0,345,3,74,0, -345,3,75,0,345, -3,76,0,345,3, -77,0,345,3,78, -0,345,3,79,0, -345,3,80,0,345, -3,81,0,345,3, -82,0,345,3,83, -0,345,3,84,0, -345,3,85,0,345, -3,86,0,345,3, -87,0,345,3,88, -0,345,3,89,0, -345,3,90,0,345, -3,95,0,345,3, -97,0,345,3,98, -0,345,3,99,0, -345,3,100,0,345, -3,101,0,345,3, -102,0,345,3,103, -0,345,3,104,0, -345,3,105,0,345, -3,106,0,345,3, -107,0,345,3,108, -0,345,1113,11,1, -720,0,1114,4,52, -82,0,85,0,78, -0,95,0,84,0, -73,0,77,0,69, -0,95,0,80,0, -69,0,82,0,77, -0,73,0,83,0, -83,0,73,0,79, -0,78,0,83,0, -95,0,69,0,86, -0,69,0,78,0, -84,0,1,-1,3, -116,0,345,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,345,3, -98,0,345,3,99, -0,345,3,100,0, -345,3,101,0,345, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -345,3,106,0,345, -3,107,0,345,3, -108,0,345,1115,11, -1,867,0,348,1, --1,3,111,0,345, -3,112,0,345,3, -113,0,345,3,114, -0,345,3,115,0, -345,3,116,0,345, -3,117,0,345,3, -118,0,345,3,119, -0,345,3,120,0, -345,3,121,0,345, -3,122,0,345,3, -48,0,345,3,49, -0,345,3,50,0, -345,3,51,0,345, -3,52,0,345,3, -53,0,345,3,54, -0,345,3,55,0, -345,3,56,0,345, -3,57,0,345,3, -65,0,345,3,66, -0,345,3,67,0, -345,3,68,0,345, -3,69,0,345,3, -70,0,345,3,71, -0,345,3,72,0, -345,3,73,0,345, -3,74,0,345,3, -75,0,345,3,76, -0,345,3,77,0, -345,3,78,0,345, -3,79,0,345,3, -80,0,345,3,81, -0,345,3,82,0, -345,3,83,0,345, -3,84,0,345,3, -85,0,345,3,86, -0,345,3,87,0, -345,3,88,0,345, -3,89,0,345,3, -90,0,345,3,95, -0,345,3,97,0, -345,3,98,0,345, -3,99,0,345,3, -100,0,345,3,101, -0,345,3,102,0, -345,3,103,0,345, -3,104,0,345,3, -105,0,345,3,106, -0,345,3,107,0, -345,3,108,0,345, -1116,11,1,867,0, -348,1,-1,3,112, -0,345,3,113,0, -345,3,114,0,345, -3,115,0,345,3, -116,0,345,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,345,3, -98,0,345,3,99, -0,345,3,100,0, -345,3,101,0,345, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -345,3,106,0,345, -3,107,0,345,3, -108,0,345,1117,11, -1,867,0,348,1, --1,3,106,0,345, -3,107,0,345,3, -108,0,345,1118,11, -1,867,0,348,1, --1,3,116,0,345, -3,117,0,345,3, -118,0,345,3,119, -0,345,3,120,0, -345,3,121,0,345, -3,122,0,345,3, -48,0,345,3,49, -0,345,3,50,0, -345,3,51,0,345, -3,52,0,345,3, -53,0,345,3,54, -0,345,3,55,0, -345,3,56,0,345, -3,57,0,345,3, -65,0,345,3,66, -0,345,3,67,0, -345,3,68,0,345, -3,69,0,345,3, -70,0,345,3,71, -0,345,3,72,0, -345,3,73,0,345, -3,74,0,345,3, -75,0,345,3,76, -0,345,3,77,0, -345,3,78,0,345, -3,79,0,345,3, -80,0,345,3,81, -0,345,3,82,0, -345,3,83,0,345, -3,84,0,345,3, -85,0,345,3,86, -0,345,3,87,0, -345,3,88,0,345, -3,89,0,345,3, -90,0,345,3,95, -0,345,3,97,0, -345,3,98,0,345, -3,99,0,345,3, -100,0,345,3,101, -0,345,3,102,0, -345,3,103,0,345, -3,104,0,345,3, -105,0,345,3,106, -0,345,3,107,0, -345,3,108,0,345, -1119,11,1,867,0, -348,1,-1,3,116, -0,345,3,117,0, -345,3,118,0,345, -3,119,0,345,3, -120,0,345,3,121, -0,345,3,122,0, -345,3,48,0,345, -3,49,0,345,3, -50,0,345,3,51, -0,345,3,52,0, -345,3,53,0,345, -3,54,0,345,3, -55,0,345,3,56, -0,345,3,57,0, -345,3,65,0,345, -3,66,0,345,3, -67,0,345,3,68, -0,345,3,69,0, -345,3,70,0,345, -3,71,0,345,3, -72,0,345,3,73, -0,345,3,74,0, -345,3,75,0,345, -3,76,0,345,3, -77,0,345,3,78, -0,345,3,79,0, -345,3,80,0,345, -3,81,0,345,3, -82,0,345,3,83, -0,345,3,84,0, -345,3,85,0,345, -3,86,0,345,3, -87,0,345,3,88, -0,345,3,89,0, -345,3,90,0,345, -3,95,0,345,3, -97,0,345,3,98, -0,345,3,99,0, -345,3,100,0,345, -3,101,0,345,3, -102,0,345,3,103, -0,345,3,104,0, -345,3,105,0,345, -3,106,0,345,3, -107,0,345,3,108, -0,345,1120,11,1, -867,0,348,1,-1, -3,106,0,345,3, -107,0,345,3,108, -0,345,1121,11,1, -867,0,348,1,-1, -3,110,0,345,3, -111,0,345,3,112, -0,345,3,113,0, -345,3,114,0,345, -3,115,0,345,3, -116,0,345,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,345,3, -98,0,345,3,99, -0,345,3,100,0, -345,3,101,0,345, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -345,3,106,0,345, -3,107,0,345,3, -108,0,345,1122,11, -1,867,0,348,1, --1,3,115,0,345, -3,116,0,345,3, -117,0,345,3,118, -0,345,3,119,0, -345,3,120,0,345, -3,121,0,345,3, -122,0,345,3,48, -0,345,3,49,0, -345,3,50,0,345, -3,51,0,345,3, -52,0,345,3,53, -0,345,3,54,0, -345,3,55,0,345, -3,56,0,345,3, -57,0,345,3,65, -0,345,3,66,0, -345,3,67,0,345, -3,68,0,345,3, -69,0,345,3,70, -0,345,3,71,0, -345,3,72,0,345, -3,73,0,345,3, -74,0,345,3,75, -0,345,3,76,0, -345,3,77,0,345, -3,78,0,345,3, -79,0,345,3,80, -0,345,3,81,0, -345,3,82,0,345, -3,83,0,345,3, -84,0,345,3,85, -0,345,3,86,0, -345,3,87,0,345, -3,88,0,345,3, -89,0,345,3,90, -0,345,3,95,0, -345,3,97,0,345, -3,98,0,345,3, -99,0,345,3,100, -0,345,3,101,0, -345,3,102,0,345, -3,103,0,345,3, -104,0,345,3,105, -0,345,3,106,0, -345,3,107,0,345, -3,108,0,345,1123, -11,1,867,0,348, -1,-1,3,102,0, -345,3,103,0,345, -3,104,0,345,3, -105,0,345,3,106, -0,345,3,107,0, -345,3,108,0,345, -1124,11,1,867,0, -348,1,-1,3,113, -0,345,3,114,0, -345,3,115,0,345, -3,116,0,345,3, -117,0,345,3,118, -0,345,3,119,0, -345,3,120,0,345, -3,121,0,345,3, -122,0,345,3,48, -0,345,3,49,0, -345,3,50,0,345, -3,51,0,345,3, -52,0,345,3,53, -0,345,3,54,0, -345,3,55,0,345, -3,56,0,345,3, -57,0,345,3,65, -0,345,3,66,0, -345,3,67,0,345, -3,68,0,345,3, -69,0,345,3,70, -0,345,3,71,0, -345,3,72,0,345, -3,73,0,345,3, -74,0,345,3,75, -0,345,3,76,0, -345,3,77,0,345, -3,78,0,345,3, -79,0,345,3,80, -0,345,3,81,0, -345,3,82,0,345, -3,83,0,345,3, -84,0,345,3,85, -0,345,3,86,0, -345,3,87,0,345, -3,88,0,345,3, -89,0,345,3,90, -0,345,3,95,0, -345,3,97,0,345, -3,98,0,345,3, -99,0,345,3,100, -0,345,3,101,0, -345,3,102,0,345, -3,103,0,345,3, -104,0,345,3,105, -0,345,3,106,0, -345,3,107,0,345, -3,108,0,345,1125, -11,1,867,0,348, -1,-1,3,97,0, -345,3,98,0,345, -3,99,0,345,3, -100,0,345,3,101, -0,345,3,102,0, -345,3,103,0,345, -3,104,0,345,3, -105,0,345,3,106, -0,345,3,107,0, -345,3,108,0,345, -1126,11,1,867,0, -348,1,-1,3,102, -0,345,3,103,0, -345,3,104,0,345, -3,105,0,345,3, -106,0,345,3,107, -0,345,3,108,0, -345,1127,11,1,867, -0,348,1,-1,3, -110,0,345,3,111, -0,345,3,112,0, -345,3,113,0,345, -3,114,0,345,3, -115,0,345,3,116, -0,345,3,117,0, -345,3,118,0,345, -3,119,0,345,3, -120,0,345,3,121, -0,345,3,122,0, -345,3,48,0,345, -3,49,0,345,3, -50,0,345,3,51, -0,345,3,52,0, -345,3,53,0,345, -3,54,0,345,3, -55,0,345,3,56, -0,345,3,57,0, -345,3,65,0,345, -3,66,0,345,3, -67,0,345,3,68, -0,345,3,69,0, -345,3,70,0,345, -3,71,0,345,3, -72,0,345,3,73, -0,345,3,74,0, -345,3,75,0,345, -3,76,0,345,3, -77,0,345,3,78, -0,345,3,79,0, -345,3,80,0,345, -3,81,0,345,3, -82,0,345,3,83, -0,345,3,84,0, -345,3,85,0,345, -3,86,0,345,3, -87,0,345,3,88, -0,345,3,89,0, -345,3,90,0,345, -3,95,0,345,3, -97,0,345,3,98, -0,345,3,99,0, -345,3,100,0,345, -3,101,0,345,3, -102,0,345,3,103, -0,345,3,104,0, -345,3,105,0,345, -3,106,0,345,3, -107,0,345,3,108, -0,345,1128,11,1, -867,0,348,1,-1, -3,106,0,345,3, -107,0,345,3,108, -0,345,1129,11,1, -867,0,348,1,-1, -3,117,0,345,3, -118,0,345,3,119, -0,345,3,120,0, -345,3,121,0,345, -3,122,0,345,3, -48,0,345,3,49, -0,345,3,50,0, -345,3,51,0,345, -3,52,0,345,3, -53,0,345,3,54, -0,345,3,55,0, -345,3,56,0,345, -3,57,0,345,3, -65,0,345,3,66, -0,345,3,67,0, -345,3,68,0,345, -3,69,0,345,3, -70,0,345,3,71, -0,345,3,72,0, -345,3,73,0,345, -3,74,0,345,3, -75,0,345,3,76, -0,345,3,77,0, -345,3,78,0,345, -3,79,0,345,3, -80,0,345,3,81, -0,345,3,82,0, -345,3,83,0,345, -3,84,0,345,3, -85,0,345,3,86, -0,345,3,87,0, -345,3,88,0,345, -3,89,0,345,3, -90,0,345,3,95, -0,345,3,97,0, -345,3,98,0,345, -3,99,0,345,3, -100,0,345,3,101, -0,345,3,102,0, -345,3,103,0,345, -3,104,0,345,3, -105,0,345,3,106, -0,345,3,107,0, -345,3,108,0,345, -1130,11,1,867,0, -348,1,-1,3,97, -0,345,3,98,0, -345,3,99,0,345, -3,100,0,345,3, -101,0,345,3,102, -0,345,3,103,0, -345,3,104,0,345, -3,105,0,345,3, -106,0,345,3,107, -0,345,3,108,0, -345,1131,11,1,867, -0,348,1,-1,3, -111,0,345,3,112, -0,345,3,113,0, -345,3,114,0,345, -3,115,0,345,3, -116,0,345,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,345,3, -98,0,345,3,99, -0,345,3,100,0, -345,3,101,0,345, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -345,3,106,0,345, -3,107,0,345,3, -108,0,345,1132,11, -1,867,0,348,1, --1,3,118,0,345, -3,119,0,345,3, -120,0,345,3,121, -0,345,3,122,0, -345,3,48,0,345, -3,49,0,345,3, -50,0,345,3,51, -0,345,3,52,0, -345,3,53,0,345, -3,54,0,345,3, -55,0,345,3,56, -0,345,3,57,0, -345,3,65,0,345, -3,66,0,345,3, -67,0,345,3,68, -0,345,3,69,0, -345,3,70,0,345, -3,71,0,345,3, -72,0,345,3,73, -0,345,3,74,0, -345,3,75,0,345, -3,76,0,345,3, -77,0,345,3,78, -0,345,3,79,0, -345,3,80,0,345, -3,81,0,345,3, -82,0,345,3,83, -0,345,3,84,0, -345,3,85,0,345, -3,86,0,345,3, -87,0,345,3,88, -0,345,3,89,0, -345,3,90,0,345, -3,95,0,345,3, -97,0,345,3,98, -0,345,3,99,0, -345,3,100,0,345, -3,101,0,1133,12, -1,12696,1134,5,63, -3,109,0,1135,12, -1,12724,1136,5,63, -3,109,0,345,3, -110,0,345,3,111, -0,1137,12,1,12754, -1138,5,63,3,109, -0,345,3,110,0, -345,3,111,0,345, -3,112,0,345,3, -113,0,345,3,114, -0,345,3,115,0, -345,3,116,0,1139, -12,1,12789,1140,5, -63,3,109,0,345, -3,110,0,345,3, -111,0,345,3,112, -0,345,3,113,0, -345,3,114,0,345, -3,115,0,345,3, -116,0,345,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,345,3, -98,0,345,3,99, -0,345,3,100,0, -345,3,101,0,1141, -12,1,12836,1142,5, -63,3,109,0,345, -3,110,0,345,3, -111,0,345,3,112, -0,345,3,113,0, -345,3,114,0,345, -3,115,0,345,3, -116,0,345,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,1143, -12,1,12922,1144,5, -63,3,109,0,345, -3,110,0,345,3, -111,0,345,3,112, -0,345,3,113,0, -345,3,114,0,345, -3,115,0,345,3, -116,0,345,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,345,3, -98,0,345,3,99, -0,345,3,100,0, -1145,12,1,12968,1146, -5,63,3,109,0, -345,3,110,0,345, -3,111,0,345,3, -112,0,345,3,113, -0,345,3,114,0, -345,3,115,0,345, -3,116,0,345,3, -117,0,345,3,118, -0,345,3,119,0, -345,3,120,0,345, -3,121,0,345,3, -122,0,345,3,48, -0,345,3,49,0, -345,3,50,0,345, -3,51,0,345,3, -52,0,345,3,53, -0,345,3,54,0, -345,3,55,0,345, -3,56,0,345,3, -57,0,345,3,65, -0,345,3,66,0, -345,3,67,0,345, -3,68,0,345,3, -69,0,345,3,70, -0,345,3,71,0, -345,3,72,0,345, -3,73,0,345,3, -74,0,345,3,75, -0,345,3,76,0, -345,3,77,0,345, -3,78,0,345,3, -79,0,345,3,80, -0,345,3,81,0, -345,3,82,0,345, -3,83,0,345,3, -84,0,345,3,85, -0,345,3,86,0, -345,3,87,0,345, -3,88,0,345,3, -89,0,345,3,90, -0,345,3,95,0, -345,3,97,0,1147, -12,1,13011,1148,5, -63,3,109,0,345, -3,110,0,345,3, -111,0,345,3,112, -0,345,3,113,0, -345,3,114,0,345, -3,115,0,345,3, -116,0,1149,12,1, -13046,1150,5,63,3, -109,0,345,3,110, -0,345,3,111,0, -345,3,112,0,345, -3,113,0,345,3, -114,0,345,3,115, -0,345,3,116,0, -345,3,117,0,345, -3,118,0,345,3, -119,0,345,3,120, -0,345,3,121,0, -345,3,122,0,345, -3,48,0,345,3, -49,0,345,3,50, -0,345,3,51,0, -345,3,52,0,345, -3,53,0,345,3, -54,0,345,3,55, -0,345,3,56,0, -345,3,57,0,345, -3,65,0,345,3, -66,0,345,3,67, -0,345,3,68,0, -345,3,69,0,345, -3,70,0,345,3, -71,0,345,3,72, -0,345,3,73,0, -345,3,74,0,345, -3,75,0,345,3, -76,0,345,3,77, -0,345,3,78,0, -345,3,79,0,345, -3,80,0,345,3, -81,0,345,3,82, -0,345,3,83,0, -345,3,84,0,345, -3,85,0,345,3, -86,0,345,3,87, -0,345,3,88,0, -345,3,89,0,345, -3,90,0,345,3, -95,0,345,3,97, -0,1151,12,1,13089, -1152,5,63,3,109, -0,345,3,110,0, -345,3,111,0,345, -3,112,0,345,3, -113,0,345,3,114, -0,345,3,115,0, -345,3,116,0,345, -3,117,0,345,3, -118,0,345,3,119, -0,345,3,120,0, -345,3,121,0,345, -3,122,0,345,3, -48,0,345,3,49, -0,345,3,50,0, -345,3,51,0,345, -3,52,0,345,3, -53,0,345,3,54, -0,345,3,55,0, -345,3,56,0,345, -3,57,0,345,3, -65,0,345,3,66, -0,345,3,67,0, -345,3,68,0,345, -3,69,0,345,3, -70,0,345,3,71, -0,345,3,72,0, -345,3,73,0,345, -3,74,0,345,3, -75,0,345,3,76, -0,345,3,77,0, -345,3,78,0,345, -3,79,0,345,3, -80,0,345,3,81, -0,345,3,82,0, -345,3,83,0,345, -3,84,0,345,3, -85,0,345,3,86, -0,345,3,87,0, -345,3,88,0,345, -3,89,0,345,3, -90,0,345,3,95, -0,345,3,97,0, -345,3,98,0,345, -3,99,0,345,3, -100,0,345,3,101, -0,345,3,102,0, -345,3,103,0,345, -3,104,0,345,3, -105,0,345,3,106, -0,345,3,107,0, -345,3,108,0,345, -1153,11,1,705,0, -1154,4,34,82,0, -69,0,77,0,79, -0,84,0,69,0, -95,0,68,0,65, +65,0,84,0,95, 0,84,0,65,0, -95,0,69,0,86, -0,69,0,78,0, -84,0,1,-1,3, -98,0,345,3,99, -0,345,3,100,0, -345,3,101,0,345, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -345,3,106,0,345, -3,107,0,345,3, -108,0,345,1155,11, -1,867,0,348,1, --1,3,117,0,345, -3,118,0,345,3, -119,0,345,3,120, -0,345,3,121,0, -345,3,122,0,345, -3,48,0,345,3, -49,0,345,3,50, -0,345,3,51,0, -345,3,52,0,345, -3,53,0,345,3, -54,0,345,3,55, -0,345,3,56,0, -345,3,57,0,345, -3,65,0,345,3, -66,0,345,3,67, -0,345,3,68,0, -345,3,69,0,345, -3,70,0,345,3, -71,0,345,3,72, -0,345,3,73,0, -345,3,74,0,345, -3,75,0,345,3, -76,0,345,3,77, -0,345,3,78,0, -345,3,79,0,345, -3,80,0,345,3, -81,0,345,3,82, -0,345,3,83,0, -345,3,84,0,345, -3,85,0,345,3, -86,0,345,3,87, -0,345,3,88,0, -345,3,89,0,345, -3,90,0,345,3, -95,0,345,3,97, -0,345,3,98,0, -345,3,99,0,345, -3,100,0,345,3, -101,0,345,3,102, -0,345,3,103,0, -345,3,104,0,345, -3,105,0,345,3, -106,0,345,3,107, -0,345,3,108,0, -345,1156,11,1,867, -0,348,1,-1,3, -98,0,345,3,99, -0,345,3,100,0, -345,3,101,0,345, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -345,3,106,0,345, -3,107,0,345,3, -108,0,345,1157,11, -1,867,0,348,1, --1,3,101,0,345, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -345,3,106,0,345, -3,107,0,345,3, -108,0,345,1158,11, -1,867,0,348,1, --1,3,97,0,345, -3,98,0,345,3, -99,0,345,3,100, -0,345,3,101,0, -345,3,102,0,345, -3,103,0,345,3, -104,0,345,3,105, -0,345,3,106,0, -345,3,107,0,345, -3,108,0,345,1159, -11,1,867,0,348, -1,-1,3,102,0, -345,3,103,0,345, -3,104,0,345,3, -105,0,345,3,106, -0,345,3,107,0, -345,3,108,0,345, -1160,11,1,867,0, -348,1,-1,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,345,3, -98,0,345,3,99, -0,345,3,100,0, -345,3,101,0,345, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -345,3,106,0,345, -3,107,0,345,3, -108,0,345,1161,11, -1,867,0,348,1, --1,3,112,0,345, -3,113,0,345,3, -114,0,345,3,115, -0,345,3,116,0, -345,3,117,0,345, -3,118,0,345,3, -119,0,345,3,120, -0,345,3,121,0, -345,3,122,0,345, -3,48,0,345,3, -49,0,345,3,50, -0,345,3,51,0, -345,3,52,0,345, -3,53,0,345,3, -54,0,345,3,55, -0,345,3,56,0, -345,3,57,0,345, -3,65,0,345,3, -66,0,345,3,67, -0,345,3,68,0, -345,3,69,0,345, -3,70,0,345,3, -71,0,345,3,72, -0,345,3,73,0, -345,3,74,0,345, -3,75,0,345,3, -76,0,345,3,77, -0,345,3,78,0, -345,3,79,0,345, -3,80,0,345,3, -81,0,345,3,82, -0,345,3,83,0, -345,3,84,0,345, -3,85,0,345,3, -86,0,345,3,87, -0,345,3,88,0, -345,3,89,0,345, -3,90,0,345,3, -95,0,345,3,97, -0,345,3,98,0, -345,3,99,0,345, -3,100,0,345,3, -101,0,345,3,102, -0,345,3,103,0, -345,3,104,0,345, -3,105,0,345,3, -106,0,345,3,107, -0,345,3,108,0, -345,1162,11,1,867, -0,348,1,-1,3, -110,0,345,3,111, -0,345,3,112,0, -345,3,113,0,345, -3,114,0,345,3, -115,0,345,3,116, -0,1163,12,1,13811, -1164,5,63,3,109, -0,345,3,110,0, -345,3,111,0,345, -3,112,0,345,3, -113,0,345,3,114, -0,345,3,115,0, -345,3,116,0,345, -3,117,0,1165,12, -1,13847,1166,5,63, -3,109,0,345,3, -110,0,345,3,111, -0,345,3,112,0, -345,3,113,0,345, -3,114,0,1167,12, -1,13880,1168,5,63, -3,109,0,345,3, -110,0,1169,12,1, -13909,1170,5,63,3, -109,0,345,3,110, -0,345,3,111,0, -345,3,112,0,345, -3,113,0,345,3, -114,0,345,3,115, -0,345,3,116,0, -345,3,117,0,345, -3,118,0,345,3, -119,0,345,3,120, -0,345,3,121,0, -345,3,122,0,345, -3,48,0,345,3, -49,0,345,3,50, -0,345,3,51,0, -345,3,52,0,345, -3,53,0,345,3, -54,0,345,3,55, -0,345,3,56,0, -345,3,57,0,345, -3,65,0,345,3, -66,0,345,3,67, -0,345,3,68,0, -345,3,69,0,345, -3,70,0,345,3, -71,0,345,3,72, -0,345,3,73,0, -345,3,74,0,345, -3,75,0,345,3, -76,0,345,3,77, -0,345,3,78,0, -345,3,79,0,345, -3,80,0,345,3, -81,0,345,3,82, -0,345,3,83,0, -345,3,84,0,345, -3,85,0,345,3, -86,0,345,3,87, -0,345,3,88,0, -345,3,89,0,345, -3,90,0,345,3, -95,0,345,3,97, -0,345,3,98,0, -345,3,99,0,345, -3,100,0,345,3, -101,0,345,3,102, -0,345,3,103,0, -345,3,104,0,345, -3,105,0,345,3, -106,0,345,3,107, -0,345,3,108,0, -345,1171,11,1,273, -0,1172,4,12,82, -0,69,0,84,0, -85,0,82,0,78, -0,1,-1,3,111, -0,345,3,112,0, -345,3,113,0,345, -3,114,0,345,3, -115,0,345,3,116, -0,345,3,117,0, -345,3,118,0,345, -3,119,0,345,3, -120,0,345,3,121, -0,345,3,122,0, -345,3,48,0,345, -3,49,0,345,3, -50,0,345,3,51, -0,345,3,52,0, -345,3,53,0,345, -3,54,0,345,3, -55,0,345,3,56, -0,345,3,57,0, -345,3,65,0,345, -3,66,0,345,3, -67,0,345,3,68, -0,345,3,69,0, -345,3,70,0,345, -3,71,0,345,3, -72,0,345,3,73, -0,345,3,74,0, -345,3,75,0,345, -3,76,0,345,3, -77,0,345,3,78, -0,345,3,79,0, -345,3,80,0,345, -3,81,0,345,3, -82,0,345,3,83, -0,345,3,84,0, -345,3,85,0,345, -3,86,0,345,3, -87,0,345,3,88, -0,345,3,89,0, -345,3,90,0,345, -3,95,0,345,3, -97,0,345,3,98, -0,345,3,99,0, -345,3,100,0,345, -3,101,0,345,3, -102,0,345,3,103, -0,345,3,104,0, -345,3,105,0,345, -3,106,0,345,3, -107,0,345,3,108, -0,345,1173,11,1, -867,0,348,1,-1, -3,115,0,345,3, -116,0,345,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,345,3, -98,0,345,3,99, -0,345,3,100,0, -345,3,101,0,345, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -345,3,106,0,345, -3,107,0,345,3, -108,0,345,1174,11, -1,867,0,348,1, --1,3,118,0,345, -3,119,0,345,3, -120,0,345,3,121, -0,345,3,122,0, -345,3,48,0,345, -3,49,0,345,3, -50,0,345,3,51, -0,345,3,52,0, -345,3,53,0,345, -3,54,0,345,3, -55,0,345,3,56, -0,345,3,57,0, -345,3,65,0,345, -3,66,0,345,3, -67,0,345,3,68, -0,345,3,69,0, -345,3,70,0,345, -3,71,0,345,3, -72,0,345,3,73, -0,345,3,74,0, -345,3,75,0,345, -3,76,0,345,3, -77,0,345,3,78, -0,345,3,79,0, -345,3,80,0,345, -3,81,0,345,3, -82,0,345,3,83, -0,345,3,84,0, -345,3,85,0,345, -3,86,0,345,3, -87,0,345,3,88, -0,345,3,89,0, -345,3,90,0,345, -3,95,0,345,3, -97,0,345,3,98, -0,345,3,99,0, -345,3,100,0,345, -3,101,0,345,3, -102,0,345,3,103, -0,345,3,104,0, -345,3,105,0,345, -3,106,0,345,3, -107,0,345,3,108, -0,345,1175,11,1, -867,0,348,1,-1, -3,117,0,345,3, -118,0,345,3,119, -0,345,3,120,0, -345,3,121,0,345, -3,122,0,345,3, -48,0,345,3,49, -0,345,3,50,0, -345,3,51,0,345, -3,52,0,345,3, -53,0,345,3,54, -0,345,3,55,0, -345,3,56,0,345, -3,57,0,345,3, -65,0,345,3,66, -0,345,3,67,0, -345,3,68,0,345, -3,69,0,345,3, -70,0,345,3,71, -0,345,3,72,0, -345,3,73,0,345, -3,74,0,345,3, -75,0,345,3,76, -0,345,3,77,0, -345,3,78,0,345, -3,79,0,345,3, -80,0,345,3,81, -0,345,3,82,0, -345,3,83,0,345, -3,84,0,345,3, -85,0,345,3,86, -0,345,3,87,0, -345,3,88,0,345, -3,89,0,345,3, -90,0,345,3,95, -0,345,3,97,0, -345,3,98,0,345, -3,99,0,345,3, -100,0,345,3,101, -0,345,3,102,0, -345,3,103,0,345, -3,104,0,345,3, -105,0,345,3,106, -0,345,3,107,0, -345,3,108,0,345, -1176,11,1,867,0, -348,1,-1,3,102, -0,345,3,103,0, -345,3,104,0,345, -3,105,0,345,3, -106,0,345,3,107, -0,345,3,108,0, -345,1177,11,1,867, -0,348,1,-1,3, -115,0,1178,12,1, -14450,1179,5,63,3, -109,0,345,3,110, -0,345,3,111,0, -345,3,112,0,345, -3,113,0,345,3, -114,0,345,3,115, -0,345,3,116,0, -1180,12,1,14485,1181, -5,63,3,109,0, -345,3,110,0,345, -3,111,0,345,3, -112,0,345,3,113, -0,345,3,114,0, -1182,12,1,14518,1183, -5,63,3,109,0, -345,3,110,0,345, -3,111,0,345,3, -112,0,345,3,113, -0,345,3,114,0, -345,3,115,0,345, -3,116,0,345,3, -117,0,345,3,118, -0,345,3,119,0, -345,3,120,0,345, -3,121,0,345,3, -122,0,345,3,48, -0,345,3,49,0, -345,3,50,0,345, -3,51,0,345,3, -52,0,345,3,53, -0,345,3,54,0, -345,3,55,0,345, -3,56,0,345,3, -57,0,345,3,65, -0,345,3,66,0, -345,3,67,0,345, -3,68,0,345,3, -69,0,345,3,70, -0,345,3,71,0, -345,3,72,0,345, -3,73,0,345,3, -74,0,345,3,75, -0,345,3,76,0, -345,3,77,0,345, -3,78,0,345,3, -79,0,345,3,80, -0,345,3,81,0, -345,3,82,0,345, -3,83,0,345,3, -84,0,345,3,85, -0,345,3,86,0, -345,3,87,0,345, -3,88,0,345,3, -89,0,345,3,90, -0,345,3,95,0, -345,3,97,0,345, -3,98,0,345,3, -99,0,345,3,100, -0,345,3,101,0, -345,3,102,0,345, -3,103,0,345,3, -104,0,345,3,105, -0,1184,12,1,14569, -1185,5,63,3,109, -0,345,3,110,0, -1186,12,1,14598,1187, -5,63,3,109,0, -345,3,110,0,345, -3,111,0,345,3, -112,0,345,3,113, -0,345,3,114,0, -345,3,115,0,345, -3,116,0,345,3, -117,0,345,3,118, -0,345,3,119,0, -345,3,120,0,345, -3,121,0,345,3, -122,0,345,3,48, -0,345,3,49,0, -345,3,50,0,345, -3,51,0,345,3, -52,0,345,3,53, -0,345,3,54,0, -345,3,55,0,345, -3,56,0,345,3, -57,0,345,3,65, -0,345,3,66,0, -345,3,67,0,345, -3,68,0,345,3, -69,0,345,3,70, -0,345,3,71,0, -345,3,72,0,345, -3,73,0,345,3, -74,0,345,3,75, -0,345,3,76,0, -345,3,77,0,345, -3,78,0,345,3, -79,0,345,3,80, -0,345,3,81,0, -345,3,82,0,345, -3,83,0,345,3, -84,0,345,3,85, -0,345,3,86,0, -345,3,87,0,345, -3,88,0,345,3, -89,0,345,3,90, -0,345,3,95,0, -345,3,97,0,345, -3,98,0,345,3, -99,0,345,3,100, -0,345,3,101,0, -345,3,102,0,345, -3,103,0,1188,12, -1,14647,1189,5,63, -3,109,0,345,3, -110,0,345,3,111, -0,345,3,112,0, -345,3,113,0,345, -3,114,0,345,3, -115,0,345,3,116, -0,345,3,117,0, -345,3,118,0,345, -3,119,0,345,3, -120,0,345,3,121, -0,345,3,122,0, -345,3,48,0,345, -3,49,0,345,3, -50,0,345,3,51, -0,345,3,52,0, -345,3,53,0,345, -3,54,0,345,3, -55,0,345,3,56, -0,345,3,57,0, -345,3,65,0,345, -3,66,0,345,3, -67,0,345,3,68, -0,345,3,69,0, -345,3,70,0,345, -3,71,0,345,3, -72,0,345,3,73, -0,345,3,74,0, -345,3,75,0,345, -3,76,0,345,3, -77,0,345,3,78, -0,345,3,79,0, -345,3,80,0,345, -3,81,0,345,3, -82,0,345,3,83, -0,345,3,84,0, -345,3,85,0,345, -3,86,0,345,3, -87,0,345,3,88, -0,345,3,89,0, -345,3,90,0,345, -3,95,0,345,3, -97,0,345,3,98, -0,345,3,99,0, -345,3,100,0,345, -3,101,0,345,3, -102,0,345,3,103, -0,345,3,104,0, -345,3,105,0,345, -3,106,0,345,3, -107,0,345,3,108, -0,345,1190,11,1, -303,0,1191,4,22, -83,0,84,0,82, -0,73,0,78,0, -71,0,95,0,84, -0,89,0,80,0, -69,0,1,-1,3, -104,0,345,3,105, -0,345,3,106,0, -345,3,107,0,345, -3,108,0,345,1192, -11,1,867,0,348, -1,-1,3,111,0, -345,3,112,0,345, -3,113,0,345,3, -114,0,345,3,115, -0,345,3,116,0, -345,3,117,0,345, -3,118,0,345,3, -119,0,345,3,120, -0,345,3,121,0, -345,3,122,0,345, -3,48,0,345,3, -49,0,345,3,50, -0,345,3,51,0, -345,3,52,0,345, -3,53,0,345,3, -54,0,345,3,55, -0,345,3,56,0, -345,3,57,0,345, -3,65,0,345,3, -66,0,345,3,67, -0,345,3,68,0, -345,3,69,0,345, -3,70,0,345,3, -71,0,345,3,72, -0,345,3,73,0, -345,3,74,0,345, -3,75,0,345,3, -76,0,345,3,77, -0,345,3,78,0, -345,3,79,0,345, -3,80,0,345,3, -81,0,345,3,82, -0,345,3,83,0, -345,3,84,0,345, -3,85,0,345,3, -86,0,345,3,87, -0,345,3,88,0, -345,3,89,0,345, -3,90,0,345,3, -95,0,345,3,97, -0,345,3,98,0, -345,3,99,0,345, -3,100,0,345,3, -101,0,345,3,102, -0,345,3,103,0, -345,3,104,0,345, -3,105,0,345,3, -106,0,345,3,107, -0,345,3,108,0, -345,1193,11,1,867, -0,348,1,-1,3, -106,0,345,3,107, -0,345,3,108,0, -345,1194,11,1,867, -0,348,1,-1,3, -115,0,345,3,116, -0,345,3,117,0, -345,3,118,0,345, -3,119,0,345,3, -120,0,345,3,121, -0,345,3,122,0, -345,3,48,0,345, -3,49,0,345,3, -50,0,345,3,51, -0,345,3,52,0, -345,3,53,0,345, -3,54,0,345,3, -55,0,345,3,56, -0,345,3,57,0, -345,3,65,0,345, -3,66,0,345,3, -67,0,345,3,68, -0,345,3,69,0, -345,3,70,0,345, -3,71,0,345,3, -72,0,345,3,73, -0,345,3,74,0, -345,3,75,0,345, -3,76,0,345,3, -77,0,345,3,78, -0,345,3,79,0, -345,3,80,0,345, -3,81,0,345,3, -82,0,345,3,83, -0,345,3,84,0, -345,3,85,0,345, -3,86,0,345,3, -87,0,345,3,88, -0,345,3,89,0, -345,3,90,0,345, -3,95,0,345,3, -97,0,1195,12,1, -15008,1196,5,63,3, -109,0,345,3,110, -0,345,3,111,0, -345,3,112,0,345, -3,113,0,345,3, -114,0,345,3,115, -0,345,3,116,0, -1197,12,1,15043,1198, -5,63,3,109,0, -345,3,110,0,345, -3,111,0,345,3, -112,0,345,3,113, -0,345,3,114,0, -345,3,115,0,345, -3,116,0,345,3, -117,0,345,3,118, -0,345,3,119,0, -345,3,120,0,345, -3,121,0,345,3, -122,0,345,3,48, -0,345,3,49,0, -345,3,50,0,345, -3,51,0,345,3, -52,0,345,3,53, -0,345,3,54,0, -345,3,55,0,345, -3,56,0,345,3, -57,0,345,3,65, -0,345,3,66,0, -345,3,67,0,345, -3,68,0,345,3, -69,0,345,3,70, -0,345,3,71,0, -345,3,72,0,345, -3,73,0,345,3, -74,0,345,3,75, -0,345,3,76,0, -345,3,77,0,345, -3,78,0,345,3, -79,0,345,3,80, -0,345,3,81,0, -345,3,82,0,345, -3,83,0,345,3, -84,0,345,3,85, -0,345,3,86,0, -345,3,87,0,345, -3,88,0,345,3, -89,0,345,3,90, -0,345,3,95,0, -345,3,97,0,345, -3,98,0,345,3, -99,0,345,3,100, -0,345,3,101,0, -1199,12,1,15090,1200, -5,63,3,109,0, -345,3,110,0,345, -3,111,0,345,3, -112,0,345,3,113, -0,345,3,114,0, -345,3,115,0,345, -3,116,0,345,3, -117,0,345,3,118, -0,345,3,119,0, -345,3,120,0,345, -3,121,0,345,3, -122,0,345,3,48, -0,345,3,49,0, -345,3,50,0,345, -3,51,0,345,3, -52,0,345,3,53, -0,345,3,54,0, -345,3,55,0,345, -3,56,0,345,3, -57,0,345,3,65, -0,345,3,66,0, -345,3,67,0,345, -3,68,0,345,3, -69,0,345,3,70, -0,345,3,71,0, -345,3,72,0,345, -3,73,0,345,3, -74,0,345,3,75, -0,345,3,76,0, -345,3,77,0,345, -3,78,0,345,3, -79,0,345,3,80, -0,345,3,81,0, -345,3,82,0,345, -3,83,0,345,3, -84,0,345,3,85, -0,345,3,86,0, -345,3,87,0,345, -3,88,0,345,3, -89,0,345,3,90, -0,345,3,95,0, -1201,12,1,15176,1202, -5,63,3,109,0, -345,3,110,0,345, -3,111,0,345,3, -112,0,345,3,113, -0,345,3,114,0, -345,3,115,0,345, -3,116,0,345,3, -117,0,345,3,118, -0,345,3,119,0, -345,3,120,0,345, -3,121,0,345,3, -122,0,345,3,48, -0,345,3,49,0, -345,3,50,0,345, -3,51,0,345,3, -52,0,345,3,53, -0,345,3,54,0, -345,3,55,0,345, -3,56,0,345,3, -57,0,345,3,65, -0,345,3,66,0, -345,3,67,0,345, -3,68,0,345,3, -69,0,345,3,70, -0,345,3,71,0, -345,3,72,0,345, -3,73,0,345,3, -74,0,345,3,75, -0,345,3,76,0, -345,3,77,0,345, -3,78,0,345,3, -79,0,345,3,80, -0,345,3,81,0, -345,3,82,0,345, -3,83,0,345,3, -84,0,345,3,85, -0,345,3,86,0, -345,3,87,0,345, -3,88,0,345,3, -89,0,345,3,90, -0,345,3,95,0, -345,3,97,0,345, -3,98,0,345,3, -99,0,345,3,100, -0,345,3,101,0, -1203,12,1,15223,1204, -5,63,3,109,0, -345,3,110,0,1205, -12,1,15252,1206,5, -63,3,109,0,345, -3,110,0,345,3, -111,0,345,3,112, -0,345,3,113,0, -345,3,114,0,345, -3,115,0,345,3, -116,0,1207,12,1, -15287,1208,5,63,3, -109,0,345,3,110, -0,345,3,111,0, -345,3,112,0,345, -3,113,0,345,3, -114,0,1209,12,1, -15320,1210,5,63,3, -109,0,345,3,110, -0,345,3,111,0, -345,3,112,0,345, -3,113,0,345,3, -114,0,345,3,115, -0,345,3,116,0, -345,3,117,0,345, -3,118,0,345,3, -119,0,345,3,120, -0,345,3,121,0, -1211,12,1,15360,1212, -5,63,3,109,0, -345,3,110,0,345, -3,111,0,345,3, -112,0,345,3,113, -0,345,3,114,0, -345,3,115,0,345, -3,116,0,345,3, -117,0,345,3,118, -0,345,3,119,0, -345,3,120,0,345, -3,121,0,345,3, -122,0,345,3,48, -0,345,3,49,0, -345,3,50,0,345, -3,51,0,345,3, -52,0,345,3,53, -0,345,3,54,0, -345,3,55,0,345, -3,56,0,345,3, -57,0,345,3,65, -0,345,3,66,0, -345,3,67,0,345, -3,68,0,345,3, -69,0,345,3,70, -0,345,3,71,0, -345,3,72,0,345, -3,73,0,345,3, -74,0,345,3,75, -0,345,3,76,0, -345,3,77,0,345, -3,78,0,345,3, -79,0,345,3,80, -0,345,3,81,0, -345,3,82,0,345, -3,83,0,345,3, -84,0,345,3,85, -0,345,3,86,0, -345,3,87,0,345, -3,88,0,345,3, -89,0,345,3,90, -0,345,3,95,0, -345,3,97,0,345, -3,98,0,345,3, -99,0,345,3,100, -0,345,3,101,0, -345,3,102,0,345, -3,103,0,345,3, -104,0,345,3,105, -0,345,3,106,0, -345,3,107,0,345, -3,108,0,345,1213, -11,1,754,0,1214, -4,34,83,0,84, -0,65,0,84,0, -69,0,95,0,69, -0,78,0,84,0, -82,0,89,0,95, -0,69,0,86,0, -69,0,78,0,84, -0,1,-1,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,345,3, -98,0,345,3,99, -0,345,3,100,0, -345,3,101,0,345, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -345,3,106,0,345, -3,107,0,345,3, -108,0,345,1215,11, -1,867,0,348,1, --1,3,115,0,345, -3,116,0,345,3, -117,0,345,3,118, -0,345,3,119,0, -345,3,120,0,345, -3,121,0,345,3, -122,0,345,3,48, -0,345,3,49,0, -345,3,50,0,345, -3,51,0,345,3, -52,0,345,3,53, -0,345,3,54,0, -345,3,55,0,345, -3,56,0,345,3, -57,0,345,3,65, -0,345,3,66,0, -345,3,67,0,345, -3,68,0,345,3, -69,0,345,3,70, -0,345,3,71,0, -345,3,72,0,345, -3,73,0,345,3, -74,0,345,3,75, -0,345,3,76,0, -345,3,77,0,345, -3,78,0,345,3, -79,0,345,3,80, -0,345,3,81,0, -345,3,82,0,345, -3,83,0,345,3, -84,0,345,3,85, -0,345,3,86,0, -345,3,87,0,345, -3,88,0,345,3, -89,0,345,3,90, -0,345,3,95,0, -345,3,97,0,345, -3,98,0,345,3, -99,0,345,3,100, -0,345,3,101,0, -345,3,102,0,345, -3,103,0,345,3, -104,0,345,3,105, -0,345,3,106,0, -345,3,107,0,345, -3,108,0,345,1216, -11,1,867,0,348, -1,-1,3,117,0, -345,3,118,0,345, -3,119,0,345,3, -120,0,345,3,121, -0,345,3,122,0, -345,3,48,0,345, -3,49,0,345,3, -50,0,345,3,51, -0,345,3,52,0, -345,3,53,0,345, -3,54,0,345,3, -55,0,345,3,56, -0,345,3,57,0, -345,3,65,0,345, -3,66,0,345,3, -67,0,345,3,68, -0,345,3,69,0, -345,3,70,0,345, -3,71,0,345,3, -72,0,345,3,73, -0,345,3,74,0, -345,3,75,0,345, -3,76,0,345,3, -77,0,345,3,78, -0,345,3,79,0, -345,3,80,0,345, -3,81,0,345,3, -82,0,345,3,83, -0,345,3,84,0, -345,3,85,0,345, -3,86,0,345,3, -87,0,345,3,88, -0,345,3,89,0, -345,3,90,0,345, -3,95,0,345,3, -97,0,345,3,98, -0,345,3,99,0, -345,3,100,0,345, -3,101,0,345,3, -102,0,345,3,103, -0,345,3,104,0, -345,3,105,0,345, -3,106,0,345,3, -107,0,345,3,108, -0,345,1217,11,1, -867,0,348,1,-1, -3,111,0,345,3, -112,0,345,3,113, -0,345,3,114,0, -345,3,115,0,345, -3,116,0,345,3, -117,0,345,3,118, -0,345,3,119,0, -345,3,120,0,1218, -12,1,15742,1219,5, -63,3,109,0,345, -3,110,0,345,3, -111,0,345,3,112, -0,345,3,113,0, -345,3,114,0,345, -3,115,0,345,3, -116,0,345,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,345,3, -98,0,345,3,99, -0,345,3,100,0, -345,3,101,0,345, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -1220,12,1,15793,1221, -5,63,3,109,0, -345,3,110,0,345, -3,111,0,345,3, -112,0,345,3,113, -0,345,3,114,0, -345,3,115,0,345, -3,116,0,1222,12, -1,15828,1223,5,63, -3,109,0,345,3, -110,0,345,3,111, -0,345,3,112,0, -345,3,113,0,345, -3,114,0,345,3, -115,0,345,3,116, -0,345,3,117,0, -345,3,118,0,345, -3,119,0,345,3, -120,0,345,3,121, -0,345,3,122,0, -345,3,48,0,345, -3,49,0,345,3, -50,0,345,3,51, -0,345,3,52,0, -345,3,53,0,345, -3,54,0,345,3, -55,0,345,3,56, -0,345,3,57,0, -345,3,65,0,345, -3,66,0,345,3, -67,0,345,3,68, -0,345,3,69,0, -345,3,70,0,345, -3,71,0,345,3, -72,0,345,3,73, -0,345,3,74,0, -345,3,75,0,345, -3,76,0,345,3, -77,0,345,3,78, -0,345,3,79,0, -345,3,80,0,345, -3,81,0,345,3, -82,0,345,3,83, -0,345,3,84,0, -345,3,85,0,345, -3,86,0,345,3, -87,0,345,3,88, -0,345,3,89,0, -345,3,90,0,345, -3,95,0,345,3, -97,0,345,3,98, -0,345,3,99,0, -345,3,100,0,345, -3,101,0,345,3, -102,0,345,3,103, -0,345,3,104,0, -345,3,105,0,345, -3,106,0,345,3, -107,0,345,3,108, -0,345,1224,11,1, -769,0,1225,4,32, -83,0,84,0,65, -0,84,0,69,0, -95,0,69,0,88, -0,73,0,84,0, -95,0,69,0,86, -0,69,0,78,0, -84,0,1,-1,3, -117,0,345,3,118, -0,345,3,119,0, -345,3,120,0,345, -3,121,0,345,3, -122,0,345,3,48, -0,345,3,49,0, -345,3,50,0,345, -3,51,0,345,3, -52,0,345,3,53, -0,345,3,54,0, -345,3,55,0,345, -3,56,0,345,3, -57,0,345,3,65, -0,345,3,66,0, -345,3,67,0,345, -3,68,0,345,3, -69,0,345,3,70, -0,345,3,71,0, -345,3,72,0,345, -3,73,0,345,3, -74,0,345,3,75, -0,345,3,76,0, -345,3,77,0,345, -3,78,0,345,3, -79,0,345,3,80, -0,345,3,81,0, -345,3,82,0,345, -3,83,0,345,3, -84,0,345,3,85, -0,345,3,86,0, -345,3,87,0,345, -3,88,0,345,3, -89,0,345,3,90, -0,345,3,95,0, -345,3,97,0,345, -3,98,0,345,3, -99,0,345,3,100, -0,345,3,101,0, -345,3,102,0,345, -3,103,0,345,3, -104,0,345,3,105, -0,345,3,106,0, -345,3,107,0,345, -3,108,0,345,1226, -11,1,867,0,348, -1,-1,3,106,0, -345,3,107,0,345, -3,108,0,345,1227, -11,1,867,0,348, -1,-1,3,121,0, -345,3,122,0,345, -3,48,0,345,3, -49,0,345,3,50, -0,345,3,51,0, -345,3,52,0,345, -3,53,0,345,3, -54,0,345,3,55, -0,345,3,56,0, -345,3,57,0,345, -3,65,0,345,3, -66,0,345,3,67, -0,345,3,68,0, -345,3,69,0,345, -3,70,0,345,3, -71,0,345,3,72, -0,345,3,73,0, -345,3,74,0,345, -3,75,0,345,3, -76,0,345,3,77, -0,345,3,78,0, -345,3,79,0,345, -3,80,0,345,3, -81,0,345,3,82, -0,345,3,83,0, -345,3,84,0,345, -3,85,0,345,3, -86,0,345,3,87, -0,345,3,88,0, -345,3,89,0,345, -3,90,0,345,3, -95,0,345,3,97, -0,345,3,98,0, -345,3,99,0,345, -3,100,0,345,3, -101,0,345,3,102, -0,345,3,103,0, -345,3,104,0,345, -3,105,0,345,3, -106,0,345,3,107, -0,345,3,108,0, -345,1228,11,1,867, -0,348,1,-1,3, -102,0,345,3,103, -0,345,3,104,0, -345,3,105,0,345, -3,106,0,345,3, -107,0,345,3,108, -0,345,1229,11,1, -867,0,348,1,-1, -3,97,0,345,3, -98,0,345,3,99, -0,345,3,100,0, -345,3,101,0,345, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -345,3,106,0,345, -3,107,0,345,3, -108,0,345,1230,11, -1,256,0,1231,4, -10,83,0,84,0, -65,0,84,0,69, -0,1,-1,3,102, -0,345,3,103,0, -345,3,104,0,345, -3,105,0,345,3, -106,0,345,3,107, -0,345,3,108,0, -345,1232,11,1,867, -0,348,1,-1,3, -117,0,345,3,118, -0,345,3,119,0, -345,3,120,0,345, -3,121,0,345,3, -122,0,345,3,48, -0,345,3,49,0, -345,3,50,0,345, -3,51,0,345,3, -52,0,345,3,53, -0,345,3,54,0, -345,3,55,0,345, -3,56,0,345,3, -57,0,345,3,65, -0,345,3,66,0, -345,3,67,0,345, -3,68,0,345,3, -69,0,345,3,70, -0,345,3,71,0, -345,3,72,0,345, -3,73,0,345,3, -74,0,345,3,75, -0,345,3,76,0, -345,3,77,0,345, -3,78,0,345,3, -79,0,345,3,80, -0,345,3,81,0, -345,3,82,0,345, -3,83,0,345,3, -84,0,345,3,85, -0,345,3,86,0, -345,3,87,0,345, -3,88,0,345,3, -89,0,345,3,90, -0,345,3,95,0, -345,3,97,0,345, -3,98,0,345,3, -99,0,345,3,100, -0,345,3,101,0, -345,3,102,0,345, -3,103,0,345,3, -104,0,345,3,105, -0,345,3,106,0, -345,3,107,0,345, -3,108,0,345,1233, -11,1,867,0,348, -1,-1,3,98,0, -345,3,99,0,345, -3,100,0,345,3, -101,0,345,3,102, -0,345,3,103,0, -345,3,104,0,345, -3,105,0,345,3, -106,0,345,3,107, -0,345,3,108,0, -345,1234,11,1,867, -0,348,1,-1,3, -117,0,345,3,118, -0,345,3,119,0, -345,3,120,0,345, -3,121,0,345,3, -122,0,345,3,48, -0,345,3,49,0, -345,3,50,0,345, -3,51,0,345,3, -52,0,345,3,53, -0,345,3,54,0, -345,3,55,0,345, -3,56,0,345,3, -57,0,345,3,65, -0,345,3,66,0, -345,3,67,0,345, -3,68,0,345,3, -69,0,345,3,70, -0,345,3,71,0, -345,3,72,0,345, -3,73,0,345,3, -74,0,345,3,75, -0,345,3,76,0, -345,3,77,0,345, -3,78,0,345,3, -79,0,345,3,80, -0,345,3,81,0, -345,3,82,0,345, -3,83,0,345,3, -84,0,345,3,85, -0,345,3,86,0, -345,3,87,0,345, -3,88,0,345,3, -89,0,345,3,90, -0,345,3,95,0, -345,3,97,0,345, -3,98,0,345,3, -99,0,345,3,100, -0,345,3,101,0, -1235,12,1,16537,1236, -5,63,3,109,0, -345,3,110,0,1237, -12,1,16566,1238,5, -63,3,109,0,345, -3,110,0,345,3, -111,0,345,3,112, -0,345,3,113,0, -345,3,114,0,345, -3,115,0,1239,12, -1,16600,1240,5,63, -3,109,0,345,3, -110,0,345,3,111, -0,1241,12,1,16630, -1242,5,63,3,109, -0,345,3,110,0, -345,3,111,0,345, -3,112,0,345,3, -113,0,345,3,114, -0,1243,12,1,16663, -1244,5,63,3,109, -0,345,3,110,0, -345,3,111,0,345, -3,112,0,345,3, -113,0,345,3,114, -0,345,3,115,0, -345,3,116,0,345, -3,117,0,345,3, -118,0,345,3,119, -0,345,3,120,0, -345,3,121,0,345, -3,122,0,345,3, -48,0,345,3,49, -0,345,3,50,0, -345,3,51,0,345, -3,52,0,345,3, -53,0,345,3,54, -0,345,3,55,0, -345,3,56,0,345, -3,57,0,345,3, -65,0,345,3,66, -0,345,3,67,0, -345,3,68,0,345, -3,69,0,345,3, -70,0,345,3,71, -0,345,3,72,0, -345,3,73,0,345, -3,74,0,345,3, -75,0,345,3,76, -0,345,3,77,0, -345,3,78,0,345, -3,79,0,345,3, -80,0,345,3,81, -0,345,3,82,0, -345,3,83,0,345, -3,84,0,345,3, -85,0,345,3,86, -0,345,3,87,0, -345,3,88,0,345, -3,89,0,345,3, -90,0,345,3,95, -0,345,3,97,0, -345,3,98,0,345, -3,99,0,345,3, -100,0,345,3,101, -0,345,3,102,0, -345,3,103,0,345, -3,104,0,345,3, -105,0,345,3,106, -0,345,3,107,0, -345,3,108,0,345, -1245,11,1,744,0, -1246,4,24,83,0, -69,0,78,0,83, -0,79,0,82,0, -95,0,69,0,86, -0,69,0,78,0, -84,0,1,-1,3, -115,0,345,3,116, -0,345,3,117,0, -345,3,118,0,345, -3,119,0,345,3, -120,0,345,3,121, -0,345,3,122,0, -345,3,48,0,345, -3,49,0,345,3, -50,0,345,3,51, -0,345,3,52,0, -345,3,53,0,345, -3,54,0,345,3, -55,0,345,3,56, -0,345,3,57,0, -345,3,65,0,345, -3,66,0,345,3, -67,0,345,3,68, -0,345,3,69,0, -345,3,70,0,345, -3,71,0,345,3, -72,0,345,3,73, -0,345,3,74,0, -345,3,75,0,345, -3,76,0,345,3, -77,0,345,3,78, -0,345,3,79,0, -345,3,80,0,345, -3,81,0,345,3, -82,0,345,3,83, -0,345,3,84,0, -345,3,85,0,345, -3,86,0,345,3, -87,0,345,3,88, -0,345,3,89,0, -345,3,90,0,345, -3,95,0,345,3, -97,0,345,3,98, -0,345,3,99,0, -345,3,100,0,345, -3,101,0,345,3, -102,0,345,3,103, -0,345,3,104,0, -345,3,105,0,345, -3,106,0,345,3, -107,0,345,3,108, -0,345,1247,11,1, -867,0,348,1,-1, -3,112,0,345,3, -113,0,345,3,114, -0,345,3,115,0, -345,3,116,0,345, -3,117,0,345,3, -118,0,345,3,119, -0,345,3,120,0, -345,3,121,0,345, -3,122,0,345,3, -48,0,345,3,49, -0,345,3,50,0, -345,3,51,0,345, -3,52,0,345,3, -53,0,345,3,54, -0,345,3,55,0, -345,3,56,0,345, -3,57,0,345,3, -65,0,345,3,66, -0,345,3,67,0, -345,3,68,0,345, -3,69,0,345,3, -70,0,345,3,71, -0,345,3,72,0, -345,3,73,0,345, -3,74,0,345,3, -75,0,345,3,76, -0,345,3,77,0, -345,3,78,0,345, -3,79,0,345,3, -80,0,345,3,81, -0,345,3,82,0, -345,3,83,0,345, -3,84,0,345,3, -85,0,345,3,86, -0,345,3,87,0, -345,3,88,0,345, -3,89,0,345,3, -90,0,345,3,95, -0,345,3,97,0, -345,3,98,0,345, -3,99,0,345,3, -100,0,345,3,101, -0,345,3,102,0, -345,3,103,0,345, -3,104,0,345,3, -105,0,345,3,106, -0,345,3,107,0, -345,3,108,0,345, -1248,11,1,867,0, -348,1,-1,3,116, -0,345,3,117,0, -345,3,118,0,345, -3,119,0,345,3, -120,0,345,3,121, -0,345,3,122,0, -345,3,48,0,345, -3,49,0,345,3, -50,0,345,3,51, -0,345,3,52,0, -345,3,53,0,345, -3,54,0,345,3, -55,0,345,3,56, -0,345,3,57,0, -345,3,65,0,345, -3,66,0,345,3, -67,0,345,3,68, -0,345,3,69,0, -345,3,70,0,345, -3,71,0,345,3, -72,0,345,3,73, -0,345,3,74,0, -345,3,75,0,345, -3,76,0,345,3, -77,0,345,3,78, -0,345,3,79,0, -345,3,80,0,345, -3,81,0,345,3, -82,0,345,3,83, -0,345,3,84,0, -345,3,85,0,345, -3,86,0,345,3, -87,0,345,3,88, -0,345,3,89,0, -345,3,90,0,345, -3,95,0,345,3, -97,0,345,3,98, -0,345,3,99,0, -345,3,100,0,345, -3,101,0,345,3, -102,0,345,3,103, -0,345,3,104,0, -345,3,105,0,345, -3,106,0,345,3, -107,0,345,3,108, -0,345,1249,11,1, -867,0,348,1,-1, -3,111,0,345,3, -112,0,345,3,113, -0,345,3,114,0, -345,3,115,0,345, -3,116,0,345,3, -117,0,345,3,118, -0,345,3,119,0, -345,3,120,0,345, -3,121,0,345,3, -122,0,345,3,48, -0,345,3,49,0, -345,3,50,0,345, -3,51,0,345,3, -52,0,345,3,53, -0,345,3,54,0, -345,3,55,0,345, -3,56,0,345,3, -57,0,345,3,65, -0,345,3,66,0, -345,3,67,0,345, -3,68,0,345,3, -69,0,345,3,70, -0,345,3,71,0, -345,3,72,0,345, -3,73,0,345,3, -74,0,345,3,75, -0,345,3,76,0, -345,3,77,0,345, -3,78,0,345,3, -79,0,345,3,80, -0,345,3,81,0, -345,3,82,0,345, -3,83,0,345,3, -84,0,345,3,85, -0,345,3,86,0, -345,3,87,0,345, -3,88,0,345,3, -89,0,345,3,90, -0,345,3,95,0, -345,3,97,0,345, -3,98,0,345,3, -99,0,345,3,100, -0,345,3,101,0, -345,3,102,0,345, -3,103,0,345,3, -104,0,345,3,105, -0,345,3,106,0, -345,3,107,0,345, -3,108,0,345,1250, -11,1,867,0,348, -1,-1,3,102,0, -345,3,103,0,345, -3,104,0,345,3, -105,0,345,3,106, -0,345,3,107,0, -345,3,108,0,345, -1251,11,1,867,0, -348,1,-1,3,116, -0,1252,12,1,17211, -1253,5,63,3,109, -0,345,3,110,0, -345,3,111,0,1254, -12,1,17241,1255,5, -63,3,109,0,345, -3,110,0,345,3, -111,0,345,3,112, -0,345,3,113,0, -345,3,114,0,345, -3,115,0,345,3, -116,0,345,3,117, -0,1256,12,1,17277, -1257,5,63,3,109, -0,345,3,110,0, -345,3,111,0,345, -3,112,0,345,3, -113,0,345,3,114, -0,345,3,115,0, -345,3,116,0,345, -3,117,0,345,3, -118,0,345,3,119, -0,345,3,120,0, -345,3,121,0,345, -3,122,0,345,3, -48,0,345,3,49, -0,345,3,50,0, -345,3,51,0,345, -3,52,0,345,3, -53,0,345,3,54, -0,345,3,55,0, -345,3,56,0,345, -3,57,0,345,3, -65,0,345,3,66, -0,345,3,67,0, -345,3,68,0,345, -3,69,0,345,3, -70,0,345,3,71, -0,345,3,72,0, -345,3,73,0,345, -3,74,0,345,3, -75,0,345,3,76, -0,345,3,77,0, -345,3,78,0,345, -3,79,0,345,3, -80,0,345,3,81, -0,345,3,82,0, -345,3,83,0,345, -3,84,0,345,3, -85,0,345,3,86, -0,345,3,87,0, -345,3,88,0,345, -3,89,0,345,3, -90,0,345,3,95, -0,345,3,97,0, -345,3,98,0,345, -3,99,0,1258,12, -1,17322,1259,5,63, -3,109,0,345,3, -110,0,345,3,111, -0,345,3,112,0, -345,3,113,0,345, -3,114,0,345,3, -115,0,345,3,116, -0,345,3,117,0, -345,3,118,0,345, -3,119,0,345,3, -120,0,345,3,121, -0,345,3,122,0, -345,3,48,0,345, -3,49,0,345,3, -50,0,345,3,51, -0,345,3,52,0, -345,3,53,0,345, -3,54,0,345,3, -55,0,345,3,56, -0,345,3,57,0, -345,3,65,0,345, -3,66,0,345,3, -67,0,345,3,68, -0,345,3,69,0, -345,3,70,0,345, -3,71,0,345,3, -72,0,345,3,73, -0,345,3,74,0, -345,3,75,0,345, -3,76,0,345,3, -77,0,345,3,78, -0,345,3,79,0, -345,3,80,0,345, -3,81,0,345,3, -82,0,345,3,83, -0,345,3,84,0, -345,3,85,0,345, -3,86,0,345,3, -87,0,345,3,88, -0,345,3,89,0, -345,3,90,0,345, -3,95,0,345,3, -97,0,345,3,98, -0,345,3,99,0, -345,3,100,0,345, -3,101,0,345,3, -102,0,345,3,103, -0,345,3,104,0, -1260,12,1,17372,1261, -5,63,3,109,0, -345,3,110,0,345, -3,111,0,345,3, -112,0,345,3,113, -0,345,3,114,0, -345,3,115,0,345, -3,116,0,345,3, -117,0,345,3,118, -0,345,3,119,0, -345,3,120,0,345, -3,121,0,345,3, -122,0,345,3,48, -0,345,3,49,0, -345,3,50,0,345, -3,51,0,345,3, -52,0,345,3,53, -0,345,3,54,0, -345,3,55,0,345, -3,56,0,345,3, -57,0,345,3,65, -0,345,3,66,0, -345,3,67,0,345, -3,68,0,345,3, -69,0,345,3,70, -0,345,3,71,0, -345,3,72,0,345, -3,73,0,345,3, -74,0,345,3,75, -0,345,3,76,0, -345,3,77,0,345, -3,78,0,345,3, -79,0,345,3,80, -0,345,3,81,0, -345,3,82,0,345, -3,83,0,345,3, -84,0,345,3,85, -0,345,3,86,0, -345,3,87,0,345, -3,88,0,345,3, -89,0,345,3,90, -0,345,3,95,0, -1262,12,1,17458,1263, -5,63,3,109,0, -345,3,110,0,345, -3,111,0,345,3, -112,0,345,3,113, -0,345,3,114,0, -345,3,115,0,1264, -12,1,17492,1265,5, -63,3,109,0,345, -3,110,0,345,3, -111,0,345,3,112, -0,345,3,113,0, -345,3,114,0,345, -3,115,0,345,3, -116,0,1266,12,1, -17527,1267,5,63,3, -109,0,345,3,110, -0,345,3,111,0, -345,3,112,0,345, -3,113,0,345,3, -114,0,345,3,115, -0,345,3,116,0, -345,3,117,0,345, -3,118,0,345,3, -119,0,345,3,120, -0,345,3,121,0, -345,3,122,0,345, -3,48,0,345,3, -49,0,345,3,50, -0,345,3,51,0, -345,3,52,0,345, -3,53,0,345,3, -54,0,345,3,55, -0,345,3,56,0, -345,3,57,0,345, -3,65,0,345,3, -66,0,345,3,67, -0,345,3,68,0, -345,3,69,0,345, -3,70,0,345,3, -71,0,345,3,72, -0,345,3,73,0, -345,3,74,0,345, -3,75,0,345,3, -76,0,345,3,77, -0,345,3,78,0, -345,3,79,0,345, -3,80,0,345,3, -81,0,345,3,82, -0,345,3,83,0, -345,3,84,0,345, -3,85,0,345,3, -86,0,345,3,87, -0,345,3,88,0, -345,3,89,0,345, -3,90,0,345,3, -95,0,345,3,97, -0,1268,12,1,17570, -1269,5,63,3,109, -0,345,3,110,0, -345,3,111,0,345, -3,112,0,345,3, -113,0,345,3,114, -0,1270,12,1,17603, -1271,5,63,3,109, -0,345,3,110,0, -345,3,111,0,345, -3,112,0,345,3, -113,0,345,3,114, -0,345,3,115,0, -345,3,116,0,1272, -12,1,17638,1273,5, -63,3,109,0,345, -3,110,0,345,3, -111,0,345,3,112, -0,345,3,113,0, -345,3,114,0,345, -3,115,0,345,3, -116,0,345,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,345,3, -98,0,345,3,99, -0,345,3,100,0, -345,3,101,0,345, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -345,3,106,0,345, -3,107,0,345,3, -108,0,345,1274,11, -1,801,0,1275,4, -34,84,0,79,0, -85,0,67,0,72, -0,95,0,83,0, -84,0,65,0,82, +82,0,71,0,69, 0,84,0,95,0, 69,0,86,0,69, 0,78,0,84,0, -1,-1,3,117,0, -345,3,118,0,345, -3,119,0,345,3, -120,0,345,3,121, -0,345,3,122,0, -345,3,48,0,345, -3,49,0,345,3, -50,0,345,3,51, -0,345,3,52,0, -345,3,53,0,345, -3,54,0,345,3, -55,0,345,3,56, -0,345,3,57,0, -345,3,65,0,345, -3,66,0,345,3, -67,0,345,3,68, -0,345,3,69,0, -345,3,70,0,345, -3,71,0,345,3, -72,0,345,3,73, -0,345,3,74,0, -345,3,75,0,345, -3,76,0,345,3, -77,0,345,3,78, -0,345,3,79,0, -345,3,80,0,345, -3,81,0,345,3, -82,0,345,3,83, -0,345,3,84,0, -345,3,85,0,345, -3,86,0,345,3, -87,0,345,3,88, -0,345,3,89,0, -345,3,90,0,345, -3,95,0,345,3, -97,0,345,3,98, -0,345,3,99,0, -345,3,100,0,345, -3,101,0,345,3, -102,0,345,3,103, -0,345,3,104,0, -345,3,105,0,345, -3,106,0,345,3, -107,0,345,3,108, -0,345,1276,11,1, -867,0,348,1,-1, -3,115,0,345,3, -116,0,345,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,345,3, -98,0,345,3,99, -0,345,3,100,0, -345,3,101,0,345, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -345,3,106,0,345, -3,107,0,345,3, -108,0,345,1277,11, -1,867,0,348,1, --1,3,98,0,345, -3,99,0,345,3, -100,0,345,3,101, -0,345,3,102,0, -345,3,103,0,345, -3,104,0,345,3, -105,0,345,3,106, -0,345,3,107,0, -345,3,108,0,345, -1278,11,1,867,0, -348,1,-1,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,345,3, -98,0,345,3,99, -0,345,3,100,0, -345,3,101,0,345, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -345,3,106,0,345, -3,107,0,345,3, -108,0,345,1279,11, -1,867,0,348,1, --1,3,116,0,345, -3,117,0,345,3, -118,0,345,3,119, -0,345,3,120,0, -345,3,121,0,345, -3,122,0,345,3, -48,0,345,3,49, -0,345,3,50,0, -345,3,51,0,345, -3,52,0,345,3, -53,0,345,3,54, -0,345,3,55,0, -345,3,56,0,345, -3,57,0,345,3, -65,0,345,3,66, -0,345,3,67,0, -345,3,68,0,345, -3,69,0,345,3, -70,0,345,3,71, -0,345,3,72,0, -345,3,73,0,345, -3,74,0,345,3, -75,0,345,3,76, -0,345,3,77,0, -345,3,78,0,345, -3,79,0,345,3, -80,0,345,3,81, -0,345,3,82,0, -345,3,83,0,345, -3,84,0,345,3, -85,0,345,3,86, -0,345,3,87,0, -345,3,88,0,345, -3,89,0,345,3, -90,0,345,3,95, -0,345,3,97,0, -345,3,98,0,345, -3,99,0,345,3, -100,0,345,3,101, -0,1280,12,1,18105, -1281,5,63,3,109, -0,345,3,110,0, -1282,12,1,18134,1283, -5,63,3,109,0, -345,3,110,0,345, -3,111,0,345,3, -112,0,345,3,113, -0,345,3,114,0, -345,3,115,0,345, -3,116,0,345,3, -117,0,345,3,118, -0,345,3,119,0, -345,3,120,0,345, -3,121,0,345,3, -122,0,345,3,48, -0,345,3,49,0, -345,3,50,0,345, -3,51,0,345,3, -52,0,345,3,53, -0,345,3,54,0, -345,3,55,0,345, -3,56,0,345,3, -57,0,345,3,65, -0,345,3,66,0, -345,3,67,0,345, -3,68,0,345,3, -69,0,345,3,70, -0,345,3,71,0, -345,3,72,0,345, -3,73,0,345,3, -74,0,345,3,75, -0,345,3,76,0, -345,3,77,0,345, -3,78,0,345,3, -79,0,345,3,80, -0,345,3,81,0, -345,3,82,0,345, -3,83,0,345,3, -84,0,345,3,85, -0,345,3,86,0, -345,3,87,0,345, -3,88,0,345,3, -89,0,345,3,90, -0,345,3,95,0, -345,3,97,0,345, -3,98,0,345,3, -99,0,345,3,100, -0,1284,12,1,18180, -1285,5,63,3,109, -0,345,3,110,0, -345,3,111,0,345, -3,112,0,345,3, -113,0,345,3,114, -0,345,3,115,0, -345,3,116,0,345, -3,117,0,345,3, -118,0,345,3,119, -0,345,3,120,0, -345,3,121,0,345, -3,122,0,345,3, -48,0,345,3,49, -0,345,3,50,0, -345,3,51,0,345, -3,52,0,345,3, -53,0,345,3,54, -0,345,3,55,0, -345,3,56,0,345, -3,57,0,345,3, -65,0,345,3,66, -0,345,3,67,0, -345,3,68,0,345, -3,69,0,345,3, -70,0,345,3,71, -0,345,3,72,0, -345,3,73,0,345, -3,74,0,345,3, -75,0,345,3,76, -0,345,3,77,0, -345,3,78,0,345, -3,79,0,345,3, -80,0,345,3,81, -0,345,3,82,0, -345,3,83,0,345, -3,84,0,345,3, -85,0,345,3,86, -0,345,3,87,0, -345,3,88,0,345, -3,89,0,345,3, -90,0,345,3,95, -0,345,3,97,0, -345,3,98,0,345, -3,99,0,345,3, -100,0,345,3,101, -0,345,3,102,0, -345,3,103,0,345, -3,104,0,345,3, -105,0,345,3,106, -0,345,3,107,0, -345,3,108,0,345, -1286,11,1,816,0, -1287,4,30,84,0, -79,0,85,0,67, -0,72,0,95,0, -69,0,78,0,68, -0,95,0,69,0, -86,0,69,0,78, -0,84,0,1,-1, -3,101,0,345,3, -102,0,345,3,103, -0,345,3,104,0, -345,3,105,0,345, -3,106,0,345,3, -107,0,345,3,108, -0,345,1288,11,1, -867,0,348,1,-1, -3,111,0,345,3, -112,0,345,3,113, -0,345,3,114,0, -345,3,115,0,345, -3,116,0,345,3, -117,0,345,3,118, -0,345,3,119,0, -345,3,120,0,345, -3,121,0,345,3, -122,0,345,3,48, -0,345,3,49,0, -345,3,50,0,345, -3,51,0,345,3, -52,0,345,3,53, -0,345,3,54,0, -345,3,55,0,345, -3,56,0,345,3, -57,0,345,3,65, -0,345,3,66,0, -345,3,67,0,345, -3,68,0,345,3, -69,0,345,3,70, -0,345,3,71,0, -345,3,72,0,345, -3,73,0,345,3, -74,0,345,3,75, -0,345,3,76,0, -345,3,77,0,345, -3,78,0,345,3, -79,0,345,3,80, -0,345,3,81,0, -345,3,82,0,345, -3,83,0,345,3, -84,0,345,3,85, -0,345,3,86,0, -345,3,87,0,345, -3,88,0,345,3, -89,0,345,3,90, -0,345,3,95,0, -345,3,97,0,345, -3,98,0,345,3, -99,0,345,3,100, -0,345,3,101,0, -345,3,102,0,345, -3,103,0,345,3, -104,0,345,3,105, -0,345,3,106,0, -345,3,107,0,345, -3,108,0,345,1289, -11,1,867,0,348, -1,-1,3,102,0, -345,3,103,0,345, -3,104,0,345,3, -105,0,345,3,106, -0,345,3,107,0, -345,3,108,0,345, -1290,11,1,867,0, -348,1,-1,3,97, -0,345,3,98,0, -345,3,99,0,345, -3,100,0,345,3, -101,0,345,3,102, -0,345,3,103,0, -345,3,104,0,345, -3,105,0,345,3, -106,0,345,3,107, -0,345,3,108,0, -345,1291,11,1,792, -0,1292,4,22,84, -0,79,0,85,0, -67,0,72,0,95, -0,69,0,86,0, -69,0,78,0,84, -0,1,-1,3,105, -0,345,3,106,0, -345,3,107,0,345, -3,108,0,345,1293, -11,1,867,0,348, -1,-1,3,100,0, -345,3,101,0,345, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -345,3,106,0,345, -3,107,0,345,3, -108,0,345,1294,11, -1,867,0,348,1, --1,3,118,0,345, -3,119,0,345,3, -120,0,345,3,121, -0,345,3,122,0, -345,3,48,0,345, -3,49,0,345,3, -50,0,345,3,51, -0,345,3,52,0, -345,3,53,0,345, -3,54,0,345,3, -55,0,345,3,56, -0,345,3,57,0, -345,3,65,0,345, -3,66,0,345,3, -67,0,345,3,68, -0,345,3,69,0, -345,3,70,0,345, -3,71,0,345,3, -72,0,345,3,73, -0,345,3,74,0, -345,3,75,0,345, -3,76,0,345,3, -77,0,345,3,78, -0,345,3,79,0, -345,3,80,0,345, -3,81,0,345,3, -82,0,345,3,83, -0,345,3,84,0, -345,3,85,0,345, -3,86,0,345,3, -87,0,345,3,88, -0,345,3,89,0, -345,3,90,0,345, -3,95,0,345,3, -97,0,345,3,98, -0,345,3,99,0, -345,3,100,0,345, -3,101,0,345,3, -102,0,345,3,103, -0,345,3,104,0, -345,3,105,0,345, -3,106,0,345,3, -107,0,345,3,108, -0,345,1295,11,1, -867,0,348,1,-1, -3,112,0,345,3, -113,0,345,3,114, -0,1296,12,1,18804, -1297,5,63,3,109, -0,345,3,110,0, -345,3,111,0,345, -3,112,0,345,3, -113,0,345,3,114, -0,345,3,115,0, -345,3,116,0,345, -3,117,0,345,3, -118,0,345,3,119, -0,345,3,120,0, -345,3,121,0,345, -3,122,0,345,3, -48,0,345,3,49, -0,345,3,50,0, -345,3,51,0,345, -3,52,0,345,3, -53,0,345,3,54, -0,345,3,55,0, -345,3,56,0,345, -3,57,0,345,3, -65,0,345,3,66, -0,345,3,67,0, -345,3,68,0,345, -3,69,0,345,3, -70,0,345,3,71, -0,345,3,72,0, -345,3,73,0,345, -3,74,0,345,3, -75,0,345,3,76, -0,345,3,77,0, -345,3,78,0,345, -3,79,0,345,3, -80,0,345,3,81, -0,345,3,82,0, -345,3,83,0,345, -3,84,0,345,3, -85,0,345,3,86, -0,345,3,87,0, -345,3,88,0,345, -3,89,0,345,3, -90,0,345,3,95, -0,345,3,97,0, -1298,12,1,18847,1299, -5,63,3,109,0, -345,3,110,0,1300, -12,1,18876,1301,5, -63,3,109,0,345, -3,110,0,345,3, -111,0,345,3,112, -0,345,3,113,0, -345,3,114,0,345, -3,115,0,1302,12, -1,18910,1303,5,63, -3,109,0,345,3, -110,0,345,3,111, -0,345,3,112,0, -345,3,113,0,345, -3,114,0,345,3, -115,0,345,3,116, -0,345,3,117,0, -345,3,118,0,345, -3,119,0,345,3, -120,0,345,3,121, -0,345,3,122,0, -345,3,48,0,345, -3,49,0,345,3, -50,0,345,3,51, -0,345,3,52,0, -345,3,53,0,345, -3,54,0,345,3, -55,0,345,3,56, -0,345,3,57,0, -345,3,65,0,345, -3,66,0,345,3, -67,0,345,3,68, -0,345,3,69,0, -345,3,70,0,345, -3,71,0,345,3, -72,0,345,3,73, -0,345,3,74,0, -345,3,75,0,345, -3,76,0,345,3, -77,0,345,3,78, -0,345,3,79,0, -345,3,80,0,345, -3,81,0,345,3, -82,0,345,3,83, -0,345,3,84,0, -345,3,85,0,345, -3,86,0,345,3, -87,0,345,3,88, -0,345,3,89,0, -345,3,90,0,345, -3,95,0,345,3, -97,0,1304,12,1, -18953,1305,5,63,3, -109,0,345,3,110, -0,345,3,111,0, -345,3,112,0,345, -3,113,0,345,3, -114,0,345,3,115, -0,345,3,116,0, -345,3,117,0,345, -3,118,0,345,3, -119,0,345,3,120, -0,345,3,121,0, -345,3,122,0,345, -3,48,0,345,3, -49,0,345,3,50, -0,345,3,51,0, -345,3,52,0,345, -3,53,0,345,3, -54,0,345,3,55, -0,345,3,56,0, -345,3,57,0,345, -3,65,0,345,3, -66,0,345,3,67, -0,345,3,68,0, -345,3,69,0,345, -3,70,0,345,3, -71,0,345,3,72, -0,345,3,73,0, -345,3,74,0,345, -3,75,0,345,3, -76,0,345,3,77, -0,345,3,78,0, -345,3,79,0,345, -3,80,0,345,3, -81,0,345,3,82, -0,345,3,83,0, -345,3,84,0,345, -3,85,0,345,3, -86,0,345,3,87, -0,345,3,88,0, -345,3,89,0,345, -3,90,0,345,3, -95,0,345,3,97, -0,345,3,98,0, -345,3,99,0,1306, -12,1,18998,1307,5, -63,3,109,0,345, -3,110,0,345,3, -111,0,345,3,112, -0,345,3,113,0, -345,3,114,0,345, -3,115,0,345,3, -116,0,1308,12,1, -19033,1309,5,63,3, -109,0,345,3,110, -0,345,3,111,0, -345,3,112,0,345, -3,113,0,345,3, -114,0,345,3,115, -0,345,3,116,0, -345,3,117,0,345, -3,118,0,345,3, -119,0,345,3,120, -0,345,3,121,0, -345,3,122,0,345, -3,48,0,345,3, -49,0,345,3,50, -0,345,3,51,0, -345,3,52,0,345, -3,53,0,345,3, -54,0,345,3,55, -0,345,3,56,0, -345,3,57,0,345, -3,65,0,345,3, -66,0,345,3,67, -0,345,3,68,0, -345,3,69,0,345, -3,70,0,345,3, -71,0,345,3,72, -0,345,3,73,0, -345,3,74,0,345, -3,75,0,345,3, -76,0,345,3,77, -0,345,3,78,0, -345,3,79,0,345, -3,80,0,345,3, -81,0,345,3,82, -0,345,3,83,0, -345,3,84,0,345, -3,85,0,345,3, -86,0,345,3,87, -0,345,3,88,0, -345,3,89,0,345, -3,90,0,345,3, -95,0,345,3,97, -0,345,3,98,0, -345,3,99,0,345, -3,100,0,345,3, -101,0,345,3,102, -0,345,3,103,0, -345,3,104,0,345, -3,105,0,1310,12, -1,19084,1311,5,63, -3,109,0,345,3, -110,0,345,3,111, -0,1312,12,1,19114, -1313,5,63,3,109, -0,345,3,110,0, -1314,12,1,19143,1315, -5,63,3,109,0, -345,3,110,0,345, -3,111,0,345,3, -112,0,345,3,113, -0,345,3,114,0, -345,3,115,0,345, -3,116,0,345,3, -117,0,345,3,118, -0,345,3,119,0, -345,3,120,0,345, -3,121,0,345,3, -122,0,345,3,48, -0,345,3,49,0, -345,3,50,0,345, -3,51,0,345,3, -52,0,345,3,53, -0,345,3,54,0, -345,3,55,0,345, -3,56,0,345,3, -57,0,345,3,65, -0,345,3,66,0, -345,3,67,0,345, -3,68,0,345,3, -69,0,345,3,70, -0,345,3,71,0, -345,3,72,0,345, -3,73,0,345,3, -74,0,345,3,75, -0,345,3,76,0, -345,3,77,0,345, -3,78,0,345,3, -79,0,345,3,80, -0,345,3,81,0, -345,3,82,0,345, -3,83,0,345,3, -84,0,345,3,85, -0,345,3,86,0, -345,3,87,0,345, -3,88,0,345,3, -89,0,345,3,90, -0,345,3,95,0, -1316,12,1,19229,1317, -5,63,3,109,0, -345,3,110,0,345, -3,111,0,345,3, -112,0,345,3,113, -0,345,3,114,0, -1318,12,1,19262,1319, -5,63,3,109,0, -345,3,110,0,345, -3,111,0,345,3, -112,0,345,3,113, -0,345,3,114,0, -345,3,115,0,345, -3,116,0,345,3, -117,0,345,3,118, -0,345,3,119,0, -345,3,120,0,345, -3,121,0,345,3, -122,0,345,3,48, -0,345,3,49,0, -345,3,50,0,345, -3,51,0,345,3, -52,0,345,3,53, -0,345,3,54,0, -345,3,55,0,345, -3,56,0,345,3, -57,0,345,3,65, -0,345,3,66,0, -345,3,67,0,345, -3,68,0,345,3, -69,0,345,3,70, -0,345,3,71,0, -345,3,72,0,345, -3,73,0,345,3, -74,0,345,3,75, -0,345,3,76,0, -345,3,77,0,345, -3,78,0,345,3, -79,0,345,3,80, -0,345,3,81,0, -345,3,82,0,345, -3,83,0,345,3, -84,0,345,3,85, -0,345,3,86,0, -345,3,87,0,345, -3,88,0,345,3, -89,0,345,3,90, -0,345,3,95,0, -345,3,97,0,345, -3,98,0,345,3, -99,0,345,3,100, -0,345,3,101,0, -1320,12,1,19309,1321, -5,63,3,109,0, -345,3,110,0,345, -3,111,0,345,3, -112,0,345,3,113, -0,345,3,114,0, -345,3,115,0,1322, -12,1,19343,1323,5, -63,3,109,0,345, -3,110,0,345,3, -111,0,345,3,112, -0,345,3,113,0, -345,3,114,0,345, -3,115,0,345,3, -116,0,345,3,117, -0,1324,12,1,19379, -1325,5,63,3,109, -0,345,3,110,0, -345,3,111,0,345, -3,112,0,345,3, -113,0,345,3,114, -0,345,3,115,0, -345,3,116,0,345, -3,117,0,345,3, -118,0,345,3,119, -0,345,3,120,0, -345,3,121,0,345, -3,122,0,345,3, -48,0,345,3,49, -0,345,3,50,0, -345,3,51,0,345, -3,52,0,345,3, -53,0,345,3,54, -0,345,3,55,0, -345,3,56,0,345, -3,57,0,345,3, -65,0,345,3,66, -0,345,3,67,0, -345,3,68,0,345, -3,69,0,345,3, -70,0,345,3,71, -0,345,3,72,0, -345,3,73,0,345, -3,74,0,345,3, -75,0,345,3,76, -0,345,3,77,0, -345,3,78,0,345, -3,79,0,345,3, -80,0,345,3,81, -0,345,3,82,0, -345,3,83,0,345, -3,84,0,345,3, -85,0,345,3,86, -0,345,3,87,0, -345,3,88,0,345, -3,89,0,345,3, -90,0,345,3,95, -0,345,3,97,0, -345,3,98,0,345, -3,99,0,345,3, -100,0,345,3,101, -0,345,3,102,0, -345,3,103,0,345, -3,104,0,345,3, -105,0,345,3,106, -0,345,3,107,0, -345,3,108,0,1326, -12,1,19433,1327,5, -63,3,109,0,345, -3,110,0,345,3, -111,0,345,3,112, -0,345,3,113,0, -345,3,114,0,345, -3,115,0,345,3, -116,0,1328,12,1, -19468,1329,5,63,3, -109,0,345,3,110, -0,345,3,111,0, -345,3,112,0,345, -3,113,0,345,3, -114,0,345,3,115, -0,345,3,116,0, -345,3,117,0,345, -3,118,0,345,3, -119,0,345,3,120, -0,345,3,121,0, -345,3,122,0,345, -3,48,0,345,3, -49,0,345,3,50, -0,345,3,51,0, -345,3,52,0,345, -3,53,0,345,3, -54,0,345,3,55, -0,345,3,56,0, -345,3,57,0,345, -3,65,0,345,3, -66,0,345,3,67, -0,345,3,68,0, -345,3,69,0,345, -3,70,0,345,3, -71,0,345,3,72, -0,345,3,73,0, -345,3,74,0,345, -3,75,0,345,3, -76,0,345,3,77, -0,345,3,78,0, -345,3,79,0,345, -3,80,0,345,3, -81,0,345,3,82, -0,345,3,83,0, -345,3,84,0,345, -3,85,0,345,3, -86,0,345,3,87, -0,345,3,88,0, -345,3,89,0,345, -3,90,0,345,3, -95,0,345,3,97, -0,345,3,98,0, -345,3,99,0,345, -3,100,0,345,3, -101,0,345,3,102, -0,345,3,103,0, -345,3,104,0,345, -3,105,0,345,3, -106,0,345,3,107, -0,345,3,108,0, -345,1330,11,1,845, -0,1331,4,48,84, -0,82,0,65,0, -78,0,83,0,65, -0,67,0,84,0, -73,0,79,0,78, +1,-1,3,89,0, +180,1273,11,1,867, +0,183,1,-1,3, +74,0,180,3,109, +0,180,3,82,0, +180,3,55,0,180, +3,117,0,180,3, +90,0,180,3,98, +0,180,3,71,0, +180,3,106,0,180, +3,79,0,180,3, +52,0,180,3,114, +0,180,3,87,0, +180,3,122,0,180, +3,95,0,180,3, +68,0,180,3,103, +0,180,3,76,0, +180,3,49,0,180, +3,111,0,180,3, +84,0,180,3,57, +0,180,3,119,0, +180,3,65,0,180, +3,100,0,180,3, +73,0,180,3,108, +0,180,3,81,0, +180,3,54,0,180, +3,116,0,180,3, +89,0,180,1274,11, +1,867,0,183,1, +-1,3,76,0,180, +3,49,0,180,3, +111,0,180,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,180,3,73, +0,180,3,108,0, +180,3,81,0,180, +3,54,0,180,3, +116,0,180,3,89, +0,180,1275,11,1, +867,0,183,1,-1, +3,87,0,180,3, +122,0,180,3,95, +0,180,3,68,0, +180,3,103,0,180, +3,76,0,180,3, +49,0,180,3,111, +0,180,3,84,0, +180,3,57,0,180, +3,119,0,180,3, +65,0,180,3,100, +0,180,3,73,0, +180,3,108,0,180, +3,81,0,180,3, +54,0,180,3,116, +0,180,3,89,0, +180,1276,11,1,867, +0,183,1,-1,3, +70,0,180,3,105, +0,180,3,78,0, +180,3,51,0,180, +3,113,0,180,3, +86,0,180,3,121, +0,180,3,67,0, +180,3,102,0,180, +3,75,0,180,3, +48,0,180,3,110, +0,180,3,83,0, +180,3,56,0,180, +3,118,0,180,3, +99,0,180,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,180,3,88, +0,180,3,69,0, +180,3,104,0,180, +3,77,0,180,3, +50,0,180,3,112, +0,180,3,85,0, +180,3,120,0,180, +3,66,0,180,3, +101,0,180,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +180,3,87,0,180, +3,122,0,180,3, +95,0,180,3,68, +0,180,3,103,0, +180,3,76,0,180, +3,49,0,180,3, +111,0,180,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,180,3,73, +0,180,3,108,0, +180,3,81,0,180, +3,54,0,180,3, +116,0,180,3,89, +0,180,1277,11,1, +867,0,183,1,-1, +3,89,0,180,1278, +11,1,867,0,183, +1,-1,3,68,0, +180,3,103,0,180, +3,76,0,180,3, +49,0,180,3,111, +0,180,3,84,0, +180,3,57,0,180, +3,119,0,180,3, +65,0,180,3,100, +0,180,3,73,0, +180,3,108,0,180, +3,81,0,180,3, +54,0,180,3,116, +0,180,3,89,0, +180,1279,11,1,867, +0,183,1,-1,3, +89,0,180,1280,11, +1,867,0,183,1, +-1,3,70,0,180, +3,105,0,180,3, +78,0,180,3,51, +0,180,3,113,0, +180,3,86,0,180, +3,121,0,180,3, +67,0,180,3,102, +0,180,3,75,0, +180,3,48,0,180, +3,110,0,180,3, +83,0,180,3,56, +0,180,3,118,0, +180,3,99,0,180, +3,72,0,180,3, +107,0,180,3,80, +0,180,3,53,0, +180,3,115,0,180, +3,88,0,180,3, +69,0,180,3,104, +0,180,3,77,0, +180,3,50,0,180, +3,112,0,180,3, +85,0,180,3,120, +0,180,3,66,0, +180,3,101,0,180, +3,74,0,180,3, +109,0,180,3,82, +0,180,3,55,0, +180,3,117,0,180, +3,90,0,180,3, +98,0,180,3,71, +0,180,3,106,0, +180,3,79,0,180, +3,52,0,180,3, +114,0,180,3,87, +0,180,3,122,0, +180,3,95,0,180, +3,68,0,180,3, +103,0,180,3,76, +0,180,3,49,0, +180,3,111,0,180, +3,84,0,180,3, +57,0,180,3,119, +0,180,3,65,0, +180,3,100,0,180, +3,73,0,180,3, +108,0,180,3,81, +0,180,3,54,0, +180,3,116,0,180, +3,89,0,180,1281, +11,1,867,0,183, +1,-1,3,68,0, +180,3,103,0,180, +3,76,0,180,3, +49,0,180,3,111, +0,180,3,84,0, +180,3,57,0,180, +3,119,0,180,3, +65,0,180,3,100, +0,180,3,73,0, +180,3,108,0,180, +3,81,0,180,3, +54,0,180,3,116, +0,180,3,89,0, +180,1282,11,1,867, +0,183,1,-1,3, +89,0,180,1283,11, +1,867,0,183,1, +-1,3,84,0,180, +3,57,0,180,3, +119,0,180,3,65, +0,180,3,100,0, +180,3,73,0,180, +3,108,0,180,3, +81,0,180,3,54, +0,180,3,116,0, +180,3,89,0,180, +1284,11,1,867,0, +183,1,-1,3,70, +0,178,3,107,0, +1285,12,1,21812,1286, +5,63,3,97,0, +180,3,70,0,180, +3,105,0,180,3, +78,0,180,3,51, +0,180,3,113,0, +180,3,86,0,180, +3,121,0,180,3, +67,0,180,3,102, +0,180,3,75,0, +180,3,48,0,180, +3,110,0,180,3, +83,0,180,3,56, +0,180,3,118,0, +180,3,99,0,180, +3,72,0,180,3, +107,0,180,3,80, +0,180,3,53,0, +180,3,115,0,180, +3,88,0,180,3, +69,0,180,3,104, +0,180,3,77,0, +180,3,50,0,180, +3,112,0,180,3, +85,0,180,3,120, +0,180,3,66,0, +180,3,101,0,1287, +12,1,21892,1288,5, +63,3,97,0,180, +3,70,0,180,3, +105,0,180,3,78, +0,180,3,51,0, +180,3,113,0,180, +3,86,0,180,3, +121,0,1289,12,1, +21962,1290,5,63,3, +97,0,180,3,70, +0,180,3,105,0, +180,3,78,0,180, +3,51,0,180,3, +113,0,180,3,86, +0,180,3,121,0, +180,3,67,0,180, +3,102,0,180,3, +75,0,180,3,48, +0,180,3,110,0, +180,3,83,0,180, +3,56,0,180,3, +118,0,180,3,99, +0,180,3,72,0, +180,3,107,0,180, +3,80,0,180,3, +53,0,180,3,115, +0,180,3,88,0, +180,3,69,0,180, +3,104,0,180,3, +77,0,180,3,50, +0,180,3,112,0, +180,3,85,0,180, +3,120,0,180,3, +66,0,180,3,101, +0,180,3,74,0, +180,3,109,0,180, +3,82,0,180,3, +55,0,180,3,117, +0,180,3,90,0, +180,3,98,0,180, +3,71,0,180,3, +106,0,180,3,79, +0,180,3,52,0, +180,3,114,0,180, +3,87,0,180,3, +122,0,180,3,95, +0,180,3,68,0, +180,3,103,0,180, +3,76,0,180,3, +49,0,180,3,111, +0,180,3,84,0, +180,3,57,0,180, +3,119,0,180,3, +65,0,180,3,100, +0,180,3,73,0, +180,3,108,0,180, +3,81,0,180,3, +54,0,180,3,116, +0,180,3,89,0, +180,1291,11,1,313, +0,1292,4,16,75, +0,69,0,89,0, +95,0,84,0,89, +0,80,0,69,0, +1,-1,3,67,0, +180,3,102,0,180, +3,75,0,180,3, +48,0,180,3,110, +0,180,3,83,0, +180,3,56,0,180, +3,118,0,180,3, +99,0,180,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,180,3,88, +0,180,3,69,0, +180,3,104,0,180, +3,77,0,180,3, +50,0,180,3,112, +0,180,3,85,0, +180,3,120,0,180, +3,66,0,180,3, +101,0,180,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +180,3,87,0,180, +3,122,0,180,3, +95,0,180,3,68, +0,180,3,103,0, +180,3,76,0,180, +3,49,0,180,3, +111,0,180,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,180,3,73, +0,180,3,108,0, +180,3,81,0,180, +3,54,0,180,3, +116,0,180,3,89, +0,180,1293,11,1, +867,0,183,1,-1, +3,74,0,180,3, +109,0,180,3,82, +0,180,3,55,0, +180,3,117,0,180, +3,90,0,180,3, +98,0,180,3,71, +0,180,3,106,0, +180,3,79,0,180, +3,52,0,180,3, +114,0,180,3,87, +0,180,3,122,0, +180,3,95,0,180, +3,68,0,180,3, +103,0,180,3,76, +0,180,3,49,0, +180,3,111,0,180, +3,84,0,180,3, +57,0,180,3,119, +0,180,3,65,0, +180,3,100,0,180, +3,73,0,180,3, +108,0,180,3,81, +0,180,3,54,0, +180,3,116,0,180, +3,89,0,180,1294, +11,1,867,0,183, +1,-1,3,67,0, +178,3,104,0,1295, +12,1,24934,1296,5, +63,3,97,0,180, +3,70,0,180,3, +105,0,180,3,78, +0,180,3,51,0, +180,3,113,0,180, +3,86,0,180,3, +121,0,180,3,67, +0,180,3,102,0, +180,3,75,0,180, +3,48,0,180,3, +110,0,180,3,83, +0,180,3,56,0, +180,3,118,0,180, +3,99,0,180,3, +72,0,180,3,107, +0,180,3,80,0, +180,3,53,0,180, +3,115,0,180,3, +88,0,180,3,69, +0,180,3,104,0, +180,3,77,0,180, +3,50,0,180,3, +112,0,180,3,85, +0,180,3,120,0, +180,3,66,0,180, +3,101,0,180,3, +74,0,180,3,109, +0,180,3,82,0, +180,3,55,0,180, +3,117,0,180,3, +90,0,180,3,98, +0,180,3,71,0, +180,3,106,0,180, +3,79,0,180,3, +52,0,180,3,114, +0,180,3,87,0, +180,3,122,0,180, +3,95,0,180,3, +68,0,180,3,103, +0,180,3,76,0, +180,3,49,0,180, +3,111,0,180,3, +84,0,180,3,57, +0,180,3,119,0, +180,3,65,0,180, +3,100,0,180,3, +73,0,180,3,108, +0,180,3,81,0, +180,3,54,0,180, +3,116,0,1297,12, +1,25027,1298,5,63, +3,97,0,180,3, +70,0,180,3,105, +0,180,3,78,0, +180,3,51,0,180, +3,113,0,180,3, +86,0,180,3,121, +0,180,3,67,0, +180,3,102,0,180, +3,75,0,180,3, +48,0,180,3,110, +0,180,3,83,0, +180,3,56,0,180, +3,118,0,180,3, +99,0,180,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,180,3,88, +0,180,3,69,0, +180,3,104,0,180, +3,77,0,180,3, +50,0,180,3,112, +0,180,3,85,0, +180,3,120,0,180, +3,66,0,180,3, +101,0,180,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +180,3,87,0,180, +3,122,0,180,3, +95,0,180,3,68, +0,180,3,103,0, +180,3,76,0,180, +3,49,0,180,3, +111,0,180,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,180,3,73, +0,180,3,108,0, +180,3,81,0,180, +3,54,0,180,3, +116,0,1299,12,1, +25120,1300,5,63,3, +97,0,180,3,70, +0,180,3,105,0, +180,3,78,0,180, +3,51,0,180,3, +113,0,180,3,86, +0,180,3,121,0, +180,3,67,0,180, +3,102,0,180,3, +75,0,180,3,48, +0,180,3,110,0, +180,3,83,0,180, +3,56,0,180,3, +118,0,180,3,99, +0,180,3,72,0, +180,3,107,0,180, +3,80,0,180,3, +53,0,180,3,115, +0,180,3,88,0, +180,3,69,0,180, +3,104,0,180,3, +77,0,180,3,50, +0,180,3,112,0, +1301,12,1,25198,1302, +5,63,3,97,0, +180,3,70,0,180, +3,105,0,180,3, +78,0,180,3,51, +0,180,3,113,0, +180,3,86,0,180, +3,121,0,180,3, +67,0,180,3,102, +0,180,3,75,0, +180,3,48,0,180, +3,110,0,180,3, +83,0,180,3,56, +0,180,3,118,0, +180,3,99,0,180, +3,72,0,180,3, +107,0,180,3,80, +0,180,3,53,0, +180,3,115,0,180, +3,88,0,180,3, +69,0,180,3,104, +0,180,3,77,0, +180,3,50,0,180, +3,112,0,180,3, +85,0,180,3,120, +0,180,3,66,0, +180,3,101,0,180, +3,74,0,180,3, +109,0,180,3,82, +0,180,3,55,0, +180,3,117,0,180, +3,90,0,180,3, +98,0,180,3,71, +0,180,3,106,0, +180,3,79,0,180, +3,52,0,180,3, +114,0,180,3,87, +0,180,3,122,0, +180,3,95,0,1303, +12,1,25234,1304,5, +63,3,97,0,180, +3,70,0,180,3, +105,0,180,3,78, +0,180,3,51,0, +180,3,113,0,180, +3,86,0,180,3, +121,0,180,3,67, +0,180,3,102,0, +180,3,75,0,180, +3,48,0,180,3, +110,0,180,3,83, +0,180,3,56,0, +180,3,118,0,180, +3,99,0,180,3, +72,0,180,3,107, +0,180,3,80,0, +180,3,53,0,180, +3,115,0,180,3, +88,0,180,3,69, +0,180,3,104,0, +180,3,77,0,180, +3,50,0,180,3, +112,0,180,3,85, +0,180,3,120,0, +180,3,66,0,180, +3,101,0,180,3, +74,0,180,3,109, +0,180,3,82,0, +180,3,55,0,180, +3,117,0,180,3, +90,0,180,3,98, +0,180,3,71,0, +180,3,106,0,180, +3,79,0,180,3, +52,0,180,3,114, +0,1305,12,1,25319, +1306,5,63,3,97, +0,180,3,70,0, +180,3,105,0,180, +3,78,0,180,3, +51,0,180,3,113, +0,180,3,86,0, +180,3,121,0,180, +3,67,0,180,3, +102,0,180,3,75, +0,180,3,48,0, +180,3,110,0,180, +3,83,0,180,3, +56,0,180,3,118, +0,180,3,99,0, +180,3,72,0,180, +3,107,0,180,3, +80,0,180,3,53, +0,180,3,115,0, +180,3,88,0,180, +3,69,0,180,3, +104,0,180,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,180,3,66, +0,180,3,101,0, +1307,12,1,25399,1308, +5,63,3,97,0, +180,3,70,0,180, +3,105,0,180,3, +78,0,180,3,51, +0,180,3,113,0, +1309,12,1,25468,1310, +5,63,3,97,0, +180,3,70,0,180, +3,105,0,180,3, +78,0,180,3,51, +0,180,3,113,0, +180,3,86,0,180, +3,121,0,180,3, +67,0,180,3,102, +0,180,3,75,0, +180,3,48,0,180, +3,110,0,180,3, +83,0,180,3,56, +0,180,3,118,0, +180,3,99,0,180, +3,72,0,180,3, +107,0,180,3,80, +0,180,3,53,0, +180,3,115,0,180, +3,88,0,180,3, +69,0,180,3,104, +0,180,3,77,0, +180,3,50,0,180, +3,112,0,180,3, +85,0,180,3,120, +0,180,3,66,0, +180,3,101,0,180, +3,74,0,180,3, +109,0,180,3,82, +0,180,3,55,0, +180,3,117,0,1311, +12,1,25550,1312,5, +63,3,97,0,180, +3,70,0,180,3, +105,0,180,3,78, +0,180,3,51,0, +180,3,113,0,180, +3,86,0,180,3, +121,0,180,3,67, +0,180,3,102,0, +180,3,75,0,180, +3,48,0,180,3, +110,0,180,3,83, +0,180,3,56,0, +180,3,118,0,180, +3,99,0,180,3, +72,0,180,3,107, +0,180,3,80,0, +180,3,53,0,180, +3,115,0,180,3, +88,0,180,3,69, +0,180,3,104,0, +180,3,77,0,180, +3,50,0,180,3, +112,0,180,3,85, +0,180,3,120,0, +180,3,66,0,180, +3,101,0,1313,12, +1,25630,1314,5,63, +3,97,0,180,3, +70,0,180,3,105, +0,180,3,78,0, +180,3,51,0,180, +3,113,0,180,3, +86,0,180,3,121, +0,180,3,67,0, +180,3,102,0,180, +3,75,0,180,3, +48,0,180,3,110, +0,180,3,83,0, +180,3,56,0,180, +3,118,0,180,3, +99,0,180,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,1315,12,1, +25706,1316,5,63,3, +97,0,180,3,70, +0,180,3,105,0, +180,3,78,0,180, +3,51,0,180,3, +113,0,180,3,86, +0,180,3,121,0, +180,3,67,0,180, +3,102,0,180,3, +75,0,180,3,48, +0,180,3,110,0, +180,3,83,0,180, +3,56,0,180,3, +118,0,180,3,99, +0,180,3,72,0, +180,3,107,0,180, +3,80,0,180,3, +53,0,180,3,115, +0,180,3,88,0, +180,3,69,0,180, +3,104,0,180,3, +77,0,180,3,50, +0,180,3,112,0, +180,3,85,0,180, +3,120,0,180,3, +66,0,180,3,101, +0,180,3,74,0, +180,3,109,0,180, +3,82,0,180,3, +55,0,180,3,117, +0,180,3,90,0, +180,3,98,0,180, +3,71,0,180,3, +106,0,180,3,79, +0,180,3,52,0, +180,3,114,0,180, +3,87,0,180,3, +122,0,180,3,95, +0,180,3,68,0, +180,3,103,0,180, +3,76,0,180,3, +49,0,180,3,111, +0,180,3,84,0, +180,3,57,0,180, +3,119,0,180,3, +65,0,180,3,100, +0,180,3,73,0, +180,3,108,0,180, +3,81,0,180,3, +54,0,180,3,116, +0,1317,12,1,25799, +1318,5,63,3,97, +0,180,3,70,0, +180,3,105,0,180, +3,78,0,180,3, +51,0,180,3,113, +0,180,3,86,0, +180,3,121,0,180, +3,67,0,180,3, +102,0,180,3,75, +0,180,3,48,0, +180,3,110,0,180, +3,83,0,180,3, +56,0,180,3,118, +0,180,3,99,0, +180,3,72,0,180, +3,107,0,180,3, +80,0,180,3,53, +0,180,3,115,0, +180,3,88,0,180, +3,69,0,180,3, +104,0,180,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,180,3,66, +0,180,3,101,0, +180,3,74,0,180, +3,109,0,180,3, +82,0,180,3,55, +0,180,3,117,0, +180,3,90,0,180, +3,98,0,180,3, +71,0,180,3,106, +0,180,3,79,0, +180,3,52,0,180, +3,114,0,180,3, +87,0,180,3,122, +0,180,3,95,0, +180,3,68,0,180, +3,103,0,180,3, +76,0,180,3,49, +0,180,3,111,0, +180,3,84,0,180, +3,57,0,180,3, +119,0,180,3,65, +0,180,3,100,0, +180,3,73,0,180, +3,108,0,180,3, +81,0,180,3,54, +0,180,3,116,0, +180,3,89,0,180, +1319,11,1,829,0, +1320,4,36,72,0, +84,0,84,0,80, 0,95,0,82,0, -69,0,83,0,85, -0,76,0,84,0, -95,0,69,0,86, -0,69,0,78,0, -84,0,1,-1,3, -117,0,345,3,118, -0,345,3,119,0, -345,3,120,0,345, -3,121,0,345,3, -122,0,345,3,48, -0,345,3,49,0, -345,3,50,0,345, -3,51,0,345,3, -52,0,345,3,53, -0,345,3,54,0, -345,3,55,0,345, -3,56,0,345,3, -57,0,345,3,65, -0,345,3,66,0, -345,3,67,0,345, -3,68,0,345,3, -69,0,345,3,70, -0,345,3,71,0, -345,3,72,0,345, -3,73,0,345,3, -74,0,345,3,75, -0,345,3,76,0, -345,3,77,0,345, -3,78,0,345,3, -79,0,345,3,80, -0,345,3,81,0, -345,3,82,0,345, -3,83,0,345,3, -84,0,345,3,85, -0,345,3,86,0, -345,3,87,0,345, -3,88,0,345,3, -89,0,345,3,90, -0,345,3,95,0, -345,3,97,0,345, -3,98,0,345,3, -99,0,345,3,100, -0,345,3,101,0, -345,3,102,0,345, -3,103,0,345,3, -104,0,345,3,105, -0,345,3,106,0, -345,3,107,0,345, -3,108,0,345,1332, -11,1,867,0,348, -1,-1,1333,11,1, -867,0,348,1,-1, -3,118,0,345,3, -119,0,345,3,120, -0,345,3,121,0, -345,3,122,0,345, -3,48,0,345,3, -49,0,345,3,50, -0,345,3,51,0, -345,3,52,0,345, -3,53,0,345,3, -54,0,345,3,55, -0,345,3,56,0, -345,3,57,0,345, -3,65,0,345,3, -66,0,345,3,67, -0,345,3,68,0, -345,3,69,0,345, -3,70,0,345,3, -71,0,345,3,72, -0,345,3,73,0, -345,3,74,0,345, -3,75,0,345,3, -76,0,345,3,77, -0,345,3,78,0, -345,3,79,0,345, -3,80,0,345,3, -81,0,345,3,82, -0,345,3,83,0, -345,3,84,0,345, -3,85,0,345,3, -86,0,345,3,87, -0,345,3,88,0, -345,3,89,0,345, -3,90,0,345,3, -95,0,345,3,97, -0,345,3,98,0, -345,3,99,0,345, -3,100,0,345,3, -101,0,345,3,102, -0,345,3,103,0, -345,3,104,0,345, -3,105,0,345,3, -106,0,345,3,107, -0,345,3,108,0, -345,1334,11,1,867, -0,348,1,-1,3, -116,0,345,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,345,3, -98,0,345,3,99, -0,345,3,100,0, -345,3,101,0,345, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -345,3,106,0,345, -3,107,0,345,3, -108,0,345,1335,11, -1,867,0,348,1, --1,3,102,0,345, -3,103,0,345,3, -104,0,345,3,105, -0,345,3,106,0, -345,3,107,0,345, -3,108,0,345,1336, -11,1,867,0,348, -1,-1,3,115,0, -345,3,116,0,345, -3,117,0,345,3, -118,0,345,3,119, -0,345,3,120,0, -345,3,121,0,345, -3,122,0,345,3, -48,0,345,3,49, -0,345,3,50,0, -345,3,51,0,345, -3,52,0,345,3, -53,0,345,3,54, -0,345,3,55,0, -345,3,56,0,345, -3,57,0,345,3, -65,0,345,3,66, -0,345,3,67,0, -345,3,68,0,345, -3,69,0,345,3, -70,0,345,3,71, -0,345,3,72,0, -345,3,73,0,345, -3,74,0,345,3, -75,0,345,3,76, -0,345,3,77,0, -345,3,78,0,345, -3,79,0,345,3, -80,0,345,3,81, -0,345,3,82,0, -345,3,83,0,345, -3,84,0,345,3, -85,0,345,3,86, -0,345,3,87,0, -345,3,88,0,345, -3,89,0,345,3, -90,0,345,3,95, -0,345,3,97,0, -345,3,98,0,345, -3,99,0,345,3, -100,0,345,3,101, -0,345,3,102,0, -345,3,103,0,345, -3,104,0,345,3, -105,0,345,3,106, -0,345,3,107,0, -345,3,108,0,345, -1337,11,1,867,0, -348,1,-1,3,97, -0,345,3,98,0, -345,3,99,0,345, -3,100,0,345,3, -101,0,345,3,102, -0,345,3,103,0, -345,3,104,0,345, -3,105,0,345,3, -106,0,345,3,107, -0,345,3,108,0, -345,1338,11,1,867, -0,348,1,-1,3, -111,0,345,3,112, -0,345,3,113,0, -345,3,114,0,345, -3,115,0,345,3, -116,0,345,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,345,3, -98,0,345,3,99, -0,345,3,100,0, -345,3,101,0,345, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -345,3,106,0,345, -3,107,0,345,3, -108,0,345,1339,11, -1,867,0,348,1, --1,3,112,0,345, -3,113,0,345,3, -114,0,345,3,115, -0,345,3,116,0, -345,3,117,0,345, -3,118,0,345,3, -119,0,345,3,120, -0,345,3,121,0, -345,3,122,0,345, -3,48,0,345,3, -49,0,345,3,50, -0,345,3,51,0, -345,3,52,0,345, -3,53,0,345,3, -54,0,345,3,55, -0,345,3,56,0, -345,3,57,0,345, -3,65,0,345,3, -66,0,345,3,67, -0,345,3,68,0, -345,3,69,0,345, -3,70,0,345,3, -71,0,345,3,72, -0,345,3,73,0, -345,3,74,0,345, -3,75,0,345,3, -76,0,345,3,77, -0,345,3,78,0, -345,3,79,0,345, -3,80,0,345,3, -81,0,345,3,82, -0,345,3,83,0, -345,3,84,0,345, -3,85,0,345,3, -86,0,345,3,87, -0,345,3,88,0, -345,3,89,0,345, -3,90,0,345,3, -95,0,345,3,97, -0,345,3,98,0, -345,3,99,0,345, -3,100,0,345,3, -101,0,345,3,102, -0,345,3,103,0, -345,3,104,0,345, -3,105,0,345,3, -106,0,345,3,107, -0,345,3,108,0, -345,1340,11,1,867, -0,348,1,-1,3, -106,0,345,3,107, -0,345,3,108,0, -345,1341,11,1,867, -0,348,1,-1,3, -117,0,345,3,118, -0,345,3,119,0, -345,3,120,0,345, -3,121,0,345,3, -122,0,345,3,48, -0,345,3,49,0, -345,3,50,0,345, -3,51,0,345,3, -52,0,345,3,53, -0,345,3,54,0, -345,3,55,0,345, -3,56,0,345,3, -57,0,345,3,65, -0,345,3,66,0, -345,3,67,0,345, -3,68,0,345,3, -69,0,345,3,70, -0,345,3,71,0, -345,3,72,0,345, -3,73,0,345,3, -74,0,345,3,75, -0,345,3,76,0, -345,3,77,0,345, -3,78,0,345,3, -79,0,345,3,80, -0,345,3,81,0, -345,3,82,0,345, -3,83,0,345,3, -84,0,345,3,85, -0,345,3,86,0, -345,3,87,0,345, -3,88,0,345,3, -89,0,345,3,90, -0,345,3,95,0, -345,3,97,0,345, -3,98,0,345,3, -99,0,345,3,100, -0,345,3,101,0, -345,3,102,0,345, -3,103,0,345,3, -104,0,345,3,105, -0,345,3,106,0, -345,3,107,0,345, -3,108,0,345,1342, -11,1,867,0,348, -1,-1,3,100,0, -345,3,101,0,345, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -345,3,106,0,345, -3,107,0,345,3, -108,0,345,1343,11, -1,867,0,348,1, --1,3,98,0,345, -3,99,0,345,3, -100,0,345,3,101, -0,345,3,102,0, -345,3,103,0,345, -3,104,0,345,3, -105,0,345,3,106, -0,345,3,107,0, -345,3,108,0,345, -1344,11,1,867,0, -348,1,-1,3,116, -0,345,3,117,0, -345,3,118,0,345, -3,119,0,345,3, -120,0,345,3,121, -0,345,3,122,0, -345,3,48,0,345, -3,49,0,345,3, -50,0,345,3,51, -0,345,3,52,0, -345,3,53,0,345, -3,54,0,345,3, -55,0,345,3,56, -0,345,3,57,0, -345,3,65,0,345, -3,66,0,345,3, -67,0,345,3,68, -0,345,3,69,0, -345,3,70,0,345, -3,71,0,345,3, -72,0,345,3,73, -0,345,3,74,0, -345,3,75,0,345, -3,76,0,345,3, -77,0,345,3,78, -0,345,3,79,0, -345,3,80,0,345, -3,81,0,345,3, -82,0,345,3,83, -0,345,3,84,0, -345,3,85,0,345, -3,86,0,345,3, -87,0,345,3,88, -0,345,3,89,0, -345,3,90,0,345, -3,95,0,345,3, -97,0,345,3,98, -0,345,3,99,0, -345,3,100,0,345, -3,101,0,345,3, -102,0,345,3,103, -0,345,3,104,0, -345,3,105,0,345, -3,106,0,345,3, -107,0,345,3,108, -0,345,1345,11,1, -867,0,348,1,-1, -3,111,0,345,3, -112,0,345,3,113, -0,345,3,114,0, -345,3,115,0,345, -3,116,0,345,3, -117,0,345,3,118, -0,345,3,119,0, -345,3,120,0,345, -3,121,0,345,3, -122,0,345,3,48, -0,345,3,49,0, -345,3,50,0,345, -3,51,0,345,3, -52,0,345,3,53, -0,345,3,54,0, -345,3,55,0,345, -3,56,0,345,3, -57,0,345,3,65, -0,345,3,66,0, -345,3,67,0,345, -3,68,0,345,3, -69,0,345,3,70, -0,345,3,71,0, -345,3,72,0,345, -3,73,0,345,3, -74,0,345,3,75, -0,345,3,76,0, -345,3,77,0,345, -3,78,0,345,3, -79,0,345,3,80, -0,345,3,81,0, -345,3,82,0,345, -3,83,0,345,3, -84,0,345,3,85, -0,345,3,86,0, -345,3,87,0,345, -3,88,0,345,3, -89,0,345,3,90, -0,345,3,95,0, -345,3,97,0,345, -3,98,0,345,3, -99,0,345,3,100, -0,345,3,101,0, -345,3,102,0,345, -3,103,0,345,3, -104,0,345,3,105, -0,345,3,106,0, -345,3,107,0,345, -3,108,0,345,1346, -11,1,867,0,348, -1,-1,3,98,0, -345,3,99,0,345, -3,100,0,345,3, -101,0,345,3,102, -0,345,3,103,0, -345,3,104,0,345, -3,105,0,345,3, -106,0,345,3,107, -0,345,3,108,0, -345,1347,11,1,867, -0,348,1,-1,3, -115,0,345,3,116, -0,345,3,117,0, -345,3,118,0,345, -3,119,0,345,3, -120,0,345,3,121, -0,345,3,122,0, -345,3,48,0,345, -3,49,0,345,3, -50,0,345,3,51, -0,345,3,52,0, -345,3,53,0,345, -3,54,0,345,3, -55,0,345,3,56, -0,345,3,57,0, -345,3,65,0,345, -3,66,0,345,3, -67,0,345,3,68, -0,345,3,69,0, -345,3,70,0,345, -3,71,0,345,3, -72,0,345,3,73, -0,345,3,74,0, -345,3,75,0,345, -3,76,0,345,3, -77,0,345,3,78, -0,345,3,79,0, -345,3,80,0,345, -3,81,0,345,3, -82,0,345,3,83, -0,345,3,84,0, -345,3,85,0,345, -3,86,0,345,3, -87,0,345,3,88, -0,345,3,89,0, -345,3,90,0,345, -3,95,0,345,3, -97,0,345,3,98, -0,345,3,99,0, -345,3,100,0,345, -3,101,0,345,3, -102,0,345,3,103, -0,345,3,104,0, -345,3,105,0,1348, -12,1,20862,1349,5, -63,3,109,0,1350, -12,1,20890,1351,5, -63,3,109,0,345, -3,110,0,345,3, -111,0,345,3,112, -0,345,3,113,0, -345,3,114,0,345, -3,115,0,345,3, -116,0,345,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,345,3, -98,0,345,3,99, -0,345,3,100,0, -345,3,101,0,1352, -12,1,20937,1353,5, -63,3,109,0,345, -3,110,0,345,3, -111,0,345,3,112, -0,345,3,113,0, -345,3,114,0,1354, -12,1,20970,1355,5, -63,3,109,0,345, -3,110,0,345,3, -111,0,345,3,112, -0,345,3,113,0, -345,3,114,0,345, -3,115,0,345,3, -116,0,345,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,345,3, -98,0,345,3,99, -0,345,3,100,0, -345,3,101,0,345, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -345,3,106,0,345, -3,107,0,345,3, -108,0,345,1356,11, -1,783,0,1357,4, -22,84,0,73,0, -77,0,69,0,82, -0,95,0,69,0, -86,0,69,0,78, +69,0,81,0,85, +0,69,0,83,0, +84,0,95,0,69, +0,86,0,69,0, +78,0,84,0,1, +-1,3,89,0,180, +1321,11,1,867,0, +183,1,-1,3,88, +0,180,3,69,0, +180,3,104,0,180, +3,77,0,180,3, +50,0,180,3,112, +0,180,3,85,0, +180,3,120,0,180, +3,66,0,180,3, +101,0,180,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +180,3,87,0,180, +3,122,0,180,3, +95,0,180,3,68, +0,180,3,103,0, +180,3,76,0,180, +3,49,0,180,3, +111,0,180,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,180,3,73, +0,180,3,108,0, +180,3,81,0,180, +3,54,0,180,3, +116,0,180,3,89, +0,180,1322,11,1, +867,0,183,1,-1, +3,74,0,180,3, +109,0,180,3,82, +0,180,3,55,0, +180,3,117,0,180, +3,90,0,180,3, +98,0,180,3,71, +0,180,3,106,0, +180,3,79,0,180, +3,52,0,180,3, +114,0,180,3,87, +0,180,3,122,0, +180,3,95,0,180, +3,68,0,180,3, +103,0,180,3,76, +0,180,3,49,0, +180,3,111,0,180, +3,84,0,180,3, +57,0,180,3,119, +0,180,3,65,0, +180,3,100,0,180, +3,73,0,180,3, +108,0,180,3,81, +0,180,3,54,0, +180,3,116,0,180, +3,89,0,180,1323, +11,1,867,0,183, +1,-1,3,90,0, +180,3,98,0,180, +3,71,0,180,3, +106,0,180,3,79, +0,180,3,52,0, +180,3,114,0,180, +3,87,0,180,3, +122,0,180,3,95, +0,180,3,68,0, +180,3,103,0,180, +3,76,0,180,3, +49,0,180,3,111, +0,180,3,84,0, +180,3,57,0,180, +3,119,0,180,3, +65,0,180,3,100, +0,180,3,73,0, +180,3,108,0,180, +3,81,0,180,3, +54,0,180,3,116, +0,180,3,89,0, +180,1324,11,1,867, +0,183,1,-1,3, +86,0,180,3,121, +0,180,3,67,0, +180,3,102,0,180, +3,75,0,180,3, +48,0,180,3,110, +0,180,3,83,0, +180,3,56,0,180, +3,118,0,180,3, +99,0,180,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,1325,12,1, +26075,1326,5,63,3, +97,0,180,3,70, +0,180,3,105,0, +180,3,78,0,180, +3,51,0,180,3, +113,0,180,3,86, +0,180,3,121,0, +180,3,67,0,180, +3,102,0,180,3, +75,0,180,3,48, +0,180,3,110,0, +180,3,83,0,180, +3,56,0,180,3, +118,0,180,3,99, +0,180,3,72,0, +180,3,107,0,180, +3,80,0,180,3, +53,0,180,3,115, +0,180,3,88,0, +180,3,69,0,180, +3,104,0,180,3, +77,0,180,3,50, +0,180,3,112,0, +1327,12,1,26153,1328, +5,63,3,97,0, +180,3,70,0,180, +3,105,0,180,3, +78,0,180,3,51, +0,180,3,113,0, +180,3,86,0,180, +3,121,0,180,3, +67,0,180,3,102, +0,180,3,75,0, +180,3,48,0,180, +3,110,0,180,3, +83,0,180,3,56, +0,180,3,118,0, +180,3,99,0,180, +3,72,0,180,3, +107,0,180,3,80, +0,180,3,53,0, +180,3,115,0,180, +3,88,0,180,3, +69,0,180,3,104, +0,180,3,77,0, +180,3,50,0,180, +3,112,0,180,3, +85,0,180,3,120, +0,180,3,66,0, +180,3,101,0,180, +3,74,0,180,3, +109,0,180,3,82, +0,180,3,55,0, +180,3,117,0,180, +3,90,0,180,3, +98,0,180,3,71, +0,180,3,106,0, +180,3,79,0,180, +3,52,0,180,3, +114,0,180,3,87, +0,180,3,122,0, +180,3,95,0,180, +3,68,0,180,3, +103,0,180,3,76, +0,180,3,49,0, +180,3,111,0,1329, +12,1,26241,1330,5, +63,3,97,0,180, +3,70,0,180,3, +105,0,180,3,78, +0,180,3,51,0, +180,3,113,0,180, +3,86,0,180,3, +121,0,180,3,67, +0,180,3,102,0, +180,3,75,0,180, +3,48,0,180,3, +110,0,1331,12,1, +26313,1332,5,63,3, +97,0,180,3,70, +0,180,3,105,0, +180,3,78,0,180, +3,51,0,180,3, +113,0,180,3,86, +0,180,3,121,0, +180,3,67,0,180, +3,102,0,180,3, +75,0,180,3,48, +0,180,3,110,0, +180,3,83,0,180, +3,56,0,180,3, +118,0,180,3,99, +0,180,3,72,0, +180,3,107,0,180, +3,80,0,180,3, +53,0,180,3,115, +0,1333,12,1,26389, +1334,5,63,3,97, +0,180,3,70,0, +180,3,105,0,180, +3,78,0,180,3, +51,0,180,3,113, +0,180,3,86,0, +180,3,121,0,180, +3,67,0,180,3, +102,0,180,3,75, +0,180,3,48,0, +180,3,110,0,180, +3,83,0,180,3, +56,0,180,3,118, +0,180,3,99,0, +180,3,72,0,180, +3,107,0,180,3, +80,0,180,3,53, +0,180,3,115,0, +180,3,88,0,180, +3,69,0,180,3, +104,0,180,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,180,3,66, +0,180,3,101,0, +1335,12,1,26469,1336, +5,63,3,97,0, +180,3,70,0,180, +3,105,0,180,3, +78,0,180,3,51, +0,180,3,113,0, +180,3,86,0,180, +3,121,0,180,3, +67,0,180,3,102, +0,180,3,75,0, +180,3,48,0,180, +3,110,0,180,3, +83,0,180,3,56, +0,180,3,118,0, +180,3,99,0,180, +3,72,0,180,3, +107,0,180,3,80, +0,180,3,53,0, +180,3,115,0,180, +3,88,0,180,3, +69,0,180,3,104, +0,180,3,77,0, +180,3,50,0,180, +3,112,0,180,3, +85,0,180,3,120, +0,180,3,66,0, +180,3,101,0,180, +3,74,0,180,3, +109,0,180,3,82, +0,180,3,55,0, +180,3,117,0,180, +3,90,0,180,3, +98,0,180,3,71, +0,180,3,106,0, +180,3,79,0,180, +3,52,0,180,3, +114,0,180,3,87, +0,180,3,122,0, +180,3,95,0,180, +3,68,0,180,3, +103,0,180,3,76, +0,180,3,49,0, +180,3,111,0,180, +3,84,0,180,3, +57,0,180,3,119, +0,180,3,65,0, +180,3,100,0,180, +3,73,0,180,3, +108,0,180,3,81, +0,180,3,54,0, +180,3,116,0,180, +3,89,0,180,1337, +11,1,484,0,1338, +4,38,72,0,84, +0,84,0,80,0, +95,0,82,0,69, +0,83,0,80,0, +79,0,78,0,83, +0,69,0,95,0, +69,0,86,0,69, +0,78,0,84,0, +1,-1,3,74,0, +180,3,109,0,180, +3,82,0,180,3, +55,0,180,3,117, +0,180,3,90,0, +180,3,98,0,180, +3,71,0,180,3, +106,0,180,3,79, +0,180,3,52,0, +180,3,114,0,180, +3,87,0,180,3, +122,0,180,3,95, +0,180,3,68,0, +180,3,103,0,180, +3,76,0,180,3, +49,0,180,3,111, +0,180,3,84,0, +180,3,57,0,180, +3,119,0,180,3, +65,0,180,3,100, +0,180,3,73,0, +180,3,108,0,180, +3,81,0,180,3, +54,0,180,3,116, +0,180,3,89,0, +180,1339,11,1,867, +0,183,1,-1,3, +88,0,180,3,69, +0,180,3,104,0, +180,3,77,0,180, +3,50,0,180,3, +112,0,180,3,85, +0,180,3,120,0, +180,3,66,0,180, +3,101,0,180,3, +74,0,180,3,109, +0,180,3,82,0, +180,3,55,0,180, +3,117,0,180,3, +90,0,180,3,98, +0,180,3,71,0, +180,3,106,0,180, +3,79,0,180,3, +52,0,180,3,114, +0,180,3,87,0, +180,3,122,0,180, +3,95,0,180,3, +68,0,180,3,103, +0,180,3,76,0, +180,3,49,0,180, +3,111,0,180,3, +84,0,180,3,57, +0,180,3,119,0, +180,3,65,0,180, +3,100,0,180,3, +73,0,180,3,108, +0,180,3,81,0, +180,3,54,0,180, +3,116,0,180,3, +89,0,180,1340,11, +1,867,0,183,1, +-1,3,83,0,180, +3,56,0,180,3, +118,0,180,3,99, +0,180,3,72,0, +180,3,107,0,180, +3,80,0,180,3, +53,0,180,3,115, +0,180,3,88,0, +180,3,69,0,180, +3,104,0,180,3, +77,0,180,3,50, +0,180,3,112,0, +180,3,85,0,180, +3,120,0,180,3, +66,0,180,3,101, +0,180,3,74,0, +180,3,109,0,180, +3,82,0,180,3, +55,0,180,3,117, +0,180,3,90,0, +180,3,98,0,180, +3,71,0,180,3, +106,0,180,3,79, +0,180,3,52,0, +180,3,114,0,180, +3,87,0,180,3, +122,0,180,3,95, +0,180,3,68,0, +180,3,103,0,180, +3,76,0,180,3, +49,0,180,3,111, +0,180,3,84,0, +180,3,57,0,180, +3,119,0,180,3, +65,0,180,3,100, +0,180,3,73,0, +180,3,108,0,180, +3,81,0,180,3, +54,0,180,3,116, +0,180,3,89,0, +180,1341,11,1,867, +0,183,1,-1,3, +84,0,180,3,57, +0,180,3,119,0, +180,3,65,0,180, +3,100,0,180,3, +73,0,180,3,108, +0,180,3,81,0, +180,3,54,0,180, +3,116,0,180,3, +89,0,180,1342,11, +1,867,0,183,1, +-1,3,85,0,180, +3,120,0,180,3, +66,0,180,3,101, +0,180,3,74,0, +180,3,109,0,180, +3,82,0,180,3, +55,0,180,3,117, +0,180,3,90,0, +180,3,98,0,180, +3,71,0,180,3, +106,0,180,3,79, +0,180,3,52,0, +180,3,114,0,180, +3,87,0,180,3, +122,0,180,3,95, +0,180,3,68,0, +180,3,103,0,180, +3,76,0,180,3, +49,0,180,3,111, +0,180,3,84,0, +180,3,57,0,180, +3,119,0,180,3, +65,0,180,3,100, +0,180,3,73,0, +180,3,108,0,180, +3,81,0,180,3, +54,0,180,3,116, +0,180,3,89,0, +180,1343,11,1,867, +0,183,1,-1,3, +88,0,180,3,69, +0,180,3,104,0, +180,3,77,0,180, +3,50,0,180,3, +112,0,180,3,85, +0,180,3,120,0, +180,3,66,0,180, +3,101,0,180,3, +74,0,180,3,109, +0,180,3,82,0, +180,3,55,0,180, +3,117,0,180,3, +90,0,180,3,98, +0,180,3,71,0, +180,3,106,0,180, +3,79,0,180,3, +52,0,180,3,114, +0,180,3,87,0, +180,3,122,0,180, +3,95,0,180,3, +68,0,180,3,103, +0,180,3,76,0, +180,3,49,0,180, +3,111,0,180,3, +84,0,180,3,57, +0,180,3,119,0, +180,3,65,0,180, +3,100,0,180,3, +73,0,180,3,108, +0,180,3,81,0, +180,3,54,0,180, +3,116,0,180,3, +89,0,180,1344,11, +1,867,0,183,1, +-1,3,74,0,180, +3,109,0,180,3, +82,0,180,3,55, +0,180,3,117,0, +180,3,90,0,180, +3,98,0,180,3, +71,0,180,3,106, +0,180,3,79,0, +180,3,52,0,180, +3,114,0,180,3, +87,0,180,3,122, +0,180,3,95,0, +180,3,68,0,180, +3,103,0,180,3, +76,0,180,3,49, +0,180,3,111,0, +180,3,84,0,180, +3,57,0,180,3, +119,0,180,3,65, +0,180,3,100,0, +180,3,73,0,180, +3,108,0,180,3, +81,0,180,3,54, +0,180,3,116,0, +180,3,89,0,180, +1345,11,1,867,0, +183,1,-1,3,87, +0,180,3,122,0, +180,3,95,0,180, +3,68,0,180,3, +103,0,180,3,76, +0,180,3,49,0, +180,3,111,0,180, +3,84,0,180,3, +57,0,180,3,119, +0,180,3,65,0, +180,3,100,0,180, +3,73,0,180,3, +108,0,180,3,81, +0,180,3,54,0, +180,3,116,0,180, +3,89,0,180,1346, +11,1,867,0,183, +1,-1,3,68,0, +180,3,103,0,180, +3,76,0,180,3, +49,0,180,3,111, +0,180,3,84,0, +180,3,57,0,180, +3,119,0,180,3, +65,0,180,3,100, +0,180,3,73,0, +180,3,108,0,180, +3,81,0,180,3, +54,0,180,3,116, +0,180,3,89,0, +180,1347,11,1,867, +0,183,1,-1,3, +85,0,180,3,120, +0,180,3,66,0, +180,3,101,0,180, +3,74,0,180,3, +109,0,180,3,82, +0,180,3,55,0, +180,3,117,0,180, +3,90,0,180,3, +98,0,180,3,71, +0,180,3,106,0, +180,3,79,0,180, +3,52,0,180,3, +114,0,180,3,87, +0,180,3,122,0, +180,3,95,0,180, +3,68,0,180,3, +103,0,180,3,76, +0,180,3,49,0, +180,3,111,0,180, +3,84,0,180,3, +57,0,180,3,119, +0,180,3,65,0, +180,3,100,0,180, +3,73,0,180,3, +108,0,180,3,81, +0,180,3,54,0, +180,3,116,0,180, +3,89,0,180,1348, +11,1,867,0,183, +1,-1,3,89,0, +180,1349,11,1,867, +0,183,1,-1,3, +89,0,180,1350,11, +1,867,0,183,1, +-1,3,64,0,1351, +12,1,6636,1352,5, +0,1353,11,1,106, +0,1354,4,4,65, 0,84,0,1,-1, -3,115,0,345,3, -116,0,345,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,345,3, -98,0,345,3,99, -0,345,3,100,0, -345,3,101,0,345, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -345,3,106,0,345, -3,107,0,345,3, -108,0,345,1358,11, -1,867,0,348,1, --1,3,102,0,345, -3,103,0,345,3, -104,0,345,3,105, -0,345,3,106,0, -345,3,107,0,345, -3,108,0,345,1359, -11,1,867,0,348, -1,-1,3,110,0, -345,3,111,0,345, -3,112,0,345,3, -113,0,345,3,114, -0,345,3,115,0, -345,3,116,0,345, -3,117,0,345,3, -118,0,345,3,119, -0,345,3,120,0, -345,3,121,0,345, -3,122,0,345,3, -48,0,345,3,49, -0,345,3,50,0, -345,3,51,0,345, -3,52,0,345,3, -53,0,345,3,54, -0,345,3,55,0, -345,3,56,0,345, -3,57,0,345,3, -65,0,345,3,66, -0,345,3,67,0, -345,3,68,0,345, -3,69,0,345,3, -70,0,345,3,71, -0,345,3,72,0, -345,3,73,0,345, -3,74,0,345,3, -75,0,345,3,76, -0,345,3,77,0, -345,3,78,0,345, -3,79,0,345,3, -80,0,345,3,81, -0,345,3,82,0, -345,3,83,0,345, -3,84,0,345,3, -85,0,345,3,86, -0,345,3,87,0, -345,3,88,0,345, -3,89,0,345,3, -90,0,345,3,95, -0,345,3,97,0, -345,3,98,0,345, -3,99,0,345,3, -100,0,345,3,101, -0,345,3,102,0, -345,3,103,0,345, -3,104,0,345,3, -105,0,345,3,106, -0,345,3,107,0, -345,3,108,0,345, -1360,11,1,867,0, -348,1,-1,3,106, -0,345,3,107,0, -345,3,108,0,345, -1361,11,1,867,0, -348,1,-1,3,117, -0,343,3,118,0, -1362,12,1,21413,1363, -5,63,3,109,0, -345,3,110,0,345, -3,111,0,345,3, -112,0,345,3,113, -0,345,3,114,0, -345,3,115,0,345, -3,116,0,345,3, -117,0,345,3,118, -0,345,3,119,0, -345,3,120,0,345, -3,121,0,345,3, -122,0,345,3,48, -0,345,3,49,0, -345,3,50,0,345, -3,51,0,345,3, -52,0,345,3,53, -0,345,3,54,0, -345,3,55,0,345, -3,56,0,345,3, -57,0,345,3,65, -0,345,3,66,0, -345,3,67,0,345, -3,68,0,345,3, -69,0,345,3,70, -0,345,3,71,0, -345,3,72,0,345, -3,73,0,345,3, -74,0,345,3,75, -0,345,3,76,0, -345,3,77,0,345, -3,78,0,345,3, -79,0,345,3,80, -0,345,3,81,0, -345,3,82,0,345, -3,83,0,345,3, -84,0,345,3,85, -0,345,3,86,0, -345,3,87,0,345, -3,88,0,345,3, -89,0,345,3,90, -0,345,3,95,0, -345,3,97,0,345, -3,98,0,345,3, -99,0,345,3,100, -0,345,3,101,0, -1364,12,1,21460,1365, -5,63,3,109,0, -345,3,110,0,345, -3,111,0,345,3, -112,0,345,3,113, -0,345,3,114,0, -345,3,115,0,345, -3,116,0,345,3, -117,0,345,3,118, -0,345,3,119,0, -345,3,120,0,345, -3,121,0,345,3, -122,0,345,3,48, -0,345,3,49,0, -345,3,50,0,345, -3,51,0,345,3, -52,0,345,3,53, -0,345,3,54,0, -345,3,55,0,345, -3,56,0,345,3, -57,0,345,3,65, -0,345,3,66,0, -345,3,67,0,345, -3,68,0,345,3, -69,0,345,3,70, -0,345,3,71,0, -345,3,72,0,345, -3,73,0,345,3, -74,0,345,3,75, -0,345,3,76,0, -345,3,77,0,345, -3,78,0,345,3, -79,0,345,3,80, -0,345,3,81,0, -345,3,82,0,345, -3,83,0,345,3, -84,0,345,3,85, -0,345,3,86,0, -345,3,87,0,345, -3,88,0,345,3, -89,0,345,3,90, -0,345,3,95,0, -345,3,97,0,345, -3,98,0,345,3, -99,0,1366,12,1, -21505,1367,5,63,3, -109,0,345,3,110, -0,345,3,111,0, -345,3,112,0,345, -3,113,0,345,3, -114,0,345,3,115, -0,345,3,116,0, -1368,12,1,21540,1369, -5,63,3,109,0, -345,3,110,0,345, -3,111,0,1370,12, -1,21570,1371,5,63, -3,109,0,345,3, -110,0,345,3,111, -0,345,3,112,0, -345,3,113,0,345, -3,114,0,1372,12, -1,21603,1373,5,63, -3,109,0,345,3, -110,0,345,3,111, -0,345,3,112,0, -345,3,113,0,345, -3,114,0,345,3, -115,0,345,3,116, -0,345,3,117,0, -345,3,118,0,345, -3,119,0,345,3, -120,0,345,3,121, -0,345,3,122,0, -345,3,48,0,345, -3,49,0,345,3, -50,0,345,3,51, -0,345,3,52,0, -345,3,53,0,345, -3,54,0,345,3, -55,0,345,3,56, -0,345,3,57,0, -345,3,65,0,345, -3,66,0,345,3, -67,0,345,3,68, -0,345,3,69,0, -345,3,70,0,345, -3,71,0,345,3, -72,0,345,3,73, -0,345,3,74,0, -345,3,75,0,345, -3,76,0,345,3, -77,0,345,3,78, -0,345,3,79,0, -345,3,80,0,345, -3,81,0,345,3, -82,0,345,3,83, -0,345,3,84,0, -345,3,85,0,345, -3,86,0,345,3, -87,0,345,3,88, -0,345,3,89,0, -345,3,90,0,345, -3,95,0,345,3, -97,0,345,3,98, -0,345,3,99,0, -345,3,100,0,345, -3,101,0,345,3, -102,0,345,3,103, -0,345,3,104,0, -345,3,105,0,345, -3,106,0,345,3, -107,0,345,3,108, -0,345,1374,11,1, -320,0,1375,4,22, -86,0,69,0,67, -0,84,0,79,0, -82,0,95,0,84, -0,89,0,80,0, -69,0,1,-1,3, -115,0,345,3,116, -0,345,3,117,0, -345,3,118,0,345, -3,119,0,345,3, -120,0,345,3,121, -0,345,3,122,0, -345,3,48,0,345, -3,49,0,345,3, -50,0,345,3,51, -0,345,3,52,0, -345,3,53,0,345, -3,54,0,345,3, -55,0,345,3,56, -0,345,3,57,0, -345,3,65,0,345, -3,66,0,345,3, -67,0,345,3,68, -0,345,3,69,0, -345,3,70,0,345, -3,71,0,345,3, -72,0,345,3,73, -0,345,3,74,0, -345,3,75,0,345, -3,76,0,345,3, -77,0,345,3,78, -0,345,3,79,0, -345,3,80,0,345, -3,81,0,345,3, -82,0,345,3,83, -0,345,3,84,0, -345,3,85,0,345, -3,86,0,345,3, -87,0,345,3,88, -0,345,3,89,0, -345,3,90,0,345, -3,95,0,345,3, -97,0,345,3,98, -0,345,3,99,0, -345,3,100,0,345, -3,101,0,345,3, -102,0,345,3,103, -0,345,3,104,0, -345,3,105,0,345, -3,106,0,345,3, -107,0,345,3,108, -0,345,1376,11,1, -867,0,348,1,-1, -3,112,0,345,3, -113,0,345,3,114, -0,345,3,115,0, -345,3,116,0,345, -3,117,0,345,3, -118,0,345,3,119, -0,345,3,120,0, -345,3,121,0,345, -3,122,0,345,3, -48,0,345,3,49, -0,345,3,50,0, -345,3,51,0,345, -3,52,0,345,3, -53,0,345,3,54, -0,345,3,55,0, -345,3,56,0,345, -3,57,0,345,3, -65,0,345,3,66, -0,345,3,67,0, -345,3,68,0,345, -3,69,0,345,3, -70,0,345,3,71, -0,345,3,72,0, -345,3,73,0,345, -3,74,0,345,3, -75,0,345,3,76, -0,345,3,77,0, -345,3,78,0,345, -3,79,0,345,3, -80,0,345,3,81, -0,345,3,82,0, -345,3,83,0,345, -3,84,0,345,3, -85,0,345,3,86, -0,345,3,87,0, -345,3,88,0,345, -3,89,0,345,3, -90,0,345,3,95, -0,345,3,97,0, -345,3,98,0,345, -3,99,0,345,3, -100,0,345,3,101, -0,345,3,102,0, -345,3,103,0,345, -3,104,0,345,3, -105,0,345,3,106, -0,345,3,107,0, -345,3,108,0,345, -1377,11,1,867,0, -348,1,-1,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,345,3, -98,0,345,3,99, -0,345,3,100,0, -345,3,101,0,345, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -345,3,106,0,345, -3,107,0,345,3, -108,0,345,1378,11, -1,867,0,348,1, --1,3,100,0,345, -3,101,0,345,3, -102,0,345,3,103, -0,345,3,104,0, -345,3,105,0,345, -3,106,0,345,3, -107,0,345,3,108, -0,345,1379,11,1, -867,0,348,1,-1, -3,102,0,345,3, -103,0,345,3,104, -0,345,3,105,0, -345,3,106,0,345, -3,107,0,345,3, -108,0,345,1380,11, -1,867,0,348,1, --1,3,119,0,1381, -12,1,22134,1382,5, -63,3,109,0,345, -3,110,0,345,3, -111,0,345,3,112, -0,345,3,113,0, -345,3,114,0,345, -3,115,0,345,3, -116,0,345,3,117, -0,345,3,118,0, -345,3,119,0,345, -3,120,0,345,3, -121,0,345,3,122, -0,345,3,48,0, -345,3,49,0,345, -3,50,0,345,3, -51,0,345,3,52, -0,345,3,53,0, -345,3,54,0,345, -3,55,0,345,3, -56,0,345,3,57, -0,345,3,65,0, -345,3,66,0,345, -3,67,0,345,3, -68,0,345,3,69, -0,345,3,70,0, -345,3,71,0,345, -3,72,0,345,3, -73,0,345,3,74, -0,345,3,75,0, -345,3,76,0,345, -3,77,0,345,3, -78,0,345,3,79, -0,345,3,80,0, -345,3,81,0,345, -3,82,0,345,3, -83,0,345,3,84, -0,345,3,85,0, -345,3,86,0,345, -3,87,0,345,3, -88,0,345,3,89, -0,345,3,90,0, -345,3,95,0,345, -3,97,0,345,3, -98,0,345,3,99, -0,345,3,100,0, -345,3,101,0,345, -3,102,0,345,3, -103,0,345,3,104, -0,1383,12,1,22184, -1384,5,63,3,109, -0,345,3,110,0, -345,3,111,0,345, -3,112,0,345,3, -113,0,345,3,114, -0,345,3,115,0, -345,3,116,0,345, -3,117,0,345,3, -118,0,345,3,119, -0,345,3,120,0, -345,3,121,0,345, -3,122,0,345,3, -48,0,345,3,49, -0,345,3,50,0, -345,3,51,0,345, -3,52,0,345,3, -53,0,345,3,54, -0,345,3,55,0, -345,3,56,0,345, -3,57,0,345,3, -65,0,345,3,66, -0,345,3,67,0, -345,3,68,0,345, -3,69,0,345,3, -70,0,345,3,71, -0,345,3,72,0, -345,3,73,0,345, -3,74,0,345,3, -75,0,345,3,76, -0,345,3,77,0, -345,3,78,0,345, -3,79,0,345,3, -80,0,345,3,81, -0,345,3,82,0, -345,3,83,0,345, -3,84,0,345,3, -85,0,345,3,86, -0,345,3,87,0, -345,3,88,0,345, -3,89,0,345,3, -90,0,345,3,95, -0,345,3,97,0, -345,3,98,0,345, -3,99,0,345,3, -100,0,345,3,101, -0,345,3,102,0, -345,3,103,0,345, -3,104,0,345,3, -105,0,1385,12,1, -22235,1386,5,63,3, -109,0,345,3,110, -0,345,3,111,0, -345,3,112,0,345, -3,113,0,345,3, -114,0,345,3,115, -0,345,3,116,0, -345,3,117,0,345, -3,118,0,345,3, -119,0,345,3,120, -0,345,3,121,0, -345,3,122,0,345, -3,48,0,345,3, -49,0,345,3,50, -0,345,3,51,0, -345,3,52,0,345, -3,53,0,345,3, -54,0,345,3,55, -0,345,3,56,0, -345,3,57,0,345, -3,65,0,345,3, -66,0,345,3,67, -0,345,3,68,0, -345,3,69,0,345, -3,70,0,345,3, -71,0,345,3,72, -0,345,3,73,0, -345,3,74,0,345, -3,75,0,345,3, -76,0,345,3,77, -0,345,3,78,0, -345,3,79,0,345, -3,80,0,345,3, -81,0,345,3,82, -0,345,3,83,0, -345,3,84,0,345, -3,85,0,345,3, -86,0,345,3,87, -0,345,3,88,0, -345,3,89,0,345, -3,90,0,345,3, -95,0,345,3,97, -0,345,3,98,0, -345,3,99,0,345, -3,100,0,345,3, -101,0,345,3,102, -0,345,3,103,0, -345,3,104,0,345, -3,105,0,345,3, -106,0,345,3,107, -0,345,3,108,0, -1387,12,1,22289,1388, -5,63,3,109,0, -345,3,110,0,345, -3,111,0,345,3, -112,0,345,3,113, -0,345,3,114,0, -345,3,115,0,345, -3,116,0,345,3, -117,0,345,3,118, -0,345,3,119,0, -345,3,120,0,345, -3,121,0,345,3, -122,0,345,3,48, -0,345,3,49,0, -345,3,50,0,345, -3,51,0,345,3, -52,0,345,3,53, -0,345,3,54,0, -345,3,55,0,345, -3,56,0,345,3, -57,0,345,3,65, -0,345,3,66,0, -345,3,67,0,345, -3,68,0,345,3, -69,0,345,3,70, -0,345,3,71,0, -345,3,72,0,345, -3,73,0,345,3, -74,0,345,3,75, -0,345,3,76,0, -345,3,77,0,345, -3,78,0,345,3, -79,0,345,3,80, -0,345,3,81,0, -345,3,82,0,345, -3,83,0,345,3, -84,0,345,3,85, -0,345,3,86,0, -345,3,87,0,345, -3,88,0,345,3, -89,0,345,3,90, -0,345,3,95,0, -345,3,97,0,345, -3,98,0,345,3, -99,0,345,3,100, -0,345,3,101,0, -1389,12,1,22336,1390, -5,63,3,109,0, -345,3,110,0,345, -3,111,0,345,3, -112,0,345,3,113, -0,345,3,114,0, -345,3,115,0,345, -3,116,0,345,3, -117,0,345,3,118, -0,345,3,119,0, -345,3,120,0,345, -3,121,0,345,3, -122,0,345,3,48, -0,345,3,49,0, -345,3,50,0,345, -3,51,0,345,3, -52,0,345,3,53, -0,345,3,54,0, -345,3,55,0,345, -3,56,0,345,3, -57,0,345,3,65, -0,345,3,66,0, -345,3,67,0,345, -3,68,0,345,3, -69,0,345,3,70, -0,345,3,71,0, -345,3,72,0,345, -3,73,0,345,3, -74,0,345,3,75, -0,345,3,76,0, -345,3,77,0,345, -3,78,0,345,3, -79,0,345,3,80, -0,345,3,81,0, -345,3,82,0,345, -3,83,0,345,3, -84,0,345,3,85, -0,345,3,86,0, -345,3,87,0,345, -3,88,0,345,3, -89,0,345,3,90, -0,345,3,95,0, -345,3,97,0,345, -3,98,0,345,3, -99,0,345,3,100, -0,345,3,101,0, -345,3,102,0,345, -3,103,0,345,3, -104,0,345,3,105, -0,345,3,106,0, -345,3,107,0,345, -3,108,0,345,1391, -11,1,229,0,1392, -4,10,87,0,72, -0,73,0,76,0, -69,0,1,-1,3, -102,0,345,3,103, -0,345,3,104,0, -345,3,105,0,345, -3,106,0,345,3, -107,0,345,3,108, -0,345,1393,11,1, -867,0,348,1,-1, -1394,11,1,867,0, -348,1,-1,3,106, -0,345,3,107,0, -345,3,108,0,345, -1395,11,1,867,0, -348,1,-1,3,105, -0,345,3,106,0, -345,3,107,0,345, -3,108,0,345,1396, -11,1,867,0,348, -1,-1,3,120,0, -343,3,121,0,343, -3,122,0,343,3, +3,101,0,1355,12, +1,27097,1356,5,63, +3,97,0,180,3, +70,0,180,3,105, +0,180,3,78,0, +180,3,51,0,180, +3,113,0,180,3, +86,0,180,3,121, +0,180,3,67,0, +180,3,102,0,180, +3,75,0,180,3, +48,0,180,3,110, +0,180,3,83,0, +180,3,56,0,180, +3,118,0,180,3, +99,0,180,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,180,3,88, +0,180,3,69,0, +180,3,104,0,180, +3,77,0,180,3, +50,0,180,3,112, +0,180,3,85,0, +180,3,120,0,180, +3,66,0,180,3, +101,0,180,3,74, +0,180,3,109,0, +1357,12,1,27178,1358, +5,63,3,97,0, +1359,12,1,27245,1360, +5,63,3,97,0, +180,3,70,0,180, +3,105,0,1361,12, +1,27313,1362,5,63, +3,97,0,180,3, +70,0,180,3,105, +0,180,3,78,0, +180,3,51,0,180, +3,113,0,180,3, +86,0,180,3,121, +0,180,3,67,0, +180,3,102,0,180, +3,75,0,180,3, +48,0,180,3,110, +0,180,3,83,0, +180,3,56,0,180, +3,118,0,180,3, +99,0,180,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,180,3,88, +0,180,3,69,0, +180,3,104,0,180, +3,77,0,180,3, +50,0,180,3,112, +0,180,3,85,0, +180,3,120,0,180, +3,66,0,180,3, +101,0,180,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +180,3,87,0,180, +3,122,0,180,3, +95,0,180,3,68, +0,180,3,103,0, +180,3,76,0,180, +3,49,0,180,3, +111,0,180,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,180,3,73, +0,180,3,108,0, +1363,12,1,27404,1364, +5,63,3,97,0, +180,3,70,0,180, +3,105,0,180,3, +78,0,180,3,51, +0,180,3,113,0, +180,3,86,0,180, +3,121,0,180,3, +67,0,180,3,102, +0,180,3,75,0, +180,3,48,0,180, +3,110,0,180,3, +83,0,180,3,56, +0,180,3,118,0, +180,3,99,0,180, +3,72,0,180,3, +107,0,180,3,80, +0,180,3,53,0, +180,3,115,0,180, +3,88,0,180,3, +69,0,180,3,104, +0,180,3,77,0, +180,3,50,0,180, +3,112,0,180,3, +85,0,180,3,120, +0,180,3,66,0, +180,3,101,0,180, +3,74,0,180,3, +109,0,180,3,82, +0,180,3,55,0, +180,3,117,0,180, +3,90,0,180,3, +98,0,180,3,71, +0,180,3,106,0, +180,3,79,0,180, +3,52,0,180,3, +114,0,180,3,87, +0,180,3,122,0, +180,3,95,0,180, +3,68,0,180,3, +103,0,180,3,76, +0,180,3,49,0, +180,3,111,0,180, +3,84,0,180,3, +57,0,180,3,119, +0,180,3,65,0, +180,3,100,0,180, +3,73,0,180,3, +108,0,180,3,81, +0,180,3,54,0, +180,3,116,0,180, +3,89,0,180,1365, +11,1,475,0,1366, +4,22,69,0,77, +0,65,0,73,0, +76,0,95,0,69, +0,86,0,69,0, +78,0,84,0,1, +-1,3,81,0,180, +3,54,0,180,3, +116,0,180,3,89, +0,180,1367,11,1, +867,0,183,1,-1, +3,78,0,180,3, +51,0,180,3,113, +0,180,3,86,0, +180,3,121,0,180, +3,67,0,180,3, +102,0,180,3,75, +0,180,3,48,0, +180,3,110,0,180, +3,83,0,180,3, +56,0,180,3,118, +0,180,3,99,0, +180,3,72,0,180, +3,107,0,180,3, +80,0,180,3,53, +0,180,3,115,0, +180,3,88,0,180, +3,69,0,180,3, +104,0,180,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,180,3,66, +0,180,3,101,0, +180,3,74,0,180, +3,109,0,180,3, +82,0,180,3,55, +0,180,3,117,0, +180,3,90,0,180, +3,98,0,180,3, +71,0,180,3,106, +0,180,3,79,0, +180,3,52,0,180, +3,114,0,180,3, +87,0,180,3,122, +0,180,3,95,0, +180,3,68,0,180, +3,103,0,180,3, +76,0,180,3,49, +0,180,3,111,0, +180,3,84,0,180, +3,57,0,180,3, +119,0,180,3,65, +0,180,3,100,0, +180,3,73,0,180, +3,108,0,180,3, +81,0,180,3,54, +0,180,3,116,0, +180,3,89,0,180, +1368,11,1,867,0, +183,1,-1,3,70, +0,180,3,105,0, +180,3,78,0,180, +3,51,0,180,3, +113,0,180,3,86, +0,180,3,121,0, +180,3,67,0,180, +3,102,0,180,3, +75,0,180,3,48, +0,180,3,110,0, +180,3,83,0,180, +3,56,0,180,3, +118,0,180,3,99, +0,180,3,72,0, +180,3,107,0,180, +3,80,0,180,3, +53,0,180,3,115, +0,180,3,88,0, +180,3,69,0,180, +3,104,0,180,3, +77,0,180,3,50, +0,180,3,112,0, +180,3,85,0,180, +3,120,0,180,3, +66,0,180,3,101, +0,180,3,74,0, +180,3,109,0,180, +3,82,0,180,3, +55,0,180,3,117, +0,180,3,90,0, +180,3,98,0,180, +3,71,0,180,3, +106,0,180,3,79, +0,180,3,52,0, +180,3,114,0,180, +3,87,0,180,3, +122,0,180,3,95, +0,180,3,68,0, +180,3,103,0,180, +3,76,0,180,3, +49,0,180,3,111, +0,180,3,84,0, +180,3,57,0,180, +3,119,0,180,3, +65,0,180,3,100, +0,180,3,73,0, +180,3,108,0,180, +3,81,0,180,3, +54,0,180,3,116, +0,180,3,89,0, +180,1369,11,1,867, +0,183,1,-1,3, +82,0,180,3,55, +0,180,3,117,0, +180,3,90,0,180, +3,98,0,180,3, +71,0,180,3,106, +0,180,3,79,0, +180,3,52,0,180, +3,114,0,180,3, +87,0,180,3,122, +0,180,3,95,0, +180,3,68,0,180, +3,103,0,180,3, +76,0,180,3,49, +0,180,3,111,0, +180,3,84,0,180, +3,57,0,180,3, +119,0,180,3,65, +0,180,3,100,0, +180,3,73,0,180, +3,108,0,1370,12, +1,27668,1371,5,63, +3,97,0,180,3, +70,0,180,3,105, +0,180,3,78,0, +180,3,51,0,180, +3,113,0,180,3, +86,0,180,3,121, +0,180,3,67,0, +180,3,102,0,180, +3,75,0,180,3, +48,0,180,3,110, +0,180,3,83,0, +180,3,56,0,180, +3,118,0,180,3, +99,0,180,3,72, +0,180,3,107,0, +180,3,80,0,180, +3,53,0,180,3, +115,0,1372,12,1, +27744,1373,5,63,3, +97,0,180,3,70, +0,180,3,105,0, +180,3,78,0,180, +3,51,0,180,3, +113,0,180,3,86, +0,180,3,121,0, +180,3,67,0,180, +3,102,0,180,3, +75,0,180,3,48, +0,180,3,110,0, +180,3,83,0,180, +3,56,0,180,3, +118,0,180,3,99, +0,180,3,72,0, +180,3,107,0,180, +3,80,0,180,3, +53,0,180,3,115, +0,180,3,88,0, +180,3,69,0,180, +3,104,0,180,3, +77,0,180,3,50, +0,180,3,112,0, +180,3,85,0,180, +3,120,0,180,3, +66,0,180,3,101, +0,1374,12,1,27824, +1375,5,63,3,97, +0,180,3,70,0, +180,3,105,0,180, +3,78,0,180,3, +51,0,180,3,113, +0,180,3,86,0, +180,3,121,0,180, +3,67,0,180,3, +102,0,180,3,75, +0,180,3,48,0, +180,3,110,0,180, +3,83,0,180,3, +56,0,180,3,118, +0,180,3,99,0, +180,3,72,0,180, +3,107,0,180,3, +80,0,180,3,53, +0,180,3,115,0, +180,3,88,0,180, +3,69,0,180,3, +104,0,180,3,77, +0,180,3,50,0, +180,3,112,0,180, +3,85,0,180,3, +120,0,180,3,66, +0,180,3,101,0, +180,3,74,0,180, +3,109,0,180,3, +82,0,180,3,55, +0,180,3,117,0, +180,3,90,0,180, +3,98,0,180,3, +71,0,180,3,106, +0,180,3,79,0, +180,3,52,0,180, +3,114,0,180,3, +87,0,180,3,122, +0,180,3,95,0, +180,3,68,0,180, +3,103,0,180,3, +76,0,180,3,49, +0,180,3,111,0, +180,3,84,0,180, +3,57,0,180,3, +119,0,180,3,65, +0,180,3,100,0, +180,3,73,0,180, +3,108,0,180,3, +81,0,180,3,54, +0,180,3,116,0, +180,3,89,0,180, +1376,11,1,215,0, +1377,4,8,69,0, +76,0,83,0,69, +0,1,-1,3,74, +0,180,3,109,0, +180,3,82,0,180, +3,55,0,180,3, +117,0,180,3,90, +0,180,3,98,0, +180,3,71,0,180, +3,106,0,180,3, +79,0,180,3,52, +0,180,3,114,0, +180,3,87,0,180, +3,122,0,180,3, +95,0,180,3,68, +0,180,3,103,0, +180,3,76,0,180, +3,49,0,180,3, +111,0,180,3,84, +0,180,3,57,0, +180,3,119,0,180, +3,65,0,180,3, +100,0,180,3,73, +0,180,3,108,0, +180,3,81,0,180, +3,54,0,180,3, +116,0,180,3,89, +0,180,1378,11,1, +867,0,183,1,-1, +3,88,0,180,3, +69,0,180,3,104, +0,180,3,77,0, +180,3,50,0,180, +3,112,0,180,3, +85,0,180,3,120, +0,180,3,66,0, +180,3,101,0,180, +3,74,0,180,3, +109,0,180,3,82, +0,180,3,55,0, +180,3,117,0,180, +3,90,0,180,3, +98,0,180,3,71, +0,180,3,106,0, +180,3,79,0,180, +3,52,0,180,3, +114,0,180,3,87, +0,180,3,122,0, +180,3,95,0,180, +3,68,0,180,3, +103,0,180,3,76, +0,180,3,49,0, +180,3,111,0,180, +3,84,0,180,3, +57,0,180,3,119, +0,180,3,65,0, +180,3,100,0,180, +3,73,0,180,3, +108,0,180,3,81, +0,180,3,54,0, +180,3,116,0,180, +3,89,0,180,1379, +11,1,867,0,183, +1,-1,3,81,0, +180,3,54,0,180, +3,116,0,180,3, +89,0,180,1380,11, +1,867,0,183,1, +-1,3,61,0,1381, +12,1,3985,1382,5, +1,3,61,0,1383, +12,1,3993,1384,5, +0,1385,11,1,136, +0,1386,4,26,69, +0,81,0,85,0, +65,0,76,0,83, +0,95,0,69,0, +81,0,85,0,65, +0,76,0,83,0, +1,-1,1387,11,1, +66,0,1388,4,12, +69,0,81,0,85, +0,65,0,76,0, +83,0,1,-1,3, +98,0,178,3,95, +0,178,3,55,0, +647,3,52,0,647, +3,89,0,178,3, +49,0,647,3,9, +0,672,3,126,0, +1389,12,1,3864,1390, +5,0,1391,11,1, +175,0,1392,4,10, +84,0,73,0,76, +0,68,0,69,0, +1,-1,3,86,0, +178,3,46,0,1393, +12,1,5674,1394,5, +14,3,48,0,651, +3,70,0,653,3, +55,0,651,3,51, +0,651,3,69,0, +657,3,54,0,651, +3,102,0,653,3, +50,0,651,3,57, +0,651,3,53,0, +651,3,101,0,657, +3,49,0,651,3, +56,0,651,3,52, +0,651,1395,11,1, +111,0,1396,4,12, +80,0,69,0,82, +0,73,0,79,0, +68,0,1,-1,3, 123,0,1397,12,1, -43065,1398,5,0,1399, +7726,1398,5,0,1399, 11,1,51,0,1400, 4,20,76,0,69, 0,70,0,84,0, 95,0,66,0,82, 0,65,0,67,0, 69,0,1,-1,3, -124,0,1401,12,1, -45968,1402,5,1,3, -124,0,1403,12,1, -46080,1404,5,0,1405, -11,1,191,0,1406, -4,26,83,0,84, -0,82,0,79,0, -75,0,69,0,95, -0,83,0,84,0, -82,0,79,0,75, -0,69,0,1,-1, -1407,11,1,165,0, -1408,4,12,83,0, -84,0,82,0,79, -0,75,0,69,0, -1,-1,3,125,0, -1409,12,1,43430,1410, -5,0,1411,11,1, -56,0,1412,4,22, -82,0,73,0,71, -0,72,0,84,0, -95,0,66,0,82, -0,65,0,67,0, -69,0,1,-1,3, -126,0,1413,12,1, -46209,1414,5,0,1415, -11,1,175,0,1416, -4,10,84,0,73, -0,76,0,68,0, -69,0,1,-1,0, +83,0,178,3,43, +0,1401,12,1,4226, +1402,5,2,3,61, +0,1403,12,1,4234, +1404,5,0,1405,11, +1,16,0,1406,4, +22,80,0,76,0, +85,0,83,0,95, +0,69,0,81,0, +85,0,65,0,76, +0,83,0,1,-1, +3,43,0,1407,12, +1,4355,1408,5,0, +1409,11,1,2,0, +1410,4,18,73,0, +78,0,67,0,82, +0,69,0,77,0, +69,0,78,0,84, +0,1,-1,1411,11, +1,81,0,1412,4, +8,80,0,76,0, +85,0,83,0,1, +-1,3,120,0,178, +3,80,0,178,3, +40,0,1413,12,1, +7848,1414,5,0,1415, +11,1,71,0,1416, +4,20,76,0,69, +0,70,0,84,0, +95,0,80,0,65, +0,82,0,69,0, +78,0,1,-1,0, 165,1,-1,1417,4, 12,83,0,84,0, 82,0,73,0,78, 0,71,0,1418,12, -1,47777,1419,5,119, -3,1,0,1420,12, -1,47778,1421,5,0, +1,1095,1419,5,119, +3,238,22,1420,12, +1,1096,1421,5,0, 1422,11,1,968,0, -165,1,-1,3,9, -0,1420,3,10,0, -1423,12,1,47979,1424, -5,0,1425,11,1, -974,0,165,1,-1, -3,13,0,1420,3, -0,3,1420,3,0, -6,1420,3,32,0, -1420,3,33,0,1420, -3,34,0,1426,12, -1,48726,1427,5,0, -1428,11,1,1032,0, -165,1,-1,3,35, -0,1420,3,36,0, +165,1,-1,3,117, +0,1420,3,63,32, 1420,3,37,0,1420, -3,38,0,1420,3, -40,0,1420,3,41, -0,1420,3,42,0, -1420,3,43,0,1420, -3,44,0,1420,3, -45,0,1420,3,46, -0,1420,3,47,0, -1420,3,3,9,1420, -3,49,0,1420,3, -50,0,1420,3,48, -0,1420,3,52,0, -1420,3,53,0,1420, -3,51,0,1420,3, -55,0,1420,3,56, -0,1420,3,54,0, -1420,3,59,0,1420, -3,57,0,1420,3, -61,0,1420,3,62, -0,1420,3,60,0, -1420,3,64,0,1420, -3,65,0,1420,3, -66,0,1420,3,67, -0,1420,3,68,0, -1420,3,69,0,1420, -3,70,0,1420,3, -71,0,1420,3,72, -0,1420,3,73,0, -1420,3,74,0,1420, -3,75,0,1420,3, -76,0,1420,3,77, -0,1420,3,78,0, -1420,3,79,0,1420, -3,80,0,1420,3, -81,0,1420,3,82, -0,1420,3,83,0, +3,114,0,1420,3, +74,0,1420,3,34, +0,1423,12,1,1836, +1424,5,0,1425,11, +1,1032,0,165,1, +-1,3,111,0,1420, +3,71,0,1420,3, +108,0,1420,3,68, +0,1420,3,105,0, +1420,3,65,0,1420, +3,102,0,1420,3, +62,0,1420,3,99, +0,1420,3,59,0, +1420,3,96,0,1420, +3,96,6,1420,3, +173,0,1420,3,93, +0,1420,3,53,0, +1420,3,13,0,1420, +3,170,0,1420,3, +90,0,1420,3,50, +0,1420,3,10,0, +1426,12,1,1975,1427, +5,0,1428,11,1, +974,0,165,1,-1, +3,87,0,1420,3, +47,0,1420,3,100, +0,1420,3,124,0, 1420,3,84,0,1420, -3,85,0,1420,3, -86,0,1420,3,87, -0,1420,3,88,0, -1420,3,89,0,1420, -3,90,0,1420,3, -91,0,1420,3,92, -0,1429,12,1,48122, -1430,5,4,3,110, -0,1431,12,1,48151, +3,44,0,1420,3, +121,0,1420,3,81, +0,1420,3,41,0, +1420,3,1,0,1420, +3,59,15,1420,3, +78,0,1420,3,38, +0,1420,3,58,15, +1420,3,115,0,1420, +3,75,0,1420,3, +35,0,1420,3,192, +0,1420,3,112,0, +1420,3,72,0,1420, +3,32,0,1420,3, +109,0,1420,3,69, +0,1420,3,187,1, +1420,3,106,0,1420, +3,66,0,1420,3, +103,0,1420,3,77, +0,1420,3,3,9, +1420,3,118,0,1420, +3,60,0,1420,3, +0,3,1420,3,197, +1,1420,3,176,2, +1420,3,57,0,1420, +3,70,0,1420,3, +94,0,1420,3,54, +0,1420,3,171,0, +1420,3,91,0,1420, +3,51,0,1420,3, +88,0,1420,3,48, +0,1420,3,125,0, +1420,3,85,0,1420, +3,56,0,1420,3, +97,0,1420,3,122, +0,1420,3,82,0, +1420,3,42,0,1420, +3,0,6,1420,3, +119,0,1420,3,79, +0,1420,3,41,32, +1420,3,116,0,1420, +3,76,0,1420,3, +36,0,1420,3,113, +0,1420,3,73,0, +1420,3,33,0,1420, +3,110,0,1420,3, +40,32,1420,3,0, +224,1420,3,187,0, +1420,3,107,0,1420, +3,67,0,1420,3, +104,0,1420,3,64, +0,1420,3,101,0, +1420,3,61,0,1420, +3,178,0,1420,3, +98,0,1420,3,45, +0,1420,3,136,4, +1420,3,95,0,1420, +3,55,0,1420,3, +172,0,1420,3,92, +0,1429,12,1,1229, +1430,5,4,3,116, +0,1431,12,1,1682, 1432,5,0,1433,11, -1,979,0,165,1, +1,991,0,165,1, -1,3,34,0,1434, -12,1,48591,1435,5, +12,1,1370,1435,5, 0,1436,11,1,1003, 0,165,1,-1,3, 92,0,1437,12,1, -48467,1438,5,0,1439, +1243,1438,5,0,1439, 11,1,1015,0,165, -1,-1,3,116,0, -1440,12,1,48277,1441, +1,-1,3,110,0, +1440,12,1,1541,1441, 5,0,1442,11,1, -991,0,165,1,-1, +979,0,165,1,-1, 1443,11,1,1027,0, -165,1,-1,3,93, -0,1420,3,94,0, -1420,3,95,0,1420, -3,96,0,1420,3, -238,22,1420,3,98, -0,1420,3,99,0, -1420,3,100,0,1420, -3,101,0,1420,3, -97,0,1420,3,103, -0,1420,3,104,0, -1420,3,105,0,1420, -3,106,0,1420,3, -102,0,1420,3,108, -0,1420,3,109,0, -1420,3,110,0,1420, -3,111,0,1420,3, -112,0,1420,3,113, -0,1420,3,114,0, -1420,3,115,0,1420, -3,116,0,1420,3, -117,0,1420,3,118, -0,1420,3,119,0, -1420,3,120,0,1420, -3,121,0,1420,3, -122,0,1420,3,123, -0,1420,3,124,0, -1420,3,125,0,1420, -3,96,6,1420,3, -107,0,1420,3,126, -0,1420,3,58,15, -1420,3,59,15,1420, -3,136,4,1420,3, -160,0,1420,3,170, -0,1420,3,171,0, -1420,3,172,0,1420, -3,173,0,1420,3, -178,0,1420,3,176, -2,1420,3,187,0, -1420,3,187,1,1420, -3,192,0,1420,3, -41,32,1420,3,197, -1,1420,3,0,224, -1420,3,40,32,1420, -3,63,32,1420,0, +165,1,-1,3,52, +0,1420,3,89,0, +1420,3,49,0,1420, +3,9,0,1420,3, +126,0,1420,3,86, +0,1420,3,46,0, +1420,3,123,0,1420, +3,83,0,1420,3, +43,0,1420,3,160, +0,1420,3,120,0, +1420,3,80,0,1420, +3,40,0,1420,0, 165,1,-1,1444,5, -94,251,1445,10,251, -1,19,573,1446,10, -573,1,47,301,1447, -10,301,1,94,1172, -1448,10,1172,1,50, -1041,1449,10,1041,1, -80,1191,1450,10,1191, -1,53,188,1451,10, -188,1,37,602,1452, -10,602,1,43,700, -1453,10,700,1,51, -613,1454,10,613,1, -46,1331,1455,10,1331, -1,92,211,1456,10, -211,1,16,215,1457, -10,215,1,17,672, -1458,10,672,1,68, -901,1459,10,901,1, -75,361,1460,10,361, -1,35,223,1461,10, -223,1,20,229,1462, -10,229,1,6,199, -1463,10,199,1,22, -286,1464,10,286,1, -21,265,1465,10,265, -1,96,1292,1466,10, -1292,1,88,481,1467, -10,481,1,64,720, -1468,10,720,1,49, -357,1469,10,357,1, -28,318,1470,10,318, -1,25,709,1471,10, -709,1,42,792,1472, -10,792,1,69,1231, -1473,10,1231,1,48, -336,1474,10,336,1, -41,850,1475,10,850, -1,57,654,1476,10, -654,1,91,233,1477, -10,233,1,4,342, -1478,10,342,1,23, -493,1479,10,493,1, -63,1246,1480,10,1246, -1,84,324,1481,10, -324,1,29,245,1482, -10,245,1,5,316, -1483,10,316,1,31, -624,1484,10,624,1, -52,889,1485,10,889, -1,76,1114,1486,10, -1114,1,83,1017,1487, -10,1017,1,81,995, -1488,10,995,1,77, -186,1489,10,186,1, -30,249,1490,10,249, -1,7,847,1491,10, -847,1,73,197,1492, -10,197,1,10,353, -1493,10,353,1,27, -294,1494,10,294,1, -95,239,1495,10,239, -1,14,269,1496,10, -269,1,24,731,1497, -10,731,1,54,281, -1498,10,281,1,9, -1225,1499,10,1225,1, -86,498,1500,10,498, -1,62,1501,4,30, +94,844,1445,10,844, +1,76,1400,1446,10, +1400,1,12,1043,1447, +10,1043,1,7,671, +1448,10,671,1,28, +1366,1449,10,1366,1, +67,1338,1450,10,1338, +1,68,1451,4,30, 83,0,84,0,82, 0,73,0,78,0, 71,0,95,0,67, 0,79,0,78,0, 83,0,84,0,65, 0,78,0,84,0, -1502,10,1501,1,3, -1392,1503,10,1392,1, -45,348,1504,10,348, -1,93,551,1505,10, -551,1,66,1068,1506, -10,1068,1,56,402, -1507,10,402,1,58, -1400,1508,10,1400,1, -12,531,1509,10,531, -1,44,312,1510,10, -312,1,40,1154,1511, -10,1154,1,82,591, -1512,10,591,1,67, -946,1513,10,946,1, -78,1416,1514,10,1416, -1,36,1408,1515,10, -1408,1,34,787,1516, -10,787,1,70,1357, -1517,10,1357,1,87, -865,1518,10,865,1, -74,338,1519,10,338, -1,26,425,1520,10, -425,1,59,207,1521, -10,207,1,33,306, -1522,10,306,1,11, -205,1523,10,205,1, -38,519,1524,10,519, -1,61,828,1525,10, -828,1,72,1287,1526, -10,1287,1,90,326, -1527,10,326,1,15, -969,1528,10,969,1, -79,1406,1529,10,1406, -1,39,332,1530,10, -332,1,32,1275,1531, -10,1275,1,89,375, -1532,10,375,1,60, -1375,1533,10,1375,1, -55,1412,1534,10,1412, -1,13,1214,1535,10, -1214,1,85,235,1536, -10,235,1,18,221, -1537,10,221,1,8, -775,1538,10,775,1, -71,449,1539,10,449, -1,65,1540,5,0,0}; - new Tfactory(this,"MINUS",new TCreator(MINUS_factory)); - new Tfactory(this,"DEFAULT_STATE",new TCreator(DEFAULT_STATE_factory)); - new Tfactory(this,"INTEGER_CONSTANT",new TCreator(INTEGER_CONSTANT_factory)); - new Tfactory(this,"RETURN",new TCreator(RETURN_factory)); - new Tfactory(this,"OBJECT_REZ_EVENT",new TCreator(OBJECT_REZ_EVENT_factory)); - new Tfactory(this,"STRING_TYPE",new TCreator(STRING_TYPE_factory)); - new Tfactory(this,"EXCLAMATION",new TCreator(EXCLAMATION_factory)); - new Tfactory(this,"ELSE",new TCreator(ELSE_factory)); - new Tfactory(this,"INTEGER_TYPE",new TCreator(INTEGER_TYPE_factory)); - new Tfactory(this,"FOR",new TCreator(FOR_factory)); - new Tfactory(this,"TRANSACTION_RESULT_EVENT",new TCreator(TRANSACTION_RESULT_EVENT_factory)); - new Tfactory(this,"LEFT_PAREN",new TCreator(LEFT_PAREN_factory)); - new Tfactory(this,"RIGHT_PAREN",new TCreator(RIGHT_PAREN_factory)); - new Tfactory(this,"HTTP_RESPONSE_EVENT",new TCreator(HTTP_RESPONSE_EVENT_factory)); - new Tfactory(this,"MOVING_END_EVENT",new TCreator(MOVING_END_EVENT_factory)); - new Tfactory(this,"CARET",new TCreator(CARET_factory)); - new Tfactory(this,"STAR",new TCreator(STAR_factory)); - new Tfactory(this,"PLUS_EQUALS",new TCreator(PLUS_EQUALS_factory)); - new Tfactory(this,"PERCENT",new TCreator(PERCENT_factory)); - new Tfactory(this,"SLASH",new TCreator(SLASH_factory)); - new Tfactory(this,"FLOAT_CONSTANT",new TCreator(FLOAT_CONSTANT_factory)); - new Tfactory(this,"TOUCH_EVENT",new TCreator(TOUCH_EVENT_factory)); - new Tfactory(this,"COLLISION_START_EVENT",new TCreator(COLLISION_START_EVENT_factory)); - new Tfactory(this,"JUMP",new TCreator(JUMP_factory)); - new Tfactory(this,"RIGHT_BRACKET",new TCreator(RIGHT_BRACKET_factory)); - new Tfactory(this,"LEFT_ANGLE",new TCreator(LEFT_ANGLE_factory)); - new Tfactory(this,"IF",new TCreator(IF_factory)); - new Tfactory(this,"LAND_COLLISION_EVENT",new TCreator(LAND_COLLISION_EVENT_factory)); - new Tfactory(this,"STATE",new TCreator(STATE_factory)); - new Tfactory(this,"RIGHT_SHIFT",new TCreator(RIGHT_SHIFT_factory)); - new Tfactory(this,"LIST_TYPE",new TCreator(LIST_TYPE_factory)); - new Tfactory(this,"HTTP_REQUEST_EVENT",new TCreator(HTTP_REQUEST_EVENT_factory)); - new Tfactory(this,"INCREMENT",new TCreator(INCREMENT_factory)); - new Tfactory(this,"AT",new TCreator(AT_factory)); - new Tfactory(this,"COLLISION_END_EVENT",new TCreator(COLLISION_END_EVENT_factory)); - new Tfactory(this,"SENSOR_EVENT",new TCreator(SENSOR_EVENT_factory)); - new Tfactory(this,"EQUALS_EQUALS",new TCreator(EQUALS_EQUALS_factory)); - new Tfactory(this,"DECREMENT",new TCreator(DECREMENT_factory)); - new Tfactory(this,"LESS_EQUALS",new TCreator(LESS_EQUALS_factory)); - new Tfactory(this,"FLOAT_TYPE",new TCreator(FLOAT_TYPE_factory)); +1452,10,1451,1,3, +1396,1453,10,1396,1, +24,856,1454,10,856, +1,75,192,1455,10, +192,1,22,944,1456, +10,944,1,25,707, +1457,10,707,1,17, +972,1458,10,972,1, +58,1416,1459,10,1416, +1,16,234,1460,10, +234,1,50,585,1461, +10,585,1,65,1272, +1462,10,1272,1,79, +732,1463,10,732,1, +38,1211,1464,10,1211, +1,77,617,1465,10, +617,1,64,820,1466, +10,820,1,74,938, +1467,10,938,1,31, +509,1468,10,509,1, +51,1179,1469,10,1179, +1,88,1320,1470,10, +1320,1,91,1057,1471, +10,1057,1,20,1037, +1472,10,1037,1,13, +1406,1473,10,1406,1, +6,1055,1474,10,1055, +1,8,464,1475,10, +464,1,72,495,1476, +10,495,1,42,1020, +1477,10,1020,1,35, +774,1478,10,774,1, +85,785,1479,10,785, +1,86,791,1480,10, +791,1,48,1354,1481, +10,1354,1,23,1249, +1482,10,1249,1,78, +548,1483,10,548,1, +41,699,1484,10,699, +1,34,667,1485,10, +667,1,94,1410,1486, +10,1410,1,4,1174, +1487,10,1174,1,90, +646,1488,10,646,1, +11,566,1489,10,566, +1,61,922,1490,10, +922,1,47,1085,1491, +10,1085,1,87,190, +1492,10,190,1,10, +1124,1493,10,1124,1, +92,1386,1494,10,1386, +1,29,734,1495,10, +734,1,33,216,1496, +10,216,1,82,486, +1497,10,486,1,57, +803,1498,10,803,1, +53,1032,1499,10,1032, +1,95,1292,1500,10, +1292,1,54,995,1501, +10,995,1,59,1189, +1502,10,1189,1,30, +1024,1503,10,1024,1, +27,1388,1504,10,1388, +1,15,1162,1505,10, +1162,1,89,875,1506, +10,875,1,49,278, +1507,10,278,1,83, +411,1508,10,411,1, +71,900,1509,10,900, +1,66,1047,1510,10, +1047,1,5,1191,1511, +10,1191,1,37,336, +1512,10,336,1,81, +544,1513,10,544,1, +32,656,1514,10,656, +1,96,423,1515,10, +423,1,70,691,1516, +10,691,1,21,428, +1517,10,428,1,69, +1069,1518,10,1069,1, +45,312,1519,10,312, +1,56,634,1520,10, +634,1,62,680,1521, +10,680,1,9,534, +1522,10,534,1,52, +942,1523,10,942,1, +40,1392,1524,10,1392, +1,36,360,1525,10, +360,1,80,703,1526, +10,703,1,14,523, +1527,10,523,1,46, +748,1528,10,748,1, +84,183,1529,10,183, +1,93,1377,1530,10, +1377,1,43,721,1531, +10,721,1,55,697, +1532,10,697,1,39, +1412,1533,10,1412,1, +18,1011,1534,10,1011, +1,60,629,1535,10, +629,1,63,550,1536, +10,550,1,26,1049, +1537,10,1049,1,19, +931,1538,10,931,1, +44,483,1539,10,483, +1,73,1540,5,0,0}; new Tfactory(this,"MOVING_START_EVENT",new TCreator(MOVING_START_EVENT_factory)); - new Tfactory(this,"RUN_TIME_PERMISSIONS_EVENT",new TCreator(RUN_TIME_PERMISSIONS_EVENT_factory)); - new Tfactory(this,"ON_REZ_EVENT",new TCreator(ON_REZ_EVENT_factory)); - new Tfactory(this,"NO_SENSOR_EVENT",new TCreator(NO_SENSOR_EVENT_factory)); - new Tfactory(this,"EXCLAMATION_EQUALS",new TCreator(EXCLAMATION_EQUALS_factory)); - new Tfactory(this,"MINUS_EQUALS",new TCreator(MINUS_EQUALS_factory)); - new Tfactory(this,"LISTEN_EVENT",new TCreator(LISTEN_EVENT_factory)); - new Tfactory(this,"PERCENT_EQUALS",new TCreator(PERCENT_EQUALS_factory)); - new Tfactory(this,"LEFT_BRACKET",new TCreator(LEFT_BRACKET_factory)); - new Tfactory(this,"HEX_INTEGER_CONSTANT",new TCreator(HEX_INTEGER_CONSTANT_factory)); - new Tfactory(this,"COMMA",new TCreator(COMMA_factory)); - new Tfactory(this,"PERIOD",new TCreator(PERIOD_factory)); - new Tfactory(this,"KEY_TYPE",new TCreator(KEY_TYPE_factory)); - new Tfactory(this,"SLASH_EQUALS",new TCreator(SLASH_EQUALS_factory)); - new Tfactory(this,"STATE_EXIT_EVENT",new TCreator(STATE_EXIT_EVENT_factory)); - new Tfactory(this,"COLLISION_EVENT",new TCreator(COLLISION_EVENT_factory)); - new Tfactory(this,"STRING_CONSTANT",new TCreator(STRING_CONSTANT_factory)); - new Tfactory(this,"WHILE",new TCreator(WHILE_factory)); - new Tfactory(this,"IDENT",new TCreator(IDENT_factory)); - new Tfactory(this,"DATASERVER_EVENT",new TCreator(DATASERVER_EVENT_factory)); - new Tfactory(this,"ROTATION_TYPE",new TCreator(ROTATION_TYPE_factory)); - new Tfactory(this,"AT_ROT_TARGET_EVENT",new TCreator(AT_ROT_TARGET_EVENT_factory)); new Tfactory(this,"LEFT_BRACE",new TCreator(LEFT_BRACE_factory)); - new Tfactory(this,"DO",new TCreator(DO_factory)); - new Tfactory(this,"LEFT_SHIFT",new TCreator(LEFT_SHIFT_factory)); - new Tfactory(this,"REMOTE_DATA_EVENT",new TCreator(REMOTE_DATA_EVENT_factory)); + new Tfactory(this,"MINUS_EQUALS",new TCreator(MINUS_EQUALS_factory)); + new Tfactory(this,"RIGHT_BRACKET",new TCreator(RIGHT_BRACKET_factory)); new Tfactory(this,"EMAIL_EVENT",new TCreator(EMAIL_EVENT_factory)); - new Tfactory(this,"NOT_AT_ROT_TARGET_EVENT",new TCreator(NOT_AT_ROT_TARGET_EVENT_factory)); - new Tfactory(this,"TILDE",new TCreator(TILDE_factory)); - new Tfactory(this,"STROKE",new TCreator(STROKE_factory)); - new Tfactory(this,"LAND_COLLISION_END_EVENT",new TCreator(LAND_COLLISION_END_EVENT_factory)); - new Tfactory(this,"TIMER_EVENT",new TCreator(TIMER_EVENT_factory)); - new Tfactory(this,"MONEY_EVENT",new TCreator(MONEY_EVENT_factory)); - new Tfactory(this,"RIGHT_ANGLE",new TCreator(RIGHT_ANGLE_factory)); - new Tfactory(this,"AT_TARGET_EVENT",new TCreator(AT_TARGET_EVENT_factory)); - new Tfactory(this,"AMP",new TCreator(AMP_factory)); - new Tfactory(this,"SEMICOLON",new TCreator(SEMICOLON_factory)); - new Tfactory(this,"AMP_AMP",new TCreator(AMP_AMP_factory)); - new Tfactory(this,"CHANGED_EVENT",new TCreator(CHANGED_EVENT_factory)); - new Tfactory(this,"LINK_MESSAGE_EVENT",new TCreator(LINK_MESSAGE_EVENT_factory)); - new Tfactory(this,"TOUCH_END_EVENT",new TCreator(TOUCH_END_EVENT_factory)); - new Tfactory(this,"EQUALS",new TCreator(EQUALS_factory)); - new Tfactory(this,"NOT_AT_TARGET_EVENT",new TCreator(NOT_AT_TARGET_EVENT_factory)); - new Tfactory(this,"STROKE_STROKE",new TCreator(STROKE_STROKE_factory)); - new Tfactory(this,"GREATER_EQUALS",new TCreator(GREATER_EQUALS_factory)); - new Tfactory(this,"TOUCH_START_EVENT",new TCreator(TOUCH_START_EVENT_factory)); - new Tfactory(this,"ATTACH_EVENT",new TCreator(ATTACH_EVENT_factory)); - new Tfactory(this,"VECTOR_TYPE",new TCreator(VECTOR_TYPE_factory)); - new Tfactory(this,"RIGHT_BRACE",new TCreator(RIGHT_BRACE_factory)); - new Tfactory(this,"STATE_ENTRY_EVENT",new TCreator(STATE_ENTRY_EVENT_factory)); - new Tfactory(this,"PLUS",new TCreator(PLUS_factory)); - new Tfactory(this,"STAR_EQUALS",new TCreator(STAR_EQUALS_factory)); - new Tfactory(this,"LAND_COLLISION_START_EVENT",new TCreator(LAND_COLLISION_START_EVENT_factory)); + new Tfactory(this,"HTTP_RESPONSE_EVENT",new TCreator(HTTP_RESPONSE_EVENT_factory)); + new Tfactory(this,"STRING_CONSTANT",new TCreator(STRING_CONSTANT_factory)); + new Tfactory(this,"PERIOD",new TCreator(PERIOD_factory)); + new Tfactory(this,"MOVING_END_EVENT",new TCreator(MOVING_END_EVENT_factory)); + new Tfactory(this,"PERCENT",new TCreator(PERCENT_factory)); + new Tfactory(this,"LEFT_ANGLE",new TCreator(LEFT_ANGLE_factory)); + new Tfactory(this,"RIGHT_PAREN",new TCreator(RIGHT_PAREN_factory)); + new Tfactory(this,"AT_ROT_TARGET_EVENT",new TCreator(AT_ROT_TARGET_EVENT_factory)); + new Tfactory(this,"LEFT_PAREN",new TCreator(LEFT_PAREN_factory)); + new Tfactory(this,"RETURN",new TCreator(RETURN_factory)); new Tfactory(this,"CONTROL_EVENT",new TCreator(CONTROL_EVENT_factory)); + new Tfactory(this,"NOT_AT_TARGET_EVENT",new TCreator(NOT_AT_TARGET_EVENT_factory)); + new Tfactory(this,"AMP_AMP",new TCreator(AMP_AMP_factory)); + new Tfactory(this,"NO_SENSOR_EVENT",new TCreator(NO_SENSOR_EVENT_factory)); + new Tfactory(this,"COLLISION_START_EVENT",new TCreator(COLLISION_START_EVENT_factory)); + new Tfactory(this,"MONEY_EVENT",new TCreator(MONEY_EVENT_factory)); + new Tfactory(this,"LESS_EQUALS",new TCreator(LESS_EQUALS_factory)); + new Tfactory(this,"INTEGER_TYPE",new TCreator(INTEGER_TYPE_factory)); + new Tfactory(this,"TOUCH_EVENT",new TCreator(TOUCH_EVENT_factory)); + new Tfactory(this,"HTTP_REQUEST_EVENT",new TCreator(HTTP_REQUEST_EVENT_factory)); + new Tfactory(this,"STAR",new TCreator(STAR_factory)); + new Tfactory(this,"RIGHT_BRACE",new TCreator(RIGHT_BRACE_factory)); + new Tfactory(this,"PLUS_EQUALS",new TCreator(PLUS_EQUALS_factory)); + new Tfactory(this,"STAR_EQUALS",new TCreator(STAR_EQUALS_factory)); + new Tfactory(this,"LINK_MESSAGE_EVENT",new TCreator(LINK_MESSAGE_EVENT_factory)); + new Tfactory(this,"IF",new TCreator(IF_factory)); + new Tfactory(this,"CARET",new TCreator(CARET_factory)); + new Tfactory(this,"STATE_ENTRY_EVENT",new TCreator(STATE_ENTRY_EVENT_factory)); + new Tfactory(this,"STATE_EXIT_EVENT",new TCreator(STATE_EXIT_EVENT_factory)); + new Tfactory(this,"STATE",new TCreator(STATE_factory)); + new Tfactory(this,"AT",new TCreator(AT_factory)); + new Tfactory(this,"NOT_AT_ROT_TARGET_EVENT",new TCreator(NOT_AT_ROT_TARGET_EVENT_factory)); + new Tfactory(this,"RIGHT_SHIFT",new TCreator(RIGHT_SHIFT_factory)); + new Tfactory(this,"STROKE",new TCreator(STROKE_factory)); + new Tfactory(this,"INTEGER_CONSTANT",new TCreator(INTEGER_CONSTANT_factory)); + new Tfactory(this,"INCREMENT",new TCreator(INCREMENT_factory)); + new Tfactory(this,"TOUCH_END_EVENT",new TCreator(TOUCH_END_EVENT_factory)); + new Tfactory(this,"SEMICOLON",new TCreator(SEMICOLON_factory)); + new Tfactory(this,"CHANGED_EVENT",new TCreator(CHANGED_EVENT_factory)); + new Tfactory(this,"DEFAULT_STATE",new TCreator(DEFAULT_STATE_factory)); + new Tfactory(this,"TIMER_EVENT",new TCreator(TIMER_EVENT_factory)); + new Tfactory(this,"PERCENT_EQUALS",new TCreator(PERCENT_EQUALS_factory)); + new Tfactory(this,"TRANSACTION_RESULT_EVENT",new TCreator(TRANSACTION_RESULT_EVENT_factory)); + new Tfactory(this,"EQUALS_EQUALS",new TCreator(EQUALS_EQUALS_factory)); + new Tfactory(this,"AMP",new TCreator(AMP_factory)); + new Tfactory(this,"REMOTE_DATA_EVENT",new TCreator(REMOTE_DATA_EVENT_factory)); + new Tfactory(this,"LIST_TYPE",new TCreator(LIST_TYPE_factory)); + new Tfactory(this,"STRING_TYPE",new TCreator(STRING_TYPE_factory)); + new Tfactory(this,"HEX_INTEGER_CONSTANT",new TCreator(HEX_INTEGER_CONSTANT_factory)); + new Tfactory(this,"KEY_TYPE",new TCreator(KEY_TYPE_factory)); + new Tfactory(this,"AT_TARGET_EVENT",new TCreator(AT_TARGET_EVENT_factory)); + new Tfactory(this,"EXCLAMATION_EQUALS",new TCreator(EXCLAMATION_EQUALS_factory)); + new Tfactory(this,"LEFT_BRACKET",new TCreator(LEFT_BRACKET_factory)); + new Tfactory(this,"EQUALS",new TCreator(EQUALS_factory)); + new Tfactory(this,"TOUCH_START_EVENT",new TCreator(TOUCH_START_EVENT_factory)); + new Tfactory(this,"JUMP",new TCreator(JUMP_factory)); + new Tfactory(this,"RUN_TIME_PERMISSIONS_EVENT",new TCreator(RUN_TIME_PERMISSIONS_EVENT_factory)); + new Tfactory(this,"LAND_COLLISION_START_EVENT",new TCreator(LAND_COLLISION_START_EVENT_factory)); + new Tfactory(this,"DATASERVER_EVENT",new TCreator(DATASERVER_EVENT_factory)); + new Tfactory(this,"DECREMENT",new TCreator(DECREMENT_factory)); + new Tfactory(this,"EXCLAMATION",new TCreator(EXCLAMATION_factory)); + new Tfactory(this,"ON_REZ_EVENT",new TCreator(ON_REZ_EVENT_factory)); + new Tfactory(this,"GREATER_EQUALS",new TCreator(GREATER_EQUALS_factory)); + new Tfactory(this,"FLOAT_CONSTANT",new TCreator(FLOAT_CONSTANT_factory)); + new Tfactory(this,"LAND_COLLISION_END_EVENT",new TCreator(LAND_COLLISION_END_EVENT_factory)); + new Tfactory(this,"SLASH",new TCreator(SLASH_factory)); + new Tfactory(this,"LAND_COLLISION_EVENT",new TCreator(LAND_COLLISION_EVENT_factory)); + new Tfactory(this,"WHILE",new TCreator(WHILE_factory)); + new Tfactory(this,"ROTATION_TYPE",new TCreator(ROTATION_TYPE_factory)); + new Tfactory(this,"COLLISION_EVENT",new TCreator(COLLISION_EVENT_factory)); + new Tfactory(this,"SLASH_EQUALS",new TCreator(SLASH_EQUALS_factory)); + new Tfactory(this,"FLOAT_TYPE",new TCreator(FLOAT_TYPE_factory)); + new Tfactory(this,"LEFT_SHIFT",new TCreator(LEFT_SHIFT_factory)); + new Tfactory(this,"TILDE",new TCreator(TILDE_factory)); + new Tfactory(this,"OBJECT_REZ_EVENT",new TCreator(OBJECT_REZ_EVENT_factory)); + new Tfactory(this,"COMMA",new TCreator(COMMA_factory)); + new Tfactory(this,"FOR",new TCreator(FOR_factory)); + new Tfactory(this,"SENSOR_EVENT",new TCreator(SENSOR_EVENT_factory)); + new Tfactory(this,"IDENT",new TCreator(IDENT_factory)); + new Tfactory(this,"ELSE",new TCreator(ELSE_factory)); + new Tfactory(this,"VECTOR_TYPE",new TCreator(VECTOR_TYPE_factory)); + new Tfactory(this,"STROKE_STROKE",new TCreator(STROKE_STROKE_factory)); + new Tfactory(this,"PLUS",new TCreator(PLUS_factory)); + new Tfactory(this,"ATTACH_EVENT",new TCreator(ATTACH_EVENT_factory)); + new Tfactory(this,"COLLISION_END_EVENT",new TCreator(COLLISION_END_EVENT_factory)); + new Tfactory(this,"RIGHT_ANGLE",new TCreator(RIGHT_ANGLE_factory)); + new Tfactory(this,"MINUS",new TCreator(MINUS_factory)); + new Tfactory(this,"DO",new TCreator(DO_factory)); + new Tfactory(this,"LISTEN_EVENT",new TCreator(LISTEN_EVENT_factory)); } -public static object MINUS_factory(Lexer yyl) { return new MINUS(yyl);} -public static object DEFAULT_STATE_factory(Lexer yyl) { return new DEFAULT_STATE(yyl);} -public static object INTEGER_CONSTANT_factory(Lexer yyl) { return new INTEGER_CONSTANT(yyl);} -public static object RETURN_factory(Lexer yyl) { return new RETURN(yyl);} -public static object OBJECT_REZ_EVENT_factory(Lexer yyl) { return new OBJECT_REZ_EVENT(yyl);} -public static object STRING_TYPE_factory(Lexer yyl) { return new STRING_TYPE(yyl);} -public static object EXCLAMATION_factory(Lexer yyl) { return new EXCLAMATION(yyl);} -public static object ELSE_factory(Lexer yyl) { return new ELSE(yyl);} -public static object INTEGER_TYPE_factory(Lexer yyl) { return new INTEGER_TYPE(yyl);} -public static object FOR_factory(Lexer yyl) { return new FOR(yyl);} -public static object TRANSACTION_RESULT_EVENT_factory(Lexer yyl) { return new TRANSACTION_RESULT_EVENT(yyl);} -public static object LEFT_PAREN_factory(Lexer yyl) { return new LEFT_PAREN(yyl);} -public static object RIGHT_PAREN_factory(Lexer yyl) { return new RIGHT_PAREN(yyl);} -public static object HTTP_RESPONSE_EVENT_factory(Lexer yyl) { return new HTTP_RESPONSE_EVENT(yyl);} -public static object MOVING_END_EVENT_factory(Lexer yyl) { return new MOVING_END_EVENT(yyl);} -public static object CARET_factory(Lexer yyl) { return new CARET(yyl);} -public static object STAR_factory(Lexer yyl) { return new STAR(yyl);} -public static object PLUS_EQUALS_factory(Lexer yyl) { return new PLUS_EQUALS(yyl);} -public static object PERCENT_factory(Lexer yyl) { return new PERCENT(yyl);} -public static object SLASH_factory(Lexer yyl) { return new SLASH(yyl);} -public static object FLOAT_CONSTANT_factory(Lexer yyl) { return new FLOAT_CONSTANT(yyl);} -public static object TOUCH_EVENT_factory(Lexer yyl) { return new TOUCH_EVENT(yyl);} -public static object COLLISION_START_EVENT_factory(Lexer yyl) { return new COLLISION_START_EVENT(yyl);} -public static object JUMP_factory(Lexer yyl) { return new JUMP(yyl);} -public static object RIGHT_BRACKET_factory(Lexer yyl) { return new RIGHT_BRACKET(yyl);} -public static object LEFT_ANGLE_factory(Lexer yyl) { return new LEFT_ANGLE(yyl);} -public static object IF_factory(Lexer yyl) { return new IF(yyl);} -public static object LAND_COLLISION_EVENT_factory(Lexer yyl) { return new LAND_COLLISION_EVENT(yyl);} -public static object STATE_factory(Lexer yyl) { return new STATE(yyl);} -public static object RIGHT_SHIFT_factory(Lexer yyl) { return new RIGHT_SHIFT(yyl);} -public static object LIST_TYPE_factory(Lexer yyl) { return new LIST_TYPE(yyl);} -public static object HTTP_REQUEST_EVENT_factory(Lexer yyl) { return new HTTP_REQUEST_EVENT(yyl);} -public static object INCREMENT_factory(Lexer yyl) { return new INCREMENT(yyl);} -public static object AT_factory(Lexer yyl) { return new AT(yyl);} -public static object COLLISION_END_EVENT_factory(Lexer yyl) { return new COLLISION_END_EVENT(yyl);} -public static object SENSOR_EVENT_factory(Lexer yyl) { return new SENSOR_EVENT(yyl);} -public static object EQUALS_EQUALS_factory(Lexer yyl) { return new EQUALS_EQUALS(yyl);} -public static object DECREMENT_factory(Lexer yyl) { return new DECREMENT(yyl);} -public static object LESS_EQUALS_factory(Lexer yyl) { return new LESS_EQUALS(yyl);} -public static object FLOAT_TYPE_factory(Lexer yyl) { return new FLOAT_TYPE(yyl);} public static object MOVING_START_EVENT_factory(Lexer yyl) { return new MOVING_START_EVENT(yyl);} -public static object RUN_TIME_PERMISSIONS_EVENT_factory(Lexer yyl) { return new RUN_TIME_PERMISSIONS_EVENT(yyl);} -public static object ON_REZ_EVENT_factory(Lexer yyl) { return new ON_REZ_EVENT(yyl);} -public static object NO_SENSOR_EVENT_factory(Lexer yyl) { return new NO_SENSOR_EVENT(yyl);} -public static object EXCLAMATION_EQUALS_factory(Lexer yyl) { return new EXCLAMATION_EQUALS(yyl);} -public static object MINUS_EQUALS_factory(Lexer yyl) { return new MINUS_EQUALS(yyl);} -public static object LISTEN_EVENT_factory(Lexer yyl) { return new LISTEN_EVENT(yyl);} -public static object PERCENT_EQUALS_factory(Lexer yyl) { return new PERCENT_EQUALS(yyl);} -public static object LEFT_BRACKET_factory(Lexer yyl) { return new LEFT_BRACKET(yyl);} -public static object HEX_INTEGER_CONSTANT_factory(Lexer yyl) { return new HEX_INTEGER_CONSTANT(yyl);} -public static object COMMA_factory(Lexer yyl) { return new COMMA(yyl);} -public static object PERIOD_factory(Lexer yyl) { return new PERIOD(yyl);} -public static object KEY_TYPE_factory(Lexer yyl) { return new KEY_TYPE(yyl);} -public static object SLASH_EQUALS_factory(Lexer yyl) { return new SLASH_EQUALS(yyl);} -public static object STATE_EXIT_EVENT_factory(Lexer yyl) { return new STATE_EXIT_EVENT(yyl);} -public static object COLLISION_EVENT_factory(Lexer yyl) { return new COLLISION_EVENT(yyl);} -public static object STRING_CONSTANT_factory(Lexer yyl) { return new STRING_CONSTANT(yyl);} -public static object WHILE_factory(Lexer yyl) { return new WHILE(yyl);} -public static object IDENT_factory(Lexer yyl) { return new IDENT(yyl);} -public static object DATASERVER_EVENT_factory(Lexer yyl) { return new DATASERVER_EVENT(yyl);} -public static object ROTATION_TYPE_factory(Lexer yyl) { return new ROTATION_TYPE(yyl);} -public static object AT_ROT_TARGET_EVENT_factory(Lexer yyl) { return new AT_ROT_TARGET_EVENT(yyl);} public static object LEFT_BRACE_factory(Lexer yyl) { return new LEFT_BRACE(yyl);} -public static object DO_factory(Lexer yyl) { return new DO(yyl);} -public static object LEFT_SHIFT_factory(Lexer yyl) { return new LEFT_SHIFT(yyl);} -public static object REMOTE_DATA_EVENT_factory(Lexer yyl) { return new REMOTE_DATA_EVENT(yyl);} +public static object MINUS_EQUALS_factory(Lexer yyl) { return new MINUS_EQUALS(yyl);} +public static object RIGHT_BRACKET_factory(Lexer yyl) { return new RIGHT_BRACKET(yyl);} public static object EMAIL_EVENT_factory(Lexer yyl) { return new EMAIL_EVENT(yyl);} -public static object NOT_AT_ROT_TARGET_EVENT_factory(Lexer yyl) { return new NOT_AT_ROT_TARGET_EVENT(yyl);} -public static object TILDE_factory(Lexer yyl) { return new TILDE(yyl);} -public static object STROKE_factory(Lexer yyl) { return new STROKE(yyl);} -public static object LAND_COLLISION_END_EVENT_factory(Lexer yyl) { return new LAND_COLLISION_END_EVENT(yyl);} -public static object TIMER_EVENT_factory(Lexer yyl) { return new TIMER_EVENT(yyl);} -public static object MONEY_EVENT_factory(Lexer yyl) { return new MONEY_EVENT(yyl);} -public static object RIGHT_ANGLE_factory(Lexer yyl) { return new RIGHT_ANGLE(yyl);} -public static object AT_TARGET_EVENT_factory(Lexer yyl) { return new AT_TARGET_EVENT(yyl);} -public static object AMP_factory(Lexer yyl) { return new AMP(yyl);} -public static object SEMICOLON_factory(Lexer yyl) { return new SEMICOLON(yyl);} -public static object AMP_AMP_factory(Lexer yyl) { return new AMP_AMP(yyl);} -public static object CHANGED_EVENT_factory(Lexer yyl) { return new CHANGED_EVENT(yyl);} -public static object LINK_MESSAGE_EVENT_factory(Lexer yyl) { return new LINK_MESSAGE_EVENT(yyl);} -public static object TOUCH_END_EVENT_factory(Lexer yyl) { return new TOUCH_END_EVENT(yyl);} -public static object EQUALS_factory(Lexer yyl) { return new EQUALS(yyl);} -public static object NOT_AT_TARGET_EVENT_factory(Lexer yyl) { return new NOT_AT_TARGET_EVENT(yyl);} -public static object STROKE_STROKE_factory(Lexer yyl) { return new STROKE_STROKE(yyl);} -public static object GREATER_EQUALS_factory(Lexer yyl) { return new GREATER_EQUALS(yyl);} -public static object TOUCH_START_EVENT_factory(Lexer yyl) { return new TOUCH_START_EVENT(yyl);} -public static object ATTACH_EVENT_factory(Lexer yyl) { return new ATTACH_EVENT(yyl);} -public static object VECTOR_TYPE_factory(Lexer yyl) { return new VECTOR_TYPE(yyl);} -public static object RIGHT_BRACE_factory(Lexer yyl) { return new RIGHT_BRACE(yyl);} -public static object STATE_ENTRY_EVENT_factory(Lexer yyl) { return new STATE_ENTRY_EVENT(yyl);} -public static object PLUS_factory(Lexer yyl) { return new PLUS(yyl);} -public static object STAR_EQUALS_factory(Lexer yyl) { return new STAR_EQUALS(yyl);} -public static object LAND_COLLISION_START_EVENT_factory(Lexer yyl) { return new LAND_COLLISION_START_EVENT(yyl);} +public static object HTTP_RESPONSE_EVENT_factory(Lexer yyl) { return new HTTP_RESPONSE_EVENT(yyl);} +public static object STRING_CONSTANT_factory(Lexer yyl) { return new STRING_CONSTANT(yyl);} +public static object PERIOD_factory(Lexer yyl) { return new PERIOD(yyl);} +public static object MOVING_END_EVENT_factory(Lexer yyl) { return new MOVING_END_EVENT(yyl);} +public static object PERCENT_factory(Lexer yyl) { return new PERCENT(yyl);} +public static object LEFT_ANGLE_factory(Lexer yyl) { return new LEFT_ANGLE(yyl);} +public static object RIGHT_PAREN_factory(Lexer yyl) { return new RIGHT_PAREN(yyl);} +public static object AT_ROT_TARGET_EVENT_factory(Lexer yyl) { return new AT_ROT_TARGET_EVENT(yyl);} +public static object LEFT_PAREN_factory(Lexer yyl) { return new LEFT_PAREN(yyl);} +public static object RETURN_factory(Lexer yyl) { return new RETURN(yyl);} public static object CONTROL_EVENT_factory(Lexer yyl) { return new CONTROL_EVENT(yyl);} +public static object NOT_AT_TARGET_EVENT_factory(Lexer yyl) { return new NOT_AT_TARGET_EVENT(yyl);} +public static object AMP_AMP_factory(Lexer yyl) { return new AMP_AMP(yyl);} +public static object NO_SENSOR_EVENT_factory(Lexer yyl) { return new NO_SENSOR_EVENT(yyl);} +public static object COLLISION_START_EVENT_factory(Lexer yyl) { return new COLLISION_START_EVENT(yyl);} +public static object MONEY_EVENT_factory(Lexer yyl) { return new MONEY_EVENT(yyl);} +public static object LESS_EQUALS_factory(Lexer yyl) { return new LESS_EQUALS(yyl);} +public static object INTEGER_TYPE_factory(Lexer yyl) { return new INTEGER_TYPE(yyl);} +public static object TOUCH_EVENT_factory(Lexer yyl) { return new TOUCH_EVENT(yyl);} +public static object HTTP_REQUEST_EVENT_factory(Lexer yyl) { return new HTTP_REQUEST_EVENT(yyl);} +public static object STAR_factory(Lexer yyl) { return new STAR(yyl);} +public static object RIGHT_BRACE_factory(Lexer yyl) { return new RIGHT_BRACE(yyl);} +public static object PLUS_EQUALS_factory(Lexer yyl) { return new PLUS_EQUALS(yyl);} +public static object STAR_EQUALS_factory(Lexer yyl) { return new STAR_EQUALS(yyl);} +public static object LINK_MESSAGE_EVENT_factory(Lexer yyl) { return new LINK_MESSAGE_EVENT(yyl);} +public static object IF_factory(Lexer yyl) { return new IF(yyl);} +public static object CARET_factory(Lexer yyl) { return new CARET(yyl);} +public static object STATE_ENTRY_EVENT_factory(Lexer yyl) { return new STATE_ENTRY_EVENT(yyl);} +public static object STATE_EXIT_EVENT_factory(Lexer yyl) { return new STATE_EXIT_EVENT(yyl);} +public static object STATE_factory(Lexer yyl) { return new STATE(yyl);} +public static object AT_factory(Lexer yyl) { return new AT(yyl);} +public static object NOT_AT_ROT_TARGET_EVENT_factory(Lexer yyl) { return new NOT_AT_ROT_TARGET_EVENT(yyl);} +public static object RIGHT_SHIFT_factory(Lexer yyl) { return new RIGHT_SHIFT(yyl);} +public static object STROKE_factory(Lexer yyl) { return new STROKE(yyl);} +public static object INTEGER_CONSTANT_factory(Lexer yyl) { return new INTEGER_CONSTANT(yyl);} +public static object INCREMENT_factory(Lexer yyl) { return new INCREMENT(yyl);} +public static object TOUCH_END_EVENT_factory(Lexer yyl) { return new TOUCH_END_EVENT(yyl);} +public static object SEMICOLON_factory(Lexer yyl) { return new SEMICOLON(yyl);} +public static object CHANGED_EVENT_factory(Lexer yyl) { return new CHANGED_EVENT(yyl);} +public static object DEFAULT_STATE_factory(Lexer yyl) { return new DEFAULT_STATE(yyl);} +public static object TIMER_EVENT_factory(Lexer yyl) { return new TIMER_EVENT(yyl);} +public static object PERCENT_EQUALS_factory(Lexer yyl) { return new PERCENT_EQUALS(yyl);} +public static object TRANSACTION_RESULT_EVENT_factory(Lexer yyl) { return new TRANSACTION_RESULT_EVENT(yyl);} +public static object EQUALS_EQUALS_factory(Lexer yyl) { return new EQUALS_EQUALS(yyl);} +public static object AMP_factory(Lexer yyl) { return new AMP(yyl);} +public static object REMOTE_DATA_EVENT_factory(Lexer yyl) { return new REMOTE_DATA_EVENT(yyl);} +public static object LIST_TYPE_factory(Lexer yyl) { return new LIST_TYPE(yyl);} +public static object STRING_TYPE_factory(Lexer yyl) { return new STRING_TYPE(yyl);} +public static object HEX_INTEGER_CONSTANT_factory(Lexer yyl) { return new HEX_INTEGER_CONSTANT(yyl);} +public static object KEY_TYPE_factory(Lexer yyl) { return new KEY_TYPE(yyl);} +public static object AT_TARGET_EVENT_factory(Lexer yyl) { return new AT_TARGET_EVENT(yyl);} +public static object EXCLAMATION_EQUALS_factory(Lexer yyl) { return new EXCLAMATION_EQUALS(yyl);} +public static object LEFT_BRACKET_factory(Lexer yyl) { return new LEFT_BRACKET(yyl);} +public static object EQUALS_factory(Lexer yyl) { return new EQUALS(yyl);} +public static object TOUCH_START_EVENT_factory(Lexer yyl) { return new TOUCH_START_EVENT(yyl);} +public static object JUMP_factory(Lexer yyl) { return new JUMP(yyl);} +public static object RUN_TIME_PERMISSIONS_EVENT_factory(Lexer yyl) { return new RUN_TIME_PERMISSIONS_EVENT(yyl);} +public static object LAND_COLLISION_START_EVENT_factory(Lexer yyl) { return new LAND_COLLISION_START_EVENT(yyl);} +public static object DATASERVER_EVENT_factory(Lexer yyl) { return new DATASERVER_EVENT(yyl);} +public static object DECREMENT_factory(Lexer yyl) { return new DECREMENT(yyl);} +public static object EXCLAMATION_factory(Lexer yyl) { return new EXCLAMATION(yyl);} +public static object ON_REZ_EVENT_factory(Lexer yyl) { return new ON_REZ_EVENT(yyl);} +public static object GREATER_EQUALS_factory(Lexer yyl) { return new GREATER_EQUALS(yyl);} +public static object FLOAT_CONSTANT_factory(Lexer yyl) { return new FLOAT_CONSTANT(yyl);} +public static object LAND_COLLISION_END_EVENT_factory(Lexer yyl) { return new LAND_COLLISION_END_EVENT(yyl);} +public static object SLASH_factory(Lexer yyl) { return new SLASH(yyl);} +public static object LAND_COLLISION_EVENT_factory(Lexer yyl) { return new LAND_COLLISION_EVENT(yyl);} +public static object WHILE_factory(Lexer yyl) { return new WHILE(yyl);} +public static object ROTATION_TYPE_factory(Lexer yyl) { return new ROTATION_TYPE(yyl);} +public static object COLLISION_EVENT_factory(Lexer yyl) { return new COLLISION_EVENT(yyl);} +public static object SLASH_EQUALS_factory(Lexer yyl) { return new SLASH_EQUALS(yyl);} +public static object FLOAT_TYPE_factory(Lexer yyl) { return new FLOAT_TYPE(yyl);} +public static object LEFT_SHIFT_factory(Lexer yyl) { return new LEFT_SHIFT(yyl);} +public static object TILDE_factory(Lexer yyl) { return new TILDE(yyl);} +public static object OBJECT_REZ_EVENT_factory(Lexer yyl) { return new OBJECT_REZ_EVENT(yyl);} +public static object COMMA_factory(Lexer yyl) { return new COMMA(yyl);} +public static object FOR_factory(Lexer yyl) { return new FOR(yyl);} +public static object SENSOR_EVENT_factory(Lexer yyl) { return new SENSOR_EVENT(yyl);} +public static object IDENT_factory(Lexer yyl) { return new IDENT(yyl);} +public static object ELSE_factory(Lexer yyl) { return new ELSE(yyl);} +public static object VECTOR_TYPE_factory(Lexer yyl) { return new VECTOR_TYPE(yyl);} +public static object STROKE_STROKE_factory(Lexer yyl) { return new STROKE_STROKE(yyl);} +public static object PLUS_factory(Lexer yyl) { return new PLUS(yyl);} +public static object ATTACH_EVENT_factory(Lexer yyl) { return new ATTACH_EVENT(yyl);} +public static object COLLISION_END_EVENT_factory(Lexer yyl) { return new COLLISION_END_EVENT(yyl);} +public static object RIGHT_ANGLE_factory(Lexer yyl) { return new RIGHT_ANGLE(yyl);} +public static object MINUS_factory(Lexer yyl) { return new MINUS(yyl);} +public static object DO_factory(Lexer yyl) { return new DO(yyl);} +public static object LISTEN_EVENT_factory(Lexer yyl) { return new LISTEN_EVENT(yyl);} public override TOKEN OldAction(Lexer yym,ref string yytext,int action, ref bool reject) { switch(action) { case -1: break; - case 1015: { ((LSLTokens)yym).str += "\\\\"; } - break; - case 991: { ((LSLTokens)yym).str += " "; } - break; - case 963: { yym.yy_begin("STRING"); ((LSLTokens)yym).str = "";} - break; - case 1037: { yym.yy_begin("COMMENT"); } - break; - case 1049: { yym.yy_begin("YYINITIAL"); } - break; - case 1027: { ((LSLTokens)yym).str += '\\'; } - break; - case 1063: ; - break; - case 1076: ; - break; - case 1032: { yym.yy_begin("YYINITIAL"); ((LSLTokens)yym).yytext = ((LSLTokens)yym).str; ((LSLTokens)yym).str = String.Empty; return new STRING_CONSTANT(yym); } - break; - case 1067: ; - break; - case 1072: ; - break; - case 1003: { ((LSLTokens)yym).str += "\\\""; } + case 1076: ; break; case 974: { ((LSLTokens)yym).str += "\\n"; } break; - case 979: { ((LSLTokens)yym).str += "\\n"; } + case 1003: { ((LSLTokens)yym).str += "\\\""; } break; case 968: { ((LSLTokens)yym).str += yytext; } break; + case 991: { ((LSLTokens)yym).str += " "; } + break; + case 1072: ; + break; + case 979: { ((LSLTokens)yym).str += "\\n"; } + break; + case 1063: ; + break; + case 963: { yym.yy_begin("STRING"); ((LSLTokens)yym).str = "";} + break; + case 1049: { yym.yy_begin("YYINITIAL"); } + break; + case 1067: ; + break; + case 1032: { yym.yy_begin("YYINITIAL"); ((LSLTokens)yym).yytext = ((LSLTokens)yym).str; ((LSLTokens)yym).str = String.Empty; return new STRING_CONSTANT(yym); } + break; + case 1027: { ((LSLTokens)yym).str += '\\'; } + break; + case 1015: { ((LSLTokens)yym).str += "\\\\"; } + break; + case 1037: { yym.yy_begin("COMMENT"); } + break; } return null; }} diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/lsl.parser.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/lsl.parser.cs index e4b58919fc..439d006807 100644 --- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/lsl.parser.cs +++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/lsl.parser.cs @@ -886,1493 +886,1493 @@ public IncrementDecrementExpression(Parser yyp):base(yyp){}} public class LSLProgramRoot_1 : LSLProgramRoot { public LSLProgramRoot_1(Parser yyq):base(yyq, - ((GlobalDefinitions)(yyq.StackAt(1).m_value)) - , - ((States)(yyq.StackAt(0).m_value)) - ){}} + ((GlobalDefinitions)(yyq.StackAt(1).m_value)) + , + ((States)(yyq.StackAt(0).m_value)) + ){}} public class LSLProgramRoot_2 : LSLProgramRoot { public LSLProgramRoot_2(Parser yyq):base(yyq, - ((States)(yyq.StackAt(0).m_value)) - ){}} + ((States)(yyq.StackAt(0).m_value)) + ){}} public class GlobalDefinitions_1 : GlobalDefinitions { public GlobalDefinitions_1(Parser yyq):base(yyq, - ((GlobalVariableDeclaration)(yyq.StackAt(0).m_value)) - ){}} + ((GlobalVariableDeclaration)(yyq.StackAt(0).m_value)) + ){}} public class GlobalDefinitions_2 : GlobalDefinitions { public GlobalDefinitions_2(Parser yyq):base(yyq, - ((GlobalDefinitions)(yyq.StackAt(1).m_value)) - , - ((GlobalVariableDeclaration)(yyq.StackAt(0).m_value)) - ){}} + ((GlobalDefinitions)(yyq.StackAt(1).m_value)) + , + ((GlobalVariableDeclaration)(yyq.StackAt(0).m_value)) + ){}} public class GlobalDefinitions_3 : GlobalDefinitions { public GlobalDefinitions_3(Parser yyq):base(yyq, - ((GlobalFunctionDefinition)(yyq.StackAt(0).m_value)) - ){}} + ((GlobalFunctionDefinition)(yyq.StackAt(0).m_value)) + ){}} public class GlobalDefinitions_4 : GlobalDefinitions { public GlobalDefinitions_4(Parser yyq):base(yyq, - ((GlobalDefinitions)(yyq.StackAt(1).m_value)) - , - ((GlobalFunctionDefinition)(yyq.StackAt(0).m_value)) - ){}} + ((GlobalDefinitions)(yyq.StackAt(1).m_value)) + , + ((GlobalFunctionDefinition)(yyq.StackAt(0).m_value)) + ){}} public class GlobalVariableDeclaration_1 : GlobalVariableDeclaration { public GlobalVariableDeclaration_1(Parser yyq):base(yyq, - ((Declaration)(yyq.StackAt(1).m_value)) - ){}} + ((Declaration)(yyq.StackAt(1).m_value)) + ){}} public class GlobalVariableDeclaration_2 : GlobalVariableDeclaration { public GlobalVariableDeclaration_2(Parser yyq):base(yyq,new Assignment(((LSLSyntax -)yyq), - ((Declaration)(yyq.StackAt(3).m_value)) - , - ((Expression)(yyq.StackAt(1).m_value)) - , - ((EQUALS)(yyq.StackAt(2).m_value)) - .yytext)){}} +)yyq), + ((Declaration)(yyq.StackAt(3).m_value)) + , + ((Expression)(yyq.StackAt(1).m_value)) + , + ((EQUALS)(yyq.StackAt(2).m_value)) + .yytext)){}} public class GlobalFunctionDefinition_1 : GlobalFunctionDefinition { - public GlobalFunctionDefinition_1(Parser yyq):base(yyq,"void", - ((IDENT)(yyq.StackAt(4).m_value)) - .yytext, - ((ArgumentDeclarationList)(yyq.StackAt(2).m_value)) - , - ((CompoundStatement)(yyq.StackAt(0).m_value)) - ){}} + public GlobalFunctionDefinition_1(Parser yyq):base(yyq,"void", + ((IDENT)(yyq.StackAt(4).m_value)) + .yytext, + ((ArgumentDeclarationList)(yyq.StackAt(2).m_value)) + , + ((CompoundStatement)(yyq.StackAt(0).m_value)) + ){}} public class GlobalFunctionDefinition_2 : GlobalFunctionDefinition { public GlobalFunctionDefinition_2(Parser yyq):base(yyq, - ((Typename)(yyq.StackAt(5).m_value)) - .yytext, - ((IDENT)(yyq.StackAt(4).m_value)) - .yytext, - ((ArgumentDeclarationList)(yyq.StackAt(2).m_value)) - , - ((CompoundStatement)(yyq.StackAt(0).m_value)) - ){}} + ((Typename)(yyq.StackAt(5).m_value)) + .yytext, + ((IDENT)(yyq.StackAt(4).m_value)) + .yytext, + ((ArgumentDeclarationList)(yyq.StackAt(2).m_value)) + , + ((CompoundStatement)(yyq.StackAt(0).m_value)) + ){}} public class States_1 : States { public States_1(Parser yyq):base(yyq, - ((State)(yyq.StackAt(0).m_value)) - ){}} + ((State)(yyq.StackAt(0).m_value)) + ){}} public class States_2 : States { public States_2(Parser yyq):base(yyq, - ((States)(yyq.StackAt(1).m_value)) - , - ((State)(yyq.StackAt(0).m_value)) - ){}} + ((States)(yyq.StackAt(1).m_value)) + , + ((State)(yyq.StackAt(0).m_value)) + ){}} public class State_1 : State { public State_1(Parser yyq):base(yyq, - ((DEFAULT_STATE)(yyq.StackAt(3).m_value)) - .yytext, - ((StateBody)(yyq.StackAt(1).m_value)) - ){}} + ((DEFAULT_STATE)(yyq.StackAt(3).m_value)) + .yytext, + ((StateBody)(yyq.StackAt(1).m_value)) + ){}} public class State_2 : State { public State_2(Parser yyq):base(yyq, - ((IDENT)(yyq.StackAt(3).m_value)) - .yytext, - ((StateBody)(yyq.StackAt(1).m_value)) - ){}} + ((IDENT)(yyq.StackAt(3).m_value)) + .yytext, + ((StateBody)(yyq.StackAt(1).m_value)) + ){}} public class StateBody_1 : StateBody { public StateBody_1(Parser yyq):base(yyq, - ((StateEvent)(yyq.StackAt(0).m_value)) - ){}} + ((StateEvent)(yyq.StackAt(0).m_value)) + ){}} public class StateBody_2 : StateBody { public StateBody_2(Parser yyq):base(yyq, - ((StateBody)(yyq.StackAt(1).m_value)) - , - ((StateEvent)(yyq.StackAt(0).m_value)) - ){}} + ((StateBody)(yyq.StackAt(1).m_value)) + , + ((StateEvent)(yyq.StackAt(0).m_value)) + ){}} public class StateBody_3 : StateBody { public StateBody_3(Parser yyq):base(yyq, - ((VoidArgStateEvent)(yyq.StackAt(0).m_value)) - ){}} + ((VoidArgStateEvent)(yyq.StackAt(0).m_value)) + ){}} public class StateBody_4 : StateBody { public StateBody_4(Parser yyq):base(yyq, - ((StateBody)(yyq.StackAt(1).m_value)) - , - ((VoidArgStateEvent)(yyq.StackAt(0).m_value)) - ){}} + ((StateBody)(yyq.StackAt(1).m_value)) + , + ((VoidArgStateEvent)(yyq.StackAt(0).m_value)) + ){}} public class StateBody_5 : StateBody { public StateBody_5(Parser yyq):base(yyq, - ((KeyArgStateEvent)(yyq.StackAt(0).m_value)) - ){}} + ((KeyArgStateEvent)(yyq.StackAt(0).m_value)) + ){}} public class StateBody_6 : StateBody { public StateBody_6(Parser yyq):base(yyq, - ((StateBody)(yyq.StackAt(1).m_value)) - , - ((KeyArgStateEvent)(yyq.StackAt(0).m_value)) - ){}} + ((StateBody)(yyq.StackAt(1).m_value)) + , + ((KeyArgStateEvent)(yyq.StackAt(0).m_value)) + ){}} public class StateBody_7 : StateBody { public StateBody_7(Parser yyq):base(yyq, - ((IntArgStateEvent)(yyq.StackAt(0).m_value)) - ){}} + ((IntArgStateEvent)(yyq.StackAt(0).m_value)) + ){}} public class StateBody_8 : StateBody { public StateBody_8(Parser yyq):base(yyq, - ((StateBody)(yyq.StackAt(1).m_value)) - , - ((IntArgStateEvent)(yyq.StackAt(0).m_value)) - ){}} + ((StateBody)(yyq.StackAt(1).m_value)) + , + ((IntArgStateEvent)(yyq.StackAt(0).m_value)) + ){}} public class StateBody_9 : StateBody { public StateBody_9(Parser yyq):base(yyq, - ((VectorArgStateEvent)(yyq.StackAt(0).m_value)) - ){}} + ((VectorArgStateEvent)(yyq.StackAt(0).m_value)) + ){}} public class StateBody_10 : StateBody { public StateBody_10(Parser yyq):base(yyq, - ((StateBody)(yyq.StackAt(1).m_value)) - , - ((VectorArgStateEvent)(yyq.StackAt(0).m_value)) - ){}} + ((StateBody)(yyq.StackAt(1).m_value)) + , + ((VectorArgStateEvent)(yyq.StackAt(0).m_value)) + ){}} public class StateBody_11 : StateBody { public StateBody_11(Parser yyq):base(yyq, - ((IntRotRotArgStateEvent)(yyq.StackAt(0).m_value)) - ){}} + ((IntRotRotArgStateEvent)(yyq.StackAt(0).m_value)) + ){}} public class StateBody_12 : StateBody { public StateBody_12(Parser yyq):base(yyq, - ((StateBody)(yyq.StackAt(1).m_value)) - , - ((IntRotRotArgStateEvent)(yyq.StackAt(0).m_value)) - ){}} + ((StateBody)(yyq.StackAt(1).m_value)) + , + ((IntRotRotArgStateEvent)(yyq.StackAt(0).m_value)) + ){}} public class StateBody_13 : StateBody { public StateBody_13(Parser yyq):base(yyq, - ((IntVecVecArgStateEvent)(yyq.StackAt(0).m_value)) - ){}} + ((IntVecVecArgStateEvent)(yyq.StackAt(0).m_value)) + ){}} public class StateBody_14 : StateBody { public StateBody_14(Parser yyq):base(yyq, - ((StateBody)(yyq.StackAt(1).m_value)) - , - ((IntVecVecArgStateEvent)(yyq.StackAt(0).m_value)) - ){}} + ((StateBody)(yyq.StackAt(1).m_value)) + , + ((IntVecVecArgStateEvent)(yyq.StackAt(0).m_value)) + ){}} public class StateBody_15 : StateBody { public StateBody_15(Parser yyq):base(yyq, - ((KeyIntIntArgStateEvent)(yyq.StackAt(0).m_value)) - ){}} + ((KeyIntIntArgStateEvent)(yyq.StackAt(0).m_value)) + ){}} public class StateBody_16 : StateBody { public StateBody_16(Parser yyq):base(yyq, - ((StateBody)(yyq.StackAt(1).m_value)) - , - ((KeyIntIntArgStateEvent)(yyq.StackAt(0).m_value)) - ){}} + ((StateBody)(yyq.StackAt(1).m_value)) + , + ((KeyIntIntArgStateEvent)(yyq.StackAt(0).m_value)) + ){}} public class StateEvent_1 : StateEvent { public StateEvent_1(Parser yyq):base(yyq, - ((Event)(yyq.StackAt(4).m_value)) - .yytext, - ((ArgumentDeclarationList)(yyq.StackAt(2).m_value)) - , - ((CompoundStatement)(yyq.StackAt(0).m_value)) - ){}} + ((Event)(yyq.StackAt(4).m_value)) + .yytext, + ((ArgumentDeclarationList)(yyq.StackAt(2).m_value)) + , + ((CompoundStatement)(yyq.StackAt(0).m_value)) + ){}} public class VoidArgStateEvent_1 : VoidArgStateEvent { public VoidArgStateEvent_1(Parser yyq):base(yyq, - ((VoidArgEvent)(yyq.StackAt(3).m_value)) - .yytext, - ((CompoundStatement)(yyq.StackAt(0).m_value)) - ){}} + ((VoidArgEvent)(yyq.StackAt(3).m_value)) + .yytext, + ((CompoundStatement)(yyq.StackAt(0).m_value)) + ){}} public class KeyArgStateEvent_1 : KeyArgStateEvent { public KeyArgStateEvent_1(Parser yyq):base(yyq, - ((KeyArgEvent)(yyq.StackAt(4).m_value)) - .yytext, - ((KeyArgumentDeclarationList)(yyq.StackAt(2).m_value)) - , - ((CompoundStatement)(yyq.StackAt(0).m_value)) - ){}} + ((KeyArgEvent)(yyq.StackAt(4).m_value)) + .yytext, + ((KeyArgumentDeclarationList)(yyq.StackAt(2).m_value)) + , + ((CompoundStatement)(yyq.StackAt(0).m_value)) + ){}} public class IntArgStateEvent_1 : IntArgStateEvent { public IntArgStateEvent_1(Parser yyq):base(yyq, - ((IntArgEvent)(yyq.StackAt(4).m_value)) - .yytext, - ((IntArgumentDeclarationList)(yyq.StackAt(2).m_value)) - , - ((CompoundStatement)(yyq.StackAt(0).m_value)) - ){}} + ((IntArgEvent)(yyq.StackAt(4).m_value)) + .yytext, + ((IntArgumentDeclarationList)(yyq.StackAt(2).m_value)) + , + ((CompoundStatement)(yyq.StackAt(0).m_value)) + ){}} public class VectorArgStateEvent_1 : VectorArgStateEvent { public VectorArgStateEvent_1(Parser yyq):base(yyq, - ((VectorArgEvent)(yyq.StackAt(4).m_value)) - .yytext, - ((VectorArgumentDeclarationList)(yyq.StackAt(2).m_value)) - , - ((CompoundStatement)(yyq.StackAt(0).m_value)) - ){}} + ((VectorArgEvent)(yyq.StackAt(4).m_value)) + .yytext, + ((VectorArgumentDeclarationList)(yyq.StackAt(2).m_value)) + , + ((CompoundStatement)(yyq.StackAt(0).m_value)) + ){}} public class IntRotRotArgStateEvent_1 : IntRotRotArgStateEvent { public IntRotRotArgStateEvent_1(Parser yyq):base(yyq, - ((IntRotRotArgEvent)(yyq.StackAt(4).m_value)) - .yytext, - ((IntRotRotArgumentDeclarationList)(yyq.StackAt(2).m_value)) - , - ((CompoundStatement)(yyq.StackAt(0).m_value)) - ){}} + ((IntRotRotArgEvent)(yyq.StackAt(4).m_value)) + .yytext, + ((IntRotRotArgumentDeclarationList)(yyq.StackAt(2).m_value)) + , + ((CompoundStatement)(yyq.StackAt(0).m_value)) + ){}} public class IntVecVecArgStateEvent_1 : IntVecVecArgStateEvent { public IntVecVecArgStateEvent_1(Parser yyq):base(yyq, - ((IntVecVecArgEvent)(yyq.StackAt(4).m_value)) - .yytext, - ((IntVecVecArgumentDeclarationList)(yyq.StackAt(2).m_value)) - , - ((CompoundStatement)(yyq.StackAt(0).m_value)) - ){}} + ((IntVecVecArgEvent)(yyq.StackAt(4).m_value)) + .yytext, + ((IntVecVecArgumentDeclarationList)(yyq.StackAt(2).m_value)) + , + ((CompoundStatement)(yyq.StackAt(0).m_value)) + ){}} public class KeyIntIntArgStateEvent_1 : KeyIntIntArgStateEvent { public KeyIntIntArgStateEvent_1(Parser yyq):base(yyq, - ((KeyIntIntArgEvent)(yyq.StackAt(4).m_value)) - .yytext, - ((KeyIntIntArgumentDeclarationList)(yyq.StackAt(2).m_value)) - , - ((CompoundStatement)(yyq.StackAt(0).m_value)) - ){}} + ((KeyIntIntArgEvent)(yyq.StackAt(4).m_value)) + .yytext, + ((KeyIntIntArgumentDeclarationList)(yyq.StackAt(2).m_value)) + , + ((CompoundStatement)(yyq.StackAt(0).m_value)) + ){}} public class ArgumentDeclarationList_1 : ArgumentDeclarationList { public ArgumentDeclarationList_1(Parser yyq):base(yyq, - ((Declaration)(yyq.StackAt(0).m_value)) - ){}} + ((Declaration)(yyq.StackAt(0).m_value)) + ){}} public class ArgumentDeclarationList_2 : ArgumentDeclarationList { public ArgumentDeclarationList_2(Parser yyq):base(yyq, - ((ArgumentDeclarationList)(yyq.StackAt(2).m_value)) - , - ((Declaration)(yyq.StackAt(0).m_value)) - ){}} + ((ArgumentDeclarationList)(yyq.StackAt(2).m_value)) + , + ((Declaration)(yyq.StackAt(0).m_value)) + ){}} public class KeyArgumentDeclarationList_1 : KeyArgumentDeclarationList { public KeyArgumentDeclarationList_1(Parser yyq):base(yyq, - ((KeyDeclaration)(yyq.StackAt(0).m_value)) - ){}} + ((KeyDeclaration)(yyq.StackAt(0).m_value)) + ){}} public class IntArgumentDeclarationList_1 : IntArgumentDeclarationList { public IntArgumentDeclarationList_1(Parser yyq):base(yyq, - ((IntDeclaration)(yyq.StackAt(0).m_value)) - ){}} + ((IntDeclaration)(yyq.StackAt(0).m_value)) + ){}} public class VectorArgumentDeclarationList_1 : VectorArgumentDeclarationList { public VectorArgumentDeclarationList_1(Parser yyq):base(yyq, - ((VecDeclaration)(yyq.StackAt(0).m_value)) - ){}} + ((VecDeclaration)(yyq.StackAt(0).m_value)) + ){}} public class IntRotRotArgumentDeclarationList_1 : IntRotRotArgumentDeclarationList { public IntRotRotArgumentDeclarationList_1(Parser yyq):base(yyq, - ((IntDeclaration)(yyq.StackAt(4).m_value)) - , - ((RotDeclaration)(yyq.StackAt(2).m_value)) - , - ((RotDeclaration)(yyq.StackAt(0).m_value)) - ){}} + ((IntDeclaration)(yyq.StackAt(4).m_value)) + , + ((RotDeclaration)(yyq.StackAt(2).m_value)) + , + ((RotDeclaration)(yyq.StackAt(0).m_value)) + ){}} public class IntVecVecArgumentDeclarationList_1 : IntVecVecArgumentDeclarationList { public IntVecVecArgumentDeclarationList_1(Parser yyq):base(yyq, - ((IntDeclaration)(yyq.StackAt(4).m_value)) - , - ((VecDeclaration)(yyq.StackAt(2).m_value)) - , - ((VecDeclaration)(yyq.StackAt(0).m_value)) - ){}} + ((IntDeclaration)(yyq.StackAt(4).m_value)) + , + ((VecDeclaration)(yyq.StackAt(2).m_value)) + , + ((VecDeclaration)(yyq.StackAt(0).m_value)) + ){}} public class KeyIntIntArgumentDeclarationList_1 : KeyIntIntArgumentDeclarationList { public KeyIntIntArgumentDeclarationList_1(Parser yyq):base(yyq, - ((KeyDeclaration)(yyq.StackAt(4).m_value)) - , - ((IntDeclaration)(yyq.StackAt(2).m_value)) - , - ((IntDeclaration)(yyq.StackAt(0).m_value)) - ){}} + ((KeyDeclaration)(yyq.StackAt(4).m_value)) + , + ((IntDeclaration)(yyq.StackAt(2).m_value)) + , + ((IntDeclaration)(yyq.StackAt(0).m_value)) + ){}} public class Declaration_1 : Declaration { public Declaration_1(Parser yyq):base(yyq, - ((Typename)(yyq.StackAt(1).m_value)) - .yytext, - ((IDENT)(yyq.StackAt(0).m_value)) - .yytext){}} + ((Typename)(yyq.StackAt(1).m_value)) + .yytext, + ((IDENT)(yyq.StackAt(0).m_value)) + .yytext){}} public class KeyDeclaration_1 : KeyDeclaration { public KeyDeclaration_1(Parser yyq):base(yyq, - ((KEY_TYPE)(yyq.StackAt(1).m_value)) - .yytext, - ((IDENT)(yyq.StackAt(0).m_value)) - .yytext){}} + ((KEY_TYPE)(yyq.StackAt(1).m_value)) + .yytext, + ((IDENT)(yyq.StackAt(0).m_value)) + .yytext){}} public class IntDeclaration_1 : IntDeclaration { public IntDeclaration_1(Parser yyq):base(yyq, - ((INTEGER_TYPE)(yyq.StackAt(1).m_value)) - .yytext, - ((IDENT)(yyq.StackAt(0).m_value)) - .yytext){}} + ((INTEGER_TYPE)(yyq.StackAt(1).m_value)) + .yytext, + ((IDENT)(yyq.StackAt(0).m_value)) + .yytext){}} public class VecDeclaration_1 : VecDeclaration { public VecDeclaration_1(Parser yyq):base(yyq, - ((VECTOR_TYPE)(yyq.StackAt(1).m_value)) - .yytext, - ((IDENT)(yyq.StackAt(0).m_value)) - .yytext){}} + ((VECTOR_TYPE)(yyq.StackAt(1).m_value)) + .yytext, + ((IDENT)(yyq.StackAt(0).m_value)) + .yytext){}} public class RotDeclaration_1 : RotDeclaration { public RotDeclaration_1(Parser yyq):base(yyq, - ((ROTATION_TYPE)(yyq.StackAt(1).m_value)) - .yytext, - ((IDENT)(yyq.StackAt(0).m_value)) - .yytext){}} + ((ROTATION_TYPE)(yyq.StackAt(1).m_value)) + .yytext, + ((IDENT)(yyq.StackAt(0).m_value)) + .yytext){}} public class CompoundStatement_1 : CompoundStatement { public CompoundStatement_1(Parser yyq):base(yyq){}} public class CompoundStatement_2 : CompoundStatement { public CompoundStatement_2(Parser yyq):base(yyq, - ((StatementList)(yyq.StackAt(1).m_value)) - ){}} + ((StatementList)(yyq.StackAt(1).m_value)) + ){}} public class StatementList_1 : StatementList { public StatementList_1(Parser yyq):base(yyq, - ((Statement)(yyq.StackAt(0).m_value)) - ){}} + ((Statement)(yyq.StackAt(0).m_value)) + ){}} public class StatementList_2 : StatementList { public StatementList_2(Parser yyq):base(yyq, - ((StatementList)(yyq.StackAt(1).m_value)) - , - ((Statement)(yyq.StackAt(0).m_value)) - ){}} + ((StatementList)(yyq.StackAt(1).m_value)) + , + ((Statement)(yyq.StackAt(0).m_value)) + ){}} public class EmptyStatement_1 : EmptyStatement { public EmptyStatement_1(Parser yyq):base(yyq){}} public class Statement_1 : Statement { public Statement_1(Parser yyq):base(yyq, - ((EmptyStatement)(yyq.StackAt(1).m_value)) - ){}} + ((EmptyStatement)(yyq.StackAt(1).m_value)) + ){}} public class Statement_2 : Statement { public Statement_2(Parser yyq):base(yyq, - ((Declaration)(yyq.StackAt(1).m_value)) - ){}} + ((Declaration)(yyq.StackAt(1).m_value)) + ){}} public class Statement_3 : Statement { public Statement_3(Parser yyq):base(yyq, - ((Assignment)(yyq.StackAt(1).m_value)) - ){}} + ((Assignment)(yyq.StackAt(1).m_value)) + ){}} public class Statement_4 : Statement { public Statement_4(Parser yyq):base(yyq, - ((Expression)(yyq.StackAt(1).m_value)) - ){}} + ((Expression)(yyq.StackAt(1).m_value)) + ){}} public class Statement_5 : Statement { public Statement_5(Parser yyq):base(yyq, - ((ReturnStatement)(yyq.StackAt(1).m_value)) - ){}} + ((ReturnStatement)(yyq.StackAt(1).m_value)) + ){}} public class Statement_6 : Statement { public Statement_6(Parser yyq):base(yyq, - ((JumpLabel)(yyq.StackAt(1).m_value)) - ){}} + ((JumpLabel)(yyq.StackAt(1).m_value)) + ){}} public class Statement_7 : Statement { public Statement_7(Parser yyq):base(yyq, - ((JumpStatement)(yyq.StackAt(1).m_value)) - ){}} + ((JumpStatement)(yyq.StackAt(1).m_value)) + ){}} public class Statement_8 : Statement { public Statement_8(Parser yyq):base(yyq, - ((StateChange)(yyq.StackAt(1).m_value)) - ){}} + ((StateChange)(yyq.StackAt(1).m_value)) + ){}} public class Statement_9 : Statement { public Statement_9(Parser yyq):base(yyq, - ((IfStatement)(yyq.StackAt(0).m_value)) - ){}} + ((IfStatement)(yyq.StackAt(0).m_value)) + ){}} public class Statement_10 : Statement { public Statement_10(Parser yyq):base(yyq, - ((WhileStatement)(yyq.StackAt(0).m_value)) - ){}} + ((WhileStatement)(yyq.StackAt(0).m_value)) + ){}} public class Statement_11 : Statement { public Statement_11(Parser yyq):base(yyq, - ((DoWhileStatement)(yyq.StackAt(0).m_value)) - ){}} + ((DoWhileStatement)(yyq.StackAt(0).m_value)) + ){}} public class Statement_12 : Statement { public Statement_12(Parser yyq):base(yyq, - ((ForLoop)(yyq.StackAt(0).m_value)) - ){}} + ((ForLoop)(yyq.StackAt(0).m_value)) + ){}} public class Statement_13 : Statement { public Statement_13(Parser yyq):base(yyq, - ((CompoundStatement)(yyq.StackAt(0).m_value)) - ){}} + ((CompoundStatement)(yyq.StackAt(0).m_value)) + ){}} public class JumpLabel_1 : JumpLabel { public JumpLabel_1(Parser yyq):base(yyq, - ((IDENT)(yyq.StackAt(0).m_value)) - .yytext){}} + ((IDENT)(yyq.StackAt(0).m_value)) + .yytext){}} public class JumpStatement_1 : JumpStatement { public JumpStatement_1(Parser yyq):base(yyq, - ((IDENT)(yyq.StackAt(0).m_value)) - .yytext){}} + ((IDENT)(yyq.StackAt(0).m_value)) + .yytext){}} public class StateChange_1 : StateChange { public StateChange_1(Parser yyq):base(yyq, - ((IDENT)(yyq.StackAt(0).m_value)) - .yytext){}} + ((IDENT)(yyq.StackAt(0).m_value)) + .yytext){}} public class StateChange_2 : StateChange { public StateChange_2(Parser yyq):base(yyq, - ((DEFAULT_STATE)(yyq.StackAt(0).m_value)) - .yytext){}} + ((DEFAULT_STATE)(yyq.StackAt(0).m_value)) + .yytext){}} public class IfStatement_1 : IfStatement { public IfStatement_1(Parser yyq):base(yyq, - ((Expression)(yyq.StackAt(2).m_value)) - , - ((Statement)(yyq.StackAt(0).m_value)) - ){}} + ((Expression)(yyq.StackAt(2).m_value)) + , + ((Statement)(yyq.StackAt(0).m_value)) + ){}} public class IfStatement_2 : IfStatement { public IfStatement_2(Parser yyq):base(yyq, - ((Expression)(yyq.StackAt(4).m_value)) - , - ((Statement)(yyq.StackAt(2).m_value)) - , - ((Statement)(yyq.StackAt(0).m_value)) - ){}} + ((Expression)(yyq.StackAt(4).m_value)) + , + ((Statement)(yyq.StackAt(2).m_value)) + , + ((Statement)(yyq.StackAt(0).m_value)) + ){}} public class IfStatement_3 : IfStatement { public IfStatement_3(Parser yyq):base(yyq, - ((SimpleAssignment)(yyq.StackAt(2).m_value)) - , - ((Statement)(yyq.StackAt(0).m_value)) - ){}} + ((SimpleAssignment)(yyq.StackAt(2).m_value)) + , + ((Statement)(yyq.StackAt(0).m_value)) + ){}} public class IfStatement_4 : IfStatement { public IfStatement_4(Parser yyq):base(yyq, - ((SimpleAssignment)(yyq.StackAt(4).m_value)) - , - ((Statement)(yyq.StackAt(2).m_value)) - , - ((Statement)(yyq.StackAt(0).m_value)) - ){}} + ((SimpleAssignment)(yyq.StackAt(4).m_value)) + , + ((Statement)(yyq.StackAt(2).m_value)) + , + ((Statement)(yyq.StackAt(0).m_value)) + ){}} public class WhileStatement_1 : WhileStatement { public WhileStatement_1(Parser yyq):base(yyq, - ((Expression)(yyq.StackAt(2).m_value)) - , - ((Statement)(yyq.StackAt(0).m_value)) - ){}} + ((Expression)(yyq.StackAt(2).m_value)) + , + ((Statement)(yyq.StackAt(0).m_value)) + ){}} public class WhileStatement_2 : WhileStatement { public WhileStatement_2(Parser yyq):base(yyq, - ((SimpleAssignment)(yyq.StackAt(2).m_value)) - , - ((Statement)(yyq.StackAt(0).m_value)) - ){}} + ((SimpleAssignment)(yyq.StackAt(2).m_value)) + , + ((Statement)(yyq.StackAt(0).m_value)) + ){}} public class DoWhileStatement_1 : DoWhileStatement { public DoWhileStatement_1(Parser yyq):base(yyq, - ((Expression)(yyq.StackAt(2).m_value)) - , - ((Statement)(yyq.StackAt(5).m_value)) - ){}} + ((Expression)(yyq.StackAt(2).m_value)) + , + ((Statement)(yyq.StackAt(5).m_value)) + ){}} public class DoWhileStatement_2 : DoWhileStatement { public DoWhileStatement_2(Parser yyq):base(yyq, - ((SimpleAssignment)(yyq.StackAt(2).m_value)) - , - ((Statement)(yyq.StackAt(5).m_value)) - ){}} + ((SimpleAssignment)(yyq.StackAt(2).m_value)) + , + ((Statement)(yyq.StackAt(5).m_value)) + ){}} public class ForLoop_1 : ForLoop { public ForLoop_1(Parser yyq):base(yyq, - ((ForLoopStatement)(yyq.StackAt(6).m_value)) - , - ((Expression)(yyq.StackAt(4).m_value)) - , - ((ForLoopStatement)(yyq.StackAt(2).m_value)) - , - ((Statement)(yyq.StackAt(0).m_value)) - ){}} + ((ForLoopStatement)(yyq.StackAt(6).m_value)) + , + ((Expression)(yyq.StackAt(4).m_value)) + , + ((ForLoopStatement)(yyq.StackAt(2).m_value)) + , + ((Statement)(yyq.StackAt(0).m_value)) + ){}} public class ForLoop_2 : ForLoop { - public ForLoop_2(Parser yyq):base(yyq,null, - ((Expression)(yyq.StackAt(4).m_value)) - , - ((ForLoopStatement)(yyq.StackAt(2).m_value)) - , - ((Statement)(yyq.StackAt(0).m_value)) - ){}} + public ForLoop_2(Parser yyq):base(yyq,null, + ((Expression)(yyq.StackAt(4).m_value)) + , + ((ForLoopStatement)(yyq.StackAt(2).m_value)) + , + ((Statement)(yyq.StackAt(0).m_value)) + ){}} public class ForLoopStatement_1 : ForLoopStatement { public ForLoopStatement_1(Parser yyq):base(yyq, - ((Expression)(yyq.StackAt(0).m_value)) - ){}} + ((Expression)(yyq.StackAt(0).m_value)) + ){}} public class ForLoopStatement_2 : ForLoopStatement { public ForLoopStatement_2(Parser yyq):base(yyq, - ((SimpleAssignment)(yyq.StackAt(0).m_value)) - ){}} + ((SimpleAssignment)(yyq.StackAt(0).m_value)) + ){}} public class ForLoopStatement_3 : ForLoopStatement { public ForLoopStatement_3(Parser yyq):base(yyq, - ((ForLoopStatement)(yyq.StackAt(2).m_value)) - , - ((Expression)(yyq.StackAt(0).m_value)) - ){}} + ((ForLoopStatement)(yyq.StackAt(2).m_value)) + , + ((Expression)(yyq.StackAt(0).m_value)) + ){}} public class ForLoopStatement_4 : ForLoopStatement { public ForLoopStatement_4(Parser yyq):base(yyq, - ((ForLoopStatement)(yyq.StackAt(2).m_value)) - , - ((SimpleAssignment)(yyq.StackAt(0).m_value)) - ){}} + ((ForLoopStatement)(yyq.StackAt(2).m_value)) + , + ((SimpleAssignment)(yyq.StackAt(0).m_value)) + ){}} public class Assignment_1 : Assignment { public Assignment_1(Parser yyq):base(yyq, - ((Declaration)(yyq.StackAt(2).m_value)) - , - ((Expression)(yyq.StackAt(0).m_value)) - , - ((EQUALS)(yyq.StackAt(1).m_value)) - .yytext){}} + ((Declaration)(yyq.StackAt(2).m_value)) + , + ((Expression)(yyq.StackAt(0).m_value)) + , + ((EQUALS)(yyq.StackAt(1).m_value)) + .yytext){}} public class Assignment_2 : Assignment { public Assignment_2(Parser yyq):base(yyq, - ((SimpleAssignment)(yyq.StackAt(0).m_value)) - ){}} + ((SimpleAssignment)(yyq.StackAt(0).m_value)) + ){}} public class SimpleAssignment_1 : SimpleAssignment { public SimpleAssignment_1(Parser yyq):base(yyq, - ((IDENT)(yyq.StackAt(2).m_value)) - , - ((Expression)(yyq.StackAt(0).m_value)) - , - ((EQUALS)(yyq.StackAt(1).m_value)) - .yytext){}} + ((IDENT)(yyq.StackAt(2).m_value)) + , + ((Expression)(yyq.StackAt(0).m_value)) + , + ((EQUALS)(yyq.StackAt(1).m_value)) + .yytext){}} public class SimpleAssignment_2 : SimpleAssignment { public SimpleAssignment_2(Parser yyq):base(yyq, - ((IDENT)(yyq.StackAt(2).m_value)) - , - ((Expression)(yyq.StackAt(0).m_value)) - , - ((PLUS_EQUALS)(yyq.StackAt(1).m_value)) - .yytext){}} + ((IDENT)(yyq.StackAt(2).m_value)) + , + ((Expression)(yyq.StackAt(0).m_value)) + , + ((PLUS_EQUALS)(yyq.StackAt(1).m_value)) + .yytext){}} public class SimpleAssignment_3 : SimpleAssignment { public SimpleAssignment_3(Parser yyq):base(yyq, - ((IDENT)(yyq.StackAt(2).m_value)) - , - ((Expression)(yyq.StackAt(0).m_value)) - , - ((MINUS_EQUALS)(yyq.StackAt(1).m_value)) - .yytext){}} + ((IDENT)(yyq.StackAt(2).m_value)) + , + ((Expression)(yyq.StackAt(0).m_value)) + , + ((MINUS_EQUALS)(yyq.StackAt(1).m_value)) + .yytext){}} public class SimpleAssignment_4 : SimpleAssignment { public SimpleAssignment_4(Parser yyq):base(yyq, - ((IDENT)(yyq.StackAt(2).m_value)) - , - ((Expression)(yyq.StackAt(0).m_value)) - , - ((STAR_EQUALS)(yyq.StackAt(1).m_value)) - .yytext){}} + ((IDENT)(yyq.StackAt(2).m_value)) + , + ((Expression)(yyq.StackAt(0).m_value)) + , + ((STAR_EQUALS)(yyq.StackAt(1).m_value)) + .yytext){}} public class SimpleAssignment_5 : SimpleAssignment { public SimpleAssignment_5(Parser yyq):base(yyq, - ((IDENT)(yyq.StackAt(2).m_value)) - , - ((Expression)(yyq.StackAt(0).m_value)) - , - ((SLASH_EQUALS)(yyq.StackAt(1).m_value)) - .yytext){}} + ((IDENT)(yyq.StackAt(2).m_value)) + , + ((Expression)(yyq.StackAt(0).m_value)) + , + ((SLASH_EQUALS)(yyq.StackAt(1).m_value)) + .yytext){}} public class SimpleAssignment_6 : SimpleAssignment { public SimpleAssignment_6(Parser yyq):base(yyq, - ((IDENT)(yyq.StackAt(2).m_value)) - , - ((Expression)(yyq.StackAt(0).m_value)) - , - ((PERCENT_EQUALS)(yyq.StackAt(1).m_value)) - .yytext){}} + ((IDENT)(yyq.StackAt(2).m_value)) + , + ((Expression)(yyq.StackAt(0).m_value)) + , + ((PERCENT_EQUALS)(yyq.StackAt(1).m_value)) + .yytext){}} public class SimpleAssignment_7 : SimpleAssignment { public SimpleAssignment_7(Parser yyq):base(yyq,new IdentDotExpression(((LSLSyntax -)yyq), - ((IDENT)(yyq.StackAt(4).m_value)) - .yytext, - ((IDENT)(yyq.StackAt(2).m_value)) - .yytext), - ((Expression)(yyq.StackAt(0).m_value)) - , - ((EQUALS)(yyq.StackAt(1).m_value)) - .yytext){}} +)yyq), + ((IDENT)(yyq.StackAt(4).m_value)) + .yytext, + ((IDENT)(yyq.StackAt(2).m_value)) + .yytext), + ((Expression)(yyq.StackAt(0).m_value)) + , + ((EQUALS)(yyq.StackAt(1).m_value)) + .yytext){}} public class SimpleAssignment_8 : SimpleAssignment { public SimpleAssignment_8(Parser yyq):base(yyq,new IdentDotExpression(((LSLSyntax -)yyq), - ((IDENT)(yyq.StackAt(4).m_value)) - .yytext, - ((IDENT)(yyq.StackAt(2).m_value)) - .yytext), - ((Expression)(yyq.StackAt(0).m_value)) - , - ((PLUS_EQUALS)(yyq.StackAt(1).m_value)) - .yytext){}} +)yyq), + ((IDENT)(yyq.StackAt(4).m_value)) + .yytext, + ((IDENT)(yyq.StackAt(2).m_value)) + .yytext), + ((Expression)(yyq.StackAt(0).m_value)) + , + ((PLUS_EQUALS)(yyq.StackAt(1).m_value)) + .yytext){}} public class SimpleAssignment_9 : SimpleAssignment { public SimpleAssignment_9(Parser yyq):base(yyq,new IdentDotExpression(((LSLSyntax -)yyq), - ((IDENT)(yyq.StackAt(4).m_value)) - .yytext, - ((IDENT)(yyq.StackAt(2).m_value)) - .yytext), - ((Expression)(yyq.StackAt(0).m_value)) - , - ((MINUS_EQUALS)(yyq.StackAt(1).m_value)) - .yytext){}} +)yyq), + ((IDENT)(yyq.StackAt(4).m_value)) + .yytext, + ((IDENT)(yyq.StackAt(2).m_value)) + .yytext), + ((Expression)(yyq.StackAt(0).m_value)) + , + ((MINUS_EQUALS)(yyq.StackAt(1).m_value)) + .yytext){}} public class SimpleAssignment_10 : SimpleAssignment { public SimpleAssignment_10(Parser yyq):base(yyq,new IdentDotExpression(((LSLSyntax -)yyq), - ((IDENT)(yyq.StackAt(4).m_value)) - .yytext, - ((IDENT)(yyq.StackAt(2).m_value)) - .yytext), - ((Expression)(yyq.StackAt(0).m_value)) - , - ((STAR_EQUALS)(yyq.StackAt(1).m_value)) - .yytext){}} +)yyq), + ((IDENT)(yyq.StackAt(4).m_value)) + .yytext, + ((IDENT)(yyq.StackAt(2).m_value)) + .yytext), + ((Expression)(yyq.StackAt(0).m_value)) + , + ((STAR_EQUALS)(yyq.StackAt(1).m_value)) + .yytext){}} public class SimpleAssignment_11 : SimpleAssignment { public SimpleAssignment_11(Parser yyq):base(yyq,new IdentDotExpression(((LSLSyntax -)yyq), - ((IDENT)(yyq.StackAt(4).m_value)) - .yytext, - ((IDENT)(yyq.StackAt(2).m_value)) - .yytext), - ((Expression)(yyq.StackAt(0).m_value)) - , - ((SLASH_EQUALS)(yyq.StackAt(1).m_value)) - .yytext){}} +)yyq), + ((IDENT)(yyq.StackAt(4).m_value)) + .yytext, + ((IDENT)(yyq.StackAt(2).m_value)) + .yytext), + ((Expression)(yyq.StackAt(0).m_value)) + , + ((SLASH_EQUALS)(yyq.StackAt(1).m_value)) + .yytext){}} public class SimpleAssignment_12 : SimpleAssignment { public SimpleAssignment_12(Parser yyq):base(yyq,new IdentDotExpression(((LSLSyntax -)yyq), - ((IDENT)(yyq.StackAt(4).m_value)) - .yytext, - ((IDENT)(yyq.StackAt(2).m_value)) - .yytext), - ((Expression)(yyq.StackAt(0).m_value)) - , - ((PERCENT_EQUALS)(yyq.StackAt(1).m_value)) - .yytext){}} +)yyq), + ((IDENT)(yyq.StackAt(4).m_value)) + .yytext, + ((IDENT)(yyq.StackAt(2).m_value)) + .yytext), + ((Expression)(yyq.StackAt(0).m_value)) + , + ((PERCENT_EQUALS)(yyq.StackAt(1).m_value)) + .yytext){}} public class SimpleAssignment_13 : SimpleAssignment { public SimpleAssignment_13(Parser yyq):base(yyq, - ((IDENT)(yyq.StackAt(2).m_value)) - , - ((SimpleAssignment)(yyq.StackAt(0).m_value)) - , - ((EQUALS)(yyq.StackAt(1).m_value)) - .yytext){}} + ((IDENT)(yyq.StackAt(2).m_value)) + , + ((SimpleAssignment)(yyq.StackAt(0).m_value)) + , + ((EQUALS)(yyq.StackAt(1).m_value)) + .yytext){}} public class SimpleAssignment_14 : SimpleAssignment { public SimpleAssignment_14(Parser yyq):base(yyq, - ((IDENT)(yyq.StackAt(2).m_value)) - , - ((SimpleAssignment)(yyq.StackAt(0).m_value)) - , - ((PLUS_EQUALS)(yyq.StackAt(1).m_value)) - .yytext){}} + ((IDENT)(yyq.StackAt(2).m_value)) + , + ((SimpleAssignment)(yyq.StackAt(0).m_value)) + , + ((PLUS_EQUALS)(yyq.StackAt(1).m_value)) + .yytext){}} public class SimpleAssignment_15 : SimpleAssignment { public SimpleAssignment_15(Parser yyq):base(yyq, - ((IDENT)(yyq.StackAt(2).m_value)) - , - ((SimpleAssignment)(yyq.StackAt(0).m_value)) - , - ((MINUS_EQUALS)(yyq.StackAt(1).m_value)) - .yytext){}} + ((IDENT)(yyq.StackAt(2).m_value)) + , + ((SimpleAssignment)(yyq.StackAt(0).m_value)) + , + ((MINUS_EQUALS)(yyq.StackAt(1).m_value)) + .yytext){}} public class SimpleAssignment_16 : SimpleAssignment { public SimpleAssignment_16(Parser yyq):base(yyq, - ((IDENT)(yyq.StackAt(2).m_value)) - , - ((SimpleAssignment)(yyq.StackAt(0).m_value)) - , - ((STAR_EQUALS)(yyq.StackAt(1).m_value)) - .yytext){}} + ((IDENT)(yyq.StackAt(2).m_value)) + , + ((SimpleAssignment)(yyq.StackAt(0).m_value)) + , + ((STAR_EQUALS)(yyq.StackAt(1).m_value)) + .yytext){}} public class SimpleAssignment_17 : SimpleAssignment { public SimpleAssignment_17(Parser yyq):base(yyq, - ((IDENT)(yyq.StackAt(2).m_value)) - , - ((SimpleAssignment)(yyq.StackAt(0).m_value)) - , - ((SLASH_EQUALS)(yyq.StackAt(1).m_value)) - .yytext){}} + ((IDENT)(yyq.StackAt(2).m_value)) + , + ((SimpleAssignment)(yyq.StackAt(0).m_value)) + , + ((SLASH_EQUALS)(yyq.StackAt(1).m_value)) + .yytext){}} public class SimpleAssignment_18 : SimpleAssignment { public SimpleAssignment_18(Parser yyq):base(yyq, - ((IDENT)(yyq.StackAt(2).m_value)) - , - ((SimpleAssignment)(yyq.StackAt(0).m_value)) - , - ((PERCENT_EQUALS)(yyq.StackAt(1).m_value)) - .yytext){}} + ((IDENT)(yyq.StackAt(2).m_value)) + , + ((SimpleAssignment)(yyq.StackAt(0).m_value)) + , + ((PERCENT_EQUALS)(yyq.StackAt(1).m_value)) + .yytext){}} public class SimpleAssignment_19 : SimpleAssignment { public SimpleAssignment_19(Parser yyq):base(yyq,new IdentDotExpression(((LSLSyntax -)yyq), - ((IDENT)(yyq.StackAt(4).m_value)) - .yytext, - ((IDENT)(yyq.StackAt(2).m_value)) - .yytext), - ((SimpleAssignment)(yyq.StackAt(0).m_value)) - , - ((EQUALS)(yyq.StackAt(1).m_value)) - .yytext){}} +)yyq), + ((IDENT)(yyq.StackAt(4).m_value)) + .yytext, + ((IDENT)(yyq.StackAt(2).m_value)) + .yytext), + ((SimpleAssignment)(yyq.StackAt(0).m_value)) + , + ((EQUALS)(yyq.StackAt(1).m_value)) + .yytext){}} public class SimpleAssignment_20 : SimpleAssignment { public SimpleAssignment_20(Parser yyq):base(yyq,new IdentDotExpression(((LSLSyntax -)yyq), - ((IDENT)(yyq.StackAt(4).m_value)) - .yytext, - ((IDENT)(yyq.StackAt(2).m_value)) - .yytext), - ((SimpleAssignment)(yyq.StackAt(0).m_value)) - , - ((PLUS_EQUALS)(yyq.StackAt(1).m_value)) - .yytext){}} +)yyq), + ((IDENT)(yyq.StackAt(4).m_value)) + .yytext, + ((IDENT)(yyq.StackAt(2).m_value)) + .yytext), + ((SimpleAssignment)(yyq.StackAt(0).m_value)) + , + ((PLUS_EQUALS)(yyq.StackAt(1).m_value)) + .yytext){}} public class SimpleAssignment_21 : SimpleAssignment { public SimpleAssignment_21(Parser yyq):base(yyq,new IdentDotExpression(((LSLSyntax -)yyq), - ((IDENT)(yyq.StackAt(4).m_value)) - .yytext, - ((IDENT)(yyq.StackAt(2).m_value)) - .yytext), - ((SimpleAssignment)(yyq.StackAt(0).m_value)) - , - ((MINUS_EQUALS)(yyq.StackAt(1).m_value)) - .yytext){}} +)yyq), + ((IDENT)(yyq.StackAt(4).m_value)) + .yytext, + ((IDENT)(yyq.StackAt(2).m_value)) + .yytext), + ((SimpleAssignment)(yyq.StackAt(0).m_value)) + , + ((MINUS_EQUALS)(yyq.StackAt(1).m_value)) + .yytext){}} public class SimpleAssignment_22 : SimpleAssignment { public SimpleAssignment_22(Parser yyq):base(yyq,new IdentDotExpression(((LSLSyntax -)yyq), - ((IDENT)(yyq.StackAt(4).m_value)) - .yytext, - ((IDENT)(yyq.StackAt(2).m_value)) - .yytext), - ((SimpleAssignment)(yyq.StackAt(0).m_value)) - , - ((STAR_EQUALS)(yyq.StackAt(1).m_value)) - .yytext){}} +)yyq), + ((IDENT)(yyq.StackAt(4).m_value)) + .yytext, + ((IDENT)(yyq.StackAt(2).m_value)) + .yytext), + ((SimpleAssignment)(yyq.StackAt(0).m_value)) + , + ((STAR_EQUALS)(yyq.StackAt(1).m_value)) + .yytext){}} public class SimpleAssignment_23 : SimpleAssignment { public SimpleAssignment_23(Parser yyq):base(yyq,new IdentDotExpression(((LSLSyntax -)yyq), - ((IDENT)(yyq.StackAt(4).m_value)) - .yytext, - ((IDENT)(yyq.StackAt(2).m_value)) - .yytext), - ((SimpleAssignment)(yyq.StackAt(0).m_value)) - , - ((SLASH_EQUALS)(yyq.StackAt(1).m_value)) - .yytext){}} +)yyq), + ((IDENT)(yyq.StackAt(4).m_value)) + .yytext, + ((IDENT)(yyq.StackAt(2).m_value)) + .yytext), + ((SimpleAssignment)(yyq.StackAt(0).m_value)) + , + ((SLASH_EQUALS)(yyq.StackAt(1).m_value)) + .yytext){}} public class SimpleAssignment_24 : SimpleAssignment { public SimpleAssignment_24(Parser yyq):base(yyq,new IdentDotExpression(((LSLSyntax -)yyq), - ((IDENT)(yyq.StackAt(4).m_value)) - .yytext, - ((IDENT)(yyq.StackAt(2).m_value)) - .yytext), - ((SimpleAssignment)(yyq.StackAt(0).m_value)) - , - ((PERCENT_EQUALS)(yyq.StackAt(1).m_value)) - .yytext){}} +)yyq), + ((IDENT)(yyq.StackAt(4).m_value)) + .yytext, + ((IDENT)(yyq.StackAt(2).m_value)) + .yytext), + ((SimpleAssignment)(yyq.StackAt(0).m_value)) + , + ((PERCENT_EQUALS)(yyq.StackAt(1).m_value)) + .yytext){}} public class ReturnStatement_1 : ReturnStatement { public ReturnStatement_1(Parser yyq):base(yyq, - ((Expression)(yyq.StackAt(0).m_value)) - ){}} + ((Expression)(yyq.StackAt(0).m_value)) + ){}} public class ReturnStatement_2 : ReturnStatement { public ReturnStatement_2(Parser yyq):base(yyq){}} public class Constant_1 : Constant { - public Constant_1(Parser yyq):base(yyq,"integer", - ((INTEGER_CONSTANT)(yyq.StackAt(0).m_value)) - .yytext){}} + public Constant_1(Parser yyq):base(yyq,"integer", + ((INTEGER_CONSTANT)(yyq.StackAt(0).m_value)) + .yytext){}} public class Constant_2 : Constant { - public Constant_2(Parser yyq):base(yyq,"integer", - ((HEX_INTEGER_CONSTANT)(yyq.StackAt(0).m_value)) - .yytext){}} + public Constant_2(Parser yyq):base(yyq,"integer", + ((HEX_INTEGER_CONSTANT)(yyq.StackAt(0).m_value)) + .yytext){}} public class Constant_3 : Constant { - public Constant_3(Parser yyq):base(yyq,"float", - ((FLOAT_CONSTANT)(yyq.StackAt(0).m_value)) - .yytext){}} + public Constant_3(Parser yyq):base(yyq,"float", + ((FLOAT_CONSTANT)(yyq.StackAt(0).m_value)) + .yytext){}} public class Constant_4 : Constant { - public Constant_4(Parser yyq):base(yyq,"string", - ((STRING_CONSTANT)(yyq.StackAt(0).m_value)) - .yytext){}} + public Constant_4(Parser yyq):base(yyq,"string", + ((STRING_CONSTANT)(yyq.StackAt(0).m_value)) + .yytext){}} public class ListConstant_1 : ListConstant { public ListConstant_1(Parser yyq):base(yyq, - ((ArgumentList)(yyq.StackAt(1).m_value)) - ){}} + ((ArgumentList)(yyq.StackAt(1).m_value)) + ){}} public class VectorConstant_1 : VectorConstant { public VectorConstant_1(Parser yyq):base(yyq, - ((Expression)(yyq.StackAt(5).m_value)) - , - ((Expression)(yyq.StackAt(3).m_value)) - , - ((Expression)(yyq.StackAt(1).m_value)) - ){}} + ((Expression)(yyq.StackAt(5).m_value)) + , + ((Expression)(yyq.StackAt(3).m_value)) + , + ((Expression)(yyq.StackAt(1).m_value)) + ){}} public class RotationConstant_1 : RotationConstant { public RotationConstant_1(Parser yyq):base(yyq, - ((Expression)(yyq.StackAt(7).m_value)) - , - ((Expression)(yyq.StackAt(5).m_value)) - , - ((Expression)(yyq.StackAt(3).m_value)) - , - ((Expression)(yyq.StackAt(1).m_value)) - ){}} + ((Expression)(yyq.StackAt(7).m_value)) + , + ((Expression)(yyq.StackAt(5).m_value)) + , + ((Expression)(yyq.StackAt(3).m_value)) + , + ((Expression)(yyq.StackAt(1).m_value)) + ){}} public class ConstantExpression_1 : ConstantExpression { public ConstantExpression_1(Parser yyq):base(yyq, - ((Constant)(yyq.StackAt(0).m_value)) - ){}} + ((Constant)(yyq.StackAt(0).m_value)) + ){}} public class IdentExpression_1 : IdentExpression { public IdentExpression_1(Parser yyq):base(yyq, - ((IDENT)(yyq.StackAt(0).m_value)) - .yytext){}} + ((IDENT)(yyq.StackAt(0).m_value)) + .yytext){}} public class IdentDotExpression_1 : IdentDotExpression { public IdentDotExpression_1(Parser yyq):base(yyq, - ((IDENT)(yyq.StackAt(2).m_value)) - .yytext, - ((IDENT)(yyq.StackAt(0).m_value)) - .yytext){}} + ((IDENT)(yyq.StackAt(2).m_value)) + .yytext, + ((IDENT)(yyq.StackAt(0).m_value)) + .yytext){}} public class IncrementDecrementExpression_1 : IncrementDecrementExpression { public IncrementDecrementExpression_1(Parser yyq):base(yyq, - ((IDENT)(yyq.StackAt(1).m_value)) - .yytext, - ((INCREMENT)(yyq.StackAt(0).m_value)) - .yytext, true){}} + ((IDENT)(yyq.StackAt(1).m_value)) + .yytext, + ((INCREMENT)(yyq.StackAt(0).m_value)) + .yytext, true){}} public class IncrementDecrementExpression_2 : IncrementDecrementExpression { public IncrementDecrementExpression_2(Parser yyq):base(yyq, - ((IDENT)(yyq.StackAt(1).m_value)) - .yytext, - ((DECREMENT)(yyq.StackAt(0).m_value)) - .yytext, true){}} + ((IDENT)(yyq.StackAt(1).m_value)) + .yytext, + ((DECREMENT)(yyq.StackAt(0).m_value)) + .yytext, true){}} public class IncrementDecrementExpression_3 : IncrementDecrementExpression { public IncrementDecrementExpression_3(Parser yyq):base(yyq,new IdentDotExpression(((LSLSyntax -)yyq), - ((IDENT)(yyq.StackAt(3).m_value)) - .yytext, - ((IDENT)(yyq.StackAt(1).m_value)) - .yytext), - ((INCREMENT)(yyq.StackAt(0).m_value)) - .yytext, true){}} +)yyq), + ((IDENT)(yyq.StackAt(3).m_value)) + .yytext, + ((IDENT)(yyq.StackAt(1).m_value)) + .yytext), + ((INCREMENT)(yyq.StackAt(0).m_value)) + .yytext, true){}} public class IncrementDecrementExpression_4 : IncrementDecrementExpression { public IncrementDecrementExpression_4(Parser yyq):base(yyq,new IdentDotExpression(((LSLSyntax -)yyq), - ((IDENT)(yyq.StackAt(3).m_value)) - .yytext, - ((IDENT)(yyq.StackAt(1).m_value)) - .yytext), - ((DECREMENT)(yyq.StackAt(0).m_value)) - .yytext, true){}} +)yyq), + ((IDENT)(yyq.StackAt(3).m_value)) + .yytext, + ((IDENT)(yyq.StackAt(1).m_value)) + .yytext), + ((DECREMENT)(yyq.StackAt(0).m_value)) + .yytext, true){}} public class IncrementDecrementExpression_5 : IncrementDecrementExpression { public IncrementDecrementExpression_5(Parser yyq):base(yyq, - ((IDENT)(yyq.StackAt(0).m_value)) - .yytext, - ((INCREMENT)(yyq.StackAt(1).m_value)) - .yytext, false){}} + ((IDENT)(yyq.StackAt(0).m_value)) + .yytext, + ((INCREMENT)(yyq.StackAt(1).m_value)) + .yytext, false){}} public class IncrementDecrementExpression_6 : IncrementDecrementExpression { public IncrementDecrementExpression_6(Parser yyq):base(yyq, - ((IDENT)(yyq.StackAt(0).m_value)) - .yytext, - ((DECREMENT)(yyq.StackAt(1).m_value)) - .yytext, false){}} + ((IDENT)(yyq.StackAt(0).m_value)) + .yytext, + ((DECREMENT)(yyq.StackAt(1).m_value)) + .yytext, false){}} public class IncrementDecrementExpression_7 : IncrementDecrementExpression { public IncrementDecrementExpression_7(Parser yyq):base(yyq,new IdentDotExpression(((LSLSyntax -)yyq), - ((IDENT)(yyq.StackAt(2).m_value)) - .yytext, - ((IDENT)(yyq.StackAt(0).m_value)) - .yytext), - ((INCREMENT)(yyq.StackAt(3).m_value)) - .yytext, false){}} +)yyq), + ((IDENT)(yyq.StackAt(2).m_value)) + .yytext, + ((IDENT)(yyq.StackAt(0).m_value)) + .yytext), + ((INCREMENT)(yyq.StackAt(3).m_value)) + .yytext, false){}} public class IncrementDecrementExpression_8 : IncrementDecrementExpression { public IncrementDecrementExpression_8(Parser yyq):base(yyq,new IdentDotExpression(((LSLSyntax -)yyq), - ((IDENT)(yyq.StackAt(2).m_value)) - .yytext, - ((IDENT)(yyq.StackAt(0).m_value)) - .yytext), - ((DECREMENT)(yyq.StackAt(3).m_value)) - .yytext, false){}} +)yyq), + ((IDENT)(yyq.StackAt(2).m_value)) + .yytext, + ((IDENT)(yyq.StackAt(0).m_value)) + .yytext), + ((DECREMENT)(yyq.StackAt(3).m_value)) + .yytext, false){}} public class FunctionCallExpression_1 : FunctionCallExpression { public FunctionCallExpression_1(Parser yyq):base(yyq, - ((FunctionCall)(yyq.StackAt(0).m_value)) - ){}} + ((FunctionCall)(yyq.StackAt(0).m_value)) + ){}} public class BinaryExpression_1 : BinaryExpression { public BinaryExpression_1(Parser yyq):base(yyq, - ((Expression)(yyq.StackAt(2).m_value)) - , - ((Expression)(yyq.StackAt(0).m_value)) - , - ((PLUS)(yyq.StackAt(1).m_value)) - .yytext){}} + ((Expression)(yyq.StackAt(2).m_value)) + , + ((Expression)(yyq.StackAt(0).m_value)) + , + ((PLUS)(yyq.StackAt(1).m_value)) + .yytext){}} public class BinaryExpression_2 : BinaryExpression { public BinaryExpression_2(Parser yyq):base(yyq, - ((Expression)(yyq.StackAt(2).m_value)) - , - ((Expression)(yyq.StackAt(0).m_value)) - , - ((MINUS)(yyq.StackAt(1).m_value)) - .yytext){}} + ((Expression)(yyq.StackAt(2).m_value)) + , + ((Expression)(yyq.StackAt(0).m_value)) + , + ((MINUS)(yyq.StackAt(1).m_value)) + .yytext){}} public class BinaryExpression_3 : BinaryExpression { public BinaryExpression_3(Parser yyq):base(yyq, - ((Expression)(yyq.StackAt(2).m_value)) - , - ((Expression)(yyq.StackAt(0).m_value)) - , - ((STAR)(yyq.StackAt(1).m_value)) - .yytext){}} + ((Expression)(yyq.StackAt(2).m_value)) + , + ((Expression)(yyq.StackAt(0).m_value)) + , + ((STAR)(yyq.StackAt(1).m_value)) + .yytext){}} public class BinaryExpression_4 : BinaryExpression { public BinaryExpression_4(Parser yyq):base(yyq, - ((Expression)(yyq.StackAt(2).m_value)) - , - ((Expression)(yyq.StackAt(0).m_value)) - , - ((SLASH)(yyq.StackAt(1).m_value)) - .yytext){}} + ((Expression)(yyq.StackAt(2).m_value)) + , + ((Expression)(yyq.StackAt(0).m_value)) + , + ((SLASH)(yyq.StackAt(1).m_value)) + .yytext){}} public class BinaryExpression_5 : BinaryExpression { public BinaryExpression_5(Parser yyq):base(yyq, - ((Expression)(yyq.StackAt(2).m_value)) - , - ((Expression)(yyq.StackAt(0).m_value)) - , - ((PERCENT)(yyq.StackAt(1).m_value)) - .yytext){}} + ((Expression)(yyq.StackAt(2).m_value)) + , + ((Expression)(yyq.StackAt(0).m_value)) + , + ((PERCENT)(yyq.StackAt(1).m_value)) + .yytext){}} public class BinaryExpression_6 : BinaryExpression { public BinaryExpression_6(Parser yyq):base(yyq, - ((Expression)(yyq.StackAt(2).m_value)) - , - ((Expression)(yyq.StackAt(0).m_value)) - , - ((AMP)(yyq.StackAt(1).m_value)) - .yytext){}} + ((Expression)(yyq.StackAt(2).m_value)) + , + ((Expression)(yyq.StackAt(0).m_value)) + , + ((AMP)(yyq.StackAt(1).m_value)) + .yytext){}} public class BinaryExpression_7 : BinaryExpression { public BinaryExpression_7(Parser yyq):base(yyq, - ((Expression)(yyq.StackAt(2).m_value)) - , - ((Expression)(yyq.StackAt(0).m_value)) - , - ((STROKE)(yyq.StackAt(1).m_value)) - .yytext){}} + ((Expression)(yyq.StackAt(2).m_value)) + , + ((Expression)(yyq.StackAt(0).m_value)) + , + ((STROKE)(yyq.StackAt(1).m_value)) + .yytext){}} public class BinaryExpression_8 : BinaryExpression { public BinaryExpression_8(Parser yyq):base(yyq, - ((Expression)(yyq.StackAt(2).m_value)) - , - ((Expression)(yyq.StackAt(0).m_value)) - , - ((CARET)(yyq.StackAt(1).m_value)) - .yytext){}} + ((Expression)(yyq.StackAt(2).m_value)) + , + ((Expression)(yyq.StackAt(0).m_value)) + , + ((CARET)(yyq.StackAt(1).m_value)) + .yytext){}} public class BinaryExpression_9 : BinaryExpression { public BinaryExpression_9(Parser yyq):base(yyq, - ((Expression)(yyq.StackAt(2).m_value)) - , - ((Expression)(yyq.StackAt(0).m_value)) - , - ((RIGHT_ANGLE)(yyq.StackAt(1).m_value)) - .yytext){}} + ((Expression)(yyq.StackAt(2).m_value)) + , + ((Expression)(yyq.StackAt(0).m_value)) + , + ((RIGHT_ANGLE)(yyq.StackAt(1).m_value)) + .yytext){}} public class BinaryExpression_10 : BinaryExpression { public BinaryExpression_10(Parser yyq):base(yyq, - ((Expression)(yyq.StackAt(2).m_value)) - , - ((Expression)(yyq.StackAt(0).m_value)) - , - ((LEFT_ANGLE)(yyq.StackAt(1).m_value)) - .yytext){}} + ((Expression)(yyq.StackAt(2).m_value)) + , + ((Expression)(yyq.StackAt(0).m_value)) + , + ((LEFT_ANGLE)(yyq.StackAt(1).m_value)) + .yytext){}} public class BinaryExpression_11 : BinaryExpression { public BinaryExpression_11(Parser yyq):base(yyq, - ((Expression)(yyq.StackAt(2).m_value)) - , - ((Expression)(yyq.StackAt(0).m_value)) - , - ((EQUALS_EQUALS)(yyq.StackAt(1).m_value)) - .yytext){}} + ((Expression)(yyq.StackAt(2).m_value)) + , + ((Expression)(yyq.StackAt(0).m_value)) + , + ((EQUALS_EQUALS)(yyq.StackAt(1).m_value)) + .yytext){}} public class BinaryExpression_12 : BinaryExpression { public BinaryExpression_12(Parser yyq):base(yyq, - ((Expression)(yyq.StackAt(2).m_value)) - , - ((Expression)(yyq.StackAt(0).m_value)) - , - ((EXCLAMATION_EQUALS)(yyq.StackAt(1).m_value)) - .yytext){}} + ((Expression)(yyq.StackAt(2).m_value)) + , + ((Expression)(yyq.StackAt(0).m_value)) + , + ((EXCLAMATION_EQUALS)(yyq.StackAt(1).m_value)) + .yytext){}} public class BinaryExpression_13 : BinaryExpression { public BinaryExpression_13(Parser yyq):base(yyq, - ((Expression)(yyq.StackAt(2).m_value)) - , - ((Expression)(yyq.StackAt(0).m_value)) - , - ((LESS_EQUALS)(yyq.StackAt(1).m_value)) - .yytext){}} + ((Expression)(yyq.StackAt(2).m_value)) + , + ((Expression)(yyq.StackAt(0).m_value)) + , + ((LESS_EQUALS)(yyq.StackAt(1).m_value)) + .yytext){}} public class BinaryExpression_14 : BinaryExpression { public BinaryExpression_14(Parser yyq):base(yyq, - ((Expression)(yyq.StackAt(2).m_value)) - , - ((Expression)(yyq.StackAt(0).m_value)) - , - ((GREATER_EQUALS)(yyq.StackAt(1).m_value)) - .yytext){}} + ((Expression)(yyq.StackAt(2).m_value)) + , + ((Expression)(yyq.StackAt(0).m_value)) + , + ((GREATER_EQUALS)(yyq.StackAt(1).m_value)) + .yytext){}} public class BinaryExpression_15 : BinaryExpression { public BinaryExpression_15(Parser yyq):base(yyq, - ((Expression)(yyq.StackAt(2).m_value)) - , - ((Expression)(yyq.StackAt(0).m_value)) - , - ((AMP_AMP)(yyq.StackAt(1).m_value)) - .yytext){}} + ((Expression)(yyq.StackAt(2).m_value)) + , + ((Expression)(yyq.StackAt(0).m_value)) + , + ((AMP_AMP)(yyq.StackAt(1).m_value)) + .yytext){}} public class BinaryExpression_16 : BinaryExpression { public BinaryExpression_16(Parser yyq):base(yyq, - ((Expression)(yyq.StackAt(2).m_value)) - , - ((Expression)(yyq.StackAt(0).m_value)) - , - ((STROKE_STROKE)(yyq.StackAt(1).m_value)) - .yytext){}} + ((Expression)(yyq.StackAt(2).m_value)) + , + ((Expression)(yyq.StackAt(0).m_value)) + , + ((STROKE_STROKE)(yyq.StackAt(1).m_value)) + .yytext){}} public class BinaryExpression_17 : BinaryExpression { public BinaryExpression_17(Parser yyq):base(yyq, - ((Expression)(yyq.StackAt(2).m_value)) - , - ((Expression)(yyq.StackAt(0).m_value)) - , - ((LEFT_SHIFT)(yyq.StackAt(1).m_value)) - .yytext){}} + ((Expression)(yyq.StackAt(2).m_value)) + , + ((Expression)(yyq.StackAt(0).m_value)) + , + ((LEFT_SHIFT)(yyq.StackAt(1).m_value)) + .yytext){}} public class BinaryExpression_18 : BinaryExpression { public BinaryExpression_18(Parser yyq):base(yyq, - ((Expression)(yyq.StackAt(2).m_value)) - , - ((Expression)(yyq.StackAt(0).m_value)) - , - ((RIGHT_SHIFT)(yyq.StackAt(1).m_value)) - .yytext){}} + ((Expression)(yyq.StackAt(2).m_value)) + , + ((Expression)(yyq.StackAt(0).m_value)) + , + ((RIGHT_SHIFT)(yyq.StackAt(1).m_value)) + .yytext){}} public class UnaryExpression_1 : UnaryExpression { public UnaryExpression_1(Parser yyq):base(yyq, - ((EXCLAMATION)(yyq.StackAt(1).m_value)) - .yytext, - ((Expression)(yyq.StackAt(0).m_value)) - ){}} + ((EXCLAMATION)(yyq.StackAt(1).m_value)) + .yytext, + ((Expression)(yyq.StackAt(0).m_value)) + ){}} public class UnaryExpression_2 : UnaryExpression { public UnaryExpression_2(Parser yyq):base(yyq, - ((MINUS)(yyq.StackAt(1).m_value)) - .yytext, - ((Expression)(yyq.StackAt(0).m_value)) - ){}} + ((MINUS)(yyq.StackAt(1).m_value)) + .yytext, + ((Expression)(yyq.StackAt(0).m_value)) + ){}} public class UnaryExpression_3 : UnaryExpression { public UnaryExpression_3(Parser yyq):base(yyq, - ((TILDE)(yyq.StackAt(1).m_value)) - .yytext, - ((Expression)(yyq.StackAt(0).m_value)) - ){}} + ((TILDE)(yyq.StackAt(1).m_value)) + .yytext, + ((Expression)(yyq.StackAt(0).m_value)) + ){}} public class ParenthesisExpression_1 : ParenthesisExpression { public ParenthesisExpression_1(Parser yyq):base(yyq, - ((Expression)(yyq.StackAt(1).m_value)) - ){}} + ((Expression)(yyq.StackAt(1).m_value)) + ){}} public class ParenthesisExpression_2 : ParenthesisExpression { public ParenthesisExpression_2(Parser yyq):base(yyq, - ((SimpleAssignment)(yyq.StackAt(1).m_value)) - ){}} + ((SimpleAssignment)(yyq.StackAt(1).m_value)) + ){}} public class TypecastExpression_1 : TypecastExpression { public TypecastExpression_1(Parser yyq):base(yyq, - ((Typename)(yyq.StackAt(2).m_value)) - .yytext, - ((Constant)(yyq.StackAt(0).m_value)) - ){}} + ((Typename)(yyq.StackAt(2).m_value)) + .yytext, + ((Constant)(yyq.StackAt(0).m_value)) + ){}} public class TypecastExpression_2 : TypecastExpression { public TypecastExpression_2(Parser yyq):base(yyq, - ((Typename)(yyq.StackAt(2).m_value)) - .yytext, new IdentExpression(((LSLSyntax -)yyq), - ((IDENT)(yyq.StackAt(0).m_value)) - .yytext)){}} + ((Typename)(yyq.StackAt(2).m_value)) + .yytext, new IdentExpression(((LSLSyntax +)yyq), + ((IDENT)(yyq.StackAt(0).m_value)) + .yytext)){}} public class TypecastExpression_3 : TypecastExpression { public TypecastExpression_3(Parser yyq):base(yyq, - ((Typename)(yyq.StackAt(4).m_value)) - .yytext, new IdentDotExpression(((LSLSyntax -)yyq), - ((IDENT)(yyq.StackAt(2).m_value)) - .yytext, - ((IDENT)(yyq.StackAt(0).m_value)) - .yytext)){}} + ((Typename)(yyq.StackAt(4).m_value)) + .yytext, new IdentDotExpression(((LSLSyntax +)yyq), + ((IDENT)(yyq.StackAt(2).m_value)) + .yytext, + ((IDENT)(yyq.StackAt(0).m_value)) + .yytext)){}} public class TypecastExpression_4 : TypecastExpression { public TypecastExpression_4(Parser yyq):base(yyq, - ((Typename)(yyq.StackAt(3).m_value)) - .yytext, new IncrementDecrementExpression(((LSLSyntax -)yyq), - ((IDENT)(yyq.StackAt(1).m_value)) - .yytext, - ((INCREMENT)(yyq.StackAt(0).m_value)) - .yytext, true)){}} + ((Typename)(yyq.StackAt(3).m_value)) + .yytext, new IncrementDecrementExpression(((LSLSyntax +)yyq), + ((IDENT)(yyq.StackAt(1).m_value)) + .yytext, + ((INCREMENT)(yyq.StackAt(0).m_value)) + .yytext, true)){}} public class TypecastExpression_5 : TypecastExpression { public TypecastExpression_5(Parser yyq):base(yyq, - ((Typename)(yyq.StackAt(5).m_value)) - .yytext, new IncrementDecrementExpression(((LSLSyntax + ((Typename)(yyq.StackAt(5).m_value)) + .yytext, new IncrementDecrementExpression(((LSLSyntax )yyq), new IdentDotExpression(((LSLSyntax -)yyq), - ((IDENT)(yyq.StackAt(3).m_value)) - .yytext, - ((IDENT)(yyq.StackAt(1).m_value)) - .yytext), - ((INCREMENT)(yyq.StackAt(0).m_value)) - .yytext, true)){}} +)yyq), + ((IDENT)(yyq.StackAt(3).m_value)) + .yytext, + ((IDENT)(yyq.StackAt(1).m_value)) + .yytext), + ((INCREMENT)(yyq.StackAt(0).m_value)) + .yytext, true)){}} public class TypecastExpression_6 : TypecastExpression { public TypecastExpression_6(Parser yyq):base(yyq, - ((Typename)(yyq.StackAt(3).m_value)) - .yytext, new IncrementDecrementExpression(((LSLSyntax -)yyq), - ((IDENT)(yyq.StackAt(1).m_value)) - .yytext, - ((DECREMENT)(yyq.StackAt(0).m_value)) - .yytext, true)){}} + ((Typename)(yyq.StackAt(3).m_value)) + .yytext, new IncrementDecrementExpression(((LSLSyntax +)yyq), + ((IDENT)(yyq.StackAt(1).m_value)) + .yytext, + ((DECREMENT)(yyq.StackAt(0).m_value)) + .yytext, true)){}} public class TypecastExpression_7 : TypecastExpression { public TypecastExpression_7(Parser yyq):base(yyq, - ((Typename)(yyq.StackAt(5).m_value)) - .yytext, new IncrementDecrementExpression(((LSLSyntax + ((Typename)(yyq.StackAt(5).m_value)) + .yytext, new IncrementDecrementExpression(((LSLSyntax )yyq), new IdentDotExpression(((LSLSyntax -)yyq), - ((IDENT)(yyq.StackAt(3).m_value)) - .yytext, - ((IDENT)(yyq.StackAt(1).m_value)) - .yytext), - ((DECREMENT)(yyq.StackAt(0).m_value)) - .yytext, true)){}} +)yyq), + ((IDENT)(yyq.StackAt(3).m_value)) + .yytext, + ((IDENT)(yyq.StackAt(1).m_value)) + .yytext), + ((DECREMENT)(yyq.StackAt(0).m_value)) + .yytext, true)){}} public class TypecastExpression_8 : TypecastExpression { public TypecastExpression_8(Parser yyq):base(yyq, - ((Typename)(yyq.StackAt(2).m_value)) - .yytext, - ((FunctionCall)(yyq.StackAt(0).m_value)) - ){}} + ((Typename)(yyq.StackAt(2).m_value)) + .yytext, + ((FunctionCall)(yyq.StackAt(0).m_value)) + ){}} public class TypecastExpression_9 : TypecastExpression { public TypecastExpression_9(Parser yyq):base(yyq, - ((Typename)(yyq.StackAt(4).m_value)) - .yytext, - ((Expression)(yyq.StackAt(1).m_value)) - ){}} + ((Typename)(yyq.StackAt(4).m_value)) + .yytext, + ((Expression)(yyq.StackAt(1).m_value)) + ){}} public class FunctionCall_1 : FunctionCall { public FunctionCall_1(Parser yyq):base(yyq, - ((IDENT)(yyq.StackAt(3).m_value)) - .yytext, - ((ArgumentList)(yyq.StackAt(1).m_value)) - ){}} + ((IDENT)(yyq.StackAt(3).m_value)) + .yytext, + ((ArgumentList)(yyq.StackAt(1).m_value)) + ){}} public class ArgumentList_1 : ArgumentList { public ArgumentList_1(Parser yyq):base(yyq, - ((Argument)(yyq.StackAt(0).m_value)) - ){}} + ((Argument)(yyq.StackAt(0).m_value)) + ){}} public class ArgumentList_2 : ArgumentList { public ArgumentList_2(Parser yyq):base(yyq, - ((ArgumentList)(yyq.StackAt(2).m_value)) - , - ((Argument)(yyq.StackAt(0).m_value)) - ){}} + ((ArgumentList)(yyq.StackAt(2).m_value)) + , + ((Argument)(yyq.StackAt(0).m_value)) + ){}} public class ExpressionArgument_1 : ExpressionArgument { public ExpressionArgument_1(Parser yyq):base(yyq, - ((Expression)(yyq.StackAt(0).m_value)) - ){}} + ((Expression)(yyq.StackAt(0).m_value)) + ){}} public class Typename_1 : Typename { public Typename_1(Parser yyq):base(yyq, - ((INTEGER_TYPE)(yyq.StackAt(0).m_value)) - .yytext){}} + ((INTEGER_TYPE)(yyq.StackAt(0).m_value)) + .yytext){}} public class Typename_2 : Typename { public Typename_2(Parser yyq):base(yyq, - ((FLOAT_TYPE)(yyq.StackAt(0).m_value)) - .yytext){}} + ((FLOAT_TYPE)(yyq.StackAt(0).m_value)) + .yytext){}} public class Typename_3 : Typename { public Typename_3(Parser yyq):base(yyq, - ((STRING_TYPE)(yyq.StackAt(0).m_value)) - .yytext){}} + ((STRING_TYPE)(yyq.StackAt(0).m_value)) + .yytext){}} public class Typename_4 : Typename { public Typename_4(Parser yyq):base(yyq, - ((KEY_TYPE)(yyq.StackAt(0).m_value)) - .yytext){}} + ((KEY_TYPE)(yyq.StackAt(0).m_value)) + .yytext){}} public class Typename_5 : Typename { public Typename_5(Parser yyq):base(yyq, - ((VECTOR_TYPE)(yyq.StackAt(0).m_value)) - .yytext){}} + ((VECTOR_TYPE)(yyq.StackAt(0).m_value)) + .yytext){}} public class Typename_6 : Typename { public Typename_6(Parser yyq):base(yyq, - ((ROTATION_TYPE)(yyq.StackAt(0).m_value)) - .yytext){}} + ((ROTATION_TYPE)(yyq.StackAt(0).m_value)) + .yytext){}} public class Typename_7 : Typename { public Typename_7(Parser yyq):base(yyq, - ((LIST_TYPE)(yyq.StackAt(0).m_value)) - .yytext){}} + ((LIST_TYPE)(yyq.StackAt(0).m_value)) + .yytext){}} public class Event_1 : Event { public Event_1(Parser yyq):base(yyq, - ((DATASERVER_EVENT)(yyq.StackAt(0).m_value)) - .yytext){}} + ((DATASERVER_EVENT)(yyq.StackAt(0).m_value)) + .yytext){}} public class Event_2 : Event { public Event_2(Parser yyq):base(yyq, - ((EMAIL_EVENT)(yyq.StackAt(0).m_value)) - .yytext){}} + ((EMAIL_EVENT)(yyq.StackAt(0).m_value)) + .yytext){}} public class Event_3 : Event { public Event_3(Parser yyq):base(yyq, - ((HTTP_RESPONSE_EVENT)(yyq.StackAt(0).m_value)) - .yytext){}} + ((HTTP_RESPONSE_EVENT)(yyq.StackAt(0).m_value)) + .yytext){}} public class Event_4 : Event { public Event_4(Parser yyq):base(yyq, - ((LINK_MESSAGE_EVENT)(yyq.StackAt(0).m_value)) - .yytext){}} + ((LINK_MESSAGE_EVENT)(yyq.StackAt(0).m_value)) + .yytext){}} public class Event_5 : Event { public Event_5(Parser yyq):base(yyq, - ((LISTEN_EVENT)(yyq.StackAt(0).m_value)) - .yytext){}} + ((LISTEN_EVENT)(yyq.StackAt(0).m_value)) + .yytext){}} public class Event_6 : Event { public Event_6(Parser yyq):base(yyq, - ((MONEY_EVENT)(yyq.StackAt(0).m_value)) - .yytext){}} + ((MONEY_EVENT)(yyq.StackAt(0).m_value)) + .yytext){}} public class Event_7 : Event { public Event_7(Parser yyq):base(yyq, - ((REMOTE_DATA_EVENT)(yyq.StackAt(0).m_value)) - .yytext){}} + ((REMOTE_DATA_EVENT)(yyq.StackAt(0).m_value)) + .yytext){}} public class Event_8 : Event { public Event_8(Parser yyq):base(yyq, - ((HTTP_REQUEST_EVENT)(yyq.StackAt(0).m_value)) - .yytext){}} + ((HTTP_REQUEST_EVENT)(yyq.StackAt(0).m_value)) + .yytext){}} public class Event_9 : Event { public Event_9(Parser yyq):base(yyq, - ((TRANSACTION_RESULT_EVENT)(yyq.StackAt(0).m_value)) - .yytext){}} + ((TRANSACTION_RESULT_EVENT)(yyq.StackAt(0).m_value)) + .yytext){}} public class VoidArgEvent_1 : VoidArgEvent { public VoidArgEvent_1(Parser yyq):base(yyq, - ((STATE_ENTRY_EVENT)(yyq.StackAt(0).m_value)) - .yytext){}} + ((STATE_ENTRY_EVENT)(yyq.StackAt(0).m_value)) + .yytext){}} public class VoidArgEvent_2 : VoidArgEvent { public VoidArgEvent_2(Parser yyq):base(yyq, - ((STATE_EXIT_EVENT)(yyq.StackAt(0).m_value)) - .yytext){}} + ((STATE_EXIT_EVENT)(yyq.StackAt(0).m_value)) + .yytext){}} public class VoidArgEvent_3 : VoidArgEvent { public VoidArgEvent_3(Parser yyq):base(yyq, - ((MOVING_END_EVENT)(yyq.StackAt(0).m_value)) - .yytext){}} + ((MOVING_END_EVENT)(yyq.StackAt(0).m_value)) + .yytext){}} public class VoidArgEvent_4 : VoidArgEvent { public VoidArgEvent_4(Parser yyq):base(yyq, - ((MOVING_START_EVENT)(yyq.StackAt(0).m_value)) - .yytext){}} + ((MOVING_START_EVENT)(yyq.StackAt(0).m_value)) + .yytext){}} public class VoidArgEvent_5 : VoidArgEvent { public VoidArgEvent_5(Parser yyq):base(yyq, - ((NO_SENSOR_EVENT)(yyq.StackAt(0).m_value)) - .yytext){}} + ((NO_SENSOR_EVENT)(yyq.StackAt(0).m_value)) + .yytext){}} public class VoidArgEvent_6 : VoidArgEvent { public VoidArgEvent_6(Parser yyq):base(yyq, - ((NOT_AT_ROT_TARGET_EVENT)(yyq.StackAt(0).m_value)) - .yytext){}} + ((NOT_AT_ROT_TARGET_EVENT)(yyq.StackAt(0).m_value)) + .yytext){}} public class VoidArgEvent_7 : VoidArgEvent { public VoidArgEvent_7(Parser yyq):base(yyq, - ((NOT_AT_TARGET_EVENT)(yyq.StackAt(0).m_value)) - .yytext){}} + ((NOT_AT_TARGET_EVENT)(yyq.StackAt(0).m_value)) + .yytext){}} public class VoidArgEvent_8 : VoidArgEvent { public VoidArgEvent_8(Parser yyq):base(yyq, - ((TIMER_EVENT)(yyq.StackAt(0).m_value)) - .yytext){}} + ((TIMER_EVENT)(yyq.StackAt(0).m_value)) + .yytext){}} public class KeyArgEvent_1 : KeyArgEvent { public KeyArgEvent_1(Parser yyq):base(yyq, - ((ATTACH_EVENT)(yyq.StackAt(0).m_value)) - .yytext){}} + ((ATTACH_EVENT)(yyq.StackAt(0).m_value)) + .yytext){}} public class KeyArgEvent_2 : KeyArgEvent { public KeyArgEvent_2(Parser yyq):base(yyq, - ((OBJECT_REZ_EVENT)(yyq.StackAt(0).m_value)) - .yytext){}} + ((OBJECT_REZ_EVENT)(yyq.StackAt(0).m_value)) + .yytext){}} public class IntArgEvent_1 : IntArgEvent { public IntArgEvent_1(Parser yyq):base(yyq, - ((CHANGED_EVENT)(yyq.StackAt(0).m_value)) - .yytext){}} + ((CHANGED_EVENT)(yyq.StackAt(0).m_value)) + .yytext){}} public class IntArgEvent_2 : IntArgEvent { public IntArgEvent_2(Parser yyq):base(yyq, - ((COLLISION_EVENT)(yyq.StackAt(0).m_value)) - .yytext){}} + ((COLLISION_EVENT)(yyq.StackAt(0).m_value)) + .yytext){}} public class IntArgEvent_3 : IntArgEvent { public IntArgEvent_3(Parser yyq):base(yyq, - ((COLLISION_END_EVENT)(yyq.StackAt(0).m_value)) - .yytext){}} + ((COLLISION_END_EVENT)(yyq.StackAt(0).m_value)) + .yytext){}} public class IntArgEvent_4 : IntArgEvent { public IntArgEvent_4(Parser yyq):base(yyq, - ((COLLISION_START_EVENT)(yyq.StackAt(0).m_value)) - .yytext){}} + ((COLLISION_START_EVENT)(yyq.StackAt(0).m_value)) + .yytext){}} public class IntArgEvent_5 : IntArgEvent { public IntArgEvent_5(Parser yyq):base(yyq, - ((ON_REZ_EVENT)(yyq.StackAt(0).m_value)) - .yytext){}} + ((ON_REZ_EVENT)(yyq.StackAt(0).m_value)) + .yytext){}} public class IntArgEvent_6 : IntArgEvent { public IntArgEvent_6(Parser yyq):base(yyq, - ((RUN_TIME_PERMISSIONS_EVENT)(yyq.StackAt(0).m_value)) - .yytext){}} + ((RUN_TIME_PERMISSIONS_EVENT)(yyq.StackAt(0).m_value)) + .yytext){}} public class IntArgEvent_7 : IntArgEvent { public IntArgEvent_7(Parser yyq):base(yyq, - ((SENSOR_EVENT)(yyq.StackAt(0).m_value)) - .yytext){}} + ((SENSOR_EVENT)(yyq.StackAt(0).m_value)) + .yytext){}} public class IntArgEvent_8 : IntArgEvent { public IntArgEvent_8(Parser yyq):base(yyq, - ((TOUCH_EVENT)(yyq.StackAt(0).m_value)) - .yytext){}} + ((TOUCH_EVENT)(yyq.StackAt(0).m_value)) + .yytext){}} public class IntArgEvent_9 : IntArgEvent { public IntArgEvent_9(Parser yyq):base(yyq, - ((TOUCH_END_EVENT)(yyq.StackAt(0).m_value)) - .yytext){}} + ((TOUCH_END_EVENT)(yyq.StackAt(0).m_value)) + .yytext){}} public class IntArgEvent_10 : IntArgEvent { public IntArgEvent_10(Parser yyq):base(yyq, - ((TOUCH_START_EVENT)(yyq.StackAt(0).m_value)) - .yytext){}} + ((TOUCH_START_EVENT)(yyq.StackAt(0).m_value)) + .yytext){}} public class VectorArgEvent_1 : VectorArgEvent { public VectorArgEvent_1(Parser yyq):base(yyq, - ((LAND_COLLISION_EVENT)(yyq.StackAt(0).m_value)) - .yytext){}} + ((LAND_COLLISION_EVENT)(yyq.StackAt(0).m_value)) + .yytext){}} public class VectorArgEvent_2 : VectorArgEvent { public VectorArgEvent_2(Parser yyq):base(yyq, - ((LAND_COLLISION_END_EVENT)(yyq.StackAt(0).m_value)) - .yytext){}} + ((LAND_COLLISION_END_EVENT)(yyq.StackAt(0).m_value)) + .yytext){}} public class VectorArgEvent_3 : VectorArgEvent { public VectorArgEvent_3(Parser yyq):base(yyq, - ((LAND_COLLISION_START_EVENT)(yyq.StackAt(0).m_value)) - .yytext){}} + ((LAND_COLLISION_START_EVENT)(yyq.StackAt(0).m_value)) + .yytext){}} public class IntRotRotArgEvent_1 : IntRotRotArgEvent { public IntRotRotArgEvent_1(Parser yyq):base(yyq, - ((AT_ROT_TARGET_EVENT)(yyq.StackAt(0).m_value)) - .yytext){}} + ((AT_ROT_TARGET_EVENT)(yyq.StackAt(0).m_value)) + .yytext){}} public class IntVecVecArgEvent_1 : IntVecVecArgEvent { public IntVecVecArgEvent_1(Parser yyq):base(yyq, - ((AT_TARGET_EVENT)(yyq.StackAt(0).m_value)) - .yytext){}} + ((AT_TARGET_EVENT)(yyq.StackAt(0).m_value)) + .yytext){}} public class KeyIntIntArgEvent_1 : KeyIntIntArgEvent { public KeyIntIntArgEvent_1(Parser yyq):base(yyq, - ((CONTROL_EVENT)(yyq.StackAt(0).m_value)) - .yytext){}} + ((CONTROL_EVENT)(yyq.StackAt(0).m_value)) + .yytext){}} public class yyLSLSyntax : YyParser { public override object Action(Parser yyq,SYMBOL yysym, int yyact) { switch(yyact) { - case -1: break; //// keep compiler happy + case -1: break; //// keep compiler happy } return null; } public class ArgumentDeclarationList_3 : ArgumentDeclarationList { @@ -2390,7 +2390,7 @@ public class ArgumentDeclarationList_4 : ArgumentDeclarationList { public class ArgumentDeclarationList_5 : ArgumentDeclarationList { public ArgumentDeclarationList_5(Parser yyq):base(yyq){}} public yyLSLSyntax -():base() { arr = new int[] { +():base() { arr = new int[] { 101,4,6,52,0, 46,0,53,0,102, 20,103,4,28,76, @@ -2402,133 +2402,198 @@ public yyLSLSyntax 116,0,1,97,1, 2,104,18,1,2845, 102,2,0,105,5, -395,1,0,106,18, -1,0,0,2,0, -1,1,107,18,1, -1,108,20,109,4, -18,76,0,73,0, -83,0,84,0,95, -0,84,0,89,0, -80,0,69,0,1, -57,1,1,2,0, -1,2,110,18,1, -2,111,20,112,4, -26,82,0,79,0, -84,0,65,0,84, -0,73,0,79,0, -78,0,95,0,84, -0,89,0,80,0, -69,0,1,56,1, -1,2,0,1,3, -113,18,1,3,114, -20,115,4,22,86, -0,69,0,67,0, -84,0,79,0,82, -0,95,0,84,0, -89,0,80,0,69, -0,1,55,1,1, -2,0,1,4,116, -18,1,4,117,20, -118,4,16,75,0, -69,0,89,0,95, -0,84,0,89,0, -80,0,69,0,1, -54,1,1,2,0, -1,5,119,18,1, -5,120,20,121,4, -22,83,0,84,0, -82,0,73,0,78, -0,71,0,95,0, -84,0,89,0,80, -0,69,0,1,53, -1,1,2,0,1, -6,122,18,1,6, -123,20,124,4,20, -70,0,76,0,79, -0,65,0,84,0, -95,0,84,0,89, -0,80,0,69,0, -1,52,1,1,2, -0,1,7,125,18, -1,7,126,20,127, -4,24,73,0,78, -0,84,0,69,0, -71,0,69,0,82, -0,95,0,84,0, -89,0,80,0,69, -0,1,51,1,1, -2,0,1,8,128, -18,1,8,129,20, -130,4,16,84,0, -121,0,112,0,101, -0,110,0,97,0, -109,0,101,0,1, -124,1,2,2,0, -1,9,131,18,1, -9,132,20,133,4, -10,73,0,68,0, -69,0,78,0,84, -0,1,93,1,1, -2,0,1,10,134, -18,1,10,135,20, -136,4,20,76,0, -69,0,70,0,84, -0,95,0,80,0, -65,0,82,0,69, -0,78,0,1,16, -1,1,2,0,1, -18,137,18,1,18, -129,2,0,1,19, -138,18,1,19,132, -2,0,1,20,139, -18,1,20,140,20, -141,4,46,65,0, -114,0,103,0,117, +395,1,1224,106,18, +1,1224,107,20,108, +4,32,83,0,105, +0,109,0,112,0, +108,0,101,0,65, +0,115,0,115,0, +105,0,103,0,110, 0,109,0,101,0, -110,0,116,0,68, -0,101,0,99,0, -108,0,97,0,114, -0,97,0,116,0, -105,0,111,0,110, -0,76,0,105,0, -115,0,116,0,1, -112,1,2,2,0, -1,21,142,18,1, -21,143,20,144,4, -10,67,0,79,0, -77,0,77,0,65, -0,1,14,1,1, -2,0,1,1694,145, -18,1,1694,146,20, -147,4,32,70,0, -111,0,114,0,76, -0,111,0,111,0, -112,0,83,0,116, -0,97,0,116,0, -101,0,109,0,101, -0,110,0,116,0, -1,147,1,2,2, -0,1,1695,148,18, -1,1695,143,2,0, -1,2811,149,18,1, -2811,150,20,151,4, +110,0,116,0,1, +138,1,2,2,0, +1,2043,109,18,1, +2043,110,20,111,4, 18,83,0,69,0, 77,0,73,0,67, 0,79,0,76,0, 79,0,78,0,1, 11,1,1,2,0, -1,2645,152,18,1, -2645,153,20,154,4, -32,73,0,110,0, -116,0,65,0,114, +1,2755,112,18,1, +2755,113,20,114,4, +22,82,0,73,0, +71,0,72,0,84, +0,95,0,66,0, +82,0,65,0,67, +0,69,0,1,13, +1,1,2,0,1, +1834,115,18,1,1834, +116,20,117,4,20, +76,0,69,0,70, +0,84,0,95,0, +80,0,65,0,82, +0,69,0,78,0, +1,16,1,1,2, +0,1,1833,118,18, +1,1833,119,20,120, +4,10,87,0,72, +0,73,0,76,0, +69,0,1,45,1, +1,2,0,1,1832, +121,18,1,1832,122, +20,123,4,18,83, +0,116,0,97,0, +116,0,101,0,109, +0,101,0,110,0, +116,0,1,135,1, +2,2,0,1,1804, +124,18,1,1804,125, +20,126,4,4,68, +0,79,0,1,44, +1,1,2,0,1, +1803,127,18,1,1803, +122,2,0,1,883, +128,18,1,883,129, +20,130,4,20,69, +0,120,0,112,0, +114,0,101,0,115, +0,115,0,105,0, +111,0,110,0,1, +156,1,2,2,0, +1,461,131,18,1, +461,132,20,133,4, +24,65,0,114,0, +103,0,117,0,109, +0,101,0,110,0, +116,0,76,0,105, +0,115,0,116,0, +1,149,1,2,2, +0,1,2703,134,18, +1,2703,135,20,136, +4,18,83,0,116, +0,97,0,116,0, +101,0,66,0,111, +0,100,0,121,0, +1,103,1,2,2, +0,1,1775,137,18, +1,1775,138,20,139, +4,22,82,0,73, +0,71,0,72,0, +84,0,95,0,80, +0,65,0,82,0, +69,0,78,0,1, +17,1,1,2,0, +1,1773,140,18,1, +1773,141,20,142,4, +32,70,0,111,0, +114,0,76,0,111, +0,111,0,112,0, +83,0,116,0,97, +0,116,0,101,0, +109,0,101,0,110, +0,116,0,1,147, +1,2,2,0,1, +1931,143,18,1,1931, +122,2,0,1,1756, +144,18,1,1756,110, +2,0,1,827,145, +18,1,827,129,2, +0,1,2541,146,18, +1,2541,147,20,148, +4,10,67,0,79, +0,77,0,77,0, +65,0,1,14,1, +1,2,0,1,2659, +149,18,1,2659,150, +20,151,4,20,76, +0,69,0,70,0, +84,0,95,0,66, +0,82,0,65,0, +67,0,69,0,1, +12,1,1,2,0, +1,2658,152,18,1, +2658,153,20,154,4, +26,68,0,69,0, +70,0,65,0,85, +0,76,0,84,0, +95,0,83,0,84, +0,65,0,84,0, +69,0,1,47,1, +1,2,0,1,2657, +155,18,1,2657,156, +20,157,4,20,83, +0,116,0,97,0, +116,0,101,0,69, +0,118,0,101,0, +110,0,116,0,1, +104,1,2,2,0, +1,1737,158,18,1, +1737,129,2,0,1, +377,159,18,1,377, +160,20,161,4,10, +73,0,68,0,69, +0,78,0,84,0, +1,93,1,1,2, +0,1,2654,162,18, +1,2654,163,20,164, +4,32,73,0,110, +0,116,0,65,0, +114,0,103,0,83, +0,116,0,97,0, +116,0,101,0,69, +0,118,0,101,0, +110,0,116,0,1, +107,1,2,2,0, +1,2033,165,18,1, +2033,166,20,167,4, +22,73,0,102,0, +83,0,116,0,97, +0,116,0,101,0, +109,0,101,0,110, +0,116,0,1,143, +1,2,2,0,1, +2652,168,18,1,2652, +169,20,170,4,44, +73,0,110,0,116, +0,82,0,111,0, +116,0,82,0,111, +0,116,0,65,0, +114,0,103,0,83, +0,116,0,97,0, +116,0,101,0,69, +0,118,0,101,0, +110,0,116,0,1, +109,1,2,2,0, +1,2651,171,18,1, +2651,172,20,173,4, +44,73,0,110,0, +116,0,86,0,101, +0,99,0,86,0, +101,0,99,0,65, +0,114,0,103,0, +83,0,116,0,97, +0,116,0,101,0, +69,0,118,0,101, +0,110,0,116,0, +1,110,1,2,2, +0,1,1731,174,18, +1,1731,110,2,0, +1,1730,175,18,1, +1730,107,2,0,1, +2648,176,18,1,2648, +156,2,0,1,2647, +177,18,1,2647,178, +20,179,4,34,86, +0,111,0,105,0, +100,0,65,0,114, 0,103,0,83,0, 116,0,97,0,116, 0,101,0,69,0, 118,0,101,0,110, -0,116,0,1,107, +0,116,0,1,105, 1,2,2,0,1, -2646,155,18,1,2646, -156,20,157,4,32, +2646,180,18,1,2646, +181,20,182,4,32, 75,0,101,0,121, 0,65,0,114,0, 103,0,83,0,116, @@ -2536,130 +2601,1358 @@ public yyLSLSyntax 101,0,69,0,118, 0,101,0,110,0, 116,0,1,106,1, -2,2,0,1,30, -158,18,1,30,159, -20,160,4,22,68, +2,2,0,1,2645, +183,18,1,2645,163, +2,0,1,2644,184, +18,1,2644,185,20, +186,4,38,86,0, +101,0,99,0,116, +0,111,0,114,0, +65,0,114,0,103, +0,83,0,116,0, +97,0,116,0,101, +0,69,0,118,0, +101,0,110,0,116, +0,1,108,1,2, +2,0,1,2643,187, +18,1,2643,169,2, +0,1,2642,188,18, +1,2642,172,2,0, +1,2641,189,18,1, +2641,190,20,191,4, +44,75,0,101,0, +121,0,73,0,110, +0,116,0,73,0, +110,0,116,0,65, +0,114,0,103,0, +83,0,116,0,97, +0,116,0,101,0, +69,0,118,0,101, +0,110,0,116,0, +1,111,1,2,2, +0,1,2767,192,18, +1,2767,193,20,194, +4,10,83,0,116, +0,97,0,116,0, +101,0,1,102,1, +2,2,0,1,2577, +195,18,1,2577,116, +2,0,1,1701,196, +18,1,1701,129,2, +0,1,1695,197,18, +1,1695,147,2,0, +1,1694,198,18,1, +1694,141,2,0,1, +2597,199,18,1,2597, +135,2,0,1,2595, +200,18,1,2595,201, +20,202,4,34,67, +0,111,0,109,0, +112,0,111,0,117, +0,110,0,100,0, +83,0,116,0,97, +0,116,0,101,0, +109,0,101,0,110, +0,116,0,1,133, +1,2,2,0,1, +2593,203,18,1,2593, +138,2,0,1,2591, +204,18,1,2591,205, +20,206,4,46,65, +0,114,0,103,0, +117,0,109,0,101, +0,110,0,116,0, +68,0,101,0,99, +0,108,0,97,0, +114,0,97,0,116, +0,105,0,111,0, +110,0,76,0,105, +0,115,0,116,0, +1,112,1,2,2, +0,1,1665,207,18, +1,1665,129,2,0, +1,2582,208,18,1, +2582,116,2,0,1, +2581,209,18,1,2581, +210,20,211,4,10, +69,0,118,0,101, +0,110,0,116,0, +1,125,1,2,2, +0,1,2580,212,18, +1,2580,201,2,0, +1,1659,213,18,1, +1659,116,2,0,1, +1658,214,18,1,1658, +215,20,216,4,6, +70,0,79,0,82, +0,1,46,1,1, +2,0,1,1657,217, +18,1,1657,110,2, +0,1,2575,218,18, +1,2575,201,2,0, +1,2573,219,18,1, +2573,138,2,0,1, +2572,220,18,1,2572, +221,20,222,4,52, +75,0,101,0,121, +0,65,0,114,0, +103,0,117,0,109, +0,101,0,110,0, +116,0,68,0,101, +0,99,0,108,0, +97,0,114,0,97, +0,116,0,105,0, +111,0,110,0,76, +0,105,0,115,0, +116,0,1,113,1, +2,2,0,1,2571, +223,18,1,2571,224, +20,225,4,28,75, +0,101,0,121,0, +68,0,101,0,99, +0,108,0,97,0, +114,0,97,0,116, +0,105,0,111,0, +110,0,1,120,1, +2,2,0,1,2569, +226,18,1,2569,116, +2,0,1,2568,227, +18,1,2568,228,20, +229,4,22,75,0, +101,0,121,0,65, +0,114,0,103,0, +69,0,118,0,101, +0,110,0,116,0, +1,127,1,2,2, +0,1,2567,230,18, +1,2567,201,2,0, +1,2565,231,18,1, +2565,138,2,0,1, +2564,232,18,1,2564, +233,20,234,4,52, +73,0,110,0,116, +0,65,0,114,0, +103,0,117,0,109, +0,101,0,110,0, +116,0,68,0,101, +0,99,0,108,0, +97,0,114,0,97, +0,116,0,105,0, +111,0,110,0,76, +0,105,0,115,0, +116,0,1,114,1, +2,2,0,1,2563, +235,18,1,2563,236, +20,237,4,28,73, +0,110,0,116,0, +68,0,101,0,99, +0,108,0,97,0, +114,0,97,0,116, +0,105,0,111,0, +110,0,1,121,1, +2,2,0,1,2561, +238,18,1,2561,116, +2,0,1,2560,239, +18,1,2560,240,20, +241,4,22,73,0, +110,0,116,0,65, +0,114,0,103,0, +69,0,118,0,101, +0,110,0,116,0, +1,128,1,2,2, +0,1,2559,242,18, +1,2559,201,2,0, +1,2557,243,18,1, +2557,138,2,0,1, +2556,244,18,1,2556, +245,20,246,4,58, +86,0,101,0,99, +0,116,0,111,0, +114,0,65,0,114, +0,103,0,117,0, +109,0,101,0,110, +0,116,0,68,0, +101,0,99,0,108, +0,97,0,114,0, +97,0,116,0,105, +0,111,0,110,0, +76,0,105,0,115, +0,116,0,1,115, +1,2,2,0,1, +2555,247,18,1,2555, +248,20,249,4,28, +86,0,101,0,99, +0,68,0,101,0, +99,0,108,0,97, +0,114,0,97,0, +116,0,105,0,111, +0,110,0,1,122, +1,2,2,0,1, +2649,250,18,1,2649, +113,2,0,1,151, +251,18,1,151,252, +20,253,4,26,69, +0,81,0,85,0, +65,0,76,0,83, +0,95,0,69,0, +81,0,85,0,65, +0,76,0,83,0, +1,29,1,1,2, +0,1,1123,254,18, +1,1123,129,2,0, +1,1939,255,18,1, +1939,129,2,0,1, +2653,256,18,1,2653, +185,2,0,1,2549, +257,18,1,2549,138, +2,0,1,2548,258, +18,1,2548,259,20, +260,4,64,73,0, +110,0,116,0,82, +0,111,0,116,0, +82,0,111,0,116, +0,65,0,114,0, +103,0,117,0,109, +0,101,0,110,0, +116,0,68,0,101, +0,99,0,108,0, +97,0,114,0,97, +0,116,0,105,0, +111,0,110,0,76, +0,105,0,115,0, +116,0,1,116,1, +2,2,0,1,1628, +261,18,1,1628,129, +2,0,1,2545,262, +18,1,2545,147,2, +0,1,2544,263,18, +1,2544,264,20,265, +4,28,82,0,111, +0,116,0,68,0, +101,0,99,0,108, +0,97,0,114,0, +97,0,116,0,105, +0,111,0,110,0, +1,123,1,2,2, +0,1,2543,266,18, +1,2543,160,2,0, +1,2542,267,18,1, +2542,268,20,269,4, +26,82,0,79,0, +84,0,65,0,84, +0,73,0,79,0, +78,0,95,0,84, +0,89,0,80,0, +69,0,1,56,1, +1,2,0,1,1622, +270,18,1,1622,271, +20,272,4,12,69, +0,81,0,85,0, +65,0,76,0,83, +0,1,15,1,1, +2,0,1,1621,273, +18,1,1621,274,20, +275,4,22,68,0, +101,0,99,0,108, +0,97,0,114,0, +97,0,116,0,105, +0,111,0,110,0, +1,119,1,2,2, +0,1,1620,276,18, +1,1620,107,2,0, +1,2538,277,18,1, +2538,116,2,0,1, +2537,278,18,1,2537, +279,20,280,4,34, +73,0,110,0,116, +0,82,0,111,0, +116,0,82,0,111, +0,116,0,65,0, +114,0,103,0,69, +0,118,0,101,0, +110,0,116,0,1, +130,1,2,2,0, +1,2536,281,18,1, +2536,201,2,0,1, +2534,282,18,1,2534, +138,2,0,1,2533, +283,18,1,2533,284, +20,285,4,64,73, +0,110,0,116,0, +86,0,101,0,99, +0,86,0,101,0, +99,0,65,0,114, +0,103,0,117,0, +109,0,101,0,110, +0,116,0,68,0, +101,0,99,0,108, +0,97,0,114,0, +97,0,116,0,105, +0,111,0,110,0, +76,0,105,0,115, +0,116,0,1,117, +1,2,2,0,1, +2532,286,18,1,2532, +248,2,0,1,2530, +287,18,1,2530,147, +2,0,1,2529,288, +18,1,2529,248,2, +0,1,2528,289,18, +1,2528,160,2,0, +1,2527,290,18,1, +2527,291,20,292,4, +22,86,0,69,0, +67,0,84,0,79, +0,82,0,95,0, +84,0,89,0,80, +0,69,0,1,55, +1,1,2,0,1, +2526,293,18,1,2526, +147,2,0,1,2525, +294,18,1,2525,236, +2,0,1,2523,295, +18,1,2523,116,2, +0,1,2522,296,18, +1,2522,297,20,298, +4,34,73,0,110, +0,116,0,86,0, +101,0,99,0,86, +0,101,0,99,0, +65,0,114,0,103, +0,69,0,118,0, +101,0,110,0,116, +0,1,131,1,2, +2,0,1,2521,299, +18,1,2521,201,2, +0,1,2519,300,18, +1,2519,138,2,0, +1,2518,301,18,1, +2518,302,20,303,4, +64,75,0,101,0, +121,0,73,0,110, +0,116,0,73,0, +110,0,116,0,65, +0,114,0,103,0, +117,0,109,0,101, +0,110,0,116,0, +68,0,101,0,99, +0,108,0,97,0, +114,0,97,0,116, +0,105,0,111,0, +110,0,76,0,105, +0,115,0,116,0, +1,118,1,2,2, +0,1,2517,304,18, +1,2517,236,2,0, +1,2515,305,18,1, +2515,147,2,0,1, +2514,306,18,1,2514, +236,2,0,1,2513, +307,18,1,2513,160, +2,0,1,2512,308, +18,1,2512,309,20, +310,4,24,73,0, +78,0,84,0,69, +0,71,0,69,0, +82,0,95,0,84, +0,89,0,80,0, +69,0,1,51,1, +1,2,0,1,2511, +311,18,1,2511,147, +2,0,1,1591,312, +18,1,1591,129,2, +0,1,2509,313,18, +1,2509,160,2,0, +1,2508,314,18,1, +2508,315,20,316,4, +16,75,0,69,0, +89,0,95,0,84, +0,89,0,80,0, +69,0,1,54,1, +1,2,0,1,2507, +317,18,1,2507,116, +2,0,1,2506,318, +18,1,2506,319,20, +320,4,34,75,0, +101,0,121,0,73, +0,110,0,116,0, +73,0,110,0,116, +0,65,0,114,0, +103,0,69,0,118, +0,101,0,110,0, +116,0,1,132,1, +2,2,0,1,2505, +321,18,1,2505,322, +20,323,4,32,68, +0,65,0,84,0, +65,0,83,0,69, +0,82,0,86,0, +69,0,82,0,95, +0,69,0,86,0, +69,0,78,0,84, +0,1,66,1,1, +2,0,1,1585,324, +18,1,1585,325,20, +326,4,12,82,0, +69,0,84,0,85, +0,82,0,78,0, +1,50,1,1,2, +0,1,2503,327,18, +1,2503,328,20,329, +4,38,72,0,84, +0,84,0,80,0, +95,0,82,0,69, +0,83,0,80,0, +79,0,78,0,83, +0,69,0,95,0, +69,0,86,0,69, +0,78,0,84,0, +1,68,1,1,2, +0,1,2502,330,18, +1,2502,331,20,332, +4,36,76,0,73, +0,78,0,75,0, +95,0,77,0,69, +0,83,0,83,0, +65,0,71,0,69, +0,95,0,69,0, +86,0,69,0,78, +0,84,0,1,72, +1,1,2,0,1, +2501,333,18,1,2501, +334,20,335,4,24, +76,0,73,0,83, +0,84,0,69,0, +78,0,95,0,69, +0,86,0,69,0, +78,0,84,0,1, +73,1,1,2,0, +1,2500,336,18,1, +2500,337,20,338,4, +22,77,0,79,0, +78,0,69,0,89, +0,95,0,69,0, +86,0,69,0,78, +0,84,0,1,74, +1,1,2,0,1, +2499,339,18,1,2499, +340,20,341,4,34, +82,0,69,0,77, +0,79,0,84,0, +69,0,95,0,68, +0,65,0,84,0, +65,0,95,0,69, +0,86,0,69,0, +78,0,84,0,1, +82,1,1,2,0, +1,2498,342,18,1, +2498,343,20,344,4, +36,72,0,84,0, +84,0,80,0,95, +0,82,0,69,0, +81,0,85,0,69, +0,83,0,84,0, +95,0,69,0,86, +0,69,0,78,0, +84,0,1,91,1, +1,2,0,1,2497, +345,18,1,2497,346, +20,347,4,48,84, +0,82,0,65,0, +78,0,83,0,65, +0,67,0,84,0, +73,0,79,0,78, +0,95,0,82,0, +69,0,83,0,85, +0,76,0,84,0, +95,0,69,0,86, +0,69,0,78,0, +84,0,1,92,1, +1,2,0,1,2496, +348,18,1,2496,349, +20,350,4,34,83, +0,84,0,65,0, +84,0,69,0,95, +0,69,0,78,0, +84,0,82,0,89, +0,95,0,69,0, +86,0,69,0,78, +0,84,0,1,85, +1,1,2,0,1, +2495,351,18,1,2495, +352,20,353,4,32, +83,0,84,0,65, +0,84,0,69,0, +95,0,69,0,88, +0,73,0,84,0, +95,0,69,0,86, +0,69,0,78,0, +84,0,1,86,1, +1,2,0,1,2494, +354,18,1,2494,355, +20,356,4,32,77, +0,79,0,86,0, +73,0,78,0,71, +0,95,0,69,0, +78,0,68,0,95, +0,69,0,86,0, +69,0,78,0,84, +0,1,75,1,1, +2,0,1,1574,357, +18,1,1574,110,2, +0,1,2492,358,18, +1,2492,359,20,360, +4,30,78,0,79, +0,95,0,83,0, +69,0,78,0,83, +0,79,0,82,0, +95,0,69,0,86, +0,69,0,78,0, +84,0,1,77,1, +1,2,0,1,2491, +361,18,1,2491,362, +20,363,4,46,78, +0,79,0,84,0, +95,0,65,0,84, +0,95,0,82,0, +79,0,84,0,95, +0,84,0,65,0, +82,0,71,0,69, +0,84,0,95,0, +69,0,86,0,69, +0,78,0,84,0, +1,78,1,1,2, +0,1,2490,364,18, +1,2490,365,20,366, +4,38,78,0,79, +0,84,0,95,0, +65,0,84,0,95, +0,84,0,65,0, +82,0,71,0,69, +0,84,0,95,0, +69,0,86,0,69, +0,78,0,84,0, +1,79,1,1,2, +0,1,2489,367,18, +1,2489,368,20,369, +4,22,84,0,73, +0,77,0,69,0, +82,0,95,0,69, +0,86,0,69,0, +78,0,84,0,1, +87,1,1,2,0, +1,2488,370,18,1, +2488,371,20,372,4, +24,65,0,84,0, +84,0,65,0,67, +0,72,0,95,0, +69,0,86,0,69, +0,78,0,84,0, +1,60,1,1,2, +0,1,2487,373,18, +1,2487,374,20,375, +4,32,79,0,66, +0,74,0,69,0, +67,0,84,0,95, +0,82,0,69,0, +90,0,95,0,69, +0,86,0,69,0, +78,0,84,0,1, +80,1,1,2,0, +1,2486,376,18,1, +2486,377,20,378,4, +26,67,0,72,0, +65,0,78,0,71, +0,69,0,68,0, +95,0,69,0,86, +0,69,0,78,0, +84,0,1,61,1, +1,2,0,1,2485, +379,18,1,2485,380, +20,381,4,30,67, +0,79,0,76,0, +76,0,73,0,83, +0,73,0,79,0, +78,0,95,0,69, +0,86,0,69,0, +78,0,84,0,1, +62,1,1,2,0, +1,2484,382,18,1, +2484,383,20,384,4, +38,67,0,79,0, +76,0,76,0,73, +0,83,0,73,0, +79,0,78,0,95, +0,69,0,78,0, +68,0,95,0,69, +0,86,0,69,0, +78,0,84,0,1, +63,1,1,2,0, +1,2483,385,18,1, +2483,386,20,387,4, +42,67,0,79,0, +76,0,76,0,73, +0,83,0,73,0, +79,0,78,0,95, +0,83,0,84,0, +65,0,82,0,84, +0,95,0,69,0, +86,0,69,0,78, +0,84,0,1,64, +1,1,2,0,1, +2482,388,18,1,2482, +389,20,390,4,24, +79,0,78,0,95, +0,82,0,69,0, +90,0,95,0,69, +0,86,0,69,0, +78,0,84,0,1, +81,1,1,2,0, +1,2481,391,18,1, +2481,392,20,393,4, +52,82,0,85,0, +78,0,95,0,84, +0,73,0,77,0, +69,0,95,0,80, +0,69,0,82,0, +77,0,73,0,83, +0,83,0,73,0, +79,0,78,0,83, +0,95,0,69,0, +86,0,69,0,78, +0,84,0,1,83, +1,1,2,0,1, +2480,394,18,1,2480, +395,20,396,4,24, +83,0,69,0,78, +0,83,0,79,0, +82,0,95,0,69, +0,86,0,69,0, +78,0,84,0,1, +84,1,1,2,0, +1,2479,397,18,1, +2479,398,20,399,4, +22,84,0,79,0, +85,0,67,0,72, +0,95,0,69,0, +86,0,69,0,78, +0,84,0,1,88, +1,1,2,0,1, +2478,400,18,1,2478, +401,20,402,4,30, +84,0,79,0,85, +0,67,0,72,0, +95,0,69,0,78, +0,68,0,95,0, +69,0,86,0,69, +0,78,0,84,0, +1,90,1,1,2, +0,1,2477,403,18, +1,2477,404,20,405, +4,34,84,0,79, +0,85,0,67,0, +72,0,95,0,83, +0,84,0,65,0, +82,0,84,0,95, +0,69,0,86,0, +69,0,78,0,84, +0,1,89,1,1, +2,0,1,2476,406, +18,1,2476,407,20, +408,4,40,76,0, +65,0,78,0,68, +0,95,0,67,0, +79,0,76,0,76, +0,73,0,83,0, +73,0,79,0,78, +0,95,0,69,0, +86,0,69,0,78, +0,84,0,1,69, +1,1,2,0,1, +2475,409,18,1,2475, +410,20,411,4,48, +76,0,65,0,78, +0,68,0,95,0, +67,0,79,0,76, +0,76,0,73,0, +83,0,73,0,79, +0,78,0,95,0, +69,0,78,0,68, +0,95,0,69,0, +86,0,69,0,78, +0,84,0,1,70, +1,1,2,0,1, +1555,412,18,1,1555, +129,2,0,1,2473, +413,18,1,2473,414, +20,415,4,38,65, +0,84,0,95,0, +82,0,79,0,84, +0,95,0,84,0, +65,0,82,0,71, +0,69,0,84,0, +95,0,69,0,86, +0,69,0,78,0, +84,0,1,58,1, +1,2,0,1,2472, +416,18,1,2472,417, +20,418,4,30,65, +0,84,0,95,0, +84,0,65,0,82, +0,71,0,69,0, +84,0,95,0,69, +0,86,0,69,0, +78,0,84,0,1, +59,1,1,2,0, +1,2471,419,18,1, +2471,420,20,421,4, +26,67,0,79,0, +78,0,84,0,82, +0,79,0,76,0, +95,0,69,0,86, +0,69,0,78,0, +84,0,1,65,1, +1,2,0,1,2470, +422,18,1,2470,150, +2,0,1,2469,423, +18,1,2469,160,2, +0,1,2468,424,18, +1,2468,425,20,426, +4,10,83,0,84, +0,65,0,84,0, +69,0,1,48,1, +1,2,0,1,2467, +427,18,1,2467,274, +2,0,1,2466,428, +18,1,2466,201,2, +0,1,2464,429,18, +1,2464,113,2,0, +1,2462,430,18,1, +2462,122,2,0,1, +2459,431,18,1,2459, +113,2,0,1,2458, +432,18,1,2458,122, +2,0,1,1113,433, +18,1,1113,434,20, +435,4,12,80,0, +69,0,82,0,73, +0,79,0,68,0, +1,24,1,1,2, +0,1,1932,436,18, +1,1932,437,20,438, +4,4,73,0,70, +0,1,42,1,1, +2,0,1,2553,439, +18,1,2553,116,2, +0,1,1521,440,18, +1,1521,129,2,0, +1,1515,441,18,1, +1515,271,2,0,1, +1514,442,18,1,1514, +107,2,0,1,2576, +443,18,1,2576,444, +20,445,4,24,86, +0,111,0,105,0, +100,0,65,0,114, +0,103,0,69,0, +118,0,101,0,110, +0,116,0,1,126, +1,2,2,0,1, +2074,446,18,1,2074, +107,2,0,1,2413, +447,18,1,2413,448, +20,449,4,26,83, +0,116,0,97,0, +116,0,101,0,109, +0,101,0,110,0, +116,0,76,0,105, +0,115,0,116,0, +1,134,1,2,2, +0,1,1485,450,18, +1,1485,129,2,0, +1,1479,451,18,1, +1479,452,20,453,4, +22,80,0,76,0, +85,0,83,0,95, +0,69,0,81,0, +85,0,65,0,76, +0,83,0,1,6, +1,1,2,0,1, +1478,454,18,1,1478, +107,2,0,1,378, +455,18,1,378,434, +2,0,1,2318,456, +18,1,2318,110,2, +0,1,1449,457,18, +1,1449,129,2,0, +1,2364,458,18,1, +2364,122,2,0,1, +525,459,18,1,525, +460,20,461,4,22, +82,0,73,0,71, +0,72,0,84,0, +95,0,65,0,78, +0,71,0,76,0, +69,0,1,26,1, +1,2,0,1,1443, +462,18,1,1443,463, +20,464,4,24,77, +0,73,0,78,0, +85,0,83,0,95, +0,69,0,81,0, +85,0,65,0,76, +0,83,0,1,7, +1,1,2,0,1, +1442,465,18,1,1442, +107,2,0,1,515, +466,18,1,515,129, +2,0,1,2650,467, +18,1,2650,190,2, +0,1,509,468,18, +1,509,147,2,0, +1,2552,469,18,1, +2552,470,20,471,4, +28,86,0,101,0, +99,0,116,0,111, +0,114,0,65,0, +114,0,103,0,69, +0,118,0,101,0, +110,0,116,0,1, +129,1,2,2,0, +1,2042,472,18,1, +2042,473,20,474,4, +20,65,0,115,0, +115,0,105,0,103, +0,110,0,109,0, +101,0,110,0,116, +0,1,137,1,2, +2,0,1,2337,475, +18,1,2337,138,2, +0,1,2335,476,18, +1,2335,141,2,0, +1,1413,477,18,1, +1413,129,2,0,1, +1407,478,18,1,1407, +479,20,480,4,22, +83,0,84,0,65, +0,82,0,95,0, +69,0,81,0,85, +0,65,0,76,0, +83,0,1,8,1, +1,2,0,1,1406, +481,18,1,1406,107, +2,0,1,2779,482, +18,1,2779,205,2, +0,1,481,483,18, +1,481,484,20,485, +4,16,65,0,114, +0,103,0,117,0, +109,0,101,0,110, +0,116,0,1,150, +1,2,2,0,1, +480,486,18,1,480, +487,20,488,4,26, +82,0,73,0,71, +0,72,0,84,0, +95,0,66,0,82, +0,65,0,67,0, +75,0,69,0,84, +0,1,28,1,1, +2,0,1,479,489, +18,1,479,490,20, +491,4,32,73,0, +78,0,84,0,69, +0,71,0,69,0, +82,0,95,0,67, +0,79,0,78,0, +83,0,84,0,65, +0,78,0,84,0, +1,94,1,1,2, +0,1,478,492,18, +1,478,493,20,494, +4,40,72,0,69, +0,88,0,95,0, +73,0,78,0,84, +0,69,0,71,0, +69,0,82,0,95, +0,67,0,79,0, +78,0,83,0,84, +0,65,0,78,0, +84,0,1,95,1, +1,2,0,1,477, +495,18,1,477,496, +20,497,4,28,70, +0,76,0,79,0, +65,0,84,0,95, +0,67,0,79,0, +78,0,83,0,84, +0,65,0,78,0, +84,0,1,96,1, +1,2,0,1,476, +498,18,1,476,499, +20,500,4,30,83, +0,84,0,82,0, +73,0,78,0,71, +0,95,0,67,0, +79,0,78,0,83, +0,84,0,65,0, +78,0,84,0,1, +3,1,1,2,0, +1,2822,501,18,1, +2822,110,2,0,1, +464,502,18,1,464, +484,2,0,1,462, +503,18,1,462,147, +2,0,1,2299,504, +18,1,2299,129,2, +0,1,459,505,18, +1,459,506,20,507, +4,24,76,0,69, +0,70,0,84,0, +95,0,66,0,82, +0,65,0,67,0, +75,0,69,0,84, +0,1,27,1,1, +2,0,1,1377,508, +18,1,1377,129,2, +0,1,2293,509,18, +1,2293,110,2,0, +1,1371,510,18,1, +1371,511,20,512,4, +24,83,0,76,0, +65,0,83,0,72, +0,95,0,69,0, +81,0,85,0,65, +0,76,0,83,0, +1,9,1,1,2, +0,1,1370,513,18, +1,1370,107,2,0, +1,447,514,18,1, +447,460,2,0,1, +2281,515,18,1,2281, +107,2,0,1,437, +516,18,1,437,129, +2,0,1,431,517, +18,1,431,147,2, +0,1,1341,518,18, +1,1341,129,2,0, +1,2842,519,18,1, +2842,520,20,521,4, +50,71,0,108,0, +111,0,98,0,97, +0,108,0,86,0, +97,0,114,0,105, +0,97,0,98,0, +108,0,101,0,68, 0,101,0,99,0, 108,0,97,0,114, 0,97,0,116,0, 105,0,111,0,110, -0,1,119,1,2, -2,0,1,31,161, -18,1,31,162,20, -163,4,22,82,0, -73,0,71,0,72, -0,84,0,95,0, -80,0,65,0,82, -0,69,0,78,0, -1,17,1,1,2, -0,1,32,164,18, -1,32,165,20,166, -4,20,76,0,69, -0,70,0,84,0, -95,0,66,0,82, -0,65,0,67,0, -69,0,1,12,1, -1,2,0,1,2650, -167,18,1,2650,168, -20,169,4,44,75, -0,101,0,121,0, -73,0,110,0,116, -0,73,0,110,0, -116,0,65,0,114, -0,103,0,83,0, -116,0,97,0,116, -0,101,0,69,0, -118,0,101,0,110, -0,116,0,1,111, -1,2,2,0,1, -2651,170,18,1,2651, -171,20,172,4,44, -73,0,110,0,116, -0,86,0,101,0, -99,0,86,0,101, -0,99,0,65,0, -114,0,103,0,83, -0,116,0,97,0, -116,0,101,0,69, -0,118,0,101,0, -110,0,116,0,1, -110,1,2,2,0, -1,1114,173,18,1, -1114,132,2,0,1, -2654,174,18,1,2654, -153,2,0,1,1152, -175,18,1,1152,176, -20,177,4,32,83, -0,105,0,109,0, -112,0,108,0,101, -0,65,0,115,0, -115,0,105,0,103, -0,110,0,109,0, -101,0,110,0,116, -0,1,138,1,2, -2,0,1,1117,178, -18,1,1117,179,20, -180,4,28,80,0, +0,1,99,1,2, +2,0,1,1335,522, +18,1,1335,523,20, +524,4,28,80,0, 69,0,82,0,67, 0,69,0,78,0, 84,0,95,0,69, 0,81,0,85,0, 65,0,76,0,83, 0,1,10,1,1, -2,0,1,40,181, -18,1,40,132,2, -0,1,41,182,18, -1,41,135,2,0, -1,42,183,18,1, -42,184,20,185,4, -20,69,0,120,0, -112,0,114,0,101, -0,115,0,115,0, -105,0,111,0,110, -0,1,156,1,2, -2,0,1,43,186, -18,1,43,187,20, -188,4,22,82,0, -73,0,71,0,72, -0,84,0,95,0, -83,0,72,0,73, -0,70,0,84,0, -1,41,1,1,2, -0,1,44,189,18, -1,44,132,2,0, -1,1159,190,18,1, -1159,184,2,0,1, -46,191,18,1,46, -192,20,193,4,12, -80,0,69,0,82, -0,73,0,79,0, -68,0,1,24,1, -1,2,0,1,47, -194,18,1,47,132, -2,0,1,48,195, -18,1,48,196,20, -197,4,18,68,0, -69,0,67,0,82, -0,69,0,77,0, -69,0,78,0,84, -0,1,5,1,1, -2,0,1,49,198, -18,1,49,199,20, -200,4,18,73,0, -78,0,67,0,82, -0,69,0,77,0, -69,0,78,0,84, -0,1,4,1,1, -2,0,1,50,201, -18,1,50,196,2, -0,1,51,202,18, -1,51,199,2,0, -1,52,203,18,1, -52,135,2,0,1, -2281,204,18,1,2281, -176,2,0,1,2841, -205,18,1,2841,206, -20,207,4,48,71, +2,0,1,2547,525, +18,1,2547,264,2, +0,1,1332,526,18, +1,1332,107,2,0, +1,412,527,18,1, +412,129,2,0,1, +2037,528,18,1,2037, +110,2,0,1,1012, +529,18,1,1012,129, +2,0,1,1840,530, +18,1,1840,129,2, +0,1,406,531,18, +1,406,147,2,0, +1,2227,532,18,1, +2227,122,2,0,1, +387,533,18,1,387, +129,2,0,1,1303, +534,18,1,1303,129, +2,0,1,381,535, +18,1,381,536,20, +537,4,20,76,0, +69,0,70,0,84, +0,95,0,65,0, +78,0,71,0,76, +0,69,0,1,25, +1,1,2,0,1, +380,538,18,1,380, +539,20,540,4,16, +67,0,111,0,110, +0,115,0,116,0, +97,0,110,0,116, +0,1,152,1,2, +2,0,1,379,541, +18,1,379,160,2, +0,1,1297,542,18, +1,1297,271,2,0, +1,1296,543,18,1, +1296,107,2,0,1, +376,544,18,1,376, +545,20,546,4,18, +73,0,78,0,67, +0,82,0,69,0, +77,0,69,0,78, +0,84,0,1,4, +1,1,2,0,1, +375,547,18,1,375, +160,2,0,1,374, +548,18,1,374,434, +2,0,1,373,549, +18,1,373,160,2, +0,1,372,550,18, +1,372,551,20,552, +4,18,68,0,69, +0,67,0,82,0, +69,0,77,0,69, +0,78,0,84,0, +1,5,1,1,2, +0,1,371,553,18, +1,371,554,20,555, +4,24,70,0,117, +0,110,0,99,0, +116,0,105,0,111, +0,110,0,67,0, +97,0,108,0,108, +0,1,148,1,2, +2,0,1,2792,556, +18,1,2792,129,2, +0,1,2198,557,18, +1,2198,138,2,0, +1,2197,558,18,1, +2197,107,2,0,1, +352,559,18,1,352, +129,2,0,1,1267, +560,18,1,1267,129, +2,0,1,346,561, +18,1,346,562,20, +563,4,8,80,0, +76,0,85,0,83, +0,1,18,1,1, +2,0,1,1261,564, +18,1,1261,452,2, +0,1,1260,565,18, +1,1260,107,2,0, +1,328,566,18,1, +328,129,2,0,1, +322,567,18,1,322, +568,20,569,4,10, +77,0,73,0,78, +0,85,0,83,0, +1,19,1,1,2, +0,1,2846,570,18, +1,2846,571,23,572, +4,6,69,0,79, +0,70,0,1,2, +1,6,2,0,1, +1231,573,18,1,1231, +129,2,0,1,1225, +574,18,1,1225,463, +2,0,1,305,575, +18,1,305,129,2, +0,1,2041,576,18, +1,2041,110,2,0, +1,2656,577,18,1, +2656,178,2,0,1, +299,578,18,1,299, +579,20,580,4,8, +83,0,84,0,65, +0,82,0,1,20, +1,1,2,0,1, +2136,581,18,1,2136, +122,2,0,1,2764, +582,18,1,2764,583, +20,584,4,12,83, +0,116,0,97,0, +116,0,101,0,115, +0,1,101,1,2, +2,0,1,283,585, +18,1,283,129,2, +0,1,277,586,18, +1,277,587,20,588, +4,10,83,0,76, +0,65,0,83,0, +72,0,1,21,1, +1,2,0,1,1195, +589,18,1,1195,129, +2,0,1,1189,590, +18,1,1189,479,2, +0,1,1188,591,18, +1,1188,107,2,0, +1,2106,592,18,1, +2106,593,20,594,4, +8,69,0,76,0, +83,0,69,0,1, +43,1,1,2,0, +1,2105,595,18,1, +2105,122,2,0,1, +1550,596,18,1,1550, +107,2,0,1,262, +597,18,1,262,129, +2,0,1,2493,598, +18,1,2493,599,20, +600,4,36,77,0, +79,0,86,0,73, +0,78,0,71,0, +95,0,83,0,84, +0,65,0,82,0, +84,0,95,0,69, +0,86,0,69,0, +78,0,84,0,1, +76,1,1,2,0, +1,256,601,18,1, +256,602,20,603,4, +14,80,0,69,0, +82,0,67,0,69, +0,78,0,84,0, +1,22,1,1,2, +0,1,242,604,18, +1,242,129,2,0, +1,1159,605,18,1, +1159,129,2,0,1, +2075,606,18,1,2075, +138,2,0,1,236, +607,18,1,236,608, +20,609,4,6,65, +0,77,0,80,0, +1,33,1,1,2, +0,1,2823,610,18, +1,2823,611,20,612, +4,34,71,0,108, +0,111,0,98,0, +97,0,108,0,68, +0,101,0,102,0, +105,0,110,0,105, +0,116,0,105,0, +111,0,110,0,115, +0,1,98,1,2, +2,0,1,1153,613, +18,1,1153,511,2, +0,1,1152,614,18, +1,1152,107,2,0, +1,223,615,18,1, +223,129,2,0,1, +217,616,18,1,217, +617,20,618,4,12, +83,0,84,0,82, +0,79,0,75,0, +69,0,1,34,1, +1,2,0,1,2036, +619,18,1,2036,620, +20,621,4,26,74, +0,117,0,109,0, +112,0,83,0,116, +0,97,0,116,0, +101,0,109,0,101, +0,110,0,116,0, +1,141,1,2,2, +0,1,2045,622,18, +1,2045,110,2,0, +1,2044,623,18,1, +2044,624,20,625,4, +28,69,0,109,0, +112,0,116,0,121, +0,83,0,116,0, +97,0,116,0,101, +0,109,0,101,0, +110,0,116,0,1, +136,1,2,2,0, +1,205,626,18,1, +205,129,2,0,1, +1001,627,18,1,1001, +554,2,0,1,1901, +628,18,1,1901,138, +2,0,1,2040,629, +18,1,2040,630,20, +631,4,30,82,0, +101,0,116,0,117, +0,114,0,110,0, +83,0,116,0,97, +0,116,0,101,0, +109,0,101,0,110, +0,116,0,1,139, +1,2,2,0,1, +2039,632,18,1,2039, +110,2,0,1,2038, +633,18,1,2038,634, +20,635,4,18,74, +0,117,0,109,0, +112,0,76,0,97, +0,98,0,101,0, +108,0,1,140,1, +2,2,0,1,199, +636,18,1,199,637, +20,638,4,10,67, +0,65,0,82,0, +69,0,84,0,1, +35,1,1,2,0, +1,1117,639,18,1, +1117,523,2,0,1, +2035,640,18,1,2035, +110,2,0,1,2034, +641,18,1,2034,642, +20,643,4,22,83, +0,116,0,97,0, +116,0,101,0,67, +0,104,0,97,0, +110,0,103,0,101, +0,1,142,1,2, +2,0,1,1114,644, +18,1,1114,160,2, +0,1,2032,645,18, +1,2032,646,20,647, +4,28,87,0,104, +0,105,0,108,0, +101,0,83,0,116, +0,97,0,116,0, +101,0,109,0,101, +0,110,0,116,0, +1,144,1,2,2, +0,1,2031,648,18, +1,2031,649,20,650, +4,32,68,0,111, +0,87,0,104,0, +105,0,108,0,101, +0,83,0,116,0, +97,0,116,0,101, +0,109,0,101,0, +110,0,116,0,1, +145,1,2,2,0, +1,2030,651,18,1, +2030,652,20,653,4, +14,70,0,111,0, +114,0,76,0,111, +0,111,0,112,0, +1,146,1,2,2, +0,1,2029,654,18, +1,2029,201,2,0, +1,2028,655,18,1, +2028,160,2,0,1, +2027,656,18,1,2027, +657,20,658,4,4, +65,0,84,0,1, +23,1,1,2,0, +1,188,659,18,1, +188,129,2,0,1, +2025,660,18,1,2025, +661,20,662,4,8, +74,0,85,0,77, +0,80,0,1,49, +1,1,2,0,1, +2024,663,18,1,2024, +160,2,0,1,2023, +664,18,1,2023,153, +2,0,1,2022,665, +18,1,2022,425,2, +0,1,2021,666,18, +1,2021,122,2,0, +1,182,667,18,1, +182,460,2,0,1, +1096,668,18,1,1096, +138,2,0,1,1094, +669,18,1,1094,132, +2,0,1,172,670, +18,1,172,129,2, +0,1,166,671,18, +1,166,536,2,0, +1,157,672,18,1, +157,129,2,0,1, +1990,673,18,1,1990, +593,2,0,1,1989, +674,18,1,1989,122, +2,0,1,2504,675, +18,1,2504,676,20, +677,4,22,69,0, +77,0,65,0,73, +0,76,0,95,0, +69,0,86,0,69, +0,78,0,84,0, +1,67,1,1,2, +0,1,143,678,18, +1,143,129,2,0, +1,137,679,18,1, +137,680,20,681,4, +36,69,0,88,0, +67,0,76,0,65, +0,77,0,65,0, +84,0,73,0,79, +0,78,0,95,0, +69,0,81,0,85, +0,65,0,76,0, +83,0,1,30,1, +1,2,0,1,130, +682,18,1,130,129, +2,0,1,1048,683, +18,1,1048,129,2, +0,1,124,684,18, +1,124,685,20,686, +4,22,76,0,69, +0,83,0,83,0, +95,0,69,0,81, +0,85,0,65,0, +76,0,83,0,1, +31,1,1,2,0, +1,2540,687,18,1, +2540,236,2,0,1, +1958,688,18,1,1958, +138,2,0,1,118, +689,18,1,118,129, +2,0,1,112,690, +18,1,112,691,20, +692,4,28,71,0, +82,0,69,0,65, +0,84,0,69,0, +82,0,95,0,69, +0,81,0,85,0, +65,0,76,0,83, +0,1,32,1,1, +2,0,1,107,693, +18,1,107,129,2, +0,1,102,694,18, +1,102,695,20,696, +4,22,69,0,88, +0,67,0,76,0, +65,0,77,0,65, +0,84,0,73,0, +79,0,78,0,1, +37,1,1,2,0, +1,1882,697,18,1, +1882,129,2,0,1, +2026,698,18,1,2026, +160,2,0,1,2551, +699,18,1,2551,201, +2,0,1,2655,700, +18,1,2655,181,2, +0,1,97,701,18, +1,97,702,20,703, +4,14,65,0,77, +0,80,0,95,0, +65,0,77,0,80, +0,1,38,1,1, +2,0,1,1933,704, +18,1,1933,116,2, +0,1,1013,705,18, +1,1013,138,2,0, +1,93,706,18,1, +93,129,2,0,1, +1011,707,18,1,1011, +138,2,0,1,1010, +708,18,1,1010,107, +2,0,1,89,709, +18,1,89,568,2, +0,1,2845,104,1, +2844,710,18,1,2844, +520,2,0,1,2843, +711,18,1,2843,712, +20,713,4,48,71, 0,108,0,111,0, 98,0,97,0,108, 0,70,0,117,0, @@ -2670,427 +3963,39 @@ public yyLSLSyntax 110,0,105,0,116, 0,105,0,111,0, 110,0,1,100,1, -2,2,0,1,2842, -208,18,1,2842,209, -20,210,4,50,71, -0,108,0,111,0, -98,0,97,0,108, -0,86,0,97,0, -114,0,105,0,97, -0,98,0,108,0, -101,0,68,0,101, -0,99,0,108,0, -97,0,114,0,97, -0,116,0,105,0, -111,0,110,0,1, -99,1,2,2,0, -1,2755,211,18,1, -2755,212,20,213,4, -22,82,0,73,0, -71,0,72,0,84, -0,95,0,66,0, -82,0,65,0,67, -0,69,0,1,13, -1,1,2,0,1, -1730,214,18,1,1730, -176,2,0,1,1731, -215,18,1,1731,150, -2,0,1,61,216, -18,1,61,129,2, -0,1,62,217,18, -1,62,162,2,0, -1,63,218,18,1, -63,132,2,0,1, -65,219,18,1,65, -192,2,0,1,66, -220,18,1,66,132, -2,0,1,67,221, -18,1,67,196,2, -0,1,68,222,18, -1,68,199,2,0, -1,69,223,18,1, -69,196,2,0,1, -70,224,18,1,70, -199,2,0,1,71, -225,18,1,71,135, -2,0,1,73,226, -18,1,73,184,2, -0,1,74,227,18, -1,74,162,2,0, -1,1189,228,18,1, -1189,229,20,230,4, -22,83,0,84,0, -65,0,82,0,95, -0,69,0,81,0, -85,0,65,0,76, -0,83,0,1,8, -1,1,2,0,1, -76,231,18,1,76, -232,20,233,4,20, -76,0,69,0,70, -0,84,0,95,0, -83,0,72,0,73, -0,70,0,84,0, -1,40,1,1,2, -0,1,1153,234,18, -1,1153,235,20,236, -4,24,83,0,76, -0,65,0,83,0, -72,0,95,0,69, -0,81,0,85,0, -65,0,76,0,83, -0,1,9,1,1, -2,0,1,79,237, -18,1,79,238,20, -239,4,10,84,0, -73,0,76,0,68, -0,69,0,1,36, -1,1,2,0,1, -1195,240,18,1,1195, -184,2,0,1,82, -241,18,1,82,184, -2,0,1,1123,242, -18,1,1123,184,2, -0,1,85,243,18, -1,85,244,20,245, -4,26,83,0,84, -0,82,0,79,0, -75,0,69,0,95, -0,83,0,84,0, -82,0,79,0,75, -0,69,0,1,39, -1,1,2,0,1, -2547,246,18,1,2547, -247,20,248,4,28, -82,0,111,0,116, -0,68,0,101,0, -99,0,108,0,97, -0,114,0,97,0, -116,0,105,0,111, -0,110,0,1,123, -1,2,2,0,1, -89,249,18,1,89, -250,20,251,4,10, -77,0,73,0,78, -0,85,0,83,0, -1,19,1,1,2, -0,1,2318,252,18, -1,2318,150,2,0, -1,93,253,18,1, -93,184,2,0,1, -2792,254,18,1,2792, -184,2,0,1,97, -255,18,1,97,256, -20,257,4,14,65, -0,77,0,80,0, -95,0,65,0,77, -0,80,0,1,38, -1,1,2,0,1, -102,258,18,1,102, -259,20,260,4,22, -69,0,88,0,67, -0,76,0,65,0, -77,0,65,0,84, -0,73,0,79,0, -78,0,1,37,1, -1,2,0,1,1775, -261,18,1,1775,162, -2,0,1,107,262, -18,1,107,184,2, -0,1,2337,263,18, -1,2337,162,2,0, -1,1224,264,18,1, -1224,176,2,0,1, -1225,265,18,1,1225, -266,20,267,4,24, -77,0,73,0,78, -0,85,0,83,0, -95,0,69,0,81, -0,85,0,65,0, -76,0,83,0,1, -7,1,1,2,0, -1,112,268,18,1, -112,269,20,270,4, -28,71,0,82,0, -69,0,65,0,84, -0,69,0,82,0, -95,0,69,0,81, -0,85,0,65,0, -76,0,83,0,1, -32,1,1,2,0, -1,1188,271,18,1, -1188,176,2,0,1, -1231,272,18,1,1231, -184,2,0,1,118, -273,18,1,118,184, -2,0,1,1737,274, -18,1,1737,184,2, -0,1,124,275,18, -1,124,276,20,277, -4,22,76,0,69, -0,83,0,83,0, -95,0,69,0,81, -0,85,0,65,0, -76,0,83,0,1, -31,1,1,2,0, -1,2657,278,18,1, -2657,279,20,280,4, -20,83,0,116,0, -97,0,116,0,101, -0,69,0,118,0, -101,0,110,0,116, -0,1,104,1,2, -2,0,1,2658,281, -18,1,2658,282,20, -283,4,26,68,0, -69,0,70,0,65, -0,85,0,76,0, -84,0,95,0,83, -0,84,0,65,0, -84,0,69,0,1, -47,1,1,2,0, -1,2659,284,18,1, -2659,165,2,0,1, -130,285,18,1,130, -184,2,0,1,2843, -286,18,1,2843,206, -2,0,1,1803,287, -18,1,1803,288,20, -289,4,18,83,0, -116,0,97,0,116, -0,101,0,109,0, -101,0,110,0,116, -0,1,135,1,2, -2,0,1,1804,290, -18,1,1804,291,20, -292,4,4,68,0, -79,0,1,44,1, -1,2,0,1,2591, -293,18,1,2591,140, -2,0,1,2364,294, -18,1,2364,288,2, -0,1,137,295,18, -1,137,296,20,297, -4,36,69,0,88, -0,67,0,76,0, -65,0,77,0,65, -0,84,0,73,0, -79,0,78,0,95, -0,69,0,81,0, -85,0,65,0,76, -0,83,0,1,30, -1,1,2,0,1, -2293,298,18,1,2293, -150,2,0,1,2834, -299,18,1,2834,300, -20,301,4,12,83, -0,116,0,97,0, -116,0,101,0,115, -0,1,101,1,2, -2,0,1,1701,302, -18,1,1701,184,2, -0,1,1756,303,18, -1,1756,150,2,0, -1,2527,304,18,1, -2527,114,2,0,1, -143,305,18,1,143, -184,2,0,1,2299, -306,18,1,2299,184, -2,0,1,1260,307, -18,1,1260,176,2, -0,1,1261,308,18, -1,1261,309,20,310, -4,22,80,0,76, -0,85,0,83,0, -95,0,69,0,81, -0,85,0,65,0, -76,0,83,0,1, -6,1,1,2,0, -1,2528,311,18,1, -2528,132,2,0,1, -2844,312,18,1,2844, -209,2,0,1,2845, -104,1,151,313,18, -1,151,314,20,315, -4,26,69,0,81, -0,85,0,65,0, -76,0,83,0,95, -0,69,0,81,0, -85,0,65,0,76, -0,83,0,1,29, -1,1,2,0,1, -1267,316,18,1,1267, -184,2,0,1,157, -317,18,1,157,184, -2,0,1,2767,318, -18,1,2767,319,20, -320,4,10,83,0, -116,0,97,0,116, -0,101,0,1,102, -1,2,2,0,1, -1773,321,18,1,1773, -146,2,0,1,1832, -322,18,1,1832,288, -2,0,1,1833,323, -18,1,1833,324,20, -325,4,10,87,0, -72,0,73,0,76, -0,69,0,1,45, -1,1,2,0,1, -1834,326,18,1,1834, -135,2,0,1,166, -327,18,1,166,328, -20,329,4,20,76, -0,69,0,70,0, -84,0,95,0,65, -0,78,0,71,0, -76,0,69,0,1, -25,1,1,2,0, -1,1840,330,18,1, -1840,184,2,0,1, -2779,331,18,1,2779, -140,2,0,1,172, -332,18,1,172,184, -2,0,1,2785,333, -18,1,2785,159,2, -0,1,2786,334,18, -1,2786,335,20,336, -4,12,69,0,81, -0,85,0,65,0, -76,0,83,0,1, -15,1,1,2,0, -1,2335,337,18,1, -2335,146,2,0,1, -1296,338,18,1,1296, -176,2,0,1,1297, -339,18,1,1297,335, -2,0,1,2413,340, -18,1,2413,341,20, -342,4,26,83,0, -116,0,97,0,116, -0,101,0,109,0, -101,0,110,0,116, -0,76,0,105,0, -115,0,116,0,1, -134,1,2,2,0, -1,1859,343,18,1, -1859,162,2,0,1, -1860,344,18,1,1860, -150,2,0,1,188, -345,18,1,188,184, -2,0,1,182,346, -18,1,182,347,20, -348,4,22,82,0, -73,0,71,0,72, -0,84,0,95,0, -65,0,78,0,71, -0,76,0,69,0, -1,26,1,1,2, -0,1,199,349,18, -1,199,350,20,351, -4,10,67,0,65, -0,82,0,69,0, -84,0,1,35,1, -1,2,0,1,1871, -352,18,1,1871,176, -2,0,1,1872,353, -18,1,1872,162,2, -0,1,1873,354,18, -1,1873,150,2,0, -1,1875,355,18,1, -1875,324,2,0,1, -205,356,18,1,205, -184,2,0,1,2581, -357,18,1,2581,358, -20,359,4,10,69, -0,118,0,101,0, -110,0,116,0,1, -125,1,2,2,0, -1,2515,360,18,1, -2515,143,2,0,1, -1882,361,18,1,1882, -184,2,0,1,2227, -362,18,1,2227,288, -2,0,1,217,363, -18,1,217,364,20, -365,4,12,83,0, +2,2,0,1,85, +714,18,1,85,715, +20,716,4,26,83, +0,84,0,82,0, +79,0,75,0,69, +0,95,0,83,0, 84,0,82,0,79, 0,75,0,69,0, -1,34,1,1,2, -0,1,1332,366,18, -1,1332,176,2,0, -1,1335,367,18,1, -1335,179,2,0,1, -223,368,18,1,223, -184,2,0,1,2846, -369,18,1,2846,370, -23,371,4,6,69, -0,79,0,70,0, -1,2,1,6,2, -0,1,1341,372,18, -1,1341,184,2,0, -1,1901,373,18,1, -1901,162,2,0,1, -1303,374,18,1,1303, -184,2,0,1,2462, -375,18,1,2462,288, -2,0,1,236,376, -18,1,236,377,20, -378,4,6,65,0, -77,0,80,0,1, -33,1,1,2,0, -1,2466,379,18,1, -2466,380,20,381,4, -34,67,0,111,0, -109,0,112,0,111, -0,117,0,110,0, -100,0,83,0,116, -0,97,0,116,0, -101,0,109,0,101, -0,110,0,116,0, -1,133,1,2,2, -0,1,2467,382,18, -1,2467,159,2,0, -1,2468,383,18,1, -2468,384,20,385,4, -10,83,0,84,0, -65,0,84,0,69, -0,1,48,1,1, -2,0,1,2469,386, -18,1,2469,132,2, -0,1,242,387,18, -1,242,184,2,0, -1,2471,388,18,1, -2471,389,20,390,4, -26,67,0,79,0, -78,0,84,0,82, -0,79,0,76,0, -95,0,69,0,86, -0,69,0,78,0, -84,0,1,65,1, -1,2,0,1,2472, -391,18,1,2472,392, -20,393,4,30,65, -0,84,0,95,0, -84,0,65,0,82, -0,71,0,69,0, -84,0,95,0,69, -0,86,0,69,0, -78,0,84,0,1, -59,1,1,2,0, -1,2473,394,18,1, -2473,395,20,396,4, -38,65,0,84,0, -95,0,82,0,79, -0,84,0,95,0, -84,0,65,0,82, -0,71,0,69,0, -84,0,95,0,69, -0,86,0,69,0, -78,0,84,0,1, -58,1,1,2,0, -1,2474,397,18,1, -2474,398,20,399,4, +1,39,1,1,2, +0,1,2841,717,18, +1,2841,712,2,0, +1,1002,718,18,1, +1002,539,2,0,1, +82,719,18,1,82, +129,2,0,1,79, +720,18,1,79,721, +20,722,4,10,84, +0,73,0,76,0, +68,0,69,0,1, +36,1,1,2,0, +1,1859,723,18,1, +1859,138,2,0,1, +2834,724,18,1,2834, +583,2,0,1,76, +725,18,1,76,726, +20,727,4,20,76, +0,69,0,70,0, +84,0,95,0,83, +0,72,0,73,0, +70,0,84,0,1, +40,1,1,2,0, +1,2474,728,18,1, +2474,729,20,730,4, 52,76,0,65,0, 78,0,68,0,95, 0,67,0,79,0, @@ -3103,630 +4008,143 @@ public yyLSLSyntax 86,0,69,0,78, 0,84,0,1,71, 1,1,2,0,1, -2475,400,18,1,2475, -401,20,402,4,48, -76,0,65,0,78, -0,68,0,95,0, -67,0,79,0,76, -0,76,0,73,0, -83,0,73,0,79, -0,78,0,95,0, -69,0,78,0,68, -0,95,0,69,0, -86,0,69,0,78, -0,84,0,1,70, -1,1,2,0,1, -2476,403,18,1,2476, -404,20,405,4,40, -76,0,65,0,78, -0,68,0,95,0, -67,0,79,0,76, -0,76,0,73,0, -83,0,73,0,79, -0,78,0,95,0, -69,0,86,0,69, -0,78,0,84,0, -1,69,1,1,2, -0,1,2477,406,18, -1,2477,407,20,408, -4,34,84,0,79, -0,85,0,67,0, -72,0,95,0,83, -0,84,0,65,0, -82,0,84,0,95, -0,69,0,86,0, -69,0,78,0,84, -0,1,89,1,1, -2,0,1,2478,409, -18,1,2478,410,20, -411,4,30,84,0, -79,0,85,0,67, -0,72,0,95,0, -69,0,78,0,68, -0,95,0,69,0, -86,0,69,0,78, -0,84,0,1,90, -1,1,2,0,1, -2479,412,18,1,2479, -413,20,414,4,22, -84,0,79,0,85, -0,67,0,72,0, -95,0,69,0,86, -0,69,0,78,0, -84,0,1,88,1, -1,2,0,1,2480, -415,18,1,2480,416, -20,417,4,24,83, -0,69,0,78,0, -83,0,79,0,82, -0,95,0,69,0, -86,0,69,0,78, -0,84,0,1,84, -1,1,2,0,1, -2481,418,18,1,2481, -419,20,420,4,52, -82,0,85,0,78, +74,731,18,1,74, +138,2,0,1,73, +732,18,1,73,129, +2,0,1,2578,733, +18,1,2578,138,2, +0,1,71,734,18, +1,71,116,2,0, +1,70,735,18,1, +70,545,2,0,1, +69,736,18,1,69, +551,2,0,1,68, +737,18,1,68,545, +2,0,1,67,738, +18,1,67,551,2, +0,1,66,739,18, +1,66,160,2,0, +1,65,740,18,1, +65,434,2,0,1, +63,741,18,1,63, +160,2,0,1,62, +742,18,1,62,138, +2,0,1,61,743, +18,1,61,744,20, +745,4,16,84,0, +121,0,112,0,101, +0,110,0,97,0, +109,0,101,0,1, +124,1,2,2,0, +1,2811,746,18,1, +2811,110,2,0,1, +52,747,18,1,52, +116,2,0,1,51, +748,18,1,51,545, +2,0,1,50,749, +18,1,50,551,2, +0,1,49,750,18, +1,49,545,2,0, +1,48,751,18,1, +48,551,2,0,1, +47,752,18,1,47, +160,2,0,1,46, +753,18,1,46,434, +2,0,1,44,754, +18,1,44,160,2, +0,1,43,755,18, +1,43,756,20,757, +4,22,82,0,73, +0,71,0,72,0, +84,0,95,0,83, +0,72,0,73,0, +70,0,84,0,1, +41,1,1,2,0, +1,42,758,18,1, +42,129,2,0,1, +41,759,18,1,41, +116,2,0,1,40, +760,18,1,40,160, +2,0,1,2510,761, +18,1,2510,224,2, +0,1,1876,762,18, +1,1876,116,2,0, +1,1875,763,18,1, +1875,119,2,0,1, +1873,764,18,1,1873, +110,2,0,1,1872, +765,18,1,1872,138, +2,0,1,1871,766, +18,1,1871,107,2, +0,1,32,767,18, +1,32,150,2,0, +1,31,768,18,1, +31,138,2,0,1, +30,769,18,1,30, +274,2,0,1,2786, +770,18,1,2786,271, +2,0,1,2785,771, +18,1,2785,274,2, +0,1,2783,772,18, +1,2783,201,2,0, +1,2781,773,18,1, +2781,138,2,0,1, +942,774,18,1,942, +129,2,0,1,1860, +775,18,1,1860,110, +2,0,1,21,776, +18,1,21,147,2, +0,1,20,777,18, +1,20,205,2,0, +1,19,778,18,1, +19,160,2,0,1, +18,779,18,1,18, +744,2,0,1,2770, +780,18,1,2770,116, +2,0,1,2769,781, +18,1,2769,160,2, +0,1,2768,782,18, +1,2768,193,2,0, +1,10,783,18,1, +10,116,2,0,1, +9,784,18,1,9, +160,2,0,1,8, +785,18,1,8,744, +2,0,1,7,786, +18,1,7,309,2, +0,1,6,787,18, +1,6,788,20,789, +4,20,70,0,76, +0,79,0,65,0, +84,0,95,0,84, +0,89,0,80,0, +69,0,1,52,1, +1,2,0,1,5, +790,18,1,5,791, +20,792,4,22,83, +0,84,0,82,0, +73,0,78,0,71, 0,95,0,84,0, -73,0,77,0,69, -0,95,0,80,0, -69,0,82,0,77, -0,73,0,83,0, -83,0,73,0,79, -0,78,0,83,0, -95,0,69,0,86, -0,69,0,78,0, -84,0,1,83,1, -1,2,0,1,2482, -421,18,1,2482,422, -20,423,4,24,79, -0,78,0,95,0, -82,0,69,0,90, -0,95,0,69,0, -86,0,69,0,78, -0,84,0,1,81, -1,1,2,0,1, -2483,424,18,1,2483, -425,20,426,4,42, -67,0,79,0,76, -0,76,0,73,0, -83,0,73,0,79, -0,78,0,95,0, -83,0,84,0,65, -0,82,0,84,0, -95,0,69,0,86, -0,69,0,78,0, -84,0,1,64,1, -1,2,0,1,256, -427,18,1,256,428, -20,429,4,14,80, -0,69,0,82,0, -67,0,69,0,78, -0,84,0,1,22, -1,1,2,0,1, -1371,430,18,1,1371, -235,2,0,1,2486, -431,18,1,2486,432, -20,433,4,26,67, -0,72,0,65,0, -78,0,71,0,69, -0,68,0,95,0, -69,0,86,0,69, -0,78,0,84,0, -1,61,1,1,2, -0,1,2487,434,18, -1,2487,435,20,436, -4,32,79,0,66, -0,74,0,69,0, -67,0,84,0,95, -0,82,0,69,0, -90,0,95,0,69, -0,86,0,69,0, -78,0,84,0,1, -80,1,1,2,0, -1,1931,437,18,1, -1931,288,2,0,1, -1932,438,18,1,1932, -439,20,440,4,4, -73,0,70,0,1, -42,1,1,2,0, -1,262,441,18,1, -262,184,2,0,1, -1377,442,18,1,1377, -184,2,0,1,2492, -443,18,1,2492,444, -20,445,4,30,78, -0,79,0,95,0, -83,0,69,0,78, -0,83,0,79,0, -82,0,95,0,69, -0,86,0,69,0, -78,0,84,0,1, -77,1,1,2,0, -1,1876,446,18,1, -1876,135,2,0,1, -2494,447,18,1,2494, -448,20,449,4,32, -77,0,79,0,86, -0,73,0,78,0, -71,0,95,0,69, -0,78,0,68,0, -95,0,69,0,86, -0,69,0,78,0, -84,0,1,75,1, -1,2,0,1,2495, -450,18,1,2495,451, -20,452,4,32,83, -0,84,0,65,0, -84,0,69,0,95, -0,69,0,88,0, -73,0,84,0,95, -0,69,0,86,0, -69,0,78,0,84, -0,1,86,1,1, -2,0,1,1939,453, -18,1,1939,184,2, -0,1,2497,454,18, -1,2497,455,20,456, -4,48,84,0,82, -0,65,0,78,0, -83,0,65,0,67, -0,84,0,73,0, -79,0,78,0,95, -0,82,0,69,0, -83,0,85,0,76, +89,0,80,0,69, +0,1,53,1,1, +2,0,1,4,793, +18,1,4,315,2, +0,1,3,794,18, +1,3,291,2,0, +1,2,795,18,1, +2,268,2,0,1, +1,796,18,1,1, +797,20,798,4,18, +76,0,73,0,83, 0,84,0,95,0, -69,0,86,0,69, -0,78,0,84,0, -1,92,1,1,2, -0,1,827,457,18, -1,827,184,2,0, -1,2499,458,18,1, -2499,459,20,460,4, -34,82,0,69,0, -77,0,79,0,84, -0,69,0,95,0, -68,0,65,0,84, -0,65,0,95,0, -69,0,86,0,69, -0,78,0,84,0, -1,82,1,1,2, -0,1,2500,461,18, -1,2500,462,20,463, -4,22,77,0,79, -0,78,0,69,0, -89,0,95,0,69, -0,86,0,69,0, -78,0,84,0,1, -74,1,1,2,0, -1,2501,464,18,1, -2501,465,20,466,4, -24,76,0,73,0, -83,0,84,0,69, -0,78,0,95,0, -69,0,86,0,69, -0,78,0,84,0, -1,73,1,1,2, -0,1,2502,467,18, -1,2502,468,20,469, -4,36,76,0,73, -0,78,0,75,0, -95,0,77,0,69, -0,83,0,83,0, -65,0,71,0,69, -0,95,0,69,0, -86,0,69,0,78, -0,84,0,1,72, +84,0,89,0,80, +0,69,0,1,57, 1,1,2,0,1, -2503,470,18,1,2503, -471,20,472,4,38, -72,0,84,0,84, -0,80,0,95,0, -82,0,69,0,83, -0,80,0,79,0, -78,0,83,0,69, -0,95,0,69,0, -86,0,69,0,78, -0,84,0,1,68, -1,1,2,0,1, -2504,473,18,1,2504, -474,20,475,4,22, -69,0,77,0,65, -0,73,0,76,0, -95,0,69,0,86, -0,69,0,78,0, -84,0,1,67,1, -1,2,0,1,277, -476,18,1,277,477, -20,478,4,10,83, -0,76,0,65,0, -83,0,72,0,1, -21,1,1,2,0, -1,2506,479,18,1, -2506,480,20,481,4, -34,75,0,101,0, -121,0,73,0,110, -0,116,0,73,0, -110,0,116,0,65, -0,114,0,103,0, -69,0,118,0,101, -0,110,0,116,0, -1,132,1,2,2, -0,1,2507,482,18, -1,2507,135,2,0, -1,2508,483,18,1, -2508,117,2,0,1, -2509,484,18,1,2509, -132,2,0,1,2510, -485,18,1,2510,486, -20,487,4,28,75, -0,101,0,121,0, -68,0,101,0,99, -0,108,0,97,0, -114,0,97,0,116, -0,105,0,111,0, -110,0,1,120,1, -2,2,0,1,283, -488,18,1,283,184, -2,0,1,2512,489, -18,1,2512,126,2, -0,1,2513,490,18, -1,2513,132,2,0, -1,2514,491,18,1, -2514,492,20,493,4, -28,73,0,110,0, -116,0,68,0,101, -0,99,0,108,0, -97,0,114,0,97, -0,116,0,105,0, -111,0,110,0,1, -121,1,2,2,0, -1,1958,494,18,1, -1958,162,2,0,1, -2517,495,18,1,2517, -492,2,0,1,2518, -496,18,1,2518,497, -20,498,4,64,75, -0,101,0,121,0, -73,0,110,0,116, -0,73,0,110,0, -116,0,65,0,114, -0,103,0,117,0, -109,0,101,0,110, -0,116,0,68,0, -101,0,99,0,108, -0,97,0,114,0, -97,0,116,0,105, -0,111,0,110,0, -76,0,105,0,115, -0,116,0,1,118, -1,2,2,0,1, -2519,499,18,1,2519, -162,2,0,1,1406, -500,18,1,1406,176, -2,0,1,1407,501, -18,1,1407,229,2, -0,1,2522,502,18, -1,2522,503,20,504, -4,34,73,0,110, -0,116,0,86,0, -101,0,99,0,86, -0,101,0,99,0, -65,0,114,0,103, -0,69,0,118,0, -101,0,110,0,116, -0,1,131,1,2, -2,0,1,2523,505, -18,1,2523,135,2, -0,1,2525,506,18, -1,2525,492,2,0, -1,2526,507,18,1, -2526,143,2,0,1, -299,508,18,1,299, -509,20,510,4,8, -83,0,84,0,65, -0,82,0,1,20, -1,1,2,0,1, -1370,511,18,1,1370, -176,2,0,1,2529, -512,18,1,2529,513, -20,514,4,28,86, -0,101,0,99,0, -68,0,101,0,99, -0,108,0,97,0, -114,0,97,0,116, -0,105,0,111,0, -110,0,1,122,1, -2,2,0,1,2530, -515,18,1,2530,143, -2,0,1,2532,516, -18,1,2532,513,2, -0,1,305,517,18, -1,305,184,2,0, -1,2534,518,18,1, -2534,162,2,0,1, -2822,519,18,1,2822, -150,2,0,1,2458, -520,18,1,2458,288, -2,0,1,2459,521, -18,1,2459,212,2, -0,1,2538,522,18, -1,2538,135,2,0, -1,2540,523,18,1, -2540,492,2,0,1, -2541,524,18,1,2541, -143,2,0,1,2542, -525,18,1,2542,111, -2,0,1,2464,526, -18,1,2464,212,2, -0,1,2544,527,18, -1,2544,247,2,0, -1,2545,528,18,1, -2545,143,2,0,1, -1989,529,18,1,1989, -288,2,0,1,1990, -530,18,1,1990,531, -20,532,4,8,69, -0,76,0,83,0, -69,0,1,43,1, -1,2,0,1,2548, -533,18,1,2548,534, -20,535,4,64,73, -0,110,0,116,0, -82,0,111,0,116, -0,82,0,111,0, -116,0,65,0,114, -0,103,0,117,0, -109,0,101,0,110, -0,116,0,68,0, -101,0,99,0,108, -0,97,0,114,0, -97,0,116,0,105, -0,111,0,110,0, -76,0,105,0,115, -0,116,0,1,116, -1,2,2,0,1, -2470,536,18,1,2470, -165,2,0,1,322, -537,18,1,322,250, -2,0,1,2551,538, -18,1,2551,380,2, -0,1,1933,539,18, -1,1933,135,2,0, -1,2553,540,18,1, -2553,135,2,0,1, -883,541,18,1,883, -184,2,0,1,2555, -542,18,1,2555,513, -2,0,1,328,543, -18,1,328,184,2, -0,1,1443,544,18, -1,1443,266,2,0, -1,2559,545,18,1, -2559,380,2,0,1, -2560,546,18,1,2560, -547,20,548,4,22, -73,0,110,0,116, -0,65,0,114,0, -103,0,69,0,118, -0,101,0,110,0, -116,0,1,128,1, -2,2,0,1,2561, -549,18,1,2561,135, -2,0,1,1449,550, -18,1,1449,184,2, -0,1,2485,551,18, -1,2485,552,20,553, -4,30,67,0,79, -0,76,0,76,0, -73,0,83,0,73, -0,79,0,78,0, -95,0,69,0,86, -0,69,0,78,0, -84,0,1,62,1, -1,2,0,1,2565, -554,18,1,2565,162, -2,0,1,2488,555, -18,1,2488,556,20, -557,4,24,65,0, -84,0,84,0,65, -0,67,0,72,0, -95,0,69,0,86, -0,69,0,78,0, -84,0,1,60,1, -1,2,0,1,2489, -558,18,1,2489,559, -20,560,4,22,84, -0,73,0,77,0, -69,0,82,0,95, -0,69,0,86,0, -69,0,78,0,84, -0,1,87,1,1, -2,0,1,2490,561, -18,1,2490,562,20, -563,4,38,78,0, -79,0,84,0,95, -0,65,0,84,0, -95,0,84,0,65, -0,82,0,71,0, -69,0,84,0,95, -0,69,0,86,0, -69,0,78,0,84, -0,1,79,1,1, -2,0,1,2491,564, -18,1,2491,565,20, -566,4,46,78,0, -79,0,84,0,95, -0,65,0,84,0, -95,0,82,0,79, -0,84,0,95,0, -84,0,65,0,82, -0,71,0,69,0, -84,0,95,0,69, -0,86,0,69,0, -78,0,84,0,1, -78,1,1,2,0, -1,2571,567,18,1, -2571,486,2,0,1, -2493,568,18,1,2493, -569,20,570,4,36, -77,0,79,0,86, -0,73,0,78,0, -71,0,95,0,83, -0,84,0,65,0, -82,0,84,0,95, -0,69,0,86,0, -69,0,78,0,84, -0,1,76,1,1, -2,0,1,1413,571, -18,1,1413,184,2, -0,1,346,572,18, -1,346,573,20,574, -4,8,80,0,76, -0,85,0,83,0, -1,18,1,1,2, -0,1,2575,575,18, -1,2575,380,2,0, -1,2496,576,18,1, -2496,577,20,578,4, -34,83,0,84,0, -65,0,84,0,69, -0,95,0,69,0, -78,0,84,0,82, -0,89,0,95,0, -69,0,86,0,69, -0,78,0,84,0, -1,85,1,1,2, -0,1,2577,579,18, -1,2577,135,2,0, -1,2021,580,18,1, -2021,288,2,0,1, -2022,581,18,1,2022, -384,2,0,1,352, -582,18,1,352,184, -2,0,1,2024,583, -18,1,2024,132,2, -0,1,2025,584,18, -1,2025,585,20,586, -4,8,74,0,85, -0,77,0,80,0, -1,49,1,1,2, -0,1,2026,587,18, -1,2026,132,2,0, -1,2027,588,18,1, -2027,589,20,590,4, -4,65,0,84,0, -1,23,1,1,2, -0,1,2028,591,18, -1,2028,132,2,0, -1,2029,592,18,1, -2029,380,2,0,1, -2030,593,18,1,2030, -594,20,595,4,14, -70,0,111,0,114, -0,76,0,111,0, -111,0,112,0,1, -146,1,2,2,0, -1,2031,596,18,1, -2031,597,20,598,4, -32,68,0,111,0, -87,0,104,0,105, -0,108,0,101,0, -83,0,116,0,97, -0,116,0,101,0, -109,0,101,0,110, -0,116,0,1,145, -1,2,2,0,1, -2032,599,18,1,2032, -600,20,601,4,28, -87,0,104,0,105, -0,108,0,101,0, -83,0,116,0,97, -0,116,0,101,0, -109,0,101,0,110, -0,116,0,1,144, -1,2,2,0,1, -2033,602,18,1,2033, -603,20,604,4,22, -73,0,102,0,83, -0,116,0,97,0, -116,0,101,0,109, -0,101,0,110,0, -116,0,1,143,1, -2,2,0,1,2034, -605,18,1,2034,606, -20,607,4,22,83, -0,116,0,97,0, -116,0,101,0,67, -0,104,0,97,0, -110,0,103,0,101, -0,1,142,1,2, -2,0,1,1478,608, -18,1,1478,176,2, -0,1,1479,609,18, -1,1479,309,2,0, -1,2037,610,18,1, -2037,150,2,0,1, -2038,611,18,1,2038, -612,20,613,4,18, -74,0,117,0,109, -0,112,0,76,0, -97,0,98,0,101, -0,108,0,1,140, -1,2,2,0,1, -2039,614,18,1,2039, -150,2,0,1,2040, -615,18,1,2040,616, -20,617,4,30,82, -0,101,0,116,0, -117,0,114,0,110, -0,83,0,116,0, -97,0,116,0,101, -0,109,0,101,0, -110,0,116,0,1, -139,1,2,2,0, -1,2041,618,18,1, -2041,150,2,0,1, -1485,619,18,1,1485, -184,2,0,1,372, -620,18,1,372,196, -2,0,1,373,621, -18,1,373,132,2, -0,1,374,622,18, -1,374,192,2,0, -1,375,623,18,1, -375,132,2,0,1, -376,624,18,1,376, -199,2,0,1,377, -625,18,1,377,132, -2,0,1,378,626, -18,1,378,192,2, -0,1,379,627,18, -1,379,132,2,0, -1,380,628,18,1, -380,629,20,630,4, -16,67,0,111,0, -110,0,115,0,116, -0,97,0,110,0, -116,0,1,152,1, -2,2,0,1,381, -631,18,1,381,328, -2,0,1,371,632, -18,1,371,633,20, -634,4,24,70,0, -117,0,110,0,99, -0,116,0,105,0, -111,0,110,0,67, -0,97,0,108,0, -108,0,1,148,1, -2,2,0,1,942, -635,18,1,942,184, -2,0,1,2533,636, -18,1,2533,637,20, -638,4,64,73,0, -110,0,116,0,86, -0,101,0,99,0, -86,0,101,0,99, -0,65,0,114,0, +0,799,18,1,0, +0,2,0,800,5, +0,801,5,381,1, +383,802,19,803,4, +50,65,0,114,0, 103,0,117,0,109, 0,101,0,110,0, 116,0,68,0,101, @@ -3735,1567 +4153,524 @@ public yyLSLSyntax 0,116,0,105,0, 111,0,110,0,76, 0,105,0,115,0, -116,0,1,117,1, -2,2,0,1,387, -639,18,1,387,184, -2,0,1,2536,640, -18,1,2536,380,2, -0,1,2537,641,18, -1,2537,642,20,643, -4,34,73,0,110, -0,116,0,82,0, -111,0,116,0,82, -0,111,0,116,0, -65,0,114,0,103, -0,69,0,118,0, -101,0,110,0,116, -0,1,130,1,2, -2,0,1,2543,644, -18,1,2543,132,2, -0,1,2823,645,18, -1,2823,646,20,647, -4,34,71,0,108, -0,111,0,98,0, -97,0,108,0,68, -0,101,0,102,0, -105,0,110,0,105, +116,0,95,0,53, +0,1,383,804,5, +3,1,2582,805,16, +0,204,1,2770,806, +16,0,482,1,10, +807,16,0,777,1, +382,808,19,809,4, +50,65,0,114,0, +103,0,117,0,109, +0,101,0,110,0, +116,0,68,0,101, +0,99,0,108,0, +97,0,114,0,97, 0,116,0,105,0, -111,0,110,0,115, -0,1,98,1,2, -2,0,1,1514,648, -18,1,1514,176,2, -0,1,1515,649,18, -1,1515,335,2,0, -1,2549,650,18,1, -2549,162,2,0,1, -2074,651,18,1,2074, -176,2,0,1,2075, -652,18,1,2075,162, -2,0,1,2552,653, -18,1,2552,654,20, -655,4,28,86,0, +111,0,110,0,76, +0,105,0,115,0, +116,0,95,0,52, +0,1,382,804,1, +381,810,19,811,4, +28,65,0,114,0, +103,0,117,0,109, +0,101,0,110,0, +116,0,76,0,105, +0,115,0,116,0, +95,0,52,0,1, +381,812,5,2,1, +41,813,16,0,669, +1,459,814,16,0, +131,1,380,815,19, +816,4,28,65,0, +114,0,103,0,117, +0,109,0,101,0, +110,0,116,0,76, +0,105,0,115,0, +116,0,95,0,51, +0,1,380,812,1, +379,817,19,818,4, +50,65,0,114,0, +103,0,117,0,109, +0,101,0,110,0, +116,0,68,0,101, +0,99,0,108,0, +97,0,114,0,97, +0,116,0,105,0, +111,0,110,0,76, +0,105,0,115,0, +116,0,95,0,51, +0,1,379,804,1, +378,819,19,820,4, +38,75,0,101,0, +121,0,73,0,110, +0,116,0,73,0, +110,0,116,0,65, +0,114,0,103,0, +69,0,118,0,101, +0,110,0,116,0, +95,0,49,0,1, +378,821,5,4,1, +2659,822,16,0,318, +1,2470,823,16,0, +318,1,2703,824,16, +0,318,1,2597,825, +16,0,318,1,377, +826,19,827,4,38, +73,0,110,0,116, +0,86,0,101,0, +99,0,86,0,101, +0,99,0,65,0, +114,0,103,0,69, +0,118,0,101,0, +110,0,116,0,95, +0,49,0,1,377, +828,5,4,1,2659, +829,16,0,296,1, +2470,830,16,0,296, +1,2703,831,16,0, +296,1,2597,832,16, +0,296,1,376,833, +19,834,4,38,73, +0,110,0,116,0, +82,0,111,0,116, +0,82,0,111,0, +116,0,65,0,114, +0,103,0,69,0, +118,0,101,0,110, +0,116,0,95,0, +49,0,1,376,835, +5,4,1,2659,836, +16,0,278,1,2470, +837,16,0,278,1, +2703,838,16,0,278, +1,2597,839,16,0, +278,1,375,840,19, +841,4,32,86,0, 101,0,99,0,116, 0,111,0,114,0, 65,0,114,0,103, 0,69,0,118,0, 101,0,110,0,116, -0,1,129,1,2, -2,0,1,406,656, -18,1,406,143,2, -0,1,1521,657,18, -1,1521,184,2,0, -1,2556,658,18,1, -2556,659,20,660,4, -58,86,0,101,0, +0,95,0,51,0, +1,375,842,5,4, +1,2659,843,16,0, +469,1,2470,844,16, +0,469,1,2703,845, +16,0,469,1,2597, +846,16,0,469,1, +374,847,19,848,4, +32,86,0,101,0, 99,0,116,0,111, 0,114,0,65,0, -114,0,103,0,117, -0,109,0,101,0, -110,0,116,0,68, -0,101,0,99,0, -108,0,97,0,114, -0,97,0,116,0, -105,0,111,0,110, -0,76,0,105,0, -115,0,116,0,1, -115,1,2,2,0, -1,2557,661,18,1, -2557,162,2,0,1, -412,662,18,1,412, -184,2,0,1,2641, -663,18,1,2641,168, -2,0,1,2484,664, -18,1,2484,665,20, -666,4,38,67,0, -79,0,76,0,76, -0,73,0,83,0, -73,0,79,0,78, -0,95,0,69,0, -78,0,68,0,95, -0,69,0,86,0, -69,0,78,0,84, -0,1,63,1,1, -2,0,1,2643,667, -18,1,2643,668,20, -669,4,44,73,0, -110,0,116,0,82, -0,111,0,116,0, -82,0,111,0,116, -0,65,0,114,0, -103,0,83,0,116, -0,97,0,116,0, -101,0,69,0,118, -0,101,0,110,0, -116,0,1,109,1, -2,2,0,1,2644, -670,18,1,2644,671, -20,672,4,38,86, -0,101,0,99,0, -116,0,111,0,114, -0,65,0,114,0, -103,0,83,0,116, -0,97,0,116,0, -101,0,69,0,118, -0,101,0,110,0, -116,0,1,108,1, -2,2,0,1,2023, -673,18,1,2023,282, -2,0,1,2564,674, -18,1,2564,675,20, -676,4,52,73,0, -110,0,116,0,65, -0,114,0,103,0, -117,0,109,0,101, -0,110,0,116,0, -68,0,101,0,99, -0,108,0,97,0, -114,0,97,0,116, -0,105,0,111,0, -110,0,76,0,105, -0,115,0,116,0, -1,114,1,2,2, -0,1,2647,677,18, -1,2647,678,20,679, -4,34,86,0,111, -0,105,0,100,0, +114,0,103,0,69, +0,118,0,101,0, +110,0,116,0,95, +0,50,0,1,374, +842,1,373,849,19, +850,4,32,86,0, +101,0,99,0,116, +0,111,0,114,0, 65,0,114,0,103, -0,83,0,116,0, -97,0,116,0,101, 0,69,0,118,0, 101,0,110,0,116, -0,1,105,1,2, -2,0,1,2648,680, -18,1,2648,279,2, -0,1,2567,681,18, -1,2567,380,2,0, -1,1442,682,18,1, -1442,176,2,0,1, -2569,683,18,1,2569, -135,2,0,1,2652, -684,18,1,2652,668, -2,0,1,2653,685, -18,1,2653,671,2, -0,1,2572,686,18, -1,2572,687,20,688, -4,52,75,0,101, -0,121,0,65,0, +0,95,0,49,0, +1,373,842,1,372, +851,19,852,4,28, +73,0,110,0,116, +0,65,0,114,0, +103,0,69,0,118, +0,101,0,110,0, +116,0,95,0,49, +0,48,0,1,372, +853,5,4,1,2659, +854,16,0,239,1, +2470,855,16,0,239, +1,2703,856,16,0, +239,1,2597,857,16, +0,239,1,371,858, +19,859,4,26,73, +0,110,0,116,0, +65,0,114,0,103, +0,69,0,118,0, +101,0,110,0,116, +0,95,0,57,0, +1,371,853,1,370, +860,19,861,4,26, +73,0,110,0,116, +0,65,0,114,0, +103,0,69,0,118, +0,101,0,110,0, +116,0,95,0,56, +0,1,370,853,1, +369,862,19,863,4, +26,73,0,110,0, +116,0,65,0,114, +0,103,0,69,0, +118,0,101,0,110, +0,116,0,95,0, +55,0,1,369,853, +1,368,864,19,865, +4,26,73,0,110, +0,116,0,65,0, +114,0,103,0,69, +0,118,0,101,0, +110,0,116,0,95, +0,54,0,1,368, +853,1,367,866,19, +867,4,26,73,0, +110,0,116,0,65, +0,114,0,103,0, +69,0,118,0,101, +0,110,0,116,0, +95,0,53,0,1, +367,853,1,366,868, +19,869,4,26,73, +0,110,0,116,0, +65,0,114,0,103, +0,69,0,118,0, +101,0,110,0,116, +0,95,0,52,0, +1,366,853,1,365, +870,19,871,4,26, +73,0,110,0,116, +0,65,0,114,0, +103,0,69,0,118, +0,101,0,110,0, +116,0,95,0,51, +0,1,365,853,1, +364,872,19,873,4, +26,73,0,110,0, +116,0,65,0,114, +0,103,0,69,0, +118,0,101,0,110, +0,116,0,95,0, +50,0,1,364,853, +1,363,874,19,875, +4,26,73,0,110, +0,116,0,65,0, +114,0,103,0,69, +0,118,0,101,0, +110,0,116,0,95, +0,49,0,1,363, +853,1,362,876,19, +877,4,26,75,0, +101,0,121,0,65, +0,114,0,103,0, +69,0,118,0,101, +0,110,0,116,0, +95,0,50,0,1, +362,878,5,4,1, +2659,879,16,0,227, +1,2470,880,16,0, +227,1,2703,881,16, +0,227,1,2597,882, +16,0,227,1,361, +883,19,884,4,26, +75,0,101,0,121, +0,65,0,114,0, +103,0,69,0,118, +0,101,0,110,0, +116,0,95,0,49, +0,1,361,878,1, +360,885,19,886,4, +28,86,0,111,0, +105,0,100,0,65, +0,114,0,103,0, +69,0,118,0,101, +0,110,0,116,0, +95,0,56,0,1, +360,887,5,4,1, +2659,888,16,0,443, +1,2470,889,16,0, +443,1,2703,890,16, +0,443,1,2597,891, +16,0,443,1,359, +892,19,893,4,28, +86,0,111,0,105, +0,100,0,65,0, +114,0,103,0,69, +0,118,0,101,0, +110,0,116,0,95, +0,55,0,1,359, +887,1,358,894,19, +895,4,28,86,0, +111,0,105,0,100, +0,65,0,114,0, +103,0,69,0,118, +0,101,0,110,0, +116,0,95,0,54, +0,1,358,887,1, +357,896,19,897,4, +28,86,0,111,0, +105,0,100,0,65, +0,114,0,103,0, +69,0,118,0,101, +0,110,0,116,0, +95,0,53,0,1, +357,887,1,356,898, +19,899,4,28,86, +0,111,0,105,0, +100,0,65,0,114, +0,103,0,69,0, +118,0,101,0,110, +0,116,0,95,0, +52,0,1,356,887, +1,355,900,19,901, +4,28,86,0,111, +0,105,0,100,0, +65,0,114,0,103, +0,69,0,118,0, +101,0,110,0,116, +0,95,0,51,0, +1,355,887,1,354, +902,19,903,4,28, +86,0,111,0,105, +0,100,0,65,0, +114,0,103,0,69, +0,118,0,101,0, +110,0,116,0,95, +0,50,0,1,354, +887,1,353,904,19, +905,4,28,86,0, +111,0,105,0,100, +0,65,0,114,0, +103,0,69,0,118, +0,101,0,110,0, +116,0,95,0,49, +0,1,353,887,1, +352,906,19,907,4, +14,69,0,118,0, +101,0,110,0,116, +0,95,0,57,0, +1,352,908,5,4, +1,2659,909,16,0, +209,1,2470,910,16, +0,209,1,2703,911, +16,0,209,1,2597, +912,16,0,209,1, +351,913,19,914,4, +14,69,0,118,0, +101,0,110,0,116, +0,95,0,56,0, +1,351,908,1,350, +915,19,916,4,14, +69,0,118,0,101, +0,110,0,116,0, +95,0,55,0,1, +350,908,1,349,917, +19,918,4,14,69, +0,118,0,101,0, +110,0,116,0,95, +0,54,0,1,349, +908,1,348,919,19, +920,4,14,69,0, +118,0,101,0,110, +0,116,0,95,0, +53,0,1,348,908, +1,347,921,19,922, +4,14,69,0,118, +0,101,0,110,0, +116,0,95,0,52, +0,1,347,908,1, +346,923,19,924,4, +14,69,0,118,0, +101,0,110,0,116, +0,95,0,51,0, +1,346,908,1,345, +925,19,926,4,14, +69,0,118,0,101, +0,110,0,116,0, +95,0,50,0,1, +345,908,1,344,927, +19,928,4,14,69, +0,118,0,101,0, +110,0,116,0,95, +0,49,0,1,344, +908,1,343,929,19, +930,4,20,84,0, +121,0,112,0,101, +0,110,0,97,0, +109,0,101,0,95, +0,55,0,1,343, +931,5,18,1,1775, +932,16,0,779,1, +2106,933,16,0,779, +1,32,934,16,0, +779,1,1990,935,16, +0,779,1,1804,936, +16,0,779,1,2582, +937,16,0,779,1, +21,938,16,0,779, +1,2198,939,16,0, +779,1,1901,940,16, +0,779,1,10,941, +16,0,779,1,2823, +942,16,0,785,1, +2770,943,16,0,779, +1,1958,944,16,0, +779,1,52,945,16, +0,743,1,2337,946, +16,0,779,1,2075, +947,16,0,779,1, +2413,948,16,0,779, +1,0,949,16,0, +785,1,342,950,19, +951,4,20,84,0, +121,0,112,0,101, +0,110,0,97,0, +109,0,101,0,95, +0,54,0,1,342, +931,1,341,952,19, +953,4,20,84,0, +121,0,112,0,101, +0,110,0,97,0, +109,0,101,0,95, +0,53,0,1,341, +931,1,340,954,19, +955,4,20,84,0, +121,0,112,0,101, +0,110,0,97,0, +109,0,101,0,95, +0,52,0,1,340, +931,1,339,956,19, +957,4,20,84,0, +121,0,112,0,101, +0,110,0,97,0, +109,0,101,0,95, +0,51,0,1,339, +931,1,338,958,19, +959,4,20,84,0, +121,0,112,0,101, +0,110,0,97,0, +109,0,101,0,95, +0,50,0,1,338, +931,1,337,960,19, +961,4,20,84,0, +121,0,112,0,101, +0,110,0,97,0, +109,0,101,0,95, +0,49,0,1,337, +931,1,336,962,19, +963,4,40,69,0, +120,0,112,0,114, +0,101,0,115,0, +115,0,105,0,111, +0,110,0,65,0, 114,0,103,0,117, 0,109,0,101,0, -110,0,116,0,68, -0,101,0,99,0, -108,0,97,0,114, -0,97,0,116,0, -105,0,111,0,110, -0,76,0,105,0, -115,0,116,0,1, -113,1,2,2,0, -1,2573,689,18,1, -2573,162,2,0,1, -2656,690,18,1,2656, -678,2,0,1,2035, -691,18,1,2035,150, -2,0,1,2036,692, -18,1,2036,693,20, -694,4,26,74,0, -117,0,109,0,112, -0,83,0,116,0, -97,0,116,0,101, -0,109,0,101,0, -110,0,116,0,1, -141,1,2,2,0, -1,431,695,18,1, -431,143,2,0,1, -2578,696,18,1,2578, -162,2,0,1,2105, -697,18,1,2105,288, -2,0,1,2106,698, -18,1,2106,531,2, -0,1,1550,699,18, -1,1550,176,2,0, -1,437,700,18,1, -437,184,2,0,1, -2044,701,18,1,2044, -702,20,703,4,28, -69,0,109,0,112, -0,116,0,121,0, -83,0,116,0,97, -0,116,0,101,0, -109,0,101,0,110, -0,116,0,1,136, -1,2,2,0,1, -2045,704,18,1,2045, -150,2,0,1,1555, -705,18,1,1555,184, -2,0,1,2511,706, -18,1,2511,143,2, -0,1,1001,707,18, -1,1001,633,2,0, -1,1002,708,18,1, -1002,629,2,0,1, -447,709,18,1,447, -347,2,0,1,2593, -710,18,1,2593,162, -2,0,1,2595,711, -18,1,2595,380,2, -0,1,2597,712,18, -1,2597,713,20,714, -4,18,83,0,116, -0,97,0,116,0, -101,0,66,0,111, -0,100,0,121,0, -1,103,1,2,2, -0,1,1010,715,18, -1,1010,176,2,0, -1,1011,716,18,1, -1011,162,2,0,1, -1012,717,18,1,1012, -184,2,0,1,1013, -718,18,1,1013,162, -2,0,1,459,719, -18,1,459,720,20, -721,4,24,76,0, -69,0,70,0,84, -0,95,0,66,0, -82,0,65,0,67, -0,75,0,69,0, -84,0,1,27,1, -1,2,0,1,1574, -722,18,1,1574,150, -2,0,1,461,723, -18,1,461,724,20, -725,4,24,65,0, +110,0,116,0,95, +0,49,0,1,336, +964,5,3,1,41, +965,16,0,483,1, +459,966,16,0,483, +1,462,967,16,0, +502,1,335,968,19, +969,4,28,65,0, 114,0,103,0,117, 0,109,0,101,0, 110,0,116,0,76, 0,105,0,115,0, -116,0,1,149,1, -2,2,0,1,462, -726,18,1,462,143, -2,0,1,464,727, -18,1,464,728,20, -729,4,16,65,0, -114,0,103,0,117, -0,109,0,101,0, -110,0,116,0,1, -150,1,2,2,0, -1,2136,730,18,1, -2136,288,2,0,1, -1585,731,18,1,1585, -732,20,733,4,12, -82,0,69,0,84, -0,85,0,82,0, -78,0,1,50,1, -1,2,0,1,2703, -734,18,1,2703,713, -2,0,1,476,735, -18,1,476,736,20, -737,4,30,83,0, -84,0,82,0,73, -0,78,0,71,0, -95,0,67,0,79, -0,78,0,83,0, -84,0,65,0,78, -0,84,0,1,3, -1,1,2,0,1, -477,738,18,1,477, -739,20,740,4,28, -70,0,76,0,79, -0,65,0,84,0, -95,0,67,0,79, -0,78,0,83,0, -84,0,65,0,78, -0,84,0,1,96, -1,1,2,0,1, -478,741,18,1,478, -742,20,743,4,40, -72,0,69,0,88, -0,95,0,73,0, -78,0,84,0,69, -0,71,0,69,0, -82,0,95,0,67, -0,79,0,78,0, -83,0,84,0,65, -0,78,0,84,0, -1,95,1,1,2, -0,1,479,744,18, -1,479,745,20,746, -4,32,73,0,78, -0,84,0,69,0, -71,0,69,0,82, -0,95,0,67,0, -79,0,78,0,83, -0,84,0,65,0, -78,0,84,0,1, -94,1,1,2,0, -1,480,747,18,1, -480,748,20,749,4, -26,82,0,73,0, -71,0,72,0,84, -0,95,0,66,0, -82,0,65,0,67, -0,75,0,69,0, -84,0,1,28,1, -1,2,0,1,481, -750,18,1,481,728, -2,0,1,1048,751, -18,1,1048,184,2, -0,1,2642,752,18, -1,2642,171,2,0, -1,2563,753,18,1, -2563,492,2,0,1, -2042,754,18,1,2042, -755,20,756,4,20, -65,0,115,0,115, -0,105,0,103,0, -110,0,109,0,101, -0,110,0,116,0, -1,137,1,2,2, -0,1,2043,757,18, -1,2043,150,2,0, -1,2568,758,18,1, -2568,759,20,760,4, -22,75,0,101,0, -121,0,65,0,114, -0,103,0,69,0, -118,0,101,0,110, -0,116,0,1,127, -1,2,2,0,1, -2649,761,18,1,2649, -212,2,0,1,1620, -762,18,1,1620,176, -2,0,1,1621,763, -18,1,1621,159,2, -0,1,1622,764,18, -1,1622,335,2,0, -1,509,765,18,1, -509,143,2,0,1, -2498,766,18,1,2498, -767,20,768,4,36, -72,0,84,0,84, -0,80,0,95,0, -82,0,69,0,81, -0,85,0,69,0, -83,0,84,0,95, -0,69,0,86,0, -69,0,78,0,84, -0,1,91,1,1, -2,0,1,2655,769, -18,1,2655,156,2, -0,1,2576,770,18, -1,2576,771,20,772, -4,24,86,0,111, -0,105,0,100,0, -65,0,114,0,103, -0,69,0,118,0, -101,0,110,0,116, -0,1,126,1,2, -2,0,1,1628,773, -18,1,1628,184,2, -0,1,515,774,18, -1,515,184,2,0, -1,2580,775,18,1, -2580,380,2,0,1, -2505,776,18,1,2505, -777,20,778,4,32, -68,0,65,0,84, -0,65,0,83,0, -69,0,82,0,86, -0,69,0,82,0, -95,0,69,0,86, -0,69,0,78,0, -84,0,1,66,1, -1,2,0,1,2582, -779,18,1,2582,135, -2,0,1,525,780, -18,1,525,347,2, -0,1,2197,781,18, -1,2197,176,2,0, -1,2198,782,18,1, -2198,162,2,0,1, -1591,783,18,1,1591, -184,2,0,1,2521, -784,18,1,2521,380, -2,0,1,2764,785, -18,1,2764,300,2, -0,1,1094,786,18, -1,1094,724,2,0, -1,1096,787,18,1, -1096,162,2,0,1, -2768,788,18,1,2768, -319,2,0,1,2769, -789,18,1,2769,132, -2,0,1,2770,790, -18,1,2770,135,2, -0,1,1657,791,18, -1,1657,150,2,0, -1,1658,792,18,1, -1658,793,20,794,4, -6,70,0,79,0, -82,0,1,46,1, -1,2,0,1,1659, -795,18,1,1659,135, -2,0,1,1665,796, -18,1,1665,184,2, -0,1,2781,797,18, -1,2781,162,2,0, -1,2783,798,18,1, -2783,380,2,0,1, -1113,799,18,1,1113, -192,2,0,800,5, -0,801,5,381,1, -2,802,19,371,1, -2,803,5,6,1, -2764,804,17,805,15, -806,4,30,37,0, -76,0,83,0,76, -0,80,0,114,0, -111,0,103,0,114, -0,97,0,109,0, -82,0,111,0,111, -0,116,0,1,-1, -1,5,807,20,808, -4,32,76,0,83, -0,76,0,80,0, -114,0,111,0,103, -0,114,0,97,0, -109,0,82,0,111, -0,111,0,116,0, -95,0,50,0,1, -168,1,3,1,2, -1,1,809,22,1, -2,1,2768,810,17, -811,15,812,4,14, -37,0,83,0,116, -0,97,0,116,0, -101,0,115,0,1, --1,1,5,813,20, -814,4,16,83,0, -116,0,97,0,116, -0,101,0,115,0, -95,0,49,0,1, -177,1,3,1,2, -1,1,815,22,1, -11,1,2755,816,17, -817,15,818,4,12, -37,0,83,0,116, -0,97,0,116,0, -101,0,1,-1,1, -5,819,20,820,4, -14,83,0,116,0, -97,0,116,0,101, -0,95,0,49,0, -1,179,1,3,1, -5,1,4,821,22, -1,13,1,2767,822, -17,823,15,812,1, --1,1,5,824,20, -825,4,16,83,0, -116,0,97,0,116, -0,101,0,115,0, -95,0,50,0,1, -178,1,3,1,3, -1,2,826,22,1, -12,1,2834,827,17, -828,15,806,1,-1, -1,5,829,20,830, -4,32,76,0,83, -0,76,0,80,0, -114,0,111,0,103, -0,114,0,97,0, -109,0,82,0,111, -0,111,0,116,0, -95,0,49,0,1, -167,1,3,1,3, -1,2,831,22,1, -1,1,2649,832,17, -833,15,818,1,-1, -1,5,834,20,835, -4,14,83,0,116, -0,97,0,116,0, -101,0,95,0,50, -0,1,180,1,3, -1,6,1,5,836, -22,1,14,1,3, -837,19,737,1,3, -838,5,95,1,256, -839,16,0,735,1, -1261,840,16,0,735, -1,509,841,16,0, -735,1,1515,842,16, -0,735,1,2021,843, -17,844,15,845,4, -24,37,0,73,0, -102,0,83,0,116, -0,97,0,116,0, -101,0,109,0,101, -0,110,0,116,0, -1,-1,1,5,846, -20,847,4,26,73, -0,102,0,83,0, -116,0,97,0,116, -0,101,0,109,0, -101,0,110,0,116, -0,95,0,50,0, -1,241,1,3,1, -8,1,7,848,22, -1,76,1,1775,849, -16,0,735,1,2029, -850,17,851,15,852, -4,20,37,0,83, -0,116,0,97,0, -116,0,101,0,109, -0,101,0,110,0, -116,0,1,-1,1, -5,853,20,854,4, -24,83,0,116,0, -97,0,116,0,101, -0,109,0,101,0, -110,0,116,0,95, -0,49,0,51,0, -1,235,1,3,1, -2,1,1,855,22, -1,70,1,2030,856, -17,857,15,852,1, --1,1,5,858,20, -859,4,24,83,0, -116,0,97,0,116, -0,101,0,109,0, -101,0,110,0,116, -0,95,0,49,0, -50,0,1,234,1, -3,1,2,1,1, -860,22,1,69,1, -2031,861,17,862,15, -852,1,-1,1,5, -863,20,864,4,24, -83,0,116,0,97, -0,116,0,101,0, -109,0,101,0,110, -0,116,0,95,0, -49,0,49,0,1, -233,1,3,1,2, -1,1,865,22,1, -68,1,2032,866,17, -867,15,852,1,-1, -1,5,868,20,869, -4,24,83,0,116, -0,97,0,116,0, -101,0,109,0,101, -0,110,0,116,0, -95,0,49,0,48, -0,1,232,1,3, -1,2,1,1,870, -22,1,67,1,2033, -871,17,872,15,852, -1,-1,1,5,873, -20,874,4,22,83, -0,116,0,97,0, -116,0,101,0,109, -0,101,0,110,0, -116,0,95,0,57, -0,1,231,1,3, -1,2,1,1,875, -22,1,66,1,277, -876,16,0,735,1, -2035,877,17,878,15, -852,1,-1,1,5, -879,20,880,4,22, -83,0,116,0,97, -0,116,0,101,0, -109,0,101,0,110, -0,116,0,95,0, -56,0,1,230,1, -3,1,3,1,2, -881,22,1,65,1, -2037,882,17,883,15, -852,1,-1,1,5, -884,20,885,4,22, -83,0,116,0,97, -0,116,0,101,0, -109,0,101,0,110, -0,116,0,95,0, -55,0,1,229,1, -3,1,3,1,2, -886,22,1,64,1, -2039,887,17,888,15, -852,1,-1,1,5, -889,20,890,4,22, -83,0,116,0,97, -0,116,0,101,0, -109,0,101,0,110, -0,116,0,95,0, -54,0,1,228,1, -3,1,3,1,2, -891,22,1,63,1, -32,892,16,0,735, -1,2041,893,17,894, -15,852,1,-1,1, -5,895,20,896,4, -22,83,0,116,0, -97,0,116,0,101, -0,109,0,101,0, -110,0,116,0,95, -0,53,0,1,227, -1,3,1,3,1, -2,897,22,1,62, -1,2293,898,16,0, -735,1,2043,899,17, -900,15,852,1,-1, -1,5,901,20,902, -4,22,83,0,116, -0,97,0,116,0, -101,0,109,0,101, -0,110,0,116,0, -95,0,51,0,1, -225,1,3,1,3, -1,2,903,22,1, -60,1,2045,904,17, -905,15,852,1,-1, -1,5,906,20,907, -4,22,83,0,116, -0,97,0,116,0, -101,0,109,0,101, -0,110,0,116,0, -95,0,49,0,1, -223,1,3,1,3, -1,2,908,22,1, -58,1,41,909,16, -0,735,1,1297,910, -16,0,735,1,43, -911,16,0,735,1, -1803,912,17,913,15, -914,4,16,37,0, -70,0,111,0,114, -0,76,0,111,0, -111,0,112,0,1, --1,1,5,915,20, -916,4,18,70,0, -111,0,114,0,76, -0,111,0,111,0, -112,0,95,0,49, -0,1,248,1,3, -1,10,1,9,917, -22,1,83,1,1804, -918,16,0,735,1, -299,919,16,0,735, -1,52,920,16,0, -735,1,2318,921,16, -0,735,1,62,922, -16,0,735,1,2075, -923,16,0,735,1, -1574,924,17,925,15, -852,1,-1,1,5, -926,20,927,4,22, -83,0,116,0,97, -0,116,0,101,0, -109,0,101,0,110, -0,116,0,95,0, -52,0,1,226,1, -3,1,3,1,2, -928,22,1,61,1, -71,929,16,0,735, -1,76,930,16,0, -735,1,1834,931,16, -0,735,1,2337,932, -16,0,735,1,79, -933,16,0,735,1, -1335,934,16,0,735, -1,322,935,16,0, -735,1,85,936,16, -0,735,1,89,937, -16,0,735,1,346, -938,16,0,735,1, -2105,939,17,940,15, -845,1,-1,1,5, -941,20,942,4,26, -73,0,102,0,83, -0,116,0,97,0, -116,0,101,0,109, -0,101,0,110,0, -116,0,95,0,51, -0,1,242,1,3, -1,6,1,5,943, -22,1,77,1,2106, -944,16,0,735,1, -97,945,16,0,735, -1,1860,946,17,947, -15,948,4,34,37, -0,68,0,111,0, -87,0,104,0,105, -0,108,0,101,0, -83,0,116,0,97, -0,116,0,101,0, -109,0,101,0,110, -0,116,0,1,-1, -1,5,949,20,950, -4,36,68,0,111, -0,87,0,104,0, -105,0,108,0,101, -0,83,0,116,0, -97,0,116,0,101, -0,109,0,101,0, -110,0,116,0,95, -0,49,0,1,246, -1,3,1,8,1, -7,951,22,1,81, -1,2364,952,17,953, -15,914,1,-1,1, -5,954,20,955,4, -18,70,0,111,0, -114,0,76,0,111, -0,111,0,112,0, -95,0,50,0,1, -249,1,3,1,9, -1,8,956,22,1, -84,1,102,957,16, -0,735,1,112,958, -16,0,735,1,1117, -959,16,0,735,1, -2786,960,16,0,735, -1,1873,961,17,962, -15,948,1,-1,1, -5,963,20,964,4, -36,68,0,111,0, -87,0,104,0,105, -0,108,0,101,0, -83,0,116,0,97, -0,116,0,101,0, -109,0,101,0,110, -0,116,0,95,0, -50,0,1,247,1, -3,1,8,1,7, -965,22,1,82,1, -1876,966,16,0,735, -1,124,967,16,0, -735,1,2136,968,17, -969,15,845,1,-1, -1,5,970,20,971, -4,26,73,0,102, -0,83,0,116,0, -97,0,116,0,101, -0,109,0,101,0, -110,0,116,0,95, -0,52,0,1,243, -1,3,1,8,1, -7,972,22,1,78, -1,381,973,16,0, -735,1,525,974,16, -0,735,1,137,975, -16,0,735,1,1901, -976,16,0,735,1, -1153,977,16,0,735, -1,151,978,16,0, -735,1,1407,979,16, -0,735,1,1659,980, -16,0,735,1,2413, -981,16,0,735,1, -406,982,16,0,735, -1,1371,983,16,0, -735,1,166,984,16, -0,735,1,1622,985, -16,0,735,1,1931, -986,17,987,15,988, -4,30,37,0,87, -0,104,0,105,0, -108,0,101,0,83, -0,116,0,97,0, -116,0,101,0,109, -0,101,0,110,0, -116,0,1,-1,1, -5,989,20,990,4, -32,87,0,104,0, -105,0,108,0,101, -0,83,0,116,0, -97,0,116,0,101, -0,109,0,101,0, -110,0,116,0,95, -0,49,0,1,244, -1,3,1,6,1, -5,991,22,1,79, -1,1933,992,16,0, -735,1,431,993,16, -0,735,1,1585,994, -16,0,735,1,182, -995,16,0,735,1, -1189,996,16,0,735, -1,1443,997,16,0, -735,1,1695,998,16, -0,735,1,2198,999, -16,0,735,1,447, -1000,16,0,735,1, -2458,1001,17,1002,15, -1003,4,28,37,0, -83,0,116,0,97, -0,116,0,101,0, -109,0,101,0,110, -0,116,0,76,0, -105,0,115,0,116, -0,1,-1,1,5, -1004,20,1005,4,30, -83,0,116,0,97, -0,116,0,101,0, -109,0,101,0,110, -0,116,0,76,0, -105,0,115,0,116, -0,95,0,50,0, -1,221,1,3,1, -3,1,2,1006,22, -1,56,1,2459,1007, -17,1008,15,1009,4, -36,37,0,67,0, -111,0,109,0,112, -0,111,0,117,0, -110,0,100,0,83, -0,116,0,97,0, -116,0,101,0,109, -0,101,0,110,0, -116,0,1,-1,1, -5,1010,20,1011,4, -38,67,0,111,0, -109,0,112,0,111, -0,117,0,110,0, -100,0,83,0,116, -0,97,0,116,0, -101,0,109,0,101, -0,110,0,116,0, -95,0,50,0,1, -219,1,3,1,4, -1,3,1012,22,1, -54,1,1958,1013,16, -0,735,1,2462,1014, -17,1015,15,1003,1, --1,1,5,1016,20, -1017,4,30,83,0, -116,0,97,0,116, -0,101,0,109,0, -101,0,110,0,116, -0,76,0,105,0, -115,0,116,0,95, -0,49,0,1,220, -1,3,1,2,1, -1,1018,22,1,55, -1,1657,1019,17,1020, -15,852,1,-1,1, -5,1021,20,1022,4, -22,83,0,116,0, -97,0,116,0,101, -0,109,0,101,0, -110,0,116,0,95, -0,50,0,1,224, -1,3,1,3,1, -2,1023,22,1,59, -1,2464,1024,17,1025, -15,1009,1,-1,1, -5,1026,20,1027,4, -38,67,0,111,0, -109,0,112,0,111, -0,117,0,110,0, -100,0,83,0,116, -0,97,0,116,0, -101,0,109,0,101, -0,110,0,116,0, -95,0,49,0,1, -218,1,3,1,3, -1,2,1028,22,1, -53,1,199,1029,16, -0,735,1,459,1030, -16,0,735,1,462, -1031,16,0,735,1, -217,1032,16,0,735, -1,2227,1033,17,1034, -15,988,1,-1,1, -5,1035,20,1036,4, -32,87,0,104,0, -105,0,108,0,101, -0,83,0,116,0, -97,0,116,0,101, -0,109,0,101,0, -110,0,116,0,95, -0,50,0,1,245, -1,3,1,6,1, -5,1037,22,1,80, -1,1225,1038,16,0, -735,1,1479,1039,16, -0,735,1,1731,1040, -16,0,735,1,1989, -1041,17,1042,15,845, -1,-1,1,5,1043, -20,1044,4,26,73, -0,102,0,83,0, -116,0,97,0,116, -0,101,0,109,0, -101,0,110,0,116, -0,95,0,49,0, -1,240,1,3,1, -6,1,5,1045,22, -1,75,1,1990,1046, -16,0,735,1,236, -1047,16,0,735,1, -1756,1048,16,0,735, -1,4,1049,19,200, -1,4,1050,5,100, -1,256,1051,16,0, -624,1,1261,1052,16, -0,624,1,509,1053, -16,0,624,1,1515, -1054,16,0,624,1, -2021,843,1,1775,1055, -16,0,624,1,2029, -850,1,2030,856,1, -2031,861,1,2032,866, -1,2033,871,1,277, -1056,16,0,624,1, -2035,877,1,2037,882, -1,2039,887,1,32, -1057,16,0,624,1, -2041,893,1,2293,1058, -16,0,624,1,2043, -899,1,2045,904,1, -40,1059,16,0,202, -1,41,1060,16,0, -624,1,1297,1061,16, -0,624,1,43,1062, -16,0,624,1,44, -1063,16,0,202,1, -1803,912,1,1804,1064, -16,0,624,1,299, -1065,16,0,624,1, -47,1066,16,0,198, -1,52,1067,16,0, -624,1,2318,1068,16, -0,624,1,63,1069, -16,0,224,1,66, -1070,16,0,222,1, -2075,1071,16,0,624, -1,1574,924,1,71, -1072,16,0,624,1, -76,1073,16,0,624, -1,1834,1074,16,0, -624,1,2337,1075,16, -0,624,1,79,1076, -16,0,624,1,1335, -1077,16,0,624,1, -322,1078,16,0,624, -1,85,1079,16,0, -624,1,89,1080,16, -0,624,1,346,1081, -16,0,624,1,97, -1082,16,0,624,1, -2106,1083,16,0,624, -1,102,1084,16,0, -624,1,1860,946,1, -2364,952,1,1114,1085, -16,0,198,1,112, -1086,16,0,624,1, -1117,1087,16,0,624, -1,2786,1088,16,0, -624,1,1873,961,1, -1876,1089,16,0,624, -1,124,1090,16,0, -624,1,2136,968,1, -381,1091,16,0,624, -1,525,1092,16,0, -624,1,137,1093,16, -0,624,1,1901,1094, -16,0,624,1,1153, -1095,16,0,624,1, -151,1096,16,0,624, -1,1407,1097,16,0, -624,1,1659,1098,16, -0,624,1,2413,1099, -16,0,624,1,406, -1100,16,0,624,1, -1371,1101,16,0,624, -1,2105,939,1,166, -1102,16,0,624,1, -1622,1103,16,0,624, -1,1931,986,1,1933, -1104,16,0,624,1, -431,1105,16,0,624, -1,1585,1106,16,0, -624,1,182,1107,16, -0,624,1,1189,1108, -16,0,624,1,1443, -1109,16,0,624,1, -1695,1110,16,0,624, -1,2198,1111,16,0, -624,1,447,1112,16, -0,624,1,2458,1001, -1,2459,1007,1,1958, -1113,16,0,624,1, -2462,1014,1,1657,1019, -1,2464,1024,1,199, -1114,16,0,624,1, -459,1115,16,0,624, -1,462,1116,16,0, -624,1,217,1117,16, -0,624,1,2227,1033, -1,1225,1118,16,0, -624,1,1479,1119,16, -0,624,1,1731,1120, -16,0,624,1,1989, -1041,1,1990,1121,16, -0,624,1,236,1122, -16,0,624,1,1756, -1123,16,0,624,1, -5,1124,19,197,1, -5,1125,5,100,1, -256,1126,16,0,620, -1,1261,1127,16,0, -620,1,509,1128,16, -0,620,1,1515,1129, -16,0,620,1,2021, -843,1,1775,1130,16, -0,620,1,2029,850, -1,2030,856,1,2031, -861,1,2032,866,1, -2033,871,1,277,1131, -16,0,620,1,2035, -877,1,2037,882,1, -2039,887,1,32,1132, -16,0,620,1,2041, -893,1,2293,1133,16, -0,620,1,2043,899, -1,2045,904,1,40, -1134,16,0,201,1, -41,1135,16,0,620, -1,1297,1136,16,0, -620,1,43,1137,16, -0,620,1,44,1138, -16,0,201,1,1803, -912,1,1804,1139,16, -0,620,1,299,1140, -16,0,620,1,47, -1141,16,0,195,1, -52,1142,16,0,620, -1,2318,1143,16,0, -620,1,63,1144,16, -0,223,1,66,1145, -16,0,221,1,2075, -1146,16,0,620,1, -1574,924,1,71,1147, -16,0,620,1,76, -1148,16,0,620,1, -1834,1149,16,0,620, -1,2337,1150,16,0, -620,1,79,1151,16, -0,620,1,1335,1152, -16,0,620,1,322, -1153,16,0,620,1, -85,1154,16,0,620, -1,89,1155,16,0, -620,1,346,1156,16, -0,620,1,97,1157, -16,0,620,1,2106, -1158,16,0,620,1, -102,1159,16,0,620, -1,1860,946,1,2364, -952,1,1114,1160,16, -0,195,1,112,1161, -16,0,620,1,1117, -1162,16,0,620,1, -2786,1163,16,0,620, -1,1873,961,1,1876, -1164,16,0,620,1, -124,1165,16,0,620, -1,2136,968,1,381, -1166,16,0,620,1, -525,1167,16,0,620, -1,137,1168,16,0, -620,1,1901,1169,16, -0,620,1,1153,1170, -16,0,620,1,151, -1171,16,0,620,1, -1407,1172,16,0,620, -1,1659,1173,16,0, -620,1,2413,1174,16, -0,620,1,406,1175, -16,0,620,1,1371, -1176,16,0,620,1, -2105,939,1,166,1177, -16,0,620,1,1622, -1178,16,0,620,1, -1931,986,1,1933,1179, -16,0,620,1,431, -1180,16,0,620,1, -1585,1181,16,0,620, -1,182,1182,16,0, -620,1,1189,1183,16, -0,620,1,1443,1184, -16,0,620,1,1695, -1185,16,0,620,1, -2198,1186,16,0,620, -1,447,1187,16,0, -620,1,2458,1001,1, -2459,1007,1,1958,1188, -16,0,620,1,2462, -1014,1,1657,1019,1, -2464,1024,1,199,1189, -16,0,620,1,459, -1190,16,0,620,1, -462,1191,16,0,620, -1,217,1192,16,0, -620,1,2227,1033,1, -1225,1193,16,0,620, -1,1479,1194,16,0, -620,1,1731,1195,16, -0,620,1,1989,1041, -1,1990,1196,16,0, -620,1,236,1197,16, -0,620,1,1756,1198, -16,0,620,1,6, -1199,19,310,1,6, -1200,5,2,1,1114, -1201,16,0,308,1, -40,1202,16,0,609, -1,7,1203,19,267, -1,7,1204,5,2, -1,1114,1205,16,0, -265,1,40,1206,16, -0,544,1,8,1207, -19,230,1,8,1208, -5,2,1,1114,1209, -16,0,228,1,40, -1210,16,0,501,1, -9,1211,19,236,1, -9,1212,5,2,1, -1114,1213,16,0,234, -1,40,1214,16,0, -430,1,10,1215,19, -180,1,10,1216,5, -2,1,1114,1217,16, -0,178,1,40,1218, -16,0,367,1,11, -1219,19,151,1,11, -1220,5,146,1,1260, -1221,17,1222,15,1223, -4,34,37,0,83, -0,105,0,109,0, -112,0,108,0,101, -0,65,0,115,0, -115,0,105,0,103, -0,110,0,109,0, -101,0,110,0,116, -0,1,-1,1,5, -1224,20,1225,4,38, -83,0,105,0,109, -0,112,0,108,0, -101,0,65,0,115, -0,115,0,105,0, -103,0,110,0,109, -0,101,0,110,0, 116,0,95,0,50, -0,49,0,1,276, -1,3,1,6,1, -5,1226,22,1,111, -1,1011,1227,17,1228, -15,1229,4,44,37, -0,80,0,97,0, -114,0,101,0,110, -0,116,0,104,0, -101,0,115,0,105, -0,115,0,69,0, -120,0,112,0,114, -0,101,0,115,0, -115,0,105,0,111, -0,110,0,1,-1, -1,5,1230,20,1231, -4,46,80,0,97, -0,114,0,101,0, -110,0,116,0,104, -0,101,0,115,0, -105,0,115,0,69, -0,120,0,112,0, -114,0,101,0,115, -0,115,0,105,0, -111,0,110,0,95, -0,50,0,1,323, -1,3,1,4,1, -3,1232,22,1,158, -1,1514,1233,17,1234, -15,1223,1,-1,1, -5,1235,20,1236,4, -38,83,0,105,0, -109,0,112,0,108, -0,101,0,65,0, -115,0,115,0,105, -0,103,0,110,0, -109,0,101,0,110, -0,116,0,95,0, -49,0,52,0,1, -269,1,3,1,4, -1,3,1237,22,1, -104,1,9,1238,17, -1239,15,1240,4,24, -37,0,68,0,101, -0,99,0,108,0, -97,0,114,0,97, -0,116,0,105,0, -111,0,110,0,1, --1,1,5,1241,20, -1242,4,26,68,0, -101,0,99,0,108, -0,97,0,114,0, -97,0,116,0,105, -0,111,0,110,0, -95,0,49,0,1, -213,1,3,1,3, -1,2,1243,22,1, -48,1,262,1244,17, -1245,15,1246,4,34, -37,0,66,0,105, -0,110,0,97,0, -114,0,121,0,69, -0,120,0,112,0, -114,0,101,0,115, -0,115,0,105,0, -111,0,110,0,1, --1,1,5,1247,20, -1248,4,36,66,0, -105,0,110,0,97, -0,114,0,121,0, -69,0,120,0,112, -0,114,0,101,0, -115,0,115,0,105, -0,111,0,110,0, -95,0,53,0,1, -305,1,3,1,4, -1,3,1249,22,1, -140,1,1267,1250,17, -1251,15,1223,1,-1, -1,5,1252,20,1253, -4,36,83,0,105, -0,109,0,112,0, -108,0,101,0,65, -0,115,0,115,0, -105,0,103,0,110, -0,109,0,101,0, -110,0,116,0,95, -0,56,0,1,263, -1,3,1,6,1, -5,1254,22,1,98, -1,2021,843,1,1521, -1255,17,1256,15,1223, -1,-1,1,5,1257, -20,1258,4,36,83, -0,105,0,109,0, -112,0,108,0,101, -0,65,0,115,0, -115,0,105,0,103, -0,110,0,109,0, -101,0,110,0,116, -0,95,0,49,0, -1,256,1,3,1, -4,1,3,1259,22, -1,91,1,2024,1260, -17,1261,15,1262,4, -24,37,0,83,0, -116,0,97,0,116, -0,101,0,67,0, -104,0,97,0,110, -0,103,0,101,0, -1,-1,1,5,1263, -20,1264,4,26,83, -0,116,0,97,0, -116,0,101,0,67, -0,104,0,97,0, -110,0,103,0,101, -0,95,0,49,0, -1,238,1,3,1, -3,1,2,1265,22, -1,73,1,1775,1266, -17,1267,15,1268,4, -30,37,0,69,0, -109,0,112,0,116, -0,121,0,83,0, -116,0,97,0,116, -0,101,0,109,0, -101,0,110,0,116, -0,1,-1,1,5, -1269,20,1270,4,32, -69,0,109,0,112, -0,116,0,121,0, -83,0,116,0,97, -0,116,0,101,0, -109,0,101,0,110, -0,116,0,95,0, -49,0,1,222,1, -3,1,1,1,0, -1271,22,1,57,1, -19,1272,17,1239,1, -2,1243,1,2028,1273, -17,1274,15,1275,4, -20,37,0,74,0, -117,0,109,0,112, -0,76,0,97,0, -98,0,101,0,108, -0,1,-1,1,5, -1276,20,1277,4,22, -74,0,117,0,109, -0,112,0,76,0, -97,0,98,0,101, -0,108,0,95,0, -49,0,1,236,1, -3,1,3,1,2, -1278,22,1,71,1, -2029,850,1,2281,1279, -17,1280,15,1281,4, -34,37,0,70,0, -111,0,114,0,76, -0,111,0,111,0, -112,0,83,0,116, -0,97,0,116,0, -101,0,109,0,101, -0,110,0,116,0, -1,-1,1,5,1282, -20,1283,4,36,70, -0,111,0,114,0, -76,0,111,0,111, -0,112,0,83,0, -116,0,97,0,116, -0,101,0,109,0, -101,0,110,0,116, -0,95,0,50,0, -1,251,1,3,1, -2,1,1,1284,22, -1,86,1,2031,861, -1,2785,1285,16,0, -519,1,2033,871,1, -2034,1286,16,0,691, -1,2035,877,1,2036, -1287,16,0,610,1, -2037,882,1,2038,1288, -16,0,614,1,2792, -1289,16,0,149,1, -32,1290,17,1267,1, -0,1271,1,2032,866, -1,2042,1291,16,0, -757,1,2043,899,1, -2044,1292,16,0,704, -1,2045,904,1,2299, -1293,16,0,252,1, -1296,1294,17,1295,15, -1223,1,-1,1,5, -1296,20,1297,4,38, -83,0,105,0,109, -0,112,0,108,0, -101,0,65,0,115, -0,115,0,105,0, -103,0,110,0,109, +0,1,335,812,1, +334,970,19,971,4, +28,65,0,114,0, +103,0,117,0,109, 0,101,0,110,0, -116,0,95,0,50, -0,48,0,1,275, -1,3,1,6,1, -5,1298,22,1,110, -1,283,1299,17,1300, -15,1246,1,-1,1, -5,1301,20,1302,4, -36,66,0,105,0, -110,0,97,0,114, -0,121,0,69,0, -120,0,112,0,114, -0,101,0,115,0, -115,0,105,0,111, -0,110,0,95,0, -52,0,1,304,1, -3,1,4,1,3, -1303,22,1,139,1, -40,1304,17,1305,15, -1306,4,32,37,0, -73,0,100,0,101, -0,110,0,116,0, -69,0,120,0,112, -0,114,0,101,0, -115,0,115,0,105, -0,111,0,110,0, -1,-1,1,5,1307, -20,1308,4,34,73, -0,100,0,101,0, -110,0,116,0,69, -0,120,0,112,0, -114,0,101,0,115, -0,115,0,105,0, -111,0,110,0,95, -0,49,0,1,290, -1,3,1,2,1, -1,1309,22,1,125, -1,44,1310,17,1305, -1,1,1309,1,1803, -912,1,47,1311,17, -1312,15,1313,4,38, -37,0,73,0,100, -0,101,0,110,0, -116,0,68,0,111, -0,116,0,69,0, -120,0,112,0,114, -0,101,0,115,0, -115,0,105,0,111, -0,110,0,1,-1, -1,5,1314,20,1315, -4,40,73,0,100, -0,101,0,110,0, -116,0,68,0,111, -0,116,0,69,0, -120,0,112,0,114, -0,101,0,115,0, -115,0,105,0,111, -0,110,0,95,0, -49,0,1,291,1, -3,1,4,1,3, -1316,22,1,126,1, -48,1317,17,1318,15, -1319,4,58,37,0, -73,0,110,0,99, -0,114,0,101,0, -109,0,101,0,110, -0,116,0,68,0, -101,0,99,0,114, -0,101,0,109,0, -101,0,110,0,116, -0,69,0,120,0, -112,0,114,0,101, -0,115,0,115,0, -105,0,111,0,110, -0,1,-1,1,5, -1320,20,1321,4,60, -73,0,110,0,99, -0,114,0,101,0, -109,0,101,0,110, -0,116,0,68,0, -101,0,99,0,114, -0,101,0,109,0, -101,0,110,0,116, -0,69,0,120,0, -112,0,114,0,101, -0,115,0,115,0, -105,0,111,0,110, -0,95,0,52,0, -1,295,1,3,1, -5,1,4,1322,22, -1,130,1,49,1323, -17,1324,15,1319,1, --1,1,5,1325,20, -1326,4,60,73,0, -110,0,99,0,114, -0,101,0,109,0, -101,0,110,0,116, -0,68,0,101,0, -99,0,114,0,101, -0,109,0,101,0, -110,0,116,0,69, -0,120,0,112,0, -114,0,101,0,115, -0,115,0,105,0, -111,0,110,0,95, -0,51,0,1,294, -1,3,1,5,1, -4,1327,22,1,129, -1,50,1328,17,1329, -15,1319,1,-1,1, -5,1330,20,1331,4, -60,73,0,110,0, -99,0,114,0,101, -0,109,0,101,0, -110,0,116,0,68, -0,101,0,99,0, -114,0,101,0,109, -0,101,0,110,0, -116,0,69,0,120, -0,112,0,114,0, -101,0,115,0,115, -0,105,0,111,0, -110,0,95,0,50, -0,1,293,1,3, -1,3,1,2,1332, -22,1,128,1,51, -1333,17,1334,15,1319, -1,-1,1,5,1335, -20,1336,4,60,73, -0,110,0,99,0, -114,0,101,0,109, -0,101,0,110,0, -116,0,68,0,101, -0,99,0,114,0, -101,0,109,0,101, -0,110,0,116,0, -69,0,120,0,112, -0,114,0,101,0, -115,0,115,0,105, -0,111,0,110,0, -95,0,49,0,1, -292,1,3,1,3, -1,2,1337,22,1, -127,1,305,1338,17, -1339,15,1246,1,-1, -1,5,1340,20,1341, -4,36,66,0,105, -0,110,0,97,0, -114,0,121,0,69, -0,120,0,112,0, -114,0,101,0,115, -0,115,0,105,0, -111,0,110,0,95, -0,51,0,1,303, -1,3,1,4,1, -3,1342,22,1,138, -1,525,1343,17,1344, -15,1345,4,34,37, -0,82,0,111,0, -116,0,97,0,116, -0,105,0,111,0, -110,0,67,0,111, -0,110,0,115,0, -116,0,97,0,110, -0,116,0,1,-1, -1,5,1346,20,1347, -4,36,82,0,111, -0,116,0,97,0, -116,0,105,0,111, -0,110,0,67,0, -111,0,110,0,115, -0,116,0,97,0, -110,0,116,0,95, -0,49,0,1,288, -1,3,1,10,1, -9,1348,22,1,123, -1,63,1349,17,1350, -15,1351,4,38,37, -0,84,0,121,0, -112,0,101,0,99, -0,97,0,115,0, -116,0,69,0,120, -0,112,0,114,0, -101,0,115,0,115, -0,105,0,111,0, -110,0,1,-1,1, -5,1352,20,1353,4, -40,84,0,121,0, -112,0,101,0,99, -0,97,0,115,0, -116,0,69,0,120, -0,112,0,114,0, -101,0,115,0,115, -0,105,0,111,0, -110,0,95,0,50, -0,1,325,1,3, -1,5,1,4,1354, -22,1,160,1,66, -1355,17,1356,15,1351, -1,-1,1,5,1357, -20,1358,4,40,84, -0,121,0,112,0, -101,0,99,0,97, +116,0,76,0,105, 0,115,0,116,0, -69,0,120,0,112, -0,114,0,101,0, -115,0,115,0,105, +95,0,49,0,1, +334,812,1,333,972, +19,973,4,28,70, +0,117,0,110,0, +99,0,116,0,105, 0,111,0,110,0, -95,0,51,0,1, -326,1,3,1,7, -1,6,1359,22,1, -161,1,67,1360,17, -1361,15,1351,1,-1, -1,5,1362,20,1363, +67,0,97,0,108, +0,108,0,95,0, +49,0,1,333,974, +5,68,1,1371,975, +16,0,553,1,1958, +976,16,0,553,1, +381,977,16,0,553, +1,217,978,16,0, +553,1,1756,979,16, +0,553,1,509,980, +16,0,553,1,2337, +981,16,0,553,1, +1153,982,16,0,553, +1,166,983,16,0, +553,1,1933,984,16, +0,553,1,2198,985, +16,0,553,1,1731, +986,16,0,553,1, +1335,987,16,0,553, +1,2318,988,16,0, +553,1,346,989,16, +0,553,1,182,990, +16,0,553,1,137, +991,16,0,553,1, +2106,992,16,0,553, +1,1775,993,16,0, +553,1,1117,994,16, +0,553,1,525,995, +16,0,553,1,1901, +996,16,0,553,1, +2293,997,16,0,553, +1,322,998,16,0, +553,1,124,999,16, +0,553,1,1695,1000, +16,0,553,1,299, +1001,16,0,553,1, +1297,1002,16,0,553, +1,151,1003,16,0, +553,1,112,1004,16, +0,553,1,2075,1005, +16,0,553,1,1876, +1006,16,0,553,1, +102,1007,16,0,553, +1,1479,1008,16,0, +553,1,97,1009,16, +0,553,1,1225,1010, +16,0,553,1,89, +1011,16,0,553,1, +85,1012,16,0,553, +1,1659,1013,16,0, +553,1,277,1014,16, +0,553,1,1261,1015, +16,0,553,1,76, +1016,16,0,553,1, +1515,1017,16,0,553, +1,71,1018,16,0, +553,1,462,1019,16, +0,553,1,459,1020, +16,0,553,1,1443, +1021,16,0,553,1, +62,1022,16,0,627, +1,1834,1023,16,0, +553,1,256,1024,16, +0,553,1,447,1025, +16,0,553,1,52, +1026,16,0,553,1, +2413,1027,16,0,553, +1,1622,1028,16,0, +553,1,43,1029,16, +0,553,1,41,1030, +16,0,553,1,236, +1031,16,0,553,1, +431,1032,16,0,553, +1,32,1033,16,0, +553,1,1804,1034,16, +0,553,1,1407,1035, +16,0,553,1,79, +1036,16,0,553,1, +1990,1037,16,0,553, +1,2786,1038,16,0, +553,1,406,1039,16, +0,553,1,1585,1040, +16,0,553,1,1189, +1041,16,0,553,1, +199,1042,16,0,553, +1,332,1043,19,1044, 4,40,84,0,121, 0,112,0,101,0, 99,0,97,0,115, @@ -5304,39 +4679,129 @@ public yyLSLSyntax 0,101,0,115,0, 115,0,105,0,111, 0,110,0,95,0, -55,0,1,330,1, -3,1,8,1,7, -1364,22,1,165,1, -68,1365,17,1366,15, -1351,1,-1,1,5, -1367,20,1368,4,40, -84,0,121,0,112, -0,101,0,99,0, -97,0,115,0,116, -0,69,0,120,0, -112,0,114,0,101, -0,115,0,115,0, -105,0,111,0,110, -0,95,0,53,0, -1,328,1,3,1, -8,1,7,1369,22, -1,163,1,69,1370, -17,1371,15,1351,1, --1,1,5,1372,20, -1373,4,40,84,0, -121,0,112,0,101, -0,99,0,97,0, -115,0,116,0,69, -0,120,0,112,0, -114,0,101,0,115, -0,115,0,105,0, -111,0,110,0,95, -0,54,0,1,329, -1,3,1,6,1, -5,1374,22,1,164, -1,70,1375,17,1376, -15,1351,1,-1,1, -5,1377,20,1378,4, +57,0,1,332,1045, +5,67,1,1371,1046, +16,0,508,1,1958, +1047,16,0,412,1, +381,1048,16,0,533, +1,217,1049,16,0, +615,1,1756,1050,16, +0,207,1,509,1051, +16,0,466,1,2337, +1052,16,0,412,1, +1153,1053,16,0,605, +1,166,1054,16,0, +670,1,1933,1055,16, +0,255,1,2198,1056, +16,0,412,1,1731, +1057,16,0,158,1, +1335,1058,16,0,518, +1,2318,1059,16,0, +207,1,346,1060,16, +0,559,1,182,1061, +16,0,659,1,137, +1062,16,0,678,1, +2106,1063,16,0,412, +1,1775,1064,16,0, +412,1,1117,1065,16, +0,254,1,525,1066, +16,0,659,1,1901, +1067,16,0,412,1, +2293,1068,16,0,504, +1,322,1069,16,0, +566,1,124,1070,16, +0,682,1,1695,1071, +16,0,196,1,299, +1072,16,0,575,1, +1297,1073,16,0,534, +1,151,1074,16,0, +672,1,112,1075,16, +0,689,1,2075,1076, +16,0,412,1,1876, +1077,16,0,697,1, +102,1078,16,0,693, +1,1479,1079,16,0, +450,1,97,1080,16, +0,145,1,1225,1081, +16,0,573,1,89, +1082,16,0,706,1, +85,1083,16,0,128, +1,1659,1084,16,0, +207,1,277,1085,16, +0,585,1,1261,1086, +16,0,560,1,76, +1087,16,0,774,1, +1515,1088,16,0,440, +1,71,1089,16,0, +732,1,462,1090,16, +0,758,1,459,1091, +16,0,758,1,1443, +1092,16,0,457,1, +1834,1093,16,0,530, +1,256,1094,16,0, +597,1,447,1095,16, +0,659,1,52,1096, +16,0,529,1,2413, +1097,16,0,412,1, +1622,1098,16,0,261, +1,43,1099,16,0, +683,1,41,1100,16, +0,758,1,236,1101, +16,0,604,1,431, +1102,16,0,516,1, +32,1103,16,0,412, +1,1804,1104,16,0, +412,1,1407,1105,16, +0,477,1,79,1106, +16,0,719,1,1990, +1107,16,0,412,1, +2786,1108,16,0,556, +1,406,1109,16,0, +527,1,1585,1110,16, +0,312,1,1189,1111, +16,0,589,1,199, +1112,16,0,626,1, +331,1113,19,1114,4, +40,84,0,121,0, +112,0,101,0,99, +0,97,0,115,0, +116,0,69,0,120, +0,112,0,114,0, +101,0,115,0,115, +0,105,0,111,0, +110,0,95,0,56, +0,1,331,1045,1, +330,1115,19,1116,4, +40,84,0,121,0, +112,0,101,0,99, +0,97,0,115,0, +116,0,69,0,120, +0,112,0,114,0, +101,0,115,0,115, +0,105,0,111,0, +110,0,95,0,55, +0,1,330,1045,1, +329,1117,19,1118,4, +40,84,0,121,0, +112,0,101,0,99, +0,97,0,115,0, +116,0,69,0,120, +0,112,0,114,0, +101,0,115,0,115, +0,105,0,111,0, +110,0,95,0,54, +0,1,329,1045,1, +328,1119,19,1120,4, +40,84,0,121,0, +112,0,101,0,99, +0,97,0,115,0, +116,0,69,0,120, +0,112,0,114,0, +101,0,115,0,115, +0,105,0,111,0, +110,0,95,0,53, +0,1,328,1045,1, +327,1121,19,1122,4, 40,84,0,121,0, 112,0,101,0,99, 0,97,0,115,0, @@ -5345,25 +4810,49 @@ public yyLSLSyntax 101,0,115,0,115, 0,105,0,111,0, 110,0,95,0,52, -0,1,327,1,3, -1,6,1,5,1379, -22,1,162,1,74, -1380,17,1381,15,1351, -1,-1,1,5,1382, -20,1383,4,40,84, -0,121,0,112,0, -101,0,99,0,97, -0,115,0,116,0, -69,0,120,0,112, -0,114,0,101,0, -115,0,115,0,105, -0,111,0,110,0, -95,0,57,0,1, -332,1,3,1,7, -1,6,1384,22,1, -167,1,1013,1385,17, -1386,15,1229,1,-1, -1,5,1387,20,1388, +0,1,327,1045,1, +326,1123,19,1124,4, +40,84,0,121,0, +112,0,101,0,99, +0,97,0,115,0, +116,0,69,0,120, +0,112,0,114,0, +101,0,115,0,115, +0,105,0,111,0, +110,0,95,0,51, +0,1,326,1045,1, +325,1125,19,1126,4, +40,84,0,121,0, +112,0,101,0,99, +0,97,0,115,0, +116,0,69,0,120, +0,112,0,114,0, +101,0,115,0,115, +0,105,0,111,0, +110,0,95,0,50, +0,1,325,1045,1, +324,1127,19,1128,4, +40,84,0,121,0, +112,0,101,0,99, +0,97,0,115,0, +116,0,69,0,120, +0,112,0,114,0, +101,0,115,0,115, +0,105,0,111,0, +110,0,95,0,49, +0,1,324,1045,1, +323,1129,19,1130,4, +46,80,0,97,0, +114,0,101,0,110, +0,116,0,104,0, +101,0,115,0,105, +0,115,0,69,0, +120,0,112,0,114, +0,101,0,115,0, +115,0,105,0,111, +0,110,0,95,0, +50,0,1,323,1045, +1,322,1131,19,1132, 4,46,80,0,97, 0,114,0,101,0, 110,0,116,0,104, @@ -5374,249 +4863,53 @@ public yyLSLSyntax 0,115,0,105,0, 111,0,110,0,95, 0,49,0,1,322, -1,3,1,4,1, -3,1389,22,1,157, -1,1332,1390,17,1391, -15,1223,1,-1,1, -5,1392,20,1393,4, -38,83,0,105,0, -109,0,112,0,108, -0,101,0,65,0, -115,0,115,0,105, -0,103,0,110,0, -109,0,101,0,110, -0,116,0,95,0, -49,0,57,0,1, -274,1,3,1,6, -1,5,1394,22,1, -109,1,2337,1395,17, -1267,1,0,1271,1, -1585,1396,17,1397,15, -1398,4,32,37,0, -82,0,101,0,116, -0,117,0,114,0, -110,0,83,0,116, -0,97,0,116,0, -101,0,109,0,101, -0,110,0,116,0, -1,-1,1,5,1399, -20,1400,4,34,82, -0,101,0,116,0, -117,0,114,0,110, -0,83,0,116,0, -97,0,116,0,101, -0,109,0,101,0, -110,0,116,0,95, -0,50,0,1,281, -1,3,1,2,1, -1,1401,22,1,116, -1,2023,1402,17,1403, -15,1262,1,-1,1, -5,1404,20,1405,4, -26,83,0,116,0, -97,0,116,0,101, -0,67,0,104,0, -97,0,110,0,103, -0,101,0,95,0, -50,0,1,239,1, -3,1,3,1,2, -1406,22,1,74,1, -2136,968,1,82,1407, -17,1408,15,1409,4, -32,37,0,85,0, +1045,1,321,1133,19, +1134,4,34,85,0, 110,0,97,0,114, 0,121,0,69,0, 120,0,112,0,114, 0,101,0,115,0, 115,0,105,0,111, -0,110,0,1,-1, -1,5,1410,20,1411, +0,110,0,95,0, +51,0,1,321,1045, +1,320,1135,19,1136, 4,34,85,0,110, 0,97,0,114,0, 121,0,69,0,120, 0,112,0,114,0, 101,0,115,0,115, 0,105,0,111,0, -110,0,95,0,51, -0,1,321,1,3, -1,3,1,2,1412, -22,1,156,1,2026, -1413,17,1414,15,1415, -4,28,37,0,74, -0,117,0,109,0, -112,0,83,0,116, -0,97,0,116,0, -101,0,109,0,101, -0,110,0,116,0, -1,-1,1,5,1416, -20,1417,4,30,74, -0,117,0,109,0, -112,0,83,0,116, -0,97,0,116,0, -101,0,109,0,101, -0,110,0,116,0, -95,0,49,0,1, -237,1,3,1,3, -1,2,1418,22,1, -72,1,1591,1419,17, -1420,15,1398,1,-1, -1,5,1421,20,1422, -4,34,82,0,101, -0,116,0,117,0, -114,0,110,0,83, -0,116,0,97,0, -116,0,101,0,109, -0,101,0,110,0, -116,0,95,0,49, -0,1,280,1,3, -1,3,1,2,1423, -22,1,115,1,1341, -1424,17,1425,15,1223, -1,-1,1,5,1426, -20,1427,4,36,83, -0,105,0,109,0, -112,0,108,0,101, -0,65,0,115,0, -115,0,105,0,103, -0,110,0,109,0, -101,0,110,0,116, -0,95,0,54,0, -1,261,1,3,1, -4,1,3,1428,22, -1,96,1,2030,856, -1,328,1429,17,1430, -15,1246,1,-1,1, -5,1431,20,1432,4, -36,66,0,105,0, -110,0,97,0,114, -0,121,0,69,0, -120,0,112,0,114, -0,101,0,115,0, -115,0,105,0,111, -0,110,0,95,0, -50,0,1,302,1, -3,1,4,1,3, -1433,22,1,137,1, -1303,1434,17,1435,15, -1223,1,-1,1,5, -1436,20,1437,4,36, -83,0,105,0,109, -0,112,0,108,0, -101,0,65,0,115, -0,115,0,105,0, -103,0,110,0,109, -0,101,0,110,0, -116,0,95,0,55, -0,1,262,1,3, -1,6,1,5,1438, -22,1,97,1,1096, -1439,17,1440,15,1441, -4,26,37,0,70, -0,117,0,110,0, -99,0,116,0,105, -0,111,0,110,0, -67,0,97,0,108, -0,108,0,1,-1, -1,5,1442,20,1443, -4,28,70,0,117, -0,110,0,99,0, -116,0,105,0,111, -0,110,0,67,0, -97,0,108,0,108, -0,95,0,49,0, -1,333,1,3,1, -5,1,4,1444,22, -1,168,1,93,1445, -17,1446,15,1409,1, --1,1,5,1447,20, -1448,4,34,85,0, -110,0,97,0,114, -0,121,0,69,0, -120,0,112,0,114, -0,101,0,115,0, -115,0,105,0,111, -0,110,0,95,0, -50,0,1,320,1, -3,1,3,1,2, -1449,22,1,155,1, -1550,1450,17,1451,15, -1223,1,-1,1,5, -1452,20,1453,4,38, -83,0,105,0,109, -0,112,0,108,0, -101,0,65,0,115, -0,115,0,105,0, -103,0,110,0,109, -0,101,0,110,0, -116,0,95,0,49, -0,51,0,1,268, -1,3,1,4,1, -3,1454,22,1,103, -1,2039,887,1,2040, -1455,16,0,618,1, -2041,893,1,1555,1456, -16,0,722,1,827, -1457,17,1458,15,1246, -1,-1,1,5,1459, -20,1460,4,38,66, -0,105,0,110,0, +110,0,95,0,50, +0,1,320,1045,1, +319,1137,19,1138,4, +34,85,0,110,0, 97,0,114,0,121, 0,69,0,120,0, 112,0,114,0,101, 0,115,0,115,0, 105,0,111,0,110, 0,95,0,49,0, -53,0,1,315,1, -3,1,4,1,3, -1461,22,1,150,1, -1859,1462,16,0,344, -1,1860,946,1,1804, -1463,17,1267,1,0, -1271,1,107,1464,17, -1465,15,1409,1,-1, -1,5,1466,20,1467, -4,34,85,0,110, +1,319,1045,1,318, +1139,19,1140,4,38, +66,0,105,0,110, 0,97,0,114,0, 121,0,69,0,120, 0,112,0,114,0, 101,0,115,0,115, 0,105,0,111,0, 110,0,95,0,49, -0,1,319,1,3, -1,3,1,2,1468, -22,1,154,1,1114, -1469,17,1312,1,3, -1316,1,1048,1470,17, -1471,15,1246,1,-1, -1,5,1472,20,1473, -4,38,66,0,105, -0,110,0,97,0, -114,0,121,0,69, -0,120,0,112,0, -114,0,101,0,115, -0,115,0,105,0, -111,0,110,0,95, -0,49,0,56,0, -1,318,1,3,1, -4,1,3,1474,22, -1,153,1,352,1475, -17,1476,15,1246,1, --1,1,5,1477,20, -1478,4,36,66,0, +0,56,0,1,318, +1045,1,317,1141,19, +1142,4,38,66,0, 105,0,110,0,97, 0,114,0,121,0, 69,0,120,0,112, 0,114,0,101,0, 115,0,115,0,105, 0,111,0,110,0, -95,0,49,0,1, -301,1,3,1,4, -1,3,1479,22,1, -136,1,1872,1480,16, -0,354,1,1873,961, -1,118,1481,17,1482, -15,1246,1,-1,1, -5,1483,20,1484,4, +95,0,49,0,55, +0,1,317,1045,1, +316,1143,19,1144,4, 38,66,0,105,0, 110,0,97,0,114, 0,121,0,69,0, @@ -5624,35 +4917,149 @@ public yyLSLSyntax 0,101,0,115,0, 115,0,105,0,111, 0,110,0,95,0, -49,0,52,0,1, -314,1,3,1,4, -1,3,1485,22,1, -149,1,1123,1486,17, -1487,15,1223,1,-1, -1,5,1488,20,1489, -4,38,83,0,105, -0,109,0,112,0, -108,0,101,0,65, +49,0,54,0,1, +316,1045,1,315,1145, +19,1146,4,38,66, +0,105,0,110,0, +97,0,114,0,121, +0,69,0,120,0, +112,0,114,0,101, 0,115,0,115,0, -105,0,103,0,110, -0,109,0,101,0, -110,0,116,0,95, -0,49,0,50,0, -1,267,1,3,1, -6,1,5,1490,22, -1,102,1,371,1491, -17,1492,15,1493,4, -46,37,0,70,0, -117,0,110,0,99, -0,116,0,105,0, -111,0,110,0,67, -0,97,0,108,0, -108,0,69,0,120, +105,0,111,0,110, +0,95,0,49,0, +53,0,1,315,1045, +1,314,1147,19,1148, +4,38,66,0,105, +0,110,0,97,0, +114,0,121,0,69, +0,120,0,112,0, +114,0,101,0,115, +0,115,0,105,0, +111,0,110,0,95, +0,49,0,52,0, +1,314,1045,1,313, +1149,19,1150,4,38, +66,0,105,0,110, +0,97,0,114,0, +121,0,69,0,120, 0,112,0,114,0, 101,0,115,0,115, 0,105,0,111,0, -110,0,1,-1,1, -5,1494,20,1495,4, +110,0,95,0,49, +0,51,0,1,313, +1045,1,312,1151,19, +1152,4,38,66,0, +105,0,110,0,97, +0,114,0,121,0, +69,0,120,0,112, +0,114,0,101,0, +115,0,115,0,105, +0,111,0,110,0, +95,0,49,0,50, +0,1,312,1045,1, +311,1153,19,1154,4, +38,66,0,105,0, +110,0,97,0,114, +0,121,0,69,0, +120,0,112,0,114, +0,101,0,115,0, +115,0,105,0,111, +0,110,0,95,0, +49,0,49,0,1, +311,1045,1,310,1155, +19,1156,4,38,66, +0,105,0,110,0, +97,0,114,0,121, +0,69,0,120,0, +112,0,114,0,101, +0,115,0,115,0, +105,0,111,0,110, +0,95,0,49,0, +48,0,1,310,1045, +1,309,1157,19,1158, +4,36,66,0,105, +0,110,0,97,0, +114,0,121,0,69, +0,120,0,112,0, +114,0,101,0,115, +0,115,0,105,0, +111,0,110,0,95, +0,57,0,1,309, +1045,1,308,1159,19, +1160,4,36,66,0, +105,0,110,0,97, +0,114,0,121,0, +69,0,120,0,112, +0,114,0,101,0, +115,0,115,0,105, +0,111,0,110,0, +95,0,56,0,1, +308,1045,1,307,1161, +19,1162,4,36,66, +0,105,0,110,0, +97,0,114,0,121, +0,69,0,120,0, +112,0,114,0,101, +0,115,0,115,0, +105,0,111,0,110, +0,95,0,55,0, +1,307,1045,1,306, +1163,19,1164,4,36, +66,0,105,0,110, +0,97,0,114,0, +121,0,69,0,120, +0,112,0,114,0, +101,0,115,0,115, +0,105,0,111,0, +110,0,95,0,54, +0,1,306,1045,1, +305,1165,19,1166,4, +36,66,0,105,0, +110,0,97,0,114, +0,121,0,69,0, +120,0,112,0,114, +0,101,0,115,0, +115,0,105,0,111, +0,110,0,95,0, +53,0,1,305,1045, +1,304,1167,19,1168, +4,36,66,0,105, +0,110,0,97,0, +114,0,121,0,69, +0,120,0,112,0, +114,0,101,0,115, +0,115,0,105,0, +111,0,110,0,95, +0,52,0,1,304, +1045,1,303,1169,19, +1170,4,36,66,0, +105,0,110,0,97, +0,114,0,121,0, +69,0,120,0,112, +0,114,0,101,0, +115,0,115,0,105, +0,111,0,110,0, +95,0,51,0,1, +303,1045,1,302,1171, +19,1172,4,36,66, +0,105,0,110,0, +97,0,114,0,121, +0,69,0,120,0, +112,0,114,0,101, +0,115,0,115,0, +105,0,111,0,110, +0,95,0,50,0, +1,302,1045,1,301, +1173,19,1174,4,36, +66,0,105,0,110, +0,97,0,114,0, +121,0,69,0,120, +0,112,0,114,0, +101,0,115,0,115, +0,105,0,111,0, +110,0,95,0,49, +0,1,301,1045,1, +300,1175,19,1176,4, 48,70,0,117,0, 110,0,99,0,116, 0,105,0,111,0, @@ -5663,42 +5070,50 @@ public yyLSLSyntax 115,0,115,0,105, 0,111,0,110,0, 95,0,49,0,1, -300,1,3,1,2, -1,1,1496,22,1, -135,1,1377,1497,17, -1498,15,1223,1,-1, -1,5,1499,20,1500, -4,36,83,0,105, -0,109,0,112,0, -108,0,101,0,65, -0,115,0,115,0, -105,0,103,0,110, -0,109,0,101,0, -110,0,116,0,95, -0,53,0,1,260, -1,3,1,4,1, -3,1501,22,1,95, -1,375,1502,17,1503, -15,1319,1,-1,1, -5,1504,20,1505,4, -60,73,0,110,0, -99,0,114,0,101, -0,109,0,101,0, -110,0,116,0,68, -0,101,0,99,0, +300,1045,1,299,1177, +19,1178,4,60,73, +0,110,0,99,0, 114,0,101,0,109, 0,101,0,110,0, -116,0,69,0,120, -0,112,0,114,0, -101,0,115,0,115, -0,105,0,111,0, -110,0,95,0,56, -0,1,299,1,3, -1,5,1,4,1506, -22,1,134,1,377, -1507,17,1508,15,1319, -1,-1,1,5,1509, -20,1510,4,60,73, +116,0,68,0,101, +0,99,0,114,0, +101,0,109,0,101, +0,110,0,116,0, +69,0,120,0,112, +0,114,0,101,0, +115,0,115,0,105, +0,111,0,110,0, +95,0,56,0,1, +299,1045,1,298,1179, +19,1180,4,60,73, +0,110,0,99,0, +114,0,101,0,109, +0,101,0,110,0, +116,0,68,0,101, +0,99,0,114,0, +101,0,109,0,101, +0,110,0,116,0, +69,0,120,0,112, +0,114,0,101,0, +115,0,115,0,105, +0,111,0,110,0, +95,0,55,0,1, +298,1045,1,297,1181, +19,1182,4,60,73, +0,110,0,99,0, +114,0,101,0,109, +0,101,0,110,0, +116,0,68,0,101, +0,99,0,114,0, +101,0,109,0,101, +0,110,0,116,0, +69,0,120,0,112, +0,114,0,101,0, +115,0,115,0,105, +0,111,0,110,0, +95,0,54,0,1, +297,1045,1,296,1183, +19,1184,4,60,73, 0,110,0,99,0, 114,0,101,0,109, 0,101,0,110,0, @@ -5711,126 +5126,302 @@ public yyLSLSyntax 115,0,115,0,105, 0,111,0,110,0, 95,0,53,0,1, -296,1,3,1,3, -1,2,1511,22,1, -131,1,379,1512,17, -1513,15,1319,1,-1, -1,5,1514,20,1515, -4,60,73,0,110, +296,1045,1,295,1185, +19,1186,4,60,73, +0,110,0,99,0, +114,0,101,0,109, +0,101,0,110,0, +116,0,68,0,101, 0,99,0,114,0, 101,0,109,0,101, 0,110,0,116,0, -68,0,101,0,99, -0,114,0,101,0, -109,0,101,0,110, -0,116,0,69,0, -120,0,112,0,114, -0,101,0,115,0, -115,0,105,0,111, -0,110,0,95,0, -55,0,1,298,1, -3,1,5,1,4, -1516,22,1,133,1, -380,1517,17,1518,15, -1519,4,38,37,0, -67,0,111,0,110, -0,115,0,116,0, -97,0,110,0,116, -0,69,0,120,0, -112,0,114,0,101, -0,115,0,115,0, -105,0,111,0,110, -0,1,-1,1,5, -1520,20,1521,4,40, -67,0,111,0,110, -0,115,0,116,0, -97,0,110,0,116, -0,69,0,120,0, -112,0,114,0,101, -0,115,0,115,0, -105,0,111,0,110, -0,95,0,49,0, -1,289,1,3,1, -2,1,1,1522,22, -1,124,1,883,1523, -17,1524,15,1246,1, --1,1,5,1525,20, -1526,4,38,66,0, -105,0,110,0,97, -0,114,0,121,0, 69,0,120,0,112, 0,114,0,101,0, 115,0,115,0,105, 0,111,0,110,0, -95,0,49,0,54, -0,1,316,1,3, -1,4,1,3,1527, -22,1,151,1,1628, -1528,17,1529,15,1530, -4,22,37,0,65, -0,115,0,115,0, -105,0,103,0,110, -0,109,0,101,0, -110,0,116,0,1, --1,1,5,1531,20, -1532,4,24,65,0, +95,0,52,0,1, +295,1045,1,294,1187, +19,1188,4,60,73, +0,110,0,99,0, +114,0,101,0,109, +0,101,0,110,0, +116,0,68,0,101, +0,99,0,114,0, +101,0,109,0,101, +0,110,0,116,0, +69,0,120,0,112, +0,114,0,101,0, 115,0,115,0,105, -0,103,0,110,0, -109,0,101,0,110, -0,116,0,95,0, -49,0,1,254,1, -3,1,4,1,3, -1533,22,1,89,1, -2075,1534,17,1267,1, -0,1271,1,373,1535, -17,1536,15,1319,1, --1,1,5,1537,20, -1538,4,60,73,0, -110,0,99,0,114, -0,101,0,109,0, -101,0,110,0,116, -0,68,0,101,0, -99,0,114,0,101, -0,109,0,101,0, +0,111,0,110,0, +95,0,51,0,1, +294,1045,1,293,1189, +19,1190,4,60,73, +0,110,0,99,0, +114,0,101,0,109, +0,101,0,110,0, +116,0,68,0,101, +0,99,0,114,0, +101,0,109,0,101, +0,110,0,116,0, +69,0,120,0,112, +0,114,0,101,0, +115,0,115,0,105, +0,111,0,110,0, +95,0,50,0,1, +293,1045,1,292,1191, +19,1192,4,60,73, +0,110,0,99,0, +114,0,101,0,109, +0,101,0,110,0, +116,0,68,0,101, +0,99,0,114,0, +101,0,109,0,101, +0,110,0,116,0, +69,0,120,0,112, +0,114,0,101,0, +115,0,115,0,105, +0,111,0,110,0, +95,0,49,0,1, +292,1045,1,291,1193, +19,1194,4,40,73, +0,100,0,101,0, +110,0,116,0,68, +0,111,0,116,0, +69,0,120,0,112, +0,114,0,101,0, +115,0,115,0,105, +0,111,0,110,0, +95,0,49,0,1, +291,1045,1,290,1195, +19,1196,4,34,73, +0,100,0,101,0, 110,0,116,0,69, 0,120,0,112,0, 114,0,101,0,115, 0,115,0,105,0, 111,0,110,0,95, -0,54,0,1,297, -1,3,1,3,1, -2,1539,22,1,132, -1,130,1540,17,1541, -15,1246,1,-1,1, -5,1542,20,1543,4, -38,66,0,105,0, -110,0,97,0,114, -0,121,0,69,0, -120,0,112,0,114, -0,101,0,115,0, -115,0,105,0,111, -0,110,0,95,0, -49,0,51,0,1, -313,1,3,1,4, -1,3,1544,22,1, -148,1,143,1545,17, -1546,15,1246,1,-1, -1,5,1547,20,1548, -4,38,66,0,105, -0,110,0,97,0, -114,0,121,0,69, +0,49,0,1,290, +1045,1,289,1197,19, +1198,4,40,67,0, +111,0,110,0,115, +0,116,0,97,0, +110,0,116,0,69, 0,120,0,112,0, 114,0,101,0,115, 0,115,0,105,0, 111,0,110,0,95, -0,49,0,50,0, -1,312,1,3,1, -4,1,3,1549,22, -1,147,1,1901,1550, -17,1267,1,0,1271, -1,1152,1551,17,1552, -15,1223,1,-1,1, -5,1553,20,1554,4, +0,49,0,1,289, +1045,1,288,1199,19, +1200,4,36,82,0, +111,0,116,0,97, +0,116,0,105,0, +111,0,110,0,67, +0,111,0,110,0, +115,0,116,0,97, +0,110,0,116,0, +95,0,49,0,1, +288,1201,5,68,1, +1371,1202,16,0,538, +1,1958,1203,16,0, +538,1,381,1204,16, +0,538,1,217,1205, +16,0,538,1,1756, +1206,16,0,538,1, +509,1207,16,0,538, +1,2337,1208,16,0, +538,1,1153,1209,16, +0,538,1,166,1210, +16,0,538,1,1933, +1211,16,0,538,1, +2198,1212,16,0,538, +1,1731,1213,16,0, +538,1,1335,1214,16, +0,538,1,2318,1215, +16,0,538,1,346, +1216,16,0,538,1, +182,1217,16,0,538, +1,137,1218,16,0, +538,1,2106,1219,16, +0,538,1,1775,1220, +16,0,538,1,1117, +1221,16,0,538,1, +525,1222,16,0,538, +1,1901,1223,16,0, +538,1,2293,1224,16, +0,538,1,322,1225, +16,0,538,1,124, +1226,16,0,538,1, +1695,1227,16,0,538, +1,299,1228,16,0, +538,1,1297,1229,16, +0,538,1,151,1230, +16,0,538,1,112, +1231,16,0,538,1, +2075,1232,16,0,538, +1,1876,1233,16,0, +538,1,102,1234,16, +0,538,1,1479,1235, +16,0,538,1,97, +1236,16,0,538,1, +1225,1237,16,0,538, +1,89,1238,16,0, +538,1,85,1239,16, +0,538,1,1659,1240, +16,0,538,1,277, +1241,16,0,538,1, +1261,1242,16,0,538, +1,76,1243,16,0, +538,1,1515,1244,16, +0,538,1,71,1245, +16,0,538,1,462, +1246,16,0,538,1, +459,1247,16,0,538, +1,1443,1248,16,0, +538,1,62,1249,16, +0,718,1,1834,1250, +16,0,538,1,256, +1251,16,0,538,1, +447,1252,16,0,538, +1,52,1253,16,0, +538,1,2413,1254,16, +0,538,1,1622,1255, +16,0,538,1,43, +1256,16,0,538,1, +41,1257,16,0,538, +1,236,1258,16,0, +538,1,431,1259,16, +0,538,1,32,1260, +16,0,538,1,1804, +1261,16,0,538,1, +1407,1262,16,0,538, +1,79,1263,16,0, +538,1,1990,1264,16, +0,538,1,2786,1265, +16,0,538,1,406, +1266,16,0,538,1, +1585,1267,16,0,538, +1,1189,1268,16,0, +538,1,199,1269,16, +0,538,1,287,1270, +19,1271,4,32,86, +0,101,0,99,0, +116,0,111,0,114, +0,67,0,111,0, +110,0,115,0,116, +0,97,0,110,0, +116,0,95,0,49, +0,1,287,1201,1, +286,1272,19,1273,4, +28,76,0,105,0, +115,0,116,0,67, +0,111,0,110,0, +115,0,116,0,97, +0,110,0,116,0, +95,0,49,0,1, +286,1201,1,285,1274, +19,1275,4,20,67, +0,111,0,110,0, +115,0,116,0,97, +0,110,0,116,0, +95,0,52,0,1, +285,1201,1,284,1276, +19,1277,4,20,67, +0,111,0,110,0, +115,0,116,0,97, +0,110,0,116,0, +95,0,51,0,1, +284,1201,1,283,1278, +19,1279,4,20,67, +0,111,0,110,0, +115,0,116,0,97, +0,110,0,116,0, +95,0,50,0,1, +283,1201,1,282,1280, +19,1281,4,20,67, +0,111,0,110,0, +115,0,116,0,97, +0,110,0,116,0, +95,0,49,0,1, +282,1201,1,281,1282, +19,1283,4,34,82, +0,101,0,116,0, +117,0,114,0,110, +0,83,0,116,0, +97,0,116,0,101, +0,109,0,101,0, +110,0,116,0,95, +0,50,0,1,281, +1284,5,11,1,2413, +1285,16,0,629,1, +2106,1286,16,0,629, +1,1901,1287,16,0, +629,1,1990,1288,16, +0,629,1,2337,1289, +16,0,629,1,1775, +1290,16,0,629,1, +2198,1291,16,0,629, +1,1958,1292,16,0, +629,1,1804,1293,16, +0,629,1,2075,1294, +16,0,629,1,32, +1295,16,0,629,1, +280,1296,19,1297,4, +34,82,0,101,0, +116,0,117,0,114, +0,110,0,83,0, +116,0,97,0,116, +0,101,0,109,0, +101,0,110,0,116, +0,95,0,49,0, +1,280,1284,1,279, +1298,19,1299,4,38, +83,0,105,0,109, +0,112,0,108,0, +101,0,65,0,115, +0,115,0,105,0, +103,0,110,0,109, +0,101,0,110,0, +116,0,95,0,50, +0,52,0,1,279, +1300,5,31,1,1153, +1301,16,0,591,1, +1775,1302,16,0,276, +1,1407,1303,16,0, +465,1,1225,1304,16, +0,565,1,1756,1305, +16,0,515,1,1933, +1306,16,0,446,1, +2198,1307,16,0,276, +1,2106,1308,16,0, +276,1,1659,1309,16, +0,515,1,1479,1310, +16,0,442,1,1834, +1311,16,0,766,1, +52,1312,16,0,708, +1,1297,1313,16,0, +526,1,1117,1314,16, +0,614,1,1958,1315, +16,0,276,1,1695, +1316,16,0,175,1, +1371,1317,16,0,481, +1,1189,1318,16,0, +106,1,1990,1319,16, +0,276,1,2075,1320, +16,0,276,1,1804, +1321,16,0,276,1, +2337,1322,16,0,276, +1,1443,1323,16,0, +454,1,1901,1324,16, +0,276,1,1261,1325, +16,0,543,1,2413, +1326,16,0,276,1, +32,1327,16,0,276, +1,1876,1328,16,0, +558,1,2318,1329,16, +0,515,1,1515,1330, +16,0,596,1,1335, +1331,16,0,513,1, +278,1332,19,1333,4, 38,83,0,105,0, 109,0,112,0,108, 0,101,0,65,0, @@ -5838,12 +5429,18 @@ public yyLSLSyntax 0,103,0,110,0, 109,0,101,0,110, 0,116,0,95,0, -50,0,52,0,1, -279,1,3,1,6, -1,5,1555,22,1, -114,1,1406,1556,17, -1557,15,1223,1,-1, -1,5,1558,20,1559, +50,0,51,0,1, +278,1300,1,277,1334, +19,1335,4,38,83, +0,105,0,109,0, +112,0,108,0,101, +0,65,0,115,0, +115,0,105,0,103, +0,110,0,109,0, +101,0,110,0,116, +0,95,0,50,0, +50,0,1,277,1300, +1,276,1336,19,1337, 4,38,83,0,105, 0,109,0,112,0, 108,0,101,0,65, @@ -5851,15 +5448,95 @@ public yyLSLSyntax 105,0,103,0,110, 0,109,0,101,0, 110,0,116,0,95, -0,49,0,55,0, -1,272,1,3,1, -4,1,3,1560,22, -1,107,1,1659,1561, -16,0,298,1,2413, -1562,17,1267,1,0, -1271,1,1159,1563,17, -1564,15,1223,1,-1, -1,5,1565,20,1566, +0,50,0,49,0, +1,276,1300,1,275, +1338,19,1339,4,38, +83,0,105,0,109, +0,112,0,108,0, +101,0,65,0,115, +0,115,0,105,0, +103,0,110,0,109, +0,101,0,110,0, +116,0,95,0,50, +0,48,0,1,275, +1300,1,274,1340,19, +1341,4,38,83,0, +105,0,109,0,112, +0,108,0,101,0, +65,0,115,0,115, +0,105,0,103,0, +110,0,109,0,101, +0,110,0,116,0, +95,0,49,0,57, +0,1,274,1300,1, +273,1342,19,1343,4, +38,83,0,105,0, +109,0,112,0,108, +0,101,0,65,0, +115,0,115,0,105, +0,103,0,110,0, +109,0,101,0,110, +0,116,0,95,0, +49,0,56,0,1, +273,1300,1,272,1344, +19,1345,4,38,83, +0,105,0,109,0, +112,0,108,0,101, +0,65,0,115,0, +115,0,105,0,103, +0,110,0,109,0, +101,0,110,0,116, +0,95,0,49,0, +55,0,1,272,1300, +1,271,1346,19,1347, +4,38,83,0,105, +0,109,0,112,0, +108,0,101,0,65, +0,115,0,115,0, +105,0,103,0,110, +0,109,0,101,0, +110,0,116,0,95, +0,49,0,54,0, +1,271,1300,1,270, +1348,19,1349,4,38, +83,0,105,0,109, +0,112,0,108,0, +101,0,65,0,115, +0,115,0,105,0, +103,0,110,0,109, +0,101,0,110,0, +116,0,95,0,49, +0,53,0,1,270, +1300,1,269,1350,19, +1351,4,38,83,0, +105,0,109,0,112, +0,108,0,101,0, +65,0,115,0,115, +0,105,0,103,0, +110,0,109,0,101, +0,110,0,116,0, +95,0,49,0,52, +0,1,269,1300,1, +268,1352,19,1353,4, +38,83,0,105,0, +109,0,112,0,108, +0,101,0,65,0, +115,0,115,0,105, +0,103,0,110,0, +109,0,101,0,110, +0,116,0,95,0, +49,0,51,0,1, +268,1300,1,267,1354, +19,1355,4,38,83, +0,105,0,109,0, +112,0,108,0,101, +0,65,0,115,0, +115,0,105,0,103, +0,110,0,109,0, +101,0,110,0,116, +0,95,0,49,0, +50,0,1,267,1300, +1,266,1356,19,1357, 4,38,83,0,105, 0,109,0,112,0, 108,0,101,0,65, @@ -5868,148 +5545,8 @@ public yyLSLSyntax 0,109,0,101,0, 110,0,116,0,95, 0,49,0,49,0, -1,266,1,3,1, -6,1,5,1567,22, -1,101,1,157,1568, -17,1569,15,1246,1, --1,1,5,1570,20, -1571,4,38,66,0, -105,0,110,0,97, -0,114,0,121,0, -69,0,120,0,112, -0,114,0,101,0, -115,0,115,0,105, -0,111,0,110,0, -95,0,49,0,49, -0,1,311,1,3, -1,4,1,3,1572, -22,1,146,1,1413, -1573,17,1574,15,1223, -1,-1,1,5,1575, -20,1576,4,36,83, -0,105,0,109,0, -112,0,108,0,101, -0,65,0,115,0, -115,0,105,0,103, -0,110,0,109,0, -101,0,110,0,116, -0,95,0,52,0, -1,259,1,3,1, -4,1,3,1577,22, -1,94,1,1370,1578, -17,1579,15,1223,1, --1,1,5,1580,20, -1581,4,38,83,0, -105,0,109,0,112, -0,108,0,101,0, -65,0,115,0,115, -0,105,0,103,0, -110,0,109,0,101, -0,110,0,116,0, -95,0,49,0,56, -0,1,273,1,3, -1,4,1,3,1582, -22,1,108,1,1478, -1583,17,1584,15,1223, -1,-1,1,5,1585, -20,1586,4,38,83, -0,105,0,109,0, -112,0,108,0,101, -0,65,0,115,0, -115,0,105,0,103, -0,110,0,109,0, -101,0,110,0,116, -0,95,0,49,0, -53,0,1,270,1, -3,1,4,1,3, -1587,22,1,105,1, -2106,1588,17,1267,1, -0,1271,1,1620,1589, -17,1590,15,1530,1, --1,1,5,1591,20, -1592,4,24,65,0, -115,0,115,0,105, -0,103,0,110,0, -109,0,101,0,110, -0,116,0,95,0, -50,0,1,255,1, -3,1,2,1,1, -1593,22,1,90,1, -1621,1594,16,0,791, -1,1574,924,1,172, -1595,17,1596,15,1246, -1,-1,1,5,1597, -20,1598,4,38,66, -0,105,0,110,0, -97,0,114,0,121, -0,69,0,120,0, -112,0,114,0,101, -0,115,0,115,0, -105,0,111,0,110, -0,95,0,49,0, -48,0,1,310,1, -3,1,4,1,3, -1599,22,1,145,1, -1931,986,1,1665,1600, -17,1601,15,1281,1, --1,1,5,1602,20, -1603,4,36,70,0, -111,0,114,0,76, -0,111,0,111,0, -112,0,83,0,116, -0,97,0,116,0, -101,0,109,0,101, -0,110,0,116,0, -95,0,49,0,1, -250,1,3,1,2, -1,1,1604,22,1, -85,1,2364,952,1, -2105,939,1,1188,1605, -17,1606,15,1223,1, --1,1,5,1607,20, -1608,4,38,83,0, -105,0,109,0,112, -0,108,0,101,0, -65,0,115,0,115, -0,105,0,103,0, -110,0,109,0,101, -0,110,0,116,0, -95,0,50,0,51, -0,1,278,1,3, -1,6,1,5,1609, -22,1,113,1,1442, -1610,17,1611,15,1223, -1,-1,1,5,1612, -20,1613,4,38,83, -0,105,0,109,0, -112,0,108,0,101, -0,65,0,115,0, -115,0,105,0,103, -0,110,0,109,0, -101,0,110,0,116, -0,95,0,49,0, -54,0,1,271,1, -3,1,4,1,3, -1614,22,1,106,1, -1694,1615,16,0,215, -1,942,1616,17,1617, -15,1246,1,-1,1, -5,1618,20,1619,4, -38,66,0,105,0, -110,0,97,0,114, -0,121,0,69,0, -120,0,112,0,114, -0,101,0,115,0, -115,0,105,0,111, -0,110,0,95,0, -49,0,55,0,1, -317,1,3,1,4, -1,3,1620,22,1, -152,1,2198,1621,17, -1267,1,0,1271,1, -1195,1622,17,1623,15, -1223,1,-1,1,5, -1624,20,1625,4,38, +1,266,1300,1,265, +1358,19,1359,4,38, 83,0,105,0,109, 0,112,0,108,0, 101,0,65,0,115, @@ -6018,11 +5555,35 @@ public yyLSLSyntax 0,101,0,110,0, 116,0,95,0,49, 0,48,0,1,265, -1,3,1,6,1, -5,1626,22,1,100, -1,1449,1627,17,1628, -15,1223,1,-1,1, -5,1629,20,1630,4, +1300,1,264,1360,19, +1361,4,36,83,0, +105,0,109,0,112, +0,108,0,101,0, +65,0,115,0,115, +0,105,0,103,0, +110,0,109,0,101, +0,110,0,116,0, +95,0,57,0,1, +264,1300,1,263,1362, +19,1363,4,36,83, +0,105,0,109,0, +112,0,108,0,101, +0,65,0,115,0, +115,0,105,0,103, +0,110,0,109,0, +101,0,110,0,116, +0,95,0,56,0, +1,263,1300,1,262, +1364,19,1365,4,36, +83,0,105,0,109, +0,112,0,108,0, +101,0,65,0,115, +0,115,0,105,0, +103,0,110,0,109, +0,101,0,110,0, +116,0,95,0,55, +0,1,262,1300,1, +261,1366,19,1367,4, 36,83,0,105,0, 109,0,112,0,108, 0,101,0,65,0, @@ -6030,719 +5591,504 @@ public yyLSLSyntax 0,103,0,110,0, 109,0,101,0,110, 0,116,0,95,0, -51,0,1,258,1, -3,1,4,1,3, -1631,22,1,93,1, -1701,1632,17,1633,15, -1281,1,-1,1,5, -1634,20,1635,4,36, +54,0,1,261,1300, +1,260,1368,19,1369, +4,36,83,0,105, +0,109,0,112,0, +108,0,101,0,65, +0,115,0,115,0, +105,0,103,0,110, +0,109,0,101,0, +110,0,116,0,95, +0,53,0,1,260, +1300,1,259,1370,19, +1371,4,36,83,0, +105,0,109,0,112, +0,108,0,101,0, +65,0,115,0,115, +0,105,0,103,0, +110,0,109,0,101, +0,110,0,116,0, +95,0,52,0,1, +259,1300,1,258,1372, +19,1373,4,36,83, +0,105,0,109,0, +112,0,108,0,101, +0,65,0,115,0, +115,0,105,0,103, +0,110,0,109,0, +101,0,110,0,116, +0,95,0,51,0, +1,258,1300,1,257, +1374,19,1375,4,36, +83,0,105,0,109, +0,112,0,108,0, +101,0,65,0,115, +0,115,0,105,0, +103,0,110,0,109, +0,101,0,110,0, +116,0,95,0,50, +0,1,257,1300,1, +256,1376,19,1377,4, +36,83,0,105,0, +109,0,112,0,108, +0,101,0,65,0, +115,0,115,0,105, +0,103,0,110,0, +109,0,101,0,110, +0,116,0,95,0, +49,0,1,256,1300, +1,255,1378,19,1379, +4,24,65,0,115, +0,115,0,105,0, +103,0,110,0,109, +0,101,0,110,0, +116,0,95,0,50, +0,1,255,1380,5, +11,1,2413,1381,16, +0,472,1,2106,1382, +16,0,472,1,1901, +1383,16,0,472,1, +1990,1384,16,0,472, +1,2337,1385,16,0, +472,1,1775,1386,16, +0,472,1,2198,1387, +16,0,472,1,1958, +1388,16,0,472,1, +1804,1389,16,0,472, +1,2075,1390,16,0, +472,1,32,1391,16, +0,472,1,254,1392, +19,1393,4,24,65, +0,115,0,115,0, +105,0,103,0,110, +0,109,0,101,0, +110,0,116,0,95, +0,49,0,1,254, +1380,1,253,1394,19, +1395,4,36,70,0, +111,0,114,0,76, +0,111,0,111,0, +112,0,83,0,116, +0,97,0,116,0, +101,0,109,0,101, +0,110,0,116,0, +95,0,52,0,1, +253,1396,5,3,1, +1756,1397,16,0,140, +1,2318,1398,16,0, +476,1,1659,1399,16, +0,198,1,252,1400, +19,1401,4,36,70, +0,111,0,114,0, +76,0,111,0,111, +0,112,0,83,0, +116,0,97,0,116, +0,101,0,109,0, +101,0,110,0,116, +0,95,0,51,0, +1,252,1396,1,251, +1402,19,1403,4,36, 70,0,111,0,114, 0,76,0,111,0, 111,0,112,0,83, 0,116,0,97,0, 116,0,101,0,109, 0,101,0,110,0, +116,0,95,0,50, +0,1,251,1396,1, +250,1404,19,1405,4, +36,70,0,111,0, +114,0,76,0,111, +0,111,0,112,0, +83,0,116,0,97, +0,116,0,101,0, +109,0,101,0,110, +0,116,0,95,0, +49,0,1,250,1396, +1,249,1406,19,1407, +4,18,70,0,111, +0,114,0,76,0, +111,0,111,0,112, +0,95,0,50,0, +1,249,1408,5,11, +1,2413,1409,16,0, +651,1,2106,1410,16, +0,651,1,1901,1411, +16,0,651,1,1990, +1412,16,0,651,1, +2337,1413,16,0,651, +1,1775,1414,16,0, +651,1,2198,1415,16, +0,651,1,1958,1416, +16,0,651,1,1804, +1417,16,0,651,1, +2075,1418,16,0,651, +1,32,1419,16,0, +651,1,248,1420,19, +1421,4,18,70,0, +111,0,114,0,76, +0,111,0,111,0, +112,0,95,0,49, +0,1,248,1408,1, +247,1422,19,1423,4, +36,68,0,111,0, +87,0,104,0,105, +0,108,0,101,0, +83,0,116,0,97, +0,116,0,101,0, +109,0,101,0,110, +0,116,0,95,0, +50,0,1,247,1424, +5,11,1,2413,1425, +16,0,648,1,2106, +1426,16,0,648,1, +1901,1427,16,0,648, +1,1990,1428,16,0, +648,1,2337,1429,16, +0,648,1,1775,1430, +16,0,648,1,2198, +1431,16,0,648,1, +1958,1432,16,0,648, +1,1804,1433,16,0, +648,1,2075,1434,16, +0,648,1,32,1435, +16,0,648,1,246, +1436,19,1437,4,36, +68,0,111,0,87, +0,104,0,105,0, +108,0,101,0,83, +0,116,0,97,0, +116,0,101,0,109, +0,101,0,110,0, +116,0,95,0,49, +0,1,246,1424,1, +245,1438,19,1439,4, +32,87,0,104,0, +105,0,108,0,101, +0,83,0,116,0, +97,0,116,0,101, +0,109,0,101,0, +110,0,116,0,95, +0,50,0,1,245, +1440,5,11,1,2413, +1441,16,0,645,1, +2106,1442,16,0,645, +1,1901,1443,16,0, +645,1,1990,1444,16, +0,645,1,2337,1445, +16,0,645,1,1775, +1446,16,0,645,1, +2198,1447,16,0,645, +1,1958,1448,16,0, +645,1,1804,1449,16, +0,645,1,2075,1450, +16,0,645,1,32, +1451,16,0,645,1, +244,1452,19,1453,4, +32,87,0,104,0, +105,0,108,0,101, +0,83,0,116,0, +97,0,116,0,101, +0,109,0,101,0, +110,0,116,0,95, +0,49,0,1,244, +1440,1,243,1454,19, +1455,4,26,73,0, +102,0,83,0,116, +0,97,0,116,0, +101,0,109,0,101, +0,110,0,116,0, +95,0,52,0,1, +243,1456,5,11,1, +2413,1457,16,0,165, +1,2106,1458,16,0, +165,1,1901,1459,16, +0,165,1,1990,1460, +16,0,165,1,2337, +1461,16,0,165,1, +1775,1462,16,0,165, +1,2198,1463,16,0, +165,1,1958,1464,16, +0,165,1,1804,1465, +16,0,165,1,2075, +1466,16,0,165,1, +32,1467,16,0,165, +1,242,1468,19,1469, +4,26,73,0,102, +0,83,0,116,0, +97,0,116,0,101, +0,109,0,101,0, +110,0,116,0,95, +0,51,0,1,242, +1456,1,241,1470,19, +1471,4,26,73,0, +102,0,83,0,116, +0,97,0,116,0, +101,0,109,0,101, +0,110,0,116,0, +95,0,50,0,1, +241,1456,1,240,1472, +19,1473,4,26,73, +0,102,0,83,0, +116,0,97,0,116, +0,101,0,109,0, +101,0,110,0,116, +0,95,0,49,0, +1,240,1456,1,239, +1474,19,1475,4,26, +83,0,116,0,97, +0,116,0,101,0, +67,0,104,0,97, +0,110,0,103,0, +101,0,95,0,50, +0,1,239,1476,5, +11,1,2413,1477,16, +0,641,1,2106,1478, +16,0,641,1,1901, +1479,16,0,641,1, +1990,1480,16,0,641, +1,2337,1481,16,0, +641,1,1775,1482,16, +0,641,1,2198,1483, +16,0,641,1,1958, +1484,16,0,641,1, +1804,1485,16,0,641, +1,2075,1486,16,0, +641,1,32,1487,16, +0,641,1,238,1488, +19,1489,4,26,83, +0,116,0,97,0, +116,0,101,0,67, +0,104,0,97,0, +110,0,103,0,101, +0,95,0,49,0, +1,238,1476,1,237, +1490,19,1491,4,30, +74,0,117,0,109, +0,112,0,83,0, +116,0,97,0,116, +0,101,0,109,0, +101,0,110,0,116, +0,95,0,49,0, +1,237,1492,5,11, +1,2413,1493,16,0, +619,1,2106,1494,16, +0,619,1,1901,1495, +16,0,619,1,1990, +1496,16,0,619,1, +2337,1497,16,0,619, +1,1775,1498,16,0, +619,1,2198,1499,16, +0,619,1,1958,1500, +16,0,619,1,1804, +1501,16,0,619,1, +2075,1502,16,0,619, +1,32,1503,16,0, +619,1,236,1504,19, +1505,4,22,74,0, +117,0,109,0,112, +0,76,0,97,0, +98,0,101,0,108, +0,95,0,49,0, +1,236,1506,5,11, +1,2413,1507,16,0, +633,1,2106,1508,16, +0,633,1,1901,1509, +16,0,633,1,1990, +1510,16,0,633,1, +2337,1511,16,0,633, +1,1775,1512,16,0, +633,1,2198,1513,16, +0,633,1,1958,1514, +16,0,633,1,1804, +1515,16,0,633,1, +2075,1516,16,0,633, +1,32,1517,16,0, +633,1,235,1518,19, +1519,4,24,83,0, +116,0,97,0,116, +0,101,0,109,0, +101,0,110,0,116, +0,95,0,49,0, +51,0,1,235,1520, +5,11,1,2413,1521, +16,0,432,1,2106, +1522,16,0,581,1, +1901,1523,16,0,143, +1,1990,1524,16,0, +666,1,2337,1525,16, +0,458,1,1775,1526, +16,0,127,1,2198, +1527,16,0,532,1, +1958,1528,16,0,674, +1,1804,1529,16,0, +121,1,2075,1530,16, +0,595,1,32,1531, +16,0,430,1,234, +1532,19,1533,4,24, +83,0,116,0,97, +0,116,0,101,0, +109,0,101,0,110, +0,116,0,95,0, +49,0,50,0,1, +234,1520,1,233,1534, +19,1535,4,24,83, +0,116,0,97,0, +116,0,101,0,109, +0,101,0,110,0, +116,0,95,0,49, +0,49,0,1,233, +1520,1,232,1536,19, +1537,4,24,83,0, +116,0,97,0,116, +0,101,0,109,0, +101,0,110,0,116, +0,95,0,49,0, +48,0,1,232,1520, +1,231,1538,19,1539, +4,22,83,0,116, +0,97,0,116,0, +101,0,109,0,101, +0,110,0,116,0, +95,0,57,0,1, +231,1520,1,230,1540, +19,1541,4,22,83, +0,116,0,97,0, +116,0,101,0,109, +0,101,0,110,0, +116,0,95,0,56, +0,1,230,1520,1, +229,1542,19,1543,4, +22,83,0,116,0, +97,0,116,0,101, +0,109,0,101,0, +110,0,116,0,95, +0,55,0,1,229, +1520,1,228,1544,19, +1545,4,22,83,0, +116,0,97,0,116, +0,101,0,109,0, +101,0,110,0,116, +0,95,0,54,0, +1,228,1520,1,227, +1546,19,1547,4,22, +83,0,116,0,97, +0,116,0,101,0, +109,0,101,0,110, +0,116,0,95,0, +53,0,1,227,1520, +1,226,1548,19,1549, +4,22,83,0,116, +0,97,0,116,0, +101,0,109,0,101, +0,110,0,116,0, +95,0,52,0,1, +226,1520,1,225,1550, +19,1551,4,22,83, +0,116,0,97,0, +116,0,101,0,109, +0,101,0,110,0, 116,0,95,0,51, -0,1,252,1,3, -1,4,1,3,1636, -22,1,87,1,447, -1637,17,1638,15,1639, -4,30,37,0,86, -0,101,0,99,0, -116,0,111,0,114, -0,67,0,111,0, -110,0,115,0,116, -0,97,0,110,0, -116,0,1,-1,1, -5,1640,20,1641,4, -32,86,0,101,0, -99,0,116,0,111, -0,114,0,67,0, -111,0,110,0,115, -0,116,0,97,0, +0,1,225,1520,1, +224,1552,19,1553,4, +22,83,0,116,0, +97,0,116,0,101, +0,109,0,101,0, 110,0,116,0,95, -0,49,0,1,287, -1,3,1,8,1, -7,1642,22,1,122, -1,2458,1001,1,2459, -1007,1,1958,1643,17, -1267,1,0,1271,1, -188,1644,17,1645,15, -1246,1,-1,1,5, -1646,20,1647,4,36, -66,0,105,0,110, -0,97,0,114,0, -121,0,69,0,120, -0,112,0,114,0, -101,0,115,0,115, -0,105,0,111,0, -110,0,95,0,57, -0,1,309,1,3, -1,4,1,3,1648, -22,1,144,1,2462, -1014,1,1657,1019,1, -2464,1024,1,205,1649, -17,1650,15,1246,1, --1,1,5,1651,20, -1652,4,36,66,0, -105,0,110,0,97, -0,114,0,121,0, -69,0,120,0,112, -0,114,0,101,0, -115,0,115,0,105, -0,111,0,110,0, -95,0,56,0,1, -308,1,3,1,4, -1,3,1653,22,1, -143,1,2227,1033,1, -1224,1654,17,1655,15, -1223,1,-1,1,5, -1656,20,1657,4,38, -83,0,105,0,109, -0,112,0,108,0, -101,0,65,0,115, -0,115,0,105,0, -103,0,110,0,109, -0,101,0,110,0, -116,0,95,0,50, -0,50,0,1,277, -1,3,1,6,1, -5,1658,22,1,112, -1,223,1659,17,1660, -15,1246,1,-1,1, -5,1661,20,1662,4, -36,66,0,105,0, -110,0,97,0,114, -0,121,0,69,0, -120,0,112,0,114, -0,101,0,115,0, -115,0,105,0,111, -0,110,0,95,0, -55,0,1,307,1, -3,1,4,1,3, -1663,22,1,142,1, -1730,1664,17,1665,15, -1281,1,-1,1,5, -1666,20,1667,4,36, -70,0,111,0,114, -0,76,0,111,0, -111,0,112,0,83, +0,50,0,1,224, +1520,1,223,1554,19, +1555,4,22,83,0, +116,0,97,0,116, +0,101,0,109,0, +101,0,110,0,116, +0,95,0,49,0, +1,223,1520,1,222, +1556,19,1557,4,32, +69,0,109,0,112, +0,116,0,121,0, +83,0,116,0,97, +0,116,0,101,0, +109,0,101,0,110, +0,116,0,95,0, +49,0,1,222,1558, +5,11,1,2413,1559, +16,0,623,1,2106, +1560,16,0,623,1, +1901,1561,16,0,623, +1,1990,1562,16,0, +623,1,2337,1563,16, +0,623,1,1775,1564, +16,0,623,1,2198, +1565,16,0,623,1, +1958,1566,16,0,623, +1,1804,1567,16,0, +623,1,2075,1568,16, +0,623,1,32,1569, +16,0,623,1,221, +1570,19,1571,4,30, +83,0,116,0,97, +0,116,0,101,0, +109,0,101,0,110, +0,116,0,76,0, +105,0,115,0,116, +0,95,0,50,0, +1,221,1572,5,1, +1,32,1573,16,0, +447,1,220,1574,19, +1575,4,30,83,0, +116,0,97,0,116, +0,101,0,109,0, +101,0,110,0,116, +0,76,0,105,0, +115,0,116,0,95, +0,49,0,1,220, +1572,1,219,1576,19, +1577,4,38,67,0, +111,0,109,0,112, +0,111,0,117,0, +110,0,100,0,83, 0,116,0,97,0, 116,0,101,0,109, 0,101,0,110,0, -116,0,95,0,52, -0,1,253,1,3, -1,4,1,3,1668, -22,1,88,1,476, -1669,17,1670,15,1671, -4,18,37,0,67, -0,111,0,110,0, -115,0,116,0,97, -0,110,0,116,0, -1,-1,1,5,1672, -20,1673,4,20,67, -0,111,0,110,0, -115,0,116,0,97, -0,110,0,116,0, -95,0,52,0,1, -285,1,3,1,2, -1,1,1674,22,1, -120,1,477,1675,17, -1676,15,1671,1,-1, -1,5,1677,20,1678, -4,20,67,0,111, -0,110,0,115,0, -116,0,97,0,110, -0,116,0,95,0, -51,0,1,284,1, -3,1,2,1,1, -1679,22,1,119,1, -1231,1680,17,1681,15, -1223,1,-1,1,5, -1682,20,1683,4,36, -83,0,105,0,109, -0,112,0,108,0, -101,0,65,0,115, -0,115,0,105,0, -103,0,110,0,109, -0,101,0,110,0, -116,0,95,0,57, -0,1,264,1,3, -1,6,1,5,1684, -22,1,99,1,479, -1685,17,1686,15,1671, -1,-1,1,5,1687, -20,1688,4,20,67, -0,111,0,110,0, -115,0,116,0,97, -0,110,0,116,0, -95,0,49,0,1, -282,1,3,1,2, -1,1,1689,22,1, -117,1,480,1690,17, -1691,15,1692,4,26, -37,0,76,0,105, -0,115,0,116,0, -67,0,111,0,110, -0,115,0,116,0, -97,0,110,0,116, -0,1,-1,1,5, -1693,20,1694,4,28, -76,0,105,0,115, -0,116,0,67,0, -111,0,110,0,115, -0,116,0,97,0, -110,0,116,0,95, -0,49,0,1,286, -1,3,1,4,1, -3,1695,22,1,121, -1,1485,1696,17,1697, -15,1223,1,-1,1, -5,1698,20,1699,4, -36,83,0,105,0, -109,0,112,0,108, -0,101,0,65,0, -115,0,115,0,105, -0,103,0,110,0, +116,0,95,0,50, +0,1,219,1578,5, +21,1,1775,1579,16, +0,654,1,2106,1580, +16,0,654,1,2593, +1581,16,0,200,1, +32,1582,16,0,654, +1,31,1583,16,0, +428,1,1990,1584,16, +0,654,1,1804,1585, +16,0,654,1,2578, +1586,16,0,212,1, +2075,1587,16,0,654, +1,2573,1588,16,0, +218,1,1958,1589,16, +0,654,1,2534,1590, +16,0,281,1,2781, +1591,16,0,772,1, +2198,1592,16,0,654, +1,1901,1593,16,0, +654,1,2565,1594,16, +0,230,1,2549,1595, +16,0,699,1,2413, +1596,16,0,654,1, +2337,1597,16,0,654, +1,2557,1598,16,0, +242,1,2519,1599,16, +0,299,1,218,1600, +19,1601,4,38,67, +0,111,0,109,0, +112,0,111,0,117, +0,110,0,100,0, +83,0,116,0,97, +0,116,0,101,0, 109,0,101,0,110, 0,116,0,95,0, -50,0,1,257,1, -3,1,4,1,3, -1700,22,1,92,1, -1737,1701,16,0,303, -1,1989,1041,1,1990, -1702,17,1267,1,0, -1271,1,242,1703,17, -1704,15,1246,1,-1, -1,5,1705,20,1706, -4,36,66,0,105, -0,110,0,97,0, -114,0,121,0,69, -0,120,0,112,0, -114,0,101,0,115, -0,115,0,105,0, -111,0,110,0,95, -0,54,0,1,306, -1,3,1,4,1, -3,1707,22,1,141, -1,478,1708,17,1709, -15,1671,1,-1,1, -5,1710,20,1711,4, -20,67,0,111,0, -110,0,115,0,116, -0,97,0,110,0, -116,0,95,0,50, -0,1,283,1,3, -1,2,1,1,1712, -22,1,118,1,1001, -1713,17,1714,15,1351, -1,-1,1,5,1715, -20,1716,4,40,84, -0,121,0,112,0, -101,0,99,0,97, -0,115,0,116,0, -69,0,120,0,112, -0,114,0,101,0, -115,0,115,0,105, -0,111,0,110,0, -95,0,56,0,1, -331,1,3,1,5, -1,4,1717,22,1, -166,1,1002,1718,17, -1719,15,1351,1,-1, -1,5,1720,20,1721, -4,40,84,0,121, -0,112,0,101,0, -99,0,97,0,115, -0,116,0,69,0, -120,0,112,0,114, -0,101,0,115,0, -115,0,105,0,111, -0,110,0,95,0, -49,0,1,324,1, -3,1,5,1,4, -1722,22,1,159,1, -12,1723,19,166,1, -12,1724,5,50,1, -1901,1725,16,0,164, -1,2075,1726,16,0, -164,1,1860,946,1, -1803,912,1,1804,1727, -16,0,164,1,2519, -1728,16,0,164,1, -2549,1729,16,0,164, -1,2413,1730,16,0, -164,1,2198,1731,16, -0,164,1,1873,961, -1,1657,1019,1,2534, -1732,16,0,164,1, -1990,1733,16,0,164, -1,31,1734,16,0, -164,1,32,1735,16, -0,164,1,2105,939, -1,2106,1736,16,0, -164,1,2573,1737,16, -0,164,1,2658,1738, -16,0,284,1,2578, -1739,16,0,164,1, -2227,1033,1,2337,1740, -16,0,164,1,2557, -1741,16,0,164,1, -2781,1742,16,0,164, -1,2565,1743,16,0, -164,1,2021,843,1, -2458,1001,1,2459,1007, -1,2462,1014,1,2136, -968,1,2464,1024,1, -2029,850,1,2030,856, -1,2031,861,1,2032, -866,1,2469,1744,16, -0,536,1,2035,877, -1,2364,952,1,2039, -887,1,1931,986,1, -2041,893,1,2043,899, -1,2045,904,1,2593, -1745,16,0,164,1, -1775,1746,16,0,164, -1,1989,1041,1,2033, -871,1,2037,882,1, -1574,924,1,1958,1747, -16,0,164,1,13, -1748,19,213,1,13, -1749,5,55,1,2536, -1750,17,1751,15,1752, -4,46,37,0,73, -0,110,0,116,0, -86,0,101,0,99, -0,86,0,101,0, -99,0,65,0,114, -0,103,0,83,0, -116,0,97,0,116, -0,101,0,69,0, -118,0,101,0,110, -0,116,0,1,-1, -1,5,1753,20,1754, -4,48,73,0,110, -0,116,0,86,0, -101,0,99,0,86, -0,101,0,99,0, -65,0,114,0,103, -0,83,0,116,0, -97,0,116,0,101, -0,69,0,118,0, -101,0,110,0,116, -0,95,0,49,0, -1,203,1,3,1, -6,1,5,1755,22, -1,37,1,2643,1756, -17,1757,15,1758,4, -20,37,0,83,0, -116,0,97,0,116, -0,101,0,66,0, -111,0,100,0,121, -0,1,-1,1,5, -1759,20,1760,4,24, -83,0,116,0,97, -0,116,0,101,0, -66,0,111,0,100, -0,121,0,95,0, -49,0,50,0,1, -192,1,3,1,3, -1,2,1761,22,1, -26,1,2647,1762,17, -1763,15,1758,1,-1, -1,5,1764,20,1765, -4,22,83,0,116, -0,97,0,116,0, -101,0,66,0,111, -0,100,0,121,0, -95,0,52,0,1, -184,1,3,1,3, -1,2,1766,22,1, -18,1,1860,946,1, -1803,912,1,2521,1767, -17,1768,15,1769,4, -46,37,0,75,0, -101,0,121,0,73, -0,110,0,116,0, -73,0,110,0,116, -0,65,0,114,0, -103,0,83,0,116, -0,97,0,116,0, -101,0,69,0,118, -0,101,0,110,0, -116,0,1,-1,1, -5,1770,20,1771,4, -48,75,0,101,0, -121,0,73,0,110, -0,116,0,73,0, -110,0,116,0,65, -0,114,0,103,0, -83,0,116,0,97, -0,116,0,101,0, -69,0,118,0,101, -0,110,0,116,0, -95,0,49,0,1, -204,1,3,1,6, -1,5,1772,22,1, -38,1,2413,1773,16, -0,521,1,2657,1774, -17,1775,15,1758,1, --1,1,5,1776,20, -1777,4,22,83,0, -116,0,97,0,116, -0,101,0,66,0, -111,0,100,0,121, -0,95,0,49,0, -1,181,1,3,1, -2,1,1,1778,22, -1,15,1,1873,961, -1,1657,1019,1,2641, -1779,17,1780,15,1758, -1,-1,1,5,1781, -20,1782,4,24,83, -0,116,0,97,0, -116,0,101,0,66, -0,111,0,100,0, -121,0,95,0,49, -0,54,0,1,196, -1,3,1,3,1, -2,1783,22,1,30, -1,2642,1784,17,1785, -15,1758,1,-1,1, -5,1786,20,1787,4, -24,83,0,116,0, -97,0,116,0,101, -0,66,0,111,0, -100,0,121,0,95, -0,49,0,52,0, -1,194,1,3,1, -3,1,2,1788,22, -1,28,1,1989,1041, -1,2644,1789,17,1790, -15,1758,1,-1,1, -5,1791,20,1792,4, -24,83,0,116,0, -97,0,116,0,101, -0,66,0,111,0, -100,0,121,0,95, -0,49,0,48,0, -1,190,1,3,1, -3,1,2,1793,22, -1,24,1,2645,1794, -17,1795,15,1758,1, --1,1,5,1796,20, -1797,4,22,83,0, -116,0,97,0,116, -0,101,0,66,0, -111,0,100,0,121, -0,95,0,56,0, -1,188,1,3,1, -3,1,2,1798,22, -1,22,1,2646,1799, -17,1800,15,1758,1, --1,1,5,1801,20, -1802,4,22,83,0, -116,0,97,0,116, -0,101,0,66,0, -111,0,100,0,121, -0,95,0,54,0, -1,186,1,3,1, -3,1,2,1803,22, -1,20,1,2037,882, -1,32,1804,16,0, -526,1,2567,1805,17, -1806,15,1807,4,34, -37,0,73,0,110, -0,116,0,65,0, -114,0,103,0,83, -0,116,0,97,0, -116,0,101,0,69, -0,118,0,101,0, -110,0,116,0,1, --1,1,5,1808,20, -1809,4,36,73,0, -110,0,116,0,65, -0,114,0,103,0, -83,0,116,0,97, -0,116,0,101,0, -69,0,118,0,101, -0,110,0,116,0, -95,0,49,0,1, -200,1,3,1,6, -1,5,1810,22,1, -34,1,2650,1811,17, -1812,15,1758,1,-1, -1,5,1813,20,1814, -4,24,83,0,116, -0,97,0,116,0, -101,0,66,0,111, -0,100,0,121,0, -95,0,49,0,53, -0,1,195,1,3, -1,2,1,1,1815, -22,1,29,1,2651, -1816,17,1817,15,1758, -1,-1,1,5,1818, -20,1819,4,24,83, -0,116,0,97,0, -116,0,101,0,66, -0,111,0,100,0, -121,0,95,0,49, -0,51,0,1,193, -1,3,1,2,1, -1,1820,22,1,27, -1,2652,1821,17,1822, -15,1758,1,-1,1, -5,1823,20,1824,4, -24,83,0,116,0, -97,0,116,0,101, -0,66,0,111,0, -100,0,121,0,95, -0,49,0,49,0, -1,191,1,3,1, -2,1,1,1825,22, -1,25,1,2653,1826, -17,1827,15,1758,1, --1,1,5,1828,20, -1829,4,22,83,0, -116,0,97,0,116, -0,101,0,66,0, -111,0,100,0,121, -0,95,0,57,0, -1,189,1,3,1, -2,1,1,1830,22, -1,23,1,2654,1831, -17,1832,15,1758,1, --1,1,5,1833,20, -1834,4,22,83,0, -116,0,97,0,116, -0,101,0,66,0, -111,0,100,0,121, -0,95,0,55,0, -1,187,1,3,1, -2,1,1,1835,22, -1,21,1,2655,1836, -17,1837,15,1758,1, --1,1,5,1838,20, -1839,4,22,83,0, -116,0,97,0,116, -0,101,0,66,0, -111,0,100,0,121, -0,95,0,53,0, -1,185,1,3,1, -2,1,1,1840,22, -1,19,1,2656,1841, -17,1842,15,1758,1, --1,1,5,1843,20, -1844,4,22,83,0, -116,0,97,0,116, -0,101,0,66,0, -111,0,100,0,121, -0,95,0,51,0, -1,183,1,3,1, -2,1,1,1845,22, -1,17,1,2575,1846, -17,1847,15,1848,4, -34,37,0,75,0, -101,0,121,0,65, -0,114,0,103,0, -83,0,116,0,97, -0,116,0,101,0, -69,0,118,0,101, -0,110,0,116,0, -1,-1,1,5,1849, -20,1850,4,36,75, -0,101,0,121,0, -65,0,114,0,103, -0,83,0,116,0, -97,0,116,0,101, -0,69,0,118,0, -101,0,110,0,116, -0,95,0,49,0, -1,199,1,3,1, -6,1,5,1851,22, -1,33,1,2551,1852, -17,1853,15,1854,4, -46,37,0,73,0, -110,0,116,0,82, -0,111,0,116,0, -82,0,111,0,116, -0,65,0,114,0, -103,0,83,0,116, -0,97,0,116,0, -101,0,69,0,118, -0,101,0,110,0, -116,0,1,-1,1, -5,1855,20,1856,4, -48,73,0,110,0, -116,0,82,0,111, -0,116,0,82,0, -111,0,116,0,65, -0,114,0,103,0, -83,0,116,0,97, -0,116,0,101,0, -69,0,118,0,101, -0,110,0,116,0, -95,0,49,0,1, -202,1,3,1,6, -1,5,1857,22,1, -36,1,2580,1858,17, -1859,15,1860,4,36, -37,0,86,0,111, -0,105,0,100,0, -65,0,114,0,103, -0,83,0,116,0, -97,0,116,0,101, -0,69,0,118,0, -101,0,110,0,116, -0,1,-1,1,5, -1861,20,1862,4,38, -86,0,111,0,105, -0,100,0,65,0, -114,0,103,0,83, -0,116,0,97,0, -116,0,101,0,69, -0,118,0,101,0, -110,0,116,0,95, -0,49,0,1,198, -1,3,1,5,1, -4,1863,22,1,32, -1,2227,1033,1,1574, -924,1,2559,1864,17, -1865,15,1866,4,40, -37,0,86,0,101, -0,99,0,116,0, -111,0,114,0,65, -0,114,0,103,0, -83,0,116,0,97, -0,116,0,101,0, -69,0,118,0,101, -0,110,0,116,0, -1,-1,1,5,1867, -20,1868,4,42,86, -0,101,0,99,0, -116,0,111,0,114, -0,65,0,114,0, -103,0,83,0,116, -0,97,0,116,0, -101,0,69,0,118, -0,101,0,110,0, -116,0,95,0,49, -0,1,201,1,3, -1,6,1,5,1869, -22,1,35,1,2021, -843,1,2458,1001,1, -2459,1007,1,2462,1014, -1,2136,968,1,2464, -1024,1,2029,850,1, -2030,856,1,2031,861, -1,2032,866,1,2033, -871,1,2035,877,1, -2364,952,1,2039,887, -1,1931,986,1,2041, -893,1,2043,899,1, -2045,904,1,2703,1870, -16,0,211,1,2595, -1871,17,1872,15,1873, -4,22,37,0,83, -0,116,0,97,0, -116,0,101,0,69, -0,118,0,101,0, -110,0,116,0,1, --1,1,5,1874,20, -1875,4,24,83,0, -116,0,97,0,116, -0,101,0,69,0, -118,0,101,0,110, -0,116,0,95,0, -49,0,1,197,1, -3,1,6,1,5, -1876,22,1,31,1, -2597,1877,16,0,761, -1,2648,1878,17,1879, -15,1758,1,-1,1, -5,1880,20,1881,4, -22,83,0,116,0, -97,0,116,0,101, -0,66,0,111,0, -100,0,121,0,95, -0,50,0,1,182, -1,3,1,3,1, -2,1882,22,1,16, -1,2105,939,1,14, -1883,19,144,1,14, -1884,5,115,1,2510, -1885,16,0,706,1, -2513,1886,17,1887,15, -1888,4,30,37,0, -73,0,110,0,116, -0,68,0,101,0, -99,0,108,0,97, -0,114,0,97,0, -116,0,105,0,111, -0,110,0,1,-1, -1,5,1889,20,1890, -4,32,73,0,110, -0,116,0,68,0, -101,0,99,0,108, -0,97,0,114,0, -97,0,116,0,105, -0,111,0,110,0, -95,0,49,0,1, -215,1,3,1,3, -1,2,1891,22,1, -50,1,2514,1892,16, -0,360,1,1260,1221, -1,1011,1227,1,1514, -1233,1,9,1238,1, -10,1893,17,1894,15, -1895,4,48,37,0, -65,0,114,0,103, -0,117,0,109,0, -101,0,110,0,116, -0,68,0,101,0, -99,0,108,0,97, -0,114,0,97,0, -116,0,105,0,111, -0,110,0,76,0, -105,0,115,0,116, -0,1,-1,1,5, -140,1,0,1,0, -1896,22,1,39,1, -262,1244,1,1267,1250, -1,2525,1897,16,0, -507,1,1773,1898,16, -0,148,1,2779,1899, -16,0,142,1,19, -1272,1,20,1900,16, -0,142,1,2281,1279, -1,525,1343,1,30, -1901,17,1902,15,1895, -1,-1,1,5,1903, -20,1904,4,50,65, -0,114,0,103,0, -117,0,109,0,101, -0,110,0,116,0, -68,0,101,0,99, -0,108,0,97,0, -114,0,97,0,116, -0,105,0,111,0, -110,0,76,0,105, -0,115,0,116,0, -95,0,50,0,1, -206,1,3,1,4, -1,3,1905,22,1, -41,1,283,1299,1, -2543,1906,17,1907,15, -1908,4,30,37,0, -82,0,111,0,116, -0,68,0,101,0, -99,0,108,0,97, -0,114,0,97,0, -116,0,105,0,111, -0,110,0,1,-1, -1,5,1909,20,1910, +49,0,1,218,1578, +1,217,1602,19,1603, 4,32,82,0,111, 0,116,0,68,0, 101,0,99,0,108, @@ -6750,813 +6096,95 @@ public yyLSLSyntax 97,0,116,0,105, 0,111,0,110,0, 95,0,49,0,1, -217,1,3,1,3, -1,2,1911,22,1, -52,1,2544,1912,16, -0,528,1,40,1304, -1,41,1913,17,1914, -15,1915,4,26,37, -0,65,0,114,0, -103,0,117,0,109, -0,101,0,110,0, -116,0,76,0,105, -0,115,0,116,0, -1,-1,1,5,724, -1,0,1,0,1916, -22,1,169,1,42, -1917,17,1918,15,1919, -4,38,37,0,69, -0,120,0,112,0, -114,0,101,0,115, -0,115,0,105,0, -111,0,110,0,65, -0,114,0,103,0, -117,0,109,0,101, -0,110,0,116,0, -1,-1,1,5,1920, -20,1921,4,40,69, -0,120,0,112,0, -114,0,101,0,115, -0,115,0,105,0, -111,0,110,0,65, -0,114,0,103,0, -117,0,109,0,101, -0,110,0,116,0, -95,0,49,0,1, -336,1,3,1,2, -1,1,1922,22,1, -172,1,44,1310,1, -47,1311,1,48,1317, -1,49,1323,1,50, -1328,1,51,1333,1, -305,1338,1,63,1349, -1,1521,1255,1,66, -1355,1,67,1360,1, -1478,1583,1,69,1370, -1,70,1375,1,68, -1365,1,74,1380,1, -1013,1385,1,2335,1923, -16,0,148,1,1332, -1390,1,1048,1470,1, -2591,1924,16,0,142, -1,82,1407,1,1296, -1294,1,1341,1424,1, -328,1429,1,1303,1434, -1,1096,1439,1,93, -1445,1,1550,1450,1, -2770,1925,17,1926,15, -1895,1,-1,1,5, -140,1,0,1,0, -1896,1,2528,1927,17, -1928,15,1929,4,30, -37,0,86,0,101, -0,99,0,68,0, -101,0,99,0,108, -0,97,0,114,0, -97,0,116,0,105, -0,111,0,110,0, -1,-1,1,5,1930, -20,1931,4,32,86, +217,1604,5,2,1, +2545,1605,16,0,525, +1,2541,1606,16,0, +263,1,216,1607,19, +1608,4,32,86,0, +101,0,99,0,68, 0,101,0,99,0, -68,0,101,0,99, -0,108,0,97,0, -114,0,97,0,116, -0,105,0,111,0, -110,0,95,0,49, -0,1,216,1,3, -1,3,1,2,1932, -22,1,51,1,2529, -1933,16,0,515,1, -352,1475,1,107,1464, -1,1114,1469,1,2540, -1934,16,0,524,1, -1370,1578,1,118,1481, -1,1123,1486,1,371, -1491,1,1377,1497,1, -375,1502,1,377,1507, -1,827,1457,1,380, -1517,1,883,1523,1, -373,1535,1,130,1540, -1,379,1512,1,143, -1545,1,1152,1551,1, -387,1935,16,0,656, -1,1406,1556,1,2582, -1936,17,1937,15,1895, -1,-1,1,5,140, -1,0,1,0,1896, -1,1159,1563,1,157, -1568,1,1413,1573,1, -1665,1600,1,412,1938, -16,0,695,1,1094, -1939,16,0,726,1, -172,1595,1,1188,1605, -1,437,1940,16,0, -765,1,1442,1610,1, -1694,1941,16,0,148, -1,942,1616,1,1195, -1622,1,1449,1627,1, -1701,1632,1,447,1637, -1,188,1644,1,205, -1649,1,2467,1942,17, -1943,15,1895,1,-1, -1,5,1944,20,1945, -4,50,65,0,114, -0,103,0,117,0, -109,0,101,0,110, -0,116,0,68,0, -101,0,99,0,108, -0,97,0,114,0, -97,0,116,0,105, -0,111,0,110,0, -76,0,105,0,115, -0,116,0,95,0, -49,0,1,205,1, -3,1,2,1,1, -1946,22,1,40,1, -461,1947,16,0,726, -1,464,1948,17,1949, -15,1915,1,-1,1, -5,1950,20,1951,4, -28,65,0,114,0, -103,0,117,0,109, -0,101,0,110,0, -116,0,76,0,105, -0,115,0,116,0, -95,0,50,0,1, -335,1,3,1,4, -1,3,1952,22,1, -171,1,1224,1654,1, -223,1659,1,1730,1664, -1,476,1669,1,477, -1675,1,1231,1680,1, -479,1685,1,480,1690, -1,1485,1696,1,459, -1953,17,1954,15,1915, -1,-1,1,5,724, -1,0,1,0,1916, -1,242,1703,1,478, -1708,1,481,1955,17, -1956,15,1915,1,-1, -1,5,1957,20,1958, -4,28,65,0,114, -0,103,0,117,0, -109,0,101,0,110, -0,116,0,76,0, -105,0,115,0,116, +108,0,97,0,114, +0,97,0,116,0, +105,0,111,0,110, 0,95,0,49,0, -1,334,1,3,1, -2,1,1,1959,22, -1,170,1,1001,1713, -1,1002,1718,1,2509, -1960,17,1961,15,1962, -4,30,37,0,75, +1,216,1609,5,3, +1,2526,1610,16,0, +288,1,2553,1611,16, +0,247,1,2530,1612, +16,0,286,1,215, +1613,19,1614,4,32, +73,0,110,0,116, +0,68,0,101,0, +99,0,108,0,97, +0,114,0,97,0, +116,0,105,0,111, +0,110,0,95,0, +49,0,1,215,1615, +5,5,1,2561,1616, +16,0,235,1,2511, +1617,16,0,306,1, +2538,1618,16,0,687, +1,2523,1619,16,0, +294,1,2515,1620,16, +0,304,1,214,1621, +19,1622,4,32,75, 0,101,0,121,0, 68,0,101,0,99, 0,108,0,97,0, 114,0,97,0,116, 0,105,0,111,0, -110,0,1,-1,1, -5,1963,20,1964,4, -32,75,0,101,0, -121,0,68,0,101, -0,99,0,108,0, -97,0,114,0,97, -0,116,0,105,0, -111,0,110,0,95, -0,49,0,1,214, -1,3,1,3,1, -2,1965,22,1,49, -1,15,1966,19,336, -1,15,1967,5,6, -1,2785,1968,16,0, -334,1,1114,1969,16, -0,339,1,1621,1970, -16,0,764,1,40, -1971,16,0,649,1, -19,1272,1,9,1238, -1,16,1972,19,136, -1,16,1973,5,147, -1,256,1974,16,0, -203,1,1261,1975,16, -0,203,1,509,1976, -16,0,203,1,2769, -1977,16,0,790,1, -9,1978,16,0,134, -1,2522,1979,16,0, -505,1,2021,843,1, -1775,1980,16,0,203, -1,2029,850,1,2030, -856,1,2031,861,1, -2032,866,1,2786,1981, -16,0,203,1,277, -1982,16,0,203,1, -2537,1983,16,0,522, -1,2037,882,1,2039, -887,1,32,1984,16, -0,203,1,2041,893, -1,2293,1985,16,0, -203,1,2043,899,1, -2045,904,1,40,1986, -16,0,182,1,41, -1987,16,0,203,1, -1297,1988,16,0,203, -1,43,1989,16,0, -203,1,44,1990,16, -0,182,1,1803,912, -1,1804,1991,16,0, -203,1,299,1992,16, -0,203,1,2480,1993, -17,1994,15,1995,4, -24,37,0,73,0, -110,0,116,0,65, -0,114,0,103,0, -69,0,118,0,101, -0,110,0,116,0, -1,-1,1,5,1996, -20,1997,4,26,73, -0,110,0,116,0, -65,0,114,0,103, -0,69,0,118,0, -101,0,110,0,116, -0,95,0,55,0, -1,369,1,3,1, -2,1,1,1998,22, -1,205,1,2560,1999, -16,0,549,1,52, -2000,16,0,203,1, -2484,2001,17,2002,15, -1995,1,-1,1,5, -2003,20,2004,4,26, -73,0,110,0,116, -0,65,0,114,0, -103,0,69,0,118, -0,101,0,110,0, -116,0,95,0,51, -0,1,365,1,3, -1,2,1,1,2005, -22,1,201,1,1515, -2006,16,0,203,1, -2318,2007,16,0,203, -1,2491,2008,17,2009, -15,2010,4,26,37, -0,86,0,111,0, -105,0,100,0,65, -0,114,0,103,0, -69,0,118,0,101, -0,110,0,116,0, -1,-1,1,5,2011, -20,2012,4,28,86, -0,111,0,105,0, -100,0,65,0,114, -0,103,0,69,0, -118,0,101,0,110, -0,116,0,95,0, -54,0,1,358,1, -3,1,2,1,1, -2013,22,1,194,1, -62,2014,16,0,225, -1,63,2015,16,0, -182,1,2495,2016,17, -2017,15,2010,1,-1, -1,5,2018,20,2019, -4,28,86,0,111, -0,105,0,100,0, -65,0,114,0,103, -0,69,0,118,0, -101,0,110,0,116, -0,95,0,50,0, -1,354,1,3,1, -2,1,1,2020,22, -1,190,1,2576,2021, -16,0,579,1,2075, -2022,16,0,203,1, -1574,924,1,1479,2023, -16,0,203,1,71, -2024,16,0,203,1, -1658,2025,16,0,795, -1,1833,2026,16,0, -326,1,1834,2027,16, -0,203,1,2337,2028, -16,0,203,1,79, -2029,16,0,203,1, -1335,2030,16,0,203, -1,322,2031,16,0, -203,1,76,2032,16, -0,203,1,85,2033, -16,0,203,1,89, -2034,16,0,203,1, -2033,871,1,2035,877, -1,346,2035,16,0, -203,1,97,2036,16, -0,203,1,2106,2037, -16,0,203,1,102, -2038,16,0,203,1, -1860,946,1,2458,1001, -1,2364,952,1,1990, -2039,16,0,203,1, -112,2040,16,0,203, -1,1117,2041,16,0, -203,1,1873,961,1, -1875,2042,16,0,446, -1,1876,2043,16,0, -203,1,2552,2044,16, -0,540,1,124,2045, -16,0,203,1,2478, -2046,17,2047,15,1995, -1,-1,1,5,2048, -20,2049,4,26,73, -0,110,0,116,0, -65,0,114,0,103, -0,69,0,118,0, -101,0,110,0,116, -0,95,0,57,0, -1,371,1,3,1, -2,1,1,2050,22, -1,207,1,2136,968, -1,381,2051,16,0, -203,1,525,2052,16, -0,203,1,137,2053, -16,0,203,1,2568, -2054,16,0,683,1, -1901,2055,16,0,203, -1,1153,2056,16,0, -203,1,151,2057,16, -0,203,1,1407,2058, -16,0,203,1,2581, -2059,16,0,779,1, -2413,2060,16,0,203, -1,406,2061,16,0, -203,1,1371,2062,16, -0,203,1,2105,939, -1,166,2063,16,0, -203,1,1622,2064,16, -0,203,1,1931,986, -1,1932,2065,16,0, -539,1,1933,2066,16, -0,203,1,431,2067, -16,0,203,1,1585, -2068,16,0,203,1, -182,2069,16,0,203, -1,1189,2070,16,0, -203,1,1443,2071,16, -0,203,1,1695,2072, -16,0,203,1,2198, -2073,16,0,203,1, -447,2074,16,0,203, -1,199,2075,16,0, -203,1,2459,1007,1, -1958,2076,16,0,203, -1,2462,1014,1,1657, -1019,1,2464,1024,1, -1659,2077,16,0,203, -1,459,2078,16,0, -203,1,462,2079,16, -0,203,1,2471,2080, -17,2081,15,2082,4, -36,37,0,75,0, -101,0,121,0,73, -0,110,0,116,0, -73,0,110,0,116, -0,65,0,114,0, -103,0,69,0,118, -0,101,0,110,0, -116,0,1,-1,1, -5,2083,20,2084,4, -38,75,0,101,0, -121,0,73,0,110, -0,116,0,73,0, -110,0,116,0,65, -0,114,0,103,0, -69,0,118,0,101, -0,110,0,116,0, -95,0,49,0,1, -378,1,3,1,2, -1,1,2085,22,1, -214,1,2472,2086,17, -2087,15,2088,4,36, -37,0,73,0,110, -0,116,0,86,0, -101,0,99,0,86, -0,101,0,99,0, -65,0,114,0,103, -0,69,0,118,0, -101,0,110,0,116, -0,1,-1,1,5, -2089,20,2090,4,38, -73,0,110,0,116, -0,86,0,101,0, -99,0,86,0,101, -0,99,0,65,0, -114,0,103,0,69, -0,118,0,101,0, -110,0,116,0,95, -0,49,0,1,377, -1,3,1,2,1, -1,2091,22,1,213, -1,2473,2092,17,2093, -15,2094,4,36,37, +110,0,95,0,49, +0,1,214,1623,5, +2,1,2507,1624,16, +0,761,1,2569,1625, +16,0,223,1,213, +1626,19,1627,4,26, +68,0,101,0,99, +0,108,0,97,0, +114,0,97,0,116, +0,105,0,111,0, +110,0,95,0,49, +0,1,213,1628,5, +17,1,1775,1629,16, +0,273,1,2106,1630, +16,0,273,1,32, +1631,16,0,273,1, +1990,1632,16,0,273, +1,1804,1633,16,0, +273,1,2582,1634,16, +0,427,1,21,1635, +16,0,769,1,2198, +1636,16,0,273,1, +1901,1637,16,0,273, +1,10,1638,16,0, +427,1,2823,1639,16, +0,771,1,2770,1640, +16,0,427,1,1958, +1641,16,0,273,1, +2337,1642,16,0,273, +1,2075,1643,16,0, +273,1,2413,1644,16, +0,273,1,0,1645, +16,0,771,1,212, +1646,19,1647,4,68, +75,0,101,0,121, 0,73,0,110,0, -116,0,82,0,111, -0,116,0,82,0, -111,0,116,0,65, -0,114,0,103,0, -69,0,118,0,101, -0,110,0,116,0, -1,-1,1,5,2095, -20,2096,4,38,73, -0,110,0,116,0, -82,0,111,0,116, -0,82,0,111,0, -116,0,65,0,114, -0,103,0,69,0, -118,0,101,0,110, -0,116,0,95,0, -49,0,1,376,1, -3,1,2,1,1, -2097,22,1,212,1, -2474,2098,17,2099,15, -2100,4,30,37,0, -86,0,101,0,99, -0,116,0,111,0, -114,0,65,0,114, -0,103,0,69,0, -118,0,101,0,110, -0,116,0,1,-1, -1,5,2101,20,2102, -4,32,86,0,101, -0,99,0,116,0, -111,0,114,0,65, -0,114,0,103,0, -69,0,118,0,101, -0,110,0,116,0, -95,0,51,0,1, -375,1,3,1,2, -1,1,2103,22,1, -211,1,2475,2104,17, -2105,15,2100,1,-1, -1,5,2106,20,2107, -4,32,86,0,101, -0,99,0,116,0, -111,0,114,0,65, -0,114,0,103,0, -69,0,118,0,101, -0,110,0,116,0, -95,0,50,0,1, -374,1,3,1,2, -1,1,2108,22,1, -210,1,2476,2109,17, -2110,15,2100,1,-1, -1,5,2111,20,2112, -4,32,86,0,101, -0,99,0,116,0, -111,0,114,0,65, -0,114,0,103,0, -69,0,118,0,101, -0,110,0,116,0, -95,0,49,0,1, -373,1,3,1,2, -1,1,2113,22,1, -209,1,2477,2114,17, -2115,15,1995,1,-1, -1,5,2116,20,2117, -4,28,73,0,110, +116,0,73,0,110, 0,116,0,65,0, -114,0,103,0,69, -0,118,0,101,0, -110,0,116,0,95, -0,49,0,48,0, -1,372,1,3,1, -2,1,1,2118,22, -1,208,1,2227,1033, -1,2479,2119,17,2120, -15,1995,1,-1,1, -5,2121,20,2122,4, -26,73,0,110,0, -116,0,65,0,114, -0,103,0,69,0, -118,0,101,0,110, -0,116,0,95,0, -56,0,1,370,1, -3,1,2,1,1, -2123,22,1,206,1, -1225,2124,16,0,203, -1,2481,2125,17,2126, -15,1995,1,-1,1, -5,2127,20,2128,4, -26,73,0,110,0, -116,0,65,0,114, -0,103,0,69,0, -118,0,101,0,110, -0,116,0,95,0, -54,0,1,368,1, -3,1,2,1,1, -2129,22,1,204,1, -2482,2130,17,2131,15, -1995,1,-1,1,5, -2132,20,2133,4,26, -73,0,110,0,116, -0,65,0,114,0, -103,0,69,0,118, -0,101,0,110,0, -116,0,95,0,53, -0,1,367,1,3, -1,2,1,1,2134, -22,1,203,1,2483, -2135,17,2136,15,1995, -1,-1,1,5,2137, -20,2138,4,26,73, -0,110,0,116,0, -65,0,114,0,103, -0,69,0,118,0, -101,0,110,0,116, -0,95,0,52,0, -1,366,1,3,1, -2,1,1,2139,22, -1,202,1,1731,2140, -16,0,203,1,2485, -2141,17,2142,15,1995, -1,-1,1,5,2143, -20,2144,4,26,73, -0,110,0,116,0, -65,0,114,0,103, -0,69,0,118,0, -101,0,110,0,116, -0,95,0,50,0, -1,364,1,3,1, -2,1,1,2145,22, -1,200,1,2486,2146, -17,2147,15,1995,1, --1,1,5,2148,20, -2149,4,26,73,0, -110,0,116,0,65, -0,114,0,103,0, -69,0,118,0,101, -0,110,0,116,0, -95,0,49,0,1, -363,1,3,1,2, -1,1,2150,22,1, -199,1,2487,2151,17, -2152,15,2153,4,24, -37,0,75,0,101, -0,121,0,65,0, -114,0,103,0,69, -0,118,0,101,0, -110,0,116,0,1, --1,1,5,2154,20, -2155,4,26,75,0, -101,0,121,0,65, -0,114,0,103,0, -69,0,118,0,101, -0,110,0,116,0, -95,0,50,0,1, -362,1,3,1,2, -1,1,2156,22,1, -198,1,2488,2157,17, -2158,15,2153,1,-1, -1,5,2159,20,2160, -4,26,75,0,101, -0,121,0,65,0, -114,0,103,0,69, -0,118,0,101,0, -110,0,116,0,95, -0,49,0,1,361, -1,3,1,2,1, -1,2161,22,1,197, -1,2489,2162,17,2163, -15,2010,1,-1,1, -5,2164,20,2165,4, -28,86,0,111,0, -105,0,100,0,65, -0,114,0,103,0, -69,0,118,0,101, -0,110,0,116,0, -95,0,56,0,1, -360,1,3,1,2, -1,1,2166,22,1, -196,1,2490,2167,17, -2168,15,2010,1,-1, -1,5,2169,20,2170, -4,28,86,0,111, -0,105,0,100,0, -65,0,114,0,103, -0,69,0,118,0, -101,0,110,0,116, -0,95,0,55,0, -1,359,1,3,1, -2,1,1,2171,22, -1,195,1,1989,1041, -1,2492,2172,17,2173, -15,2010,1,-1,1, -5,2174,20,2175,4, -28,86,0,111,0, -105,0,100,0,65, -0,114,0,103,0, -69,0,118,0,101, -0,110,0,116,0, -95,0,53,0,1, -357,1,3,1,2, -1,1,2176,22,1, -193,1,2493,2177,17, -2178,15,2010,1,-1, -1,5,2179,20,2180, -4,28,86,0,111, -0,105,0,100,0, -65,0,114,0,103, -0,69,0,118,0, -101,0,110,0,116, -0,95,0,52,0, -1,356,1,3,1, -2,1,1,2181,22, -1,192,1,2494,2182, -17,2183,15,2010,1, --1,1,5,2184,20, -2185,4,28,86,0, -111,0,105,0,100, -0,65,0,114,0, -103,0,69,0,118, -0,101,0,110,0, -116,0,95,0,51, -0,1,355,1,3, -1,2,1,1,2186, -22,1,191,1,236, -2187,16,0,203,1, -2496,2188,17,2189,15, -2010,1,-1,1,5, -2190,20,2191,4,28, -86,0,111,0,105, -0,100,0,65,0, -114,0,103,0,69, -0,118,0,101,0, -110,0,116,0,95, -0,49,0,1,353, -1,3,1,2,1, -1,2192,22,1,189, -1,2497,2193,17,2194, -15,2195,4,12,37, -0,69,0,118,0, -101,0,110,0,116, -0,1,-1,1,5, -2196,20,2197,4,14, -69,0,118,0,101, -0,110,0,116,0, -95,0,57,0,1, -352,1,3,1,2, -1,1,2198,22,1, -188,1,2498,2199,17, -2200,15,2195,1,-1, -1,5,2201,20,2202, -4,14,69,0,118, -0,101,0,110,0, -116,0,95,0,56, -0,1,351,1,3, -1,2,1,1,2203, -22,1,187,1,2499, -2204,17,2205,15,2195, -1,-1,1,5,2206, -20,2207,4,14,69, -0,118,0,101,0, -110,0,116,0,95, -0,55,0,1,350, -1,3,1,2,1, -1,2208,22,1,186, -1,2500,2209,17,2210, -15,2195,1,-1,1, -5,2211,20,2212,4, -14,69,0,118,0, -101,0,110,0,116, -0,95,0,54,0, -1,349,1,3,1, -2,1,1,2213,22, -1,185,1,2501,2214, -17,2215,15,2195,1, --1,1,5,2216,20, -2217,4,14,69,0, -118,0,101,0,110, -0,116,0,95,0, -53,0,1,348,1, -3,1,2,1,1, -2218,22,1,184,1, -2502,2219,17,2220,15, -2195,1,-1,1,5, -2221,20,2222,4,14, -69,0,118,0,101, -0,110,0,116,0, -95,0,52,0,1, -347,1,3,1,2, -1,1,2223,22,1, -183,1,2503,2224,17, -2225,15,2195,1,-1, -1,5,2226,20,2227, -4,14,69,0,118, -0,101,0,110,0, -116,0,95,0,51, -0,1,346,1,3, -1,2,1,1,2228, -22,1,182,1,2504, -2229,17,2230,15,2195, -1,-1,1,5,2231, -20,2232,4,14,69, -0,118,0,101,0, -110,0,116,0,95, -0,50,0,1,345, -1,3,1,2,1, -1,2233,22,1,181, -1,2505,2234,17,2235, -15,2195,1,-1,1, -5,2236,20,2237,4, -14,69,0,118,0, -101,0,110,0,116, -0,95,0,49,0, -1,344,1,3,1, -2,1,1,2238,22, -1,180,1,2506,2239, -16,0,482,1,217, -2240,16,0,203,1, -1756,2241,16,0,203, -1,17,2242,19,163, -1,17,2243,5,134, -1,1,2244,17,2245, -15,2246,4,18,37, -0,84,0,121,0, -112,0,101,0,110, -0,97,0,109,0, -101,0,1,-1,1, -5,2247,20,2248,4, -20,84,0,121,0, -112,0,101,0,110, -0,97,0,109,0, -101,0,95,0,55, -0,1,343,1,3, -1,2,1,1,2249, -22,1,179,1,2, -2250,17,2251,15,2246, -1,-1,1,5,2252, -20,2253,4,20,84, -0,121,0,112,0, -101,0,110,0,97, +114,0,103,0,117, 0,109,0,101,0, -95,0,54,0,1, -342,1,3,1,2, -1,1,2254,22,1, -178,1,3,2255,17, -2256,15,2246,1,-1, -1,5,2257,20,2258, -4,20,84,0,121, -0,112,0,101,0, -110,0,97,0,109, -0,101,0,95,0, -53,0,1,341,1, -3,1,2,1,1, -2259,22,1,177,1, -4,2260,17,2261,15, -2246,1,-1,1,5, -2262,20,2263,4,20, -84,0,121,0,112, -0,101,0,110,0, -97,0,109,0,101, -0,95,0,52,0, -1,340,1,3,1, -2,1,1,2264,22, -1,176,1,5,2265, -17,2266,15,2246,1, --1,1,5,2267,20, -2268,4,20,84,0, -121,0,112,0,101, -0,110,0,97,0, -109,0,101,0,95, -0,51,0,1,339, -1,3,1,2,1, -1,2269,22,1,175, -1,6,2270,17,2271, -15,2246,1,-1,1, -5,2272,20,2273,4, -20,84,0,121,0, -112,0,101,0,110, -0,97,0,109,0, -101,0,95,0,50, -0,1,338,1,3, -1,2,1,1,2274, -22,1,174,1,7, -2275,17,2276,15,2246, -1,-1,1,5,2277, -20,2278,4,20,84, -0,121,0,112,0, -101,0,110,0,97, -0,109,0,101,0, -95,0,49,0,1, -337,1,3,1,2, -1,1,2279,22,1, -173,1,2518,2280,16, -0,499,1,9,1238, -1,10,1893,1,262, -1244,1,1267,1250,1, -1521,1255,1,1773,2281, -16,0,261,1,2528, -1927,1,19,1272,1, -20,2282,16,0,161, -1,2532,2283,17,2284, -15,2285,4,66,37, -0,73,0,110,0, +110,0,116,0,68, +0,101,0,99,0, +108,0,97,0,114, +0,97,0,116,0, +105,0,111,0,110, +0,76,0,105,0, +115,0,116,0,95, +0,49,0,1,212, +1648,5,1,1,2507, +1649,16,0,301,1, +211,1650,19,1651,4, +68,73,0,110,0, 116,0,86,0,101, 0,99,0,86,0, 101,0,99,0,65, @@ -7569,67 +6197,28 @@ public yyLSLSyntax 0,105,0,111,0, 110,0,76,0,105, 0,115,0,116,0, -1,-1,1,5,2286, -20,2287,4,68,73, -0,110,0,116,0, -86,0,101,0,99, -0,86,0,101,0, -99,0,65,0,114, -0,103,0,117,0, -109,0,101,0,110, -0,116,0,68,0, -101,0,99,0,108, -0,97,0,114,0, -97,0,116,0,105, -0,111,0,110,0, -76,0,105,0,115, -0,116,0,95,0, -49,0,1,211,1, -3,1,6,1,5, -2288,22,1,46,1, -2533,2289,16,0,518, -1,30,1901,1,283, -1299,1,2543,1906,1, -2547,2290,17,2291,15, -2292,4,66,37,0, -73,0,110,0,116, -0,82,0,111,0, -116,0,82,0,111, -0,116,0,65,0, -114,0,103,0,117, -0,109,0,101,0, -110,0,116,0,68, -0,101,0,99,0, -108,0,97,0,114, -0,97,0,116,0, -105,0,111,0,110, -0,76,0,105,0, -115,0,116,0,1, --1,1,5,2293,20, -2294,4,68,73,0, -110,0,116,0,82, +95,0,49,0,1, +211,1652,5,1,1, +2523,1653,16,0,283, +1,210,1654,19,1655, +4,68,73,0,110, +0,116,0,82,0, +111,0,116,0,82, 0,111,0,116,0, -82,0,111,0,116, -0,65,0,114,0, -103,0,117,0,109, -0,101,0,110,0, -116,0,68,0,101, -0,99,0,108,0, -97,0,114,0,97, -0,116,0,105,0, -111,0,110,0,76, -0,105,0,115,0, -116,0,95,0,49, -0,1,210,1,3, -1,6,1,5,2295, -22,1,45,1,2548, -2296,16,0,650,1, -1010,2297,16,0,716, -1,40,1304,1,41, -1913,1,42,1917,1, -44,1310,1,2555,2298, -17,2299,15,2300,4, -60,37,0,86,0, +65,0,114,0,103, +0,117,0,109,0, +101,0,110,0,116, +0,68,0,101,0, +99,0,108,0,97, +0,114,0,97,0, +116,0,105,0,111, +0,110,0,76,0, +105,0,115,0,116, +0,95,0,49,0, +1,210,1656,5,1, +1,2538,1657,16,0, +258,1,209,1658,19, +1659,4,62,86,0, 101,0,99,0,116, 0,111,0,114,0, 65,0,114,0,103, @@ -7641,11 +6230,5599 @@ public yyLSLSyntax 116,0,105,0,111, 0,110,0,76,0, 105,0,115,0,116, +0,95,0,49,0, +1,209,1660,5,1, +1,2553,1661,16,0, +244,1,208,1662,19, +1663,4,56,73,0, +110,0,116,0,65, +0,114,0,103,0, +117,0,109,0,101, +0,110,0,116,0, +68,0,101,0,99, +0,108,0,97,0, +114,0,97,0,116, +0,105,0,111,0, +110,0,76,0,105, +0,115,0,116,0, +95,0,49,0,1, +208,1664,5,1,1, +2561,1665,16,0,232, +1,207,1666,19,1667, +4,56,75,0,101, +0,121,0,65,0, +114,0,103,0,117, +0,109,0,101,0, +110,0,116,0,68, +0,101,0,99,0, +108,0,97,0,114, +0,97,0,116,0, +105,0,111,0,110, +0,76,0,105,0, +115,0,116,0,95, +0,49,0,1,207, +1668,5,1,1,2569, +1669,16,0,220,1, +206,1670,19,1671,4, +50,65,0,114,0, +103,0,117,0,109, +0,101,0,110,0, +116,0,68,0,101, +0,99,0,108,0, +97,0,114,0,97, +0,116,0,105,0, +111,0,110,0,76, +0,105,0,115,0, +116,0,95,0,50, +0,1,206,804,1, +205,1672,19,1673,4, +50,65,0,114,0, +103,0,117,0,109, +0,101,0,110,0, +116,0,68,0,101, +0,99,0,108,0, +97,0,114,0,97, +0,116,0,105,0, +111,0,110,0,76, +0,105,0,115,0, +116,0,95,0,49, +0,1,205,804,1, +204,1674,19,1675,4, +48,75,0,101,0, +121,0,73,0,110, +0,116,0,73,0, +110,0,116,0,65, +0,114,0,103,0, +83,0,116,0,97, +0,116,0,101,0, +69,0,118,0,101, +0,110,0,116,0, +95,0,49,0,1, +204,1676,5,4,1, +2659,1677,16,0,467, +1,2470,1678,16,0, +467,1,2703,1679,16, +0,189,1,2597,1680, +16,0,189,1,203, +1681,19,1682,4,48, +73,0,110,0,116, +0,86,0,101,0, +99,0,86,0,101, +0,99,0,65,0, +114,0,103,0,83, +0,116,0,97,0, +116,0,101,0,69, +0,118,0,101,0, +110,0,116,0,95, +0,49,0,1,203, +1683,5,4,1,2659, +1684,16,0,171,1, +2470,1685,16,0,171, +1,2703,1686,16,0, +188,1,2597,1687,16, +0,188,1,202,1688, +19,1689,4,48,73, +0,110,0,116,0, +82,0,111,0,116, +0,82,0,111,0, +116,0,65,0,114, +0,103,0,83,0, +116,0,97,0,116, +0,101,0,69,0, +118,0,101,0,110, +0,116,0,95,0, +49,0,1,202,1690, +5,4,1,2659,1691, +16,0,168,1,2470, +1692,16,0,168,1, +2703,1693,16,0,187, +1,2597,1694,16,0, +187,1,201,1695,19, +1696,4,42,86,0, +101,0,99,0,116, +0,111,0,114,0, +65,0,114,0,103, +0,83,0,116,0, +97,0,116,0,101, +0,69,0,118,0, +101,0,110,0,116, +0,95,0,49,0, +1,201,1697,5,4, +1,2659,1698,16,0, +256,1,2470,1699,16, +0,256,1,2703,1700, +16,0,184,1,2597, +1701,16,0,184,1, +200,1702,19,1703,4, +36,73,0,110,0, +116,0,65,0,114, +0,103,0,83,0, +116,0,97,0,116, +0,101,0,69,0, +118,0,101,0,110, +0,116,0,95,0, +49,0,1,200,1704, +5,4,1,2659,1705, +16,0,162,1,2470, +1706,16,0,162,1, +2703,1707,16,0,183, +1,2597,1708,16,0, +183,1,199,1709,19, +1710,4,36,75,0, +101,0,121,0,65, +0,114,0,103,0, +83,0,116,0,97, +0,116,0,101,0, +69,0,118,0,101, +0,110,0,116,0, +95,0,49,0,1, +199,1711,5,4,1, +2659,1712,16,0,700, +1,2470,1713,16,0, +700,1,2703,1714,16, +0,180,1,2597,1715, +16,0,180,1,198, +1716,19,1717,4,38, +86,0,111,0,105, +0,100,0,65,0, +114,0,103,0,83, +0,116,0,97,0, +116,0,101,0,69, +0,118,0,101,0, +110,0,116,0,95, +0,49,0,1,198, +1718,5,4,1,2659, +1719,16,0,577,1, +2470,1720,16,0,577, +1,2703,1721,16,0, +177,1,2597,1722,16, +0,177,1,197,1723, +19,1724,4,24,83, +0,116,0,97,0, +116,0,101,0,69, +0,118,0,101,0, +110,0,116,0,95, +0,49,0,1,197, +1725,5,4,1,2659, +1726,16,0,155,1, +2470,1727,16,0,155, +1,2703,1728,16,0, +176,1,2597,1729,16, +0,176,1,196,1730, +19,1731,4,24,83, +0,116,0,97,0, +116,0,101,0,66, +0,111,0,100,0, +121,0,95,0,49, +0,54,0,1,196, +1732,5,2,1,2470, +1733,16,0,199,1, +2659,1734,16,0,134, +1,195,1735,19,1736, +4,24,83,0,116, +0,97,0,116,0, +101,0,66,0,111, +0,100,0,121,0, +95,0,49,0,53, +0,1,195,1732,1, +194,1737,19,1738,4, +24,83,0,116,0, +97,0,116,0,101, +0,66,0,111,0, +100,0,121,0,95, +0,49,0,52,0, +1,194,1732,1,193, +1739,19,1740,4,24, +83,0,116,0,97, +0,116,0,101,0, +66,0,111,0,100, +0,121,0,95,0, +49,0,51,0,1, +193,1732,1,192,1741, +19,1742,4,24,83, +0,116,0,97,0, +116,0,101,0,66, +0,111,0,100,0, +121,0,95,0,49, +0,50,0,1,192, +1732,1,191,1743,19, +1744,4,24,83,0, +116,0,97,0,116, +0,101,0,66,0, +111,0,100,0,121, +0,95,0,49,0, +49,0,1,191,1732, +1,190,1745,19,1746, +4,24,83,0,116, +0,97,0,116,0, +101,0,66,0,111, +0,100,0,121,0, +95,0,49,0,48, +0,1,190,1732,1, +189,1747,19,1748,4, +22,83,0,116,0, +97,0,116,0,101, +0,66,0,111,0, +100,0,121,0,95, +0,57,0,1,189, +1732,1,188,1749,19, +1750,4,22,83,0, +116,0,97,0,116, +0,101,0,66,0, +111,0,100,0,121, +0,95,0,56,0, +1,188,1732,1,187, +1751,19,1752,4,22, +83,0,116,0,97, +0,116,0,101,0, +66,0,111,0,100, +0,121,0,95,0, +55,0,1,187,1732, +1,186,1753,19,1754, +4,22,83,0,116, +0,97,0,116,0, +101,0,66,0,111, +0,100,0,121,0, +95,0,54,0,1, +186,1732,1,185,1755, +19,1756,4,22,83, +0,116,0,97,0, +116,0,101,0,66, +0,111,0,100,0, +121,0,95,0,53, +0,1,185,1732,1, +184,1757,19,1758,4, +22,83,0,116,0, +97,0,116,0,101, +0,66,0,111,0, +100,0,121,0,95, +0,52,0,1,184, +1732,1,183,1759,19, +1760,4,22,83,0, +116,0,97,0,116, +0,101,0,66,0, +111,0,100,0,121, +0,95,0,51,0, +1,183,1732,1,182, +1761,19,1762,4,22, +83,0,116,0,97, +0,116,0,101,0, +66,0,111,0,100, +0,121,0,95,0, +50,0,1,182,1732, +1,181,1763,19,1764, +4,22,83,0,116, +0,97,0,116,0, +101,0,66,0,111, +0,100,0,121,0, +95,0,49,0,1, +181,1732,1,180,1765, +19,1766,4,14,83, +0,116,0,97,0, +116,0,101,0,95, +0,50,0,1,180, +1767,5,4,1,2764, +1768,16,0,192,1, +2834,1769,16,0,192, +1,2823,1770,16,0, +782,1,0,1771,16, +0,782,1,179,1772, +19,1773,4,14,83, +0,116,0,97,0, +116,0,101,0,95, +0,49,0,1,179, +1767,1,178,1774,19, +1775,4,16,83,0, +116,0,97,0,116, +0,101,0,115,0, +95,0,50,0,1, +178,1776,5,2,1, +0,1777,16,0,582, +1,2823,1778,16,0, +724,1,177,1779,19, +1780,4,16,83,0, +116,0,97,0,116, +0,101,0,115,0, +95,0,49,0,1, +177,1776,1,176,1781, +19,1782,4,52,71, +0,108,0,111,0, +98,0,97,0,108, +0,70,0,117,0, +110,0,99,0,116, +0,105,0,111,0, +110,0,68,0,101, +0,102,0,105,0, +110,0,105,0,116, +0,105,0,111,0, +110,0,95,0,50, +0,1,176,1783,5, +2,1,0,1784,16, +0,711,1,2823,1785, +16,0,717,1,175, +1786,19,1787,4,52, +71,0,108,0,111, +0,98,0,97,0, +108,0,70,0,117, +0,110,0,99,0, +116,0,105,0,111, +0,110,0,68,0, +101,0,102,0,105, +0,110,0,105,0, +116,0,105,0,111, +0,110,0,95,0, +49,0,1,175,1783, +1,174,1788,19,1789, +4,54,71,0,108, +0,111,0,98,0, +97,0,108,0,86, +0,97,0,114,0, +105,0,97,0,98, +0,108,0,101,0, +68,0,101,0,99, +0,108,0,97,0, +114,0,97,0,116, +0,105,0,111,0, +110,0,95,0,50, +0,1,174,1790,5, +2,1,0,1791,16, +0,710,1,2823,1792, +16,0,519,1,173, +1793,19,1794,4,54, +71,0,108,0,111, +0,98,0,97,0, +108,0,86,0,97, +0,114,0,105,0, +97,0,98,0,108, +0,101,0,68,0, +101,0,99,0,108, +0,97,0,114,0, +97,0,116,0,105, +0,111,0,110,0, +95,0,49,0,1, +173,1790,1,172,1795, +19,1796,4,38,71, +0,108,0,111,0, +98,0,97,0,108, +0,68,0,101,0, +102,0,105,0,110, +0,105,0,116,0, +105,0,111,0,110, +0,115,0,95,0, +52,0,1,172,1797, +5,1,1,0,1798, +16,0,610,1,171, +1799,19,1800,4,38, +71,0,108,0,111, +0,98,0,97,0, +108,0,68,0,101, +0,102,0,105,0, +110,0,105,0,116, +0,105,0,111,0, +110,0,115,0,95, +0,51,0,1,171, +1797,1,170,1801,19, +1802,4,38,71,0, +108,0,111,0,98, +0,97,0,108,0, +68,0,101,0,102, +0,105,0,110,0, +105,0,116,0,105, +0,111,0,110,0, +115,0,95,0,50, +0,1,170,1797,1, +169,1803,19,1804,4, +38,71,0,108,0, +111,0,98,0,97, +0,108,0,68,0, +101,0,102,0,105, +0,110,0,105,0, +116,0,105,0,111, +0,110,0,115,0, +95,0,49,0,1, +169,1797,1,168,1805, +19,1806,4,32,76, +0,83,0,76,0, +80,0,114,0,111, +0,103,0,114,0, +97,0,109,0,82, +0,111,0,111,0, +116,0,95,0,50, +0,1,168,1807,5, +1,1,0,1808,16, +0,104,1,167,1809, +19,1810,4,32,76, +0,83,0,76,0, +80,0,114,0,111, +0,103,0,114,0, +97,0,109,0,82, +0,111,0,111,0, +116,0,95,0,49, +0,1,167,1807,1, +165,1811,19,1812,4, +56,73,0,110,0, +99,0,114,0,101, +0,109,0,101,0, +110,0,116,0,68, +0,101,0,99,0, +114,0,101,0,109, +0,101,0,110,0, +116,0,69,0,120, +0,112,0,114,0, +101,0,115,0,115, +0,105,0,111,0, +110,0,1,165,1045, +1,164,1813,19,1814, +4,42,80,0,97, +0,114,0,101,0, +110,0,116,0,104, +0,101,0,115,0, +105,0,115,0,69, +0,120,0,112,0, +114,0,101,0,115, +0,115,0,105,0, +111,0,110,0,1, +164,1045,1,163,1815, +19,1816,4,36,84, +0,121,0,112,0, +101,0,99,0,97, +0,115,0,116,0, +69,0,120,0,112, +0,114,0,101,0, +115,0,115,0,105, +0,111,0,110,0, +1,163,1045,1,162, +1817,19,1818,4,30, +85,0,110,0,97, +0,114,0,121,0, +69,0,120,0,112, +0,114,0,101,0, +115,0,115,0,105, +0,111,0,110,0, +1,162,1045,1,161, +1819,19,1820,4,32, +66,0,105,0,110, +0,97,0,114,0, +121,0,69,0,120, +0,112,0,114,0, +101,0,115,0,115, +0,105,0,111,0, +110,0,1,161,1045, +1,160,1821,19,1822, +4,44,70,0,117, +0,110,0,99,0, +116,0,105,0,111, +0,110,0,67,0, +97,0,108,0,108, +0,69,0,120,0, +112,0,114,0,101, +0,115,0,115,0, +105,0,111,0,110, +0,1,160,1045,1, +159,1823,19,1824,4, +36,73,0,100,0, +101,0,110,0,116, +0,68,0,111,0, +116,0,69,0,120, +0,112,0,114,0, +101,0,115,0,115, +0,105,0,111,0, +110,0,1,159,1045, +1,158,1825,19,1826, +4,30,73,0,100, +0,101,0,110,0, +116,0,69,0,120, +0,112,0,114,0, +101,0,115,0,115, +0,105,0,111,0, +110,0,1,158,1045, +1,157,1827,19,1828, +4,36,67,0,111, +0,110,0,115,0, +116,0,97,0,110, +0,116,0,69,0, +120,0,112,0,114, +0,101,0,115,0, +115,0,105,0,111, +0,110,0,1,157, +1045,1,156,1829,19, +130,1,156,1045,1, +155,1830,19,1831,4, +24,76,0,105,0, +115,0,116,0,67, +0,111,0,110,0, +115,0,116,0,97, +0,110,0,116,0, +1,155,1201,1,154, +1832,19,1833,4,32, +82,0,111,0,116, +0,97,0,116,0, +105,0,111,0,110, +0,67,0,111,0, +110,0,115,0,116, +0,97,0,110,0, +116,0,1,154,1201, +1,153,1834,19,1835, +4,28,86,0,101, +0,99,0,116,0, +111,0,114,0,67, +0,111,0,110,0, +115,0,116,0,97, +0,110,0,116,0, +1,153,1201,1,152, +1836,19,540,1,152, +1201,1,151,1837,19, +1838,4,36,69,0, +120,0,112,0,114, +0,101,0,115,0, +115,0,105,0,111, +0,110,0,65,0, +114,0,103,0,117, +0,109,0,101,0, +110,0,116,0,1, +151,964,1,150,1839, +19,485,1,150,964, +1,149,1840,19,133, +1,149,812,1,148, +1841,19,555,1,148, +974,1,147,1842,19, +142,1,147,1396,1, +146,1843,19,653,1, +146,1408,1,145,1844, +19,650,1,145,1424, +1,144,1845,19,647, +1,144,1440,1,143, +1846,19,167,1,143, +1456,1,142,1847,19, +643,1,142,1476,1, +141,1848,19,621,1, +141,1492,1,140,1849, +19,635,1,140,1506, +1,139,1850,19,631, +1,139,1284,1,138, +1851,19,108,1,138, +1300,1,137,1852,19, +474,1,137,1380,1, +136,1853,19,625,1, +136,1558,1,135,1854, +19,123,1,135,1520, +1,134,1855,19,449, +1,134,1572,1,133, +1856,19,202,1,133, +1578,1,132,1857,19, +320,1,132,821,1, +131,1858,19,298,1, +131,828,1,130,1859, +19,280,1,130,835, +1,129,1860,19,471, +1,129,842,1,128, +1861,19,241,1,128, +853,1,127,1862,19, +229,1,127,878,1, +126,1863,19,445,1, +126,887,1,125,1864, +19,211,1,125,908, +1,124,1865,19,745, +1,124,931,1,123, +1866,19,265,1,123, +1604,1,122,1867,19, +249,1,122,1609,1, +121,1868,19,237,1, +121,1615,1,120,1869, +19,225,1,120,1623, +1,119,1870,19,275, +1,119,1628,1,118, +1871,19,303,1,118, +1648,1,117,1872,19, +285,1,117,1652,1, +116,1873,19,260,1, +116,1656,1,115,1874, +19,246,1,115,1660, +1,114,1875,19,234, +1,114,1664,1,113, +1876,19,222,1,113, +1668,1,112,1877,19, +206,1,112,804,1, +111,1878,19,191,1, +111,1676,1,110,1879, +19,173,1,110,1683, +1,109,1880,19,170, +1,109,1690,1,108, +1881,19,186,1,108, +1697,1,107,1882,19, +164,1,107,1704,1, +106,1883,19,182,1, +106,1711,1,105,1884, +19,179,1,105,1718, +1,104,1885,19,157, +1,104,1725,1,103, +1886,19,136,1,103, +1732,1,102,1887,19, +194,1,102,1767,1, +101,1888,19,584,1, +101,1776,1,100,1889, +19,713,1,100,1783, +1,99,1890,19,521, +1,99,1790,1,98, +1891,19,612,1,98, +1797,1,97,1892,19, +103,1,97,1807,1, +96,1893,19,497,1, +96,1894,5,95,1, +1574,1895,17,1896,15, +1897,4,20,37,0, +83,0,116,0,97, +0,116,0,101,0, +109,0,101,0,110, +0,116,0,1,-1, +1,5,1898,20,1549, +1,226,1,3,1, +3,1,2,1899,22, +1,61,1,2035,1900, +17,1901,15,1897,1, +-1,1,5,1902,20, +1541,1,230,1,3, +1,3,1,2,1903, +22,1,65,1,1371, +1904,16,0,495,1, +71,1905,16,0,495, +1,1958,1906,16,0, +495,1,381,1907,16, +0,495,1,2106,1908, +16,0,495,1,1931, +1909,17,1910,15,1911, +4,30,37,0,87, +0,104,0,105,0, +108,0,101,0,83, +0,116,0,97,0, +116,0,101,0,109, +0,101,0,110,0, +116,0,1,-1,1, +5,1912,20,1453,1, +244,1,3,1,6, +1,5,1913,22,1, +79,1,1756,1914,16, +0,495,1,2031,1915, +17,1916,15,1897,1, +-1,1,5,1917,20, +1535,1,233,1,3, +1,2,1,1,1918, +22,1,68,1,509, +1919,16,0,495,1, +2337,1920,16,0,495, +1,2029,1921,17,1922, +15,1897,1,-1,1, +5,1923,20,1519,1, +235,1,3,1,2, +1,1,1924,22,1, +70,1,1153,1925,16, +0,495,1,2136,1926, +17,1927,15,1928,4, +24,37,0,73,0, +102,0,83,0,116, +0,97,0,116,0, +101,0,109,0,101, +0,110,0,116,0, +1,-1,1,5,1929, +20,1455,1,243,1, +3,1,8,1,7, +1930,22,1,78,1, +1933,1931,16,0,495, +1,2198,1932,16,0, +495,1,1731,1933,16, +0,495,1,1335,1934, +16,0,495,1,2318, +1935,16,0,495,1, +346,1936,16,0,495, +1,182,1937,16,0, +495,1,137,1938,16, +0,495,1,1515,1939, +16,0,495,1,2105, +1940,17,1941,15,1928, +1,-1,1,5,1942, +20,1469,1,242,1, +3,1,6,1,5, +1943,22,1,77,1, +1775,1944,16,0,495, +1,1117,1945,16,0, +495,1,525,1946,16, +0,495,1,52,1947, +16,0,495,1,1901, +1948,16,0,495,1, +2293,1949,16,0,495, +1,322,1950,16,0, +495,1,124,1951,16, +0,495,1,1695,1952, +16,0,495,1,1297, +1953,16,0,495,1, +151,1954,16,0,495, +1,112,1955,16,0, +495,1,1990,1956,16, +0,495,1,76,1957, +16,0,495,1,43, +1958,16,0,495,1, +2075,1959,16,0,495, +1,1876,1960,16,0, +495,1,299,1961,16, +0,495,1,1479,1962, +16,0,495,1,2462, +1963,17,1964,15,1965, +4,28,37,0,83, +0,116,0,97,0, +116,0,101,0,109, +0,101,0,110,0, +116,0,76,0,105, +0,115,0,116,0, +1,-1,1,5,1966, +20,1575,1,220,1, +3,1,2,1,1, +1967,22,1,55,1, +97,1968,16,0,495, +1,2459,1969,17,1970, +15,1971,4,36,37, +0,67,0,111,0, +109,0,112,0,111, +0,117,0,110,0, +100,0,83,0,116, +0,97,0,116,0, +101,0,109,0,101, +0,110,0,116,0, +1,-1,1,5,1972, +20,1577,1,219,1, +3,1,4,1,3, +1973,22,1,54,1, +2458,1974,17,1975,15, +1965,1,-1,1,5, +1976,20,1571,1,221, +1,3,1,3,1, +2,1977,22,1,56, +1,2030,1978,17,1979, +15,1897,1,-1,1, +5,1980,20,1533,1, +234,1,3,1,2, +1,1,1981,22,1, +69,1,89,1982,16, +0,495,1,1860,1983, +17,1984,15,1985,4, +34,37,0,68,0, +111,0,87,0,104, +0,105,0,108,0, +101,0,83,0,116, +0,97,0,116,0, +101,0,109,0,101, +0,110,0,116,0, +1,-1,1,5,1986, +20,1437,1,246,1, +3,1,8,1,7, +1987,22,1,81,1, +85,1988,16,0,495, +1,1659,1989,16,0, +495,1,1657,1990,17, +1991,15,1897,1,-1, +1,5,1992,20,1553, +1,224,1,3,1, +3,1,2,1993,22, +1,59,1,277,1994, +16,0,495,1,1261, +1995,16,0,495,1, +166,1996,16,0,495, +1,2045,1997,17,1998, +15,1897,1,-1,1, +5,1999,20,1555,1, +223,1,3,1,3, +1,2,2000,22,1, +58,1,2043,2001,17, +2002,15,1897,1,-1, +1,5,2003,20,1551, +1,225,1,3,1, +3,1,2,2004,22, +1,60,1,2041,2005, +17,2006,15,1897,1, +-1,1,5,2007,20, +1547,1,227,1,3, +1,3,1,2,2008, +22,1,62,1,2039, +2009,17,2010,15,1897, +1,-1,1,5,2011, +20,1545,1,228,1, +3,1,3,1,2, +2012,22,1,63,1, +462,2013,16,0,495, +1,2037,2014,17,2015, +15,1897,1,-1,1, +5,2016,20,1543,1, +229,1,3,1,3, +1,2,2017,22,1, +64,1,459,2018,16, +0,495,1,1443,2019, +16,0,495,1,2033, +2020,17,2021,15,1897, +1,-1,1,5,2022, +20,1539,1,231,1, +3,1,2,1,1, +2023,22,1,66,1, +2032,2024,17,2025,15, +1897,1,-1,1,5, +2026,20,1537,1,232, +1,3,1,2,1, +1,2027,22,1,67, +1,1834,2028,16,0, +495,1,2227,2029,17, +2030,15,1911,1,-1, +1,5,2031,20,1439, +1,245,1,3,1, +6,1,5,2032,22, +1,80,1,256,2033, +16,0,495,1,447, +2034,16,0,495,1, +62,2035,16,0,495, +1,2021,2036,17,2037, +15,1928,1,-1,1, +5,2038,20,1471,1, +241,1,3,1,8, +1,7,2039,22,1, +76,1,2413,2040,16, +0,495,1,1622,2041, +16,0,495,1,2464, +2042,17,2043,15,1971, +1,-1,1,5,2044, +20,1601,1,218,1, +3,1,3,1,2, +2045,22,1,53,1, +1225,2046,16,0,495, +1,41,2047,16,0, +495,1,236,2048,16, +0,495,1,431,2049, +16,0,495,1,32, +2050,16,0,495,1, +1804,2051,16,0,495, +1,1803,2052,17,2053, +15,2054,4,16,37, +0,70,0,111,0, +114,0,76,0,111, +0,111,0,112,0, +1,-1,1,5,2055, +20,1421,1,248,1, +3,1,10,1,9, +2056,22,1,83,1, +1407,2057,16,0,495, +1,79,2058,16,0, +495,1,217,2059,16, +0,495,1,1989,2060, +17,2061,15,1928,1, +-1,1,5,2062,20, +1473,1,240,1,3, +1,6,1,5,2063, +22,1,75,1,102, +2064,16,0,495,1, +2786,2065,16,0,495, +1,406,2066,16,0, +495,1,1585,2067,16, +0,495,1,1189,2068, +16,0,495,1,1873, +2069,17,2070,15,1985, +1,-1,1,5,2071, +20,1423,1,247,1, +3,1,8,1,7, +2072,22,1,82,1, +199,2073,16,0,495, +1,2364,2074,17,2075, +15,2054,1,-1,1, +5,2076,20,1407,1, +249,1,3,1,9, +1,8,2077,22,1, +84,1,95,2078,19, +494,1,95,2079,5, +95,1,1574,1895,1, +2035,1900,1,1371,2080, +16,0,492,1,71, +2081,16,0,492,1, +1958,2082,16,0,492, +1,381,2083,16,0, +492,1,2106,2084,16, +0,492,1,1931,1909, +1,1756,2085,16,0, +492,1,2031,1915,1, +509,2086,16,0,492, +1,2337,2087,16,0, +492,1,2029,1921,1, +1153,2088,16,0,492, +1,2136,1926,1,1933, +2089,16,0,492,1, +2198,2090,16,0,492, +1,1731,2091,16,0, +492,1,1335,2092,16, +0,492,1,2318,2093, +16,0,492,1,346, +2094,16,0,492,1, +182,2095,16,0,492, +1,137,2096,16,0, +492,1,1515,2097,16, +0,492,1,2105,1940, +1,1775,2098,16,0, +492,1,1117,2099,16, +0,492,1,525,2100, +16,0,492,1,52, +2101,16,0,492,1, +1901,2102,16,0,492, +1,2293,2103,16,0, +492,1,322,2104,16, +0,492,1,124,2105, +16,0,492,1,1695, +2106,16,0,492,1, +1297,2107,16,0,492, +1,151,2108,16,0, +492,1,112,2109,16, +0,492,1,1990,2110, +16,0,492,1,76, +2111,16,0,492,1, +43,2112,16,0,492, +1,2075,2113,16,0, +492,1,1876,2114,16, +0,492,1,299,2115, +16,0,492,1,1479, +2116,16,0,492,1, +2462,1963,1,97,2117, +16,0,492,1,2459, +1969,1,2458,1974,1, +2030,1978,1,89,2118, +16,0,492,1,1860, +1983,1,85,2119,16, +0,492,1,1659,2120, +16,0,492,1,1657, +1990,1,277,2121,16, +0,492,1,1261,2122, +16,0,492,1,166, +2123,16,0,492,1, +2045,1997,1,2043,2001, +1,2041,2005,1,2039, +2009,1,462,2124,16, +0,492,1,2037,2014, +1,459,2125,16,0, +492,1,1443,2126,16, +0,492,1,2033,2020, +1,2032,2024,1,1834, +2127,16,0,492,1, +2227,2029,1,256,2128, +16,0,492,1,447, +2129,16,0,492,1, +62,2130,16,0,492, +1,2021,2036,1,2413, +2131,16,0,492,1, +1622,2132,16,0,492, +1,2464,2042,1,1225, +2133,16,0,492,1, +41,2134,16,0,492, +1,236,2135,16,0, +492,1,431,2136,16, +0,492,1,32,2137, +16,0,492,1,1804, +2138,16,0,492,1, +1803,2052,1,1407,2139, +16,0,492,1,79, +2140,16,0,492,1, +217,2141,16,0,492, +1,1989,2060,1,102, +2142,16,0,492,1, +2786,2143,16,0,492, +1,406,2144,16,0, +492,1,1585,2145,16, +0,492,1,1189,2146, +16,0,492,1,1873, +2069,1,199,2147,16, +0,492,1,2364,2074, +1,94,2148,19,491, +1,94,2149,5,95, +1,1574,1895,1,2035, +1900,1,1371,2150,16, +0,489,1,71,2151, +16,0,489,1,1958, +2152,16,0,489,1, +381,2153,16,0,489, +1,2106,2154,16,0, +489,1,1931,1909,1, +1756,2155,16,0,489, +1,2031,1915,1,509, +2156,16,0,489,1, +2337,2157,16,0,489, +1,2029,1921,1,1153, +2158,16,0,489,1, +2136,1926,1,1933,2159, +16,0,489,1,2198, +2160,16,0,489,1, +1731,2161,16,0,489, +1,1335,2162,16,0, +489,1,2318,2163,16, +0,489,1,346,2164, +16,0,489,1,182, +2165,16,0,489,1, +137,2166,16,0,489, +1,1515,2167,16,0, +489,1,2105,1940,1, +1775,2168,16,0,489, +1,1117,2169,16,0, +489,1,525,2170,16, +0,489,1,52,2171, +16,0,489,1,1901, +2172,16,0,489,1, +2293,2173,16,0,489, +1,322,2174,16,0, +489,1,124,2175,16, +0,489,1,1695,2176, +16,0,489,1,1297, +2177,16,0,489,1, +151,2178,16,0,489, +1,112,2179,16,0, +489,1,1990,2180,16, +0,489,1,76,2181, +16,0,489,1,43, +2182,16,0,489,1, +2075,2183,16,0,489, +1,1876,2184,16,0, +489,1,299,2185,16, +0,489,1,1479,2186, +16,0,489,1,2462, +1963,1,97,2187,16, +0,489,1,2459,1969, +1,2458,1974,1,2030, +1978,1,89,2188,16, +0,489,1,1860,1983, +1,85,2189,16,0, +489,1,1659,2190,16, +0,489,1,1657,1990, +1,277,2191,16,0, +489,1,1261,2192,16, +0,489,1,166,2193, +16,0,489,1,2045, +1997,1,2043,2001,1, +2041,2005,1,2039,2009, +1,462,2194,16,0, +489,1,2037,2014,1, +459,2195,16,0,489, +1,1443,2196,16,0, +489,1,2033,2020,1, +2032,2024,1,1834,2197, +16,0,489,1,2227, +2029,1,256,2198,16, +0,489,1,447,2199, +16,0,489,1,62, +2200,16,0,489,1, +2021,2036,1,2413,2201, +16,0,489,1,1622, +2202,16,0,489,1, +2464,2042,1,1225,2203, +16,0,489,1,41, +2204,16,0,489,1, +236,2205,16,0,489, +1,431,2206,16,0, +489,1,32,2207,16, +0,489,1,1804,2208, +16,0,489,1,1803, +2052,1,1407,2209,16, +0,489,1,79,2210, +16,0,489,1,217, +2211,16,0,489,1, +1989,2060,1,102,2212, +16,0,489,1,2786, +2213,16,0,489,1, +406,2214,16,0,489, +1,1585,2215,16,0, +489,1,1189,2216,16, +0,489,1,1873,2069, +1,199,2217,16,0, +489,1,2364,2074,1, +93,2218,19,161,1, +93,2219,5,129,1, +1574,1895,1,2035,1900, +1,1371,2220,16,0, +760,1,71,2221,16, +0,754,1,1958,2222, +16,0,760,1,381, +2223,16,0,754,1, +2106,2224,16,0,760, +1,1931,1909,1,378, +2225,16,0,541,1, +1756,2226,16,0,760, +1,376,2227,16,0, +159,1,2542,2228,16, +0,266,1,374,2229, +16,0,547,1,372, +2230,16,0,549,1, +509,2231,16,0,754, +1,2337,2232,16,0, +760,1,2029,1921,1, +1153,2233,16,0,760, +1,1901,2234,16,0, +760,1,2136,1926,1, +85,2235,16,0,754, +1,2527,2236,16,0, +289,1,65,2237,16, +0,739,1,1933,2238, +16,0,760,1,2198, +2239,16,0,760,1, +2811,2240,17,2241,15, +2242,4,52,37,0, +71,0,108,0,111, +0,98,0,97,0, +108,0,86,0,97, +0,114,0,105,0, +97,0,98,0,108, +0,101,0,68,0, +101,0,99,0,108, +0,97,0,114,0, +97,0,116,0,105, +0,111,0,110,0, +1,-1,1,5,2243, +20,1789,1,174,1, +3,1,5,1,4, +2244,22,1,8,1, +1731,2245,16,0,754, +1,1335,2246,16,0, +760,1,2318,2247,16, +0,760,1,346,2248, +16,0,754,1,2512, +2249,16,0,307,1, +2508,2250,16,0,313, +1,182,2251,16,0, +754,1,137,2252,16, +0,754,1,1515,2253, +16,0,760,1,2105, +1940,1,1873,2069,1, +1117,2254,16,0,760, +1,525,2255,16,0, +754,1,52,2256,16, +0,760,1,1113,2257, +16,0,644,1,46, +2258,16,0,752,1, +2293,2259,16,0,754, +1,322,2260,16,0, +754,1,124,2261,16, +0,754,1,1695,2262, +16,0,760,1,1297, +2263,16,0,760,1, +151,2264,16,0,754, +1,112,2265,16,0, +754,1,1990,2266,16, +0,760,1,199,2267, +16,0,754,1,76, +2268,16,0,754,1, +43,2269,16,0,754, +1,2075,2270,16,0, +760,1,2468,2271,16, +0,423,1,2822,2272, +17,2273,15,2242,1, +-1,1,5,2274,20, +1794,1,173,1,3, +1,3,1,2,2275, +22,1,7,1,299, +2276,16,0,754,1, +1479,2277,16,0,760, +1,2462,1963,1,97, +2278,16,0,754,1, +2031,1915,1,2459,1969, +1,2458,1974,1,2030, +1978,1,89,2279,16, +0,754,1,1860,1983, +1,2844,2280,17,2281, +15,2282,4,36,37, +0,71,0,108,0, +111,0,98,0,97, +0,108,0,68,0, +101,0,102,0,105, +0,110,0,105,0, +116,0,105,0,111, +0,110,0,115,0, +1,-1,1,5,2283, +20,1804,1,169,1, +3,1,2,1,1, +2284,22,1,3,1, +2843,2285,17,2286,15, +2282,1,-1,1,5, +2287,20,1800,1,171, +1,3,1,2,1, +1,2288,22,1,5, +1,2842,2289,17,2290, +15,2282,1,-1,1, +5,2291,20,1802,1, +170,1,3,1,3, +1,2,2292,22,1, +4,1,1659,2293,16, +0,760,1,1657,1990, +1,277,2294,16,0, +754,1,1261,2295,16, +0,760,1,2841,2296, +17,2297,15,2282,1, +-1,1,5,2298,20, +1796,1,172,1,3, +1,3,1,2,2299, +22,1,6,1,166, +2300,16,0,754,1, +2045,1997,1,2043,2001, +1,2041,2005,1,2039, +2009,1,462,2301,16, +0,754,1,2037,2014, +1,459,2302,16,0, +754,1,1443,2303,16, +0,760,1,2033,2020, +1,2032,2024,1,1834, +2304,16,0,760,1, +2227,2029,1,256,2305, +16,0,754,1,2027, +2306,16,0,655,1, +2025,2307,16,0,698, +1,447,2308,16,0, +754,1,2466,2309,17, +2310,15,2311,4,50, +37,0,71,0,108, +0,111,0,98,0, +97,0,108,0,70, +0,117,0,110,0, +99,0,116,0,105, +0,111,0,110,0, +68,0,101,0,102, +0,105,0,110,0, +105,0,116,0,105, +0,111,0,110,0, +1,-1,1,5,2312, +20,1782,1,176,1, +3,1,7,1,6, +2313,22,1,10,1, +2021,2036,1,7,2314, +17,2315,15,2316,4, +18,37,0,84,0, +121,0,112,0,101, +0,110,0,97,0, +109,0,101,0,1, +-1,1,5,2317,20, +961,1,337,1,3, +1,2,1,1,2318, +22,1,173,1,2413, +2319,16,0,760,1, +1876,2320,16,0,760, +1,1622,2321,16,0, +754,1,2464,2042,1, +1225,2322,16,0,760, +1,2022,2323,16,0, +663,1,41,2324,16, +0,754,1,236,2325, +16,0,754,1,431, +2326,16,0,754,1, +8,2327,16,0,784, +1,62,2328,16,0, +741,1,1804,2329,16, +0,760,1,1803,2052, +1,32,2330,16,0, +760,1,1407,2331,16, +0,760,1,2783,2332, +17,2333,15,2311,1, +-1,1,5,2334,20, +1787,1,175,1,3, +1,6,1,5,2335, +22,1,9,1,2, +2336,17,2337,15,2316, +1,-1,1,5,2338, +20,951,1,342,1, +3,1,2,1,1, +2339,22,1,178,1, +79,2340,16,0,754, +1,217,2341,16,0, +754,1,1989,2060,1, +18,2342,16,0,778, +1,102,2343,16,0, +754,1,2786,2344,16, +0,754,1,406,2345, +16,0,754,1,0, +2346,16,0,781,1, +1585,2347,16,0,754, +1,2823,2348,16,0, +781,1,1189,2349,16, +0,760,1,6,2350, +17,2351,15,2316,1, +-1,1,5,2352,20, +959,1,338,1,3, +1,2,1,1,2353, +22,1,174,1,5, +2354,17,2355,15,2316, +1,-1,1,5,2356, +20,957,1,339,1, +3,1,2,1,1, +2357,22,1,175,1, +4,2358,17,2359,15, +2316,1,-1,1,5, +2360,20,955,1,340, +1,3,1,2,1, +1,2361,22,1,176, +1,3,2362,17,2363, +15,2316,1,-1,1, +5,2364,20,953,1, +341,1,3,1,2, +1,1,2365,22,1, +177,1,1775,2366,16, +0,760,1,1,2367, +17,2368,15,2316,1, +-1,1,5,2369,20, +930,1,343,1,3, +1,2,1,1,2370, +22,1,179,1,2364, +2074,1,92,2371,19, +347,1,92,2372,5, +30,1,2580,2373,17, +2374,15,2375,4,36, +37,0,86,0,111, +0,105,0,100,0, +65,0,114,0,103, +0,83,0,116,0, +97,0,116,0,101, +0,69,0,118,0, +101,0,110,0,116, 0,1,-1,1,5, -2301,20,2302,4,62, -86,0,101,0,99, -0,116,0,111,0, -114,0,65,0,114, +2376,20,1717,1,198, +1,3,1,5,1, +4,2377,22,1,32, +1,2648,2378,17,2379, +15,2380,4,20,37, +0,83,0,116,0, +97,0,116,0,101, +0,66,0,111,0, +100,0,121,0,1, +-1,1,5,2381,20, +1762,1,182,1,3, +1,3,1,2,2382, +22,1,16,1,2575, +2383,17,2384,15,2385, +4,34,37,0,75, +0,101,0,121,0, +65,0,114,0,103, +0,83,0,116,0, +97,0,116,0,101, +0,69,0,118,0, +101,0,110,0,116, +0,1,-1,1,5, +2386,20,1710,1,199, +1,3,1,6,1, +5,2387,22,1,33, +1,2659,2388,16,0, +345,1,2657,2389,17, +2390,15,2380,1,-1, +1,5,2391,20,1764, +1,181,1,3,1, +2,1,1,2392,22, +1,15,1,2567,2393, +17,2394,15,2395,4, +34,37,0,73,0, +110,0,116,0,65, +0,114,0,103,0, +83,0,116,0,97, +0,116,0,101,0, +69,0,118,0,101, +0,110,0,116,0, +1,-1,1,5,2396, +20,1703,1,200,1, +3,1,6,1,5, +2397,22,1,34,1, +2655,2398,17,2399,15, +2380,1,-1,1,5, +2400,20,1756,1,185, +1,3,1,2,1, +1,2401,22,1,19, +1,2654,2402,17,2403, +15,2380,1,-1,1, +5,2404,20,1752,1, +187,1,3,1,2, +1,1,2405,22,1, +21,1,2653,2406,17, +2407,15,2380,1,-1, +1,5,2408,20,1748, +1,189,1,3,1, +2,1,1,2409,22, +1,23,1,2652,2410, +17,2411,15,2380,1, +-1,1,5,2412,20, +1744,1,191,1,3, +1,2,1,1,2413, +22,1,25,1,2651, +2414,17,2415,15,2380, +1,-1,1,5,2416, +20,1740,1,193,1, +3,1,2,1,1, +2417,22,1,27,1, +2650,2418,17,2419,15, +2380,1,-1,1,5, +2420,20,1736,1,195, +1,3,1,2,1, +1,2421,22,1,29, +1,2559,2422,17,2423, +15,2424,4,40,37, +0,86,0,101,0, +99,0,116,0,111, +0,114,0,65,0, +114,0,103,0,83, +0,116,0,97,0, +116,0,101,0,69, +0,118,0,101,0, +110,0,116,0,1, +-1,1,5,2425,20, +1696,1,201,1,3, +1,6,1,5,2426, +22,1,35,1,2647, +2427,17,2428,15,2380, +1,-1,1,5,2429, +20,1758,1,184,1, +3,1,3,1,2, +2430,22,1,18,1, +2646,2431,17,2432,15, +2380,1,-1,1,5, +2433,20,1754,1,186, +1,3,1,3,1, +2,2434,22,1,20, +1,2645,2435,17,2436, +15,2380,1,-1,1, +5,2437,20,1750,1, +188,1,3,1,3, +1,2,2438,22,1, +22,1,2644,2439,17, +2440,15,2380,1,-1, +1,5,2441,20,1746, +1,190,1,3,1, +3,1,2,2442,22, +1,24,1,2643,2443, +17,2444,15,2380,1, +-1,1,5,2445,20, +1742,1,192,1,3, +1,3,1,2,2446, +22,1,26,1,2464, +2042,1,2641,2447,17, +2448,15,2380,1,-1, +1,5,2449,20,1731, +1,196,1,3,1, +3,1,2,2450,22, +1,30,1,2551,2451, +17,2452,15,2453,4, +46,37,0,73,0, +110,0,116,0,82, +0,111,0,116,0, +82,0,111,0,116, +0,65,0,114,0, +103,0,83,0,116, +0,97,0,116,0, +101,0,69,0,118, +0,101,0,110,0, +116,0,1,-1,1, +5,2454,20,1689,1, +202,1,3,1,6, +1,5,2455,22,1, +36,1,2470,2456,16, +0,345,1,2459,1969, +1,2536,2457,17,2458, +15,2459,4,46,37, +0,73,0,110,0, +116,0,86,0,101, +0,99,0,86,0, +101,0,99,0,65, +0,114,0,103,0, +83,0,116,0,97, +0,116,0,101,0, +69,0,118,0,101, +0,110,0,116,0, +1,-1,1,5,2460, +20,1682,1,203,1, +3,1,6,1,5, +2461,22,1,37,1, +2703,2462,16,0,345, +1,2521,2463,17,2464, +15,2465,4,46,37, +0,75,0,101,0, +121,0,73,0,110, +0,116,0,73,0, +110,0,116,0,65, +0,114,0,103,0, +83,0,116,0,97, +0,116,0,101,0, +69,0,118,0,101, +0,110,0,116,0, +1,-1,1,5,2466, +20,1675,1,204,1, +3,1,6,1,5, +2467,22,1,38,1, +2642,2468,17,2469,15, +2380,1,-1,1,5, +2470,20,1738,1,194, +1,3,1,3,1, +2,2471,22,1,28, +1,2656,2472,17,2473, +15,2380,1,-1,1, +5,2474,20,1760,1, +183,1,3,1,2, +1,1,2475,22,1, +17,1,2597,2476,16, +0,345,1,2595,2477, +17,2478,15,2479,4, +22,37,0,83,0, +116,0,97,0,116, +0,101,0,69,0, +118,0,101,0,110, +0,116,0,1,-1, +1,5,2480,20,1724, +1,197,1,3,1, +6,1,5,2481,22, +1,31,1,91,2482, +19,344,1,91,2483, +5,30,1,2580,2373, +1,2648,2378,1,2575, +2383,1,2659,2484,16, +0,342,1,2657,2389, +1,2567,2393,1,2655, +2398,1,2654,2402,1, +2653,2406,1,2652,2410, +1,2651,2414,1,2650, +2418,1,2559,2422,1, +2647,2427,1,2646,2431, +1,2645,2435,1,2644, +2439,1,2643,2443,1, +2464,2042,1,2641,2447, +1,2551,2451,1,2470, +2485,16,0,342,1, +2459,1969,1,2536,2457, +1,2703,2486,16,0, +342,1,2521,2463,1, +2642,2468,1,2656,2472, +1,2597,2487,16,0, +342,1,2595,2477,1, +90,2488,19,402,1, +90,2489,5,30,1, +2580,2373,1,2648,2378, +1,2575,2383,1,2659, +2490,16,0,400,1, +2657,2389,1,2567,2393, +1,2655,2398,1,2654, +2402,1,2653,2406,1, +2652,2410,1,2651,2414, +1,2650,2418,1,2559, +2422,1,2647,2427,1, +2646,2431,1,2645,2435, +1,2644,2439,1,2643, +2443,1,2464,2042,1, +2641,2447,1,2551,2451, +1,2470,2491,16,0, +400,1,2459,1969,1, +2536,2457,1,2703,2492, +16,0,400,1,2521, +2463,1,2642,2468,1, +2656,2472,1,2597,2493, +16,0,400,1,2595, +2477,1,89,2494,19, +405,1,89,2495,5, +30,1,2580,2373,1, +2648,2378,1,2575,2383, +1,2659,2496,16,0, +403,1,2657,2389,1, +2567,2393,1,2655,2398, +1,2654,2402,1,2653, +2406,1,2652,2410,1, +2651,2414,1,2650,2418, +1,2559,2422,1,2647, +2427,1,2646,2431,1, +2645,2435,1,2644,2439, +1,2643,2443,1,2464, +2042,1,2641,2447,1, +2551,2451,1,2470,2497, +16,0,403,1,2459, +1969,1,2536,2457,1, +2703,2498,16,0,403, +1,2521,2463,1,2642, +2468,1,2656,2472,1, +2597,2499,16,0,403, +1,2595,2477,1,88, +2500,19,399,1,88, +2501,5,30,1,2580, +2373,1,2648,2378,1, +2575,2383,1,2659,2502, +16,0,397,1,2657, +2389,1,2567,2393,1, +2655,2398,1,2654,2402, +1,2653,2406,1,2652, +2410,1,2651,2414,1, +2650,2418,1,2559,2422, +1,2647,2427,1,2646, +2431,1,2645,2435,1, +2644,2439,1,2643,2443, +1,2464,2042,1,2641, +2447,1,2551,2451,1, +2470,2503,16,0,397, +1,2459,1969,1,2536, +2457,1,2703,2504,16, +0,397,1,2521,2463, +1,2642,2468,1,2656, +2472,1,2597,2505,16, +0,397,1,2595,2477, +1,87,2506,19,369, +1,87,2507,5,30, +1,2580,2373,1,2648, +2378,1,2575,2383,1, +2659,2508,16,0,367, +1,2657,2389,1,2567, +2393,1,2655,2398,1, +2654,2402,1,2653,2406, +1,2652,2410,1,2651, +2414,1,2650,2418,1, +2559,2422,1,2647,2427, +1,2646,2431,1,2645, +2435,1,2644,2439,1, +2643,2443,1,2464,2042, +1,2641,2447,1,2551, +2451,1,2470,2509,16, +0,367,1,2459,1969, +1,2536,2457,1,2703, +2510,16,0,367,1, +2521,2463,1,2642,2468, +1,2656,2472,1,2597, +2511,16,0,367,1, +2595,2477,1,86,2512, +19,353,1,86,2513, +5,30,1,2580,2373, +1,2648,2378,1,2575, +2383,1,2659,2514,16, +0,351,1,2657,2389, +1,2567,2393,1,2655, +2398,1,2654,2402,1, +2653,2406,1,2652,2410, +1,2651,2414,1,2650, +2418,1,2559,2422,1, +2647,2427,1,2646,2431, +1,2645,2435,1,2644, +2439,1,2643,2443,1, +2464,2042,1,2641,2447, +1,2551,2451,1,2470, +2515,16,0,351,1, +2459,1969,1,2536,2457, +1,2703,2516,16,0, +351,1,2521,2463,1, +2642,2468,1,2656,2472, +1,2597,2517,16,0, +351,1,2595,2477,1, +85,2518,19,350,1, +85,2519,5,30,1, +2580,2373,1,2648,2378, +1,2575,2383,1,2659, +2520,16,0,348,1, +2657,2389,1,2567,2393, +1,2655,2398,1,2654, +2402,1,2653,2406,1, +2652,2410,1,2651,2414, +1,2650,2418,1,2559, +2422,1,2647,2427,1, +2646,2431,1,2645,2435, +1,2644,2439,1,2643, +2443,1,2464,2042,1, +2641,2447,1,2551,2451, +1,2470,2521,16,0, +348,1,2459,1969,1, +2536,2457,1,2703,2522, +16,0,348,1,2521, +2463,1,2642,2468,1, +2656,2472,1,2597,2523, +16,0,348,1,2595, +2477,1,84,2524,19, +396,1,84,2525,5, +30,1,2580,2373,1, +2648,2378,1,2575,2383, +1,2659,2526,16,0, +394,1,2657,2389,1, +2567,2393,1,2655,2398, +1,2654,2402,1,2653, +2406,1,2652,2410,1, +2651,2414,1,2650,2418, +1,2559,2422,1,2647, +2427,1,2646,2431,1, +2645,2435,1,2644,2439, +1,2643,2443,1,2464, +2042,1,2641,2447,1, +2551,2451,1,2470,2527, +16,0,394,1,2459, +1969,1,2536,2457,1, +2703,2528,16,0,394, +1,2521,2463,1,2642, +2468,1,2656,2472,1, +2597,2529,16,0,394, +1,2595,2477,1,83, +2530,19,393,1,83, +2531,5,30,1,2580, +2373,1,2648,2378,1, +2575,2383,1,2659,2532, +16,0,391,1,2657, +2389,1,2567,2393,1, +2655,2398,1,2654,2402, +1,2653,2406,1,2652, +2410,1,2651,2414,1, +2650,2418,1,2559,2422, +1,2647,2427,1,2646, +2431,1,2645,2435,1, +2644,2439,1,2643,2443, +1,2464,2042,1,2641, +2447,1,2551,2451,1, +2470,2533,16,0,391, +1,2459,1969,1,2536, +2457,1,2703,2534,16, +0,391,1,2521,2463, +1,2642,2468,1,2656, +2472,1,2597,2535,16, +0,391,1,2595,2477, +1,82,2536,19,341, +1,82,2537,5,30, +1,2580,2373,1,2648, +2378,1,2575,2383,1, +2659,2538,16,0,339, +1,2657,2389,1,2567, +2393,1,2655,2398,1, +2654,2402,1,2653,2406, +1,2652,2410,1,2651, +2414,1,2650,2418,1, +2559,2422,1,2647,2427, +1,2646,2431,1,2645, +2435,1,2644,2439,1, +2643,2443,1,2464,2042, +1,2641,2447,1,2551, +2451,1,2470,2539,16, +0,339,1,2459,1969, +1,2536,2457,1,2703, +2540,16,0,339,1, +2521,2463,1,2642,2468, +1,2656,2472,1,2597, +2541,16,0,339,1, +2595,2477,1,81,2542, +19,390,1,81,2543, +5,30,1,2580,2373, +1,2648,2378,1,2575, +2383,1,2659,2544,16, +0,388,1,2657,2389, +1,2567,2393,1,2655, +2398,1,2654,2402,1, +2653,2406,1,2652,2410, +1,2651,2414,1,2650, +2418,1,2559,2422,1, +2647,2427,1,2646,2431, +1,2645,2435,1,2644, +2439,1,2643,2443,1, +2464,2042,1,2641,2447, +1,2551,2451,1,2470, +2545,16,0,388,1, +2459,1969,1,2536,2457, +1,2703,2546,16,0, +388,1,2521,2463,1, +2642,2468,1,2656,2472, +1,2597,2547,16,0, +388,1,2595,2477,1, +80,2548,19,375,1, +80,2549,5,30,1, +2580,2373,1,2648,2378, +1,2575,2383,1,2659, +2550,16,0,373,1, +2657,2389,1,2567,2393, +1,2655,2398,1,2654, +2402,1,2653,2406,1, +2652,2410,1,2651,2414, +1,2650,2418,1,2559, +2422,1,2647,2427,1, +2646,2431,1,2645,2435, +1,2644,2439,1,2643, +2443,1,2464,2042,1, +2641,2447,1,2551,2451, +1,2470,2551,16,0, +373,1,2459,1969,1, +2536,2457,1,2703,2552, +16,0,373,1,2521, +2463,1,2642,2468,1, +2656,2472,1,2597,2553, +16,0,373,1,2595, +2477,1,79,2554,19, +366,1,79,2555,5, +30,1,2580,2373,1, +2648,2378,1,2575,2383, +1,2659,2556,16,0, +364,1,2657,2389,1, +2567,2393,1,2655,2398, +1,2654,2402,1,2653, +2406,1,2652,2410,1, +2651,2414,1,2650,2418, +1,2559,2422,1,2647, +2427,1,2646,2431,1, +2645,2435,1,2644,2439, +1,2643,2443,1,2464, +2042,1,2641,2447,1, +2551,2451,1,2470,2557, +16,0,364,1,2459, +1969,1,2536,2457,1, +2703,2558,16,0,364, +1,2521,2463,1,2642, +2468,1,2656,2472,1, +2597,2559,16,0,364, +1,2595,2477,1,78, +2560,19,363,1,78, +2561,5,30,1,2580, +2373,1,2648,2378,1, +2575,2383,1,2659,2562, +16,0,361,1,2657, +2389,1,2567,2393,1, +2655,2398,1,2654,2402, +1,2653,2406,1,2652, +2410,1,2651,2414,1, +2650,2418,1,2559,2422, +1,2647,2427,1,2646, +2431,1,2645,2435,1, +2644,2439,1,2643,2443, +1,2464,2042,1,2641, +2447,1,2551,2451,1, +2470,2563,16,0,361, +1,2459,1969,1,2536, +2457,1,2703,2564,16, +0,361,1,2521,2463, +1,2642,2468,1,2656, +2472,1,2597,2565,16, +0,361,1,2595,2477, +1,77,2566,19,360, +1,77,2567,5,30, +1,2580,2373,1,2648, +2378,1,2575,2383,1, +2659,2568,16,0,358, +1,2657,2389,1,2567, +2393,1,2655,2398,1, +2654,2402,1,2653,2406, +1,2652,2410,1,2651, +2414,1,2650,2418,1, +2559,2422,1,2647,2427, +1,2646,2431,1,2645, +2435,1,2644,2439,1, +2643,2443,1,2464,2042, +1,2641,2447,1,2551, +2451,1,2470,2569,16, +0,358,1,2459,1969, +1,2536,2457,1,2703, +2570,16,0,358,1, +2521,2463,1,2642,2468, +1,2656,2472,1,2597, +2571,16,0,358,1, +2595,2477,1,76,2572, +19,600,1,76,2573, +5,30,1,2580,2373, +1,2648,2378,1,2575, +2383,1,2659,2574,16, +0,598,1,2657,2389, +1,2567,2393,1,2655, +2398,1,2654,2402,1, +2653,2406,1,2652,2410, +1,2651,2414,1,2650, +2418,1,2559,2422,1, +2647,2427,1,2646,2431, +1,2645,2435,1,2644, +2439,1,2643,2443,1, +2464,2042,1,2641,2447, +1,2551,2451,1,2470, +2575,16,0,598,1, +2459,1969,1,2536,2457, +1,2703,2576,16,0, +598,1,2521,2463,1, +2642,2468,1,2656,2472, +1,2597,2577,16,0, +598,1,2595,2477,1, +75,2578,19,356,1, +75,2579,5,30,1, +2580,2373,1,2648,2378, +1,2575,2383,1,2659, +2580,16,0,354,1, +2657,2389,1,2567,2393, +1,2655,2398,1,2654, +2402,1,2653,2406,1, +2652,2410,1,2651,2414, +1,2650,2418,1,2559, +2422,1,2647,2427,1, +2646,2431,1,2645,2435, +1,2644,2439,1,2643, +2443,1,2464,2042,1, +2641,2447,1,2551,2451, +1,2470,2581,16,0, +354,1,2459,1969,1, +2536,2457,1,2703,2582, +16,0,354,1,2521, +2463,1,2642,2468,1, +2656,2472,1,2597,2583, +16,0,354,1,2595, +2477,1,74,2584,19, +338,1,74,2585,5, +30,1,2580,2373,1, +2648,2378,1,2575,2383, +1,2659,2586,16,0, +336,1,2657,2389,1, +2567,2393,1,2655,2398, +1,2654,2402,1,2653, +2406,1,2652,2410,1, +2651,2414,1,2650,2418, +1,2559,2422,1,2647, +2427,1,2646,2431,1, +2645,2435,1,2644,2439, +1,2643,2443,1,2464, +2042,1,2641,2447,1, +2551,2451,1,2470,2587, +16,0,336,1,2459, +1969,1,2536,2457,1, +2703,2588,16,0,336, +1,2521,2463,1,2642, +2468,1,2656,2472,1, +2597,2589,16,0,336, +1,2595,2477,1,73, +2590,19,335,1,73, +2591,5,30,1,2580, +2373,1,2648,2378,1, +2575,2383,1,2659,2592, +16,0,333,1,2657, +2389,1,2567,2393,1, +2655,2398,1,2654,2402, +1,2653,2406,1,2652, +2410,1,2651,2414,1, +2650,2418,1,2559,2422, +1,2647,2427,1,2646, +2431,1,2645,2435,1, +2644,2439,1,2643,2443, +1,2464,2042,1,2641, +2447,1,2551,2451,1, +2470,2593,16,0,333, +1,2459,1969,1,2536, +2457,1,2703,2594,16, +0,333,1,2521,2463, +1,2642,2468,1,2656, +2472,1,2597,2595,16, +0,333,1,2595,2477, +1,72,2596,19,332, +1,72,2597,5,30, +1,2580,2373,1,2648, +2378,1,2575,2383,1, +2659,2598,16,0,330, +1,2657,2389,1,2567, +2393,1,2655,2398,1, +2654,2402,1,2653,2406, +1,2652,2410,1,2651, +2414,1,2650,2418,1, +2559,2422,1,2647,2427, +1,2646,2431,1,2645, +2435,1,2644,2439,1, +2643,2443,1,2464,2042, +1,2641,2447,1,2551, +2451,1,2470,2599,16, +0,330,1,2459,1969, +1,2536,2457,1,2703, +2600,16,0,330,1, +2521,2463,1,2642,2468, +1,2656,2472,1,2597, +2601,16,0,330,1, +2595,2477,1,71,2602, +19,730,1,71,2603, +5,30,1,2580,2373, +1,2648,2378,1,2575, +2383,1,2659,2604,16, +0,728,1,2657,2389, +1,2567,2393,1,2655, +2398,1,2654,2402,1, +2653,2406,1,2652,2410, +1,2651,2414,1,2650, +2418,1,2559,2422,1, +2647,2427,1,2646,2431, +1,2645,2435,1,2644, +2439,1,2643,2443,1, +2464,2042,1,2641,2447, +1,2551,2451,1,2470, +2605,16,0,728,1, +2459,1969,1,2536,2457, +1,2703,2606,16,0, +728,1,2521,2463,1, +2642,2468,1,2656,2472, +1,2597,2607,16,0, +728,1,2595,2477,1, +70,2608,19,411,1, +70,2609,5,30,1, +2580,2373,1,2648,2378, +1,2575,2383,1,2659, +2610,16,0,409,1, +2657,2389,1,2567,2393, +1,2655,2398,1,2654, +2402,1,2653,2406,1, +2652,2410,1,2651,2414, +1,2650,2418,1,2559, +2422,1,2647,2427,1, +2646,2431,1,2645,2435, +1,2644,2439,1,2643, +2443,1,2464,2042,1, +2641,2447,1,2551,2451, +1,2470,2611,16,0, +409,1,2459,1969,1, +2536,2457,1,2703,2612, +16,0,409,1,2521, +2463,1,2642,2468,1, +2656,2472,1,2597,2613, +16,0,409,1,2595, +2477,1,69,2614,19, +408,1,69,2615,5, +30,1,2580,2373,1, +2648,2378,1,2575,2383, +1,2659,2616,16,0, +406,1,2657,2389,1, +2567,2393,1,2655,2398, +1,2654,2402,1,2653, +2406,1,2652,2410,1, +2651,2414,1,2650,2418, +1,2559,2422,1,2647, +2427,1,2646,2431,1, +2645,2435,1,2644,2439, +1,2643,2443,1,2464, +2042,1,2641,2447,1, +2551,2451,1,2470,2617, +16,0,406,1,2459, +1969,1,2536,2457,1, +2703,2618,16,0,406, +1,2521,2463,1,2642, +2468,1,2656,2472,1, +2597,2619,16,0,406, +1,2595,2477,1,68, +2620,19,329,1,68, +2621,5,30,1,2580, +2373,1,2648,2378,1, +2575,2383,1,2659,2622, +16,0,327,1,2657, +2389,1,2567,2393,1, +2655,2398,1,2654,2402, +1,2653,2406,1,2652, +2410,1,2651,2414,1, +2650,2418,1,2559,2422, +1,2647,2427,1,2646, +2431,1,2645,2435,1, +2644,2439,1,2643,2443, +1,2464,2042,1,2641, +2447,1,2551,2451,1, +2470,2623,16,0,327, +1,2459,1969,1,2536, +2457,1,2703,2624,16, +0,327,1,2521,2463, +1,2642,2468,1,2656, +2472,1,2597,2625,16, +0,327,1,2595,2477, +1,67,2626,19,677, +1,67,2627,5,30, +1,2580,2373,1,2648, +2378,1,2575,2383,1, +2659,2628,16,0,675, +1,2657,2389,1,2567, +2393,1,2655,2398,1, +2654,2402,1,2653,2406, +1,2652,2410,1,2651, +2414,1,2650,2418,1, +2559,2422,1,2647,2427, +1,2646,2431,1,2645, +2435,1,2644,2439,1, +2643,2443,1,2464,2042, +1,2641,2447,1,2551, +2451,1,2470,2629,16, +0,675,1,2459,1969, +1,2536,2457,1,2703, +2630,16,0,675,1, +2521,2463,1,2642,2468, +1,2656,2472,1,2597, +2631,16,0,675,1, +2595,2477,1,66,2632, +19,323,1,66,2633, +5,30,1,2580,2373, +1,2648,2378,1,2575, +2383,1,2659,2634,16, +0,321,1,2657,2389, +1,2567,2393,1,2655, +2398,1,2654,2402,1, +2653,2406,1,2652,2410, +1,2651,2414,1,2650, +2418,1,2559,2422,1, +2647,2427,1,2646,2431, +1,2645,2435,1,2644, +2439,1,2643,2443,1, +2464,2042,1,2641,2447, +1,2551,2451,1,2470, +2635,16,0,321,1, +2459,1969,1,2536,2457, +1,2703,2636,16,0, +321,1,2521,2463,1, +2642,2468,1,2656,2472, +1,2597,2637,16,0, +321,1,2595,2477,1, +65,2638,19,421,1, +65,2639,5,30,1, +2580,2373,1,2648,2378, +1,2575,2383,1,2659, +2640,16,0,419,1, +2657,2389,1,2567,2393, +1,2655,2398,1,2654, +2402,1,2653,2406,1, +2652,2410,1,2651,2414, +1,2650,2418,1,2559, +2422,1,2647,2427,1, +2646,2431,1,2645,2435, +1,2644,2439,1,2643, +2443,1,2464,2042,1, +2641,2447,1,2551,2451, +1,2470,2641,16,0, +419,1,2459,1969,1, +2536,2457,1,2703,2642, +16,0,419,1,2521, +2463,1,2642,2468,1, +2656,2472,1,2597,2643, +16,0,419,1,2595, +2477,1,64,2644,19, +387,1,64,2645,5, +30,1,2580,2373,1, +2648,2378,1,2575,2383, +1,2659,2646,16,0, +385,1,2657,2389,1, +2567,2393,1,2655,2398, +1,2654,2402,1,2653, +2406,1,2652,2410,1, +2651,2414,1,2650,2418, +1,2559,2422,1,2647, +2427,1,2646,2431,1, +2645,2435,1,2644,2439, +1,2643,2443,1,2464, +2042,1,2641,2447,1, +2551,2451,1,2470,2647, +16,0,385,1,2459, +1969,1,2536,2457,1, +2703,2648,16,0,385, +1,2521,2463,1,2642, +2468,1,2656,2472,1, +2597,2649,16,0,385, +1,2595,2477,1,63, +2650,19,384,1,63, +2651,5,30,1,2580, +2373,1,2648,2378,1, +2575,2383,1,2659,2652, +16,0,382,1,2657, +2389,1,2567,2393,1, +2655,2398,1,2654,2402, +1,2653,2406,1,2652, +2410,1,2651,2414,1, +2650,2418,1,2559,2422, +1,2647,2427,1,2646, +2431,1,2645,2435,1, +2644,2439,1,2643,2443, +1,2464,2042,1,2641, +2447,1,2551,2451,1, +2470,2653,16,0,382, +1,2459,1969,1,2536, +2457,1,2703,2654,16, +0,382,1,2521,2463, +1,2642,2468,1,2656, +2472,1,2597,2655,16, +0,382,1,2595,2477, +1,62,2656,19,381, +1,62,2657,5,30, +1,2580,2373,1,2648, +2378,1,2575,2383,1, +2659,2658,16,0,379, +1,2657,2389,1,2567, +2393,1,2655,2398,1, +2654,2402,1,2653,2406, +1,2652,2410,1,2651, +2414,1,2650,2418,1, +2559,2422,1,2647,2427, +1,2646,2431,1,2645, +2435,1,2644,2439,1, +2643,2443,1,2464,2042, +1,2641,2447,1,2551, +2451,1,2470,2659,16, +0,379,1,2459,1969, +1,2536,2457,1,2703, +2660,16,0,379,1, +2521,2463,1,2642,2468, +1,2656,2472,1,2597, +2661,16,0,379,1, +2595,2477,1,61,2662, +19,378,1,61,2663, +5,30,1,2580,2373, +1,2648,2378,1,2575, +2383,1,2659,2664,16, +0,376,1,2657,2389, +1,2567,2393,1,2655, +2398,1,2654,2402,1, +2653,2406,1,2652,2410, +1,2651,2414,1,2650, +2418,1,2559,2422,1, +2647,2427,1,2646,2431, +1,2645,2435,1,2644, +2439,1,2643,2443,1, +2464,2042,1,2641,2447, +1,2551,2451,1,2470, +2665,16,0,376,1, +2459,1969,1,2536,2457, +1,2703,2666,16,0, +376,1,2521,2463,1, +2642,2468,1,2656,2472, +1,2597,2667,16,0, +376,1,2595,2477,1, +60,2668,19,372,1, +60,2669,5,30,1, +2580,2373,1,2648,2378, +1,2575,2383,1,2659, +2670,16,0,370,1, +2657,2389,1,2567,2393, +1,2655,2398,1,2654, +2402,1,2653,2406,1, +2652,2410,1,2651,2414, +1,2650,2418,1,2559, +2422,1,2647,2427,1, +2646,2431,1,2645,2435, +1,2644,2439,1,2643, +2443,1,2464,2042,1, +2641,2447,1,2551,2451, +1,2470,2671,16,0, +370,1,2459,1969,1, +2536,2457,1,2703,2672, +16,0,370,1,2521, +2463,1,2642,2468,1, +2656,2472,1,2597,2673, +16,0,370,1,2595, +2477,1,59,2674,19, +418,1,59,2675,5, +30,1,2580,2373,1, +2648,2378,1,2575,2383, +1,2659,2676,16,0, +416,1,2657,2389,1, +2567,2393,1,2655,2398, +1,2654,2402,1,2653, +2406,1,2652,2410,1, +2651,2414,1,2650,2418, +1,2559,2422,1,2647, +2427,1,2646,2431,1, +2645,2435,1,2644,2439, +1,2643,2443,1,2464, +2042,1,2641,2447,1, +2551,2451,1,2470,2677, +16,0,416,1,2459, +1969,1,2536,2457,1, +2703,2678,16,0,416, +1,2521,2463,1,2642, +2468,1,2656,2472,1, +2597,2679,16,0,416, +1,2595,2477,1,58, +2680,19,415,1,58, +2681,5,30,1,2580, +2373,1,2648,2378,1, +2575,2383,1,2659,2682, +16,0,413,1,2657, +2389,1,2567,2393,1, +2655,2398,1,2654,2402, +1,2653,2406,1,2652, +2410,1,2651,2414,1, +2650,2418,1,2559,2422, +1,2647,2427,1,2646, +2431,1,2645,2435,1, +2644,2439,1,2643,2443, +1,2464,2042,1,2641, +2447,1,2551,2451,1, +2470,2683,16,0,413, +1,2459,1969,1,2536, +2457,1,2703,2684,16, +0,413,1,2521,2463, +1,2642,2468,1,2656, +2472,1,2597,2685,16, +0,413,1,2595,2477, +1,57,2686,19,798, +1,57,2687,5,53, +1,1803,2052,1,2043, +2001,1,1775,2688,16, +0,796,1,2041,2005, +1,2843,2285,1,2039, +2009,1,1860,1983,1, +2037,2014,1,2035,1900, +1,2033,2020,1,2032, +2024,1,2031,1915,1, +2030,1978,1,2029,1921, +1,2106,2689,16,0, +796,1,2842,2289,1, +2823,2690,16,0,796, +1,2464,2042,1,2822, +2272,1,1931,1909,1, +1574,1895,1,2462,1963, +1,2105,1940,1,52, +2691,16,0,796,1, +2459,1969,1,2458,1974, +1,10,2692,16,0, +796,1,2811,2240,1, +2364,2074,1,32,2693, +16,0,796,1,2783, +2332,1,1958,2694,16, +0,796,1,2841,2296, +1,2582,2695,16,0, +796,1,2198,2696,16, +0,796,1,2021,2036, +1,1901,2697,16,0, +796,1,1989,2060,1, +1990,2698,16,0,796, +1,2075,2699,16,0, +796,1,1804,2700,16, +0,796,1,2337,2701, +16,0,796,1,21, +2702,16,0,796,1, +1657,1990,1,2770,2703, +16,0,796,1,2413, +2704,16,0,796,1, +2844,2280,1,2045,1997, +1,1873,2069,1,0, +2705,16,0,796,1, +2227,2029,1,2466,2309, +1,2136,1926,1,56, +2706,19,269,1,56, +2707,5,55,1,1803, +2052,1,2043,2001,1, +1775,2708,16,0,795, +1,2041,2005,1,2843, +2285,1,2039,2009,1, +1860,1983,1,2037,2014, +1,2035,1900,1,2075, +2709,16,0,795,1, +2033,2020,1,2032,2024, +1,2031,1915,1,2030, +1978,1,2029,1921,1, +2106,2710,16,0,795, +1,2842,2289,1,2823, +2711,16,0,795,1, +2464,2042,1,2822,2272, +1,1931,1909,1,1574, +1895,1,2462,1963,1, +2105,1940,1,52,2712, +16,0,795,1,2459, +1969,1,2458,1974,1, +2545,2713,16,0,267, +1,2811,2240,1,2364, +2074,1,2541,2714,16, +0,267,1,2783,2332, +1,1958,2715,16,0, +795,1,2841,2296,1, +2198,2716,16,0,795, +1,2021,2036,1,1901, +2717,16,0,795,1, +1989,2060,1,1990,2718, +16,0,795,1,2466, +2309,1,32,2719,16, +0,795,1,1804,2720, +16,0,795,1,2337, +2721,16,0,795,1, +21,2722,16,0,795, +1,1657,1990,1,2770, +2723,16,0,795,1, +2413,2724,16,0,795, +1,2844,2280,1,2045, +1997,1,10,2725,16, +0,795,1,1873,2069, +1,0,2726,16,0, +795,1,2227,2029,1, +2582,2727,16,0,795, +1,2136,1926,1,55, +2728,19,292,1,55, +2729,5,56,1,1803, +2052,1,2043,2001,1, +1775,2730,16,0,794, +1,2041,2005,1,2843, +2285,1,2039,2009,1, +1860,1983,1,2037,2014, +1,2035,1900,1,2033, +2020,1,2032,2024,1, +2031,1915,1,2030,1978, +1,2029,1921,1,2106, +2731,16,0,794,1, +2842,2289,1,2823,2732, +16,0,794,1,2464, +2042,1,2822,2272,1, +1931,1909,1,2553,2733, +16,0,290,1,2462, +1963,1,2105,1940,1, +52,2734,16,0,794, +1,2459,1969,1,2458, +1974,1,10,2735,16, +0,794,1,2811,2240, +1,2364,2074,1,32, +2736,16,0,794,1, +2783,2332,1,1958,2737, +16,0,794,1,2841, +2296,1,2582,2738,16, +0,794,1,2530,2739, +16,0,290,1,2198, +2740,16,0,794,1, +2021,2036,1,2526,2741, +16,0,290,1,1901, +2742,16,0,794,1, +1989,2060,1,1990,2743, +16,0,794,1,2075, +2744,16,0,794,1, +1804,2745,16,0,794, +1,2337,2746,16,0, +794,1,21,2747,16, +0,794,1,1574,1895, +1,1657,1990,1,2770, +2748,16,0,794,1, +2413,2749,16,0,794, +1,2844,2280,1,2045, +1997,1,1873,2069,1, +0,2750,16,0,794, +1,2227,2029,1,2466, +2309,1,2136,1926,1, +54,2751,19,316,1, +54,2752,5,55,1, +1803,2052,1,2043,2001, +1,1775,2753,16,0, +793,1,2041,2005,1, +2843,2285,1,2039,2009, +1,1860,1983,1,2037, +2014,1,2569,2754,16, +0,314,1,2811,2240, +1,2033,2020,1,2032, +2024,1,2031,1915,1, +2030,1978,1,2029,1921, +1,2106,2755,16,0, +793,1,2842,2289,1, +2823,2756,16,0,793, +1,2464,2042,1,2822, +2272,1,1931,1909,1, +1574,1895,1,2462,1963, +1,2105,1940,1,52, +2757,16,0,793,1, +2459,1969,1,2458,1974, +1,10,2758,16,0, +793,1,2841,2296,1, +2364,2074,1,32,2759, +16,0,793,1,2783, +2332,1,1958,2760,16, +0,793,1,2035,1900, +1,2582,2761,16,0, +793,1,2198,2762,16, +0,793,1,2021,2036, +1,1901,2763,16,0, +793,1,1989,2060,1, +1990,2764,16,0,793, +1,2075,2765,16,0, +793,1,1804,2766,16, +0,793,1,2337,2767, +16,0,793,1,21, +2768,16,0,793,1, +1657,1990,1,2507,2769, +16,0,314,1,2770, +2770,16,0,793,1, +2413,2771,16,0,793, +1,2844,2280,1,2045, +1997,1,1873,2069,1, +0,2772,16,0,793, +1,2227,2029,1,2466, +2309,1,2136,1926,1, +53,2773,19,792,1, +53,2774,5,53,1, +1803,2052,1,2043,2001, +1,1775,2775,16,0, +790,1,2041,2005,1, +2843,2285,1,2039,2009, +1,1860,1983,1,2037, +2014,1,2035,1900,1, +2033,2020,1,2032,2024, +1,2031,1915,1,2030, +1978,1,2029,1921,1, +2106,2776,16,0,790, +1,2842,2289,1,2823, +2777,16,0,790,1, +2464,2042,1,2822,2272, +1,1931,1909,1,1574, +1895,1,2462,1963,1, +2105,1940,1,52,2778, +16,0,790,1,2459, +1969,1,2458,1974,1, +10,2779,16,0,790, +1,2811,2240,1,2364, +2074,1,32,2780,16, +0,790,1,2783,2332, +1,1958,2781,16,0, +790,1,2841,2296,1, +2582,2782,16,0,790, +1,2198,2783,16,0, +790,1,2021,2036,1, +1901,2784,16,0,790, +1,1989,2060,1,1990, +2785,16,0,790,1, +2075,2786,16,0,790, +1,1804,2787,16,0, +790,1,2337,2788,16, +0,790,1,21,2789, +16,0,790,1,1657, +1990,1,2770,2790,16, +0,790,1,2413,2791, +16,0,790,1,2844, +2280,1,2045,1997,1, +1873,2069,1,0,2792, +16,0,790,1,2227, +2029,1,2466,2309,1, +2136,1926,1,52,2793, +19,789,1,52,2794, +5,53,1,1803,2052, +1,2043,2001,1,1775, +2795,16,0,787,1, +2041,2005,1,2843,2285, +1,2039,2009,1,1860, +1983,1,2037,2014,1, +2035,1900,1,2033,2020, +1,2032,2024,1,2031, +1915,1,2030,1978,1, +2029,1921,1,2106,2796, +16,0,787,1,2842, +2289,1,2823,2797,16, +0,787,1,2464,2042, +1,2822,2272,1,1931, +1909,1,1574,1895,1, +2462,1963,1,2105,1940, +1,52,2798,16,0, +787,1,2459,1969,1, +2458,1974,1,10,2799, +16,0,787,1,2811, +2240,1,2364,2074,1, +32,2800,16,0,787, +1,2783,2332,1,1958, +2801,16,0,787,1, +2841,2296,1,2582,2802, +16,0,787,1,2198, +2803,16,0,787,1, +2021,2036,1,1901,2804, +16,0,787,1,1989, +2060,1,1990,2805,16, +0,787,1,2075,2806, +16,0,787,1,1804, +2807,16,0,787,1, +2337,2808,16,0,787, +1,21,2809,16,0, +787,1,1657,1990,1, +2770,2810,16,0,787, +1,2413,2811,16,0, +787,1,2844,2280,1, +2045,1997,1,1873,2069, +1,0,2812,16,0, +787,1,2227,2029,1, +2466,2309,1,2136,1926, +1,51,2813,19,310, +1,51,2814,5,58, +1,1803,2052,1,2043, +2001,1,1775,2815,16, +0,786,1,2842,2289, +1,2843,2285,1,2039, +2009,1,1860,1983,1, +2037,2014,1,2035,1900, +1,2033,2020,1,2032, +2024,1,2198,2816,16, +0,786,1,2030,1978, +1,2515,2817,16,0, +308,1,2106,2818,16, +0,786,1,2561,2819, +16,0,308,1,1873, +2069,1,2823,2820,16, +0,786,1,2466,2309, +1,1931,1909,1,2464, +2042,1,2783,2332,1, +2462,1963,1,2105,1940, +1,52,2821,16,0, +786,1,2459,1969,1, +2458,1974,1,2822,2272, +1,2811,2240,1,2364, +2074,1,32,2822,16, +0,786,1,2029,1921, +1,2538,2823,16,0, +308,1,2841,2296,1, +2041,2005,1,1657,1990, +1,2021,2036,1,1901, +2824,16,0,786,1, +2523,2825,16,0,308, +1,1990,2826,16,0, +786,1,2075,2827,16, +0,786,1,1804,2828, +16,0,786,1,2337, +2829,16,0,786,1, +21,2830,16,0,786, +1,1574,1895,1,1989, +2060,1,2511,2831,16, +0,308,1,2770,2832, +16,0,786,1,2413, +2833,16,0,786,1, +2844,2280,1,2045,1997, +1,10,2834,16,0, +786,1,0,2835,16, +0,786,1,2031,1915, +1,1958,2836,16,0, +786,1,2227,2029,1, +2582,2837,16,0,786, +1,2136,1926,1,50, +2838,19,326,1,50, +2839,5,38,1,2045, +1997,1,2043,2001,1, +1775,2840,16,0,324, +1,2041,2005,1,2039, +2009,1,1860,1983,1, +2037,2014,1,2035,1900, +1,2033,2020,1,2032, +2024,1,2031,1915,1, +2030,1978,1,2029,1921, +1,2106,2841,16,0, +324,1,2464,2042,1, +1931,1909,1,1574,1895, +1,2462,1963,1,2105, +1940,1,2459,1969,1, +2458,1974,1,2364,2074, +1,1958,2842,16,0, +324,1,2198,2843,16, +0,324,1,2021,2036, +1,1901,2844,16,0, +324,1,1989,2060,1, +1803,2052,1,2075,2845, +16,0,324,1,1990, +2846,16,0,324,1, +1804,2847,16,0,324, +1,2337,2848,16,0, +324,1,1657,1990,1, +2413,2849,16,0,324, +1,32,2850,16,0, +324,1,1873,2069,1, +2227,2029,1,2136,1926, +1,49,2851,19,662, +1,49,2852,5,38, +1,2045,1997,1,2043, +2001,1,1775,2853,16, +0,660,1,2041,2005, +1,2039,2009,1,1860, +1983,1,2037,2014,1, +2035,1900,1,2033,2020, +1,2032,2024,1,2031, +1915,1,2030,1978,1, +2029,1921,1,2106,2854, +16,0,660,1,2464, +2042,1,1931,1909,1, +1574,1895,1,2462,1963, +1,2105,1940,1,2459, +1969,1,2458,1974,1, +2364,2074,1,1958,2855, +16,0,660,1,2198, +2856,16,0,660,1, +2021,2036,1,1901,2857, +16,0,660,1,1989, +2060,1,1803,2052,1, +2075,2858,16,0,660, +1,1990,2859,16,0, +660,1,1804,2860,16, +0,660,1,2337,2861, +16,0,660,1,1657, +1990,1,2413,2862,16, +0,660,1,32,2863, +16,0,660,1,1873, +2069,1,2227,2029,1, +2136,1926,1,48,2864, +19,426,1,48,2865, +5,54,1,1803,2052, +1,2043,2001,1,2755, +2866,17,2867,15,2868, +4,12,37,0,83, +0,116,0,97,0, +116,0,101,0,1, +-1,1,5,2869,20, +1773,1,179,1,3, +1,5,1,4,2870, +22,1,13,1,2041, +2005,1,2843,2285,1, +2039,2009,1,1860,1983, +1,2037,2014,1,2035, +1900,1,2033,2020,1, +2032,2024,1,2031,1915, +1,2030,1978,1,2029, +1921,1,2106,2871,16, +0,665,1,2842,2289, +1,2649,2872,17,2873, +15,2868,1,-1,1, +5,2874,20,1766,1, +180,1,3,1,6, +1,5,2875,22,1, +14,1,2768,2876,17, +2877,15,2878,4,14, +37,0,83,0,116, +0,97,0,116,0, +101,0,115,0,1, +-1,1,5,2879,20, +1780,1,177,1,3, +1,2,1,1,2880, +22,1,11,1,2823, +2881,16,0,424,1, +2822,2272,1,1931,1909, +1,2464,2042,1,2462, +1963,1,2105,1940,1, +2459,1969,1,2458,1974, +1,2811,2240,1,2364, +2074,1,32,2882,16, +0,665,1,2783,2332, +1,1958,2883,16,0, +665,1,2834,2884,16, +0,424,1,2841,2296, +1,2198,2885,16,0, +665,1,2021,2036,1, +1901,2886,16,0,665, +1,1989,2060,1,1990, +2887,16,0,665,1, +2075,2888,16,0,665, +1,1804,2889,16,0, +665,1,2337,2890,16, +0,665,1,1574,1895, +1,2045,1997,1,1657, +1990,1,1775,2891,16, +0,665,1,2413,2892, +16,0,665,1,2844, +2280,1,2767,2893,17, +2894,15,2878,1,-1, +1,5,2895,20,1775, +1,178,1,3,1, +3,1,2,2896,22, +1,12,1,2764,2897, +16,0,424,1,1873, +2069,1,0,2898,16, +0,424,1,2227,2029, +1,2466,2309,1,2136, +1926,1,47,2899,19, +154,1,47,2900,5, +19,1,2811,2240,1, +2768,2876,1,2844,2280, +1,2843,2285,1,2842, +2289,1,2767,2893,1, +2764,2901,16,0,152, +1,2022,2902,16,0, +664,1,2649,2872,1, +2834,2903,16,0,152, +1,2464,2042,1,2755, +2866,1,2841,2296,1, +2459,1969,1,2823,2904, +16,0,152,1,2822, +2272,1,2783,2332,1, +2466,2309,1,0,2905, +16,0,152,1,46, +2906,19,216,1,46, +2907,5,38,1,2045, +1997,1,2043,2001,1, +1775,2908,16,0,214, +1,2041,2005,1,2039, +2009,1,1860,1983,1, +2037,2014,1,2035,1900, +1,2033,2020,1,2032, +2024,1,2031,1915,1, +2030,1978,1,2029,1921, +1,2106,2909,16,0, +214,1,2464,2042,1, +1931,1909,1,1574,1895, +1,2462,1963,1,2105, +1940,1,2459,1969,1, +2458,1974,1,2364,2074, +1,1958,2910,16,0, +214,1,2198,2911,16, +0,214,1,2021,2036, +1,1901,2912,16,0, +214,1,1989,2060,1, +1803,2052,1,2075,2913, +16,0,214,1,1990, +2914,16,0,214,1, +1804,2915,16,0,214, +1,2337,2916,16,0, +214,1,1657,1990,1, +2413,2917,16,0,214, +1,32,2918,16,0, +214,1,1873,2069,1, +2227,2029,1,2136,1926, +1,45,2919,19,120, +1,45,2920,5,39, +1,2045,1997,1,2043, +2001,1,1775,2921,16, +0,763,1,2041,2005, +1,2039,2009,1,1860, +1983,1,2037,2014,1, +2035,1900,1,2033,2020, +1,2032,2024,1,2031, +1915,1,2030,1978,1, +2029,1921,1,2106,2922, +16,0,763,1,2464, +2042,1,1931,1909,1, +1574,1895,1,2462,1963, +1,2105,1940,1,2459, +1969,1,2458,1974,1, +1832,2923,16,0,118, +1,2364,2074,1,1958, +2924,16,0,763,1, +2198,2925,16,0,763, +1,2021,2036,1,1901, +2926,16,0,763,1, +1989,2060,1,1803,2052, +1,2075,2927,16,0, +763,1,1990,2928,16, +0,763,1,1804,2929, +16,0,763,1,2337, +2930,16,0,763,1, +1657,1990,1,2413,2931, +16,0,763,1,32, +2932,16,0,763,1, +1873,2069,1,2227,2029, +1,2136,1926,1,44, +2933,19,126,1,44, +2934,5,38,1,2045, +1997,1,2043,2001,1, +1775,2935,16,0,124, +1,2041,2005,1,2039, +2009,1,1860,1983,1, +2037,2014,1,2035,1900, +1,2033,2020,1,2032, +2024,1,2031,1915,1, +2030,1978,1,2029,1921, +1,2106,2936,16,0, +124,1,2464,2042,1, +1931,1909,1,1574,1895, +1,2462,1963,1,2105, +1940,1,2459,1969,1, +2458,1974,1,2364,2074, +1,1958,2937,16,0, +124,1,2198,2938,16, +0,124,1,2021,2036, +1,1901,2939,16,0, +124,1,1989,2060,1, +1803,2052,1,2075,2940, +16,0,124,1,1990, +2941,16,0,124,1, +1804,2942,16,0,124, +1,2337,2943,16,0, +124,1,1657,1990,1, +2413,2944,16,0,124, +1,32,2945,16,0, +124,1,1873,2069,1, +2227,2029,1,2136,1926, +1,43,2946,19,594, +1,43,2947,5,25, +1,1860,1983,1,2033, +2020,1,2032,2024,1, +2364,2074,1,2030,1978, +1,2029,1921,1,1657, +1990,1,1989,2948,16, +0,673,1,1803,2052, +1,2021,2036,1,2464, +2042,1,1574,1895,1, +2459,1969,1,1873,2069, +1,2136,1926,1,2031, +1915,1,2105,2949,16, +0,592,1,2045,1997, +1,2043,2001,1,1931, +1909,1,2041,2005,1, +2227,2029,1,2039,2009, +1,2037,2014,1,2035, +1900,1,42,2950,19, +438,1,42,2951,5, +38,1,2045,1997,1, +2043,2001,1,1775,2952, +16,0,436,1,2041, +2005,1,2039,2009,1, +1860,1983,1,2037,2014, +1,2035,1900,1,2033, +2020,1,2032,2024,1, +2031,1915,1,2030,1978, +1,2029,1921,1,2106, +2953,16,0,436,1, +2464,2042,1,1931,1909, +1,1574,1895,1,2462, +1963,1,2105,1940,1, +2459,1969,1,2458,1974, +1,2364,2074,1,1958, +2954,16,0,436,1, +2198,2955,16,0,436, +1,2021,2036,1,1901, +2956,16,0,436,1, +1989,2060,1,1803,2052, +1,2075,2957,16,0, +436,1,1990,2958,16, +0,436,1,1804,2959, +16,0,436,1,2337, +2960,16,0,436,1, +1657,1990,1,2413,2961, +16,0,436,1,32, +2962,16,0,436,1, +1873,2069,1,2227,2029, +1,2136,1926,1,41, +2963,19,757,1,41, +2964,5,84,1,1377, +2965,16,0,755,1, +387,2966,16,0,755, +1,188,2967,16,0, +755,1,380,2968,17, +2969,15,2970,4,38, +37,0,67,0,111, +0,110,0,115,0, +116,0,97,0,110, +0,116,0,69,0, +120,0,112,0,114, +0,101,0,115,0, +115,0,105,0,111, +0,110,0,1,-1, +1,5,2971,20,1198, +1,289,1,3,1, +2,1,1,2972,22, +1,124,1,379,2973, +17,2974,15,2975,4, +58,37,0,73,0, +110,0,99,0,114, +0,101,0,109,0, +101,0,110,0,116, +0,68,0,101,0, +99,0,114,0,101, +0,109,0,101,0, +110,0,116,0,69, +0,120,0,112,0, +114,0,101,0,115, +0,115,0,105,0, +111,0,110,0,1, +-1,1,5,2976,20, +1180,1,298,1,3, +1,5,1,4,2977, +22,1,133,1,377, +2978,17,2979,15,2975, +1,-1,1,5,2980, +20,1184,1,296,1, +3,1,3,1,2, +2981,22,1,131,1, +2792,2982,16,0,755, +1,375,2983,17,2984, +15,2975,1,-1,1, +5,2985,20,1178,1, +299,1,3,1,5, +1,4,2986,22,1, +134,1,373,2987,17, +2988,15,2975,1,-1, +1,5,2989,20,1182, +1,297,1,3,1, +3,1,2,2990,22, +1,132,1,371,2991, +17,2992,15,2993,4, +46,37,0,70,0, +117,0,110,0,99, +0,116,0,105,0, +111,0,110,0,67, +0,97,0,108,0, +108,0,69,0,120, +0,112,0,114,0, +101,0,115,0,115, +0,105,0,111,0, +110,0,1,-1,1, +5,2994,20,1176,1, +300,1,3,1,2, +1,1,2995,22,1, +135,1,172,2996,16, +0,755,1,67,2997, +17,2998,15,2999,4, +38,37,0,84,0, +121,0,112,0,101, +0,99,0,97,0, +115,0,116,0,69, +0,120,0,112,0, +114,0,101,0,115, +0,115,0,105,0, +111,0,110,0,1, +-1,1,5,3000,20, +1116,1,330,1,3, +1,8,1,7,3001, +22,1,165,1,1939, +3002,16,0,755,1, +1737,3003,16,0,755, +1,1341,3004,16,0, +755,1,157,3005,16, +0,755,1,480,3006, +17,3007,15,3008,4, +26,37,0,76,0, +105,0,115,0,116, +0,67,0,111,0, +110,0,115,0,116, +0,97,0,110,0, +116,0,1,-1,1, +5,3009,20,1273,1, +286,1,3,1,4, +1,3,3010,22,1, +121,1,942,3011,17, +3012,15,3013,4,34, +37,0,66,0,105, +0,110,0,97,0, +114,0,121,0,69, +0,120,0,112,0, +114,0,101,0,115, +0,115,0,105,0, +111,0,110,0,1, +-1,1,5,3014,20, +1142,1,317,1,3, +1,4,1,3,3015, +22,1,152,1,49, +3016,17,3017,15,2975, +1,-1,1,5,3018, +20,1188,1,294,1, +3,1,5,1,4, +3019,22,1,129,1, +143,3020,16,0,755, +1,1521,3021,16,0, +755,1,1123,3022,16, +0,755,1,82,3023, +17,3024,15,3025,4, +32,37,0,85,0, +110,0,97,0,114, +0,121,0,69,0, +120,0,112,0,114, +0,101,0,115,0, +115,0,105,0,111, +0,110,0,1,-1, +1,5,3026,20,1134, +1,321,1,3,1, +3,1,2,3027,22, +1,156,1,2299,3028, +16,0,755,1,328, +3029,17,3030,15,3013, +1,-1,1,5,3031, +20,1172,1,302,1, +3,1,4,1,3, +3032,22,1,137,1, +130,3033,16,0,755, +1,1114,3034,17,3035, +15,3036,4,38,37, +0,73,0,100,0, +101,0,110,0,116, +0,68,0,111,0, +116,0,69,0,120, +0,112,0,114,0, +101,0,115,0,115, +0,105,0,111,0, +110,0,1,-1,1, +5,3037,20,1194,1, +291,1,3,1,4, +1,3,3038,22,1, +126,1,1701,3039,16, +0,755,1,1303,3040, +16,0,755,1,118, +3041,16,0,755,1, +1096,3042,17,3043,15, +3044,4,26,37,0, +70,0,117,0,110, +0,99,0,116,0, +105,0,111,0,110, +0,67,0,97,0, +108,0,108,0,1, +-1,1,5,3045,20, +973,1,333,1,3, +1,5,1,4,3046, +22,1,168,1,1882, +3047,16,0,755,1, +305,3048,17,3049,15, +3013,1,-1,1,5, +3050,20,1170,1,303, +1,3,1,4,1, +3,3051,22,1,138, +1,107,3052,17,3053, +15,3025,1,-1,1, +5,3054,20,1138,1, +319,1,3,1,3, +1,2,3055,22,1, +154,1,1485,3056,16, +0,755,1,70,3057, +17,3058,15,2999,1, +-1,1,5,3059,20, +1122,1,327,1,3, +1,6,1,5,3060, +22,1,162,1,1555, +3061,16,0,755,1, +883,3062,16,0,755, +1,93,3063,17,3064, +15,3025,1,-1,1, +5,3065,20,1136,1, +320,1,3,1,3, +1,2,3066,22,1, +155,1,1665,3067,16, +0,755,1,283,3068, +17,3069,15,3013,1, +-1,1,5,3070,20, +1168,1,304,1,3, +1,4,1,3,3071, +22,1,139,1,479, +3072,17,3073,15,3074, +4,18,37,0,67, +0,111,0,110,0, +115,0,116,0,97, +0,110,0,116,0, +1,-1,1,5,3075, +20,1281,1,282,1, +3,1,2,1,1, +3076,22,1,117,1, +478,3077,17,3078,15, +3074,1,-1,1,5, +3079,20,1279,1,283, +1,3,1,2,1, +1,3080,22,1,118, +1,477,3081,17,3082, +15,3074,1,-1,1, +5,3083,20,1277,1, +284,1,3,1,2, +1,1,3084,22,1, +119,1,476,3085,17, +3086,15,3074,1,-1, +1,5,3087,20,1275, +1,285,1,3,1, +2,1,1,3088,22, +1,120,1,74,3089, +17,3090,15,2999,1, +-1,1,5,3091,20, +1044,1,332,1,3, +1,7,1,6,3092, +22,1,167,1,73, +3093,16,0,755,1, +1449,3094,16,0,755, +1,69,3095,17,3096, +15,2999,1,-1,1, +5,3097,20,1118,1, +329,1,3,1,6, +1,5,3098,22,1, +164,1,68,3099,17, +3100,15,2999,1,-1, +1,5,3101,20,1120, +1,328,1,3,1, +8,1,7,3102,22, +1,163,1,1840,3103, +16,0,755,1,66, +3104,17,3105,15,2999, +1,-1,1,5,3106, +20,1124,1,326,1, +3,1,7,1,6, +3107,22,1,161,1, +262,3108,17,3109,15, +3013,1,-1,1,5, +3110,20,1166,1,305, +1,3,1,4,1, +3,3111,22,1,140, +1,1267,3112,16,0, +755,1,1048,3113,17, +3114,15,3013,1,-1, +1,5,3115,20,1140, +1,318,1,3,1, +4,1,3,3116,22, +1,153,1,447,3117, +17,3118,15,3119,4, +30,37,0,86,0, +101,0,99,0,116, +0,111,0,114,0, +67,0,111,0,110, +0,115,0,116,0, +97,0,110,0,116, +0,1,-1,1,5, +3120,20,1271,1,287, +1,3,1,8,1, +7,3121,22,1,122, +1,1628,3122,16,0, +755,1,51,3123,17, +3124,15,2975,1,-1, +1,5,3125,20,1192, +1,292,1,3,1, +3,1,2,3126,22, +1,127,1,63,3127, +17,3128,15,2999,1, +-1,1,5,3129,20, +1126,1,325,1,3, +1,5,1,4,3130, +22,1,160,1,1231, +3131,16,0,755,1, +48,3132,17,3133,15, +2975,1,-1,1,5, +3134,20,1186,1,295, +1,3,1,5,1, +4,3135,22,1,130, +1,47,3136,17,3035, +1,3,3038,1,242, +3137,16,0,755,1, +44,3138,17,3139,15, +3140,4,32,37,0, +73,0,100,0,101, +0,110,0,116,0, +69,0,120,0,112, +0,114,0,101,0, +115,0,115,0,105, +0,111,0,110,0, +1,-1,1,5,3141, +20,1196,1,290,1, +3,1,2,1,1, +3142,22,1,125,1, +437,3143,16,0,755, +1,42,3144,16,0, +755,1,525,3145,17, +3146,15,3147,4,34, +37,0,82,0,111, +0,116,0,97,0, +116,0,105,0,111, +0,110,0,67,0, +111,0,110,0,115, +0,116,0,97,0, +110,0,116,0,1, +-1,1,5,3148,20, +1200,1,288,1,3, +1,10,1,9,3149, +22,1,123,1,827, +3150,16,0,755,1, +352,3151,17,3152,15, +3013,1,-1,1,5, +3153,20,1174,1,301, +1,3,1,4,1, +3,3154,22,1,136, +1,1413,3155,16,0, +755,1,1013,3156,17, +3157,15,3158,4,44, +37,0,80,0,97, +0,114,0,101,0, +110,0,116,0,104, +0,101,0,115,0, +105,0,115,0,69, +0,120,0,112,0, +114,0,101,0,115, +0,115,0,105,0, +111,0,110,0,1, +-1,1,5,3159,20, +1132,1,322,1,3, +1,4,1,3,3160, +22,1,157,1,1012, +3161,16,0,755,1, +223,3162,16,0,755, +1,1159,3163,16,0, +755,1,1011,3164,17, +3165,15,3158,1,-1, +1,5,3166,20,1130, +1,323,1,3,1, +4,1,3,3167,22, +1,158,1,412,3168, +16,0,755,1,1002, +3169,17,3170,15,2999, +1,-1,1,5,3171, +20,1128,1,324,1, +3,1,5,1,4, +3172,22,1,159,1, +1001,3173,17,3174,15, +2999,1,-1,1,5, +3175,20,1114,1,331, +1,3,1,5,1, +4,3176,22,1,166, +1,1591,3177,16,0, +755,1,1195,3178,16, +0,755,1,40,3179, +17,3139,1,1,3142, +1,205,3180,16,0, +755,1,50,3181,17, +3182,15,2975,1,-1, +1,5,3183,20,1190, +1,293,1,3,1, +3,1,2,3184,22, +1,128,1,515,3185, +16,0,755,1,40, +3186,19,727,1,40, +3187,5,84,1,1377, +3188,16,0,725,1, +387,3189,16,0,725, +1,188,3190,16,0, +725,1,380,2968,1, +379,2973,1,377,2978, +1,2792,3191,16,0, +725,1,375,2983,1, +373,2987,1,371,2991, +1,172,3192,16,0, +725,1,67,2997,1, +1939,3193,16,0,725, +1,1737,3194,16,0, +725,1,1341,3195,16, +0,725,1,157,3196, +16,0,725,1,480, +3006,1,942,3011,1, +49,3016,1,143,3197, +16,0,725,1,1521, +3198,16,0,725,1, +1123,3199,16,0,725, +1,82,3023,1,2299, +3200,16,0,725,1, +328,3029,1,130,3201, +16,0,725,1,1114, +3034,1,1701,3202,16, +0,725,1,1303,3203, +16,0,725,1,118, +3204,16,0,725,1, +1096,3042,1,1882,3205, +16,0,725,1,305, +3048,1,107,3052,1, +1485,3206,16,0,725, +1,70,3057,1,1555, +3207,16,0,725,1, +883,3208,16,0,725, +1,93,3063,1,1665, +3209,16,0,725,1, +283,3068,1,479,3072, +1,478,3077,1,477, +3081,1,476,3085,1, +74,3089,1,73,3210, +16,0,725,1,1449, +3211,16,0,725,1, +69,3095,1,68,3099, +1,1840,3212,16,0, +725,1,66,3104,1, +262,3108,1,1267,3213, +16,0,725,1,1048, +3113,1,447,3117,1, +1628,3214,16,0,725, +1,51,3123,1,63, +3127,1,1231,3215,16, +0,725,1,48,3132, +1,47,3136,1,242, +3216,16,0,725,1, +44,3138,1,437,3217, +16,0,725,1,42, +3218,16,0,725,1, +525,3145,1,827,3219, +16,0,725,1,352, +3151,1,1413,3220,16, +0,725,1,1013,3156, +1,1012,3221,16,0, +725,1,223,3222,16, +0,725,1,1159,3223, +16,0,725,1,1011, +3164,1,412,3224,16, +0,725,1,1002,3169, +1,1001,3173,1,1591, +3225,16,0,725,1, +1195,3226,16,0,725, +1,40,3179,1,205, +3227,16,0,725,1, +50,3181,1,515,3228, +16,0,725,1,39, +3229,19,716,1,39, +3230,5,84,1,1377, +3231,16,0,714,1, +387,3232,16,0,714, +1,188,3233,17,3234, +15,3013,1,-1,1, +5,3235,20,1158,1, +309,1,3,1,4, +1,3,3236,22,1, +144,1,380,2968,1, +379,2973,1,377,2978, +1,2792,3237,16,0, +714,1,375,2983,1, +373,2987,1,371,2991, +1,172,3238,17,3239, +15,3013,1,-1,1, +5,3240,20,1156,1, +310,1,3,1,4, +1,3,3241,22,1, +145,1,67,2997,1, +1939,3242,16,0,714, +1,1737,3243,16,0, +714,1,1341,3244,16, +0,714,1,157,3245, +17,3246,15,3013,1, +-1,1,5,3247,20, +1154,1,311,1,3, +1,4,1,3,3248, +22,1,146,1,480, +3006,1,942,3011,1, +49,3016,1,143,3249, +17,3250,15,3013,1, +-1,1,5,3251,20, +1152,1,312,1,3, +1,4,1,3,3252, +22,1,147,1,1521, +3253,16,0,714,1, +1123,3254,16,0,714, +1,82,3023,1,2299, +3255,16,0,714,1, +328,3029,1,130,3256, +17,3257,15,3013,1, +-1,1,5,3258,20, +1150,1,313,1,3, +1,4,1,3,3259, +22,1,148,1,1114, +3034,1,1701,3260,16, +0,714,1,1303,3261, +16,0,714,1,118, +3262,17,3263,15,3013, +1,-1,1,5,3264, +20,1148,1,314,1, +3,1,4,1,3, +3265,22,1,149,1, +1096,3042,1,1882,3266, +16,0,714,1,305, +3048,1,107,3052,1, +1485,3267,16,0,714, +1,70,3057,1,1555, +3268,16,0,714,1, +883,3269,17,3270,15, +3013,1,-1,1,5, +3271,20,1144,1,316, +1,3,1,4,1, +3,3272,22,1,151, +1,93,3063,1,1665, +3273,16,0,714,1, +283,3068,1,479,3072, +1,478,3077,1,477, +3081,1,476,3085,1, +74,3089,1,73,3274, +16,0,714,1,1449, +3275,16,0,714,1, +69,3095,1,68,3099, +1,1840,3276,16,0, +714,1,66,3104,1, +262,3108,1,1267,3277, +16,0,714,1,1048, +3113,1,447,3117,1, +1628,3278,16,0,714, +1,51,3123,1,63, +3127,1,1231,3279,16, +0,714,1,48,3132, +1,47,3136,1,242, +3280,17,3281,15,3013, +1,-1,1,5,3282, +20,1164,1,306,1, +3,1,4,1,3, +3283,22,1,141,1, +44,3138,1,437,3284, +16,0,714,1,42, +3285,16,0,714,1, +525,3145,1,827,3286, +17,3287,15,3013,1, +-1,1,5,3288,20, +1146,1,315,1,3, +1,4,1,3,3289, +22,1,150,1,352, +3151,1,1413,3290,16, +0,714,1,1013,3156, +1,1012,3291,16,0, +714,1,223,3292,17, +3293,15,3013,1,-1, +1,5,3294,20,1162, +1,307,1,3,1, +4,1,3,3295,22, +1,142,1,1159,3296, +16,0,714,1,1011, +3164,1,412,3297,16, +0,714,1,1002,3169, +1,1001,3173,1,1591, +3298,16,0,714,1, +1195,3299,16,0,714, +1,40,3179,1,205, +3300,17,3301,15,3013, +1,-1,1,5,3302, +20,1160,1,308,1, +3,1,4,1,3, +3303,22,1,143,1, +50,3181,1,515,3304, +16,0,714,1,38, +3305,19,703,1,38, +3306,5,84,1,1377, +3307,16,0,701,1, +387,3308,16,0,701, +1,188,3233,1,380, +2968,1,379,2973,1, +377,2978,1,2792,3309, +16,0,701,1,375, +2983,1,373,2987,1, +371,2991,1,172,3238, +1,67,2997,1,1939, +3310,16,0,701,1, +1737,3311,16,0,701, +1,1341,3312,16,0, +701,1,157,3245,1, +480,3006,1,942,3011, +1,49,3016,1,143, +3249,1,1521,3313,16, +0,701,1,1123,3314, +16,0,701,1,82, +3023,1,2299,3315,16, +0,701,1,328,3029, +1,130,3256,1,1114, +3034,1,1701,3316,16, +0,701,1,1303,3317, +16,0,701,1,118, +3262,1,1096,3042,1, +1882,3318,16,0,701, +1,305,3048,1,107, +3052,1,1485,3319,16, +0,701,1,70,3057, +1,1555,3320,16,0, +701,1,883,3269,1, +93,3063,1,1665,3321, +16,0,701,1,283, +3068,1,479,3072,1, +478,3077,1,477,3081, +1,476,3085,1,74, +3089,1,73,3322,16, +0,701,1,1449,3323, +16,0,701,1,69, +3095,1,68,3099,1, +1840,3324,16,0,701, +1,66,3104,1,262, +3108,1,1267,3325,16, +0,701,1,1048,3113, +1,447,3117,1,1628, +3326,16,0,701,1, +51,3123,1,63,3127, +1,1231,3327,16,0, +701,1,48,3132,1, +47,3136,1,242,3280, +1,44,3138,1,437, +3328,16,0,701,1, +42,3329,16,0,701, +1,525,3145,1,827, +3286,1,352,3151,1, +1413,3330,16,0,701, +1,1013,3156,1,1012, +3331,16,0,701,1, +223,3292,1,1159,3332, +16,0,701,1,1011, +3164,1,412,3333,16, +0,701,1,1002,3169, +1,1001,3173,1,1591, +3334,16,0,701,1, +1195,3335,16,0,701, +1,40,3179,1,205, +3300,1,50,3181,1, +515,3336,16,0,701, +1,37,3337,19,696, +1,37,3338,5,94, +1,1574,1895,1,2035, +1900,1,1371,3339,16, +0,694,1,71,3340, +16,0,694,1,1958, +3341,16,0,694,1, +381,3342,16,0,694, +1,2106,3343,16,0, +694,1,1931,1909,1, +1756,3344,16,0,694, +1,2031,1915,1,509, +3345,16,0,694,1, +2337,3346,16,0,694, +1,2029,1921,1,1153, +3347,16,0,694,1, +2136,1926,1,1933,3348, +16,0,694,1,2198, +3349,16,0,694,1, +1731,3350,16,0,694, +1,1335,3351,16,0, +694,1,2318,3352,16, +0,694,1,346,3353, +16,0,694,1,182, +3354,16,0,694,1, +137,3355,16,0,694, +1,1515,3356,16,0, +694,1,2105,1940,1, +1775,3357,16,0,694, +1,1117,3358,16,0, +694,1,525,3359,16, +0,694,1,1901,3360, +16,0,694,1,2293, +3361,16,0,694,1, +322,3362,16,0,694, +1,124,3363,16,0, +694,1,1695,3364,16, +0,694,1,1297,3365, +16,0,694,1,151, +3366,16,0,694,1, +112,3367,16,0,694, +1,1990,3368,16,0, +694,1,76,3369,16, +0,694,1,43,3370, +16,0,694,1,2075, +3371,16,0,694,1, +1876,3372,16,0,694, +1,299,3373,16,0, +694,1,1479,3374,16, +0,694,1,2462,1963, +1,97,3375,16,0, +694,1,2459,1969,1, +2458,1974,1,2030,1978, +1,89,3376,16,0, +694,1,1860,1983,1, +85,3377,16,0,694, +1,1659,3378,16,0, +694,1,1657,1990,1, +277,3379,16,0,694, +1,1261,3380,16,0, +694,1,166,3381,16, +0,694,1,2045,1997, +1,2043,2001,1,2041, +2005,1,2039,2009,1, +462,3382,16,0,694, +1,2037,2014,1,459, +3383,16,0,694,1, +1443,3384,16,0,694, +1,2033,2020,1,2032, +2024,1,1834,3385,16, +0,694,1,2227,2029, +1,256,3386,16,0, +694,1,447,3387,16, +0,694,1,52,3388, +16,0,694,1,2021, +2036,1,2413,3389,16, +0,694,1,1622,3390, +16,0,694,1,2464, +2042,1,1225,3391,16, +0,694,1,41,3392, +16,0,694,1,236, +3393,16,0,694,1, +431,3394,16,0,694, +1,32,3395,16,0, +694,1,1804,3396,16, +0,694,1,1803,2052, +1,1407,3397,16,0, +694,1,79,3398,16, +0,694,1,217,3399, +16,0,694,1,1989, +2060,1,102,3400,16, +0,694,1,2786,3401, +16,0,694,1,406, +3402,16,0,694,1, +1585,3403,16,0,694, +1,1189,3404,16,0, +694,1,1873,2069,1, +199,3405,16,0,694, +1,2364,2074,1,36, +3406,19,722,1,36, +3407,5,94,1,1574, +1895,1,2035,1900,1, +1371,3408,16,0,720, +1,71,3409,16,0, +720,1,1958,3410,16, +0,720,1,381,3411, +16,0,720,1,2106, +3412,16,0,720,1, +1931,1909,1,1756,3413, +16,0,720,1,2031, +1915,1,509,3414,16, +0,720,1,2337,3415, +16,0,720,1,2029, +1921,1,1153,3416,16, +0,720,1,2136,1926, +1,1933,3417,16,0, +720,1,2198,3418,16, +0,720,1,1731,3419, +16,0,720,1,1335, +3420,16,0,720,1, +2318,3421,16,0,720, +1,346,3422,16,0, +720,1,182,3423,16, +0,720,1,137,3424, +16,0,720,1,1515, +3425,16,0,720,1, +2105,1940,1,1775,3426, +16,0,720,1,1117, +3427,16,0,720,1, +525,3428,16,0,720, +1,1901,3429,16,0, +720,1,2293,3430,16, +0,720,1,322,3431, +16,0,720,1,124, +3432,16,0,720,1, +1695,3433,16,0,720, +1,1297,3434,16,0, +720,1,151,3435,16, +0,720,1,112,3436, +16,0,720,1,1990, +3437,16,0,720,1, +76,3438,16,0,720, +1,43,3439,16,0, +720,1,2075,3440,16, +0,720,1,1876,3441, +16,0,720,1,299, +3442,16,0,720,1, +1479,3443,16,0,720, +1,2462,1963,1,97, +3444,16,0,720,1, +2459,1969,1,2458,1974, +1,2030,1978,1,89, +3445,16,0,720,1, +1860,1983,1,85,3446, +16,0,720,1,1659, +3447,16,0,720,1, +1657,1990,1,277,3448, +16,0,720,1,1261, +3449,16,0,720,1, +166,3450,16,0,720, +1,2045,1997,1,2043, +2001,1,2041,2005,1, +2039,2009,1,462,3451, +16,0,720,1,2037, +2014,1,459,3452,16, +0,720,1,1443,3453, +16,0,720,1,2033, +2020,1,2032,2024,1, +1834,3454,16,0,720, +1,2227,2029,1,256, +3455,16,0,720,1, +447,3456,16,0,720, +1,52,3457,16,0, +720,1,2021,2036,1, +2413,3458,16,0,720, +1,1622,3459,16,0, +720,1,2464,2042,1, +1225,3460,16,0,720, +1,41,3461,16,0, +720,1,236,3462,16, +0,720,1,431,3463, +16,0,720,1,32, +3464,16,0,720,1, +1804,3465,16,0,720, +1,1803,2052,1,1407, +3466,16,0,720,1, +79,3467,16,0,720, +1,217,3468,16,0, +720,1,1989,2060,1, +102,3469,16,0,720, +1,2786,3470,16,0, +720,1,406,3471,16, +0,720,1,1585,3472, +16,0,720,1,1189, +3473,16,0,720,1, +1873,2069,1,199,3474, +16,0,720,1,2364, +2074,1,35,3475,19, +638,1,35,3476,5, +84,1,1377,3477,16, +0,636,1,387,3478, +16,0,636,1,188, +3233,1,380,2968,1, +379,2973,1,377,2978, +1,2792,3479,16,0, +636,1,375,2983,1, +373,2987,1,371,2991, +1,172,3238,1,67, +2997,1,1939,3480,16, +0,636,1,1737,3481, +16,0,636,1,1341, +3482,16,0,636,1, +157,3245,1,480,3006, +1,942,3011,1,49, +3016,1,143,3249,1, +1521,3483,16,0,636, +1,1123,3484,16,0, +636,1,82,3023,1, +2299,3485,16,0,636, +1,328,3029,1,130, +3256,1,1114,3034,1, +1701,3486,16,0,636, +1,1303,3487,16,0, +636,1,118,3262,1, +1096,3042,1,1882,3488, +16,0,636,1,305, +3048,1,107,3052,1, +1485,3489,16,0,636, +1,70,3057,1,1555, +3490,16,0,636,1, +883,3491,16,0,636, +1,93,3063,1,1665, +3492,16,0,636,1, +283,3068,1,479,3072, +1,478,3077,1,477, +3081,1,476,3085,1, +74,3089,1,73,3493, +16,0,636,1,1449, +3494,16,0,636,1, +69,3095,1,68,3099, +1,1840,3495,16,0, +636,1,66,3104,1, +262,3108,1,1267,3496, +16,0,636,1,1048, +3113,1,447,3117,1, +1628,3497,16,0,636, +1,51,3123,1,63, +3127,1,1231,3498,16, +0,636,1,48,3132, +1,47,3136,1,242, +3280,1,44,3138,1, +437,3499,16,0,636, +1,42,3500,16,0, +636,1,525,3145,1, +827,3501,16,0,636, +1,352,3151,1,1413, +3502,16,0,636,1, +1013,3156,1,1012,3503, +16,0,636,1,223, +3504,16,0,636,1, +1159,3505,16,0,636, +1,1011,3164,1,412, +3506,16,0,636,1, +1002,3169,1,1001,3173, +1,1591,3507,16,0, +636,1,1195,3508,16, +0,636,1,40,3179, +1,205,3300,1,50, +3181,1,515,3509,16, +0,636,1,34,3510, +19,618,1,34,3511, +5,84,1,1377,3512, +16,0,616,1,387, +3513,16,0,616,1, +188,3233,1,380,2968, +1,379,2973,1,377, +2978,1,2792,3514,16, +0,616,1,375,2983, +1,373,2987,1,371, +2991,1,172,3238,1, +67,2997,1,1939,3515, +16,0,616,1,1737, +3516,16,0,616,1, +1341,3517,16,0,616, +1,157,3245,1,480, +3006,1,942,3011,1, +49,3016,1,143,3249, +1,1521,3518,16,0, +616,1,1123,3519,16, +0,616,1,82,3023, +1,2299,3520,16,0, +616,1,328,3029,1, +130,3256,1,1114,3034, +1,1701,3521,16,0, +616,1,1303,3522,16, +0,616,1,118,3262, +1,1096,3042,1,1882, +3523,16,0,616,1, +305,3048,1,107,3052, +1,1485,3524,16,0, +616,1,70,3057,1, +1555,3525,16,0,616, +1,883,3526,16,0, +616,1,93,3063,1, +1665,3527,16,0,616, +1,283,3068,1,479, +3072,1,478,3077,1, +477,3081,1,476,3085, +1,74,3089,1,73, +3528,16,0,616,1, +1449,3529,16,0,616, +1,69,3095,1,68, +3099,1,1840,3530,16, +0,616,1,66,3104, +1,262,3108,1,1267, +3531,16,0,616,1, +1048,3113,1,447,3117, +1,1628,3532,16,0, +616,1,51,3123,1, +63,3127,1,1231,3533, +16,0,616,1,48, +3132,1,47,3136,1, +242,3280,1,44,3138, +1,437,3534,16,0, +616,1,42,3535,16, +0,616,1,525,3145, +1,827,3536,16,0, +616,1,352,3151,1, +1413,3537,16,0,616, +1,1013,3156,1,1012, +3538,16,0,616,1, +223,3292,1,1159,3539, +16,0,616,1,1011, +3164,1,412,3540,16, +0,616,1,1002,3169, +1,1001,3173,1,1591, +3541,16,0,616,1, +1195,3542,16,0,616, +1,40,3179,1,205, +3300,1,50,3181,1, +515,3543,16,0,616, +1,33,3544,19,609, +1,33,3545,5,84, +1,1377,3546,16,0, +607,1,387,3547,16, +0,607,1,188,3233, +1,380,2968,1,379, +2973,1,377,2978,1, +2792,3548,16,0,607, +1,375,2983,1,373, +2987,1,371,2991,1, +172,3238,1,67,2997, +1,1939,3549,16,0, +607,1,1737,3550,16, +0,607,1,1341,3551, +16,0,607,1,157, +3245,1,480,3006,1, +942,3011,1,49,3016, +1,143,3249,1,1521, +3552,16,0,607,1, +1123,3553,16,0,607, +1,82,3023,1,2299, +3554,16,0,607,1, +328,3029,1,130,3256, +1,1114,3034,1,1701, +3555,16,0,607,1, +1303,3556,16,0,607, +1,118,3262,1,1096, +3042,1,1882,3557,16, +0,607,1,305,3048, +1,107,3052,1,1485, +3558,16,0,607,1, +70,3057,1,1555,3559, +16,0,607,1,883, +3560,16,0,607,1, +93,3063,1,1665,3561, +16,0,607,1,283, +3068,1,479,3072,1, +478,3077,1,477,3081, +1,476,3085,1,74, +3089,1,73,3562,16, +0,607,1,1449,3563, +16,0,607,1,69, +3095,1,68,3099,1, +1840,3564,16,0,607, +1,66,3104,1,262, +3108,1,1267,3565,16, +0,607,1,1048,3113, +1,447,3117,1,1628, +3566,16,0,607,1, +51,3123,1,63,3127, +1,1231,3567,16,0, +607,1,48,3132,1, +47,3136,1,242,3280, +1,44,3138,1,437, +3568,16,0,607,1, +42,3569,16,0,607, +1,525,3145,1,827, +3570,16,0,607,1, +352,3151,1,1413,3571, +16,0,607,1,1013, +3156,1,1012,3572,16, +0,607,1,223,3573, +16,0,607,1,1159, +3574,16,0,607,1, +1011,3164,1,412,3575, +16,0,607,1,1002, +3169,1,1001,3173,1, +1591,3576,16,0,607, +1,1195,3577,16,0, +607,1,40,3179,1, +205,3578,16,0,607, +1,50,3181,1,515, +3579,16,0,607,1, +32,3580,19,692,1, +32,3581,5,84,1, +1377,3582,16,0,690, +1,387,3583,16,0, +690,1,188,3233,1, +380,2968,1,379,2973, +1,377,2978,1,2792, +3584,16,0,690,1, +375,2983,1,373,2987, +1,371,2991,1,172, +3238,1,67,2997,1, +1939,3585,16,0,690, +1,1737,3586,16,0, +690,1,1341,3587,16, +0,690,1,157,3588, +16,0,690,1,480, +3006,1,942,3011,1, +49,3016,1,143,3589, +16,0,690,1,1521, +3590,16,0,690,1, +1123,3591,16,0,690, +1,82,3023,1,2299, +3592,16,0,690,1, +328,3029,1,130,3256, +1,1114,3034,1,1701, +3593,16,0,690,1, +1303,3594,16,0,690, +1,118,3262,1,1096, +3042,1,1882,3595,16, +0,690,1,305,3048, +1,107,3052,1,1485, +3596,16,0,690,1, +70,3057,1,1555,3597, +16,0,690,1,883, +3598,16,0,690,1, +93,3063,1,1665,3599, +16,0,690,1,283, +3068,1,479,3072,1, +478,3077,1,477,3081, +1,476,3085,1,74, +3089,1,73,3600,16, +0,690,1,1449,3601, +16,0,690,1,69, +3095,1,68,3099,1, +1840,3602,16,0,690, +1,66,3104,1,262, +3108,1,1267,3603,16, +0,690,1,1048,3113, +1,447,3117,1,1628, +3604,16,0,690,1, +51,3123,1,63,3127, +1,1231,3605,16,0, +690,1,48,3132,1, +47,3136,1,242,3606, +16,0,690,1,44, +3138,1,437,3607,16, +0,690,1,42,3608, +16,0,690,1,525, +3145,1,827,3609,16, +0,690,1,352,3151, +1,1413,3610,16,0, +690,1,1013,3156,1, +1012,3611,16,0,690, +1,223,3612,16,0, +690,1,1159,3613,16, +0,690,1,1011,3164, +1,412,3614,16,0, +690,1,1002,3169,1, +1001,3173,1,1591,3615, +16,0,690,1,1195, +3616,16,0,690,1, +40,3179,1,205,3617, +16,0,690,1,50, +3181,1,515,3618,16, +0,690,1,31,3619, +19,686,1,31,3620, +5,84,1,1377,3621, +16,0,684,1,387, +3622,16,0,684,1, +188,3233,1,380,2968, +1,379,2973,1,377, +2978,1,2792,3623,16, +0,684,1,375,2983, +1,373,2987,1,371, +2991,1,172,3238,1, +67,2997,1,1939,3624, +16,0,684,1,1737, +3625,16,0,684,1, +1341,3626,16,0,684, +1,157,3627,16,0, +684,1,480,3006,1, +942,3011,1,49,3016, +1,143,3628,16,0, +684,1,1521,3629,16, +0,684,1,1123,3630, +16,0,684,1,82, +3023,1,2299,3631,16, +0,684,1,328,3029, +1,130,3256,1,1114, +3034,1,1701,3632,16, +0,684,1,1303,3633, +16,0,684,1,118, +3262,1,1096,3042,1, +1882,3634,16,0,684, +1,305,3048,1,107, +3052,1,1485,3635,16, +0,684,1,70,3057, +1,1555,3636,16,0, +684,1,883,3637,16, +0,684,1,93,3063, +1,1665,3638,16,0, +684,1,283,3068,1, +479,3072,1,478,3077, +1,477,3081,1,476, +3085,1,74,3089,1, +73,3639,16,0,684, +1,1449,3640,16,0, +684,1,69,3095,1, +68,3099,1,1840,3641, +16,0,684,1,66, +3104,1,262,3108,1, +1267,3642,16,0,684, +1,1048,3113,1,447, +3117,1,1628,3643,16, +0,684,1,51,3123, +1,63,3127,1,1231, +3644,16,0,684,1, +48,3132,1,47,3136, +1,242,3645,16,0, +684,1,44,3138,1, +437,3646,16,0,684, +1,42,3647,16,0, +684,1,525,3145,1, +827,3648,16,0,684, +1,352,3151,1,1413, +3649,16,0,684,1, +1013,3156,1,1012,3650, +16,0,684,1,223, +3651,16,0,684,1, +1159,3652,16,0,684, +1,1011,3164,1,412, +3653,16,0,684,1, +1002,3169,1,1001,3173, +1,1591,3654,16,0, +684,1,1195,3655,16, +0,684,1,40,3179, +1,205,3656,16,0, +684,1,50,3181,1, +515,3657,16,0,684, +1,30,3658,19,681, +1,30,3659,5,84, +1,1377,3660,16,0, +679,1,387,3661,16, +0,679,1,188,3233, +1,380,2968,1,379, +2973,1,377,2978,1, +2792,3662,16,0,679, +1,375,2983,1,373, +2987,1,371,2991,1, +172,3238,1,67,2997, +1,1939,3663,16,0, +679,1,1737,3664,16, +0,679,1,1341,3665, +16,0,679,1,157, +3245,1,480,3006,1, +942,3011,1,49,3016, +1,143,3249,1,1521, +3666,16,0,679,1, +1123,3667,16,0,679, +1,82,3023,1,2299, +3668,16,0,679,1, +328,3029,1,130,3256, +1,1114,3034,1,1701, +3669,16,0,679,1, +1303,3670,16,0,679, +1,118,3262,1,1096, +3042,1,1882,3671,16, +0,679,1,305,3048, +1,107,3052,1,1485, +3672,16,0,679,1, +70,3057,1,1555,3673, +16,0,679,1,883, +3674,16,0,679,1, +93,3063,1,1665,3675, +16,0,679,1,283, +3068,1,479,3072,1, +478,3077,1,477,3081, +1,476,3085,1,74, +3089,1,73,3676,16, +0,679,1,1449,3677, +16,0,679,1,69, +3095,1,68,3099,1, +1840,3678,16,0,679, +1,66,3104,1,262, +3108,1,1267,3679,16, +0,679,1,1048,3113, +1,447,3117,1,1628, +3680,16,0,679,1, +51,3123,1,63,3127, +1,1231,3681,16,0, +679,1,48,3132,1, +47,3136,1,242,3682, +16,0,679,1,44, +3138,1,437,3683,16, +0,679,1,42,3684, +16,0,679,1,525, +3145,1,827,3685,16, +0,679,1,352,3151, +1,1413,3686,16,0, +679,1,1013,3156,1, +1012,3687,16,0,679, +1,223,3688,16,0, +679,1,1159,3689,16, +0,679,1,1011,3164, +1,412,3690,16,0, +679,1,1002,3169,1, +1001,3173,1,1591,3691, +16,0,679,1,1195, +3692,16,0,679,1, +40,3179,1,205,3693, +16,0,679,1,50, +3181,1,515,3694,16, +0,679,1,29,3695, +19,253,1,29,3696, +5,84,1,1377,3697, +16,0,251,1,387, +3698,16,0,251,1, +188,3233,1,380,2968, +1,379,2973,1,377, +2978,1,2792,3699,16, +0,251,1,375,2983, +1,373,2987,1,371, +2991,1,172,3238,1, +67,2997,1,1939,3700, +16,0,251,1,1737, +3701,16,0,251,1, +1341,3702,16,0,251, +1,157,3245,1,480, +3006,1,942,3011,1, +49,3016,1,143,3249, +1,1521,3703,16,0, +251,1,1123,3704,16, +0,251,1,82,3023, +1,2299,3705,16,0, +251,1,328,3029,1, +130,3256,1,1114,3034, +1,1701,3706,16,0, +251,1,1303,3707,16, +0,251,1,118,3262, +1,1096,3042,1,1882, +3708,16,0,251,1, +305,3048,1,107,3052, +1,1485,3709,16,0, +251,1,70,3057,1, +1555,3710,16,0,251, +1,883,3711,16,0, +251,1,93,3063,1, +1665,3712,16,0,251, +1,283,3068,1,479, +3072,1,478,3077,1, +477,3081,1,476,3085, +1,74,3089,1,73, +3713,16,0,251,1, +1449,3714,16,0,251, +1,69,3095,1,68, +3099,1,1840,3715,16, +0,251,1,66,3104, +1,262,3108,1,1267, +3716,16,0,251,1, +1048,3113,1,447,3117, +1,1628,3717,16,0, +251,1,51,3123,1, +63,3127,1,1231,3718, +16,0,251,1,48, +3132,1,47,3136,1, +242,3719,16,0,251, +1,44,3138,1,437, +3720,16,0,251,1, +42,3721,16,0,251, +1,525,3145,1,827, +3722,16,0,251,1, +352,3151,1,1413,3723, +16,0,251,1,1013, +3156,1,1012,3724,16, +0,251,1,223,3725, +16,0,251,1,1159, +3726,16,0,251,1, +1011,3164,1,412,3727, +16,0,251,1,1002, +3169,1,1001,3173,1, +1591,3728,16,0,251, +1,1195,3729,16,0, +251,1,40,3179,1, +205,3730,16,0,251, +1,50,3181,1,515, +3731,16,0,251,1, +28,3732,19,488,1, +28,3733,5,60,1, +283,3068,1,69,3095, +1,157,3245,1,352, +3151,1,262,3108,1, +172,3238,1,883,3269, +1,525,3145,1,74, +3089,1,68,3099,1, +70,3057,1,1048,3113, +1,464,3734,17,3735, +15,3736,4,26,37, +0,65,0,114,0, +103,0,117,0,109, +0,101,0,110,0, +116,0,76,0,105, +0,115,0,116,0, +1,-1,1,5,3737, +20,969,1,335,1, +3,1,4,1,3, +3738,22,1,171,1, +67,2997,1,66,3104, +1,242,3280,1,63, +3127,1,328,3029,1, +143,3249,1,41,3739, +17,3740,15,3736,1, +-1,1,5,132,1, +0,1,0,3741,22, +1,169,1,942,3011, +1,51,3123,1,50, +3181,1,49,3016,1, +48,3132,1,47,3136, +1,1114,3034,1,223, +3292,1,1002,3169,1, +42,3742,17,3743,15, +3744,4,38,37,0, +69,0,120,0,112, +0,114,0,101,0, +115,0,115,0,105, +0,111,0,110,0, +65,0,114,0,103, +0,117,0,109,0, +101,0,110,0,116, +0,1,-1,1,5, +3745,20,963,1,336, +1,3,1,2,1, +1,3746,22,1,172, +1,130,3256,1,40, +3179,1,305,3048,1, +82,3023,1,481,3747, +17,3748,15,3736,1, +-1,1,5,3749,20, +971,1,334,1,3, +1,2,1,1,3750, +22,1,170,1,480, +3006,1,479,3072,1, +478,3077,1,477,3081, +1,476,3085,1,118, +3262,1,1096,3042,1, +205,3300,1,827,3286, +1,380,2968,1,379, +2973,1,1001,3173,1, +377,2978,1,375,2983, +1,107,3052,1,373, +2987,1,461,3751,16, +0,486,1,371,2991, +1,459,3752,17,3753, +15,3736,1,-1,1, +5,132,1,0,1, +0,3741,1,188,3233, +1,1011,3164,1,93, +3063,1,1013,3156,1, +447,3117,1,44,3138, +1,27,3754,19,507, +1,27,3755,5,95, +1,1574,1895,1,2035, +1900,1,1371,3756,16, +0,505,1,71,3757, +16,0,505,1,1958, +3758,16,0,505,1, +381,3759,16,0,505, +1,2106,3760,16,0, +505,1,1931,1909,1, +1756,3761,16,0,505, +1,2031,1915,1,509, +3762,16,0,505,1, +2337,3763,16,0,505, +1,2029,1921,1,1153, +3764,16,0,505,1, +2136,1926,1,1933,3765, +16,0,505,1,2198, +3766,16,0,505,1, +1731,3767,16,0,505, +1,1335,3768,16,0, +505,1,2318,3769,16, +0,505,1,346,3770, +16,0,505,1,182, +3771,16,0,505,1, +137,3772,16,0,505, +1,1515,3773,16,0, +505,1,2105,1940,1, +1775,3774,16,0,505, +1,1117,3775,16,0, +505,1,525,3776,16, +0,505,1,52,3777, +16,0,505,1,1901, +3778,16,0,505,1, +2293,3779,16,0,505, +1,322,3780,16,0, +505,1,124,3781,16, +0,505,1,1695,3782, +16,0,505,1,1297, +3783,16,0,505,1, +151,3784,16,0,505, +1,112,3785,16,0, +505,1,1990,3786,16, +0,505,1,76,3787, +16,0,505,1,43, +3788,16,0,505,1, +2075,3789,16,0,505, +1,1876,3790,16,0, +505,1,299,3791,16, +0,505,1,1479,3792, +16,0,505,1,2462, +1963,1,97,3793,16, +0,505,1,2459,1969, +1,2458,1974,1,2030, +1978,1,89,3794,16, +0,505,1,1860,1983, +1,85,3795,16,0, +505,1,1659,3796,16, +0,505,1,1657,1990, +1,277,3797,16,0, +505,1,1261,3798,16, +0,505,1,166,3799, +16,0,505,1,2045, +1997,1,2043,2001,1, +2041,2005,1,2039,2009, +1,462,3800,16,0, +505,1,2037,2014,1, +459,3801,16,0,505, +1,1443,3802,16,0, +505,1,2033,2020,1, +2032,2024,1,1834,3803, +16,0,505,1,2227, +2029,1,256,3804,16, +0,505,1,447,3805, +16,0,505,1,62, +3806,16,0,505,1, +2021,2036,1,2413,3807, +16,0,505,1,1622, +3808,16,0,505,1, +2464,2042,1,1225,3809, +16,0,505,1,41, +3810,16,0,505,1, +236,3811,16,0,505, +1,431,3812,16,0, +505,1,32,3813,16, +0,505,1,1804,3814, +16,0,505,1,1803, +2052,1,1407,3815,16, +0,505,1,79,3816, +16,0,505,1,217, +3817,16,0,505,1, +1989,2060,1,102,3818, +16,0,505,1,2786, +3819,16,0,505,1, +406,3820,16,0,505, +1,1585,3821,16,0, +505,1,1189,3822,16, +0,505,1,1873,2069, +1,199,3823,16,0, +505,1,2364,2074,1, +26,3824,19,461,1, +26,3825,5,84,1, +1377,3826,16,0,667, +1,387,3827,16,0, +667,1,188,3233,1, +380,2968,1,379,2973, +1,377,2978,1,2792, +3828,16,0,667,1, +375,2983,1,373,2987, +1,371,2991,1,172, +3238,1,67,2997,1, +1939,3829,16,0,667, +1,1737,3830,16,0, +667,1,1341,3831,16, +0,667,1,157,3832, +16,0,667,1,480, +3006,1,942,3011,1, +49,3016,1,143,3833, +16,0,667,1,1521, +3834,16,0,667,1, +1123,3835,16,0,667, +1,82,3023,1,2299, +3836,16,0,667,1, +328,3029,1,130,3256, +1,1114,3034,1,1701, +3837,16,0,667,1, +1303,3838,16,0,667, +1,118,3262,1,1096, +3042,1,1882,3839,16, +0,667,1,305,3048, +1,107,3052,1,1485, +3840,16,0,667,1, +70,3057,1,1555,3841, +16,0,667,1,883, +3842,16,0,667,1, +93,3063,1,1665,3843, +16,0,667,1,283, +3068,1,479,3072,1, +478,3077,1,477,3081, +1,476,3085,1,74, +3089,1,73,3844,16, +0,667,1,1449,3845, +16,0,667,1,69, +3095,1,68,3099,1, +1840,3846,16,0,667, +1,66,3104,1,262, +3108,1,1267,3847,16, +0,667,1,1048,3113, +1,447,3117,1,1628, +3848,16,0,667,1, +51,3123,1,63,3127, +1,1231,3849,16,0, +667,1,48,3132,1, +47,3136,1,242,3850, +16,0,667,1,44, +3138,1,437,3851,16, +0,514,1,42,3852, +16,0,667,1,525, +3145,1,827,3853,16, +0,667,1,352,3151, +1,1413,3854,16,0, +667,1,1013,3156,1, +1012,3855,16,0,667, +1,223,3856,16,0, +667,1,1159,3857,16, +0,667,1,1011,3164, +1,412,3858,16,0, +667,1,1002,3169,1, +1001,3173,1,1591,3859, +16,0,667,1,1195, +3860,16,0,667,1, +40,3179,1,205,3861, +16,0,667,1,50, +3181,1,515,3862,16, +0,459,1,25,3863, +19,537,1,25,3864, +5,177,1,42,3865, +16,0,671,1,412, +3866,16,0,671,1, +1701,3867,16,0,671, +1,406,3868,16,0, +535,1,1267,3869,16, +0,671,1,1695,3870, +16,0,535,1,1261, +3871,16,0,535,1, +827,3872,16,0,671, +1,2031,1915,1,387, +3873,16,0,671,1, +2106,3874,16,0,535, +1,2105,1940,1,380, +2968,1,379,2973,1, +377,2978,1,375,2983, +1,2029,1921,1,373, +2987,1,1665,3875,16, +0,671,1,371,2991, +1,1231,3876,16,0, +671,1,1555,3877,16, +0,671,1,1659,3878, +16,0,535,1,1657, +1990,1,1225,3879,16, +0,535,1,1479,3880, +16,0,535,1,352, +3151,1,2075,3881,16, +0,535,1,346,3882, +16,0,535,1,1628, +3883,16,0,671,1, +1195,3884,16,0,671, +1,1622,3885,16,0, +535,1,328,3029,1, +1189,3886,16,0,535, +1,322,3887,16,0, +535,1,2045,1997,1, +2043,2001,1,2041,2005, +1,2039,2009,1,2037, +2014,1,2035,1900,1, +2464,2042,1,2032,2024, +1,2462,1963,1,2030, +1978,1,305,3048,1, +2459,1969,1,2458,1974, +1,299,3888,16,0, +535,1,1591,3889,16, +0,671,1,1159,3890, +16,0,671,1,1585, +3891,16,0,535,1, +1153,3892,16,0,535, +1,2136,1926,1,66, +3104,1,283,3068,1, +1574,1895,1,277,3893, +16,0,535,1,1377, +3894,16,0,671,1, +32,3895,16,0,535, +1,49,3016,1,1990, +3896,16,0,535,1, +1989,2060,1,262,3108, +1,1123,3897,16,0, +671,1,2413,3898,16, +0,535,1,256,3899, +16,0,535,1,1117, +3900,16,0,535,1, +1114,3034,1,242,3901, +16,0,671,1,1933, +3902,16,0,535,1, +236,3903,16,0,535, +1,1096,3042,1,1521, +3904,16,0,671,1, +223,3905,16,0,671, +1,1515,3906,16,0, +535,1,217,3907,16, +0,535,1,1939,3908, +16,0,671,1,70, +3057,1,2364,2074,1, +1931,1909,1,2792,3909, +16,0,671,1,205, +3910,16,0,671,1, +2786,3911,16,0,535, +1,199,3912,16,0, +535,1,942,3011,1, +1485,3913,16,0,671, +1,188,3233,1,1048, +3113,1,182,3914,16, +0,535,1,1901,3915, +16,0,535,1,172, +3238,1,2021,2036,1, +48,3132,1,166,3916, +16,0,535,1,2318, +3917,16,0,535,1, +381,3918,16,0,535, +1,1882,3919,16,0, +671,1,157,3920,16, +0,671,1,1449,3921, +16,0,671,1,1876, +3922,16,0,535,1, +151,3923,16,0,535, +1,1012,3924,16,0, +671,1,2337,3925,16, +0,535,1,2299,3926, +16,0,671,1,143, +3927,16,0,671,1, +1002,3169,1,1001,3173, +1,2293,3928,16,0, +535,1,137,3929,16, +0,535,1,1860,1983, +1,130,3256,1,79, +3930,16,0,535,1, +124,3931,16,0,535, +1,1443,3932,16,0, +535,1,1011,3164,1, +1413,3933,16,0,671, +1,118,3262,1,1840, +3934,16,0,671,1, +1407,3935,16,0,535, +1,112,3936,16,0, +535,1,1834,3937,16, +0,535,1,1958,3938, +16,0,535,1,107, +3052,1,2033,2020,1, +97,3939,16,0,535, +1,1873,2069,1,525, +3940,16,0,535,1, +93,3063,1,1371,3941, +16,0,535,1,89, +3942,16,0,535,1, +43,3943,16,0,535, +1,85,3944,16,0, +535,1,515,3945,16, +0,671,1,82,3023, +1,1804,3946,16,0, +535,1,1803,2052,1, +509,3947,16,0,535, +1,76,3948,16,0, +535,1,74,3089,1, +73,3949,16,0,671, +1,2227,2029,1,71, +3950,16,0,535,1, +1013,3156,1,69,3095, +1,68,3099,1,67, +2997,1,102,3951,16, +0,535,1,47,3136, +1,63,3127,1,62, +3952,16,0,535,1, +52,3953,16,0,535, +1,1775,3954,16,0, +535,1,50,3181,1, +480,3006,1,479,3072, +1,478,3077,1,477, +3081,1,476,3085,1, +44,3138,1,2198,3955, +16,0,535,1,1335, +3956,16,0,535,1, +41,3957,16,0,535, +1,40,3179,1,1341, +3958,16,0,671,1, +51,3123,1,1756,3959, +16,0,535,1,462, +3960,16,0,535,1, +459,3961,16,0,535, +1,883,3962,16,0, +671,1,447,3963,16, +0,535,1,1737,3964, +16,0,671,1,1303, +3965,16,0,671,1, +1731,3966,16,0,535, +1,437,3967,16,0, +671,1,1297,3968,16, +0,535,1,431,3969, +16,0,535,1,24, +3970,19,435,1,24, +3971,5,5,1,377, +3972,16,0,455,1, +44,3973,16,0,753, +1,373,3974,16,0, +548,1,40,3975,16, +0,433,1,63,3976, +16,0,740,1,23, +3977,19,658,1,23, +3978,5,38,1,2045, +1997,1,2043,2001,1, +1775,3979,16,0,656, +1,2041,2005,1,2039, +2009,1,1860,1983,1, +2037,2014,1,2035,1900, +1,2033,2020,1,2032, +2024,1,2031,1915,1, +2030,1978,1,2029,1921, +1,2106,3980,16,0, +656,1,2464,2042,1, +1931,1909,1,1574,1895, +1,2462,1963,1,2105, +1940,1,2459,1969,1, +2458,1974,1,2364,2074, +1,1958,3981,16,0, +656,1,2198,3982,16, +0,656,1,2021,2036, +1,1901,3983,16,0, +656,1,1989,2060,1, +1803,2052,1,2075,3984, +16,0,656,1,1990, +3985,16,0,656,1, +1804,3986,16,0,656, +1,2337,3987,16,0, +656,1,1657,1990,1, +2413,3988,16,0,656, +1,32,3989,16,0, +656,1,1873,2069,1, +2227,2029,1,2136,1926, +1,22,3990,19,603, +1,22,3991,5,84, +1,1377,3992,16,0, +601,1,387,3993,16, +0,601,1,188,3994, +16,0,601,1,380, +2968,1,379,2973,1, +377,2978,1,2792,3995, +16,0,601,1,375, +2983,1,373,2987,1, +371,2991,1,172,3996, +16,0,601,1,67, +2997,1,1939,3997,16, +0,601,1,1737,3998, +16,0,601,1,1341, +3999,16,0,601,1, +157,4000,16,0,601, +1,480,3006,1,942, +4001,16,0,601,1, +49,3016,1,143,4002, +16,0,601,1,1521, +4003,16,0,601,1, +1123,4004,16,0,601, +1,82,3023,1,2299, +4005,16,0,601,1, +328,4006,16,0,601, +1,130,4007,16,0, +601,1,1114,3034,1, +1701,4008,16,0,601, +1,1303,4009,16,0, +601,1,118,4010,16, +0,601,1,1096,3042, +1,1882,4011,16,0, +601,1,305,3048,1, +107,3052,1,1485,4012, +16,0,601,1,70, +3057,1,1555,4013,16, +0,601,1,883,4014, +16,0,601,1,93, +3063,1,1665,4015,16, +0,601,1,283,3068, +1,479,3072,1,478, +3077,1,477,3081,1, +476,3085,1,74,3089, +1,73,4016,16,0, +601,1,1449,4017,16, +0,601,1,69,3095, +1,68,3099,1,1840, +4018,16,0,601,1, +66,3104,1,262,3108, +1,1267,4019,16,0, +601,1,1048,4020,16, +0,601,1,447,3117, +1,1628,4021,16,0, +601,1,51,3123,1, +63,3127,1,1231,4022, +16,0,601,1,48, +3132,1,47,3136,1, +242,4023,16,0,601, +1,44,3138,1,437, +4024,16,0,601,1, +42,4025,16,0,601, +1,525,3145,1,827, +4026,16,0,601,1, +352,4027,16,0,601, +1,1413,4028,16,0, +601,1,1013,3156,1, +1012,4029,16,0,601, +1,223,4030,16,0, +601,1,1159,4031,16, +0,601,1,1011,3164, +1,412,4032,16,0, +601,1,1002,3169,1, +1001,3173,1,1591,4033, +16,0,601,1,1195, +4034,16,0,601,1, +40,3179,1,205,4035, +16,0,601,1,50, +3181,1,515,4036,16, +0,601,1,21,4037, +19,588,1,21,4038, +5,84,1,1377,4039, +16,0,586,1,387, +4040,16,0,586,1, +188,4041,16,0,586, +1,380,2968,1,379, +2973,1,377,2978,1, +2792,4042,16,0,586, +1,375,2983,1,373, +2987,1,371,2991,1, +172,4043,16,0,586, +1,67,2997,1,1939, +4044,16,0,586,1, +1737,4045,16,0,586, +1,1341,4046,16,0, +586,1,157,4047,16, +0,586,1,480,3006, +1,942,4048,16,0, +586,1,49,3016,1, +143,4049,16,0,586, +1,1521,4050,16,0, +586,1,1123,4051,16, +0,586,1,82,3023, +1,2299,4052,16,0, +586,1,328,4053,16, +0,586,1,130,4054, +16,0,586,1,1114, +3034,1,1701,4055,16, +0,586,1,1303,4056, +16,0,586,1,118, +4057,16,0,586,1, +1096,3042,1,1882,4058, +16,0,586,1,305, +3048,1,107,3052,1, +1485,4059,16,0,586, +1,70,3057,1,1555, +4060,16,0,586,1, +883,4061,16,0,586, +1,93,3063,1,1665, +4062,16,0,586,1, +283,3068,1,479,3072, +1,478,3077,1,477, +3081,1,476,3085,1, +74,3089,1,73,4063, +16,0,586,1,1449, +4064,16,0,586,1, +69,3095,1,68,3099, +1,1840,4065,16,0, +586,1,66,3104,1, +262,3108,1,1267,4066, +16,0,586,1,1048, +4067,16,0,586,1, +447,3117,1,1628,4068, +16,0,586,1,51, +3123,1,63,3127,1, +1231,4069,16,0,586, +1,48,3132,1,47, +3136,1,242,4070,16, +0,586,1,44,3138, +1,437,4071,16,0, +586,1,42,4072,16, +0,586,1,525,3145, +1,827,4073,16,0, +586,1,352,4074,16, +0,586,1,1413,4075, +16,0,586,1,1013, +3156,1,1012,4076,16, +0,586,1,223,4077, +16,0,586,1,1159, +4078,16,0,586,1, +1011,3164,1,412,4079, +16,0,586,1,1002, +3169,1,1001,3173,1, +1591,4080,16,0,586, +1,1195,4081,16,0, +586,1,40,3179,1, +205,4082,16,0,586, +1,50,3181,1,515, +4083,16,0,586,1, +20,4084,19,580,1, +20,4085,5,84,1, +1377,4086,16,0,578, +1,387,4087,16,0, +578,1,188,4088,16, +0,578,1,380,2968, +1,379,2973,1,377, +2978,1,2792,4089,16, +0,578,1,375,2983, +1,373,2987,1,371, +2991,1,172,4090,16, +0,578,1,67,2997, +1,1939,4091,16,0, +578,1,1737,4092,16, +0,578,1,1341,4093, +16,0,578,1,157, +4094,16,0,578,1, +480,3006,1,942,4095, +16,0,578,1,49, +3016,1,143,4096,16, +0,578,1,1521,4097, +16,0,578,1,1123, +4098,16,0,578,1, +82,3023,1,2299,4099, +16,0,578,1,328, +4100,16,0,578,1, +130,4101,16,0,578, +1,1114,3034,1,1701, +4102,16,0,578,1, +1303,4103,16,0,578, +1,118,4104,16,0, +578,1,1096,3042,1, +1882,4105,16,0,578, +1,305,3048,1,107, +3052,1,1485,4106,16, +0,578,1,70,3057, +1,1555,4107,16,0, +578,1,883,4108,16, +0,578,1,93,3063, +1,1665,4109,16,0, +578,1,283,3068,1, +479,3072,1,478,3077, +1,477,3081,1,476, +3085,1,74,3089,1, +73,4110,16,0,578, +1,1449,4111,16,0, +578,1,69,3095,1, +68,3099,1,1840,4112, +16,0,578,1,66, +3104,1,262,3108,1, +1267,4113,16,0,578, +1,1048,4114,16,0, +578,1,447,3117,1, +1628,4115,16,0,578, +1,51,3123,1,63, +3127,1,1231,4116,16, +0,578,1,48,3132, +1,47,3136,1,242, +4117,16,0,578,1, +44,3138,1,437,4118, +16,0,578,1,42, +4119,16,0,578,1, +525,3145,1,827,4120, +16,0,578,1,352, +4121,16,0,578,1, +1413,4122,16,0,578, +1,1013,3156,1,1012, +4123,16,0,578,1, +223,4124,16,0,578, +1,1159,4125,16,0, +578,1,1011,3164,1, +412,4126,16,0,578, +1,1002,3169,1,1001, +3173,1,1591,4127,16, +0,578,1,1195,4128, +16,0,578,1,40, +3179,1,205,4129,16, +0,578,1,50,3181, +1,515,4130,16,0, +578,1,19,4131,19, +569,1,19,4132,5, +176,1,42,4133,16, +0,567,1,412,4134, +16,0,567,1,1701, +4135,16,0,567,1, +406,4136,16,0,709, +1,1267,4137,16,0, +567,1,1695,4138,16, +0,709,1,1261,4139, +16,0,709,1,827, +4140,16,0,567,1, +2031,1915,1,387,4141, +16,0,567,1,2106, +4142,16,0,709,1, +2105,1940,1,380,2968, +1,379,2973,1,377, +2978,1,375,2983,1, +2029,1921,1,373,2987, +1,1665,4143,16,0, +567,1,371,2991,1, +1231,4144,16,0,567, +1,1555,4145,16,0, +567,1,1659,4146,16, +0,709,1,1657,1990, +1,1225,4147,16,0, +709,1,1479,4148,16, +0,709,1,352,3151, +1,2075,4149,16,0, +709,1,346,4150,16, +0,709,1,1628,4151, +16,0,567,1,1195, +4152,16,0,567,1, +1622,4153,16,0,709, +1,328,3029,1,1189, +4154,16,0,709,1, +322,4155,16,0,709, +1,2045,1997,1,2043, +2001,1,2041,2005,1, +2039,2009,1,2037,2014, +1,2035,1900,1,2464, +2042,1,2032,2024,1, +2462,1963,1,2030,1978, +1,305,3048,1,2459, +1969,1,2458,1974,1, +299,4156,16,0,709, +1,1591,4157,16,0, +567,1,1159,4158,16, +0,567,1,1585,4159, +16,0,709,1,1153, +4160,16,0,709,1, +2136,1926,1,66,3104, +1,283,3068,1,1574, +1895,1,277,4161,16, +0,709,1,1377,4162, +16,0,567,1,32, +4163,16,0,709,1, +49,3016,1,1990,4164, +16,0,709,1,1989, +2060,1,262,3108,1, +1123,4165,16,0,567, +1,2413,4166,16,0, +709,1,256,4167,16, +0,709,1,1117,4168, +16,0,709,1,1114, +3034,1,242,4169,16, +0,567,1,1933,4170, +16,0,709,1,236, +4171,16,0,709,1, +1096,3042,1,1521,4172, +16,0,567,1,223, +4173,16,0,567,1, +1515,4174,16,0,709, +1,217,4175,16,0, +709,1,1939,4176,16, +0,567,1,70,3057, +1,2364,2074,1,1931, +1909,1,2792,4177,16, +0,567,1,205,4178, +16,0,567,1,2786, +4179,16,0,709,1, +199,4180,16,0,709, +1,942,4181,16,0, +567,1,1485,4182,16, +0,567,1,188,4183, +16,0,567,1,1048, +4184,16,0,567,1, +182,4185,16,0,709, +1,1901,4186,16,0, +709,1,172,4187,16, +0,567,1,2021,2036, +1,48,3132,1,166, +4188,16,0,709,1, +2318,4189,16,0,709, +1,381,4190,16,0, +709,1,1882,4191,16, +0,567,1,157,4192, +16,0,567,1,1449, +4193,16,0,567,1, +1876,4194,16,0,709, +1,151,4195,16,0, +709,1,1012,4196,16, +0,567,1,2337,4197, +16,0,709,1,2299, +4198,16,0,567,1, +143,4199,16,0,567, +1,1002,3169,1,1001, +3173,1,2293,4200,16, +0,709,1,137,4201, +16,0,709,1,1860, +1983,1,130,4202,16, +0,567,1,79,4203, +16,0,709,1,124, +4204,16,0,709,1, +1443,4205,16,0,709, +1,1011,3164,1,1413, +4206,16,0,567,1, +118,4207,16,0,567, +1,1840,4208,16,0, +567,1,1407,4209,16, +0,709,1,112,4210, +16,0,709,1,1834, +4211,16,0,709,1, +1958,4212,16,0,709, +1,107,3052,1,2033, +2020,1,97,4213,16, +0,709,1,1873,2069, +1,525,4214,16,0, +709,1,93,3063,1, +1371,4215,16,0,709, +1,89,4216,16,0, +709,1,43,4217,16, +0,709,1,85,4218, +16,0,709,1,515, +4219,16,0,567,1, +82,3023,1,1804,4220, +16,0,709,1,1803, +2052,1,509,4221,16, +0,709,1,76,4222, +16,0,709,1,74, +3089,1,73,4223,16, +0,567,1,2227,2029, +1,71,4224,16,0, +709,1,1013,3156,1, +69,3095,1,68,3099, +1,67,2997,1,102, +4225,16,0,709,1, +47,3136,1,63,3127, +1,52,4226,16,0, +709,1,1775,4227,16, +0,709,1,50,3181, +1,480,3006,1,479, +3072,1,478,3077,1, +477,3081,1,476,3085, +1,44,3138,1,2198, +4228,16,0,709,1, +1335,4229,16,0,709, +1,41,4230,16,0, +709,1,40,3179,1, +1341,4231,16,0,567, +1,51,3123,1,1756, +4232,16,0,709,1, +462,4233,16,0,709, +1,459,4234,16,0, +709,1,883,4235,16, +0,567,1,447,4236, +16,0,709,1,1737, +4237,16,0,567,1, +1303,4238,16,0,567, +1,1731,4239,16,0, +709,1,437,4240,16, +0,567,1,1297,4241, +16,0,709,1,431, +4242,16,0,709,1, +18,4243,19,563,1, +18,4244,5,84,1, +1377,4245,16,0,561, +1,387,4246,16,0, +561,1,188,4247,16, +0,561,1,380,2968, +1,379,2973,1,377, +2978,1,2792,4248,16, +0,561,1,375,2983, +1,373,2987,1,371, +2991,1,172,4249,16, +0,561,1,67,2997, +1,1939,4250,16,0, +561,1,1737,4251,16, +0,561,1,1341,4252, +16,0,561,1,157, +4253,16,0,561,1, +480,3006,1,942,4254, +16,0,561,1,49, +3016,1,143,4255,16, +0,561,1,1521,4256, +16,0,561,1,1123, +4257,16,0,561,1, +82,3023,1,2299,4258, +16,0,561,1,328, +3029,1,130,4259,16, +0,561,1,1114,3034, +1,1701,4260,16,0, +561,1,1303,4261,16, +0,561,1,118,4262, +16,0,561,1,1096, +3042,1,1882,4263,16, +0,561,1,305,3048, +1,107,3052,1,1485, +4264,16,0,561,1, +70,3057,1,1555,4265, +16,0,561,1,883, +4266,16,0,561,1, +93,3063,1,1665,4267, +16,0,561,1,283, +3068,1,479,3072,1, +478,3077,1,477,3081, +1,476,3085,1,74, +3089,1,73,4268,16, +0,561,1,1449,4269, +16,0,561,1,69, +3095,1,68,3099,1, +1840,4270,16,0,561, +1,66,3104,1,262, +3108,1,1267,4271,16, +0,561,1,1048,4272, +16,0,561,1,447, +3117,1,1628,4273,16, +0,561,1,51,3123, +1,63,3127,1,1231, +4274,16,0,561,1, +48,3132,1,47,3136, +1,242,4275,16,0, +561,1,44,3138,1, +437,4276,16,0,561, +1,42,4277,16,0, +561,1,525,3145,1, +827,4278,16,0,561, +1,352,3151,1,1413, +4279,16,0,561,1, +1013,3156,1,1012,4280, +16,0,561,1,223, +4281,16,0,561,1, +1159,4282,16,0,561, +1,1011,3164,1,412, +4283,16,0,561,1, +1002,3169,1,1001,3173, +1,1591,4284,16,0, +561,1,1195,4285,16, +0,561,1,40,3179, +1,205,4286,16,0, +561,1,50,3181,1, +515,4287,16,0,561, +1,17,4288,19,139, +1,17,4289,5,134, +1,2281,4290,17,4291, +15,4292,4,34,37, +0,70,0,111,0, +114,0,76,0,111, +0,111,0,112,0, +83,0,116,0,97, +0,116,0,101,0, +109,0,101,0,110, +0,116,0,1,-1, +1,5,4293,20,1403, +1,251,1,3,1, +2,1,1,4294,22, +1,86,1,1377,4295, +17,4296,15,4297,4, +34,37,0,83,0, +105,0,109,0,112, +0,108,0,101,0, +65,0,115,0,115, +0,105,0,103,0, +110,0,109,0,101, +0,110,0,116,0, +1,-1,1,5,4298, +20,1369,1,260,1, +3,1,4,1,3, +4299,22,1,95,1, +67,2997,1,2556,4300, +16,0,243,1,2555, +4301,17,4302,15,4303, +4,60,37,0,86, +0,101,0,99,0, +116,0,111,0,114, +0,65,0,114,0, +103,0,117,0,109, +0,101,0,110,0, +116,0,68,0,101, +0,99,0,108,0, +97,0,114,0,97, +0,116,0,105,0, +111,0,110,0,76, +0,105,0,115,0, +116,0,1,-1,1, +5,4304,20,1659,1, +209,1,3,1,2, +1,1,4305,22,1, +44,1,1370,4306,17, +4307,15,4297,1,-1, +1,5,4308,20,1343, +1,273,1,3,1, +4,1,3,4309,22, +1,108,1,2548,4310, +16,0,257,1,380, +2968,1,379,2973,1, +377,2978,1,2543,4311, +17,4312,15,4313,4, +30,37,0,82,0, +111,0,116,0,68, +0,101,0,99,0, +108,0,97,0,114, +0,97,0,116,0, +105,0,111,0,110, +0,1,-1,1,5, +4314,20,1603,1,217, +1,3,1,3,1, +2,4315,22,1,52, +1,2547,4316,17,4317, +15,4318,4,66,37, +0,73,0,110,0, +116,0,82,0,111, +0,116,0,82,0, +111,0,116,0,65, +0,114,0,103,0, +117,0,109,0,101, +0,110,0,116,0, +68,0,101,0,99, +0,108,0,97,0, +114,0,97,0,116, +0,105,0,111,0, +110,0,76,0,105, +0,115,0,116,0, +1,-1,1,5,4319, +20,1655,1,210,1, +3,1,6,1,5, +4320,22,1,45,1, +373,2987,1,371,2991, +1,172,3238,1,1550, +4321,17,4322,15,4297, +1,-1,1,5,4323, +20,1353,1,268,1, +3,1,4,1,3, +4324,22,1,103,1, +2533,4325,16,0,282, +1,2335,4326,16,0, +475,1,1152,4327,17, +4328,15,4297,1,-1, +1,5,4329,20,1299, +1,279,1,3,1, +6,1,5,4330,22, +1,114,1,1939,4331, +16,0,688,1,2528, +4332,17,4333,15,4334, +4,30,37,0,86, +0,101,0,99,0, +68,0,101,0,99, +0,108,0,97,0, +114,0,97,0,116, +0,105,0,111,0, +110,0,1,-1,1, +5,4335,20,1608,1, +216,1,3,1,3, +1,2,4336,22,1, +51,1,1341,4337,17, +4338,15,4297,1,-1, +1,5,4339,20,1367, +1,261,1,3,1, +4,1,3,4340,22, +1,96,1,157,3245, +1,42,3742,1,352, +3151,1,2518,4341,16, +0,300,1,2517,4342, +17,4343,15,4344,4, +66,37,0,75,0, +101,0,121,0,73, +0,110,0,116,0, +73,0,110,0,116, +0,65,0,114,0, +103,0,117,0,109, +0,101,0,110,0, +116,0,68,0,101, +0,99,0,108,0, +97,0,114,0,97, +0,116,0,105,0, +111,0,110,0,76, +0,105,0,115,0, +116,0,1,-1,1, +5,4345,20,1647,1, +212,1,3,1,6, +1,5,4346,22,1, +47,1,1332,4347,17, +4348,15,4297,1,-1, +1,5,4349,20,1341, +1,274,1,3,1, +6,1,5,4350,22, +1,109,1,2513,4351, +17,4352,15,4353,4, +30,37,0,73,0, +110,0,116,0,68, +0,101,0,99,0, +108,0,97,0,114, +0,97,0,116,0, +105,0,111,0,110, +0,1,-1,1,5, +4354,20,1614,1,215, +1,3,1,3,1, +2,4355,22,1,50, +1,2509,4356,17,4357, +15,4358,4,30,37, +0,75,0,101,0, +121,0,68,0,101, +0,99,0,108,0, +97,0,114,0,97, +0,116,0,105,0, +111,0,110,0,1, +-1,1,5,4359,20, +1622,1,214,1,3, +1,3,1,2,4360, +22,1,49,1,1001, +3173,1,1521,4361,17, +4362,15,4297,1,-1, +1,5,4363,20,1377, +1,256,1,3,1, +4,1,3,4364,22, +1,91,1,188,3233, +1,1123,4365,17,4366, +15,4297,1,-1,1, +5,4367,20,1355,1, +267,1,3,1,6, +1,5,4368,22,1, +102,1,328,3029,1, +1514,4369,17,4370,15, +4297,1,-1,1,5, +4371,20,1351,1,269, +1,3,1,4,1, +3,4372,22,1,104, +1,10,4373,17,4374, +15,4375,4,48,37, +0,65,0,114,0, +103,0,117,0,109, +0,101,0,110,0, +116,0,68,0,101, +0,99,0,108,0, +97,0,114,0,97, +0,116,0,105,0, +111,0,110,0,76, +0,105,0,115,0, +116,0,1,-1,1, +5,205,1,0,1, +0,4376,22,1,39, +1,82,3023,1,525, +3145,1,130,3256,1, +1114,3034,1,7,2314, +1,1701,4377,17,4378, +15,4292,1,-1,1, +5,4379,20,1401,1, +252,1,3,1,4, +1,3,4380,22,1, +87,1,1012,4381,16, +0,705,1,942,3011, +1,1303,4382,17,4383, +15,4297,1,-1,1, +5,4384,20,1365,1, +262,1,3,1,6, +1,5,4385,22,1, +97,1,2532,4386,17, +4387,15,4388,4,66, +37,0,73,0,110, +0,116,0,86,0, +101,0,99,0,86, +0,101,0,99,0, +65,0,114,0,103, +0,117,0,109,0, +101,0,110,0,116, +0,68,0,101,0, +99,0,108,0,97, +0,114,0,97,0, +116,0,105,0,111, +0,110,0,76,0, +105,0,115,0,116, +0,1,-1,1,5, +4389,20,1651,1,211, +1,3,1,6,1, +5,4390,22,1,46, +1,118,3262,1,1010, +4391,16,0,707,1, +1296,4392,17,4393,15, +4297,1,-1,1,5, +4394,20,1339,1,275, +1,3,1,6,1, +5,4395,22,1,110, +1,68,3099,1,1096, +3042,1,1,2367,1, +1094,4396,16,0,668, +1,305,3048,1,107, +3052,1,1485,4397,17, +4398,15,4297,1,-1, +1,5,4399,20,1375, +1,257,1,3,1, +4,1,3,4400,22, +1,92,1,2074,4401, +16,0,606,1,2467, +4402,17,4403,15,4375, +1,-1,1,5,4404, +20,1673,1,205,1, +3,1,2,1,1, +4405,22,1,40,1, +49,3016,1,6,2350, +1,70,3057,1,1478, +4406,17,4407,15,4297, +1,-1,1,5,4408, +20,1349,1,270,1, +3,1,4,1,3, +4409,22,1,105,1, +1871,4410,16,0,765, +1,143,3249,1,883, +3269,1,93,3063,1, +1665,4411,17,4412,15, +4292,1,-1,1,5, +4413,20,1405,1,250, +1,3,1,2,1, +1,4414,22,1,85, +1,481,3747,1,480, +3006,1,479,3072,1, +478,3077,1,477,3081, +1,476,3085,1,20, +4415,16,0,768,1, +1260,4416,17,4417,15, +4297,1,-1,1,5, +4418,20,1337,1,276, +1,3,1,6,1, +5,4419,22,1,111, +1,375,2983,1,74, +3089,1,73,4420,16, +0,731,1,1048,3113, +1,1882,4421,16,0, +628,1,464,3734,1, +69,3095,1,262,3108, +1,1840,4422,16,0, +723,1,66,3104,1, +459,3752,1,1267,4423, +17,4424,15,4297,1, +-1,1,5,4425,20, +1363,1,263,1,3, +1,6,1,5,4426, +22,1,98,1,1442, +4427,17,4428,15,4297, +1,-1,1,5,4429, +20,1347,1,271,1, +3,1,4,1,3, +4430,22,1,106,1, +61,4431,16,0,742, +1,2197,4432,16,0, +557,1,447,3117,1, +1730,4433,17,4434,15, +4292,1,-1,1,5, +4435,20,1395,1,253, +1,3,1,4,1, +3,4436,22,1,88, +1,51,3123,1,63, +3127,1,1231,4437,17, +4438,15,4297,1,-1, +1,5,4439,20,1361, +1,264,1,3,1, +6,1,5,4440,22, +1,99,1,48,3132, +1,47,3136,1,242, +3280,1,44,3138,1, +4,2358,1,1224,4441, +17,4442,15,4297,1, +-1,1,5,4443,20, +1335,1,277,1,3, +1,6,1,5,4444, +22,1,112,1,41, +3739,1,40,3179,1, +827,3286,1,1413,4445, +17,4446,15,4297,1, +-1,1,5,4447,20, +1371,1,259,1,3, +1,4,1,3,4448, +22,1,94,1,2591, +4449,16,0,203,1, +2779,4450,16,0,773, +1,1013,3156,1,1406, +4451,17,4452,15,4297, +1,-1,1,5,4453, +20,1345,1,272,1, +3,1,4,1,3, +4454,22,1,107,1, +223,3292,1,1159,4455, +17,4456,15,4297,1, +-1,1,5,4457,20, +1357,1,266,1,3, +1,6,1,5,4458, +22,1,101,1,2, +2336,1,3,2362,1, +2582,4459,17,4460,15, +4375,1,-1,1,5, +205,1,0,1,0, +4376,1,283,3068,1, +19,4461,17,4462,15, +4463,4,24,37,0, +68,0,101,0,99, +0,108,0,97,0, +114,0,97,0,116, +0,105,0,111,0, +110,0,1,-1,1, +5,4464,20,1627,1, +213,1,3,1,3, +1,2,4465,22,1, +48,1,1002,3169,1, +2577,4466,16,0,733, +1,30,4467,17,4468, +15,4375,1,-1,1, +5,4469,20,1671,1, +206,1,3,1,4, +1,3,4470,22,1, +41,1,1195,4471,17, +4472,15,4297,1,-1, +1,5,4473,20,1359, +1,265,1,3,1, +6,1,5,4474,22, +1,100,1,2770,4475, +17,4476,15,4375,1, +-1,1,5,205,1, +0,1,0,4376,1, +2572,4477,16,0,219, +1,2571,4478,17,4479, +15,4480,4,54,37, +0,75,0,101,0, +121,0,65,0,114, 0,103,0,117,0, 109,0,101,0,110, 0,116,0,68,0, @@ -7654,15 +11831,27 @@ public yyLSLSyntax 97,0,116,0,105, 0,111,0,110,0, 76,0,105,0,115, -0,116,0,95,0, -49,0,1,209,1, -3,1,2,1,1, -2303,22,1,44,1, -1260,1221,1,47,1311, -1,48,1317,1,49, -1323,1,50,1328,1, -51,1333,1,2563,2304, -17,2305,15,2306,4, +0,116,0,1,-1, +1,5,4481,20,1667, +1,207,1,3,1, +2,1,1,4482,22, +1,42,1,9,4483, +17,4462,1,2,4465, +1,205,3300,1,1449, +4484,17,4485,15,4297, +1,-1,1,5,4486, +20,1373,1,258,1, +3,1,4,1,3, +4487,22,1,93,1, +1188,4488,17,4489,15, +4297,1,-1,1,5, +4490,20,1333,1,278, +1,3,1,6,1, +5,4491,22,1,113, +1,5,2354,1,50, +3181,1,2564,4492,16, +0,231,1,2563,4493, +17,4494,15,4495,4, 54,37,0,73,0, 110,0,116,0,65, 0,114,0,103,0, @@ -7674,5859 +11863,1649 @@ public yyLSLSyntax 0,105,0,111,0, 110,0,76,0,105, 0,115,0,116,0, -1,-1,1,5,2307, -20,2308,4,56,73, -0,110,0,116,0, -65,0,114,0,103, -0,117,0,109,0, -101,0,110,0,116, -0,68,0,101,0, -99,0,108,0,97, -0,114,0,97,0, -116,0,105,0,111, -0,110,0,76,0, -105,0,115,0,116, -0,95,0,49,0, -1,208,1,3,1, -2,1,1,2309,22, -1,43,1,305,1338, -1,1514,1233,1,525, -1343,1,61,2310,16, -0,217,1,2572,2311, -16,0,689,1,63, -1349,1,66,1355,1, -67,1360,1,68,1365, -1,69,1370,1,70, -1375,1,2582,1936,1, -73,2312,16,0,227, -1,827,1457,1,1013, -1385,1,2335,2313,16, -0,263,1,1332,1390, -1,74,1380,1,2591, -2314,16,0,710,1, -82,1407,1,2513,1886, -1,1341,1424,1,2517, -2315,17,2316,15,2317, -4,66,37,0,75, -0,101,0,121,0, -73,0,110,0,116, -0,73,0,110,0, -116,0,65,0,114, -0,103,0,117,0, -109,0,101,0,110, -0,116,0,68,0, -101,0,99,0,108, -0,97,0,114,0, -97,0,116,0,105, -0,111,0,110,0, -76,0,105,0,115, -0,116,0,1,-1, -1,5,2318,20,2319, -4,68,75,0,101, -0,121,0,73,0, -110,0,116,0,73, -0,110,0,116,0, -65,0,114,0,103, -0,117,0,109,0, -101,0,110,0,116, -0,68,0,101,0, -99,0,108,0,97, -0,114,0,97,0, -116,0,105,0,111, -0,110,0,76,0, -105,0,115,0,116, -0,95,0,49,0, -1,212,1,3,1, -6,1,5,2320,22, -1,47,1,328,1429, -1,1303,1434,1,1096, -1439,1,93,1445,1, -1550,1450,1,2281,1279, -1,2770,1925,1,352, -1475,1,2779,2321,16, -0,797,1,107,1464, -1,1114,1469,1,1048, -1470,1,1871,2322,16, -0,353,1,1370,1578, -1,1478,1583,1,118, -1481,1,1123,1486,1, -371,1491,1,1377,1497, -1,375,1502,1,1882, -2323,16,0,373,1, -377,1507,1,2556,2324, -16,0,661,1,379, -1512,1,380,1517,1, -130,1540,1,2074,2325, -16,0,652,1,373, -1535,1,2564,2326,16, -0,554,1,1011,1227, -1,1012,2327,16,0, -718,1,1840,2328,16, -0,343,1,143,1545, -1,1152,1551,1,2577, -2329,16,0,696,1, -1406,1556,1,1159,1563, -1,157,1568,1,1413, -1573,1,883,1523,1, -1094,2330,16,0,787, -1,1296,1294,1,172, -1595,1,1665,1600,1, -1939,2331,16,0,494, -1,1188,1605,1,1442, -1610,1,188,1644,1, -942,1616,1,1195,1622, -1,1449,1627,1,1701, -1632,1,447,1637,1, -205,1649,1,2467,1942, -1,464,1948,1,2197, -2332,16,0,782,1, -1224,1654,1,223,1659, -1,1730,1664,1,2571, -2333,17,2334,15,2335, -4,54,37,0,75, -0,101,0,121,0, -65,0,114,0,103, -0,117,0,109,0, -101,0,110,0,116, -0,68,0,101,0, -99,0,108,0,97, -0,114,0,97,0, -116,0,105,0,111, -0,110,0,76,0, -105,0,115,0,116, -0,1,-1,1,5, -2336,20,2337,4,56, -75,0,101,0,121, -0,65,0,114,0, -103,0,117,0,109, -0,101,0,110,0, -116,0,68,0,101, -0,99,0,108,0, -97,0,114,0,97, -0,116,0,105,0, -111,0,110,0,76, -0,105,0,115,0, -116,0,95,0,49, -0,1,207,1,3, -1,2,1,1,2338, -22,1,42,1,477, -1675,1,1231,1680,1, -479,1685,1,480,1690, -1,1485,1696,1,459, -1953,1,476,1669,1, -242,1703,1,478,1708, -1,481,1955,1,1001, -1713,1,1002,1718,1, -2509,1960,1,18,2339, -19,574,1,18,2340, -5,84,1,1011,1227, -1,1012,2341,16,0, -572,1,1013,1385,1, -262,1244,1,1267,2342, -16,0,572,1,515, -2343,16,0,572,1, -1521,2344,16,0,572, -1,525,1343,1,2792, -2345,16,0,572,1, -283,1299,1,2299,2346, -16,0,572,1,42, -2347,16,0,572,1, -40,1304,1,44,1310, -1,47,1311,1,1303, -2348,16,0,572,1, -1555,2349,16,0,572, -1,50,1328,1,48, -1317,1,49,1323,1, -51,1333,1,63,1349, -1,305,1338,1,66, -1355,1,67,1360,1, -68,1365,1,69,1370, -1,70,1375,1,73, -2350,16,0,572,1, -74,1380,1,328,1429, -1,1048,2351,16,0, -572,1,82,2352,16, -0,572,1,1840,2353, -16,0,572,1,1591, -2354,16,0,572,1, -1341,2355,16,0,572, -1,1096,1439,1,93, -1445,1,352,1475,1, -107,2356,16,0,572, -1,1114,1469,1,118, -2357,16,0,572,1, -1123,2358,16,0,572, -1,371,1491,1,1628, -2359,16,0,572,1, -375,1502,1,1882,2360, -16,0,572,1,377, -1507,1,379,1512,1, -380,1517,1,883,2361, -16,0,572,1,373, -1535,1,130,2362,16, -0,572,1,143,2363, -16,0,572,1,387, -2364,16,0,572,1, -1159,2365,16,0,572, -1,157,2366,16,0, -572,1,1413,2367,16, -0,572,1,1665,2368, -16,0,572,1,412, -2369,16,0,572,1, -1377,2370,16,0,572, -1,172,2371,16,0, -572,1,1939,2372,16, -0,572,1,437,2373, -16,0,572,1,188, -2374,16,0,572,1, -942,2375,16,0,572, -1,1195,2376,16,0, -572,1,1449,2377,16, -0,572,1,1701,2378, -16,0,572,1,447, -1637,1,205,2379,16, -0,572,1,827,2380, -16,0,572,1,223, -2381,16,0,572,1, -476,1669,1,477,1675, -1,1231,2382,16,0, -572,1,479,1685,1, -480,1690,1,1485,2383, -16,0,572,1,1737, -2384,16,0,572,1, -242,2385,16,0,572, -1,478,1708,1,1001, -1713,1,1002,1718,1, -19,2386,19,251,1, -19,2387,5,176,1, -942,2388,16,0,537, -1,256,2389,16,0, -249,1,1261,2390,16, -0,249,1,1011,1227, -1,1012,2391,16,0, -537,1,2458,1001,1, -262,1244,1,1267,2392, -16,0,537,1,2021, -843,1,1521,2393,16, -0,537,1,1775,2394, -16,0,249,1,2029, -850,1,2030,856,1, -2031,861,1,2032,866, -1,2786,2395,16,0, -249,1,277,2396,16, -0,249,1,2035,877, -1,2037,882,1,2792, -2397,16,0,537,1, -32,2398,16,0,249, -1,2464,1024,1,2293, -2399,16,0,249,1, -2043,899,1,2045,904, -1,2299,2400,16,0, -537,1,41,2401,16, -0,249,1,42,2402, -16,0,537,1,40, -1304,1,44,1310,1, -43,2403,16,0,249, -1,1804,2404,16,0, -249,1,48,1317,1, -49,1323,1,47,1311, -1,51,1333,1,52, -2405,16,0,249,1, -50,1328,1,305,1338, -1,1096,1439,1,1515, -2406,16,0,249,1, -2318,2407,16,0,249, -1,283,1299,1,63, -1349,1,66,1355,1, -67,1360,1,68,1365, -1,69,1370,1,70, -1375,1,71,2408,16, -0,249,1,73,2409, -16,0,537,1,74, -1380,1,1013,1385,1, -76,2410,16,0,249, -1,1834,2411,16,0, -249,1,2337,2412,16, -0,249,1,79,2413, -16,0,249,1,1335, -2414,16,0,249,1, -299,2415,16,0,249, -1,82,2416,16,0, -537,1,1840,2417,16, -0,537,1,1297,2418, -16,0,249,1,85, -2419,16,0,249,1, -1341,2420,16,0,537, -1,89,2421,16,0, -249,1,1303,2422,16, -0,537,1,509,2423, -16,0,249,1,93, -1445,1,322,2424,16, -0,249,1,2039,887, -1,97,2425,16,0, -249,1,2041,893,1, -1555,2426,16,0,537, -1,827,2427,16,0, -537,1,102,2428,16, -0,249,1,1860,946, -1,1803,912,1,2364, -952,1,107,2429,16, -0,537,1,1114,1469, -1,112,2430,16,0, -249,1,1117,2431,16, -0,249,1,352,1475, -1,1873,961,1,118, -2432,16,0,537,1, -1123,2433,16,0,537, -1,371,1491,1,515, -2434,16,0,537,1, -1377,2435,16,0,537, -1,124,2436,16,0, -249,1,1882,2437,16, -0,537,1,377,1507, -1,379,1512,1,380, -1517,1,130,2438,16, -0,537,1,346,2439, -16,0,249,1,2075, -2440,16,0,249,1, -373,1535,1,387,2441, -16,0,537,1,137, -2442,16,0,249,1, -143,2443,16,0,537, -1,1901,2444,16,0, -249,1,1048,2445,16, -0,537,1,1153,2446, -16,0,249,1,375, -1502,1,151,2447,16, -0,249,1,1407,2448, -16,0,249,1,1659, -2449,16,0,249,1, -2413,2450,16,0,249, -1,1159,2451,16,0, -537,1,381,2452,16, -0,249,1,157,2453, -16,0,537,1,1413, -2454,16,0,537,1, -883,2455,16,0,537, -1,1371,2456,16,0, -249,1,328,1429,1, -2105,939,1,2106,2457, -16,0,249,1,166, -2458,16,0,249,1, -525,2459,16,0,249, -1,1622,2460,16,0, -249,1,406,2461,16, -0,249,1,1574,924, -1,172,2462,16,0, -537,1,1931,986,1, -412,2463,16,0,537, -1,1933,2464,16,0, -249,1,1876,2465,16, -0,249,1,431,2466, -16,0,249,1,1585, -2467,16,0,249,1, -182,2468,16,0,249, -1,1628,2469,16,0, -537,1,1189,2470,16, -0,249,1,437,2471, -16,0,537,1,1591, -2472,16,0,537,1, -188,2473,16,0,537, -1,1695,2474,16,0, -249,1,2198,2475,16, -0,249,1,1195,2476, -16,0,537,1,1449, -2477,16,0,537,1, -1701,2478,16,0,537, -1,447,2479,16,0, -249,1,199,2480,16, -0,249,1,2459,1007, -1,1958,2481,16,0, -249,1,2462,1014,1, -1657,1019,1,205,2482, -16,0,537,1,459, -2483,16,0,249,1, -462,2484,16,0,249, -1,1665,2485,16,0, -537,1,217,2486,16, -0,249,1,2227,1033, -1,2033,871,1,1225, -2487,16,0,249,1, -223,2488,16,0,537, -1,1479,2489,16,0, -249,1,1731,2490,16, -0,249,1,477,1675, -1,1231,2491,16,0, -537,1,479,1685,1, -480,1690,1,1485,2492, -16,0,537,1,1737, -2493,16,0,537,1, -1989,1041,1,1990,2494, -16,0,249,1,1443, -2495,16,0,249,1, -236,2496,16,0,249, -1,2136,968,1,476, -1669,1,242,2497,16, -0,537,1,478,1708, -1,1939,2498,16,0, -537,1,1001,1713,1, -1002,1718,1,1756,2499, -16,0,249,1,20, -2500,19,510,1,20, -2501,5,84,1,1011, -1227,1,1012,2502,16, -0,508,1,1013,1385, -1,262,1244,1,1267, -2503,16,0,508,1, -515,2504,16,0,508, -1,1521,2505,16,0, -508,1,525,1343,1, -2792,2506,16,0,508, -1,283,1299,1,2299, -2507,16,0,508,1, -42,2508,16,0,508, -1,40,1304,1,44, -1310,1,47,1311,1, -1303,2509,16,0,508, -1,1555,2510,16,0, -508,1,50,1328,1, -48,1317,1,49,1323, -1,51,1333,1,63, -1349,1,305,1338,1, -66,1355,1,67,1360, -1,68,1365,1,69, -1370,1,70,1375,1, -73,2511,16,0,508, -1,74,1380,1,328, -2512,16,0,508,1, -1048,2513,16,0,508, -1,82,2514,16,0, -508,1,1840,2515,16, -0,508,1,1591,2516, -16,0,508,1,1341, -2517,16,0,508,1, -1096,1439,1,93,1445, -1,352,2518,16,0, -508,1,107,2519,16, -0,508,1,1114,1469, -1,118,2520,16,0, -508,1,1123,2521,16, -0,508,1,371,1491, -1,1628,2522,16,0, -508,1,375,1502,1, -1882,2523,16,0,508, -1,377,1507,1,379, -1512,1,380,1517,1, -883,2524,16,0,508, -1,373,1535,1,130, -2525,16,0,508,1, -143,2526,16,0,508, -1,387,2527,16,0, -508,1,1159,2528,16, -0,508,1,157,2529, -16,0,508,1,1413, -2530,16,0,508,1, -1665,2531,16,0,508, -1,412,2532,16,0, -508,1,1377,2533,16, -0,508,1,172,2534, -16,0,508,1,1939, -2535,16,0,508,1, -437,2536,16,0,508, -1,188,2537,16,0, -508,1,942,2538,16, -0,508,1,1195,2539, -16,0,508,1,1449, -2540,16,0,508,1, -1701,2541,16,0,508, -1,447,1637,1,205, -2542,16,0,508,1, -827,2543,16,0,508, -1,223,2544,16,0, -508,1,476,1669,1, -477,1675,1,1231,2545, -16,0,508,1,479, -1685,1,480,1690,1, -1485,2546,16,0,508, -1,1737,2547,16,0, -508,1,242,2548,16, -0,508,1,478,1708, -1,1001,1713,1,1002, -1718,1,21,2549,19, -478,1,21,2550,5, -84,1,1011,1227,1, -1012,2551,16,0,476, -1,1013,1385,1,262, -1244,1,1267,2552,16, -0,476,1,515,2553, -16,0,476,1,1521, -2554,16,0,476,1, -525,1343,1,2792,2555, -16,0,476,1,283, -1299,1,2299,2556,16, -0,476,1,42,2557, -16,0,476,1,40, -1304,1,44,1310,1, -47,1311,1,1303,2558, -16,0,476,1,1555, -2559,16,0,476,1, -50,1328,1,48,1317, -1,49,1323,1,51, -1333,1,63,1349,1, -305,1338,1,66,1355, -1,67,1360,1,68, -1365,1,69,1370,1, -70,1375,1,73,2560, -16,0,476,1,74, -1380,1,328,2561,16, -0,476,1,1048,2562, -16,0,476,1,82, -2563,16,0,476,1, -1840,2564,16,0,476, -1,1591,2565,16,0, -476,1,1341,2566,16, -0,476,1,1096,1439, -1,93,1445,1,352, -2567,16,0,476,1, -107,2568,16,0,476, -1,1114,1469,1,118, -2569,16,0,476,1, -1123,2570,16,0,476, -1,371,1491,1,1628, -2571,16,0,476,1, -375,1502,1,1882,2572, -16,0,476,1,377, -1507,1,379,1512,1, -380,1517,1,883,2573, -16,0,476,1,373, -1535,1,130,2574,16, -0,476,1,143,2575, -16,0,476,1,387, -2576,16,0,476,1, -1159,2577,16,0,476, -1,157,2578,16,0, -476,1,1413,2579,16, -0,476,1,1665,2580, -16,0,476,1,412, -2581,16,0,476,1, -1377,2582,16,0,476, -1,172,2583,16,0, -476,1,1939,2584,16, -0,476,1,437,2585, -16,0,476,1,188, -2586,16,0,476,1, -942,2587,16,0,476, -1,1195,2588,16,0, -476,1,1449,2589,16, -0,476,1,1701,2590, -16,0,476,1,447, -1637,1,205,2591,16, -0,476,1,827,2592, -16,0,476,1,223, -2593,16,0,476,1, -476,1669,1,477,1675, -1,1231,2594,16,0, -476,1,479,1685,1, -480,1690,1,1485,2595, -16,0,476,1,1737, -2596,16,0,476,1, -242,2597,16,0,476, -1,478,1708,1,1001, -1713,1,1002,1718,1, -22,2598,19,429,1, -22,2599,5,84,1, -1011,1227,1,1012,2600, -16,0,427,1,1013, -1385,1,262,1244,1, -1267,2601,16,0,427, -1,515,2602,16,0, -427,1,1521,2603,16, -0,427,1,525,1343, -1,2792,2604,16,0, -427,1,283,1299,1, -2299,2605,16,0,427, -1,42,2606,16,0, -427,1,40,1304,1, -44,1310,1,47,1311, -1,1303,2607,16,0, -427,1,1555,2608,16, -0,427,1,50,1328, -1,48,1317,1,49, -1323,1,51,1333,1, -63,1349,1,305,1338, -1,66,1355,1,67, -1360,1,68,1365,1, -69,1370,1,70,1375, -1,73,2609,16,0, -427,1,74,1380,1, -328,2610,16,0,427, -1,1048,2611,16,0, -427,1,82,2612,16, -0,427,1,1840,2613, -16,0,427,1,1591, -2614,16,0,427,1, -1341,2615,16,0,427, -1,1096,1439,1,93, -1445,1,352,2616,16, -0,427,1,107,2617, -16,0,427,1,1114, -1469,1,118,2618,16, -0,427,1,1123,2619, -16,0,427,1,371, -1491,1,1628,2620,16, -0,427,1,375,1502, -1,1882,2621,16,0, -427,1,377,1507,1, -379,1512,1,380,1517, -1,883,2622,16,0, -427,1,373,1535,1, -130,2623,16,0,427, -1,143,2624,16,0, -427,1,387,2625,16, -0,427,1,1159,2626, -16,0,427,1,157, -2627,16,0,427,1, -1413,2628,16,0,427, -1,1665,2629,16,0, -427,1,412,2630,16, -0,427,1,1377,2631, -16,0,427,1,172, -2632,16,0,427,1, -1939,2633,16,0,427, -1,437,2634,16,0, -427,1,188,2635,16, -0,427,1,942,2636, -16,0,427,1,1195, -2637,16,0,427,1, -1449,2638,16,0,427, -1,1701,2639,16,0, -427,1,447,1637,1, -205,2640,16,0,427, -1,827,2641,16,0, -427,1,223,2642,16, -0,427,1,476,1669, -1,477,1675,1,1231, -2643,16,0,427,1, -479,1685,1,480,1690, -1,1485,2644,16,0, -427,1,1737,2645,16, -0,427,1,242,2646, -16,0,427,1,478, -1708,1,1001,1713,1, -1002,1718,1,23,2647, -19,590,1,23,2648, -5,38,1,1901,2649, -16,0,588,1,2075, -2650,16,0,588,1, -1860,946,1,1803,912, -1,1804,2651,16,0, -588,1,2413,2652,16, -0,588,1,2198,2653, -16,0,588,1,1873, -961,1,1657,1019,1, -1989,1041,1,1990,2654, -16,0,588,1,1775, -2655,16,0,588,1, -32,2656,16,0,588, -1,2105,939,1,2106, -2657,16,0,588,1, -2364,952,1,2227,1033, -1,2337,2658,16,0, -588,1,2021,843,1, -2458,1001,1,2459,1007, -1,2462,1014,1,2136, -968,1,2464,1024,1, -2029,850,1,2030,856, -1,2031,861,1,2032, -866,1,2033,871,1, -2035,877,1,2037,882, -1,2039,887,1,1931, -986,1,2041,893,1, -2043,899,1,2045,904, -1,1574,924,1,1958, -2659,16,0,588,1, -24,2660,19,193,1, -24,2661,5,5,1, -44,2662,16,0,191, -1,377,2663,16,0, -626,1,40,2664,16, -0,799,1,63,2665, -16,0,219,1,373, -2666,16,0,622,1, -25,2667,19,329,1, -25,2668,5,177,1, -942,1616,1,256,2669, -16,0,631,1,1261, -2670,16,0,631,1, -1011,1227,1,1012,2671, -16,0,327,1,2458, -1001,1,262,1244,1, -1267,2672,16,0,327, -1,2021,843,1,1521, -2673,16,0,327,1, -1775,2674,16,0,631, -1,2029,850,1,2030, -856,1,2031,861,1, -2032,866,1,2786,2675, -16,0,631,1,277, -2676,16,0,631,1, -2035,877,1,2037,882, -1,2792,2677,16,0, -327,1,32,2678,16, -0,631,1,2464,1024, -1,2293,2679,16,0, -631,1,2043,899,1, -2045,904,1,2299,2680, -16,0,327,1,41, -2681,16,0,631,1, -42,2682,16,0,327, -1,40,1304,1,44, -1310,1,43,2683,16, -0,631,1,1804,2684, -16,0,631,1,48, -1317,1,49,1323,1, -47,1311,1,51,1333, -1,52,2685,16,0, -631,1,50,1328,1, -305,1338,1,1096,1439, -1,1515,2686,16,0, -631,1,2318,2687,16, -0,631,1,62,2688, -16,0,631,1,63, -1349,1,66,1355,1, -67,1360,1,68,1365, -1,69,1370,1,70, -1375,1,71,2689,16, -0,631,1,283,1299, -1,73,2690,16,0, -327,1,74,1380,1, -1013,1385,1,76,2691, -16,0,631,1,1834, -2692,16,0,631,1, -2337,2693,16,0,631, -1,79,2694,16,0, -631,1,1335,2695,16, -0,631,1,299,2696, -16,0,631,1,82, -2697,16,0,327,1, -1840,2698,16,0,327, -1,1297,2699,16,0, -631,1,85,2700,16, -0,631,1,1341,2701, -16,0,327,1,89, -2702,16,0,631,1, -1303,2703,16,0,327, -1,509,2704,16,0, -631,1,93,1445,1, -322,2705,16,0,631, -1,2039,887,1,97, -2706,16,0,631,1, -2041,893,1,1555,2707, -16,0,327,1,827, -2708,16,0,327,1, -102,2709,16,0,631, -1,1860,946,1,1803, -912,1,2364,952,1, -107,2710,16,0,327, -1,1114,1469,1,112, -2711,16,0,631,1, -1117,2712,16,0,631, -1,352,1475,1,1873, -961,1,118,1481,1, -1123,2713,16,0,327, -1,371,1491,1,515, -2714,16,0,327,1, -1377,2715,16,0,327, -1,124,2716,16,0, -631,1,1882,2717,16, -0,327,1,377,1507, -1,379,1512,1,380, -1517,1,130,1540,1, -346,2718,16,0,631, -1,2075,2719,16,0, -631,1,373,1535,1, -387,2720,16,0,327, -1,137,2721,16,0, -631,1,143,2722,16, -0,327,1,1901,2723, -16,0,631,1,1048, -1470,1,1153,2724,16, -0,631,1,375,1502, -1,151,2725,16,0, -631,1,1407,2726,16, -0,631,1,1659,2727, -16,0,631,1,2413, -2728,16,0,631,1, -1159,2729,16,0,327, -1,381,2730,16,0, -631,1,157,2731,16, -0,327,1,1413,2732, -16,0,327,1,883, -2733,16,0,327,1, -1371,2734,16,0,631, -1,328,1429,1,2105, -939,1,2106,2735,16, -0,631,1,166,2736, -16,0,631,1,525, -2737,16,0,631,1, -1622,2738,16,0,631, -1,406,2739,16,0, -631,1,1574,924,1, -172,1595,1,1931,986, -1,412,2740,16,0, -327,1,1933,2741,16, -0,631,1,1876,2742, -16,0,631,1,431, -2743,16,0,631,1, -1585,2744,16,0,631, -1,182,2745,16,0, -631,1,1628,2746,16, -0,327,1,1189,2747, -16,0,631,1,437, -2748,16,0,327,1, -1591,2749,16,0,327, -1,188,1644,1,1695, -2750,16,0,631,1, -2198,2751,16,0,631, -1,1195,2752,16,0, -327,1,1449,2753,16, -0,327,1,1701,2754, -16,0,327,1,447, -2755,16,0,631,1, -199,2756,16,0,631, -1,2459,1007,1,1958, -2757,16,0,631,1, -2462,1014,1,1657,1019, -1,205,2758,16,0, -327,1,459,2759,16, -0,631,1,462,2760, -16,0,631,1,1665, -2761,16,0,327,1, -217,2762,16,0,631, -1,2227,1033,1,2033, -871,1,1225,2763,16, -0,631,1,223,2764, -16,0,327,1,1479, -2765,16,0,631,1, -1731,2766,16,0,631, -1,477,1675,1,1231, -2767,16,0,327,1, -479,1685,1,480,1690, -1,1485,2768,16,0, -327,1,1737,2769,16, -0,327,1,1989,1041, -1,1990,2770,16,0, -631,1,1443,2771,16, -0,631,1,236,2772, -16,0,631,1,2136, -968,1,476,1669,1, -242,2773,16,0,327, -1,478,1708,1,1939, -2774,16,0,327,1, -1001,1713,1,1002,1718, -1,1756,2775,16,0, -631,1,26,2776,19, -348,1,26,2777,5, -84,1,1011,1227,1, -1012,2778,16,0,346, -1,1013,1385,1,262, -1244,1,1267,2779,16, -0,346,1,515,2780, -16,0,780,1,1521, -2781,16,0,346,1, -525,1343,1,2792,2782, -16,0,346,1,283, -1299,1,2299,2783,16, -0,346,1,42,2784, -16,0,346,1,40, -1304,1,44,1310,1, -47,1311,1,1303,2785, -16,0,346,1,1555, -2786,16,0,346,1, -50,1328,1,48,1317, -1,49,1323,1,51, -1333,1,63,1349,1, -305,1338,1,66,1355, -1,67,1360,1,68, -1365,1,69,1370,1, -70,1375,1,73,2787, -16,0,346,1,74, -1380,1,328,1429,1, -1048,1470,1,82,2788, -16,0,346,1,1840, -2789,16,0,346,1, -1591,2790,16,0,346, -1,1341,2791,16,0, -346,1,1096,1439,1, -93,1445,1,352,1475, -1,107,2792,16,0, -346,1,1114,1469,1, -118,1481,1,1123,2793, -16,0,346,1,371, -1491,1,1628,2794,16, -0,346,1,375,1502, -1,1882,2795,16,0, -346,1,377,1507,1, -379,1512,1,380,1517, -1,883,2796,16,0, -346,1,373,1535,1, -130,1540,1,143,2797, -16,0,346,1,387, -2798,16,0,346,1, -1159,2799,16,0,346, -1,157,2800,16,0, -346,1,1413,2801,16, -0,346,1,1665,2802, -16,0,346,1,412, -2803,16,0,346,1, -1377,2804,16,0,346, -1,172,1595,1,1939, -2805,16,0,346,1, -437,2806,16,0,709, -1,188,1644,1,942, -1616,1,1195,2807,16, -0,346,1,1449,2808, -16,0,346,1,1701, -2809,16,0,346,1, -447,1637,1,205,2810, -16,0,346,1,827, -2811,16,0,346,1, -223,2812,16,0,346, -1,476,1669,1,477, -1675,1,1231,2813,16, -0,346,1,479,1685, -1,480,1690,1,1485, -2814,16,0,346,1, -1737,2815,16,0,346, -1,242,2816,16,0, -346,1,478,1708,1, -1001,1713,1,1002,1718, -1,27,2817,19,721, -1,27,2818,5,95, -1,256,2819,16,0, -719,1,1261,2820,16, -0,719,1,509,2821, -16,0,719,1,1515, -2822,16,0,719,1, -2021,843,1,1775,2823, -16,0,719,1,2029, -850,1,2030,856,1, -2031,861,1,2032,866, -1,2033,871,1,277, -2824,16,0,719,1, -2035,877,1,2037,882, -1,2039,887,1,32, -2825,16,0,719,1, -2041,893,1,2293,2826, -16,0,719,1,2043, -899,1,2045,904,1, -41,2827,16,0,719, -1,1297,2828,16,0, -719,1,43,2829,16, -0,719,1,1803,912, -1,1804,2830,16,0, -719,1,299,2831,16, -0,719,1,52,2832, -16,0,719,1,2318, -2833,16,0,719,1, -62,2834,16,0,719, -1,2075,2835,16,0, -719,1,1574,924,1, -71,2836,16,0,719, -1,76,2837,16,0, -719,1,1834,2838,16, -0,719,1,2337,2839, -16,0,719,1,79, -2840,16,0,719,1, -1335,2841,16,0,719, -1,322,2842,16,0, -719,1,85,2843,16, -0,719,1,89,2844, -16,0,719,1,346, -2845,16,0,719,1, -2105,939,1,2106,2846, -16,0,719,1,97, -2847,16,0,719,1, -1860,946,1,2364,952, -1,102,2848,16,0, -719,1,112,2849,16, -0,719,1,1117,2850, -16,0,719,1,2786, -2851,16,0,719,1, -1873,961,1,1876,2852, -16,0,719,1,124, -2853,16,0,719,1, -2136,968,1,381,2854, -16,0,719,1,525, -2855,16,0,719,1, -137,2856,16,0,719, -1,1901,2857,16,0, -719,1,1153,2858,16, -0,719,1,151,2859, -16,0,719,1,1407, -2860,16,0,719,1, -1659,2861,16,0,719, -1,2413,2862,16,0, -719,1,406,2863,16, -0,719,1,1371,2864, -16,0,719,1,166, -2865,16,0,719,1, -1622,2866,16,0,719, -1,1931,986,1,1933, -2867,16,0,719,1, -431,2868,16,0,719, -1,1585,2869,16,0, -719,1,182,2870,16, -0,719,1,1189,2871, -16,0,719,1,1443, -2872,16,0,719,1, -1695,2873,16,0,719, -1,2198,2874,16,0, -719,1,447,2875,16, -0,719,1,2458,1001, -1,2459,1007,1,1958, -2876,16,0,719,1, -2462,1014,1,1657,1019, -1,2464,1024,1,199, -2877,16,0,719,1, -459,2878,16,0,719, -1,462,2879,16,0, -719,1,217,2880,16, -0,719,1,2227,1033, -1,1225,2881,16,0, -719,1,1479,2882,16, -0,719,1,1731,2883, -16,0,719,1,1989, -1041,1,1990,2884,16, -0,719,1,236,2885, -16,0,719,1,1756, -2886,16,0,719,1, -28,2887,19,749,1, -28,2888,5,60,1, -328,1429,1,223,1659, -1,1096,1439,1,118, -1481,1,883,1523,1, -525,1343,1,1001,1713, -1,130,1540,1,459, -1953,1,1114,1469,1, -352,1475,1,447,1637, -1,464,1948,1,1011, -1227,1,1013,1385,1, -242,1703,1,143,1545, -1,40,1304,1,41, -1913,1,42,1917,1, -479,1685,1,44,1310, -1,481,1955,1,373, -1535,1,47,1311,1, -157,1568,1,49,1323, -1,50,1328,1,48, -1317,1,379,1512,1, -380,1517,1,51,1333, -1,476,1669,1,371, -1491,1,478,1708,1, -1048,1470,1,375,1502, -1,172,1595,1,262, -1244,1,283,1299,1, -63,1349,1,67,1360, -1,68,1365,1,69, -1370,1,66,1355,1, -461,2889,16,0,747, -1,74,1380,1,377, -1507,1,1002,1718,1, -70,1375,1,188,1644, -1,82,1407,1,305, -1338,1,477,1675,1, -827,1457,1,93,1445, -1,480,1690,1,205, -1649,1,942,1616,1, -107,1464,1,29,2890, -19,315,1,29,2891, -5,84,1,1011,1227, -1,1012,2892,16,0, -313,1,1013,1385,1, -262,1244,1,1267,2893, -16,0,313,1,515, -2894,16,0,313,1, -1521,2895,16,0,313, -1,525,1343,1,2792, -2896,16,0,313,1, -283,1299,1,2299,2897, -16,0,313,1,42, -2898,16,0,313,1, -40,1304,1,44,1310, -1,47,1311,1,1303, -2899,16,0,313,1, -1555,2900,16,0,313, -1,50,1328,1,48, -1317,1,49,1323,1, -51,1333,1,63,1349, -1,305,1338,1,66, -1355,1,67,1360,1, -68,1365,1,69,1370, -1,70,1375,1,73, -2901,16,0,313,1, -74,1380,1,328,1429, -1,1048,1470,1,82, -2902,16,0,313,1, -1840,2903,16,0,313, -1,1591,2904,16,0, -313,1,1341,2905,16, -0,313,1,1096,1439, -1,93,1445,1,352, -1475,1,107,2906,16, -0,313,1,1114,1469, -1,118,1481,1,1123, -2907,16,0,313,1, -371,1491,1,1628,2908, -16,0,313,1,375, -1502,1,1882,2909,16, -0,313,1,377,1507, -1,379,1512,1,380, -1517,1,883,2910,16, -0,313,1,373,1535, -1,130,1540,1,143, -1545,1,387,2911,16, -0,313,1,1159,2912, -16,0,313,1,157, -1568,1,1413,2913,16, -0,313,1,1665,2914, -16,0,313,1,412, -2915,16,0,313,1, -1377,2916,16,0,313, -1,172,1595,1,1939, -2917,16,0,313,1, -437,2918,16,0,313, -1,188,1644,1,942, -1616,1,1195,2919,16, -0,313,1,1449,2920, -16,0,313,1,1701, -2921,16,0,313,1, -447,1637,1,205,2922, -16,0,313,1,827, -2923,16,0,313,1, -223,2924,16,0,313, -1,476,1669,1,477, -1675,1,1231,2925,16, -0,313,1,479,1685, -1,480,1690,1,1485, -2926,16,0,313,1, -1737,2927,16,0,313, -1,242,2928,16,0, -313,1,478,1708,1, -1001,1713,1,1002,1718, -1,30,2929,19,297, -1,30,2930,5,84, -1,1011,1227,1,1012, -2931,16,0,295,1, -1013,1385,1,262,1244, -1,1267,2932,16,0, -295,1,515,2933,16, -0,295,1,1521,2934, -16,0,295,1,525, -1343,1,2792,2935,16, -0,295,1,283,1299, -1,2299,2936,16,0, -295,1,42,2937,16, -0,295,1,40,1304, -1,44,1310,1,47, -1311,1,1303,2938,16, -0,295,1,1555,2939, -16,0,295,1,50, -1328,1,48,1317,1, -49,1323,1,51,1333, -1,63,1349,1,305, -1338,1,66,1355,1, -67,1360,1,68,1365, -1,69,1370,1,70, -1375,1,73,2940,16, -0,295,1,74,1380, -1,328,1429,1,1048, -1470,1,82,2941,16, -0,295,1,1840,2942, -16,0,295,1,1591, -2943,16,0,295,1, -1341,2944,16,0,295, -1,1096,1439,1,93, -1445,1,352,1475,1, -107,2945,16,0,295, -1,1114,1469,1,118, -1481,1,1123,2946,16, -0,295,1,371,1491, -1,1628,2947,16,0, -295,1,375,1502,1, -1882,2948,16,0,295, -1,377,1507,1,379, -1512,1,380,1517,1, -883,2949,16,0,295, -1,373,1535,1,130, -1540,1,143,1545,1, -387,2950,16,0,295, -1,1159,2951,16,0, -295,1,157,1568,1, -1413,2952,16,0,295, -1,1665,2953,16,0, -295,1,412,2954,16, -0,295,1,1377,2955, -16,0,295,1,172, -1595,1,1939,2956,16, -0,295,1,437,2957, -16,0,295,1,188, -1644,1,942,1616,1, -1195,2958,16,0,295, -1,1449,2959,16,0, -295,1,1701,2960,16, -0,295,1,447,1637, -1,205,2961,16,0, -295,1,827,2962,16, -0,295,1,223,2963, -16,0,295,1,476, -1669,1,477,1675,1, -1231,2964,16,0,295, -1,479,1685,1,480, -1690,1,1485,2965,16, -0,295,1,1737,2966, -16,0,295,1,242, -2967,16,0,295,1, -478,1708,1,1001,1713, -1,1002,1718,1,31, -2968,19,277,1,31, -2969,5,84,1,1011, -1227,1,1012,2970,16, -0,275,1,1013,1385, -1,262,1244,1,1267, -2971,16,0,275,1, -515,2972,16,0,275, -1,1521,2973,16,0, -275,1,525,1343,1, -2792,2974,16,0,275, -1,283,1299,1,2299, -2975,16,0,275,1, -42,2976,16,0,275, -1,40,1304,1,44, -1310,1,47,1311,1, -1303,2977,16,0,275, -1,1555,2978,16,0, -275,1,50,1328,1, -48,1317,1,49,1323, -1,51,1333,1,63, -1349,1,305,1338,1, -66,1355,1,67,1360, -1,68,1365,1,69, -1370,1,70,1375,1, -73,2979,16,0,275, -1,74,1380,1,328, -1429,1,1048,1470,1, -82,2980,16,0,275, -1,1840,2981,16,0, -275,1,1591,2982,16, -0,275,1,1341,2983, -16,0,275,1,1096, -1439,1,93,1445,1, -352,1475,1,107,2984, -16,0,275,1,1114, -1469,1,118,1481,1, -1123,2985,16,0,275, -1,371,1491,1,1628, -2986,16,0,275,1, -375,1502,1,1882,2987, -16,0,275,1,377, -1507,1,379,1512,1, -380,1517,1,883,2988, -16,0,275,1,373, -1535,1,130,1540,1, -143,2989,16,0,275, -1,387,2990,16,0, -275,1,1159,2991,16, -0,275,1,157,2992, -16,0,275,1,1413, -2993,16,0,275,1, -1665,2994,16,0,275, -1,412,2995,16,0, -275,1,1377,2996,16, -0,275,1,172,1595, -1,1939,2997,16,0, -275,1,437,2998,16, -0,275,1,188,1644, -1,942,1616,1,1195, -2999,16,0,275,1, -1449,3000,16,0,275, -1,1701,3001,16,0, -275,1,447,1637,1, -205,3002,16,0,275, -1,827,3003,16,0, -275,1,223,3004,16, -0,275,1,476,1669, -1,477,1675,1,1231, -3005,16,0,275,1, -479,1685,1,480,1690, -1,1485,3006,16,0, -275,1,1737,3007,16, -0,275,1,242,3008, -16,0,275,1,478, -1708,1,1001,1713,1, -1002,1718,1,32,3009, -19,270,1,32,3010, -5,84,1,1011,1227, -1,1012,3011,16,0, -268,1,1013,1385,1, -262,1244,1,1267,3012, -16,0,268,1,515, -3013,16,0,268,1, -1521,3014,16,0,268, -1,525,1343,1,2792, -3015,16,0,268,1, -283,1299,1,2299,3016, -16,0,268,1,42, -3017,16,0,268,1, -40,1304,1,44,1310, -1,47,1311,1,1303, -3018,16,0,268,1, -1555,3019,16,0,268, -1,50,1328,1,48, -1317,1,49,1323,1, -51,1333,1,63,1349, -1,305,1338,1,66, -1355,1,67,1360,1, -68,1365,1,69,1370, -1,70,1375,1,73, -3020,16,0,268,1, -74,1380,1,328,1429, -1,1048,1470,1,82, -3021,16,0,268,1, -1840,3022,16,0,268, -1,1591,3023,16,0, -268,1,1341,3024,16, -0,268,1,1096,1439, -1,93,1445,1,352, -1475,1,107,3025,16, -0,268,1,1114,1469, -1,118,1481,1,1123, -3026,16,0,268,1, -371,1491,1,1628,3027, -16,0,268,1,375, -1502,1,1882,3028,16, -0,268,1,377,1507, -1,379,1512,1,380, -1517,1,883,3029,16, -0,268,1,373,1535, -1,130,1540,1,143, -3030,16,0,268,1, -387,3031,16,0,268, -1,1159,3032,16,0, -268,1,157,3033,16, -0,268,1,1413,3034, -16,0,268,1,1665, -3035,16,0,268,1, -412,3036,16,0,268, -1,1377,3037,16,0, -268,1,172,1595,1, -1939,3038,16,0,268, -1,437,3039,16,0, -268,1,188,1644,1, -942,1616,1,1195,3040, -16,0,268,1,1449, -3041,16,0,268,1, -1701,3042,16,0,268, -1,447,1637,1,205, -3043,16,0,268,1, -827,3044,16,0,268, -1,223,3045,16,0, -268,1,476,1669,1, -477,1675,1,1231,3046, -16,0,268,1,479, -1685,1,480,1690,1, -1485,3047,16,0,268, -1,1737,3048,16,0, -268,1,242,3049,16, -0,268,1,478,1708, -1,1001,1713,1,1002, -1718,1,33,3050,19, -378,1,33,3051,5, -84,1,1011,1227,1, -1012,3052,16,0,376, -1,1013,1385,1,262, -1244,1,1267,3053,16, -0,376,1,515,3054, -16,0,376,1,1521, -3055,16,0,376,1, -525,1343,1,2792,3056, -16,0,376,1,283, -1299,1,2299,3057,16, -0,376,1,42,3058, -16,0,376,1,40, -1304,1,44,1310,1, -47,1311,1,1303,3059, -16,0,376,1,1555, -3060,16,0,376,1, -50,1328,1,48,1317, -1,49,1323,1,51, -1333,1,63,1349,1, -305,1338,1,66,1355, -1,67,1360,1,68, -1365,1,69,1370,1, -70,1375,1,73,3061, -16,0,376,1,74, -1380,1,328,1429,1, -1048,1470,1,82,3062, -16,0,376,1,1840, -3063,16,0,376,1, -1591,3064,16,0,376, -1,1341,3065,16,0, -376,1,1096,1439,1, -93,1445,1,352,1475, -1,107,3066,16,0, -376,1,1114,1469,1, -118,1481,1,1123,3067, -16,0,376,1,371, -1491,1,1628,3068,16, -0,376,1,375,1502, -1,1882,3069,16,0, -376,1,377,1507,1, -379,1512,1,380,1517, -1,883,3070,16,0, -376,1,373,1535,1, -130,1540,1,143,1545, -1,387,3071,16,0, -376,1,1159,3072,16, -0,376,1,157,1568, -1,1413,3073,16,0, -376,1,1665,3074,16, -0,376,1,412,3075, -16,0,376,1,1377, -3076,16,0,376,1, -172,1595,1,1939,3077, -16,0,376,1,437, -3078,16,0,376,1, -188,1644,1,942,1616, -1,1195,3079,16,0, -376,1,1449,3080,16, -0,376,1,1701,3081, -16,0,376,1,447, -1637,1,205,3082,16, -0,376,1,827,3083, -16,0,376,1,223, -3084,16,0,376,1, -476,1669,1,477,1675, -1,1231,3085,16,0, -376,1,479,1685,1, -480,1690,1,1485,3086, -16,0,376,1,1737, -3087,16,0,376,1, -242,1703,1,478,1708, -1,1001,1713,1,1002, -1718,1,34,3088,19, -365,1,34,3089,5, -84,1,1011,1227,1, -1012,3090,16,0,363, -1,1013,1385,1,262, -1244,1,1267,3091,16, -0,363,1,515,3092, -16,0,363,1,1521, -3093,16,0,363,1, -525,1343,1,2792,3094, -16,0,363,1,283, -1299,1,2299,3095,16, -0,363,1,42,3096, -16,0,363,1,40, -1304,1,44,1310,1, -47,1311,1,1303,3097, -16,0,363,1,1555, -3098,16,0,363,1, -50,1328,1,48,1317, -1,49,1323,1,51, -1333,1,63,1349,1, -305,1338,1,66,1355, -1,67,1360,1,68, -1365,1,69,1370,1, -70,1375,1,73,3099, -16,0,363,1,74, -1380,1,328,1429,1, -1048,1470,1,82,3100, -16,0,363,1,1840, -3101,16,0,363,1, -1591,3102,16,0,363, -1,1341,3103,16,0, -363,1,1096,1439,1, -93,1445,1,352,1475, -1,107,3104,16,0, -363,1,1114,1469,1, -118,1481,1,1123,3105, -16,0,363,1,371, -1491,1,1628,3106,16, -0,363,1,375,1502, -1,1882,3107,16,0, -363,1,377,1507,1, -379,1512,1,380,1517, -1,883,3108,16,0, -363,1,373,1535,1, -130,1540,1,143,1545, -1,387,3109,16,0, -363,1,1159,3110,16, -0,363,1,157,1568, -1,1413,3111,16,0, -363,1,1665,3112,16, -0,363,1,412,3113, -16,0,363,1,1377, -3114,16,0,363,1, -172,1595,1,1939,3115, -16,0,363,1,437, -3116,16,0,363,1, -188,1644,1,942,1616, -1,1195,3117,16,0, -363,1,1449,3118,16, -0,363,1,1701,3119, -16,0,363,1,447, -1637,1,205,1649,1, -827,3120,16,0,363, -1,223,1659,1,476, -1669,1,477,1675,1, -1231,3121,16,0,363, -1,479,1685,1,480, -1690,1,1485,3122,16, -0,363,1,1737,3123, -16,0,363,1,242, -1703,1,478,1708,1, -1001,1713,1,1002,1718, -1,35,3124,19,351, -1,35,3125,5,84, -1,1011,1227,1,1012, -3126,16,0,349,1, -1013,1385,1,262,1244, -1,1267,3127,16,0, -349,1,515,3128,16, -0,349,1,1521,3129, -16,0,349,1,525, -1343,1,2792,3130,16, -0,349,1,283,1299, -1,2299,3131,16,0, -349,1,42,3132,16, -0,349,1,40,1304, -1,44,1310,1,47, -1311,1,1303,3133,16, -0,349,1,1555,3134, -16,0,349,1,50, -1328,1,48,1317,1, -49,1323,1,51,1333, -1,63,1349,1,305, -1338,1,66,1355,1, -67,1360,1,68,1365, -1,69,1370,1,70, -1375,1,73,3135,16, -0,349,1,74,1380, -1,328,1429,1,1048, -1470,1,82,3136,16, -0,349,1,1840,3137, -16,0,349,1,1591, -3138,16,0,349,1, -1341,3139,16,0,349, -1,1096,1439,1,93, -1445,1,352,1475,1, -107,3140,16,0,349, -1,1114,1469,1,118, -1481,1,1123,3141,16, -0,349,1,371,1491, -1,1628,3142,16,0, -349,1,375,1502,1, -1882,3143,16,0,349, -1,377,1507,1,379, -1512,1,380,1517,1, -883,3144,16,0,349, -1,373,1535,1,130, -1540,1,143,1545,1, -387,3145,16,0,349, -1,1159,3146,16,0, -349,1,157,1568,1, -1413,3147,16,0,349, -1,1665,3148,16,0, -349,1,412,3149,16, -0,349,1,1377,3150, -16,0,349,1,172, -1595,1,1939,3151,16, -0,349,1,437,3152, -16,0,349,1,188, -1644,1,942,1616,1, -1195,3153,16,0,349, -1,1449,3154,16,0, -349,1,1701,3155,16, -0,349,1,447,1637, -1,205,1649,1,827, -3156,16,0,349,1, -223,3157,16,0,349, -1,476,1669,1,477, -1675,1,1231,3158,16, -0,349,1,479,1685, -1,480,1690,1,1485, -3159,16,0,349,1, -1737,3160,16,0,349, -1,242,1703,1,478, -1708,1,1001,1713,1, -1002,1718,1,36,3161, -19,239,1,36,3162, -5,94,1,256,3163, -16,0,237,1,1261, -3164,16,0,237,1, -509,3165,16,0,237, -1,1515,3166,16,0, -237,1,2021,843,1, -1775,3167,16,0,237, -1,2029,850,1,2030, -856,1,2031,861,1, -2032,866,1,2033,871, -1,277,3168,16,0, -237,1,2035,877,1, -2037,882,1,2039,887, -1,32,3169,16,0, -237,1,2041,893,1, -2293,3170,16,0,237, -1,2043,899,1,2045, -904,1,41,3171,16, -0,237,1,1297,3172, -16,0,237,1,43, -3173,16,0,237,1, -1803,912,1,1804,3174, -16,0,237,1,299, -3175,16,0,237,1, -52,3176,16,0,237, -1,2318,3177,16,0, -237,1,2075,3178,16, -0,237,1,1574,924, -1,71,3179,16,0, -237,1,76,3180,16, -0,237,1,1834,3181, -16,0,237,1,2337, -3182,16,0,237,1, -79,3183,16,0,237, -1,1335,3184,16,0, -237,1,322,3185,16, -0,237,1,85,3186, -16,0,237,1,89, -3187,16,0,237,1, -346,3188,16,0,237, -1,2105,939,1,2106, -3189,16,0,237,1, -97,3190,16,0,237, -1,1860,946,1,2364, -952,1,102,3191,16, -0,237,1,112,3192, -16,0,237,1,1117, -3193,16,0,237,1, -2786,3194,16,0,237, -1,1873,961,1,1876, -3195,16,0,237,1, -124,3196,16,0,237, -1,2136,968,1,381, -3197,16,0,237,1, -525,3198,16,0,237, -1,137,3199,16,0, -237,1,1901,3200,16, -0,237,1,1153,3201, -16,0,237,1,151, -3202,16,0,237,1, -1407,3203,16,0,237, -1,1659,3204,16,0, -237,1,2413,3205,16, -0,237,1,406,3206, -16,0,237,1,1371, -3207,16,0,237,1, -166,3208,16,0,237, -1,1622,3209,16,0, -237,1,1931,986,1, -1933,3210,16,0,237, -1,431,3211,16,0, -237,1,1585,3212,16, -0,237,1,182,3213, -16,0,237,1,1189, -3214,16,0,237,1, -1443,3215,16,0,237, -1,1695,3216,16,0, -237,1,2198,3217,16, -0,237,1,447,3218, -16,0,237,1,2458, -1001,1,2459,1007,1, -1958,3219,16,0,237, -1,2462,1014,1,1657, -1019,1,2464,1024,1, -199,3220,16,0,237, -1,459,3221,16,0, -237,1,462,3222,16, -0,237,1,217,3223, -16,0,237,1,2227, -1033,1,1225,3224,16, -0,237,1,1479,3225, -16,0,237,1,1731, -3226,16,0,237,1, -1989,1041,1,1990,3227, -16,0,237,1,236, -3228,16,0,237,1, -1756,3229,16,0,237, -1,37,3230,19,260, -1,37,3231,5,94, -1,256,3232,16,0, -258,1,1261,3233,16, -0,258,1,509,3234, -16,0,258,1,1515, -3235,16,0,258,1, -2021,843,1,1775,3236, -16,0,258,1,2029, -850,1,2030,856,1, -2031,861,1,2032,866, -1,2033,871,1,277, -3237,16,0,258,1, -2035,877,1,2037,882, -1,2039,887,1,32, -3238,16,0,258,1, -2041,893,1,2293,3239, -16,0,258,1,2043, -899,1,2045,904,1, -41,3240,16,0,258, -1,1297,3241,16,0, -258,1,43,3242,16, -0,258,1,1803,912, -1,1804,3243,16,0, -258,1,299,3244,16, -0,258,1,52,3245, -16,0,258,1,2318, -3246,16,0,258,1, -2075,3247,16,0,258, -1,1574,924,1,71, -3248,16,0,258,1, -76,3249,16,0,258, -1,1834,3250,16,0, -258,1,2337,3251,16, -0,258,1,79,3252, -16,0,258,1,1335, -3253,16,0,258,1, -322,3254,16,0,258, -1,85,3255,16,0, -258,1,89,3256,16, -0,258,1,346,3257, -16,0,258,1,2105, -939,1,2106,3258,16, -0,258,1,97,3259, -16,0,258,1,1860, -946,1,2364,952,1, -102,3260,16,0,258, -1,112,3261,16,0, -258,1,1117,3262,16, -0,258,1,2786,3263, -16,0,258,1,1873, -961,1,1876,3264,16, -0,258,1,124,3265, -16,0,258,1,2136, -968,1,381,3266,16, -0,258,1,525,3267, -16,0,258,1,137, -3268,16,0,258,1, -1901,3269,16,0,258, -1,1153,3270,16,0, -258,1,151,3271,16, -0,258,1,1407,3272, -16,0,258,1,1659, -3273,16,0,258,1, -2413,3274,16,0,258, -1,406,3275,16,0, -258,1,1371,3276,16, -0,258,1,166,3277, -16,0,258,1,1622, -3278,16,0,258,1, -1931,986,1,1933,3279, -16,0,258,1,431, -3280,16,0,258,1, -1585,3281,16,0,258, -1,182,3282,16,0, -258,1,1189,3283,16, -0,258,1,1443,3284, -16,0,258,1,1695, -3285,16,0,258,1, -2198,3286,16,0,258, -1,447,3287,16,0, -258,1,2458,1001,1, -2459,1007,1,1958,3288, -16,0,258,1,2462, -1014,1,1657,1019,1, -2464,1024,1,199,3289, -16,0,258,1,459, -3290,16,0,258,1, -462,3291,16,0,258, -1,217,3292,16,0, -258,1,2227,1033,1, -1225,3293,16,0,258, -1,1479,3294,16,0, -258,1,1731,3295,16, -0,258,1,1989,1041, -1,1990,3296,16,0, -258,1,236,3297,16, -0,258,1,1756,3298, -16,0,258,1,38, -3299,19,257,1,38, -3300,5,84,1,1011, -1227,1,1012,3301,16, -0,255,1,1013,1385, -1,262,1244,1,1267, -3302,16,0,255,1, -515,3303,16,0,255, -1,1521,3304,16,0, -255,1,525,1343,1, -2792,3305,16,0,255, -1,283,1299,1,2299, -3306,16,0,255,1, -42,3307,16,0,255, -1,40,1304,1,44, -1310,1,47,1311,1, -1303,3308,16,0,255, -1,1555,3309,16,0, -255,1,50,1328,1, -48,1317,1,49,1323, -1,51,1333,1,63, -1349,1,305,1338,1, -66,1355,1,67,1360, -1,68,1365,1,69, -1370,1,70,1375,1, -73,3310,16,0,255, -1,74,1380,1,328, -1429,1,1048,1470,1, -82,3311,16,0,255, -1,1840,3312,16,0, -255,1,1591,3313,16, -0,255,1,1341,3314, -16,0,255,1,1096, -1439,1,93,1445,1, -352,1475,1,107,3315, -16,0,255,1,1114, -1469,1,118,1481,1, -1123,3316,16,0,255, -1,371,1491,1,1628, -3317,16,0,255,1, -375,1502,1,1882,3318, -16,0,255,1,377, -1507,1,379,1512,1, -380,1517,1,883,1523, -1,373,1535,1,130, -1540,1,143,1545,1, -387,3319,16,0,255, -1,1159,3320,16,0, -255,1,157,1568,1, -1413,3321,16,0,255, -1,1665,3322,16,0, -255,1,412,3323,16, -0,255,1,1377,3324, -16,0,255,1,172, -1595,1,1939,3325,16, -0,255,1,437,3326, -16,0,255,1,188, -1644,1,942,1616,1, -1195,3327,16,0,255, -1,1449,3328,16,0, -255,1,1701,3329,16, -0,255,1,447,1637, -1,205,1649,1,827, -1457,1,223,1659,1, -476,1669,1,477,1675, -1,1231,3330,16,0, -255,1,479,1685,1, -480,1690,1,1485,3331, -16,0,255,1,1737, -3332,16,0,255,1, -242,1703,1,478,1708, -1,1001,1713,1,1002, -1718,1,39,3333,19, -245,1,39,3334,5, -84,1,1011,1227,1, -1012,3335,16,0,243, -1,1013,1385,1,262, -1244,1,1267,3336,16, -0,243,1,515,3337, -16,0,243,1,1521, -3338,16,0,243,1, -525,1343,1,2792,3339, -16,0,243,1,283, -1299,1,2299,3340,16, -0,243,1,42,3341, -16,0,243,1,40, -1304,1,44,1310,1, -47,1311,1,1303,3342, -16,0,243,1,1555, -3343,16,0,243,1, -50,1328,1,48,1317, -1,49,1323,1,51, -1333,1,63,1349,1, -305,1338,1,66,1355, -1,67,1360,1,68, -1365,1,69,1370,1, -70,1375,1,73,3344, -16,0,243,1,74, -1380,1,328,1429,1, -1048,1470,1,82,3345, -16,0,243,1,1840, -3346,16,0,243,1, -1591,3347,16,0,243, -1,1341,3348,16,0, -243,1,1096,1439,1, -93,1445,1,352,1475, -1,107,3349,16,0, -243,1,1114,1469,1, -118,1481,1,1123,3350, -16,0,243,1,371, -1491,1,1628,3351,16, -0,243,1,375,1502, -1,1882,3352,16,0, -243,1,377,1507,1, -379,1512,1,380,1517, -1,883,1523,1,373, -1535,1,130,1540,1, -143,1545,1,387,3353, -16,0,243,1,1159, -3354,16,0,243,1, -157,1568,1,1413,3355, -16,0,243,1,1665, -3356,16,0,243,1, -412,3357,16,0,243, -1,1377,3358,16,0, -243,1,172,1595,1, -1939,3359,16,0,243, -1,437,3360,16,0, -243,1,188,1644,1, -942,1616,1,1195,3361, -16,0,243,1,1449, -3362,16,0,243,1, -1701,3363,16,0,243, -1,447,1637,1,205, -1649,1,827,1457,1, -223,1659,1,476,1669, -1,477,1675,1,1231, -3364,16,0,243,1, -479,1685,1,480,1690, -1,1485,3365,16,0, -243,1,1737,3366,16, -0,243,1,242,1703, -1,478,1708,1,1001, -1713,1,1002,1718,1, -40,3367,19,233,1, -40,3368,5,84,1, -1011,1227,1,1012,3369, -16,0,231,1,1013, -1385,1,262,1244,1, -1267,3370,16,0,231, -1,515,3371,16,0, -231,1,1521,3372,16, -0,231,1,525,1343, -1,2792,3373,16,0, -231,1,283,1299,1, -2299,3374,16,0,231, -1,42,3375,16,0, -231,1,40,1304,1, -44,1310,1,47,1311, -1,1303,3376,16,0, -231,1,1555,3377,16, -0,231,1,50,1328, -1,48,1317,1,49, -1323,1,51,1333,1, -63,1349,1,305,1338, -1,66,1355,1,67, -1360,1,68,1365,1, -69,1370,1,70,1375, -1,73,3378,16,0, -231,1,74,1380,1, -328,1429,1,1048,1470, -1,82,3379,16,0, -231,1,1840,3380,16, -0,231,1,1591,3381, -16,0,231,1,1341, -3382,16,0,231,1, -1096,1439,1,93,1445, -1,352,1475,1,107, -3383,16,0,231,1, -1114,1469,1,118,3384, -16,0,231,1,1123, -3385,16,0,231,1, -371,1491,1,1628,3386, -16,0,231,1,375, -1502,1,1882,3387,16, -0,231,1,377,1507, -1,379,1512,1,380, -1517,1,883,3388,16, -0,231,1,373,1535, -1,130,3389,16,0, -231,1,143,3390,16, -0,231,1,387,3391, -16,0,231,1,1159, -3392,16,0,231,1, -157,3393,16,0,231, -1,1413,3394,16,0, -231,1,1665,3395,16, -0,231,1,412,3396, -16,0,231,1,1377, -3397,16,0,231,1, -172,3398,16,0,231, -1,1939,3399,16,0, -231,1,437,3400,16, -0,231,1,188,3401, -16,0,231,1,942, -1616,1,1195,3402,16, -0,231,1,1449,3403, -16,0,231,1,1701, -3404,16,0,231,1, -447,1637,1,205,3405, -16,0,231,1,827, -3406,16,0,231,1, -223,3407,16,0,231, -1,476,1669,1,477, -1675,1,1231,3408,16, -0,231,1,479,1685, -1,480,1690,1,1485, -3409,16,0,231,1, -1737,3410,16,0,231, -1,242,3411,16,0, -231,1,478,1708,1, -1001,1713,1,1002,1718, -1,41,3412,19,188, -1,41,3413,5,84, -1,1011,1227,1,1012, -3414,16,0,186,1, -1013,1385,1,262,1244, -1,1267,3415,16,0, -186,1,515,3416,16, -0,186,1,1521,3417, -16,0,186,1,525, -1343,1,2792,3418,16, -0,186,1,283,1299, -1,2299,3419,16,0, -186,1,42,3420,16, -0,186,1,40,1304, -1,44,1310,1,47, -1311,1,1303,3421,16, -0,186,1,1555,3422, -16,0,186,1,50, -1328,1,48,1317,1, -49,1323,1,51,1333, -1,63,1349,1,305, -1338,1,66,1355,1, -67,1360,1,68,1365, -1,69,1370,1,70, -1375,1,73,3423,16, -0,186,1,74,1380, -1,328,1429,1,1048, -1470,1,82,3424,16, -0,186,1,1840,3425, -16,0,186,1,1591, -3426,16,0,186,1, -1341,3427,16,0,186, -1,1096,1439,1,93, -1445,1,352,1475,1, -107,3428,16,0,186, -1,1114,1469,1,118, -3429,16,0,186,1, -1123,3430,16,0,186, -1,371,1491,1,1628, -3431,16,0,186,1, -375,1502,1,1882,3432, -16,0,186,1,377, -1507,1,379,1512,1, -380,1517,1,883,3433, -16,0,186,1,373, -1535,1,130,3434,16, -0,186,1,143,3435, -16,0,186,1,387, -3436,16,0,186,1, -1159,3437,16,0,186, -1,157,3438,16,0, -186,1,1413,3439,16, -0,186,1,1665,3440, -16,0,186,1,412, -3441,16,0,186,1, -1377,3442,16,0,186, -1,172,3443,16,0, -186,1,1939,3444,16, -0,186,1,437,3445, -16,0,186,1,188, -3446,16,0,186,1, -942,1616,1,1195,3447, -16,0,186,1,1449, -3448,16,0,186,1, -1701,3449,16,0,186, -1,447,1637,1,205, -3450,16,0,186,1, -827,3451,16,0,186, -1,223,3452,16,0, -186,1,476,1669,1, -477,1675,1,1231,3453, -16,0,186,1,479, -1685,1,480,1690,1, -1485,3454,16,0,186, -1,1737,3455,16,0, -186,1,242,3456,16, -0,186,1,478,1708, -1,1001,1713,1,1002, -1718,1,42,3457,19, -440,1,42,3458,5, -38,1,1901,3459,16, -0,438,1,2075,3460, -16,0,438,1,1860, -946,1,1803,912,1, -1804,3461,16,0,438, -1,2413,3462,16,0, -438,1,2198,3463,16, -0,438,1,1873,961, -1,1657,1019,1,1989, -1041,1,1990,3464,16, -0,438,1,1775,3465, -16,0,438,1,32, -3466,16,0,438,1, -2105,939,1,2106,3467, -16,0,438,1,2364, -952,1,2227,1033,1, -2337,3468,16,0,438, -1,2021,843,1,2458, -1001,1,2459,1007,1, -2462,1014,1,2136,968, -1,2464,1024,1,2029, -850,1,2030,856,1, -2031,861,1,2032,866, -1,2033,871,1,2035, -877,1,2037,882,1, -2039,887,1,1931,986, -1,2041,893,1,2043, -899,1,2045,904,1, -1574,924,1,1958,3469, -16,0,438,1,43, -3470,19,532,1,43, -3471,5,25,1,2035, -877,1,2037,882,1, -2039,887,1,2041,893, -1,2227,1033,1,2043, -899,1,1657,1019,1, -1860,946,1,2136,968, -1,2021,843,1,2459, -1007,1,1574,924,1, -2105,3472,16,0,698, -1,1931,986,1,1873, -961,1,2031,861,1, -1803,912,1,1989,3473, -16,0,530,1,2464, -1024,1,2029,850,1, -2030,856,1,2364,952, -1,2032,866,1,2033, -871,1,2045,904,1, -44,3474,19,292,1, -44,3475,5,38,1, -1901,3476,16,0,290, -1,2075,3477,16,0, -290,1,1860,946,1, -1803,912,1,1804,3478, -16,0,290,1,2413, -3479,16,0,290,1, -2198,3480,16,0,290, -1,1873,961,1,1657, -1019,1,1989,1041,1, -1990,3481,16,0,290, -1,1775,3482,16,0, -290,1,32,3483,16, -0,290,1,2105,939, -1,2106,3484,16,0, -290,1,2364,952,1, -2227,1033,1,2337,3485, -16,0,290,1,2021, -843,1,2458,1001,1, -2459,1007,1,2462,1014, -1,2136,968,1,2464, -1024,1,2029,850,1, -2030,856,1,2031,861, -1,2032,866,1,2033, -871,1,2035,877,1, -2037,882,1,2039,887, -1,1931,986,1,2041, -893,1,2043,899,1, -2045,904,1,1574,924, -1,1958,3486,16,0, -290,1,45,3487,19, -325,1,45,3488,5, -39,1,1901,3489,16, -0,355,1,2075,3490, -16,0,355,1,1860, -946,1,1803,912,1, -1804,3491,16,0,355, -1,2413,3492,16,0, -355,1,2198,3493,16, -0,355,1,1873,961, -1,1657,1019,1,1989, -1041,1,1990,3494,16, -0,355,1,1775,3495, -16,0,355,1,32, -3496,16,0,355,1, -2105,939,1,2106,3497, -16,0,355,1,2364, -952,1,2227,1033,1, -2337,3498,16,0,355, -1,2021,843,1,2458, -1001,1,2459,1007,1, -2462,1014,1,2136,968, -1,2464,1024,1,2029, -850,1,2030,856,1, -2031,861,1,2032,866, -1,2033,871,1,2035, -877,1,2037,882,1, -2039,887,1,1931,986, -1,2041,893,1,2043, -899,1,2045,904,1, -1832,3499,16,0,323, -1,1574,924,1,1958, -3500,16,0,355,1, -46,3501,19,794,1, -46,3502,5,38,1, -1901,3503,16,0,792, -1,2075,3504,16,0, -792,1,1860,946,1, -1803,912,1,1804,3505, -16,0,792,1,2413, -3506,16,0,792,1, -2198,3507,16,0,792, -1,1873,961,1,1657, -1019,1,1989,1041,1, -1990,3508,16,0,792, -1,1775,3509,16,0, -792,1,32,3510,16, -0,792,1,2105,939, -1,2106,3511,16,0, -792,1,2364,952,1, -2227,1033,1,2337,3512, -16,0,792,1,2021, -843,1,2458,1001,1, -2459,1007,1,2462,1014, -1,2136,968,1,2464, -1024,1,2029,850,1, -2030,856,1,2031,861, -1,2032,866,1,2033, -871,1,2035,877,1, -2037,882,1,2039,887, -1,1931,986,1,2041, -893,1,2043,899,1, -2045,904,1,1574,924, -1,1958,3513,16,0, -792,1,47,3514,19, -283,1,47,3515,5, -19,1,0,3516,16, -0,281,1,2783,3517, -17,3518,15,3519,4, -50,37,0,71,0, -108,0,111,0,98, -0,97,0,108,0, -70,0,117,0,110, -0,99,0,116,0, -105,0,111,0,110, -0,68,0,101,0, -102,0,105,0,110, -0,105,0,116,0, -105,0,111,0,110, -0,1,-1,1,5, -3520,20,3521,4,52, -71,0,108,0,111, -0,98,0,97,0, -108,0,70,0,117, -0,110,0,99,0, -116,0,105,0,111, -0,110,0,68,0, -101,0,102,0,105, -0,110,0,105,0, -116,0,105,0,111, -0,110,0,95,0, -49,0,1,175,1, -3,1,6,1,5, -3522,22,1,9,1, -2464,1024,1,2767,822, -1,2768,810,1,2822, -3523,17,3524,15,3525, -4,52,37,0,71, -0,108,0,111,0, -98,0,97,0,108, -0,86,0,97,0, -114,0,105,0,97, -0,98,0,108,0, -101,0,68,0,101, -0,99,0,108,0, -97,0,114,0,97, -0,116,0,105,0, -111,0,110,0,1, --1,1,5,3526,20, -3527,4,54,71,0, -108,0,111,0,98, -0,97,0,108,0, -86,0,97,0,114, -0,105,0,97,0, -98,0,108,0,101, -0,68,0,101,0, -99,0,108,0,97, -0,114,0,97,0, -116,0,105,0,111, -0,110,0,95,0, -49,0,1,173,1, -3,1,3,1,2, -3528,22,1,7,1, -2823,3529,16,0,281, -1,2022,3530,16,0, -673,1,2755,816,1, -2834,3531,16,0,281, -1,2459,1007,1,2466, -3532,17,3533,15,3519, -1,-1,1,5,3534, -20,3535,4,52,71, -0,108,0,111,0, -98,0,97,0,108, -0,70,0,117,0, -110,0,99,0,116, -0,105,0,111,0, -110,0,68,0,101, -0,102,0,105,0, -110,0,105,0,116, -0,105,0,111,0, -110,0,95,0,50, -0,1,176,1,3, -1,7,1,6,3536, -22,1,10,1,2764, -3537,16,0,281,1, -2841,3538,17,3539,15, -3540,4,36,37,0, -71,0,108,0,111, -0,98,0,97,0, -108,0,68,0,101, -0,102,0,105,0, -110,0,105,0,116, -0,105,0,111,0, -110,0,115,0,1, --1,1,5,3541,20, -3542,4,38,71,0, -108,0,111,0,98, -0,97,0,108,0, -68,0,101,0,102, -0,105,0,110,0, -105,0,116,0,105, -0,111,0,110,0, -115,0,95,0,52, -0,1,172,1,3, -1,3,1,2,3543, -22,1,6,1,2842, -3544,17,3545,15,3540, -1,-1,1,5,3546, -20,3547,4,38,71, -0,108,0,111,0, -98,0,97,0,108, -0,68,0,101,0, -102,0,105,0,110, -0,105,0,116,0, -105,0,111,0,110, -0,115,0,95,0, -50,0,1,170,1, -3,1,3,1,2, -3548,22,1,4,1, -2843,3549,17,3550,15, -3540,1,-1,1,5, -3551,20,3552,4,38, -71,0,108,0,111, -0,98,0,97,0, -108,0,68,0,101, -0,102,0,105,0, -110,0,105,0,116, -0,105,0,111,0, -110,0,115,0,95, -0,51,0,1,171, -1,3,1,2,1, -1,3553,22,1,5, -1,2844,3554,17,3555, -15,3540,1,-1,1, -5,3556,20,3557,4, -38,71,0,108,0, -111,0,98,0,97, -0,108,0,68,0, -101,0,102,0,105, -0,110,0,105,0, -116,0,105,0,111, -0,110,0,115,0, -95,0,49,0,1, -169,1,3,1,2, -1,1,3558,22,1, -3,1,2649,832,1, -2811,3559,17,3560,15, -3525,1,-1,1,5, -3561,20,3562,4,54, -71,0,108,0,111, -0,98,0,97,0, -108,0,86,0,97, -0,114,0,105,0, -97,0,98,0,108, -0,101,0,68,0, -101,0,99,0,108, -0,97,0,114,0, -97,0,116,0,105, -0,111,0,110,0, -95,0,50,0,1, -174,1,3,1,5, -1,4,3563,22,1, -8,1,48,3564,19, -385,1,48,3565,5, -54,1,0,3566,16, -0,383,1,2075,3567, -16,0,581,1,1860, -946,1,2842,3544,1, -1804,3568,16,0,581, -1,2844,3554,1,2413, -3569,16,0,581,1, -2198,3570,16,0,581, -1,1873,961,1,1657, -1019,1,2030,856,1, -1989,1041,1,1990,3571, -16,0,581,1,2755, -816,1,1775,3572,16, -0,581,1,32,3573, -16,0,581,1,2649, -832,1,2105,939,1, -2106,3574,16,0,581, -1,2764,3575,16,0, -383,1,2841,3538,1, -1574,924,1,2767,822, -1,2768,810,1,2227, -1033,1,2337,3576,16, -0,581,1,2783,3517, -1,1803,912,1,2458, -1001,1,1901,3577,16, -0,581,1,2462,1014, -1,2136,968,1,2464, -1024,1,2029,850,1, -2466,3532,1,2031,861, -1,2032,866,1,2033, -871,1,2035,877,1, -2364,952,1,2039,887, -1,1931,986,1,2041, -893,1,2021,843,1, -2043,899,1,2045,904, -1,2811,3559,1,2834, -3578,16,0,383,1, -2037,882,1,2822,3523, -1,2823,3579,16,0, -383,1,2843,3549,1, -1958,3580,16,0,581, -1,2459,1007,1,49, -3581,19,586,1,49, -3582,5,38,1,1901, -3583,16,0,584,1, -2075,3584,16,0,584, -1,1860,946,1,1803, -912,1,1804,3585,16, -0,584,1,2413,3586, -16,0,584,1,2198, -3587,16,0,584,1, -1873,961,1,1657,1019, -1,1989,1041,1,1990, -3588,16,0,584,1, -1775,3589,16,0,584, -1,32,3590,16,0, -584,1,2105,939,1, -2106,3591,16,0,584, -1,2364,952,1,2227, -1033,1,2337,3592,16, -0,584,1,2021,843, -1,2458,1001,1,2459, -1007,1,2462,1014,1, -2136,968,1,2464,1024, -1,2029,850,1,2030, -856,1,2031,861,1, -2032,866,1,2033,871, -1,2035,877,1,2037, -882,1,2039,887,1, -1931,986,1,2041,893, -1,2043,899,1,2045, -904,1,1574,924,1, -1958,3593,16,0,584, -1,50,3594,19,733, -1,50,3595,5,38, -1,1901,3596,16,0, -731,1,2075,3597,16, -0,731,1,1860,946, -1,1803,912,1,1804, -3598,16,0,731,1, -2413,3599,16,0,731, -1,2198,3600,16,0, -731,1,1873,961,1, -1657,1019,1,1989,1041, -1,1990,3601,16,0, -731,1,1775,3602,16, -0,731,1,32,3603, -16,0,731,1,2105, -939,1,2106,3604,16, -0,731,1,2364,952, -1,2227,1033,1,2337, -3605,16,0,731,1, -2021,843,1,2458,1001, -1,2459,1007,1,2462, -1014,1,2136,968,1, -2464,1024,1,2029,850, -1,2030,856,1,2031, -861,1,2032,866,1, -2033,871,1,2035,877, -1,2037,882,1,2039, -887,1,1931,986,1, -2041,893,1,2043,899, -1,2045,904,1,1574, -924,1,1958,3606,16, -0,731,1,51,3607, -19,127,1,51,3608, -5,58,1,0,3609, -16,0,125,1,2538, -3610,16,0,489,1, -2075,3611,16,0,125, -1,2841,3538,1,2515, -3612,16,0,489,1, -2843,3549,1,10,3613, -16,0,125,1,2413, -3614,16,0,125,1, -2523,3615,16,0,489, -1,2198,3616,16,0, -125,1,1873,961,1, -21,3617,16,0,125, -1,1657,1019,1,2029, -850,1,2030,856,1, -1989,1041,1,1990,3618, -16,0,125,1,2458, -1001,1,2459,1007,1, -1775,3619,16,0,125, -1,32,3620,16,0, -125,1,2105,939,1, -2106,3621,16,0,125, -1,2823,3622,16,0, -125,1,2770,3623,16, -0,125,1,2227,1033, -1,2337,3624,16,0, -125,1,52,3625,16, -0,125,1,2561,3626, -16,0,489,1,2783, -3517,1,1803,912,1, -1804,3627,16,0,125, -1,1901,3628,16,0, -125,1,2462,1014,1, -2136,968,1,2464,1024, -1,1860,946,1,2466, -3532,1,2031,861,1, -2032,866,1,2033,871, -1,2035,877,1,2364, -952,1,2039,887,1, -1931,986,1,2041,893, -1,2021,843,1,2043, -899,1,2045,904,1, -2511,3629,16,0,489, -1,2811,3559,1,2037, -882,1,2822,3523,1, -2842,3544,1,1574,924, -1,2844,3554,1,2582, -3630,16,0,125,1, -1958,3631,16,0,125, -1,52,3632,19,124, -1,52,3633,5,53, -1,0,3634,16,0, -122,1,2075,3635,16, -0,122,1,2841,3538, -1,2842,3544,1,1804, -3636,16,0,122,1, -10,3637,16,0,122, -1,2413,3638,16,0, -122,1,2198,3639,16, -0,122,1,1873,961, -1,21,3640,16,0, -122,1,1657,1019,1, -2029,850,1,2030,856, -1,1989,1041,1,1990, -3641,16,0,122,1, -2459,1007,1,1775,3642, -16,0,122,1,32, -3643,16,0,122,1, -2105,939,1,2106,3644, -16,0,122,1,1574, -924,1,2770,3645,16, -0,122,1,2227,1033, -1,2337,3646,16,0, -122,1,52,3647,16, -0,122,1,2783,3517, -1,1803,912,1,2458, -1001,1,1901,3648,16, -0,122,1,2462,1014, -1,2136,968,1,2464, -1024,1,1860,946,1, -2466,3532,1,2031,861, -1,2032,866,1,2033, -871,1,2035,877,1, -2364,952,1,2039,887, -1,1931,986,1,2041, -893,1,2021,843,1, -2043,899,1,2045,904, -1,2811,3559,1,2037, -882,1,2822,3523,1, -2823,3649,16,0,122, -1,2843,3549,1,2844, -3554,1,2582,3650,16, -0,122,1,1958,3651, -16,0,122,1,53, -3652,19,121,1,53, -3653,5,53,1,0, -3654,16,0,119,1, -2075,3655,16,0,119, -1,2841,3538,1,2842, -3544,1,1804,3656,16, -0,119,1,10,3657, -16,0,119,1,2413, -3658,16,0,119,1, -2198,3659,16,0,119, -1,1873,961,1,21, -3660,16,0,119,1, -1657,1019,1,2029,850, -1,2030,856,1,1989, -1041,1,1990,3661,16, -0,119,1,2459,1007, -1,1775,3662,16,0, -119,1,32,3663,16, -0,119,1,2105,939, -1,2106,3664,16,0, -119,1,1574,924,1, -2770,3665,16,0,119, -1,2227,1033,1,2337, -3666,16,0,119,1, -52,3667,16,0,119, -1,2783,3517,1,1803, -912,1,2458,1001,1, -1901,3668,16,0,119, -1,2462,1014,1,2136, -968,1,2464,1024,1, -1860,946,1,2466,3532, -1,2031,861,1,2032, -866,1,2033,871,1, -2035,877,1,2364,952, -1,2039,887,1,1931, -986,1,2041,893,1, -2021,843,1,2043,899, -1,2045,904,1,2811, -3559,1,2037,882,1, -2822,3523,1,2823,3669, -16,0,119,1,2843, -3549,1,2844,3554,1, -2582,3670,16,0,119, -1,1958,3671,16,0, -119,1,54,3672,19, -118,1,54,3673,5, -55,1,0,3674,16, -0,116,1,2075,3675, -16,0,116,1,2841, -3538,1,2842,3544,1, -1804,3676,16,0,116, -1,10,3677,16,0, -116,1,2413,3678,16, -0,116,1,2198,3679, -16,0,116,1,1873, -961,1,21,3680,16, -0,116,1,1657,1019, -1,2029,850,1,2030, -856,1,1989,1041,1, -1990,3681,16,0,116, -1,2459,1007,1,1775, -3682,16,0,116,1, -32,3683,16,0,116, -1,2105,939,1,2106, -3684,16,0,116,1, -2021,843,1,1574,924, -1,2770,3685,16,0, -116,1,2227,1033,1, -2337,3686,16,0,116, -1,52,3687,16,0, -116,1,2783,3517,1, -1803,912,1,2458,1001, -1,1901,3688,16,0, -116,1,2569,3689,16, -0,483,1,2462,1014, -1,2136,968,1,2464, -1024,1,1860,946,1, -2466,3532,1,2031,861, -1,2032,866,1,2033, -871,1,2035,877,1, -2364,952,1,2039,887, -1,1931,986,1,2041, -893,1,2507,3690,16, -0,483,1,2043,899, -1,2045,904,1,2811, -3559,1,2037,882,1, -2822,3523,1,2823,3691, -16,0,116,1,2843, -3549,1,2844,3554,1, -2582,3692,16,0,116, -1,1958,3693,16,0, -116,1,55,3694,19, -115,1,55,3695,5, -56,1,0,3696,16, -0,113,1,2075,3697, -16,0,113,1,2841, -3538,1,2842,3544,1, -2843,3549,1,10,3698, -16,0,113,1,2413, -3699,16,0,113,1, -2198,3700,16,0,113, -1,2526,3701,16,0, -304,1,1873,961,1, -21,3702,16,0,113, -1,1657,1019,1,2530, -3703,16,0,304,1, -2030,856,1,1989,1041, -1,1990,3704,16,0, -113,1,2458,1001,1, -2459,1007,1,1775,3705, -16,0,113,1,32, -3706,16,0,113,1, -2105,939,1,2106,3707, -16,0,113,1,2770, -3708,16,0,113,1, -2553,3709,16,0,304, -1,2227,1033,1,2337, -3710,16,0,113,1, -52,3711,16,0,113, -1,2783,3517,1,1803, -912,1,1804,3712,16, -0,113,1,1901,3713, -16,0,113,1,2462, -1014,1,2136,968,1, -2464,1024,1,1860,946, -1,2466,3532,1,2031, -861,1,2032,866,1, -2033,871,1,2035,877, -1,2364,952,1,2039, -887,1,1931,986,1, -2041,893,1,2021,843, -1,2043,899,1,2045, -904,1,2811,3559,1, -2029,850,1,2037,882, -1,2822,3523,1,2823, -3714,16,0,113,1, -1574,924,1,2844,3554, -1,2582,3715,16,0, -113,1,1958,3716,16, -0,113,1,56,3717, -19,112,1,56,3718, -5,55,1,0,3719, -16,0,110,1,2075, -3720,16,0,110,1, -2841,3538,1,2842,3544, -1,1804,3721,16,0, -110,1,10,3722,16, -0,110,1,2413,3723, -16,0,110,1,2198, -3724,16,0,110,1, -1873,961,1,21,3725, -16,0,110,1,1657, -1019,1,2029,850,1, -2030,856,1,1989,1041, -1,1990,3726,16,0, -110,1,2459,1007,1, -1775,3727,16,0,110, -1,32,3728,16,0, -110,1,2541,3729,16, -0,525,1,2106,3730, -16,0,110,1,2545, -3731,16,0,525,1, -1574,924,1,2770,3732, -16,0,110,1,2227, -1033,1,2337,3733,16, -0,110,1,52,3734, -16,0,110,1,2783, -3517,1,1803,912,1, -2458,1001,1,1901,3735, -16,0,110,1,2462, -1014,1,2136,968,1, -2464,1024,1,1860,946, -1,2466,3532,1,2031, -861,1,2032,866,1, -2033,871,1,2035,877, -1,2364,952,1,2039, -887,1,1931,986,1, -2041,893,1,2021,843, -1,2043,899,1,2045, -904,1,2811,3559,1, -2037,882,1,2822,3523, -1,2823,3736,16,0, -110,1,2843,3549,1, -2844,3554,1,2105,939, -1,2582,3737,16,0, -110,1,1958,3738,16, -0,110,1,57,3739, -19,109,1,57,3740, -5,53,1,0,3741, -16,0,107,1,2075, -3742,16,0,107,1, -2841,3538,1,2842,3544, -1,1804,3743,16,0, -107,1,10,3744,16, -0,107,1,2413,3745, -16,0,107,1,2198, -3746,16,0,107,1, -1873,961,1,21,3747, -16,0,107,1,1657, -1019,1,2029,850,1, -2030,856,1,1989,1041, -1,1990,3748,16,0, -107,1,2459,1007,1, -1775,3749,16,0,107, -1,32,3750,16,0, -107,1,2105,939,1, -2106,3751,16,0,107, -1,1574,924,1,2770, -3752,16,0,107,1, -2227,1033,1,2337,3753, -16,0,107,1,52, -3754,16,0,107,1, -2783,3517,1,1803,912, -1,2458,1001,1,1901, -3755,16,0,107,1, -2462,1014,1,2136,968, -1,2464,1024,1,1860, -946,1,2466,3532,1, -2031,861,1,2032,866, -1,2033,871,1,2035, -877,1,2364,952,1, -2039,887,1,1931,986, -1,2041,893,1,2021, -843,1,2043,899,1, -2045,904,1,2811,3559, -1,2037,882,1,2822, -3523,1,2823,3756,16, -0,107,1,2843,3549, -1,2844,3554,1,2582, -3757,16,0,107,1, -1958,3758,16,0,107, -1,58,3759,19,396, -1,58,3760,5,30, -1,2536,1750,1,2521, -1767,1,2641,1779,1, -2642,1784,1,2643,1756, -1,2644,1789,1,2645, -1794,1,2646,1799,1, -2647,1762,1,2648,1878, -1,2650,1811,1,2651, -1816,1,2652,1821,1, -2653,1826,1,2654,1831, -1,2655,1836,1,2656, -1841,1,2657,1774,1, -2659,3761,16,0,394, -1,2551,1852,1,2559, -1864,1,2567,1805,1, -2459,1007,1,2464,1024, -1,2575,1846,1,2470, -3762,16,0,394,1, -2580,1858,1,2703,3763, -16,0,394,1,2595, -1871,1,2597,3764,16, -0,394,1,59,3765, -19,393,1,59,3766, -5,30,1,2536,1750, -1,2521,1767,1,2641, -1779,1,2642,1784,1, -2643,1756,1,2644,1789, -1,2645,1794,1,2646, -1799,1,2647,1762,1, -2648,1878,1,2650,1811, -1,2651,1816,1,2652, -1821,1,2653,1826,1, -2654,1831,1,2655,1836, -1,2656,1841,1,2657, -1774,1,2659,3767,16, -0,391,1,2551,1852, -1,2559,1864,1,2567, -1805,1,2459,1007,1, -2464,1024,1,2575,1846, -1,2470,3768,16,0, -391,1,2580,1858,1, -2703,3769,16,0,391, -1,2595,1871,1,2597, -3770,16,0,391,1, -60,3771,19,557,1, -60,3772,5,30,1, -2536,1750,1,2521,1767, -1,2641,1779,1,2642, -1784,1,2643,1756,1, -2644,1789,1,2645,1794, -1,2646,1799,1,2647, -1762,1,2648,1878,1, -2650,1811,1,2651,1816, -1,2652,1821,1,2653, -1826,1,2654,1831,1, -2655,1836,1,2656,1841, -1,2657,1774,1,2659, -3773,16,0,555,1, -2551,1852,1,2559,1864, -1,2567,1805,1,2459, -1007,1,2464,1024,1, -2575,1846,1,2470,3774, -16,0,555,1,2580, -1858,1,2703,3775,16, -0,555,1,2595,1871, -1,2597,3776,16,0, -555,1,61,3777,19, -433,1,61,3778,5, -30,1,2536,1750,1, -2521,1767,1,2641,1779, -1,2642,1784,1,2643, -1756,1,2644,1789,1, -2645,1794,1,2646,1799, -1,2647,1762,1,2648, -1878,1,2650,1811,1, -2651,1816,1,2652,1821, -1,2653,1826,1,2654, -1831,1,2655,1836,1, -2656,1841,1,2657,1774, -1,2659,3779,16,0, -431,1,2551,1852,1, -2559,1864,1,2567,1805, -1,2459,1007,1,2464, -1024,1,2575,1846,1, -2470,3780,16,0,431, -1,2580,1858,1,2703, -3781,16,0,431,1, -2595,1871,1,2597,3782, -16,0,431,1,62, -3783,19,553,1,62, -3784,5,30,1,2536, -1750,1,2521,1767,1, -2641,1779,1,2642,1784, -1,2643,1756,1,2644, -1789,1,2645,1794,1, -2646,1799,1,2647,1762, -1,2648,1878,1,2650, -1811,1,2651,1816,1, -2652,1821,1,2653,1826, -1,2654,1831,1,2655, -1836,1,2656,1841,1, -2657,1774,1,2659,3785, -16,0,551,1,2551, -1852,1,2559,1864,1, -2567,1805,1,2459,1007, -1,2464,1024,1,2575, -1846,1,2470,3786,16, -0,551,1,2580,1858, -1,2703,3787,16,0, -551,1,2595,1871,1, -2597,3788,16,0,551, -1,63,3789,19,666, -1,63,3790,5,30, -1,2536,1750,1,2521, -1767,1,2641,1779,1, -2642,1784,1,2643,1756, -1,2644,1789,1,2645, -1794,1,2646,1799,1, -2647,1762,1,2648,1878, -1,2650,1811,1,2651, -1816,1,2652,1821,1, -2653,1826,1,2654,1831, -1,2655,1836,1,2656, -1841,1,2657,1774,1, -2659,3791,16,0,664, -1,2551,1852,1,2559, -1864,1,2567,1805,1, -2459,1007,1,2464,1024, -1,2575,1846,1,2470, -3792,16,0,664,1, -2580,1858,1,2703,3793, -16,0,664,1,2595, -1871,1,2597,3794,16, -0,664,1,64,3795, -19,426,1,64,3796, -5,30,1,2536,1750, -1,2521,1767,1,2641, -1779,1,2642,1784,1, -2643,1756,1,2644,1789, -1,2645,1794,1,2646, -1799,1,2647,1762,1, -2648,1878,1,2650,1811, -1,2651,1816,1,2652, -1821,1,2653,1826,1, -2654,1831,1,2655,1836, -1,2656,1841,1,2657, -1774,1,2659,3797,16, -0,424,1,2551,1852, -1,2559,1864,1,2567, -1805,1,2459,1007,1, -2464,1024,1,2575,1846, -1,2470,3798,16,0, -424,1,2580,1858,1, -2703,3799,16,0,424, -1,2595,1871,1,2597, -3800,16,0,424,1, -65,3801,19,390,1, -65,3802,5,30,1, -2536,1750,1,2521,1767, -1,2641,1779,1,2642, -1784,1,2643,1756,1, -2644,1789,1,2645,1794, -1,2646,1799,1,2647, -1762,1,2648,1878,1, -2650,1811,1,2651,1816, -1,2652,1821,1,2653, -1826,1,2654,1831,1, -2655,1836,1,2656,1841, -1,2657,1774,1,2659, -3803,16,0,388,1, -2551,1852,1,2559,1864, -1,2567,1805,1,2459, -1007,1,2464,1024,1, -2575,1846,1,2470,3804, -16,0,388,1,2580, -1858,1,2703,3805,16, -0,388,1,2595,1871, -1,2597,3806,16,0, -388,1,66,3807,19, -778,1,66,3808,5, -30,1,2536,1750,1, -2521,1767,1,2641,1779, -1,2642,1784,1,2643, -1756,1,2644,1789,1, -2645,1794,1,2646,1799, -1,2647,1762,1,2648, -1878,1,2650,1811,1, -2651,1816,1,2652,1821, -1,2653,1826,1,2654, -1831,1,2655,1836,1, -2656,1841,1,2657,1774, -1,2659,3809,16,0, -776,1,2551,1852,1, -2559,1864,1,2567,1805, -1,2459,1007,1,2464, -1024,1,2575,1846,1, -2470,3810,16,0,776, -1,2580,1858,1,2703, -3811,16,0,776,1, -2595,1871,1,2597,3812, -16,0,776,1,67, -3813,19,475,1,67, -3814,5,30,1,2536, -1750,1,2521,1767,1, -2641,1779,1,2642,1784, -1,2643,1756,1,2644, -1789,1,2645,1794,1, -2646,1799,1,2647,1762, -1,2648,1878,1,2650, -1811,1,2651,1816,1, -2652,1821,1,2653,1826, -1,2654,1831,1,2655, -1836,1,2656,1841,1, -2657,1774,1,2659,3815, -16,0,473,1,2551, -1852,1,2559,1864,1, -2567,1805,1,2459,1007, -1,2464,1024,1,2575, -1846,1,2470,3816,16, -0,473,1,2580,1858, -1,2703,3817,16,0, -473,1,2595,1871,1, -2597,3818,16,0,473, -1,68,3819,19,472, -1,68,3820,5,30, -1,2536,1750,1,2521, -1767,1,2641,1779,1, -2642,1784,1,2643,1756, -1,2644,1789,1,2645, -1794,1,2646,1799,1, -2647,1762,1,2648,1878, -1,2650,1811,1,2651, -1816,1,2652,1821,1, -2653,1826,1,2654,1831, -1,2655,1836,1,2656, -1841,1,2657,1774,1, -2659,3821,16,0,470, -1,2551,1852,1,2559, -1864,1,2567,1805,1, -2459,1007,1,2464,1024, -1,2575,1846,1,2470, -3822,16,0,470,1, -2580,1858,1,2703,3823, -16,0,470,1,2595, -1871,1,2597,3824,16, -0,470,1,69,3825, -19,405,1,69,3826, -5,30,1,2536,1750, -1,2521,1767,1,2641, -1779,1,2642,1784,1, -2643,1756,1,2644,1789, -1,2645,1794,1,2646, -1799,1,2647,1762,1, -2648,1878,1,2650,1811, -1,2651,1816,1,2652, -1821,1,2653,1826,1, -2654,1831,1,2655,1836, -1,2656,1841,1,2657, -1774,1,2659,3827,16, -0,403,1,2551,1852, -1,2559,1864,1,2567, -1805,1,2459,1007,1, -2464,1024,1,2575,1846, -1,2470,3828,16,0, -403,1,2580,1858,1, -2703,3829,16,0,403, -1,2595,1871,1,2597, -3830,16,0,403,1, -70,3831,19,402,1, -70,3832,5,30,1, -2536,1750,1,2521,1767, -1,2641,1779,1,2642, -1784,1,2643,1756,1, -2644,1789,1,2645,1794, -1,2646,1799,1,2647, -1762,1,2648,1878,1, -2650,1811,1,2651,1816, -1,2652,1821,1,2653, -1826,1,2654,1831,1, -2655,1836,1,2656,1841, -1,2657,1774,1,2659, -3833,16,0,400,1, -2551,1852,1,2559,1864, -1,2567,1805,1,2459, -1007,1,2464,1024,1, -2575,1846,1,2470,3834, -16,0,400,1,2580, -1858,1,2703,3835,16, -0,400,1,2595,1871, -1,2597,3836,16,0, -400,1,71,3837,19, -399,1,71,3838,5, -30,1,2536,1750,1, -2521,1767,1,2641,1779, -1,2642,1784,1,2643, -1756,1,2644,1789,1, -2645,1794,1,2646,1799, -1,2647,1762,1,2648, -1878,1,2650,1811,1, -2651,1816,1,2652,1821, -1,2653,1826,1,2654, -1831,1,2655,1836,1, -2656,1841,1,2657,1774, -1,2659,3839,16,0, -397,1,2551,1852,1, -2559,1864,1,2567,1805, -1,2459,1007,1,2464, -1024,1,2575,1846,1, -2470,3840,16,0,397, -1,2580,1858,1,2703, -3841,16,0,397,1, -2595,1871,1,2597,3842, -16,0,397,1,72, -3843,19,469,1,72, -3844,5,30,1,2536, -1750,1,2521,1767,1, -2641,1779,1,2642,1784, -1,2643,1756,1,2644, -1789,1,2645,1794,1, -2646,1799,1,2647,1762, -1,2648,1878,1,2650, -1811,1,2651,1816,1, -2652,1821,1,2653,1826, -1,2654,1831,1,2655, -1836,1,2656,1841,1, -2657,1774,1,2659,3845, -16,0,467,1,2551, -1852,1,2559,1864,1, -2567,1805,1,2459,1007, -1,2464,1024,1,2575, -1846,1,2470,3846,16, -0,467,1,2580,1858, -1,2703,3847,16,0, -467,1,2595,1871,1, -2597,3848,16,0,467, -1,73,3849,19,466, -1,73,3850,5,30, -1,2536,1750,1,2521, -1767,1,2641,1779,1, -2642,1784,1,2643,1756, -1,2644,1789,1,2645, -1794,1,2646,1799,1, -2647,1762,1,2648,1878, -1,2650,1811,1,2651, -1816,1,2652,1821,1, -2653,1826,1,2654,1831, -1,2655,1836,1,2656, -1841,1,2657,1774,1, -2659,3851,16,0,464, -1,2551,1852,1,2559, -1864,1,2567,1805,1, -2459,1007,1,2464,1024, -1,2575,1846,1,2470, -3852,16,0,464,1, -2580,1858,1,2703,3853, -16,0,464,1,2595, -1871,1,2597,3854,16, -0,464,1,74,3855, -19,463,1,74,3856, -5,30,1,2536,1750, -1,2521,1767,1,2641, -1779,1,2642,1784,1, -2643,1756,1,2644,1789, -1,2645,1794,1,2646, -1799,1,2647,1762,1, -2648,1878,1,2650,1811, -1,2651,1816,1,2652, -1821,1,2653,1826,1, -2654,1831,1,2655,1836, -1,2656,1841,1,2657, -1774,1,2659,3857,16, -0,461,1,2551,1852, -1,2559,1864,1,2567, -1805,1,2459,1007,1, -2464,1024,1,2575,1846, -1,2470,3858,16,0, -461,1,2580,1858,1, -2703,3859,16,0,461, -1,2595,1871,1,2597, -3860,16,0,461,1, -75,3861,19,449,1, -75,3862,5,30,1, -2536,1750,1,2521,1767, -1,2641,1779,1,2642, -1784,1,2643,1756,1, -2644,1789,1,2645,1794, -1,2646,1799,1,2647, -1762,1,2648,1878,1, -2650,1811,1,2651,1816, -1,2652,1821,1,2653, -1826,1,2654,1831,1, -2655,1836,1,2656,1841, -1,2657,1774,1,2659, -3863,16,0,447,1, -2551,1852,1,2559,1864, -1,2567,1805,1,2459, -1007,1,2464,1024,1, -2575,1846,1,2470,3864, -16,0,447,1,2580, -1858,1,2703,3865,16, -0,447,1,2595,1871, -1,2597,3866,16,0, -447,1,76,3867,19, -570,1,76,3868,5, -30,1,2536,1750,1, -2521,1767,1,2641,1779, -1,2642,1784,1,2643, -1756,1,2644,1789,1, -2645,1794,1,2646,1799, -1,2647,1762,1,2648, -1878,1,2650,1811,1, -2651,1816,1,2652,1821, -1,2653,1826,1,2654, -1831,1,2655,1836,1, -2656,1841,1,2657,1774, -1,2659,3869,16,0, -568,1,2551,1852,1, -2559,1864,1,2567,1805, -1,2459,1007,1,2464, -1024,1,2575,1846,1, -2470,3870,16,0,568, -1,2580,1858,1,2703, -3871,16,0,568,1, -2595,1871,1,2597,3872, -16,0,568,1,77, -3873,19,445,1,77, -3874,5,30,1,2536, -1750,1,2521,1767,1, -2641,1779,1,2642,1784, -1,2643,1756,1,2644, -1789,1,2645,1794,1, -2646,1799,1,2647,1762, -1,2648,1878,1,2650, -1811,1,2651,1816,1, -2652,1821,1,2653,1826, -1,2654,1831,1,2655, -1836,1,2656,1841,1, -2657,1774,1,2659,3875, -16,0,443,1,2551, -1852,1,2559,1864,1, -2567,1805,1,2459,1007, -1,2464,1024,1,2575, -1846,1,2470,3876,16, -0,443,1,2580,1858, -1,2703,3877,16,0, -443,1,2595,1871,1, -2597,3878,16,0,443, -1,78,3879,19,566, -1,78,3880,5,30, -1,2536,1750,1,2521, -1767,1,2641,1779,1, -2642,1784,1,2643,1756, -1,2644,1789,1,2645, -1794,1,2646,1799,1, -2647,1762,1,2648,1878, -1,2650,1811,1,2651, -1816,1,2652,1821,1, -2653,1826,1,2654,1831, -1,2655,1836,1,2656, -1841,1,2657,1774,1, -2659,3881,16,0,564, -1,2551,1852,1,2559, -1864,1,2567,1805,1, -2459,1007,1,2464,1024, -1,2575,1846,1,2470, -3882,16,0,564,1, -2580,1858,1,2703,3883, -16,0,564,1,2595, -1871,1,2597,3884,16, -0,564,1,79,3885, -19,563,1,79,3886, -5,30,1,2536,1750, -1,2521,1767,1,2641, -1779,1,2642,1784,1, -2643,1756,1,2644,1789, -1,2645,1794,1,2646, -1799,1,2647,1762,1, -2648,1878,1,2650,1811, -1,2651,1816,1,2652, -1821,1,2653,1826,1, -2654,1831,1,2655,1836, -1,2656,1841,1,2657, -1774,1,2659,3887,16, -0,561,1,2551,1852, -1,2559,1864,1,2567, -1805,1,2459,1007,1, -2464,1024,1,2575,1846, -1,2470,3888,16,0, -561,1,2580,1858,1, -2703,3889,16,0,561, -1,2595,1871,1,2597, -3890,16,0,561,1, -80,3891,19,436,1, -80,3892,5,30,1, -2536,1750,1,2521,1767, -1,2641,1779,1,2642, -1784,1,2643,1756,1, -2644,1789,1,2645,1794, -1,2646,1799,1,2647, -1762,1,2648,1878,1, -2650,1811,1,2651,1816, -1,2652,1821,1,2653, -1826,1,2654,1831,1, -2655,1836,1,2656,1841, -1,2657,1774,1,2659, -3893,16,0,434,1, -2551,1852,1,2559,1864, -1,2567,1805,1,2459, -1007,1,2464,1024,1, -2575,1846,1,2470,3894, -16,0,434,1,2580, -1858,1,2703,3895,16, -0,434,1,2595,1871, -1,2597,3896,16,0, -434,1,81,3897,19, -423,1,81,3898,5, -30,1,2536,1750,1, -2521,1767,1,2641,1779, -1,2642,1784,1,2643, -1756,1,2644,1789,1, -2645,1794,1,2646,1799, -1,2647,1762,1,2648, -1878,1,2650,1811,1, -2651,1816,1,2652,1821, -1,2653,1826,1,2654, -1831,1,2655,1836,1, -2656,1841,1,2657,1774, -1,2659,3899,16,0, -421,1,2551,1852,1, -2559,1864,1,2567,1805, -1,2459,1007,1,2464, -1024,1,2575,1846,1, -2470,3900,16,0,421, -1,2580,1858,1,2703, -3901,16,0,421,1, -2595,1871,1,2597,3902, -16,0,421,1,82, -3903,19,460,1,82, -3904,5,30,1,2536, -1750,1,2521,1767,1, -2641,1779,1,2642,1784, -1,2643,1756,1,2644, -1789,1,2645,1794,1, -2646,1799,1,2647,1762, -1,2648,1878,1,2650, -1811,1,2651,1816,1, -2652,1821,1,2653,1826, -1,2654,1831,1,2655, -1836,1,2656,1841,1, -2657,1774,1,2659,3905, -16,0,458,1,2551, -1852,1,2559,1864,1, -2567,1805,1,2459,1007, -1,2464,1024,1,2575, -1846,1,2470,3906,16, -0,458,1,2580,1858, -1,2703,3907,16,0, -458,1,2595,1871,1, -2597,3908,16,0,458, -1,83,3909,19,420, -1,83,3910,5,30, -1,2536,1750,1,2521, -1767,1,2641,1779,1, -2642,1784,1,2643,1756, -1,2644,1789,1,2645, -1794,1,2646,1799,1, -2647,1762,1,2648,1878, -1,2650,1811,1,2651, -1816,1,2652,1821,1, -2653,1826,1,2654,1831, -1,2655,1836,1,2656, -1841,1,2657,1774,1, -2659,3911,16,0,418, -1,2551,1852,1,2559, -1864,1,2567,1805,1, -2459,1007,1,2464,1024, -1,2575,1846,1,2470, -3912,16,0,418,1, -2580,1858,1,2703,3913, -16,0,418,1,2595, -1871,1,2597,3914,16, -0,418,1,84,3915, -19,417,1,84,3916, -5,30,1,2536,1750, -1,2521,1767,1,2641, -1779,1,2642,1784,1, -2643,1756,1,2644,1789, -1,2645,1794,1,2646, -1799,1,2647,1762,1, -2648,1878,1,2650,1811, -1,2651,1816,1,2652, -1821,1,2653,1826,1, -2654,1831,1,2655,1836, -1,2656,1841,1,2657, -1774,1,2659,3917,16, -0,415,1,2551,1852, -1,2559,1864,1,2567, -1805,1,2459,1007,1, -2464,1024,1,2575,1846, -1,2470,3918,16,0, -415,1,2580,1858,1, -2703,3919,16,0,415, -1,2595,1871,1,2597, -3920,16,0,415,1, -85,3921,19,578,1, -85,3922,5,30,1, -2536,1750,1,2521,1767, -1,2641,1779,1,2642, -1784,1,2643,1756,1, -2644,1789,1,2645,1794, -1,2646,1799,1,2647, -1762,1,2648,1878,1, -2650,1811,1,2651,1816, -1,2652,1821,1,2653, -1826,1,2654,1831,1, -2655,1836,1,2656,1841, -1,2657,1774,1,2659, -3923,16,0,576,1, -2551,1852,1,2559,1864, -1,2567,1805,1,2459, -1007,1,2464,1024,1, -2575,1846,1,2470,3924, -16,0,576,1,2580, -1858,1,2703,3925,16, -0,576,1,2595,1871, -1,2597,3926,16,0, -576,1,86,3927,19, -452,1,86,3928,5, -30,1,2536,1750,1, -2521,1767,1,2641,1779, -1,2642,1784,1,2643, -1756,1,2644,1789,1, -2645,1794,1,2646,1799, -1,2647,1762,1,2648, -1878,1,2650,1811,1, -2651,1816,1,2652,1821, -1,2653,1826,1,2654, -1831,1,2655,1836,1, -2656,1841,1,2657,1774, -1,2659,3929,16,0, -450,1,2551,1852,1, -2559,1864,1,2567,1805, -1,2459,1007,1,2464, -1024,1,2575,1846,1, -2470,3930,16,0,450, -1,2580,1858,1,2703, -3931,16,0,450,1, -2595,1871,1,2597,3932, -16,0,450,1,87, -3933,19,560,1,87, -3934,5,30,1,2536, -1750,1,2521,1767,1, -2641,1779,1,2642,1784, -1,2643,1756,1,2644, -1789,1,2645,1794,1, -2646,1799,1,2647,1762, -1,2648,1878,1,2650, -1811,1,2651,1816,1, -2652,1821,1,2653,1826, -1,2654,1831,1,2655, -1836,1,2656,1841,1, -2657,1774,1,2659,3935, -16,0,558,1,2551, -1852,1,2559,1864,1, -2567,1805,1,2459,1007, -1,2464,1024,1,2575, -1846,1,2470,3936,16, -0,558,1,2580,1858, -1,2703,3937,16,0, -558,1,2595,1871,1, -2597,3938,16,0,558, -1,88,3939,19,414, -1,88,3940,5,30, -1,2536,1750,1,2521, -1767,1,2641,1779,1, -2642,1784,1,2643,1756, -1,2644,1789,1,2645, -1794,1,2646,1799,1, -2647,1762,1,2648,1878, -1,2650,1811,1,2651, -1816,1,2652,1821,1, -2653,1826,1,2654,1831, -1,2655,1836,1,2656, -1841,1,2657,1774,1, -2659,3941,16,0,412, -1,2551,1852,1,2559, -1864,1,2567,1805,1, -2459,1007,1,2464,1024, -1,2575,1846,1,2470, -3942,16,0,412,1, -2580,1858,1,2703,3943, -16,0,412,1,2595, -1871,1,2597,3944,16, -0,412,1,89,3945, -19,408,1,89,3946, -5,30,1,2536,1750, -1,2521,1767,1,2641, -1779,1,2642,1784,1, -2643,1756,1,2644,1789, -1,2645,1794,1,2646, -1799,1,2647,1762,1, -2648,1878,1,2650,1811, -1,2651,1816,1,2652, -1821,1,2653,1826,1, -2654,1831,1,2655,1836, -1,2656,1841,1,2657, -1774,1,2659,3947,16, -0,406,1,2551,1852, -1,2559,1864,1,2567, -1805,1,2459,1007,1, -2464,1024,1,2575,1846, -1,2470,3948,16,0, -406,1,2580,1858,1, -2703,3949,16,0,406, -1,2595,1871,1,2597, -3950,16,0,406,1, -90,3951,19,411,1, -90,3952,5,30,1, -2536,1750,1,2521,1767, -1,2641,1779,1,2642, -1784,1,2643,1756,1, -2644,1789,1,2645,1794, -1,2646,1799,1,2647, -1762,1,2648,1878,1, -2650,1811,1,2651,1816, -1,2652,1821,1,2653, -1826,1,2654,1831,1, -2655,1836,1,2656,1841, -1,2657,1774,1,2659, -3953,16,0,409,1, -2551,1852,1,2559,1864, -1,2567,1805,1,2459, -1007,1,2464,1024,1, -2575,1846,1,2470,3954, -16,0,409,1,2580, -1858,1,2703,3955,16, -0,409,1,2595,1871, -1,2597,3956,16,0, -409,1,91,3957,19, -768,1,91,3958,5, -30,1,2536,1750,1, -2521,1767,1,2641,1779, -1,2642,1784,1,2643, -1756,1,2644,1789,1, -2645,1794,1,2646,1799, -1,2647,1762,1,2648, -1878,1,2650,1811,1, -2651,1816,1,2652,1821, -1,2653,1826,1,2654, -1831,1,2655,1836,1, -2656,1841,1,2657,1774, -1,2659,3959,16,0, -766,1,2551,1852,1, -2559,1864,1,2567,1805, -1,2459,1007,1,2464, -1024,1,2575,1846,1, -2470,3960,16,0,766, -1,2580,1858,1,2703, -3961,16,0,766,1, -2595,1871,1,2597,3962, -16,0,766,1,92, -3963,19,456,1,92, -3964,5,30,1,2536, -1750,1,2521,1767,1, -2641,1779,1,2642,1784, -1,2643,1756,1,2644, -1789,1,2645,1794,1, -2646,1799,1,2647,1762, -1,2648,1878,1,2650, -1811,1,2651,1816,1, -2652,1821,1,2653,1826, -1,2654,1831,1,2655, -1836,1,2656,1841,1, -2657,1774,1,2659,3965, -16,0,454,1,2551, -1852,1,2559,1864,1, -2567,1805,1,2459,1007, -1,2464,1024,1,2575, -1846,1,2470,3966,16, -0,454,1,2580,1858, -1,2703,3967,16,0, -454,1,2595,1871,1, -2597,3968,16,0,454, -1,93,3969,19,133, -1,93,3970,5,129, -1,0,3971,16,0, -789,1,1,2244,1, -2,2250,1,3,2255, -1,4,2260,1,5, -2265,1,6,2270,1, -7,2275,1,8,3972, -16,0,131,1,1515, -3973,16,0,181,1, -2021,843,1,2022,3974, -16,0,583,1,256, -3975,16,0,189,1, -2527,3976,16,0,311, -1,18,3977,16,0, -138,1,2027,3978,16, -0,591,1,2029,850, -1,2030,856,1,2031, -861,1,2032,866,1, -2786,3979,16,0,189, -1,277,3980,16,0, -189,1,2035,877,1, -2037,882,1,2039,887, -1,32,3981,16,0, -181,1,2041,893,1, -2293,3982,16,0,189, -1,2043,899,1,2045, -904,1,41,3983,16, -0,189,1,1297,3984, -16,0,181,1,43, -3985,16,0,189,1, -46,3986,16,0,194, -1,1804,3987,16,0, -181,1,299,3988,16, -0,189,1,2811,3559, -1,52,3989,16,0, -181,1,509,3990,16, -0,189,1,2318,3991, -16,0,181,1,2822, -3523,1,62,3992,16, -0,218,1,65,3993, -16,0,220,1,2075, -3994,16,0,181,1, -1574,924,1,71,3995, -16,0,189,1,1775, -3996,16,0,181,1, -76,3997,16,0,189, -1,1834,3998,16,0, -181,1,2337,3999,16, -0,181,1,79,4000, -16,0,189,1,1335, -4001,16,0,181,1, -2842,3544,1,2843,3549, -1,2844,3554,1,85, -4002,16,0,189,1, -1261,4003,16,0,181, -1,89,4004,16,0, -189,1,2033,871,1, -322,4005,16,0,189, -1,97,4006,16,0, -189,1,2106,4007,16, -0,181,1,102,4008, -16,0,189,1,1860, -946,1,1803,912,1, -2364,952,1,346,4009, -16,0,189,1,1113, -4010,16,0,173,1, -2783,3517,1,112,4011, -16,0,189,1,1117, -4012,16,0,181,1, -1371,4013,16,0,181, -1,1876,4014,16,0, -181,1,372,4015,16, -0,621,1,374,4016, -16,0,623,1,124, -4017,16,0,189,1, -376,4018,16,0,625, -1,378,4019,16,0, -627,1,2136,968,1, -381,4020,16,0,189, -1,525,4021,16,0, -189,1,137,4022,16, -0,189,1,1901,4023, -16,0,181,1,2025, -4024,16,0,587,1, -1153,4025,16,0,181, -1,151,4026,16,0, -189,1,1407,4027,16, -0,181,1,1659,4028, -16,0,181,1,2413, -4029,16,0,181,1, -406,4030,16,0,189, -1,2512,4031,16,0, -490,1,2105,939,1, -166,4032,16,0,189, -1,1622,4033,16,0, -189,1,2841,3538,1, -1931,986,1,1873,961, -1,431,4034,16,0, -189,1,1585,4035,16, -0,189,1,182,4036, -16,0,189,1,1189, -4037,16,0,181,1, -1443,4038,16,0,181, -1,1695,4039,16,0, -181,1,2198,4040,16, -0,181,1,2542,4041, -16,0,644,1,447, -4042,16,0,189,1, -2458,1001,1,2459,1007, -1,1958,4043,16,0, -181,1,2462,1014,1, -1657,1019,1,2464,1024, -1,2466,3532,1,459, -4044,16,0,189,1, -2468,4045,16,0,386, -1,462,4046,16,0, -189,1,199,4047,16, -0,189,1,217,4048, -16,0,189,1,2227, -1033,1,1225,4049,16, -0,181,1,1479,4050, -16,0,181,1,1731, -4051,16,0,189,1, -1989,1041,1,1990,4052, -16,0,181,1,236, -4053,16,0,189,1, -1933,4054,16,0,181, -1,2823,4055,16,0, -789,1,2508,4056,16, -0,484,1,1756,4057, -16,0,181,1,94, -4058,19,746,1,94, -4059,5,95,1,256, -4060,16,0,744,1, -1261,4061,16,0,744, -1,509,4062,16,0, -744,1,1515,4063,16, -0,744,1,2021,843, -1,1775,4064,16,0, -744,1,2029,850,1, -2030,856,1,2031,861, -1,2032,866,1,2033, -871,1,277,4065,16, -0,744,1,2035,877, -1,2037,882,1,2039, -887,1,32,4066,16, -0,744,1,2041,893, -1,2293,4067,16,0, -744,1,2043,899,1, -2045,904,1,41,4068, -16,0,744,1,1297, -4069,16,0,744,1, -43,4070,16,0,744, -1,1803,912,1,1804, -4071,16,0,744,1, -299,4072,16,0,744, -1,52,4073,16,0, -744,1,2318,4074,16, -0,744,1,62,4075, -16,0,744,1,2075, -4076,16,0,744,1, -1574,924,1,71,4077, -16,0,744,1,76, -4078,16,0,744,1, -1834,4079,16,0,744, -1,2337,4080,16,0, -744,1,79,4081,16, -0,744,1,1335,4082, -16,0,744,1,322, -4083,16,0,744,1, -85,4084,16,0,744, -1,89,4085,16,0, -744,1,346,4086,16, -0,744,1,2105,939, -1,2106,4087,16,0, -744,1,97,4088,16, -0,744,1,1860,946, -1,2364,952,1,102, -4089,16,0,744,1, -112,4090,16,0,744, -1,1117,4091,16,0, -744,1,2786,4092,16, -0,744,1,1873,961, -1,1876,4093,16,0, -744,1,124,4094,16, -0,744,1,2136,968, -1,381,4095,16,0, -744,1,525,4096,16, -0,744,1,137,4097, -16,0,744,1,1901, -4098,16,0,744,1, -1153,4099,16,0,744, -1,151,4100,16,0, -744,1,1407,4101,16, -0,744,1,1659,4102, -16,0,744,1,2413, -4103,16,0,744,1, -406,4104,16,0,744, -1,1371,4105,16,0, -744,1,166,4106,16, -0,744,1,1622,4107, -16,0,744,1,1931, -986,1,1933,4108,16, -0,744,1,431,4109, -16,0,744,1,1585, -4110,16,0,744,1, -182,4111,16,0,744, -1,1189,4112,16,0, -744,1,1443,4113,16, -0,744,1,1695,4114, -16,0,744,1,2198, -4115,16,0,744,1, -447,4116,16,0,744, -1,2458,1001,1,2459, -1007,1,1958,4117,16, -0,744,1,2462,1014, -1,1657,1019,1,2464, -1024,1,199,4118,16, -0,744,1,459,4119, -16,0,744,1,462, -4120,16,0,744,1, -217,4121,16,0,744, -1,2227,1033,1,1225, -4122,16,0,744,1, -1479,4123,16,0,744, -1,1731,4124,16,0, -744,1,1989,1041,1, -1990,4125,16,0,744, -1,236,4126,16,0, -744,1,1756,4127,16, -0,744,1,95,4128, -19,743,1,95,4129, -5,95,1,256,4130, -16,0,741,1,1261, -4131,16,0,741,1, -509,4132,16,0,741, -1,1515,4133,16,0, -741,1,2021,843,1, -1775,4134,16,0,741, -1,2029,850,1,2030, -856,1,2031,861,1, -2032,866,1,2033,871, -1,277,4135,16,0, -741,1,2035,877,1, -2037,882,1,2039,887, -1,32,4136,16,0, -741,1,2041,893,1, -2293,4137,16,0,741, -1,2043,899,1,2045, -904,1,41,4138,16, -0,741,1,1297,4139, -16,0,741,1,43, -4140,16,0,741,1, -1803,912,1,1804,4141, -16,0,741,1,299, -4142,16,0,741,1, -52,4143,16,0,741, -1,2318,4144,16,0, -741,1,62,4145,16, -0,741,1,2075,4146, -16,0,741,1,1574, -924,1,71,4147,16, -0,741,1,76,4148, -16,0,741,1,1834, -4149,16,0,741,1, -2337,4150,16,0,741, -1,79,4151,16,0, -741,1,1335,4152,16, -0,741,1,322,4153, -16,0,741,1,85, -4154,16,0,741,1, -89,4155,16,0,741, -1,346,4156,16,0, -741,1,2105,939,1, -2106,4157,16,0,741, -1,97,4158,16,0, -741,1,1860,946,1, -2364,952,1,102,4159, -16,0,741,1,112, -4160,16,0,741,1, -1117,4161,16,0,741, -1,2786,4162,16,0, -741,1,1873,961,1, -1876,4163,16,0,741, -1,124,4164,16,0, -741,1,2136,968,1, -381,4165,16,0,741, -1,525,4166,16,0, -741,1,137,4167,16, -0,741,1,1901,4168, -16,0,741,1,1153, -4169,16,0,741,1, -151,4170,16,0,741, -1,1407,4171,16,0, -741,1,1659,4172,16, -0,741,1,2413,4173, -16,0,741,1,406, -4174,16,0,741,1, -1371,4175,16,0,741, -1,166,4176,16,0, -741,1,1622,4177,16, -0,741,1,1931,986, -1,1933,4178,16,0, -741,1,431,4179,16, -0,741,1,1585,4180, -16,0,741,1,182, -4181,16,0,741,1, -1189,4182,16,0,741, -1,1443,4183,16,0, -741,1,1695,4184,16, -0,741,1,2198,4185, -16,0,741,1,447, -4186,16,0,741,1, -2458,1001,1,2459,1007, -1,1958,4187,16,0, -741,1,2462,1014,1, -1657,1019,1,2464,1024, -1,199,4188,16,0, -741,1,459,4189,16, -0,741,1,462,4190, -16,0,741,1,217, -4191,16,0,741,1, -2227,1033,1,1225,4192, -16,0,741,1,1479, -4193,16,0,741,1, -1731,4194,16,0,741, -1,1989,1041,1,1990, -4195,16,0,741,1, -236,4196,16,0,741, -1,1756,4197,16,0, -741,1,96,4198,19, -740,1,96,4199,5, -95,1,256,4200,16, -0,738,1,1261,4201, -16,0,738,1,509, -4202,16,0,738,1, -1515,4203,16,0,738, -1,2021,843,1,1775, -4204,16,0,738,1, -2029,850,1,2030,856, -1,2031,861,1,2032, -866,1,2033,871,1, -277,4205,16,0,738, -1,2035,877,1,2037, -882,1,2039,887,1, -32,4206,16,0,738, -1,2041,893,1,2293, -4207,16,0,738,1, -2043,899,1,2045,904, -1,41,4208,16,0, -738,1,1297,4209,16, -0,738,1,43,4210, -16,0,738,1,1803, -912,1,1804,4211,16, -0,738,1,299,4212, -16,0,738,1,52, -4213,16,0,738,1, -2318,4214,16,0,738, -1,62,4215,16,0, -738,1,2075,4216,16, -0,738,1,1574,924, -1,71,4217,16,0, -738,1,76,4218,16, -0,738,1,1834,4219, -16,0,738,1,2337, -4220,16,0,738,1, -79,4221,16,0,738, -1,1335,4222,16,0, -738,1,322,4223,16, -0,738,1,85,4224, -16,0,738,1,89, -4225,16,0,738,1, -346,4226,16,0,738, -1,2105,939,1,2106, -4227,16,0,738,1, -97,4228,16,0,738, -1,1860,946,1,2364, -952,1,102,4229,16, -0,738,1,112,4230, -16,0,738,1,1117, -4231,16,0,738,1, -2786,4232,16,0,738, -1,1873,961,1,1876, -4233,16,0,738,1, -124,4234,16,0,738, -1,2136,968,1,381, -4235,16,0,738,1, -525,4236,16,0,738, -1,137,4237,16,0, -738,1,1901,4238,16, -0,738,1,1153,4239, -16,0,738,1,151, -4240,16,0,738,1, -1407,4241,16,0,738, -1,1659,4242,16,0, -738,1,2413,4243,16, -0,738,1,406,4244, -16,0,738,1,1371, -4245,16,0,738,1, -166,4246,16,0,738, -1,1622,4247,16,0, -738,1,1931,986,1, -1933,4248,16,0,738, -1,431,4249,16,0, -738,1,1585,4250,16, -0,738,1,182,4251, -16,0,738,1,1189, -4252,16,0,738,1, -1443,4253,16,0,738, -1,1695,4254,16,0, -738,1,2198,4255,16, -0,738,1,447,4256, -16,0,738,1,2458, -1001,1,2459,1007,1, -1958,4257,16,0,738, -1,2462,1014,1,1657, -1019,1,2464,1024,1, -199,4258,16,0,738, -1,459,4259,16,0, -738,1,462,4260,16, -0,738,1,217,4261, -16,0,738,1,2227, -1033,1,1225,4262,16, -0,738,1,1479,4263, -16,0,738,1,1731, -4264,16,0,738,1, -1989,1041,1,1990,4265, -16,0,738,1,236, -4266,16,0,738,1, -1756,4267,16,0,738, -1,97,4268,19,103, -1,97,4269,5,1, -1,0,4270,16,0, -104,1,98,4271,19, -647,1,98,4272,5, -1,1,0,4273,16, -0,645,1,99,4274, -19,210,1,99,4275, -5,2,1,0,4276, -16,0,312,1,2823, -4277,16,0,208,1, -100,4278,19,207,1, -100,4279,5,2,1, -0,4280,16,0,286, -1,2823,4281,16,0, -205,1,101,4282,19, -301,1,101,4283,5, -2,1,0,4284,16, -0,785,1,2823,4285, -16,0,299,1,102, -4286,19,320,1,102, -4287,5,4,1,0, -4288,16,0,788,1, -2764,4289,16,0,318, -1,2823,4290,16,0, -788,1,2834,4291,16, -0,318,1,103,4292, -19,714,1,103,4293, -5,2,1,2470,4294, -16,0,712,1,2659, -4295,16,0,734,1, -104,4296,19,280,1, -104,4297,5,4,1, -2597,4298,16,0,680, -1,2703,4299,16,0, -680,1,2470,4300,16, -0,278,1,2659,4301, -16,0,278,1,105, -4302,19,679,1,105, -4303,5,4,1,2597, -4304,16,0,677,1, -2703,4305,16,0,677, -1,2470,4306,16,0, -690,1,2659,4307,16, -0,690,1,106,4308, -19,157,1,106,4309, -5,4,1,2597,4310, -16,0,155,1,2703, -4311,16,0,155,1, -2470,4312,16,0,769, -1,2659,4313,16,0, -769,1,107,4314,19, -154,1,107,4315,5, -4,1,2597,4316,16, -0,152,1,2703,4317, -16,0,152,1,2470, -4318,16,0,174,1, -2659,4319,16,0,174, -1,108,4320,19,672, -1,108,4321,5,4, -1,2597,4322,16,0, -670,1,2703,4323,16, -0,670,1,2470,4324, -16,0,685,1,2659, -4325,16,0,685,1, -109,4326,19,669,1, -109,4327,5,4,1, -2597,4328,16,0,667, -1,2703,4329,16,0, -667,1,2470,4330,16, -0,684,1,2659,4331, -16,0,684,1,110, -4332,19,172,1,110, -4333,5,4,1,2597, -4334,16,0,752,1, -2703,4335,16,0,752, -1,2470,4336,16,0, -170,1,2659,4337,16, -0,170,1,111,4338, -19,169,1,111,4339, -5,4,1,2597,4340, -16,0,663,1,2703, -4341,16,0,663,1, -2470,4342,16,0,167, -1,2659,4343,16,0, -167,1,112,4344,19, -141,1,112,4345,5, -3,1,2582,4346,16, -0,293,1,2770,4347, -16,0,331,1,10, -4348,16,0,139,1, -113,4349,19,688,1, -113,4350,5,1,1, -2569,4351,16,0,686, -1,114,4352,19,676, -1,114,4353,5,1, -1,2561,4354,16,0, -674,1,115,4355,19, -660,1,115,4356,5, -1,1,2553,4357,16, -0,658,1,116,4358, -19,535,1,116,4359, -5,1,1,2538,4360, -16,0,533,1,117, -4361,19,638,1,117, -4362,5,1,1,2523, -4363,16,0,636,1, -118,4364,19,498,1, -118,4365,5,1,1, -2507,4366,16,0,496, -1,119,4367,19,160, -1,119,4368,5,17, -1,0,4369,16,0, -333,1,2582,4370,16, -0,382,1,2075,4371, -16,0,763,1,2337, -4372,16,0,763,1, -2413,4373,16,0,763, -1,10,4374,16,0, -382,1,2823,4375,16, -0,333,1,1901,4376, -16,0,763,1,2198, -4377,16,0,763,1, -21,4378,16,0,158, -1,2106,4379,16,0, -763,1,2770,4380,16, -0,382,1,1804,4381, -16,0,763,1,1990, -4382,16,0,763,1, -32,4383,16,0,763, -1,1958,4384,16,0, -763,1,1775,4385,16, -0,763,1,120,4386, -19,487,1,120,4387, -5,2,1,2569,4388, -16,0,567,1,2507, -4389,16,0,485,1, -121,4390,19,493,1, -121,4391,5,5,1, -2511,4392,16,0,491, -1,2523,4393,16,0, -506,1,2515,4394,16, -0,495,1,2538,4395, -16,0,523,1,2561, -4396,16,0,753,1, -122,4397,19,514,1, -122,4398,5,3,1, -2530,4399,16,0,516, -1,2553,4400,16,0, -542,1,2526,4401,16, -0,512,1,123,4402, -19,248,1,123,4403, -5,2,1,2541,4404, -16,0,527,1,2545, -4405,16,0,246,1, -124,4406,19,130,1, -124,4407,5,18,1, -0,4408,16,0,128, -1,2582,4409,16,0, -137,1,2075,4410,16, -0,137,1,2337,4411, -16,0,137,1,2413, -4412,16,0,137,1, -10,4413,16,0,137, -1,2823,4414,16,0, -128,1,2198,4415,16, -0,137,1,1901,4416, -16,0,137,1,52, -4417,16,0,216,1, -21,4418,16,0,137, -1,2106,4419,16,0, -137,1,2770,4420,16, -0,137,1,1804,4421, -16,0,137,1,1990, -4422,16,0,137,1, -32,4423,16,0,137, -1,1958,4424,16,0, -137,1,1775,4425,16, -0,137,1,125,4426, -19,359,1,125,4427, -5,4,1,2597,4428, -16,0,357,1,2703, -4429,16,0,357,1, -2470,4430,16,0,357, -1,2659,4431,16,0, -357,1,126,4432,19, -772,1,126,4433,5, -4,1,2597,4434,16, -0,770,1,2703,4435, -16,0,770,1,2470, -4436,16,0,770,1, -2659,4437,16,0,770, -1,127,4438,19,760, -1,127,4439,5,4, -1,2597,4440,16,0, -758,1,2703,4441,16, -0,758,1,2470,4442, -16,0,758,1,2659, -4443,16,0,758,1, -128,4444,19,548,1, -128,4445,5,4,1, -2597,4446,16,0,546, -1,2703,4447,16,0, -546,1,2470,4448,16, -0,546,1,2659,4449, -16,0,546,1,129, -4450,19,655,1,129, -4451,5,4,1,2597, -4452,16,0,653,1, -2703,4453,16,0,653, -1,2470,4454,16,0, -653,1,2659,4455,16, -0,653,1,130,4456, -19,643,1,130,4457, -5,4,1,2597,4458, -16,0,641,1,2703, -4459,16,0,641,1, -2470,4460,16,0,641, -1,2659,4461,16,0, -641,1,131,4462,19, -504,1,131,4463,5, -4,1,2597,4464,16, -0,502,1,2703,4465, -16,0,502,1,2470, -4466,16,0,502,1, -2659,4467,16,0,502, -1,132,4468,19,481, -1,132,4469,5,4, -1,2597,4470,16,0, -479,1,2703,4471,16, -0,479,1,2470,4472, -16,0,479,1,2659, -4473,16,0,479,1, -133,4474,19,381,1, -133,4475,5,21,1, -2781,4476,16,0,798, -1,2519,4477,16,0, -784,1,2557,4478,16, -0,545,1,2337,4479, -16,0,592,1,2413, -4480,16,0,592,1, -2593,4481,16,0,711, -1,2565,4482,16,0, -681,1,1901,4483,16, -0,592,1,2198,4484, -16,0,592,1,2534, -4485,16,0,640,1, -2573,4486,16,0,575, -1,2106,4487,16,0, -592,1,2578,4488,16, -0,775,1,2075,4489, -16,0,592,1,1804, -4490,16,0,592,1, -1990,4491,16,0,592, -1,31,4492,16,0, -379,1,32,4493,16, -0,592,1,2549,4494, -16,0,538,1,1958, -4495,16,0,592,1, -1775,4496,16,0,592, -1,134,4497,19,342, -1,134,4498,5,1, -1,32,4499,16,0, -340,1,135,4500,19, -289,1,135,4501,5, -11,1,2075,4502,16, -0,697,1,2337,4503, -16,0,294,1,2413, -4504,16,0,520,1, -1901,4505,16,0,437, -1,2198,4506,16,0, -362,1,2106,4507,16, -0,730,1,1804,4508, -16,0,322,1,1990, -4509,16,0,580,1, -32,4510,16,0,375, -1,1958,4511,16,0, -529,1,1775,4512,16, -0,287,1,136,4513, -19,703,1,136,4514, -5,11,1,2075,4515, -16,0,701,1,2337, -4516,16,0,701,1, -2413,4517,16,0,701, -1,1901,4518,16,0, -701,1,2198,4519,16, -0,701,1,2106,4520, -16,0,701,1,1804, -4521,16,0,701,1, -1990,4522,16,0,701, -1,32,4523,16,0, -701,1,1958,4524,16, -0,701,1,1775,4525, -16,0,701,1,137, -4526,19,756,1,137, -4527,5,11,1,2075, -4528,16,0,754,1, -2337,4529,16,0,754, -1,2413,4530,16,0, -754,1,1901,4531,16, -0,754,1,2198,4532, -16,0,754,1,2106, -4533,16,0,754,1, -1804,4534,16,0,754, -1,1990,4535,16,0, -754,1,32,4536,16, -0,754,1,1958,4537, -16,0,754,1,1775, -4538,16,0,754,1, -138,4539,19,177,1, -138,4540,5,31,1, -1901,4541,16,0,762, -1,1479,4542,16,0, -648,1,2075,4543,16, -0,762,1,1695,4544, -16,0,214,1,1756, -4545,16,0,204,1, -2413,4546,16,0,762, -1,2198,4547,16,0, -762,1,1876,4548,16, -0,781,1,1659,4549, -16,0,204,1,1443, -4550,16,0,608,1, -1117,4551,16,0,175, -1,1990,4552,16,0, -762,1,1189,4553,16, -0,264,1,1775,4554, -16,0,762,1,32, -4555,16,0,762,1, -2106,4556,16,0,762, -1,1515,4557,16,0, -699,1,2337,4558,16, -0,762,1,52,4559, -16,0,715,1,1804, -4560,16,0,762,1, -1261,4561,16,0,338, -1,1153,4562,16,0, -271,1,1225,4563,16, -0,307,1,1335,4564, -16,0,511,1,1933, -4565,16,0,651,1, -1834,4566,16,0,352, -1,1297,4567,16,0, -366,1,1407,4568,16, -0,682,1,2318,4569, -16,0,204,1,1958, -4570,16,0,762,1, -1371,4571,16,0,500, -1,139,4572,19,617, -1,139,4573,5,11, -1,2075,4574,16,0, -615,1,2337,4575,16, -0,615,1,2413,4576, -16,0,615,1,1901, -4577,16,0,615,1, -2198,4578,16,0,615, -1,2106,4579,16,0, -615,1,1804,4580,16, -0,615,1,1990,4581, -16,0,615,1,32, -4582,16,0,615,1, -1958,4583,16,0,615, -1,1775,4584,16,0, -615,1,140,4585,19, -613,1,140,4586,5, -11,1,2075,4587,16, -0,611,1,2337,4588, -16,0,611,1,2413, -4589,16,0,611,1, -1901,4590,16,0,611, -1,2198,4591,16,0, -611,1,2106,4592,16, -0,611,1,1804,4593, -16,0,611,1,1990, -4594,16,0,611,1, -32,4595,16,0,611, -1,1958,4596,16,0, -611,1,1775,4597,16, -0,611,1,141,4598, -19,694,1,141,4599, -5,11,1,2075,4600, -16,0,692,1,2337, -4601,16,0,692,1, -2413,4602,16,0,692, -1,1901,4603,16,0, -692,1,2198,4604,16, -0,692,1,2106,4605, -16,0,692,1,1804, -4606,16,0,692,1, -1990,4607,16,0,692, -1,32,4608,16,0, -692,1,1958,4609,16, -0,692,1,1775,4610, -16,0,692,1,142, -4611,19,607,1,142, -4612,5,11,1,2075, -4613,16,0,605,1, -2337,4614,16,0,605, -1,2413,4615,16,0, -605,1,1901,4616,16, -0,605,1,2198,4617, -16,0,605,1,2106, -4618,16,0,605,1, -1804,4619,16,0,605, -1,1990,4620,16,0, -605,1,32,4621,16, -0,605,1,1958,4622, -16,0,605,1,1775, -4623,16,0,605,1, -143,4624,19,604,1, -143,4625,5,11,1, -2075,4626,16,0,602, -1,2337,4627,16,0, -602,1,2413,4628,16, -0,602,1,1901,4629, -16,0,602,1,2198, -4630,16,0,602,1, -2106,4631,16,0,602, -1,1804,4632,16,0, -602,1,1990,4633,16, -0,602,1,32,4634, -16,0,602,1,1958, -4635,16,0,602,1, -1775,4636,16,0,602, -1,144,4637,19,601, -1,144,4638,5,11, -1,2075,4639,16,0, -599,1,2337,4640,16, -0,599,1,2413,4641, -16,0,599,1,1901, -4642,16,0,599,1, -2198,4643,16,0,599, -1,2106,4644,16,0, -599,1,1804,4645,16, -0,599,1,1990,4646, -16,0,599,1,32, -4647,16,0,599,1, -1958,4648,16,0,599, -1,1775,4649,16,0, -599,1,145,4650,19, -598,1,145,4651,5, -11,1,2075,4652,16, -0,596,1,2337,4653, -16,0,596,1,2413, -4654,16,0,596,1, -1901,4655,16,0,596, -1,2198,4656,16,0, -596,1,2106,4657,16, -0,596,1,1804,4658, -16,0,596,1,1990, -4659,16,0,596,1, -32,4660,16,0,596, -1,1958,4661,16,0, -596,1,1775,4662,16, -0,596,1,146,4663, -19,595,1,146,4664, -5,11,1,2075,4665, -16,0,593,1,2337, -4666,16,0,593,1, -2413,4667,16,0,593, -1,1901,4668,16,0, -593,1,2198,4669,16, -0,593,1,2106,4670, -16,0,593,1,1804, -4671,16,0,593,1, -1990,4672,16,0,593, -1,32,4673,16,0, -593,1,1958,4674,16, -0,593,1,1775,4675, -16,0,593,1,147, -4676,19,147,1,147, -4677,5,3,1,1756, -4678,16,0,321,1, -2318,4679,16,0,337, -1,1659,4680,16,0, -145,1,148,4681,19, -634,1,148,4682,5, -68,1,1901,4683,16, -0,632,1,1479,4684, -16,0,632,1,112, -4685,16,0,632,1, -2293,4686,16,0,632, -1,1804,4687,16,0, -632,1,431,4688,16, -0,632,1,1443,4689, -16,0,632,1,1756, -4690,16,0,632,1, -124,4691,16,0,632, -1,525,4692,16,0, -632,1,236,4693,16, -0,632,1,346,4694, -16,0,632,1,1876, -4695,16,0,632,1, -1659,4696,16,0,632, -1,1225,4697,16,0, -632,1,1117,4698,16, -0,632,1,137,4699, -16,0,632,1,2318, -4700,16,0,632,1, -1775,4701,16,0,632, -1,32,4702,16,0, -632,1,1407,4703,16, -0,632,1,256,4704, -16,0,632,1,459, -4705,16,0,632,1, -406,4706,16,0,632, -1,41,4707,16,0, -632,1,151,4708,16, -0,632,1,43,4709, -16,0,632,1,1585, -4710,16,0,632,1, -1990,4711,16,0,632, -1,2337,4712,16,0, -632,1,509,4713,16, -0,632,1,52,4714, -16,0,632,1,381, -4715,16,0,632,1, -447,4716,16,0,632, -1,166,4717,16,0, -632,1,462,4718,16, -0,632,1,277,4719, -16,0,632,1,1695, -4720,16,0,632,1, -2786,4721,16,0,632, -1,62,4722,16,0, -707,1,1153,4723,16, -0,632,1,2106,4724, -16,0,632,1,1335, -4725,16,0,632,1, -71,4726,16,0,632, -1,182,4727,16,0, -632,1,76,4728,16, -0,632,1,79,4729, -16,0,632,1,1933, -4730,16,0,632,1, -299,4731,16,0,632, -1,85,4732,16,0, -632,1,1515,4733,16, -0,632,1,2198,4734, -16,0,632,1,89, -4735,16,0,632,1, -1834,4736,16,0,632, -1,1622,4737,16,0, -632,1,2413,4738,16, -0,632,1,2075,4739, -16,0,632,1,1731, -4740,16,0,632,1, -97,4741,16,0,632, -1,1297,4742,16,0, -632,1,1189,4743,16, -0,632,1,102,4744, -16,0,632,1,1261, -4745,16,0,632,1, -322,4746,16,0,632, -1,1958,4747,16,0, -632,1,199,4748,16, -0,632,1,1371,4749, -16,0,632,1,217, -4750,16,0,632,1, -149,4751,19,725,1, -149,4752,5,2,1, -459,4753,16,0,723, -1,41,4754,16,0, -786,1,150,4755,19, -729,1,150,4756,5, -3,1,462,4757,16, -0,727,1,459,4758, -16,0,750,1,41, -4759,16,0,750,1, -151,4760,19,4761,4, -36,69,0,120,0, -112,0,114,0,101, -0,115,0,115,0, -105,0,111,0,110, -0,65,0,114,0, -103,0,117,0,109, -0,101,0,110,0, -116,0,1,151,4756, -1,152,4762,19,630, -1,152,4763,5,68, -1,1901,4764,16,0, -628,1,1479,4765,16, -0,628,1,112,4766, -16,0,628,1,2293, -4767,16,0,628,1, -1804,4768,16,0,628, -1,431,4769,16,0, -628,1,1443,4770,16, -0,628,1,1756,4771, -16,0,628,1,124, -4772,16,0,628,1, -525,4773,16,0,628, -1,236,4774,16,0, -628,1,346,4775,16, -0,628,1,1876,4776, -16,0,628,1,1659, -4777,16,0,628,1, -1225,4778,16,0,628, -1,1117,4779,16,0, -628,1,137,4780,16, -0,628,1,2318,4781, -16,0,628,1,1775, -4782,16,0,628,1, -32,4783,16,0,628, -1,1407,4784,16,0, -628,1,256,4785,16, -0,628,1,459,4786, -16,0,628,1,406, -4787,16,0,628,1, -41,4788,16,0,628, -1,151,4789,16,0, -628,1,43,4790,16, -0,628,1,1585,4791, -16,0,628,1,1990, -4792,16,0,628,1, -2337,4793,16,0,628, -1,509,4794,16,0, -628,1,52,4795,16, -0,628,1,381,4796, -16,0,628,1,447, -4797,16,0,628,1, -166,4798,16,0,628, -1,462,4799,16,0, -628,1,277,4800,16, -0,628,1,1695,4801, -16,0,628,1,2786, -4802,16,0,628,1, -62,4803,16,0,708, -1,1153,4804,16,0, -628,1,2106,4805,16, -0,628,1,1335,4806, -16,0,628,1,71, -4807,16,0,628,1, -182,4808,16,0,628, -1,76,4809,16,0, -628,1,79,4810,16, -0,628,1,1933,4811, -16,0,628,1,299, -4812,16,0,628,1, -85,4813,16,0,628, -1,1515,4814,16,0, -628,1,2198,4815,16, -0,628,1,89,4816, -16,0,628,1,1834, -4817,16,0,628,1, -1622,4818,16,0,628, -1,2413,4819,16,0, -628,1,2075,4820,16, -0,628,1,1731,4821, -16,0,628,1,97, -4822,16,0,628,1, -1297,4823,16,0,628, -1,1189,4824,16,0, -628,1,102,4825,16, -0,628,1,1261,4826, -16,0,628,1,322, -4827,16,0,628,1, -1958,4828,16,0,628, -1,199,4829,16,0, -628,1,1371,4830,16, -0,628,1,217,4831, -16,0,628,1,153, -4832,19,4833,4,28, +1,-1,1,5,4496, +20,1663,1,208,1, +3,1,2,1,1, +4497,22,1,43,1, +1011,3164,1,1773,4498, +16,0,137,1,16, +4499,19,117,1,16, +4500,5,147,1,2581, +4501,16,0,208,1, +2576,4502,16,0,195, +1,2568,4503,16,0, +226,1,2136,1926,1, +2474,4504,17,4505,15, +4506,4,30,37,0, 86,0,101,0,99, 0,116,0,111,0, -114,0,67,0,111, -0,110,0,115,0, -116,0,97,0,110, -0,116,0,1,153, -4763,1,154,4834,19, -4835,4,32,82,0, -111,0,116,0,97, -0,116,0,105,0, -111,0,110,0,67, -0,111,0,110,0, -115,0,116,0,97, +114,0,65,0,114, +0,103,0,69,0, +118,0,101,0,110, +0,116,0,1,-1, +1,5,4507,20,841, +1,375,1,3,1, +2,1,1,4508,22, +1,211,1,406,4509, +16,0,747,1,2560, +4510,16,0,238,1, +1695,4511,16,0,747, +1,1261,4512,16,0, +747,1,2552,4513,16, +0,439,1,2476,4514, +17,4515,15,4506,1, +-1,1,5,4516,20, +850,1,373,1,3, +1,2,1,1,4517, +22,1,209,1,2537, +4518,16,0,277,1, +2105,1940,1,381,4519, +16,0,747,1,2031, +1915,1,2522,4520,16, +0,295,1,1659,4521, +16,0,747,1,1658, +4522,16,0,213,1, +1657,1990,1,1225,4523, +16,0,747,1,151, +4524,16,0,747,1, +2075,4525,16,0,747, +1,2505,4526,17,4527, +15,4528,4,12,37, +0,69,0,118,0, +101,0,110,0,116, +0,1,-1,1,5, +4529,20,928,1,344, +1,3,1,2,1, +1,4530,22,1,180, +1,2504,4531,17,4532, +15,4528,1,-1,1, +5,4533,20,926,1, +345,1,3,1,2, +1,1,4534,22,1, +181,1,2503,4535,17, +4536,15,4528,1,-1, +1,5,4537,20,924, +1,346,1,3,1, +2,1,1,4538,22, +1,182,1,2502,4539, +17,4540,15,4528,1, +-1,1,5,4541,20, +922,1,347,1,3, +1,2,1,1,4542, +22,1,183,1,2501, +4543,17,4544,15,4528, +1,-1,1,5,4545, +20,920,1,348,1, +3,1,2,1,1, +4546,22,1,184,1, +2500,4547,17,4548,15, +4528,1,-1,1,5, +4549,20,918,1,349, +1,3,1,2,1, +1,4550,22,1,185, +1,2499,4551,17,4552, +15,4528,1,-1,1, +5,4553,20,916,1, +350,1,3,1,2, +1,1,4554,22,1, +186,1,2498,4555,17, +4556,15,4528,1,-1, +1,5,4557,20,914, +1,351,1,3,1, +2,1,1,4558,22, +1,187,1,2497,4559, +17,4560,15,4528,1, +-1,1,5,4561,20, +907,1,352,1,3, +1,2,1,1,4562, +22,1,188,1,2496, +4563,17,4564,15,4565, +4,26,37,0,86, +0,111,0,105,0, +100,0,65,0,114, +0,103,0,69,0, +118,0,101,0,110, +0,116,0,1,-1, +1,5,4566,20,905, +1,353,1,3,1, +2,1,1,4567,22, +1,189,1,2495,4568, +17,4569,15,4565,1, +-1,1,5,4570,20, +903,1,354,1,3, +1,2,1,1,4571, +22,1,190,1,2494, +4572,17,4573,15,4565, +1,-1,1,5,4574, +20,901,1,355,1, +3,1,2,1,1, +4575,22,1,191,1, +2493,4576,17,4577,15, +4565,1,-1,1,5, +4578,20,899,1,356, +1,3,1,2,1, +1,4579,22,1,192, +1,2492,4580,17,4581, +15,4565,1,-1,1, +5,4582,20,897,1, +357,1,3,1,2, +1,1,4583,22,1, +193,1,2491,4584,17, +4585,15,4565,1,-1, +1,5,4586,20,895, +1,358,1,3,1, +2,1,1,4587,22, +1,194,1,2490,4588, +17,4589,15,4565,1, +-1,1,5,4590,20, +893,1,359,1,3, +1,2,1,1,4591, +22,1,195,1,2489, +4592,17,4593,15,4565, +1,-1,1,5,4594, +20,886,1,360,1, +3,1,2,1,1, +4595,22,1,196,1, +2488,4596,17,4597,15, +4598,4,24,37,0, +75,0,101,0,121, +0,65,0,114,0, +103,0,69,0,118, +0,101,0,110,0, +116,0,1,-1,1, +5,4599,20,884,1, +361,1,3,1,2, +1,1,4600,22,1, +197,1,2487,4601,17, +4602,15,4598,1,-1, +1,5,4603,20,877, +1,362,1,3,1, +2,1,1,4604,22, +1,198,1,2486,4605, +17,4606,15,4607,4, +24,37,0,73,0, +110,0,116,0,65, +0,114,0,103,0, +69,0,118,0,101, 0,110,0,116,0, -1,154,4763,1,155, -4836,19,4837,4,24, -76,0,105,0,115, -0,116,0,67,0, -111,0,110,0,115, +1,-1,1,5,4608, +20,875,1,363,1, +3,1,2,1,1, +4609,22,1,199,1, +2485,4610,17,4611,15, +4607,1,-1,1,5, +4612,20,873,1,364, +1,3,1,2,1, +1,4613,22,1,200, +1,1622,4614,16,0, +747,1,2483,4615,17, +4616,15,4607,1,-1, +1,5,4617,20,869, +1,366,1,3,1, +2,1,1,4618,22, +1,202,1,2482,4619, +17,4620,15,4607,1, +-1,1,5,4621,20, +867,1,367,1,3, +1,2,1,1,4622, +22,1,203,1,2481, +4623,17,4624,15,4607, +1,-1,1,5,4625, +20,865,1,368,1, +3,1,2,1,1, +4626,22,1,204,1, +2480,4627,17,4628,15, +4607,1,-1,1,5, +4629,20,863,1,369, +1,3,1,2,1, +1,4630,22,1,205, +1,2479,4631,17,4632, +15,4607,1,-1,1, +5,4633,20,861,1, +370,1,3,1,2, +1,1,4634,22,1, +206,1,2478,4635,17, +4636,15,4607,1,-1, +1,5,4637,20,859, +1,371,1,3,1, +2,1,1,4638,22, +1,207,1,322,4639, +16,0,747,1,2045, +1997,1,2475,4640,17, +4641,15,4506,1,-1, +1,5,4642,20,848, +1,374,1,3,1, +2,1,1,4643,22, +1,210,1,2043,2001, +1,2473,4644,17,4645, +15,4646,4,36,37, +0,73,0,110,0, +116,0,82,0,111, +0,116,0,82,0, +111,0,116,0,65, +0,114,0,103,0, +69,0,118,0,101, +0,110,0,116,0, +1,-1,1,5,4647, +20,834,1,376,1, +3,1,2,1,1, +4648,22,1,212,1, +2041,2005,1,2471,4649, +17,4650,15,4651,4, +36,37,0,75,0, +101,0,121,0,73, +0,110,0,116,0, +73,0,110,0,116, +0,65,0,114,0, +103,0,69,0,118, +0,101,0,110,0, +116,0,1,-1,1, +5,4652,20,820,1, +378,1,3,1,2, +1,1,4653,22,1, +214,1,2039,2009,1, +2037,2014,1,2035,1900, +1,2033,2020,1,2032, +2024,1,2462,1963,1, +2030,1978,1,2029,1921, +1,2459,1969,1,2458, +1974,1,299,4654,16, +0,747,1,2021,2036, +1,1585,4655,16,0, +747,1,1153,4656,16, +0,747,1,1574,1895, +1,277,4657,16,0, +747,1,1990,4658,16, +0,747,1,1989,2060, +1,2413,4659,16,0, +747,1,256,4660,16, +0,747,1,1117,4661, +16,0,747,1,2477, +4662,17,4663,15,4607, +1,-1,1,5,4664, +20,852,1,372,1, +3,1,2,1,1, +4665,22,1,208,1, +2106,4666,16,0,747, +1,236,4667,16,0, +747,1,1958,4668,16, +0,747,1,1756,4669, +16,0,747,1,1933, +4670,16,0,747,1, +1515,4671,16,0,747, +1,217,4672,16,0, +747,1,2364,2074,1, +1932,4673,16,0,704, +1,1931,1909,1,2464, +2042,1,2786,4674,16, +0,747,1,199,4675, +16,0,747,1,2506, +4676,16,0,317,1, +1479,4677,16,0,747, +1,2769,4678,16,0, +780,1,2337,4679,16, +0,747,1,1901,4680, +16,0,747,1,166, +4681,16,0,747,1, +2318,4682,16,0,747, +1,2198,4683,16,0, +747,1,2472,4684,17, +4685,15,4686,4,36, +37,0,73,0,110, +0,116,0,86,0, +101,0,99,0,86, +0,101,0,99,0, +65,0,114,0,103, +0,69,0,118,0, +101,0,110,0,116, +0,1,-1,1,5, +4687,20,827,1,377, +1,3,1,2,1, +1,4688,22,1,213, +1,1876,4689,16,0, +747,1,1875,4690,16, +0,762,1,1443,4691, +16,0,747,1,1873, +2069,1,2293,4692,16, +0,747,1,137,4693, +16,0,747,1,1189, +4694,16,0,747,1, +79,4695,16,0,747, +1,124,4696,16,0, +747,1,1407,4697,16, +0,747,1,112,4698, +16,0,747,1,1834, +4699,16,0,747,1, +1833,4700,16,0,115, +1,102,4701,16,0, +747,1,97,4702,16, +0,747,1,525,4703, +16,0,747,1,2484, +4704,17,4705,15,4607, +1,-1,1,5,4706, +20,871,1,365,1, +3,1,2,1,1, +4707,22,1,201,1, +1371,4708,16,0,747, +1,89,4709,16,0, +747,1,1860,1983,1, +85,4710,16,0,747, +1,1804,4711,16,0, +747,1,1803,2052,1, +509,4712,16,0,747, +1,76,4713,16,0, +747,1,182,4714,16, +0,747,1,2227,2029, +1,71,4715,16,0, +747,1,63,4716,16, +0,759,1,62,4717, +16,0,734,1,52, +4718,16,0,747,1, +1775,4719,16,0,747, +1,32,4720,16,0, +747,1,44,4721,16, +0,759,1,43,4722, +16,0,747,1,1335, +4723,16,0,747,1, +41,4724,16,0,747, +1,40,4725,16,0, +759,1,346,4726,16, +0,747,1,462,4727, +16,0,747,1,459, +4728,16,0,747,1, +447,4729,16,0,747, +1,9,4730,16,0, +783,1,1731,4731,16, +0,747,1,1297,4732, +16,0,747,1,431, +4733,16,0,747,1, +15,4734,19,272,1, +15,4735,5,6,1, +40,4736,16,0,441, +1,2785,4737,16,0, +770,1,1114,4738,16, +0,542,1,1621,4739, +16,0,270,1,9, +4483,1,19,4461,1, +14,4740,19,148,1, +14,4741,5,115,1, +2281,4290,1,1377,4295, +1,67,2997,1,387, +4742,16,0,531,1, +1370,4306,1,380,2968, +1,379,2973,1,377, +2978,1,2543,4311,1, +375,2983,1,373,2987, +1,371,2991,1,172, +3238,1,1550,4321,1, +42,3742,1,2335,4743, +16,0,197,1,1152, +4327,1,2529,4744,16, +0,287,1,2528,4332, +1,107,3052,1,2525, +4745,16,0,293,1, +1341,4337,1,157,3245, +1,2544,4746,16,0, +262,1,352,3151,1, +1730,4433,1,2540,4747, +16,0,146,1,2514, +4748,16,0,305,1, +2513,4351,1,2510,4749, +16,0,311,1,2509, +4356,1,143,3249,1, +1521,4361,1,188,3233, +1,1123,4365,1,1514, +4369,1,82,3023,1, +328,3029,1,130,3256, +1,1114,3034,1,1701, +4377,1,2582,4459,1, +942,3011,1,1303,4382, +1,9,4483,1,1694, +4750,16,0,197,1, +1296,4392,1,1096,3042, +1,1094,4751,16,0, +503,1,305,3048,1, +1332,4347,1,1485,4397, +1,2467,4402,1,70, +3057,1,1478,4406,1, +883,3269,1,93,3063, +1,1665,4411,1,481, +3747,1,480,3006,1, +479,3072,1,478,3077, +1,477,3081,1,476, +3085,1,20,4752,16, +0,776,1,118,3262, +1,1260,4416,1,68, +3099,1,74,3089,1, +1048,3113,1,464,3734, +1,69,3095,1,262, +3108,1,461,4753,16, +0,503,1,66,3104, +1,459,3752,1,1267, +4423,1,1442,4427,1, +447,3117,1,51,3123, +1,63,3127,1,1231, +4437,1,48,3132,1, +47,3136,1,242,3280, +1,44,3138,1,437, +4754,16,0,468,1, +1224,4441,1,41,3739, +1,525,3145,1,827, +3286,1,1413,4445,1, +2591,4755,16,0,776, +1,1013,3156,1,1406, +4451,1,223,3292,1, +1159,4455,1,2779,4756, +16,0,776,1,283, +3068,1,19,4461,1, +412,4757,16,0,517, +1,1002,3169,1,1001, +3173,1,30,4467,1, +1195,4471,1,2770,4475, +1,1011,3164,1,10, +4373,1,40,3179,1, +205,3300,1,1449,4484, +1,1188,4488,1,50, +3181,1,49,3016,1, +1773,4758,16,0,197, +1,13,4759,19,114, +1,13,4760,5,55, +1,2580,2373,1,2045, +1997,1,2043,2001,1, +2648,2378,1,2575,2383, +1,2039,2009,1,1860, +1983,1,2037,2014,1, +2458,1974,1,2657,2389, +1,2567,2393,1,2032, +2024,1,2654,2402,1, +2653,2406,1,2652,2410, +1,2651,2414,1,2650, +2418,1,2464,2042,1, +2559,2422,1,2647,2427, +1,2646,2431,1,2645, +2435,1,2644,2439,1, +1931,1909,1,2642,2468, +1,2641,2447,1,2462, +1963,1,2105,1940,1, +2459,1969,1,1657,1990, +1,2656,2472,1,2364, +2074,1,2029,1921,1, +2033,2020,1,2536,2457, +1,2030,1978,1,2041, +2005,1,1873,2069,1, +2703,4761,16,0,112, +1,32,4762,16,0, +429,1,1989,2060,1, +2521,2463,1,2021,2036, +1,1803,2052,1,2551, +2451,1,1574,1895,1, +2597,4763,16,0,250, +1,2595,2477,1,2643, +2443,1,2035,1900,1, +2413,4764,16,0,431, +1,2655,2398,1,2031, +1915,1,2227,2029,1, +2136,1926,1,12,4765, +19,151,1,12,4766, +5,50,1,1803,2052, +1,2578,4767,16,0, +767,1,2043,2001,1, +1775,4768,16,0,767, +1,2041,2005,1,2573, +4769,16,0,767,1, +1860,1983,1,2037,2014, +1,2658,4770,16,0, +149,1,2033,2020,1, +2032,2024,1,2565,4771, +16,0,767,1,2030, +1978,1,2029,1921,1, +2106,4772,16,0,767, +1,2469,4773,16,0, +422,1,2557,4774,16, +0,767,1,2464,2042, +1,1931,1909,1,1574, +1895,1,2462,1963,1, +2105,1940,1,2549,4775, +16,0,767,1,2459, +1969,1,2458,1974,1, +2039,2009,1,2364,2074, +1,32,4776,16,0, +767,1,2198,4777,16, +0,767,1,1958,4778, +16,0,767,1,2035, +1900,1,2534,4779,16, +0,767,1,1873,2069, +1,1657,1990,1,2021, +2036,1,1901,4780,16, +0,767,1,1989,2060, +1,1990,4781,16,0, +767,1,2075,4782,16, +0,767,1,2519,4783, +16,0,767,1,1804, +4784,16,0,767,1, +2337,4785,16,0,767, +1,2781,4786,16,0, +767,1,2593,4787,16, +0,767,1,2413,4788, +16,0,767,1,31, +4789,16,0,767,1, +2045,1997,1,2031,1915, +1,2227,2029,1,2136, +1926,1,11,4790,19, +111,1,11,4791,5, +146,1,2462,1963,1, +2136,1926,1,1701,4377, +1,1267,4423,1,1694, +4792,16,0,174,1, +1260,4416,1,1159,4455, +1,827,3286,1,2106, +4793,17,4794,15,4795, +4,30,37,0,69, +0,109,0,112,0, +116,0,121,0,83, 0,116,0,97,0, -110,0,116,0,1, -155,4763,1,156,4838, -19,185,1,156,4839, -5,67,1,1901,4840, -16,0,705,1,1479, -4841,16,0,619,1, -112,4842,16,0,273, -1,2293,4843,16,0, -306,1,1804,4844,16, -0,705,1,431,4845, -16,0,700,1,1443, -4846,16,0,550,1, -1756,4847,16,0,796, -1,124,4848,16,0, -285,1,525,4849,16, -0,345,1,236,4850, -16,0,387,1,346, -4851,16,0,582,1, -1876,4852,16,0,361, -1,1659,4853,16,0, -796,1,1225,4854,16, -0,272,1,1117,4855, -16,0,242,1,137, -4856,16,0,305,1, -2318,4857,16,0,796, -1,1775,4858,16,0, -705,1,32,4859,16, -0,705,1,1407,4860, -16,0,571,1,256, -4861,16,0,441,1, -459,4862,16,0,183, -1,406,4863,16,0, -662,1,41,4864,16, -0,183,1,151,4865, -16,0,317,1,43, -4866,16,0,751,1, -1990,4867,16,0,705, -1,2337,4868,16,0, -705,1,509,4869,16, -0,774,1,52,4870, -16,0,717,1,381, -4871,16,0,639,1, -447,4872,16,0,345, -1,166,4873,16,0, -332,1,462,4874,16, -0,183,1,277,4875, -16,0,488,1,1695, -4876,16,0,302,1, -2786,4877,16,0,254, -1,1261,4878,16,0, -316,1,1153,4879,16, -0,190,1,2106,4880, -16,0,705,1,1335, -4881,16,0,372,1, -71,4882,16,0,226, -1,182,4883,16,0, -345,1,76,4884,16, -0,635,1,79,4885, -16,0,241,1,1933, -4886,16,0,453,1, -299,4887,16,0,517, -1,85,4888,16,0, -541,1,1515,4889,16, -0,657,1,2198,4890, -16,0,705,1,89, -4891,16,0,253,1, -1834,4892,16,0,330, -1,1622,4893,16,0, -773,1,2413,4894,16, -0,705,1,2075,4895, -16,0,705,1,1731, -4896,16,0,274,1, -97,4897,16,0,457, -1,1297,4898,16,0, -374,1,1189,4899,16, -0,240,1,102,4900, -16,0,262,1,1585, -4901,16,0,783,1, -322,4902,16,0,543, -1,1958,4903,16,0, -705,1,199,4904,16, -0,356,1,1371,4905, -16,0,442,1,217, -4906,16,0,368,1, -157,4907,19,4908,4, -36,67,0,111,0, -110,0,115,0,116, -0,97,0,110,0, -116,0,69,0,120, -0,112,0,114,0, -101,0,115,0,115, -0,105,0,111,0, -110,0,1,157,4839, -1,158,4909,19,4910, -4,30,73,0,100, +116,0,101,0,109, 0,101,0,110,0, -116,0,69,0,120, -0,112,0,114,0, -101,0,115,0,115, -0,105,0,111,0, -110,0,1,158,4839, -1,159,4911,19,4912, -4,36,73,0,100, -0,101,0,110,0, -116,0,68,0,111, -0,116,0,69,0, -120,0,112,0,114, -0,101,0,115,0, -115,0,105,0,111, -0,110,0,1,159, -4839,1,160,4913,19, -4914,4,44,70,0, -117,0,110,0,99, -0,116,0,105,0, -111,0,110,0,67, -0,97,0,108,0, -108,0,69,0,120, -0,112,0,114,0, -101,0,115,0,115, -0,105,0,111,0, -110,0,1,160,4839, -1,161,4915,19,4916, -4,32,66,0,105, -0,110,0,97,0, -114,0,121,0,69, -0,120,0,112,0, -114,0,101,0,115, -0,115,0,105,0, -111,0,110,0,1, -161,4839,1,162,4917, -19,4918,4,30,85, -0,110,0,97,0, -114,0,121,0,69, -0,120,0,112,0, -114,0,101,0,115, -0,115,0,105,0, -111,0,110,0,1, -162,4839,1,163,4919, -19,4920,4,36,84, -0,121,0,112,0, -101,0,99,0,97, -0,115,0,116,0, -69,0,120,0,112, -0,114,0,101,0, -115,0,115,0,105, -0,111,0,110,0, -1,163,4839,1,164, -4921,19,4922,4,42, -80,0,97,0,114, -0,101,0,110,0, -116,0,104,0,101, -0,115,0,105,0, -115,0,69,0,120, -0,112,0,114,0, -101,0,115,0,115, -0,105,0,111,0, -110,0,1,164,4839, -1,165,4923,19,4924, -4,56,73,0,110, -0,99,0,114,0, +116,0,1,-1,1, +5,4796,20,1557,1, +222,1,3,1,1, +1,0,4797,22,1, +57,1,2105,1940,1, +380,2968,1,379,2973, +1,377,2978,1,375, +2983,1,373,2987,1, +1665,4411,1,371,2991, +1,1231,4437,1,1555, +4798,16,0,357,1, +1659,4799,16,0,509, +1,1657,1990,1,1224, +4441,1,352,3151,1, +2075,4800,17,4794,1, +0,4797,1,328,3029, +1,1628,4801,17,4802, +15,4803,4,22,37, +0,65,0,115,0, +115,0,105,0,103, +0,110,0,109,0, +101,0,110,0,116, +0,1,-1,1,5, +4804,20,1393,1,254, +1,3,1,4,1, +3,4805,22,1,89, +1,1195,4471,1,1621, +4806,16,0,217,1, +1620,4807,17,4808,15, +4803,1,-1,1,5, +4809,20,1379,1,255, +1,3,1,2,1, +1,4810,22,1,90, +1,1188,4488,1,2045, +1997,1,2044,4811,16, +0,622,1,2043,2001, +1,2042,4812,16,0, +109,1,2041,2005,1, +2040,4813,16,0,576, +1,2039,2009,1,2038, +4814,16,0,632,1, +2037,2014,1,2036,4815, +16,0,528,1,2035, +1900,1,2034,4816,16, +0,640,1,2464,2042, +1,2032,2024,1,2031, +1915,1,2030,1978,1, +2029,1921,1,2028,4817, +17,4818,15,4819,4, +20,37,0,74,0, +117,0,109,0,112, +0,76,0,97,0, +98,0,101,0,108, +0,1,-1,1,5, +4820,20,1505,1,236, +1,3,1,3,1, +2,4821,22,1,71, +1,2458,1974,1,2026, +4822,17,4823,15,4824, +4,28,37,0,74, +0,117,0,109,0, +112,0,83,0,116, +0,97,0,116,0, 101,0,109,0,101, 0,110,0,116,0, -68,0,101,0,99, -0,114,0,101,0, +1,-1,1,5,4825, +20,1491,1,237,1, +3,1,3,1,2, +4826,22,1,72,1, +2024,4827,17,4828,15, +4829,4,24,37,0, +83,0,116,0,97, +0,116,0,101,0, +67,0,104,0,97, +0,110,0,103,0, +101,0,1,-1,1, +5,4830,20,1489,1, +238,1,3,1,3, +1,2,4831,22,1, +73,1,2023,4832,17, +4833,15,4829,1,-1, +1,5,4834,20,1475, +1,239,1,3,1, +3,1,2,4835,22, +1,74,1,1591,4836, +17,4837,15,4838,4, +32,37,0,82,0, +101,0,116,0,117, +0,114,0,110,0, +83,0,116,0,97, +0,116,0,101,0, 109,0,101,0,110, -0,116,0,69,0, -120,0,112,0,114, -0,101,0,115,0, -115,0,105,0,111, -0,110,0,1,165, -4839,1,167,4925,19, -830,1,167,4269,1, -168,4926,19,808,1, -168,4269,1,169,4927, -19,3557,1,169,4272, -1,170,4928,19,3547, -1,170,4272,1,171, -4929,19,3552,1,171, -4272,1,172,4930,19, -3542,1,172,4272,1, -173,4931,19,3527,1, -173,4275,1,174,4932, -19,3562,1,174,4275, -1,175,4933,19,3521, -1,175,4279,1,176, -4934,19,3535,1,176, -4279,1,177,4935,19, -814,1,177,4283,1, -178,4936,19,825,1, -178,4283,1,179,4937, -19,820,1,179,4287, -1,180,4938,19,835, -1,180,4287,1,181, -4939,19,1777,1,181, -4293,1,182,4940,19, -1881,1,182,4293,1, -183,4941,19,1844,1, -183,4293,1,184,4942, -19,1765,1,184,4293, -1,185,4943,19,1839, -1,185,4293,1,186, -4944,19,1802,1,186, -4293,1,187,4945,19, -1834,1,187,4293,1, -188,4946,19,1797,1, -188,4293,1,189,4947, -19,1829,1,189,4293, -1,190,4948,19,1792, -1,190,4293,1,191, -4949,19,1824,1,191, -4293,1,192,4950,19, -1760,1,192,4293,1, -193,4951,19,1819,1, -193,4293,1,194,4952, -19,1787,1,194,4293, -1,195,4953,19,1814, -1,195,4293,1,196, -4954,19,1782,1,196, -4293,1,197,4955,19, -1875,1,197,4297,1, -198,4956,19,1862,1, -198,4303,1,199,4957, -19,1850,1,199,4309, -1,200,4958,19,1809, -1,200,4315,1,201, -4959,19,1868,1,201, -4321,1,202,4960,19, -1856,1,202,4327,1, -203,4961,19,1754,1, -203,4333,1,204,4962, -19,1771,1,204,4339, -1,205,4963,19,1945, -1,205,4345,1,206, -4964,19,1904,1,206, -4345,1,207,4965,19, -2337,1,207,4350,1, -208,4966,19,2308,1, -208,4353,1,209,4967, -19,2302,1,209,4356, -1,210,4968,19,2294, -1,210,4359,1,211, -4969,19,2287,1,211, -4362,1,212,4970,19, -2319,1,212,4365,1, -213,4971,19,1242,1, -213,4368,1,214,4972, -19,1964,1,214,4387, -1,215,4973,19,1890, -1,215,4391,1,216, -4974,19,1931,1,216, -4398,1,217,4975,19, -1910,1,217,4403,1, -218,4976,19,1027,1, -218,4475,1,219,4977, -19,1011,1,219,4475, -1,220,4978,19,1017, -1,220,4498,1,221, -4979,19,1005,1,221, -4498,1,222,4980,19, -1270,1,222,4514,1, -223,4981,19,907,1, -223,4501,1,224,4982, -19,1022,1,224,4501, -1,225,4983,19,902, -1,225,4501,1,226, -4984,19,927,1,226, -4501,1,227,4985,19, -896,1,227,4501,1, -228,4986,19,890,1, -228,4501,1,229,4987, -19,885,1,229,4501, -1,230,4988,19,880, -1,230,4501,1,231, -4989,19,874,1,231, -4501,1,232,4990,19, -869,1,232,4501,1, -233,4991,19,864,1, -233,4501,1,234,4992, -19,859,1,234,4501, -1,235,4993,19,854, -1,235,4501,1,236, -4994,19,1277,1,236, -4586,1,237,4995,19, -1417,1,237,4599,1, -238,4996,19,1264,1, -238,4612,1,239,4997, -19,1405,1,239,4612, -1,240,4998,19,1044, -1,240,4625,1,241, -4999,19,847,1,241, -4625,1,242,5000,19, -942,1,242,4625,1, -243,5001,19,971,1, -243,4625,1,244,5002, -19,990,1,244,4638, -1,245,5003,19,1036, -1,245,4638,1,246, -5004,19,950,1,246, -4651,1,247,5005,19, -964,1,247,4651,1, -248,5006,19,916,1, -248,4664,1,249,5007, -19,955,1,249,4664, -1,250,5008,19,1603, -1,250,4677,1,251, -5009,19,1283,1,251, -4677,1,252,5010,19, -1635,1,252,4677,1, -253,5011,19,1667,1, -253,4677,1,254,5012, -19,1532,1,254,4527, -1,255,5013,19,1592, -1,255,4527,1,256, -5014,19,1258,1,256, -4540,1,257,5015,19, -1699,1,257,4540,1, -258,5016,19,1630,1, -258,4540,1,259,5017, -19,1576,1,259,4540, -1,260,5018,19,1500, -1,260,4540,1,261, -5019,19,1427,1,261, -4540,1,262,5020,19, -1437,1,262,4540,1, -263,5021,19,1253,1, -263,4540,1,264,5022, -19,1683,1,264,4540, -1,265,5023,19,1625, -1,265,4540,1,266, -5024,19,1566,1,266, -4540,1,267,5025,19, -1489,1,267,4540,1, -268,5026,19,1453,1, -268,4540,1,269,5027, -19,1236,1,269,4540, -1,270,5028,19,1586, -1,270,4540,1,271, -5029,19,1613,1,271, -4540,1,272,5030,19, -1559,1,272,4540,1, -273,5031,19,1581,1, -273,4540,1,274,5032, -19,1393,1,274,4540, -1,275,5033,19,1297, -1,275,4540,1,276, -5034,19,1225,1,276, -4540,1,277,5035,19, -1657,1,277,4540,1, -278,5036,19,1608,1, -278,4540,1,279,5037, -19,1554,1,279,4540, -1,280,5038,19,1422, -1,280,4573,1,281, -5039,19,1400,1,281, -4573,1,282,5040,19, -1688,1,282,4763,1, -283,5041,19,1711,1, -283,4763,1,284,5042, -19,1678,1,284,4763, -1,285,5043,19,1673, -1,285,4763,1,286, -5044,19,1694,1,286, -4763,1,287,5045,19, -1641,1,287,4763,1, -288,5046,19,1347,1, -288,4763,1,289,5047, -19,1521,1,289,4839, -1,290,5048,19,1308, -1,290,4839,1,291, -5049,19,1315,1,291, -4839,1,292,5050,19, -1336,1,292,4839,1, -293,5051,19,1331,1, -293,4839,1,294,5052, -19,1326,1,294,4839, -1,295,5053,19,1321, -1,295,4839,1,296, -5054,19,1510,1,296, -4839,1,297,5055,19, -1538,1,297,4839,1, -298,5056,19,1515,1, -298,4839,1,299,5057, -19,1505,1,299,4839, -1,300,5058,19,1495, -1,300,4839,1,301, -5059,19,1478,1,301, -4839,1,302,5060,19, -1432,1,302,4839,1, -303,5061,19,1341,1, -303,4839,1,304,5062, -19,1302,1,304,4839, -1,305,5063,19,1248, -1,305,4839,1,306, -5064,19,1706,1,306, -4839,1,307,5065,19, -1662,1,307,4839,1, -308,5066,19,1652,1, -308,4839,1,309,5067, -19,1647,1,309,4839, -1,310,5068,19,1598, -1,310,4839,1,311, -5069,19,1571,1,311, -4839,1,312,5070,19, -1548,1,312,4839,1, -313,5071,19,1543,1, -313,4839,1,314,5072, -19,1484,1,314,4839, -1,315,5073,19,1460, -1,315,4839,1,316, -5074,19,1526,1,316, -4839,1,317,5075,19, -1619,1,317,4839,1, -318,5076,19,1473,1, -318,4839,1,319,5077, -19,1467,1,319,4839, -1,320,5078,19,1448, -1,320,4839,1,321, -5079,19,1411,1,321, -4839,1,322,5080,19, -1388,1,322,4839,1, -323,5081,19,1231,1, -323,4839,1,324,5082, -19,1721,1,324,4839, -1,325,5083,19,1353, -1,325,4839,1,326, -5084,19,1358,1,326, -4839,1,327,5085,19, -1378,1,327,4839,1, -328,5086,19,1368,1, -328,4839,1,329,5087, -19,1373,1,329,4839, -1,330,5088,19,1363, -1,330,4839,1,331, -5089,19,1716,1,331, -4839,1,332,5090,19, -1383,1,332,4839,1, -333,5091,19,1443,1, -333,4682,1,334,5092, -19,1958,1,334,4752, -1,335,5093,19,1951, -1,335,4752,1,336, -5094,19,1921,1,336, -4756,1,337,5095,19, -2278,1,337,4407,1, -338,5096,19,2273,1, -338,4407,1,339,5097, -19,2268,1,339,4407, -1,340,5098,19,2263, -1,340,4407,1,341, -5099,19,2258,1,341, -4407,1,342,5100,19, -2253,1,342,4407,1, -343,5101,19,2248,1, -343,4407,1,344,5102, -19,2237,1,344,4427, -1,345,5103,19,2232, -1,345,4427,1,346, -5104,19,2227,1,346, -4427,1,347,5105,19, -2222,1,347,4427,1, -348,5106,19,2217,1, -348,4427,1,349,5107, -19,2212,1,349,4427, -1,350,5108,19,2207, -1,350,4427,1,351, -5109,19,2202,1,351, -4427,1,352,5110,19, -2197,1,352,4427,1, -353,5111,19,2191,1, -353,4433,1,354,5112, -19,2019,1,354,4433, -1,355,5113,19,2185, -1,355,4433,1,356, -5114,19,2180,1,356, -4433,1,357,5115,19, -2175,1,357,4433,1, -358,5116,19,2012,1, -358,4433,1,359,5117, -19,2170,1,359,4433, -1,360,5118,19,2165, -1,360,4433,1,361, -5119,19,2160,1,361, -4439,1,362,5120,19, -2155,1,362,4439,1, -363,5121,19,2149,1, -363,4445,1,364,5122, -19,2144,1,364,4445, -1,365,5123,19,2004, -1,365,4445,1,366, -5124,19,2138,1,366, -4445,1,367,5125,19, -2133,1,367,4445,1, -368,5126,19,2128,1, -368,4445,1,369,5127, -19,1997,1,369,4445, -1,370,5128,19,2122, -1,370,4445,1,371, -5129,19,2049,1,371, -4445,1,372,5130,19, -2117,1,372,4445,1, -373,5131,19,2112,1, -373,4451,1,374,5132, -19,2107,1,374,4451, -1,375,5133,19,2102, -1,375,4451,1,376, -5134,19,2096,1,376, -4457,1,377,5135,19, -2090,1,377,4463,1, -378,5136,19,2084,1, -378,4469,1,379,5137, -19,5138,4,50,65, -0,114,0,103,0, -117,0,109,0,101, -0,110,0,116,0, -68,0,101,0,99, -0,108,0,97,0, -114,0,97,0,116, -0,105,0,111,0, -110,0,76,0,105, -0,115,0,116,0, -95,0,51,0,1, -379,4345,1,380,5139, -19,5140,4,28,65, -0,114,0,103,0, -117,0,109,0,101, -0,110,0,116,0, -76,0,105,0,115, -0,116,0,95,0, -51,0,1,380,4752, -1,381,5141,19,5142, -4,28,65,0,114, -0,103,0,117,0, -109,0,101,0,110, -0,116,0,76,0, -105,0,115,0,116, -0,95,0,52,0, -1,381,4752,1,382, -5143,19,5144,4,50, -65,0,114,0,103, -0,117,0,109,0, -101,0,110,0,116, -0,68,0,101,0, -99,0,108,0,97, -0,114,0,97,0, -116,0,105,0,111, -0,110,0,76,0, -105,0,115,0,116, -0,95,0,52,0, -1,382,4345,1,383, -5145,19,5146,4,50, -65,0,114,0,103, -0,117,0,109,0, -101,0,110,0,116, -0,68,0,101,0, -99,0,108,0,97, -0,114,0,97,0, -116,0,105,0,111, -0,110,0,76,0, -105,0,115,0,116, -0,95,0,53,0, -1,383,4345,2,0,0}; -new Sfactory(this,"ExpressionArgument_1",new SCreator(ExpressionArgument_1_factory)); -new Sfactory(this,"VectorArgStateEvent",new SCreator(VectorArgStateEvent_factory)); -new Sfactory(this,"IntVecVecArgStateEvent",new SCreator(IntVecVecArgStateEvent_factory)); -new Sfactory(this,"IntArgStateEvent_1",new SCreator(IntArgStateEvent_1_factory)); -new Sfactory(this,"SimpleAssignment_9",new SCreator(SimpleAssignment_9_factory)); -new Sfactory(this,"StatementList_1",new SCreator(StatementList_1_factory)); -new Sfactory(this,"RotDeclaration_1",new SCreator(RotDeclaration_1_factory)); -new Sfactory(this,"IntRotRotArgEvent_1",new SCreator(IntRotRotArgEvent_1_factory)); -new Sfactory(this,"StateChange_1",new SCreator(StateChange_1_factory)); -new Sfactory(this,"EmptyStatement",new SCreator(EmptyStatement_factory)); -new Sfactory(this,"Declaration",new SCreator(Declaration_factory)); -new Sfactory(this,"IdentExpression",new SCreator(IdentExpression_factory)); -new Sfactory(this,"error",new SCreator(error_factory)); -new Sfactory(this,"BinaryExpression_2",new SCreator(BinaryExpression_2_factory)); -new Sfactory(this,"BinaryExpression_3",new SCreator(BinaryExpression_3_factory)); -new Sfactory(this,"BinaryExpression_4",new SCreator(BinaryExpression_4_factory)); -new Sfactory(this,"BinaryExpression_5",new SCreator(BinaryExpression_5_factory)); -new Sfactory(this,"ReturnStatement_2",new SCreator(ReturnStatement_2_factory)); -new Sfactory(this,"SimpleAssignment_19",new SCreator(SimpleAssignment_19_factory)); -new Sfactory(this,"BinaryExpression_9",new SCreator(BinaryExpression_9_factory)); -new Sfactory(this,"VectorConstant_1",new SCreator(VectorConstant_1_factory)); -new Sfactory(this,"ParenthesisExpression",new SCreator(ParenthesisExpression_factory)); -new Sfactory(this,"StatementList",new SCreator(StatementList_factory)); -new Sfactory(this,"IntRotRotArgEvent",new SCreator(IntRotRotArgEvent_factory)); -new Sfactory(this,"UnaryExpression",new SCreator(UnaryExpression_factory)); +0,116,0,1,-1, +1,5,4839,20,1297, +1,280,1,3,1, +3,1,2,4840,22, +1,115,1,2021,2036, +1,1585,4841,17,4842, +15,4838,1,-1,1, +5,4843,20,1283,1, +281,1,3,1,2, +1,1,4844,22,1, +116,1,1152,4327,1, +283,3068,1,1574,1895, +1,49,3016,1,479, +3072,1,1990,4845,17, +4794,1,0,4797,1, +1989,2060,1,262,3108, +1,1123,4365,1,2413, +4846,17,4794,1,0, +4797,1,1550,4321,1, +1114,3034,1,242,3280, +1,1096,3042,1,1521, +4361,1,223,3292,1, +1514,4369,1,2364,2074, +1,1931,1909,1,2792, +4847,16,0,746,1, +205,3300,1,2785,4848, +16,0,501,1,883, +3269,1,942,3011,1, +1485,4397,1,188,3233, +1,1048,3113,1,1478, +4406,1,2337,4849,17, +4794,1,0,4797,1, +1901,4850,17,4794,1, +0,4797,1,172,3238, +1,478,3077,1,157, +3245,1,1449,4484,1, +1013,3156,1,305,3048, +1,1011,3164,1,1872, +4851,16,0,764,1, +2299,4852,16,0,456, +1,143,3249,1,1002, +3169,1,1001,3173,1, +1860,1983,1,1859,4853, +16,0,775,1,130, +3256,1,2281,4290,1, +2459,1969,1,1873,2069, +1,1413,4445,1,118, +3262,1,1406,4451,1, +1958,4854,17,4794,1, +0,4797,1,107,3052, +1,2033,2020,1,525, +3145,1,93,3063,1, +1377,4295,1,82,3023, +1,1804,4855,17,4794, +1,0,4797,1,1803, +2052,1,1370,4306,1, +74,3089,1,2227,2029, +1,70,3057,1,69, +3095,1,68,3099,1, +67,2997,1,66,3104, +1,63,3127,1,1775, +4856,17,4794,1,0, +4797,1,50,3181,1, +480,3006,1,48,3132, +1,47,3136,1,477, +3081,1,476,3085,1, +44,3138,1,2198,4857, +17,4794,1,0,4797, +1,51,3123,1,40, +3179,1,1332,4347,1, +32,4858,17,4794,1, +0,4797,1,1341,4337, +1,1442,4427,1,19, +4461,1,447,3117,1, +1737,4859,16,0,144, +1,1303,4382,1,9, +4483,1,1730,4433,1, +1296,4392,1,10,4860, +19,524,1,10,4861, +5,2,1,40,4862, +16,0,522,1,1114, +4863,16,0,639,1, +9,4864,19,512,1, +9,4865,5,2,1, +40,4866,16,0,510, +1,1114,4867,16,0, +613,1,8,4868,19, +480,1,8,4869,5, +2,1,40,4870,16, +0,478,1,1114,4871, +16,0,590,1,7, +4872,19,464,1,7, +4873,5,2,1,40, +4874,16,0,462,1, +1114,4875,16,0,574, +1,6,4876,19,453, +1,6,4877,5,2, +1,40,4878,16,0, +451,1,1114,4879,16, +0,564,1,5,4880, +19,552,1,5,4881, +5,100,1,1574,1895, +1,2035,1900,1,1371, +4882,16,0,550,1, +71,4883,16,0,550, +1,1958,4884,16,0, +550,1,381,4885,16, +0,550,1,2106,4886, +16,0,550,1,1931, +1909,1,1756,4887,16, +0,550,1,2031,1915, +1,509,4888,16,0, +550,1,2337,4889,16, +0,550,1,2029,1921, +1,1153,4890,16,0, +550,1,2136,1926,1, +1933,4891,16,0,550, +1,2198,4892,16,0, +550,1,1731,4893,16, +0,550,1,1335,4894, +16,0,550,1,2318, +4895,16,0,550,1, +346,4896,16,0,550, +1,182,4897,16,0, +550,1,137,4898,16, +0,550,1,1515,4899, +16,0,550,1,2105, +1940,1,1775,4900,16, +0,550,1,1117,4901, +16,0,550,1,525, +4902,16,0,550,1, +1114,4903,16,0,751, +1,1901,4904,16,0, +550,1,2293,4905,16, +0,550,1,322,4906, +16,0,550,1,124, +4907,16,0,550,1, +1695,4908,16,0,550, +1,1297,4909,16,0, +550,1,151,4910,16, +0,550,1,44,4911, +16,0,749,1,112, +4912,16,0,550,1, +1990,4913,16,0,550, +1,76,4914,16,0, +550,1,43,4915,16, +0,550,1,2075,4916, +16,0,550,1,1876, +4917,16,0,550,1, +299,4918,16,0,550, +1,1479,4919,16,0, +550,1,2462,1963,1, +97,4920,16,0,550, +1,2459,1969,1,2458, +1974,1,2030,1978,1, +89,4921,16,0,550, +1,1860,1983,1,85, +4922,16,0,550,1, +1659,4923,16,0,550, +1,1657,1990,1,277, +4924,16,0,550,1, +1261,4925,16,0,550, +1,166,4926,16,0, +550,1,2045,1997,1, +2043,2001,1,2041,2005, +1,2039,2009,1,462, +4927,16,0,550,1, +2037,2014,1,66,4928, +16,0,738,1,459, +4929,16,0,550,1, +1443,4930,16,0,550, +1,2033,2020,1,2032, +2024,1,1834,4931,16, +0,550,1,2227,2029, +1,256,4932,16,0, +550,1,447,4933,16, +0,550,1,52,4934, +16,0,550,1,2021, +2036,1,63,4935,16, +0,736,1,2413,4936, +16,0,550,1,47, +4937,16,0,751,1, +1622,4938,16,0,550, +1,2464,2042,1,1225, +4939,16,0,550,1, +41,4940,16,0,550, +1,40,4941,16,0, +749,1,236,4942,16, +0,550,1,431,4943, +16,0,550,1,32, +4944,16,0,550,1, +1804,4945,16,0,550, +1,1803,2052,1,1407, +4946,16,0,550,1, +79,4947,16,0,550, +1,217,4948,16,0, +550,1,1989,2060,1, +102,4949,16,0,550, +1,2786,4950,16,0, +550,1,406,4951,16, +0,550,1,1585,4952, +16,0,550,1,1189, +4953,16,0,550,1, +1873,2069,1,199,4954, +16,0,550,1,2364, +2074,1,4,4955,19, +546,1,4,4956,5, +100,1,1574,1895,1, +2035,1900,1,1371,4957, +16,0,544,1,71, +4958,16,0,544,1, +1958,4959,16,0,544, +1,381,4960,16,0, +544,1,2106,4961,16, +0,544,1,1931,1909, +1,1756,4962,16,0, +544,1,2031,1915,1, +509,4963,16,0,544, +1,2337,4964,16,0, +544,1,2029,1921,1, +1153,4965,16,0,544, +1,2136,1926,1,1933, +4966,16,0,544,1, +2198,4967,16,0,544, +1,1731,4968,16,0, +544,1,1335,4969,16, +0,544,1,2318,4970, +16,0,544,1,346, +4971,16,0,544,1, +182,4972,16,0,544, +1,137,4973,16,0, +544,1,1515,4974,16, +0,544,1,2105,1940, +1,1775,4975,16,0, +544,1,1117,4976,16, +0,544,1,525,4977, +16,0,544,1,1114, +4978,16,0,750,1, +1901,4979,16,0,544, +1,2293,4980,16,0, +544,1,322,4981,16, +0,544,1,124,4982, +16,0,544,1,1695, +4983,16,0,544,1, +1297,4984,16,0,544, +1,151,4985,16,0, +544,1,44,4986,16, +0,748,1,112,4987, +16,0,544,1,1990, +4988,16,0,544,1, +76,4989,16,0,544, +1,43,4990,16,0, +544,1,2075,4991,16, +0,544,1,1876,4992, +16,0,544,1,299, +4993,16,0,544,1, +1479,4994,16,0,544, +1,2462,1963,1,97, +4995,16,0,544,1, +2459,1969,1,2458,1974, +1,2030,1978,1,89, +4996,16,0,544,1, +1860,1983,1,85,4997, +16,0,544,1,1659, +4998,16,0,544,1, +1657,1990,1,277,4999, +16,0,544,1,1261, +5000,16,0,544,1, +166,5001,16,0,544, +1,2045,1997,1,2043, +2001,1,2041,2005,1, +2039,2009,1,462,5002, +16,0,544,1,2037, +2014,1,66,5003,16, +0,737,1,459,5004, +16,0,544,1,1443, +5005,16,0,544,1, +2033,2020,1,2032,2024, +1,1834,5006,16,0, +544,1,2227,2029,1, +256,5007,16,0,544, +1,447,5008,16,0, +544,1,52,5009,16, +0,544,1,2021,2036, +1,63,5010,16,0, +735,1,2413,5011,16, +0,544,1,47,5012, +16,0,750,1,1622, +5013,16,0,544,1, +2464,2042,1,1225,5014, +16,0,544,1,41, +5015,16,0,544,1, +40,5016,16,0,748, +1,236,5017,16,0, +544,1,431,5018,16, +0,544,1,32,5019, +16,0,544,1,1804, +5020,16,0,544,1, +1803,2052,1,1407,5021, +16,0,544,1,79, +5022,16,0,544,1, +217,5023,16,0,544, +1,1989,2060,1,102, +5024,16,0,544,1, +2786,5025,16,0,544, +1,406,5026,16,0, +544,1,1585,5027,16, +0,544,1,1189,5028, +16,0,544,1,1873, +2069,1,199,5029,16, +0,544,1,2364,2074, +1,3,5030,19,500, +1,3,5031,5,95, +1,1574,1895,1,2035, +1900,1,1371,5032,16, +0,498,1,71,5033, +16,0,498,1,1958, +5034,16,0,498,1, +381,5035,16,0,498, +1,2106,5036,16,0, +498,1,1931,1909,1, +1756,5037,16,0,498, +1,2031,1915,1,509, +5038,16,0,498,1, +2337,5039,16,0,498, +1,2029,1921,1,1153, +5040,16,0,498,1, +2136,1926,1,1933,5041, +16,0,498,1,2198, +5042,16,0,498,1, +1731,5043,16,0,498, +1,1335,5044,16,0, +498,1,2318,5045,16, +0,498,1,346,5046, +16,0,498,1,182, +5047,16,0,498,1, +137,5048,16,0,498, +1,1515,5049,16,0, +498,1,2105,1940,1, +1775,5050,16,0,498, +1,1117,5051,16,0, +498,1,525,5052,16, +0,498,1,52,5053, +16,0,498,1,1901, +5054,16,0,498,1, +2293,5055,16,0,498, +1,322,5056,16,0, +498,1,124,5057,16, +0,498,1,1695,5058, +16,0,498,1,1297, +5059,16,0,498,1, +151,5060,16,0,498, +1,112,5061,16,0, +498,1,1990,5062,16, +0,498,1,76,5063, +16,0,498,1,43, +5064,16,0,498,1, +2075,5065,16,0,498, +1,1876,5066,16,0, +498,1,299,5067,16, +0,498,1,1479,5068, +16,0,498,1,2462, +1963,1,97,5069,16, +0,498,1,2459,1969, +1,2458,1974,1,2030, +1978,1,89,5070,16, +0,498,1,1860,1983, +1,85,5071,16,0, +498,1,1659,5072,16, +0,498,1,1657,1990, +1,277,5073,16,0, +498,1,1261,5074,16, +0,498,1,166,5075, +16,0,498,1,2045, +1997,1,2043,2001,1, +2041,2005,1,2039,2009, +1,462,5076,16,0, +498,1,2037,2014,1, +459,5077,16,0,498, +1,1443,5078,16,0, +498,1,2033,2020,1, +2032,2024,1,1834,5079, +16,0,498,1,2227, +2029,1,256,5080,16, +0,498,1,447,5081, +16,0,498,1,62, +5082,16,0,498,1, +2021,2036,1,2413,5083, +16,0,498,1,1622, +5084,16,0,498,1, +2464,2042,1,1225,5085, +16,0,498,1,41, +5086,16,0,498,1, +236,5087,16,0,498, +1,431,5088,16,0, +498,1,32,5089,16, +0,498,1,1804,5090, +16,0,498,1,1803, +2052,1,1407,5091,16, +0,498,1,79,5092, +16,0,498,1,217, +5093,16,0,498,1, +1989,2060,1,102,5094, +16,0,498,1,2786, +5095,16,0,498,1, +406,5096,16,0,498, +1,1585,5097,16,0, +498,1,1189,5098,16, +0,498,1,1873,2069, +1,199,5099,16,0, +498,1,2364,2074,1, +2,5100,19,572,1, +2,5101,5,6,1, +2768,2876,1,2649,2872, +1,2767,2893,1,2834, +5102,17,5103,15,5104, +4,30,37,0,76, +0,83,0,76,0, +80,0,114,0,111, +0,103,0,114,0, +97,0,109,0,82, +0,111,0,111,0, +116,0,1,-1,1, +5,5105,20,1810,1, +167,1,3,1,3, +1,2,5106,22,1, +1,1,2764,5107,17, +5108,15,5104,1,-1, +1,5,5109,20,1806, +1,168,1,3,1, +2,1,1,5110,22, +1,2,1,2755,2866, +2,0,0}; +new Sfactory(this,"IncrementDecrementExpression_1",new SCreator(IncrementDecrementExpression_1_factory)); +new Sfactory(this,"StateChange",new SCreator(StateChange_factory)); +new Sfactory(this,"ArgumentDeclarationList_3",new SCreator(ArgumentDeclarationList_3_factory)); +new Sfactory(this,"BinaryExpression",new SCreator(BinaryExpression_factory)); +new Sfactory(this,"VoidArgEvent_5",new SCreator(VoidArgEvent_5_factory)); new Sfactory(this,"IdentDotExpression_1",new SCreator(IdentDotExpression_1_factory)); -new Sfactory(this,"ArgumentList_4",new SCreator(ArgumentList_4_factory)); -new Sfactory(this,"Typename",new SCreator(Typename_factory)); -new Sfactory(this,"IfStatement_1",new SCreator(IfStatement_1_factory)); -new Sfactory(this,"RotationConstant_1",new SCreator(RotationConstant_1_factory)); -new Sfactory(this,"Assignment",new SCreator(Assignment_factory)); -new Sfactory(this,"IfStatement_4",new SCreator(IfStatement_4_factory)); -new Sfactory(this,"CompoundStatement_1",new SCreator(CompoundStatement_1_factory)); -new Sfactory(this,"CompoundStatement_2",new SCreator(CompoundStatement_2_factory)); -new Sfactory(this,"KeyIntIntArgumentDeclarationList_1",new SCreator(KeyIntIntArgumentDeclarationList_1_factory)); -new Sfactory(this,"BinaryExpression_8",new SCreator(BinaryExpression_8_factory)); -new Sfactory(this,"VectorArgEvent",new SCreator(VectorArgEvent_factory)); +new Sfactory(this,"StateBody_10",new SCreator(StateBody_10_factory)); +new Sfactory(this,"VectorArgEvent_1",new SCreator(VectorArgEvent_1_factory)); new Sfactory(this,"ReturnStatement_1",new SCreator(ReturnStatement_1_factory)); +new Sfactory(this,"ReturnStatement_2",new SCreator(ReturnStatement_2_factory)); +new Sfactory(this,"Typename_7",new SCreator(Typename_7_factory)); +new Sfactory(this,"ExpressionArgument",new SCreator(ExpressionArgument_factory)); +new Sfactory(this,"ForLoop",new SCreator(ForLoop_factory)); +new Sfactory(this,"GlobalDefinitions",new SCreator(GlobalDefinitions_factory)); +new Sfactory(this,"Typename_1",new SCreator(Typename_1_factory)); +new Sfactory(this,"TypecastExpression_3",new SCreator(TypecastExpression_3_factory)); +new Sfactory(this,"IncrementDecrementExpression_6",new SCreator(IncrementDecrementExpression_6_factory)); +new Sfactory(this,"SimpleAssignment_2",new SCreator(SimpleAssignment_2_factory)); +new Sfactory(this,"IntVecVecArgEvent_1",new SCreator(IntVecVecArgEvent_1_factory)); +new Sfactory(this,"LSLProgramRoot_2",new SCreator(LSLProgramRoot_2_factory)); new Sfactory(this,"IdentDotExpression",new SCreator(IdentDotExpression_factory)); -new Sfactory(this,"Argument",new SCreator(Argument_factory)); +new Sfactory(this,"UnaryExpression_1",new SCreator(UnaryExpression_1_factory)); +new Sfactory(this,"RotationConstant",new SCreator(RotationConstant_factory)); +new Sfactory(this,"IntArgumentDeclarationList",new SCreator(IntArgumentDeclarationList_factory)); +new Sfactory(this,"ArgumentList",new SCreator(ArgumentList_factory)); +new Sfactory(this,"BinaryExpression_3",new SCreator(BinaryExpression_3_factory)); +new Sfactory(this,"Event_2",new SCreator(Event_2_factory)); +new Sfactory(this,"ArgumentList_4",new SCreator(ArgumentList_4_factory)); +new Sfactory(this,"IntVecVecArgEvent",new SCreator(IntVecVecArgEvent_factory)); +new Sfactory(this,"WhileStatement_2",new SCreator(WhileStatement_2_factory)); +new Sfactory(this,"Assignment",new SCreator(Assignment_factory)); +new Sfactory(this,"Statement_12",new SCreator(Statement_12_factory)); +new Sfactory(this,"IncrementDecrementExpression_8",new SCreator(IncrementDecrementExpression_8_factory)); +new Sfactory(this,"VectorArgEvent_2",new SCreator(VectorArgEvent_2_factory)); +new Sfactory(this,"Constant_2",new SCreator(Constant_2_factory)); +new Sfactory(this,"Statement_1",new SCreator(Statement_1_factory)); +new Sfactory(this,"VectorArgEvent",new SCreator(VectorArgEvent_factory)); +new Sfactory(this,"ForLoopStatement_1",new SCreator(ForLoopStatement_1_factory)); +new Sfactory(this,"IncrementDecrementExpression_2",new SCreator(IncrementDecrementExpression_2_factory)); +new Sfactory(this,"IntArgumentDeclarationList_1",new SCreator(IntArgumentDeclarationList_1_factory)); +new Sfactory(this,"VoidArgEvent_4",new SCreator(VoidArgEvent_4_factory)); +new Sfactory(this,"ForLoop_1",new SCreator(ForLoop_1_factory)); +new Sfactory(this,"Typename_4",new SCreator(Typename_4_factory)); +new Sfactory(this,"IdentExpression",new SCreator(IdentExpression_factory)); +new Sfactory(this,"ForLoop_2",new SCreator(ForLoop_2_factory)); +new Sfactory(this,"DoWhileStatement",new SCreator(DoWhileStatement_factory)); +new Sfactory(this,"SimpleAssignment_6",new SCreator(SimpleAssignment_6_factory)); +new Sfactory(this,"IntDeclaration_1",new SCreator(IntDeclaration_1_factory)); +new Sfactory(this,"State_1",new SCreator(State_1_factory)); +new Sfactory(this,"StateBody_9",new SCreator(StateBody_9_factory)); +new Sfactory(this,"StateBody_8",new SCreator(StateBody_8_factory)); new Sfactory(this,"State_2",new SCreator(State_2_factory)); -new Sfactory(this,"GlobalDefinitions_3",new SCreator(GlobalDefinitions_3_factory)); -new Sfactory(this,"GlobalDefinitions_4",new SCreator(GlobalDefinitions_4_factory)); -new Sfactory(this,"Event_1",new SCreator(Event_1_factory)); -new Sfactory(this,"ListConstant",new SCreator(ListConstant_factory)); +new Sfactory(this,"StateBody_3",new SCreator(StateBody_3_factory)); +new Sfactory(this,"StateBody_2",new SCreator(StateBody_2_factory)); +new Sfactory(this,"StateBody_1",new SCreator(StateBody_1_factory)); +new Sfactory(this,"Typename_6",new SCreator(Typename_6_factory)); +new Sfactory(this,"StateBody_7",new SCreator(StateBody_7_factory)); +new Sfactory(this,"StateBody_4",new SCreator(StateBody_4_factory)); +new Sfactory(this,"IfStatement_1",new SCreator(IfStatement_1_factory)); +new Sfactory(this,"IfStatement_3",new SCreator(IfStatement_3_factory)); +new Sfactory(this,"IfStatement_2",new SCreator(IfStatement_2_factory)); +new Sfactory(this,"SimpleAssignment_1",new SCreator(SimpleAssignment_1_factory)); +new Sfactory(this,"VoidArgEvent_6",new SCreator(VoidArgEvent_6_factory)); +new Sfactory(this,"IfStatement",new SCreator(IfStatement_factory)); +new Sfactory(this,"ConstantExpression",new SCreator(ConstantExpression_factory)); +new Sfactory(this,"BinaryExpression_7",new SCreator(BinaryExpression_7_factory)); +new Sfactory(this,"IncrementDecrementExpression",new SCreator(IncrementDecrementExpression_factory)); +new Sfactory(this,"Statement_9",new SCreator(Statement_9_factory)); +new Sfactory(this,"IntVecVecArgStateEvent",new SCreator(IntVecVecArgStateEvent_factory)); +new Sfactory(this,"Declaration_1",new SCreator(Declaration_1_factory)); +new Sfactory(this,"KeyIntIntArgumentDeclarationList",new SCreator(KeyIntIntArgumentDeclarationList_factory)); +new Sfactory(this,"VectorArgumentDeclarationList_1",new SCreator(VectorArgumentDeclarationList_1_factory)); +new Sfactory(this,"SimpleAssignment",new SCreator(SimpleAssignment_factory)); +new Sfactory(this,"BinaryExpression_9",new SCreator(BinaryExpression_9_factory)); +new Sfactory(this,"IntDeclaration",new SCreator(IntDeclaration_factory)); +new Sfactory(this,"IntArgEvent_10",new SCreator(IntArgEvent_10_factory)); +new Sfactory(this,"ArgumentDeclarationList_2",new SCreator(ArgumentDeclarationList_2_factory)); +new Sfactory(this,"ArgumentDeclarationList_1",new SCreator(ArgumentDeclarationList_1_factory)); +new Sfactory(this,"ArgumentDeclarationList_4",new SCreator(ArgumentDeclarationList_4_factory)); +new Sfactory(this,"SimpleAssignment_9",new SCreator(SimpleAssignment_9_factory)); +new Sfactory(this,"ForLoopStatement_2",new SCreator(ForLoopStatement_2_factory)); +new Sfactory(this,"StatementList",new SCreator(StatementList_factory)); +new Sfactory(this,"StateBody_13",new SCreator(StateBody_13_factory)); +new Sfactory(this,"Typename_3",new SCreator(Typename_3_factory)); +new Sfactory(this,"KeyArgumentDeclarationList_1",new SCreator(KeyArgumentDeclarationList_1_factory)); +new Sfactory(this,"UnaryExpression_3",new SCreator(UnaryExpression_3_factory)); +new Sfactory(this,"StateBody_16",new SCreator(StateBody_16_factory)); +new Sfactory(this,"VectorArgumentDeclarationList",new SCreator(VectorArgumentDeclarationList_factory)); +new Sfactory(this,"IntArgEvent_3",new SCreator(IntArgEvent_3_factory)); +new Sfactory(this,"StatementList_2",new SCreator(StatementList_2_factory)); +new Sfactory(this,"KeyArgStateEvent",new SCreator(KeyArgStateEvent_factory)); +new Sfactory(this,"LSLProgramRoot_1",new SCreator(LSLProgramRoot_1_factory)); +new Sfactory(this,"Typename_2",new SCreator(Typename_2_factory)); +new Sfactory(this,"TypecastExpression_6",new SCreator(TypecastExpression_6_factory)); new Sfactory(this,"Event_3",new SCreator(Event_3_factory)); -new Sfactory(this,"Event_4",new SCreator(Event_4_factory)); +new Sfactory(this,"IntArgStateEvent",new SCreator(IntArgStateEvent_factory)); +new Sfactory(this,"StateChange_2",new SCreator(StateChange_2_factory)); +new Sfactory(this,"StateChange_1",new SCreator(StateChange_1_factory)); +new Sfactory(this,"VectorConstant_1",new SCreator(VectorConstant_1_factory)); +new Sfactory(this,"KeyDeclaration",new SCreator(KeyDeclaration_factory)); +new Sfactory(this,"States_2",new SCreator(States_2_factory)); +new Sfactory(this,"VoidArgEvent",new SCreator(VoidArgEvent_factory)); +new Sfactory(this,"WhileStatement",new SCreator(WhileStatement_factory)); +new Sfactory(this,"UnaryExpression",new SCreator(UnaryExpression_factory)); +new Sfactory(this,"BinaryExpression_6",new SCreator(BinaryExpression_6_factory)); +new Sfactory(this,"ConstantExpression_1",new SCreator(ConstantExpression_1_factory)); +new Sfactory(this,"ForLoopStatement",new SCreator(ForLoopStatement_factory)); +new Sfactory(this,"BinaryExpression_1",new SCreator(BinaryExpression_1_factory)); +new Sfactory(this,"StateEvent",new SCreator(StateEvent_factory)); new Sfactory(this,"Event_5",new SCreator(Event_5_factory)); new Sfactory(this,"SimpleAssignment_5",new SCreator(SimpleAssignment_5_factory)); -new Sfactory(this,"Typename_1",new SCreator(Typename_1_factory)); -new Sfactory(this,"VoidArgStateEvent_1",new SCreator(VoidArgStateEvent_1_factory)); -new Sfactory(this,"Typename_3",new SCreator(Typename_3_factory)); -new Sfactory(this,"IntRotRotArgStateEvent",new SCreator(IntRotRotArgStateEvent_factory)); -new Sfactory(this,"Typename_5",new SCreator(Typename_5_factory)); -new Sfactory(this,"Typename_6",new SCreator(Typename_6_factory)); -new Sfactory(this,"Typename_7",new SCreator(Typename_7_factory)); -new Sfactory(this,"ArgumentDeclarationList",new SCreator(ArgumentDeclarationList_factory)); -new Sfactory(this,"ConstantExpression",new SCreator(ConstantExpression_factory)); -new Sfactory(this,"LSLProgramRoot_1",new SCreator(LSLProgramRoot_1_factory)); -new Sfactory(this,"LSLProgramRoot_2",new SCreator(LSLProgramRoot_2_factory)); -new Sfactory(this,"KeyIntIntArgEvent_1",new SCreator(KeyIntIntArgEvent_1_factory)); -new Sfactory(this,"States_1",new SCreator(States_1_factory)); -new Sfactory(this,"States_2",new SCreator(States_2_factory)); -new Sfactory(this,"FunctionCallExpression_1",new SCreator(FunctionCallExpression_1_factory)); -new Sfactory(this,"KeyArgEvent_1",new SCreator(KeyArgEvent_1_factory)); -new Sfactory(this,"ForLoopStatement",new SCreator(ForLoopStatement_factory)); -new Sfactory(this,"IntArgStateEvent",new SCreator(IntArgStateEvent_factory)); -new Sfactory(this,"StateBody_15",new SCreator(StateBody_15_factory)); -new Sfactory(this,"IntRotRotArgumentDeclarationList_1",new SCreator(IntRotRotArgumentDeclarationList_1_factory)); -new Sfactory(this,"IntArgEvent_9",new SCreator(IntArgEvent_9_factory)); -new Sfactory(this,"DoWhileStatement_1",new SCreator(DoWhileStatement_1_factory)); -new Sfactory(this,"DoWhileStatement_2",new SCreator(DoWhileStatement_2_factory)); -new Sfactory(this,"ForLoopStatement_4",new SCreator(ForLoopStatement_4_factory)); -new Sfactory(this,"SimpleAssignment_11",new SCreator(SimpleAssignment_11_factory)); -new Sfactory(this,"SimpleAssignment_12",new SCreator(SimpleAssignment_12_factory)); -new Sfactory(this,"SimpleAssignment_13",new SCreator(SimpleAssignment_13_factory)); -new Sfactory(this,"JumpLabel",new SCreator(JumpLabel_factory)); -new Sfactory(this,"SimpleAssignment_15",new SCreator(SimpleAssignment_15_factory)); -new Sfactory(this,"IntVecVecArgEvent",new SCreator(IntVecVecArgEvent_factory)); -new Sfactory(this,"VecDeclaration",new SCreator(VecDeclaration_factory)); -new Sfactory(this,"StateBody_14",new SCreator(StateBody_14_factory)); -new Sfactory(this,"GlobalDefinitions",new SCreator(GlobalDefinitions_factory)); -new Sfactory(this,"StateBody_16",new SCreator(StateBody_16_factory)); -new Sfactory(this,"KeyIntIntArgumentDeclarationList",new SCreator(KeyIntIntArgumentDeclarationList_factory)); -new Sfactory(this,"ConstantExpression_1",new SCreator(ConstantExpression_1_factory)); -new Sfactory(this,"VoidArgEvent_4",new SCreator(VoidArgEvent_4_factory)); -new Sfactory(this,"FunctionCall_1",new SCreator(FunctionCall_1_factory)); -new Sfactory(this,"Assignment_1",new SCreator(Assignment_1_factory)); -new Sfactory(this,"Assignment_2",new SCreator(Assignment_2_factory)); -new Sfactory(this,"IntVecVecArgEvent_1",new SCreator(IntVecVecArgEvent_1_factory)); -new Sfactory(this,"TypecastExpression_1",new SCreator(TypecastExpression_1_factory)); -new Sfactory(this,"SimpleAssignment_21",new SCreator(SimpleAssignment_21_factory)); -new Sfactory(this,"SimpleAssignment_22",new SCreator(SimpleAssignment_22_factory)); -new Sfactory(this,"KeyIntIntArgStateEvent",new SCreator(KeyIntIntArgStateEvent_factory)); -new Sfactory(this,"TypecastExpression_9",new SCreator(TypecastExpression_9_factory)); -new Sfactory(this,"VoidArgEvent_2",new SCreator(VoidArgEvent_2_factory)); -new Sfactory(this,"Event_9",new SCreator(Event_9_factory)); -new Sfactory(this,"ArgumentDeclarationList_1",new SCreator(ArgumentDeclarationList_1_factory)); -new Sfactory(this,"ArgumentDeclarationList_2",new SCreator(ArgumentDeclarationList_2_factory)); -new Sfactory(this,"GlobalDefinitions_1",new SCreator(GlobalDefinitions_1_factory)); -new Sfactory(this,"GlobalDefinitions_2",new SCreator(GlobalDefinitions_2_factory)); -new Sfactory(this,"IncrementDecrementExpression",new SCreator(IncrementDecrementExpression_factory)); -new Sfactory(this,"GlobalVariableDeclaration",new SCreator(GlobalVariableDeclaration_factory)); -new Sfactory(this,"IntArgumentDeclarationList_1",new SCreator(IntArgumentDeclarationList_1_factory)); -new Sfactory(this,"IntDeclaration_1",new SCreator(IntDeclaration_1_factory)); -new Sfactory(this,"ArgumentDeclarationList_5",new SCreator(ArgumentDeclarationList_5_factory)); -new Sfactory(this,"IntVecVecArgumentDeclarationList",new SCreator(IntVecVecArgumentDeclarationList_factory)); -new Sfactory(this,"VectorArgumentDeclarationList_1",new SCreator(VectorArgumentDeclarationList_1_factory)); -new Sfactory(this,"KeyArgumentDeclarationList",new SCreator(KeyArgumentDeclarationList_factory)); -new Sfactory(this,"TypecastExpression_2",new SCreator(TypecastExpression_2_factory)); -new Sfactory(this,"KeyArgStateEvent",new SCreator(KeyArgStateEvent_factory)); -new Sfactory(this,"TypecastExpression_5",new SCreator(TypecastExpression_5_factory)); -new Sfactory(this,"TypecastExpression_8",new SCreator(TypecastExpression_8_factory)); -new Sfactory(this,"Constant_1",new SCreator(Constant_1_factory)); -new Sfactory(this,"Expression",new SCreator(Expression_factory)); -new Sfactory(this,"Constant_3",new SCreator(Constant_3_factory)); -new Sfactory(this,"Constant_4",new SCreator(Constant_4_factory)); -new Sfactory(this,"IntArgEvent_5",new SCreator(IntArgEvent_5_factory)); -new Sfactory(this,"BinaryExpression_1",new SCreator(BinaryExpression_1_factory)); -new Sfactory(this,"IfStatement_2",new SCreator(IfStatement_2_factory)); -new Sfactory(this,"IfStatement_3",new SCreator(IfStatement_3_factory)); -new Sfactory(this,"KeyArgEvent",new SCreator(KeyArgEvent_factory)); -new Sfactory(this,"Event_2",new SCreator(Event_2_factory)); -new Sfactory(this,"JumpLabel_1",new SCreator(JumpLabel_1_factory)); -new Sfactory(this,"RotationConstant",new SCreator(RotationConstant_factory)); -new Sfactory(this,"Statement_12",new SCreator(Statement_12_factory)); -new Sfactory(this,"Statement_13",new SCreator(Statement_13_factory)); -new Sfactory(this,"UnaryExpression_1",new SCreator(UnaryExpression_1_factory)); -new Sfactory(this,"UnaryExpression_2",new SCreator(UnaryExpression_2_factory)); -new Sfactory(this,"UnaryExpression_3",new SCreator(UnaryExpression_3_factory)); -new Sfactory(this,"ArgumentList_1",new SCreator(ArgumentList_1_factory)); -new Sfactory(this,"KeyIntIntArgEvent",new SCreator(KeyIntIntArgEvent_factory)); -new Sfactory(this,"ArgumentList_3",new SCreator(ArgumentList_3_factory)); +new Sfactory(this,"RotationConstant_1",new SCreator(RotationConstant_1_factory)); new Sfactory(this,"Constant",new SCreator(Constant_factory)); -new Sfactory(this,"State",new SCreator(State_factory)); -new Sfactory(this,"StateBody_13",new SCreator(StateBody_13_factory)); -new Sfactory(this,"KeyArgStateEvent_1",new SCreator(KeyArgStateEvent_1_factory)); +new Sfactory(this,"IntArgEvent_1",new SCreator(IntArgEvent_1_factory)); new Sfactory(this,"SimpleAssignment_8",new SCreator(SimpleAssignment_8_factory)); +new Sfactory(this,"ForLoopStatement_3",new SCreator(ForLoopStatement_3_factory)); +new Sfactory(this,"IntArgEvent_2",new SCreator(IntArgEvent_2_factory)); new Sfactory(this,"LSLProgramRoot",new SCreator(LSLProgramRoot_factory)); -new Sfactory(this,"StateChange",new SCreator(StateChange_factory)); -new Sfactory(this,"VecDeclaration_1",new SCreator(VecDeclaration_1_factory)); -new Sfactory(this,"GlobalVariableDeclaration_1",new SCreator(GlobalVariableDeclaration_1_factory)); -new Sfactory(this,"GlobalVariableDeclaration_2",new SCreator(GlobalVariableDeclaration_2_factory)); -new Sfactory(this,"IncrementDecrementExpression_5",new SCreator(IncrementDecrementExpression_5_factory)); -new Sfactory(this,"ReturnStatement",new SCreator(ReturnStatement_factory)); -new Sfactory(this,"StateBody_10",new SCreator(StateBody_10_factory)); -new Sfactory(this,"StateBody_11",new SCreator(StateBody_11_factory)); new Sfactory(this,"StateBody_12",new SCreator(StateBody_12_factory)); -new Sfactory(this,"IntVecVecArgStateEvent_1",new SCreator(IntVecVecArgStateEvent_1_factory)); -new Sfactory(this,"KeyDeclaration",new SCreator(KeyDeclaration_factory)); +new Sfactory(this,"IntArgEvent_4",new SCreator(IntArgEvent_4_factory)); +new Sfactory(this,"IntArgEvent_7",new SCreator(IntArgEvent_7_factory)); new Sfactory(this,"IntArgEvent_6",new SCreator(IntArgEvent_6_factory)); -new Sfactory(this,"ArgumentDeclarationList_3",new SCreator(ArgumentDeclarationList_3_factory)); -new Sfactory(this,"ArgumentList_2",new SCreator(ArgumentList_2_factory)); -new Sfactory(this,"IntArgEvent_10",new SCreator(IntArgEvent_10_factory)); -new Sfactory(this,"CompoundStatement",new SCreator(CompoundStatement_factory)); -new Sfactory(this,"TypecastExpression_3",new SCreator(TypecastExpression_3_factory)); -new Sfactory(this,"IntArgumentDeclarationList",new SCreator(IntArgumentDeclarationList_factory)); -new Sfactory(this,"ArgumentDeclarationList_4",new SCreator(ArgumentDeclarationList_4_factory)); -new Sfactory(this,"SimpleAssignment_3",new SCreator(SimpleAssignment_3_factory)); +new Sfactory(this,"IntArgEvent_9",new SCreator(IntArgEvent_9_factory)); +new Sfactory(this,"TypecastExpression_7",new SCreator(TypecastExpression_7_factory)); +new Sfactory(this,"StateBody_15",new SCreator(StateBody_15_factory)); +new Sfactory(this,"VoidArgStateEvent_1",new SCreator(VoidArgStateEvent_1_factory)); +new Sfactory(this,"error",new SCreator(error_factory)); +new Sfactory(this,"TypecastExpression_1",new SCreator(TypecastExpression_1_factory)); +new Sfactory(this,"GlobalDefinitions_4",new SCreator(GlobalDefinitions_4_factory)); +new Sfactory(this,"GlobalDefinitions_3",new SCreator(GlobalDefinitions_3_factory)); +new Sfactory(this,"GlobalDefinitions_2",new SCreator(GlobalDefinitions_2_factory)); +new Sfactory(this,"GlobalDefinitions_1",new SCreator(GlobalDefinitions_1_factory)); +new Sfactory(this,"ArgumentList_1",new SCreator(ArgumentList_1_factory)); +new Sfactory(this,"IncrementDecrementExpression_7",new SCreator(IncrementDecrementExpression_7_factory)); +new Sfactory(this,"UnaryExpression_2",new SCreator(UnaryExpression_2_factory)); +new Sfactory(this,"Argument",new SCreator(Argument_factory)); +new Sfactory(this,"SimpleAssignment_24",new SCreator(SimpleAssignment_24_factory)); +new Sfactory(this,"ExpressionArgument_1",new SCreator(ExpressionArgument_1_factory)); +new Sfactory(this,"EmptyStatement",new SCreator(EmptyStatement_factory)); +new Sfactory(this,"KeyIntIntArgStateEvent",new SCreator(KeyIntIntArgStateEvent_factory)); +new Sfactory(this,"VectorArgStateEvent_1",new SCreator(VectorArgStateEvent_1_factory)); +new Sfactory(this,"GlobalFunctionDefinition_1",new SCreator(GlobalFunctionDefinition_1_factory)); +new Sfactory(this,"FunctionCallExpression_1",new SCreator(FunctionCallExpression_1_factory)); +new Sfactory(this,"DoWhileStatement_2",new SCreator(DoWhileStatement_2_factory)); +new Sfactory(this,"VoidArgEvent_1",new SCreator(VoidArgEvent_1_factory)); +new Sfactory(this,"KeyArgumentDeclarationList",new SCreator(KeyArgumentDeclarationList_factory)); +new Sfactory(this,"KeyIntIntArgEvent",new SCreator(KeyIntIntArgEvent_factory)); +new Sfactory(this,"ListConstant_1",new SCreator(ListConstant_1_factory)); +new Sfactory(this,"StateEvent_1",new SCreator(StateEvent_1_factory)); +new Sfactory(this,"SimpleAssignment_20",new SCreator(SimpleAssignment_20_factory)); +new Sfactory(this,"SimpleAssignment_23",new SCreator(SimpleAssignment_23_factory)); +new Sfactory(this,"SimpleAssignment_22",new SCreator(SimpleAssignment_22_factory)); +new Sfactory(this,"IntArgEvent_5",new SCreator(IntArgEvent_5_factory)); +new Sfactory(this,"ParenthesisExpression",new SCreator(ParenthesisExpression_factory)); +new Sfactory(this,"JumpStatement",new SCreator(JumpStatement_factory)); +new Sfactory(this,"IntRotRotArgumentDeclarationList_1",new SCreator(IntRotRotArgumentDeclarationList_1_factory)); new Sfactory(this,"SimpleAssignment_4",new SCreator(SimpleAssignment_4_factory)); -new Sfactory(this,"Statement_1",new SCreator(Statement_1_factory)); -new Sfactory(this,"Statement_2",new SCreator(Statement_2_factory)); +new Sfactory(this,"KeyArgEvent",new SCreator(KeyArgEvent_factory)); +new Sfactory(this,"Assignment_2",new SCreator(Assignment_2_factory)); +new Sfactory(this,"ForLoopStatement_4",new SCreator(ForLoopStatement_4_factory)); +new Sfactory(this,"Statement_13",new SCreator(Statement_13_factory)); +new Sfactory(this,"RotDeclaration",new SCreator(RotDeclaration_factory)); +new Sfactory(this,"StateBody_11",new SCreator(StateBody_11_factory)); +new Sfactory(this,"KeyArgEvent_2",new SCreator(KeyArgEvent_2_factory)); +new Sfactory(this,"StatementList_1",new SCreator(StatementList_1_factory)); +new Sfactory(this,"StateBody_6",new SCreator(StateBody_6_factory)); +new Sfactory(this,"Constant_1",new SCreator(Constant_1_factory)); +new Sfactory(this,"VecDeclaration",new SCreator(VecDeclaration_factory)); +new Sfactory(this,"TypecastExpression_5",new SCreator(TypecastExpression_5_factory)); +new Sfactory(this,"GlobalFunctionDefinition_2",new SCreator(GlobalFunctionDefinition_2_factory)); +new Sfactory(this,"KeyIntIntArgEvent_1",new SCreator(KeyIntIntArgEvent_1_factory)); +new Sfactory(this,"Constant_4",new SCreator(Constant_4_factory)); +new Sfactory(this,"TypecastExpression_9",new SCreator(TypecastExpression_9_factory)); +new Sfactory(this,"IntRotRotArgStateEvent_1",new SCreator(IntRotRotArgStateEvent_1_factory)); +new Sfactory(this,"IncrementDecrementExpression_3",new SCreator(IncrementDecrementExpression_3_factory)); +new Sfactory(this,"States_1",new SCreator(States_1_factory)); +new Sfactory(this,"GlobalVariableDeclaration",new SCreator(GlobalVariableDeclaration_factory)); +new Sfactory(this,"VoidArgEvent_3",new SCreator(VoidArgEvent_3_factory)); +new Sfactory(this,"Assignment_1",new SCreator(Assignment_1_factory)); +new Sfactory(this,"BinaryExpression_5",new SCreator(BinaryExpression_5_factory)); +new Sfactory(this,"IfStatement_4",new SCreator(IfStatement_4_factory)); +new Sfactory(this,"IntVecVecArgumentDeclarationList_1",new SCreator(IntVecVecArgumentDeclarationList_1_factory)); +new Sfactory(this,"KeyIntIntArgumentDeclarationList_1",new SCreator(KeyIntIntArgumentDeclarationList_1_factory)); +new Sfactory(this,"Statement",new SCreator(Statement_factory)); +new Sfactory(this,"ParenthesisExpression_1",new SCreator(ParenthesisExpression_1_factory)); +new Sfactory(this,"ParenthesisExpression_2",new SCreator(ParenthesisExpression_2_factory)); +new Sfactory(this,"DoWhileStatement_1",new SCreator(DoWhileStatement_1_factory)); +new Sfactory(this,"VoidArgStateEvent",new SCreator(VoidArgStateEvent_factory)); +new Sfactory(this,"GlobalFunctionDefinition",new SCreator(GlobalFunctionDefinition_factory)); +new Sfactory(this,"Event_4",new SCreator(Event_4_factory)); +new Sfactory(this,"IntArgEvent",new SCreator(IntArgEvent_factory)); +new Sfactory(this,"SimpleAssignment_11",new SCreator(SimpleAssignment_11_factory)); +new Sfactory(this,"SimpleAssignment_10",new SCreator(SimpleAssignment_10_factory)); +new Sfactory(this,"SimpleAssignment_13",new SCreator(SimpleAssignment_13_factory)); +new Sfactory(this,"SimpleAssignment_12",new SCreator(SimpleAssignment_12_factory)); +new Sfactory(this,"SimpleAssignment_15",new SCreator(SimpleAssignment_15_factory)); +new Sfactory(this,"SimpleAssignment_14",new SCreator(SimpleAssignment_14_factory)); +new Sfactory(this,"SimpleAssignment_17",new SCreator(SimpleAssignment_17_factory)); +new Sfactory(this,"SimpleAssignment_16",new SCreator(SimpleAssignment_16_factory)); +new Sfactory(this,"SimpleAssignment_19",new SCreator(SimpleAssignment_19_factory)); +new Sfactory(this,"SimpleAssignment_18",new SCreator(SimpleAssignment_18_factory)); +new Sfactory(this,"IntVecVecArgumentDeclarationList",new SCreator(IntVecVecArgumentDeclarationList_factory)); +new Sfactory(this,"StateBody_5",new SCreator(StateBody_5_factory)); +new Sfactory(this,"BinaryExpression_17",new SCreator(BinaryExpression_17_factory)); +new Sfactory(this,"BinaryExpression_16",new SCreator(BinaryExpression_16_factory)); +new Sfactory(this,"BinaryExpression_15",new SCreator(BinaryExpression_15_factory)); +new Sfactory(this,"BinaryExpression_14",new SCreator(BinaryExpression_14_factory)); +new Sfactory(this,"BinaryExpression_13",new SCreator(BinaryExpression_13_factory)); +new Sfactory(this,"BinaryExpression_12",new SCreator(BinaryExpression_12_factory)); +new Sfactory(this,"BinaryExpression_11",new SCreator(BinaryExpression_11_factory)); +new Sfactory(this,"BinaryExpression_10",new SCreator(BinaryExpression_10_factory)); +new Sfactory(this,"VectorArgStateEvent",new SCreator(VectorArgStateEvent_factory)); +new Sfactory(this,"Statement_10",new SCreator(Statement_10_factory)); +new Sfactory(this,"BinaryExpression_8",new SCreator(BinaryExpression_8_factory)); +new Sfactory(this,"BinaryExpression_18",new SCreator(BinaryExpression_18_factory)); +new Sfactory(this,"BinaryExpression_2",new SCreator(BinaryExpression_2_factory)); +new Sfactory(this,"FunctionCallExpression",new SCreator(FunctionCallExpression_factory)); +new Sfactory(this,"VectorArgEvent_3",new SCreator(VectorArgEvent_3_factory)); +new Sfactory(this,"IdentExpression_1",new SCreator(IdentExpression_1_factory)); +new Sfactory(this,"IntArgEvent_8",new SCreator(IntArgEvent_8_factory)); +new Sfactory(this,"VoidArgEvent_7",new SCreator(VoidArgEvent_7_factory)); +new Sfactory(this,"IncrementDecrementExpression_4",new SCreator(IncrementDecrementExpression_4_factory)); +new Sfactory(this,"FunctionCall",new SCreator(FunctionCall_factory)); +new Sfactory(this,"ArgumentList_3",new SCreator(ArgumentList_3_factory)); +new Sfactory(this,"KeyIntIntArgStateEvent_1",new SCreator(KeyIntIntArgStateEvent_1_factory)); +new Sfactory(this,"IntRotRotArgumentDeclarationList",new SCreator(IntRotRotArgumentDeclarationList_factory)); +new Sfactory(this,"KeyDeclaration_1",new SCreator(KeyDeclaration_1_factory)); +new Sfactory(this,"BinaryExpression_4",new SCreator(BinaryExpression_4_factory)); +new Sfactory(this,"FunctionCall_1",new SCreator(FunctionCall_1_factory)); +new Sfactory(this,"KeyArgStateEvent_1",new SCreator(KeyArgStateEvent_1_factory)); +new Sfactory(this,"IntArgStateEvent_1",new SCreator(IntArgStateEvent_1_factory)); +new Sfactory(this,"Event",new SCreator(Event_factory)); +new Sfactory(this,"IntRotRotArgEvent",new SCreator(IntRotRotArgEvent_factory)); +new Sfactory(this,"SimpleAssignment_7",new SCreator(SimpleAssignment_7_factory)); +new Sfactory(this,"Statement_3",new SCreator(Statement_3_factory)); +new Sfactory(this,"Expression",new SCreator(Expression_factory)); +new Sfactory(this,"CompoundStatement_2",new SCreator(CompoundStatement_2_factory)); +new Sfactory(this,"CompoundStatement_1",new SCreator(CompoundStatement_1_factory)); +new Sfactory(this,"JumpLabel",new SCreator(JumpLabel_factory)); +new Sfactory(this,"State",new SCreator(State_factory)); +new Sfactory(this,"TypecastExpression",new SCreator(TypecastExpression_factory)); +new Sfactory(this,"IntRotRotArgEvent_1",new SCreator(IntRotRotArgEvent_1_factory)); +new Sfactory(this,"Statement_11",new SCreator(Statement_11_factory)); +new Sfactory(this,"VoidArgEvent_2",new SCreator(VoidArgEvent_2_factory)); +new Sfactory(this,"Typename",new SCreator(Typename_factory)); +new Sfactory(this,"ArgumentDeclarationList",new SCreator(ArgumentDeclarationList_factory)); +new Sfactory(this,"StateBody",new SCreator(StateBody_factory)); +new Sfactory(this,"Event_8",new SCreator(Event_8_factory)); +new Sfactory(this,"Event_9",new SCreator(Event_9_factory)); +new Sfactory(this,"Event_6",new SCreator(Event_6_factory)); +new Sfactory(this,"Event_7",new SCreator(Event_7_factory)); +new Sfactory(this,"Statement_8",new SCreator(Statement_8_factory)); +new Sfactory(this,"CompoundStatement",new SCreator(CompoundStatement_factory)); +new Sfactory(this,"Event_1",new SCreator(Event_1_factory)); new Sfactory(this,"Statement_4",new SCreator(Statement_4_factory)); new Sfactory(this,"Statement_5",new SCreator(Statement_5_factory)); new Sfactory(this,"Statement_6",new SCreator(Statement_6_factory)); -new Sfactory(this,"Statement_8",new SCreator(Statement_8_factory)); -new Sfactory(this,"Statement_9",new SCreator(Statement_9_factory)); -new Sfactory(this,"ExpressionArgument",new SCreator(ExpressionArgument_factory)); -new Sfactory(this,"GlobalFunctionDefinition",new SCreator(GlobalFunctionDefinition_factory)); -new Sfactory(this,"State_1",new SCreator(State_1_factory)); -new Sfactory(this,"DoWhileStatement",new SCreator(DoWhileStatement_factory)); -new Sfactory(this,"ParenthesisExpression_1",new SCreator(ParenthesisExpression_1_factory)); -new Sfactory(this,"ParenthesisExpression_2",new SCreator(ParenthesisExpression_2_factory)); -new Sfactory(this,"StateBody",new SCreator(StateBody_factory)); -new Sfactory(this,"Event_7",new SCreator(Event_7_factory)); -new Sfactory(this,"Event_8",new SCreator(Event_8_factory)); -new Sfactory(this,"IncrementDecrementExpression_1",new SCreator(IncrementDecrementExpression_1_factory)); -new Sfactory(this,"IncrementDecrementExpression_2",new SCreator(IncrementDecrementExpression_2_factory)); -new Sfactory(this,"IntVecVecArgumentDeclarationList_1",new SCreator(IntVecVecArgumentDeclarationList_1_factory)); -new Sfactory(this,"IncrementDecrementExpression_4",new SCreator(IncrementDecrementExpression_4_factory)); -new Sfactory(this,"IncrementDecrementExpression_6",new SCreator(IncrementDecrementExpression_6_factory)); -new Sfactory(this,"IncrementDecrementExpression_7",new SCreator(IncrementDecrementExpression_7_factory)); -new Sfactory(this,"StateEvent",new SCreator(StateEvent_factory)); -new Sfactory(this,"IntArgEvent_3",new SCreator(IntArgEvent_3_factory)); -new Sfactory(this,"IntArgEvent_4",new SCreator(IntArgEvent_4_factory)); -new Sfactory(this,"KeyDeclaration_1",new SCreator(KeyDeclaration_1_factory)); -new Sfactory(this,"Statement_3",new SCreator(Statement_3_factory)); -new Sfactory(this,"IntArgEvent_7",new SCreator(IntArgEvent_7_factory)); -new Sfactory(this,"IntArgEvent_8",new SCreator(IntArgEvent_8_factory)); -new Sfactory(this,"SimpleAssignment_10",new SCreator(SimpleAssignment_10_factory)); -new Sfactory(this,"StatementList_2",new SCreator(StatementList_2_factory)); -new Sfactory(this,"IntRotRotArgStateEvent_1",new SCreator(IntRotRotArgStateEvent_1_factory)); -new Sfactory(this,"VectorArgEvent_2",new SCreator(VectorArgEvent_2_factory)); -new Sfactory(this,"Event",new SCreator(Event_factory)); -new Sfactory(this,"SimpleAssignment_14",new SCreator(SimpleAssignment_14_factory)); -new Sfactory(this,"SimpleAssignment_16",new SCreator(SimpleAssignment_16_factory)); -new Sfactory(this,"SimpleAssignment_17",new SCreator(SimpleAssignment_17_factory)); -new Sfactory(this,"SimpleAssignment_18",new SCreator(SimpleAssignment_18_factory)); -new Sfactory(this,"Statement_10",new SCreator(Statement_10_factory)); -new Sfactory(this,"Statement_11",new SCreator(Statement_11_factory)); -new Sfactory(this,"SimpleAssignment",new SCreator(SimpleAssignment_factory)); -new Sfactory(this,"TypecastExpression",new SCreator(TypecastExpression_factory)); -new Sfactory(this,"JumpStatement_1",new SCreator(JumpStatement_1_factory)); -new Sfactory(this,"SimpleAssignment_20",new SCreator(SimpleAssignment_20_factory)); new Sfactory(this,"Statement_7",new SCreator(Statement_7_factory)); -new Sfactory(this,"SimpleAssignment_23",new SCreator(SimpleAssignment_23_factory)); -new Sfactory(this,"SimpleAssignment_24",new SCreator(SimpleAssignment_24_factory)); -new Sfactory(this,"SimpleAssignment_1",new SCreator(SimpleAssignment_1_factory)); -new Sfactory(this,"SimpleAssignment_2",new SCreator(SimpleAssignment_2_factory)); -new Sfactory(this,"BinaryExpression",new SCreator(BinaryExpression_factory)); -new Sfactory(this,"FunctionCallExpression",new SCreator(FunctionCallExpression_factory)); -new Sfactory(this,"SimpleAssignment_6",new SCreator(SimpleAssignment_6_factory)); -new Sfactory(this,"StateBody_1",new SCreator(StateBody_1_factory)); -new Sfactory(this,"StateBody_2",new SCreator(StateBody_2_factory)); -new Sfactory(this,"StateBody_3",new SCreator(StateBody_3_factory)); -new Sfactory(this,"StateBody_4",new SCreator(StateBody_4_factory)); -new Sfactory(this,"StateBody_5",new SCreator(StateBody_5_factory)); -new Sfactory(this,"StateBody_6",new SCreator(StateBody_6_factory)); -new Sfactory(this,"StateBody_7",new SCreator(StateBody_7_factory)); -new Sfactory(this,"StateBody_8",new SCreator(StateBody_8_factory)); -new Sfactory(this,"StateBody_9",new SCreator(StateBody_9_factory)); -new Sfactory(this,"Statement",new SCreator(Statement_factory)); -new Sfactory(this,"IncrementDecrementExpression_3",new SCreator(IncrementDecrementExpression_3_factory)); -new Sfactory(this,"JumpStatement",new SCreator(JumpStatement_factory)); -new Sfactory(this,"BinaryExpression_11",new SCreator(BinaryExpression_11_factory)); -new Sfactory(this,"IntArgEvent",new SCreator(IntArgEvent_factory)); -new Sfactory(this,"IncrementDecrementExpression_8",new SCreator(IncrementDecrementExpression_8_factory)); -new Sfactory(this,"BinaryExpression_14",new SCreator(BinaryExpression_14_factory)); -new Sfactory(this,"BinaryExpression_15",new SCreator(BinaryExpression_15_factory)); -new Sfactory(this,"BinaryExpression_16",new SCreator(BinaryExpression_16_factory)); -new Sfactory(this,"BinaryExpression_6",new SCreator(BinaryExpression_6_factory)); -new Sfactory(this,"BinaryExpression_7",new SCreator(BinaryExpression_7_factory)); -new Sfactory(this,"Typename_2",new SCreator(Typename_2_factory)); -new Sfactory(this,"Typename_4",new SCreator(Typename_4_factory)); -new Sfactory(this,"ArgumentList",new SCreator(ArgumentList_factory)); -new Sfactory(this,"BinaryExpression_12",new SCreator(BinaryExpression_12_factory)); -new Sfactory(this,"BinaryExpression_13",new SCreator(BinaryExpression_13_factory)); -new Sfactory(this,"GlobalFunctionDefinition_2",new SCreator(GlobalFunctionDefinition_2_factory)); -new Sfactory(this,"StateChange_2",new SCreator(StateChange_2_factory)); -new Sfactory(this,"VoidArgEvent_1",new SCreator(VoidArgEvent_1_factory)); -new Sfactory(this,"VoidArgEvent_3",new SCreator(VoidArgEvent_3_factory)); -new Sfactory(this,"BinaryExpression_10",new SCreator(BinaryExpression_10_factory)); -new Sfactory(this,"VoidArgEvent_5",new SCreator(VoidArgEvent_5_factory)); -new Sfactory(this,"VoidArgEvent_6",new SCreator(VoidArgEvent_6_factory)); -new Sfactory(this,"VoidArgEvent_7",new SCreator(VoidArgEvent_7_factory)); -new Sfactory(this,"VoidArgEvent_8",new SCreator(VoidArgEvent_8_factory)); -new Sfactory(this,"BinaryExpression_17",new SCreator(BinaryExpression_17_factory)); -new Sfactory(this,"StateEvent_1",new SCreator(StateEvent_1_factory)); -new Sfactory(this,"VectorConstant",new SCreator(VectorConstant_factory)); -new Sfactory(this,"VectorArgEvent_1",new SCreator(VectorArgEvent_1_factory)); -new Sfactory(this,"IntDeclaration",new SCreator(IntDeclaration_factory)); -new Sfactory(this,"VectorArgEvent_3",new SCreator(VectorArgEvent_3_factory)); -new Sfactory(this,"TypecastExpression_4",new SCreator(TypecastExpression_4_factory)); -new Sfactory(this,"TypecastExpression_6",new SCreator(TypecastExpression_6_factory)); -new Sfactory(this,"TypecastExpression_7",new SCreator(TypecastExpression_7_factory)); -new Sfactory(this,"FunctionCall",new SCreator(FunctionCall_factory)); -new Sfactory(this,"ListConstant_1",new SCreator(ListConstant_1_factory)); -new Sfactory(this,"BinaryExpression_18",new SCreator(BinaryExpression_18_factory)); -new Sfactory(this,"Event_6",new SCreator(Event_6_factory)); -new Sfactory(this,"KeyArgEvent_2",new SCreator(KeyArgEvent_2_factory)); -new Sfactory(this,"Declaration_1",new SCreator(Declaration_1_factory)); -new Sfactory(this,"EmptyStatement_1",new SCreator(EmptyStatement_1_factory)); -new Sfactory(this,"SimpleAssignment_7",new SCreator(SimpleAssignment_7_factory)); -new Sfactory(this,"ForLoop",new SCreator(ForLoop_factory)); -new Sfactory(this,"ForLoop_2",new SCreator(ForLoop_2_factory)); -new Sfactory(this,"KeyIntIntArgStateEvent_1",new SCreator(KeyIntIntArgStateEvent_1_factory)); -new Sfactory(this,"KeyArgumentDeclarationList_1",new SCreator(KeyArgumentDeclarationList_1_factory)); -new Sfactory(this,"GlobalFunctionDefinition_1",new SCreator(GlobalFunctionDefinition_1_factory)); -new Sfactory(this,"IfStatement",new SCreator(IfStatement_factory)); -new Sfactory(this,"ForLoopStatement_1",new SCreator(ForLoopStatement_1_factory)); -new Sfactory(this,"ForLoopStatement_2",new SCreator(ForLoopStatement_2_factory)); -new Sfactory(this,"ForLoopStatement_3",new SCreator(ForLoopStatement_3_factory)); -new Sfactory(this,"IntRotRotArgumentDeclarationList",new SCreator(IntRotRotArgumentDeclarationList_factory)); -new Sfactory(this,"IntArgEvent_1",new SCreator(IntArgEvent_1_factory)); -new Sfactory(this,"IntArgEvent_2",new SCreator(IntArgEvent_2_factory)); -new Sfactory(this,"WhileStatement",new SCreator(WhileStatement_factory)); -new Sfactory(this,"ForLoop_1",new SCreator(ForLoop_1_factory)); -new Sfactory(this,"Constant_2",new SCreator(Constant_2_factory)); -new Sfactory(this,"VoidArgEvent",new SCreator(VoidArgEvent_factory)); -new Sfactory(this,"RotDeclaration",new SCreator(RotDeclaration_factory)); -new Sfactory(this,"WhileStatement_1",new SCreator(WhileStatement_1_factory)); -new Sfactory(this,"WhileStatement_2",new SCreator(WhileStatement_2_factory)); -new Sfactory(this,"VectorArgStateEvent_1",new SCreator(VectorArgStateEvent_1_factory)); -new Sfactory(this,"IdentExpression_1",new SCreator(IdentExpression_1_factory)); -new Sfactory(this,"VectorArgumentDeclarationList",new SCreator(VectorArgumentDeclarationList_factory)); +new Sfactory(this,"IncrementDecrementExpression_5",new SCreator(IncrementDecrementExpression_5_factory)); +new Sfactory(this,"Statement_2",new SCreator(Statement_2_factory)); +new Sfactory(this,"ListConstant",new SCreator(ListConstant_factory)); new Sfactory(this,"States",new SCreator(States_factory)); -new Sfactory(this,"VoidArgStateEvent",new SCreator(VoidArgStateEvent_factory)); +new Sfactory(this,"TypecastExpression_2",new SCreator(TypecastExpression_2_factory)); +new Sfactory(this,"ArgumentList_2",new SCreator(ArgumentList_2_factory)); +new Sfactory(this,"StateBody_14",new SCreator(StateBody_14_factory)); +new Sfactory(this,"KeyArgEvent_1",new SCreator(KeyArgEvent_1_factory)); +new Sfactory(this,"VectorConstant",new SCreator(VectorConstant_factory)); +new Sfactory(this,"SimpleAssignment_3",new SCreator(SimpleAssignment_3_factory)); +new Sfactory(this,"Typename_5",new SCreator(Typename_5_factory)); +new Sfactory(this,"TypecastExpression_8",new SCreator(TypecastExpression_8_factory)); +new Sfactory(this,"SimpleAssignment_21",new SCreator(SimpleAssignment_21_factory)); +new Sfactory(this,"JumpLabel_1",new SCreator(JumpLabel_1_factory)); +new Sfactory(this,"TypecastExpression_4",new SCreator(TypecastExpression_4_factory)); +new Sfactory(this,"JumpStatement_1",new SCreator(JumpStatement_1_factory)); +new Sfactory(this,"VoidArgEvent_8",new SCreator(VoidArgEvent_8_factory)); +new Sfactory(this,"GlobalVariableDeclaration_2",new SCreator(GlobalVariableDeclaration_2_factory)); +new Sfactory(this,"GlobalVariableDeclaration_1",new SCreator(GlobalVariableDeclaration_1_factory)); +new Sfactory(this,"RotDeclaration_1",new SCreator(RotDeclaration_1_factory)); +new Sfactory(this,"WhileStatement_1",new SCreator(WhileStatement_1_factory)); +new Sfactory(this,"VecDeclaration_1",new SCreator(VecDeclaration_1_factory)); +new Sfactory(this,"IntRotRotArgStateEvent",new SCreator(IntRotRotArgStateEvent_factory)); +new Sfactory(this,"Constant_3",new SCreator(Constant_3_factory)); +new Sfactory(this,"Declaration",new SCreator(Declaration_factory)); +new Sfactory(this,"IntVecVecArgStateEvent_1",new SCreator(IntVecVecArgStateEvent_1_factory)); +new Sfactory(this,"ArgumentDeclarationList_5",new SCreator(ArgumentDeclarationList_5_factory)); +new Sfactory(this,"ReturnStatement",new SCreator(ReturnStatement_factory)); +new Sfactory(this,"EmptyStatement_1",new SCreator(EmptyStatement_1_factory)); } -public static object ExpressionArgument_1_factory(Parser yyp) { return new ExpressionArgument_1(yyp); } -public static object VectorArgStateEvent_factory(Parser yyp) { return new VectorArgStateEvent(yyp); } -public static object IntVecVecArgStateEvent_factory(Parser yyp) { return new IntVecVecArgStateEvent(yyp); } -public static object IntArgStateEvent_1_factory(Parser yyp) { return new IntArgStateEvent_1(yyp); } -public static object SimpleAssignment_9_factory(Parser yyp) { return new SimpleAssignment_9(yyp); } -public static object StatementList_1_factory(Parser yyp) { return new StatementList_1(yyp); } -public static object RotDeclaration_1_factory(Parser yyp) { return new RotDeclaration_1(yyp); } -public static object IntRotRotArgEvent_1_factory(Parser yyp) { return new IntRotRotArgEvent_1(yyp); } -public static object StateChange_1_factory(Parser yyp) { return new StateChange_1(yyp); } -public static object EmptyStatement_factory(Parser yyp) { return new EmptyStatement(yyp); } -public static object Declaration_factory(Parser yyp) { return new Declaration(yyp); } -public static object IdentExpression_factory(Parser yyp) { return new IdentExpression(yyp); } -public static object error_factory(Parser yyp) { return new error(yyp); } -public static object BinaryExpression_2_factory(Parser yyp) { return new BinaryExpression_2(yyp); } -public static object BinaryExpression_3_factory(Parser yyp) { return new BinaryExpression_3(yyp); } -public static object BinaryExpression_4_factory(Parser yyp) { return new BinaryExpression_4(yyp); } -public static object BinaryExpression_5_factory(Parser yyp) { return new BinaryExpression_5(yyp); } -public static object ReturnStatement_2_factory(Parser yyp) { return new ReturnStatement_2(yyp); } -public static object SimpleAssignment_19_factory(Parser yyp) { return new SimpleAssignment_19(yyp); } -public static object BinaryExpression_9_factory(Parser yyp) { return new BinaryExpression_9(yyp); } -public static object VectorConstant_1_factory(Parser yyp) { return new VectorConstant_1(yyp); } -public static object ParenthesisExpression_factory(Parser yyp) { return new ParenthesisExpression(yyp); } -public static object StatementList_factory(Parser yyp) { return new StatementList(yyp); } -public static object IntRotRotArgEvent_factory(Parser yyp) { return new IntRotRotArgEvent(yyp); } -public static object UnaryExpression_factory(Parser yyp) { return new UnaryExpression(yyp); } +public static object IncrementDecrementExpression_1_factory(Parser yyp) { return new IncrementDecrementExpression_1(yyp); } +public static object StateChange_factory(Parser yyp) { return new StateChange(yyp); } +public static object ArgumentDeclarationList_3_factory(Parser yyp) { return new ArgumentDeclarationList_3(yyp); } +public static object BinaryExpression_factory(Parser yyp) { return new BinaryExpression(yyp); } +public static object VoidArgEvent_5_factory(Parser yyp) { return new VoidArgEvent_5(yyp); } public static object IdentDotExpression_1_factory(Parser yyp) { return new IdentDotExpression_1(yyp); } -public static object ArgumentList_4_factory(Parser yyp) { return new ArgumentList_4(yyp); } -public static object Typename_factory(Parser yyp) { return new Typename(yyp); } -public static object IfStatement_1_factory(Parser yyp) { return new IfStatement_1(yyp); } -public static object RotationConstant_1_factory(Parser yyp) { return new RotationConstant_1(yyp); } -public static object Assignment_factory(Parser yyp) { return new Assignment(yyp); } -public static object IfStatement_4_factory(Parser yyp) { return new IfStatement_4(yyp); } -public static object CompoundStatement_1_factory(Parser yyp) { return new CompoundStatement_1(yyp); } -public static object CompoundStatement_2_factory(Parser yyp) { return new CompoundStatement_2(yyp); } -public static object KeyIntIntArgumentDeclarationList_1_factory(Parser yyp) { return new KeyIntIntArgumentDeclarationList_1(yyp); } -public static object BinaryExpression_8_factory(Parser yyp) { return new BinaryExpression_8(yyp); } -public static object VectorArgEvent_factory(Parser yyp) { return new VectorArgEvent(yyp); } +public static object StateBody_10_factory(Parser yyp) { return new StateBody_10(yyp); } +public static object VectorArgEvent_1_factory(Parser yyp) { return new VectorArgEvent_1(yyp); } public static object ReturnStatement_1_factory(Parser yyp) { return new ReturnStatement_1(yyp); } +public static object ReturnStatement_2_factory(Parser yyp) { return new ReturnStatement_2(yyp); } +public static object Typename_7_factory(Parser yyp) { return new Typename_7(yyp); } +public static object ExpressionArgument_factory(Parser yyp) { return new ExpressionArgument(yyp); } +public static object ForLoop_factory(Parser yyp) { return new ForLoop(yyp); } +public static object GlobalDefinitions_factory(Parser yyp) { return new GlobalDefinitions(yyp); } +public static object Typename_1_factory(Parser yyp) { return new Typename_1(yyp); } +public static object TypecastExpression_3_factory(Parser yyp) { return new TypecastExpression_3(yyp); } +public static object IncrementDecrementExpression_6_factory(Parser yyp) { return new IncrementDecrementExpression_6(yyp); } +public static object SimpleAssignment_2_factory(Parser yyp) { return new SimpleAssignment_2(yyp); } +public static object IntVecVecArgEvent_1_factory(Parser yyp) { return new IntVecVecArgEvent_1(yyp); } +public static object LSLProgramRoot_2_factory(Parser yyp) { return new LSLProgramRoot_2(yyp); } public static object IdentDotExpression_factory(Parser yyp) { return new IdentDotExpression(yyp); } -public static object Argument_factory(Parser yyp) { return new Argument(yyp); } +public static object UnaryExpression_1_factory(Parser yyp) { return new UnaryExpression_1(yyp); } +public static object RotationConstant_factory(Parser yyp) { return new RotationConstant(yyp); } +public static object IntArgumentDeclarationList_factory(Parser yyp) { return new IntArgumentDeclarationList(yyp); } +public static object ArgumentList_factory(Parser yyp) { return new ArgumentList(yyp); } +public static object BinaryExpression_3_factory(Parser yyp) { return new BinaryExpression_3(yyp); } +public static object Event_2_factory(Parser yyp) { return new Event_2(yyp); } +public static object ArgumentList_4_factory(Parser yyp) { return new ArgumentList_4(yyp); } +public static object IntVecVecArgEvent_factory(Parser yyp) { return new IntVecVecArgEvent(yyp); } +public static object WhileStatement_2_factory(Parser yyp) { return new WhileStatement_2(yyp); } +public static object Assignment_factory(Parser yyp) { return new Assignment(yyp); } +public static object Statement_12_factory(Parser yyp) { return new Statement_12(yyp); } +public static object IncrementDecrementExpression_8_factory(Parser yyp) { return new IncrementDecrementExpression_8(yyp); } +public static object VectorArgEvent_2_factory(Parser yyp) { return new VectorArgEvent_2(yyp); } +public static object Constant_2_factory(Parser yyp) { return new Constant_2(yyp); } +public static object Statement_1_factory(Parser yyp) { return new Statement_1(yyp); } +public static object VectorArgEvent_factory(Parser yyp) { return new VectorArgEvent(yyp); } +public static object ForLoopStatement_1_factory(Parser yyp) { return new ForLoopStatement_1(yyp); } +public static object IncrementDecrementExpression_2_factory(Parser yyp) { return new IncrementDecrementExpression_2(yyp); } +public static object IntArgumentDeclarationList_1_factory(Parser yyp) { return new IntArgumentDeclarationList_1(yyp); } +public static object VoidArgEvent_4_factory(Parser yyp) { return new VoidArgEvent_4(yyp); } +public static object ForLoop_1_factory(Parser yyp) { return new ForLoop_1(yyp); } +public static object Typename_4_factory(Parser yyp) { return new Typename_4(yyp); } +public static object IdentExpression_factory(Parser yyp) { return new IdentExpression(yyp); } +public static object ForLoop_2_factory(Parser yyp) { return new ForLoop_2(yyp); } +public static object DoWhileStatement_factory(Parser yyp) { return new DoWhileStatement(yyp); } +public static object SimpleAssignment_6_factory(Parser yyp) { return new SimpleAssignment_6(yyp); } +public static object IntDeclaration_1_factory(Parser yyp) { return new IntDeclaration_1(yyp); } +public static object State_1_factory(Parser yyp) { return new State_1(yyp); } +public static object StateBody_9_factory(Parser yyp) { return new StateBody_9(yyp); } +public static object StateBody_8_factory(Parser yyp) { return new StateBody_8(yyp); } public static object State_2_factory(Parser yyp) { return new State_2(yyp); } -public static object GlobalDefinitions_3_factory(Parser yyp) { return new GlobalDefinitions_3(yyp); } -public static object GlobalDefinitions_4_factory(Parser yyp) { return new GlobalDefinitions_4(yyp); } -public static object Event_1_factory(Parser yyp) { return new Event_1(yyp); } -public static object ListConstant_factory(Parser yyp) { return new ListConstant(yyp); } +public static object StateBody_3_factory(Parser yyp) { return new StateBody_3(yyp); } +public static object StateBody_2_factory(Parser yyp) { return new StateBody_2(yyp); } +public static object StateBody_1_factory(Parser yyp) { return new StateBody_1(yyp); } +public static object Typename_6_factory(Parser yyp) { return new Typename_6(yyp); } +public static object StateBody_7_factory(Parser yyp) { return new StateBody_7(yyp); } +public static object StateBody_4_factory(Parser yyp) { return new StateBody_4(yyp); } +public static object IfStatement_1_factory(Parser yyp) { return new IfStatement_1(yyp); } +public static object IfStatement_3_factory(Parser yyp) { return new IfStatement_3(yyp); } +public static object IfStatement_2_factory(Parser yyp) { return new IfStatement_2(yyp); } +public static object SimpleAssignment_1_factory(Parser yyp) { return new SimpleAssignment_1(yyp); } +public static object VoidArgEvent_6_factory(Parser yyp) { return new VoidArgEvent_6(yyp); } +public static object IfStatement_factory(Parser yyp) { return new IfStatement(yyp); } +public static object ConstantExpression_factory(Parser yyp) { return new ConstantExpression(yyp); } +public static object BinaryExpression_7_factory(Parser yyp) { return new BinaryExpression_7(yyp); } +public static object IncrementDecrementExpression_factory(Parser yyp) { return new IncrementDecrementExpression(yyp); } +public static object Statement_9_factory(Parser yyp) { return new Statement_9(yyp); } +public static object IntVecVecArgStateEvent_factory(Parser yyp) { return new IntVecVecArgStateEvent(yyp); } +public static object Declaration_1_factory(Parser yyp) { return new Declaration_1(yyp); } +public static object KeyIntIntArgumentDeclarationList_factory(Parser yyp) { return new KeyIntIntArgumentDeclarationList(yyp); } +public static object VectorArgumentDeclarationList_1_factory(Parser yyp) { return new VectorArgumentDeclarationList_1(yyp); } +public static object SimpleAssignment_factory(Parser yyp) { return new SimpleAssignment(yyp); } +public static object BinaryExpression_9_factory(Parser yyp) { return new BinaryExpression_9(yyp); } +public static object IntDeclaration_factory(Parser yyp) { return new IntDeclaration(yyp); } +public static object IntArgEvent_10_factory(Parser yyp) { return new IntArgEvent_10(yyp); } +public static object ArgumentDeclarationList_2_factory(Parser yyp) { return new ArgumentDeclarationList_2(yyp); } +public static object ArgumentDeclarationList_1_factory(Parser yyp) { return new ArgumentDeclarationList_1(yyp); } +public static object ArgumentDeclarationList_4_factory(Parser yyp) { return new ArgumentDeclarationList_4(yyp); } +public static object SimpleAssignment_9_factory(Parser yyp) { return new SimpleAssignment_9(yyp); } +public static object ForLoopStatement_2_factory(Parser yyp) { return new ForLoopStatement_2(yyp); } +public static object StatementList_factory(Parser yyp) { return new StatementList(yyp); } +public static object StateBody_13_factory(Parser yyp) { return new StateBody_13(yyp); } +public static object Typename_3_factory(Parser yyp) { return new Typename_3(yyp); } +public static object KeyArgumentDeclarationList_1_factory(Parser yyp) { return new KeyArgumentDeclarationList_1(yyp); } +public static object UnaryExpression_3_factory(Parser yyp) { return new UnaryExpression_3(yyp); } +public static object StateBody_16_factory(Parser yyp) { return new StateBody_16(yyp); } +public static object VectorArgumentDeclarationList_factory(Parser yyp) { return new VectorArgumentDeclarationList(yyp); } +public static object IntArgEvent_3_factory(Parser yyp) { return new IntArgEvent_3(yyp); } +public static object StatementList_2_factory(Parser yyp) { return new StatementList_2(yyp); } +public static object KeyArgStateEvent_factory(Parser yyp) { return new KeyArgStateEvent(yyp); } +public static object LSLProgramRoot_1_factory(Parser yyp) { return new LSLProgramRoot_1(yyp); } +public static object Typename_2_factory(Parser yyp) { return new Typename_2(yyp); } +public static object TypecastExpression_6_factory(Parser yyp) { return new TypecastExpression_6(yyp); } public static object Event_3_factory(Parser yyp) { return new Event_3(yyp); } -public static object Event_4_factory(Parser yyp) { return new Event_4(yyp); } +public static object IntArgStateEvent_factory(Parser yyp) { return new IntArgStateEvent(yyp); } +public static object StateChange_2_factory(Parser yyp) { return new StateChange_2(yyp); } +public static object StateChange_1_factory(Parser yyp) { return new StateChange_1(yyp); } +public static object VectorConstant_1_factory(Parser yyp) { return new VectorConstant_1(yyp); } +public static object KeyDeclaration_factory(Parser yyp) { return new KeyDeclaration(yyp); } +public static object States_2_factory(Parser yyp) { return new States_2(yyp); } +public static object VoidArgEvent_factory(Parser yyp) { return new VoidArgEvent(yyp); } +public static object WhileStatement_factory(Parser yyp) { return new WhileStatement(yyp); } +public static object UnaryExpression_factory(Parser yyp) { return new UnaryExpression(yyp); } +public static object BinaryExpression_6_factory(Parser yyp) { return new BinaryExpression_6(yyp); } +public static object ConstantExpression_1_factory(Parser yyp) { return new ConstantExpression_1(yyp); } +public static object ForLoopStatement_factory(Parser yyp) { return new ForLoopStatement(yyp); } +public static object BinaryExpression_1_factory(Parser yyp) { return new BinaryExpression_1(yyp); } +public static object StateEvent_factory(Parser yyp) { return new StateEvent(yyp); } public static object Event_5_factory(Parser yyp) { return new Event_5(yyp); } public static object SimpleAssignment_5_factory(Parser yyp) { return new SimpleAssignment_5(yyp); } -public static object Typename_1_factory(Parser yyp) { return new Typename_1(yyp); } -public static object VoidArgStateEvent_1_factory(Parser yyp) { return new VoidArgStateEvent_1(yyp); } -public static object Typename_3_factory(Parser yyp) { return new Typename_3(yyp); } -public static object IntRotRotArgStateEvent_factory(Parser yyp) { return new IntRotRotArgStateEvent(yyp); } -public static object Typename_5_factory(Parser yyp) { return new Typename_5(yyp); } -public static object Typename_6_factory(Parser yyp) { return new Typename_6(yyp); } -public static object Typename_7_factory(Parser yyp) { return new Typename_7(yyp); } -public static object ArgumentDeclarationList_factory(Parser yyp) { return new ArgumentDeclarationList(yyp); } -public static object ConstantExpression_factory(Parser yyp) { return new ConstantExpression(yyp); } -public static object LSLProgramRoot_1_factory(Parser yyp) { return new LSLProgramRoot_1(yyp); } -public static object LSLProgramRoot_2_factory(Parser yyp) { return new LSLProgramRoot_2(yyp); } -public static object KeyIntIntArgEvent_1_factory(Parser yyp) { return new KeyIntIntArgEvent_1(yyp); } -public static object States_1_factory(Parser yyp) { return new States_1(yyp); } -public static object States_2_factory(Parser yyp) { return new States_2(yyp); } -public static object FunctionCallExpression_1_factory(Parser yyp) { return new FunctionCallExpression_1(yyp); } -public static object KeyArgEvent_1_factory(Parser yyp) { return new KeyArgEvent_1(yyp); } -public static object ForLoopStatement_factory(Parser yyp) { return new ForLoopStatement(yyp); } -public static object IntArgStateEvent_factory(Parser yyp) { return new IntArgStateEvent(yyp); } -public static object StateBody_15_factory(Parser yyp) { return new StateBody_15(yyp); } -public static object IntRotRotArgumentDeclarationList_1_factory(Parser yyp) { return new IntRotRotArgumentDeclarationList_1(yyp); } -public static object IntArgEvent_9_factory(Parser yyp) { return new IntArgEvent_9(yyp); } -public static object DoWhileStatement_1_factory(Parser yyp) { return new DoWhileStatement_1(yyp); } -public static object DoWhileStatement_2_factory(Parser yyp) { return new DoWhileStatement_2(yyp); } -public static object ForLoopStatement_4_factory(Parser yyp) { return new ForLoopStatement_4(yyp); } -public static object SimpleAssignment_11_factory(Parser yyp) { return new SimpleAssignment_11(yyp); } -public static object SimpleAssignment_12_factory(Parser yyp) { return new SimpleAssignment_12(yyp); } -public static object SimpleAssignment_13_factory(Parser yyp) { return new SimpleAssignment_13(yyp); } -public static object JumpLabel_factory(Parser yyp) { return new JumpLabel(yyp); } -public static object SimpleAssignment_15_factory(Parser yyp) { return new SimpleAssignment_15(yyp); } -public static object IntVecVecArgEvent_factory(Parser yyp) { return new IntVecVecArgEvent(yyp); } -public static object VecDeclaration_factory(Parser yyp) { return new VecDeclaration(yyp); } -public static object StateBody_14_factory(Parser yyp) { return new StateBody_14(yyp); } -public static object GlobalDefinitions_factory(Parser yyp) { return new GlobalDefinitions(yyp); } -public static object StateBody_16_factory(Parser yyp) { return new StateBody_16(yyp); } -public static object KeyIntIntArgumentDeclarationList_factory(Parser yyp) { return new KeyIntIntArgumentDeclarationList(yyp); } -public static object ConstantExpression_1_factory(Parser yyp) { return new ConstantExpression_1(yyp); } -public static object VoidArgEvent_4_factory(Parser yyp) { return new VoidArgEvent_4(yyp); } -public static object FunctionCall_1_factory(Parser yyp) { return new FunctionCall_1(yyp); } -public static object Assignment_1_factory(Parser yyp) { return new Assignment_1(yyp); } -public static object Assignment_2_factory(Parser yyp) { return new Assignment_2(yyp); } -public static object IntVecVecArgEvent_1_factory(Parser yyp) { return new IntVecVecArgEvent_1(yyp); } -public static object TypecastExpression_1_factory(Parser yyp) { return new TypecastExpression_1(yyp); } -public static object SimpleAssignment_21_factory(Parser yyp) { return new SimpleAssignment_21(yyp); } -public static object SimpleAssignment_22_factory(Parser yyp) { return new SimpleAssignment_22(yyp); } -public static object KeyIntIntArgStateEvent_factory(Parser yyp) { return new KeyIntIntArgStateEvent(yyp); } -public static object TypecastExpression_9_factory(Parser yyp) { return new TypecastExpression_9(yyp); } -public static object VoidArgEvent_2_factory(Parser yyp) { return new VoidArgEvent_2(yyp); } -public static object Event_9_factory(Parser yyp) { return new Event_9(yyp); } -public static object ArgumentDeclarationList_1_factory(Parser yyp) { return new ArgumentDeclarationList_1(yyp); } -public static object ArgumentDeclarationList_2_factory(Parser yyp) { return new ArgumentDeclarationList_2(yyp); } -public static object GlobalDefinitions_1_factory(Parser yyp) { return new GlobalDefinitions_1(yyp); } -public static object GlobalDefinitions_2_factory(Parser yyp) { return new GlobalDefinitions_2(yyp); } -public static object IncrementDecrementExpression_factory(Parser yyp) { return new IncrementDecrementExpression(yyp); } -public static object GlobalVariableDeclaration_factory(Parser yyp) { return new GlobalVariableDeclaration(yyp); } -public static object IntArgumentDeclarationList_1_factory(Parser yyp) { return new IntArgumentDeclarationList_1(yyp); } -public static object IntDeclaration_1_factory(Parser yyp) { return new IntDeclaration_1(yyp); } -public static object ArgumentDeclarationList_5_factory(Parser yyp) { return new ArgumentDeclarationList_5(yyp); } -public static object IntVecVecArgumentDeclarationList_factory(Parser yyp) { return new IntVecVecArgumentDeclarationList(yyp); } -public static object VectorArgumentDeclarationList_1_factory(Parser yyp) { return new VectorArgumentDeclarationList_1(yyp); } -public static object KeyArgumentDeclarationList_factory(Parser yyp) { return new KeyArgumentDeclarationList(yyp); } -public static object TypecastExpression_2_factory(Parser yyp) { return new TypecastExpression_2(yyp); } -public static object KeyArgStateEvent_factory(Parser yyp) { return new KeyArgStateEvent(yyp); } -public static object TypecastExpression_5_factory(Parser yyp) { return new TypecastExpression_5(yyp); } -public static object TypecastExpression_8_factory(Parser yyp) { return new TypecastExpression_8(yyp); } -public static object Constant_1_factory(Parser yyp) { return new Constant_1(yyp); } -public static object Expression_factory(Parser yyp) { return new Expression(yyp); } -public static object Constant_3_factory(Parser yyp) { return new Constant_3(yyp); } -public static object Constant_4_factory(Parser yyp) { return new Constant_4(yyp); } -public static object IntArgEvent_5_factory(Parser yyp) { return new IntArgEvent_5(yyp); } -public static object BinaryExpression_1_factory(Parser yyp) { return new BinaryExpression_1(yyp); } -public static object IfStatement_2_factory(Parser yyp) { return new IfStatement_2(yyp); } -public static object IfStatement_3_factory(Parser yyp) { return new IfStatement_3(yyp); } -public static object KeyArgEvent_factory(Parser yyp) { return new KeyArgEvent(yyp); } -public static object Event_2_factory(Parser yyp) { return new Event_2(yyp); } -public static object JumpLabel_1_factory(Parser yyp) { return new JumpLabel_1(yyp); } -public static object RotationConstant_factory(Parser yyp) { return new RotationConstant(yyp); } -public static object Statement_12_factory(Parser yyp) { return new Statement_12(yyp); } -public static object Statement_13_factory(Parser yyp) { return new Statement_13(yyp); } -public static object UnaryExpression_1_factory(Parser yyp) { return new UnaryExpression_1(yyp); } -public static object UnaryExpression_2_factory(Parser yyp) { return new UnaryExpression_2(yyp); } -public static object UnaryExpression_3_factory(Parser yyp) { return new UnaryExpression_3(yyp); } -public static object ArgumentList_1_factory(Parser yyp) { return new ArgumentList_1(yyp); } -public static object KeyIntIntArgEvent_factory(Parser yyp) { return new KeyIntIntArgEvent(yyp); } -public static object ArgumentList_3_factory(Parser yyp) { return new ArgumentList_3(yyp); } +public static object RotationConstant_1_factory(Parser yyp) { return new RotationConstant_1(yyp); } public static object Constant_factory(Parser yyp) { return new Constant(yyp); } -public static object State_factory(Parser yyp) { return new State(yyp); } -public static object StateBody_13_factory(Parser yyp) { return new StateBody_13(yyp); } -public static object KeyArgStateEvent_1_factory(Parser yyp) { return new KeyArgStateEvent_1(yyp); } +public static object IntArgEvent_1_factory(Parser yyp) { return new IntArgEvent_1(yyp); } public static object SimpleAssignment_8_factory(Parser yyp) { return new SimpleAssignment_8(yyp); } +public static object ForLoopStatement_3_factory(Parser yyp) { return new ForLoopStatement_3(yyp); } +public static object IntArgEvent_2_factory(Parser yyp) { return new IntArgEvent_2(yyp); } public static object LSLProgramRoot_factory(Parser yyp) { return new LSLProgramRoot(yyp); } -public static object StateChange_factory(Parser yyp) { return new StateChange(yyp); } -public static object VecDeclaration_1_factory(Parser yyp) { return new VecDeclaration_1(yyp); } -public static object GlobalVariableDeclaration_1_factory(Parser yyp) { return new GlobalVariableDeclaration_1(yyp); } -public static object GlobalVariableDeclaration_2_factory(Parser yyp) { return new GlobalVariableDeclaration_2(yyp); } -public static object IncrementDecrementExpression_5_factory(Parser yyp) { return new IncrementDecrementExpression_5(yyp); } -public static object ReturnStatement_factory(Parser yyp) { return new ReturnStatement(yyp); } -public static object StateBody_10_factory(Parser yyp) { return new StateBody_10(yyp); } -public static object StateBody_11_factory(Parser yyp) { return new StateBody_11(yyp); } public static object StateBody_12_factory(Parser yyp) { return new StateBody_12(yyp); } -public static object IntVecVecArgStateEvent_1_factory(Parser yyp) { return new IntVecVecArgStateEvent_1(yyp); } -public static object KeyDeclaration_factory(Parser yyp) { return new KeyDeclaration(yyp); } +public static object IntArgEvent_4_factory(Parser yyp) { return new IntArgEvent_4(yyp); } +public static object IntArgEvent_7_factory(Parser yyp) { return new IntArgEvent_7(yyp); } public static object IntArgEvent_6_factory(Parser yyp) { return new IntArgEvent_6(yyp); } -public static object ArgumentDeclarationList_3_factory(Parser yyp) { return new ArgumentDeclarationList_3(yyp); } -public static object ArgumentList_2_factory(Parser yyp) { return new ArgumentList_2(yyp); } -public static object IntArgEvent_10_factory(Parser yyp) { return new IntArgEvent_10(yyp); } -public static object CompoundStatement_factory(Parser yyp) { return new CompoundStatement(yyp); } -public static object TypecastExpression_3_factory(Parser yyp) { return new TypecastExpression_3(yyp); } -public static object IntArgumentDeclarationList_factory(Parser yyp) { return new IntArgumentDeclarationList(yyp); } -public static object ArgumentDeclarationList_4_factory(Parser yyp) { return new ArgumentDeclarationList_4(yyp); } -public static object SimpleAssignment_3_factory(Parser yyp) { return new SimpleAssignment_3(yyp); } +public static object IntArgEvent_9_factory(Parser yyp) { return new IntArgEvent_9(yyp); } +public static object TypecastExpression_7_factory(Parser yyp) { return new TypecastExpression_7(yyp); } +public static object StateBody_15_factory(Parser yyp) { return new StateBody_15(yyp); } +public static object VoidArgStateEvent_1_factory(Parser yyp) { return new VoidArgStateEvent_1(yyp); } +public static object error_factory(Parser yyp) { return new error(yyp); } +public static object TypecastExpression_1_factory(Parser yyp) { return new TypecastExpression_1(yyp); } +public static object GlobalDefinitions_4_factory(Parser yyp) { return new GlobalDefinitions_4(yyp); } +public static object GlobalDefinitions_3_factory(Parser yyp) { return new GlobalDefinitions_3(yyp); } +public static object GlobalDefinitions_2_factory(Parser yyp) { return new GlobalDefinitions_2(yyp); } +public static object GlobalDefinitions_1_factory(Parser yyp) { return new GlobalDefinitions_1(yyp); } +public static object ArgumentList_1_factory(Parser yyp) { return new ArgumentList_1(yyp); } +public static object IncrementDecrementExpression_7_factory(Parser yyp) { return new IncrementDecrementExpression_7(yyp); } +public static object UnaryExpression_2_factory(Parser yyp) { return new UnaryExpression_2(yyp); } +public static object Argument_factory(Parser yyp) { return new Argument(yyp); } +public static object SimpleAssignment_24_factory(Parser yyp) { return new SimpleAssignment_24(yyp); } +public static object ExpressionArgument_1_factory(Parser yyp) { return new ExpressionArgument_1(yyp); } +public static object EmptyStatement_factory(Parser yyp) { return new EmptyStatement(yyp); } +public static object KeyIntIntArgStateEvent_factory(Parser yyp) { return new KeyIntIntArgStateEvent(yyp); } +public static object VectorArgStateEvent_1_factory(Parser yyp) { return new VectorArgStateEvent_1(yyp); } +public static object GlobalFunctionDefinition_1_factory(Parser yyp) { return new GlobalFunctionDefinition_1(yyp); } +public static object FunctionCallExpression_1_factory(Parser yyp) { return new FunctionCallExpression_1(yyp); } +public static object DoWhileStatement_2_factory(Parser yyp) { return new DoWhileStatement_2(yyp); } +public static object VoidArgEvent_1_factory(Parser yyp) { return new VoidArgEvent_1(yyp); } +public static object KeyArgumentDeclarationList_factory(Parser yyp) { return new KeyArgumentDeclarationList(yyp); } +public static object KeyIntIntArgEvent_factory(Parser yyp) { return new KeyIntIntArgEvent(yyp); } +public static object ListConstant_1_factory(Parser yyp) { return new ListConstant_1(yyp); } +public static object StateEvent_1_factory(Parser yyp) { return new StateEvent_1(yyp); } +public static object SimpleAssignment_20_factory(Parser yyp) { return new SimpleAssignment_20(yyp); } +public static object SimpleAssignment_23_factory(Parser yyp) { return new SimpleAssignment_23(yyp); } +public static object SimpleAssignment_22_factory(Parser yyp) { return new SimpleAssignment_22(yyp); } +public static object IntArgEvent_5_factory(Parser yyp) { return new IntArgEvent_5(yyp); } +public static object ParenthesisExpression_factory(Parser yyp) { return new ParenthesisExpression(yyp); } +public static object JumpStatement_factory(Parser yyp) { return new JumpStatement(yyp); } +public static object IntRotRotArgumentDeclarationList_1_factory(Parser yyp) { return new IntRotRotArgumentDeclarationList_1(yyp); } public static object SimpleAssignment_4_factory(Parser yyp) { return new SimpleAssignment_4(yyp); } -public static object Statement_1_factory(Parser yyp) { return new Statement_1(yyp); } -public static object Statement_2_factory(Parser yyp) { return new Statement_2(yyp); } +public static object KeyArgEvent_factory(Parser yyp) { return new KeyArgEvent(yyp); } +public static object Assignment_2_factory(Parser yyp) { return new Assignment_2(yyp); } +public static object ForLoopStatement_4_factory(Parser yyp) { return new ForLoopStatement_4(yyp); } +public static object Statement_13_factory(Parser yyp) { return new Statement_13(yyp); } +public static object RotDeclaration_factory(Parser yyp) { return new RotDeclaration(yyp); } +public static object StateBody_11_factory(Parser yyp) { return new StateBody_11(yyp); } +public static object KeyArgEvent_2_factory(Parser yyp) { return new KeyArgEvent_2(yyp); } +public static object StatementList_1_factory(Parser yyp) { return new StatementList_1(yyp); } +public static object StateBody_6_factory(Parser yyp) { return new StateBody_6(yyp); } +public static object Constant_1_factory(Parser yyp) { return new Constant_1(yyp); } +public static object VecDeclaration_factory(Parser yyp) { return new VecDeclaration(yyp); } +public static object TypecastExpression_5_factory(Parser yyp) { return new TypecastExpression_5(yyp); } +public static object GlobalFunctionDefinition_2_factory(Parser yyp) { return new GlobalFunctionDefinition_2(yyp); } +public static object KeyIntIntArgEvent_1_factory(Parser yyp) { return new KeyIntIntArgEvent_1(yyp); } +public static object Constant_4_factory(Parser yyp) { return new Constant_4(yyp); } +public static object TypecastExpression_9_factory(Parser yyp) { return new TypecastExpression_9(yyp); } +public static object IntRotRotArgStateEvent_1_factory(Parser yyp) { return new IntRotRotArgStateEvent_1(yyp); } +public static object IncrementDecrementExpression_3_factory(Parser yyp) { return new IncrementDecrementExpression_3(yyp); } +public static object States_1_factory(Parser yyp) { return new States_1(yyp); } +public static object GlobalVariableDeclaration_factory(Parser yyp) { return new GlobalVariableDeclaration(yyp); } +public static object VoidArgEvent_3_factory(Parser yyp) { return new VoidArgEvent_3(yyp); } +public static object Assignment_1_factory(Parser yyp) { return new Assignment_1(yyp); } +public static object BinaryExpression_5_factory(Parser yyp) { return new BinaryExpression_5(yyp); } +public static object IfStatement_4_factory(Parser yyp) { return new IfStatement_4(yyp); } +public static object IntVecVecArgumentDeclarationList_1_factory(Parser yyp) { return new IntVecVecArgumentDeclarationList_1(yyp); } +public static object KeyIntIntArgumentDeclarationList_1_factory(Parser yyp) { return new KeyIntIntArgumentDeclarationList_1(yyp); } +public static object Statement_factory(Parser yyp) { return new Statement(yyp); } +public static object ParenthesisExpression_1_factory(Parser yyp) { return new ParenthesisExpression_1(yyp); } +public static object ParenthesisExpression_2_factory(Parser yyp) { return new ParenthesisExpression_2(yyp); } +public static object DoWhileStatement_1_factory(Parser yyp) { return new DoWhileStatement_1(yyp); } +public static object VoidArgStateEvent_factory(Parser yyp) { return new VoidArgStateEvent(yyp); } +public static object GlobalFunctionDefinition_factory(Parser yyp) { return new GlobalFunctionDefinition(yyp); } +public static object Event_4_factory(Parser yyp) { return new Event_4(yyp); } +public static object IntArgEvent_factory(Parser yyp) { return new IntArgEvent(yyp); } +public static object SimpleAssignment_11_factory(Parser yyp) { return new SimpleAssignment_11(yyp); } +public static object SimpleAssignment_10_factory(Parser yyp) { return new SimpleAssignment_10(yyp); } +public static object SimpleAssignment_13_factory(Parser yyp) { return new SimpleAssignment_13(yyp); } +public static object SimpleAssignment_12_factory(Parser yyp) { return new SimpleAssignment_12(yyp); } +public static object SimpleAssignment_15_factory(Parser yyp) { return new SimpleAssignment_15(yyp); } +public static object SimpleAssignment_14_factory(Parser yyp) { return new SimpleAssignment_14(yyp); } +public static object SimpleAssignment_17_factory(Parser yyp) { return new SimpleAssignment_17(yyp); } +public static object SimpleAssignment_16_factory(Parser yyp) { return new SimpleAssignment_16(yyp); } +public static object SimpleAssignment_19_factory(Parser yyp) { return new SimpleAssignment_19(yyp); } +public static object SimpleAssignment_18_factory(Parser yyp) { return new SimpleAssignment_18(yyp); } +public static object IntVecVecArgumentDeclarationList_factory(Parser yyp) { return new IntVecVecArgumentDeclarationList(yyp); } +public static object StateBody_5_factory(Parser yyp) { return new StateBody_5(yyp); } +public static object BinaryExpression_17_factory(Parser yyp) { return new BinaryExpression_17(yyp); } +public static object BinaryExpression_16_factory(Parser yyp) { return new BinaryExpression_16(yyp); } +public static object BinaryExpression_15_factory(Parser yyp) { return new BinaryExpression_15(yyp); } +public static object BinaryExpression_14_factory(Parser yyp) { return new BinaryExpression_14(yyp); } +public static object BinaryExpression_13_factory(Parser yyp) { return new BinaryExpression_13(yyp); } +public static object BinaryExpression_12_factory(Parser yyp) { return new BinaryExpression_12(yyp); } +public static object BinaryExpression_11_factory(Parser yyp) { return new BinaryExpression_11(yyp); } +public static object BinaryExpression_10_factory(Parser yyp) { return new BinaryExpression_10(yyp); } +public static object VectorArgStateEvent_factory(Parser yyp) { return new VectorArgStateEvent(yyp); } +public static object Statement_10_factory(Parser yyp) { return new Statement_10(yyp); } +public static object BinaryExpression_8_factory(Parser yyp) { return new BinaryExpression_8(yyp); } +public static object BinaryExpression_18_factory(Parser yyp) { return new BinaryExpression_18(yyp); } +public static object BinaryExpression_2_factory(Parser yyp) { return new BinaryExpression_2(yyp); } +public static object FunctionCallExpression_factory(Parser yyp) { return new FunctionCallExpression(yyp); } +public static object VectorArgEvent_3_factory(Parser yyp) { return new VectorArgEvent_3(yyp); } +public static object IdentExpression_1_factory(Parser yyp) { return new IdentExpression_1(yyp); } +public static object IntArgEvent_8_factory(Parser yyp) { return new IntArgEvent_8(yyp); } +public static object VoidArgEvent_7_factory(Parser yyp) { return new VoidArgEvent_7(yyp); } +public static object IncrementDecrementExpression_4_factory(Parser yyp) { return new IncrementDecrementExpression_4(yyp); } +public static object FunctionCall_factory(Parser yyp) { return new FunctionCall(yyp); } +public static object ArgumentList_3_factory(Parser yyp) { return new ArgumentList_3(yyp); } +public static object KeyIntIntArgStateEvent_1_factory(Parser yyp) { return new KeyIntIntArgStateEvent_1(yyp); } +public static object IntRotRotArgumentDeclarationList_factory(Parser yyp) { return new IntRotRotArgumentDeclarationList(yyp); } +public static object KeyDeclaration_1_factory(Parser yyp) { return new KeyDeclaration_1(yyp); } +public static object BinaryExpression_4_factory(Parser yyp) { return new BinaryExpression_4(yyp); } +public static object FunctionCall_1_factory(Parser yyp) { return new FunctionCall_1(yyp); } +public static object KeyArgStateEvent_1_factory(Parser yyp) { return new KeyArgStateEvent_1(yyp); } +public static object IntArgStateEvent_1_factory(Parser yyp) { return new IntArgStateEvent_1(yyp); } +public static object Event_factory(Parser yyp) { return new Event(yyp); } +public static object IntRotRotArgEvent_factory(Parser yyp) { return new IntRotRotArgEvent(yyp); } +public static object SimpleAssignment_7_factory(Parser yyp) { return new SimpleAssignment_7(yyp); } +public static object Statement_3_factory(Parser yyp) { return new Statement_3(yyp); } +public static object Expression_factory(Parser yyp) { return new Expression(yyp); } +public static object CompoundStatement_2_factory(Parser yyp) { return new CompoundStatement_2(yyp); } +public static object CompoundStatement_1_factory(Parser yyp) { return new CompoundStatement_1(yyp); } +public static object JumpLabel_factory(Parser yyp) { return new JumpLabel(yyp); } +public static object State_factory(Parser yyp) { return new State(yyp); } +public static object TypecastExpression_factory(Parser yyp) { return new TypecastExpression(yyp); } +public static object IntRotRotArgEvent_1_factory(Parser yyp) { return new IntRotRotArgEvent_1(yyp); } +public static object Statement_11_factory(Parser yyp) { return new Statement_11(yyp); } +public static object VoidArgEvent_2_factory(Parser yyp) { return new VoidArgEvent_2(yyp); } +public static object Typename_factory(Parser yyp) { return new Typename(yyp); } +public static object ArgumentDeclarationList_factory(Parser yyp) { return new ArgumentDeclarationList(yyp); } +public static object StateBody_factory(Parser yyp) { return new StateBody(yyp); } +public static object Event_8_factory(Parser yyp) { return new Event_8(yyp); } +public static object Event_9_factory(Parser yyp) { return new Event_9(yyp); } +public static object Event_6_factory(Parser yyp) { return new Event_6(yyp); } +public static object Event_7_factory(Parser yyp) { return new Event_7(yyp); } +public static object Statement_8_factory(Parser yyp) { return new Statement_8(yyp); } +public static object CompoundStatement_factory(Parser yyp) { return new CompoundStatement(yyp); } +public static object Event_1_factory(Parser yyp) { return new Event_1(yyp); } public static object Statement_4_factory(Parser yyp) { return new Statement_4(yyp); } public static object Statement_5_factory(Parser yyp) { return new Statement_5(yyp); } public static object Statement_6_factory(Parser yyp) { return new Statement_6(yyp); } -public static object Statement_8_factory(Parser yyp) { return new Statement_8(yyp); } -public static object Statement_9_factory(Parser yyp) { return new Statement_9(yyp); } -public static object ExpressionArgument_factory(Parser yyp) { return new ExpressionArgument(yyp); } -public static object GlobalFunctionDefinition_factory(Parser yyp) { return new GlobalFunctionDefinition(yyp); } -public static object State_1_factory(Parser yyp) { return new State_1(yyp); } -public static object DoWhileStatement_factory(Parser yyp) { return new DoWhileStatement(yyp); } -public static object ParenthesisExpression_1_factory(Parser yyp) { return new ParenthesisExpression_1(yyp); } -public static object ParenthesisExpression_2_factory(Parser yyp) { return new ParenthesisExpression_2(yyp); } -public static object StateBody_factory(Parser yyp) { return new StateBody(yyp); } -public static object Event_7_factory(Parser yyp) { return new Event_7(yyp); } -public static object Event_8_factory(Parser yyp) { return new Event_8(yyp); } -public static object IncrementDecrementExpression_1_factory(Parser yyp) { return new IncrementDecrementExpression_1(yyp); } -public static object IncrementDecrementExpression_2_factory(Parser yyp) { return new IncrementDecrementExpression_2(yyp); } -public static object IntVecVecArgumentDeclarationList_1_factory(Parser yyp) { return new IntVecVecArgumentDeclarationList_1(yyp); } -public static object IncrementDecrementExpression_4_factory(Parser yyp) { return new IncrementDecrementExpression_4(yyp); } -public static object IncrementDecrementExpression_6_factory(Parser yyp) { return new IncrementDecrementExpression_6(yyp); } -public static object IncrementDecrementExpression_7_factory(Parser yyp) { return new IncrementDecrementExpression_7(yyp); } -public static object StateEvent_factory(Parser yyp) { return new StateEvent(yyp); } -public static object IntArgEvent_3_factory(Parser yyp) { return new IntArgEvent_3(yyp); } -public static object IntArgEvent_4_factory(Parser yyp) { return new IntArgEvent_4(yyp); } -public static object KeyDeclaration_1_factory(Parser yyp) { return new KeyDeclaration_1(yyp); } -public static object Statement_3_factory(Parser yyp) { return new Statement_3(yyp); } -public static object IntArgEvent_7_factory(Parser yyp) { return new IntArgEvent_7(yyp); } -public static object IntArgEvent_8_factory(Parser yyp) { return new IntArgEvent_8(yyp); } -public static object SimpleAssignment_10_factory(Parser yyp) { return new SimpleAssignment_10(yyp); } -public static object StatementList_2_factory(Parser yyp) { return new StatementList_2(yyp); } -public static object IntRotRotArgStateEvent_1_factory(Parser yyp) { return new IntRotRotArgStateEvent_1(yyp); } -public static object VectorArgEvent_2_factory(Parser yyp) { return new VectorArgEvent_2(yyp); } -public static object Event_factory(Parser yyp) { return new Event(yyp); } -public static object SimpleAssignment_14_factory(Parser yyp) { return new SimpleAssignment_14(yyp); } -public static object SimpleAssignment_16_factory(Parser yyp) { return new SimpleAssignment_16(yyp); } -public static object SimpleAssignment_17_factory(Parser yyp) { return new SimpleAssignment_17(yyp); } -public static object SimpleAssignment_18_factory(Parser yyp) { return new SimpleAssignment_18(yyp); } -public static object Statement_10_factory(Parser yyp) { return new Statement_10(yyp); } -public static object Statement_11_factory(Parser yyp) { return new Statement_11(yyp); } -public static object SimpleAssignment_factory(Parser yyp) { return new SimpleAssignment(yyp); } -public static object TypecastExpression_factory(Parser yyp) { return new TypecastExpression(yyp); } -public static object JumpStatement_1_factory(Parser yyp) { return new JumpStatement_1(yyp); } -public static object SimpleAssignment_20_factory(Parser yyp) { return new SimpleAssignment_20(yyp); } public static object Statement_7_factory(Parser yyp) { return new Statement_7(yyp); } -public static object SimpleAssignment_23_factory(Parser yyp) { return new SimpleAssignment_23(yyp); } -public static object SimpleAssignment_24_factory(Parser yyp) { return new SimpleAssignment_24(yyp); } -public static object SimpleAssignment_1_factory(Parser yyp) { return new SimpleAssignment_1(yyp); } -public static object SimpleAssignment_2_factory(Parser yyp) { return new SimpleAssignment_2(yyp); } -public static object BinaryExpression_factory(Parser yyp) { return new BinaryExpression(yyp); } -public static object FunctionCallExpression_factory(Parser yyp) { return new FunctionCallExpression(yyp); } -public static object SimpleAssignment_6_factory(Parser yyp) { return new SimpleAssignment_6(yyp); } -public static object StateBody_1_factory(Parser yyp) { return new StateBody_1(yyp); } -public static object StateBody_2_factory(Parser yyp) { return new StateBody_2(yyp); } -public static object StateBody_3_factory(Parser yyp) { return new StateBody_3(yyp); } -public static object StateBody_4_factory(Parser yyp) { return new StateBody_4(yyp); } -public static object StateBody_5_factory(Parser yyp) { return new StateBody_5(yyp); } -public static object StateBody_6_factory(Parser yyp) { return new StateBody_6(yyp); } -public static object StateBody_7_factory(Parser yyp) { return new StateBody_7(yyp); } -public static object StateBody_8_factory(Parser yyp) { return new StateBody_8(yyp); } -public static object StateBody_9_factory(Parser yyp) { return new StateBody_9(yyp); } -public static object Statement_factory(Parser yyp) { return new Statement(yyp); } -public static object IncrementDecrementExpression_3_factory(Parser yyp) { return new IncrementDecrementExpression_3(yyp); } -public static object JumpStatement_factory(Parser yyp) { return new JumpStatement(yyp); } -public static object BinaryExpression_11_factory(Parser yyp) { return new BinaryExpression_11(yyp); } -public static object IntArgEvent_factory(Parser yyp) { return new IntArgEvent(yyp); } -public static object IncrementDecrementExpression_8_factory(Parser yyp) { return new IncrementDecrementExpression_8(yyp); } -public static object BinaryExpression_14_factory(Parser yyp) { return new BinaryExpression_14(yyp); } -public static object BinaryExpression_15_factory(Parser yyp) { return new BinaryExpression_15(yyp); } -public static object BinaryExpression_16_factory(Parser yyp) { return new BinaryExpression_16(yyp); } -public static object BinaryExpression_6_factory(Parser yyp) { return new BinaryExpression_6(yyp); } -public static object BinaryExpression_7_factory(Parser yyp) { return new BinaryExpression_7(yyp); } -public static object Typename_2_factory(Parser yyp) { return new Typename_2(yyp); } -public static object Typename_4_factory(Parser yyp) { return new Typename_4(yyp); } -public static object ArgumentList_factory(Parser yyp) { return new ArgumentList(yyp); } -public static object BinaryExpression_12_factory(Parser yyp) { return new BinaryExpression_12(yyp); } -public static object BinaryExpression_13_factory(Parser yyp) { return new BinaryExpression_13(yyp); } -public static object GlobalFunctionDefinition_2_factory(Parser yyp) { return new GlobalFunctionDefinition_2(yyp); } -public static object StateChange_2_factory(Parser yyp) { return new StateChange_2(yyp); } -public static object VoidArgEvent_1_factory(Parser yyp) { return new VoidArgEvent_1(yyp); } -public static object VoidArgEvent_3_factory(Parser yyp) { return new VoidArgEvent_3(yyp); } -public static object BinaryExpression_10_factory(Parser yyp) { return new BinaryExpression_10(yyp); } -public static object VoidArgEvent_5_factory(Parser yyp) { return new VoidArgEvent_5(yyp); } -public static object VoidArgEvent_6_factory(Parser yyp) { return new VoidArgEvent_6(yyp); } -public static object VoidArgEvent_7_factory(Parser yyp) { return new VoidArgEvent_7(yyp); } -public static object VoidArgEvent_8_factory(Parser yyp) { return new VoidArgEvent_8(yyp); } -public static object BinaryExpression_17_factory(Parser yyp) { return new BinaryExpression_17(yyp); } -public static object StateEvent_1_factory(Parser yyp) { return new StateEvent_1(yyp); } -public static object VectorConstant_factory(Parser yyp) { return new VectorConstant(yyp); } -public static object VectorArgEvent_1_factory(Parser yyp) { return new VectorArgEvent_1(yyp); } -public static object IntDeclaration_factory(Parser yyp) { return new IntDeclaration(yyp); } -public static object VectorArgEvent_3_factory(Parser yyp) { return new VectorArgEvent_3(yyp); } -public static object TypecastExpression_4_factory(Parser yyp) { return new TypecastExpression_4(yyp); } -public static object TypecastExpression_6_factory(Parser yyp) { return new TypecastExpression_6(yyp); } -public static object TypecastExpression_7_factory(Parser yyp) { return new TypecastExpression_7(yyp); } -public static object FunctionCall_factory(Parser yyp) { return new FunctionCall(yyp); } -public static object ListConstant_1_factory(Parser yyp) { return new ListConstant_1(yyp); } -public static object BinaryExpression_18_factory(Parser yyp) { return new BinaryExpression_18(yyp); } -public static object Event_6_factory(Parser yyp) { return new Event_6(yyp); } -public static object KeyArgEvent_2_factory(Parser yyp) { return new KeyArgEvent_2(yyp); } -public static object Declaration_1_factory(Parser yyp) { return new Declaration_1(yyp); } -public static object EmptyStatement_1_factory(Parser yyp) { return new EmptyStatement_1(yyp); } -public static object SimpleAssignment_7_factory(Parser yyp) { return new SimpleAssignment_7(yyp); } -public static object ForLoop_factory(Parser yyp) { return new ForLoop(yyp); } -public static object ForLoop_2_factory(Parser yyp) { return new ForLoop_2(yyp); } -public static object KeyIntIntArgStateEvent_1_factory(Parser yyp) { return new KeyIntIntArgStateEvent_1(yyp); } -public static object KeyArgumentDeclarationList_1_factory(Parser yyp) { return new KeyArgumentDeclarationList_1(yyp); } -public static object GlobalFunctionDefinition_1_factory(Parser yyp) { return new GlobalFunctionDefinition_1(yyp); } -public static object IfStatement_factory(Parser yyp) { return new IfStatement(yyp); } -public static object ForLoopStatement_1_factory(Parser yyp) { return new ForLoopStatement_1(yyp); } -public static object ForLoopStatement_2_factory(Parser yyp) { return new ForLoopStatement_2(yyp); } -public static object ForLoopStatement_3_factory(Parser yyp) { return new ForLoopStatement_3(yyp); } -public static object IntRotRotArgumentDeclarationList_factory(Parser yyp) { return new IntRotRotArgumentDeclarationList(yyp); } -public static object IntArgEvent_1_factory(Parser yyp) { return new IntArgEvent_1(yyp); } -public static object IntArgEvent_2_factory(Parser yyp) { return new IntArgEvent_2(yyp); } -public static object WhileStatement_factory(Parser yyp) { return new WhileStatement(yyp); } -public static object ForLoop_1_factory(Parser yyp) { return new ForLoop_1(yyp); } -public static object Constant_2_factory(Parser yyp) { return new Constant_2(yyp); } -public static object VoidArgEvent_factory(Parser yyp) { return new VoidArgEvent(yyp); } -public static object RotDeclaration_factory(Parser yyp) { return new RotDeclaration(yyp); } -public static object WhileStatement_1_factory(Parser yyp) { return new WhileStatement_1(yyp); } -public static object WhileStatement_2_factory(Parser yyp) { return new WhileStatement_2(yyp); } -public static object VectorArgStateEvent_1_factory(Parser yyp) { return new VectorArgStateEvent_1(yyp); } -public static object IdentExpression_1_factory(Parser yyp) { return new IdentExpression_1(yyp); } -public static object VectorArgumentDeclarationList_factory(Parser yyp) { return new VectorArgumentDeclarationList(yyp); } +public static object IncrementDecrementExpression_5_factory(Parser yyp) { return new IncrementDecrementExpression_5(yyp); } +public static object Statement_2_factory(Parser yyp) { return new Statement_2(yyp); } +public static object ListConstant_factory(Parser yyp) { return new ListConstant(yyp); } public static object States_factory(Parser yyp) { return new States(yyp); } -public static object VoidArgStateEvent_factory(Parser yyp) { return new VoidArgStateEvent(yyp); } +public static object TypecastExpression_2_factory(Parser yyp) { return new TypecastExpression_2(yyp); } +public static object ArgumentList_2_factory(Parser yyp) { return new ArgumentList_2(yyp); } +public static object StateBody_14_factory(Parser yyp) { return new StateBody_14(yyp); } +public static object KeyArgEvent_1_factory(Parser yyp) { return new KeyArgEvent_1(yyp); } +public static object VectorConstant_factory(Parser yyp) { return new VectorConstant(yyp); } +public static object SimpleAssignment_3_factory(Parser yyp) { return new SimpleAssignment_3(yyp); } +public static object Typename_5_factory(Parser yyp) { return new Typename_5(yyp); } +public static object TypecastExpression_8_factory(Parser yyp) { return new TypecastExpression_8(yyp); } +public static object SimpleAssignment_21_factory(Parser yyp) { return new SimpleAssignment_21(yyp); } +public static object JumpLabel_1_factory(Parser yyp) { return new JumpLabel_1(yyp); } +public static object TypecastExpression_4_factory(Parser yyp) { return new TypecastExpression_4(yyp); } +public static object JumpStatement_1_factory(Parser yyp) { return new JumpStatement_1(yyp); } +public static object VoidArgEvent_8_factory(Parser yyp) { return new VoidArgEvent_8(yyp); } +public static object GlobalVariableDeclaration_2_factory(Parser yyp) { return new GlobalVariableDeclaration_2(yyp); } +public static object GlobalVariableDeclaration_1_factory(Parser yyp) { return new GlobalVariableDeclaration_1(yyp); } +public static object RotDeclaration_1_factory(Parser yyp) { return new RotDeclaration_1(yyp); } +public static object WhileStatement_1_factory(Parser yyp) { return new WhileStatement_1(yyp); } +public static object VecDeclaration_1_factory(Parser yyp) { return new VecDeclaration_1(yyp); } +public static object IntRotRotArgStateEvent_factory(Parser yyp) { return new IntRotRotArgStateEvent(yyp); } +public static object Constant_3_factory(Parser yyp) { return new Constant_3(yyp); } +public static object Declaration_factory(Parser yyp) { return new Declaration(yyp); } +public static object IntVecVecArgStateEvent_1_factory(Parser yyp) { return new IntVecVecArgStateEvent_1(yyp); } +public static object ArgumentDeclarationList_5_factory(Parser yyp) { return new ArgumentDeclarationList_5(yyp); } +public static object ReturnStatement_factory(Parser yyp) { return new ReturnStatement(yyp); } +public static object EmptyStatement_1_factory(Parser yyp) { return new EmptyStatement_1(yyp); } } public class LSLSyntax : Parser { diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs index 9d72b1c697..a98311e17b 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs @@ -771,7 +771,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance /// public object EventProcessor() { - EventParams data = null; // We check here as the thread stopping this instance from running may itself hold the m_Script lock. if (!Running) return 0; diff --git a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs index f16fd0146b..e9ee9371bc 100644 --- a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs +++ b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs @@ -28,6 +28,7 @@ using System; using System.Collections; using System.Globalization; +using System.Text; using System.Text.RegularExpressions; using OpenSim.Framework; @@ -38,7 +39,6 @@ using OMV_Quaternion = OpenMetaverse.Quaternion; namespace OpenSim.Region.ScriptEngine.Shared { - [Serializable] public partial class LSL_Types { // Types are kept is separate .dll to avoid having to add whatever .dll it is in it to script AppDomain @@ -270,13 +270,15 @@ namespace OpenSim.Region.ScriptEngine.Shared // Vector-Rotation Math public static Vector3 operator *(Vector3 v, Quaternion r) { - Quaternion vq = new Quaternion(v.x, v.y, v.z, 0); - Quaternion nq = new Quaternion(-r.x, -r.y, -r.z, r.s); + double rx = r.s * v.x + r.y * v.z - r.z * v.y; + double ry = r.s * v.y + r.z * v.x - r.x * v.z; + double rz = r.s * v.z + r.x * v.y - r.y * v.x; - // adapted for operator * computing "b * a" - Quaternion result = nq * (vq * r); + v.x += 2.0f * (rz * r.y - ry * r.z); + v.y += 2.0f * (rx * r.z - rz * r.x); + v.z += 2.0f * (ry * r.x - rx * r.y); - return new Vector3(result.x, result.y, result.z); + return v; } public static Vector3 operator /(Vector3 v, Quaternion r) @@ -304,6 +306,11 @@ namespace OpenSim.Region.ScriptEngine.Shared ); } + public static double MagSquare(Vector3 v) + { + return v.x * v.x + v.y * v.y + v.z * v.z; + } + public static double Mag(Vector3 v) { return Math.Sqrt(v.x * v.x + v.y * v.y + v.z * v.z); @@ -385,8 +392,8 @@ namespace OpenSim.Region.ScriptEngine.Shared #region Methods public Quaternion Normalize() { - double length = Math.Sqrt(x * x + y * y + z * z + s * s); - if (length < float.Epsilon) + double lengthsq = x * x + y * y + z * z + s * s; + if (lengthsq < float.Epsilon) { x = 0; y = 0; @@ -396,7 +403,7 @@ namespace OpenSim.Region.ScriptEngine.Shared else { - double invLength = 1.0 / length; + double invLength = 1.0 / Math.Sqrt(lengthsq); x *= invLength; y *= invLength; z *= invLength; @@ -467,7 +474,8 @@ namespace OpenSim.Region.ScriptEngine.Shared { // LSL quaternions can normalize to 0, normal Quaternions can't. if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0) - rot.z = 1; // ZERO_ROTATION = 0,0,0,1 + return OMV_Quaternion.Identity; // ZERO_ROTATION = 0,0,0,1 + OMV_Quaternion omvrot = new OMV_Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s); omvrot.Normalize(); return omvrot; @@ -503,6 +511,7 @@ namespace OpenSim.Region.ScriptEngine.Shared public static Quaternion operator /(Quaternion a, Quaternion b) { + // assuming normalized b.s = -b.s; return a * b; } @@ -525,7 +534,7 @@ namespace OpenSim.Region.ScriptEngine.Shared } [Serializable] - public struct list + public class list { private object[] m_data; @@ -1152,34 +1161,35 @@ namespace OpenSim.Region.ScriptEngine.Shared public string ToCSV() { - string ret = ""; - foreach (object o in this.Data) + if(m_data == null || m_data.Length == 0) + return String.Empty; + + Object o = m_data[0]; + int len = m_data.Length; + if(len == 1) + return o.ToString(); + + StringBuilder sb = new StringBuilder(1024); + sb.Append(o.ToString()); + for(int i = 1 ; i < len; i++) { - if (ret == "") - { - ret = o.ToString(); - } - else - { - ret = ret + ", " + o.ToString(); - } + sb.Append(","); + sb.Append(o.ToString()); } - return ret; + return sb.ToString(); } private string ToSoup() { - string output; - output = String.Empty; - if (Data.Length == 0) - { + if(m_data == null || m_data.Length == 0) return String.Empty; - } - foreach (object o in Data) + + StringBuilder sb = new StringBuilder(1024); + foreach (object o in m_data) { - output = output + o.ToString(); + sb.Append(o.ToString()); } - return output; + return sb.ToString(); } public static explicit operator String(list l) @@ -1369,26 +1379,33 @@ namespace OpenSim.Region.ScriptEngine.Shared public string ToPrettyString() { - string output; - if (Data.Length == 0) - { + if(m_data == null || m_data.Length == 0) return "[]"; - } - output = "["; - foreach (object o in Data) + + StringBuilder sb = new StringBuilder(1024); + int len = m_data.Length; + int last = len - 1; + object o; + + sb.Append("["); + for(int i = 0; i < len; i++ ) { + o = m_data[i]; if (o is String) { - output = output + "\"" + o + "\", "; + sb.Append("\""); + sb.Append((String)o); + sb.Append("\""); } else { - output = output + o.ToString() + ", "; + sb.Append(o.ToString()); } + if(i < last) + sb.Append(","); } - output = output.Substring(0, output.Length - 2); - output = output + "]"; - return output; + sb.Append("]"); + return sb.ToString(); } public class AlphaCompare : IComparer diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiHttpTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiHttpTests.cs index 4dc8fc6829..8e6adddc46 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiHttpTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiHttpTests.cs @@ -87,17 +87,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests uint port = 9999; MainServer.RemoveHttpServer(port); - BaseHttpServer server = new BaseHttpServer(port, false, 0, ""); + m_engine = new MockScriptEngine(); + m_urlModule = new UrlModule(); + + IConfigSource config = new IniConfigSource(); + config.AddConfig("Network"); + config.Configs["Network"].Set("ExternalHostNameForLSL", "127.0.0.1"); + m_scene = new SceneHelpers().SetupScene(); + + BaseHttpServer server = new BaseHttpServer(port); MainServer.AddHttpServer(server); MainServer.Instance = server; server.Start(); - m_engine = new MockScriptEngine(); - m_urlModule = new UrlModule(); - - m_scene = new SceneHelpers().SetupScene(); - SceneHelpers.SetupSceneModules(m_scene, new IniConfigSource(), m_engine, m_urlModule); + SceneHelpers.SetupSceneModules(m_scene, config, m_engine, m_urlModule); SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene); m_scriptItem = TaskInventoryHelpers.AddScript(m_scene.AssetService, so.RootPart); @@ -153,7 +157,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests using (HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse()) {} } - catch (WebException e) + catch (WebException) { // using (HttpWebResponse response = (HttpWebResponse)e.Response) // gotExpectedException = response.StatusCode == HttpStatusCode.NotFound; diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 0ccc6835c6..c86a50e43b 100755 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -78,7 +78,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine /// A parameter to allow us to notify the log if at least one script has a compilation that is not compatible /// with ScriptStopStrategy. /// - public bool HaveNotifiedLogOfScriptStopMistmatch { get; private set; } + public bool HaveNotifiedLogOfScriptStopMismatch { get; private set; } private SmartThreadPool m_ThreadPool; private int m_MaxScriptQueue; @@ -827,6 +827,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine if (m_ScriptEngines.Contains(this)) m_ScriptEngines.Remove(this); } + + lock(m_Scripts) + m_ThreadPool.Shutdown(); } public object DoBackup(object o) @@ -1076,6 +1079,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine "[XEngine]: Started {0} scripts in {1}", scriptsStarted, m_Scene.Name); } } + catch (System.Threading.ThreadAbortException) { } catch (Exception e) { m_log.Error( @@ -1476,7 +1480,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine } } - if (m_coopTermination != coopTerminationForThisScript && !HaveNotifiedLogOfScriptStopMistmatch) + if (m_coopTermination != coopTerminationForThisScript && !HaveNotifiedLogOfScriptStopMismatch) { // Notify the log that there is at least one script compile that doesn't match the // ScriptStopStrategy. Operator has to manually delete old DLLs - we can't do this on Windows @@ -1486,7 +1490,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine + "\nContinuing with script compiled strategy but to remove this message please set [XEngine] DeleteScriptsOnStartup = true for one simulator session to remove old script DLLs (script state will not be lost).", World.Name, coopTerminationForThisScript ? "co-op" : "abort", m_coopTermination ? "co-op" : "abort"); - HaveNotifiedLogOfScriptStopMistmatch = true; + HaveNotifiedLogOfScriptStopMismatch = true; } instance = new ScriptInstance(this, part, @@ -2094,6 +2098,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine string xml = instance.GetXMLState(); XmlDocument sdoc = new XmlDocument(); + bool loadedState = true; try { @@ -2145,10 +2150,11 @@ namespace OpenSim.Region.ScriptEngine.XEngine string fn = Path.GetFileName(assemName); string assem = String.Empty; + string assemNameText = assemName + ".text"; - if (File.Exists(assemName + ".text")) + if (File.Exists(assemNameText)) { - FileInfo tfi = new FileInfo(assemName + ".text"); + FileInfo tfi = new FileInfo(assemNameText); if (tfi != null) { @@ -2156,7 +2162,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine try { - using (FileStream tfs = File.Open(assemName + ".text", + using (FileStream tfs = File.Open(assemNameText, FileMode.Open, FileAccess.Read)) { tfs.Read(tdata, 0, tdata.Length); diff --git a/OpenSim/Region/ScriptEngine/YEngine/MMRDelegateCommon.cs b/OpenSim/Region/ScriptEngine/YEngine/MMRDelegateCommon.cs new file mode 100644 index 0000000000..433062ad77 --- /dev/null +++ b/OpenSim/Region/ScriptEngine/YEngine/MMRDelegateCommon.cs @@ -0,0 +1,117 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Reflection.Emit; + +namespace OpenSim.Region.ScriptEngine.Yengine +{ + + public class DelegateCommon + { + private string sig; // rettype(arg1type,arg2type,...), eg, "void(list,string,integer)" + private Type type; // resultant delegate type + + private static Dictionary delegateCommons = new Dictionary(); + private static Dictionary delegateCommonsBySysType = new Dictionary(); + private static ModuleBuilder delegateModuleBuilder = null; + public static Type[] constructorArgTypes = new Type[] { typeof(object), typeof(IntPtr) }; + + private DelegateCommon() + { + } + + public static Type GetType(System.Type ret, System.Type[] args, string sig) + { + DelegateCommon dc; + lock(delegateCommons) + { + if(!delegateCommons.TryGetValue(sig, out dc)) + { + dc = new DelegateCommon(); + dc.sig = sig; + dc.type = CreateDelegateType(sig, ret, args); + delegateCommons.Add(sig, dc); + delegateCommonsBySysType.Add(dc.type, dc); + } + } + return dc.type; + } + + public static Type TryGetType(string sig) + { + DelegateCommon dc; + lock(delegateCommons) + { + if(!delegateCommons.TryGetValue(sig, out dc)) + dc = null; + } + return (dc == null) ? null : dc.type; + } + + public static string TryGetName(Type t) + { + DelegateCommon dc; + lock(delegateCommons) + { + if(!delegateCommonsBySysType.TryGetValue(t, out dc)) + dc = null; + } + return (dc == null) ? null : dc.sig; + } + + // http://blog.bittercoder.com/PermaLink,guid,a770377a-b1ad-4590-9145-36381757a52b.aspx + private static Type CreateDelegateType(string name, Type retType, Type[] argTypes) + { + if(delegateModuleBuilder == null) + { + AssemblyName assembly = new AssemblyName(); + assembly.Name = "CustomDelegateAssembly"; + AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assembly, AssemblyBuilderAccess.Run); + delegateModuleBuilder = assemblyBuilder.DefineDynamicModule("CustomDelegateModule"); + } + + TypeBuilder typeBuilder = delegateModuleBuilder.DefineType(name, + TypeAttributes.Public | TypeAttributes.Sealed | TypeAttributes.Class | + TypeAttributes.AnsiClass | TypeAttributes.AutoClass, typeof(MulticastDelegate)); + + ConstructorBuilder constructorBuilder = typeBuilder.DefineConstructor( + MethodAttributes.RTSpecialName | MethodAttributes.HideBySig | MethodAttributes.Public, + CallingConventions.Standard, constructorArgTypes); + constructorBuilder.SetImplementationFlags(MethodImplAttributes.Runtime | MethodImplAttributes.Managed); + + MethodBuilder methodBuilder = typeBuilder.DefineMethod("Invoke", + MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.NewSlot | + MethodAttributes.Virtual, retType, argTypes); + methodBuilder.SetImplementationFlags(MethodImplAttributes.Managed | MethodImplAttributes.Runtime); + + return typeBuilder.CreateType(); + } + } +} diff --git a/OpenSim/Region/ScriptEngine/YEngine/MMRIEventHandlers.cs b/OpenSim/Region/ScriptEngine/YEngine/MMRIEventHandlers.cs new file mode 100644 index 0000000000..905a23072f --- /dev/null +++ b/OpenSim/Region/ScriptEngine/YEngine/MMRIEventHandlers.cs @@ -0,0 +1,78 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; +using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; +using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; +using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list; +using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; +using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; +using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; + +namespace OpenSim.Region.ScriptEngine.Yengine +{ + public interface IEventHandlers + { + void at_rot_target(int tnum, LSL_Rotation targetrot, LSL_Rotation ourrot); + void at_target(int tnum, LSL_Vector targetpos, LSL_Vector ourpos); + void attach(string id); + void changed(int change); + void collision(int num_detected); + void collision_end(int num_detected); + void collision_start(int num_detected); + void control(string id, int held, int change); + void dataserver(string queryid, string data); + void email(string time, string address, string subj, string message, int num_left); + void http_request(string request_id, string method, string body); + void http_response(string request_id, int status, LSL_List metadata, string body); + void land_collision(LSL_Vector pos); + void land_collision_end(LSL_Vector pos); + void land_collision_start(LSL_Vector pos); + void link_message(int sender_num, int num, string str, string id); + void listen(int channel, string name, string id, string message); + void money(string id, int amount); + void moving_end(); + void moving_start(); + void no_sensor(); + void not_at_rot_target(); + void not_at_target(); + void object_rez(string id); + void on_rez(int start_param); + void remote_data(int event_type, string channel, string message_id, string sender, int idata, string sdata); + void run_time_permissions(int perm); + void sensor(int num_detected); + void state_entry(); + void state_exit(); + void timer(); + void touch(int num_detected); + void touch_start(int num_detected); + void touch_end(int num_detected); + void transaction_result(string id, int success, string data); + void path_update(int type, LSL_List data); + void region_cross(LSL_Vector newpos, LSL_Vector oldpos); + } +} diff --git a/OpenSim/Region/ScriptEngine/YEngine/MMRInternalFuncDict.cs b/OpenSim/Region/ScriptEngine/YEngine/MMRInternalFuncDict.cs new file mode 100644 index 0000000000..ca7c372d6d --- /dev/null +++ b/OpenSim/Region/ScriptEngine/YEngine/MMRInternalFuncDict.cs @@ -0,0 +1,93 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.IO; +using System.Reflection; + +namespace OpenSim.Region.ScriptEngine.Yengine +{ + + public class InternalFuncDict: VarDict + { + /** + * @brief build dictionary of internal functions from an interface. + * @param iface = interface with function definitions + * @param inclSig = true: catalog by name with arg sig, eg, llSay(integer,string) + * false: catalog by simple name only, eg, state_entry + * @returns dictionary of function definition tokens + */ + public InternalFuncDict(Type iface, bool inclSig) + : base(false) + { + // Loop through list of all methods declared in the interface. + System.Reflection.MethodInfo[] ifaceMethods = iface.GetMethods(); + foreach(System.Reflection.MethodInfo ifaceMethod in ifaceMethods) + { + string key = ifaceMethod.Name; + + // Only do ones that begin with lower-case letters... + // as any others can't be referenced by scripts + if((key[0] < 'a') || (key[0] > 'z')) + continue; + + try + { + // Create a corresponding TokenDeclVar struct. + System.Reflection.ParameterInfo[] parameters = ifaceMethod.GetParameters(); + TokenArgDecl argDecl = new TokenArgDecl(null); + for(int i = 0; i < parameters.Length; i++) + { + System.Reflection.ParameterInfo param = parameters[i]; + TokenType type = TokenType.FromSysType(null, param.ParameterType); + TokenName name = new TokenName(null, param.Name); + argDecl.AddArg(type, name); + } + TokenDeclVar declFunc = new TokenDeclVar(null, null, null); + declFunc.name = new TokenName(null, key); + declFunc.retType = TokenType.FromSysType(null, ifaceMethod.ReturnType); + declFunc.argDecl = argDecl; + + // Add the TokenDeclVar struct to the dictionary. + this.AddEntry(declFunc); + } + catch(Exception except) + { + + string msg = except.ToString(); + int i = msg.IndexOf("\n"); + if(i > 0) + msg = msg.Substring(0, i); + Console.WriteLine("InternalFuncDict*: {0}: {1}", key, msg); + + ///??? IGNORE ANY THAT FAIL - LIKE UNRECOGNIZED TYPE ???/// + } + } + } + } +} diff --git a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptBinOpStr.cs b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptBinOpStr.cs new file mode 100644 index 0000000000..0d6d4bd7c1 --- /dev/null +++ b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptBinOpStr.cs @@ -0,0 +1,1569 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using OpenSim.Region.ScriptEngine.Shared.ScriptBase; +using OpenSim.Region.ScriptEngine.Yengine; +using System; +using System.Collections.Generic; +using System.IO; +using System.Reflection; +using System.Reflection.Emit; +using System.Text; +using System.Text.RegularExpressions; + +using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; +using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; +using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; +using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list; +using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; +using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; +using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; + +namespace OpenSim.Region.ScriptEngine.Yengine +{ + + /** + * @brief This class is used to catalog the code emit routines based on a key string + * The key string has the two types (eg, "integer", "rotation") and the operator (eg, "*", "!=") + */ + public delegate void BinOpStrEmitBO(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result); + public class BinOpStr + { + public static readonly Dictionary defined = DefineBinOps(); + + public Type outtype; // type of result of computation + public BinOpStrEmitBO emitBO; // how to compute result + public bool rmwOK; // is the = form valid? + + public BinOpStr(Type outtype, BinOpStrEmitBO emitBO) + { + this.outtype = outtype; + this.emitBO = emitBO; + this.rmwOK = false; + } + + public BinOpStr(Type outtype, BinOpStrEmitBO emitBO, bool rmwOK) + { + this.outtype = outtype; + this.emitBO = emitBO; + this.rmwOK = rmwOK; + } + + private static TokenTypeBool tokenTypeBool = new TokenTypeBool(null); + private static TokenTypeChar tokenTypeChar = new TokenTypeChar(null); + private static TokenTypeFloat tokenTypeFloat = new TokenTypeFloat(null); + private static TokenTypeInt tokenTypeInt = new TokenTypeInt(null); + private static TokenTypeList tokenTypeList = new TokenTypeList(null); + private static TokenTypeRot tokenTypeRot = new TokenTypeRot(null); + private static TokenTypeStr tokenTypeStr = new TokenTypeStr(null); + private static TokenTypeVec tokenTypeVec = new TokenTypeVec(null); + + private static MethodInfo stringAddStringMethInfo = ScriptCodeGen.GetStaticMethod(typeof(string), "Concat", new Type[] { typeof(string), typeof(string) }); + private static MethodInfo stringCmpStringMethInfo = ScriptCodeGen.GetStaticMethod(typeof(string), "Compare", new Type[] { typeof(string), typeof(string) }); + + private static MethodInfo infoMethListAddFloat = GetBinOpsMethod("MethListAddFloat", new Type[] { typeof(LSL_List), typeof(double) }); + private static MethodInfo infoMethListAddInt = GetBinOpsMethod("MethListAddInt", new Type[] { typeof(LSL_List), typeof(int) }); + private static MethodInfo infoMethListAddKey = GetBinOpsMethod("MethListAddKey", new Type[] { typeof(LSL_List), typeof(string) }); + private static MethodInfo infoMethListAddRot = GetBinOpsMethod("MethListAddRot", new Type[] { typeof(LSL_List), typeof(LSL_Rotation) }); + private static MethodInfo infoMethListAddStr = GetBinOpsMethod("MethListAddStr", new Type[] { typeof(LSL_List), typeof(string) }); + private static MethodInfo infoMethListAddVec = GetBinOpsMethod("MethListAddVec", new Type[] { typeof(LSL_List), typeof(LSL_Vector) }); + private static MethodInfo infoMethListAddList = GetBinOpsMethod("MethListAddList", new Type[] { typeof(LSL_List), typeof(LSL_List) }); + private static MethodInfo infoMethFloatAddList = GetBinOpsMethod("MethFloatAddList", new Type[] { typeof(double), typeof(LSL_List) }); + private static MethodInfo infoMethIntAddList = GetBinOpsMethod("MethIntAddList", new Type[] { typeof(int), typeof(LSL_List) }); + private static MethodInfo infoMethKeyAddList = GetBinOpsMethod("MethKeyAddList", new Type[] { typeof(string), typeof(LSL_List) }); + private static MethodInfo infoMethRotAddList = GetBinOpsMethod("MethRotAddList", new Type[] { typeof(LSL_Rotation), typeof(LSL_List) }); + private static MethodInfo infoMethStrAddList = GetBinOpsMethod("MethStrAddList", new Type[] { typeof(string), typeof(LSL_List) }); + private static MethodInfo infoMethVecAddList = GetBinOpsMethod("MethVecAddList", new Type[] { typeof(LSL_Vector), typeof(LSL_List) }); + private static MethodInfo infoMethListEqList = GetBinOpsMethod("MethListEqList", new Type[] { typeof(LSL_List), typeof(LSL_List) }); + private static MethodInfo infoMethListNeList = GetBinOpsMethod("MethListNeList", new Type[] { typeof(LSL_List), typeof(LSL_List) }); + private static MethodInfo infoMethRotEqRot = GetBinOpsMethod("MethRotEqRot", new Type[] { typeof(LSL_Rotation), typeof(LSL_Rotation) }); + private static MethodInfo infoMethRotNeRot = GetBinOpsMethod("MethRotNeRot", new Type[] { typeof(LSL_Rotation), typeof(LSL_Rotation) }); + private static MethodInfo infoMethRotAddRot = GetBinOpsMethod("MethRotAddRot", new Type[] { typeof(LSL_Rotation), typeof(LSL_Rotation) }); + private static MethodInfo infoMethRotSubRot = GetBinOpsMethod("MethRotSubRot", new Type[] { typeof(LSL_Rotation), typeof(LSL_Rotation) }); + private static MethodInfo infoMethRotMulRot = GetBinOpsMethod("MethRotMulRot", new Type[] { typeof(LSL_Rotation), typeof(LSL_Rotation) }); + private static MethodInfo infoMethRotDivRot = GetBinOpsMethod("MethRotDivRot", new Type[] { typeof(LSL_Rotation), typeof(LSL_Rotation) }); + private static MethodInfo infoMethVecEqVec = GetBinOpsMethod("MethVecEqVec", new Type[] { typeof(LSL_Vector), typeof(LSL_Vector) }); + private static MethodInfo infoMethVecNeVec = GetBinOpsMethod("MethVecNeVec", new Type[] { typeof(LSL_Vector), typeof(LSL_Vector) }); + private static MethodInfo infoMethVecAddVec = GetBinOpsMethod("MethVecAddVec", new Type[] { typeof(LSL_Vector), typeof(LSL_Vector) }); + private static MethodInfo infoMethVecSubVec = GetBinOpsMethod("MethVecSubVec", new Type[] { typeof(LSL_Vector), typeof(LSL_Vector) }); + private static MethodInfo infoMethVecMulVec = GetBinOpsMethod("MethVecMulVec", new Type[] { typeof(LSL_Vector), typeof(LSL_Vector) }); + private static MethodInfo infoMethVecModVec = GetBinOpsMethod("MethVecModVec", new Type[] { typeof(LSL_Vector), typeof(LSL_Vector) }); + private static MethodInfo infoMethVecMulFloat = GetBinOpsMethod("MethVecMulFloat", new Type[] { typeof(LSL_Vector), typeof(double) }); + private static MethodInfo infoMethFloatMulVec = GetBinOpsMethod("MethFloatMulVec", new Type[] { typeof(double), typeof(LSL_Vector) }); + private static MethodInfo infoMethVecDivFloat = GetBinOpsMethod("MethVecDivFloat", new Type[] { typeof(LSL_Vector), typeof(double) }); + private static MethodInfo infoMethVecMulInt = GetBinOpsMethod("MethVecMulInt", new Type[] { typeof(LSL_Vector), typeof(int) }); + private static MethodInfo infoMethIntMulVec = GetBinOpsMethod("MethIntMulVec", new Type[] { typeof(int), typeof(LSL_Vector) }); + private static MethodInfo infoMethVecDivInt = GetBinOpsMethod("MethVecDivInt", new Type[] { typeof(LSL_Vector), typeof(int) }); + private static MethodInfo infoMethVecMulRot = GetBinOpsMethod("MethVecMulRot", new Type[] { typeof(LSL_Vector), typeof(LSL_Rotation) }); + private static MethodInfo infoMethVecDivRot = GetBinOpsMethod("MethVecDivRot", new Type[] { typeof(LSL_Vector), typeof(LSL_Rotation) }); + + private static MethodInfo GetBinOpsMethod(string name, Type[] types) + { + return ScriptCodeGen.GetStaticMethod(typeof(BinOpStr), name, types); + } + + /** + * @brief Create a dictionary for processing binary operators. + * This tells us, for a given type, an operator and another type, + * is the operation permitted, and if so, what is the type of the result? + * The key is , + * where and are strings returned by (TokenType...).ToString() + * and is string returned by (TokenKw...).ToString() + * The value is a BinOpStr struct giving the resultant type and a method to generate the code. + */ + private static Dictionary DefineBinOps() + { + Dictionary bos = new Dictionary(); + + string[] booltypes = new string[] { "bool", "char", "float", "integer", "key", "list", "string" }; + + /* + * Get the && and || all out of the way... + * Simply cast their left and right operands to boolean then process. + */ + for(int i = 0; i < booltypes.Length; i++) + { + for(int j = 0; j < booltypes.Length; j++) + { + bos.Add(booltypes[i] + "&&" + booltypes[j], + new BinOpStr(typeof(bool), BinOpStrAndAnd)); + bos.Add(booltypes[i] + "||" + booltypes[j], + new BinOpStr(typeof(bool), BinOpStrOrOr)); + } + } + + /* + * Pound through all the other combinations we support. + */ + + // boolean : somethingelse + DefineBinOpsBoolX(bos, "bool"); + DefineBinOpsBoolX(bos, "char"); + DefineBinOpsBoolX(bos, "float"); + DefineBinOpsBoolX(bos, "integer"); + DefineBinOpsBoolX(bos, "key"); + DefineBinOpsBoolX(bos, "list"); + DefineBinOpsBoolX(bos, "string"); + + // stuff with chars + DefineBinOpsChar(bos); + + // somethingelse : boolean + DefineBinOpsXBool(bos, "char"); + DefineBinOpsXBool(bos, "float"); + DefineBinOpsXBool(bos, "integer"); + DefineBinOpsXBool(bos, "key"); + DefineBinOpsXBool(bos, "list"); + DefineBinOpsXBool(bos, "string"); + + // float : somethingelse + DefineBinOpsFloatX(bos, "float"); + DefineBinOpsFloatX(bos, "integer"); + + // integer : float + DefineBinOpsXFloat(bos, "integer"); + + // anything else with integers + DefineBinOpsInteger(bos); + + // key : somethingelse + DefineBinOpsKeyX(bos, "key"); + DefineBinOpsKeyX(bos, "string"); + + // string : key + DefineBinOpsXKey(bos, "string"); + + // things with lists + DefineBinOpsList(bos); + + // things with rotations + DefineBinOpsRotation(bos); + + // things with strings + DefineBinOpsString(bos); + + // things with vectors + DefineBinOpsVector(bos); + + // Contrary to some beliefs, scripts do things like string+integer and integer+string + bos.Add("bool+string", new BinOpStr(typeof(string), BinOpStrStrAddStr)); + bos.Add("char+string", new BinOpStr(typeof(string), BinOpStrStrAddStr)); + bos.Add("float+string", new BinOpStr(typeof(string), BinOpStrStrAddStr)); + bos.Add("integer+string", new BinOpStr(typeof(string), BinOpStrStrAddStr)); + bos.Add("string+bool", new BinOpStr(typeof(string), BinOpStrStrAddStr, true)); + bos.Add("string+char", new BinOpStr(typeof(string), BinOpStrStrAddStr, true)); + bos.Add("string+float", new BinOpStr(typeof(string), BinOpStrStrAddStr, true)); + bos.Add("string+integer", new BinOpStr(typeof(string), BinOpStrStrAddStr, true)); + + // Now for our final slight-of-hand, we're going to scan through all those. + // And wherever we see an 'integer' in the key, we are going to make another + // entry with 'bool', as we want to accept a bool as having a value of 0 or 1. + // This lets us do things like 3.5 * (x > 0). + + Dictionary bos2 = new Dictionary(); + foreach(KeyValuePair kvp in bos) + { + string key = kvp.Key; + BinOpStr val = kvp.Value; + bos2.Add(key, val); + } + Regex wordReg = new Regex("\\w+"); + Regex opReg = new Regex("\\W+"); + foreach(KeyValuePair kvp in bos) + { + string key = kvp.Key; + BinOpStr val = kvp.Value; + MatchCollection matches = wordReg.Matches(key); + if(matches.Count != 2) + continue; + Match opM = opReg.Match(key); + if(!opM.Success) + continue; + string left = matches[0].Value; + string right = matches[1].Value; + string op = opM.Value; + string key2; + if(left == "integer" && right == "integer") + { + key2 = "bool" + op + "bool"; + if(!bos2.ContainsKey(key2)) + bos2.Add(key2, val); + key2 = "bool" + op + "integer"; + if(!bos2.ContainsKey(key2)) + bos2.Add(key2, val); + key2 = "integer" + op + "bool"; + if(!bos2.ContainsKey(key2)) + bos2.Add(key2, val); + } + else + { + key2 = key.Replace("integer", "bool"); + if(!bos2.ContainsKey(key2)) + bos2.Add(key2, val); + } + } + return bos2; + } + + private static void DefineBinOpsBoolX(Dictionary bos, string x) + { + bos.Add("bool|" + x, new BinOpStr(typeof(int), BinOpStrBoolOrX)); + bos.Add("bool^" + x, new BinOpStr(typeof(int), BinOpStrBoolXorX)); + bos.Add("bool&" + x, new BinOpStr(typeof(int), BinOpStrBoolAndX)); + bos.Add("bool==" + x, new BinOpStr(typeof(bool), BinOpStrBoolEqX)); + bos.Add("bool!=" + x, new BinOpStr(typeof(bool), BinOpStrBoolNeX)); + } + + private static void DefineBinOpsXBool(Dictionary bos, string x) + { + bos.Add(x + "|bool", new BinOpStr(typeof(int), BinOpStrBoolOrX)); + bos.Add(x + "^bool", new BinOpStr(typeof(int), BinOpStrBoolXorX)); + bos.Add(x + "&bool", new BinOpStr(typeof(int), BinOpStrBoolAndX)); + bos.Add(x + "==bool", new BinOpStr(typeof(bool), BinOpStrBoolEqX)); + bos.Add(x + "!=bool", new BinOpStr(typeof(bool), BinOpStrBoolNeX)); + } + + private static void DefineBinOpsFloatX(Dictionary bos, string x) + { + bos.Add("float==" + x, new BinOpStr(typeof(bool), BinOpStrFloatEqX)); + bos.Add("float!=" + x, new BinOpStr(typeof(bool), BinOpStrFloatNeX)); + bos.Add("float<" + x, new BinOpStr(typeof(bool), BinOpStrFloatLtX)); + bos.Add("float<=" + x, new BinOpStr(typeof(bool), BinOpStrFloatLeX)); + bos.Add("float>" + x, new BinOpStr(typeof(bool), BinOpStrFloatGtX)); + bos.Add("float>=" + x, new BinOpStr(typeof(bool), BinOpStrFloatGeX)); + bos.Add("float+" + x, new BinOpStr(typeof(double), BinOpStrFloatAddX, true)); + bos.Add("float-" + x, new BinOpStr(typeof(double), BinOpStrFloatSubX, true)); + bos.Add("float*" + x, new BinOpStr(typeof(double), BinOpStrFloatMulX, true)); + bos.Add("float/" + x, new BinOpStr(typeof(double), BinOpStrFloatDivX, true)); + bos.Add("float%" + x, new BinOpStr(typeof(double), BinOpStrFloatModX, true)); + } + + private static void DefineBinOpsXFloat(Dictionary bos, string x) + { + bos.Add(x + "==float", new BinOpStr(typeof(bool), BinOpStrXEqFloat)); + bos.Add(x + "!=float", new BinOpStr(typeof(bool), BinOpStrXNeFloat)); + bos.Add(x + "float", new BinOpStr(typeof(bool), BinOpStrXGtFloat)); + bos.Add(x + ">=float", new BinOpStr(typeof(bool), BinOpStrXGeFloat)); + bos.Add(x + "+float", new BinOpStr(typeof(double), BinOpStrXAddFloat, true)); + bos.Add(x + "-float", new BinOpStr(typeof(double), BinOpStrXSubFloat, true)); + bos.Add(x + "*float", new BinOpStr(typeof(double), BinOpStrXMulFloat, true)); + bos.Add(x + "/float", new BinOpStr(typeof(double), BinOpStrXDivFloat, true)); + bos.Add(x + "%float", new BinOpStr(typeof(double), BinOpStrXModFloat, true)); + } + + private static void DefineBinOpsChar(Dictionary bos) + { + bos.Add("char==char", new BinOpStr(typeof(bool), BinOpStrCharEqChar)); + bos.Add("char!=char", new BinOpStr(typeof(bool), BinOpStrCharNeChar)); + bos.Add("charchar", new BinOpStr(typeof(bool), BinOpStrCharGtChar)); + bos.Add("char>=char", new BinOpStr(typeof(bool), BinOpStrCharGeChar)); + bos.Add("char+integer", new BinOpStr(typeof(char), BinOpStrCharAddInt, true)); + bos.Add("char-integer", new BinOpStr(typeof(char), BinOpStrCharSubInt, true)); + bos.Add("char-char", new BinOpStr(typeof(int), BinOpStrCharSubChar)); + } + + private static void DefineBinOpsInteger(Dictionary bos) + { + bos.Add("integer==integer", new BinOpStr(typeof(bool), BinOpStrIntEqInt)); + bos.Add("integer!=integer", new BinOpStr(typeof(bool), BinOpStrIntNeInt)); + bos.Add("integerinteger", new BinOpStr(typeof(bool), BinOpStrIntGtInt)); + bos.Add("integer>=integer", new BinOpStr(typeof(bool), BinOpStrIntGeInt)); + bos.Add("integer|integer", new BinOpStr(typeof(int), BinOpStrIntOrInt, true)); + bos.Add("integer^integer", new BinOpStr(typeof(int), BinOpStrIntXorInt, true)); + bos.Add("integer&integer", new BinOpStr(typeof(int), BinOpStrIntAndInt, true)); + bos.Add("integer+integer", new BinOpStr(typeof(int), BinOpStrIntAddInt, true)); + bos.Add("integer-integer", new BinOpStr(typeof(int), BinOpStrIntSubInt, true)); + bos.Add("integer*integer", new BinOpStr(typeof(int), BinOpStrIntMulInt, true)); + bos.Add("integer/integer", new BinOpStr(typeof(int), BinOpStrIntDivInt, true)); + bos.Add("integer%integer", new BinOpStr(typeof(int), BinOpStrIntModInt, true)); + bos.Add("integer<>integer", new BinOpStr(typeof(int), BinOpStrIntShrInt, true)); + } + + private static void DefineBinOpsKeyX(Dictionary bos, string x) + { + bos.Add("key==" + x, new BinOpStr(typeof(bool), BinOpStrKeyEqX)); + bos.Add("key!=" + x, new BinOpStr(typeof(bool), BinOpStrKeyNeX)); + } + + private static void DefineBinOpsXKey(Dictionary bos, string x) + { + bos.Add(x + "==key", new BinOpStr(typeof(bool), BinOpStrKeyEqX)); + bos.Add(x + "!=key", new BinOpStr(typeof(bool), BinOpStrKeyNeX)); + } + + private static void DefineBinOpsList(Dictionary bos) + { + bos.Add("list+float", new BinOpStr(typeof(LSL_List), BinOpStrListAddFloat, true)); + bos.Add("list+integer", new BinOpStr(typeof(LSL_List), BinOpStrListAddInt, true)); + bos.Add("list+key", new BinOpStr(typeof(LSL_List), BinOpStrListAddKey, true)); + bos.Add("list+list", new BinOpStr(typeof(LSL_List), BinOpStrListAddList, true)); + bos.Add("list+rotation", new BinOpStr(typeof(LSL_List), BinOpStrListAddRot, true)); + bos.Add("list+string", new BinOpStr(typeof(LSL_List), BinOpStrListAddStr, true)); + bos.Add("list+vector", new BinOpStr(typeof(LSL_List), BinOpStrListAddVec, true)); + + bos.Add("float+list", new BinOpStr(typeof(LSL_List), BinOpStrFloatAddList)); + bos.Add("integer+list", new BinOpStr(typeof(LSL_List), BinOpStrIntAddList)); + bos.Add("key+list", new BinOpStr(typeof(LSL_List), BinOpStrKeyAddList)); + bos.Add("rotation+list", new BinOpStr(typeof(LSL_List), BinOpStrRotAddList)); + bos.Add("string+list", new BinOpStr(typeof(LSL_List), BinOpStrStrAddList)); + bos.Add("vector+list", new BinOpStr(typeof(LSL_List), BinOpStrVecAddList)); + + bos.Add("list==list", new BinOpStr(typeof(bool), BinOpStrListEqList)); + bos.Add("list!=list", new BinOpStr(typeof(int), BinOpStrListNeList)); + } + + // all operations allowed by LSL_Rotation definition + private static void DefineBinOpsRotation(Dictionary bos) + { + bos.Add("rotation==rotation", new BinOpStr(typeof(bool), BinOpStrRotEqRot)); + bos.Add("rotation!=rotation", new BinOpStr(typeof(bool), BinOpStrRotNeRot)); + bos.Add("rotation+rotation", new BinOpStr(typeof(LSL_Rotation), BinOpStrRotAddRot, true)); + bos.Add("rotation-rotation", new BinOpStr(typeof(LSL_Rotation), BinOpStrRotSubRot, true)); + bos.Add("rotation*rotation", new BinOpStr(typeof(LSL_Rotation), BinOpStrRotMulRot, true)); + bos.Add("rotation/rotation", new BinOpStr(typeof(LSL_Rotation), BinOpStrRotDivRot, true)); + } + + private static void DefineBinOpsString(Dictionary bos) + { + bos.Add("string==string", new BinOpStr(typeof(bool), BinOpStrStrEqStr)); + bos.Add("string!=string", new BinOpStr(typeof(bool), BinOpStrStrNeStr)); + bos.Add("stringstring", new BinOpStr(typeof(bool), BinOpStrStrGtStr)); + bos.Add("string>=string", new BinOpStr(typeof(bool), BinOpStrStrGeStr)); + bos.Add("string+string", new BinOpStr(typeof(string), BinOpStrStrAddStr, true)); + } + + // all operations allowed by LSL_Vector definition + private static void DefineBinOpsVector(Dictionary bos) + { + bos.Add("vector==vector", new BinOpStr(typeof(bool), BinOpStrVecEqVec)); + bos.Add("vector!=vector", new BinOpStr(typeof(bool), BinOpStrVecNeVec)); + bos.Add("vector+vector", new BinOpStr(typeof(LSL_Vector), BinOpStrVecAddVec, true)); + bos.Add("vector-vector", new BinOpStr(typeof(LSL_Vector), BinOpStrVecSubVec, true)); + bos.Add("vector*vector", new BinOpStr(typeof(double), BinOpStrVecMulVec)); + bos.Add("vector%vector", new BinOpStr(typeof(LSL_Vector), BinOpStrVecModVec, true)); + + bos.Add("vector*float", new BinOpStr(typeof(LSL_Vector), BinOpStrVecMulFloat, true)); + bos.Add("float*vector", new BinOpStr(typeof(LSL_Vector), BinOpStrFloatMulVec)); + bos.Add("vector/float", new BinOpStr(typeof(LSL_Vector), BinOpStrVecDivFloat, true)); + + bos.Add("vector*integer", new BinOpStr(typeof(LSL_Vector), BinOpStrVecMulInt, true)); + bos.Add("integer*vector", new BinOpStr(typeof(LSL_Vector), BinOpStrIntMulVec)); + bos.Add("vector/integer", new BinOpStr(typeof(LSL_Vector), BinOpStrVecDivInt, true)); + + bos.Add("vector*rotation", new BinOpStr(typeof(LSL_Vector), BinOpStrVecMulRot, true)); + bos.Add("vector/rotation", new BinOpStr(typeof(LSL_Vector), BinOpStrVecDivRot, true)); + } + + /** + * @brief These methods actually emit the code to perform the arithmetic. + * @param scg = what script we are compiling + * @param left = left-hand operand location in memory (type as given by BinOpStr entry) + * @param right = right-hand operand location in memory (type as given by BinOpStr entry) + * @param result = result location in memory (type as given by BinOpStr entry) + */ + private static void BinOpStrAndAnd(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeBool); + right.PushVal(scg, errorAt, tokenTypeBool); + scg.ilGen.Emit(errorAt, OpCodes.And); + result.PopPost(scg, errorAt, tokenTypeBool); + } + + private static void BinOpStrOrOr(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeBool); + right.PushVal(scg, errorAt, tokenTypeBool); + scg.ilGen.Emit(errorAt, OpCodes.Or); + result.PopPost(scg, errorAt, tokenTypeBool); + } + + private static void BinOpStrBoolOrX(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeInt); + right.PushVal(scg, errorAt, tokenTypeInt); + scg.ilGen.Emit(errorAt, OpCodes.Or); + result.PopPost(scg, errorAt, tokenTypeInt); + } + + private static void BinOpStrBoolXorX(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeInt); + right.PushVal(scg, errorAt, tokenTypeInt); + scg.ilGen.Emit(errorAt, OpCodes.Xor); + result.PopPost(scg, errorAt, tokenTypeInt); + } + + private static void BinOpStrBoolAndX(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeInt); + right.PushVal(scg, errorAt, tokenTypeInt); + scg.ilGen.Emit(errorAt, OpCodes.And); + result.PopPost(scg, errorAt, tokenTypeInt); + } + + private static void BinOpStrBoolEqX(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeBool); + right.PushVal(scg, errorAt, tokenTypeBool); + scg.ilGen.Emit(errorAt, OpCodes.Ceq); + result.PopPost(scg, errorAt, tokenTypeBool); + } + + private static void BinOpStrBoolNeX(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeBool); + right.PushVal(scg, errorAt, tokenTypeBool); + scg.ilGen.Emit(errorAt, OpCodes.Xor); + result.PopPost(scg, errorAt, tokenTypeBool); + } + + private static void BinOpStrFloatEqX(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeFloat); + right.PushVal(scg, errorAt, tokenTypeFloat); + scg.ilGen.Emit(errorAt, OpCodes.Ceq); + result.PopPost(scg, errorAt, tokenTypeBool); + } + + private static void BinOpStrFloatNeX(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeFloat); + right.PushVal(scg, errorAt, tokenTypeFloat); + scg.ilGen.Emit(errorAt, OpCodes.Ceq); + scg.ilGen.Emit(errorAt, OpCodes.Ldc_I4_1); + scg.ilGen.Emit(errorAt, OpCodes.Xor); + result.PopPost(scg, errorAt, tokenTypeBool); + } + + private static void BinOpStrFloatLtX(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeFloat); + right.PushVal(scg, errorAt, tokenTypeFloat); + scg.ilGen.Emit(errorAt, OpCodes.Clt); + result.PopPost(scg, errorAt, tokenTypeBool); + } + + private static void BinOpStrFloatLeX(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeFloat); + right.PushVal(scg, errorAt, tokenTypeFloat); + scg.ilGen.Emit(errorAt, OpCodes.Cgt); + scg.ilGen.Emit(errorAt, OpCodes.Ldc_I4_1); + scg.ilGen.Emit(errorAt, OpCodes.Xor); + result.PopPost(scg, errorAt, tokenTypeBool); + } + + private static void BinOpStrFloatGtX(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeFloat); + right.PushVal(scg, errorAt, tokenTypeFloat); + scg.ilGen.Emit(errorAt, OpCodes.Cgt); + result.PopPost(scg, errorAt, tokenTypeBool); + } + + private static void BinOpStrFloatGeX(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeFloat); + right.PushVal(scg, errorAt, tokenTypeFloat); + scg.ilGen.Emit(errorAt, OpCodes.Clt); + scg.ilGen.Emit(errorAt, OpCodes.Ldc_I4_1); + scg.ilGen.Emit(errorAt, OpCodes.Xor); + result.PopPost(scg, errorAt, tokenTypeBool); + } + + private static void BinOpStrFloatAddX(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeFloat); + right.PushVal(scg, errorAt, tokenTypeFloat); + scg.ilGen.Emit(errorAt, OpCodes.Add); + result.PopPost(scg, errorAt, tokenTypeFloat); + } + + private static void BinOpStrFloatSubX(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeFloat); + right.PushVal(scg, errorAt, tokenTypeFloat); + scg.ilGen.Emit(errorAt, OpCodes.Sub); + result.PopPost(scg, errorAt, tokenTypeFloat); + } + + private static void BinOpStrFloatMulX(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeFloat); + right.PushVal(scg, errorAt, tokenTypeFloat); + scg.ilGen.Emit(errorAt, OpCodes.Mul); + result.PopPost(scg, errorAt, tokenTypeFloat); + } + + private static void BinOpStrFloatDivX(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeFloat); + right.PushVal(scg, errorAt, tokenTypeFloat); + scg.ilGen.Emit(errorAt, OpCodes.Div); + result.PopPost(scg, errorAt, tokenTypeFloat); + } + + private static void BinOpStrFloatModX(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeFloat); + right.PushVal(scg, errorAt, tokenTypeFloat); + scg.ilGen.Emit(errorAt, OpCodes.Rem); + result.PopPost(scg, errorAt, tokenTypeFloat); + } + + private static void BinOpStrXEqFloat(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeFloat); + right.PushVal(scg, errorAt, tokenTypeFloat); + scg.ilGen.Emit(errorAt, OpCodes.Ceq); + result.PopPost(scg, errorAt, tokenTypeBool); + } + + private static void BinOpStrXNeFloat(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeFloat); + right.PushVal(scg, errorAt, tokenTypeFloat); + scg.ilGen.Emit(errorAt, OpCodes.Ceq); + scg.ilGen.Emit(errorAt, OpCodes.Ldc_I4_1); + scg.ilGen.Emit(errorAt, OpCodes.Xor); + result.PopPost(scg, errorAt, tokenTypeBool); + } + + private static void BinOpStrXLtFloat(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeFloat); + right.PushVal(scg, errorAt, tokenTypeFloat); + scg.ilGen.Emit(errorAt, OpCodes.Clt); + result.PopPost(scg, errorAt, tokenTypeBool); + } + + private static void BinOpStrXLeFloat(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeFloat); + right.PushVal(scg, errorAt, tokenTypeFloat); + scg.ilGen.Emit(errorAt, OpCodes.Cgt); + scg.ilGen.Emit(errorAt, OpCodes.Ldc_I4_1); + scg.ilGen.Emit(errorAt, OpCodes.Xor); + result.PopPost(scg, errorAt, tokenTypeBool); + } + + private static void BinOpStrXGtFloat(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeFloat); + right.PushVal(scg, errorAt, tokenTypeFloat); + scg.ilGen.Emit(errorAt, OpCodes.Cgt); + result.PopPost(scg, errorAt, tokenTypeBool); + } + + private static void BinOpStrXGeFloat(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeFloat); + right.PushVal(scg, errorAt, tokenTypeFloat); + scg.ilGen.Emit(errorAt, OpCodes.Clt); + scg.ilGen.Emit(errorAt, OpCodes.Ldc_I4_1); + scg.ilGen.Emit(errorAt, OpCodes.Xor); + result.PopPost(scg, errorAt, tokenTypeBool); + } + + private static void BinOpStrXAddFloat(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeFloat); + right.PushVal(scg, errorAt, tokenTypeFloat); + scg.ilGen.Emit(errorAt, OpCodes.Add); + result.PopPost(scg, errorAt, tokenTypeFloat); + } + + private static void BinOpStrXSubFloat(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeFloat); + right.PushVal(scg, errorAt, tokenTypeFloat); + scg.ilGen.Emit(errorAt, OpCodes.Sub); + result.PopPost(scg, errorAt, tokenTypeFloat); + } + + private static void BinOpStrXMulFloat(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeFloat); + right.PushVal(scg, errorAt, tokenTypeFloat); + scg.ilGen.Emit(errorAt, OpCodes.Mul); + result.PopPost(scg, errorAt, tokenTypeFloat); + } + + private static void BinOpStrXDivFloat(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeFloat); + right.PushVal(scg, errorAt, tokenTypeFloat); + scg.ilGen.Emit(errorAt, OpCodes.Div); + result.PopPost(scg, errorAt, tokenTypeFloat); + } + + private static void BinOpStrXModFloat(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeFloat); + right.PushVal(scg, errorAt, tokenTypeFloat); + scg.ilGen.Emit(errorAt, OpCodes.Rem); + result.PopPost(scg, errorAt, tokenTypeFloat); + } + + private static void BinOpStrCharEqChar(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeChar); + right.PushVal(scg, errorAt, tokenTypeChar); + scg.ilGen.Emit(errorAt, OpCodes.Ceq); + result.PopPost(scg, errorAt, tokenTypeBool); + } + + private static void BinOpStrCharNeChar(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeChar); + right.PushVal(scg, errorAt, tokenTypeChar); + scg.ilGen.Emit(errorAt, OpCodes.Ceq); + scg.ilGen.Emit(errorAt, OpCodes.Ldc_I4_1); + scg.ilGen.Emit(errorAt, OpCodes.Xor); + result.PopPost(scg, errorAt, tokenTypeBool); + } + + private static void BinOpStrCharLtChar(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeChar); + right.PushVal(scg, errorAt, tokenTypeChar); + scg.ilGen.Emit(errorAt, OpCodes.Clt); + result.PopPost(scg, errorAt, tokenTypeBool); + } + + private static void BinOpStrCharLeChar(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeChar); + right.PushVal(scg, errorAt, tokenTypeChar); + scg.ilGen.Emit(errorAt, OpCodes.Cgt); + scg.ilGen.Emit(errorAt, OpCodes.Ldc_I4_1); + scg.ilGen.Emit(errorAt, OpCodes.Xor); + result.PopPost(scg, errorAt, tokenTypeBool); + } + + private static void BinOpStrCharGtChar(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeChar); + right.PushVal(scg, errorAt, tokenTypeChar); + scg.ilGen.Emit(errorAt, OpCodes.Cgt); + result.PopPost(scg, errorAt, tokenTypeBool); + } + + private static void BinOpStrCharGeChar(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeChar); + right.PushVal(scg, errorAt, tokenTypeChar); + scg.ilGen.Emit(errorAt, OpCodes.Clt); + scg.ilGen.Emit(errorAt, OpCodes.Ldc_I4_1); + scg.ilGen.Emit(errorAt, OpCodes.Xor); + result.PopPost(scg, errorAt, tokenTypeBool); + } + + private static void BinOpStrCharAddInt(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeChar); + right.PushVal(scg, errorAt, tokenTypeInt); + scg.ilGen.Emit(errorAt, OpCodes.Add); + result.PopPost(scg, errorAt, tokenTypeChar); + } + + private static void BinOpStrCharSubInt(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeChar); + right.PushVal(scg, errorAt, tokenTypeInt); + scg.ilGen.Emit(errorAt, OpCodes.Sub); + result.PopPost(scg, errorAt, tokenTypeChar); + } + + private static void BinOpStrCharSubChar(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeChar); + right.PushVal(scg, errorAt, tokenTypeChar); + scg.ilGen.Emit(errorAt, OpCodes.Sub); + result.PopPost(scg, errorAt, tokenTypeInt); + } + + private static void BinOpStrIntEqInt(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeInt); + right.PushVal(scg, errorAt, tokenTypeInt); + scg.ilGen.Emit(errorAt, OpCodes.Ceq); + result.PopPost(scg, errorAt, tokenTypeBool); + } + + private static void BinOpStrIntNeInt(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeInt); + right.PushVal(scg, errorAt, tokenTypeInt); + scg.ilGen.Emit(errorAt, OpCodes.Ceq); + scg.ilGen.Emit(errorAt, OpCodes.Ldc_I4_1); + scg.ilGen.Emit(errorAt, OpCodes.Xor); + result.PopPost(scg, errorAt, tokenTypeBool); + } + + private static void BinOpStrIntLtInt(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeInt); + right.PushVal(scg, errorAt, tokenTypeInt); + scg.ilGen.Emit(errorAt, OpCodes.Clt); + result.PopPost(scg, errorAt, tokenTypeBool); + } + + private static void BinOpStrIntLeInt(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeInt); + right.PushVal(scg, errorAt, tokenTypeInt); + scg.ilGen.Emit(errorAt, OpCodes.Cgt); + scg.ilGen.Emit(errorAt, OpCodes.Ldc_I4_1); + scg.ilGen.Emit(errorAt, OpCodes.Xor); + result.PopPost(scg, errorAt, tokenTypeBool); + } + + private static void BinOpStrIntGtInt(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeInt); + right.PushVal(scg, errorAt, tokenTypeInt); + scg.ilGen.Emit(errorAt, OpCodes.Cgt); + result.PopPost(scg, errorAt, tokenTypeBool); + } + + private static void BinOpStrIntGeInt(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeInt); + right.PushVal(scg, errorAt, tokenTypeInt); + scg.ilGen.Emit(errorAt, OpCodes.Clt); + scg.ilGen.Emit(errorAt, OpCodes.Ldc_I4_1); + scg.ilGen.Emit(errorAt, OpCodes.Xor); + result.PopPost(scg, errorAt, tokenTypeBool); + } + + private static void BinOpStrIntOrInt(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeInt); + right.PushVal(scg, errorAt, tokenTypeInt); + scg.ilGen.Emit(errorAt, OpCodes.Or); + result.PopPost(scg, errorAt, tokenTypeInt); + } + + private static void BinOpStrIntXorInt(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeInt); + right.PushVal(scg, errorAt, tokenTypeInt); + scg.ilGen.Emit(errorAt, OpCodes.Xor); + result.PopPost(scg, errorAt, tokenTypeInt); + } + + private static void BinOpStrIntAndInt(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeInt); + right.PushVal(scg, errorAt, tokenTypeInt); + scg.ilGen.Emit(errorAt, OpCodes.And); + result.PopPost(scg, errorAt, tokenTypeInt); + } + + private static void BinOpStrIntAddInt(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeInt); + right.PushVal(scg, errorAt, tokenTypeInt); + scg.ilGen.Emit(errorAt, OpCodes.Add); + result.PopPost(scg, errorAt, tokenTypeInt); + } + + private static void BinOpStrIntSubInt(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeInt); + right.PushVal(scg, errorAt, tokenTypeInt); + scg.ilGen.Emit(errorAt, OpCodes.Sub); + result.PopPost(scg, errorAt, tokenTypeInt); + } + + private static void BinOpStrIntMulInt(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeInt); + right.PushVal(scg, errorAt, tokenTypeInt); + scg.ilGen.Emit(errorAt, OpCodes.Mul); + result.PopPost(scg, errorAt, tokenTypeInt); + } + + private static void BinOpStrIntDivInt(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + // note that we must allow 0x800000/-1 -> 0x80000000 for lslangtest1.lsl + // so sign-extend the operands to 64-bit then divide and truncate result + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeInt); + scg.ilGen.Emit(errorAt, OpCodes.Conv_I8); + right.PushVal(scg, errorAt, tokenTypeInt); + scg.ilGen.Emit(errorAt, OpCodes.Conv_I8); + scg.ilGen.Emit(errorAt, OpCodes.Div); + scg.ilGen.Emit(errorAt, OpCodes.Conv_I4); + result.PopPost(scg, errorAt, tokenTypeInt); + } + + private static void BinOpStrIntModInt(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + // note that we must allow 0x800000%-1 -> 0 for lslangtest1.lsl + // so sign-extend the operands to 64-bit then mod and truncate result + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeInt); + scg.ilGen.Emit(errorAt, OpCodes.Conv_I8); + right.PushVal(scg, errorAt, tokenTypeInt); + scg.ilGen.Emit(errorAt, OpCodes.Conv_I8); + scg.ilGen.Emit(errorAt, OpCodes.Rem); + scg.ilGen.Emit(errorAt, OpCodes.Conv_I4); + result.PopPost(scg, errorAt, tokenTypeInt); + } + + private static void BinOpStrIntShlInt(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeInt); + right.PushVal(scg, errorAt, tokenTypeInt); + scg.ilGen.Emit(errorAt, OpCodes.Shl); + result.PopPost(scg, errorAt, tokenTypeInt); + } + + private static void BinOpStrIntShrInt(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeInt); + right.PushVal(scg, errorAt, tokenTypeInt); + scg.ilGen.Emit(errorAt, OpCodes.Shr); + result.PopPost(scg, errorAt, tokenTypeInt); + } + + private static void BinOpStrKeyEqX(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeStr); + right.PushVal(scg, errorAt, tokenTypeStr); + scg.ilGen.Emit(errorAt, OpCodes.Call, stringCmpStringMethInfo); + scg.ilGen.Emit(errorAt, OpCodes.Ldc_I4_0); + scg.ilGen.Emit(errorAt, OpCodes.Ceq); + result.PopPost(scg, errorAt, tokenTypeBool); + } + + private static void BinOpStrKeyNeX(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeStr); + right.PushVal(scg, errorAt, tokenTypeStr); + scg.ilGen.Emit(errorAt, OpCodes.Call, stringCmpStringMethInfo); + scg.ilGen.Emit(errorAt, OpCodes.Ldc_I4_0); + scg.ilGen.Emit(errorAt, OpCodes.Ceq); + scg.ilGen.Emit(errorAt, OpCodes.Ldc_I4_1); + scg.ilGen.Emit(errorAt, OpCodes.Xor); + result.PopPost(scg, errorAt, tokenTypeBool); + } + + private static void BinOpStrListAddFloat(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeList); + right.PushVal(scg, errorAt, tokenTypeFloat); + scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethListAddFloat); + result.PopPost(scg, errorAt, tokenTypeList); + } + + private static void BinOpStrListAddInt(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeList); + right.PushVal(scg, errorAt, tokenTypeInt); + scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethListAddInt); + result.PopPost(scg, errorAt, tokenTypeList); + } + + private static void BinOpStrListAddKey(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeList); + right.PushVal(scg, errorAt, tokenTypeStr); + scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethListAddKey); + result.PopPost(scg, errorAt, tokenTypeList); + } + + private static void BinOpStrListAddList(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeList); + right.PushVal(scg, errorAt, tokenTypeList); + scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethListAddList); + result.PopPost(scg, errorAt, tokenTypeList); + } + + private static void BinOpStrListAddRot(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeList); + right.PushVal(scg, errorAt, tokenTypeRot); + scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethListAddRot); + result.PopPost(scg, errorAt, tokenTypeList); + } + + private static void BinOpStrListAddStr(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeList); + right.PushVal(scg, errorAt, tokenTypeStr); + scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethListAddStr); + result.PopPost(scg, errorAt, tokenTypeList); + } + + private static void BinOpStrListAddVec(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeList); + right.PushVal(scg, errorAt, tokenTypeVec); + scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethListAddVec); + result.PopPost(scg, errorAt, tokenTypeList); + } + + private static void BinOpStrFloatAddList(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeFloat); + right.PushVal(scg, errorAt, tokenTypeList); + scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethFloatAddList); + result.PopPost(scg, errorAt, tokenTypeList); + } + + private static void BinOpStrIntAddList(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeInt); + right.PushVal(scg, errorAt, tokenTypeList); + scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethIntAddList); + result.PopPost(scg, errorAt, tokenTypeList); + } + + private static void BinOpStrKeyAddList(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeStr); + right.PushVal(scg, errorAt, tokenTypeList); + scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethKeyAddList); + result.PopPost(scg, errorAt, tokenTypeList); + } + + private static void BinOpStrRotAddList(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeRot); + right.PushVal(scg, errorAt, tokenTypeList); + scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethRotAddList); + result.PopPost(scg, errorAt, tokenTypeList); + } + + private static void BinOpStrStrAddList(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeStr); + right.PushVal(scg, errorAt, tokenTypeList); + scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethStrAddList); + result.PopPost(scg, errorAt, tokenTypeList); + } + + private static void BinOpStrVecAddList(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeVec); + right.PushVal(scg, errorAt, tokenTypeList); + scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethVecAddList); + result.PopPost(scg, errorAt, tokenTypeList); + } + + private static void BinOpStrListEqList(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeList); + right.PushVal(scg, errorAt, tokenTypeList); + scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethListEqList); + result.PopPost(scg, errorAt, tokenTypeBool); + } + + private static void BinOpStrListNeList(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeList); + right.PushVal(scg, errorAt, tokenTypeList); + scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethListNeList); + result.PopPost(scg, errorAt, tokenTypeBool); + } + + private static void BinOpStrRotEqRot(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeRot); + right.PushVal(scg, errorAt, tokenTypeRot); + scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethRotEqRot); + result.PopPost(scg, errorAt, tokenTypeBool); + } + + private static void BinOpStrRotNeRot(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeRot); + right.PushVal(scg, errorAt, tokenTypeRot); + scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethRotNeRot); + result.PopPost(scg, errorAt, tokenTypeBool); + } + + private static void BinOpStrRotAddRot(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeRot); + right.PushVal(scg, errorAt, tokenTypeRot); + scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethRotAddRot); + result.PopPost(scg, errorAt, tokenTypeRot); + } + + private static void BinOpStrRotSubRot(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeRot); + right.PushVal(scg, errorAt, tokenTypeRot); + scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethRotSubRot); + result.PopPost(scg, errorAt, tokenTypeRot); + } + + private static void BinOpStrRotMulRot(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeRot); + right.PushVal(scg, errorAt, tokenTypeRot); + scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethRotMulRot); + result.PopPost(scg, errorAt, tokenTypeRot); + } + + private static void BinOpStrRotDivRot(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeRot); + right.PushVal(scg, errorAt, tokenTypeRot); + scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethRotDivRot); + result.PopPost(scg, errorAt, tokenTypeRot); + } + + private static void BinOpStrStrEqStr(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeStr); + right.PushVal(scg, errorAt, tokenTypeStr); + scg.ilGen.Emit(errorAt, OpCodes.Call, stringCmpStringMethInfo); + scg.ilGen.Emit(errorAt, OpCodes.Ldc_I4_0); + scg.ilGen.Emit(errorAt, OpCodes.Ceq); + result.PopPost(scg, errorAt, tokenTypeBool); + } + + private static void BinOpStrStrNeStr(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeStr); + right.PushVal(scg, errorAt, tokenTypeStr); + scg.ilGen.Emit(errorAt, OpCodes.Call, stringCmpStringMethInfo); + scg.ilGen.Emit(errorAt, OpCodes.Ldc_I4_0); + scg.ilGen.Emit(errorAt, OpCodes.Ceq); + scg.ilGen.Emit(errorAt, OpCodes.Ldc_I4_1); + scg.ilGen.Emit(errorAt, OpCodes.Xor); + result.PopPost(scg, errorAt, tokenTypeBool); + } + + private static void BinOpStrStrLtStr(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeStr); + right.PushVal(scg, errorAt, tokenTypeStr); + scg.ilGen.Emit(errorAt, OpCodes.Call, stringCmpStringMethInfo); + scg.ilGen.Emit(errorAt, OpCodes.Ldc_I4_0); + scg.ilGen.Emit(errorAt, OpCodes.Clt); + result.PopPost(scg, errorAt, tokenTypeBool); + } + + private static void BinOpStrStrLeStr(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeStr); + right.PushVal(scg, errorAt, tokenTypeStr); + scg.ilGen.Emit(errorAt, OpCodes.Call, stringCmpStringMethInfo); + scg.ilGen.Emit(errorAt, OpCodes.Ldc_I4_1); + scg.ilGen.Emit(errorAt, OpCodes.Clt); + result.PopPost(scg, errorAt, tokenTypeBool); + } + + private static void BinOpStrStrGtStr(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeStr); + right.PushVal(scg, errorAt, tokenTypeStr); + scg.ilGen.Emit(errorAt, OpCodes.Call, stringCmpStringMethInfo); + scg.ilGen.Emit(errorAt, OpCodes.Ldc_I4_0); + scg.ilGen.Emit(errorAt, OpCodes.Cgt); + result.PopPost(scg, errorAt, tokenTypeBool); + } + + private static void BinOpStrStrGeStr(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeStr); + right.PushVal(scg, errorAt, tokenTypeStr); + scg.ilGen.Emit(errorAt, OpCodes.Call, stringCmpStringMethInfo); + scg.ilGen.Emit(errorAt, OpCodes.Ldc_I4_M1); + scg.ilGen.Emit(errorAt, OpCodes.Cgt); + result.PopPost(scg, errorAt, tokenTypeBool); + } + + // Called by many type combinations so both operands need to be cast to strings + private static void BinOpStrStrAddStr(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeStr); + right.PushVal(scg, errorAt, tokenTypeStr); + scg.ilGen.Emit(errorAt, OpCodes.Call, stringAddStringMethInfo); + result.PopPost(scg, errorAt, tokenTypeStr); + } + + private static void BinOpStrVecEqVec(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeVec); + right.PushVal(scg, errorAt, tokenTypeVec); + scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethVecEqVec); + result.PopPost(scg, errorAt, tokenTypeBool); + } + + private static void BinOpStrVecNeVec(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeVec); + right.PushVal(scg, errorAt, tokenTypeVec); + scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethVecNeVec); + result.PopPost(scg, errorAt, tokenTypeBool); + } + + private static void BinOpStrVecAddVec(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeVec); + right.PushVal(scg, errorAt, tokenTypeVec); + scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethVecAddVec); + result.PopPost(scg, errorAt, tokenTypeVec); + } + + private static void BinOpStrVecSubVec(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeVec); + right.PushVal(scg, errorAt, tokenTypeVec); + scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethVecSubVec); + result.PopPost(scg, errorAt, tokenTypeVec); + } + + private static void BinOpStrVecMulVec(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeVec); + right.PushVal(scg, errorAt, tokenTypeVec); + scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethVecMulVec); + result.PopPost(scg, errorAt, tokenTypeFloat); + } + + private static void BinOpStrVecModVec(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeVec); + right.PushVal(scg, errorAt, tokenTypeVec); + scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethVecModVec); + result.PopPost(scg, errorAt, tokenTypeVec); + } + + private static void BinOpStrVecMulFloat(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeVec); + right.PushVal(scg, errorAt, tokenTypeFloat); + scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethVecMulFloat); + result.PopPost(scg, errorAt, tokenTypeVec); + } + + private static void BinOpStrFloatMulVec(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeFloat); + right.PushVal(scg, errorAt, tokenTypeVec); + scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethFloatMulVec); + result.PopPost(scg, errorAt, tokenTypeVec); + } + + private static void BinOpStrVecDivFloat(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeVec); + right.PushVal(scg, errorAt, tokenTypeFloat); + scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethVecDivFloat); + result.PopPost(scg, errorAt, tokenTypeVec); + } + + private static void BinOpStrVecMulInt(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeVec); + right.PushVal(scg, errorAt, tokenTypeInt); + scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethVecMulInt); + result.PopPost(scg, errorAt, tokenTypeVec); + } + + private static void BinOpStrIntMulVec(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeInt); + right.PushVal(scg, errorAt, tokenTypeVec); + scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethIntMulVec); + result.PopPost(scg, errorAt, tokenTypeVec); + } + + private static void BinOpStrVecDivInt(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeVec); + right.PushVal(scg, errorAt, tokenTypeInt); + scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethVecDivInt); + result.PopPost(scg, errorAt, tokenTypeVec); + } + + private static void BinOpStrVecMulRot(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeVec); + right.PushVal(scg, errorAt, tokenTypeRot); + scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethVecMulRot); + result.PopPost(scg, errorAt, tokenTypeVec); + } + + private static void BinOpStrVecDivRot(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) + { + result.PopPre(scg, errorAt); + left.PushVal(scg, errorAt, tokenTypeVec); + right.PushVal(scg, errorAt, tokenTypeRot); + scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethVecDivRot); + result.PopPost(scg, errorAt, tokenTypeVec); + } + + /** + * @brief These methods are called at runtime as helpers. + * Needed to pick up functionality defined by overloaded operators of LSL_ types. + * They need to be marked public or runtime says they are inaccessible. + */ + public static LSL_List MethListAddFloat(LSL_List left, double right) + { + return MethListAddObj(left, new LSL_Float(right)); + } + public static LSL_List MethListAddInt(LSL_List left, int right) + { + return MethListAddObj(left, new LSL_Integer(right)); + } + public static LSL_List MethListAddKey(LSL_List left, string right) + { + return MethListAddObj(left, new LSL_Key(right)); + } + public static LSL_List MethListAddRot(LSL_List left, LSL_Rotation right) + { + return MethListAddObj(left, right); + } + public static LSL_List MethListAddStr(LSL_List left, string right) + { + return MethListAddObj(left, new LSL_String(right)); + } + public static LSL_List MethListAddVec(LSL_List left, LSL_Vector right) + { + return MethListAddObj(left, right); + } + public static LSL_List MethListAddObj(LSL_List left, object right) + { + int oldlen = left.Length; + object[] newarr = new object[oldlen + 1]; + Array.Copy(left.Data, newarr, oldlen); + newarr[oldlen] = right; + return new LSL_List(newarr); + } + + public static LSL_List MethListAddList(LSL_List left, LSL_List right) + { + int leftlen = left.Length; + int ritelen = right.Length; + object[] newarr = new object[leftlen + ritelen]; + Array.Copy(left.Data, newarr, leftlen); + Array.Copy(right.Data, 0, newarr, leftlen, ritelen); + return new LSL_List(newarr); + } + + public static LSL_List MethFloatAddList(double left, LSL_List right) + { + return MethObjAddList(new LSL_Float(left), right); + } + public static LSL_List MethIntAddList(int left, LSL_List right) + { + return MethObjAddList(new LSL_Integer(left), right); + } + public static LSL_List MethKeyAddList(string left, LSL_List right) + { + return MethObjAddList(new LSL_Key(left), right); + } + public static LSL_List MethRotAddList(LSL_Rotation left, LSL_List right) + { + return MethObjAddList(left, right); + } + public static LSL_List MethStrAddList(string left, LSL_List right) + { + return MethObjAddList(new LSL_String(left), right); + } + public static LSL_List MethVecAddList(LSL_Vector left, LSL_List right) + { + return MethObjAddList(left, right); + } + public static LSL_List MethObjAddList(object left, LSL_List right) + { + int oldlen = right.Length; + object[] newarr = new object[oldlen + 1]; + newarr[0] = left; + Array.Copy(right.Data, 0, newarr, 1, oldlen); + return new LSL_List(newarr); + } + + public static bool MethListEqList(LSL_List left, LSL_List right) + { + return left == right; + } + + // According to http://wiki.secondlife.com/wiki/LlGetListLength + // jackassed LSL allows 'somelist != []' to get the length of a list + public static int MethListNeList(LSL_List left, LSL_List right) + { + int leftlen = left.Length; + int ritelen = right.Length; + return leftlen - ritelen; + } + + public static bool MethRotEqRot(LSL_Rotation left, LSL_Rotation right) + { + return left == right; + } + + public static bool MethRotNeRot(LSL_Rotation left, LSL_Rotation right) + { + return left != right; + } + + public static LSL_Rotation MethRotAddRot(LSL_Rotation left, LSL_Rotation right) + { + return left + right; + } + + public static LSL_Rotation MethRotSubRot(LSL_Rotation left, LSL_Rotation right) + { + return left - right; + } + + public static LSL_Rotation MethRotMulRot(LSL_Rotation left, LSL_Rotation right) + { + return left * right; + } + + public static LSL_Rotation MethRotDivRot(LSL_Rotation left, LSL_Rotation right) + { + return left / right; + } + + public static bool MethVecEqVec(LSL_Vector left, LSL_Vector right) + { + return left == right; + } + + public static bool MethVecNeVec(LSL_Vector left, LSL_Vector right) + { + return left != right; + } + + public static LSL_Vector MethVecAddVec(LSL_Vector left, LSL_Vector right) + { + return left + right; + } + + public static LSL_Vector MethVecSubVec(LSL_Vector left, LSL_Vector right) + { + return left - right; + } + + public static double MethVecMulVec(LSL_Vector left, LSL_Vector right) + { + return (double)(left * right).value; + } + + public static LSL_Vector MethVecModVec(LSL_Vector left, LSL_Vector right) + { + return left % right; + } + + public static LSL_Vector MethVecMulFloat(LSL_Vector left, double right) + { + return left * right; + } + + public static LSL_Vector MethFloatMulVec(double left, LSL_Vector right) + { + return left * right; + } + + public static LSL_Vector MethVecDivFloat(LSL_Vector left, double right) + { + return left / right; + } + + public static LSL_Vector MethVecMulInt(LSL_Vector left, int right) + { + return left * right; + } + + public static LSL_Vector MethIntMulVec(int left, LSL_Vector right) + { + return left * right; + } + + public static LSL_Vector MethVecDivInt(LSL_Vector left, int right) + { + return left / right; + } + + public static LSL_Vector MethVecMulRot(LSL_Vector left, LSL_Rotation right) + { + return left * right; + } + + public static LSL_Vector MethVecDivRot(LSL_Vector left, LSL_Rotation right) + { + return left / right; + } + } +} diff --git a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptCodeGen.cs b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptCodeGen.cs new file mode 100644 index 0000000000..5f00f867c8 --- /dev/null +++ b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptCodeGen.cs @@ -0,0 +1,6547 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using OpenSim.Region.ScriptEngine.Shared.ScriptBase; +using OpenSim.Region.ScriptEngine.Yengine; +using System; +using System.Collections.Generic; +using System.IO; +using System.Reflection; +using System.Reflection.Emit; +using System.Runtime.Serialization; +using System.Text; +using System.Threading; + +using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; +using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; +using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; +using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list; +using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; +using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; +using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; + +/** + * @brief translate a reduced script token into corresponding CIL code. + * The single script token contains a tokenized and textured version of the whole script file. + */ + +namespace OpenSim.Region.ScriptEngine.Yengine +{ + public interface IScriptCodeGen + { + ScriptMyILGen ilGen + { + get; + } // the output instruction stream + void ErrorMsg(Token token, string message); + void PushDefaultValue(TokenType type); + void PushXMRInst(); + } + + public class ScriptCodeGen: IScriptCodeGen + { + private static readonly bool DEBUG_STACKCAPRES = false; + private static readonly bool DEBUG_TRYSTMT = false; + + public static readonly string OBJECT_CODE_MAGIC = "YObjectCode"; + // reserve positive version values for original xmr + public static int COMPILED_VERSION_VALUE = -1; // decremented when compiler or object file changes + + public static readonly int CALL_FRAME_MEMUSE = 64; + public static readonly int STRING_LEN_TO_MEMUSE = 2; + + public static Type xmrInstSuperType = null; // typeof whatever is actually malloc'd for script instances + // - must inherit from XMRInstAbstract + + // Static tables that there only needs to be one copy of for all. + private static VarDict legalEventHandlers = CreateLegalEventHandlers(); + private static CompValu[] zeroCompValus = new CompValu[0]; + private static TokenType[] zeroArgs = new TokenType[0]; + private static TokenTypeBool tokenTypeBool = new TokenTypeBool(null); + private static TokenTypeExc tokenTypeExc = new TokenTypeExc(null); + private static TokenTypeFloat tokenTypeFlt = new TokenTypeFloat(null); + private static TokenTypeInt tokenTypeInt = new TokenTypeInt(null); + private static TokenTypeObject tokenTypeObj = new TokenTypeObject(null); + private static TokenTypeRot tokenTypeRot = new TokenTypeRot(null); + private static TokenTypeStr tokenTypeStr = new TokenTypeStr(null); + private static TokenTypeVec tokenTypeVec = new TokenTypeVec(null); + private static Type[] instanceTypeArg = new Type[] { typeof(XMRInstAbstract) }; + private static string[] instanceNameArg = new string[] { "$xmrthis" }; + + private static ConstructorInfo lslFloatConstructorInfo = typeof(LSL_Float).GetConstructor(new Type[] { typeof(double) }); + private static ConstructorInfo lslIntegerConstructorInfo = typeof(LSL_Integer).GetConstructor(new Type[] { typeof(int) }); + private static ConstructorInfo lslListConstructorInfo = typeof(LSL_List).GetConstructor(new Type[] { typeof(object[]) }); + public static ConstructorInfo lslRotationConstructorInfo = typeof(LSL_Rotation).GetConstructor(new Type[] { typeof(double), typeof(double), typeof(double), typeof(double) }); + private static ConstructorInfo lslStringConstructorInfo = typeof(LSL_String).GetConstructor(new Type[] { typeof(string) }); + public static ConstructorInfo lslVectorConstructorInfo = typeof(LSL_Vector).GetConstructor(new Type[] { typeof(double), typeof(double), typeof(double) }); + private static ConstructorInfo scriptBadCallNoExceptionConstructorInfo = typeof(ScriptBadCallNoException).GetConstructor(new Type[] { typeof(int) }); + private static ConstructorInfo scriptChangeStateExceptionConstructorInfo = typeof(ScriptChangeStateException).GetConstructor(new Type[] { typeof(int) }); + private static ConstructorInfo scriptRestoreCatchExceptionConstructorInfo = typeof(ScriptRestoreCatchException).GetConstructor(new Type[] { typeof(Exception) }); + private static ConstructorInfo scriptUndefinedStateExceptionConstructorInfo = typeof(ScriptUndefinedStateException).GetConstructor(new Type[] { typeof(string) }); + private static ConstructorInfo sdtClassConstructorInfo = typeof(XMRSDTypeClObj).GetConstructor(new Type[] { typeof(XMRInstAbstract), typeof(int) }); + private static ConstructorInfo xmrArrayConstructorInfo = typeof(XMR_Array).GetConstructor(new Type[] { typeof(XMRInstAbstract) }); + private static FieldInfo callModeFieldInfo = typeof(XMRInstAbstract).GetField("callMode"); + private static FieldInfo doGblInitFieldInfo = typeof(XMRInstAbstract).GetField("doGblInit"); + private static FieldInfo ehArgsFieldInfo = typeof(XMRInstAbstract).GetField("ehArgs"); + private static FieldInfo rotationXFieldInfo = typeof(LSL_Rotation).GetField("x"); + private static FieldInfo rotationYFieldInfo = typeof(LSL_Rotation).GetField("y"); + private static FieldInfo rotationZFieldInfo = typeof(LSL_Rotation).GetField("z"); + private static FieldInfo rotationSFieldInfo = typeof(LSL_Rotation).GetField("s"); + private static FieldInfo sdtXMRInstFieldInfo = typeof(XMRSDTypeClObj).GetField("xmrInst"); + private static FieldInfo stackLeftFieldInfo = typeof(XMRInstAbstract).GetField("m_StackLeft"); + private static FieldInfo vectorXFieldInfo = typeof(LSL_Vector).GetField("x"); + private static FieldInfo vectorYFieldInfo = typeof(LSL_Vector).GetField("y"); + private static FieldInfo vectorZFieldInfo = typeof(LSL_Vector).GetField("z"); + + private static MethodInfo arrayClearMethodInfo = typeof(XMR_Array).GetMethod("__pub_clear", new Type[] { }); + private static MethodInfo arrayCountMethodInfo = typeof(XMR_Array).GetMethod("__pub_count", new Type[] { }); + private static MethodInfo arrayIndexMethodInfo = typeof(XMR_Array).GetMethod("__pub_index", new Type[] { typeof(int) }); + private static MethodInfo arrayValueMethodInfo = typeof(XMR_Array).GetMethod("__pub_value", new Type[] { typeof(int) }); + private static MethodInfo checkRunStackMethInfo = typeof(XMRInstAbstract).GetMethod("CheckRunStack", new Type[] { }); + private static MethodInfo checkRunQuickMethInfo = typeof(XMRInstAbstract).GetMethod("CheckRunQuick", new Type[] { }); + private static MethodInfo ehArgUnwrapFloat = GetStaticMethod(typeof(TypeCast), "EHArgUnwrapFloat", new Type[] { typeof(object) }); + private static MethodInfo ehArgUnwrapInteger = GetStaticMethod(typeof(TypeCast), "EHArgUnwrapInteger", new Type[] { typeof(object) }); + private static MethodInfo ehArgUnwrapRotation = GetStaticMethod(typeof(TypeCast), "EHArgUnwrapRotation", new Type[] { typeof(object) }); + private static MethodInfo ehArgUnwrapString = GetStaticMethod(typeof(TypeCast), "EHArgUnwrapString", new Type[] { typeof(object) }); + private static MethodInfo ehArgUnwrapVector = GetStaticMethod(typeof(TypeCast), "EHArgUnwrapVector", new Type[] { typeof(object) }); + private static MethodInfo xmrArrPubIndexMethod = typeof(XMR_Array).GetMethod("__pub_index", new Type[] { typeof(int) }); + private static MethodInfo xmrArrPubValueMethod = typeof(XMR_Array).GetMethod("__pub_value", new Type[] { typeof(int) }); + private static MethodInfo captureStackFrameMethodInfo = typeof(XMRInstAbstract).GetMethod("CaptureStackFrame", new Type[] { typeof(string), typeof(int), typeof(int) }); + private static MethodInfo restoreStackFrameMethodInfo = typeof(XMRInstAbstract).GetMethod("RestoreStackFrame", new Type[] { typeof(string), typeof(int).MakeByRefType() }); + private static MethodInfo stringCompareMethodInfo = GetStaticMethod(typeof(String), "Compare", new Type[] { typeof(string), typeof(string), typeof(StringComparison) }); + private static MethodInfo stringConcat2MethodInfo = GetStaticMethod(typeof(String), "Concat", new Type[] { typeof(string), typeof(string) }); + private static MethodInfo stringConcat3MethodInfo = GetStaticMethod(typeof(String), "Concat", new Type[] { typeof(string), typeof(string), typeof(string) }); + private static MethodInfo stringConcat4MethodInfo = GetStaticMethod(typeof(String), "Concat", new Type[] { typeof(string), typeof(string), typeof(string), typeof(string) }); + private static MethodInfo lslRotationNegateMethodInfo = GetStaticMethod(typeof(ScriptCodeGen), + "LSLRotationNegate", + new Type[] { typeof(LSL_Rotation) }); + private static MethodInfo lslVectorNegateMethodInfo = GetStaticMethod(typeof(ScriptCodeGen), + "LSLVectorNegate", + new Type[] { typeof(LSL_Vector) }); + private static MethodInfo scriptRestoreCatchExceptionUnwrap = GetStaticMethod(typeof(ScriptRestoreCatchException), "Unwrap", new Type[] { typeof(Exception) }); + private static MethodInfo thrownExceptionWrapMethodInfo = GetStaticMethod(typeof(ScriptThrownException), "Wrap", new Type[] { typeof(object) }); + + private static MethodInfo catchExcToStrMethodInfo = GetStaticMethod(typeof(ScriptCodeGen), + "CatchExcToStr", + new Type[] { typeof(Exception) }); + + private static MethodInfo consoleWriteMethodInfo = GetStaticMethod(typeof(ScriptCodeGen), "ConsoleWrite", new Type[] { typeof(object) }); + public static void ConsoleWrite(object o) + { + if(o == null) + o = "<>"; + Console.Write(o.ToString()); + } + + public static bool CodeGen(TokenScript tokenScript, BinaryWriter objFileWriter, string sourceHash) + { + // Run compiler such that it has a 'this' context for convenience. + ScriptCodeGen scg = new ScriptCodeGen(tokenScript, objFileWriter, sourceHash); + + // Return pointer to resultant script object code. + return !scg.youveAnError; + } + + // There is one set of these variables for each script being compiled. + private bool mightGetHere = false; + private bool youveAnError = false; + private BreakContTarg curBreakTarg = null; + private BreakContTarg curContTarg = null; + private int lastErrorLine = 0; + private int nStates = 0; + private string sourceHash; + private string lastErrorFile = ""; + private string[] stateNames; + private XMRInstArSizes glblSizes = new XMRInstArSizes(); + private Token errorMessageToken = null; + private TokenDeclVar curDeclFunc = null; + private TokenStmtBlock curStmtBlock = null; + private BinaryWriter objFileWriter = null; + private TokenScript tokenScript = null; + public int tempCompValuNum = 0; + private TokenDeclSDTypeClass currentSDTClass = null; + + private Dictionary stateIndices = null; + + // These get cleared at beginning of every function definition + private ScriptMyLocal instancePointer; // holds XMRInstanceSuperType pointer + private ScriptMyLabel retLabel = null; // where to jump to exit function + private ScriptMyLocal retValue = null; + private ScriptMyLocal actCallNo = null; // for the active try/catch/finally stack or the big one outside them all + private LinkedList actCallLabels = new LinkedList(); // for the active try/catch/finally stack or the big one outside them all + private LinkedList allCallLabels = new LinkedList(); // this holds each and every one for all stacks in total + public CallLabel openCallLabel = null; // only one call label can be open at a time + // - the call label is open from the time of CallPre() until corresponding CallPost() + // - so no non-trivial pushes/pops etc allowed between a CallPre() and a CallPost() + + private ScriptMyILGen _ilGen; + public ScriptMyILGen ilGen + { + get + { + return _ilGen; + } + } + + private ScriptCodeGen(TokenScript tokenScript, BinaryWriter objFileWriter, string sourceHash) + { + this.tokenScript = tokenScript; + this.objFileWriter = objFileWriter; + this.sourceHash = sourceHash; + + try + { + PerformCompilation(); + } + catch + { + // if we've an error, just punt on any exception + // it's probably just a null reference from something + // not being filled in etc. + if(!youveAnError) + throw; + } + finally + { + objFileWriter = null; + } + } + + /** + * @brief Convert 'tokenScript' to 'objFileWriter' format. + * 'tokenScript' is a parsed/reduced abstract syntax tree of the script source file + * 'objFileWriter' is a serialized form of the CIL code that we generate + */ + private void PerformCompilation() + { + // errorMessageToken is used only when the given token doesn't have a + // output delegate associated with it such as for backend API functions + // that only have one copy for the whole system. It is kept up-to-date + // approximately but is rarely needed so going to assume it doesn't have + // to be exact. + errorMessageToken = tokenScript; + + // Set up dictionary to translate state names to their index number. + stateIndices = new Dictionary(); + + // Assign each state its own unique index. + // The default state gets 0. + nStates = 0; + tokenScript.defaultState.body.index = nStates++; + stateIndices.Add("default", 0); + foreach(KeyValuePair kvp in tokenScript.states) + { + TokenDeclState declState = kvp.Value; + declState.body.index = nStates++; + stateIndices.Add(declState.name.val, declState.body.index); + } + + // Make up an array that translates state indices to state name strings. + stateNames = new string[nStates]; + stateNames[0] = "default"; + foreach(KeyValuePair kvp in tokenScript.states) + { + TokenDeclState declState = kvp.Value; + stateNames[declState.body.index] = declState.name.val; + } + + // Make sure we have delegates for all script-defined functions and methods, + // creating anonymous ones if needed. Note that this includes all property + // getter and setter methods. + foreach(TokenDeclVar declFunc in tokenScript.variablesStack) + { + if(declFunc.retType != null) + { + declFunc.GetDelType(); + } + } + while(true) + { + bool itIsAGoodDayToDie = true; + try + { + foreach(TokenDeclSDType sdType in tokenScript.sdSrcTypesValues) + { + itIsAGoodDayToDie = false; + if(sdType is TokenDeclSDTypeClass) + { + TokenDeclSDTypeClass sdtClass = (TokenDeclSDTypeClass)sdType; + foreach(TokenDeclVar declFunc in sdtClass.members) + { + if(declFunc.retType != null) + { + declFunc.GetDelType(); + if(declFunc.funcNameSig.val.StartsWith("$ctor(")) + { + // this is for the "$new()" static method that we create below. + // See GenerateStmtNewobj() etc. + new TokenTypeSDTypeDelegate(declFunc, sdtClass.MakeRefToken(declFunc), + declFunc.argDecl.types, tokenScript); + } + } + } + } + if(sdType is TokenDeclSDTypeInterface) + { + TokenDeclSDTypeInterface sdtIFace = (TokenDeclSDTypeInterface)sdType; + foreach(TokenDeclVar declFunc in sdtIFace.methsNProps) + { + if(declFunc.retType != null) + { + declFunc.GetDelType(); + } + } + } + itIsAGoodDayToDie = true; + } + break; + } + catch(InvalidOperationException) + { + if(!itIsAGoodDayToDie) + throw; + // fetching the delegate created an anonymous entry in tokenScript.sdSrcTypesValues + // which made the foreach statement puque, so start over... + } + } + + // No more types can be defined or we won't be able to write them to the object file. + tokenScript.sdSrcTypesSeal(); + + // Assign all global variables a slot in its corresponding XMRInstance.gbls[] array. + // Global variables are simply elements of those arrays at runtime, thus we don't need to create + // an unique class for each script, we can just use XMRInstance as is for all. + foreach(TokenDeclVar declVar in tokenScript.variablesStack) + { + // Omit 'constant' variables as they are coded inline so don't need a slot. + if(declVar.constant) + continue; + + // Do functions later. + if(declVar.retType != null) + continue; + + // Create entry in the value array for the variable or property. + declVar.location = new CompValuGlobalVar(declVar, glblSizes); + } + + // Likewise for any static fields in script-defined classes. + // They can be referenced anywhere by ., see + // GenerateFromLValSField(). + foreach(TokenDeclSDType sdType in tokenScript.sdSrcTypesValues) + { + if(!(sdType is TokenDeclSDTypeClass)) + continue; + TokenDeclSDTypeClass sdtClass = (TokenDeclSDTypeClass)sdType; + + foreach(TokenDeclVar declVar in sdtClass.members) + { + // Omit 'constant' variables as they are coded inline so don't need a slot. + if(declVar.constant) + continue; + + // Do methods later. + if(declVar.retType != null) + continue; + + // Ignore non-static fields for now. + // They get assigned below. + if((declVar.sdtFlags & ScriptReduce.SDT_STATIC) == 0) + continue; + + // Create entry in the value array for the static field or static property. + declVar.location = new CompValuGlobalVar(declVar, glblSizes); + } + } + + // Assign slots for all interface method prototypes. + // These indices are used to index the array of delegates that holds a class' implementation of an + // interface. + // Properties do not get a slot because they aren't called as such. But their corresponding + // $get() and $set() methods are in the table and they each get a slot. + foreach(TokenDeclSDType sdType in tokenScript.sdSrcTypesValues) + { + if(!(sdType is TokenDeclSDTypeInterface)) + continue; + TokenDeclSDTypeInterface sdtIFace = (TokenDeclSDTypeInterface)sdType; + int vti = 0; + foreach(TokenDeclVar im in sdtIFace.methsNProps) + { + if((im.getProp == null) && (im.setProp == null)) + { + im.vTableIndex = vti++; + } + } + } + + // Assign slots for all instance fields and virtual methods of script-defined classes. + int maxExtends = tokenScript.sdSrcTypesCount; + bool didOne; + do + { + didOne = false; + foreach(TokenDeclSDType sdType in tokenScript.sdSrcTypesValues) + { + if(!(sdType is TokenDeclSDTypeClass)) + continue; + TokenDeclSDTypeClass sdtClass = (TokenDeclSDTypeClass)sdType; + if(sdtClass.slotsAssigned) + continue; + + // If this class extends another, the extended class has to already + // be set up, because our slots add on to the end of the extended class. + TokenDeclSDTypeClass extends = sdtClass.extends; + if(extends != null) + { + if(!extends.slotsAssigned) + continue; + sdtClass.instSizes = extends.instSizes; + sdtClass.numVirtFuncs = extends.numVirtFuncs; + sdtClass.numInterfaces = extends.numInterfaces; + + int n = maxExtends; + for(TokenDeclSDTypeClass ex = extends; ex != null; ex = ex.extends) + { + if(--n < 0) + break; + } + if(n < 0) + { + ErrorMsg(sdtClass, "loop in extended classes"); + sdtClass.slotsAssigned = true; + continue; + } + } + + // Extended class's slots all assigned, assign our instance fields + // slots in the XMRSDTypeClObj arrays. + foreach(TokenDeclVar declVar in sdtClass.members) + { + if(declVar.retType != null) + continue; + if(declVar.constant) + continue; + if((declVar.sdtFlags & ScriptReduce.SDT_STATIC) != 0) + continue; + if((declVar.getProp == null) && (declVar.setProp == null)) + { + declVar.type.AssignVarSlot(declVar, sdtClass.instSizes); + } + } + + // ... and assign virtual method vtable slots. + // + // - : error if any overridden method, doesn't need a slot + // abstract : error if any overridden method, alloc new slot but leave it empty + // new : ignore any overridden method, doesn't need a slot + // new abstract : ignore any overridden method, alloc new slot but leave it empty + // override : must have overridden abstract/virtual, use old slot + // override abstract : must have overridden abstract, use old slot but it is still empty + // static : error if any overridden method, doesn't need a slot + // static new : ignore any overridden method, doesn't need a slot + // virtual : error if any overridden method, alloc new slot and fill it in + // virtual new : ignore any overridden method, alloc new slot and fill it in + foreach(TokenDeclVar declFunc in sdtClass.members) + { + if(declFunc.retType == null) + continue; + curDeclFunc = declFunc; + + // See if there is a method in an extended class that this method overshadows. + // If so, check for various conflicts. + // In any case, SDT_NEW on our method means to ignore any overshadowed method. + string declLongName = sdtClass.longName.val + "." + declFunc.funcNameSig.val; + uint declFlags = declFunc.sdtFlags; + TokenDeclVar overridden = null; + if((declFlags & ScriptReduce.SDT_NEW) == 0) + { + for(TokenDeclSDTypeClass sdtd = extends; sdtd != null; sdtd = sdtd.extends) + { + overridden = FindExactWithRet(sdtd.members, declFunc.name, declFunc.retType, declFunc.argDecl.types); + if(overridden != null) + break; + } + } + if(overridden != null) + do + { + string overLongName = overridden.sdtClass.longName.val; + uint overFlags = overridden.sdtFlags; + + // See if overridden method allows itself to be overridden. + if((overFlags & ScriptReduce.SDT_ABSTRACT) != 0) + { + if((declFlags & (ScriptReduce.SDT_ABSTRACT | ScriptReduce.SDT_OVERRIDE)) == 0) + { + ErrorMsg(declFunc, declLongName + " overshadows abstract " + overLongName + " but is not marked abstract, new or override"); + break; + } + } + else if((overFlags & ScriptReduce.SDT_FINAL) != 0) + { + ErrorMsg(declFunc, declLongName + " overshadows final " + overLongName + " but is not marked new"); + } + else if((overFlags & (ScriptReduce.SDT_OVERRIDE | ScriptReduce.SDT_VIRTUAL)) != 0) + { + if((declFlags & (ScriptReduce.SDT_NEW | ScriptReduce.SDT_OVERRIDE)) == 0) + { + ErrorMsg(declFunc, declLongName + " overshadows virtual " + overLongName + " but is not marked new or override"); + break; + } + } + else + { + ErrorMsg(declFunc, declLongName + " overshadows non-virtual " + overLongName + " but is not marked new"); + break; + } + + // See if our method is capable of overriding the other method. + if((declFlags & ScriptReduce.SDT_ABSTRACT) != 0) + { + if((overFlags & ScriptReduce.SDT_ABSTRACT) == 0) + { + ErrorMsg(declFunc, declLongName + " abstract overshadows non-abstract " + overLongName + " but is not marked new"); + break; + } + } + else if((declFlags & ScriptReduce.SDT_OVERRIDE) != 0) + { + if((overFlags & (ScriptReduce.SDT_ABSTRACT | ScriptReduce.SDT_OVERRIDE | ScriptReduce.SDT_VIRTUAL)) == 0) + { + ErrorMsg(declFunc, declLongName + " override overshadows non-abstract/non-virtual " + overLongName); + break; + } + } + else + { + ErrorMsg(declFunc, declLongName + " overshadows " + overLongName + " but is not marked new"); + break; + } + } while(false); + + // Now we can assign it a vtable slot if it needs one (ie, it is virtual). + declFunc.vTableIndex = -1; + if(overridden != null) + { + declFunc.vTableIndex = overridden.vTableIndex; + } + else if((declFlags & ScriptReduce.SDT_OVERRIDE) != 0) + { + ErrorMsg(declFunc, declLongName + " marked override but nothing matching found that it overrides"); + } + if((declFlags & (ScriptReduce.SDT_ABSTRACT | ScriptReduce.SDT_VIRTUAL)) != 0) + { + declFunc.vTableIndex = sdtClass.numVirtFuncs++; + } + } + curDeclFunc = null; + + // ... and assign implemented interface slots. + // Note that our implementations of a given interface is completely independent of any + // rootward class's implementation of that same interface. + int nIFaces = sdtClass.numInterfaces + sdtClass.implements.Count; + sdtClass.iFaces = new TokenDeclSDTypeInterface[nIFaces]; + sdtClass.iImplFunc = new TokenDeclVar[nIFaces][]; + for(int i = 0; i < sdtClass.numInterfaces; i++) + { + sdtClass.iFaces[i] = extends.iFaces[i]; + sdtClass.iImplFunc[i] = extends.iImplFunc[i]; + } + + foreach(TokenDeclSDTypeInterface intf in sdtClass.implements) + { + int i = sdtClass.numInterfaces++; + sdtClass.iFaces[i] = intf; + sdtClass.intfIndices.Add(intf.longName.val, i); + int nMeths = 0; + foreach(TokenDeclVar m in intf.methsNProps) + { + if((m.getProp == null) && (m.setProp == null)) + nMeths++; + } + sdtClass.iImplFunc[i] = new TokenDeclVar[nMeths]; + } + + foreach(TokenDeclVar classMeth in sdtClass.members) + { + if(classMeth.retType == null) + continue; + curDeclFunc = classMeth; + for(TokenIntfImpl intfImpl = classMeth.implements; intfImpl != null; intfImpl = (TokenIntfImpl)intfImpl.nextToken) + { + // One of the class methods implements an interface method. + // Try to find the interface method that is implemented and verify its signature. + TokenDeclSDTypeInterface intfType = intfImpl.intfType.decl; + TokenDeclVar intfMeth = FindExactWithRet(intfType.methsNProps, intfImpl.methName, classMeth.retType, classMeth.argDecl.types); + if(intfMeth == null) + { + ErrorMsg(intfImpl, "interface does not define method " + intfImpl.methName.val + classMeth.argDecl.GetArgSig()); + continue; + } + + // See if this class was declared to implement that interface. + bool found = false; + foreach(TokenDeclSDTypeInterface intf in sdtClass.implements) + { + if(intf == intfType) + { + found = true; + break; + } + } + if(!found) + { + ErrorMsg(intfImpl, "class not declared to implement " + intfType.longName.val); + continue; + } + + // Get index in iFaces[] and iImplFunc[] arrays. + // Start scanning from the end in case one of our rootward classes also implements the interface. + // We should always be successful because we know by now that this class implements the interface. + int i; + for(i = sdtClass.numInterfaces; --i >= 0;) + { + if(sdtClass.iFaces[i] == intfType) + break; + } + + // Now remember which of the class methods implements that interface method. + int j = intfMeth.vTableIndex; + if(sdtClass.iImplFunc[i][j] != null) + { + ErrorMsg(intfImpl, "also implemented by " + sdtClass.iImplFunc[i][j].funcNameSig.val); + continue; + } + sdtClass.iImplFunc[i][j] = classMeth; + } + } + curDeclFunc = null; + + // Now make sure this class implements all methods for all declared interfaces. + for(int i = sdtClass.numInterfaces - sdtClass.implements.Count; i < sdtClass.numInterfaces; i++) + { + TokenDeclVar[] implementations = sdtClass.iImplFunc[i]; + for(int j = implementations.Length; --j >= 0;) + { + if(implementations[j] == null) + { + TokenDeclSDTypeInterface intf = sdtClass.iFaces[i]; + TokenDeclVar meth = null; + foreach(TokenDeclVar im in intf.methsNProps) + { + if(im.vTableIndex == j) + { + meth = im; + break; + } + } + ErrorMsg(sdtClass, "does not implement " + intf.longName.val + "." + meth.funcNameSig.val); + } + } + } + + // All slots for this class have been assigned. + sdtClass.slotsAssigned = true; + didOne = true; + } + } while(didOne); + + // Compute final values for all variables/fields declared as 'constant'. + // Note that there may be forward references. + do + { + didOne = false; + foreach(TokenDeclVar tdv in tokenScript.variablesStack) + { + if(tdv.constant && !(tdv.init is TokenRValConst)) + { + tdv.init = tdv.init.TryComputeConstant(LookupInitConstants, ref didOne); + } + } + foreach(TokenDeclSDType sdType in tokenScript.sdSrcTypesValues) + { + if(!(sdType is TokenDeclSDTypeClass)) + continue; + currentSDTClass = (TokenDeclSDTypeClass)sdType; + foreach(TokenDeclVar tdv in currentSDTClass.members) + { + if(tdv.constant && !(tdv.init is TokenRValConst)) + { + tdv.init = tdv.init.TryComputeConstant(LookupInitConstants, ref didOne); + } + } + } + currentSDTClass = null; + } while(didOne); + + // Now we should be able to assign all those constants their type and location. + foreach(TokenDeclVar tdv in tokenScript.variablesStack) + { + if(tdv.constant) + { + if(tdv.init is TokenRValConst) + { + TokenRValConst rvc = (TokenRValConst)tdv.init; + tdv.type = rvc.tokType; + tdv.location = rvc.GetCompValu(); + } + else + { + ErrorMsg(tdv, "value is not constant"); + } + } + } + foreach(TokenDeclSDType sdType in tokenScript.sdSrcTypesValues) + { + if(!(sdType is TokenDeclSDTypeClass)) + continue; + currentSDTClass = (TokenDeclSDTypeClass)sdType; + foreach(TokenDeclVar tdv in currentSDTClass.members) + { + if(tdv.constant) + { + if(tdv.init is TokenRValConst) + { + TokenRValConst rvc = (TokenRValConst)tdv.init; + tdv.type = rvc.tokType; + tdv.location = rvc.GetCompValu(); + } + else + { + ErrorMsg(tdv, "value is not constant"); + } + } + } + } + currentSDTClass = null; + + // For all classes that define all the methods needed for the class, ie, they aren't abstract, + // define a static class.$new() method with same args as the $ctor(s). This will allow the + // class to be instantiated via the new operator. + foreach(TokenDeclSDType sdType in tokenScript.sdSrcTypesValues) + { + if(!(sdType is TokenDeclSDTypeClass)) + continue; + TokenDeclSDTypeClass sdtClass = (TokenDeclSDTypeClass)sdType; + + // See if the class as it stands would be able to fill every slot of its vtable. + bool[] filled = new bool[sdtClass.numVirtFuncs]; + int numFilled = 0; + for(TokenDeclSDTypeClass sdtc = sdtClass; sdtc != null; sdtc = sdtc.extends) + { + foreach(TokenDeclVar tdf in sdtc.members) + { + if((tdf.retType != null) && (tdf.vTableIndex >= 0) && ((tdf.sdtFlags & ScriptReduce.SDT_ABSTRACT) == 0)) + { + if(!filled[tdf.vTableIndex]) + { + filled[tdf.vTableIndex] = true; + numFilled++; + } + } + } + } + + // If so, define a static class.$new() method for every constructor defined for the class. + // Give it the same access (private/protected/public) as the script declared for the constructor. + // Note that the reducer made sure there is at least a default constructor for every class. + if(numFilled >= sdtClass.numVirtFuncs) + { + List newobjDeclFuncs = new List(); + foreach(TokenDeclVar ctorDeclFunc in sdtClass.members) + { + if((ctorDeclFunc.funcNameSig != null) && ctorDeclFunc.funcNameSig.val.StartsWith("$ctor(")) + { + TokenDeclVar newobjDeclFunc = DefineNewobjFunc(ctorDeclFunc); + newobjDeclFuncs.Add(newobjDeclFunc); + } + } + foreach(TokenDeclVar newobjDeclFunc in newobjDeclFuncs) + { + sdtClass.members.AddEntry(newobjDeclFunc); + } + } + } + + // Write fixed portion of object file. + objFileWriter.Write(OBJECT_CODE_MAGIC.ToCharArray()); + objFileWriter.Write(COMPILED_VERSION_VALUE); + objFileWriter.Write(sourceHash); + glblSizes.WriteToFile(objFileWriter); + + objFileWriter.Write(nStates); + for(int i = 0; i < nStates; i++) + { + objFileWriter.Write(stateNames[i]); + } + + // For debugging, we also write out global variable array slot assignments. + foreach(TokenDeclVar declVar in tokenScript.variablesStack) + { + if(declVar.retType == null) + { + WriteOutGblAssignment("", declVar); + } + } + foreach(TokenDeclSDType sdType in tokenScript.sdSrcTypesValues) + { + if(!(sdType is TokenDeclSDTypeClass)) + continue; + TokenDeclSDTypeClass sdtClass = (TokenDeclSDTypeClass)sdType; + foreach(TokenDeclVar declVar in sdtClass.members) + { + if((declVar.sdtFlags & ScriptReduce.SDT_STATIC) != 0) + { + WriteOutGblAssignment(sdtClass.longName.val + ".", declVar); + } + } + } + objFileWriter.Write(""); + + // Write out script-defined types. + foreach(TokenDeclSDType sdType in tokenScript.sdSrcTypesValues) + { + objFileWriter.Write(sdType.longName.val); + sdType.WriteToFile(objFileWriter); + } + objFileWriter.Write(""); + + // Output function headers then bodies. + // Do all headers first in case bodies do forward references. + // Do both global functions, script-defined class static methods and + // script-defined instance methods, as we handle the differences + // during compilation of the functions/methods themselves. + + // headers + foreach(TokenDeclVar declFunc in tokenScript.variablesStack) + { + if(declFunc.retType != null) + GenerateMethodHeader(declFunc); + } + foreach(TokenDeclSDType sdType in tokenScript.sdSrcTypesValues) + { + if(sdType is TokenDeclSDTypeClass) + { + TokenDeclSDTypeClass sdtClass = (TokenDeclSDTypeClass)sdType; + foreach(TokenDeclVar declFunc in sdtClass.members) + { + if((declFunc.retType != null) && ((declFunc.sdtFlags & ScriptReduce.SDT_ABSTRACT) == 0)) + GenerateMethodHeader(declFunc); + } + } + } + + // now bodies + foreach(TokenDeclVar declFunc in tokenScript.variablesStack) + { + if(declFunc.retType != null) + GenerateMethodBody(declFunc); + } + foreach(TokenDeclSDType sdType in tokenScript.sdSrcTypesValues) + { + if(sdType is TokenDeclSDTypeClass) + { + TokenDeclSDTypeClass sdtClass = (TokenDeclSDTypeClass)sdType; + foreach(TokenDeclVar declFunc in sdtClass.members) + { + if((declFunc.retType != null) && ((declFunc.sdtFlags & ScriptReduce.SDT_ABSTRACT) == 0)) + GenerateMethodBody(declFunc); + } + } + } + + // Output default state event handler functions. + // Each event handler is a private static method named 'default '. + // Splice in a default state_entry() handler if none defined so we can init global vars. + TokenDeclVar defaultStateEntry = null; + for(defaultStateEntry = tokenScript.defaultState.body.eventFuncs; + defaultStateEntry != null; + defaultStateEntry = (TokenDeclVar)defaultStateEntry.nextToken) + { + if(defaultStateEntry.funcNameSig.val == "state_entry()") + break; + } + if(defaultStateEntry == null) + { + defaultStateEntry = new TokenDeclVar(tokenScript.defaultState.body, null, tokenScript); + defaultStateEntry.name = new TokenName(tokenScript.defaultState.body, "state_entry"); + defaultStateEntry.retType = new TokenTypeVoid(tokenScript.defaultState.body); + defaultStateEntry.argDecl = new TokenArgDecl(tokenScript.defaultState.body); + defaultStateEntry.body = new TokenStmtBlock(tokenScript.defaultState.body); + defaultStateEntry.body.function = defaultStateEntry; + + defaultStateEntry.nextToken = tokenScript.defaultState.body.eventFuncs; + tokenScript.defaultState.body.eventFuncs = defaultStateEntry; + } + GenerateStateEventHandlers("default", tokenScript.defaultState.body); + + // Output script-defined state event handler methods. + // Each event handler is a private static method named + foreach(KeyValuePair kvp in tokenScript.states) + { + TokenDeclState declState = kvp.Value; + GenerateStateEventHandlers(declState.name.val, declState.body); + } + + ScriptObjWriter.TheEnd(objFileWriter); + } + + /** + * @brief Write out what slot was assigned for a global or sdtclass static variable. + * Constants, functions, instance fields, methods, properties do not have slots in the global variables arrays. + */ + private void WriteOutGblAssignment(string pfx, TokenDeclVar declVar) + { + if(!declVar.constant && (declVar.retType == null) && (declVar.getProp == null) && (declVar.setProp == null)) + { + objFileWriter.Write(pfx + declVar.name.val); // string + objFileWriter.Write(declVar.vTableArray.Name); // string + objFileWriter.Write(declVar.vTableIndex); // int + } + } + + /** + * @brief generate event handler code + * Writes out a function definition for each state handler + * named + * + * However, each has just 'XMRInstance __sw' as its single argument + * and each of its user-visible argments is extracted from __sw.ehArgs[]. + * + * So we end up generating something like this: + * + * private static void (XMRInstance __sw) + * { + * = ()__sw.ehArgs[0]; + * = ()__sw.ehArgs[1]; + * + * ... script code ... + * } + * + * The continuations code assumes there will be no references to ehArgs[] + * after the first call to CheckRun() as CheckRun() makes no attempt to + * serialize the ehArgs[] array, as doing so would be redundant. Any values + * from ehArgs[] that are being used will be in local stack variables and + * thus preserved that way. + */ + private void GenerateStateEventHandlers(string statename, TokenStateBody body) + { + Dictionary statehandlers = new Dictionary(); + for(Token t = body.eventFuncs; t != null; t = t.nextToken) + { + TokenDeclVar tdv = (TokenDeclVar)t; + string eventname = tdv.GetSimpleName(); + if(statehandlers.ContainsKey(eventname)) + { + ErrorMsg(tdv, "event handler " + eventname + " already defined for state " + statename); + } + else + { + statehandlers.Add(eventname, tdv); + GenerateEventHandler(statename, tdv); + } + } + } + + private void GenerateEventHandler(string statename, TokenDeclVar declFunc) + { + string eventname = declFunc.GetSimpleName(); + TokenArgDecl argDecl = declFunc.argDecl; + + // Make sure event handler name is valid and that number and type of arguments is correct. + // Apparently some scripts exist with fewer than correct number of args in their declaration + // so allow for that. It is ok because the handlers are called with the arguments in an + // object[] array, and we just won't access the missing argments in the vector. But the + // specified types must match one of the prototypes in legalEventHandlers. + TokenDeclVar protoDeclFunc = legalEventHandlers.FindExact(eventname, argDecl.types); + if(protoDeclFunc == null) + { + ErrorMsg(declFunc, "unknown event handler " + eventname + argDecl.GetArgSig()); + return; + } + + // Output function header. + // They just have the XMRInstAbstract pointer as the one argument. + string functionName = statename + " " + eventname; + _ilGen = new ScriptObjWriter(tokenScript, + functionName, + typeof(void), + instanceTypeArg, + instanceNameArg, + objFileWriter); + StartFunctionBody(declFunc); + + // Create a temp to hold XMRInstanceSuperType version of arg 0. + instancePointer = ilGen.DeclareLocal(xmrInstSuperType, "__xmrinst"); + ilGen.Emit(declFunc, OpCodes.Ldarg_0); + ilGen.Emit(declFunc, OpCodes.Castclass, xmrInstSuperType); + ilGen.Emit(declFunc, OpCodes.Stloc, instancePointer); + + // Output args as variable definitions and initialize each from __sw.ehArgs[]. + // If the script writer goofed, the typecast will complain. + int nArgs = argDecl.vars.Length; + for(int i = 0; i < nArgs; i++) + { + // Say that the argument variable is going to be located in a local var. + TokenDeclVar argVar = argDecl.vars[i]; + TokenType argTokType = argVar.type; + CompValuLocalVar local = new CompValuLocalVar(argTokType, argVar.name.val, this); + argVar.location = local; + + // Copy from the ehArgs[i] element to the temp var. + // Cast as needed, there is a lot of craziness like OpenMetaverse.Quaternion. + local.PopPre(this, argVar.name); + PushXMRInst(); // instance + ilGen.Emit(declFunc, OpCodes.Ldfld, ehArgsFieldInfo); // instance.ehArgs (array of objects) + ilGen.Emit(declFunc, OpCodes.Ldc_I4, i); // array index = i + ilGen.Emit(declFunc, OpCodes.Ldelem, typeof(object)); // select the argument we want + TokenType stkTokType = tokenTypeObj; // stack has a type 'object' on it now + Type argSysType = argTokType.ToSysType(); // this is the type the script expects + if(argSysType == typeof(double)) + { // LSL_Float/double -> double + ilGen.Emit(declFunc, OpCodes.Call, ehArgUnwrapFloat); + stkTokType = tokenTypeFlt; // stack has a type 'double' on it now + } + if(argSysType == typeof(int)) + { // LSL_Integer/int -> int + ilGen.Emit(declFunc, OpCodes.Call, ehArgUnwrapInteger); + stkTokType = tokenTypeInt; // stack has a type 'int' on it now + } + if(argSysType == typeof(LSL_List)) + { // LSL_List -> LSL_List + TypeCast.CastTopOfStack(this, argVar.name, stkTokType, argTokType, true); + stkTokType = argTokType; // stack has a type 'LSL_List' on it now + } + if(argSysType == typeof(LSL_Rotation)) + { // OpenMetaverse.Quaternion/LSL_Rotation -> LSL_Rotation + ilGen.Emit(declFunc, OpCodes.Call, ehArgUnwrapRotation); + stkTokType = tokenTypeRot; // stack has a type 'LSL_Rotation' on it now + } + if(argSysType == typeof(string)) + { // LSL_Key/LSL_String/string -> string + ilGen.Emit(declFunc, OpCodes.Call, ehArgUnwrapString); + stkTokType = tokenTypeStr; // stack has a type 'string' on it now + } + if(argSysType == typeof(LSL_Vector)) + { // OpenMetaverse.Vector3/LSL_Vector -> LSL_Vector + ilGen.Emit(declFunc, OpCodes.Call, ehArgUnwrapVector); + stkTokType = tokenTypeVec; // stack has a type 'LSL_Vector' on it now + } + local.PopPost(this, argVar.name, stkTokType); // pop stack type into argtype + } + + // Output code for the statements and clean up. + GenerateFuncBody(); + } + + /** + * @brief generate header for an arbitrary script-defined global function. + * @param declFunc = function being defined + */ + private void GenerateMethodHeader(TokenDeclVar declFunc) + { + curDeclFunc = declFunc; + + // Make up array of all argument types as seen by the code generator. + // We splice in XMRInstanceSuperType or XMRSDTypeClObj for the first + // arg as the function itself is static, followed by script-visible + // arg types. + TokenArgDecl argDecl = declFunc.argDecl; + int nArgs = argDecl.vars.Length; + Type[] argTypes = new Type[nArgs + 1]; + string[] argNames = new string[nArgs + 1]; + if(IsSDTInstMethod()) + { + argTypes[0] = typeof(XMRSDTypeClObj); + argNames[0] = "$sdtthis"; + } + else + { + argTypes[0] = xmrInstSuperType; + argNames[0] = "$xmrthis"; + } + for(int i = 0; i < nArgs; i++) + { + argTypes[i + 1] = argDecl.vars[i].type.ToSysType(); + argNames[i + 1] = argDecl.vars[i].name.val; + } + + // Set up entrypoint. + string objCodeName = declFunc.GetObjCodeName(); + declFunc.ilGen = new ScriptObjWriter(tokenScript, + objCodeName, + declFunc.retType.ToSysType(), + argTypes, + argNames, + objFileWriter); + + // This says how to generate a call to the function and to get a delegate. + declFunc.location = new CompValuGlobalMeth(declFunc); + + curDeclFunc = null; + } + + /** + * @brief generate code for an arbitrary script-defined function. + * @param name = name of the function + * @param argDecl = argument declarations + * @param body = function's code body + */ + private void GenerateMethodBody(TokenDeclVar declFunc) + { + // Set up code generator for the function's contents. + _ilGen = declFunc.ilGen; + StartFunctionBody(declFunc); + + // Create a temp to hold XMRInstanceSuperType version of arg 0. + // For most functions, arg 0 is already XMRInstanceSuperType. + // But for script-defined class instance methods, arg 0 holds + // the XMRSDTypeClObj pointer and so we read the XMRInstAbstract + // pointer from its XMRSDTypeClObj.xmrInst field then cast it to + // XMRInstanceSuperType. + if(IsSDTInstMethod()) + { + instancePointer = ilGen.DeclareLocal(xmrInstSuperType, "__xmrinst"); + ilGen.Emit(declFunc, OpCodes.Ldarg_0); + ilGen.Emit(declFunc, OpCodes.Ldfld, sdtXMRInstFieldInfo); + ilGen.Emit(declFunc, OpCodes.Castclass, xmrInstSuperType); + ilGen.Emit(declFunc, OpCodes.Stloc, instancePointer); + } + + // Define location of all script-level arguments so script body can access them. + // The argument indices need to have +1 added to them because XMRInstance or + // XMRSDTypeClObj is spliced in at arg 0. + TokenArgDecl argDecl = declFunc.argDecl; + int nArgs = argDecl.vars.Length; + for(int i = 0; i < nArgs; i++) + { + TokenDeclVar argVar = argDecl.vars[i]; + argVar.location = new CompValuArg(argVar.type, i + 1); + } + + // Output code for the statements and clean up. + GenerateFuncBody(); + } + + private void StartFunctionBody(TokenDeclVar declFunc) + { + // Start current function being processed. + // Set 'mightGetHere' as the code at the top is always executed. + instancePointer = null; + mightGetHere = true; + curBreakTarg = null; + curContTarg = null; + curDeclFunc = declFunc; + + // Start generating code. + ((ScriptObjWriter)ilGen).BegMethod(); + } + + /** + * @brief Define function for a script-defined type's .$new() method. + * See GenerateStmtNewobj() for more info. + */ + private TokenDeclVar DefineNewobjFunc(TokenDeclVar ctorDeclFunc) + { + // Set up 'static classname $new(params-same-as-ctor) { }'. + TokenDeclVar newobjDeclFunc = new TokenDeclVar(ctorDeclFunc, null, tokenScript); + newobjDeclFunc.name = new TokenName(newobjDeclFunc, "$new"); + newobjDeclFunc.retType = ctorDeclFunc.sdtClass.MakeRefToken(newobjDeclFunc); + newobjDeclFunc.argDecl = ctorDeclFunc.argDecl; + newobjDeclFunc.sdtClass = ctorDeclFunc.sdtClass; + newobjDeclFunc.sdtFlags = ScriptReduce.SDT_STATIC | ctorDeclFunc.sdtFlags; + + // Declare local variable named '$objptr' in a frame just under + // what the '$new(...)' function's arguments are declared in. + TokenDeclVar objptrVar = new TokenDeclVar(newobjDeclFunc, newobjDeclFunc, tokenScript); + objptrVar.type = newobjDeclFunc.retType; + objptrVar.name = new TokenName(newobjDeclFunc, "$objptr"); + VarDict newFrame = new VarDict(false); + newFrame.outerVarDict = ctorDeclFunc.argDecl.varDict; + newFrame.AddEntry(objptrVar); + + // Set up '$objptr.$ctor' + TokenLValName objptrLValName = new TokenLValName(objptrVar.name, newFrame); + + // ref a var by giving its name + TokenLValIField objptrDotCtor = new TokenLValIField(newobjDeclFunc); // an instance member reference + objptrDotCtor.baseRVal = objptrLValName; // '$objptr' + objptrDotCtor.fieldName = ctorDeclFunc.name; // '.' '$ctor' + + // Set up '$objptr.$ctor(arglist)' call for use in the '$new(...)' body. + // Copy the arglist from the constructor declaration so triviality + // processing will pick the correct overloaded constructor. + TokenRValCall callCtorRVal = new TokenRValCall(newobjDeclFunc); // doing a call of some sort + callCtorRVal.meth = objptrDotCtor; // calling $objptr.$ctor() + TokenDeclVar[] argList = newobjDeclFunc.argDecl.vars; // get args $new() was declared with + callCtorRVal.nArgs = argList.Length; // ...that is nArgs we are passing to $objptr.$ctor() + for(int i = argList.Length; --i >= 0;) + { + TokenDeclVar arg = argList[i]; // find out about one of the args + TokenLValName argLValName = new TokenLValName(arg.name, ctorDeclFunc.argDecl.varDict); + // pass arg of that name to $objptr.$ctor() + argLValName.nextToken = callCtorRVal.args; // link to list of args passed to $objptr.$ctor() + callCtorRVal.args = argLValName; + } + + // Set up a funky call to the constructor for the code body. + // This will let code generator know there is some craziness. + // See GenerateStmtNewobj(). + // + // This is in essence: + // { + // classname $objptr = newobj (classname); + // $objptr.$ctor (...); + // return $objptr; + // } + TokenStmtNewobj newobjStmtBody = new TokenStmtNewobj(ctorDeclFunc); + newobjStmtBody.objptrVar = objptrVar; + newobjStmtBody.rValCall = callCtorRVal; + TokenStmtBlock newobjBody = new TokenStmtBlock(ctorDeclFunc); + newobjBody.statements = newobjStmtBody; + + // Link that code as the body of the function. + newobjDeclFunc.body = newobjBody; + + // Say the function calls '$objptr.$ctor(arglist)' so we will inherit ctor's triviality. + newobjDeclFunc.unknownTrivialityCalls.AddLast(callCtorRVal); + return newobjDeclFunc; + } + + private class TokenStmtNewobj: TokenStmt + { + public TokenDeclVar objptrVar; + public TokenRValCall rValCall; + public TokenStmtNewobj(Token original) : base(original) { } + } + + /** + * @brief Output function body (either event handler or script-defined method). + */ + private void GenerateFuncBody() + { + // We want to know if the function's code is trivial, ie, + // if it doesn't have anything that might be an infinite + // loop and that is doesn't call anything that might have + // an infinite loop. If it is, we don't need any CheckRun() + // stuff or any of the frame save/restore stuff. + bool isTrivial = curDeclFunc.IsFuncTrivial(this); + + // Clear list of all call labels. + // A call label is inserted just before every call that can possibly + // call CheckRun(), including any direct calls to CheckRun(). + // Then, when restoring stack, we can just switch to this label to + // resume at the correct spot. + actCallLabels.Clear(); + allCallLabels.Clear(); + openCallLabel = null; + + // Alloc stack space for local vars. + int stackframesize = AllocLocalVarStackSpace(); + + // Include argument variables in stack space for this frame. + foreach(TokenType tokType in curDeclFunc.argDecl.types) + { + stackframesize += LocalVarStackSize(tokType); + } + + // Any return statements inside function body jump to this label + // after putting return value in __retval. + retLabel = ilGen.DefineLabel("__retlbl"); + retValue = null; + if(!(curDeclFunc.retType is TokenTypeVoid)) + { + retValue = ilGen.DeclareLocal(curDeclFunc.retType.ToSysType(), "__retval"); + } + + // Output: + // int __mainCallNo = -1; + // instance.m_StackLeft -= stackframesize; + // try { + // if (instance.callMode != CallMode_NORMAL) goto __cmRestore; + actCallNo = null; + ScriptMyLabel cmRestore = null; + if(!isTrivial) + { + actCallNo = ilGen.DeclareLocal(typeof(int), "__mainCallNo"); + SetCallNo(curDeclFunc, actCallNo, -1); + PushXMRInst(); + ilGen.Emit(curDeclFunc, OpCodes.Dup); + ilGen.Emit(curDeclFunc, OpCodes.Ldfld, stackLeftFieldInfo); + ilGen.Emit(curDeclFunc, OpCodes.Ldc_I4, stackframesize); + ilGen.Emit(curDeclFunc, OpCodes.Sub); + ilGen.Emit(curDeclFunc, OpCodes.Stfld, stackLeftFieldInfo); + cmRestore = ilGen.DefineLabel("__cmRestore"); + ilGen.BeginExceptionBlock(); + PushXMRInst(); + ilGen.Emit(curDeclFunc, OpCodes.Ldfld, ScriptCodeGen.callModeFieldInfo); + ilGen.Emit(curDeclFunc, OpCodes.Ldc_I4, XMRInstAbstract.CallMode_NORMAL); + ilGen.Emit(curDeclFunc, OpCodes.Bne_Un, cmRestore); + } + + // Splice in the code optimizer for the body of the function. + ScriptCollector collector = new ScriptCollector((ScriptObjWriter)ilGen); + _ilGen = collector; + + // If this is the default state_entry() handler, output code to set all global + // variables to their initial values. Note that every script must have a + // default state_entry() handler, we provide one if the script doesn't explicitly + // define one. + string methname = ilGen.methName; + if(methname == "default state_entry") + { + + // if (!doGblInit) goto skipGblInit; + ScriptMyLabel skipGblInitLabel = ilGen.DefineLabel("__skipGblInit"); + PushXMRInst(); // instance + ilGen.Emit(curDeclFunc, OpCodes.Ldfld, doGblInitFieldInfo); // instance.doGblInit + ilGen.Emit(curDeclFunc, OpCodes.Brfalse, skipGblInitLabel); + + // $globalvarinit(); + TokenDeclVar gviFunc = tokenScript.globalVarInit; + if(gviFunc.body.statements != null) + { + gviFunc.location.CallPre(this, gviFunc); + gviFunc.location.CallPost(this, gviFunc); + } + + // various $staticfieldinit(); + foreach(TokenDeclSDType sdType in tokenScript.sdSrcTypesValues) + { + if(sdType is TokenDeclSDTypeClass) + { + TokenDeclVar sfiFunc = ((TokenDeclSDTypeClass)sdType).staticFieldInit; + if((sfiFunc != null) && (sfiFunc.body.statements != null)) + { + sfiFunc.location.CallPre(this, sfiFunc); + sfiFunc.location.CallPost(this, sfiFunc); + } + } + } + + // doGblInit = 0; + PushXMRInst(); // instance + ilGen.Emit(curDeclFunc, OpCodes.Ldc_I4_0); + ilGen.Emit(curDeclFunc, OpCodes.Stfld, doGblInitFieldInfo); // instance.doGblInit + + //skipGblInit: + ilGen.MarkLabel(skipGblInitLabel); + } + + // If this is a script-defined type constructor, call the base constructor and call + // this class's $instfieldinit() method to initialize instance fields. + if((curDeclFunc.sdtClass != null) && curDeclFunc.funcNameSig.val.StartsWith("$ctor(")) + { + if(curDeclFunc.baseCtorCall != null) + { + GenerateFromRValCall(curDeclFunc.baseCtorCall); + } + TokenDeclVar ifiFunc = ((TokenDeclSDTypeClass)curDeclFunc.sdtClass).instFieldInit; + if(ifiFunc.body.statements != null) + { + CompValu thisCompValu = new CompValuArg(ifiFunc.sdtClass.MakeRefToken(ifiFunc), 0); + CompValu ifiFuncLocn = new CompValuInstMember(ifiFunc, thisCompValu, true); + ifiFuncLocn.CallPre(this, ifiFunc); + ifiFuncLocn.CallPost(this, ifiFunc); + } + } + + // See if time to suspend in case they are doing a loop with recursion. + if(!isTrivial) + EmitCallCheckRun(curDeclFunc, true); + + // Output code body. + GenerateStmtBlock(curDeclFunc.body); + + // If code falls through to this point, means they are missing + // a return statement. And that is legal only if the function + // returns 'void'. + if(mightGetHere) + { + if(!(curDeclFunc.retType is TokenTypeVoid)) + { + ErrorMsg(curDeclFunc.body, "missing final return statement"); + } + ilGen.Emit(curDeclFunc, OpCodes.Leave, retLabel); + } + + // End of the code to be optimized. + // Do optimizations then write it all out to object file. + // After this, all code gets written directly to object file. + // Optimization must be completed before we scan the allCallLabels + // list below to look for active locals and temps. + collector.Optimize(); + _ilGen = collector.WriteOutAll(); + collector = null; + + // Output code to restore stack frame from stream. + // It jumps back to the call labels within the function body. + List activeTemps = null; + if(!isTrivial) + { + // Build list of locals and temps active at all the call labels. + activeTemps = new List(); + foreach(CallLabel cl in allCallLabels) + { + foreach(ScriptMyLocal lcl in cl.callLabel.whereAmI.localsReadBeforeWritten) + { + if(!activeTemps.Contains(lcl)) + { + activeTemps.Add(lcl); + } + } + } + + // Output code to restore the args, locals and temps then jump to + // the call label that we were interrupted at. + ilGen.MarkLabel(cmRestore); + GenerateFrameRestoreCode(activeTemps); + } + + // Output epilog that saves stack frame state if CallMode_SAVE. + // + // finally { + // instance.m_StackLeft += stackframesize; + // if (instance.callMode != CallMode_SAVE) goto __endFin; + // GenerateFrameCaptureCode(); + // __endFin: + // } + ScriptMyLabel endFin = null; + if(!isTrivial) + { + ilGen.BeginFinallyBlock(); + PushXMRInst(); + ilGen.Emit(curDeclFunc, OpCodes.Dup); + ilGen.Emit(curDeclFunc, OpCodes.Ldfld, stackLeftFieldInfo); + ilGen.Emit(curDeclFunc, OpCodes.Ldc_I4, stackframesize); + ilGen.Emit(curDeclFunc, OpCodes.Add); + ilGen.Emit(curDeclFunc, OpCodes.Stfld, stackLeftFieldInfo); + endFin = ilGen.DefineLabel("__endFin"); + PushXMRInst(); + ilGen.Emit(curDeclFunc, OpCodes.Ldfld, callModeFieldInfo); + ilGen.Emit(curDeclFunc, OpCodes.Ldc_I4, XMRInstAbstract.CallMode_SAVE); + ilGen.Emit(curDeclFunc, OpCodes.Bne_Un, endFin); + GenerateFrameCaptureCode(activeTemps); + ilGen.MarkLabel(endFin); + ilGen.Emit(curDeclFunc, OpCodes.Endfinally); + ilGen.EndExceptionBlock(); + } + + // Output the 'real' return opcode. + ilGen.MarkLabel(retLabel); + if(!(curDeclFunc.retType is TokenTypeVoid)) + { + ilGen.Emit(curDeclFunc, OpCodes.Ldloc, retValue); + } + ilGen.Emit(curDeclFunc, OpCodes.Ret); + retLabel = null; + retValue = null; + + // No more instructions for this method. + ((ScriptObjWriter)ilGen).EndMethod(); + _ilGen = null; + + // Not generating function code any more. + curBreakTarg = null; + curContTarg = null; + curDeclFunc = null; + } + + /** + * @brief Allocate stack space for all local variables, regardless of + * which { } statement block they are actually defined in. + * @returns approximate stack frame size + */ + private int AllocLocalVarStackSpace() + { + int stackframesize = 64; // RIP, RBX, RBP, R12..R15, one extra + foreach(TokenDeclVar localVar in curDeclFunc.localVars) + { + // Skip all 'constant' vars as they were handled by the reducer. + if(localVar.constant) + continue; + + // Get a stack location for the local variable. + localVar.location = new CompValuLocalVar(localVar.type, localVar.name.val, this); + + // Stack size for the local variable. + stackframesize += LocalVarStackSize(localVar.type); + } + return stackframesize; + } + + private static int LocalVarStackSize(TokenType tokType) + { + Type sysType = tokType.ToSysType(); + return sysType.IsValueType ? System.Runtime.InteropServices.Marshal.SizeOf(sysType) : 8; + } + + /** + * @brief Generate code to write all arguments and locals to the capture stack frame. + * This includes temp variables. + * We only need to save what is active at the point of callLabels through because + * those are the only points we will jump to on restore. This saves us from saving + * all the little temp vars we create. + * @param activeTemps = list of locals and temps that we care about, ie, which + * ones get restored by GenerateFrameRestoreCode(). + */ + private void GenerateFrameCaptureCode(List activeTemps) + { + // Compute total number of slots we need to save stuff. + // Assume we need to save all call arguments. + int nSaves = curDeclFunc.argDecl.vars.Length + activeTemps.Count; + + // Output code to allocate a stack frame object with an object array. + // This also pushes the stack frame object on the instance.stackFrames list. + // It returns a pointer to the object array it allocated. + PushXMRInst(); + ilGen.Emit(curDeclFunc, OpCodes.Ldstr, ilGen.methName); + GetCallNo(curDeclFunc, actCallNo); + ilGen.Emit(curDeclFunc, OpCodes.Ldc_I4, nSaves); + ilGen.Emit(curDeclFunc, OpCodes.Call, captureStackFrameMethodInfo); + + if(DEBUG_STACKCAPRES) + { + ilGen.Emit(curDeclFunc, OpCodes.Ldstr, ilGen.methName + "*: capture mainCallNo="); + ilGen.Emit(curDeclFunc, OpCodes.Call, consoleWriteMethodInfo); + ilGen.Emit(curDeclFunc, OpCodes.Ldloc, actCallNo); + ilGen.Emit(curDeclFunc, OpCodes.Box, typeof(int)); + ilGen.Emit(curDeclFunc, OpCodes.Call, consoleWriteMethodInfo); + } + + // Copy arg values to object array, boxing as needed. + int i = 0; + foreach(TokenDeclVar argVar in curDeclFunc.argDecl.varDict) + { + ilGen.Emit(curDeclFunc, OpCodes.Dup); + ilGen.Emit(curDeclFunc, OpCodes.Ldc_I4, i); + argVar.location.PushVal(this, argVar.name, tokenTypeObj); + if(DEBUG_STACKCAPRES) + { + ilGen.Emit(curDeclFunc, OpCodes.Ldstr, "\n arg:" + argVar.name.val + "="); + ilGen.Emit(curDeclFunc, OpCodes.Call, consoleWriteMethodInfo); + ilGen.Emit(curDeclFunc, OpCodes.Dup); + ilGen.Emit(curDeclFunc, OpCodes.Call, consoleWriteMethodInfo); + } + ilGen.Emit(curDeclFunc, OpCodes.Stelem_Ref); + i++; + } + + // Copy local and temp values to object array, boxing as needed. + foreach(ScriptMyLocal lcl in activeTemps) + { + ilGen.Emit(curDeclFunc, OpCodes.Dup); + ilGen.Emit(curDeclFunc, OpCodes.Ldc_I4, i++); + ilGen.Emit(curDeclFunc, OpCodes.Ldloc, lcl); + Type t = lcl.type; + if(t == typeof(HeapTrackerList)) + { + t = HeapTrackerList.GenPush(curDeclFunc, ilGen); + } + if(t == typeof(HeapTrackerObject)) + { + t = HeapTrackerObject.GenPush(curDeclFunc, ilGen); + } + if(t == typeof(HeapTrackerString)) + { + t = HeapTrackerString.GenPush(curDeclFunc, ilGen); + } + if(t.IsValueType) + { + ilGen.Emit(curDeclFunc, OpCodes.Box, t); + } + if(DEBUG_STACKCAPRES) + { + ilGen.Emit(curDeclFunc, OpCodes.Ldstr, "\n lcl:" + lcl.name + "="); + ilGen.Emit(curDeclFunc, OpCodes.Call, consoleWriteMethodInfo); + ilGen.Emit(curDeclFunc, OpCodes.Dup); + ilGen.Emit(curDeclFunc, OpCodes.Call, consoleWriteMethodInfo); + } + ilGen.Emit(curDeclFunc, OpCodes.Stelem_Ref); + } + if(DEBUG_STACKCAPRES) + { + ilGen.Emit(curDeclFunc, OpCodes.Ldstr, "\n"); + ilGen.Emit(curDeclFunc, OpCodes.Call, consoleWriteMethodInfo); + } + + ilGen.Emit(curDeclFunc, OpCodes.Pop); + } + + /** + * @brief Generate code to restore all arguments and locals from the restore stack frame. + * This includes temp variables. + */ + private void GenerateFrameRestoreCode(List activeTemps) + { + ScriptMyLocal objArray = ilGen.DeclareLocal(typeof(object[]), "__restObjArray"); + + // Output code to pop stack frame from instance.stackFrames. + // It returns a pointer to the object array that contains values to be restored. + PushXMRInst(); + ilGen.Emit(curDeclFunc, OpCodes.Ldstr, ilGen.methName); + ilGen.Emit(curDeclFunc, OpCodes.Ldloca, actCallNo); // __mainCallNo + ilGen.Emit(curDeclFunc, OpCodes.Call, restoreStackFrameMethodInfo); + ilGen.Emit(curDeclFunc, OpCodes.Stloc, objArray); + if(DEBUG_STACKCAPRES) + { + ilGen.Emit(curDeclFunc, OpCodes.Ldstr, ilGen.methName + "*: restore mainCallNo="); + ilGen.Emit(curDeclFunc, OpCodes.Call, consoleWriteMethodInfo); + ilGen.Emit(curDeclFunc, OpCodes.Ldloc, actCallNo); + ilGen.Emit(curDeclFunc, OpCodes.Box, typeof(int)); + ilGen.Emit(curDeclFunc, OpCodes.Call, consoleWriteMethodInfo); + } + + // Restore argument values from object array, unboxing as needed. + // Although the caller has restored them to what it called us with, it's possible that this + // function has modified them since, so we need to do our own restore. + int i = 0; + foreach(TokenDeclVar argVar in curDeclFunc.argDecl.varDict) + { + CompValu argLoc = argVar.location; + argLoc.PopPre(this, argVar.name); + ilGen.Emit(curDeclFunc, OpCodes.Ldloc, objArray); + ilGen.Emit(curDeclFunc, OpCodes.Ldc_I4, i); + ilGen.Emit(curDeclFunc, OpCodes.Ldelem_Ref); + if(DEBUG_STACKCAPRES) + { + ilGen.Emit(curDeclFunc, OpCodes.Ldstr, "\n arg:" + argVar.name.val + "="); + ilGen.Emit(curDeclFunc, OpCodes.Call, consoleWriteMethodInfo); + ilGen.Emit(curDeclFunc, OpCodes.Dup); + ilGen.Emit(curDeclFunc, OpCodes.Call, consoleWriteMethodInfo); + } + TypeCast.CastTopOfStack(this, argVar.name, tokenTypeObj, argLoc.type, true); + argLoc.PopPost(this, argVar.name); + i++; + } + + // Restore local and temp values from object array, unboxing as needed. + foreach(ScriptMyLocal lcl in activeTemps) + { + Type t = lcl.type; + Type u = t; + if(t == typeof(HeapTrackerList)) + u = typeof(LSL_List); + if(t == typeof(HeapTrackerObject)) + u = typeof(object); + if(t == typeof(HeapTrackerString)) + u = typeof(string); + if(u != t) + { + ilGen.Emit(curDeclFunc, OpCodes.Ldloc, lcl); + } + ilGen.Emit(curDeclFunc, OpCodes.Ldloc, objArray); + ilGen.Emit(curDeclFunc, OpCodes.Ldc_I4, i++); + ilGen.Emit(curDeclFunc, OpCodes.Ldelem_Ref); + if(DEBUG_STACKCAPRES) + { + ilGen.Emit(curDeclFunc, OpCodes.Ldstr, "\n lcl:" + lcl.name + "="); + ilGen.Emit(curDeclFunc, OpCodes.Call, consoleWriteMethodInfo); + ilGen.Emit(curDeclFunc, OpCodes.Dup); + ilGen.Emit(curDeclFunc, OpCodes.Call, consoleWriteMethodInfo); + } + if(u.IsValueType) + { + ilGen.Emit(curDeclFunc, OpCodes.Unbox_Any, u); + } + else if(u != typeof(object)) + { + ilGen.Emit(curDeclFunc, OpCodes.Castclass, u); + } + if(u != t) + { + if(t == typeof(HeapTrackerList)) + HeapTrackerList.GenPop(curDeclFunc, ilGen); + if(t == typeof(HeapTrackerObject)) + HeapTrackerObject.GenPop(curDeclFunc, ilGen); + if(t == typeof(HeapTrackerString)) + HeapTrackerString.GenPop(curDeclFunc, ilGen); + } + else + { + ilGen.Emit(curDeclFunc, OpCodes.Stloc, lcl); + } + } + if(DEBUG_STACKCAPRES) + { + ilGen.Emit(curDeclFunc, OpCodes.Ldstr, "\n"); + ilGen.Emit(curDeclFunc, OpCodes.Call, consoleWriteMethodInfo); + } + + OutputCallNoSwitchStmt(); + } + + /** + * @brief Output a switch statement with a case for each possible + * value of whatever callNo is currently active, either + * __mainCallNo or one of the try/catch/finally's callNos. + * + * switch (callNo) { + * case 0: goto __call_0; + * case 1: goto __call_1; + * ... + * } + * throw new ScriptBadCallNoException (callNo); + */ + private void OutputCallNoSwitchStmt() + { + ScriptMyLabel[] callLabels = new ScriptMyLabel[actCallLabels.Count]; + foreach(CallLabel cl in actCallLabels) + { + callLabels[cl.index] = cl.callLabel; + } + GetCallNo(curDeclFunc, actCallNo); + ilGen.Emit(curDeclFunc, OpCodes.Switch, callLabels); + + GetCallNo(curDeclFunc, actCallNo); + ilGen.Emit(curDeclFunc, OpCodes.Newobj, scriptBadCallNoExceptionConstructorInfo); + ilGen.Emit(curDeclFunc, OpCodes.Throw); + } + + /** + * @brief There is one of these per call that can possibly call CheckRun(), + * including direct calls to CheckRun(). + * They mark points that the stack capture/restore code will save & restore to. + * All object-code level local vars active at the call label's point will + * be saved & restored. + * + * callNo = 5; + * __call_5: + * push call arguments from temps + * call SomethingThatCallsCheckRun() + * + * If SomethingThatCallsCheckRun() actually calls CheckRun(), our restore code + * will restore our args, locals & temps, then jump to __call_5, which will then + * call SomethingThatCallsCheckRun() again, which will restore its stuff likewise. + * When eventually the actual CheckRun() call is restored, it will turn off restore + * mode (by changing callMode from CallMode_RESTORE to CallMode_NORMAL) and return, + * allowing the code to run normally from that point. + */ + public class CallLabel + { + public int index; // sequential integer, starting at 0, within actCallLabels + // - used for the switch statement + public ScriptMyLabel callLabel; // the actual label token + + public CallLabel(ScriptCodeGen scg, Token errorAt) + { + if(scg.openCallLabel != null) + throw new Exception("call label already open"); + + if(!scg.curDeclFunc.IsFuncTrivial(scg)) + { + this.index = scg.actCallLabels.Count; + string name = "__call_" + index + "_" + scg.allCallLabels.Count; + + // Make sure eval stack is empty because the frame capture/restore + // code expects such (restore switch stmt has an empty stack). + int depth = ((ScriptCollector)scg.ilGen).stackDepth.Count; + if(depth > 0) + { + // maybe need to call Trivialize() + throw new Exception("call label stack depth " + depth + " at " + errorAt.SrcLoc); + } + + // Eval stack is empty so the restore code can handle it. + this.index = scg.actCallLabels.Count; + scg.actCallLabels.AddLast(this); + scg.allCallLabels.AddLast(this); + this.callLabel = scg.ilGen.DefineLabel(name); + scg.SetCallNo(errorAt, scg.actCallNo, this.index); + scg.ilGen.MarkLabel(this.callLabel); + } + + scg.openCallLabel = this; + } + }; + + /** + * @brief generate code for an arbitrary statement. + */ + private void GenerateStmt(TokenStmt stmt) + { + errorMessageToken = stmt; + if(stmt is TokenDeclVar) + { + GenerateDeclVar((TokenDeclVar)stmt); + return; + } + if(stmt is TokenStmtBlock) + { + GenerateStmtBlock((TokenStmtBlock)stmt); + return; + } + if(stmt is TokenStmtBreak) + { + GenerateStmtBreak((TokenStmtBreak)stmt); + return; + } + if(stmt is TokenStmtCont) + { + GenerateStmtCont((TokenStmtCont)stmt); + return; + } + if(stmt is TokenStmtDo) + { + GenerateStmtDo((TokenStmtDo)stmt); + return; + } + if(stmt is TokenStmtFor) + { + GenerateStmtFor((TokenStmtFor)stmt); + return; + } + if(stmt is TokenStmtForEach) + { + GenerateStmtForEach((TokenStmtForEach)stmt); + return; + } + if(stmt is TokenStmtIf) + { + GenerateStmtIf((TokenStmtIf)stmt); + return; + } + if(stmt is TokenStmtJump) + { + GenerateStmtJump((TokenStmtJump)stmt); + return; + } + if(stmt is TokenStmtLabel) + { + GenerateStmtLabel((TokenStmtLabel)stmt); + return; + } + if(stmt is TokenStmtNewobj) + { + GenerateStmtNewobj((TokenStmtNewobj)stmt); + return; + } + if(stmt is TokenStmtNull) + { + return; + } + if(stmt is TokenStmtRet) + { + GenerateStmtRet((TokenStmtRet)stmt); + return; + } + if(stmt is TokenStmtRVal) + { + GenerateStmtRVal((TokenStmtRVal)stmt); + return; + } + if(stmt is TokenStmtState) + { + GenerateStmtState((TokenStmtState)stmt); + return; + } + if(stmt is TokenStmtSwitch) + { + GenerateStmtSwitch((TokenStmtSwitch)stmt); + return; + } + if(stmt is TokenStmtThrow) + { + GenerateStmtThrow((TokenStmtThrow)stmt); + return; + } + if(stmt is TokenStmtTry) + { + GenerateStmtTry((TokenStmtTry)stmt); + return; + } + if(stmt is TokenStmtVarIniDef) + { + GenerateStmtVarIniDef((TokenStmtVarIniDef)stmt); + return; + } + if(stmt is TokenStmtWhile) + { + GenerateStmtWhile((TokenStmtWhile)stmt); + return; + } + throw new Exception("unknown TokenStmt type " + stmt.GetType().ToString()); + } + + /** + * @brief generate statement block (ie, with braces) + */ + private void GenerateStmtBlock(TokenStmtBlock stmtBlock) + { + if(!mightGetHere) + return; + + // Push new current statement block pointer for anyone who cares. + TokenStmtBlock oldStmtBlock = curStmtBlock; + curStmtBlock = stmtBlock; + + // Output the statements that make up the block. + for(Token t = stmtBlock.statements; t != null; t = t.nextToken) + { + GenerateStmt((TokenStmt)t); + } + + // Pop the current statement block. + curStmtBlock = oldStmtBlock; + } + + /** + * @brief output code for a 'break' statement + */ + private void GenerateStmtBreak(TokenStmtBreak breakStmt) + { + if(!mightGetHere) + return; + + // Make sure we are in a breakable situation. + if(curBreakTarg == null) + { + ErrorMsg(breakStmt, "not in a breakable situation"); + return; + } + + // Tell anyone who cares that the break target was actually used. + curBreakTarg.used = true; + + // Output the instructions. + EmitJumpCode(curBreakTarg.label, curBreakTarg.block, breakStmt); + } + + /** + * @brief output code for a 'continue' statement + */ + private void GenerateStmtCont(TokenStmtCont contStmt) + { + if(!mightGetHere) + return; + + // Make sure we are in a contable situation. + if(curContTarg == null) + { + ErrorMsg(contStmt, "not in a continueable situation"); + return; + } + + // Tell anyone who cares that the continue target was actually used. + curContTarg.used = true; + + // Output the instructions. + EmitJumpCode(curContTarg.label, curContTarg.block, contStmt); + } + + /** + * @brief output code for a 'do' statement + */ + private void GenerateStmtDo(TokenStmtDo doStmt) + { + if(!mightGetHere) + return; + + BreakContTarg oldBreakTarg = curBreakTarg; + BreakContTarg oldContTarg = curContTarg; + ScriptMyLabel loopLabel = ilGen.DefineLabel("doloop_" + doStmt.Unique); + + curBreakTarg = new BreakContTarg(this, "dobreak_" + doStmt.Unique); + curContTarg = new BreakContTarg(this, "docont_" + doStmt.Unique); + + ilGen.MarkLabel(loopLabel); + GenerateStmt(doStmt.bodyStmt); + if(curContTarg.used) + { + ilGen.MarkLabel(curContTarg.label); + mightGetHere = true; + } + + if(mightGetHere) + { + EmitCallCheckRun(doStmt, false); + CompValu testRVal = GenerateFromRVal(doStmt.testRVal); + if(IsConstBoolExprTrue(testRVal)) + { + // Unconditional looping, unconditional branch and + // say we never fall through to next statement. + ilGen.Emit(doStmt, OpCodes.Br, loopLabel); + mightGetHere = false; + } + else + { + // Conditional looping, test and brach back to top of loop. + testRVal.PushVal(this, doStmt.testRVal, tokenTypeBool); + ilGen.Emit(doStmt, OpCodes.Brtrue, loopLabel); + } + } + + // If 'break' statement was used, output target label. + // And assume that since a 'break' statement was used, it's possible for the code to get here. + if(curBreakTarg.used) + { + ilGen.MarkLabel(curBreakTarg.label); + mightGetHere = true; + } + + curBreakTarg = oldBreakTarg; + curContTarg = oldContTarg; + } + + /** + * @brief output code for a 'for' statement + */ + private void GenerateStmtFor(TokenStmtFor forStmt) + { + if(!mightGetHere) + return; + + BreakContTarg oldBreakTarg = curBreakTarg; + BreakContTarg oldContTarg = curContTarg; + ScriptMyLabel loopLabel = ilGen.DefineLabel("forloop_" + forStmt.Unique); + + curBreakTarg = new BreakContTarg(this, "forbreak_" + forStmt.Unique); + curContTarg = new BreakContTarg(this, "forcont_" + forStmt.Unique); + + if(forStmt.initStmt != null) + { + GenerateStmt(forStmt.initStmt); + } + ilGen.MarkLabel(loopLabel); + + // See if we have a test expression that is other than a constant TRUE. + // If so, test it and conditionally branch to end if false. + if(forStmt.testRVal != null) + { + CompValu testRVal = GenerateFromRVal(forStmt.testRVal); + if(!IsConstBoolExprTrue(testRVal)) + { + testRVal.PushVal(this, forStmt.testRVal, tokenTypeBool); + ilGen.Emit(forStmt, OpCodes.Brfalse, curBreakTarg.label); + curBreakTarg.used = true; + } + } + + // Output loop body. + GenerateStmt(forStmt.bodyStmt); + + // Here's where a 'continue' statement jumps to. + if(curContTarg.used) + { + ilGen.MarkLabel(curContTarg.label); + mightGetHere = true; + } + + if(mightGetHere) + { + // After checking for excessive CPU time, output increment statement, if any. + EmitCallCheckRun(forStmt, false); + if(forStmt.incrRVal != null) + { + GenerateFromRVal(forStmt.incrRVal); + } + + // Unconditional branch back to beginning of loop. + ilGen.Emit(forStmt, OpCodes.Br, loopLabel); + } + + // If test needs label, output label for it to jump to. + // Otherwise, clear mightGetHere as we know loop never + // falls out the bottom. + mightGetHere = curBreakTarg.used; + if(mightGetHere) + { + ilGen.MarkLabel(curBreakTarg.label); + } + + curBreakTarg = oldBreakTarg; + curContTarg = oldContTarg; + } + + private void GenerateStmtForEach(TokenStmtForEach forEachStmt) + { + if(!mightGetHere) + return; + + BreakContTarg oldBreakTarg = curBreakTarg; + BreakContTarg oldContTarg = curContTarg; + CompValu keyLVal = null; + CompValu valLVal = null; + CompValu arrayRVal = GenerateFromRVal(forEachStmt.arrayRVal); + + if(forEachStmt.keyLVal != null) + { + keyLVal = GenerateFromLVal(forEachStmt.keyLVal); + if(!(keyLVal.type is TokenTypeObject)) + { + ErrorMsg(forEachStmt.arrayRVal, "must be object"); + } + } + if(forEachStmt.valLVal != null) + { + valLVal = GenerateFromLVal(forEachStmt.valLVal); + if(!(valLVal.type is TokenTypeObject)) + { + ErrorMsg(forEachStmt.arrayRVal, "must be object"); + } + } + if(!(arrayRVal.type is TokenTypeArray)) + { + ErrorMsg(forEachStmt.arrayRVal, "must be an array"); + } + + curBreakTarg = new BreakContTarg(this, "foreachbreak_" + forEachStmt.Unique); + curContTarg = new BreakContTarg(this, "foreachcont_" + forEachStmt.Unique); + + CompValuTemp indexVar = new CompValuTemp(new TokenTypeInt(forEachStmt), this); + ScriptMyLabel loopLabel = ilGen.DefineLabel("foreachloop_" + forEachStmt.Unique); + + // indexVar = 0 + ilGen.Emit(forEachStmt, OpCodes.Ldc_I4_0); + indexVar.Pop(this, forEachStmt); + + ilGen.MarkLabel(loopLabel); + + // key = array.__pub_index (indexVar); + // if (key == null) goto curBreakTarg; + if(keyLVal != null) + { + keyLVal.PopPre(this, forEachStmt.keyLVal); + arrayRVal.PushVal(this, forEachStmt.arrayRVal); + indexVar.PushVal(this, forEachStmt); + ilGen.Emit(forEachStmt, OpCodes.Call, xmrArrPubIndexMethod); + keyLVal.PopPost(this, forEachStmt.keyLVal); + keyLVal.PushVal(this, forEachStmt.keyLVal); + ilGen.Emit(forEachStmt, OpCodes.Brfalse, curBreakTarg.label); + curBreakTarg.used = true; + } + + // val = array._pub_value (indexVar); + // if (val == null) goto curBreakTarg; + if(valLVal != null) + { + valLVal.PopPre(this, forEachStmt.valLVal); + arrayRVal.PushVal(this, forEachStmt.arrayRVal); + indexVar.PushVal(this, forEachStmt); + ilGen.Emit(forEachStmt, OpCodes.Call, xmrArrPubValueMethod); + valLVal.PopPost(this, forEachStmt.valLVal); + if(keyLVal == null) + { + valLVal.PushVal(this, forEachStmt.valLVal); + ilGen.Emit(forEachStmt, OpCodes.Brfalse, curBreakTarg.label); + curBreakTarg.used = true; + } + } + + // indexVar ++; + indexVar.PushVal(this, forEachStmt); + ilGen.Emit(forEachStmt, OpCodes.Ldc_I4_1); + ilGen.Emit(forEachStmt, OpCodes.Add); + indexVar.Pop(this, forEachStmt); + + // body statement + GenerateStmt(forEachStmt.bodyStmt); + + // continue label + if(curContTarg.used) + { + ilGen.MarkLabel(curContTarg.label); + mightGetHere = true; + } + + // call CheckRun() + if(mightGetHere) + { + EmitCallCheckRun(forEachStmt, false); + ilGen.Emit(forEachStmt, OpCodes.Br, loopLabel); + } + + // break label + ilGen.MarkLabel(curBreakTarg.label); + mightGetHere = true; + + curBreakTarg = oldBreakTarg; + curContTarg = oldContTarg; + } + + /** + * @brief output code for an 'if' statement + * Braces are necessary because what may be one statement for trueStmt or elseStmt in + * the script may translate to more than one statement in the resultant C# code. + */ + private void GenerateStmtIf(TokenStmtIf ifStmt) + { + if(!mightGetHere) + return; + + bool constVal; + + // Test condition and see if constant test expression. + CompValu testRVal = GenerateFromRVal(ifStmt.testRVal); + if(IsConstBoolExpr(testRVal, out constVal)) + { + // Constant, output just either the true or else part. + if(constVal) + { + GenerateStmt(ifStmt.trueStmt); + } + else if(ifStmt.elseStmt != null) + { + GenerateStmt(ifStmt.elseStmt); + } + } + else if(ifStmt.elseStmt == null) + { + // This is an 'if' statement without an 'else' clause. + testRVal.PushVal(this, ifStmt.testRVal, tokenTypeBool); + ScriptMyLabel doneLabel = ilGen.DefineLabel("ifdone_" + ifStmt.Unique); + ilGen.Emit(ifStmt, OpCodes.Brfalse, doneLabel); // brfalse doneLabel + GenerateStmt(ifStmt.trueStmt); // generate true body code + ilGen.MarkLabel(doneLabel); + mightGetHere = true; // there's always a possibility of getting here + } + else + { + // This is an 'if' statement with an 'else' clause. + testRVal.PushVal(this, ifStmt.testRVal, tokenTypeBool); + ScriptMyLabel elseLabel = ilGen.DefineLabel("ifelse_" + ifStmt.Unique); + ilGen.Emit(ifStmt, OpCodes.Brfalse, elseLabel); // brfalse elseLabel + GenerateStmt(ifStmt.trueStmt); // generate true body code + bool trueMightGetHere = mightGetHere; // save whether or not true falls through + ScriptMyLabel doneLabel = ilGen.DefineLabel("ifdone_" + ifStmt.Unique); + ilGen.Emit(ifStmt, OpCodes.Br, doneLabel); // branch to done + ilGen.MarkLabel(elseLabel); // beginning of else code + mightGetHere = true; // the top of the else might be executed + GenerateStmt(ifStmt.elseStmt); // output else code + ilGen.MarkLabel(doneLabel); // where end of true clause code branches to + mightGetHere |= trueMightGetHere; // gets this far if either true or else falls through + } + } + + /** + * @brief output code for a 'jump' statement + */ + private void GenerateStmtJump(TokenStmtJump jumpStmt) + { + if(!mightGetHere) + return; + + // Make sure the target label is defined somewhere in the function. + TokenStmtLabel stmtLabel; + if(!curDeclFunc.labels.TryGetValue(jumpStmt.label.val, out stmtLabel)) + { + ErrorMsg(jumpStmt, "undefined label " + jumpStmt.label.val); + return; + } + if(!stmtLabel.labelTagged) + { + stmtLabel.labelStruct = ilGen.DefineLabel("jump_" + stmtLabel.name.val); + stmtLabel.labelTagged = true; + } + + // Emit instructions to do the jump. + EmitJumpCode(stmtLabel.labelStruct, stmtLabel.block, jumpStmt); + } + + /** + * @brief Emit code to jump to a label + * @param target = label being jumped to + * @param targetsBlock = { ... } the label is defined in + */ + private void EmitJumpCode(ScriptMyLabel target, TokenStmtBlock targetsBlock, Token errorAt) + { + // Jumps never fall through. + + mightGetHere = false; + + // Find which block the target label is in. Must be in this or an outer block, + // no laterals allowed. And if we exit a try/catch block, use Leave instead of Br. + // + // jump lateral; + // { + // @lateral; + // } + bool useLeave = false; + TokenStmtBlock stmtBlock; + Stack finallyBlocksCalled = new Stack(); + for(stmtBlock = curStmtBlock; stmtBlock != targetsBlock; stmtBlock = stmtBlock.outerStmtBlock) + { + if(stmtBlock == null) + { + ErrorMsg(errorAt, "no lateral jumps allowed"); + return; + } + if(stmtBlock.isFinally) + { + ErrorMsg(errorAt, "cannot jump out of finally"); + return; + } + if(stmtBlock.isTry || stmtBlock.isCatch) + useLeave = true; + if((stmtBlock.tryStmt != null) && (stmtBlock.tryStmt.finallyStmt != null)) + { + finallyBlocksCalled.Push(stmtBlock.tryStmt); + } + } + + // If popping through more than one finally block, we have to break it down for the stack + // capture and restore code, one finally block at a time. + // + // try { + // try { + // try { + // jump exit; + // } finally { + // llOwnerSay ("exiting inner"); + // } + // } finally { + // llOwnerSay ("exiting middle"); + // } + // } finally { + // llOwnerSay ("exiting outer"); + // } + // @exit; + // + // try { + // try { + // try { + // jump intr2_exit; <<< gets its own tryNo call label so inner try knows where to restore to + // } finally { + // llOwnerSay ("exiting inner"); + // } + // jump outtry2; + // @intr2_exit; jump intr1_exit; <<< gets its own tryNo call label so middle try knows where to restore to + // @outtry2; + // } finally { + // llOwnerSay ("exiting middle"); + // } + // jump outtry1; + // @intr1_exit: jump exit; <<< gets its own tryNo call label so outer try knows where to restore to + // @outtry1; + // } finally { + // llOwnerSay ("exiting outer"); + // } + // @exit; + int level = 0; + while(finallyBlocksCalled.Count > 1) + { + TokenStmtTry finallyBlock = finallyBlocksCalled.Pop(); + string intername = "intr" + (++level) + "_" + target.name; + IntermediateLeave iLeave; + if(!finallyBlock.iLeaves.TryGetValue(intername, out iLeave)) + { + iLeave = new IntermediateLeave(); + iLeave.jumpIntoLabel = ilGen.DefineLabel(intername); + iLeave.jumpAwayLabel = target; + finallyBlock.iLeaves.Add(intername, iLeave); + } + target = iLeave.jumpIntoLabel; + } + + // Finally output the branch/leave opcode. + // If using Leave, prefix with a call label in case the corresponding finally block + // calls CheckRun() and that CheckRun() captures the stack, it will have a point to + // restore to that will properly jump back into the finally block. + if(useLeave) + { + new CallLabel(this, errorAt); + ilGen.Emit(errorAt, OpCodes.Leave, target); + openCallLabel = null; + } + else + { + ilGen.Emit(errorAt, OpCodes.Br, target); + } + } + + /** + * @brief output code for a jump target label statement. + * If there are any backward jumps to the label, do a CheckRun() also. + */ + private void GenerateStmtLabel(TokenStmtLabel labelStmt) + { + if(!labelStmt.labelTagged) + { + labelStmt.labelStruct = ilGen.DefineLabel("jump_" + labelStmt.name.val); + labelStmt.labelTagged = true; + } + ilGen.MarkLabel(labelStmt.labelStruct); + if(labelStmt.hasBkwdRefs) + { + EmitCallCheckRun(labelStmt, false); + } + + // We are going to say that the label falls through. + // It would be nice if we could analyze all referencing + // goto's to see if all of them are not used but we are + // going to assume that if the script writer put a label + // somewhere, it is probably going to be used. + mightGetHere = true; + } + + /** + * @brief Generate code for a script-defined type's .$new() method. + * It is used to malloc the object and initialize it. + * It is defined as a script-defined type static method, so the object level + * method gets the XMRInstance pointer passed as arg 0, and the method is + * supposed to return the allocated and constructed XMRSDTypeClObj + * object pointer. + */ + private void GenerateStmtNewobj(TokenStmtNewobj newobjStmt) + { + // First off, malloc a new empty XMRSDTypeClObj object + // then call the XMRSDTypeClObj()-level constructor. + // Store the result in local var $objptr. + newobjStmt.objptrVar.location.PopPre(this, newobjStmt); + ilGen.Emit(newobjStmt, OpCodes.Ldarg_0); + ilGen.Emit(newobjStmt, OpCodes.Ldc_I4, curDeclFunc.sdtClass.sdTypeIndex); + ilGen.Emit(newobjStmt, OpCodes.Newobj, sdtClassConstructorInfo); + newobjStmt.objptrVar.location.PopPost(this, newobjStmt); + + // Now call the script-level constructor. + // Pass the object pointer in $objptr as it's 'this' argument. + // The rest of the args are the script-visible args and are just copied from $new() call. + GenerateFromRValCall(newobjStmt.rValCall); + + // Put object pointer in retval so it gets returned to caller. + newobjStmt.objptrVar.location.PushVal(this, newobjStmt); + ilGen.Emit(newobjStmt, OpCodes.Stloc, retValue); + + // Exit the function like a return statement. + // And thus we don't fall through. + ilGen.Emit(newobjStmt, OpCodes.Leave, retLabel); + mightGetHere = false; + } + + /** + * @brief output code for a return statement. + * @param retStmt = return statement token, including return value if any + */ + private void GenerateStmtRet(TokenStmtRet retStmt) + { + if(!mightGetHere) + return; + + for(TokenStmtBlock stmtBlock = curStmtBlock; stmtBlock != null; stmtBlock = stmtBlock.outerStmtBlock) + { + if(stmtBlock.isFinally) + { + ErrorMsg(retStmt, "cannot return out of finally"); + return; + } + } + + if(curDeclFunc.retType is TokenTypeVoid) + { + if(retStmt.rVal != null) + { + ErrorMsg(retStmt, "function returns void, no value allowed"); + return; + } + } + else + { + if(retStmt.rVal == null) + { + ErrorMsg(retStmt, "function requires return value type " + curDeclFunc.retType.ToString()); + return; + } + CompValu rVal = GenerateFromRVal(retStmt.rVal); + rVal.PushVal(this, retStmt.rVal, curDeclFunc.retType); + ilGen.Emit(retStmt, OpCodes.Stloc, retValue); + } + + // Use a OpCodes.Leave instruction to break out of any try { } blocks. + // All Leave's inside script-defined try { } need call labels (see GenerateStmtTry()). + bool brokeOutOfTry = false; + for(TokenStmtBlock stmtBlock = curStmtBlock; stmtBlock != null; stmtBlock = stmtBlock.outerStmtBlock) + { + if(stmtBlock.isTry) + { + brokeOutOfTry = true; + break; + } + } + if(brokeOutOfTry) + new CallLabel(this, retStmt); + ilGen.Emit(retStmt, OpCodes.Leave, retLabel); + if(brokeOutOfTry) + openCallLabel = null; + + // 'return' statements never fall through. + mightGetHere = false; + } + + /** + * @brief the statement is just an expression, most likely an assignment or a ++ or -- thing. + */ + private void GenerateStmtRVal(TokenStmtRVal rValStmt) + { + if(!mightGetHere) + return; + + GenerateFromRVal(rValStmt.rVal); + } + + /** + * @brief generate code for a 'state' statement that transitions state. + * It sets the new state by throwing a ScriptChangeStateException. + */ + private void GenerateStmtState(TokenStmtState stateStmt) + { + if(!mightGetHere) + return; + + int index = 0; // 'default' state + + // Set new state value by throwing an exception. + // These exceptions aren't catchable by script-level try { } catch { }. + if((stateStmt.state != null) && !stateIndices.TryGetValue(stateStmt.state.val, out index)) + { + // The moron XEngine compiles scripts that reference undefined states. + // So rather than produce a compile-time error, we'll throw an exception at runtime. + // ErrorMsg (stateStmt, "undefined state " + stateStmt.state.val); + + // throw new UndefinedStateException (stateStmt.state.val); + ilGen.Emit(stateStmt, OpCodes.Ldstr, stateStmt.state.val); + ilGen.Emit(stateStmt, OpCodes.Newobj, scriptUndefinedStateExceptionConstructorInfo); + } + else + { + ilGen.Emit(stateStmt, OpCodes.Ldc_I4, index); // new state's index + ilGen.Emit(stateStmt, OpCodes.Newobj, scriptChangeStateExceptionConstructorInfo); + } + ilGen.Emit(stateStmt, OpCodes.Throw); + + // 'state' statements never fall through. + mightGetHere = false; + } + + /** + * @brief output code for a 'switch' statement + */ + private void GenerateStmtSwitch(TokenStmtSwitch switchStmt) + { + if(!mightGetHere) + return; + + // Output code to calculate index. + CompValu testRVal = GenerateFromRVal(switchStmt.testRVal); + + // Generate code based on string or integer index. + if((testRVal.type is TokenTypeKey) || (testRVal.type is TokenTypeStr)) + GenerateStmtSwitchStr(testRVal, switchStmt); + else + GenerateStmtSwitchInt(testRVal, switchStmt); + } + + private void GenerateStmtSwitchInt(CompValu testRVal, TokenStmtSwitch switchStmt) + { + testRVal.PushVal(this, switchStmt.testRVal, tokenTypeInt); + + BreakContTarg oldBreakTarg = curBreakTarg; + ScriptMyLabel defaultLabel = null; + TokenSwitchCase sortedCases = null; + TokenSwitchCase defaultCase = null; + + curBreakTarg = new BreakContTarg(this, "switchbreak_" + switchStmt.Unique); + + // Build list of cases sorted by ascending values. + // There should not be any overlapping of values. + for(TokenSwitchCase thisCase = switchStmt.cases; thisCase != null; thisCase = thisCase.nextCase) + { + thisCase.label = ilGen.DefineLabel("case_" + thisCase.Unique); + + // The default case if any, goes in its own separate slot. + if(thisCase.rVal1 == null) + { + if(defaultCase != null) + { + ErrorMsg(thisCase, "only one default case allowed"); + ErrorMsg(defaultCase, "...prior default case"); + return; + } + defaultCase = thisCase; + defaultLabel = thisCase.label; + continue; + } + + // Evaluate case operands, they must be compile-time integer constants. + CompValu rVal = GenerateFromRVal(thisCase.rVal1); + if(!IsConstIntExpr(rVal, out thisCase.val1)) + { + ErrorMsg(thisCase.rVal1, "must be compile-time char or integer constant"); + return; + } + thisCase.val2 = thisCase.val1; + if(thisCase.rVal2 != null) + { + rVal = GenerateFromRVal(thisCase.rVal2); + if(!IsConstIntExpr(rVal, out thisCase.val2)) + { + ErrorMsg(thisCase.rVal2, "must be compile-time char or integer constant"); + return; + } + } + if(thisCase.val2 < thisCase.val1) + { + ErrorMsg(thisCase.rVal2, "must be .ge. first value for the case"); + return; + } + + // Insert into list, sorted by value. + // Note that both limits are inclusive. + TokenSwitchCase lastCase = null; + TokenSwitchCase nextCase; + for(nextCase = sortedCases; nextCase != null; nextCase = nextCase.nextSortedCase) + { + if(nextCase.val1 > thisCase.val2) + break; + if(nextCase.val2 >= thisCase.val1) + { + ErrorMsg(thisCase, "value used by previous case"); + ErrorMsg(nextCase, "...previous case"); + return; + } + lastCase = nextCase; + } + thisCase.nextSortedCase = nextCase; + if(lastCase == null) + { + sortedCases = thisCase; + } + else + { + lastCase.nextSortedCase = thisCase; + } + } + + if(defaultLabel == null) + { + defaultLabel = ilGen.DefineLabel("default_" + switchStmt.Unique); + } + + // Output code to jump to the case statement's labels based on integer index on stack. + // Note that each case still has the integer index on stack when jumped to. + int offset = 0; + for(TokenSwitchCase thisCase = sortedCases; thisCase != null;) + { + // Scan through list of cases to find the maximum number of cases who's numvalues-to-case ratio + // is from 0.5 to 2.0. If such a group is found, use a CIL switch for them. If not, just use a + // compare-and-branch for the current case. + int numCases = 0; + int numFound = 0; + int lowValue = thisCase.val1; + int numValues = 0; + for(TokenSwitchCase scanCase = thisCase; scanCase != null; scanCase = scanCase.nextSortedCase) + { + int nVals = scanCase.val2 - thisCase.val1 + 1; + double ratio = (double)nVals / (double)(++numCases); + if((ratio >= 0.5) && (ratio <= 2.0)) + { + numFound = numCases; + numValues = nVals; + } + } + if(numFound > 1) + { + // There is a group of case's, starting with thisCase, that fall within our criteria, ie, + // that have a nice density of meaningful jumps. + // + // So first generate an array of jumps to the default label (explicit or implicit). + ScriptMyLabel[] labels = new ScriptMyLabel[numValues]; + for(int i = 0; i < numValues; i++) + { + labels[i] = defaultLabel; + } + + // Next, for each case in that group, fill in the corresponding array entries to jump to + // that case's label. + do + { + for(int i = thisCase.val1; i <= thisCase.val2; i++) + { + labels[i - lowValue] = thisCase.label; + } + thisCase = thisCase.nextSortedCase; + } while(--numFound > 0); + + // Subtract the low value and do the computed jump. + // The OpCodes.Switch falls through if out of range (unsigned compare). + if(offset != lowValue) + { + ilGen.Emit(switchStmt, OpCodes.Ldc_I4, lowValue - offset); + ilGen.Emit(switchStmt, OpCodes.Sub); + offset = lowValue; + } + ilGen.Emit(switchStmt, OpCodes.Dup); + ilGen.Emit(switchStmt, OpCodes.Switch, labels); + } + else + { + // It's not economical to do with a computed jump, so output a subtract/compare/branch + // for thisCase. + if(lowValue == thisCase.val2) + { + ilGen.Emit(switchStmt, OpCodes.Dup); + ilGen.Emit(switchStmt, OpCodes.Ldc_I4, lowValue - offset); + ilGen.Emit(switchStmt, OpCodes.Beq, thisCase.label); + } + else + { + if(offset != lowValue) + { + ilGen.Emit(switchStmt, OpCodes.Ldc_I4, lowValue - offset); + ilGen.Emit(switchStmt, OpCodes.Sub); + offset = lowValue; + } + ilGen.Emit(switchStmt, OpCodes.Dup); + ilGen.Emit(switchStmt, OpCodes.Ldc_I4, thisCase.val2 - offset); + ilGen.Emit(switchStmt, OpCodes.Ble_Un, thisCase.label); + } + thisCase = thisCase.nextSortedCase; + } + } + ilGen.Emit(switchStmt, OpCodes.Br, defaultLabel); + + // Output code for the cases themselves, in the order given by the programmer, + // so they fall through as programmer wants. This includes the default case, if any. + // + // Each label is jumped to with the index still on the stack. So pop it off in case + // the case body does a goto outside the switch or a return. If the case body might + // fall through to the next case or the bottom of the switch, push a zero so the stack + // matches in all cases. + for(TokenSwitchCase thisCase = switchStmt.cases; thisCase != null; thisCase = thisCase.nextCase) + { + ilGen.MarkLabel(thisCase.label); // the branch comes here + ilGen.Emit(thisCase, OpCodes.Pop); // pop the integer index off stack + mightGetHere = true; // it's possible to get here + for(TokenStmt stmt = thisCase.stmts; stmt != null; stmt = (TokenStmt)(stmt.nextToken)) + { + GenerateStmt(stmt); // output the case/explicit default body + } + if(mightGetHere) + { + ilGen.Emit(thisCase, OpCodes.Ldc_I4_0); + // in case we fall through, push a dummy integer index + } + } + + // If no explicit default case, output the default label here. + if(defaultCase == null) + { + ilGen.MarkLabel(defaultLabel); + mightGetHere = true; + } + + // If the last case of the switch falls through out the bottom, + // we have to pop the index still on the stack. + if(mightGetHere) + { + ilGen.Emit(switchStmt, OpCodes.Pop); + } + + // Output the 'break' statement target label. + // Note that the integer index is not on the stack at this point. + if(curBreakTarg.used) + { + ilGen.MarkLabel(curBreakTarg.label); + mightGetHere = true; + } + + curBreakTarg = oldBreakTarg; + } + + private void GenerateStmtSwitchStr(CompValu testRVal, TokenStmtSwitch switchStmt) + { + BreakContTarg oldBreakTarg = curBreakTarg; + ScriptMyLabel defaultLabel = null; + TokenSwitchCase caseTreeTop = null; + TokenSwitchCase defaultCase = null; + + curBreakTarg = new BreakContTarg(this, "switchbreak_" + switchStmt.Unique); + + // Make sure value is in a temp so we don't compute it more than once. + if(!(testRVal is CompValuTemp)) + { + CompValuTemp temp = new CompValuTemp(testRVal.type, this); + testRVal.PushVal(this, switchStmt); + temp.Pop(this, switchStmt); + testRVal = temp; + } + + // Build tree of cases. + // There should not be any overlapping of values. + for(TokenSwitchCase thisCase = switchStmt.cases; thisCase != null; thisCase = thisCase.nextCase) + { + thisCase.label = ilGen.DefineLabel("case"); + + // The default case if any, goes in its own separate slot. + if(thisCase.rVal1 == null) + { + if(defaultCase != null) + { + ErrorMsg(thisCase, "only one default case allowed"); + ErrorMsg(defaultCase, "...prior default case"); + return; + } + defaultCase = thisCase; + defaultLabel = thisCase.label; + continue; + } + + // Evaluate case operands, they must be compile-time string constants. + CompValu rVal = GenerateFromRVal(thisCase.rVal1); + if(!IsConstStrExpr(rVal, out thisCase.str1)) + { + ErrorMsg(thisCase.rVal1, "must be compile-time string constant"); + continue; + } + thisCase.str2 = thisCase.str1; + if(thisCase.rVal2 != null) + { + rVal = GenerateFromRVal(thisCase.rVal2); + if(!IsConstStrExpr(rVal, out thisCase.str2)) + { + ErrorMsg(thisCase.rVal2, "must be compile-time string constant"); + continue; + } + } + if(String.Compare(thisCase.str2, thisCase.str1, StringComparison.Ordinal) < 0) + { + ErrorMsg(thisCase.rVal2, "must be .ge. first value for the case"); + continue; + } + + // Insert into list, sorted by value. + // Note that both limits are inclusive. + caseTreeTop = InsertCaseInTree(caseTreeTop, thisCase); + } + + // Balance tree so we end up generating code that does O(log2 n) comparisons. + caseTreeTop = BalanceTree(caseTreeTop); + + // Output compare and branch instructions in a tree-like fashion so we do O(log2 n) comparisons. + if(defaultLabel == null) + { + defaultLabel = ilGen.DefineLabel("default"); + } + OutputStrCase(testRVal, caseTreeTop, defaultLabel); + + // Output code for the cases themselves, in the order given by the programmer, + // so they fall through as programmer wants. This includes the default case, if any. + for(TokenSwitchCase thisCase = switchStmt.cases; thisCase != null; thisCase = thisCase.nextCase) + { + ilGen.MarkLabel(thisCase.label); // the branch comes here + mightGetHere = true; // it's possible to get here + for(TokenStmt stmt = thisCase.stmts; stmt != null; stmt = (TokenStmt)(stmt.nextToken)) + { + GenerateStmt(stmt); // output the case/explicit default body + } + } + + // If no explicit default case, output the default label here. + if(defaultCase == null) + { + ilGen.MarkLabel(defaultLabel); + mightGetHere = true; + } + + // Output the 'break' statement target label. + if(curBreakTarg.used) + { + ilGen.MarkLabel(curBreakTarg.label); + mightGetHere = true; + } + + curBreakTarg = oldBreakTarg; + } + + /** + * @brief Insert a case in a tree of cases + * @param r = root of existing cases to insert into + * @param n = new case being inserted + * @returns new root with new case inserted + */ + private TokenSwitchCase InsertCaseInTree(TokenSwitchCase r, TokenSwitchCase n) + { + if(r == null) + return n; + + TokenSwitchCase t = r; + while(true) + { + if(String.Compare(n.str2, t.str1, StringComparison.Ordinal) < 0) + { + if(t.lowerCase == null) + { + t.lowerCase = n; + break; + } + t = t.lowerCase; + continue; + } + if(String.Compare(n.str1, t.str2, StringComparison.Ordinal) > 0) + { + if(t.higherCase == null) + { + t.higherCase = n; + break; + } + t = t.higherCase; + continue; + } + ErrorMsg(n, "duplicate case"); + ErrorMsg(r, "...duplicate of"); + break; + } + return r; + } + + /** + * @brief Balance a tree so left & right halves contain same number within +-1 + * @param r = root of tree to balance + * @returns new root + */ + private static TokenSwitchCase BalanceTree(TokenSwitchCase r) + { + if(r == null) + return r; + + int lc = CountTree(r.lowerCase); + int hc = CountTree(r.higherCase); + TokenSwitchCase n, x; + + // If lower side is heavy, move highest nodes from lower side to + // higher side until balanced. + while(lc > hc + 1) + { + x = ExtractHighest(r.lowerCase, out n); + n.lowerCase = x; + n.higherCase = r; + r.lowerCase = null; + r = n; + lc--; + hc++; + } + + // If higher side is heavy, move lowest nodes from higher side to + // lower side until balanced. + while(hc > lc + 1) + { + x = ExtractLowest(r.higherCase, out n); + n.higherCase = x; + n.lowerCase = r; + r.higherCase = null; + r = n; + lc++; + hc--; + } + + // Now balance each side because they can be lopsided individually. + r.lowerCase = BalanceTree(r.lowerCase); + r.higherCase = BalanceTree(r.higherCase); + return r; + } + + /** + * @brief Get number of nodes in a tree + * @param n = root of tree to count + * @returns number of nodes including root + */ + private static int CountTree(TokenSwitchCase n) + { + if(n == null) + return 0; + return 1 + CountTree(n.lowerCase) + CountTree(n.higherCase); + } + + // Extract highest node from a tree + // @param r = root of tree to extract highest from + // @returns new root after node has been extracted + // n = node that was extracted from tree + private static TokenSwitchCase ExtractHighest(TokenSwitchCase r, out TokenSwitchCase n) + { + if(r.higherCase == null) + { + n = r; + return r.lowerCase; + } + r.higherCase = ExtractHighest(r.higherCase, out n); + return r; + } + + // Extract lowest node from a tree + // @param r = root of tree to extract lowest from + // @returns new root after node has been extracted + // n = node that was extracted from tree + private static TokenSwitchCase ExtractLowest(TokenSwitchCase r, out TokenSwitchCase n) + { + if(r.lowerCase == null) + { + n = r; + return r.higherCase; + } + r.lowerCase = ExtractLowest(r.lowerCase, out n); + return r; + } + + /** + * Output code for string-style case of a switch/case to jump to the script code associated with the case. + * @param testRVal = value being switched on + * @param thisCase = case that the code is being output for + * @param defaultLabel = where the default clause is (or past all cases if none) + * Note: + * Outputs code for this case and the lowerCase and higherCases if any. + * If no lowerCase or higherCase, outputs a br to defaultLabel so this code never falls through. + */ + private void OutputStrCase(CompValu testRVal, TokenSwitchCase thisCase, ScriptMyLabel defaultLabel) + { + // If nothing lower on tree and there is a single case value, + // just do one compare for equality. + if((thisCase.lowerCase == null) && (thisCase.higherCase == null) && (thisCase.str1 == thisCase.str2)) + { + testRVal.PushVal(this, thisCase, tokenTypeStr); + ilGen.Emit(thisCase, OpCodes.Ldstr, thisCase.str1); + ilGen.Emit(thisCase, OpCodes.Ldc_I4, (int)StringComparison.Ordinal); + ilGen.Emit(thisCase, OpCodes.Call, stringCompareMethodInfo); + ilGen.Emit(thisCase, OpCodes.Brfalse, thisCase.label); + ilGen.Emit(thisCase, OpCodes.Br, defaultLabel); + return; + } + + // Determine where to jump if switch value is lower than lower case value. + ScriptMyLabel lowerLabel = defaultLabel; + if(thisCase.lowerCase != null) + { + lowerLabel = ilGen.DefineLabel("lower"); + } + + // If single case value, put comparison result in this temp. + CompValuTemp cmpv1 = null; + if(thisCase.str1 == thisCase.str2) + { + cmpv1 = new CompValuTemp(tokenTypeInt, this); + } + + // If switch value .lt. lower case value, jump to lower label. + // Maybe save comparison result in a temp. + testRVal.PushVal(this, thisCase, tokenTypeStr); + ilGen.Emit(thisCase, OpCodes.Ldstr, thisCase.str1); + ilGen.Emit(thisCase, OpCodes.Ldc_I4, (int)StringComparison.Ordinal); + ilGen.Emit(thisCase, OpCodes.Call, stringCompareMethodInfo); + if(cmpv1 != null) + { + ilGen.Emit(thisCase, OpCodes.Dup); + cmpv1.Pop(this, thisCase); + } + ilGen.Emit(thisCase, OpCodes.Ldc_I4_0); + ilGen.Emit(thisCase, OpCodes.Blt, lowerLabel); + + // If switch value .le. higher case value, jump to case code. + // Maybe get comparison from the temp. + if(cmpv1 == null) + { + testRVal.PushVal(this, thisCase, tokenTypeStr); + ilGen.Emit(thisCase, OpCodes.Ldstr, thisCase.str2); + ilGen.Emit(thisCase, OpCodes.Ldc_I4, (int)StringComparison.Ordinal); + ilGen.Emit(thisCase, OpCodes.Call, stringCompareMethodInfo); + } + else + { + cmpv1.PushVal(this, thisCase); + } + ilGen.Emit(thisCase, OpCodes.Ldc_I4_0); + ilGen.Emit(thisCase, OpCodes.Ble, thisCase.label); + + // Output code for higher comparison if any. + if(thisCase.higherCase == null) + { + ilGen.Emit(thisCase, OpCodes.Br, defaultLabel); + } + else + { + OutputStrCase(testRVal, thisCase.higherCase, defaultLabel); + } + + // Output code for lower comparison if any. + if(thisCase.lowerCase != null) + { + ilGen.MarkLabel(lowerLabel); + OutputStrCase(testRVal, thisCase.lowerCase, defaultLabel); + } + } + + /** + * @brief output code for a throw statement. + * @param throwStmt = throw statement token, including value to be thrown + */ + private void GenerateStmtThrow(TokenStmtThrow throwStmt) + { + if(!mightGetHere) + return; + + // 'throw' statements never fall through. + mightGetHere = false; + + // Output code for either a throw or a rethrow. + if(throwStmt.rVal == null) + { + for(TokenStmtBlock blk = curStmtBlock; blk != null; blk = blk.outerStmtBlock) + { + if(curStmtBlock.isCatch) + { + ilGen.Emit(throwStmt, OpCodes.Rethrow); + return; + } + } + ErrorMsg(throwStmt, "rethrow allowed only in catch clause"); + } + else + { + CompValu rVal = GenerateFromRVal(throwStmt.rVal); + rVal.PushVal(this, throwStmt.rVal, tokenTypeObj); + ilGen.Emit(throwStmt, OpCodes.Call, thrownExceptionWrapMethodInfo); + ilGen.Emit(throwStmt, OpCodes.Throw); + } + } + + /** + * @brief output code for a try/catch/finally block + */ + private void GenerateStmtTry(TokenStmtTry tryStmt) + { + if(!mightGetHere) + return; + + /* + * Reducer should make sure we have exactly one of catch or finally. + */ + if((tryStmt.catchStmt == null) && (tryStmt.finallyStmt == null)) + { + throw new Exception("must have a catch or a finally on try"); + } + if((tryStmt.catchStmt != null) && (tryStmt.finallyStmt != null)) + { + throw new Exception("can't have both catch and finally on same try"); + } + + // Stack the call labels. + // Try blocks have their own series of call labels. + ScriptMyLocal saveCallNo = actCallNo; + LinkedList saveCallLabels = actCallLabels; + + // Generate code for either try { } catch { } or try { } finally { }. + if(tryStmt.catchStmt != null) + GenerateStmtTryCatch(tryStmt); + if(tryStmt.finallyStmt != null) + GenerateStmtTryFinally(tryStmt); + + // Restore call labels. + actCallNo = saveCallNo; + actCallLabels = saveCallLabels; + } + + + /** + * @brief output code for a try/catch block + * + * int __tryCallNo = -1; // call number within try { } subblock + * int __catCallNo = -1; // call number within catch { } subblock + * Exception __catThrown = null; // caught exception + * : // the outside world jumps here to restore us no matter ... + * try { // ... where we actually were inside of try/catch + * if (__tryCallNo >= 0) goto tryCallSw; // maybe go do restore + * // execute script-defined code + * // ...stack capture WILL run catch { } subblock + * leave tryEnd; // exits + * tryThrow:: + * throw new ScriptRestoreCatchException(__catThrown); // catch { } was running, jump to its beginning + * tryCallSw: // restoring... + * switch (__tryCallNo) back up into // not catching, jump back inside try + * } catch (Exception exc) { + * exc = ScriptRestoreCatchException.Unwrap(exc); // unwrap possible ScriptRestoreCatchException + * if (exc == null) goto catchRetro; // rethrow if IXMRUncatchable (eg, StackCaptureException) + * __catThrown = exc; // save what was thrown so restoring try { } will throw it again + * catchVar = exc; // set up script-visible variable + * __tryCallNo = tryThrow: + * if (__catCallNo >= 0) goto catchCallSw; // if restoring, go check below + * // normal, execute script-defined code + * leave tryEnd; // all done, exit catch { } + * catchRetro: + * rethrow; + * catchCallSw: + * switch (__catCallNo) back up into // restart catch { } code wherever it was + * } + * tryEnd: + */ + private void GenerateStmtTryCatch(TokenStmtTry tryStmt) + { + CompValuTemp tryCallNo = new CompValuTemp(tokenTypeInt, this); + CompValuTemp catCallNo = new CompValuTemp(tokenTypeInt, this); + CompValuTemp catThrown = new CompValuTemp(tokenTypeExc, this); + + ScriptMyLabel tryCallSw = ilGen.DefineLabel("__tryCallSw_" + tryStmt.Unique); + ScriptMyLabel catchRetro = ilGen.DefineLabel("__catchRetro_" + tryStmt.Unique); + ScriptMyLabel catchCallSw = ilGen.DefineLabel("__catchCallSw_" + tryStmt.Unique); + ScriptMyLabel tryEnd = ilGen.DefineLabel("__tryEnd_" + tryStmt.Unique); + + SetCallNo(tryStmt, tryCallNo, -1); + SetCallNo(tryStmt, catCallNo, -1); + ilGen.Emit(tryStmt, OpCodes.Ldnull); + catThrown.Pop(this, tryStmt); + + new CallLabel(this, tryStmt); // : + ilGen.BeginExceptionBlock(); // try { + openCallLabel = null; + if(DEBUG_TRYSTMT) + { + ilGen.Emit(tryStmt, OpCodes.Ldstr, "enter try*: " + tryStmt.line + " callMode="); + ilGen.Emit(tryStmt, OpCodes.Call, consoleWriteMethodInfo); + PushXMRInst(); + ilGen.Emit(tryStmt, OpCodes.Ldfld, callModeFieldInfo); + ilGen.Emit(tryStmt, OpCodes.Box, typeof(int)); + ilGen.Emit(tryStmt, OpCodes.Call, consoleWriteMethodInfo); + ilGen.Emit(tryStmt, OpCodes.Ldstr, " tryCallNo="); + ilGen.Emit(tryStmt, OpCodes.Call, consoleWriteMethodInfo); + tryCallNo.PushVal(this, tryStmt); + ilGen.Emit(tryStmt, OpCodes.Box, typeof(int)); + ilGen.Emit(tryStmt, OpCodes.Call, consoleWriteMethodInfo); + ilGen.Emit(tryStmt, OpCodes.Ldstr, " catThrown.IsNull="); + ilGen.Emit(tryStmt, OpCodes.Call, consoleWriteMethodInfo); + catThrown.PushVal(this, tryStmt); + ilGen.Emit(tryStmt, OpCodes.Ldnull); + ilGen.Emit(tryStmt, OpCodes.Ceq); + ilGen.Emit(tryStmt, OpCodes.Box, typeof(int)); + ilGen.Emit(tryStmt, OpCodes.Call, consoleWriteMethodInfo); + ilGen.Emit(tryStmt, OpCodes.Ldstr, " catCallNo="); + ilGen.Emit(tryStmt, OpCodes.Call, consoleWriteMethodInfo); + catCallNo.PushVal(this, tryStmt); + ilGen.Emit(tryStmt, OpCodes.Box, typeof(int)); + ilGen.Emit(tryStmt, OpCodes.Call, consoleWriteMethodInfo); + ilGen.Emit(tryStmt, OpCodes.Ldstr, "\n"); + ilGen.Emit(tryStmt, OpCodes.Call, consoleWriteMethodInfo); + } + + GetCallNo(tryStmt, tryCallNo); // if (__tryCallNo >= 0) goto tryCallSw; + ilGen.Emit(tryStmt, OpCodes.Ldc_I4_0); + ilGen.Emit(tryStmt, OpCodes.Bge, tryCallSw); + + actCallNo = tryCallNo.localBuilder; // set up __tryCallNo for call labels + actCallLabels = new LinkedList(); + + GenerateStmtBlock(tryStmt.tryStmt); // output the try block statement subblock + + bool tryBlockFallsOutBottom = mightGetHere; + if(tryBlockFallsOutBottom) + { + new CallLabel(this, tryStmt); // : + ilGen.Emit(tryStmt, OpCodes.Leave, tryEnd); // leave tryEnd; + openCallLabel = null; + } + + CallLabel tryThrow = new CallLabel(this, tryStmt); // tryThrow:: + if(DEBUG_TRYSTMT) + { + ilGen.Emit(tryStmt, OpCodes.Ldstr, "tryThrow*: " + tryStmt.line + " catThrown="); + ilGen.Emit(tryStmt, OpCodes.Call, consoleWriteMethodInfo); + catThrown.PushVal(this, tryStmt); + ilGen.Emit(tryStmt, OpCodes.Call, consoleWriteMethodInfo); + ilGen.Emit(tryStmt, OpCodes.Ldstr, "\n"); + ilGen.Emit(tryStmt, OpCodes.Call, consoleWriteMethodInfo); + } + catThrown.PushVal(this, tryStmt); // throw new ScriptRestoreCatchException (__catThrown); + ilGen.Emit(tryStmt, OpCodes.Newobj, scriptRestoreCatchExceptionConstructorInfo); + ilGen.Emit(tryStmt, OpCodes.Throw); + openCallLabel = null; + + ilGen.MarkLabel(tryCallSw); // tryCallSw: + if(DEBUG_TRYSTMT) + { + ilGen.Emit(tryStmt, OpCodes.Ldstr, "tryCallSw*: " + tryStmt.line + " tryCallNo="); + ilGen.Emit(tryStmt, OpCodes.Call, consoleWriteMethodInfo); + tryCallNo.PushVal(this, tryStmt); + ilGen.Emit(tryStmt, OpCodes.Box, typeof(int)); + ilGen.Emit(tryStmt, OpCodes.Call, consoleWriteMethodInfo); + ilGen.Emit(tryStmt, OpCodes.Ldstr, "\n"); + ilGen.Emit(tryStmt, OpCodes.Call, consoleWriteMethodInfo); + } + OutputCallNoSwitchStmt(); // switch (tryCallNo) ... + + CompValuLocalVar catchVarLocExc = null; + CompValuTemp catchVarLocStr = null; + + if(tryStmt.catchVar.type.ToSysType() == typeof(Exception)) + { + catchVarLocExc = new CompValuLocalVar(tryStmt.catchVar.type, tryStmt.catchVar.name.val, this); + } + else if(tryStmt.catchVar.type.ToSysType() == typeof(String)) + { + catchVarLocStr = new CompValuTemp(tryStmt.catchVar.type, this); + } + + ScriptMyLocal excLocal = ilGen.DeclareLocal(typeof(String), "catchstr_" + tryStmt.Unique); + + ilGen.BeginCatchBlock(typeof(Exception)); // start of the catch block that can catch any exception + if(DEBUG_TRYSTMT) + { + ilGen.Emit(tryStmt.catchStmt, OpCodes.Ldstr, "enter catch*: " + tryStmt.line + " callMode="); + ilGen.Emit(tryStmt.catchStmt, OpCodes.Call, consoleWriteMethodInfo); + PushXMRInst(); + ilGen.Emit(tryStmt.catchStmt, OpCodes.Ldfld, callModeFieldInfo); + ilGen.Emit(tryStmt.catchStmt, OpCodes.Box, typeof(int)); + ilGen.Emit(tryStmt.catchStmt, OpCodes.Call, consoleWriteMethodInfo); + ilGen.Emit(tryStmt.catchStmt, OpCodes.Ldstr, " catCallNo="); + ilGen.Emit(tryStmt.catchStmt, OpCodes.Call, consoleWriteMethodInfo); + catCallNo.PushVal(this, tryStmt); + ilGen.Emit(tryStmt.catchStmt, OpCodes.Box, typeof(int)); + ilGen.Emit(tryStmt.catchStmt, OpCodes.Call, consoleWriteMethodInfo); + ilGen.Emit(tryStmt.catchStmt, OpCodes.Ldstr, " exc="); + ilGen.Emit(tryStmt.catchStmt, OpCodes.Call, consoleWriteMethodInfo); + ilGen.Emit(tryStmt.catchStmt, OpCodes.Dup); + ilGen.Emit(tryStmt.catchStmt, OpCodes.Call, consoleWriteMethodInfo); + ilGen.Emit(tryStmt.catchStmt, OpCodes.Ldstr, "\n"); + ilGen.Emit(tryStmt.catchStmt, OpCodes.Call, consoleWriteMethodInfo); + } + ilGen.Emit(tryStmt.catchStmt, OpCodes.Call, scriptRestoreCatchExceptionUnwrap); + // exc = ScriptRestoreCatchException.Unwrap (exc); + ilGen.Emit(tryStmt.catchStmt, OpCodes.Dup); // rethrow if IXMRUncatchable (eg, StackCaptureException) + ilGen.Emit(tryStmt.catchStmt, OpCodes.Brfalse, catchRetro); + if(tryStmt.catchVar.type.ToSysType() == typeof(Exception)) + { + tryStmt.catchVar.location = catchVarLocExc; + ilGen.Emit(tryStmt.catchStmt, OpCodes.Dup); + catThrown.Pop(this, tryStmt); // store exception object in catThrown + catchVarLocExc.Pop(this, tryStmt.catchVar.name); // also store in script-visible variable + } + else if(tryStmt.catchVar.type.ToSysType() == typeof(String)) + { + tryStmt.catchVar.location = catchVarLocStr; + ilGen.Emit(tryStmt.catchStmt, OpCodes.Dup); + catThrown.Pop(this, tryStmt); // store exception object in catThrown + ilGen.Emit(tryStmt.catchStmt, OpCodes.Call, catchExcToStrMethodInfo); + + ilGen.Emit(tryStmt.catchStmt, OpCodes.Stloc, excLocal); + catchVarLocStr.PopPre(this, tryStmt.catchVar.name); + ilGen.Emit(tryStmt.catchStmt, OpCodes.Ldloc, excLocal); + catchVarLocStr.PopPost(this, tryStmt.catchVar.name, tokenTypeStr); + } + else + { + throw new Exception("bad catch var type " + tryStmt.catchVar.type.ToString()); + } + + SetCallNo(tryStmt, tryCallNo, tryThrow.index); // __tryCallNo = tryThrow so it knows to do 'throw catThrown' on restore + + GetCallNo(tryStmt, catCallNo); // if (__catCallNo >= 0) goto catchCallSw; + ilGen.Emit(tryStmt.catchStmt, OpCodes.Ldc_I4_0); + ilGen.Emit(tryStmt.catchStmt, OpCodes.Bge, catchCallSw); + + actCallNo = catCallNo.localBuilder; // set up __catCallNo for call labels + actCallLabels.Clear(); + mightGetHere = true; // if we can get to the 'try' assume we can get to the 'catch' + GenerateStmtBlock(tryStmt.catchStmt); // output catch clause statement subblock + + if(mightGetHere) + { + new CallLabel(this, tryStmt.catchStmt); + ilGen.Emit(tryStmt.catchStmt, OpCodes.Leave, tryEnd); + openCallLabel = null; + } + + ilGen.MarkLabel(catchRetro); // not a script-visible exception, rethrow it + ilGen.Emit(tryStmt.catchStmt, OpCodes.Pop); + ilGen.Emit(tryStmt.catchStmt, OpCodes.Rethrow); + + ilGen.MarkLabel(catchCallSw); + OutputCallNoSwitchStmt(); // restoring, jump back inside script-defined body + + ilGen.EndExceptionBlock(); + ilGen.MarkLabel(tryEnd); + + mightGetHere |= tryBlockFallsOutBottom; // also get here if try body falls out bottom + } + + /** + * @brief output code for a try/finally block + * + * This is such a mess because there is hidden state for the finally { } that we have to recreate. + * The finally { } can be entered either via an exception being thrown in the try { } or a leave + * being executed in the try { } whose target is outside the try { } finally { }. + * + * For the thrown exception case, we slip in a try { } catch { } wrapper around the original try { } + * body. This will sense any thrown exception that would execute the finally { }. Then we have our + * try { } throw the exception on restore which gets the finally { } called and on its way again. + * + * For the leave case, we prefix all leave instructions with a call label and we explicitly chain + * all leaves through each try { } that has an associated finally { } that the leave would unwind + * through. This gets each try { } to simply jump to the correct leave instruction which immediately + * invokes the corresponding finally { } and then chains to the next leave instruction on out until + * it gets to its target. + * + * int __finCallNo = -1; // call number within finally { } subblock + * int __tryCallNo = -1; // call number within try { } subblock + * Exception __catThrown = null; // caught exception + * : // the outside world jumps here to restore us no matter ... + * try { // ... where we actually were inside of try/finally + * try { + * if (__tryCallNo >= 0) goto tryCallSw; // maybe go do restore + * // execute script-defined code + * // ...stack capture WILL run catch/finally { } subblock + * leave tryEnd; // executes finally { } subblock and exits + * tryThrow:: + * throw new ScriptRestoreCatchException(__catThrown); // catch { } was running, jump to its beginning + * tryCallSw: // restoring... + * switch (__tryCallNo) back up into // jump back inside try, ... + * // ... maybe to a leave if we were doing finally { } subblock + * } catch (Exception exc) { // in case we're getting to finally { } via a thrown exception: + * exc = ScriptRestoreCatchException.Unwrap(exc); // unwrap possible ScriptRestoreCatchException + * if (callMode == CallMode_SAVE) goto catchRetro; // don't touch anything if capturing stack + * __catThrown = exc; // save exception so try { } can throw it on restore + * __tryCallNo = tryThrow:; // tell try { } to throw it on restore + * catchRetro: + * rethrow; // in any case, go on to finally { } subblock now + * } + * } finally { + * if (callMode == CallMode_SAVE) goto finEnd; // don't touch anything if capturing stack + * if (__finCallNo >= 0) goto finCallSw; // maybe go do restore + * // normal, execute script-defined code + * finEnd: + * endfinally // jump to leave/throw target or next outer finally { } + * finCallSw: + * switch (__finCallNo) back up into // restoring, restart finally { } code wherever it was + * } + * tryEnd: + */ + private void GenerateStmtTryFinally(TokenStmtTry tryStmt) + { + CompValuTemp finCallNo = new CompValuTemp(tokenTypeInt, this); + CompValuTemp tryCallNo = new CompValuTemp(tokenTypeInt, this); + CompValuTemp catThrown = new CompValuTemp(tokenTypeExc, this); + + ScriptMyLabel tryCallSw = ilGen.DefineLabel("__tryCallSw_" + tryStmt.Unique); + ScriptMyLabel catchRetro = ilGen.DefineLabel("__catchRetro_" + tryStmt.Unique); + ScriptMyLabel finCallSw = ilGen.DefineLabel("__finCallSw_" + tryStmt.Unique); + BreakContTarg finEnd = new BreakContTarg(this, "__finEnd_" + tryStmt.Unique); + ScriptMyLabel tryEnd = ilGen.DefineLabel("__tryEnd_" + tryStmt.Unique); + + SetCallNo(tryStmt, finCallNo, -1); + SetCallNo(tryStmt, tryCallNo, -1); + ilGen.Emit(tryStmt, OpCodes.Ldnull); + catThrown.Pop(this, tryStmt); + + new CallLabel(this, tryStmt); // : + ilGen.BeginExceptionBlock(); // try { + ilGen.BeginExceptionBlock(); // try { + openCallLabel = null; + if(DEBUG_TRYSTMT) + { + ilGen.Emit(tryStmt, OpCodes.Ldstr, "enter try*: " + tryStmt.line + " callMode="); + ilGen.Emit(tryStmt, OpCodes.Call, consoleWriteMethodInfo); + PushXMRInst(); + ilGen.Emit(tryStmt, OpCodes.Ldfld, callModeFieldInfo); + ilGen.Emit(tryStmt, OpCodes.Box, typeof(int)); + ilGen.Emit(tryStmt, OpCodes.Call, consoleWriteMethodInfo); + ilGen.Emit(tryStmt, OpCodes.Ldstr, " tryCallNo="); + ilGen.Emit(tryStmt, OpCodes.Call, consoleWriteMethodInfo); + tryCallNo.PushVal(this, tryStmt); + ilGen.Emit(tryStmt, OpCodes.Box, typeof(int)); + ilGen.Emit(tryStmt, OpCodes.Call, consoleWriteMethodInfo); + ilGen.Emit(tryStmt, OpCodes.Ldstr, " finCallNo="); + ilGen.Emit(tryStmt, OpCodes.Call, consoleWriteMethodInfo); + finCallNo.PushVal(this, tryStmt); + ilGen.Emit(tryStmt, OpCodes.Box, typeof(int)); + ilGen.Emit(tryStmt, OpCodes.Call, consoleWriteMethodInfo); + ilGen.Emit(tryStmt, OpCodes.Ldstr, " catThrown.IsNull="); + ilGen.Emit(tryStmt, OpCodes.Call, consoleWriteMethodInfo); + catThrown.PushVal(this, tryStmt); + ilGen.Emit(tryStmt, OpCodes.Ldnull); + ilGen.Emit(tryStmt, OpCodes.Ceq); + ilGen.Emit(tryStmt, OpCodes.Box, typeof(int)); + ilGen.Emit(tryStmt, OpCodes.Call, consoleWriteMethodInfo); + ilGen.Emit(tryStmt, OpCodes.Ldstr, "\n"); + ilGen.Emit(tryStmt, OpCodes.Call, consoleWriteMethodInfo); + } + + GetCallNo(tryStmt, tryCallNo); // if (__tryCallNo >= 0) goto tryCallSw; + ilGen.Emit(tryStmt, OpCodes.Ldc_I4_0); + ilGen.Emit(tryStmt, OpCodes.Bge, tryCallSw); + + actCallNo = tryCallNo.localBuilder; // set up __tryCallNo for call labels + actCallLabels = new LinkedList(); + + GenerateStmtBlock(tryStmt.tryStmt); // output the try block statement subblock + + if(mightGetHere) + { + new CallLabel(this, tryStmt); // : + ilGen.Emit(tryStmt, OpCodes.Leave, tryEnd); // leave tryEnd; + openCallLabel = null; + } + + foreach(IntermediateLeave iLeave in tryStmt.iLeaves.Values) + { + ilGen.MarkLabel(iLeave.jumpIntoLabel); // intr2_exit: + new CallLabel(this, tryStmt); // tryCallNo = n; + ilGen.Emit(tryStmt, OpCodes.Leave, iLeave.jumpAwayLabel); // __callNo_n_: leave int1_exit; + openCallLabel = null; + } + + CallLabel tryThrow = new CallLabel(this, tryStmt); // tryThrow:: + if(DEBUG_TRYSTMT) + { + ilGen.Emit(tryStmt, OpCodes.Ldstr, "tryThrow*: " + tryStmt.line + " catThrown="); + ilGen.Emit(tryStmt, OpCodes.Call, consoleWriteMethodInfo); + catThrown.PushVal(this, tryStmt); + ilGen.Emit(tryStmt, OpCodes.Call, consoleWriteMethodInfo); + ilGen.Emit(tryStmt, OpCodes.Ldstr, "\n"); + ilGen.Emit(tryStmt, OpCodes.Call, consoleWriteMethodInfo); + } + catThrown.PushVal(this, tryStmt); // throw new ScriptRestoreCatchException (__catThrown); + ilGen.Emit(tryStmt, OpCodes.Newobj, scriptRestoreCatchExceptionConstructorInfo); + ilGen.Emit(tryStmt, OpCodes.Throw); + openCallLabel = null; + + ilGen.MarkLabel(tryCallSw); // tryCallSw: + OutputCallNoSwitchStmt(); // switch (tryCallNo) ... + // } + + ilGen.BeginCatchBlock(typeof(Exception)); // start of the catch block that can catch any exception + if(DEBUG_TRYSTMT) + { + ilGen.Emit(tryStmt, OpCodes.Ldstr, "enter catch*: " + tryStmt.line + " callMode="); + ilGen.Emit(tryStmt, OpCodes.Call, consoleWriteMethodInfo); + PushXMRInst(); + ilGen.Emit(tryStmt, OpCodes.Ldfld, callModeFieldInfo); + ilGen.Emit(tryStmt, OpCodes.Box, typeof(int)); + ilGen.Emit(tryStmt, OpCodes.Call, consoleWriteMethodInfo); + ilGen.Emit(tryStmt, OpCodes.Ldstr, " exc="); + ilGen.Emit(tryStmt, OpCodes.Call, consoleWriteMethodInfo); + ilGen.Emit(tryStmt, OpCodes.Dup); + ilGen.Emit(tryStmt, OpCodes.Call, consoleWriteMethodInfo); + ilGen.Emit(tryStmt, OpCodes.Ldstr, "\n"); + ilGen.Emit(tryStmt, OpCodes.Call, consoleWriteMethodInfo); + } + ilGen.Emit(tryStmt, OpCodes.Call, scriptRestoreCatchExceptionUnwrap); // exc = ScriptRestoreCatchException.Unwrap (exc); + PushXMRInst(); // if (callMode == CallMode_SAVE) goto catchRetro; + ilGen.Emit(tryStmt, OpCodes.Ldfld, callModeFieldInfo); + ilGen.Emit(tryStmt, OpCodes.Ldc_I4, XMRInstAbstract.CallMode_SAVE); + ilGen.Emit(tryStmt, OpCodes.Beq, catchRetro); + + catThrown.Pop(this, tryStmt); // __catThrown = exc; + SetCallNo(tryStmt, tryCallNo, tryThrow.index); // __tryCallNo = tryThrow:; + ilGen.Emit(tryStmt, OpCodes.Rethrow); + + ilGen.MarkLabel(catchRetro); // catchRetro: + ilGen.Emit(tryStmt, OpCodes.Pop); + ilGen.Emit(tryStmt, OpCodes.Rethrow); // rethrow; + + ilGen.EndExceptionBlock(); // } + + ilGen.BeginFinallyBlock(); // start of the finally block + + PushXMRInst(); // if (callMode == CallMode_SAVE) goto finEnd; + ilGen.Emit(tryStmt, OpCodes.Ldfld, callModeFieldInfo); + ilGen.Emit(tryStmt, OpCodes.Ldc_I4, XMRInstAbstract.CallMode_SAVE); + ilGen.Emit(tryStmt, OpCodes.Beq, finEnd.label); + + GetCallNo(tryStmt, finCallNo); // if (__finCallNo >= 0) goto finCallSw; + ilGen.Emit(tryStmt, OpCodes.Ldc_I4_0); + ilGen.Emit(tryStmt, OpCodes.Bge, finCallSw); + + actCallNo = finCallNo.localBuilder; // set up __finCallNo for call labels + actCallLabels.Clear(); + mightGetHere = true; // if we can get to the 'try' assume we can get to the 'finally' + GenerateStmtBlock(tryStmt.finallyStmt); // output finally clause statement subblock + + ilGen.MarkLabel(finEnd.label); // finEnd: + ilGen.Emit(tryStmt, OpCodes.Endfinally); // return out to next finally { } or catch { } or leave target + + ilGen.MarkLabel(finCallSw); // restore mode, switch (finCallNo) ... + OutputCallNoSwitchStmt(); + + ilGen.EndExceptionBlock(); + ilGen.MarkLabel(tryEnd); + + mightGetHere |= finEnd.used; // get here if finally body falls through or has a break statement + } + + /** + * @brief Generate code to initialize a variable to its default value. + */ + private void GenerateStmtVarIniDef(TokenStmtVarIniDef varIniDefStmt) + { + if(!mightGetHere) + return; + + CompValu left = GenerateFromLVal(varIniDefStmt.var); + left.PopPre(this, varIniDefStmt); + PushDefaultValue(left.type); + left.PopPost(this, varIniDefStmt); + } + + /** + * @brief generate code for a 'while' statement including the loop body. + */ + private void GenerateStmtWhile(TokenStmtWhile whileStmt) + { + if(!mightGetHere) + return; + + BreakContTarg oldBreakTarg = curBreakTarg; + BreakContTarg oldContTarg = curContTarg; + ScriptMyLabel loopLabel = ilGen.DefineLabel("whileloop_" + whileStmt.Unique); + + curBreakTarg = new BreakContTarg(this, "whilebreak_" + whileStmt.Unique); + curContTarg = new BreakContTarg(this, "whilecont_" + whileStmt.Unique); + + ilGen.MarkLabel(loopLabel); // loop: + CompValu testRVal = GenerateFromRVal(whileStmt.testRVal); // testRVal = while test expression + if(!IsConstBoolExprTrue(testRVal)) + { + testRVal.PushVal(this, whileStmt.testRVal, tokenTypeBool); // if (!testRVal) + ilGen.Emit(whileStmt, OpCodes.Brfalse, curBreakTarg.label); // goto break + curBreakTarg.used = true; + } + GenerateStmt(whileStmt.bodyStmt); // while body statement + if(curContTarg.used) + { + ilGen.MarkLabel(curContTarg.label); // cont: + mightGetHere = true; + } + if(mightGetHere) + { + EmitCallCheckRun(whileStmt, false); // __sw.CheckRun() + ilGen.Emit(whileStmt, OpCodes.Br, loopLabel); // goto loop + } + mightGetHere = curBreakTarg.used; + if(mightGetHere) + { + ilGen.MarkLabel(curBreakTarg.label); // done: + } + + curBreakTarg = oldBreakTarg; + curContTarg = oldContTarg; + } + + /** + * @brief process a local variable declaration statement, possibly with initialization expression. + * Note that the function header processing allocated stack space (CompValuTemp) for the + * variable and now all we do is write its initialization value. + */ + private void GenerateDeclVar(TokenDeclVar declVar) + { + // Script gave us an initialization value, so just store init value in var like an assignment statement. + // If no init given, set it to its default value. + CompValu local = declVar.location; + if(declVar.init != null) + { + CompValu rVal = GenerateFromRVal(declVar.init, local.GetArgTypes()); + local.PopPre(this, declVar); + rVal.PushVal(this, declVar.init, declVar.type); + local.PopPost(this, declVar); + } + else + { + local.PopPre(this, declVar); + PushDefaultValue(declVar.type); + local.PopPost(this, declVar); + } + } + + /** + * @brief Get the type and location of an L-value (eg, variable) + * @param lVal = L-value expression to evaluate + * @param argsig = null: it's a field/property + * else: select overload method that fits these arg types + */ + private CompValu GenerateFromLVal(TokenLVal lVal) + { + return GenerateFromLVal(lVal, null); + } + private CompValu GenerateFromLVal(TokenLVal lVal, TokenType[] argsig) + { + if(lVal is TokenLValArEle) + return GenerateFromLValArEle((TokenLValArEle)lVal); + if(lVal is TokenLValBaseField) + return GenerateFromLValBaseField((TokenLValBaseField)lVal, argsig); + if(lVal is TokenLValIField) + return GenerateFromLValIField((TokenLValIField)lVal, argsig); + if(lVal is TokenLValName) + return GenerateFromLValName((TokenLValName)lVal, argsig); + if(lVal is TokenLValSField) + return GenerateFromLValSField((TokenLValSField)lVal, argsig); + throw new Exception("bad lval class"); + } + + /** + * @brief we have an L-value token that is an element within an array. + * @returns a CompValu giving the type and location of the element of the array. + */ + private CompValu GenerateFromLValArEle(TokenLValArEle lVal) + { + CompValu subCompValu; + + // Compute location of array itself. + CompValu baseCompValu = GenerateFromRVal(lVal.baseRVal); + + // Maybe it is a fixed array access. + string basetypestring = baseCompValu.type.ToString(); + if(basetypestring.EndsWith("]")) + { + TokenRVal subRVal = lVal.subRVal; + int nSubs = 1; + if(subRVal is TokenRValList) + { + nSubs = ((TokenRValList)subRVal).nItems; + subRVal = ((TokenRValList)subRVal).rVal; + } + + int rank = basetypestring.IndexOf(']') - basetypestring.IndexOf('['); + if(nSubs != rank) + { + ErrorMsg(lVal.baseRVal, "expect " + rank + " subscript" + ((rank == 1) ? "" : "s") + " but have " + nSubs); + } + CompValu[] subCompValus = new CompValu[rank]; + int i; + for(i = 0; (subRVal != null) && (i < rank); i++) + { + subCompValus[i] = GenerateFromRVal(subRVal); + subRVal = (TokenRVal)subRVal.nextToken; + } + while(i < rank) + subCompValus[i++] = new CompValuInteger(new TokenTypeInt(lVal.subRVal), 0); + return new CompValuFixArEl(this, baseCompValu, subCompValus); + } + + // Maybe it is accessing the $idxprop property of a script-defined class. + if(baseCompValu.type is TokenTypeSDTypeClass) + { + TokenName name = new TokenName(lVal, "$idxprop"); + TokenTypeSDTypeClass sdtType = (TokenTypeSDTypeClass)baseCompValu.type; + TokenDeclSDTypeClass sdtDecl = sdtType.decl; + TokenDeclVar idxProp = FindThisMember(sdtDecl, name, null); + if(idxProp == null) + { + ErrorMsg(lVal, "no index property in class " + sdtDecl.longName.val); + return new CompValuVoid(lVal); + } + if((idxProp.sdtFlags & ScriptReduce.SDT_STATIC) != 0) + { + ErrorMsg(lVal, "non-static reference to static member " + idxProp.name.val); + return new CompValuVoid(idxProp); + } + CheckAccess(idxProp, name); + + TokenType[] argTypes = IdxPropArgTypes(idxProp); + CompValu[] compValus = IdxPropCompValus(lVal, argTypes.Length); + return new CompValuIdxProp(idxProp, baseCompValu, argTypes, compValus); + + } + + // Maybe they are accessing $idxprop property of a script-defined interface. + if(baseCompValu.type is TokenTypeSDTypeInterface) + { + TokenName name = new TokenName(lVal, "$idxprop"); + TokenTypeSDTypeInterface sdtType = (TokenTypeSDTypeInterface)baseCompValu.type; + TokenDeclVar idxProp = FindInterfaceMember(sdtType, name, null, ref baseCompValu); + if(idxProp == null) + { + ErrorMsg(lVal, "no index property defined for interface " + sdtType.decl.longName.val); + return baseCompValu; + } + + TokenType[] argTypes = IdxPropArgTypes(idxProp); + CompValu[] compValus = IdxPropCompValus(lVal, argTypes.Length); + return new CompValuIdxProp(idxProp, baseCompValu, argTypes, compValus); + } + + // Maybe it is extracting a character from a string. + if((baseCompValu.type is TokenTypeKey) || (baseCompValu.type is TokenTypeStr)) + { + subCompValu = GenerateFromRVal(lVal.subRVal); + return new CompValuStrChr(new TokenTypeChar(lVal), baseCompValu, subCompValu); + } + + // Maybe it is extracting an element from a list. + if(baseCompValu.type is TokenTypeList) + { + subCompValu = GenerateFromRVal(lVal.subRVal); + return new CompValuListEl(new TokenTypeObject(lVal), baseCompValu, subCompValu); + } + + // Access should be to XMR_Array otherwise. + if(!(baseCompValu.type is TokenTypeArray)) + { + ErrorMsg(lVal, "taking subscript of non-array"); + return baseCompValu; + } + subCompValu = GenerateFromRVal(lVal.subRVal); + return new CompValuArEle(new TokenTypeObject(lVal), baseCompValu, subCompValu); + } + + /** + * @brief Get number and type of arguments required by an index property. + */ + private static TokenType[] IdxPropArgTypes(TokenDeclVar idxProp) + { + TokenType[] argTypes; + if(idxProp.getProp != null) + { + int nArgs = idxProp.getProp.argDecl.varDict.Count; + argTypes = new TokenType[nArgs]; + foreach(TokenDeclVar var in idxProp.getProp.argDecl.varDict) + { + argTypes[var.vTableIndex] = var.type; + } + } + else + { + int nArgs = idxProp.setProp.argDecl.varDict.Count - 1; + argTypes = new TokenType[nArgs]; + foreach(TokenDeclVar var in idxProp.setProp.argDecl.varDict) + { + if(var.vTableIndex < nArgs) + { + argTypes[var.vTableIndex] = var.type; + } + } + } + return argTypes; + } + + /** + * @brief Get number and computed value of index property arguments. + * @param lVal = list of arguments + * @param nArgs = number of arguments required + * @returns null: argument count mismatch + * else: array of index property argument values + */ + private CompValu[] IdxPropCompValus(TokenLValArEle lVal, int nArgs) + { + TokenRVal subRVal = lVal.subRVal; + int nSubs = 1; + if(subRVal is TokenRValList) + { + nSubs = ((TokenRValList)subRVal).nItems; + subRVal = ((TokenRValList)subRVal).rVal; + } + + if(nSubs != nArgs) + { + ErrorMsg(lVal, "index property requires " + nArgs + " subscript(s)"); + return null; + } + + CompValu[] subCompValus = new CompValu[nArgs]; + for(int i = 0; i < nArgs; i++) + { + subCompValus[i] = GenerateFromRVal(subRVal); + subRVal = (TokenRVal)subRVal.nextToken; + } + return subCompValus; + } + + /** + * @brief using 'base' within a script-defined instance method to refer to an instance field/method + * of the class being extended. + */ + private CompValu GenerateFromLValBaseField(TokenLValBaseField baseField, TokenType[] argsig) + { + string fieldName = baseField.fieldName.val; + + TokenDeclSDType sdtDecl = curDeclFunc.sdtClass; + if((sdtDecl == null) || ((curDeclFunc.sdtFlags & ScriptReduce.SDT_STATIC) != 0)) + { + ErrorMsg(baseField, "cannot use 'base' outside instance method body"); + return new CompValuVoid(baseField); + } + if(!IsSDTInstMethod()) + { + ErrorMsg(baseField, "cannot access instance member of base class from static method"); + return new CompValuVoid(baseField); + } + + TokenDeclVar declVar = FindThisMember(sdtDecl.extends, baseField.fieldName, argsig); + if(declVar != null) + { + CheckAccess(declVar, baseField.fieldName); + TokenType baseType = declVar.sdtClass.MakeRefToken(baseField); + CompValu basePtr = new CompValuArg(baseType, 0); + return AccessInstanceMember(declVar, basePtr, baseField, true); + } + + ErrorMsg(baseField, "no member " + fieldName + ArgSigString(argsig) + " rootward of " + sdtDecl.longName.val); + return new CompValuVoid(baseField); + } + + /** + * @brief We have an L-value token that is an instance field/method within a struct. + * @returns a CompValu giving the type and location of the field/method in the struct. + */ + private CompValu GenerateFromLValIField(TokenLValIField lVal, TokenType[] argsig) + { + CompValu baseRVal = GenerateFromRVal(lVal.baseRVal); + string fieldName = lVal.fieldName.val + ArgSigString(argsig); + + // Maybe they are accessing an instance field, method or property of a script-defined class. + if(baseRVal.type is TokenTypeSDTypeClass) + { + TokenTypeSDTypeClass sdtType = (TokenTypeSDTypeClass)baseRVal.type; + TokenDeclSDTypeClass sdtDecl = sdtType.decl; + TokenDeclVar declVar = FindThisMember(sdtDecl, lVal.fieldName, argsig); + if(declVar != null) + { + CheckAccess(declVar, lVal.fieldName); + return AccessInstanceMember(declVar, baseRVal, lVal, false); + } + ErrorMsg(lVal.fieldName, "no member " + fieldName + " in class " + sdtDecl.longName.val); + return new CompValuVoid(lVal.fieldName); + } + + // Maybe they are accessing a method or property of a script-defined interface. + if(baseRVal.type is TokenTypeSDTypeInterface) + { + TokenTypeSDTypeInterface sdtType = (TokenTypeSDTypeInterface)baseRVal.type; + TokenDeclVar declVar = FindInterfaceMember(sdtType, lVal.fieldName, argsig, ref baseRVal); + if(declVar != null) + { + return new CompValuIntfMember(declVar, baseRVal); + } + ErrorMsg(lVal.fieldName, "no member " + fieldName + " in interface " + sdtType.decl.longName.val); + return new CompValuVoid(lVal.fieldName); + } + + // Since we only have a few built-in types with fields, just pound them out. + if(baseRVal.type is TokenTypeArray) + { + + // no arguments, no parentheses, just the field name, returning integer + // but internally, it is a call to a method() + if(fieldName == "count") + { + return new CompValuIntInstROProp(tokenTypeInt, baseRVal, arrayCountMethodInfo); + } + + // no arguments but with the parentheses, returning void + if(fieldName == "clear()") + { + return new CompValuIntInstMeth(XMR_Array.clearDelegate, baseRVal, arrayClearMethodInfo); + } + + // single integer argument, returning an object + if(fieldName == "index(integer)") + { + return new CompValuIntInstMeth(XMR_Array.indexDelegate, baseRVal, arrayIndexMethodInfo); + } + if(fieldName == "value(integer)") + { + return new CompValuIntInstMeth(XMR_Array.valueDelegate, baseRVal, arrayValueMethodInfo); + } + } + if(baseRVal.type is TokenTypeRot) + { + FieldInfo fi = null; + if(fieldName == "x") + fi = rotationXFieldInfo; + if(fieldName == "y") + fi = rotationYFieldInfo; + if(fieldName == "z") + fi = rotationZFieldInfo; + if(fieldName == "s") + fi = rotationSFieldInfo; + if(fi != null) + { + return new CompValuField(new TokenTypeFloat(lVal), baseRVal, fi); + } + } + if(baseRVal.type is TokenTypeVec) + { + FieldInfo fi = null; + if(fieldName == "x") + fi = vectorXFieldInfo; + if(fieldName == "y") + fi = vectorYFieldInfo; + if(fieldName == "z") + fi = vectorZFieldInfo; + if(fi != null) + { + return new CompValuField(new TokenTypeFloat(lVal), baseRVal, fi); + } + } + + ErrorMsg(lVal, "type " + baseRVal.type.ToString() + " does not define member " + fieldName); + return baseRVal; + } + + /** + * @brief We have an L-value token that is a function, method or variable name. + * @param lVal = name we are looking for + * @param argsig = null: just look for name as a variable + * else: look for name as a function/method being called with the given argument types + * eg, "(string,integer,list)" + * @returns a CompValu giving the type and location of the function, method or variable. + */ + private CompValu GenerateFromLValName(TokenLValName lVal, TokenType[] argsig) + { + // Look in variable stack then look for built-in constants and functions. + TokenDeclVar var = FindNamedVar(lVal, argsig); + if(var == null) + { + ErrorMsg(lVal, "undefined constant/function/variable " + lVal.name.val + ArgSigString(argsig)); + return new CompValuVoid(lVal); + } + + // Maybe it has an implied 'this.' on the front. + if((var.sdtClass != null) && ((var.sdtFlags & ScriptReduce.SDT_STATIC) == 0)) + { + + if(!IsSDTInstMethod()) + { + ErrorMsg(lVal, "cannot access instance member of class from static method"); + return new CompValuVoid(lVal); + } + + // Don't allow something such as: + // + // class A { + // integer I; + // class B { + // Print () + // { + // llOwnerSay ("I=" + (string)I); <- access to I not allowed inside class B. + // explicit reference required as we don't + // have a valid reference to class A. + // } + // } + // } + // + // But do allow something such as: + // + // class A { + // integer I; + // } + // class B : A { + // Print () + // { + // llOwnerSay ("I=" + (string)I); + // } + // } + for(TokenDeclSDType c = curDeclFunc.sdtClass; c != var.sdtClass; c = c.extends) + { + if(c == null) + { + // our arg0 points to an instance of curDeclFunc.sdtClass, not var.sdtClass + ErrorMsg(lVal, "cannot access instance member of outer class with implied 'this'"); + break; + } + } + + CompValu thisCompValu = new CompValuArg(var.sdtClass.MakeRefToken(lVal), 0); + return AccessInstanceMember(var, thisCompValu, lVal, false); + } + + // It's a local variable, static field, global, constant, etc. + return var.location; + } + + /** + * @brief Access a script-defined type's instance member + * @param declVar = which member (field,method,property) to access + * @param basePtr = points to particular object instance + * @param ignoreVirt = true: access declVar's method directly; else: maybe use vTable + * @returns where the field/method/property is located + */ + private CompValu AccessInstanceMember(TokenDeclVar declVar, CompValu basePtr, Token errorAt, bool ignoreVirt) + { + if((declVar.sdtFlags & ScriptReduce.SDT_STATIC) != 0) + { + ErrorMsg(errorAt, "non-static reference to static member " + declVar.name.val); + return new CompValuVoid(declVar); + } + return new CompValuInstMember(declVar, basePtr, ignoreVirt); + } + + /** + * @brief we have an L-value token that is a static member within a struct. + * @returns a CompValu giving the type and location of the member in the struct. + */ + private CompValu GenerateFromLValSField(TokenLValSField lVal, TokenType[] argsig) + { + TokenType stType = lVal.baseType; + string fieldName = lVal.fieldName.val + ArgSigString(argsig); + + // Maybe they are accessing a static member of a script-defined class. + if(stType is TokenTypeSDTypeClass) + { + TokenTypeSDTypeClass sdtType = (TokenTypeSDTypeClass)stType; + TokenDeclVar declVar = FindThisMember(sdtType.decl, lVal.fieldName, argsig); + if(declVar != null) + { + CheckAccess(declVar, lVal.fieldName); + if((declVar.sdtFlags & ScriptReduce.SDT_STATIC) == 0) + { + ErrorMsg(lVal.fieldName, "static reference to non-static member " + fieldName); + return new CompValuVoid(lVal.fieldName); + } + return declVar.location; + } + } + + ErrorMsg(lVal.fieldName, "no member " + fieldName + " in " + stType.ToString()); + return new CompValuVoid(lVal.fieldName); + } + + /** + * @brief generate code from an RVal expression and return its type and where the result is stored. + * For anything that has side-effects, statements are generated that perform the computation then + * the result it put in a temp var and the temp var name is returned. + * For anything without side-effects, they are returned as an equivalent sequence of Emits. + * @param rVal = rVal token to be evaluated + * @param argsig = null: not being used in an function/method context + * else: string giving argument types, eg, "(string,integer,list,vector)" + * that can be used to select among overloaded methods + * @returns resultant type and location + */ + private CompValu GenerateFromRVal(TokenRVal rVal) + { + return GenerateFromRVal(rVal, null); + } + private CompValu GenerateFromRVal(TokenRVal rVal, TokenType[] argsig) + { + errorMessageToken = rVal; + + // Maybe the expression can be converted to a constant. + bool didOne; + do + { + didOne = false; + rVal = rVal.TryComputeConstant(LookupBodyConstants, ref didOne); + } while(didOne); + + // Generate code for the computation and return resulting type and location. + CompValu cVal = null; + if(rVal is TokenRValAsnPost) + cVal = GenerateFromRValAsnPost((TokenRValAsnPost)rVal); + if(rVal is TokenRValAsnPre) + cVal = GenerateFromRValAsnPre((TokenRValAsnPre)rVal); + if(rVal is TokenRValCall) + cVal = GenerateFromRValCall((TokenRValCall)rVal); + if(rVal is TokenRValCast) + cVal = GenerateFromRValCast((TokenRValCast)rVal); + if(rVal is TokenRValCondExpr) + cVal = GenerateFromRValCondExpr((TokenRValCondExpr)rVal); + if(rVal is TokenRValConst) + cVal = GenerateFromRValConst((TokenRValConst)rVal); + if(rVal is TokenRValInitDef) + cVal = GenerateFromRValInitDef((TokenRValInitDef)rVal); + if(rVal is TokenRValIsType) + cVal = GenerateFromRValIsType((TokenRValIsType)rVal); + if(rVal is TokenRValList) + cVal = GenerateFromRValList((TokenRValList)rVal); + if(rVal is TokenRValNewArIni) + cVal = GenerateFromRValNewArIni((TokenRValNewArIni)rVal); + if(rVal is TokenRValOpBin) + cVal = GenerateFromRValOpBin((TokenRValOpBin)rVal); + if(rVal is TokenRValOpUn) + cVal = GenerateFromRValOpUn((TokenRValOpUn)rVal); + if(rVal is TokenRValParen) + cVal = GenerateFromRValParen((TokenRValParen)rVal); + if(rVal is TokenRValRot) + cVal = GenerateFromRValRot((TokenRValRot)rVal); + if(rVal is TokenRValThis) + cVal = GenerateFromRValThis((TokenRValThis)rVal); + if(rVal is TokenRValUndef) + cVal = GenerateFromRValUndef((TokenRValUndef)rVal); + if(rVal is TokenRValVec) + cVal = GenerateFromRValVec((TokenRValVec)rVal); + if(rVal is TokenLVal) + cVal = GenerateFromLVal((TokenLVal)rVal, argsig); + + if(cVal == null) + throw new Exception("bad rval class " + rVal.GetType().ToString()); + + // Sanity check. + if(!youveAnError) + { + if(cVal.type == null) + throw new Exception("cVal has no type " + cVal.GetType()); + string cValType = cVal.type.ToString(); + string rValType = rVal.GetRValType(this, argsig).ToString(); + if(cValType == "bool") + cValType = "integer"; + if(rValType == "bool") + rValType = "integer"; + if(cValType != rValType) + { + throw new Exception("cVal.type " + cValType + " != rVal.type " + rValType + + " (" + rVal.GetType().Name + " " + rVal.SrcLoc + ")"); + } + } + + return cVal; + } + + /** + * @brief compute the result of a binary operator (eg, add, subtract, multiply, lessthan) + * @param token = binary operator token, includes the left and right operands + * @returns where the resultant R-value is as something that doesn't have side effects + */ + private CompValu GenerateFromRValOpBin(TokenRValOpBin token) + { + CompValu left, right; + string opcodeIndex = token.opcode.ToString(); + + // Comma operators are special, as they say to compute the left-hand value and + // discard it, then compute the right-hand argument and that is the result. + if(opcodeIndex == ",") + { + // Compute left-hand operand but throw away result. + GenerateFromRVal(token.rValLeft); + + // Compute right-hand operand and that is the value of the expression. + return GenerateFromRVal(token.rValRight); + } + + // Simple overwriting assignments are their own special case, + // as we want to cast the R-value to the type of the L-value. + // And in the case of delegates, we want to use the arg signature + // of the delegate to select which overloaded method to use. + if(opcodeIndex == "=") + { + if(!(token.rValLeft is TokenLVal)) + { + ErrorMsg(token, "invalid L-value for ="); + return GenerateFromRVal(token.rValLeft); + } + left = GenerateFromLVal((TokenLVal)token.rValLeft); + right = Trivialize(GenerateFromRVal(token.rValRight, left.GetArgTypes()), token.rValRight); + left.PopPre(this, token.rValLeft); + right.PushVal(this, token.rValRight, left.type); // push (left.type)right + left.PopPost(this, token.rValLeft); // pop to left + return left; + } + + // There are String.Concat() methods available for 2, 3 and 4 operands. + // So see if we have a string concat op and optimize if so. + if((opcodeIndex == "+") || + ((opcodeIndex == "+=") && + (token.rValLeft is TokenLVal) && + (token.rValLeft.GetRValType(this, null) is TokenTypeStr))) + { + + // We are adding something. Maybe it's a bunch of strings together. + List scorvs = new List(); + if(StringConcatOperands(token.rValLeft, token.rValRight, scorvs, token.opcode)) + { + // Evaluate all the operands, right-to-left on purpose per LSL scripting. + int i; + int n = scorvs.Count; + CompValu[] scocvs = new CompValu[n]; + for(i = n; --i >= 0;) + { + scocvs[i] = GenerateFromRVal(scorvs[i]); + if(i > 0) + scocvs[i] = Trivialize(scocvs[i], scorvs[i]); + } + + /* + * Figure out where to put the result. + * A temp if '+', or back in original L-value if '+='. + */ + CompValu retcv; + if(opcodeIndex == "+") + { + retcv = new CompValuTemp(new TokenTypeStr(token.opcode), this); + } + else + { + retcv = GenerateFromLVal((TokenLVal)token.rValLeft); + } + retcv.PopPre(this, token); + + // Call the String.Concat() methods, passing operands in left-to-right order. + // Force a cast to string (retcv.type) for each operand. + ++i; + scocvs[i].PushVal(this, scorvs[i], retcv.type); + while(i + 3 < n) + { + ++i; + scocvs[i].PushVal(this, scorvs[i], retcv.type); + ++i; + scocvs[i].PushVal(this, scorvs[i], retcv.type); + ++i; + scocvs[i].PushVal(this, scorvs[i], retcv.type); + ilGen.Emit(scorvs[i], OpCodes.Call, stringConcat4MethodInfo); + } + if(i + 2 < n) + { + ++i; + scocvs[i].PushVal(this, scorvs[i], retcv.type); + ++i; + scocvs[i].PushVal(this, scorvs[i], retcv.type); + ilGen.Emit(scorvs[i], OpCodes.Call, stringConcat3MethodInfo); + } + if(i + 1 < n) + { + ++i; + scocvs[i].PushVal(this, scorvs[i], retcv.type); + ilGen.Emit(scorvs[i], OpCodes.Call, stringConcat2MethodInfo); + } + + // Put the result where we want it and return where we put it. + retcv.PopPost(this, token); + return retcv; + } + } + + // If "&&&", it is a short-circuiting AND. + // Compute left-hand operand and if true, compute right-hand operand. + if(opcodeIndex == "&&&") + { + bool leftVal, rightVal; + left = GenerateFromRVal(token.rValLeft); + if(!IsConstBoolExpr(left, out leftVal)) + { + ScriptMyLabel falseLabel = ilGen.DefineLabel("ssandfalse"); + left.PushVal(this, tokenTypeBool); + ilGen.Emit(token, OpCodes.Brfalse, falseLabel); + right = GenerateFromRVal(token.rValRight); + if(!IsConstBoolExpr(right, out rightVal)) + { + right.PushVal(this, tokenTypeBool); + goto donessand; + } + if(!rightVal) + { + ilGen.MarkLabel(falseLabel); + return new CompValuInteger(new TokenTypeInt(token.rValLeft), 0); + } + ilGen.Emit(token, OpCodes.Ldc_I4_1); + donessand: + ScriptMyLabel doneLabel = ilGen.DefineLabel("ssanddone"); + ilGen.Emit(token, OpCodes.Br, doneLabel); + ilGen.MarkLabel(falseLabel); + ilGen.Emit(token, OpCodes.Ldc_I4_0); + ilGen.MarkLabel(doneLabel); + CompValuTemp retRVal = new CompValuTemp(new TokenTypeInt(token), this); + retRVal.Pop(this, token); + return retRVal; + } + + if(!leftVal) + { + return new CompValuInteger(new TokenTypeInt(token.rValLeft), 0); + } + + right = GenerateFromRVal(token.rValRight); + if(!IsConstBoolExpr(right, out rightVal)) + { + right.PushVal(this, tokenTypeBool); + CompValuTemp retRVal = new CompValuTemp(new TokenTypeInt(token), this); + retRVal.Pop(this, token); + return retRVal; + } + return new CompValuInteger(new TokenTypeInt(token), rightVal ? 1 : 0); + } + + // If "|||", it is a short-circuiting OR. + // Compute left-hand operand and if false, compute right-hand operand. + if(opcodeIndex == "|||") + { + bool leftVal, rightVal; + left = GenerateFromRVal(token.rValLeft); + if(!IsConstBoolExpr(left, out leftVal)) + { + ScriptMyLabel trueLabel = ilGen.DefineLabel("ssortrue"); + left.PushVal(this, tokenTypeBool); + ilGen.Emit(token, OpCodes.Brtrue, trueLabel); + right = GenerateFromRVal(token.rValRight); + if(!IsConstBoolExpr(right, out rightVal)) + { + right.PushVal(this, tokenTypeBool); + goto donessor; + } + if(rightVal) + { + ilGen.MarkLabel(trueLabel); + return new CompValuInteger(new TokenTypeInt(token.rValLeft), 1); + } + ilGen.Emit(token, OpCodes.Ldc_I4_0); + donessor: + ScriptMyLabel doneLabel = ilGen.DefineLabel("ssanddone"); + ilGen.Emit(token, OpCodes.Br, doneLabel); + ilGen.MarkLabel(trueLabel); + ilGen.Emit(token, OpCodes.Ldc_I4_1); + ilGen.MarkLabel(doneLabel); + CompValuTemp retRVal = new CompValuTemp(new TokenTypeInt(token), this); + retRVal.Pop(this, token); + return retRVal; + } + + if(leftVal) + { + return new CompValuInteger(new TokenTypeInt(token.rValLeft), 1); + } + + right = GenerateFromRVal(token.rValRight); + if(!IsConstBoolExpr(right, out rightVal)) + { + right.PushVal(this, tokenTypeBool); + CompValuTemp retRVal = new CompValuTemp(new TokenTypeInt(token), this); + retRVal.Pop(this, token); + return retRVal; + } + return new CompValuInteger(new TokenTypeInt(token), rightVal ? 1 : 0); + } + + // Computation of some sort, compute right-hand operand value then left-hand value + // because LSL is supposed to be right-to-left evaluation. + right = Trivialize(GenerateFromRVal(token.rValRight), token.rValRight); + + // If left is a script-defined class and there is a method with the operator's name, + // convert this to a call to that method with the right value as its single parameter. + // Except don't if the right value is 'undef' so they can always compare to undef. + TokenType leftType = token.rValLeft.GetRValType(this, null); + if((leftType is TokenTypeSDTypeClass) && !(right.type is TokenTypeUndef)) + { + TokenTypeSDTypeClass sdtType = (TokenTypeSDTypeClass)leftType; + TokenDeclSDTypeClass sdtDecl = sdtType.decl; + TokenType[] argsig = new TokenType[] { right.type }; + TokenName funcName = new TokenName(token.opcode, "$op" + opcodeIndex); + TokenDeclVar declFunc = FindThisMember(sdtDecl, funcName, argsig); + if(declFunc != null) + { + CheckAccess(declFunc, funcName); + left = GenerateFromRVal(token.rValLeft); + CompValu method = AccessInstanceMember(declFunc, left, token, false); + CompValu[] argRVals = new CompValu[] { right }; + return GenerateACall(method, argRVals, token); + } + } + + // Formulate key string for binOpStrings = (lefttype)(operator)(righttype) + string leftIndex = leftType.ToString(); + string rightIndex = right.type.ToString(); + string key = leftIndex + opcodeIndex + rightIndex; + + // If that key exists in table, then the operation is defined between those types + // ... and it produces an R-value of type as given in the table. + BinOpStr binOpStr; + if(BinOpStr.defined.TryGetValue(key, out binOpStr)) + { + // If table contained an explicit assignment type like +=, output the statement without + // casting the L-value, then return the L-value as the resultant value. + // + // Make sure we don't include comparisons (such as ==, >=, etc). + // Nothing like +=, -=, %=, etc, generate a boolean, only the comparisons. + if((binOpStr.outtype != typeof(bool)) && opcodeIndex.EndsWith("=") && (opcodeIndex != "!=")) + { + if(!(token.rValLeft is TokenLVal)) + { + ErrorMsg(token.rValLeft, "invalid L-value"); + return GenerateFromRVal(token.rValLeft); + } + left = GenerateFromLVal((TokenLVal)token.rValLeft); + binOpStr.emitBO(this, token, left, right, left); + return left; + } + + // It's of the form left binop right. + // Compute left, perform operation then put result in a temp. + left = GenerateFromRVal(token.rValLeft); + CompValu retRVal = new CompValuTemp(TokenType.FromSysType(token.opcode, binOpStr.outtype), this); + binOpStr.emitBO(this, token, left, right, retRVal); + return retRVal; + } + + // Nothing in the table, check for comparing object pointers because of the myriad of types possible. + // This will compare list pointers, null pointers, script-defined type pointers, array pointers, etc. + // It will show equal iff the memory addresses are equal and that is good enough. + if(!leftType.ToSysType().IsValueType && !right.type.ToSysType().IsValueType && ((opcodeIndex == "==") || (opcodeIndex == "!="))) + { + CompValuTemp retRVal = new CompValuTemp(new TokenTypeInt(token), this); + left = GenerateFromRVal(token.rValLeft); + left.PushVal(this, token.rValLeft); + right.PushVal(this, token.rValRight); + ilGen.Emit(token, OpCodes.Ceq); + if(opcodeIndex == "!=") + { + ilGen.Emit(token, OpCodes.Ldc_I4_1); + ilGen.Emit(token, OpCodes.Xor); + } + retRVal.Pop(this, token); + return retRVal; + } + + // If the opcode ends with "=", it may be something like "+=". + // So look up the key as if we didn't have the "=" to tell us if the operation is legal. + // Also, the binary operation's output type must be the same as the L-value type. + // Likewise, integer += float not allowed because result is float, but float += integer is ok. + if(opcodeIndex.EndsWith("=")) + { + key = leftIndex + opcodeIndex.Substring(0, opcodeIndex.Length - 1) + rightIndex; + if(BinOpStr.defined.TryGetValue(key, out binOpStr)) + { + if(!(token.rValLeft is TokenLVal)) + { + ErrorMsg(token, "invalid L-value for ="); + return GenerateFromRVal(token.rValLeft); + } + if(!binOpStr.rmwOK) + { + ErrorMsg(token, "= not allowed: " + leftIndex + " " + opcodeIndex + " " + rightIndex); + return new CompValuVoid(token); + } + + // Now we know for something like %= that left%right is legal for the types given. + left = GenerateFromLVal((TokenLVal)token.rValLeft); + if(binOpStr.outtype == leftType.ToSysType()) + { + binOpStr.emitBO(this, token, left, right, left); + } + else + { + CompValu temp = new CompValuTemp(TokenType.FromSysType(token, binOpStr.outtype), this); + binOpStr.emitBO(this, token, left, right, temp); + left.PopPre(this, token); + temp.PushVal(this, token, leftType); + left.PopPost(this, token); + } + return left; + } + } + + // Can't find it, oh well. + ErrorMsg(token, "op not defined: " + leftIndex + " " + opcodeIndex + " " + rightIndex); + return new CompValuVoid(token); + } + + /** + * @brief Queue the given operands to the end of the scos list. + * If it can be broken down into more string concat operands, do so. + * Otherwise, just push it as one operand. + * @param leftRVal = left-hand operand of a '+' operation + * @param rightRVal = right-hand operand of a '+' operation + * @param scos = left-to-right list of operands for the string concat so far + * @param addop = the add operator token (either '+' or '+=') + * @returns false: neither operand is a string, nothing added to scos + * true: scos = updated with leftRVal then rightRVal added onto the end, possibly broken down further + */ + private bool StringConcatOperands(TokenRVal leftRVal, TokenRVal rightRVal, List scos, TokenKw addop) + { + /* + * If neither operand is a string (eg, float+integer), then the result isn't going to be a string. + */ + TokenType leftType = leftRVal.GetRValType(this, null); + TokenType rightType = rightRVal.GetRValType(this, null); + if(!(leftType is TokenTypeStr) && !(rightType is TokenTypeStr)) + return false; + + // Also, list+string => list so reject that too. + // Also, string+list => list so reject that too. + if(leftType is TokenTypeList) + return false; + if(rightType is TokenTypeList) + return false; + + // Append values to the end of the list in left-to-right order. + // If value is formed from a something+something => string, + // push them as separate values, otherwise push as one value. + StringConcatOperand(leftType, leftRVal, scos); + StringConcatOperand(rightType, rightRVal, scos); + + // Maybe constant strings can be concatted. + try + { + int len; + while(((len = scos.Count) >= 2) && + ((leftRVal = scos[len - 2]) is TokenRValConst) && + ((rightRVal = scos[len - 1]) is TokenRValConst)) + { + object sum = addop.binOpConst(((TokenRValConst)leftRVal).val, + ((TokenRValConst)rightRVal).val); + scos[len - 2] = new TokenRValConst(addop, sum); + scos.RemoveAt(len - 1); + } + } + catch + { + } + + // We pushed some string stuff. + return true; + } + + /** + * @brief Queue the given operand to the end of the scos list. + * If it can be broken down into more string concat operands, do so. + * Otherwise, just push it as one operand. + * @param type = rVal's resultant type + * @param rVal = operand to examine + * @param scos = left-to-right list of operands for the string concat so far + * @returns with scos = updated with rVal added onto the end, possibly broken down further + */ + private void StringConcatOperand(TokenType type, TokenRVal rVal, List scos) + { + bool didOne; + do + { + didOne = false; + rVal = rVal.TryComputeConstant(LookupBodyConstants, ref didOne); + } while(didOne); + + if(!(type is TokenTypeStr)) + goto pushasis; + if(!(rVal is TokenRValOpBin)) + goto pushasis; + TokenRValOpBin rValOpBin = (TokenRValOpBin)rVal; + if(!(rValOpBin.opcode is TokenKwAdd)) + goto pushasis; + if(StringConcatOperands(rValOpBin.rValLeft, rValOpBin.rValRight, scos, rValOpBin.opcode)) + return; + pushasis: + scos.Add(rVal); + } + + /** + * @brief compute the result of an unary operator + * @param token = unary operator token, includes the operand + * @returns where the resultant R-value is + */ + private CompValu GenerateFromRValOpUn(TokenRValOpUn token) + { + CompValu inRVal = GenerateFromRVal(token.rVal); + + // Script-defined types can define their own methods to handle unary operators. + if(inRVal.type is TokenTypeSDTypeClass) + { + TokenTypeSDTypeClass sdtType = (TokenTypeSDTypeClass)inRVal.type; + TokenDeclSDTypeClass sdtDecl = sdtType.decl; + TokenName funcName = new TokenName(token.opcode, "$op" + token.opcode.ToString()); + TokenDeclVar declFunc = FindThisMember(sdtDecl, funcName, zeroArgs); + if(declFunc != null) + { + CheckAccess(declFunc, funcName); + CompValu method = AccessInstanceMember(declFunc, inRVal, token, false); + return GenerateACall(method, zeroCompValus, token); + } + } + + // Otherwise use the default. + return UnOpGenerate(inRVal, token.opcode); + } + + /** + * @brief postfix operator -- this returns the type and location of the resultant value + */ + private CompValu GenerateFromRValAsnPost(TokenRValAsnPost asnPost) + { + CompValu lVal = GenerateFromLVal(asnPost.lVal); + + // Make up a temp to save original value in. + CompValuTemp result = new CompValuTemp(lVal.type, this); + + // Prepare to pop incremented value back into variable being incremented. + lVal.PopPre(this, asnPost.lVal); + + // Copy original value to temp and leave value on stack. + lVal.PushVal(this, asnPost.lVal); + ilGen.Emit(asnPost.lVal, OpCodes.Dup); + result.Pop(this, asnPost.lVal); + + // Perform the ++/--. + if((lVal.type is TokenTypeChar) || (lVal.type is TokenTypeInt)) + { + ilGen.Emit(asnPost, OpCodes.Ldc_I4_1); + } + else if(lVal.type is TokenTypeFloat) + { + ilGen.Emit(asnPost, OpCodes.Ldc_R4, 1.0f); + } + else + { + lVal.PopPost(this, asnPost.lVal); + ErrorMsg(asnPost, "invalid type for " + asnPost.postfix.ToString()); + return lVal; + } + switch(asnPost.postfix.ToString()) + { + case "++": + { + ilGen.Emit(asnPost, OpCodes.Add); + break; + } + case "--": + { + ilGen.Emit(asnPost, OpCodes.Sub); + break; + } + default: + throw new Exception("unknown asnPost op"); + } + + // Store new value in original variable. + lVal.PopPost(this, asnPost.lVal); + + return result; + } + + /** + * @brief prefix operator -- this returns the type and location of the resultant value + */ + private CompValu GenerateFromRValAsnPre(TokenRValAsnPre asnPre) + { + CompValu lVal = GenerateFromLVal(asnPre.lVal); + + // Make up a temp to put result in. + CompValuTemp result = new CompValuTemp(lVal.type, this); + + // Prepare to pop incremented value back into variable being incremented. + lVal.PopPre(this, asnPre.lVal); + + // Push original value. + lVal.PushVal(this, asnPre.lVal); + + // Perform the ++/--. + if((lVal.type is TokenTypeChar) || (lVal.type is TokenTypeInt)) + { + ilGen.Emit(asnPre, OpCodes.Ldc_I4_1); + } + else if(lVal.type is TokenTypeFloat) + { + ilGen.Emit(asnPre, OpCodes.Ldc_R4, 1.0f); + } + else + { + lVal.PopPost(this, asnPre.lVal); + ErrorMsg(asnPre, "invalid type for " + asnPre.prefix.ToString()); + return lVal; + } + switch(asnPre.prefix.ToString()) + { + case "++": + { + ilGen.Emit(asnPre, OpCodes.Add); + break; + } + case "--": + { + ilGen.Emit(asnPre, OpCodes.Sub); + break; + } + default: + throw new Exception("unknown asnPre op"); + } + + // Store new value in temp variable, keeping new value on stack. + ilGen.Emit(asnPre.lVal, OpCodes.Dup); + result.Pop(this, asnPre.lVal); + + // Store new value in original variable. + lVal.PopPost(this, asnPre.lVal); + + return result; + } + + /** + * @brief Generate code that calls a function or object's method. + * @returns where the call's return value is stored (a TokenTypeVoid if void) + */ + private CompValu GenerateFromRValCall(TokenRValCall call) + { + CompValu method; + CompValu[] argRVals; + int i, nargs; + TokenRVal arg; + TokenType[] argTypes; + + // Compute the values of all the function's call arguments. + // Save where the computation results are in the argRVals[] array. + // Might as well build the argument signature from the argument types, too. + nargs = call.nArgs; + argRVals = new CompValu[nargs]; + argTypes = new TokenType[nargs]; + if(nargs > 0) + { + i = 0; + for(arg = call.args; arg != null; arg = (TokenRVal)arg.nextToken) + { + argRVals[i] = GenerateFromRVal(arg); + argTypes[i] = argRVals[i].type; + i++; + } + } + + // Get function/method's entrypoint that matches the call argument types. + method = GenerateFromRVal(call.meth, argTypes); + if(method == null) + return null; + + return GenerateACall(method, argRVals, call); + } + + /** + * @brief Generate call to a function/method. + * @param method = function/method being called + * @param argVRVals = its call parameters (zero length if none) + * @param call = where in source code call is being made from (for error messages) + * @returns type and location of return value (CompValuVoid if none) + */ + private CompValu GenerateACall(CompValu method, CompValu[] argRVals, Token call) + { + CompValuTemp result; + int i, nArgs; + TokenType retType; + TokenType[] argTypes; + + // Must be some kind of callable. + retType = method.GetRetType(); // TokenTypeVoid if void; null means a variable + if(retType == null) + { + ErrorMsg(call, "must be a delegate, function or method"); + return new CompValuVoid(call); + } + + // Get a location for return value. + if(retType is TokenTypeVoid) + { + result = new CompValuVoid(call); + } + else + { + result = new CompValuTemp(retType, this); + } + + // Make sure all arguments are trivial, ie, don't involve their own call labels. + // For any that aren't, output code to calculate the arg and put in a temporary. + nArgs = argRVals.Length; + for(i = 0; i < nArgs; i++) + { + if(!argRVals[i].IsReadTrivial(this, call)) + { + argRVals[i] = Trivialize(argRVals[i], call); + } + } + + // Inline functions know how to generate their own call. + if(method is CompValuInline) + { + CompValuInline inline = (CompValuInline)method; + inline.declInline.CodeGen(this, call, result, argRVals); + return result; + } + + // Push whatever the function/method needs as a this argument, if anything. + method.CallPre(this, call); + + // Push the script-visible args, left-to-right. + argTypes = method.GetArgTypes(); + for(i = 0; i < nArgs; i++) + { + if(argTypes == null) + { + argRVals[i].PushVal(this, call); + } + else + { + argRVals[i].PushVal(this, call, argTypes[i]); + } + } + + // Now output call instruction. + method.CallPost(this, call); + + // Deal with the return value (if any), by putting it in 'result'. + result.Pop(this, call, retType); + return result; + } + + /** + * @brief This is needed to avoid nesting call labels around non-trivial properties. + * It should be used for the second (and later) operands. + * Note that a 'call' is considered an operator, so all arguments of a call + * should be trivialized, but the method itself does not need to be. + */ + public CompValu Trivialize(CompValu operand, Token errorAt) + { + if(operand.IsReadTrivial(this, errorAt)) + return operand; + CompValuTemp temp = new CompValuTemp(operand.type, this); + operand.PushVal(this, errorAt); + temp.Pop(this, errorAt); + return temp; + } + + /** + * @brief Generate code that casts a value to a particular type. + * @returns where the result of the conversion is stored. + */ + private CompValu GenerateFromRValCast(TokenRValCast cast) + { + // If casting to a delegate type, use the argment signature + // of the delegate to help select the function/method, eg, + // '(delegate string(integer))ToString' + // will select 'string ToString(integer x)' + // instaead of 'string ToString(float x)' or anything else + TokenType[] argsig = null; + TokenType outType = cast.castTo; + if(outType is TokenTypeSDTypeDelegate) + { + argsig = ((TokenTypeSDTypeDelegate)outType).decl.GetArgTypes(); + } + + // Generate the value that is being cast. + // If the value is already the requested type, just use it as is. + CompValu inRVal = GenerateFromRVal(cast.rVal, argsig); + if(inRVal.type == outType) + return inRVal; + + // Different type, generate casting code, putting the result in a temp of the output type. + CompValu outRVal = new CompValuTemp(outType, this); + outRVal.PopPre(this, cast); + inRVal.PushVal(this, cast, outType, true); + outRVal.PopPost(this, cast); + return outRVal; + } + + /** + * @brief Compute conditional expression value. + * @returns type and location of computed value. + */ + private CompValu GenerateFromRValCondExpr(TokenRValCondExpr rValCondExpr) + { + bool condVal; + CompValu condValu = GenerateFromRVal(rValCondExpr.condExpr); + if(IsConstBoolExpr(condValu, out condVal)) + { + return GenerateFromRVal(condVal ? rValCondExpr.trueExpr : rValCondExpr.falseExpr); + } + + ScriptMyLabel falseLabel = ilGen.DefineLabel("condexfalse"); + ScriptMyLabel doneLabel = ilGen.DefineLabel("condexdone"); + + condValu.PushVal(this, rValCondExpr.condExpr, tokenTypeBool); + ilGen.Emit(rValCondExpr, OpCodes.Brfalse, falseLabel); + + CompValu trueValu = GenerateFromRVal(rValCondExpr.trueExpr); + trueValu.PushVal(this, rValCondExpr.trueExpr); + ilGen.Emit(rValCondExpr, OpCodes.Br, doneLabel); + + ilGen.MarkLabel(falseLabel); + CompValu falseValu = GenerateFromRVal(rValCondExpr.falseExpr); + falseValu.PushVal(this, rValCondExpr.falseExpr); + + if(trueValu.type.GetType() != falseValu.type.GetType()) + { + ErrorMsg(rValCondExpr, "? operands " + trueValu.type.ToString() + " : " + + falseValu.type.ToString() + " must be of same type"); + } + + ilGen.MarkLabel(doneLabel); + CompValuTemp retRVal = new CompValuTemp(trueValu.type, this); + retRVal.Pop(this, rValCondExpr); + return retRVal; + } + + /** + * @brief Constant in the script somewhere + * @returns where the constants value is stored + */ + private CompValu GenerateFromRValConst(TokenRValConst rValConst) + { + switch(rValConst.type) + { + case TokenRValConstType.CHAR: + { + return new CompValuChar(new TokenTypeChar(rValConst), (char)(rValConst.val)); + } + case TokenRValConstType.FLOAT: + { + return new CompValuFloat(new TokenTypeFloat(rValConst), (double)(rValConst.val)); + } + case TokenRValConstType.INT: + { + return new CompValuInteger(new TokenTypeInt(rValConst), (int)(rValConst.val)); + } + case TokenRValConstType.KEY: + { + return new CompValuString(new TokenTypeKey(rValConst), (string)(rValConst.val)); + } + case TokenRValConstType.STRING: + { + return new CompValuString(new TokenTypeStr(rValConst), (string)(rValConst.val)); + } + } + throw new Exception("unknown constant type " + rValConst.val.GetType()); + } + + /** + * @brief generate a new list object + * @param rValList = an rVal to create it from + */ + private CompValu GenerateFromRValList(TokenRValList rValList) + { + // Compute all element values and remember where we put them. + // Do it right-to-left as customary for LSL scripts. + int i = 0; + TokenRVal lastRVal = null; + for(TokenRVal val = rValList.rVal; val != null; val = (TokenRVal)val.nextToken) + { + i++; + val.prevToken = lastRVal; + lastRVal = val; + } + CompValu[] vals = new CompValu[i]; + for(TokenRVal val = lastRVal; val != null; val = (TokenRVal)val.prevToken) + { + vals[--i] = GenerateFromRVal(val); + } + + // This is the temp that will hold the created list. + CompValuTemp newList = new CompValuTemp(new TokenTypeList(rValList.rVal), this); + + // Create a temp object[] array to hold all the initial values. + ilGen.Emit(rValList, OpCodes.Ldc_I4, rValList.nItems); + ilGen.Emit(rValList, OpCodes.Newarr, typeof(object)); + + // Populate the array. + i = 0; + for(TokenRVal val = rValList.rVal; val != null; val = (TokenRVal)val.nextToken) + { + + // Get pointer to temp array object. + ilGen.Emit(rValList, OpCodes.Dup); + + // Get index in that array. + ilGen.Emit(rValList, OpCodes.Ldc_I4, i); + + // Store initialization value in array location. + // However, floats and ints need to be converted to LSL_Float and LSL_Integer, + // or things like llSetPayPrice() will puque when they try to cast the elements + // to LSL_Float or LSL_Integer. Likewise with string/LSL_String. + // + // Maybe it's already LSL-boxed so we don't do anything with it except make sure + // it is an object, not a struct. + CompValu eRVal = vals[i++]; + eRVal.PushVal(this, val); + if(eRVal.type.ToLSLWrapType() == null) + { + if(eRVal.type is TokenTypeFloat) + { + ilGen.Emit(val, OpCodes.Newobj, lslFloatConstructorInfo); + ilGen.Emit(val, OpCodes.Box, typeof(LSL_Float)); + } + else if(eRVal.type is TokenTypeInt) + { + ilGen.Emit(val, OpCodes.Newobj, lslIntegerConstructorInfo); + ilGen.Emit(val, OpCodes.Box, typeof(LSL_Integer)); + } + else if((eRVal.type is TokenTypeKey) || (eRVal.type is TokenTypeStr)) + { + ilGen.Emit(val, OpCodes.Newobj, lslStringConstructorInfo); + ilGen.Emit(val, OpCodes.Box, typeof(LSL_String)); + } + else if(eRVal.type.ToSysType().IsValueType) + { + ilGen.Emit(val, OpCodes.Box, eRVal.type.ToSysType()); + } + } + else if(eRVal.type.ToLSLWrapType().IsValueType) + { + + // Convert the LSL value structs to an object of the LSL-boxed type + ilGen.Emit(val, OpCodes.Box, eRVal.type.ToLSLWrapType()); + } + ilGen.Emit(val, OpCodes.Stelem, typeof(object)); + } + + // Create new list object from temp initial value array (whose ref is still on the stack). + ilGen.Emit(rValList, OpCodes.Newobj, lslListConstructorInfo); + newList.Pop(this, rValList); + return newList; + } + + /** + * @brief New array allocation with initializer expressions. + */ + private CompValu GenerateFromRValNewArIni(TokenRValNewArIni rValNewArIni) + { + return MallocAndInitArray(rValNewArIni.arrayType, rValNewArIni.valueList); + } + + /** + * @brief Mallocate and initialize an array from its initialization list. + * @param arrayType = type of the array to be allocated and initialized + * @param values = initialization value list used to size and initialize the array. + * @returns memory location of the resultant initialized array. + */ + private CompValu MallocAndInitArray(TokenType arrayType, TokenList values) + { + TokenDeclSDTypeClass arrayDecl = ((TokenTypeSDTypeClass)arrayType).decl; + TokenType eleType = arrayDecl.arrayOfType; + int rank = arrayDecl.arrayOfRank; + + // Get size of each of the dimensions by scanning the initialization value list + int[] dimSizes = new int[rank]; + FillInDimSizes(dimSizes, 0, rank, values); + + // Figure out where the array's $new() method is + TokenType[] newargsig = new TokenType[rank]; + for(int k = 0; k < rank; k++) + { + newargsig[k] = tokenTypeInt; + } + TokenDeclVar newMeth = FindThisMember(arrayDecl, new TokenName(null, "$new"), newargsig); + + // Output a call to malloc the array with all default values + // array = ArrayType.$new (dimSizes[0], dimSizes[1], ...) + CompValuTemp array = new CompValuTemp(arrayType, this); + PushXMRInst(); + for(int k = 0; k < rank; k++) + { + ilGen.Emit(values, OpCodes.Ldc_I4, dimSizes[k]); + } + ilGen.Emit(values, OpCodes.Call, newMeth.ilGen); + array.Pop(this, arrayType); + + // Figure out where the array's Set() method is + TokenType[] setargsig = new TokenType[rank + 1]; + for(int k = 0; k < rank; k++) + { + setargsig[k] = tokenTypeInt; + } + setargsig[rank] = eleType; + TokenDeclVar setMeth = FindThisMember(arrayDecl, new TokenName(null, "Set"), setargsig); + + // Fill in the array with the initializer values + FillInInitVals(array, setMeth, dimSizes, 0, rank, values, eleType); + + // The array is our resultant value + return array; + } + + /** + * @brief Compute an array's dimensions given its initialization value list + * @param dimSizes = filled in with array's dimensions + * @param dimNo = what dimension the 'values' list applies to + * @param rank = total number of dimensions of the array + * @param values = list of values to initialize the array's 'dimNo' dimension with + * @returns with dimSizes[dimNo..rank-1] filled in + */ + private static void FillInDimSizes(int[] dimSizes, int dimNo, int rank, TokenList values) + { + // the size of a dimension is the largest number of initializer elements at this level + // for dimNo 0, this is the number of elements in the top-level list + if(dimSizes[dimNo] < values.tl.Count) + dimSizes[dimNo] = values.tl.Count; + + // see if there is another dimension to calculate + if(++dimNo < rank) + { + + // its size is the size of the largest initializer list at the next inner level + foreach(Token val in values.tl) + { + if(val is TokenList) + { + TokenList subvals = (TokenList)val; + FillInDimSizes(dimSizes, dimNo, rank, subvals); + } + } + } + } + + /** + * @brief Output code to fill in array's initialization values + * @param array = array to be filled in + * @param setMeth = the array's Set() method + * @param subscripts = holds subscripts being built + * @param dimNo = which dimension the 'values' are for + * @param values = list of initialization values for dimension 'dimNo' + * @param rank = number of dimensions of 'array' + * @param values = list of values to initialize the array's 'dimNo' dimension with + * @param eleType = the element's type + * @returns with code emitted to initialize array's [subscripts[0], ..., subscripts[dimNo-1], *, *, ...] + * dimNo and up completely filled ---^ + */ + private void FillInInitVals(CompValu array, TokenDeclVar setMeth, int[] subscripts, int dimNo, int rank, TokenList values, TokenType eleType) + { + subscripts[dimNo] = 0; + foreach(Token val in values.tl) + { + CompValu initValue = null; + + // If it is a sublist, process it. + // If we don't have enough subscripts yet, hopefully that sublist will have enough. + // If we already have enough subscripts, then that sublist can be for an element of this supposedly jagged array. + if(val is TokenList) + { + TokenList sublist = (TokenList)val; + if(dimNo + 1 < rank) + { + // We don't have enough subscripts yet, hopefully the sublist has the rest. + FillInInitVals(array, setMeth, subscripts, dimNo + 1, rank, sublist, eleType); + } + else if((eleType is TokenTypeSDTypeClass) && (((TokenTypeSDTypeClass)eleType).decl.arrayOfType == null)) + { + // If we aren't a jagged array either, we can't do anything with the sublist. + ErrorMsg(val, "too many brace levels"); + } + else + { + // We are a jagged array, so malloc a subarray and initialize it with the sublist. + // Then we can use that subarray to fill this array's element. + initValue = MallocAndInitArray(eleType, sublist); + } + } + + // If it is a value expression, then output code to compute the value. + if(val is TokenRVal) + { + if(dimNo + 1 < rank) + { + ErrorMsg((Token)val, "not enough brace levels"); + } + else + { + initValue = GenerateFromRVal((TokenRVal)val); + } + } + + // If there is an initValue, output "array.Set (subscript[0], subscript[1], ..., initValue)" + if(initValue != null) + { + array.PushVal(this, val); + for(int i = 0; i <= dimNo; i++) + { + ilGen.Emit(val, OpCodes.Ldc_I4, subscripts[i]); + } + initValue.PushVal(this, val, eleType); + ilGen.Emit(val, OpCodes.Call, setMeth.ilGen); + } + + // That subscript is processed one way or another, on to the next. + subscripts[dimNo]++; + } + } + + /** + * @brief parenthesized expression + * @returns type and location of the result of the computation. + */ + private CompValu GenerateFromRValParen(TokenRValParen rValParen) + { + return GenerateFromRVal(rValParen.rVal); + } + + /** + * @brief create a rotation object from the x,y,z,w value expressions. + */ + private CompValu GenerateFromRValRot(TokenRValRot rValRot) + { + CompValu xRVal, yRVal, zRVal, wRVal; + + xRVal = Trivialize(GenerateFromRVal(rValRot.xRVal), rValRot); + yRVal = Trivialize(GenerateFromRVal(rValRot.yRVal), rValRot); + zRVal = Trivialize(GenerateFromRVal(rValRot.zRVal), rValRot); + wRVal = Trivialize(GenerateFromRVal(rValRot.wRVal), rValRot); + return new CompValuRot(new TokenTypeRot(rValRot), xRVal, yRVal, zRVal, wRVal); + } + + /** + * @brief Using 'this' as a pointer to the current script-defined instance object. + * The value is located in arg #0 of the current instance method. + */ + private CompValu GenerateFromRValThis(TokenRValThis zhis) + { + if(!IsSDTInstMethod()) + { + ErrorMsg(zhis, "cannot access instance member of class from static method"); + return new CompValuVoid(zhis); + } + return new CompValuArg(curDeclFunc.sdtClass.MakeRefToken(zhis), 0); + } + + /** + * @brief 'undefined' constant. + * If this constant gets written to an array element, it will delete that element from the array. + * If the script retrieves an element by key that is not defined, it will get this value. + * This value can be stored in and retrieved from variables of type 'object' or script-defined classes. + * It is a runtime error to cast this value to any other type, eg, + * we don't allow list or string variables to be null pointers. + */ + private CompValu GenerateFromRValUndef(TokenRValUndef rValUndef) + { + return new CompValuNull(new TokenTypeUndef(rValUndef)); + } + + /** + * @brief create a vector object from the x,y,z value expressions. + */ + private CompValu GenerateFromRValVec(TokenRValVec rValVec) + { + CompValu xRVal, yRVal, zRVal; + + xRVal = Trivialize(GenerateFromRVal(rValVec.xRVal), rValVec); + yRVal = Trivialize(GenerateFromRVal(rValVec.yRVal), rValVec); + zRVal = Trivialize(GenerateFromRVal(rValVec.zRVal), rValVec); + return new CompValuVec(new TokenTypeVec(rValVec), xRVal, yRVal, zRVal); + } + + /** + * @brief Generate code to get the default initialization value for a variable. + */ + private CompValu GenerateFromRValInitDef(TokenRValInitDef rValInitDef) + { + TokenType type = rValInitDef.type; + + if(type is TokenTypeChar) + { + return new CompValuChar(type, (char)0); + } + if(type is TokenTypeRot) + { + CompValuFloat x = new CompValuFloat(type, ScriptBaseClass.ZERO_ROTATION.x); + CompValuFloat y = new CompValuFloat(type, ScriptBaseClass.ZERO_ROTATION.y); + CompValuFloat z = new CompValuFloat(type, ScriptBaseClass.ZERO_ROTATION.z); + CompValuFloat s = new CompValuFloat(type, ScriptBaseClass.ZERO_ROTATION.s); + return new CompValuRot(type, x, y, z, s); + } + if((type is TokenTypeKey) || (type is TokenTypeStr)) + { + return new CompValuString(type, ""); + } + if(type is TokenTypeVec) + { + CompValuFloat x = new CompValuFloat(type, ScriptBaseClass.ZERO_VECTOR.x); + CompValuFloat y = new CompValuFloat(type, ScriptBaseClass.ZERO_VECTOR.y); + CompValuFloat z = new CompValuFloat(type, ScriptBaseClass.ZERO_VECTOR.z); + return new CompValuVec(type, x, y, z); + } + if(type is TokenTypeInt) + { + return new CompValuInteger(type, 0); + } + if(type is TokenTypeFloat) + { + return new CompValuFloat(type, 0); + } + if(type is TokenTypeVoid) + { + return new CompValuVoid(type); + } + + // Default for 'object' type is 'undef'. + // Likewise for script-defined classes and interfaces. + if((type is TokenTypeObject) || (type is TokenTypeSDTypeClass) || (type is TokenTypeSDTypeDelegate) || + (type is TokenTypeSDTypeInterface) || (type is TokenTypeExc)) + { + return new CompValuNull(type); + } + + // array and list + CompValuTemp temp = new CompValuTemp(type, this); + PushDefaultValue(type); + temp.Pop(this, rValInitDef, type); + return temp; + } + + /** + * @brief Generate code to process an is expression, and produce a boolean value. + */ + private CompValu GenerateFromRValIsType(TokenRValIsType rValIsType) + { + // Expression we want to know the type of. + CompValu val = GenerateFromRVal(rValIsType.rValExp); + + // Pass it in to top-level type expression decoder. + return GenerateFromTypeExp(val, rValIsType.typeExp); + } + + /** + * @brief See if the type of the given value matches the type expression. + * @param val = where the value to be evaluated is stored + * @param typeExp = script tokens representing type expression + * @returns location where the boolean result is stored + */ + private CompValu GenerateFromTypeExp(CompValu val, TokenTypeExp typeExp) + { + if(typeExp is TokenTypeExpBinOp) + { + CompValu left = GenerateFromTypeExp(val, ((TokenTypeExpBinOp)typeExp).leftOp); + CompValu right = GenerateFromTypeExp(val, ((TokenTypeExpBinOp)typeExp).rightOp); + CompValuTemp result = new CompValuTemp(tokenTypeBool, this); + Token op = ((TokenTypeExpBinOp)typeExp).binOp; + left.PushVal(this, ((TokenTypeExpBinOp)typeExp).leftOp); + right.PushVal(this, ((TokenTypeExpBinOp)typeExp).rightOp); + if(op is TokenKwAnd) + { + ilGen.Emit(typeExp, OpCodes.And); + } + else if(op is TokenKwOr) + { + ilGen.Emit(typeExp, OpCodes.Or); + } + else + { + throw new Exception("unknown TokenTypeExpBinOp " + op.GetType()); + } + result.Pop(this, typeExp); + return result; + } + if(typeExp is TokenTypeExpNot) + { + CompValu interm = GenerateFromTypeExp(val, ((TokenTypeExpNot)typeExp).typeExp); + CompValuTemp result = new CompValuTemp(tokenTypeBool, this); + interm.PushVal(this, ((TokenTypeExpNot)typeExp).typeExp, tokenTypeBool); + ilGen.Emit(typeExp, OpCodes.Ldc_I4_1); + ilGen.Emit(typeExp, OpCodes.Xor); + result.Pop(this, typeExp); + return result; + } + if(typeExp is TokenTypeExpPar) + { + return GenerateFromTypeExp(val, ((TokenTypeExpPar)typeExp).typeExp); + } + if(typeExp is TokenTypeExpType) + { + CompValuTemp result = new CompValuTemp(tokenTypeBool, this); + val.PushVal(this, typeExp); + ilGen.Emit(typeExp, OpCodes.Isinst, ((TokenTypeExpType)typeExp).typeToken.ToSysType()); + ilGen.Emit(typeExp, OpCodes.Ldnull); + ilGen.Emit(typeExp, OpCodes.Ceq); + ilGen.Emit(typeExp, OpCodes.Ldc_I4_1); + ilGen.Emit(typeExp, OpCodes.Xor); + result.Pop(this, typeExp); + return result; + } + if(typeExp is TokenTypeExpUndef) + { + CompValuTemp result = new CompValuTemp(tokenTypeBool, this); + val.PushVal(this, typeExp); + ilGen.Emit(typeExp, OpCodes.Ldnull); + ilGen.Emit(typeExp, OpCodes.Ceq); + result.Pop(this, typeExp); + return result; + } + throw new Exception("unknown TokenTypeExp type " + typeExp.GetType()); + } + + /** + * @brief Push the default (null) value for a particular variable + * @param var = variable to get the default value for + * @returns with value pushed on stack + */ + public void PushVarDefaultValue(TokenDeclVar var) + { + PushDefaultValue(var.type); + } + public void PushDefaultValue(TokenType type) + { + if(type is TokenTypeArray) + { + PushXMRInst(); // instance + ilGen.Emit(type, OpCodes.Newobj, xmrArrayConstructorInfo); + return; + } + if(type is TokenTypeChar) + { + ilGen.Emit(type, OpCodes.Ldc_I4_0); + return; + } + if(type is TokenTypeList) + { + ilGen.Emit(type, OpCodes.Ldc_I4_0); + ilGen.Emit(type, OpCodes.Newarr, typeof(object)); + ilGen.Emit(type, OpCodes.Newobj, lslListConstructorInfo); + return; + } + if(type is TokenTypeRot) + { + // Mono is tOO stOOpid to allow: ilGen.Emit (OpCodes.Ldsfld, zeroRotationFieldInfo); + ilGen.Emit(type, OpCodes.Ldc_R8, ScriptBaseClass.ZERO_ROTATION.x); + ilGen.Emit(type, OpCodes.Ldc_R8, ScriptBaseClass.ZERO_ROTATION.y); + ilGen.Emit(type, OpCodes.Ldc_R8, ScriptBaseClass.ZERO_ROTATION.z); + ilGen.Emit(type, OpCodes.Ldc_R8, ScriptBaseClass.ZERO_ROTATION.s); + ilGen.Emit(type, OpCodes.Newobj, lslRotationConstructorInfo); + return; + } + if((type is TokenTypeKey) || (type is TokenTypeStr)) + { + ilGen.Emit(type, OpCodes.Ldstr, ""); + return; + } + if(type is TokenTypeVec) + { + // Mono is tOO stOOpid to allow: ilGen.Emit (OpCodes.Ldsfld, zeroVectorFieldInfo); + ilGen.Emit(type, OpCodes.Ldc_R8, ScriptBaseClass.ZERO_VECTOR.x); + ilGen.Emit(type, OpCodes.Ldc_R8, ScriptBaseClass.ZERO_VECTOR.y); + ilGen.Emit(type, OpCodes.Ldc_R8, ScriptBaseClass.ZERO_VECTOR.z); + ilGen.Emit(type, OpCodes.Newobj, lslVectorConstructorInfo); + return; + } + if(type is TokenTypeInt) + { + ilGen.Emit(type, OpCodes.Ldc_I4_0); + return; + } + if(type is TokenTypeFloat) + { + ilGen.Emit(type, OpCodes.Ldc_R4, 0.0f); + return; + } + + // Default for 'object' type is 'undef'. + // Likewise for script-defined classes and interfaces. + if((type is TokenTypeObject) || (type is TokenTypeSDTypeClass) || (type is TokenTypeSDTypeInterface) || (type is TokenTypeExc)) + { + ilGen.Emit(type, OpCodes.Ldnull); + return; + } + + // Void is pushed as the default return value of a void function. + // So just push nothing as expected of void functions. + if(type is TokenTypeVoid) + { + return; + } + + // Default for 'delegate' type is 'undef'. + if(type is TokenTypeSDTypeDelegate) + { + ilGen.Emit(type, OpCodes.Ldnull); + return; + } + + throw new Exception("unknown type " + type.GetType().ToString()); + } + + /** + * @brief Determine if the expression has a constant boolean value + * and if so, if the value is true or false. + * @param expr = expression to evaluate + * @returns true: expression is contant and has boolean value true + * false: otherwise + */ + private bool IsConstBoolExprTrue(CompValu expr) + { + bool constVal; + return IsConstBoolExpr(expr, out constVal) && constVal; + } + + private bool IsConstBoolExpr(CompValu expr, out bool constVal) + { + if(expr is CompValuChar) + { + constVal = ((CompValuChar)expr).x != 0; + return true; + } + if(expr is CompValuFloat) + { + constVal = ((CompValuFloat)expr).x != (double)0; + return true; + } + if(expr is CompValuInteger) + { + constVal = ((CompValuInteger)expr).x != 0; + return true; + } + if(expr is CompValuString) + { + string s = ((CompValuString)expr).x; + constVal = s != ""; + if(constVal && (expr.type is TokenTypeKey)) + { + constVal = s != ScriptBaseClass.NULL_KEY; + } + return true; + } + + constVal = false; + return false; + } + + /** + * @brief Determine if the expression has a constant integer value + * and if so, return the integer value. + * @param expr = expression to evaluate + * @returns true: expression is contant and has integer value + * false: otherwise + */ + private bool IsConstIntExpr(CompValu expr, out int constVal) + { + if(expr is CompValuChar) + { + constVal = (int)((CompValuChar)expr).x; + return true; + } + if(expr is CompValuInteger) + { + constVal = ((CompValuInteger)expr).x; + return true; + } + + constVal = 0; + return false; + } + + /** + * @brief Determine if the expression has a constant string value + * and if so, return the string value. + * @param expr = expression to evaluate + * @returns true: expression is contant and has string value + * false: otherwise + */ + private bool IsConstStrExpr(CompValu expr, out string constVal) + { + if(expr is CompValuString) + { + constVal = ((CompValuString)expr).x; + return true; + } + constVal = ""; + return false; + } + + /** + * @brief create table of legal event handler prototypes. + * This is used to make sure script's event handler declrations are valid. + */ + private static VarDict CreateLegalEventHandlers() + { + // Get handler prototypes with full argument lists. + VarDict leh = new InternalFuncDict(typeof(IEventHandlers), false); + + // We want the scripts to be able to declare their handlers with + // fewer arguments than the full argument lists. So define additional + // prototypes with fewer arguments. + TokenDeclVar[] fullArgProtos = new TokenDeclVar[leh.Count]; + int i = 0; + foreach(TokenDeclVar fap in leh) + fullArgProtos[i++] = fap; + + foreach(TokenDeclVar fap in fullArgProtos) + { + TokenArgDecl fal = fap.argDecl; + int fullArgCount = fal.vars.Length; + for(i = 0; i < fullArgCount; i++) + { + TokenArgDecl shortArgList = new TokenArgDecl(null); + for(int j = 0; j < i; j++) + { + TokenDeclVar var = fal.vars[j]; + shortArgList.AddArg(var.type, var.name); + } + TokenDeclVar shortArgProto = new TokenDeclVar(null, null, null); + shortArgProto.name = new TokenName(null, fap.GetSimpleName()); + shortArgProto.retType = fap.retType; + shortArgProto.argDecl = shortArgList; + leh.AddEntry(shortArgProto); + } + } + + return leh; + } + + /** + * @brief Emit a call to CheckRun(), (voluntary multitasking switch) + */ + public void EmitCallCheckRun(Token errorAt, bool stack) + { + if(curDeclFunc.IsFuncTrivial(this)) + throw new Exception(curDeclFunc.fullName + " is supposed to be trivial"); + new CallLabel(this, errorAt); // jump here when stack restored + PushXMRInst(); // instance + ilGen.Emit(errorAt, OpCodes.Call, stack ? checkRunStackMethInfo : checkRunQuickMethInfo); + openCallLabel = null; + } + + /** + * @brief Emit code to push a callNo var on the stack. + */ + public void GetCallNo(Token errorAt, ScriptMyLocal callNoVar) + { + ilGen.Emit(errorAt, OpCodes.Ldloc, callNoVar); + //ilGen.Emit (errorAt, OpCodes.Ldloca, callNoVar); + //ilGen.Emit (errorAt, OpCodes.Volatile); + //ilGen.Emit (errorAt, OpCodes.Ldind_I4); + } + public void GetCallNo(Token errorAt, CompValu callNoVar) + { + callNoVar.PushVal(this, errorAt); + //callNoVar.PushRef (this, errorAt); + //ilGen.Emit (errorAt, OpCodes.Volatile); + //ilGen.Emit (errorAt, OpCodes.Ldind_I4); + } + + /** + * @brief Emit code to set a callNo var to a given constant. + */ + public void SetCallNo(Token errorAt, ScriptMyLocal callNoVar, int val) + { + ilGen.Emit(errorAt, OpCodes.Ldc_I4, val); + ilGen.Emit(errorAt, OpCodes.Stloc, callNoVar); + //ilGen.Emit (errorAt, OpCodes.Ldloca, callNoVar); + //ilGen.Emit (errorAt, OpCodes.Ldc_I4, val); + //ilGen.Emit (errorAt, OpCodes.Volatile); + //ilGen.Emit (errorAt, OpCodes.Stind_I4); + } + public void SetCallNo(Token errorAt, CompValu callNoVar, int val) + { + callNoVar.PopPre(this, errorAt); + ilGen.Emit(errorAt, OpCodes.Ldc_I4, val); + callNoVar.PopPost(this, errorAt); + //callNoVar.PushRef (this, errorAt); + //ilGen.Emit (errorAt, OpCodes.Ldc_I4, val); + //ilGen.Emit (errorAt, OpCodes.Volatile); + //ilGen.Emit (errorAt, OpCodes.Stind_I4); + } + + /** + * @brief handle a unary operator, such as -x. + */ + private CompValu UnOpGenerate(CompValu inRVal, Token opcode) + { + // - Negate + if(opcode is TokenKwSub) + { + if(inRVal.type is TokenTypeFloat) + { + CompValuTemp outRVal = new CompValuTemp(new TokenTypeFloat(opcode), this); + inRVal.PushVal(this, opcode, outRVal.type); // push value to negate, make sure not LSL-boxed + ilGen.Emit(opcode, OpCodes.Neg); // compute the negative + outRVal.Pop(this, opcode); // pop into result + return outRVal; // tell caller where we put it + } + if(inRVal.type is TokenTypeInt) + { + CompValuTemp outRVal = new CompValuTemp(new TokenTypeInt(opcode), this); + inRVal.PushVal(this, opcode, outRVal.type); // push value to negate, make sure not LSL-boxed + ilGen.Emit(opcode, OpCodes.Neg); // compute the negative + outRVal.Pop(this, opcode); // pop into result + return outRVal; // tell caller where we put it + } + if(inRVal.type is TokenTypeRot) + { + CompValuTemp outRVal = new CompValuTemp(inRVal.type, this); + inRVal.PushVal(this, opcode); // push rotation, then call negate routine + ilGen.Emit(opcode, OpCodes.Call, lslRotationNegateMethodInfo); + outRVal.Pop(this, opcode); // pop into result + return outRVal; // tell caller where we put it + } + if(inRVal.type is TokenTypeVec) + { + CompValuTemp outRVal = new CompValuTemp(inRVal.type, this); + inRVal.PushVal(this, opcode); // push vector, then call negate routine + ilGen.Emit(opcode, OpCodes.Call, lslVectorNegateMethodInfo); + outRVal.Pop(this, opcode); // pop into result + return outRVal; // tell caller where we put it + } + ErrorMsg(opcode, "can't negate a " + inRVal.type.ToString()); + return inRVal; + } + + // ~ Complement (bitwise integer) + if(opcode is TokenKwTilde) + { + if(inRVal.type is TokenTypeInt) + { + CompValuTemp outRVal = new CompValuTemp(new TokenTypeInt(opcode), this); + inRVal.PushVal(this, opcode, outRVal.type); // push value to negate, make sure not LSL-boxed + ilGen.Emit(opcode, OpCodes.Not); // compute the complement + outRVal.Pop(this, opcode); // pop into result + return outRVal; // tell caller where we put it + } + ErrorMsg(opcode, "can't complement a " + inRVal.type.ToString()); + return inRVal; + } + + // ! Not (boolean) + // + // We stuff the 0/1 result in an int because I've seen x+!y in scripts + // and we don't want to have to create tables to handle int+bool and + // everything like that. + if(opcode is TokenKwExclam) + { + CompValuTemp outRVal = new CompValuTemp(new TokenTypeInt(opcode), this); + inRVal.PushVal(this, opcode, tokenTypeBool); // anything converts to boolean + ilGen.Emit(opcode, OpCodes.Ldc_I4_1); // then XOR with 1 to flip it + ilGen.Emit(opcode, OpCodes.Xor); + outRVal.Pop(this, opcode); // pop into result + return outRVal; // tell caller where we put it + } + + throw new Exception("unhandled opcode " + opcode.ToString()); + } + + /** + * @brief This is called while trying to compute the value of constant initializers. + * It is passed a name and that name is looked up in the constant tables. + */ + private TokenRVal LookupInitConstants(TokenRVal rVal, ref bool didOne) + { + // If it is a static field of a script-defined type, look it up and hopefully we find a constant there. + TokenDeclVar gblVar; + if(rVal is TokenLValSField) + { + TokenLValSField lvsf = (TokenLValSField)rVal; + if(lvsf.baseType is TokenTypeSDTypeClass) + { + TokenDeclSDTypeClass sdtClass = ((TokenTypeSDTypeClass)lvsf.baseType).decl; + gblVar = sdtClass.members.FindExact(lvsf.fieldName.val, null); + if(gblVar != null) + { + if(gblVar.constant && (gblVar.init is TokenRValConst)) + { + didOne = true; + return gblVar.init; + } + } + } + return rVal; + } + + // Only other thing we handle is stand-alone names. + if(!(rVal is TokenLValName)) + return rVal; + string name = ((TokenLValName)rVal).name.val; + + // If we are doing the initializations for a script-defined type, + // look for the constant among the fields for that type. + if(currentSDTClass != null) + { + gblVar = currentSDTClass.members.FindExact(name, null); + if(gblVar != null) + { + if(gblVar.constant && (gblVar.init is TokenRValConst)) + { + didOne = true; + return gblVar.init; + } + return rVal; + } + } + + // Look it up as a script-defined global variable. + // Then if the variable is defined as a constant and has a constant value, + // we are successful. If it is defined as something else, return failure. + gblVar = tokenScript.variablesStack.FindExact(name, null); + if(gblVar != null) + { + if(gblVar.constant && (gblVar.init is TokenRValConst)) + { + didOne = true; + return gblVar.init; + } + return rVal; + } + + // Maybe it is a built-in symbolic constant. + ScriptConst scriptConst = ScriptConst.Lookup(name); + if(scriptConst != null) + { + rVal = CompValuConst2RValConst(scriptConst.rVal, rVal); + if(rVal is TokenRValConst) + { + didOne = true; + return rVal; + } + } + + // Don't know what it is, return failure. + return rVal; + } + + /** + * @brief This is called while trying to compute the value of constant expressions. + * It is passed a name and that name is looked up in the constant tables. + */ + private TokenRVal LookupBodyConstants(TokenRVal rVal, ref bool didOne) + { + // If it is a static field of a script-defined type, look it up and hopefully we find a constant there. + TokenDeclVar gblVar; + if(rVal is TokenLValSField) + { + TokenLValSField lvsf = (TokenLValSField)rVal; + if(lvsf.baseType is TokenTypeSDTypeClass) + { + TokenDeclSDTypeClass sdtClass = ((TokenTypeSDTypeClass)lvsf.baseType).decl; + gblVar = sdtClass.members.FindExact(lvsf.fieldName.val, null); + if((gblVar != null) && gblVar.constant && (gblVar.init is TokenRValConst)) + { + didOne = true; + return gblVar.init; + } + } + return rVal; + } + + // Only other thing we handle is stand-alone names. + if(!(rVal is TokenLValName)) + return rVal; + string name = ((TokenLValName)rVal).name.val; + + // Scan through the variable stack and hopefully we find a constant there. + // But we stop as soon as we get a match because that's what the script is referring to. + CompValu val; + for(VarDict vars = ((TokenLValName)rVal).stack; vars != null; vars = vars.outerVarDict) + { + TokenDeclVar var = vars.FindExact(name, null); + if(var != null) + { + val = var.location; + goto foundit; + } + + TokenDeclSDTypeClass baseClass = vars.thisClass; + if(baseClass != null) + { + while((baseClass = baseClass.extends) != null) + { + var = baseClass.members.FindExact(name, null); + if(var != null) + { + val = var.location; + goto foundit; + } + } + } + } + + // Maybe it is a built-in symbolic constant. + ScriptConst scriptConst = ScriptConst.Lookup(name); + if(scriptConst != null) + { + val = scriptConst.rVal; + goto foundit; + } + + // Don't know what it is, return failure. + return rVal; + + // Found a CompValu. If it's a simple constant, then use it. + // Otherwise tell caller we failed to simplify. + foundit: + rVal = CompValuConst2RValConst(val, rVal); + if(rVal is TokenRValConst) + { + didOne = true; + } + return rVal; + } + + private static TokenRVal CompValuConst2RValConst(CompValu val, TokenRVal rVal) + { + if(val is CompValuChar) + rVal = new TokenRValConst(rVal, ((CompValuChar)val).x); + if(val is CompValuFloat) + rVal = new TokenRValConst(rVal, ((CompValuFloat)val).x); + if(val is CompValuInteger) + rVal = new TokenRValConst(rVal, ((CompValuInteger)val).x); + if(val is CompValuString) + rVal = new TokenRValConst(rVal, ((CompValuString)val).x); + return rVal; + } + + /** + * @brief Generate code to push XMRInstanceSuperType pointer on stack. + */ + public void PushXMRInst() + { + if(instancePointer == null) + { + ilGen.Emit(null, OpCodes.Ldarg_0); + } + else + { + ilGen.Emit(null, OpCodes.Ldloc, instancePointer); + } + } + + /** + * @returns true: Ldarg_0 gives XMRSDTypeClObj pointer + * - this is the case for instance methods + * false: Ldarg_0 gives XMR_Instance pointer + * - this is the case for both global functions and static methods + */ + public bool IsSDTInstMethod() + { + return (curDeclFunc.sdtClass != null) && + ((curDeclFunc.sdtFlags & ScriptReduce.SDT_STATIC) == 0); + } + + /** + * @brief Look for a simply named function or variable (not a field or method) + */ + public TokenDeclVar FindNamedVar(TokenLValName lValName, TokenType[] argsig) + { + // Look in variable stack for the given name. + for(VarDict vars = lValName.stack; vars != null; vars = vars.outerVarDict) + { + + // first look for it possibly with an argument signature + // so we pick the correct overloaded method + TokenDeclVar var = FindSingleMember(vars, lValName.name, argsig); + if(var != null) + return var; + + // if that fails, try it without the argument signature. + // delegates get entered like any other variable, ie, + // no signature on their name. + if(argsig != null) + { + var = FindSingleMember(vars, lValName.name, null); + if(var != null) + return var; + } + + // if this is the frame for some class members, try searching base class members too + TokenDeclSDTypeClass baseClass = vars.thisClass; + if(baseClass != null) + { + while((baseClass = baseClass.extends) != null) + { + var = FindSingleMember(baseClass.members, lValName.name, argsig); + if(var != null) + return var; + if(argsig != null) + { + var = FindSingleMember(baseClass.members, lValName.name, null); + if(var != null) + return var; + } + } + } + } + + // If not found, try one of the built-in constants or functions. + if(argsig == null) + { + ScriptConst scriptConst = ScriptConst.Lookup(lValName.name.val); + if(scriptConst != null) + { + TokenDeclVar var = new TokenDeclVar(lValName.name, null, tokenScript); + var.name = lValName.name; + var.type = scriptConst.rVal.type; + var.location = scriptConst.rVal; + return var; + } + } + else + { + TokenDeclVar inline = FindSingleMember(TokenDeclInline.inlineFunctions, lValName.name, argsig); + if(inline != null) + return inline; + } + + return null; + } + + + /** + * @brief Find a member of an interface. + * @param sdType = interface type + * @param name = name of member to find + * @param argsig = null: field/property; else: script-visible method argument types + * @param baseRVal = pointer to interface object + * @returns null: no such member + * else: pointer to member + * baseRVal = possibly modified to point to type-casted interface object + */ + private TokenDeclVar FindInterfaceMember(TokenTypeSDTypeInterface sdtType, TokenName name, TokenType[] argsig, ref CompValu baseRVal) + { + TokenDeclSDTypeInterface sdtDecl = sdtType.decl; + TokenDeclSDTypeInterface impl; + TokenDeclVar declVar = sdtDecl.FindIFaceMember(this, name, argsig, out impl); + if((declVar != null) && (impl != sdtDecl)) + { + // Accessing a method or propterty of another interface that the primary interface says it implements. + // In this case, we have to cast from the primary interface to that secondary interface. + // + // interface IEnumerable { + // IEnumerator GetEnumerator (); + // } + // interface ICountable : IEnumerable { + // integer GetCount (); + // } + // class List : ICountable { + // public GetCount () : ICountable { ... } + // public GetEnumerator () : IEnumerable { ... } + // } + // + // ICountable aList = new List (); + // IEnumerator anEnumer = aList.GetEnumerator (); << we are here + // << baseRVal = aList + // << sdtDecl = ICountable + // << impl = IEnumerable + // << name = GetEnumerator + // << argsig = () + // So we have to cast aList from ICountable to IEnumerable. + + // make type token for the secondary interface type + TokenType subIntfType = impl.MakeRefToken(name); + + // make a temp variable of the secondary interface type + CompValuTemp castBase = new CompValuTemp(subIntfType, this); + + // output code to cast from the primary interface to the secondary interface + // this is 2 basic steps: + // 1) cast from primary interface object -> class object + // ...gets it from interfaceObject.delegateArray[0].Target + // 2) cast from class object -> secondary interface object + // ...gets it from classObject.sdtcITable[interfaceIndex] + baseRVal.PushVal(this, name, subIntfType); + + // save result of casting in temp + castBase.Pop(this, name); + + // return temp reference + baseRVal = castBase; + } + + return declVar; + } + + /** + * @brief Find a member of a script-defined type class. + * @param sdtType = reference to class declaration + * @param name = name of member to find + * @param argsig = argument signature used to select among overloaded members + * @returns null: no such member found + * else: the member found + */ + public TokenDeclVar FindThisMember(TokenTypeSDTypeClass sdtType, TokenName name, TokenType[] argsig) + { + return FindThisMember(sdtType.decl, name, argsig); + } + public TokenDeclVar FindThisMember(TokenDeclSDTypeClass sdtDecl, TokenName name, TokenType[] argsig) + { + for(TokenDeclSDTypeClass sdtd = sdtDecl; sdtd != null; sdtd = sdtd.extends) + { + TokenDeclVar declVar = FindSingleMember(sdtd.members, name, argsig); + if(declVar != null) + return declVar; + } + return null; + } + + /** + * @brief Look for a single member that matches the given name and argument signature + * @param where = which dictionary to look in + * @param name = basic name of the field or method, eg, "Printable" + * @param argsig = argument types the method is being called with, eg, "(string)" + * or null to find a field + * @returns null: no member found + * else: the member found + */ + public TokenDeclVar FindSingleMember(VarDict where, TokenName name, TokenType[] argsig) + { + TokenDeclVar[] members = where.FindCallables(name.val, argsig); + if(members == null) + return null; + if(members.Length > 1) + { + ErrorMsg(name, "more than one matching member"); + for(int i = 0; i < members.Length; i++) + { + ErrorMsg(members[i], " " + members[i].argDecl.GetArgSig()); + } + } + return members[0]; + } + + /** + * @brief Find an exact function name and argument signature match. + * Also verify that the return value type is an exact match. + * @param where = which method dictionary to look in + * @param name = basic name of the method, eg, "Printable" + * @param ret = expected return value type + * @param argsig = argument types the method is being called with, eg, "(string)" + * @returns null: no exact match found + * else: the matching function + */ + private TokenDeclVar FindExactWithRet(VarDict where, TokenName name, TokenType ret, TokenType[] argsig) + { + TokenDeclVar func = where.FindExact(name.val, argsig); + if((func != null) && (func.retType.ToString() != ret.ToString())) + { + ErrorMsg(name, "return type mismatch, have " + func.retType.ToString() + ", expect " + ret.ToString()); + } + if(func != null) + CheckAccess(func, name); + return func; + } + + /** + * @brief Check the private/protected/public access flags of a member. + */ + private void CheckAccess(TokenDeclVar var, Token errorAt) + { + TokenDeclSDType nested; + TokenDeclSDType definedBy = var.sdtClass; + TokenDeclSDType accessedBy = curDeclFunc.sdtClass; + + //******************************* + // Check member-level access + //******************************* + + // Note that if accessedBy is null, ie, accessing from global function (or event handlers), + // anything tagged as SDT_PRIVATE or SDT_PROTECTED will fail. + + // Private means accessed by the class that defined the member or accessed by a nested class + // of the class that defined the member. + if((var.sdtFlags & ScriptReduce.SDT_PRIVATE) != 0) + { + for(nested = accessedBy; nested != null; nested = nested.outerSDType) + { + if(nested == definedBy) + goto acc1ok; + } + ErrorMsg(errorAt, "private member " + var.fullName + " cannot be accessed by " + curDeclFunc.fullName); + return; + } + + // Protected means: + // If being accessed by an inner class, the inner class has access to it if the inner class derives + // from the declaring class. It also has access to it if an outer class derives from the declaring + // class. + if((var.sdtFlags & ScriptReduce.SDT_PROTECTED) != 0) + { + for(nested = accessedBy; nested != null; nested = nested.outerSDType) + { + for(TokenDeclSDType rootward = nested; rootward != null; rootward = rootward.extends) + { + if(rootward == definedBy) + goto acc1ok; + } + } + ErrorMsg(errorAt, "protected member " + var.fullName + " cannot be accessed by " + curDeclFunc.fullName); + return; + } + acc1ok: + + //****************************** + // Check class-level access + //****************************** + + // If being accessed by same or inner class than where defined, it is ok. + // + // class DefiningClass { + // varBeingAccessed; + // . + // . + // . + // class AccessingClass { + // functionDoingAccess() { } + // } + // . + // . + // . + // } + nested = accessedBy; + while(true) + { + if(nested == definedBy) + return; + if(nested == null) + break; + nested = (TokenDeclSDTypeClass)nested.outerSDType; + } + + // It is being accessed by an outer class than where defined, + // check for a 'private' or 'protected' class tag that blocks. + do + { + // If the field's class is defined directly inside the accessing class, + // access is allowed regardless of class-level private or protected tags. + // + // class AccessingClass { + // functionDoingAccess() { } + // class DefiningClass { + // varBeingAccessed; + // } + // } + if(definedBy.outerSDType == accessedBy) + return; + + // If the field's class is defined two or more levels inside the accessing class, + // access is denied if the defining class is tagged private. + // + // class AccessingClass { + // functionDoingAccess() { } + // . + // . + // . + // class IntermediateClass { + // private class DefiningClass { + // varBeingAccessed; + // } + // } + // . + // . + // . + // } + if((definedBy.accessLevel & ScriptReduce.SDT_PRIVATE) != 0) + { + ErrorMsg(errorAt, "member " + var.fullName + " cannot be accessed by " + curDeclFunc.fullName + + " because of private class " + definedBy.longName.val); + return; + } + + // Likewise, if DefiningClass is tagged protected, the AccessingClass must derive from the + // IntermediateClass or access is denied. + if((definedBy.accessLevel & ScriptReduce.SDT_PROTECTED) != 0) + { + for(TokenDeclSDType extends = accessedBy; extends != definedBy.outerSDType; extends = extends.extends) + { + if(extends == null) + { + ErrorMsg(errorAt, "member " + var.fullName + " cannot be accessed by " + curDeclFunc.fullName + + " because of protected class " + definedBy.longName.val); + return; + } + } + } + + // Check next outer level. + definedBy = definedBy.outerSDType; + } while(definedBy != null); + } + + /** + * @brief Convert a list of argument types to printable string, eg, "(list,string,float,integer)" + * If given a null, return "" indicating it is a field not a method + */ + public static string ArgSigString(TokenType[] argsig) + { + if(argsig == null) + return ""; + StringBuilder sb = new StringBuilder("("); + for(int i = 0; i < argsig.Length; i++) + { + if(i > 0) + sb.Append(","); + sb.Append(argsig[i].ToString()); + } + sb.Append(")"); + return sb.ToString(); + } + + /** + * @brief output error message and remember that we did + */ + public void ErrorMsg(Token token, string message) + { + if((token == null) || (token.emsg == null)) + token = errorMessageToken; + if(!youveAnError || (token.file != lastErrorFile) || (token.line > lastErrorLine)) + { + token.ErrorMsg(message); + youveAnError = true; + lastErrorFile = token.file; + lastErrorLine = token.line; + } + } + + /** + * @brief Find a private static method. + * @param owner = class the method is part of + * @param name = name of method to find + * @param args = array of argument types + * @returns pointer to method + */ + public static MethodInfo GetStaticMethod(Type owner, string name, Type[] args) + { + MethodInfo mi = owner.GetMethod(name, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, args, null); + if(mi == null) + { + throw new Exception("undefined method " + owner.ToString() + "." + name); + } + return mi; + } + + // http://wiki.secondlife.com/wiki/Rotation 'negate a rotation' says just negate .s component + // but http://wiki.secondlife.com/wiki/LSL_Language_Test (lslangtest1.lsl) says negate all 4 values + public static LSL_Rotation LSLRotationNegate(LSL_Rotation r) + { + return new LSL_Rotation(-r.x, -r.y, -r.z, -r.s); + } + public static LSL_Vector LSLVectorNegate(LSL_Vector v) + { + return -v; + } + public static string CatchExcToStr(Exception exc) + { + return exc.ToString(); + } + //public static void ConsoleWrite (string str) { Console.Write(str); } + + /** + * @brief Defines an internal label that is used as a target for 'break' and 'continue' statements. + */ + private class BreakContTarg + { + public bool used; + public ScriptMyLabel label; + public TokenStmtBlock block; + + public BreakContTarg(ScriptCodeGen scg, string name) + { + used = false; // assume it isn't referenced at all + label = scg.ilGen.DefineLabel(name); // label that the break/continue jumps to + block = scg.curStmtBlock; // { ... } that the break/continue label is in + } + } + } + + /** + * @brief Marker interface indicates an exception that can't be caught by a script-level try/catch. + */ + public interface IXMRUncatchable + { + } + + /** + * @brief Thrown by a script when it attempts to change to an undefined state. + * These can be detected at compile time but the moron XEngine compiles + * such things, so we compile them as runtime errors. + */ + [SerializableAttribute] + public class ScriptUndefinedStateException: Exception, ISerializable + { + public string stateName; + public ScriptUndefinedStateException(string stateName) : base("undefined state " + stateName) + { + this.stateName = stateName; + } + protected ScriptUndefinedStateException(SerializationInfo info, StreamingContext context) : base(info, context) + { + } + } + + /** + * @brief Created by a throw statement. + */ + [SerializableAttribute] + public class ScriptThrownException: Exception, ISerializable + { + public object thrown; + + /** + * @brief Called by a throw statement to wrap the object in a unique + * tag that capable of capturing a stack trace. Script can + * unwrap it by calling xmrExceptionThrownValue(). + */ + public static Exception Wrap(object thrown) + { + return new ScriptThrownException(thrown); + } + private ScriptThrownException(object thrown) : base(thrown.ToString()) + { + this.thrown = thrown; + } + + /** + * @brief Used by serialization/deserialization. + */ + protected ScriptThrownException(SerializationInfo info, StreamingContext context) : base(info, context) + { + } + } + + /** + * @brief Thrown by a script when it attempts to change to a defined state. + */ + [SerializableAttribute] + public class ScriptChangeStateException: Exception, ISerializable, IXMRUncatchable + { + public int newState; + public ScriptChangeStateException(int newState) + { + this.newState = newState; + } + protected ScriptChangeStateException(SerializationInfo info, StreamingContext context) : base(info, context) + { + } + } + + /** + * @brief We are restoring to the body of a catch { } so we need to + * wrap the original exception in an outer exception, so the + * system won't try to refill the stack trace. + * + * We don't mark this one serializable as it should never get + * serialized out. It only lives from the throw to the very + * beginning of the catch handler where it is promptly unwrapped. + * No CheckRun() call can possibly intervene. + */ + public class ScriptRestoreCatchException: Exception + { + + // old code uses these + private object e; + public ScriptRestoreCatchException(object e) + { + this.e = e; + } + public static object Unwrap(object o) + { + if(o is IXMRUncatchable) + return null; + if(o is ScriptRestoreCatchException) + return ((ScriptRestoreCatchException)o).e; + return o; + } + + // new code uses these + private Exception ee; + public ScriptRestoreCatchException(Exception ee) + { + this.ee = ee; + } + public static Exception Unwrap(Exception oo) + { + if(oo is IXMRUncatchable) + return null; + if(oo is ScriptRestoreCatchException) + return ((ScriptRestoreCatchException)oo).ee; + return oo; + } + } + + [SerializableAttribute] + public class ScriptBadCallNoException: Exception + { + public ScriptBadCallNoException(int callNo) : base("bad callNo " + callNo) { } + protected ScriptBadCallNoException(SerializationInfo info, StreamingContext context) : base(info, context) + { + } + } + + public class CVVMismatchException: Exception + { + public CVVMismatchException(string msg) : base(msg) + { + } + } +} diff --git a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptCollector.cs b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptCollector.cs new file mode 100644 index 0000000000..75eae53627 --- /dev/null +++ b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptCollector.cs @@ -0,0 +1,3040 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using OpenSim.Region.ScriptEngine.Shared.ScriptBase; +using System; +using System.Collections.Generic; +using System.IO; +using System.Reflection; +using System.Reflection.Emit; +using System.Text; + + +/** + * @brief Wrapper class for ScriptMyILGen to do simple optimizations. + * The main one is to figure out which locals are active at the labels + * so the stack capture/restore code doesn't have to do everything. + * Second is it removes unnecessary back-to-back stloc/ldloc's. + */ + +namespace OpenSim.Region.ScriptEngine.Yengine +{ + /** + * @brief This is a list that keeps track of types pushed on the evaluation stack. + */ + public class StackDepth: List + { + public List isBoxeds = new List(); + + /** + * @brief Clear both stacks. + */ + public new void Clear() + { + base.Clear(); + isBoxeds.Clear(); + } + + /** + * @brief Pop call parameters and validate the types. + */ + public void Pop(ParameterInfo[] pis) + { + int n = pis.Length; + int c = this.Count; + if(n > c) + throw new Exception("stack going negative"); + for(int i = n; --i >= 0;) + { + --c; + ExpectedVsOnStack(pis[i].ParameterType, this[c], isBoxeds[c]); + } + Pop(n); + } + + /** + * @brief Pop values and validate the types. + */ + public void Pop(Type[] ts) + { + int n = ts.Length; + int c = this.Count; + if(n > c) + throw new Exception("stack going negative"); + for(int i = ts.Length; --i >= 0;) + { + --c; + ExpectedVsOnStack(ts[i], this[c], isBoxeds[c]); + } + Pop(n); + } + + /** + * @brief Pop a single value and validate the type. + */ + public void Pop(Type t) + { + int c = this.Count; + if(c < 1) + throw new Exception("stack going negative"); + ExpectedVsOnStack(t, this[c - 1], isBoxeds[c - 1]); + Pop(1); + } + + /** + * @brief Pop a single value and validate that it is a numeric type. + */ + public Type PopNumVal() + { + int c = this.Count; + if(c < 1) + throw new Exception("stack going negative"); + Type st = this[--c]; + if(st == null) + { + throw new Exception("stack has null, expecting a numeric"); + } + if(isBoxeds[c]) + { + throw new Exception("stack is boxed " + st.Name + ", expecting a numeric"); + } + if((st != typeof(bool)) && (st != typeof(char)) && (st != typeof(int)) && + (st != typeof(long)) && (st != typeof(float)) && (st != typeof(double))) + { + throw new Exception("stack has " + st.Name + ", expecting a numeric"); + } + return Pop(1); + } + + /** + * @brief Pop a single value and validate that it is a reference type + */ + public Type PopRef() + { + int c = this.Count; + if(c < 1) + throw new Exception("stack going negative"); + Type st = this[--c]; + if((st != null) && !isBoxeds[c] && st.IsValueType) + { + throw new Exception("stack has " + st.Name + ", expecting a ref type"); + } + return Pop(1); + } + + /** + * @brief Pop a single value and validate that it is a value type + */ + public Type PopValue() + { + int c = this.Count; + if(c < 1) + throw new Exception("stack going negative"); + Type st = this[--c]; + if(st == null) + { + throw new Exception("stack has null, expecting a value type"); + } + if(!st.IsValueType) + { + throw new Exception("stack has " + st.Name + ", expecting a value type"); + } + if(isBoxeds[c]) + { + throw new Exception("stack has boxed " + st.Name + ", expecting an unboxed value type"); + } + return Pop(1); + } + + // ex = what is expected to be on stack + // st = what is actually on stack (null for ldnull) + // stBoxed = stack value is boxed + public static void ExpectedVsOnStack(Type ex, Type st, bool stBoxed) + { + // ldnull pushed on stack can go into any pointer type + if(st == null) + { + if(ex.IsByRef || ex.IsPointer || ex.IsClass || ex.IsInterface) + return; + throw new Exception("stack has null, expect " + ex.Name); + } + + // simple case of expecting an object + // ...so the stack can have object,string, etc + // but we cant allow int = boxed int here + if(ex.IsAssignableFrom(st) && !stBoxed) + return; + + // case of expecting an enum on the stack + // but all the CIL code knows about are ints etc + // so convert the Enum type to integer or whatever + // and that should be assignable from what's on stack + if(ex.IsEnum && typeof(int).IsAssignableFrom(st)) + return; + + // bool, char, int are interchangeable on the stack + if((ex == typeof(bool) || ex == typeof(char) || ex == typeof(int)) && + (st == typeof(bool) || st == typeof(char) || st == typeof(int))) + return; + + // float and double are interchangeable on the stack + if((ex == typeof(float) || ex == typeof(double)) && + (st == typeof(float) || st == typeof(double))) + return; + + // object can accept any boxed type + if((ex == typeof(object)) && stBoxed) + return; + + // otherwise, it is disallowed + throw new Exception("stack has " + StackTypeString(st, stBoxed) + ", expect " + ex.Name); + } + + /** + * @brief Pop values without any validation. + */ + public Type Pop(int n) + { + if(this.Count != isBoxeds.Count) + throw new Exception("isBoxeds count bad"); + Type lastPopped = null; + int c = this.Count; + if(n > c) + throw new Exception("stack going negative"); + if(n > 0) + { + lastPopped = this[c - n]; + this.RemoveRange(c - n, n); + isBoxeds.RemoveRange(c - n, n); + } + if(this.Count != isBoxeds.Count) + throw new Exception("isBoxeds count bad"); + return lastPopped; + } + + /** + * @brief Peek at the n'th stack value. + * n = 0 : top of stack + * 1 : next to top + * ... + */ + public Type Peek(int n) + { + int c = this.Count; + if(n > c - 1) + throw new Exception("stack going negative"); + if(this.Count != isBoxeds.Count) + throw new Exception("isBoxeds count bad"); + return this[c - n - 1]; + } + public bool PeekBoxed(int n) + { + int c = isBoxeds.Count; + if(n > c - 1) + throw new Exception("stack going negative"); + if(this.Count != isBoxeds.Count) + throw new Exception("isBoxeds count bad"); + return isBoxeds[c - n - 1]; + } + + /** + * @brief Push a single value of the given type. + */ + public void Push(Type t) + { + Push(t, false); + } + public void Push(Type t, bool isBoxed) + { + if(this.Count != isBoxeds.Count) + throw new Exception("isBoxeds count bad"); + this.Add(t); + isBoxeds.Add(isBoxed); + } + + /** + * @brief See if the types at a given label exactly match those on the stack. + * We should have the stack types be the same no matter how we branched + * or fell through to a particular label. + */ + public void Matches(ScriptMyLabel label) + { + Type[] ts = label.stackDepth; + bool[] tsBoxeds = label.stackBoxeds; + int i; + + if(this.Count != isBoxeds.Count) + throw new Exception("isBoxeds count bad"); + + if(ts == null) + { + label.stackDepth = this.ToArray(); + label.stackBoxeds = isBoxeds.ToArray(); + } + else if(ts.Length != this.Count) + { + throw new Exception("stack depth mismatch"); + } + else + { + for(i = this.Count; --i >= 0;) + { + if(tsBoxeds[i] != this.isBoxeds[i]) + goto mismatch; + if(ts[i] == this[i]) + continue; + if((ts[i] == typeof(bool) || ts[i] == typeof(char) || ts[i] == typeof(int)) && + (this[i] == typeof(bool) || this[i] == typeof(char) || this[i] == typeof(int))) + continue; + if((ts[i] == typeof(double) || ts[i] == typeof(float)) && + (this[i] == typeof(double) || this[i] == typeof(float))) + continue; + goto mismatch; + } + } + return; + mismatch: + throw new Exception("stack type mismatch: " + StackTypeString(ts[i], tsBoxeds[i]) + " vs " + StackTypeString(this[i], this.isBoxeds[i])); + } + + private static string StackTypeString(Type ts, bool isBoxed) + { + if(!isBoxed) + return ts.Name; + return "[" + ts.Name + "]"; + } + } + + /** + * @brief One of these per opcode and label in the function plus other misc markers. + * They form the CIL instruction stream of the function. + */ + public abstract class GraphNode + { + private static readonly bool DEBUG = false; + + public const int OPINDENT = 4; + public const int OPDEBLEN = 12; + + public ScriptCollector coll; + public GraphNodeBeginExceptionBlock tryBlock; // start of enclosing try block + // valid in the try section + // null in the catch/finally sections + // null outside of try block + // for the try node itself, links to outer try block + public GraphNodeBeginExceptionBlock excBlock; // start of enclosing try block + // valid in the try/catch/finally sections + // null outside of try/catch/finally block + // for the try node itself, links to outer try block + + /* + * List of nodes in order as originally given. + */ + public GraphNode nextLin, prevLin; + public int linSeqNo; + + /** + * @brief Save pointer to collector. + */ + public GraphNode(ScriptCollector coll) + { + this.coll = coll; + } + + /** + * @brief Chain graph node to end of linear list. + */ + public virtual void ChainLin() + { + coll.lastLin.nextLin = this; + this.prevLin = coll.lastLin; + coll.lastLin = this; + this.tryBlock = coll.curTryBlock; + this.excBlock = coll.curExcBlock; + + if(DEBUG) + { + StringBuilder sb = new StringBuilder("ChainLin*:"); + sb.Append(coll.stackDepth.Count.ToString("D2")); + sb.Append(' '); + this.DebString(sb); + Console.WriteLine(sb.ToString()); + } + } + + /** + * @brief Append full info to debugging string for printing out the instruction. + */ + public void DebStringExt(StringBuilder sb) + { + int x = sb.Length; + sb.Append(this.linSeqNo.ToString().PadLeft(5)); + sb.Append(": "); + this.DebString(sb); + + if(this.ReadsLocal() != null) + ScriptCollector.PadToLength(sb, x + 60, " [read]"); + if(this.WritesLocal() != null) + ScriptCollector.PadToLength(sb, x + 68, " [write]"); + ScriptCollector.PadToLength(sb, x + 72, " ->"); + bool first = true; + foreach(GraphNode nn in this.NextNodes) + { + if(first) + { + sb.Append(nn.linSeqNo.ToString().PadLeft(5)); + first = false; + } + else + { + sb.Append(','); + sb.Append(nn.linSeqNo); + } + } + } + + /** + * @brief See if it's possible for it to fall through to the next inline (nextLin) instruction. + */ + public virtual bool CanFallThrough() + { + return true; + } + + /** + * @brief Append to debugging string for printing out the instruction. + */ + public abstract void DebString(StringBuilder sb); + public override string ToString() + { + StringBuilder sb = new StringBuilder(); + this.DebString(sb); + return sb.ToString(); + } + + /** + * @brief See if this instruction reads a local variable. + */ + public virtual ScriptMyLocal ReadsLocal() + { + return null; + } + + /** + * @brief See if this instruction writes a local variable. + */ + public virtual ScriptMyLocal WritesLocal() + { + return null; + } + + /** + * @brief Write this instruction out to the wrapped object file. + */ + public abstract void WriteOutOne(ScriptMyILGen ilGen); + + /** + * @brief Iterate through all the possible next nodes, including the next inline node, if any. + * The next inline code is excluded if the instruction never falls through, eg, return, unconditional branch. + * It includes a possible conditional branch to the beginning of the corresponding catch/finally of every + * instruction in a try section. + */ + private System.Collections.Generic.IEnumerable nextNodes, nextNodesCatchFinally; + public System.Collections.Generic.IEnumerable NextNodes + { + get + { + if(nextNodes == null) + { + nextNodes = GetNNEnumerable(); + nextNodesCatchFinally = new NNEnumerableCatchFinally(this); + } + return nextNodesCatchFinally; + } + } + + /** + * @brief This acts as a wrapper around all the other NNEnumerable's below. + * It assumes every instruction in a try { } can throw an exception so it + * says that every instruction in a try { } can conditionally branch to + * the beginning of the corresponding catch { } or finally { }. + */ + private class NNEnumerableCatchFinally: System.Collections.Generic.IEnumerable + { + private GraphNode gn; + public NNEnumerableCatchFinally(GraphNode gn) + { + this.gn = gn; + } + System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator() + { + return new NNEnumeratorCatchFinally(gn); + } + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() + { + return new NNEnumeratorCatchFinally(gn); + } + } + private class NNEnumeratorCatchFinally: NNEnumeratorBase + { + private GraphNode gn; + private int index = 0; + private System.Collections.Generic.IEnumerator realEnumerator; + public NNEnumeratorCatchFinally(GraphNode gn) + { + this.gn = gn; + this.realEnumerator = gn.nextNodes.GetEnumerator(); + } + public override bool MoveNext() + { + // First off, return any targets the instruction can come up with. + if(realEnumerator.MoveNext()) + { + nn = realEnumerator.Current; + return true; + } + + // Then if this instruction is in a try section, say this instruction + // can potentially branch to the beginning of the corresponding + // catch/finally. + if((index == 0) && (gn.tryBlock != null)) + { + index++; + nn = gn.tryBlock.catchFinallyBlock; + return true; + } + + // That's all we can do. + nn = null; + return false; + } + public override void Reset() + { + realEnumerator.Reset(); + index = 0; + nn = null; + } + } + + /** + * @brief This default iterator always returns the next inline node as the one-and-only next node. + * Other instructions need to override it if they can possibly do other than that. + */ + + /** + * @brief GetNNEnumerable() gets the nextnode enumerable part of a GraphNode, + * which in turn gives the list of nodes that can possibly be next in + * a flow-control sense. It simply instantiates the NNEnumerator sub- + * class which does the actual enumeration. + */ + protected virtual System.Collections.Generic.IEnumerable GetNNEnumerable() + { + return new NNEnumerable(this, typeof(NNEnumerator)); + } + + private class NNEnumerator: NNEnumeratorBase + { + private GraphNode gn; + private int index; + public NNEnumerator(GraphNode gn) + { + this.gn = gn; + } + public override bool MoveNext() + { + switch(index) + { + case 0: + { + index++; + nn = gn.nextLin; + return nn != null; + } + case 1: + { + nn = null; + return false; + } + } + throw new Exception(); + } + public override void Reset() + { + index = 0; + nn = null; + } + } + } + + /** + * @brief Things that derive from this are the beginning of a block. + * A block of code is that which begins with a label or is the beginning of all code + * and it contains no labels, ie, it can't be jumped into other than at its beginning. + */ + public abstract class GraphNodeBlock: GraphNode + { + public List localsWrittenBeforeRead = new List(); + public List localsReadBeforeWritten = new List(); + public int hasBeenResolved; + public GraphNodeBlock(ScriptCollector coll) : base(coll) { } + } + + /** + * @brief This placeholder is at the beginning of the code so the first few instructions + * belong to some block. + */ + public class GraphNodeBegin: GraphNodeBlock + { + public GraphNodeBegin(ScriptCollector coll) : base(coll) { } + public override void DebString(StringBuilder sb) + { + sb.Append("begin"); + } + public override void WriteOutOne(ScriptMyILGen ilGen) + { + } + } + + /** + * @brief Beginning of try block. + */ + public class GraphNodeBeginExceptionBlock: GraphNodeBlock + { + public GraphNodeBeginExceptionBlock outerTryBlock; // next outer try opcode or null + public GraphNodeCatchFinallyBlock catchFinallyBlock; // start of associated catch or finally + public GraphNodeEndExceptionBlock endExcBlock; // end of associated catch or finally + public int excBlkSeqNo; // debugging + + public GraphNodeBeginExceptionBlock(ScriptCollector coll) : base(coll) + { + } + + public override void ChainLin() + { + base.ChainLin(); + + // we should always start try blocks with nothing on stack + // ...as CLI wipes stack for various conditions + if(coll.stackDepth.Count != 0) + { + throw new Exception("stack depth " + coll.stackDepth.Count); + } + } + + public override void DebString(StringBuilder sb) + { + sb.Append(" beginexceptionblock_"); + sb.Append(excBlkSeqNo); + } + + public override void WriteOutOne(ScriptMyILGen ilGen) + { + ilGen.BeginExceptionBlock(); + } + } + + /** + * @brief Beginning of catch or finally block. + */ + public abstract class GraphNodeCatchFinallyBlock: GraphNodeBlock + { + public GraphNodeCatchFinallyBlock(ScriptCollector coll) : base(coll) + { + } + + public override void ChainLin() + { + base.ChainLin(); + + // we should always start catch/finally blocks with nothing on stack + // ...as CLI wipes stack for various conditions + if(coll.stackDepth.Count != 0) + { + throw new Exception("stack depth " + coll.stackDepth.Count); + } + } + } + + /** + * @brief Beginning of catch block. + */ + public class GraphNodeBeginCatchBlock: GraphNodeCatchFinallyBlock + { + public Type excType; + + public GraphNodeBeginCatchBlock(ScriptCollector coll, Type excType) : base(coll) + { + this.excType = excType; + } + + public override void ChainLin() + { + base.ChainLin(); + + // catch block always enters with one value on stack + if(coll.stackDepth.Count != 0) + { + throw new Exception("stack depth " + coll.stackDepth.Count); + } + coll.stackDepth.Push(excType); + } + + public override void DebString(StringBuilder sb) + { + sb.Append(" begincatchblock_"); + sb.Append(excBlock.excBlkSeqNo); + } + + public override void WriteOutOne(ScriptMyILGen ilGen) + { + ilGen.BeginCatchBlock(excType); + } + + /** + * @brief The beginning of every catch { } conditinally branches to the beginning + * of all outer catch { }s up to and including the next outer finally { }. + */ + protected override System.Collections.Generic.IEnumerable GetNNEnumerable() + { + return new NNEnumerable(this, typeof(NNEnumerator)); + } + + private class NNEnumerator: NNEnumeratorBase + { + private GraphNodeBeginCatchBlock gn; + private int index; + public NNEnumerator(GraphNodeBeginCatchBlock gn) + { + this.gn = gn; + } + public override bool MoveNext() + { + while(true) + { + switch(index) + { + case 0: + { + // start with the fallthru + nn = gn.nextLin; + index++; + return true; + } + + case 1: + { + // get the first outer catch { } or finally { } + // pretend we last returned beginning of this catch { } + // then loop back to get next outer catch { } or finally { } + nn = gn; + break; + } + + case 2: + { + // nn points to a catch { } previously returned + // get the corresponding try { } + GraphNodeBeginExceptionBlock nntry = nn.excBlock; + + // step out to next outer try { } + nntry = nntry.excBlock; + if(nntry == null) + break; + + // return corresponding catch { } or finally { } + nn = nntry.catchFinallyBlock; + + // if it's a finally { } we don't do anything after that + if(nn is GraphNodeBeginFinallyBlock) + index++; + return true; + } + + case 3: + { + // we've returned the fallthru, catches and one finally + // so there's nothing more to say + nn = null; + return false; + } + + default: + throw new Exception(); + } + index++; + } + } + public override void Reset() + { + index = 0; + nn = null; + } + } + } + + /** + * @brief Beginning of finally block. + */ + public class GraphNodeBeginFinallyBlock: GraphNodeCatchFinallyBlock + { + + // leaveTargets has a list of all the targets of any contained + // leave instructions, ie, where an endfinally can possibly jump. + // But only those targets within the next outer finally { }, we + // don't contain any targets outside of that, those targets are + // stored in the actual finally that will jump to the target. + // The endfinally enumerator assumes that it is always possible + // for it to jump to the next outer finally (as would happen for + // an uncaught exception), so no need to do anything special. + public List leaveTargets = new List(); + + public GraphNodeBeginFinallyBlock(ScriptCollector coll) : base(coll) + { + } + + public override void DebString(StringBuilder sb) + { + sb.Append(" beginfinallyblock_"); + sb.Append(excBlock.excBlkSeqNo); + } + + public override void WriteOutOne(ScriptMyILGen ilGen) + { + ilGen.BeginFinallyBlock(); + } + } + + /** + * @brief End of try/catch/finally block. + */ + public class GraphNodeEndExceptionBlock: GraphNode + { + public GraphNodeEndExceptionBlock(ScriptCollector coll) : base(coll) + { + } + + public override void ChainLin() + { + base.ChainLin(); + + // we should always end exception blocks with nothing on stack + // ...as CLI wipes stack for various conditions + if(coll.stackDepth.Count != 0) + { + throw new Exception("stack depth " + coll.stackDepth.Count); + } + } + + public override void DebString(StringBuilder sb) + { + sb.Append(" endexceptionblock_"); + sb.Append(excBlock.excBlkSeqNo); + } + + public override void WriteOutOne(ScriptMyILGen ilGen) + { + ilGen.EndExceptionBlock(); + } + } + + /** + * @brief Actual instruction emits... + */ + public abstract class GraphNodeEmit: GraphNode + { + public OpCode opcode; + public Token errorAt; + + public GraphNodeEmit(ScriptCollector coll, Token errorAt, OpCode opcode) : base(coll) + { + this.opcode = opcode; + this.errorAt = errorAt; + } + + public override void ChainLin() + { + base.ChainLin(); + + // compute resultant stack depth + int stack = coll.stackDepth.Count; + + if((stack != 0) && ((opcode == OpCodes.Endfinally) || (opcode == OpCodes.Leave) || (opcode == OpCodes.Rethrow))) + { + throw new Exception(opcode + " stack depth " + stack); + } + if((stack != 1) && (opcode == OpCodes.Throw)) + { + throw new Exception(opcode + " stack depth " + stack); + } + } + + /** + * @brief See if it's possible for it to fall through to the next inline (nextLin) instruction. + */ + public override bool CanFallThrough() + { + switch(opcode.FlowControl) + { + case FlowControl.Branch: + return false; // unconditional branch + case FlowControl.Break: + return true; // break + case FlowControl.Call: + return true; // call + case FlowControl.Cond_Branch: + return true; // conditional branch + case FlowControl.Next: + return true; // falls through to next instruction + case FlowControl.Return: + return false; // return + case FlowControl.Throw: + return false; // throw + default: + { + string op = opcode.ToString(); + if(op == "volatile.") + return true; + throw new Exception("unknown flow control " + opcode.FlowControl + " for " + op); + } + } + } + + // if followed by OpCodes.Pop, it can be discarded + public bool isPoppable + { + get + { + return + ((opcode.StackBehaviourPop == StackBehaviour.Pop0) && // ldarg,ldloc,ldsfld + (opcode.StackBehaviourPush == StackBehaviour.Push1)) || + ((opcode.StackBehaviourPop == StackBehaviour.Pop0) && // ldarga,ldloca,ldc,ldsflda,... + (opcode.StackBehaviourPush == StackBehaviour.Pushi)) || + (opcode == OpCodes.Ldnull) || + (opcode == OpCodes.Ldc_R4) || + (opcode == OpCodes.Ldc_R8) || + (opcode == OpCodes.Ldstr) || + (opcode == OpCodes.Ldc_I8) || + (opcode == OpCodes.Dup); + } + } + + public override void DebString(StringBuilder sb) + { + sb.Append("".PadRight(OPINDENT)); + sb.Append(opcode.ToString().PadRight(OPDEBLEN)); + } + + /** + * @brief If instruction is terminating, we say there is nothing following (eg, return). + * Otherwise, say the one-and-only next instruction is the next instruction inline. + */ + protected override System.Collections.Generic.IEnumerable GetNNEnumerable() + { + return new NNEnumerable(this, typeof(NNEnumerator)); + } + + private class NNEnumerator: NNEnumeratorBase + { + private GraphNodeEmit gn; + private int index; + public NNEnumerator(GraphNodeEmit gn) + { + this.gn = gn; + } + public override bool MoveNext() + { + switch(index) + { + case 0: + { + if(gn.CanFallThrough()) + { + index++; + nn = gn.nextLin; + return nn != null; + } + return false; + } + case 1: + { + nn = null; + return false; + } + } + throw new Exception(); + } + public override void Reset() + { + index = 0; + nn = null; + } + } + } + + public class GraphNodeEmitNull: GraphNodeEmit + { + public GraphNodeEmitNull(ScriptCollector coll, Token errorAt, OpCode opcode) : base(coll, errorAt, opcode) + { + } + + public override void ChainLin() + { + base.ChainLin(); + + switch(opcode.ToString()) + { + case "nop": + break; + case "break": + break; + case "volatile.": + break; + case "ldarg.0": + coll.stackDepth.Push(coll.wrapped.argTypes[0]); + break; + case "ldarg.1": + coll.stackDepth.Push(coll.wrapped.argTypes[1]); + break; + case "ldarg.2": + coll.stackDepth.Push(coll.wrapped.argTypes[2]); + break; + case "ldarg.3": + coll.stackDepth.Push(coll.wrapped.argTypes[3]); + break; + case "ldnull": + coll.stackDepth.Push(null); + break; + case "ldc.i4.m1": + case "ldc.i4.0": + case "ldc.i4.1": + case "ldc.i4.2": + case "ldc.i4.3": + case "ldc.i4.4": + case "ldc.i4.5": + case "ldc.i4.6": + case "ldc.i4.7": + case "ldc.i4.8": + { + coll.stackDepth.Push(typeof(int)); + break; + } + case "dup": + { + Type t = coll.stackDepth.Peek(0); + bool b = coll.stackDepth.PeekBoxed(0); + coll.stackDepth.Push(t, b); + break; + } + case "pop": + { + coll.stackDepth.Pop(1); + break; + } + case "ret": + { + int sd = (coll.wrapped.retType != typeof(void)) ? 1 : 0; + if(coll.stackDepth.Count != sd) + throw new Exception("bad stack depth"); + if(sd > 0) + { + coll.stackDepth.Pop(coll.wrapped.retType); + } + break; + } + case "add": + case "sub": + case "mul": + case "div": + case "div.un": + case "rem": + case "rem.un": + case "and": + case "or": + case "xor": + case "shl": + case "shr": + case "shr.un": + case "add.ovf": + case "add.ovf.un": + case "mul.ovf": + case "mul.ovf.un": + case "sub.ovf": + case "sub.ovf.un": + { + coll.stackDepth.PopNumVal(); + Type t = coll.stackDepth.PopNumVal(); + coll.stackDepth.Push(t); + break; + } + case "neg": + case "not": + { + Type t = coll.stackDepth.PopNumVal(); + coll.stackDepth.Push(t); + break; + } + case "conv.i1": + case "conv.i2": + case "conv.i4": + case "conv.i8": + case "conv.r4": + case "conv.r8": + case "conv.u4": + case "conv.u8": + case "conv.r.un": + case "conv.ovf.i1.un": + case "conv.ovf.i2.un": + case "conv.ovf.i4.un": + case "conv.ovf.i8.un": + case "conv.ovf.u1.un": + case "conv.ovf.u2.un": + case "conv.ovf.u4.un": + case "conv.ovf.u8.un": + case "conv.ovf.i.un": + case "conv.ovf.u.un": + case "conv.ovf.i1": + case "conv.ovf.u1": + case "conv.ovf.i2": + case "conv.ovf.u2": + case "conv.ovf.i4": + case "conv.ovf.u4": + case "conv.ovf.i8": + case "conv.ovf.u8": + case "conv.u2": + case "conv.u1": + case "conv.i": + case "conv.ovf.i": + case "conv.ovf.u": + case "conv.u": + { + coll.stackDepth.PopNumVal(); + coll.stackDepth.Push(ConvToType(opcode)); + break; + } + case "throw": + { + if(coll.stackDepth.Count != 1) + throw new Exception("bad stack depth " + coll.stackDepth.Count); + coll.stackDepth.PopRef(); + break; + } + case "ldlen": + { + coll.stackDepth.Pop(typeof(string)); + coll.stackDepth.Push(typeof(int)); + break; + } + case "ldelem.i1": + case "ldelem.u1": + case "ldelem.i2": + case "ldelem.u2": + case "ldelem.i4": + case "ldelem.u4": + case "ldelem.i8": + case "ldelem.i": + case "ldelem.r4": + case "ldelem.r8": + case "ldelem.ref": + { + Type t = coll.stackDepth.Peek(1).GetElementType(); + coll.stackDepth.Pop(typeof(int)); + coll.stackDepth.Pop(t.MakeArrayType()); + coll.stackDepth.Push(t); + break; + } + case "stelem.i": + case "stelem.i1": + case "stelem.i2": + case "stelem.i4": + case "stelem.i8": + case "stelem.r4": + case "stelem.r8": + case "stelem.ref": + { + Type t = coll.stackDepth.Peek(2).GetElementType(); + coll.stackDepth.Pop(t); + coll.stackDepth.Pop(typeof(int)); + coll.stackDepth.Pop(t.MakeArrayType()); + break; + } + case "endfinally": + case "rethrow": + { + if(coll.stackDepth.Count != 0) + throw new Exception("bad stack depth " + coll.stackDepth.Count); + break; + } + case "ceq": + { + Type t = coll.stackDepth.Pop(1); + if(t == null) + { + coll.stackDepth.PopRef(); + } + else + { + coll.stackDepth.Pop(t); + } + coll.stackDepth.Push(typeof(int)); + break; + } + case "cgt": + case "cgt.un": + case "clt": + case "clt.un": + { + coll.stackDepth.PopNumVal(); + coll.stackDepth.PopNumVal(); + coll.stackDepth.Push(typeof(int)); + break; + } + case "ldind.i4": + { + coll.stackDepth.Pop(typeof(int).MakeByRefType()); + coll.stackDepth.Push(typeof(int)); + break; + } + case "stind.i4": + { + coll.stackDepth.Pop(typeof(int)); + coll.stackDepth.Pop(typeof(int).MakeByRefType()); + break; + } + default: + throw new Exception("unknown opcode " + opcode.ToString()); + } + } + + private static Type ConvToType(OpCode opcode) + { + string s = opcode.ToString(); + s = s.Substring(5); // strip off "conv." + if(s.StartsWith("ovf.")) + s = s.Substring(4); + if(s.EndsWith(".un")) + s = s.Substring(0, s.Length - 3); + + switch(s) + { + case "i": + return typeof(IntPtr); + case "i1": + return typeof(sbyte); + case "i2": + return typeof(short); + case "i4": + return typeof(int); + case "i8": + return typeof(long); + case "r": + case "r4": + return typeof(float); + case "r8": + return typeof(double); + case "u1": + return typeof(byte); + case "u2": + return typeof(ushort); + case "u4": + return typeof(uint); + case "u8": + return typeof(ulong); + case "u": + return typeof(UIntPtr); + default: + throw new Exception("unknown opcode " + opcode.ToString()); + } + } + + public override void WriteOutOne(ScriptMyILGen ilGen) + { + ilGen.Emit(errorAt, opcode); + } + } + + public class GraphNodeEmitNullEndfinally: GraphNodeEmitNull + { + public GraphNodeEmitNullEndfinally(ScriptCollector coll, Token errorAt) : base(coll, errorAt, OpCodes.Endfinally) + { + } + + /** + * @brief Endfinally can branch to: + * 1) the corresponding EndExceptionBlock + * 2) any of the corresponding BeginFinallyBlock's leaveTargets + * 3) the next outer BeginFinallyBlock + */ + protected override System.Collections.Generic.IEnumerable GetNNEnumerable() + { + return new NNEnumerable(this, typeof(NNEnumerator)); + } + + private class NNEnumerator: NNEnumeratorBase + { + private GraphNodeEmitNullEndfinally gn; + private IEnumerator leaveTargetEnumerator; + private int index; + public NNEnumerator(GraphNodeEmitNullEndfinally gn) + { + this.gn = gn; + + // endfinally instruction must be within some try/catch/finally mess + GraphNodeBeginExceptionBlock thistry = gn.excBlock; + + // endfinally instruction must be within some finally { } mess + GraphNodeBeginFinallyBlock thisfin = (GraphNodeBeginFinallyBlock)thistry.catchFinallyBlock; + + // get the list of the finally { } leave instruction targets + this.leaveTargetEnumerator = thisfin.leaveTargets.GetEnumerator(); + } + public override bool MoveNext() + { + while(true) + { + switch(index) + { + + // to start, return end of our finally { } + case 0: + { + GraphNodeBeginExceptionBlock thistry = gn.excBlock; + nn = thistry.endExcBlock; + if(nn == null) + throw new NullReferenceException("thistry.endExcBlock"); + index++; + return true; + } + + // return next one of our finally { }'s leave targets + // ie, where any leave instructions in the try { } want + // the finally { } to go to when it finishes + case 1: + { + if(this.leaveTargetEnumerator.MoveNext()) + { + nn = this.leaveTargetEnumerator.Current; + if(nn == null) + throw new NullReferenceException("this.leaveTargetEnumerator.Current"); + return true; + } + break; + } + + // return beginning of next outer finally { } + case 2: + { + GraphNodeBeginExceptionBlock nntry = gn.excBlock; + while((nntry = nntry.excBlock) != null) + { + if(nntry.catchFinallyBlock is GraphNodeBeginFinallyBlock) + { + nn = nntry.catchFinallyBlock; + if(nn == null) + throw new NullReferenceException("nntry.catchFinallyBlock"); + index++; + return true; + } + } + break; + } + + // got nothing more + case 3: + { + return false; + } + + default: + throw new Exception(); + } + index++; + } + } + public override void Reset() + { + leaveTargetEnumerator.Reset(); + index = 0; + nn = null; + } + } + } + + public class GraphNodeEmitField: GraphNodeEmit + { + public FieldInfo field; + + public GraphNodeEmitField(ScriptCollector coll, Token errorAt, OpCode opcode, FieldInfo field) : base(coll, errorAt, opcode) + { + this.field = field; + } + + public override void ChainLin() + { + base.ChainLin(); + + switch(opcode.ToString()) + { + case "ldfld": + PopPointer(); + coll.stackDepth.Push(field.FieldType); + break; + case "ldflda": + PopPointer(); + coll.stackDepth.Push(field.FieldType.MakeByRefType()); + break; + case "stfld": + coll.stackDepth.Pop(field.FieldType); + PopPointer(); + break; + case "ldsfld": + coll.stackDepth.Push(field.FieldType); + break; + case "ldsflda": + coll.stackDepth.Push(field.FieldType.MakeByRefType()); + break; + case "stsfld": + coll.stackDepth.Pop(field.FieldType); + break; + default: + throw new Exception("unknown opcode " + opcode.ToString()); + } + } + private void PopPointer() + { + Type t = field.DeclaringType; // get class/field type + if(t.IsValueType) + { + Type brt = t.MakeByRefType(); // if value type, eg Vector, it can be pushed by reference or by value + int c = coll.stackDepth.Count; + if((c > 0) && (coll.stackDepth[c - 1] == brt)) + t = brt; + } + coll.stackDepth.Pop(t); // type of what should be on the stack pointing to object or struct + } + + public override void DebString(StringBuilder sb) + { + base.DebString(sb); + sb.Append(field.Name); + } + + public override void WriteOutOne(ScriptMyILGen ilGen) + { + ilGen.Emit(errorAt, opcode, field); + } + } + + public class GraphNodeEmitLocal: GraphNodeEmit + { + public ScriptMyLocal myLocal; + + public GraphNodeEmitLocal(ScriptCollector coll, Token errorAt, OpCode opcode, ScriptMyLocal myLocal) : base(coll, errorAt, opcode) + { + this.myLocal = myLocal; + } + + public override void ChainLin() + { + base.ChainLin(); + + switch(opcode.ToString()) + { + case "ldloc": + coll.stackDepth.Push(myLocal.type); + break; + case "ldloca": + coll.stackDepth.Push(myLocal.type.MakeByRefType()); + break; + case "stloc": + coll.stackDepth.Pop(myLocal.type); + break; + default: + throw new Exception("unknown opcode " + opcode.ToString()); + } + } + + public override void DebString(StringBuilder sb) + { + base.DebString(sb); + sb.Append(myLocal.name); + } + + public override ScriptMyLocal ReadsLocal() + { + if(opcode == OpCodes.Ldloc) + return myLocal; + if(opcode == OpCodes.Ldloca) + return myLocal; + if(opcode == OpCodes.Stloc) + return null; + throw new Exception("unknown opcode " + opcode); + } + public override ScriptMyLocal WritesLocal() + { + if(opcode == OpCodes.Ldloc) + return null; + if(opcode == OpCodes.Ldloca) + return myLocal; + if(opcode == OpCodes.Stloc) + return myLocal; + throw new Exception("unknown opcode " + opcode); + } + + public override void WriteOutOne(ScriptMyILGen ilGen) + { + ilGen.Emit(errorAt, opcode, myLocal); + } + } + + public class GraphNodeEmitType: GraphNodeEmit + { + public Type type; + + public GraphNodeEmitType(ScriptCollector coll, Token errorAt, OpCode opcode, Type type) : base(coll, errorAt, opcode) + { + this.type = type; + } + + public override void ChainLin() + { + base.ChainLin(); + + switch(opcode.ToString()) + { + case "castclass": + case "isinst": + { + coll.stackDepth.PopRef(); + coll.stackDepth.Push(type, type.IsValueType); + break; + } + case "box": + { + if(!type.IsValueType) + throw new Exception("can't box a non-value type"); + coll.stackDepth.Pop(type); + coll.stackDepth.Push(type, true); + break; + } + case "unbox": + case "unbox.any": + { + if(!type.IsValueType) + throw new Exception("can't unbox to a non-value type"); + coll.stackDepth.PopRef(); + coll.stackDepth.Push(type); + break; + } + case "newarr": + { + coll.stackDepth.Pop(typeof(int)); + coll.stackDepth.Push(type.MakeArrayType()); + break; + } + case "sizeof": + { + coll.stackDepth.Pop(1); + coll.stackDepth.Push(typeof(int)); + break; + } + case "ldelem": + { + coll.stackDepth.Pop(typeof(int)); + coll.stackDepth.Pop(type.MakeArrayType()); + coll.stackDepth.Push(type); + break; + } + case "ldelema": + { + coll.stackDepth.Pop(typeof(int)); + coll.stackDepth.Pop(type.MakeArrayType()); + coll.stackDepth.Push(type.MakeByRefType()); + break; + } + case "stelem": + { + coll.stackDepth.Pop(type); + coll.stackDepth.Pop(typeof(int)); + coll.stackDepth.Pop(type.MakeArrayType()); + break; + } + default: + throw new Exception("unknown opcode " + opcode.ToString()); + } + } + + public override void DebString(StringBuilder sb) + { + base.DebString(sb); + sb.Append(type.Name); + } + + public override void WriteOutOne(ScriptMyILGen ilGen) + { + ilGen.Emit(errorAt, opcode, type); + } + } + + public class GraphNodeEmitLabel: GraphNodeEmit + { + public ScriptMyLabel myLabel; + + public GraphNodeEmitLabel(ScriptCollector coll, Token errorAt, OpCode opcode, ScriptMyLabel myLabel) : base(coll, errorAt, opcode) + { + this.myLabel = myLabel; + } + + public override void ChainLin() + { + base.ChainLin(); + + switch(opcode.ToString()) + { + case "brfalse.s": + case "brtrue.s": + case "brfalse": + case "brtrue": + { + coll.stackDepth.Pop(1); + break; + } + case "beq.s": + case "bge.s": + case "bgt.s": + case "ble.s": + case "blt.s": + case "bne.un.s": + case "bge.un.s": + case "bgt.un.s": + case "ble.un.s": + case "blt.un.s": + case "beq": + case "bge": + case "bgt": + case "ble": + case "blt": + case "bne.un": + case "bge.un": + case "bgt.un": + case "ble.un": + case "blt.un": + { + coll.stackDepth.PopNumVal(); + coll.stackDepth.PopNumVal(); + break; + } + case "br": + case "br.s": + break; + case "leave": + { + if(coll.stackDepth.Count != 0) + throw new Exception("bad stack depth " + coll.stackDepth.Count); + break; + } + default: + throw new Exception("unknown opcode " + opcode.ToString()); + } + + // if a target doesn't have a depth yet, set its depth to the depth after instruction executes + // otherwise, make sure it matches all other branches to that target and what fell through to it + coll.stackDepth.Matches(myLabel); + } + + public override void DebString(StringBuilder sb) + { + base.DebString(sb); + sb.Append(myLabel.name); + } + + public override void WriteOutOne(ScriptMyILGen ilGen) + { + ilGen.Emit(errorAt, opcode, myLabel); + } + + /** + * @brief Conditional branches return the next inline followed by the branch target + * Unconditional branches return only the branch target + * But if the target is outside our scope (eg __retlbl), omit it from the list + */ + protected override System.Collections.Generic.IEnumerable GetNNEnumerable() + { + return new NNEnumerable(this, typeof(NNEnumerator)); + } + + private class NNEnumerator: NNEnumeratorBase + { + private GraphNodeEmitLabel gn; + private int index; + public NNEnumerator(GraphNodeEmitLabel gn) + { + this.gn = gn; + } + public override bool MoveNext() + { + switch(gn.opcode.FlowControl) + { + case FlowControl.Branch: + { + // unconditional branch just goes to target and nothing else + switch(index) + { + case 0: + { + nn = gn.myLabel.whereAmI; + index++; + return nn != null; + } + case 1: + { + return false; + } + } + throw new Exception(); + } + case FlowControl.Cond_Branch: + { + // conditional branch goes inline and to target + switch(index) + { + case 0: + { + nn = gn.nextLin; + index++; + return true; + } + case 1: + { + nn = gn.myLabel.whereAmI; + index++; + return nn != null; + } + case 2: + { + return false; + } + } + throw new Exception(); + } + default: + throw new Exception("unknown flow control " + gn.opcode.FlowControl.ToString() + + " of " + gn.opcode.ToString()); + } + } + public override void Reset() + { + index = 0; + nn = null; + } + } + } + + public class GraphNodeEmitLabelLeave: GraphNodeEmitLabel + { + public GraphNodeBlock unwindTo; // if unwinding, innermost finally block being unwound + // else, same as myTarget.whereAmI + // null if unwinding completely out of scope, eg, __retlbl + + public GraphNodeEmitLabelLeave(ScriptCollector coll, Token errorAt, ScriptMyLabel myLabel) : base(coll, errorAt, OpCodes.Leave, myLabel) + { + } + + /** + * @brief Leave instructions have exactly one unconditional next node. + * Either the given target if within the same try block + * or the beginning of the intervening finally block. + */ + protected override System.Collections.Generic.IEnumerable GetNNEnumerable() + { + return new NNEnumerable(this, typeof(NNEnumerator)); + } + + private class NNEnumerator: NNEnumeratorBase + { + private GraphNodeEmitLabelLeave gn; + private int index; + public NNEnumerator(GraphNodeEmitLabelLeave gn) + { + this.gn = gn; + } + public override bool MoveNext() + { + if(index == 0) + { + nn = gn.unwindTo; + index++; + return nn != null; + } + nn = null; + return false; + } + public override void Reset() + { + index = 0; + nn = null; + } + } + } + + public class GraphNodeEmitLabels: GraphNodeEmit + { + public ScriptMyLabel[] myLabels; + + public GraphNodeEmitLabels(ScriptCollector coll, Token errorAt, OpCode opcode, ScriptMyLabel[] myLabels) : base(coll, errorAt, opcode) + { + this.myLabels = myLabels; + } + + public override void ChainLin() + { + base.ChainLin(); + + switch(opcode.ToString()) + { + case "switch": + { + coll.stackDepth.Pop(typeof(int)); + break; + } + default: + throw new Exception("unknown opcode " + opcode.ToString()); + } + + // if a target doesn't have a depth yet, set its depth to the depth after instruction executes + // otherwise, make sure it matches all other branches to that target and what fell through to it + foreach(ScriptMyLabel myLabel in myLabels) + { + coll.stackDepth.Matches(myLabel); + } + } + + public override void DebString(StringBuilder sb) + { + base.DebString(sb); + bool first = true; + foreach(ScriptMyLabel lbl in myLabels) + { + if(!first) + sb.Append(','); + sb.Append(lbl.name); + first = false; + } + } + + public override void WriteOutOne(ScriptMyILGen ilGen) + { + ilGen.Emit(errorAt, opcode, myLabels); + } + + /** + * @brief Return list of all labels followed by the next linear instruction + * But if the target is outside our scope (eg __retlbl), omit it from the list + */ + protected override System.Collections.Generic.IEnumerable GetNNEnumerable() + { + return new NNEnumerable(this, typeof(NNEnumerator)); + } + + private class NNEnumerator: NNEnumeratorBase + { + private GraphNodeEmitLabels gn; + private int index; + public NNEnumerator(GraphNodeEmitLabels gn) + { + this.gn = gn; + } + public override bool MoveNext() + { + // Return next from list of switch case labels. + while(index < gn.myLabels.Length) + { + nn = gn.myLabels[index++].whereAmI; + if(nn != null) + return true; + } + + // If all ran out, the switch instruction falls through. + if(index == gn.myLabels.Length) + { + index++; + nn = gn.nextLin; + return true; + } + + // Even ran out of that, say there's nothing more. + nn = null; + return false; + } + public override void Reset() + { + index = 0; + nn = null; + } + } + } + + public class GraphNodeEmitIntMeth: GraphNodeEmit + { + public ScriptObjWriter method; + + public GraphNodeEmitIntMeth(ScriptCollector coll, Token errorAt, OpCode opcode, ScriptObjWriter method) : base(coll, errorAt, opcode) + { + this.method = method; + } + + public override void ChainLin() + { + base.ChainLin(); + + switch(opcode.ToString()) + { + case "call": + { + + // calls have Varpop so pop the number of arguments + // they are all static so there is no separate 'this' parameter + coll.stackDepth.Pop(this.method.argTypes); + + // calls are also Varpush so they push a return value iff non-void + if(this.method.retType != typeof(void)) + coll.stackDepth.Push(this.method.retType); + break; + } + + default: + throw new Exception("unknown opcode " + opcode.ToString()); + } + } + + public override void DebString(StringBuilder sb) + { + base.DebString(sb); + sb.Append(method.methName); + } + + public override void WriteOutOne(ScriptMyILGen ilGen) + { + ilGen.Emit(errorAt, opcode, method); + } + } + + public class GraphNodeEmitExtMeth: GraphNodeEmit + { + public MethodInfo method; + + public GraphNodeEmitExtMeth(ScriptCollector coll, Token errorAt, OpCode opcode, MethodInfo method) : base(coll, errorAt, opcode) + { + this.method = method; + } + + public override void ChainLin() + { + base.ChainLin(); + + switch(opcode.ToString()) + { + case "call": + case "callvirt": + { + + // calls have Varpop so pop the number of arguments + coll.stackDepth.Pop(this.method.GetParameters()); + if((this.method.CallingConvention & CallingConventions.HasThis) != 0) + { + coll.stackDepth.Pop(method.DeclaringType); + } + + // calls are also Varpush so they push a return value iff non-void + if(this.method.ReturnType != typeof(void)) + coll.stackDepth.Push(this.method.ReturnType); + break; + } + + default: + throw new Exception("unknown opcode " + opcode.ToString()); + } + } + + public override void DebString(StringBuilder sb) + { + base.DebString(sb); + sb.Append(method.Name); + } + + public override void WriteOutOne(ScriptMyILGen ilGen) + { + ilGen.Emit(errorAt, opcode, method); + } + } + + public class GraphNodeEmitCtor: GraphNodeEmit + { + public ConstructorInfo ctor; + + public GraphNodeEmitCtor(ScriptCollector coll, Token errorAt, OpCode opcode, ConstructorInfo ctor) : base(coll, errorAt, opcode) + { + this.ctor = ctor; + } + + public override void ChainLin() + { + base.ChainLin(); + + switch(opcode.ToString()) + { + case "newobj": + { + coll.stackDepth.Pop(ctor.GetParameters()); + coll.stackDepth.Push(ctor.DeclaringType); + break; + } + + default: + throw new Exception("unknown opcode " + opcode.ToString()); + } + } + + public override void DebString(StringBuilder sb) + { + base.DebString(sb); + sb.Append(ctor.ReflectedType.Name); + } + + public override void WriteOutOne(ScriptMyILGen ilGen) + { + ilGen.Emit(errorAt, opcode, ctor); + } + } + + public class GraphNodeEmitDouble: GraphNodeEmit + { + public double value; + + public GraphNodeEmitDouble(ScriptCollector coll, Token errorAt, OpCode opcode, double value) : base(coll, errorAt, opcode) + { + this.value = value; + } + + public override void ChainLin() + { + base.ChainLin(); + + switch(opcode.ToString()) + { + case "ldc.r8": + coll.stackDepth.Push(typeof(double)); + break; + default: + throw new Exception("unknown opcode " + opcode.ToString()); + } + } + + public override void DebString(StringBuilder sb) + { + base.DebString(sb); + sb.Append(value); + } + + public override void WriteOutOne(ScriptMyILGen ilGen) + { + ilGen.Emit(errorAt, opcode, value); + } + } + + public class GraphNodeEmitFloat: GraphNodeEmit + { + public float value; + + public GraphNodeEmitFloat(ScriptCollector coll, Token errorAt, OpCode opcode, float value) : base(coll, errorAt, opcode) + { + this.value = value; + } + + public override void ChainLin() + { + base.ChainLin(); + + switch(opcode.ToString()) + { + case "ldc.r4": + coll.stackDepth.Push(typeof(float)); + break; + default: + throw new Exception("unknown opcode " + opcode.ToString()); + } + } + + public override void DebString(StringBuilder sb) + { + base.DebString(sb); + sb.Append(value); + } + + public override void WriteOutOne(ScriptMyILGen ilGen) + { + ilGen.Emit(errorAt, opcode, value); + } + } + + public class GraphNodeEmitInt: GraphNodeEmit + { + public int value; + + public GraphNodeEmitInt(ScriptCollector coll, Token errorAt, OpCode opcode, int value) : base(coll, errorAt, opcode) + { + this.value = value; + } + + public override void ChainLin() + { + base.ChainLin(); + + switch(opcode.ToString()) + { + case "ldarg": + case "ldarg.s": + coll.stackDepth.Push(coll.wrapped.argTypes[value]); + break; + case "ldarga": + case "ldarga.s": + coll.stackDepth.Push(coll.wrapped.argTypes[value].MakeByRefType()); + break; + case "starg": + case "starg.s": + coll.stackDepth.Pop(coll.wrapped.argTypes[value]); + break; + case "ldc.i4": + case "ldc.i4.s": + coll.stackDepth.Push(typeof(int)); + break; + default: + throw new Exception("unknown opcode " + opcode.ToString()); + } + } + + public override void DebString(StringBuilder sb) + { + base.DebString(sb); + sb.Append(value); + } + + public override void WriteOutOne(ScriptMyILGen ilGen) + { + ilGen.Emit(errorAt, opcode, value); + } + } + + public class GraphNodeEmitString: GraphNodeEmit + { + public string value; + + public GraphNodeEmitString(ScriptCollector coll, Token errorAt, OpCode opcode, string value) : base(coll, errorAt, opcode) + { + this.value = value; + } + + public override void ChainLin() + { + base.ChainLin(); + + switch(opcode.ToString()) + { + case "ldstr": + coll.stackDepth.Push(typeof(string)); + break; + default: + throw new Exception("unknown opcode " + opcode.ToString()); + } + } + + public override void DebString(StringBuilder sb) + { + base.DebString(sb); + sb.Append("\""); + sb.Append(value); + sb.Append("\""); + } + + public override void WriteOutOne(ScriptMyILGen ilGen) + { + ilGen.Emit(errorAt, opcode, value); + } + } + + public class GraphNodeMarkLabel: GraphNodeBlock + { + public ScriptMyLabel myLabel; + + public GraphNodeMarkLabel(ScriptCollector coll, ScriptMyLabel myLabel) : base(coll) + { + this.myLabel = myLabel; + } + + public override void ChainLin() + { + base.ChainLin(); + + // if previous instruction can fall through to this label, + // if the label doesn't yet have a stack depth, mark it with current stack depth + // else, the label's stack depth from forward branches and current stack depth must match + // else, + // label must have had a forward branch to it so we can know stack depth + // set the current stack depth to the label's stack depth as of that forward branch + if(myLabel.whereAmI.prevLin.CanFallThrough()) + { + coll.stackDepth.Matches(myLabel); + } + else + { + if(myLabel.stackDepth == null) + { + throw new Exception("stack depth unknown at " + myLabel.name); + } + coll.stackDepth.Clear(); + int n = myLabel.stackDepth.Length; + for(int i = 0; i < n; i++) + { + coll.stackDepth.Push(myLabel.stackDepth[i], myLabel.stackBoxeds[i]); + } + } + } + + public override void DebString(StringBuilder sb) + { + sb.Append(myLabel.name); + sb.Append(':'); + if(myLabel.stackDepth != null) + { + sb.Append(" ["); + sb.Append(myLabel.stackDepth.Length); + sb.Append(']'); + } + } + + public override void WriteOutOne(ScriptMyILGen ilGen) + { + ilGen.MarkLabel(myLabel); + } + } + + + /** + * @brief Generates enumerator that steps through list of nodes that can + * possibly be next in a flow-control sense. + */ + public class NNEnumerable: System.Collections.Generic.IEnumerable + { + private object[] cps; + private ConstructorInfo ci; + + public NNEnumerable(GraphNode gn, Type nnEnumeratorType) + { + this.cps = new object[] { gn }; + this.ci = nnEnumeratorType.GetConstructor(new Type[] { gn.GetType() }); + } + System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator() + { + return (System.Collections.Generic.IEnumerator)ci.Invoke(cps); + } + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() + { + return (System.Collections.IEnumerator)ci.Invoke(cps); + } + } + + + /** + * @brief Steps through list of nodes that can possible be next in a flow-control sense. + */ + public abstract class NNEnumeratorBase: System.Collections.Generic.IEnumerator + { + protected GraphNode nn; + + public abstract bool MoveNext(); + public abstract void Reset(); + + GraphNode System.Collections.Generic.IEnumerator.Current + { + get + { + return this.nn; + } + } + object System.Collections.IEnumerator.Current + { + get + { + return this.nn; + } + } + void System.IDisposable.Dispose() + { + } + } + + + public class ScriptCollector: ScriptMyILGen + { + public static readonly bool DEBUG = false; + + public ScriptObjWriter wrapped; + public GraphNode firstLin, lastLin; + private bool resolvedSomething; + private int resolveSequence; + private int excBlkSeqNos; + public StackDepth stackDepth = new StackDepth(); + + public GraphNodeBeginExceptionBlock curTryBlock = null; // pushed at beginning of try + // popped at BEGINNING of catch/finally + public GraphNodeBeginExceptionBlock curExcBlock = null; // pushed at beginning of try + // popped at END of catch/finally + + private List declaredLocals = new List(); + private List definedLabels = new List(); + + public string methName + { + get + { + return wrapped.methName; + } + } + + /** + * @brief Wrap the optimizer around the ScriptObjWriter to collect the instruction stream. + * All stream-writing calls get saved to our graph nodes instead of being written to object file. + */ + public ScriptCollector(ScriptObjWriter wrapped) + { + this.wrapped = wrapped; + GraphNodeBegin gnb = new GraphNodeBegin(this); + this.firstLin = gnb; + this.lastLin = gnb; + } + + public ScriptMyLocal DeclareLocal(Type type, string name) + { + ScriptMyLocal loc = new ScriptMyLocal(); + loc.name = name; + loc.type = type; + loc.number = wrapped.localNumber++; + declaredLocals.Add(loc); + return loc; + } + + public ScriptMyLabel DefineLabel(string name) + { + ScriptMyLabel lbl = new ScriptMyLabel(); + lbl.name = name; + lbl.number = wrapped.labelNumber++; + definedLabels.Add(lbl); + return lbl; + } + + public void BeginExceptionBlock() + { + GraphNodeBeginExceptionBlock tryBlock = new GraphNodeBeginExceptionBlock(this); + tryBlock.ChainLin(); + tryBlock.excBlkSeqNo = ++this.excBlkSeqNos; + this.curExcBlock = tryBlock; + this.curTryBlock = tryBlock; + } + + public void BeginCatchBlock(Type excType) + { + GraphNodeBeginCatchBlock catchBlock = new GraphNodeBeginCatchBlock(this, excType); + catchBlock.ChainLin(); + if(curExcBlock.catchFinallyBlock != null) + throw new Exception("only one catch/finally allowed per try"); + curExcBlock.catchFinallyBlock = catchBlock; + curTryBlock = curExcBlock.tryBlock; + } + + public void BeginFinallyBlock() + { + GraphNodeBeginFinallyBlock finallyBlock = new GraphNodeBeginFinallyBlock(this); + finallyBlock.ChainLin(); + if(curExcBlock.catchFinallyBlock != null) + throw new Exception("only one catch/finally allowed per try"); + curExcBlock.catchFinallyBlock = finallyBlock; + curTryBlock = curExcBlock.tryBlock; + } + + public void EndExceptionBlock() + { + GraphNodeEndExceptionBlock endExcBlock = new GraphNodeEndExceptionBlock(this); + endExcBlock.ChainLin(); + curExcBlock.endExcBlock = endExcBlock; + curTryBlock = curExcBlock.tryBlock; + curExcBlock = curExcBlock.excBlock; + } + + public void Emit(Token errorAt, OpCode opcode) + { + if(opcode == OpCodes.Endfinally) + { + new GraphNodeEmitNullEndfinally(this, errorAt).ChainLin(); + } + else + { + new GraphNodeEmitNull(this, errorAt, opcode).ChainLin(); + } + } + + public void Emit(Token errorAt, OpCode opcode, FieldInfo field) + { + if(field == null) + throw new ArgumentNullException("field"); + new GraphNodeEmitField(this, errorAt, opcode, field).ChainLin(); + } + + public void Emit(Token errorAt, OpCode opcode, ScriptMyLocal myLocal) + { + new GraphNodeEmitLocal(this, errorAt, opcode, myLocal).ChainLin(); + } + + public void Emit(Token errorAt, OpCode opcode, Type type) + { + new GraphNodeEmitType(this, errorAt, opcode, type).ChainLin(); + } + + public void Emit(Token errorAt, OpCode opcode, ScriptMyLabel myLabel) + { + if(opcode == OpCodes.Leave) + { + new GraphNodeEmitLabelLeave(this, errorAt, myLabel).ChainLin(); + } + else + { + new GraphNodeEmitLabel(this, errorAt, opcode, myLabel).ChainLin(); + } + } + + public void Emit(Token errorAt, OpCode opcode, ScriptMyLabel[] myLabels) + { + new GraphNodeEmitLabels(this, errorAt, opcode, myLabels).ChainLin(); + } + + public void Emit(Token errorAt, OpCode opcode, ScriptObjWriter method) + { + if(method == null) + throw new ArgumentNullException("method"); + new GraphNodeEmitIntMeth(this, errorAt, opcode, method).ChainLin(); + } + + public void Emit(Token errorAt, OpCode opcode, MethodInfo method) + { + if(method == null) + throw new ArgumentNullException("method"); + new GraphNodeEmitExtMeth(this, errorAt, opcode, method).ChainLin(); + } + + public void Emit(Token errorAt, OpCode opcode, ConstructorInfo ctor) + { + if(ctor == null) + throw new ArgumentNullException("ctor"); + new GraphNodeEmitCtor(this, errorAt, opcode, ctor).ChainLin(); + } + + public void Emit(Token errorAt, OpCode opcode, double value) + { + new GraphNodeEmitDouble(this, errorAt, opcode, value).ChainLin(); + } + + public void Emit(Token errorAt, OpCode opcode, float value) + { + new GraphNodeEmitFloat(this, errorAt, opcode, value).ChainLin(); + } + + public void Emit(Token errorAt, OpCode opcode, int value) + { + new GraphNodeEmitInt(this, errorAt, opcode, value).ChainLin(); + } + + public void Emit(Token errorAt, OpCode opcode, string value) + { + new GraphNodeEmitString(this, errorAt, opcode, value).ChainLin(); + } + + public void MarkLabel(ScriptMyLabel myLabel) + { + myLabel.whereAmI = new GraphNodeMarkLabel(this, myLabel); + myLabel.whereAmI.ChainLin(); + } + + /** + * @brief Write the whole graph out to the object file. + */ + public ScriptMyILGen WriteOutAll() + { + foreach(ScriptMyLocal loc in declaredLocals) + { + if(loc.isReferenced) + wrapped.DeclareLocal(loc); + } + foreach(ScriptMyLabel lbl in definedLabels) + { + wrapped.DefineLabel(lbl); + } + for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) + { + gn.WriteOutOne(wrapped); + } + return wrapped; + } + + /** + * @brief Perform optimizations. + */ + public void Optimize() + { + if(curExcBlock != null) + throw new Exception("exception block still open"); + + // If an instruction says it doesn't fall through, remove all instructions to + // the end of the block. + for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) + { + if(!gn.CanFallThrough()) + { + GraphNode nn; + while(((nn = gn.nextLin) != null) && !(nn is GraphNodeBlock) && + !(nn is GraphNodeEndExceptionBlock)) + { + if((gn.nextLin = nn.nextLin) != null) + { + nn.nextLin.prevLin = gn; + } + } + } + } + + // Scan for OpCodes.Leave instructions. + // For each found, its target for flow analysis purposes is the beginning of the corresponding + // finally block. And the end of the finally block gets a conditional branch target of the + // leave instruction's target. A leave instruction can unwind zero or more finally blocks. + for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) + { + if(gn is GraphNodeEmitLabelLeave) + { + GraphNodeEmitLabelLeave leaveInstr = (GraphNodeEmitLabelLeave)gn; // the leave instruction + GraphNodeMarkLabel leaveTarget = leaveInstr.myLabel.whereAmI; // label being targeted by leave + GraphNodeBeginExceptionBlock leaveTargetsTryBlock = // try block directly enclosing leave target + (leaveTarget == null) ? null : leaveTarget.tryBlock; // ...it must not be unwound + + // Step through try { }s from the leave instruction towards its target looking for try { }s with finally { }s. + // The leave instruction unconditionally branches to the beginning of the innermost one found. + // The end of the last one found conditionally branches to the leave instruction's target. + // If none found, the leave is a simple unconditional branch to its target. + GraphNodeBeginFinallyBlock innerFinallyBlock = null; + for(GraphNodeBeginExceptionBlock tryBlock = leaveInstr.tryBlock; + tryBlock != leaveTargetsTryBlock; + tryBlock = tryBlock.tryBlock) + { + if(tryBlock == null) + throw new Exception("leave target not at or outer to leave instruction"); + GraphNodeCatchFinallyBlock cfb = tryBlock.catchFinallyBlock; + if(cfb is GraphNodeBeginFinallyBlock) + { + if(innerFinallyBlock == null) + { + leaveInstr.unwindTo = cfb; + } + innerFinallyBlock = (GraphNodeBeginFinallyBlock)cfb; + } + } + + // The end of the outermost finally being unwound can conditionally jump to the target of the leave instruction. + // In the case of no finallies being unwound, the leave is just a simple unconditional branch. + if(innerFinallyBlock == null) + { + leaveInstr.unwindTo = leaveTarget; + } + else if(!innerFinallyBlock.leaveTargets.Contains(leaveTarget)) + { + innerFinallyBlock.leaveTargets.Add(leaveTarget); + } + } + } + + // See which variables a particular block reads before writing. + // This just considers the block itself and nothing that it branches to or fallsthru to. + GraphNodeBlock currentBlock = null; + for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) + { + if(gn is GraphNodeBlock) + currentBlock = (GraphNodeBlock)gn; + ScriptMyLocal rdlcl = gn.ReadsLocal(); + if((rdlcl != null) && + !currentBlock.localsWrittenBeforeRead.Contains(rdlcl) && + !currentBlock.localsReadBeforeWritten.Contains(rdlcl)) + { + currentBlock.localsReadBeforeWritten.Add(rdlcl); + } + ScriptMyLocal wrlcl = gn.WritesLocal(); + if((wrlcl != null) && + !currentBlock.localsWrittenBeforeRead.Contains(wrlcl) && + !currentBlock.localsReadBeforeWritten.Contains(wrlcl)) + { + currentBlock.localsWrittenBeforeRead.Add(wrlcl); + } + } + + // For every block we branch to, add that blocks readables to our list of readables, + // because we need to have those values valid on entry to our block. But if we write the + // variable before we can possibly branch to that block, then we don't need to have it valid + // on entry to our block. So basically it looks like the branch instruction is reading + // everything required by any blocks it can branch to. + do + { + this.resolvedSomething = false; + this.resolveSequence++; + this.ResolveBlock((GraphNodeBlock)firstLin); + } while(this.resolvedSomething); + + // Repeat the cutting loops as long as we keep finding stuff. + bool didSomething; + do + { + didSomething = false; + + // Strip out ldc.i4.1/xor/ldc.i4.1/xor + for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) + { + if(!(gn is GraphNodeEmit)) + continue; + GraphNodeEmit xor2 = (GraphNodeEmit)gn; + if(xor2.opcode != OpCodes.Xor) + continue; + if(!(xor2.prevLin is GraphNodeEmit)) + continue; + GraphNodeEmit ld12 = (GraphNodeEmit)xor2.prevLin; + if(ld12.opcode != OpCodes.Ldc_I4_1) + continue; + if(!(ld12.prevLin is GraphNodeEmit)) + continue; + GraphNodeEmit xor1 = (GraphNodeEmit)ld12.prevLin; + if(xor1.opcode != OpCodes.Xor) + continue; + if(!(xor2.prevLin is GraphNodeEmit)) + continue; + GraphNodeEmit ld11 = (GraphNodeEmit)xor1.prevLin; + if(ld11.opcode != OpCodes.Ldc_I4_1) + continue; + ld11.prevLin.nextLin = xor2.nextLin; + xor2.nextLin.prevLin = ld11.prevLin; + didSomething = true; + } + + // Replace c{cond}/ldc.i4.1/xor/br{false,true} -> c{cond}/br{true,false} + for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) + { + if(!(gn is GraphNodeEmit)) + continue; + GraphNodeEmit brft = (GraphNodeEmit)gn; + if((brft.opcode != OpCodes.Brfalse) && (brft.opcode != OpCodes.Brtrue)) + continue; + if(!(brft.prevLin is GraphNodeEmit)) + continue; + GraphNodeEmit xor = (GraphNodeEmit)brft.prevLin; + if(xor.opcode != OpCodes.Xor) + continue; + if(!(xor.prevLin is GraphNodeEmit)) + continue; + GraphNodeEmit ldc = (GraphNodeEmit)xor.prevLin; + if(ldc.opcode != OpCodes.Ldc_I4_1) + continue; + if(!(ldc.prevLin is GraphNodeEmit)) + continue; + GraphNodeEmit cmp = (GraphNodeEmit)ldc.prevLin; + if(cmp.opcode.StackBehaviourPop != StackBehaviour.Pop1_pop1) + continue; + if(cmp.opcode.StackBehaviourPush != StackBehaviour.Pushi) + continue; + cmp.nextLin = brft; + brft.prevLin = cmp; + brft.opcode = (brft.opcode == OpCodes.Brfalse) ? OpCodes.Brtrue : OpCodes.Brfalse; + didSomething = true; + } + + // Replace c{cond}/br{false,true} -> b{!,}{cond} + for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) + { + if(!(gn is GraphNodeEmit)) + continue; + GraphNodeEmit brft = (GraphNodeEmit)gn; + if((brft.opcode != OpCodes.Brfalse) && (brft.opcode != OpCodes.Brtrue)) + continue; + if(!(brft.prevLin is GraphNodeEmit)) + continue; + GraphNodeEmit cmp = (GraphNodeEmit)brft.prevLin; + if(cmp.opcode.StackBehaviourPop != StackBehaviour.Pop1_pop1) + continue; + if(cmp.opcode.StackBehaviourPush != StackBehaviour.Pushi) + continue; + cmp.prevLin.nextLin = brft; + brft.prevLin = cmp.prevLin; + bool brtru = (brft.opcode == OpCodes.Brtrue); + if(cmp.opcode == OpCodes.Ceq) + brft.opcode = brtru ? OpCodes.Beq : OpCodes.Bne_Un; + else if(cmp.opcode == OpCodes.Cgt) + brft.opcode = brtru ? OpCodes.Bgt : OpCodes.Ble; + else if(cmp.opcode == OpCodes.Cgt_Un) + brft.opcode = brtru ? OpCodes.Bgt_Un : OpCodes.Ble_Un; + else if(cmp.opcode == OpCodes.Clt) + brft.opcode = brtru ? OpCodes.Blt : OpCodes.Bge; + else if(cmp.opcode == OpCodes.Clt_Un) + brft.opcode = brtru ? OpCodes.Blt_Un : OpCodes.Bge_Un; + else + throw new Exception(); + didSomething = true; + } + + // Replace ld{c.i4.0,null}/br{ne.un,eq} -> br{true,false} + for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) + { + if(!(gn is GraphNodeEmit)) + continue; + GraphNodeEmit brcc = (GraphNodeEmit)gn; + if((brcc.opcode != OpCodes.Bne_Un) && (brcc.opcode != OpCodes.Beq)) + continue; + if(!(brcc.prevLin is GraphNodeEmit)) + continue; + GraphNodeEmit ldc0 = (GraphNodeEmit)brcc.prevLin; + if((ldc0.opcode != OpCodes.Ldc_I4_0) && (ldc0.opcode != OpCodes.Ldnull)) + continue; + ldc0.prevLin.nextLin = brcc; + brcc.prevLin = ldc0.prevLin; + brcc.opcode = (brcc.opcode == OpCodes.Bne_Un) ? OpCodes.Brtrue : OpCodes.Brfalse; + didSomething = true; + } + + // Replace: + // ldloc v1 + // stloc v2 + // ld except ld v2 + // ldloc v2 + // ...v2 unreferenced hereafter + // With: + // ld except ld v2 + // ldloc v1 + for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) + { + + // check for 'ldloc v1' instruction + if(!(gn is GraphNodeEmitLocal)) + continue; + GraphNodeEmitLocal ldlv1 = (GraphNodeEmitLocal)gn; + if(ldlv1.opcode != OpCodes.Ldloc) + continue; + + // check for 'stloc v2' instruction + if(!(ldlv1.nextLin is GraphNodeEmitLocal)) + continue; + GraphNodeEmitLocal stlv2 = (GraphNodeEmitLocal)ldlv1.nextLin; + if(stlv2.opcode != OpCodes.Stloc) + continue; + + // check for 'ld except ld v2' instruction + if(!(stlv2.nextLin is GraphNodeEmit)) + continue; + GraphNodeEmit ldany = (GraphNodeEmit)stlv2.nextLin; + if(!ldany.opcode.ToString().StartsWith("ld")) + continue; + if((ldany is GraphNodeEmitLocal) && + ((GraphNodeEmitLocal)ldany).myLocal == stlv2.myLocal) + continue; + + // check for 'ldloc v2' instruction + if(!(ldany.nextLin is GraphNodeEmitLocal)) + continue; + GraphNodeEmitLocal ldlv2 = (GraphNodeEmitLocal)ldany.nextLin; + if(ldlv2.opcode != OpCodes.Ldloc) + continue; + if(ldlv2.myLocal != stlv2.myLocal) + continue; + + // check that v2 is not needed after this at all + if(IsLocalNeededAfterThis(ldlv2, ldlv2.myLocal)) + continue; + + // make 'ld...' the first instruction + ldany.prevLin = ldlv1.prevLin; + ldany.prevLin.nextLin = ldany; + + // make 'ldloc v1' the second instruction + ldany.nextLin = ldlv1; + ldlv1.prevLin = ldany; + + // and make 'ldloc v1' the last instruction + ldlv1.nextLin = ldlv2.nextLin; + ldlv1.nextLin.prevLin = ldlv1; + + didSomething = true; + } + + // Remove all the stloc/ldloc that are back-to-back without the local + // being needed afterwards. If it is needed afterwards, replace the + // stloc/ldloc with dup/stloc. + for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) + { + if((gn is GraphNodeEmitLocal) && + (gn.prevLin is GraphNodeEmitLocal)) + { + GraphNodeEmitLocal stloc = (GraphNodeEmitLocal)gn.prevLin; + GraphNodeEmitLocal ldloc = (GraphNodeEmitLocal)gn; + if((stloc.opcode == OpCodes.Stloc) && + (ldloc.opcode == OpCodes.Ldloc) && + (stloc.myLocal == ldloc.myLocal)) + { + if(IsLocalNeededAfterThis(ldloc, ldloc.myLocal)) + { + GraphNodeEmitNull dup = new GraphNodeEmitNull(this, stloc.errorAt, OpCodes.Dup); + dup.nextLin = stloc; + dup.prevLin = stloc.prevLin; + stloc.nextLin = ldloc.nextLin; + stloc.prevLin = dup; + dup.prevLin.nextLin = dup; + stloc.nextLin.prevLin = stloc; + gn = stloc; + } + else + { + stloc.prevLin.nextLin = ldloc.nextLin; + ldloc.nextLin.prevLin = stloc.prevLin; + gn = stloc.prevLin; + } + didSomething = true; + } + } + } + + // Remove all write-only local variables, ie, those with no ldloc[a] references. + // Replace any stloc instructions with pops. + for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) + { + ScriptMyLocal rdlcl = gn.ReadsLocal(); + if(rdlcl != null) + rdlcl.isReferenced = true; + } + for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) + { + ScriptMyLocal wrlcl = gn.WritesLocal(); + if((wrlcl != null) && !wrlcl.isReferenced) + { + if(!(gn is GraphNodeEmitLocal) || (((GraphNodeEmitLocal)gn).opcode != OpCodes.Stloc)) + { + throw new Exception("expecting stloc"); + } + GraphNodeEmitNull pop = new GraphNodeEmitNull(this, ((GraphNodeEmit)gn).errorAt, OpCodes.Pop); + pop.nextLin = gn.nextLin; + pop.prevLin = gn.prevLin; + gn.nextLin.prevLin = pop; + gn.prevLin.nextLin = pop; + gn = pop; + didSomething = true; + } + } + + // Remove any Ld/Dup,Pop. + for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) + { + if((gn is GraphNodeEmit) && + (gn.nextLin is GraphNodeEmit)) + { + GraphNodeEmit gne = (GraphNodeEmit)gn; + GraphNodeEmit nne = (GraphNodeEmit)gn.nextLin; + if(gne.isPoppable && (nne.opcode == OpCodes.Pop)) + { + gne.prevLin.nextLin = nne.nextLin; + nne.nextLin.prevLin = gne.prevLin; + gn = gne.prevLin; + didSomething = true; + } + } + } + } while(didSomething); + + // Dump out the results. + if(DEBUG) + { + Console.WriteLine(""); + Console.WriteLine(methName); + Console.WriteLine(" resolveSequence=" + this.resolveSequence); + + Console.WriteLine(" Locals:"); + foreach(ScriptMyLocal loc in declaredLocals) + { + Console.WriteLine(" " + loc.type.Name + " " + loc.name); + } + + Console.WriteLine(" Labels:"); + foreach(ScriptMyLabel lbl in definedLabels) + { + Console.WriteLine(" " + lbl.name); + } + + Console.WriteLine(" Code:"); + DumpCode(); + } + } + + private void DumpCode() + { + int linSeqNos = 0; + for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) + { + gn.linSeqNo = ++linSeqNos; + } + for(GraphNode gn = firstLin; gn != null; gn = gn.nextLin) + { + StringBuilder sb = new StringBuilder(); + gn.DebStringExt(sb); + Console.WriteLine(sb.ToString()); + if(gn is GraphNodeBlock) + { + GraphNodeBlock gnb = (GraphNodeBlock)gn; + foreach(ScriptMyLocal lcl in gnb.localsReadBeforeWritten) + { + Console.WriteLine(" reads " + lcl.name); + } + } + } + } + + /** + * @brief Scan the given block for branches to other blocks. + * For any locals read by those blocks, mark them as being read by this block, + * provided this block has not written them by that point. This makes it look + * as though the branch instruction is reading all the locals needed by any + * target blocks. + */ + private void ResolveBlock(GraphNodeBlock currentBlock) + { + if(currentBlock.hasBeenResolved == this.resolveSequence) + return; + + // So we don't recurse forever on a backward branch. + currentBlock.hasBeenResolved = this.resolveSequence; + + // Assume we haven't written any locals yet. + List localsWrittenSoFar = new List(); + + // Scan through the instructions in this block. + for(GraphNode gn = currentBlock; gn != null;) + { + + // See if the instruction writes a local we don't know about yet. + ScriptMyLocal wrlcl = gn.WritesLocal(); + if((wrlcl != null) && !localsWrittenSoFar.Contains(wrlcl)) + { + localsWrittenSoFar.Add(wrlcl); + } + + // Scan through all the possible next instructions after this. + // Note that if we are in the first part of a try/catch/finally block, + // every instruction conditionally branches to the beginning of the + // second part (the catch/finally block). + GraphNode nextFallthruNode = null; + foreach(GraphNode nn in gn.NextNodes) + { + if(nn is GraphNodeBlock) + { + // Start of a block, go through all locals needed by that block on entry. + GraphNodeBlock nextBlock = (GraphNodeBlock)nn; + ResolveBlock(nextBlock); + foreach(ScriptMyLocal readByNextBlock in nextBlock.localsReadBeforeWritten) + { + // If this block hasn't written it by now and this block doesn't already + // require it on entry, say this block requires it on entry. + if(!localsWrittenSoFar.Contains(readByNextBlock) && + !currentBlock.localsReadBeforeWritten.Contains(readByNextBlock)) + { + currentBlock.localsReadBeforeWritten.Add(readByNextBlock); + this.resolvedSomething = true; + } + } + } + else + { + // Not start of a block, should be normal fallthru instruction. + if(nextFallthruNode != null) + throw new Exception("more than one fallthru from " + gn.ToString()); + nextFallthruNode = nn; + } + } + + // Process next instruction if it isn't the start of a block. + if(nextFallthruNode == gn) + throw new Exception("can't fallthru to self"); + gn = nextFallthruNode; + } + } + + /** + * @brief Figure out whether the value in a local var is needed after the given instruction. + * True if we reach the end of the program on all branches before reading it + * True if we write the local var on all branches before reading it + * False otherwise + */ + private bool IsLocalNeededAfterThis(GraphNode node, ScriptMyLocal local) + { + do + { + GraphNode nextFallthruNode = null; + foreach(GraphNode nn in node.NextNodes) + { + if(nn is GraphNodeBlock) + { + if(((GraphNodeBlock)nn).localsReadBeforeWritten.Contains(local)) + { + return true; + } + } + else + { + nextFallthruNode = nn; + } + } + node = nextFallthruNode; + if(node == null) + return false; + if(node.ReadsLocal() == local) + return true; + } while(node.WritesLocal() != local); + return false; + } + + public static void PadToLength(StringBuilder sb, int len, string str) + { + int pad = len - sb.Length; + if(pad < 0) + pad = 0; + sb.Append(str.PadLeft(pad)); + } + } +} diff --git a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptCompValu.cs b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptCompValu.cs new file mode 100644 index 0000000000..675ab9ae25 --- /dev/null +++ b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptCompValu.cs @@ -0,0 +1,1897 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using OpenSim.Region.ScriptEngine.Shared.ScriptBase; +using OpenSim.Region.ScriptEngine.Yengine; +using System; +using System.Collections.Generic; +using System.IO; +using System.Reflection; +using System.Reflection.Emit; + +using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; +using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; +using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; +using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list; +using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; +using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; +using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; + +/** + * @brief Compute values used during code generation to keep track of where computed values are stored. + * + * Conceptually holds the memory address and type of the value + * such as that used for a local variable, global variable, temporary variable. + * Also used for things like constants and function/method entrypoints, + * they are basically treated as read-only variables. + * + * cv.type - type of the value + * + * cv.PushVal() - pushes the value on the CIL stack + * cv.PushRef() - pushes address of the value on the CIL stack + * + * cv.PopPre() - gets ready to pop from the CIL stack + * ...by possibly pushing something + * + * cv.PushPre() - pops value from the CIL stack + * + * If the type is a TokenTypeSDTypeDelegate, the location is callable, + * so you get these additional functions: + * + * cv.GetRetType() - gets function/method's return value type + * TokenTypeVoid if void + * null if not a delegate + * cv.GetArgTypes() - gets array of argument types + * as seen by script level, ie, + * does not include any hidden 'this' type + * cv.GetArgSig() - gets argument signature eg, "(integer,list)" + * null if not a delegate + * + * cv.CallPre() - gets ready to call the function/method + * ...by possibly pushing something + * such as a 'this' pointer + * + * cv.CallPost() - calls the function/method + */ + +namespace OpenSim.Region.ScriptEngine.Yengine +{ + + /** + * @brief Location of a value + * Includes constants, expressions and temp variables. + */ + public abstract class CompValu + { + protected static readonly MethodInfo gsmdMethodInfo = + typeof(XMRInstAbstract).GetMethod("GetScriptMethodDelegate", + new Type[] { typeof(string), typeof(string), typeof(object) }); + + private static readonly MethodInfo avpmListMethInfo = typeof(XMRInstArrays).GetMethod("PopList", new Type[] { typeof(int), typeof(LSL_List) }); + private static readonly MethodInfo avpmObjectMethInfo = typeof(XMRInstArrays).GetMethod("PopObject", new Type[] { typeof(int), typeof(object) }); + private static readonly MethodInfo avpmStringMethInfo = typeof(XMRInstArrays).GetMethod("PopString", new Type[] { typeof(int), typeof(string) }); + + public TokenType type; // type of the value and where in the source it was used + + public CompValu(TokenType type) + { + this.type = type; + } + + public Type ToSysType() + { + return (type.ToLSLWrapType() != null) ? type.ToLSLWrapType() : type.ToSysType(); + } + + /* + * if a field of an XMRInstArrays array cannot be directly written, + * get the method that can write it + */ + private static MethodInfo ArrVarPopMeth(FieldInfo fi) + { + if(fi.Name == "iarLists") + return avpmListMethInfo; + if(fi.Name == "iarObjects") + return avpmObjectMethInfo; + if(fi.Name == "iarStrings") + return avpmStringMethInfo; + return null; + } + + /* + * emit code to push value onto stack + */ + public void PushVal(ScriptCodeGen scg, Token errorAt, TokenType stackType) + { + this.PushVal(scg, errorAt, stackType, false); + } + public void PushVal(ScriptCodeGen scg, Token errorAt, TokenType stackType, bool explicitAllowed) + { + this.PushVal(scg, errorAt); + TypeCast.CastTopOfStack(scg, errorAt, this.type, stackType, explicitAllowed); + } + public abstract void PushVal(ScriptCodeGen scg, Token errorAt); + public abstract void PushRef(ScriptCodeGen scg, Token errorAt); + + /* + * emit code to pop value from stack + */ + public void PopPost(ScriptCodeGen scg, Token errorAt, TokenType stackType) + { + TypeCast.CastTopOfStack(scg, errorAt, stackType, this.type, false); + this.PopPost(scg, errorAt); + } + public virtual void PopPre(ScriptCodeGen scg, Token errorAt) + { + } + + /* + * call this before pushing value to be popped + */ + public abstract void PopPost(ScriptCodeGen scg, Token errorAt); // call this after pushing value to be popped + + + /* + * return true: doing a PushVal() does not involve CheckRun() + * false: otherwise + */ + public virtual bool IsReadTrivial(ScriptCodeGen scg, Token readAt) + { + return true; + } + + /* + * These additional functions are available if the type is a delegate + */ + public TokenType GetRetType() + { + if(!(type is TokenTypeSDTypeDelegate)) + return null; + return ((TokenTypeSDTypeDelegate)type).decl.GetRetType(); + } + public TokenType[] GetArgTypes() + { + if(!(type is TokenTypeSDTypeDelegate)) + return null; + return ((TokenTypeSDTypeDelegate)type).decl.GetArgTypes(); + } + public string GetArgSig() + { + if(!(type is TokenTypeSDTypeDelegate)) + return null; + return ((TokenTypeSDTypeDelegate)type).decl.GetArgSig(); + } + + /* + * These are used only if type is a delegate too + * - but it is a real delegate pointer in a global or local variable or a field, etc + * - ie, PushVal() pushes a delegate pointer + * - so we must have CallPre() push the delegate pointer as a 'this' for this.Invoke(...) + * - and CallPost() call the delegate's Invoke() method + * - we assume the target function is non-trivial so we always use a call label + */ + public virtual void CallPre(ScriptCodeGen scg, Token errorAt) // call this before pushing arguments + { + new ScriptCodeGen.CallLabel(scg, errorAt); + this.PushVal(scg, errorAt); + } + public virtual void CallPost(ScriptCodeGen scg, Token errorAt) // call this after pushing arguments + { + TokenTypeSDTypeDelegate ttd = (TokenTypeSDTypeDelegate)type; + MethodInfo invokeMethodInfo = ttd.decl.GetInvokerInfo(); + scg.ilGen.Emit(errorAt, OpCodes.Callvirt, invokeMethodInfo); + scg.openCallLabel = null; + } + + /* + * Utilities used by CompValuGlobalVar and CompValuInstField + * where the value is located in a type-dependent array. + */ + protected void EmitFieldPushVal(ScriptCodeGen scg, Token errorAt, TokenDeclVar var) + { + scg.ilGen.Emit(errorAt, OpCodes.Ldfld, var.vTableArray); // which array + scg.ilGen.Emit(errorAt, OpCodes.Ldc_I4, var.vTableIndex); // which array element + if(type is TokenTypeFloat) + { + scg.ilGen.Emit(errorAt, OpCodes.Ldelem_R8); + } + else if(type is TokenTypeInt) + { + scg.ilGen.Emit(errorAt, OpCodes.Ldelem_I4); + } + else if(type is TokenTypeSDTypeDelegate) + { + scg.ilGen.Emit(errorAt, OpCodes.Ldelem, typeof(object)); + scg.ilGen.Emit(errorAt, OpCodes.Castclass, ToSysType()); + } + else + { + scg.ilGen.Emit(errorAt, OpCodes.Ldelem, ToSysType()); + } + } + + protected void EmitFieldPushRef(ScriptCodeGen scg, Token errorAt, TokenDeclVar var) + { + if(ArrVarPopMeth(var.vTableArray) != null) + { + scg.ErrorMsg(errorAt, "can't take address of this variable"); + } + scg.ilGen.Emit(errorAt, OpCodes.Ldfld, var.vTableArray); + scg.ilGen.Emit(errorAt, OpCodes.Ldc_I4, var.vTableIndex); + scg.ilGen.Emit(errorAt, OpCodes.Ldelema, ToSysType()); + } + + protected void EmitFieldPopPre(ScriptCodeGen scg, Token errorAt, TokenDeclVar var) + { + if(ArrVarPopMeth(var.vTableArray) != null) + { + scg.ilGen.Emit(errorAt, OpCodes.Ldc_I4, var.vTableIndex); + } + else + { + scg.ilGen.Emit(errorAt, OpCodes.Ldfld, var.vTableArray); + scg.ilGen.Emit(errorAt, OpCodes.Ldc_I4, var.vTableIndex); + } + } + + protected void EmitFieldPopPost(ScriptCodeGen scg, Token errorAt, TokenDeclVar var) + { + if(ArrVarPopMeth(var.vTableArray) != null) + { + scg.ilGen.Emit(errorAt, OpCodes.Call, ArrVarPopMeth(var.vTableArray)); + } + else if(type is TokenTypeFloat) + { + scg.ilGen.Emit(errorAt, OpCodes.Stelem_R8); + } + else if(type is TokenTypeInt) + { + scg.ilGen.Emit(errorAt, OpCodes.Stelem_I4); + } + else if(type is TokenTypeSDTypeDelegate) + { + scg.ilGen.Emit(errorAt, OpCodes.Stelem, typeof(object)); + } + else + { + scg.ilGen.Emit(errorAt, OpCodes.Stelem, ToSysType()); + } + } + + /** + * @brief With value pushed on stack, emit code to set a property by calling its setter() method. + * @param scg = which script is being compiled + * @param errorAt = for error messages + * @param type = property type + * @param setProp = setter() method + */ + protected void EmitPopPostProp(ScriptCodeGen scg, Token errorAt, TokenType type, CompValu setProp) + { + ScriptMyLocal temp = scg.ilGen.DeclareLocal(type.ToSysType(), "__spr_" + errorAt.Unique); + scg.ilGen.Emit(errorAt, OpCodes.Stloc, temp); + setProp.CallPre(scg, errorAt); + scg.ilGen.Emit(errorAt, OpCodes.Ldloc, temp); + setProp.CallPost(scg, errorAt); + } + } + + // The value is kept in an (XMR_Array) array element + public class CompValuArEle: CompValu + { + public CompValu arr; + private CompValu idx; + private TokenTypeObject tto; + + private static readonly MethodInfo getByKeyMethodInfo = typeof(XMR_Array).GetMethod("GetByKey", + new Type[] { typeof(object) }); + private static readonly MethodInfo setByKeyMethodInfo = typeof(XMR_Array).GetMethod("SetByKey", + new Type[] { typeof (object), + typeof (object) }); + + // type = TokenTypeObject always, as our array elements are always of type 'object' + // arr = where the array object itself is stored + // idx = where the index value is stored + public CompValuArEle(TokenType type, CompValu arr, CompValu idx) : base(type) + { + this.arr = arr; + this.idx = idx; + this.tto = new TokenTypeObject(this.type); + } + public override void PushVal(ScriptCodeGen scg, Token errorAt) + { + arr.PushVal(scg, errorAt); // array + idx.PushVal(scg, errorAt, this.tto); // key + scg.ilGen.Emit(errorAt, OpCodes.Call, getByKeyMethodInfo); + } + public override void PushRef(ScriptCodeGen scg, Token errorAt) + { + scg.ErrorMsg(errorAt, "array element not allowed here"); + scg.ilGen.Emit(errorAt, OpCodes.Ldnull); + } + public override void PopPre(ScriptCodeGen scg, Token errorAt) + { + arr.PushVal(scg, errorAt); // array + idx.PushVal(scg, errorAt, this.tto); // key + } + public override void PopPost(ScriptCodeGen scg, Token errorAt) + { + scg.ilGen.Emit(errorAt, OpCodes.Call, setByKeyMethodInfo); + } + + // non-trivial because it needs to be copied into a temp + // in case the idiot does dumb-ass side effects tricks + // eg, (x = 0) + x + 2 + // should read old value of x not 0 + // but if 'xmroption norighttoleft;' in effect, + // we can read it in any order so reading an + // XMR_Array element is trivial + public override bool IsReadTrivial(ScriptCodeGen scg, Token readAt) + { + return readAt.nr2l; + } + } + + // The value is kept in the current function's argument list + public class CompValuArg: CompValu + { + public int index; + public bool readOnly; + + private static OpCode[] ldargs = { OpCodes.Ldarg_0, OpCodes.Ldarg_1, + OpCodes.Ldarg_2, OpCodes.Ldarg_3 }; + + public CompValuArg(TokenType type, int index) : base(type) + { + this.index = index; + } + public CompValuArg(TokenType type, int index, bool ro) : base(type) + { + this.index = index; + this.readOnly = ro; + } + public override void PushVal(ScriptCodeGen scg, Token errorAt) + { + if(index < ldargs.Length) + scg.ilGen.Emit(errorAt, ldargs[index]); + else if(index <= 255) + scg.ilGen.Emit(errorAt, OpCodes.Ldarg_S, index); + else + scg.ilGen.Emit(errorAt, OpCodes.Ldarg, index); + } + public override void PushRef(ScriptCodeGen scg, Token errorAt) + { + if(readOnly) + { + scg.ErrorMsg(errorAt, "location cannot be written to"); + } + if(index <= 255) + scg.ilGen.Emit(errorAt, OpCodes.Ldarga_S, index); + else + scg.ilGen.Emit(errorAt, OpCodes.Ldarga, index); + } + public override void PopPost(ScriptCodeGen scg, Token errorAt) + { + if(readOnly) + { + scg.ErrorMsg(errorAt, "location cannot be written to"); + } + scg.ilGen.Emit(errorAt, OpCodes.Starg, index); + } + + // non-trivial because it needs to be copied into a temp + // in case the idiot does dumb-ass side effects tricks + // eg, (x = 0) + x + 2 + // should read old value of x not 0 + // but if 'xmroption norighttoleft;' in effect, + // we can read it in any order so reading an + // argument is trivial + public override bool IsReadTrivial(ScriptCodeGen scg, Token readAt) + { + return readAt.nr2l; + } + } + + // The value is a character constant + public class CompValuChar: CompValu + { + public char x; + + public CompValuChar(TokenType type, char x) : base(type) + { + if(!(this.type is TokenTypeChar)) + { + this.type = new TokenTypeChar(this.type); + } + this.x = x; + } + public override void PushVal(ScriptCodeGen scg, Token errorAt) + { + scg.ilGen.Emit(errorAt, OpCodes.Ldc_I4, (int)x); + } + public override void PushRef(ScriptCodeGen scg, Token errorAt) + { + throw new Exception("cannot get constant's address"); + } + public override void PopPost(ScriptCodeGen scg, Token errorAt) + { + throw new Exception("cannot store into contant"); + } + } + + // The value is kept in a struct/class field of an internal struct/class + public class CompValuField: CompValu + { + CompValu obj; + FieldInfo field; + + public CompValuField(TokenType type, CompValu obj, FieldInfo field) : base(type) + { + this.obj = obj; + this.field = field; + } + public override void PushVal(ScriptCodeGen scg, Token errorAt) + { + if(field.ReflectedType.IsValueType) + { + obj.PushRef(scg, errorAt); + } + else + { + obj.PushVal(scg, errorAt); + } + scg.ilGen.Emit(errorAt, OpCodes.Ldfld, field); + } + public override void PushRef(ScriptCodeGen scg, Token errorAt) + { + if(field.ReflectedType.IsValueType) + { + obj.PushRef(scg, errorAt); + } + else + { + obj.PushVal(scg, errorAt); + } + scg.ilGen.Emit(errorAt, OpCodes.Ldflda, field); + } + public override void PopPre(ScriptCodeGen scg, Token errorAt) + { + if(field.ReflectedType.IsValueType) + { + obj.PushRef(scg, errorAt); + } + else + { + obj.PushVal(scg, errorAt); + } + } + public override void PopPost(ScriptCodeGen scg, Token errorAt) + { + scg.ilGen.Emit(errorAt, OpCodes.Stfld, field); + } + + // non-trivial because it needs to be copied into a temp + // in case the idiot does dumb-ass side effects tricks + // eg, (x = 0) + x + 2 + // should read old value of x not 0 + // but if 'xmroption norighttoleft;' in effect, + // we can read it in any order so reading an + // field of a class/struct is trivial + public override bool IsReadTrivial(ScriptCodeGen scg, Token readAt) + { + return readAt.nr2l; + } + } + + // Accessing an element of a fixed-dimension array + public class CompValuFixArEl: CompValu + { + private CompValu baseRVal; + private CompValu[] subRVals; + + private int nSubs; + private TokenDeclVar getFunc; + private TokenDeclVar setFunc; + private TokenTypeInt tokenTypeInt; + + /** + * @brief Set up to access an element of an array. + * @param scg = what script we are compiling + * @param baseRVal = what array we are accessing + * @param subRVals = the subscripts being applied + */ + public CompValuFixArEl(ScriptCodeGen scg, CompValu baseRVal, CompValu[] subRVals) : base(GetElementType(scg, baseRVal, subRVals)) + { + this.baseRVal = baseRVal; // location of the array itself + this.subRVals = subRVals; // subscript values + this.nSubs = subRVals.Length; + + TokenTypeSDTypeClass sdtType = (TokenTypeSDTypeClass)baseRVal.type; + TokenDeclSDTypeClass sdtDecl = sdtType.decl; + tokenTypeInt = new TokenTypeInt(sdtType); + + TokenName name = new TokenName(sdtType, "Get"); + TokenType[] argsig = new TokenType[nSubs]; + for(int i = 0; i < nSubs; i++) + { + argsig[i] = tokenTypeInt; + } + getFunc = scg.FindThisMember(sdtDecl, name, argsig); + + name = new TokenName(sdtType, "Set"); + argsig = new TokenType[nSubs + 1]; + for(int i = 0; i < nSubs; i++) + { + argsig[i] = tokenTypeInt; + } + argsig[nSubs] = getFunc.retType; + setFunc = scg.FindThisMember(sdtDecl, name, argsig); + } + + /** + * @brief Read array element and push value on stack. + */ + public override void PushVal(ScriptCodeGen scg, Token errorAt) + { + // call script-defined class' Get() method to fetch the value + baseRVal.PushVal(scg, errorAt); + for(int i = 0; i < nSubs; i++) + { + subRVals[i].PushVal(scg, errorAt, tokenTypeInt); + } + scg.ilGen.Emit(errorAt, OpCodes.Call, getFunc.ilGen); + } + + /** + * @brief Push address of array element on stack. + */ + public override void PushRef(ScriptCodeGen scg, Token errorAt) + { + throw new Exception("tu stOOpid to get array element address"); + } + + /** + * @brief Prepare to write array element. + */ + public override void PopPre(ScriptCodeGen scg, Token errorAt) + { + // set up call to script-defined class' Set() method to write the value + baseRVal.PushVal(scg, errorAt); + for(int i = 0; i < nSubs; i++) + { + subRVals[i].PushVal(scg, errorAt, tokenTypeInt); + } + } + + /** + * @brief Pop value from stack and write array element. + */ + public override void PopPost(ScriptCodeGen scg, Token errorAt) + { + // call script-defined class' Set() method to write the value + scg.ilGen.Emit(errorAt, OpCodes.Call, setFunc.ilGen); + } + + /** + * @brief Get the array element type by getting the Get() functions return type. + * Crude but effective. + * @param scg = what script we are compiling + * @param baseRVal = what array we are accessing + * @param subRVals = the subscripts being applied + * @returns array element type + */ + private static TokenType GetElementType(ScriptCodeGen scg, CompValu baseRVal, CompValu[] subRVals) + { + TokenTypeSDTypeClass sdtType = (TokenTypeSDTypeClass)baseRVal.type; + TokenDeclSDTypeClass sdtDecl = sdtType.decl; + TokenName name = new TokenName(sdtType, "Get"); + int nSubs = subRVals.Length; + TokenType[] argsig = new TokenType[nSubs]; + argsig[0] = new TokenTypeInt(sdtType); + for(int i = 0; ++i < nSubs;) + { + argsig[i] = argsig[0]; + } + TokenDeclVar getFunc = scg.FindThisMember(sdtDecl, name, argsig); + return getFunc.retType; + } + + // non-trivial because it needs to be copied into a temp + // in case the idiot does dumb-ass side effects tricks + // eg, (x = 0) + x + 2 + // should read old value of x not 0 + // but if 'xmroption norighttoleft;' in effect, + // we can read it in any order so reading an + // fixed-dimension array element is trivial + public override bool IsReadTrivial(ScriptCodeGen scg, Token readAt) + { + return readAt.nr2l; + } + } + + // The value is a float constant + public class CompValuFloat: CompValu + { + public double x; + + public CompValuFloat(TokenType type, double x) : base(type) + { + if(!(this.type is TokenTypeFloat)) + { + this.type = new TokenTypeFloat(this.type); + } + this.x = x; + } + public override void PushVal(ScriptCodeGen scg, Token errorAt) + { + scg.ilGen.Emit(errorAt, OpCodes.Ldc_R8, x); + } + public override void PushRef(ScriptCodeGen scg, Token errorAt) + { + throw new Exception("cannot get constant's address"); + } + public override void PopPost(ScriptCodeGen scg, Token errorAt) + { + throw new Exception("cannot store into constant"); + } + } + + // The value is the entrypoint of a script-defined global function. + // These are also used for script-defined type static methods as the calling convention is the same, + // ie, the XMRInstance pointer is a hidden first argument. + // There is just one of these created when the function is being compiled as there is only one value + // of the function. + public class CompValuGlobalMeth: CompValu + { + private TokenDeclVar func; + + public CompValuGlobalMeth(TokenDeclVar declFunc) : base(declFunc.GetDelType()) + { + this.func = declFunc; + } + + /** + * @brief PushVal for a function/method means push a delegate on the stack. + * We build a call to the DynamicMethod's CreateDelegate() function + * to create the delegate. Slip the scriptinstance pointer as the + * function's arg 0 so it will get passed to the function when called. + */ + public override void PushVal(ScriptCodeGen scg, Token errorAt) + { + string dtn = type.ToString(); + if(dtn.StartsWith("delegate ")) + dtn = dtn.Substring(9); + + // delegateinstance = (signature)scriptinstance.GetScriptMethodDelegate (methName, signature, arg0); + // where methName = [.]() + // signature = () + // arg0 = scriptinstance (XMRInstance) + scg.PushXMRInst(); // [0] scriptinstance + scg.ilGen.Emit(errorAt, OpCodes.Ldstr, func.ilGen.methName); // [1] method name + scg.ilGen.Emit(errorAt, OpCodes.Ldstr, dtn); // [2] delegate type name + scg.PushXMRInst(); // [3] scriptinstance + scg.ilGen.Emit(errorAt, OpCodes.Callvirt, gsmdMethodInfo); // [0] delegate instance + scg.ilGen.Emit(errorAt, OpCodes.Castclass, type.ToSysType()); // [0] cast to correct delegate class + } + public override void PushRef(ScriptCodeGen scg, Token errorAt) + { + throw new Exception("cannot get ref to global method"); + } + public override void PopPost(ScriptCodeGen scg, Token errorAt) + { + throw new Exception("cannot store into global method"); + } + + /** + * @brief A direct call is much simpler than pushing a delegate. + * Just push the XMRInstance pointer, push the args and finally call the function. + */ + public override void CallPre(ScriptCodeGen scg, Token errorAt) + { + if(!this.func.IsFuncTrivial(scg)) + new ScriptCodeGen.CallLabel(scg, errorAt); + + // all script-defined global functions are static methods created by DynamicMethod() + // and the first argument is always the XMR_Instance pointer + scg.PushXMRInst(); + } + public override void CallPost(ScriptCodeGen scg, Token errorAt) + { + scg.ilGen.Emit(errorAt, OpCodes.Call, func.ilGen); + if(!this.func.IsFuncTrivial(scg)) + scg.openCallLabel = null; + } + } + + // The value is in a script-global variable = ScriptModule instance variable + // It could also be a script-global property + public class CompValuGlobalVar: CompValu + { + private static readonly FieldInfo glblVarsFieldInfo = typeof(XMRInstAbstract).GetField("glblVars"); + + private TokenDeclVar declVar; + + public CompValuGlobalVar(TokenDeclVar declVar, XMRInstArSizes glblSizes) : base(declVar.type) + { + this.declVar = declVar; + if((declVar.getProp == null) && (declVar.setProp == null)) + { + declVar.type.AssignVarSlot(declVar, glblSizes); + } + } + public override void PushVal(ScriptCodeGen scg, Token errorAt) + { + if((declVar.getProp == null) && (declVar.setProp == null)) + { + scg.PushXMRInst(); + scg.ilGen.Emit(errorAt, OpCodes.Ldfld, glblVarsFieldInfo); + EmitFieldPushVal(scg, errorAt, declVar); + } + else if(declVar.getProp != null) + { + declVar.getProp.location.CallPre(scg, errorAt); + declVar.getProp.location.CallPost(scg, errorAt); + } + else + { + scg.ErrorMsg(errorAt, "property not readable"); + scg.PushDefaultValue(declVar.type); + } + } + public override void PushRef(ScriptCodeGen scg, Token errorAt) + { + if((declVar.getProp == null) && (declVar.setProp == null)) + { + scg.PushXMRInst(); + scg.ilGen.Emit(errorAt, OpCodes.Ldfld, glblVarsFieldInfo); + EmitFieldPushRef(scg, errorAt, declVar); + } + else + { + scg.ErrorMsg(errorAt, "cannot get address of property"); + } + } + public override void PopPre(ScriptCodeGen scg, Token errorAt) + { + if((declVar.getProp == null) && (declVar.setProp == null)) + { + scg.PushXMRInst(); + scg.ilGen.Emit(errorAt, OpCodes.Ldfld, glblVarsFieldInfo); + EmitFieldPopPre(scg, errorAt, declVar); + } + else if(declVar.setProp == null) + { + scg.ErrorMsg(errorAt, "property not writable"); + } + } + public override void PopPost(ScriptCodeGen scg, Token errorAt) + { + if((declVar.getProp == null) && (declVar.setProp == null)) + { + EmitFieldPopPost(scg, errorAt, declVar); + } + else if(declVar.setProp != null) + { + EmitPopPostProp(scg, errorAt, declVar.type, declVar.setProp.location); + } + else + { + scg.ilGen.Emit(errorAt, OpCodes.Pop); + } + } + + // non-trivial because it needs to be copied into a temp + // in case the idiot does dumb-ass side effects tricks + // eg, (x = 0) + x + 2 + // should read old value of x not 0 + // but if 'xmroption norighttoleft;' in effect, + // we can read it in any order so reading an + // global variable is trivial provided it is + // not a property or the property function is + // trivial. + public override bool IsReadTrivial(ScriptCodeGen scg, Token readAt) + { + return readAt.nr2l && ((declVar.getProp == null) || declVar.getProp.IsFuncTrivial(scg)); + } + } + + // The value is in an $idxprop property of a script-defined type class or interface instance. + // Reading and writing is via a method call. + public class CompValuIdxProp: CompValu + { + private TokenDeclVar idxProp; // $idxprop property within baseRVal + private CompValu baseRVal; // pointer to class or interface object containing property + private TokenType[] argTypes; // argument types as required by $idxprop declaration + private CompValu[] indices; // actual index values to pass to getter/setter method + private CompValu setProp; // location of setter method + + public CompValuIdxProp(TokenDeclVar idxProp, CompValu baseRVal, TokenType[] argTypes, CompValu[] indices) : base(idxProp.type) + { + this.idxProp = idxProp; + this.baseRVal = baseRVal; + this.argTypes = argTypes; + this.indices = indices; + } + + /** + * @brief Pushing the property's value is a matter of calling the getter method + * with the supplied argument list as is. + */ + public override void PushVal(ScriptCodeGen scg, Token errorAt) + { + if(idxProp.getProp != null) + { + if(!idxProp.getProp.IsFuncTrivial(scg)) + { + for(int i = indices.Length; --i >= 0;) + { + indices[i] = scg.Trivialize(indices[i], errorAt); + } + } + CompValu getProp = GetIdxPropMeth(idxProp.getProp); + getProp.CallPre(scg, errorAt); + for(int i = 0; i < indices.Length; i++) + { + indices[i].PushVal(scg, errorAt, argTypes[i]); + } + getProp.CallPost(scg, errorAt); + } + else + { + // write-only property + scg.ErrorMsg(errorAt, "member not readable"); + scg.PushDefaultValue(idxProp.type); + } + } + + /** + * @brief A property does not have a memory address. + */ + public override void PushRef(ScriptCodeGen scg, Token errorAt) + { + scg.ErrorMsg(errorAt, "member has no address"); + scg.ilGen.Emit(errorAt, OpCodes.Ldnull); + } + + /** + * @brief Preparing to write a property consists of preparing to call the setter method + * then pushing the index arguments. + */ + public override void PopPre(ScriptCodeGen scg, Token errorAt) + { + if(idxProp.setProp != null) + { + if(!idxProp.setProp.IsFuncTrivial(scg)) + { + for(int i = indices.Length; --i >= 0;) + { + indices[i] = scg.Trivialize(indices[i], errorAt); + } + } + this.setProp = GetIdxPropMeth(idxProp.setProp); + this.setProp.CallPre(scg, errorAt); + for(int i = 0; i < indices.Length; i++) + { + indices[i].PushVal(scg, errorAt, argTypes[i]); + } + } + else + { + // read-only property + scg.ErrorMsg(errorAt, "member not writable"); + } + } + + /** + * @brief Finishing writing a property consists of finishing the call to the setter method + * now that the value to be written has been pushed by our caller. + */ + public override void PopPost(ScriptCodeGen scg, Token errorAt) + { + if(idxProp.setProp != null) + { + this.setProp.CallPost(scg, errorAt); + } + else + { + scg.ilGen.Emit(errorAt, OpCodes.Pop); + } + } + + public override bool IsReadTrivial(ScriptCodeGen scg, Token readAt) + { + // if no getter, reading would throw an error, so doesn't really matter what we say + if(idxProp.getProp == null) + return true; + + // assume interface methods are always non-trivial because we don't know anything about the actual implementation + if(baseRVal.type is TokenTypeSDTypeInterface) + return false; + + // accessing it in any way can't be trivial if reading the pointer isn't trivial + if(!baseRVal.IsReadTrivial(scg, readAt)) + return false; + + // likewise with the indices + foreach(CompValu idx in indices) + { + if(!idx.IsReadTrivial(scg, readAt)) + return false; + } + + // now the only way it can be non-trivial to read is if the getter() method itself is non-trivial. + return idxProp.getProp.IsFuncTrivial(scg); + } + + /** + * @brief Get how to call the getter or setter method. + */ + private CompValu GetIdxPropMeth(TokenDeclVar meth) + { + if(baseRVal.type is TokenTypeSDTypeClass) + { + return new CompValuInstMember(meth, baseRVal, false); + } + return new CompValuIntfMember(meth, baseRVal); + } + } + + // This represents the type and location of an internally-defined function + // that a script can call + public class CompValuInline: CompValu + { + public TokenDeclInline declInline; + + public CompValuInline(TokenDeclInline declInline) : base(declInline.GetDelType()) + { + this.declInline = declInline; + } + + public override void PushVal(ScriptCodeGen scg, Token errorAt) + { + scg.ErrorMsg(errorAt, "cannot use built-in for delegate, wrap it"); + scg.ilGen.Emit(errorAt, OpCodes.Ldnull); + } + public override void PushRef(ScriptCodeGen scg, Token errorAt) + { + scg.ErrorMsg(errorAt, "cannot use built-in for delegate, wrap it"); + scg.ilGen.Emit(errorAt, OpCodes.Ldnull); + } + public override void PopPre(ScriptCodeGen scg, Token errorAt) + { + scg.ErrorMsg(errorAt, "cannot use built-in for delegate, wrap it"); + } + public override void PopPost(ScriptCodeGen scg, Token errorAt) + { + scg.ErrorMsg(errorAt, "cannot use built-in for delegate, wrap it"); + scg.ilGen.Emit(errorAt, OpCodes.Pop); + } + } + + // The value is the entrypoint of a script-defined type's interface method combined with + // the pointer used to access the method. Thus there is one of these per call site. + // They also handle accessing interface properties. + public class CompValuIntfMember: CompValu + { + private TokenDeclVar declVar; + private CompValu baseRVal; + + public CompValuIntfMember(TokenDeclVar declVar, CompValu baseRVal) : base(declVar.type) + { + if(this.type == null) + throw new Exception("interface member type is null"); + this.declVar = declVar; // which element of the baseRVal vector to be accessed + this.baseRVal = baseRVal; // the vector of delegates implementing the interface + } + + /** + * @brief Reading a method's value means getting a delegate to that method. + * Reading a property's value means calling the getter method for that property. + */ + public override void PushVal(ScriptCodeGen scg, Token errorAt) + { + if(declVar.retType != null) + { + baseRVal.PushVal(scg, errorAt); // push pointer to delegate array on stack + scg.ilGen.Emit(errorAt, OpCodes.Ldc_I4, declVar.vTableIndex); // select which delegate to access + scg.ilGen.Emit(errorAt, OpCodes.Ldelem, typeof(Delegate)); // push delegate on stack + scg.ilGen.Emit(errorAt, OpCodes.Castclass, type.ToSysType()); // cast to correct delegate class + } + else if(declVar.getProp != null) + { + CompValu getProp = new CompValuIntfMember(declVar.getProp, baseRVal); + getProp.CallPre(scg, errorAt); // reading property, call its getter + getProp.CallPost(scg, errorAt); // ... with no arguments + } + else + { + scg.ErrorMsg(errorAt, "member not readable"); + scg.PushDefaultValue(declVar.type); + } + } + + /** + * @brief Can't get the address of either a method or a property. + */ + public override void PushRef(ScriptCodeGen scg, Token errorAt) + { + scg.ErrorMsg(errorAt, "member has no address"); + scg.ilGen.Emit(errorAt, OpCodes.Ldnull); + } + + /** + * @brief Can't write a method. + * For property, it means calling the setter method for that property. + */ + public override void PopPre(ScriptCodeGen scg, Token errorAt) + { + if(declVar.setProp == null) + { + // read-only property + scg.ErrorMsg(errorAt, "member not writable"); + } + } + public override void PopPost(ScriptCodeGen scg, Token errorAt) + { + if(declVar.setProp != null) + { + CompValu setProp = new CompValuIntfMember(declVar.setProp, baseRVal); + EmitPopPostProp(scg, errorAt, declVar.type, setProp); + } + else + { + scg.ilGen.Emit(errorAt, OpCodes.Pop); + } + } + + /** + * @brief Reading a method (ie, it's delegate) is always trivial, it's just retrieving + * an element from the delegate array that make up the interface object. + * + * Reading a property is always non-trivial because we don't know which implementation + * the interface is pointing to, so we don't know if it's trivial or not, so assume + * the worst, ie, that it is non-trivial and might call CheckRun(). + * + * But all that assumes that locating the interface object in the first place is + * trivial, ie, baseRVal.PushVal() must not call CheckRun() either. + */ + public override bool IsReadTrivial(ScriptCodeGen scg, Token readAt) + { + return baseRVal.IsReadTrivial(scg, readAt) && (declVar.getProp == null); + } + + /** + * @brief We just defer to the default CallPre() and CallPost() methods. + * They expect this.PushVal() to push a delegate to the method to be called. + * If this member is a method, our PushVal() will read the correct element + * of the iTable array and push it on the stack, ready for Invoke() to be + * called. If this member is a property, the only way it can be called is + * if the property is a delegate, in which case PushVal() will retrieve the + * delegate by calling the property's getter method. + */ + } + + // The value is the entrypoint of an internal instance method + // such as XMR_Array.index() + public class CompValuIntInstMeth: CompValu + { + private TokenTypeSDTypeDelegate delType; + private CompValu baseRVal; + private MethodInfo methInfo; + + public CompValuIntInstMeth(TokenTypeSDTypeDelegate delType, CompValu baseRVal, MethodInfo methInfo) : base(delType) + { + this.delType = delType; + this.baseRVal = baseRVal; + this.methInfo = methInfo; + } + + public override void PushVal(ScriptCodeGen scg, Token errorAt) + { + // its value, ie, without applying the (arglist), is a delegate... + baseRVal.PushVal(scg, errorAt); + scg.ilGen.Emit(errorAt, OpCodes.Ldftn, methInfo); + scg.ilGen.Emit(errorAt, OpCodes.Newobj, delType.decl.GetConstructorInfo()); + } + public override void PushRef(ScriptCodeGen scg, Token errorAt) + { + throw new Exception("cannot get ref to instance method"); + } + public override void PopPost(ScriptCodeGen scg, Token errorAt) + { + throw new Exception("cannot store into instance method"); + } + + public override void CallPre(ScriptCodeGen scg, Token errorAt) + { + // internal instance methods are always trivial so never need a CallLabel. + baseRVal.PushVal(scg, errorAt); + } + public override void CallPost(ScriptCodeGen scg, Token errorAt) + { + scg.ilGen.Emit(errorAt, OpCodes.Call, methInfo); + } + } + + // The value is fetched by calling an internal instance method + // such as XMR_Array.count + public class CompValuIntInstROProp: CompValu + { + private CompValu baseRVal; + private MethodInfo methInfo; + + public CompValuIntInstROProp(TokenType valType, CompValu baseRVal, MethodInfo methInfo) : base(valType) + { + this.baseRVal = baseRVal; + this.methInfo = methInfo; + } + + public override void PushVal(ScriptCodeGen scg, Token errorAt) + { + baseRVal.PushVal(scg, errorAt); + scg.ilGen.Emit(errorAt, OpCodes.Call, methInfo); + } + public override void PushRef(ScriptCodeGen scg, Token errorAt) + { + scg.ErrorMsg(errorAt, "cannot get ref to read-only property"); + scg.ilGen.Emit(errorAt, OpCodes.Ldnull); + } + public override void PopPost(ScriptCodeGen scg, Token errorAt) + { + scg.ErrorMsg(errorAt, "cannot store into read-only property"); + scg.ilGen.Emit(errorAt, OpCodes.Pop); + } + } + + // The value is in a member of a script-defined type class instance. + // field: value is in one of the arrays contained within XMRSDTypeClObj.instVars + // method: value is a delegate; can be called + // property: reading and writing is via a method call + public class CompValuInstMember: CompValu + { + private static readonly FieldInfo instVarsFieldInfo = typeof(XMRSDTypeClObj).GetField("instVars"); + private static readonly FieldInfo vTableFieldInfo = typeof(XMRSDTypeClObj).GetField("sdtcVTable"); + + private TokenDeclVar declVar; // member being accessed + private CompValu baseRVal; // pointer to particular object instance + private bool ignoreVirt; // ignore virtual attribute; use declVar's non-virtual method/property + + public CompValuInstMember(TokenDeclVar declVar, CompValu baseRVal, bool ignoreVirt) : base(declVar.type) + { + this.declVar = declVar; + this.baseRVal = baseRVal; + this.ignoreVirt = ignoreVirt; + } + + public override void PushVal(ScriptCodeGen scg, Token errorAt) + { + if(declVar.retType != null) + { + // a method's value, ie, without applying the (arglist), is a delegate... + PushValMethod(scg, errorAt); + } + else if(declVar.vTableArray != null) + { + // a field's value is its XMRSDTypeClObj.instVars array element + baseRVal.PushVal(scg, errorAt); + scg.ilGen.Emit(errorAt, OpCodes.Ldfld, instVarsFieldInfo); + EmitFieldPushVal(scg, errorAt, declVar); + } + else if(declVar.getProp != null) + { + // a property's value is calling its get method with no arguments + CompValu getProp = new CompValuInstMember(declVar.getProp, baseRVal, ignoreVirt); + getProp.CallPre(scg, errorAt); + getProp.CallPost(scg, errorAt); + } + else + { + // write-only property + scg.ErrorMsg(errorAt, "member not readable"); + scg.PushDefaultValue(declVar.type); + } + } + public override void PushRef(ScriptCodeGen scg, Token errorAt) + { + if(declVar.vTableArray != null) + { + // a field's value is its XMRSDTypeClObj.instVars array element + baseRVal.PushVal(scg, errorAt); + scg.ilGen.Emit(errorAt, OpCodes.Ldfld, instVarsFieldInfo); + EmitFieldPushRef(scg, errorAt, declVar); + } + else + { + scg.ErrorMsg(errorAt, "member has no address"); + scg.ilGen.Emit(errorAt, OpCodes.Ldnull); + } + } + public override void PopPre(ScriptCodeGen scg, Token errorAt) + { + if(declVar.vTableArray != null) + { + // a field's value is its XMRSDTypeClObj.instVars array element + baseRVal.PushVal(scg, errorAt); + scg.ilGen.Emit(errorAt, OpCodes.Ldfld, instVarsFieldInfo); + EmitFieldPopPre(scg, errorAt, declVar); + } + else if(declVar.setProp == null) + { + // read-only property + scg.ErrorMsg(errorAt, "member not writable"); + } + } + public override void PopPost(ScriptCodeGen scg, Token errorAt) + { + if(declVar.vTableArray != null) + { + EmitFieldPopPost(scg, errorAt, declVar); + } + else if(declVar.setProp != null) + { + CompValu setProp = new CompValuInstMember(declVar.setProp, baseRVal, ignoreVirt); + EmitPopPostProp(scg, errorAt, declVar.type, setProp); + } + else + { + scg.ilGen.Emit(errorAt, OpCodes.Pop); + } + } + + public override bool IsReadTrivial(ScriptCodeGen scg, Token readAt) + { + // accessing it in any way can't be trivial if reading the pointer isn't trivial. + // this also handles strict right-to-left mode detection as the side-effect can + // only apply to the pointer (it can't change which field or method we access). + if(!baseRVal.IsReadTrivial(scg, readAt)) + return false; + + // now the only way it can be non-trivial to read is if it is a property and the + // getter() method is non-trivial. reading a method means getting a delegate + // which is always trivial, and reading a simple field is always trivial, ie, no + // CheckRun() call can possibly be involved. + if(declVar.retType != null) + { + // a method's value, ie, without applying the (arglist), is a delegate... + return true; + } + if(declVar.vTableArray != null) + { + // a field's value is its XMRSDTypeClObj.instVars array element + return true; + } + if(declVar.getProp != null) + { + // a property's value is calling its get method with no arguments + return declVar.getProp.IsFuncTrivial(scg); + } + + // write-only property + return true; + } + + public override void CallPre(ScriptCodeGen scg, Token errorAt) + { + if(declVar.retType != null) + { + CallPreMethod(scg, errorAt); + } + else + { + base.CallPre(scg, errorAt); + } + } + public override void CallPost(ScriptCodeGen scg, Token errorAt) + { + if(declVar.retType != null) + { + CallPostMethod(scg, errorAt); + } + else + { + base.CallPost(scg, errorAt); + } + } + + /** + * @brief A PushVal() for a method means to push a delegate for the method on the stack. + */ + private void PushValMethod(ScriptCodeGen scg, Token errorAt) + { + if((declVar.sdtFlags & ScriptReduce.SDT_STATIC) != 0) + throw new Exception("dont use for statics"); + + if(ignoreVirt || (declVar.vTableIndex < 0)) + { + + /* + * Non-virtual instance method, create a delegate that references the method. + */ + string dtn = type.ToString(); + + // delegateinstance = (signature)scriptinstance.GetScriptMethodDelegate (methName, signature, arg0); + // where methName = .() + // signature = () + // arg0 = sdt istance (XMRSDTypeClObj) 'this' value + scg.PushXMRInst(); // [0] scriptinstance + scg.ilGen.Emit(errorAt, OpCodes.Ldstr, declVar.ilGen.methName); // [1] method name + scg.ilGen.Emit(errorAt, OpCodes.Ldstr, dtn); // [2] delegate type name + baseRVal.PushVal(scg, errorAt); // [3] sdtinstance + scg.ilGen.Emit(errorAt, OpCodes.Callvirt, gsmdMethodInfo); // [0] delegate instance + scg.ilGen.Emit(errorAt, OpCodes.Castclass, type.ToSysType()); // [0] cast to correct delegate class + } + else + { + + /* + * Virtual instance method, get the delegate from the vtable. + */ + baseRVal.PushVal(scg, errorAt); // 'this' selecting the instance + scg.ilGen.Emit(errorAt, OpCodes.Ldfld, vTableFieldInfo); // get pointer to instance's vtable array + scg.ilGen.Emit(errorAt, OpCodes.Ldc_I4, declVar.vTableIndex); // select vtable element + scg.ilGen.Emit(errorAt, OpCodes.Ldelem, typeof(Delegate)); // get delegate pointer = 'this' for 'Invoke()' + scg.ilGen.Emit(errorAt, OpCodes.Castclass, type.ToSysType()); // cast to correct delegate class + } + } + + private void CallPreMethod(ScriptCodeGen scg, Token errorAt) + { + if((declVar.sdtFlags & ScriptReduce.SDT_STATIC) != 0) + throw new Exception("dont use for statics"); + + if(!this.declVar.IsFuncTrivial(scg)) + new ScriptCodeGen.CallLabel(scg, errorAt); + + if(ignoreVirt || (declVar.vTableIndex < 0)) + { + baseRVal.PushVal(scg, errorAt); // 'this' being passed directly to method + } + else + { + baseRVal.PushVal(scg, errorAt); // 'this' selecting the instance + scg.ilGen.Emit(errorAt, OpCodes.Ldfld, vTableFieldInfo); // get pointer to instance's vtable array + scg.ilGen.Emit(errorAt, OpCodes.Ldc_I4, declVar.vTableIndex); // select vtable element + scg.ilGen.Emit(errorAt, OpCodes.Ldelem, typeof(Delegate)); // get delegate pointer = 'this' for 'Invoke()' + scg.ilGen.Emit(errorAt, OpCodes.Castclass, type.ToSysType()); // cast to correct delegate class + } + } + private void CallPostMethod(ScriptCodeGen scg, Token errorAt) + { + if(ignoreVirt || (declVar.vTableIndex < 0)) + { + // non-virt instance, just call function directly + scg.ilGen.Emit(errorAt, OpCodes.Call, declVar.ilGen); + } + else + { + // virtual, call via delegate Invoke(...) method + TokenTypeSDTypeDelegate ttd = (TokenTypeSDTypeDelegate)type; + MethodInfo invokeMethodInfo = ttd.decl.GetInvokerInfo(); + scg.ilGen.Emit(errorAt, OpCodes.Callvirt, invokeMethodInfo); + } + + if(!this.declVar.IsFuncTrivial(scg)) + scg.openCallLabel = null; + } + } + + // The value is an integer constant + public class CompValuInteger: CompValu + { + public int x; + + public CompValuInteger(TokenType type, int x) : base(type) + { + if(!(this.type is TokenTypeInt)) + { + this.type = new TokenTypeInt(this.type); + } + this.x = x; + } + public override void PushVal(ScriptCodeGen scg, Token errorAt) + { + scg.ilGen.Emit(errorAt, OpCodes.Ldc_I4, x); + } + public override void PushRef(ScriptCodeGen scg, Token errorAt) + { + throw new Exception("cannot get constant's address"); + } + public override void PopPost(ScriptCodeGen scg, Token errorAt) + { + throw new Exception("cannot store into constant"); + } + } + + // The value is an element of a list + public class CompValuListEl: CompValu + { + private static readonly MethodInfo getElementFromListMethodInfo = + typeof(CompValuListEl).GetMethod("GetElementFromList", new Type[] { typeof(LSL_List), typeof(int) }); + + private CompValu theList; + private CompValu subscript; + + public CompValuListEl(TokenType type, CompValu theList, CompValu subscript) : base(type) + { + this.theList = theList; + this.subscript = subscript; + } + public override void PushVal(ScriptCodeGen scg, Token errorAt) + { + theList.PushVal(scg, errorAt, new TokenTypeList(type)); + subscript.PushVal(scg, errorAt, new TokenTypeInt(type)); + scg.ilGen.Emit(errorAt, OpCodes.Call, getElementFromListMethodInfo); + } + public override void PushRef(ScriptCodeGen scg, Token errorAt) + { + throw new Exception("cannot get list element's address"); + } + public override void PopPost(ScriptCodeGen scg, Token errorAt) + { + scg.ErrorMsg(errorAt, "cannot store into list element"); + scg.ilGen.Emit(errorAt, OpCodes.Pop); + } + + public static object GetElementFromList(LSL_List lis, int idx) + { + object element = lis.Data[idx]; + if(element is LSL_Float) + return TypeCast.EHArgUnwrapFloat(element); + if(element is LSL_Integer) + return TypeCast.EHArgUnwrapInteger(element); + if(element is LSL_String) + return TypeCast.EHArgUnwrapString(element); + if(element is OpenMetaverse.Quaternion) + return TypeCast.EHArgUnwrapRotation(element); + if(element is OpenMetaverse.Vector3) + return TypeCast.EHArgUnwrapVector(element); + return element; + } + } + + // The value is kept in a script-addressable local variable + public class CompValuLocalVar: CompValu + { + private static int htpopseq = 0; + + private ScriptMyLocal localBuilder; + + public CompValuLocalVar(TokenType type, string name, ScriptCodeGen scg) : base(type) + { + if(type.ToHeapTrackerType() != null) + { + this.localBuilder = scg.ilGen.DeclareLocal(type.ToHeapTrackerType(), name); + scg.PushXMRInst(); + scg.ilGen.Emit(type, OpCodes.Newobj, type.GetHeapTrackerCtor()); + scg.ilGen.Emit(type, OpCodes.Stloc, localBuilder); + } + else + { + this.localBuilder = scg.ilGen.DeclareLocal(ToSysType(), name); + } + } + + public override void PushVal(ScriptCodeGen scg, Token errorAt) + { + scg.ilGen.Emit(errorAt, OpCodes.Ldloc, localBuilder); + if(type.ToHeapTrackerType() != null) + { + type.CallHeapTrackerPushMeth(errorAt, scg.ilGen); + } + } + public override void PushRef(ScriptCodeGen scg, Token errorAt) + { + if(type.ToHeapTrackerType() != null) + { + scg.ErrorMsg(errorAt, "can't take ref of heap-tracked type " + type.ToString()); + scg.ilGen.Emit(errorAt, OpCodes.Ldnull); + } + else + { + scg.ilGen.Emit(errorAt, OpCodes.Ldloca, localBuilder); + } + } + + public override void PopPre(ScriptCodeGen scg, Token errorAt) + { + if(type.ToHeapTrackerType() != null) + { + scg.ilGen.Emit(errorAt, OpCodes.Ldloc, localBuilder); + } + } + public override void PopPost(ScriptCodeGen scg, Token errorAt) + { + if(type.ToHeapTrackerType() != null) + { + type.CallHeapTrackerPopMeth(errorAt, scg.ilGen); + } + else + { + scg.ilGen.Emit(errorAt, OpCodes.Stloc, localBuilder); + } + } + + public void Pop(ScriptCodeGen scg, Token errorAt) + { + if(type.ToHeapTrackerType() != null) + { + /* + * Popping into a heap tracker wrapped local variable. + * First pop value into a temp var, then call the heap tracker's pop method. + */ + ScriptMyLocal htpop = scg.ilGen.DeclareLocal(type.ToSysType(), "htpop$" + (++htpopseq).ToString()); + scg.ilGen.Emit(errorAt, OpCodes.Stloc, htpop); + scg.ilGen.Emit(errorAt, OpCodes.Ldloc, localBuilder); + scg.ilGen.Emit(errorAt, OpCodes.Ldloc, htpop); + type.CallHeapTrackerPopMeth(errorAt, scg.ilGen); + } + else + { + + /* + * Not a heap-tracked local var, just pop directly into it. + */ + scg.ilGen.Emit(errorAt, OpCodes.Stloc, localBuilder); + } + } + + // non-trivial because it needs to be copied into a temp + // in case the idiot does dumb-ass side effects tricks + // eg, (x = 0) + x + 2 + // should read old value of x not 0 + // but if 'xmroption norighttoleft;' in effect, + // we can read it in any order so reading a + // local variable is trivial. + public override bool IsReadTrivial(ScriptCodeGen scg, Token readAt) + { + return readAt.nr2l; + } + } + + // The value is a null + public class CompValuNull: CompValu + { + public CompValuNull(TokenType type) : base(type) { } + public override void PushVal(ScriptCodeGen scg, Token errorAt) + { + scg.ilGen.Emit(errorAt, OpCodes.Ldnull); + } + public override void PushRef(ScriptCodeGen scg, Token errorAt) + { + throw new Exception("cannot get null's address"); + } + public override void PopPost(ScriptCodeGen scg, Token errorAt) + { + throw new Exception("cannot store into null"); + } + } + + // The value is a rotation + public class CompValuRot: CompValu + { + public CompValu x; + public CompValu y; + public CompValu z; + public CompValu w; + + private static readonly ConstructorInfo lslRotConstructorInfo = + typeof(LSL_Rotation).GetConstructor(new Type[] { typeof (double), + typeof (double), + typeof (double), + typeof (double) }); + + public CompValuRot(TokenType type, CompValu x, CompValu y, CompValu z, CompValu w) : + base(type) + { + if(!(type is TokenTypeRot)) + { + this.type = new TokenTypeRot(type); + } + this.x = x; + this.y = y; + this.z = z; + this.w = w; + } + public override void PushVal(ScriptCodeGen scg, Token errorAt) + { + this.x.PushVal(scg, errorAt, new TokenTypeFloat(this.x.type)); + this.y.PushVal(scg, errorAt, new TokenTypeFloat(this.y.type)); + this.z.PushVal(scg, errorAt, new TokenTypeFloat(this.z.type)); + this.w.PushVal(scg, errorAt, new TokenTypeFloat(this.w.type)); + scg.ilGen.Emit(errorAt, OpCodes.Newobj, lslRotConstructorInfo); + } + public override void PushRef(ScriptCodeGen scg, Token errorAt) + { + throw new Exception("cannot get constant's address"); + } + public override void PopPost(ScriptCodeGen scg, Token errorAt) + { + throw new Exception("cannot store into constant"); + } + + public override bool IsReadTrivial(ScriptCodeGen scg, Token readAt) + { + // the supplied values must be trivial because when we call their PushVal()s + // there will be stuff on the stack for all but the first PushVal() and so + // they would have a non-empty stack at their call label. + if(!this.w.IsReadTrivial(scg, readAt) || + !this.x.IsReadTrivial(scg, readAt) || + !this.y.IsReadTrivial(scg, readAt) || + !this.z.IsReadTrivial(scg, readAt)) + { + throw new Exception("rotation values must be trivial"); + } + + return true; + } + } + + // The value is in a static field of an internally defined struct/class + public class CompValuSField: CompValu + { + public FieldInfo field; + + public CompValuSField(TokenType type, FieldInfo field) : base(type) + { + this.field = field; + } + public override void PushVal(ScriptCodeGen scg, Token errorAt) + { + if((field.Attributes & FieldAttributes.Literal) == 0) + { + scg.ilGen.Emit(errorAt, OpCodes.Ldsfld, field); + return; + } + if(field.FieldType == typeof(LSL_Rotation)) + { + LSL_Rotation rot = (LSL_Rotation)field.GetValue(null); + scg.ilGen.Emit(errorAt, OpCodes.Ldc_R8, rot.x); + scg.ilGen.Emit(errorAt, OpCodes.Ldc_R8, rot.y); + scg.ilGen.Emit(errorAt, OpCodes.Ldc_R8, rot.z); + scg.ilGen.Emit(errorAt, OpCodes.Ldc_R8, rot.s); + scg.ilGen.Emit(errorAt, OpCodes.Newobj, ScriptCodeGen.lslRotationConstructorInfo); + return; + } + if(field.FieldType == typeof(LSL_Vector)) + { + LSL_Vector vec = (LSL_Vector)field.GetValue(null); + scg.ilGen.Emit(errorAt, OpCodes.Ldc_R8, vec.x); + scg.ilGen.Emit(errorAt, OpCodes.Ldc_R8, vec.y); + scg.ilGen.Emit(errorAt, OpCodes.Ldc_R8, vec.z); + scg.ilGen.Emit(errorAt, OpCodes.Newobj, ScriptCodeGen.lslRotationConstructorInfo); + return; + } + if(field.FieldType == typeof(string)) + { + string str = (string)field.GetValue(null); + scg.ilGen.Emit(errorAt, OpCodes.Ldstr, str); + return; + } + throw new Exception("unsupported literal type " + field.FieldType.Name); + } + public override void PushRef(ScriptCodeGen scg, Token errorAt) + { + if((field.Attributes & FieldAttributes.Literal) != 0) + { + throw new Exception("can't write a constant"); + } + scg.ilGen.Emit(errorAt, OpCodes.Ldflda, field); + } + public override void PopPre(ScriptCodeGen scg, Token errorAt) + { + } + public override void PopPost(ScriptCodeGen scg, Token errorAt) + { + if((field.Attributes & FieldAttributes.Literal) != 0) + { + throw new Exception("can't write a constant"); + } + scg.ilGen.Emit(errorAt, OpCodes.Stsfld, field); + } + + // non-trivial because it needs to be copied into a temp + // in case the idiot does dumb-ass side effects tricks + // eg, (x = 0) + x + 2 + // should read old value of x not 0 + // but if 'xmroption norighttoleft;' in effect, + // we can read it in any order so reading a + // local variable is trivial. + public override bool IsReadTrivial(ScriptCodeGen scg, Token readAt) + { + return readAt.nr2l; + } + } + + // The value is a character within a string + public class CompValuStrChr: CompValu + { + private static readonly MethodInfo getCharFromStringMethodInfo = + typeof(CompValuStrChr).GetMethod("GetCharFromString", new Type[] { typeof(string), typeof(int) }); + + private CompValu theString; + private CompValu subscript; + + public CompValuStrChr(TokenType type, CompValu theString, CompValu subscript) : base(type) + { + this.theString = theString; + this.subscript = subscript; + } + public override void PushVal(ScriptCodeGen scg, Token errorAt) + { + theString.PushVal(scg, errorAt, new TokenTypeStr(type)); + subscript.PushVal(scg, errorAt, new TokenTypeInt(type)); + scg.ilGen.Emit(errorAt, OpCodes.Call, getCharFromStringMethodInfo); + } + public override void PushRef(ScriptCodeGen scg, Token errorAt) + { + throw new Exception("cannot get string character's address"); + } + public override void PopPost(ScriptCodeGen scg, Token errorAt) + { + scg.ErrorMsg(errorAt, "cannot store into string character"); + scg.ilGen.Emit(errorAt, OpCodes.Pop); + } + + public static char GetCharFromString(string s, int i) + { + return s[i]; + } + } + + // The value is a key or string constant + public class CompValuString: CompValu + { + public string x; + + public CompValuString(TokenType type, string x) : base(type) + { + if(!(type is TokenTypeKey) && !(this.type is TokenTypeStr)) + { + throw new Exception("bad type " + type.ToString()); + } + this.x = x; + } + public override void PushVal(ScriptCodeGen scg, Token errorAt) + { + scg.ilGen.Emit(errorAt, OpCodes.Ldstr, x); + } + public override void PushRef(ScriptCodeGen scg, Token errorAt) + { + throw new Exception("cannot get constant's address"); + } + public override void PopPost(ScriptCodeGen scg, Token errorAt) + { + throw new Exception("cannot store into constant"); + } + } + + // The value is kept in a temp local variable + public class CompValuTemp: CompValu + { + public ScriptMyLocal localBuilder; + + public CompValuTemp(TokenType type, ScriptCodeGen scg) : base(type) + { + string name = "tmp$" + (++scg.tempCompValuNum); + this.localBuilder = scg.ilGen.DeclareLocal(ToSysType(), name); + } + protected CompValuTemp(TokenType type) : base(type) { } // CompValuVoid uses this + + public override void PushVal(ScriptCodeGen scg, Token errorAt) + { + scg.ilGen.Emit(errorAt, OpCodes.Ldloc, localBuilder); + } + public override void PushRef(ScriptCodeGen scg, Token errorAt) + { + scg.ilGen.Emit(errorAt, OpCodes.Ldloca, localBuilder); + } + public override void PopPost(ScriptCodeGen scg, Token errorAt) + { + scg.ilGen.Emit(errorAt, OpCodes.Stloc, localBuilder); + } + public void Pop(ScriptCodeGen scg, Token errorAt, TokenType stackType) + { + TypeCast.CastTopOfStack(scg, errorAt, stackType, this.type, false); + this.PopPost(scg, errorAt); // in case PopPost() overridden eg by CompValuVoid + } + public void Pop(ScriptCodeGen scg, Token errorAt) + { + this.PopPost(scg, errorAt); // in case PopPost() overridden eg by CompValuVoid + } + } + + // The value is a vector + public class CompValuVec: CompValu + { + public CompValu x; + public CompValu y; + public CompValu z; + + private static readonly ConstructorInfo lslVecConstructorInfo = + typeof(LSL_Vector).GetConstructor(new Type[] { typeof (double), + typeof (double), + typeof (double) }); + + public CompValuVec(TokenType type, CompValu x, CompValu y, CompValu z) : base(type) + { + if(!(type is TokenTypeVec)) + { + this.type = new TokenTypeVec(type); + } + this.x = x; + this.y = y; + this.z = z; + } + public override void PushVal(ScriptCodeGen scg, Token errorAt) + { + this.x.PushVal(scg, errorAt, new TokenTypeFloat(this.x.type)); + this.y.PushVal(scg, errorAt, new TokenTypeFloat(this.y.type)); + this.z.PushVal(scg, errorAt, new TokenTypeFloat(this.z.type)); + scg.ilGen.Emit(errorAt, OpCodes.Newobj, lslVecConstructorInfo); + } + public override void PushRef(ScriptCodeGen scg, Token errorAt) + { + throw new Exception("cannot get constant's address"); + } + public override void PopPost(ScriptCodeGen scg, Token errorAt) + { + throw new Exception("cannot store into constant"); + } + + public override bool IsReadTrivial(ScriptCodeGen scg, Token readAt) + { + // the supplied values must be trivial because when we call their PushVal()s + // there will be stuff on the stack for all but the first PushVal() and so + // they would have a non-empty stack at their call label. + if(!this.x.IsReadTrivial(scg, readAt) || + !this.y.IsReadTrivial(scg, readAt) || + !this.z.IsReadTrivial(scg, readAt)) + { + throw new Exception("vector values must be trivial"); + } + + return true; + } + } + + // Used to indicate value will be discarded (eg, where to put return value from a call) + public class CompValuVoid: CompValuTemp + { + public CompValuVoid(Token token) : base((token is TokenTypeVoid) ? (TokenTypeVoid)token : new TokenTypeVoid(token)) + { + } + public override void PushVal(ScriptCodeGen scg, Token errorAt) + { + } + public override void PushRef(ScriptCodeGen scg, Token errorAt) + { + throw new Exception("cannot get void address"); + } + public override void PopPost(ScriptCodeGen scg, Token errorAt) + { + } + } +} diff --git a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptCompile.cs b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptCompile.cs new file mode 100644 index 0000000000..f37efd48d1 --- /dev/null +++ b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptCompile.cs @@ -0,0 +1,187 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @brief Compile a script to produce a ScriptObjCode object + */ + +using System; +using System.IO; + +namespace OpenSim.Region.ScriptEngine.Yengine +{ + public partial class XMRInstance + { + /** + * @brief Compile a script to produce a ScriptObjCode object + * @returns object code pointer or null if compile error + * also can throw compile error exception + */ + public ScriptObjCode Compile() + { + Stream objFileStream = null; + StreamWriter asmFileWriter = null; + string sourceHash = null; + TextWriter saveSource = null; + + string objFileName = GetScriptFileName (m_ScriptObjCodeKey + ".yobj"); + string tmpFileName = GetScriptFileName (m_ScriptObjCodeKey + ".ytmp"); + + // If we already have an object file, don't bother compiling. + if (!m_ForceRecomp && File.Exists(objFileName)) + { + objFileStream = File.OpenRead (objFileName); + } + else + { + // If source file empty, try to read from asset server. + if (EmptySource (m_SourceCode)) + m_SourceCode = FetchSource (m_CameFrom); + + // Maybe write script source to a file for debugging. + if (m_Engine.m_ScriptDebugSaveSource) + { + string lslFileName = GetScriptFileName (m_ScriptObjCodeKey + ".lsl"); +// m_log.Debug ("[YEngine]: MMRScriptCompileSaveSource: saving to " + lslFileName); + saveSource = File.CreateText (lslFileName); + } + + // Parse source string into tokens. + TokenBegin tokenBegin; + try + { + tokenBegin = TokenBegin.Construct(m_CameFrom, saveSource, ErrorHandler, m_SourceCode, out sourceHash); + } + finally + { + if (saveSource != null) + saveSource.Close (); + } + if (tokenBegin == null) + { + m_log.Debug ("[YEngine]: parsing errors on " + m_ScriptObjCodeKey); + return null; + } + + // Create object file one way or another. + try + { + // Create abstract syntax tree from raw tokens. + TokenScript tokenScript = ScriptReduce.Reduce(tokenBegin); + if (tokenScript == null) + { + m_log.Warn ("[YEngine]: reduction errors on " + m_ScriptObjCodeKey + " (" + m_CameFrom + ")"); + PrintCompilerErrors(); + return null; + } + + // Compile abstract syntax tree to write object file. + using(BinaryWriter objFileWriter = new BinaryWriter(File.Create(tmpFileName))) + { + bool ok = ScriptCodeGen.CodeGen(tokenScript, objFileWriter, sourceHash); + if (!ok) + { + m_log.Warn ("[YEngine]: compile error on " + m_ScriptObjCodeKey + " (" + m_CameFrom + ")"); + PrintCompilerErrors (); + return null; + } + } + + // File has been completely written. + // If there is an old one laying around, delete it now. + // Then re-open the new file for reading from the beginning. + if (File.Exists(objFileName)) + File.Replace(tmpFileName, objFileName, null); + else + File.Move(tmpFileName, objFileName); + + objFileStream = File.OpenRead(objFileName); + } + finally + { + // In case something went wrong writing temp file, delete it. + File.Delete (tmpFileName); + } + + // Since we just wrote the .xmrobj file, maybe save disassembly. + if (m_Engine.m_ScriptDebugSaveIL) + { + string asmFileName = GetScriptFileName (m_ScriptObjCodeKey + ".yasm"); +// m_log.Debug ("[YEngine]: MMRScriptCompileSaveILGen: saving to " + asmFileName); + asmFileWriter = File.CreateText (asmFileName); + } + } + + // Read object file to create ScriptObjCode object. + // Maybe also write disassembly to a file for debugging. + BinaryReader objFileReader = new BinaryReader (objFileStream); + ScriptObjCode scriptObjCode = null; + try + { + scriptObjCode = new ScriptObjCode (objFileReader, asmFileWriter, null); + } + finally + { + objFileReader.Close (); + if (asmFileWriter != null) + { + asmFileWriter.Flush (); + asmFileWriter.Close (); + } + } + + return scriptObjCode; + } + + private void PrintCompilerErrors () + { + m_log.Info ("[YEngine]: - " + m_Part.GetWorldPosition () + " " + m_DescName); + foreach (string error in m_CompilerErrors) + { + m_log.Info ("[YEngine]: - " + error); + } + } + + /** + * @brief Check for empty source, allowing for a first line of //... script engine selector. + */ + public static bool EmptySource (string source) + { + int len = source.Length; + bool skipeol = false; + for (int i = 0; i < len; i ++) + { + char c = source[i]; + skipeol &= c != '\n'; + skipeol |= (c == '/') && (i + 1 < len) && (source[i+1] == '/'); + if ((c > ' ') && !skipeol) + return false; + } + return true; + } + } +} diff --git a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptConsts.cs b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptConsts.cs new file mode 100644 index 0000000000..b44c4e2dee --- /dev/null +++ b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptConsts.cs @@ -0,0 +1,275 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Text; + +using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; +using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; +using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; +using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list; +using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; +using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; +using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; + +namespace OpenSim.Region.ScriptEngine.Yengine +{ + + public class ScriptConst + { + + public static Dictionary scriptConstants = Init(); + + /** + * @brief look up the value of a given built-in constant. + * @param name = name of constant + * @returns null: no constant by that name defined + * else: pointer to ScriptConst struct + */ + public static ScriptConst Lookup(string name) + { + ScriptConst sc; + if(!scriptConstants.TryGetValue(name, out sc)) + sc = null; + return sc; + } + + private static Dictionary Init() + { + Dictionary sc = new Dictionary(); + + // For every event code, define XMREVENTCODE_ and XMREVENTMASKn_ symbols. + for(int i = 0; i < 64; i++) + { + try + { + string s = ((ScriptEventCode)i).ToString(); + if((s.Length > 0) && (s[0] >= 'a') && (s[0] <= 'z')) + { + new ScriptConst(sc, + "XMREVENTCODE_" + s, + new CompValuInteger(new TokenTypeInt(null), i)); + int n = i / 32 + 1; + int m = 1 << (i % 32); + new ScriptConst(sc, + "XMREVENTMASK" + n + "_" + s, + new CompValuInteger(new TokenTypeInt(null), m)); + } + } + catch { } + } + + // Also get all the constants from XMRInstAbstract and ScriptBaseClass etc as well. + for(Type t = typeof(XMRInstAbstract); t != typeof(object); t = t.BaseType) + { + AddInterfaceConstants(sc, t.GetFields()); + } + + return sc; + } + + /** + * @brief Add all constants defined by the given interface. + */ + // this one accepts only upper-case named fields + public static void AddInterfaceConstants(Dictionary sc, FieldInfo[] allFields) + { + List ucfs = new List(allFields.Length); + foreach(FieldInfo f in allFields) + { + string fieldName = f.Name; + int i; + for(i = fieldName.Length; --i >= 0;) + { + if("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_".IndexOf(fieldName[i]) < 0) + break; + } + if(i < 0) + ucfs.Add(f); + } + AddInterfaceConstants(sc, ucfs.GetEnumerator()); + } + + // this one accepts all fields given to it + public static void AddInterfaceConstants(Dictionary sc, IEnumerator fields) + { + if(sc == null) + sc = scriptConstants; + + for(fields.Reset(); fields.MoveNext();) + { + FieldInfo constField = fields.Current; + Type fieldType = constField.FieldType; + CompValu cv; + + // The location of a simple number is the number itself. + // Access to the value gets compiled as an ldc instruction. + if(fieldType == typeof(double)) + { + cv = new CompValuFloat(new TokenTypeFloat(null), + (double)(double)constField.GetValue(null)); + } + else if(fieldType == typeof(int)) + { + cv = new CompValuInteger(new TokenTypeInt(null), + (int)constField.GetValue(null)); + } + else if(fieldType == typeof(LSL_Integer)) + { + cv = new CompValuInteger(new TokenTypeInt(null), + ((LSL_Integer)constField.GetValue(null)).value); + } + + // The location of a string is the string itself. + // Access to the value gets compiled as an ldstr instruction. + else if(fieldType == typeof(string)) + { + cv = new CompValuString(new TokenTypeStr(null), + (string)constField.GetValue(null)); + } + else if(fieldType == typeof(LSL_String)) + { + cv = new CompValuString(new TokenTypeStr(null), + (string)(LSL_String)constField.GetValue(null)); + } + + // The location of everything else (objects) is the static field in the interface definition. + // Access to the value gets compiled as an ldsfld instruction. + else + { + cv = new CompValuSField(TokenType.FromSysType(null, fieldType), constField); + } + + // Add to dictionary. + new ScriptConst(sc, constField.Name, cv); + } + } + + /** + * @brief Add arbitrary constant available to script compilation. + * CAUTION: These values get compiled-in to a script and must not + * change over time as previously compiled scripts will + * still have the old values. + */ + public static ScriptConst AddConstant(string name, object value) + { + CompValu cv = null; + + if(value is char) + { + cv = new CompValuChar(new TokenTypeChar(null), (char)value); + } + if(value is double) + { + cv = new CompValuFloat(new TokenTypeFloat(null), (double)(double)value); + } + if(value is float) + { + cv = new CompValuFloat(new TokenTypeFloat(null), (double)(float)value); + } + if(value is int) + { + cv = new CompValuInteger(new TokenTypeInt(null), (int)value); + } + if(value is string) + { + cv = new CompValuString(new TokenTypeStr(null), (string)value); + } + + if(value is LSL_Float) + { + cv = new CompValuFloat(new TokenTypeFloat(null), (double)((LSL_Float)value).value); + } + if(value is LSL_Integer) + { + cv = new CompValuInteger(new TokenTypeInt(null), ((LSL_Integer)value).value); + } + if(value is LSL_Rotation) + { + LSL_Rotation r = (LSL_Rotation)value; + CompValu x = new CompValuFloat(new TokenTypeFloat(null), r.x); + CompValu y = new CompValuFloat(new TokenTypeFloat(null), r.y); + CompValu z = new CompValuFloat(new TokenTypeFloat(null), r.z); + CompValu s = new CompValuFloat(new TokenTypeFloat(null), r.s); + cv = new CompValuRot(new TokenTypeRot(null), x, y, z, s); + } + if(value is LSL_String) + { + cv = new CompValuString(new TokenTypeStr(null), (string)(LSL_String)value); + } + if(value is LSL_Vector) + { + LSL_Vector v = (LSL_Vector)value; + CompValu x = new CompValuFloat(new TokenTypeFloat(null), v.x); + CompValu y = new CompValuFloat(new TokenTypeFloat(null), v.y); + CompValu z = new CompValuFloat(new TokenTypeFloat(null), v.z); + cv = new CompValuVec(new TokenTypeVec(null), x, y, z); + } + + if(value is OpenMetaverse.Quaternion) + { + OpenMetaverse.Quaternion r = (OpenMetaverse.Quaternion)value; + CompValu x = new CompValuFloat(new TokenTypeFloat(null), r.X); + CompValu y = new CompValuFloat(new TokenTypeFloat(null), r.Y); + CompValu z = new CompValuFloat(new TokenTypeFloat(null), r.Z); + CompValu s = new CompValuFloat(new TokenTypeFloat(null), r.W); + cv = new CompValuRot(new TokenTypeRot(null), x, y, z, s); + } + if(value is OpenMetaverse.UUID) + { + cv = new CompValuString(new TokenTypeKey(null), value.ToString()); + } + if(value is OpenMetaverse.Vector3) + { + OpenMetaverse.Vector3 v = (OpenMetaverse.Vector3)value; + CompValu x = new CompValuFloat(new TokenTypeFloat(null), v.X); + CompValu y = new CompValuFloat(new TokenTypeFloat(null), v.Y); + CompValu z = new CompValuFloat(new TokenTypeFloat(null), v.Z); + cv = new CompValuVec(new TokenTypeVec(null), x, y, z); + } + + if(cv == null) + throw new Exception("bad type " + value.GetType().Name); + return new ScriptConst(scriptConstants, name, cv); + } + + /* + * Instance variables + */ + public string name; + public CompValu rVal; + + private ScriptConst(Dictionary lc, string name, CompValu rVal) + { + lc.Add(name, this); + this.name = name; + this.rVal = rVal; + } + } +} diff --git a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptEventCode.cs b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptEventCode.cs new file mode 100644 index 0000000000..c00e8d4dda --- /dev/null +++ b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptEventCode.cs @@ -0,0 +1,97 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +namespace OpenSim.Region.ScriptEngine.Yengine +{ + + /** + * @brief List of event codes that can be passed to StartEventHandler(). + * Must have same name as corresponding event handler name, so + * the compiler will know what column in the seht to put the + * event handler entrypoint in. + * + * Also, ScriptConst.Init() builds symbols of name XMREVENTCODE_ + * and XMREVENTMASK_ with the values and masks of all symbols + * in range 0..63 that begin with a lower-case letter for scripts to + * reference. + */ + public enum ScriptEventCode: int + { + + // used by XMRInstance to indicate no event being processed + None = -1, + + // must be bit numbers of equivalent values in ... + // OpenSim.Region.ScriptEngine.Shared.ScriptBase.scriptEvents + // ... so they can be passed to m_Part.SetScriptEvents(). + attach = 0, + state_exit = 1, + timer = 2, + touch = 3, + collision = 4, + collision_end = 5, + collision_start = 6, + control = 7, + dataserver = 8, + email = 9, + http_response = 10, + land_collision = 11, + land_collision_end = 12, + land_collision_start = 13, + at_target = 14, + listen = 15, + money = 16, + moving_end = 17, + moving_start = 18, + not_at_rot_target = 19, + not_at_target = 20, + touch_start = 21, + object_rez = 22, + remote_data = 23, + at_rot_target = 24, + transaction_result = 25, + run_time_permissions = 28, + touch_end = 29, + state_entry = 30, + + // events not passed to m_Part.SetScriptEvents(). + changed = 33, + link_message = 34, + no_sensor = 35, + on_rez = 36, + sensor = 37, + http_request = 38, + + path_update = 40, + + // XMRE specific + region_cross = 63, + + // marks highest numbered event, ie, number of columns in seht. + Size = 64 + } +} diff --git a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptInlines.cs b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptInlines.cs new file mode 100644 index 0000000000..e17d41ac2d --- /dev/null +++ b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptInlines.cs @@ -0,0 +1,727 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Reflection.Emit; +using System.Text; + +using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; +using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; +using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; +using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list; +using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; +using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; +using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; + +/** + * @brief Generate code for the backend API calls. + */ +namespace OpenSim.Region.ScriptEngine.Yengine +{ + public abstract class TokenDeclInline: TokenDeclVar + { + public static VarDict inlineFunctions = CreateDictionary(); + + public abstract void CodeGen(ScriptCodeGen scg, Token errorAt, CompValuTemp result, CompValu[] args); + + private static string[] noCheckRuns; + private static string[] keyReturns; + + protected bool isTaggedCallsCheckRun; + + /** + * @brief Create a dictionary of inline backend API functions. + */ + private static VarDict CreateDictionary() + { + /* + * For those listed in noCheckRun, we just generate the call (simple computations). + * For all others, we generate the call then a call to CheckRun(). + */ + noCheckRuns = new string[] { + "llBase64ToString", + "llCSV2List", + "llDeleteSubList", + "llDeleteSubString", + "llDumpList2String", + "llEscapeURL", + "llEuler2Rot", + "llGetListEntryType", + "llGetListLength", + "llGetSubString", + "llGetUnixTime", + "llInsertString", + "llList2CSV", + "llList2Float", + "llList2Integer", + "llList2Key", + "llList2List", + "llList2ListStrided", + "llList2Rot", + "llList2String", + "llList2Vector", + "llListFindList", + "llListInsertList", + "llListRandomize", + "llListReplaceList", + "llListSort", + "llListStatistics", + "llMD5String", + "llParseString2List", + "llParseStringKeepNulls", + "llRot2Euler", + "llStringLength", + "llStringToBase64", + "llStringTrim", + "llSubStringIndex", + "llUnescapeURL" + }; + + /* + * These functions really return a 'key' even though we see them as + * returning 'string' because OpenSim has key and string as same type. + */ + keyReturns = new string[] { + "llAvatarOnLinkSitTarget", + "llAvatarOnSitTarget", + "llDetectedKey", + "llDetectedOwner", + "llGenerateKey", + "llGetCreator", + "llGetInventoryCreator", + "llGetInventoryKey", + "llGetKey", + "llGetLandOwnerAt", + "llGetLinkKey", + "llGetNotecardLine", + "llGetNumberOfNotecardLines", + "llGetOwner", + "llGetOwnerKey", + "llGetPermissionsKey", + "llHTTPRequest", + "llList2Key", + "llRequestAgentData", + "llRequestDisplayName", + "llRequestInventoryData", + "llRequestSecureURL", + "llRequestSimulatorData", + "llRequestURL", + "llRequestUsername", + "llSendRemoteData", + "llTransferLindenDollars" + }; + + VarDict ifd = new VarDict(false); + + Type[] oneDoub = new Type[] { typeof(double) }; + Type[] twoDoubs = new Type[] { typeof(double), typeof(double) }; + + /* + * Mono generates an FPU instruction for many math calls. + */ + new TokenDeclInline_LLAbs(ifd); + new TokenDeclInline_Math(ifd, "llAcos(float)", "Acos", oneDoub); + new TokenDeclInline_Math(ifd, "llAsin(float)", "Asin", oneDoub); + new TokenDeclInline_Math(ifd, "llAtan2(float,float)", "Atan2", twoDoubs); + new TokenDeclInline_Math(ifd, "llCos(float)", "Cos", oneDoub); + new TokenDeclInline_Math(ifd, "llFabs(float)", "Abs", oneDoub); + new TokenDeclInline_Math(ifd, "llLog(float)", "Log", oneDoub); + new TokenDeclInline_Math(ifd, "llLog10(float)", "Log10", oneDoub); + new TokenDeclInline_Math(ifd, "llPow(float,float)", "Pow", twoDoubs); + new TokenDeclInline_LLRound(ifd); + new TokenDeclInline_Math(ifd, "llSin(float)", "Sin", oneDoub); + new TokenDeclInline_Math(ifd, "llSqrt(float)", "Sqrt", oneDoub); + new TokenDeclInline_Math(ifd, "llTan(float)", "Tan", oneDoub); + + /* + * Something weird about the code generation for these calls, so they all have their own handwritten code generators. + */ + new TokenDeclInline_GetFreeMemory(ifd); + new TokenDeclInline_GetUsedMemory(ifd); + + /* + * These are all the xmr...() calls directly in XMRInstAbstract. + * Includes the calls from ScriptBaseClass that has all the stubs + * which convert XMRInstAbstract to the various _Api contexts. + */ + MethodInfo[] absmeths = typeof(XMRInstAbstract).GetMethods(); + AddInterfaceMethods(ifd, absmeths, null); + + return ifd; + } + + /** + * @brief Add API functions from the given interface to list of built-in functions. + * Only functions beginning with a lower-case letter are entered, all others ignored. + * @param ifd = internal function dictionary to add them to + * @param ifaceMethods = list of API functions + * @param acf = which field in XMRInstanceSuperType holds method's 'this' pointer + */ + // this one accepts only names beginning with a lower-case letter + public static void AddInterfaceMethods(VarDict ifd, MethodInfo[] ifaceMethods, FieldInfo acf) + { + List lcms = new List(ifaceMethods.Length); + foreach(MethodInfo meth in ifaceMethods) + { + string name = meth.Name; + if((name[0] >= 'a') && (name[0] <= 'z')) + { + lcms.Add(meth); + } + } + AddInterfaceMethods(ifd, lcms.GetEnumerator(), acf); + } + + // this one accepts all methods given to it + public static void AddInterfaceMethods(VarDict ifd, IEnumerator ifaceMethods, FieldInfo acf) + { + if(ifd == null) + ifd = inlineFunctions; + + for(ifaceMethods.Reset(); ifaceMethods.MoveNext();) + { + MethodInfo ifaceMethod = ifaceMethods.Current; + string key = ifaceMethod.Name; + + try + { + /* + * See if we will generate a call to CheckRun() right + * after we generate a call to the function. + * If function begins with xmr, assume we will not call CheckRun() + * Otherwise, assume we will call CheckRun() + */ + bool dcr = !key.StartsWith("xmr"); + foreach(string ncr in noCheckRuns) + { + if(ncr == key) + { + dcr = false; + break; + } + } + + /* + * Add function to dictionary. + */ + new TokenDeclInline_BEApi(ifd, dcr, ifaceMethod, acf); + } + catch + { + ///??? IGNORE ANY THAT FAIL - LIKE UNRECOGNIZED TYPE ???/// + ///??? and OVERLOADED NAMES ???/// + } + } + } + + /** + * @brief Add an inline function definition to the dictionary. + * @param ifd = dictionary to add inline definition to + * @param doCheckRun = true iff the generated code or the function itself can possibly call CheckRun() + * @param nameArgSig = inline function signature string, in form (,...) + * @param retType = return type, use TokenTypeVoid if no return value + */ + protected TokenDeclInline(VarDict ifd, + bool doCheckRun, + string nameArgSig, + TokenType retType) + : base(null, null, null) + { + this.retType = retType; + this.triviality = doCheckRun ? Triviality.complex : Triviality.trivial; + + int j = nameArgSig.IndexOf('('); + this.name = new TokenName(null, nameArgSig.Substring(0, j++)); + + this.argDecl = new TokenArgDecl(null); + if(nameArgSig[j] != ')') + { + int i; + TokenName name; + TokenType type; + + for(i = j; nameArgSig[i] != ')'; i++) + { + if(nameArgSig[i] == ',') + { + type = TokenType.FromLSLType(null, nameArgSig.Substring(j, i - j)); + name = new TokenName(null, "arg" + this.argDecl.varDict.Count); + this.argDecl.AddArg(type, name); + j = i + 1; + } + } + + type = TokenType.FromLSLType(null, nameArgSig.Substring(j, i - j)); + name = new TokenName(null, "arg" + this.argDecl.varDict.Count); + this.argDecl.AddArg(type, name); + } + + this.location = new CompValuInline(this); + if(ifd == null) + ifd = inlineFunctions; + ifd.AddEntry(this); + } + + protected TokenDeclInline(VarDict ifd, + bool doCheckRun, + MethodInfo methInfo) + : base(null, null, null) + { + TokenType retType = TokenType.FromSysType(null, methInfo.ReturnType); + + this.isTaggedCallsCheckRun = IsTaggedCallsCheckRun(methInfo); + this.name = new TokenName(null, methInfo.Name); + this.retType = GetRetType(methInfo, retType); + this.argDecl = GetArgDecl(methInfo.GetParameters()); + this.triviality = (doCheckRun || this.isTaggedCallsCheckRun) ? Triviality.complex : Triviality.trivial; + this.location = new CompValuInline(this); + + if(ifd == null) + ifd = inlineFunctions; + ifd.AddEntry(this); + } + + private static TokenArgDecl GetArgDecl(ParameterInfo[] parameters) + { + TokenArgDecl argDecl = new TokenArgDecl(null); + foreach(ParameterInfo pi in parameters) + { + TokenType type = TokenType.FromSysType(null, pi.ParameterType); + TokenName name = new TokenName(null, pi.Name); + argDecl.AddArg(type, name); + } + return argDecl; + } + + /** + * @brief The above code assumes all methods beginning with 'xmr' are trivial, ie, + * they do not call CheckRun() and also we do not generate a CheckRun() + * call after they return. So if an 'xmr' method does call CheckRun(), it + * must be tagged with attribute 'xmrMethodCallsCheckRunAttribute' so we know + * the method is not trivial. But in neither case do we emit our own call + * to CheckRun(), the 'xmr' method must do its own. We do however set up a + * call label before the call to the non-trivial 'xmr' method so when we are + * restoring the call stack, the restore will call directly in to the 'xmr' + * method without re-executing any code before the call to the 'xmr' method. + */ + private static bool IsTaggedCallsCheckRun(MethodInfo methInfo) + { + return (methInfo != null) && + Attribute.IsDefined(methInfo, typeof(xmrMethodCallsCheckRunAttribute)); + } + + /** + * @brief The dumbass OpenSim has key and string as the same type so non-ll + * methods must be tagged with xmrMethodReturnsKeyAttribute if we + * are to think they return a key type, otherwise we will think they + * return string. + */ + private static TokenType GetRetType(MethodInfo methInfo, TokenType retType) + { + if((methInfo != null) && (retType != null) && (retType is TokenTypeStr)) + { + if(Attribute.IsDefined(methInfo, typeof(xmrMethodReturnsKeyAttribute))) + { + return ChangeToKeyType(retType); + } + + string mn = methInfo.Name; + foreach(string kr in keyReturns) + { + if(kr == mn) + return ChangeToKeyType(retType); + } + + } + return retType; + } + private static TokenType ChangeToKeyType(TokenType retType) + { + if(retType is TokenTypeLSLString) + { + retType = new TokenTypeLSLKey(null); + } + else + { + retType = new TokenTypeKey(null); + } + return retType; + } + + public virtual MethodInfo GetMethodInfo() + { + return null; + } + + /** + * @brief Print out a list of all the built-in functions and constants. + */ + public delegate void WriteLine(string str); + public static void PrintBuiltins(bool inclNoisyTag, WriteLine writeLine) + { + writeLine("\nBuilt-in functions:\n"); + SortedDictionary bifs = new SortedDictionary(); + foreach(TokenDeclVar bif in TokenDeclInline.inlineFunctions) + { + bifs.Add(bif.fullName, (TokenDeclInline)bif); + } + foreach(TokenDeclInline bif in bifs.Values) + { + char noisy = (!inclNoisyTag || !IsTaggedNoisy(bif.GetMethodInfo())) ? ' ' : (bif.retType is TokenTypeVoid) ? 'N' : 'R'; + writeLine(noisy + " " + bif.retType.ToString().PadLeft(8) + " " + bif.fullName); + } + if(inclNoisyTag) + { + writeLine("\nN - stub that writes name and arguments to stdout"); + writeLine("R - stub that writes name and arguments to stdout then reads return value from stdin"); + writeLine(" format is: function_name : return_value"); + writeLine(" example: llKey2Name:\"Kunta Kinte\""); + } + + writeLine("\nBuilt-in constants:\n"); + SortedDictionary scs = new SortedDictionary(); + int widest = 0; + foreach(ScriptConst sc in ScriptConst.scriptConstants.Values) + { + if(widest < sc.name.Length) + widest = sc.name.Length; + scs.Add(sc.name, sc); + } + foreach(ScriptConst sc in scs.Values) + { + writeLine(" " + sc.rVal.type.ToString().PadLeft(8) + " " + sc.name.PadRight(widest) + " = " + BuiltInConstVal(sc.rVal)); + } + } + + public static bool IsTaggedNoisy(MethodInfo methInfo) + { + return (methInfo != null) && Attribute.IsDefined(methInfo, typeof(xmrMethodIsNoisyAttribute)); + } + + public static string BuiltInConstVal(CompValu rVal) + { + if(rVal is CompValuInteger) + { + int x = ((CompValuInteger)rVal).x; + return "0x" + x.ToString("X8") + " = " + x.ToString().PadLeft(11); + } + if(rVal is CompValuFloat) + return ((CompValuFloat)rVal).x.ToString(); + if(rVal is CompValuString) + { + StringBuilder sb = new StringBuilder(); + PrintParam(sb, ((CompValuString)rVal).x); + return sb.ToString(); + } + if(rVal is CompValuSField) + { + FieldInfo fi = ((CompValuSField)rVal).field; + StringBuilder sb = new StringBuilder(); + PrintParam(sb, fi.GetValue(null)); + return sb.ToString(); + } + return rVal.ToString(); // just prints the type + } + + public static void PrintParam(StringBuilder sb, object p) + { + if(p == null) + { + sb.Append("null"); + } + else if(p is LSL_List) + { + sb.Append('['); + object[] d = ((LSL_List)p).Data; + for(int i = 0; i < d.Length; i++) + { + if(i > 0) + sb.Append(','); + PrintParam(sb, d[i]); + } + sb.Append(']'); + } + else if(p is LSL_Rotation) + { + LSL_Rotation r = (LSL_Rotation)p; + sb.Append('<'); + sb.Append(r.x); + sb.Append(','); + sb.Append(r.y); + sb.Append(','); + sb.Append(r.z); + sb.Append(','); + sb.Append(r.s); + sb.Append('>'); + } + else if(p is LSL_String) + { + PrintParamString(sb, (string)(LSL_String)p); + } + else if(p is LSL_Vector) + { + LSL_Vector v = (LSL_Vector)p; + sb.Append('<'); + sb.Append(v.x); + sb.Append(','); + sb.Append(v.y); + sb.Append(','); + sb.Append(v.z); + sb.Append('>'); + } + else if(p is string) + { + PrintParamString(sb, (string)p); + } + else + { + sb.Append(p.ToString()); + } + } + + public static void PrintParamString(StringBuilder sb, string p) + { + sb.Append('"'); + foreach(char c in p) + { + if(c == '\b') + { + sb.Append("\\b"); + continue; + } + if(c == '\n') + { + sb.Append("\\n"); + continue; + } + if(c == '\r') + { + sb.Append("\\r"); + continue; + } + if(c == '\t') + { + sb.Append("\\t"); + continue; + } + if(c == '"') + { + sb.Append("\\\""); + continue; + } + if(c == '\\') + { + sb.Append("\\\\"); + continue; + } + sb.Append(c); + } + sb.Append('"'); + } + } + + /** + * @brief Code generators... + * @param scg = script we are generating code for + * @param result = type/location for result (type matches function definition) + * @param args = type/location of arguments (types match function definition) + */ + + public class TokenDeclInline_LLAbs: TokenDeclInline + { + public TokenDeclInline_LLAbs(VarDict ifd) + : base(ifd, false, "llAbs(integer)", new TokenTypeInt(null)) { } + + public override void CodeGen(ScriptCodeGen scg, Token errorAt, CompValuTemp result, CompValu[] args) + { + ScriptMyLabel itsPosLabel = scg.ilGen.DefineLabel("llAbstemp"); + + args[0].PushVal(scg, errorAt); + scg.ilGen.Emit(errorAt, OpCodes.Dup); + scg.ilGen.Emit(errorAt, OpCodes.Ldc_I4_0); + scg.ilGen.Emit(errorAt, OpCodes.Bge_S, itsPosLabel); + scg.ilGen.Emit(errorAt, OpCodes.Neg); + scg.ilGen.MarkLabel(itsPosLabel); + result.Pop(scg, errorAt, retType); + } + } + + public class TokenDeclInline_Math: TokenDeclInline + { + private MethodInfo methInfo; + + public TokenDeclInline_Math(VarDict ifd, string sig, string name, Type[] args) + : base(ifd, false, sig, new TokenTypeFloat(null)) + { + methInfo = ScriptCodeGen.GetStaticMethod(typeof(System.Math), name, args); + } + + public override void CodeGen(ScriptCodeGen scg, Token errorAt, CompValuTemp result, CompValu[] args) + { + for(int i = 0; i < args.Length; i++) + { + args[i].PushVal(scg, errorAt, argDecl.types[i]); + } + scg.ilGen.Emit(errorAt, OpCodes.Call, methInfo); + result.Pop(scg, errorAt, retType); + } + } + + public class TokenDeclInline_LLRound: TokenDeclInline + { + + private static MethodInfo roundMethInfo = ScriptCodeGen.GetStaticMethod(typeof(System.Math), "Round", + new Type[] { typeof(double), typeof(MidpointRounding) }); + + public TokenDeclInline_LLRound(VarDict ifd) + : base(ifd, false, "llRound(float)", new TokenTypeInt(null)) { } + + public override void CodeGen(ScriptCodeGen scg, Token errorAt, CompValuTemp result, CompValu[] args) + { + args[0].PushVal(scg, errorAt, new TokenTypeFloat(null)); + scg.ilGen.Emit(errorAt, OpCodes.Ldc_I4, (int)System.MidpointRounding.AwayFromZero); + scg.ilGen.Emit(errorAt, OpCodes.Call, roundMethInfo); + result.Pop(scg, errorAt, new TokenTypeFloat(null)); + } + } + + public class TokenDeclInline_GetFreeMemory: TokenDeclInline + { + private static readonly MethodInfo getFreeMemMethInfo = typeof(XMRInstAbstract).GetMethod("xmrHeapLeft", new Type[] { }); + + public TokenDeclInline_GetFreeMemory(VarDict ifd) + : base(ifd, false, "llGetFreeMemory()", new TokenTypeInt(null)) { } + + // appears as llGetFreeMemory() in script source code + // but actually calls xmrHeapLeft() + public override void CodeGen(ScriptCodeGen scg, Token errorAt, CompValuTemp result, CompValu[] args) + { + scg.PushXMRInst(); + scg.ilGen.Emit(errorAt, OpCodes.Call, getFreeMemMethInfo); + result.Pop(scg, errorAt, new TokenTypeInt(null)); + } + } + + public class TokenDeclInline_GetUsedMemory: TokenDeclInline + { + private static readonly MethodInfo getUsedMemMethInfo = typeof(XMRInstAbstract).GetMethod("xmrHeapUsed", new Type[] { }); + + public TokenDeclInline_GetUsedMemory(VarDict ifd) + : base(ifd, false, "llGetUsedMemory()", new TokenTypeInt(null)) { } + + // appears as llGetUsedMemory() in script source code + // but actually calls xmrHeapUsed() + public override void CodeGen(ScriptCodeGen scg, Token errorAt, CompValuTemp result, CompValu[] args) + { + scg.PushXMRInst(); + scg.ilGen.Emit(errorAt, OpCodes.Call, getUsedMemMethInfo); + result.Pop(scg, errorAt, new TokenTypeInt(null)); + } + } + + /** + * @brief Generate code for the usual ll...() functions. + */ + public class TokenDeclInline_BEApi: TokenDeclInline + { + // private static readonly MethodInfo fixLLParcelMediaQuery = ScriptCodeGen.GetStaticMethod + // (typeof (XMRInstAbstract), "FixLLParcelMediaQuery", new Type[] { typeof (LSL_List) }); + + // private static readonly MethodInfo fixLLParcelMediaCommandList = ScriptCodeGen.GetStaticMethod + // (typeof (XMRInstAbstract), "FixLLParcelMediaCommandList", new Type[] { typeof (LSL_List) }); + + public bool doCheckRun; + private FieldInfo apiContextField; + private MethodInfo methInfo; + + /** + * @brief Constructor + * @param ifd = dictionary to add the function to + * @param dcr = append a call to CheckRun() + * @param methInfo = ll...() method to be called + */ + public TokenDeclInline_BEApi(VarDict ifd, bool dcr, MethodInfo methInfo, FieldInfo acf) + : base(ifd, dcr, methInfo) + { + this.methInfo = methInfo; + doCheckRun = dcr; + apiContextField = acf; + } + + public override MethodInfo GetMethodInfo() + { + return methInfo; + } + + /** + * @brief Generate call to backend API function (eg llSay()) maybe followed by a call to CheckRun(). + * @param scg = script being compiled + * @param result = where to place result (might be void) + * @param args = script-visible arguments to pass to API function + */ + public override void CodeGen(ScriptCodeGen scg, Token errorAt, CompValuTemp result, CompValu[] args) + { + if(isTaggedCallsCheckRun) + { // see if 'xmr' method that calls CheckRun() internally + new ScriptCodeGen.CallLabel(scg, errorAt); // if so, put a call label immediately before it + // .. so restoring the frame will jump immediately to the + // .. call without re-executing any code before this + } + if(!methInfo.IsStatic) + { + scg.PushXMRInst(); // XMRInstanceSuperType pointer + if(apiContextField != null) // 'this' pointer for API function + scg.ilGen.Emit(errorAt, OpCodes.Ldfld, apiContextField); + + } + for(int i = 0; i < args.Length; i++) // push arguments, boxing/unboxing as needed + args[i].PushVal(scg, errorAt, argDecl.types[i]); + + // this should not be needed + // if (methInfo.Name == "llParcelMediaQuery") { + // scg.ilGen.Emit (errorAt, OpCodes.Call, fixLLParcelMediaQuery); + // } + // this should not be needed + // if (methInfo.Name == "llParcelMediaCommandList") { + // scg.ilGen.Emit (errorAt, OpCodes.Call, fixLLParcelMediaCommandList); + // } + if(methInfo.IsVirtual) // call API function + scg.ilGen.Emit(errorAt, OpCodes.Callvirt, methInfo); + else + scg.ilGen.Emit(errorAt, OpCodes.Call, methInfo); + + result.Pop(scg, errorAt, retType); // pop result, boxing/unboxing as needed + if(isTaggedCallsCheckRun) + scg.openCallLabel = null; + + if(doCheckRun) + scg.EmitCallCheckRun(errorAt, false); // maybe call CheckRun() + } + } +} diff --git a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptMyILGen.cs b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptMyILGen.cs new file mode 100644 index 0000000000..bf0db119d1 --- /dev/null +++ b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptMyILGen.cs @@ -0,0 +1,86 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Reflection; +using System.Reflection.Emit; + +namespace OpenSim.Region.ScriptEngine.Yengine +{ + public interface ScriptMyILGen + { + string methName + { + get; + } + ScriptMyLocal DeclareLocal(Type type, string name); + ScriptMyLabel DefineLabel(string name); + void BeginExceptionBlock(); + void BeginCatchBlock(Type excType); + void BeginFinallyBlock(); + void EndExceptionBlock(); + void Emit(Token errorAt, OpCode opcode); + void Emit(Token errorAt, OpCode opcode, FieldInfo field); + void Emit(Token errorAt, OpCode opcode, ScriptMyLocal myLocal); + void Emit(Token errorAt, OpCode opcode, Type type); + void Emit(Token errorAt, OpCode opcode, ScriptMyLabel myLabel); + void Emit(Token errorAt, OpCode opcode, ScriptMyLabel[] myLabels); + void Emit(Token errorAt, OpCode opcode, ScriptObjWriter method); + void Emit(Token errorAt, OpCode opcode, MethodInfo method); + void Emit(Token errorAt, OpCode opcode, ConstructorInfo ctor); + void Emit(Token errorAt, OpCode opcode, double value); + void Emit(Token errorAt, OpCode opcode, float value); + void Emit(Token errorAt, OpCode opcode, int value); + void Emit(Token errorAt, OpCode opcode, string value); + void MarkLabel(ScriptMyLabel myLabel); + } + + /** + * @brief One of these per label defined in the function. + */ + public class ScriptMyLabel + { + public string name; + public int number; + + public GraphNodeMarkLabel whereAmI; + public Type[] stackDepth; + public bool[] stackBoxeds; + } + + /** + * @brief One of these per local variable defined in the function. + */ + public class ScriptMyLocal + { + public string name; + public Type type; + public int number; + + public bool isReferenced; + } +} diff --git a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptObjCode.cs b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptObjCode.cs new file mode 100644 index 0000000000..bbdec99e18 --- /dev/null +++ b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptObjCode.cs @@ -0,0 +1,237 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using OpenSim.Region.ScriptEngine.Yengine; +using System; +using System.Collections.Generic; +using System.IO; +using System.Reflection; +using System.Reflection.Emit; + +namespace OpenSim.Region.ScriptEngine.Yengine +{ + public delegate void ScriptEventHandler(XMRInstAbstract instance); + + /* + * This object represents the output of the compilation. + * Once the compilation is complete, its contents should be + * considered 'read-only', so it can be shared among multiple + * instances of the script. + * + * It gets created by ScriptCodeGen. + * It gets used by XMRInstance to create script instances. + */ + public class ScriptObjCode + { + public string sourceHash; // source text hash code + public XMRInstArSizes glblSizes = new XMRInstArSizes(); + // number of global variables of various types + + public string[] stateNames; // convert state number to corresponding string + public ScriptEventHandler[,] scriptEventHandlerTable; + // entrypoints to all event handler functions + // 1st subscript = state code number (0=default) + // 2nd subscript = event code number + // null entry means no handler defined for that state,event + + public Dictionary sdObjTypesName; + // all script-defined types by name + + public TokenDeclSDType[] sdObjTypesIndx; + // all script-defined types by sdTypeIndex + + public Dictionary sdDelTypes; + // all script-defined delegates (including anonymous) + + public Dictionary dynamicMethods; + // all dyanmic methods + + public Dictionary[]> scriptSrcLocss; + // method,iloffset -> source file,line,posn + + public int refCount; // used by engine to keep track of number of + // instances that are using this object code + + public Dictionary> globalVarNames = new Dictionary>(); + + /** + * @brief Fill in ScriptObjCode from an YEngine object file. + * 'objFileReader' is a serialized form of the CIL code we generated + * 'asmFileWriter' is where we write the disassembly to (or null if not wanted) + * 'srcFileWriter' is where we write the decompilation to (or null if not wanted) + * Throws an exception if there is any error (theoretically). + */ + public ScriptObjCode(BinaryReader objFileReader, TextWriter asmFileWriter, TextWriter srcFileWriter) + { + // Check version number to make sure we know how to process file contents. + char[] ocm = objFileReader.ReadChars(ScriptCodeGen.OBJECT_CODE_MAGIC.Length); + if(new String(ocm) != ScriptCodeGen.OBJECT_CODE_MAGIC) + throw new CVVMismatchException("Not an Yengine object file (bad magic)"); + + int cvv = objFileReader.ReadInt32(); + if(cvv != ScriptCodeGen.COMPILED_VERSION_VALUE) + throw new CVVMismatchException( + "Object version is " + cvv.ToString() + " but accept only " + ScriptCodeGen.COMPILED_VERSION_VALUE.ToString()); + // Fill in simple parts of scriptObjCode object. + sourceHash = objFileReader.ReadString(); + glblSizes.ReadFromFile(objFileReader); + int nStates = objFileReader.ReadInt32(); + + stateNames = new string[nStates]; + for(int i = 0; i < nStates; i++) + { + stateNames[i] = objFileReader.ReadString(); + if(asmFileWriter != null) + asmFileWriter.WriteLine(" state[{0}] = {1}", i, stateNames[i]); + } + + if(asmFileWriter != null) + glblSizes.WriteAsmFile(asmFileWriter, "numGbl"); + + string gblName; + while((gblName = objFileReader.ReadString()) != "") + { + string gblType = objFileReader.ReadString(); + int gblIndex = objFileReader.ReadInt32(); + Dictionary names; + if(!globalVarNames.TryGetValue(gblType, out names)) + { + names = new Dictionary(); + globalVarNames.Add(gblType, names); + } + names.Add(gblIndex, gblName); + if(asmFileWriter != null) + asmFileWriter.WriteLine(" {0} = {1}[{2}]", gblName, gblType, gblIndex); + } + + // Read in script-defined types. + sdObjTypesName = new Dictionary(); + sdDelTypes = new Dictionary(); + int maxIndex = -1; + while((gblName = objFileReader.ReadString()) != "") + { + TokenDeclSDType sdt = TokenDeclSDType.ReadFromFile(sdObjTypesName, + gblName, objFileReader, asmFileWriter); + sdObjTypesName.Add(gblName, sdt); + if(maxIndex < sdt.sdTypeIndex) + maxIndex = sdt.sdTypeIndex; + if(sdt is TokenDeclSDTypeDelegate) + sdDelTypes.Add(sdt.GetSysType(), gblName); + } + sdObjTypesIndx = new TokenDeclSDType[maxIndex + 1]; + foreach(TokenDeclSDType sdt in sdObjTypesName.Values) + sdObjTypesIndx[sdt.sdTypeIndex] = sdt; + + // Now fill in the methods (the hard part). + scriptEventHandlerTable = new ScriptEventHandler[nStates, (int)ScriptEventCode.Size]; + dynamicMethods = new Dictionary(); + scriptSrcLocss = new Dictionary[]>(); + + ObjectTokens objectTokens = null; + if(asmFileWriter != null) + objectTokens = new OTDisassemble(this, asmFileWriter); + else if(srcFileWriter != null) + objectTokens = new OTDecompile(this, srcFileWriter); + + try + { + ScriptObjWriter.CreateObjCode(sdObjTypesName, objFileReader, this, objectTokens); + } + finally + { + if(objectTokens != null) + objectTokens.Close(); + } + + // We enter all script event handler methods in the ScriptEventHandler table. + // They are named: + foreach(KeyValuePair kvp in dynamicMethods) + { + string methName = kvp.Key; + int i = methName.IndexOf(' '); + if(i < 0) + continue; + string stateName = methName.Substring(0, i); + string eventName = methName.Substring(++i); + int stateCode; + for(stateCode = stateNames.Length; --stateCode >= 0;) + if(stateNames[stateCode] == stateName) + break; + + int eventCode = (int)Enum.Parse(typeof(ScriptEventCode), eventName); + scriptEventHandlerTable[stateCode, eventCode] = + (ScriptEventHandler)kvp.Value.CreateDelegate(typeof(ScriptEventHandler)); + } + + // Fill in all script-defined class vtables. + foreach(TokenDeclSDType sdt in sdObjTypesIndx) + { + if((sdt != null) && (sdt is TokenDeclSDTypeClass)) + { + TokenDeclSDTypeClass sdtc = (TokenDeclSDTypeClass)sdt; + sdtc.FillVTables(this); + } + } + } + + /** + * @brief Called once for every method found in objFileReader file. + * It enters the method in the ScriptObjCode object table so it can be called. + */ + public void EndMethod(DynamicMethod method, Dictionary srcLocs) + { + // Save method object code pointer. + dynamicMethods.Add(method.Name, method); + + // Build and sort iloffset -> source code location array. + int n = srcLocs.Count; + KeyValuePair[] srcLocArray = new KeyValuePair[n]; + n = 0; + foreach(KeyValuePair kvp in srcLocs) + srcLocArray[n++] = kvp; + Array.Sort(srcLocArray, endMethodWrapper); + + // Save sorted array. + scriptSrcLocss.Add(method.Name, srcLocArray); + } + + /** + * @brief Called once for every method found in objFileReader file. + * It enters the method in the ScriptObjCode object table so it can be called. + */ + private static EndMethodWrapper endMethodWrapper = new EndMethodWrapper(); + private class EndMethodWrapper: System.Collections.IComparer + { + public int Compare(object x, object y) + { + KeyValuePair kvpx = (KeyValuePair)x; + KeyValuePair kvpy = (KeyValuePair)y; + return kvpx.Key - kvpy.Key; + } + } + } +} diff --git a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptObjWriter.cs b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptObjWriter.cs new file mode 100644 index 0000000000..6ab0bb5763 --- /dev/null +++ b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptObjWriter.cs @@ -0,0 +1,986 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using OpenSim.Region.ScriptEngine.Shared.ScriptBase; +using System; +using System.Collections.Generic; +using System.IO; +using System.Reflection; +using System.Reflection.Emit; +using System.Text; + +using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; +using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; +using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; +using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list; +using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; +using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; +using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; + +/** + * @brief Wrapper class for ILGenerator. + * It writes the object code to a file and can then make real ILGenerator calls + * based on the file's contents. + */ +namespace OpenSim.Region.ScriptEngine.Yengine +{ + public enum ScriptObjWriterCode: byte + { + BegMethod, EndMethod, TheEnd, + DclLabel, DclLocal, DclMethod, MarkLabel, + EmitNull, EmitField, EmitLocal, EmitType, EmitLabel, EmitMethodExt, + EmitMethodInt, EmitCtor, EmitDouble, EmitFloat, EmitInteger, EmitString, + EmitLabels, + BegExcBlk, BegCatBlk, BegFinBlk, EndExcBlk + } + + public class ScriptObjWriter: ScriptMyILGen + { + private static Dictionary opCodes = PopulateOpCodes(); + private static Dictionary string2Type = PopulateS2T(); + private static Dictionary type2String = PopulateT2S(); + + private static MethodInfo monoGetCurrentOffset = typeof(ILGenerator).GetMethod("Mono_GetCurrentOffset", + BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, + new Type[] { typeof(ILGenerator) }, null); + + private static readonly OpCode[] opCodesLdcI4M1P8 = new OpCode[] { + OpCodes.Ldc_I4_M1, OpCodes.Ldc_I4_0, OpCodes.Ldc_I4_1, OpCodes.Ldc_I4_2, OpCodes.Ldc_I4_3, + OpCodes.Ldc_I4_4, OpCodes.Ldc_I4_5, OpCodes.Ldc_I4_6, OpCodes.Ldc_I4_7, OpCodes.Ldc_I4_8 + }; + + private BinaryWriter objFileWriter; + private string lastErrorAtFile = ""; + private int lastErrorAtLine = 0; + private int lastErrorAtPosn = 0; + + private Dictionary sdTypesRev = new Dictionary(); + public int labelNumber = 0; + public int localNumber = 0; + + private string _methName; + public string methName + { + get + { + return _methName; + } + } + + public Type retType; + public Type[] argTypes; + + /** + * @brief Begin function declaration + * @param sdTypes = script-defined types + * @param methName = name of the method being declared, eg, "Verify(array,list,string)" + * @param retType = its return value type + * @param argTypes[] = its argument types + * @param objFileWriter = file to write its object code to + * + * After calling this function, the following functions should be called: + * this.BegMethod (); + * this. (); + * this.EndMethod (); + * + * The design of this object is such that many constructors may be called, + * but once a BegMethod() is called for one of the objects, no method may + * called for any of the other objects until EndMethod() is called (or it + * would break up the object stream for that method). But we need to have + * many constructors possible so we get function headers at the beginning + * of the object file in case there are forward references to the functions. + */ + public ScriptObjWriter(TokenScript tokenScript, string methName, Type retType, Type[] argTypes, string[] argNames, BinaryWriter objFileWriter) + { + this._methName = methName; + this.retType = retType; + this.argTypes = argTypes; + this.objFileWriter = objFileWriter; + + // Build list that translates system-defined types to script defined types. + foreach(TokenDeclSDType sdt in tokenScript.sdSrcTypesValues) + { + Type sys = sdt.GetSysType(); + if(sys != null) + sdTypesRev[sys] = sdt.longName.val; + } + + // This tells the reader to call 'new DynamicMethod()' to create + // the function header. Then any forward reference calls to this + // method will have a MethodInfo struct to call. + objFileWriter.Write((byte)ScriptObjWriterCode.DclMethod); + objFileWriter.Write(methName); + objFileWriter.Write(GetStrFromType(retType)); + + int nArgs = argTypes.Length; + objFileWriter.Write(nArgs); + for(int i = 0; i < nArgs; i++) + { + objFileWriter.Write(GetStrFromType(argTypes[i])); + objFileWriter.Write(argNames[i]); + } + } + + /** + * @brief Begin outputting object code for the function + */ + public void BegMethod() + { + // This tells the reader to call methodInfo.GetILGenerator() + // so it can start writing CIL code for the method. + objFileWriter.Write((byte)ScriptObjWriterCode.BegMethod); + objFileWriter.Write(methName); + } + + /** + * @brief End of object code for the function + */ + public void EndMethod() + { + // This tells the reader that all code for the method has + // been written and so it will typically call CreateDelegate() + // to finalize the method and create an entrypoint. + objFileWriter.Write((byte)ScriptObjWriterCode.EndMethod); + + objFileWriter = null; + } + + /** + * @brief Declare a local variable for use by the function + */ + public ScriptMyLocal DeclareLocal(Type type, string name) + { + ScriptMyLocal myLocal = new ScriptMyLocal(); + myLocal.type = type; + myLocal.name = name; + myLocal.number = localNumber++; + myLocal.isReferenced = true; // so ScriptCollector won't optimize references away + return DeclareLocal(myLocal); + } + public ScriptMyLocal DeclareLocal(ScriptMyLocal myLocal) + { + objFileWriter.Write((byte)ScriptObjWriterCode.DclLocal); + objFileWriter.Write(myLocal.number); + objFileWriter.Write(myLocal.name); + objFileWriter.Write(GetStrFromType(myLocal.type)); + return myLocal; + } + + /** + * @brief Define a label for use by the function + */ + public ScriptMyLabel DefineLabel(string name) + { + ScriptMyLabel myLabel = new ScriptMyLabel(); + myLabel.name = name; + myLabel.number = labelNumber++; + return DefineLabel(myLabel); + } + public ScriptMyLabel DefineLabel(ScriptMyLabel myLabel) + { + objFileWriter.Write((byte)ScriptObjWriterCode.DclLabel); + objFileWriter.Write(myLabel.number); + objFileWriter.Write(myLabel.name); + return myLabel; + } + + /** + * @brief try/catch blocks. + */ + public void BeginExceptionBlock() + { + objFileWriter.Write((byte)ScriptObjWriterCode.BegExcBlk); + } + + public void BeginCatchBlock(Type excType) + { + objFileWriter.Write((byte)ScriptObjWriterCode.BegCatBlk); + objFileWriter.Write(GetStrFromType(excType)); + } + + public void BeginFinallyBlock() + { + objFileWriter.Write((byte)ScriptObjWriterCode.BegFinBlk); + } + + public void EndExceptionBlock() + { + objFileWriter.Write((byte)ScriptObjWriterCode.EndExcBlk); + } + + public void Emit(Token errorAt, OpCode opcode) + { + objFileWriter.Write((byte)ScriptObjWriterCode.EmitNull); + WriteOpCode(errorAt, opcode); + } + + public void Emit(Token errorAt, OpCode opcode, FieldInfo field) + { + objFileWriter.Write((byte)ScriptObjWriterCode.EmitField); + WriteOpCode(errorAt, opcode); + objFileWriter.Write(GetStrFromType(field.ReflectedType)); + objFileWriter.Write(field.Name); + } + + public void Emit(Token errorAt, OpCode opcode, ScriptMyLocal myLocal) + { + objFileWriter.Write((byte)ScriptObjWriterCode.EmitLocal); + WriteOpCode(errorAt, opcode); + objFileWriter.Write(myLocal.number); + } + + public void Emit(Token errorAt, OpCode opcode, Type type) + { + objFileWriter.Write((byte)ScriptObjWriterCode.EmitType); + WriteOpCode(errorAt, opcode); + objFileWriter.Write(GetStrFromType(type)); + } + + public void Emit(Token errorAt, OpCode opcode, ScriptMyLabel myLabel) + { + objFileWriter.Write((byte)ScriptObjWriterCode.EmitLabel); + WriteOpCode(errorAt, opcode); + objFileWriter.Write(myLabel.number); + } + + public void Emit(Token errorAt, OpCode opcode, ScriptMyLabel[] myLabels) + { + objFileWriter.Write((byte)ScriptObjWriterCode.EmitLabels); + WriteOpCode(errorAt, opcode); + int nLabels = myLabels.Length; + objFileWriter.Write(nLabels); + for(int i = 0; i < nLabels; i++) + { + objFileWriter.Write(myLabels[i].number); + } + } + + public void Emit(Token errorAt, OpCode opcode, ScriptObjWriter method) + { + if(method == null) + throw new ArgumentNullException("method"); + objFileWriter.Write((byte)ScriptObjWriterCode.EmitMethodInt); + WriteOpCode(errorAt, opcode); + objFileWriter.Write(method.methName); + } + + public void Emit(Token errorAt, OpCode opcode, MethodInfo method) + { + objFileWriter.Write((byte)ScriptObjWriterCode.EmitMethodExt); + WriteOpCode(errorAt, opcode); + objFileWriter.Write(method.Name); + objFileWriter.Write(GetStrFromType(method.ReflectedType)); + ParameterInfo[] parms = method.GetParameters(); + int nArgs = parms.Length; + objFileWriter.Write(nArgs); + for(int i = 0; i < nArgs; i++) + { + objFileWriter.Write(GetStrFromType(parms[i].ParameterType)); + } + } + + public void Emit(Token errorAt, OpCode opcode, ConstructorInfo ctor) + { + objFileWriter.Write((byte)ScriptObjWriterCode.EmitCtor); + WriteOpCode(errorAt, opcode); + objFileWriter.Write(GetStrFromType(ctor.ReflectedType)); + ParameterInfo[] parms = ctor.GetParameters(); + int nArgs = parms.Length; + objFileWriter.Write(nArgs); + for(int i = 0; i < nArgs; i++) + { + objFileWriter.Write(GetStrFromType(parms[i].ParameterType)); + } + } + + public void Emit(Token errorAt, OpCode opcode, double value) + { + if(opcode != OpCodes.Ldc_R8) + { + throw new Exception("bad opcode " + opcode.ToString()); + } + objFileWriter.Write((byte)ScriptObjWriterCode.EmitDouble); + WriteOpCode(errorAt, opcode); + objFileWriter.Write(value); + } + + public void Emit(Token errorAt, OpCode opcode, float value) + { + if(opcode != OpCodes.Ldc_R4) + { + throw new Exception("bad opcode " + opcode.ToString()); + } + objFileWriter.Write((byte)ScriptObjWriterCode.EmitFloat); + WriteOpCode(errorAt, opcode); + objFileWriter.Write(value); + } + + public void Emit(Token errorAt, OpCode opcode, int value) + { + objFileWriter.Write((byte)ScriptObjWriterCode.EmitInteger); + WriteOpCode(errorAt, opcode); + objFileWriter.Write(value); + } + + public void Emit(Token errorAt, OpCode opcode, string value) + { + objFileWriter.Write((byte)ScriptObjWriterCode.EmitString); + WriteOpCode(errorAt, opcode); + objFileWriter.Write(value); + } + + /** + * @brief Declare that the target of a label is the next instruction. + */ + public void MarkLabel(ScriptMyLabel myLabel) + { + objFileWriter.Write((byte)ScriptObjWriterCode.MarkLabel); + objFileWriter.Write(myLabel.number); + } + + /** + * @brief Write end-of-file marker to binary file. + */ + public static void TheEnd(BinaryWriter objFileWriter) + { + objFileWriter.Write((byte)ScriptObjWriterCode.TheEnd); + } + + /** + * @brief Take an object file created by ScriptObjWriter() and convert it to a series of dynamic methods. + * @param sdTypes = script-defined types + * @param objReader = where to read object file from (as written by ScriptObjWriter above). + * @param scriptObjCode.EndMethod = called for each method defined at the end of the methods definition + * @param objectTokens = write disassemble/decompile data (or null if not wanted) + */ + public static void CreateObjCode(Dictionary sdTypes, BinaryReader objReader, + ScriptObjCode scriptObjCode, ObjectTokens objectTokens) + { + Dictionary methods = new Dictionary(); + DynamicMethod method = null; + ILGenerator ilGen = null; + Dictionary labels = new Dictionary(); + Dictionary locals = new Dictionary(); + Dictionary labelNames = new Dictionary(); + Dictionary localNames = new Dictionary(); + object[] ilGenArg = new object[1]; + int offset = 0; + Dictionary srcLocs = null; + string srcFile = ""; + int srcLine = 0; + int srcPosn = 0; + + while(true) + { + // Get IL instruction offset at beginning of instruction. + offset = 0; + if((ilGen != null) && (monoGetCurrentOffset != null)) + { + offset = (int)monoGetCurrentOffset.Invoke(null, ilGenArg); + } + + // Read and decode next internal format code from input file (.xmrobj file). + ScriptObjWriterCode code = (ScriptObjWriterCode)objReader.ReadByte(); + switch(code) + { + // Reached end-of-file so we are all done. + case ScriptObjWriterCode.TheEnd: + return; + + // Beginning of method's contents. + // Method must have already been declared via DclMethod + // so all we need is its name to retrieve from methods[]. + case ScriptObjWriterCode.BegMethod: + { + string methName = objReader.ReadString(); + + method = methods[methName]; + ilGen = method.GetILGenerator(); + ilGenArg[0] = ilGen; + + labels.Clear(); + locals.Clear(); + labelNames.Clear(); + localNames.Clear(); + + srcLocs = new Dictionary(); + if(objectTokens != null) + objectTokens.BegMethod(method); + break; + } + + // End of method's contents (ie, an OpCodes.Ret was probably just output). + // Call the callback to tell it the method is complete, and it can do whatever + // it wants with the method. + case ScriptObjWriterCode.EndMethod: + { + ilGen = null; + ilGenArg[0] = null; + scriptObjCode.EndMethod(method, srcLocs); + srcLocs = null; + if(objectTokens != null) + objectTokens.EndMethod(); + break; + } + + // Declare a label for branching to. + case ScriptObjWriterCode.DclLabel: + { + int number = objReader.ReadInt32(); + string name = objReader.ReadString(); + + labels.Add(number, ilGen.DefineLabel()); + labelNames.Add(number, name + "_" + number.ToString()); + if(objectTokens != null) + objectTokens.DefineLabel(number, name); + break; + } + + // Declare a local variable to store into. + case ScriptObjWriterCode.DclLocal: + { + int number = objReader.ReadInt32(); + string name = objReader.ReadString(); + string type = objReader.ReadString(); + Type syType = GetTypeFromStr(sdTypes, type); + + locals.Add(number, ilGen.DeclareLocal(syType)); + localNames.Add(number, name + "_" + number.ToString()); + if(objectTokens != null) + objectTokens.DefineLocal(number, name, type, syType); + break; + } + + // Declare a method that will subsequently be defined. + // We create the DynamicMethod object at this point in case there + // are forward references from other method bodies. + case ScriptObjWriterCode.DclMethod: + { + string methName = objReader.ReadString(); + Type retType = GetTypeFromStr(sdTypes, objReader.ReadString()); + int nArgs = objReader.ReadInt32(); + + Type[] argTypes = new Type[nArgs]; + string[] argNames = new string[nArgs]; + for(int i = 0; i < nArgs; i++) + { + argTypes[i] = GetTypeFromStr(sdTypes, objReader.ReadString()); + argNames[i] = objReader.ReadString(); + } + methods.Add(methName, new DynamicMethod(methName, retType, argTypes)); + if(objectTokens != null) + objectTokens.DefineMethod(methName, retType, argTypes, argNames); + break; + } + + // Mark a previously declared label at this spot. + case ScriptObjWriterCode.MarkLabel: + { + int number = objReader.ReadInt32(); + + ilGen.MarkLabel(labels[number]); + + if(objectTokens != null) + objectTokens.MarkLabel(offset, number); + break; + } + + // Try/Catch blocks. + case ScriptObjWriterCode.BegExcBlk: + { + ilGen.BeginExceptionBlock(); + if(objectTokens != null) + objectTokens.BegExcBlk(offset); + break; + } + + case ScriptObjWriterCode.BegCatBlk: + { + Type excType = GetTypeFromStr(sdTypes, objReader.ReadString()); + ilGen.BeginCatchBlock(excType); + if(objectTokens != null) + objectTokens.BegCatBlk(offset, excType); + break; + } + + case ScriptObjWriterCode.BegFinBlk: + { + ilGen.BeginFinallyBlock(); + if(objectTokens != null) + objectTokens.BegFinBlk(offset); + break; + } + + case ScriptObjWriterCode.EndExcBlk: + { + ilGen.EndExceptionBlock(); + if(objectTokens != null) + objectTokens.EndExcBlk(offset); + break; + } + + // Emit an opcode with no operand. + case ScriptObjWriterCode.EmitNull: + { + OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn); + + SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn); + ilGen.Emit(opCode); + + if(objectTokens != null) + objectTokens.EmitNull(offset, opCode); + break; + } + + // Emit an opcode with a FieldInfo operand. + case ScriptObjWriterCode.EmitField: + { + OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn); + Type reflectedType = GetTypeFromStr(sdTypes, objReader.ReadString()); + string fieldName = objReader.ReadString(); + + FieldInfo field = reflectedType.GetField(fieldName); + SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn); + ilGen.Emit(opCode, field); + + if(objectTokens != null) + objectTokens.EmitField(offset, opCode, field); + break; + } + + // Emit an opcode with a LocalBuilder operand. + case ScriptObjWriterCode.EmitLocal: + { + OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn); + int number = objReader.ReadInt32(); + SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn); + ilGen.Emit(opCode, locals[number]); + + if(objectTokens != null) + objectTokens.EmitLocal(offset, opCode, number); + break; + } + + // Emit an opcode with a Type operand. + case ScriptObjWriterCode.EmitType: + { + OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn); + string name = objReader.ReadString(); + Type type = GetTypeFromStr(sdTypes, name); + + SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn); + ilGen.Emit(opCode, type); + + if(objectTokens != null) + objectTokens.EmitType(offset, opCode, type); + break; + } + + // Emit an opcode with a Label operand. + case ScriptObjWriterCode.EmitLabel: + { + OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn); + int number = objReader.ReadInt32(); + + SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn); + ilGen.Emit(opCode, labels[number]); + + if(objectTokens != null) + objectTokens.EmitLabel(offset, opCode, number); + break; + } + + // Emit an opcode with a Label array operand. + case ScriptObjWriterCode.EmitLabels: + { + OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn); + int nLabels = objReader.ReadInt32(); + Label[] lbls = new Label[nLabels]; + int[] nums = new int[nLabels]; + for(int i = 0; i < nLabels; i++) + { + nums[i] = objReader.ReadInt32(); + lbls[i] = labels[nums[i]]; + } + + SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn); + ilGen.Emit(opCode, lbls); + + if(objectTokens != null) + objectTokens.EmitLabels(offset, opCode, nums); + break; + } + + // Emit an opcode with a MethodInfo operand (such as a call) of an external function. + case ScriptObjWriterCode.EmitMethodExt: + { + OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn); + string methName = objReader.ReadString(); + Type methType = GetTypeFromStr(sdTypes, objReader.ReadString()); + int nArgs = objReader.ReadInt32(); + + Type[] argTypes = new Type[nArgs]; + for(int i = 0; i < nArgs; i++) + { + argTypes[i] = GetTypeFromStr(sdTypes, objReader.ReadString()); + } + MethodInfo methInfo = methType.GetMethod(methName, argTypes); + SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn); + ilGen.Emit(opCode, methInfo); + + if(objectTokens != null) + objectTokens.EmitMethod(offset, opCode, methInfo); + break; + } + + // Emit an opcode with a MethodInfo operand of an internal function + // (previously declared via DclMethod). + case ScriptObjWriterCode.EmitMethodInt: + { + OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn); + string methName = objReader.ReadString(); + + MethodInfo methInfo = methods[methName]; + SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn); + ilGen.Emit(opCode, methInfo); + + if(objectTokens != null) + objectTokens.EmitMethod(offset, opCode, methInfo); + break; + } + + // Emit an opcode with a ConstructorInfo operand. + case ScriptObjWriterCode.EmitCtor: + { + OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn); + Type ctorType = GetTypeFromStr(sdTypes, objReader.ReadString()); + int nArgs = objReader.ReadInt32(); + Type[] argTypes = new Type[nArgs]; + for(int i = 0; i < nArgs; i++) + { + argTypes[i] = GetTypeFromStr(sdTypes, objReader.ReadString()); + } + + ConstructorInfo ctorInfo = ctorType.GetConstructor(argTypes); + SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn); + ilGen.Emit(opCode, ctorInfo); + + if(objectTokens != null) + objectTokens.EmitCtor(offset, opCode, ctorInfo); + break; + } + + // Emit an opcode with a constant operand of various types. + case ScriptObjWriterCode.EmitDouble: + { + OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn); + double value = objReader.ReadDouble(); + + if(opCode != OpCodes.Ldc_R8) + { + throw new Exception("bad opcode " + opCode.ToString()); + } + SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn); + ilGen.Emit(opCode, value); + + if(objectTokens != null) + objectTokens.EmitDouble(offset, opCode, value); + break; + } + + case ScriptObjWriterCode.EmitFloat: + { + OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn); + float value = objReader.ReadSingle(); + + if(opCode != OpCodes.Ldc_R4) + { + throw new Exception("bad opcode " + opCode.ToString()); + } + SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn); + ilGen.Emit(opCode, value); + + if(objectTokens != null) + objectTokens.EmitFloat(offset, opCode, value); + break; + } + + case ScriptObjWriterCode.EmitInteger: + { + OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn); + int value = objReader.ReadInt32(); + + SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn); + + if(opCode == OpCodes.Ldc_I4) + { + if((value >= -1) && (value <= 8)) + { + opCode = opCodesLdcI4M1P8[value + 1]; + ilGen.Emit(opCode); + if(objectTokens != null) + objectTokens.EmitNull(offset, opCode); + break; + } + if((value >= 0) && (value <= 127)) + { + opCode = OpCodes.Ldc_I4_S; + ilGen.Emit(OpCodes.Ldc_I4_S, (sbyte)value); + goto pemitint; + } + } + + ilGen.Emit(opCode, value); + pemitint: + if(objectTokens != null) + objectTokens.EmitInteger(offset, opCode, value); + break; + } + + case ScriptObjWriterCode.EmitString: + { + OpCode opCode = ReadOpCode(objReader, ref srcFile, ref srcLine, ref srcPosn); + string value = objReader.ReadString(); + + SaveSrcLoc(srcLocs, offset, srcFile, srcLine, srcPosn); + ilGen.Emit(opCode, value); + + if(objectTokens != null) + objectTokens.EmitString(offset, opCode, value); + break; + } + + // Who knows what? + default: + throw new Exception("bad ScriptObjWriterCode " + ((byte)code).ToString()); + } + } + } + + /** + * @brief Generate array to quickly translate OpCode.Value to full OpCode struct. + */ + private static Dictionary PopulateOpCodes() + { + Dictionary opCodeDict = new Dictionary(); + FieldInfo[] fields = typeof(OpCodes).GetFields(); + for(int i = 0; i < fields.Length; i++) + { + OpCode opcode = (OpCode)fields[i].GetValue(null); + opCodeDict.Add(opcode.Value, opcode); + } + return opCodeDict; + } + + /** + * @brief Write opcode out to file. + */ + private void WriteOpCode(Token errorAt, OpCode opcode) + { + if(errorAt == null) + { + objFileWriter.Write(""); + objFileWriter.Write(lastErrorAtLine); + objFileWriter.Write(lastErrorAtPosn); + } + else + { + if(errorAt.file != lastErrorAtFile) + { + objFileWriter.Write(errorAt.file); + lastErrorAtFile = errorAt.file; + } + else + { + objFileWriter.Write(""); + } + objFileWriter.Write(errorAt.line); + objFileWriter.Write(errorAt.posn); + lastErrorAtLine = errorAt.line; + lastErrorAtPosn = errorAt.posn; + } + objFileWriter.Write(opcode.Value); + } + + /** + * @brief Read opcode in from file. + */ + private static OpCode ReadOpCode(BinaryReader objReader, ref string srcFile, ref int srcLine, ref int srcPosn) + { + string f = objReader.ReadString(); + if(f != "") + srcFile = f; + srcLine = objReader.ReadInt32(); + srcPosn = objReader.ReadInt32(); + + short value = objReader.ReadInt16(); + return opCodes[value]; + } + + /** + * @brief Save an IL_offset -> source location translation entry + * @param srcLocs = saved entries for the current function + * @param offset = offset in IL object code for next instruction + * @param src{File,Line,Posn} = location in source file corresponding to opcode + * @returns with entry added to srcLocs + */ + private static void SaveSrcLoc(Dictionary srcLocs, int offset, string srcFile, int srcLine, int srcPosn) + { + ScriptSrcLoc srcLoc = new ScriptSrcLoc(); + srcLoc.file = srcFile; + srcLoc.line = srcLine; + srcLoc.posn = srcPosn; + srcLocs[offset] = srcLoc; + } + + /** + * @brief Create type<->string conversions. + * Using Type.AssemblyQualifiedName is horribly inefficient + * and all our types should be known. + */ + private static Dictionary PopulateS2T() + { + Dictionary s2t = new Dictionary(); + + s2t.Add("badcallx", typeof(ScriptBadCallNoException)); + s2t.Add("binopstr", typeof(BinOpStr)); + s2t.Add("bool", typeof(bool)); + s2t.Add("char", typeof(char)); + s2t.Add("delegate", typeof(Delegate)); + s2t.Add("delarr[]", typeof(Delegate[])); + s2t.Add("double", typeof(double)); + s2t.Add("exceptn", typeof(Exception)); + s2t.Add("float", typeof(float)); + s2t.Add("htlist", typeof(HeapTrackerList)); + s2t.Add("htobject", typeof(HeapTrackerObject)); + s2t.Add("htstring", typeof(HeapTrackerString)); + s2t.Add("inlfunc", typeof(CompValuInline)); + s2t.Add("int", typeof(int)); + s2t.Add("int*", typeof(int).MakeByRefType()); + s2t.Add("intrlokd", typeof(System.Threading.Interlocked)); + s2t.Add("lslfloat", typeof(LSL_Float)); + s2t.Add("lslint", typeof(LSL_Integer)); + s2t.Add("lsllist", typeof(LSL_List)); + s2t.Add("lslrot", typeof(LSL_Rotation)); + s2t.Add("lslstr", typeof(LSL_String)); + s2t.Add("lslvec", typeof(LSL_Vector)); + s2t.Add("math", typeof(Math)); + s2t.Add("midround", typeof(MidpointRounding)); + s2t.Add("object", typeof(object)); + s2t.Add("object*", typeof(object).MakeByRefType()); + s2t.Add("object[]", typeof(object[])); + s2t.Add("scrbase", typeof(ScriptBaseClass)); + s2t.Add("scrcode", typeof(ScriptCodeGen)); + s2t.Add("sdtclobj", typeof(XMRSDTypeClObj)); + s2t.Add("string", typeof(string)); + s2t.Add("typecast", typeof(TypeCast)); + s2t.Add("undstatx", typeof(ScriptUndefinedStateException)); + s2t.Add("void", typeof(void)); + s2t.Add("xmrarray", typeof(XMR_Array)); + s2t.Add("xmrinst", typeof(XMRInstAbstract)); + + return s2t; + } + + private static Dictionary PopulateT2S() + { + Dictionary s2t = PopulateS2T(); + Dictionary t2s = new Dictionary(); + foreach(KeyValuePair kvp in s2t) + { + t2s.Add(kvp.Value, kvp.Key); + } + return t2s; + } + + /** + * @brief Add to list of internally recognized types. + */ + public static void DefineInternalType(string name, Type type) + { + if(!string2Type.ContainsKey(name)) + { + string2Type.Add(name, type); + type2String.Add(type, name); + } + } + + private string GetStrFromType(Type t) + { + string s = GetStrFromTypeWork(t); + return s; + } + private string GetStrFromTypeWork(Type t) + { + string s; + + // internal fixed types like int and xmrarray etc + if(type2String.TryGetValue(t, out s)) + return s; + + // script-defined types + if(sdTypesRev.TryGetValue(t, out s)) + return "sdt$" + s; + + // inline function types + s = TokenDeclSDTypeDelegate.TryGetInlineName(t); + if(s != null) + return s; + + // last resort + return t.AssemblyQualifiedName; + } + + private static Type GetTypeFromStr(Dictionary sdTypes, string s) + { + Type t; + + // internal fixed types like int and xmrarray etc + if(string2Type.TryGetValue(s, out t)) + return t; + + // script-defined types + if(s.StartsWith("sdt$")) + return sdTypes[s.Substring(4)].GetSysType(); + + // inline function types + t = TokenDeclSDTypeDelegate.TryGetInlineSysType(s); + if(t != null) + return t; + + // last resort + return Type.GetType(s, true); + } + } + + public class ScriptSrcLoc + { + public string file; + public int line; + public int posn; + } +} diff --git a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptReduce.cs b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptReduce.cs new file mode 100644 index 0000000000..85bc9aa260 --- /dev/null +++ b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptReduce.cs @@ -0,0 +1,8180 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @brief Reduce parser tokens to abstract syntax tree tokens. + * + * Usage: + * + * tokenBegin = returned by TokenBegin.Analyze () + * representing the whole script source + * as a flat list of tokens + * + * TokenScript tokenScript = Reduce.Analyze (TokenBegin tokenBegin); + * + * tokenScript = represents the whole script source + * as a tree of tokens + */ + +using OpenSim.Region.ScriptEngine.Shared.ScriptBase; +using System; +using System.Collections.Generic; +using System.IO; +using System.Reflection; +using System.Reflection.Emit; +using System.Text; + +using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; +using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; +using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; +using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list; +using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; +using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; +using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; + +namespace OpenSim.Region.ScriptEngine.Yengine +{ + public class ScriptReduce + { + public const uint SDT_PRIVATE = 1; + public const uint SDT_PROTECTED = 2; + public const uint SDT_PUBLIC = 4; + public const uint SDT_ABSTRACT = 8; + public const uint SDT_FINAL = 16; + public const uint SDT_NEW = 32; + public const uint SDT_OVERRIDE = 64; + public const uint SDT_STATIC = 128; + public const uint SDT_VIRTUAL = 256; + + private const int ASNPR = 50; + + private static Dictionary precedence = PrecedenceInit(); + + private static readonly Type[] brkCloseOnly = new Type[] { typeof(TokenKwBrkClose) }; + private static readonly Type[] cmpGTOnly = new Type[] { typeof(TokenKwCmpGT) }; + private static readonly Type[] colonOnly = new Type[] { typeof(TokenKwColon) }; + private static readonly Type[] commaOrBrcClose = new Type[] { typeof(TokenKwComma), typeof(TokenKwBrcClose) }; + private static readonly Type[] colonOrDotDotDot = new Type[] { typeof(TokenKwColon), typeof(TokenKwDotDotDot) }; + private static readonly Type[] parCloseOnly = new Type[] { typeof(TokenKwParClose) }; + private static readonly Type[] semiOnly = new Type[] { typeof(TokenKwSemi) }; + + /** + * @brief Initialize operator precedence table + * @returns with precedence table pointer + */ + private static Dictionary PrecedenceInit() + { + Dictionary p = new Dictionary(); + + // http://www.lslwiki.net/lslwiki/wakka.php?wakka=operators + + p.Add(typeof(TokenKwComma), 30); + + p.Add(typeof(TokenKwAsnLSh), ASNPR); // all assignment operators of equal precedence + p.Add(typeof(TokenKwAsnRSh), ASNPR); // ... so they get processed strictly right-to-left + p.Add(typeof(TokenKwAsnAdd), ASNPR); + p.Add(typeof(TokenKwAsnAnd), ASNPR); + p.Add(typeof(TokenKwAsnSub), ASNPR); + p.Add(typeof(TokenKwAsnMul), ASNPR); + p.Add(typeof(TokenKwAsnDiv), ASNPR); + p.Add(typeof(TokenKwAsnMod), ASNPR); + p.Add(typeof(TokenKwAsnOr), ASNPR); + p.Add(typeof(TokenKwAsnXor), ASNPR); + p.Add(typeof(TokenKwAssign), ASNPR); + + p.Add(typeof(TokenKwQMark), 60); + + p.Add(typeof(TokenKwOrOrOr), 70); + p.Add(typeof(TokenKwAndAndAnd), 80); + + p.Add(typeof(TokenKwOrOr), 100); + + p.Add(typeof(TokenKwAndAnd), 120); + + p.Add(typeof(TokenKwOr), 140); + + p.Add(typeof(TokenKwXor), 160); + + p.Add(typeof(TokenKwAnd), 180); + + p.Add(typeof(TokenKwCmpEQ), 200); + p.Add(typeof(TokenKwCmpNE), 200); + + p.Add(typeof(TokenKwCmpLT), 240); + p.Add(typeof(TokenKwCmpLE), 240); + p.Add(typeof(TokenKwCmpGT), 240); + p.Add(typeof(TokenKwCmpGE), 240); + + p.Add(typeof(TokenKwRSh), 260); + p.Add(typeof(TokenKwLSh), 260); + + p.Add(typeof(TokenKwAdd), 280); + p.Add(typeof(TokenKwSub), 280); + + p.Add(typeof(TokenKwMul), 320); + p.Add(typeof(TokenKwDiv), 320); + p.Add(typeof(TokenKwMod), 320); + + return p; + } + + /** + * @brief Reduce raw token stream to a single script token. + * Performs a little semantic testing, ie, undefined variables, etc. + * @param tokenBegin = points to a TokenBegin + * followed by raw tokens + * and last token is a TokenEnd + * @returns null: not a valid script, error messages have been output + * else: valid script top token + */ + public static TokenScript Reduce(TokenBegin tokenBegin) + { + return new ScriptReduce(tokenBegin).tokenScript; + } + + /* + * Instance variables. + */ + private bool errors = false; + private string lastErrorFile = ""; + private int lastErrorLine = 0; + private int numTypedefs = 0; + private TokenDeclVar currentDeclFunc = null; + private TokenDeclSDType currentDeclSDType = null; + private TokenScript tokenScript; + private TokenStmtBlock currentStmtBlock = null; + + /** + * @brief the constructor does all the processing. + * @param token = first token of script after the TokenBegin token + * @returns tokenScript = null: there were errors + * else: successful + */ + private ScriptReduce(TokenBegin tokenBegin) + { + // Create a place to put the top-level script components, + // eg, state bodies, functions, global variables. + tokenScript = new TokenScript(tokenBegin.nextToken); + + // 'class', 'delegate', 'instance' all define types. + // So we pre-scan the source tokens for those keywords + // to build a script-defined type table and substitute + // type tokens for those names in the source. This is + // done as a separate scan so they can cross-reference + // each other. Also does likewise for fixed array types. + // + // Also, all 'typedef's are processed here. Their definitions + // remain in the source token stream after this, but they can + // be skipped over, because their bodies have been substituted + // in the source for any references. + ParseSDTypePreScanPassOne(tokenBegin); // catalog definitions + ParseSDTypePreScanPassTwo(tokenBegin); // substitute references + + /* + int braces = 0; + Token prevTok = null; + for (Token token = tokenBegin; token != null; token = token.nextToken) { + if (token is TokenKwParClose) braces -= 2; + if (token is TokenKwBrcClose) braces -= 4; + StringBuilder sb = new StringBuilder ("ScriptReduce*: "); + sb.Append (token.GetHashCode ().ToString ("X8")); + sb.Append (" "); + sb.Append (token.line.ToString ().PadLeft (3)); + sb.Append ("."); + sb.Append (token.posn.ToString ().PadLeft (3)); + sb.Append (" "); + sb.Append (token.GetType ().Name.PadRight (24)); + sb.Append (" : "); + for (int i = 0; i < braces; i ++) sb.Append (' '); + token.DebString (sb); + Console.WriteLine (sb.ToString ()); + if (token.prevToken != prevTok) { + Console.WriteLine ("ScriptReduce*: -- prevToken link bad => " + token.prevToken.GetHashCode ().ToString ("X8")); + } + if (token is TokenKwBrcOpen) braces += 4; + if (token is TokenKwParOpen) braces += 2; + prevTok = token; + } + */ + + // Create a function $globalvarinit to hold all explicit + // global variable initializations. + TokenDeclVar gviFunc = new TokenDeclVar(tokenBegin, null, tokenScript); + gviFunc.name = new TokenName(gviFunc, "$globalvarinit"); + gviFunc.retType = new TokenTypeVoid(gviFunc); + gviFunc.argDecl = new TokenArgDecl(gviFunc); + TokenStmtBlock gviBody = new TokenStmtBlock(gviFunc); + gviBody.function = gviFunc; + gviFunc.body = gviBody; + tokenScript.globalVarInit = gviFunc; + tokenScript.AddVarEntry(gviFunc); + + // Scan through the tokens until we reach the end. + for(Token token = tokenBegin.nextToken; !(token is TokenEnd);) + { + if(token is TokenKwSemi) + { + token = token.nextToken; + continue; + } + + // Script-defined type declarations. + if(ParseDeclSDTypes(ref token, null, SDT_PUBLIC)) + continue; + + // constant = ; + if(token is TokenKwConst) + { + ParseDeclVar(ref token, null); + continue; + } + + // ; + // = ; + if((token is TokenType) && + (token.nextToken is TokenName) && + ((token.nextToken.nextToken is TokenKwSemi) || + (token.nextToken.nextToken is TokenKwAssign))) + { + TokenDeclVar var = ParseDeclVar(ref token, gviFunc); + if(var != null) + { + // = ; + TokenLValName left = new TokenLValName(var.name, tokenScript.variablesStack); + DoVarInit(gviFunc, left, var.init); + } + continue; + } + + // { [ get { } ] [ set { } ] } + if((token is TokenType) && + (token.nextToken is TokenName) && + (token.nextToken.nextToken is TokenKwBrcOpen)) + { + ParseProperty(ref token, false, true); + continue; + } + + // + // global function returning specified type + if(token is TokenType) + { + TokenType tokenType = (TokenType)token; + + token = token.nextToken; + if(!(token is TokenName)) + { + ErrorMsg(token, "expecting variable/function name"); + token = SkipPastSemi(token); + continue; + } + TokenName tokenName = (TokenName)token; + token = token.nextToken; + if(!(token is TokenKwParOpen)) + { + ErrorMsg(token, " must be followed by ; = or ("); + token = SkipPastSemi(token); + continue; + } + token = tokenType; + TokenDeclVar tokenDeclFunc = ParseDeclFunc(ref token, false, false, false); + if(tokenDeclFunc == null) + continue; + if(!tokenScript.AddVarEntry(tokenDeclFunc)) + { + ErrorMsg(tokenName, "duplicate function " + tokenDeclFunc.funcNameSig.val); + } + continue; + } + + // + // global function returning void + if(token is TokenName) + { + TokenName tokenName = (TokenName)token; + token = token.nextToken; + if(!(token is TokenKwParOpen)) + { + ErrorMsg(token, "looking for open paren after assuming " + + tokenName.val + " is a function name"); + token = SkipPastSemi(token); + continue; + } + token = tokenName; + TokenDeclVar tokenDeclFunc = ParseDeclFunc(ref token, false, false, false); + if(tokenDeclFunc == null) + continue; + if(!tokenScript.AddVarEntry(tokenDeclFunc)) + ErrorMsg(tokenName, "duplicate function " + tokenDeclFunc.funcNameSig.val); + + continue; + } + + // default + if(token is TokenKwDefault) + { + TokenDeclState tokenDeclState = new TokenDeclState(token); + token = token.nextToken; + tokenDeclState.body = ParseStateBody(ref token); + if(tokenDeclState.body == null) + continue; + if(tokenScript.defaultState != null) + { + ErrorMsg(tokenDeclState, "default state already declared"); + continue; + } + tokenScript.defaultState = tokenDeclState; + continue; + } + + // state + if(token is TokenKwState) + { + TokenDeclState tokenDeclState = new TokenDeclState(token); + token = token.nextToken; + if(!(token is TokenName)) + { + ErrorMsg(token, "state must be followed by state name"); + token = SkipPastSemi(token); + continue; + } + tokenDeclState.name = (TokenName)token; + token = token.nextToken; + tokenDeclState.body = ParseStateBody(ref token); + if(tokenDeclState.body == null) + continue; + if(tokenScript.states.ContainsKey(tokenDeclState.name.val)) + { + ErrorMsg(tokenDeclState.name, "duplicate state definition"); + continue; + } + tokenScript.states.Add(tokenDeclState.name.val, tokenDeclState); + continue; + } + + // Doesn't fit any of those forms, output message and skip to next statement. + ErrorMsg(token, "looking for var name, type, state or default, script-defined type declaration"); + token = SkipPastSemi(token); + continue; + } + + // Must have a default state to start in. + if(!errors && (tokenScript.defaultState == null)) + { + ErrorMsg(tokenScript, "no default state defined"); + } + + // If any error messages were written out, set return value to null. + if(errors) + tokenScript = null; + } + + /** + * @brief Pre-scan the source for class, delegate, interface, typedef definition keywords. + * Clump the keywords and name being defined together, but leave the body intact. + * In the case of a delegate with an explicit return type, it reverses the name and return type. + * After this completes there shouldn't be any TokenKw{Class,Delegate,Interface,Typedef} + * keywords in the source, they are all replaced by TokenDeclSDType{Class,Delegate,Interface, + * Typedef} tokens which also encapsulate the name of the type being defined and any generic + * parameter names. The body remains intact in the source token stream following the + * TokenDeclSDType* token. + */ + private void ParseSDTypePreScanPassOne(Token tokenBegin) + { + Stack braceLevels = new Stack(); + Stack outerLevels = new Stack(); + int openBraceLevel = 0; + braceLevels.Push(-1); + outerLevels.Push(null); + + for(Token t = tokenBegin; !((t = t.nextToken) is TokenEnd);) + { + // Keep track of nested definitions so we can link them up. + // We also need to detect the end of class and interface definitions. + if(t is TokenKwBrcOpen) + { + openBraceLevel++; + continue; + } + if(t is TokenKwBrcClose) + { + if(--openBraceLevel < 0) + { + ErrorMsg(t, "{ } mismatch"); + return; + } + if(braceLevels.Peek() == openBraceLevel) + { + braceLevels.Pop(); + outerLevels.Pop().endToken = t; + } + continue; + } + + // Check for 'class' or 'interface'. + // They always define a new class or interface. + // They can contain nested script-defined type definitions. + if((t is TokenKwClass) || (t is TokenKwInterface)) + { + Token kw = t; + t = t.nextToken; + if(!(t is TokenName)) + { + ErrorMsg(t, "expecting class or interface name"); + t = SkipPastSemi(t).prevToken; + continue; + } + TokenName name = (TokenName)t; + t = t.nextToken; + + // Malloc the script-defined type object. + TokenDeclSDType decl; + if(kw is TokenKwClass) + decl = new TokenDeclSDTypeClass(name, kw.prevToken is TokenKwPartial); + else + decl = new TokenDeclSDTypeInterface(name); + decl.outerSDType = outerLevels.Peek(); + + // Check for generic parameter list. + if(!ParseGenProtoParamList(ref t, decl)) + continue; + + // Splice in a TokenDeclSDType token that replaces the keyword and the name tokens + // and any generic parameters including the '<', ','s and '>'. + // kw = points to 'class' or 'interface' keyword. + // t = points to just past last part of class name parsed, hopefully a ':' or '{'. + decl.prevToken = decl.isPartial ? kw.prevToken.prevToken : kw.prevToken; + decl.nextToken = t; + decl.prevToken.nextToken = decl; + decl.nextToken.prevToken = decl; + + // Enter it in name lists so it can be seen by others. + Token partialNewBody = CatalogSDTypeDecl(decl); + + // Start inner type definitions. + braceLevels.Push(openBraceLevel); + outerLevels.Push(decl); + + // Scan the body starting on for before the '{'. + // + // If this body had an old partial merged into it, + // resume scanning at the beginning of the new body, + // ie, what used to be the first token after the '{' + // before the old body was spliced in. + if(partialNewBody != null) + { + // We have a partial that has had old partial body merged + // into new partial body. So resume scanning at the beginning + // of the new partial body so we don't get any duplicate scanning + // of the old partial body. + // + // ... { } + // ^- resume scanning here + // but inc openBraceLevel because + // we skipped scanning the '{' + openBraceLevel++; + t = partialNewBody; + } + t = t.prevToken; + continue; + } + + // Check for 'delegate'. + // It always defines a new delegate. + // Delegates never define nested types. + if(t is TokenKwDelegate) + { + Token kw = t; + t = t.nextToken; + + // Next thing might be an explicit return type or the delegate's name. + // If it's a type token, then it's the return type, simple enough. + // But if it's a name token, it might be the name of some other script-defined type. + // The way to tell is that the delegate name is followed by a '(', whereas an + // explicit return type is followed by the delegate name. + Token retType = t; + TokenName delName = null; + Token u; + int angles = 0; + for(u = t; !(u is TokenKwParOpen); u = u.nextToken) + { + if((u is TokenKwSemi) || (u is TokenEnd)) + break; + if(u is TokenKwCmpLT) + angles++; + if(u is TokenKwCmpGT) + angles--; + if(u is TokenKwRSh) + angles -= 2; // idiot >> + if((angles == 0) && (u is TokenName)) + delName = (TokenName)u; + } + if(!(u is TokenKwParOpen)) + { + ErrorMsg(u, "expecting ( for delegate parameter list"); + t = SkipPastSemi(t).prevToken; + continue; + } + if(delName == null) + { + ErrorMsg(u, "expecting delegate name"); + t = SkipPastSemi(t).prevToken; + continue; + } + if(retType == delName) + retType = null; + + // Malloc the script-defined type object. + TokenDeclSDTypeDelegate decl = new TokenDeclSDTypeDelegate(delName); + decl.outerSDType = outerLevels.Peek(); + + // Check for generic parameter list. + t = delName.nextToken; + if(!ParseGenProtoParamList(ref t, decl)) + continue; + + // Enter it in name lists so it can be seen by others. + CatalogSDTypeDecl(decl); + + // Splice in the token that replaces the 'delegate' keyword and the whole name + // (including the '<' name ... '>' parts). The return type token(s), if any, + // follow the splice token and come before the '('. + decl.prevToken = kw.prevToken; + kw.prevToken.nextToken = decl; + + if(retType == null) + { + decl.nextToken = t; + t.prevToken = decl; + } + else + { + decl.nextToken = retType; + retType.prevToken = decl; + retType.nextToken = t; + t.prevToken = retType; + } + + // Scan for terminating ';'. + // There cannot be an intervening class, delegate, interfate, typedef, { or }. + for(t = decl; !(t is TokenKwSemi); t = u) + { + u = t.nextToken; + if((u is TokenEnd) || + (u is TokenKwClass) || + (u is TokenKwDelegate) || + (u is TokenKwInterface) || + (u is TokenKwTypedef) || + (u is TokenKwBrcOpen) || + (u is TokenKwBrcClose)) + { + ErrorMsg(t, "delegate missing terminating ;"); + break; + } + } + decl.endToken = t; + continue; + } + + // Check for 'typedef'. + // It always defines a new macro. + // Typedefs never define nested types. + if(t is TokenKwTypedef) + { + Token kw = t; + t = t.nextToken; + + if(!(t is TokenName)) + { + ErrorMsg(t, "expecting typedef name"); + t = SkipPastSemi(t).prevToken; + continue; + } + TokenName tdName = (TokenName)t; + t = t.nextToken; + + // Malloc the script-defined type object. + TokenDeclSDTypeTypedef decl = new TokenDeclSDTypeTypedef(tdName); + decl.outerSDType = outerLevels.Peek(); + + // Check for generic parameter list. + if(!ParseGenProtoParamList(ref t, decl)) + continue; + + // Enter it in name lists so it can be seen by others. + CatalogSDTypeDecl(decl); + numTypedefs++; + + // Splice in the token that replaces the 'typedef' keyword and the whole name + // (including the '<' name ... '>' parts). + decl.prevToken = kw.prevToken; + kw.prevToken.nextToken = decl; + decl.nextToken = t; + t.prevToken = decl; + + // Scan for terminating ';'. + // There cannot be an intervening class, delegate, interfate, typedef, { or }. + Token u; + for(t = decl; !(t is TokenKwSemi); t = u) + { + u = t.nextToken; + if((u is TokenEnd) || + (u is TokenKwClass) || + (u is TokenKwDelegate) || + (u is TokenKwInterface) || + (u is TokenKwTypedef) || + (u is TokenKwBrcOpen) || + (u is TokenKwBrcClose)) + { + ErrorMsg(t, "typedef missing terminating ;"); + break; + } + } + decl.endToken = t; + continue; + } + } + } + + /** + * @brief Parse a possibly generic type definition's parameter list. + * @param t = points to the possible opening '<' on entry + * points just past the closing '>' on return + * @param decl = the generic type being declared + * @returns false: parse error + * true: decl.genParams = filled in with parameter list + * decl.innerSDTypes = filled in with parameter list + */ + private bool ParseGenProtoParamList(ref Token t, TokenDeclSDType decl) + { + // Maybe there aren't any generic parameters. + // If so, leave decl.genParams = null. + if(!(t is TokenKwCmpLT)) + return true; + + // Build list of generic parameter names. + Dictionary parms = new Dictionary(); + do + { + t = t.nextToken; + if(!(t is TokenName)) + { + ErrorMsg(t, "expecting generic parameter name"); + break; + } + TokenName tn = (TokenName)t; + if(parms.ContainsKey(tn.val)) + ErrorMsg(tn, "duplicate use of generic parameter name"); + else + parms.Add(tn.val, parms.Count); + t = t.nextToken; + } while(t is TokenKwComma); + + if(!(t is TokenKwCmpGT)) + { + ErrorMsg(t, "expecting , for more params or > to end param list"); + return false; + } + t = t.nextToken; + decl.genParams = parms; + + return true; + } + + /** + * @brief Catalog a script-defined type. + * Its short name (eg, 'Node') gets put in the next outer level (eg, 'List')'s inner type definition table. + * Its long name (eg, 'List.Node') gets put in the global type definition table. + */ + public Token CatalogSDTypeDecl(TokenDeclSDType decl) + { + string longName = decl.longName.val; + TokenDeclSDType dupDecl; + if(!tokenScript.sdSrcTypesTryGetValue(longName, out dupDecl)) + { + tokenScript.sdSrcTypesAdd(longName, decl); + if(decl.outerSDType != null) + decl.outerSDType.innerSDTypes.Add(decl.shortName.val, decl); + + return null; + } + + if(!dupDecl.isPartial || !decl.isPartial) + { + ErrorMsg(decl, "duplicate definition of type " + longName); + ErrorMsg(dupDecl, "previous definition here"); + return null; + } + + if(!GenericParametersMatch(decl, dupDecl)) + ErrorMsg(decl, "all partial class generic parameters must match"); + + // Have new declaration be the cataloged one because body is going to get + // snipped out of old declaration and pasted into new declaration. + tokenScript.sdSrcTypesRep(longName, decl); + if(decl.outerSDType != null) + decl.outerSDType.innerSDTypes[decl.shortName.val] = decl; + + // Find old partial definition's opening brace. + Token dupBrcOpen; + for(dupBrcOpen = dupDecl; !(dupBrcOpen is TokenKwBrcOpen); dupBrcOpen = dupBrcOpen.nextToken) + { + if(dupBrcOpen == dupDecl.endToken) + { + ErrorMsg(dupDecl, "missing {"); + return null; + } + } + + // Find new partial definition's opening brace. + Token brcOpen; + for(brcOpen = decl; !(brcOpen is TokenKwBrcOpen); brcOpen = brcOpen.nextToken) + { + if(brcOpen is TokenEnd) + { + ErrorMsg(decl, "missing {"); + return null; + } + } + Token body = brcOpen.nextToken; + + // Stick old partial definition's extends/implementeds list just + // in front of new partial definition's extends/implementeds list. + // + // class oldextimp { oldbody } ... + // dupDecl dupBrcOpen dupDecl.endToken + // + // class newextimp { newbody } ... + // decl brcOpen body decl.endToken + // + // becomes + // + // class ... + // dupDecl + // dupDecl.endToken + // + // class oldextimp newextimp { oldbody newbody } ... + // decl brcOpen body decl.endToken + if(dupBrcOpen != dupDecl.nextToken) + { + dupBrcOpen.prevToken.nextToken = decl.nextToken; + dupDecl.nextToken.prevToken = decl; + decl.nextToken.prevToken = dupBrcOpen.prevToken; + decl.nextToken = dupDecl.nextToken; + } + + // Stick old partial definition's body just + // in front of new partial definition's body. + if(dupBrcOpen.nextToken != dupDecl.endToken) + { + dupBrcOpen.nextToken.prevToken = brcOpen; + dupDecl.endToken.prevToken.nextToken = body; + body.prevToken = dupDecl.endToken.prevToken; + brcOpen.nextToken = dupBrcOpen.nextToken; + } + + // Null out old definition's extends/implementeds list and body + // by having the declaration token be the only thing left. + dupDecl.nextToken = dupDecl.endToken.nextToken; + dupDecl.nextToken.prevToken = dupDecl; + dupDecl.endToken = dupDecl; + + return body; + } + + /** + * @brief Determine whether or not the generic parameters of two class declarations match exactly. + */ + private static bool GenericParametersMatch(TokenDeclSDType c1, TokenDeclSDType c2) + { + if((c1.genParams == null) && (c2.genParams == null)) + return true; + if((c1.genParams == null) || (c2.genParams == null)) + return false; + Dictionary gp1 = c1.genParams; + Dictionary gp2 = c2.genParams; + if(gp1.Count != gp2.Count) + return false; + foreach(KeyValuePair kvp1 in gp1) + { + int v2; + if(!gp2.TryGetValue(kvp1.Key, out v2)) + return false; + if(v2 != kvp1.Value) + return false; + } + return true; + } + + /** + * @brief Replace all TokenName tokens that refer to the script-defined types with + * corresponding TokenTypeSDType{Class,Delegate,GenParam,Interface} tokens. + * Also handle generic references, ie, recognize that 'List' is an + * instantiation of 'List<>' and instantiate the generic. + */ + private const uint REPEAT_NOTYPE = 1; + private const uint REPEAT_INSTGEN = 2; + private const uint REPEAT_SUBST = 4; + + private void ParseSDTypePreScanPassTwo(Token tokenBegin) + { + List noTypes = new List(); + TokenDeclSDType outerSDType; + uint repeat; + + do + { + repeat = 0; + outerSDType = null; + noTypes.Clear(); + + for(Token t = tokenBegin; !((t = t.nextToken) is TokenEnd);) + { + // Maybe it's time to pop out of an outer class definition. + if((outerSDType != null) && (outerSDType.endToken == t)) + { + outerSDType = outerSDType.outerSDType; + continue; + } + + // Skip completely over any script-defined generic prototypes. + // We only need to process their instantiations which are non- + // generic versions of the generics. + if((t is TokenDeclSDType) && (((TokenDeclSDType)t).genParams != null)) + { + t = ((TokenDeclSDType)t).endToken; + continue; + } + + // Check for beginning of non-generic script-defined type definitions. + // They can have nested definitions in their innerSDTypes[] that match + // name tokens, so add them to the stack. + // + // But just ignore any preliminary partial definitions as they have had + // their entire contents spliced out and spliced into a subsequent partial + // definition. So if we originally had: + // partial class Abc { public intenger one; } + // partial class Abc { public intenger two; } + // We now have: + // partial_class_Abc <== if we are here, just ignore the partial_class_Abc token + // partial_class_Abc { public intenger one; public intenger two; } + if(t is TokenDeclSDType) + { + if(((TokenDeclSDType)t).endToken != t) + outerSDType = (TokenDeclSDType)t; + + continue; + } + + // For names not preceded by a '.', scan the script-defined type definition + // stack for that name. Splice the name out and replace with equivalent token. + if((t is TokenName) && !(t.prevToken is TokenKwDot)) + t = TrySpliceTypeRef(t, outerSDType, ref repeat, noTypes); + + // This handles types such as integer[,][], List[], etc. + // They are an instantiation of an internally generated type of the same name, brackets and all. + // Note that to malloc an array, use something like 'new float[,][](3,5)', not 'new float[3,5][]'. + // + // Note that we must not get confused by $idxprop property declarations such as: + // float [string kee] { get { ... } } + // ... and try to convert 'float' '[' to an array type. + if((t is TokenType) && (t.nextToken is TokenKwBrkOpen)) + { + if((t.nextToken.nextToken is TokenKwBrkClose) || + (t.nextToken.nextToken is TokenKwComma)) + { + t = InstantiateJaggedArray(t, tokenBegin, ref repeat); + } + } + } + + // If we instantiated a generic, loop back to process its contents + // just as if the source code had the instantiated code to begin with. + // Also repeat if we found a non-type inside the <> of a generic reference + // provided we have made at least one name->type substitution. + } while(((repeat & REPEAT_INSTGEN) != 0) || + ((repeat & (REPEAT_NOTYPE | REPEAT_SUBST)) == (REPEAT_NOTYPE | REPEAT_SUBST))); + + // These are places where we required a type be present, + // eg, a generic type argument or the body of a typedef. + foreach(Token t in noTypes) + ErrorMsg(t, "looking for type"); + } + + /** + * @brief Try to convert the source token string to a type reference + * and splice the type reference into the source token string + * replacing the original token(s). + * @param t = points to the initial TokenName token + * @param outerSDType = null: this is a top-level code reference + * else: this code is within outerSDType + * @returns pointer to last token parsed + * possibly with spliced-in type token + * repeat = possibly set true if need to do another pass + */ + private Token TrySpliceTypeRef(Token t, TokenDeclSDType outerSDType, ref uint repeat, List noTypes) + { + Token start = t; + string tnamestr = ((TokenName)t).val; + + // Look for the name as a type declared by outerSDType or anything + // even farther out than that. If not found, simply return + // without updating t, meaning that t isn't the name of a type. + TokenDeclSDType decl = null; + while(outerSDType != null) + { + if(outerSDType.innerSDTypes.TryGetValue(tnamestr, out decl)) + break; + outerSDType = outerSDType.outerSDType; + } + if((outerSDType == null) && !tokenScript.sdSrcTypesTryGetValue(tnamestr, out decl)) + return t; + + TokenDeclSDType instdecl; + while(true) + { + // If it is a generic type, it must be followed by instantiation arguments. + instdecl = decl; + if(decl.genParams != null) + { + t = t.nextToken; + if(!(t is TokenKwCmpLT)) + { + ErrorMsg(t, "expecting < for generic argument list"); + return t; + } + tnamestr += "<"; + int nArgs = decl.genParams.Count; + TokenType[] genArgs = new TokenType[nArgs]; + for(int i = 0; i < nArgs;) + { + t = t.nextToken; + if(!(t is TokenType)) + { + repeat |= REPEAT_NOTYPE; + noTypes.Add(t); + return t.prevToken; // make sure name gets processed + // so substitution can occur on it + } + TokenType ga = (TokenType)t; + genArgs[i] = ga; + tnamestr += ga.ToString(); + t = t.nextToken; + if(++i < nArgs) + { + if(!(t is TokenKwComma)) + { + ErrorMsg(t, "expecting , for more generic arguments"); + return t; + } + tnamestr += ","; + } + } + if(t is TokenKwRSh) + { // idiot >> + Token u = new TokenKwCmpGT(t); + Token v = new TokenKwCmpGT(t); + v.posn++; + u.prevToken = t.prevToken; + u.nextToken = v; + v.nextToken = t.nextToken; + v.prevToken = u; + u.prevToken.nextToken = u; + v.nextToken.prevToken = v; + t = u; + } + if(!(t is TokenKwCmpGT)) + { + ErrorMsg(t, "expecting > at end of generic argument list"); + return t; + } + tnamestr += ">"; + if(outerSDType != null) + { + outerSDType.innerSDTypes.TryGetValue(tnamestr, out instdecl); + } + else + { + tokenScript.sdSrcTypesTryGetValue(tnamestr, out instdecl); + } + + // Couldn't find 'List' but found 'List' and we have genArgs = 'string'. + // Instantiate the generic to create 'List'. This splices the definition + // of 'List' into the source token stream just as if it had been there all + // along. We have to then repeat the scan to process the instance's contents. + if(instdecl == null) + { + instdecl = decl.InstantiateGeneric(tnamestr, genArgs, this); + CatalogSDTypeDecl(instdecl); + repeat |= REPEAT_INSTGEN; + } + } + + // Maybe caller wants a subtype by putting a '.' following all that. + if(!(t.nextToken is TokenKwDot)) + break; + if(!(t.nextToken.nextToken is TokenName)) + break; + tnamestr = ((TokenName)t.nextToken.nextToken).val; + if(!instdecl.innerSDTypes.TryGetValue(tnamestr, out decl)) + break; + t = t.nextToken.nextToken; + outerSDType = instdecl; + } + + // Create a reference in the source to the definition + // that encapsulates the long dotted type name given in + // the source, and replace the long dotted type name in + // the source with the reference token, eg, replace + // 'Dictionary' '<' 'string' ',' 'integer' '>' '.' 'ValueList' + // with 'Dictionary.ValueList'. + TokenType refer = instdecl.MakeRefToken(start); + if(refer == null) + { + // typedef body is not yet a type + noTypes.Add(start); + repeat |= REPEAT_NOTYPE; + return start; + } + refer.prevToken = start.prevToken; // start points right at the first TokenName + refer.nextToken = t.nextToken; // t points at the last TokenName or TokenKwCmpGT + refer.prevToken.nextToken = refer; + refer.nextToken.prevToken = refer; + repeat |= REPEAT_SUBST; + + return refer; + } + + /** + * @brief We are known to have '[' so make an equivalent array type. + * @param t = points to the TokenType + * @param tokenBegin = where we can safely splice in new array class definitions + * @param repeat = set REPEAT_INSTGEN if new type created + * @returns pointer to last token parsed + * possibly with spliced-in type token + * repeat = possibly set true if need to do another pass + */ + private Token InstantiateJaggedArray(Token t, Token tokenBegin, ref uint repeat) + { + Token start = t; + TokenType ofType = (TokenType)t; + + Stack ranks = new Stack(); + + // When script specifies 'float[,][]' it means a two-dimensional matrix + // that points to one-dimensional vectors of floats. So we would push + // a 2 then a 1 in this parsing code... + do + { + t = t.nextToken; // point at '[' + int rank = 0; + do + { + rank++; // count '[' and ','s + t = t.nextToken; // point at ',' or ']' + } while(t is TokenKwComma); + if(!(t is TokenKwBrkClose)) + { + ErrorMsg(t, "expecting only [ , or ] for array type specification"); + return t; + } + ranks.Push(rank); + } while(t.nextToken is TokenKwBrkOpen); + + // Now we build the types in reverse order. For the example above we will: + // first, create a type that is a one-dimensional vector of floats, float[] + // second, create a type that is a two-dimensional matrix of that. + // This keeps declaration and referencing similar, eg, + // float[,][] jag = new float[,][] (3,4); + // jag[i,j][k] ... is used to access the elements + do + { + int rank = ranks.Pop(); + TokenDeclSDType decl = InstantiateFixedArray(rank, ofType, tokenBegin, ref repeat); + ofType = decl.MakeRefToken(ofType); + } while(ranks.Count > 0); + + // Finally splice in the resultant array type to replace the original tokens. + ofType.prevToken = start.prevToken; + ofType.nextToken = t.nextToken; + ofType.prevToken.nextToken = ofType; + ofType.nextToken.prevToken = ofType; + + // Resume parsing just after the spliced-in array type token. + return ofType; + } + + /** + * @brief Instantiate a script-defined class type to handle fixed-dimension arrays. + * @param rank = number of dimensions for the array + * @param ofType = type of each element of the array + * @returns script-defined class declaration created to handle the array + */ + private TokenDeclSDType InstantiateFixedArray(int rank, TokenType ofType, Token tokenBegin, ref uint repeat) + { + // Create the array type's name. + // If starting with a non-array type, just append the rank to it, eg, float + rank=1 -> float[] + // If starting with an array type, slip this rank in front of existing array, eg, float[] + rank=2 -> float[,][]. + // This makes it consistent with what the script-writer sees for both a type specification and when + // referencing elements in a jagged array. + string name = ofType.ToString(); + StringBuilder sb = new StringBuilder(name); + int ix = name.IndexOf('['); + if(ix < 0) + ix = name.Length; + sb.Insert(ix++, '['); + for(int i = 0; ++i < rank;) + { + sb.Insert(ix++, ','); + } + sb.Insert(ix, ']'); + name = sb.ToString(); + + TokenDeclSDType fa; + if(!tokenScript.sdSrcTypesTryGetValue(name, out fa)) + { + char suffix = 'O'; + if(ofType is TokenTypeChar) + suffix = 'C'; + if(ofType is TokenTypeFloat) + suffix = 'F'; + if(ofType is TokenTypeInt) + suffix = 'I'; + + // Don't already have one, create a new skeleton struct. + // Splice in a definition for the class at beginning of source file. + // + // class { + fa = new TokenDeclSDTypeClass(new TokenName(tokenScript, name), false); + CatalogSDTypeDecl(fa); + repeat |= REPEAT_INSTGEN; + ((TokenDeclSDTypeClass)fa).arrayOfType = ofType; + ((TokenDeclSDTypeClass)fa).arrayOfRank = rank; + + Token t = SpliceAfter(tokenBegin, fa); + t = SpliceAfter(t, new TokenKwBrcOpen(t)); + + // public integer len0; + // public integer len1; + // ... + // public object obj; + for(int i = 0; i < rank; i++) + { + t = SpliceAfter(t, new TokenKwPublic(t)); + t = SpliceAfter(t, new TokenTypeInt(t)); + t = SpliceAfter(t, new TokenName(t, "len" + i)); + t = SpliceAfter(t, new TokenKwSemi(t)); + } + + t = SpliceAfter(t, new TokenKwPublic(t)); + t = SpliceAfter(t, new TokenTypeObject(t)); + t = SpliceAfter(t, new TokenName(t, "obj")); + t = SpliceAfter(t, new TokenKwSemi(t)); + + // public constructor (integer len0, integer len1, ...) { + // this.len0 = len0; + // this.len1 = len1; + // ... + // this.obj = xmrFixedArrayAlloc (len0 * len1 * ...); + // } + t = SpliceAfter(t, new TokenKwPublic(t)); + t = SpliceAfter(t, new TokenKwConstructor(t)); + t = SpliceAfter(t, new TokenKwParOpen(t)); + for(int i = 0; i < rank; i++) + { + if(i > 0) + t = SpliceAfter(t, new TokenKwComma(t)); + t = SpliceAfter(t, new TokenTypeInt(t)); + t = SpliceAfter(t, new TokenName(t, "len" + i)); + } + t = SpliceAfter(t, new TokenKwParClose(t)); + t = SpliceAfter(t, new TokenKwBrcOpen(t)); + + for(int i = 0; i < rank; i++) + { + t = SpliceAfter(t, new TokenKwThis(t)); + t = SpliceAfter(t, new TokenKwDot(t)); + t = SpliceAfter(t, new TokenName(t, "len" + i)); + t = SpliceAfter(t, new TokenKwAssign(t)); + t = SpliceAfter(t, new TokenName(t, "len" + i)); + t = SpliceAfter(t, new TokenKwSemi(t)); + } + + t = SpliceAfter(t, new TokenKwThis(t)); + t = SpliceAfter(t, new TokenKwDot(t)); + t = SpliceAfter(t, new TokenName(t, "obj")); + t = SpliceAfter(t, new TokenKwAssign(t)); + t = SpliceAfter(t, new TokenName(t, "xmrFixedArrayAlloc" + suffix)); + t = SpliceAfter(t, new TokenKwParOpen(t)); + for(int i = 0; i < rank; i++) + { + if(i > 0) + t = SpliceAfter(t, new TokenKwMul(t)); + t = SpliceAfter(t, new TokenName(t, "len" + i)); + } + t = SpliceAfter(t, new TokenKwParClose(t)); + t = SpliceAfter(t, new TokenKwSemi(t)); + t = SpliceAfter(t, new TokenKwBrcClose(t)); + + // public integer Length { get { + // return this.len0 * this.len1 * ... ; + // } } + t = SpliceAfter(t, new TokenKwPublic(t)); + t = SpliceAfter(t, new TokenTypeInt(t)); + t = SpliceAfter(t, new TokenName(t, "Length")); + t = SpliceAfter(t, new TokenKwBrcOpen(t)); + t = SpliceAfter(t, new TokenKwGet(t)); + t = SpliceAfter(t, new TokenKwBrcOpen(t)); + + t = SpliceAfter(t, new TokenKwRet(t)); + for(int i = 0; i < rank; i++) + { + if(i > 0) + t = SpliceAfter(t, new TokenKwMul(t)); + t = SpliceAfter(t, new TokenKwThis(t)); + t = SpliceAfter(t, new TokenKwDot(t)); + t = SpliceAfter(t, new TokenName(t, "len" + i)); + } + t = SpliceAfter(t, new TokenKwSemi(t)); + + t = SpliceAfter(t, new TokenKwBrcClose(t)); + t = SpliceAfter(t, new TokenKwBrcClose(t)); + + // public integer Length (integer dim) { + // switch (dim) { + // case 0: return this.len0; + // case 1: return this.len1; + // ... + // } + // return 0; + // } + t = SpliceAfter(t, new TokenKwPublic(t)); + t = SpliceAfter(t, new TokenTypeInt(t)); + t = SpliceAfter(t, new TokenName(t, "Length")); + t = SpliceAfter(t, new TokenKwParOpen(t)); + t = SpliceAfter(t, new TokenTypeInt(t)); + t = SpliceAfter(t, new TokenName(t, "dim")); + t = SpliceAfter(t, new TokenKwParClose(t)); + t = SpliceAfter(t, new TokenKwBrcOpen(t)); + + t = SpliceAfter(t, new TokenKwSwitch(t)); + t = SpliceAfter(t, new TokenKwParOpen(t)); + t = SpliceAfter(t, new TokenName(t, "dim")); + t = SpliceAfter(t, new TokenKwParClose(t)); + t = SpliceAfter(t, new TokenKwBrcOpen(t)); + + for(int i = 0; i < rank; i++) + { + t = SpliceAfter(t, new TokenKwCase(t)); + t = SpliceAfter(t, new TokenInt(t, i)); + t = SpliceAfter(t, new TokenKwColon(t)); + t = SpliceAfter(t, new TokenKwRet(t)); + t = SpliceAfter(t, new TokenKwThis(t)); + t = SpliceAfter(t, new TokenKwDot(t)); + t = SpliceAfter(t, new TokenName(t, "len" + i)); + t = SpliceAfter(t, new TokenKwSemi(t)); + } + t = SpliceAfter(t, new TokenKwBrcClose(t)); + + t = SpliceAfter(t, new TokenKwRet(t)); + t = SpliceAfter(t, new TokenInt(t, 0)); + t = SpliceAfter(t, new TokenKwSemi(t)); + t = SpliceAfter(t, new TokenKwBrcClose(t)); + + // public integer Index (integer idx0, integet idx1, ...) { + // integer idx = idx0; + // idx *= this.len1; idx += idx1; + // idx *= this.len2; idx += idx2; + // ... + // return idx; + // } + t = SpliceAfter(t, new TokenKwPublic(t)); + t = SpliceAfter(t, new TokenTypeInt(t)); + t = SpliceAfter(t, new TokenName(t, "Index")); + t = SpliceAfter(t, new TokenKwParOpen(t)); + for(int i = 0; i < rank; i++) + { + if(i > 0) + t = SpliceAfter(t, new TokenKwComma(t)); + t = SpliceAfter(t, new TokenTypeInt(t)); + t = SpliceAfter(t, new TokenName(t, "idx" + i)); + } + t = SpliceAfter(t, new TokenKwParClose(t)); + t = SpliceAfter(t, new TokenKwBrcOpen(t)); + + t = SpliceAfter(t, new TokenTypeInt(t)); + t = SpliceAfter(t, new TokenName(t, "idx")); + t = SpliceAfter(t, new TokenKwAssign(t)); + t = SpliceAfter(t, new TokenName(t, "idx0")); + t = SpliceAfter(t, new TokenKwSemi(t)); + + for(int i = 1; i < rank; i++) + { + t = SpliceAfter(t, new TokenName(t, "idx")); + t = SpliceAfter(t, new TokenKwAsnMul(t)); + t = SpliceAfter(t, new TokenKwThis(t)); + t = SpliceAfter(t, new TokenKwDot(t)); + t = SpliceAfter(t, new TokenName(t, "len" + i)); + t = SpliceAfter(t, new TokenKwSemi(t)); + t = SpliceAfter(t, new TokenName(t, "idx")); + t = SpliceAfter(t, new TokenKwAsnAdd(t)); + t = SpliceAfter(t, new TokenName(t, "idx" + i)); + t = SpliceAfter(t, new TokenKwSemi(t)); + } + + t = SpliceAfter(t, new TokenKwRet(t)); + t = SpliceAfter(t, new TokenName(t, "idx")); + t = SpliceAfter(t, new TokenKwSemi(t)); + t = SpliceAfter(t, new TokenKwBrcClose(t)); + + // public Get (integer idx0, integet idx1, ...) { + // integer idx = idx0; + // idx *= this.len1; idx += idx1; + // idx *= this.len2; idx += idx2; + // ... + // return () xmrFixedArrayGet (this.obj, idx); + // } + t = SpliceAfter(t, new TokenKwPublic(t)); + t = SpliceAfter(t, ofType.CopyToken(t)); + t = SpliceAfter(t, new TokenName(t, "Get")); + t = SpliceAfter(t, new TokenKwParOpen(t)); + for(int i = 0; i < rank; i++) + { + if(i > 0) + t = SpliceAfter(t, new TokenKwComma(t)); + t = SpliceAfter(t, new TokenTypeInt(t)); + t = SpliceAfter(t, new TokenName(t, "idx" + i)); + } + t = SpliceAfter(t, new TokenKwParClose(t)); + t = SpliceAfter(t, new TokenKwBrcOpen(t)); + + t = SpliceAfter(t, new TokenTypeInt(t)); + t = SpliceAfter(t, new TokenName(t, "idx")); + t = SpliceAfter(t, new TokenKwAssign(t)); + t = SpliceAfter(t, new TokenName(t, "idx0")); + t = SpliceAfter(t, new TokenKwSemi(t)); + + for(int i = 1; i < rank; i++) + { + t = SpliceAfter(t, new TokenName(t, "idx")); + t = SpliceAfter(t, new TokenKwAsnMul(t)); + t = SpliceAfter(t, new TokenKwThis(t)); + t = SpliceAfter(t, new TokenKwDot(t)); + t = SpliceAfter(t, new TokenName(t, "len" + i)); + t = SpliceAfter(t, new TokenKwSemi(t)); + t = SpliceAfter(t, new TokenName(t, "idx")); + t = SpliceAfter(t, new TokenKwAsnAdd(t)); + t = SpliceAfter(t, new TokenName(t, "idx" + i)); + t = SpliceAfter(t, new TokenKwSemi(t)); + } + + t = SpliceAfter(t, new TokenKwRet(t)); + if(suffix == 'O') + { + t = SpliceAfter(t, new TokenKwParOpen(t)); + t = SpliceAfter(t, ofType.CopyToken(t)); + t = SpliceAfter(t, new TokenKwParClose(t)); + } + t = SpliceAfter(t, new TokenName(t, "xmrFixedArrayGet" + suffix)); + t = SpliceAfter(t, new TokenKwParOpen(t)); + t = SpliceAfter(t, new TokenKwThis(t)); + t = SpliceAfter(t, new TokenKwDot(t)); + t = SpliceAfter(t, new TokenName(t, "obj")); + t = SpliceAfter(t, new TokenKwComma(t)); + t = SpliceAfter(t, new TokenName(t, "idx")); + t = SpliceAfter(t, new TokenKwParClose(t)); + t = SpliceAfter(t, new TokenKwSemi(t)); + t = SpliceAfter(t, new TokenKwBrcClose(t)); + + // public void Set (integer idx0, integer idx1, ..., val) { + // integer idx = idx0; + // idx *= this.len1; idx += idx1; + // idx *= this.len2; idx += idx2; + // ... + // xmrFixedArraySet (this.obj, idx, val); + // } + t = SpliceAfter(t, new TokenKwPublic(t)); + t = SpliceAfter(t, new TokenTypeVoid(t)); + t = SpliceAfter(t, new TokenName(t, "Set")); + t = SpliceAfter(t, new TokenKwParOpen(t)); + for(int i = 0; i < rank; i++) + { + t = SpliceAfter(t, new TokenTypeInt(t)); + t = SpliceAfter(t, new TokenName(t, "idx" + i)); + t = SpliceAfter(t, new TokenKwComma(t)); + } + t = SpliceAfter(t, ofType.CopyToken(t)); + t = SpliceAfter(t, new TokenName(t, "val")); + t = SpliceAfter(t, new TokenKwParClose(t)); + t = SpliceAfter(t, new TokenKwBrcOpen(t)); + + t = SpliceAfter(t, new TokenTypeInt(t)); + t = SpliceAfter(t, new TokenName(t, "idx")); + t = SpliceAfter(t, new TokenKwAssign(t)); + t = SpliceAfter(t, new TokenName(t, "idx0")); + t = SpliceAfter(t, new TokenKwSemi(t)); + for(int i = 1; i < rank; i++) + { + t = SpliceAfter(t, new TokenName(t, "idx")); + t = SpliceAfter(t, new TokenKwAsnMul(t)); + t = SpliceAfter(t, new TokenKwThis(t)); + t = SpliceAfter(t, new TokenKwDot(t)); + t = SpliceAfter(t, new TokenName(t, "len" + i)); + t = SpliceAfter(t, new TokenKwSemi(t)); + t = SpliceAfter(t, new TokenName(t, "idx")); + t = SpliceAfter(t, new TokenKwAsnAdd(t)); + t = SpliceAfter(t, new TokenName(t, "idx" + i)); + t = SpliceAfter(t, new TokenKwSemi(t)); + } + + t = SpliceAfter(t, new TokenName(t, "xmrFixedArraySet" + suffix)); + t = SpliceAfter(t, new TokenKwParOpen(t)); + t = SpliceAfter(t, new TokenKwThis(t)); + t = SpliceAfter(t, new TokenKwDot(t)); + t = SpliceAfter(t, new TokenName(t, "obj")); + t = SpliceAfter(t, new TokenKwComma(t)); + t = SpliceAfter(t, new TokenName(t, "idx")); + t = SpliceAfter(t, new TokenKwComma(t)); + t = SpliceAfter(t, new TokenName(t, "val")); + t = SpliceAfter(t, new TokenKwParClose(t)); + t = SpliceAfter(t, new TokenKwSemi(t)); + + t = SpliceAfter(t, new TokenKwBrcClose(t)); + t = SpliceAfter(t, new TokenKwBrcClose(t)); + } + return fa; + } + private Token SpliceAfter(Token before, Token after) + { + after.nextToken = before.nextToken; + after.prevToken = before; + before.nextToken = after; + after.nextToken.prevToken = after; + return after; + } + + /** + * @brief Parse script-defined type declarations. + * @param token = points to possible script-defined type keyword + * @param outerSDType = null: top-level type + * else: sub-type of this type + * @param flags = access level (SDT_{PRIVATE,PROTECTED,PUBLIC}) + * @returns true: something defined; else: not a sd type def + */ + private bool ParseDeclSDTypes(ref Token token, TokenDeclSDType outerSDType, uint flags) + { + if(!(token is TokenDeclSDType)) + return false; + + TokenDeclSDType decl = (TokenDeclSDType)token; + + /* + * If declaration of generic type, skip it. + * The instantiations get parsed (ie, when we know the concrete types) + * below because they appear as non-generic types. + */ + if(decl.genParams != null) + { + token = decl.endToken.nextToken; + return true; + } + + /* + * Also skip over any typedefs. They were all processed in + * ParseSDTypePreScanPassTwo(). + */ + if(decl is TokenDeclSDTypeTypedef) + { + token = decl.endToken.nextToken; + return true; + } + + /* + * Non-generic types get parsed inline because we know all their types. + */ + if(decl is TokenDeclSDTypeClass) + { + ParseDeclClass(ref token, outerSDType, flags); + return true; + } + if(decl is TokenDeclSDTypeDelegate) + { + ParseDeclDelegate(ref token, outerSDType, flags); + return true; + } + if(decl is TokenDeclSDTypeInterface) + { + ParseDeclInterface(ref token, outerSDType, flags); + return true; + } + + throw new Exception("unhandled token " + token.GetType().ToString()); + } + + /** + * @brief Parse a class declaration. + * @param token = points to TokenDeclSDTypeClass token + * points just past closing '}' on return + * @param outerSDType = null: this is a top-level class + * else: this class is being defined inside this type + * @param flags = SDT_{PRIVATE,PROTECTED,PUBLIC} + */ + private void ParseDeclClass(ref Token token, TokenDeclSDType outerSDType, uint flags) + { + bool haveExplicitConstructor = false; + Token u = token; + TokenDeclSDTypeClass tokdeclcl; + + tokdeclcl = (TokenDeclSDTypeClass)u; + tokdeclcl.outerSDType = outerSDType; + tokdeclcl.accessLevel = flags; + u = u.nextToken; + + // maybe it is a partial class that had its body snipped out + // by a later partial class declaration of the same class + if(tokdeclcl.endToken == tokdeclcl) + { + token = u; + return; + } + + // make this class the currently compiled class + // used for retrieving stuff like 'this' possibly + // in field initialization code + TokenDeclSDType saveCurSDType = currentDeclSDType; + currentDeclSDType = tokdeclcl; + + // next can be ':' followed by list of implemented + // interfaces and one extended class + if(u is TokenKwColon) + { + u = u.nextToken; + while(true) + { + if(u is TokenTypeSDTypeClass) + { + TokenDeclSDTypeClass c = ((TokenTypeSDTypeClass)u).decl; + if(tokdeclcl.extends == null) + { + tokdeclcl.extends = c; + } + else if(tokdeclcl.extends != c) + { + ErrorMsg(u, "can extend from only one class"); + } + } + else if(u is TokenTypeSDTypeInterface) + { + TokenDeclSDTypeInterface i = ((TokenTypeSDTypeInterface)u).decl; + i.AddToClassDecl(tokdeclcl); + } + else + { + ErrorMsg(u, "expecting class or interface name"); + if(u is TokenKwBrcOpen) + break; + } + u = u.nextToken; + + // allow : in case it is spliced from multiple partial class definitions + if(!(u is TokenKwComma) && !(u is TokenKwColon)) + break; + u = u.nextToken; + } + } + + // next must be '{' to open class declaration body + if(!(u is TokenKwBrcOpen)) + { + ErrorMsg(u, "expecting { to open class declaration body"); + token = SkipPastSemi(token); + goto ret; + } + token = u.nextToken; + + // push a var frame to put all the class members in + tokdeclcl.members.thisClass = tokdeclcl; + tokenScript.PushVarFrame(tokdeclcl.members); + + // Create a function $instfieldnit to hold all explicit + // instance field initializations. + TokenDeclVar ifiFunc = new TokenDeclVar(tokdeclcl, null, tokenScript); + ifiFunc.name = new TokenName(ifiFunc, "$instfieldinit"); + ifiFunc.retType = new TokenTypeVoid(ifiFunc); + ifiFunc.argDecl = new TokenArgDecl(ifiFunc); + ifiFunc.sdtClass = tokdeclcl; + ifiFunc.sdtFlags = SDT_PUBLIC | SDT_NEW; + TokenStmtBlock ifiBody = new TokenStmtBlock(ifiFunc); + ifiBody.function = ifiFunc; + ifiFunc.body = ifiBody; + tokdeclcl.instFieldInit = ifiFunc; + tokenScript.AddVarEntry(ifiFunc); + + // Create a function $staticfieldnit to hold all explicit + // static field initializations. + TokenDeclVar sfiFunc = new TokenDeclVar(tokdeclcl, null, tokenScript); + sfiFunc.name = new TokenName(sfiFunc, "$staticfieldinit"); + sfiFunc.retType = new TokenTypeVoid(sfiFunc); + sfiFunc.argDecl = new TokenArgDecl(sfiFunc); + sfiFunc.sdtClass = tokdeclcl; + sfiFunc.sdtFlags = SDT_PUBLIC | SDT_STATIC | SDT_NEW; + TokenStmtBlock sfiBody = new TokenStmtBlock(sfiFunc); + sfiBody.function = sfiFunc; + sfiFunc.body = sfiBody; + tokdeclcl.staticFieldInit = sfiFunc; + tokenScript.AddVarEntry(sfiFunc); + + // process declaration statements until '}' + while(!(token is TokenKwBrcClose)) + { + if(token is TokenKwSemi) + { + token = token.nextToken; + continue; + } + + // Check for all qualifiers. + // typedef has an implied 'public' qualifier. + flags = SDT_PUBLIC; + if(!(token is TokenDeclSDTypeTypedef)) + { + flags = ParseQualifierFlags(ref token); + } + + // Parse nested script-defined type definitions. + if(ParseDeclSDTypes(ref token, tokdeclcl, flags)) + continue; + + // constant = ; + if(token is TokenKwConst) + { + if((flags & (SDT_ABSTRACT | SDT_NEW | SDT_OVERRIDE | SDT_VIRTUAL)) != 0) + { + ErrorMsg(token, "cannot have abstract, new, override or virtual field"); + } + TokenDeclVar var = ParseDeclVar(ref token, null); + if(var != null) + { + var.sdtClass = tokdeclcl; + var.sdtFlags = flags | SDT_STATIC; + } + continue; + } + + // ; + // = ; + if((token is TokenType) && + (token.nextToken is TokenName) && + ((token.nextToken.nextToken is TokenKwSemi) || + (token.nextToken.nextToken is TokenKwAssign))) + { + if((flags & (SDT_ABSTRACT | SDT_FINAL | SDT_NEW | SDT_OVERRIDE | SDT_VIRTUAL)) != 0) + { + ErrorMsg(token, "cannot have abstract, final, new, override or virtual field"); + } + TokenDeclVar var = ParseDeclVar(ref token, ifiFunc); + if(var != null) + { + var.sdtClass = tokdeclcl; + var.sdtFlags = flags; + if((flags & SDT_STATIC) != 0) + { + // . = ; + TokenLValSField left = new TokenLValSField(var.init); + left.baseType = tokdeclcl.MakeRefToken(var); + left.fieldName = var.name; + DoVarInit(sfiFunc, left, var.init); + } + else if(var.init != null) + { + // this. = ; + TokenLValIField left = new TokenLValIField(var.init); + left.baseRVal = new TokenRValThis(var.init, tokdeclcl); + left.fieldName = var.name; + DoVarInit(ifiFunc, left, var.init); + } + } + continue; + } + + // [ : ] { [ get { } ] [ set { } ] } + // '[' ... ']' [ : ] { [ get { } ] [ set { } ] } + bool prop = (token is TokenType) && + (token.nextToken is TokenName) && + (token.nextToken.nextToken is TokenKwBrcOpen || + token.nextToken.nextToken is TokenKwColon); + prop |= (token is TokenType) && (token.nextToken is TokenKwBrkOpen); + if(prop) + { + TokenDeclVar var = ParseProperty(ref token, (flags & SDT_ABSTRACT) != 0, true); + if(var != null) + { + var.sdtClass = tokdeclcl; + var.sdtFlags = flags; + if(var.getProp != null) + { + var.getProp.sdtClass = tokdeclcl; + var.getProp.sdtFlags = flags; + } + if(var.setProp != null) + { + var.setProp.sdtClass = tokdeclcl; + var.setProp.sdtFlags = flags; + } + } + continue; + } + + // 'constructor' '(' arglist ')' [ ':' [ 'base' ] '(' baseconstructorcall ')' ] '{' body '}' + if(token is TokenKwConstructor) + { + ParseSDTClassCtorDecl(ref token, flags, tokdeclcl); + haveExplicitConstructor = true; + continue; + } + + // + // method with explicit return type + if(token is TokenType) + { + ParseSDTClassMethodDecl(ref token, flags, tokdeclcl); + continue; + } + + // + // method returning void + if((token is TokenName) || ((token is TokenKw) && ((TokenKw)token).sdtClassOp)) + { + ParseSDTClassMethodDecl(ref token, flags, tokdeclcl); + continue; + } + + // That's all we support in a class declaration. + ErrorMsg(token, "expecting field or method declaration"); + token = SkipPastSemi(token); + } + + // If script didn't specify any constructor, create a default no-argument one. + if(!haveExplicitConstructor) + { + TokenDeclVar tokenDeclFunc = new TokenDeclVar(token, null, tokenScript); + tokenDeclFunc.name = new TokenName(token, "$ctor"); + tokenDeclFunc.retType = new TokenTypeVoid(token); + tokenDeclFunc.argDecl = new TokenArgDecl(token); + tokenDeclFunc.sdtClass = tokdeclcl; + tokenDeclFunc.sdtFlags = SDT_PUBLIC | SDT_NEW; + tokenDeclFunc.body = new TokenStmtBlock(token); + tokenDeclFunc.body.function = tokenDeclFunc; + + if(tokdeclcl.extends != null) + { + SetUpDefaultBaseCtorCall(tokenDeclFunc); + } + else + { + // default constructor that doesn't do anything is trivial + tokenDeclFunc.triviality = Triviality.trivial; + } + + tokenScript.AddVarEntry(tokenDeclFunc); + } + + // Skip over the closing brace and pop corresponding var frame. + token = token.nextToken; + tokenScript.PopVarFrame(); + ret: + currentDeclSDType = saveCurSDType; + } + + /** + * @brief Parse out abstract/override/private/protected/public/static/virtual keywords. + * @param token = first token to evaluate + * @returns flags found; token = unprocessed token + */ + private Dictionary foundFlags = new Dictionary(); + private uint ParseQualifierFlags(ref Token token) + { + foundFlags.Clear(); + while(true) + { + if(token is TokenKwPrivate) + { + token = AddQualifierFlag(token, SDT_PRIVATE, SDT_PROTECTED | SDT_PUBLIC); + continue; + } + if(token is TokenKwProtected) + { + token = AddQualifierFlag(token, SDT_PROTECTED, SDT_PRIVATE | SDT_PUBLIC); + continue; + } + if(token is TokenKwPublic) + { + token = AddQualifierFlag(token, SDT_PUBLIC, SDT_PRIVATE | SDT_PROTECTED); + continue; + } + if(token is TokenKwAbstract) + { + token = AddQualifierFlag(token, SDT_ABSTRACT, SDT_FINAL | SDT_STATIC | SDT_VIRTUAL); + continue; + } + if(token is TokenKwFinal) + { + token = AddQualifierFlag(token, SDT_FINAL, SDT_ABSTRACT | SDT_VIRTUAL); + continue; + } + if(token is TokenKwNew) + { + token = AddQualifierFlag(token, SDT_NEW, SDT_OVERRIDE); + continue; + } + if(token is TokenKwOverride) + { + token = AddQualifierFlag(token, SDT_OVERRIDE, SDT_NEW | SDT_STATIC); + continue; + } + if(token is TokenKwStatic) + { + token = AddQualifierFlag(token, SDT_STATIC, SDT_ABSTRACT | SDT_OVERRIDE | SDT_VIRTUAL); + continue; + } + if(token is TokenKwVirtual) + { + token = AddQualifierFlag(token, SDT_VIRTUAL, SDT_ABSTRACT | SDT_STATIC); + continue; + } + break; + } + + uint flags = 0; + foreach(uint flag in foundFlags.Keys) + flags |= flag; + + if((flags & (SDT_PRIVATE | SDT_PROTECTED | SDT_PUBLIC)) == 0) + ErrorMsg(token, "must specify exactly one of private, protected or public"); + + return flags; + } + private Token AddQualifierFlag(Token token, uint add, uint confs) + { + while(confs != 0) + { + uint conf = (uint)(confs & -confs); + Token confToken; + if(foundFlags.TryGetValue(conf, out confToken)) + { + ErrorMsg(token, "conflicts with " + confToken.ToString()); + } + confs -= conf; + } + foundFlags[add] = token; + return token.nextToken; + } + + /** + * @brief Parse a property declaration. + * @param token = points to the property type token on entry + * points just past the closing brace on return + * @param abs = true: property is abstract + * false: property is concrete + * @param imp = allow implemented interface specs + * @returns null: parse failure + * else: property + * + * [ : ] { [ get { } ] [ set { } ] } + * '[' ... ']' [ : ] { [ get { } ] [ set { } ] } + */ + private TokenDeclVar ParseProperty(ref Token token, bool abs, bool imp) + { + // Parse out the property's type and name. + // + TokenType type = (TokenType)token; + TokenName name; + TokenArgDecl args; + Token argTokens = null; + token = token.nextToken; + if(token is TokenKwBrkOpen) + { + argTokens = token; + name = new TokenName(token, "$idxprop"); + args = ParseFuncArgs(ref token, typeof(TokenKwBrkClose)); + } + else + { + name = (TokenName)token; + token = token.nextToken; + args = new TokenArgDecl(token); + } + + // Maybe it claims to implement some interface properties. + // [ ':' [.] ',' ... ] + TokenIntfImpl implements = null; + if(token is TokenKwColon) + { + implements = ParseImplements(ref token, name); + if(implements == null) + return null; + if(!imp) + { + ErrorMsg(token, "cannot implement interface property"); + } + } + + // Should have an opening brace. + if(!(token is TokenKwBrcOpen)) + { + ErrorMsg(token, "expect { to open property definition"); + token = SkipPastSemi(token); + return null; + } + token = token.nextToken; + + // Parse out the getter and/or setter. + // 'get' { | ';' } + // 'set' { | ';' } + TokenDeclVar getFunc = null; + TokenDeclVar setFunc = null; + while(!(token is TokenKwBrcClose)) + { + // Maybe create a getter function. + if(token is TokenKwGet) + { + getFunc = new TokenDeclVar(token, null, tokenScript); + getFunc.name = new TokenName(token, name.val + "$get"); + getFunc.retType = type; + getFunc.argDecl = args; + getFunc.implements = MakePropertyImplements(implements, "$get"); + + token = token.nextToken; + if(!ParseFunctionBody(ref token, getFunc, abs)) + { + getFunc = null; + } + else if(!tokenScript.AddVarEntry(getFunc)) + { + ErrorMsg(getFunc, "duplicate getter"); + } + continue; + } + + // Maybe create a setter function. + if(token is TokenKwSet) + { + TokenArgDecl argDecl = args; + if(getFunc != null) + { + argDecl = (argTokens == null) ? new TokenArgDecl(token) : + ParseFuncArgs(ref argTokens, typeof(TokenKwBrkClose)); + } + argDecl.AddArg(type, new TokenName(token, "value")); + + setFunc = new TokenDeclVar(token, null, tokenScript); + setFunc.name = new TokenName(token, name.val + "$set"); + setFunc.retType = new TokenTypeVoid(token); + setFunc.argDecl = argDecl; + setFunc.implements = MakePropertyImplements(implements, "$set"); + + token = token.nextToken; + if(!ParseFunctionBody(ref token, setFunc, abs)) + { + setFunc = null; + } + else if(!tokenScript.AddVarEntry(setFunc)) + { + ErrorMsg(setFunc, "duplicate setter"); + } + continue; + } + + ErrorMsg(token, "expecting get or set"); + token = SkipPastSemi(token); + return null; + } + token = token.nextToken; + + if((getFunc == null) && (setFunc == null)) + { + ErrorMsg(name, "must specify at least one of get, set"); + return null; + } + + // Set up a variable for the property. + TokenDeclVar tokenDeclVar = new TokenDeclVar(name, null, tokenScript); + tokenDeclVar.type = type; + tokenDeclVar.name = name; + tokenDeclVar.getProp = getFunc; + tokenDeclVar.setProp = setFunc; + + // Can't be same name already in block. + if(!tokenScript.AddVarEntry(tokenDeclVar)) + { + ErrorMsg(tokenDeclVar, "duplicate member " + name.val); + return null; + } + return tokenDeclVar; + } + + /** + * @brief Given a list of implemented interface methods, create a similar list with suffix added to all the names + * @param implements = original list of implemented interface methods + * @param suffix = string to be added to end of implemented interface method names + * @returns list similar to implements with suffix added to end of implemented interface method names + */ + private TokenIntfImpl MakePropertyImplements(TokenIntfImpl implements, string suffix) + { + TokenIntfImpl gsimpls = null; + for(TokenIntfImpl impl = implements; impl != null; impl = (TokenIntfImpl)impl.nextToken) + { + TokenIntfImpl gsimpl = new TokenIntfImpl(impl.intfType, + new TokenName(impl.methName, impl.methName.val + suffix)); + gsimpl.nextToken = gsimpls; + gsimpls = gsimpl; + } + return gsimpls; + } + + /** + * @brief Parse a constructor definition for a script-defined type class. + * @param token = points to 'constructor' keyword + * @param flags = abstract/override/static/virtual flags + * @param tokdeclcl = which script-defined type class this method is in + * @returns with method parsed and cataloged (or error message(s) printed) + */ + private void ParseSDTClassCtorDecl(ref Token token, uint flags, TokenDeclSDTypeClass tokdeclcl) + { + if((flags & (SDT_ABSTRACT | SDT_OVERRIDE | SDT_STATIC | SDT_VIRTUAL)) != 0) + { + ErrorMsg(token, "cannot have abstract, override, static or virtual constructor"); + } + + TokenDeclVar tokenDeclFunc = new TokenDeclVar(token, null, tokenScript); + tokenDeclFunc.name = new TokenName(tokenDeclFunc, "$ctor"); + tokenDeclFunc.retType = new TokenTypeVoid(token); + tokenDeclFunc.sdtClass = tokdeclcl; + tokenDeclFunc.sdtFlags = flags | SDT_NEW; + + token = token.nextToken; + if(!(token is TokenKwParOpen)) + { + ErrorMsg(token, "expecting ( for constructor argument list"); + token = SkipPastSemi(token); + return; + } + tokenDeclFunc.argDecl = ParseFuncArgs(ref token, typeof(TokenKwParClose)); + if(tokenDeclFunc.argDecl == null) + return; + + TokenDeclVar saveDeclFunc = currentDeclFunc; + currentDeclFunc = tokenDeclFunc; + tokenScript.PushVarFrame(tokenDeclFunc.argDecl.varDict); + try + { + // Set up reference to base constructor. + TokenLValBaseField baseCtor = new TokenLValBaseField(token, + new TokenName(token, "$ctor"), + tokdeclcl); + + // Parse any base constructor call as if it were the first statement of the + // constructor itself. + if(token is TokenKwColon) + { + token = token.nextToken; + if(token is TokenKwBase) + { + token = token.nextToken; + } + if(!(token is TokenKwParOpen)) + { + ErrorMsg(token, "expecting ( for base constructor call arguments"); + token = SkipPastSemi(token); + return; + } + TokenRValCall rvc = ParseRValCall(ref token, baseCtor); + if(rvc == null) + return; + if(tokdeclcl.extends != null) + { + tokenDeclFunc.baseCtorCall = rvc; + tokenDeclFunc.unknownTrivialityCalls.AddLast(rvc); + } + else + { + ErrorMsg(rvc, "base constructor call cannot be specified if not extending anything"); + } + } + else if(tokdeclcl.extends != null) + { + // Caller didn't specify a constructor but we are extending, so we will + // call the extended class's default constructor. + SetUpDefaultBaseCtorCall(tokenDeclFunc); + } + + // Parse the constructor body. + tokenDeclFunc.body = ParseStmtBlock(ref token); + if(tokenDeclFunc.body == null) + return; + if(tokenDeclFunc.argDecl == null) + return; + } + finally + { + tokenScript.PopVarFrame(); + currentDeclFunc = saveDeclFunc; + } + + // Add to list of methods defined by this class. + // It has the name "$ctor(argsig)". + if(!tokenScript.AddVarEntry(tokenDeclFunc)) + { + ErrorMsg(tokenDeclFunc, "duplicate constructor definition"); + } + } + + /** + * @brief Set up a call from a constructor to its default base constructor. + */ + private void SetUpDefaultBaseCtorCall(TokenDeclVar thisCtor) + { + TokenLValBaseField baseCtor = new TokenLValBaseField(thisCtor, + new TokenName(thisCtor, "$ctor"), + (TokenDeclSDTypeClass)thisCtor.sdtClass); + TokenRValCall rvc = new TokenRValCall(thisCtor); + rvc.meth = baseCtor; + thisCtor.baseCtorCall = rvc; + thisCtor.unknownTrivialityCalls.AddLast(rvc); + } + + /** + * @brief Parse a method definition for a script-defined type class. + * @param token = points to return type (or method name for implicit return type of void) + * @param flags = abstract/override/static/virtual flags + * @param tokdeclcl = which script-defined type class this method is in + * @returns with method parsed and cataloged (or error message(s) printed) + */ + private void ParseSDTClassMethodDecl(ref Token token, uint flags, TokenDeclSDTypeClass tokdeclcl) + { + TokenDeclVar tokenDeclFunc = ParseDeclFunc(ref token, + (flags & SDT_ABSTRACT) != 0, + (flags & SDT_STATIC) == 0, + (flags & SDT_STATIC) == 0); + if(tokenDeclFunc != null) + { + tokenDeclFunc.sdtClass = tokdeclcl; + tokenDeclFunc.sdtFlags = flags; + if(!tokenScript.AddVarEntry(tokenDeclFunc)) + { + string funcNameSig = tokenDeclFunc.funcNameSig.val; + ErrorMsg(tokenDeclFunc.funcNameSig, "duplicate method name " + funcNameSig); + } + } + } + + /** + * @brief Parse a delegate declaration statement. + * @param token = points to TokenDeclSDTypeDelegate token on entry + * points just past ';' on return + * @param outerSDType = null: this is a top-level delegate + * else: this delegate is being defined inside this type + * @param flags = SDT_{PRIVATE,PROTECTED,PUBLIC} + */ + private void ParseDeclDelegate(ref Token token, TokenDeclSDType outerSDType, uint flags) + { + Token u = token; + TokenDeclSDTypeDelegate tokdecldel; + TokenType retType; + + tokdecldel = (TokenDeclSDTypeDelegate)u; + tokdecldel.outerSDType = outerSDType; + tokdecldel.accessLevel = flags; + + // first thing following that should be return type + // but we will fill in 'void' if it is missing + u = u.nextToken; + if(u is TokenType) + { + retType = (TokenType)u; + u = u.nextToken; + } + else + { + retType = new TokenTypeVoid(u); + } + + // get list of argument types until we see a ')' + List args = new List(); + bool first = true; + do + { + if(first) + { + + // first time should have '(' ')' or '(' + if(!(u is TokenKwParOpen)) + { + ErrorMsg(u, "expecting ( after delegate name"); + token = SkipPastSemi(token); + return; + } + first = false; + u = u.nextToken; + if(u is TokenKwParClose) + break; + } + else + { + // other times should have ',' + if(!(u is TokenKwComma)) + { + ErrorMsg(u, "expecting , separating arg types"); + token = SkipPastSemi(token); + return; + } + u = u.nextToken; + } + if(!(u is TokenType)) + { + ErrorMsg(u, "expecting argument type"); + token = SkipPastSemi(token); + return; + } + args.Add((TokenType)u); + u = u.nextToken; + + // they can put in a dummy name that we toss out + if(u is TokenName) + u = u.nextToken; + + // scanning ends on a ')' + } while(!(u is TokenKwParClose)); + + // fill in the return type and argment type array + tokdecldel.SetRetArgTypes(retType, args.ToArray()); + + // and finally must have ';' to finish the delegate declaration statement + u = u.nextToken; + if(!(u is TokenKwSemi)) + { + ErrorMsg(u, "expecting ; after ) in delegate"); + token = SkipPastSemi(token); + return; + } + token = u.nextToken; + } + + /** + * @brief Parse an interface declaration. + * @param token = points to TokenDeclSDTypeInterface token on entry + * points just past closing '}' on return + * @param outerSDType = null: this is a top-level interface + * else: this interface is being defined inside this type + * @param flags = SDT_{PRIVATE,PROTECTED,PUBLIC} + */ + private void ParseDeclInterface(ref Token token, TokenDeclSDType outerSDType, uint flags) + { + Token u = token; + TokenDeclSDTypeInterface tokdeclin; + + tokdeclin = (TokenDeclSDTypeInterface)u; + tokdeclin.outerSDType = outerSDType; + tokdeclin.accessLevel = flags; + u = u.nextToken; + + // next can be ':' followed by list of implemented interfaces + if(u is TokenKwColon) + { + u = u.nextToken; + while(true) + { + if(u is TokenTypeSDTypeInterface) + { + TokenDeclSDTypeInterface i = ((TokenTypeSDTypeInterface)u).decl; + if(!tokdeclin.implements.Contains(i)) + { + tokdeclin.implements.Add(i); + } + } + else + { + ErrorMsg(u, "expecting interface name"); + if(u is TokenKwBrcOpen) + break; + } + u = u.nextToken; + if(!(u is TokenKwComma)) + break; + u = u.nextToken; + } + } + + // next must be '{' to open interface declaration body + if(!(u is TokenKwBrcOpen)) + { + ErrorMsg(u, "expecting { to open interface declaration body"); + token = SkipPastSemi(token); + return; + } + token = u.nextToken; + + // start a var definition frame to collect the interface members + tokenScript.PushVarFrame(false); + tokdeclin.methsNProps = tokenScript.variablesStack; + + // process declaration statements until '}' + while(!(token is TokenKwBrcClose)) + { + if(token is TokenKwSemi) + { + token = token.nextToken; + continue; + } + + // Parse nested script-defined type definitions. + if(ParseDeclSDTypes(ref token, tokdeclin, SDT_PUBLIC)) + continue; + + // ; + // abstract method with explicit return type + if((token is TokenType) && + (token.nextToken is TokenName) && + (token.nextToken.nextToken is TokenKwParOpen)) + { + Token name = token.nextToken; + TokenDeclVar tokenDeclFunc = ParseDeclFunc(ref token, true, false, false); + if(tokenDeclFunc == null) + continue; + if(!tokenScript.AddVarEntry(tokenDeclFunc)) + { + ErrorMsg(name, "duplicate method name"); + continue; + } + continue; + } + + // ; + // abstract method returning void + if((token is TokenName) && + (token.nextToken is TokenKwParOpen)) + { + Token name = token; + TokenDeclVar tokenDeclFunc = ParseDeclFunc(ref token, true, false, false); + if(tokenDeclFunc == null) + continue; + if(!tokenScript.AddVarEntry(tokenDeclFunc)) + { + ErrorMsg(name, "duplicate method name"); + } + continue; + } + + // { [ get ; ] [ set ; ] } + // '[' ... ']' { [ get ; ] [ set ; ] } + // abstract property + bool prop = (token is TokenType) && + (token.nextToken is TokenName) && + (token.nextToken.nextToken is TokenKwBrcOpen || + token.nextToken.nextToken is TokenKwColon); + prop |= (token is TokenType) && (token.nextToken is TokenKwBrkOpen); + if(prop) + { + ParseProperty(ref token, true, false); + continue; + } + + // That's all we support in an interface declaration. + ErrorMsg(token, "expecting method or property prototype"); + token = SkipPastSemi(token); + } + + // Skip over the closing brace and pop the corresponding var frame. + token = token.nextToken; + tokenScript.PopVarFrame(); + } + + /** + * @brief parse state body (including all its event handlers) + * @param token = points to TokenKwBrcOpen + * @returns null: state body parse error + * else: token representing state + * token = points past close brace + */ + private TokenStateBody ParseStateBody(ref Token token) + { + TokenStateBody tokenStateBody = new TokenStateBody(token); + + if(!(token is TokenKwBrcOpen)) + { + ErrorMsg(token, "expecting { at beg of state"); + token = SkipPastSemi(token); + return null; + } + + token = token.nextToken; + while(!(token is TokenKwBrcClose)) + { + if(token is TokenEnd) + { + ErrorMsg(tokenStateBody, "eof parsing state body"); + return null; + } + TokenDeclVar tokenDeclFunc = ParseDeclFunc(ref token, false, false, false); + if(tokenDeclFunc == null) + return null; + if(!(tokenDeclFunc.retType is TokenTypeVoid)) + { + ErrorMsg(tokenDeclFunc.retType, "event handlers don't have return types"); + return null; + } + tokenDeclFunc.nextToken = tokenStateBody.eventFuncs; + tokenStateBody.eventFuncs = tokenDeclFunc; + } + token = token.nextToken; + return tokenStateBody; + } + + /** + * @brief Parse a function declaration, including its arg list and body + * @param token = points to function return type token (or function name token if return type void) + * @param abs = false: concrete function; true: abstract declaration + * @param imp = allow implemented interface specs + * @param ops = accept operators (==, +, etc) for function name + * @returns null: error parsing function definition + * else: function declaration + * token = advanced just past function, ie, just past the closing brace + */ + private TokenDeclVar ParseDeclFunc(ref Token token, bool abs, bool imp, bool ops) + { + TokenType retType; + if(token is TokenType) + { + retType = (TokenType)token; + token = token.nextToken; + } + else + { + retType = new TokenTypeVoid(token); + } + + TokenName simpleName; + if((token is TokenKw) && ((TokenKw)token).sdtClassOp) + { + if(!ops) + ErrorMsg(token, "operator functions disallowed in static contexts"); + simpleName = new TokenName(token, "$op" + token.ToString()); + } + else if(!(token is TokenName)) + { + ErrorMsg(token, "expecting function name"); + token = SkipPastSemi(token); + return null; + } + else + { + simpleName = (TokenName)token; + } + token = token.nextToken; + + return ParseDeclFunc(ref token, abs, imp, retType, simpleName); + } + + /** + * @brief Parse a function declaration, including its arg list and body + * This version enters with token pointing to the '(' at beginning of arg list + * @param token = points to the '(' of the arg list + * @param abs = false: concrete function; true: abstract declaration + * @param imp = allow implemented interface specs + * @param retType = return type (TokenTypeVoid if void, never null) + * @param simpleName = function name without any signature + * @returns null: error parsing remainder of function definition + * else: function declaration + * token = advanced just past function, ie, just past the closing brace + */ + private TokenDeclVar ParseDeclFunc(ref Token token, bool abs, bool imp, TokenType retType, TokenName simpleName) + { + TokenDeclVar tokenDeclFunc = new TokenDeclVar(simpleName, null, tokenScript); + tokenDeclFunc.name = simpleName; + tokenDeclFunc.retType = retType; + tokenDeclFunc.argDecl = ParseFuncArgs(ref token, typeof(TokenKwParClose)); + if(tokenDeclFunc.argDecl == null) + return null; + + if(token is TokenKwColon) + { + tokenDeclFunc.implements = ParseImplements(ref token, simpleName); + if(tokenDeclFunc.implements == null) + return null; + if(!imp) + { + ErrorMsg(tokenDeclFunc.implements, "cannot implement interface method"); + tokenDeclFunc.implements = null; + } + } + + if(!ParseFunctionBody(ref token, tokenDeclFunc, abs)) + return null; + if(tokenDeclFunc.argDecl == null) + return null; + return tokenDeclFunc; + } + + /** + * @brief Parse interface implementation list. + * @param token = points to ':' on entry + * points just past list on return + * @param simpleName = simple name (no arg signature) of method/property that + * is implementing the interface method/property + * @returns list of implemented interface methods/properties + */ + private TokenIntfImpl ParseImplements(ref Token token, TokenName simpleName) + { + TokenIntfImpl implements = null; + do + { + token = token.nextToken; + if(!(token is TokenTypeSDTypeInterface)) + { + ErrorMsg(token, "expecting interface type"); + token = SkipPastSemi(token); + return null; + } + TokenTypeSDTypeInterface intfType = (TokenTypeSDTypeInterface)token; + token = token.nextToken; + TokenName methName = simpleName; + if((token is TokenKwDot) && (token.nextToken is TokenName)) + { + methName = (TokenName)token.nextToken; + token = token.nextToken.nextToken; + } + TokenIntfImpl intfImpl = new TokenIntfImpl(intfType, methName); + intfImpl.nextToken = implements; + implements = intfImpl; + } while(token is TokenKwComma); + return implements; + } + + + /** + * @brief Parse function declaration's body + * @param token = points to body, ie, ';' or '{' + * @param tokenDeclFunc = function being declared + * @param abs = false: concrete function; true: abstract declaration + * @returns whether or not the function definition parsed correctly + */ + private bool ParseFunctionBody(ref Token token, TokenDeclVar tokenDeclFunc, bool abs) + { + if(token is TokenKwSemi) + { + if(!abs) + { + ErrorMsg(token, "concrete function must have body"); + token = SkipPastSemi(token); + return false; + } + token = token.nextToken; + return true; + } + + // Declare this function as being the one currently being processed + // for anything that cares. We also start a variable frame that + // includes all the declared parameters. + TokenDeclVar saveDeclFunc = currentDeclFunc; + currentDeclFunc = tokenDeclFunc; + tokenScript.PushVarFrame(tokenDeclFunc.argDecl.varDict); + + // Now parse the function statement block. + tokenDeclFunc.body = ParseStmtBlock(ref token); + + // Pop the var frame that contains the arguments. + tokenScript.PopVarFrame(); + currentDeclFunc = saveDeclFunc; + + // Check final errors. + if(tokenDeclFunc.body == null) + return false; + if(abs) + { + ErrorMsg(tokenDeclFunc.body, "abstract function must not have body"); + tokenDeclFunc.body = null; + return false; + } + return true; + } + + + /** + * @brief Parse statement + * @param token = first token of statement + * @returns null: parse error + * else: token representing whole statement + * token = points past statement + */ + private TokenStmt ParseStmt(ref Token token) + { + // Statements that begin with a specific keyword. + if(token is TokenKwAt) + return ParseStmtLabel(ref token); + if(token is TokenKwBrcOpen) + return ParseStmtBlock(ref token); + if(token is TokenKwBreak) + return ParseStmtBreak(ref token); + if(token is TokenKwCont) + return ParseStmtCont(ref token); + if(token is TokenKwDo) + return ParseStmtDo(ref token); + if(token is TokenKwFor) + return ParseStmtFor(ref token); + if(token is TokenKwForEach) + return ParseStmtForEach(ref token); + if(token is TokenKwIf) + return ParseStmtIf(ref token); + if(token is TokenKwJump) + return ParseStmtJump(ref token); + if(token is TokenKwRet) + return ParseStmtRet(ref token); + if(token is TokenKwSemi) + return ParseStmtNull(ref token); + if(token is TokenKwState) + return ParseStmtState(ref token); + if(token is TokenKwSwitch) + return ParseStmtSwitch(ref token); + if(token is TokenKwThrow) + return ParseStmtThrow(ref token); + if(token is TokenKwTry) + return ParseStmtTry(ref token); + if(token is TokenKwWhile) + return ParseStmtWhile(ref token); + + // Try to parse anything else as an expression, possibly calling + // something and/or writing to a variable. + TokenRVal tokenRVal = ParseRVal(ref token, semiOnly); + if(tokenRVal != null) + { + TokenStmtRVal tokenStmtRVal = new TokenStmtRVal(tokenRVal); + tokenStmtRVal.rVal = tokenRVal; + return tokenStmtRVal; + } + + // Who knows what it is... + ErrorMsg(token, "unknown statement"); + token = SkipPastSemi(token); + return null; + } + + /** + * @brief parse a statement block, ie, group of statements between braces + * @param token = points to { token + * @returns null: error parsing + * else: statements bundled in this token + * token = advanced just past the } token + */ + private TokenStmtBlock ParseStmtBlock(ref Token token) + { + if(!(token is TokenKwBrcOpen)) + { + ErrorMsg(token, "statement block body must begin with a {"); + token = SkipPastSemi(token); + return null; + } + TokenStmtBlock tokenStmtBlock = new TokenStmtBlock(token); + tokenStmtBlock.function = currentDeclFunc; + tokenStmtBlock.outerStmtBlock = currentStmtBlock; + currentStmtBlock = tokenStmtBlock; + VarDict outerVariablesStack = tokenScript.variablesStack; + try + { + Token prevStmt = null; + token = token.nextToken; + while(!(token is TokenKwBrcClose)) + { + if(token is TokenEnd) + { + ErrorMsg(tokenStmtBlock, "missing }"); + return null; + } + Token thisStmt; + if(((token is TokenType) && (token.nextToken is TokenName)) || + (token is TokenKwConst)) + { + thisStmt = ParseDeclVar(ref token, null); + } + else + { + thisStmt = ParseStmt(ref token); + } + if(thisStmt == null) + return null; + if(prevStmt == null) + tokenStmtBlock.statements = thisStmt; + else + prevStmt.nextToken = thisStmt; + prevStmt = thisStmt; + } + token = token.nextToken; + } + finally + { + tokenScript.variablesStack = outerVariablesStack; + currentStmtBlock = tokenStmtBlock.outerStmtBlock; + } + return tokenStmtBlock; + } + + /** + * @brief parse a 'break' statement + * @param token = points to break keyword token + * @returns null: error parsing + * else: statements bundled in this token + * token = advanced just past the ; token + */ + private TokenStmtBreak ParseStmtBreak(ref Token token) + { + TokenStmtBreak tokenStmtBreak = new TokenStmtBreak(token); + token = token.nextToken; + if(!(token is TokenKwSemi)) + { + ErrorMsg(token, "expecting ;"); + token = SkipPastSemi(token); + return null; + } + token = token.nextToken; + return tokenStmtBreak; + } + + /** + * @brief parse a 'continue' statement + * @param token = points to continue keyword token + * @returns null: error parsing + * else: statements bundled in this token + * token = advanced just past the ; token + */ + private TokenStmtCont ParseStmtCont(ref Token token) + { + TokenStmtCont tokenStmtCont = new TokenStmtCont(token); + token = token.nextToken; + if(!(token is TokenKwSemi)) + { + ErrorMsg(token, "expecting ;"); + token = SkipPastSemi(token); + return null; + } + token = token.nextToken; + return tokenStmtCont; + } + + /** + * @brief parse a 'do' statement + * @params token = points to 'do' keyword token + * @returns null: parse error + * else: pointer to token encapsulating the do statement, including body + * token = advanced just past the body statement + */ + private TokenStmtDo ParseStmtDo(ref Token token) + { + currentDeclFunc.triviality = Triviality.complex; + TokenStmtDo tokenStmtDo = new TokenStmtDo(token); + token = token.nextToken; + tokenStmtDo.bodyStmt = ParseStmt(ref token); + if(tokenStmtDo.bodyStmt == null) + return null; + if(!(token is TokenKwWhile)) + { + ErrorMsg(token, "expecting while clause"); + return null; + } + token = token.nextToken; + tokenStmtDo.testRVal = ParseRValParen(ref token); + if(tokenStmtDo.testRVal == null) + return null; + if(!(token is TokenKwSemi)) + { + ErrorMsg(token, "while clause must terminate on semicolon"); + token = SkipPastSemi(token); + return null; + } + token = token.nextToken; + return tokenStmtDo; + } + + /** + * @brief parse a for statement + * @param token = points to 'for' keyword token + * @returns null: parse error + * else: pointer to encapsulated for statement token + * token = advanced just past for body statement + */ + private TokenStmt ParseStmtFor(ref Token token) + { + currentDeclFunc.triviality = Triviality.complex; + + // Create encapsulating token and skip past 'for (' + TokenStmtFor tokenStmtFor = new TokenStmtFor(token); + token = token.nextToken; + if(!(token is TokenKwParOpen)) + { + ErrorMsg(token, "for must be followed by ("); + return null; + } + token = token.nextToken; + + // If a plain for, ie, not declaring a variable, it's straightforward. + if(!(token is TokenType)) + { + tokenStmtFor.initStmt = ParseStmt(ref token); + if(tokenStmtFor.initStmt == null) + return null; + return ParseStmtFor2(tokenStmtFor, ref token) ? tokenStmtFor : null; + } + + // Initialization declares a variable, so encapsulate it in a block so + // variable has scope only in the for statement, including its body. + TokenStmtBlock forStmtBlock = new TokenStmtBlock(tokenStmtFor); + forStmtBlock.outerStmtBlock = currentStmtBlock; + forStmtBlock.function = currentDeclFunc; + currentStmtBlock = forStmtBlock; + tokenScript.PushVarFrame(true); + + TokenDeclVar tokenDeclVar = ParseDeclVar(ref token, null); + if(tokenDeclVar == null) + { + tokenScript.PopVarFrame(); + currentStmtBlock = forStmtBlock.outerStmtBlock; + return null; + } + + forStmtBlock.statements = tokenDeclVar; + tokenDeclVar.nextToken = tokenStmtFor; + + bool ok = ParseStmtFor2(tokenStmtFor, ref token); + tokenScript.PopVarFrame(); + currentStmtBlock = forStmtBlock.outerStmtBlock; + return ok ? forStmtBlock : null; + } + + /** + * @brief parse rest of 'for' statement starting with the test expression. + * @param tokenStmtFor = token encapsulating the for statement + * @param token = points to test expression + * @returns false: parse error + * true: successful + * token = points just past body statement + */ + private bool ParseStmtFor2(TokenStmtFor tokenStmtFor, ref Token token) + { + if(token is TokenKwSemi) + { + token = token.nextToken; + } + else + { + tokenStmtFor.testRVal = ParseRVal(ref token, semiOnly); + if(tokenStmtFor.testRVal == null) + return false; + } + if(token is TokenKwParClose) + { + token = token.nextToken; + } + else + { + tokenStmtFor.incrRVal = ParseRVal(ref token, parCloseOnly); + if(tokenStmtFor.incrRVal == null) + return false; + } + tokenStmtFor.bodyStmt = ParseStmt(ref token); + return tokenStmtFor.bodyStmt != null; + } + + /** + * @brief parse a foreach statement + * @param token = points to 'foreach' keyword token + * @returns null: parse error + * else: pointer to encapsulated foreach statement token + * token = advanced just past for body statement + */ + private TokenStmt ParseStmtForEach(ref Token token) + { + currentDeclFunc.triviality = Triviality.complex; + + // Create encapsulating token and skip past 'foreach (' + TokenStmtForEach tokenStmtForEach = new TokenStmtForEach(token); + token = token.nextToken; + if(!(token is TokenKwParOpen)) + { + ErrorMsg(token, "foreach must be followed by ("); + return null; + } + token = token.nextToken; + + if(token is TokenName) + { + tokenStmtForEach.keyLVal = new TokenLValName((TokenName)token, tokenScript.variablesStack); + token = token.nextToken; + } + if(!(token is TokenKwComma)) + { + ErrorMsg(token, "expecting comma"); + token = SkipPastSemi(token); + return null; + } + token = token.nextToken; + if(token is TokenName) + { + tokenStmtForEach.valLVal = new TokenLValName((TokenName)token, tokenScript.variablesStack); + token = token.nextToken; + } + if(!(token is TokenKwIn)) + { + ErrorMsg(token, "expecting 'in'"); + token = SkipPastSemi(token); + return null; + } + token = token.nextToken; + tokenStmtForEach.arrayRVal = GetOperand(ref token); + if(tokenStmtForEach.arrayRVal == null) + return null; + if(!(token is TokenKwParClose)) + { + ErrorMsg(token, "expecting )"); + token = SkipPastSemi(token); + return null; + } + token = token.nextToken; + tokenStmtForEach.bodyStmt = ParseStmt(ref token); + if(tokenStmtForEach.bodyStmt == null) + return null; + return tokenStmtForEach; + } + + private TokenStmtIf ParseStmtIf(ref Token token) + { + TokenStmtIf tokenStmtIf = new TokenStmtIf(token); + token = token.nextToken; + tokenStmtIf.testRVal = ParseRValParen(ref token); + if(tokenStmtIf.testRVal == null) + return null; + tokenStmtIf.trueStmt = ParseStmt(ref token); + if(tokenStmtIf.trueStmt == null) + return null; + if(token is TokenKwElse) + { + token = token.nextToken; + tokenStmtIf.elseStmt = ParseStmt(ref token); + if(tokenStmtIf.elseStmt == null) + return null; + } + return tokenStmtIf; + } + + private TokenStmtJump ParseStmtJump(ref Token token) + { + // Create jump statement token to encapsulate the whole statement. + TokenStmtJump tokenStmtJump = new TokenStmtJump(token); + token = token.nextToken; + if(!(token is TokenName) || !(token.nextToken is TokenKwSemi)) + { + ErrorMsg(token, "expecting label;"); + token = SkipPastSemi(token); + return null; + } + tokenStmtJump.label = (TokenName)token; + token = token.nextToken.nextToken; + + // If label is already defined, it means this is a backward (looping) + // jump, so remember the label has backward jump references. + // We also then assume the function is complex, ie, it has a loop. + if(currentDeclFunc.labels.ContainsKey(tokenStmtJump.label.val)) + { + currentDeclFunc.labels[tokenStmtJump.label.val].hasBkwdRefs = true; + currentDeclFunc.triviality = Triviality.complex; + } + + return tokenStmtJump; + } + + /** + * @brief parse a jump target label statement + * @param token = points to the '@' token + * @returns null: error parsing + * else: the label + * token = advanced just past the ; + */ + private TokenStmtLabel ParseStmtLabel(ref Token token) + { + if(!(token.nextToken is TokenName) || + !(token.nextToken.nextToken is TokenKwSemi)) + { + ErrorMsg(token, "invalid label"); + token = SkipPastSemi(token); + return null; + } + TokenStmtLabel stmtLabel = new TokenStmtLabel(token); + stmtLabel.name = (TokenName)token.nextToken; + stmtLabel.block = currentStmtBlock; + if(currentDeclFunc.labels.ContainsKey(stmtLabel.name.val)) + { + ErrorMsg(token.nextToken, "duplicate label"); + ErrorMsg(currentDeclFunc.labels[stmtLabel.name.val], "previously defined here"); + token = SkipPastSemi(token); + return null; + } + currentDeclFunc.labels.Add(stmtLabel.name.val, stmtLabel); + token = token.nextToken.nextToken.nextToken; + return stmtLabel; + } + + private TokenStmtNull ParseStmtNull(ref Token token) + { + TokenStmtNull tokenStmtNull = new TokenStmtNull(token); + token = token.nextToken; + return tokenStmtNull; + } + + private TokenStmtRet ParseStmtRet(ref Token token) + { + TokenStmtRet tokenStmtRet = new TokenStmtRet(token); + token = token.nextToken; + if(token is TokenKwSemi) + { + token = token.nextToken; + } + else + { + tokenStmtRet.rVal = ParseRVal(ref token, semiOnly); + if(tokenStmtRet.rVal == null) + return null; + } + return tokenStmtRet; + } + + private TokenStmtSwitch ParseStmtSwitch(ref Token token) + { + TokenStmtSwitch tokenStmtSwitch = new TokenStmtSwitch(token); + token = token.nextToken; + tokenStmtSwitch.testRVal = ParseRValParen(ref token); + if(tokenStmtSwitch.testRVal == null) + return null; + if(!(token is TokenKwBrcOpen)) + { + ErrorMsg(token, "expecting open brace"); + token = SkipPastSemi(token); + return null; + } + token = token.nextToken; + TokenSwitchCase tokenSwitchCase = null; + bool haveComplained = false; + while(!(token is TokenKwBrcClose)) + { + if(token is TokenKwCase) + { + tokenSwitchCase = new TokenSwitchCase(token); + if(tokenStmtSwitch.lastCase == null) + { + tokenStmtSwitch.cases = tokenSwitchCase; + } + else + { + tokenStmtSwitch.lastCase.nextCase = tokenSwitchCase; + } + tokenStmtSwitch.lastCase = tokenSwitchCase; + + token = token.nextToken; + tokenSwitchCase.rVal1 = ParseRVal(ref token, colonOrDotDotDot); + if(tokenSwitchCase.rVal1 == null) + return null; + if(token is TokenKwDotDotDot) + { + token = token.nextToken; + tokenSwitchCase.rVal2 = ParseRVal(ref token, colonOnly); + if(tokenSwitchCase.rVal2 == null) + return null; + } + else + { + if(!(token is TokenKwColon)) + { + ErrorMsg(token, "expecting : or ..."); + token = SkipPastSemi(token); + return null; + } + token = token.nextToken; + } + } + else if(token is TokenKwDefault) + { + tokenSwitchCase = new TokenSwitchCase(token); + if(tokenStmtSwitch.lastCase == null) + { + tokenStmtSwitch.cases = tokenSwitchCase; + } + else + { + tokenStmtSwitch.lastCase.nextCase = tokenSwitchCase; + } + tokenStmtSwitch.lastCase = tokenSwitchCase; + + token = token.nextToken; + if(!(token is TokenKwColon)) + { + ErrorMsg(token, "expecting :"); + token = SkipPastSemi(token); + return null; + } + token = token.nextToken; + } + else if(tokenSwitchCase != null) + { + TokenStmt bodyStmt = ParseStmt(ref token); + if(bodyStmt == null) + return null; + if(tokenSwitchCase.lastStmt == null) + { + tokenSwitchCase.stmts = bodyStmt; + } + else + { + tokenSwitchCase.lastStmt.nextToken = bodyStmt; + } + tokenSwitchCase.lastStmt = bodyStmt; + bodyStmt.nextToken = null; + } + else if(!haveComplained) + { + ErrorMsg(token, "expecting case or default label"); + token = SkipPastSemi(token); + haveComplained = true; + } + } + token = token.nextToken; + return tokenStmtSwitch; + } + + private TokenStmtState ParseStmtState(ref Token token) + { + TokenStmtState tokenStmtState = new TokenStmtState(token); + token = token.nextToken; + if((!(token is TokenName) && !(token is TokenKwDefault)) || !(token.nextToken is TokenKwSemi)) + { + ErrorMsg(token, "expecting state;"); + token = SkipPastSemi(token); + return null; + } + if(token is TokenName) + { + tokenStmtState.state = (TokenName)token; + } + token = token.nextToken.nextToken; + return tokenStmtState; + } + + private TokenStmtThrow ParseStmtThrow(ref Token token) + { + TokenStmtThrow tokenStmtThrow = new TokenStmtThrow(token); + token = token.nextToken; + if(token is TokenKwSemi) + { + token = token.nextToken; + } + else + { + tokenStmtThrow.rVal = ParseRVal(ref token, semiOnly); + if(tokenStmtThrow.rVal == null) + return null; + } + return tokenStmtThrow; + } + + /** + * @brief Parse a try { ... } catch { ... } finally { ... } statement block + * @param token = point to 'try' keyword on entry + * points past last '}' processed on return + * @returns encapsulated try/catch/finally or null if parsing error + */ + private TokenStmtTry ParseStmtTry(ref Token token) + { + // Parse out the 'try { ... }' part + Token tryKw = token; + token = token.nextToken; + TokenStmt body = ParseStmtBlock(ref token); + + while(true) + { + TokenStmtTry tokenStmtTry; + if(token is TokenKwCatch) + { + if(!(token.nextToken is TokenKwParOpen) || + !(token.nextToken.nextToken is TokenType) || + !(token.nextToken.nextToken.nextToken is TokenName) || + !(token.nextToken.nextToken.nextToken.nextToken is TokenKwParClose)) + { + ErrorMsg(token, "catch must be followed by ( ) { ... }"); + return null; + } + token = token.nextToken.nextToken; // skip over 'catch' '(' + TokenDeclVar tag = new TokenDeclVar(token.nextToken, currentDeclFunc, tokenScript); + tag.type = (TokenType)token; + token = token.nextToken; // skip over + tag.name = (TokenName)token; + token = token.nextToken.nextToken; // skip over ')' + + if((!(tag.type is TokenTypeExc)) && (!(tag.type is TokenTypeStr))) + { + ErrorMsg(tag.type, "must be type 'exception' or 'string'"); + } + + tokenStmtTry = new TokenStmtTry(tryKw); + tokenStmtTry.tryStmt = WrapTryCatFinInBlock(body); + tokenStmtTry.catchVar = tag; + tokenScript.PushVarFrame(false); + tokenScript.AddVarEntry(tag); + tokenStmtTry.catchStmt = ParseStmtBlock(ref token); + tokenScript.PopVarFrame(); + if(tokenStmtTry.catchStmt == null) + return null; + tokenStmtTry.tryStmt.isTry = true; + tokenStmtTry.tryStmt.tryStmt = tokenStmtTry; + tokenStmtTry.catchStmt.isCatch = true; + tokenStmtTry.catchStmt.tryStmt = tokenStmtTry; + } + else if(token is TokenKwFinally) + { + token = token.nextToken; + + tokenStmtTry = new TokenStmtTry(tryKw); + tokenStmtTry.tryStmt = WrapTryCatFinInBlock(body); + tokenStmtTry.finallyStmt = ParseStmtBlock(ref token); + if(tokenStmtTry.finallyStmt == null) + return null; + tokenStmtTry.tryStmt.isTry = true; + tokenStmtTry.tryStmt.tryStmt = tokenStmtTry; + tokenStmtTry.finallyStmt.isFinally = true; + tokenStmtTry.finallyStmt.tryStmt = tokenStmtTry; + } + else + break; + + body = tokenStmtTry; + } + + if(!(body is TokenStmtTry)) + { + ErrorMsg(body, "try must have a matching catch and/or finally"); + return null; + } + return (TokenStmtTry)body; + } + + /** + * @brief Wrap a possible try/catch/finally statement block in a block statement. + * + * Given body = try { } catch (string s) { } + * + * we return { try { } catch (string s) { } } + * + * @param body = a TokenStmtTry or a TokenStmtBlock + * @returns a TokenStmtBlock + */ + private TokenStmtBlock WrapTryCatFinInBlock(TokenStmt body) + { + if(body is TokenStmtBlock) + return (TokenStmtBlock)body; + + TokenStmtTry innerTry = (TokenStmtTry)body; + + TokenStmtBlock wrapper = new TokenStmtBlock(body); + wrapper.statements = innerTry; + wrapper.outerStmtBlock = currentStmtBlock; + wrapper.function = currentDeclFunc; + + innerTry.tryStmt.outerStmtBlock = wrapper; + if(innerTry.catchStmt != null) + innerTry.catchStmt.outerStmtBlock = wrapper; + if(innerTry.finallyStmt != null) + innerTry.finallyStmt.outerStmtBlock = wrapper; + + return wrapper; + } + + private TokenStmtWhile ParseStmtWhile(ref Token token) + { + currentDeclFunc.triviality = Triviality.complex; + TokenStmtWhile tokenStmtWhile = new TokenStmtWhile(token); + token = token.nextToken; + tokenStmtWhile.testRVal = ParseRValParen(ref token); + if(tokenStmtWhile.testRVal == null) + return null; + tokenStmtWhile.bodyStmt = ParseStmt(ref token); + if(tokenStmtWhile.bodyStmt == null) + return null; + return tokenStmtWhile; + } + + /** + * @brief parse a variable declaration statement, including init value if any. + * @param token = points to type or 'constant' token + * @param initFunc = null: parsing a local var declaration + * put initialization code in .init + * else: parsing a global var or field var declaration + * put initialization code in initFunc.body + * @returns null: parsing error + * else: variable declaration encapulating token + * token = advanced just past semi-colon + * variables = modified to include the new variable + */ + private TokenDeclVar ParseDeclVar(ref Token token, TokenDeclVar initFunc) + { + TokenDeclVar tokenDeclVar = new TokenDeclVar(token.nextToken, currentDeclFunc, tokenScript); + + // Handle constant declaration. + // It ends up in the declared variables list for the statement block just like + // any other variable, except it has .constant = true. + // The code generator will test that the initialization expression is constant. + // + // constant = ; + if(token is TokenKwConst) + { + token = token.nextToken; + if(!(token is TokenName)) + { + ErrorMsg(token, "expecting constant name"); + token = SkipPastSemi(token); + return null; + } + tokenDeclVar.name = (TokenName)token; + token = token.nextToken; + if(!(token is TokenKwAssign)) + { + ErrorMsg(token, "expecting ="); + token = SkipPastSemi(token); + return null; + } + token = token.nextToken; + TokenRVal rVal = ParseRVal(ref token, semiOnly); + if(rVal == null) + return null; + tokenDeclVar.init = rVal; + tokenDeclVar.constant = true; + } + + // Otherwise, normal variable declaration with optional initialization value. + else + { + // Build basic encapsulating token with type and name. + tokenDeclVar.type = (TokenType)token; + token = token.nextToken; + if(!(token is TokenName)) + { + ErrorMsg(token, "expecting variable name"); + token = SkipPastSemi(token); + return null; + } + tokenDeclVar.name = (TokenName)token; + token = token.nextToken; + + // If just a ;, there is no explicit initialization value. + // Otherwise, look for an =RVal; expression that has init value. + if(token is TokenKwSemi) + { + token = token.nextToken; + if(initFunc != null) + { + tokenDeclVar.init = TokenRValInitDef.Construct(tokenDeclVar); + } + } + else if(token is TokenKwAssign) + { + token = token.nextToken; + if(initFunc != null) + { + currentDeclFunc = initFunc; + tokenDeclVar.init = ParseRVal(ref token, semiOnly); + currentDeclFunc = null; + } + else + { + tokenDeclVar.init = ParseRVal(ref token, semiOnly); + } + if(tokenDeclVar.init == null) + return null; + } + else + { + ErrorMsg(token, "expecting = or ;"); + token = SkipPastSemi(token); + return null; + } + } + + // If doing local vars, each var goes in its own var frame, + // to make sure no code before this point can reference it. + if(currentStmtBlock != null) + { + tokenScript.PushVarFrame(true); + } + + // Can't be same name already in block. + if(!tokenScript.AddVarEntry(tokenDeclVar)) + { + ErrorMsg(tokenDeclVar, "duplicate variable " + tokenDeclVar.name.val); + return null; + } + return tokenDeclVar; + } + + /** + * @brief Add variable initialization to $globalvarinit, $staticfieldinit or $instfieldinit function. + * @param initFunc = $globalvarinit, $staticfieldinit or $instfieldinit function + * @param left = variable being initialized + * @param init = null: initialize to default value + * else: initialize to this value + */ + private void DoVarInit(TokenDeclVar initFunc, TokenLVal left, TokenRVal init) + { + // Make a statement that assigns the initialization value to the variable. + TokenStmt stmt; + if(init == null) + { + TokenStmtVarIniDef tsvid = new TokenStmtVarIniDef(left); + tsvid.var = left; + stmt = tsvid; + } + else + { + TokenKw op = new TokenKwAssign(left); + TokenStmtRVal tsrv = new TokenStmtRVal(init); + tsrv.rVal = new TokenRValOpBin(left, op, init); + stmt = tsrv; + } + + // Add statement to end of initialization function. + // Be sure to execute them in same order as in source + // as some doofus scripts depend on it. + Token lastStmt = initFunc.body.statements; + if(lastStmt == null) + { + initFunc.body.statements = stmt; + } + else + { + Token nextStmt; + while((nextStmt = lastStmt.nextToken) != null) + { + lastStmt = nextStmt; + } + lastStmt.nextToken = stmt; + } + } + + /** + * @brief parse function declaration argument list + * @param token = points to TokenKwParOpen + * @returns null: parse error + * else: points to token with types and names + * token = updated past the TokenKw{Brk,Par}Close + */ + private TokenArgDecl ParseFuncArgs(ref Token token, Type end) + { + TokenArgDecl tokenArgDecl = new TokenArgDecl(token); + + bool first = true; + do + { + token = token.nextToken; + if((token.GetType() == end) && first) + break; + if(!(token is TokenType)) + { + ErrorMsg(token, "expecting arg type"); + token = SkipPastSemi(token); + return null; + } + TokenType type = (TokenType)token; + token = token.nextToken; + if(!(token is TokenName)) + { + ErrorMsg(token, "expecting arg name"); + token = SkipPastSemi(token); + return null; + } + TokenName name = (TokenName)token; + token = token.nextToken; + + if(!tokenArgDecl.AddArg(type, name)) + { + ErrorMsg(name, "duplicate arg name"); + } + first = false; + } while(token is TokenKwComma); + + if(token.GetType() != end) + { + ErrorMsg(token, "expecting comma or close bracket/paren"); + token = SkipPastSemi(token); + return null; + } + token = token.nextToken; + + return tokenArgDecl; + } + + /** + * @brief parse right-hand value expression + * this is where arithmetic-like expressions are processed + * @param token = points to first token expression + * @param termTokenType = expression termination token type + * @returns null: not an RVal + * else: single token representing whole expression + * token = if termTokenType.Length == 1, points just past terminating token + * else, points right at terminating token + */ + public TokenRVal ParseRVal(ref Token token, Type[] termTokenTypes) + { + // Start with pushing the first operand on operand stack. + BinOp binOps = null; + TokenRVal operands = GetOperand(ref token); + if(operands == null) + return null; + + // Keep scanning until we hit the termination token. + while(true) + { + Type tokType = token.GetType(); + for(int i = termTokenTypes.Length; --i >= 0;) + { + if(tokType == termTokenTypes[i]) + goto done; + } + + // Special form: + // is + if(token is TokenKwIs) + { + TokenRValIsType tokenRValIsType = new TokenRValIsType(token); + token = token.nextToken; + + // Parse the . + tokenRValIsType.typeExp = ParseTypeExp(ref token); + if(tokenRValIsType.typeExp == null) + return null; + + // Replace top operand with result of is + tokenRValIsType.rValExp = operands; + tokenRValIsType.nextToken = operands.nextToken; + operands = tokenRValIsType; + + // token points just past so see if it is another operator. + continue; + } + + // Peek at next operator. + BinOp binOp = GetOperator(ref token); + if(binOp == null) + return null; + + // If there are stacked operators of higher or same precedence than new one, + // perform their computation then push result back on operand stack. + // + // higher or same = left-to-right application of operators + // eg, a - b - c becomes (a - b) - c + // + // higher precedence = right-to-left application of operators + // eg, a - b - c becomes a - (b - c) + // + // Now of course, there is some ugliness necessary: + // we want: a - b - c => (a - b) - c so we do 'higher or same' + // but we want: a += b = c => a += (b = c) so we do 'higher only' + // + // binOps is the first operator (or null if only one) + // binOp is the second operator (or first if only one) + while(binOps != null) + { + if(binOps.preced < binOp.preced) + break; // 1st operator lower than 2nd, so leave 1st on stack to do later + if(binOps.preced > binOp.preced) + goto do1st; // 1st op higher than 2nd, so we always do 1st op first + if(binOps.preced == ASNPR) + break; // equal preced, if assignment type, leave 1st on stack to do later + // if non-asn type, do 1st op first (ie left-to-right) + do1st: + TokenRVal result = PerformBinOp((TokenRVal)operands.prevToken, binOps, (TokenRVal)operands); + result.prevToken = operands.prevToken.prevToken; + operands = result; + binOps = binOps.pop; + } + + // Handle conditional expression as a special form: + // ? : + if(binOp.token is TokenKwQMark) + { + TokenRValCondExpr condExpr = new TokenRValCondExpr(binOp.token); + condExpr.condExpr = operands; + condExpr.trueExpr = ParseRVal(ref token, new Type[] { typeof(TokenKwColon) }); + condExpr.falseExpr = ParseRVal(ref token, termTokenTypes); + condExpr.prevToken = operands.prevToken; + operands = condExpr; + termTokenTypes = new Type[0]; + goto done; + } + + // Push new operator on its stack. + binOp.pop = binOps; + binOps = binOp; + + // Push next operand on its stack. + TokenRVal operand = GetOperand(ref token); + if(operand == null) + return null; + operand.prevToken = operands; + operands = operand; + } + done: + + // At end of expression, perform any stacked computations. + while(binOps != null) + { + TokenRVal result = PerformBinOp((TokenRVal)operands.prevToken, binOps, (TokenRVal)operands); + result.prevToken = operands.prevToken.prevToken; + operands = result; + binOps = binOps.pop; + } + + // There should be exactly one remaining operand on the stack which is our final result. + if(operands.prevToken != null) + throw new Exception("too many operands"); + + // If only one terminator type possible, advance past the terminator. + if(termTokenTypes.Length == 1) + token = token.nextToken; + + return operands; + } + + private TokenTypeExp ParseTypeExp(ref Token token) + { + TokenTypeExp leftOperand = GetTypeExp(ref token); + if(leftOperand == null) + return null; + + while((token is TokenKwAnd) || (token is TokenKwOr)) + { + Token typeBinOp = token; + token = token.nextToken; + TokenTypeExp rightOperand = GetTypeExp(ref token); + if(rightOperand == null) + return null; + TokenTypeExpBinOp typeExpBinOp = new TokenTypeExpBinOp(typeBinOp); + typeExpBinOp.leftOp = leftOperand; + typeExpBinOp.binOp = typeBinOp; + typeExpBinOp.rightOp = rightOperand; + leftOperand = typeExpBinOp; + } + return leftOperand; + } + + private TokenTypeExp GetTypeExp(ref Token token) + { + if(token is TokenKwTilde) + { + TokenTypeExpNot typeExpNot = new TokenTypeExpNot(token); + token = token.nextToken; + typeExpNot.typeExp = GetTypeExp(ref token); + if(typeExpNot.typeExp == null) + return null; + return typeExpNot; + } + if(token is TokenKwParOpen) + { + TokenTypeExpPar typeExpPar = new TokenTypeExpPar(token); + token = token.nextToken; + typeExpPar.typeExp = GetTypeExp(ref token); + if(typeExpPar.typeExp == null) + return null; + if(!(token is TokenKwParClose)) + { + ErrorMsg(token, "expected close parenthesis"); + token = SkipPastSemi(token); + return null; + } + return typeExpPar; + } + if(token is TokenKwUndef) + { + TokenTypeExpUndef typeExpUndef = new TokenTypeExpUndef(token); + token = token.nextToken; + return typeExpUndef; + } + if(token is TokenType) + { + TokenTypeExpType typeExpType = new TokenTypeExpType(token); + typeExpType.typeToken = (TokenType)token; + token = token.nextToken; + return typeExpType; + } + ErrorMsg(token, "expected type"); + token = SkipPastSemi(token); + return null; + } + + /** + * @brief get a right-hand operand expression token + * @param token = first token of operand to parse + * @returns null: invalid operand + * else: token that bundles or wraps the operand + * token = points to token following last operand token + */ + private TokenRVal GetOperand(ref Token token) + { + // Prefix unary operators (eg ++, --) requiring an L-value. + if((token is TokenKwIncr) || (token is TokenKwDecr)) + { + TokenRValAsnPre asnPre = new TokenRValAsnPre(token); + asnPre.prefix = token; + token = token.nextToken; + TokenRVal op = GetOperand(ref token); + if(op == null) + return null; + if(!(op is TokenLVal)) + { + ErrorMsg(op, "can pre{in,de}crement only an L-value"); + return null; + } + asnPre.lVal = (TokenLVal)op; + return asnPre; + } + + // Get the bulk of the operand, ie, without any of the below suffixes. + TokenRVal operand = GetOperandNoMods(ref token); + if(operand == null) + return null; + modifiers: + + // If followed by '++' or '--', it is post-{in,de}cremented. + if((token is TokenKwIncr) || (token is TokenKwDecr)) + { + TokenRValAsnPost asnPost = new TokenRValAsnPost(token); + asnPost.postfix = token; + token = token.nextToken; + if(!(operand is TokenLVal)) + { + ErrorMsg(operand, "can post{in,de}crement only an L-value"); + return null; + } + asnPost.lVal = (TokenLVal)operand; + return asnPost; + } + + // If followed by a '.', it is an instance field or instance method reference. + if(token is TokenKwDot) + { + token = token.nextToken; + if(!(token is TokenName)) + { + ErrorMsg(token, ". must be followed by field/method name"); + return null; + } + TokenLValIField field = new TokenLValIField(token); + field.baseRVal = operand; + field.fieldName = (TokenName)token; + operand = field; + token = token.nextToken; + goto modifiers; + } + + // If followed by a '[', it is an array subscript. + if(token is TokenKwBrkOpen) + { + TokenLValArEle tokenLValArEle = new TokenLValArEle(token); + token = token.nextToken; + + // Parse subscript(s) expression. + tokenLValArEle.subRVal = ParseRVal(ref token, brkCloseOnly); + if(tokenLValArEle.subRVal == null) + { + ErrorMsg(tokenLValArEle, "invalid subscript"); + return null; + } + + // See if comma-separated list of values. + TokenRVal subscriptRVals; + int numSubscripts = SplitCommaRVals(tokenLValArEle.subRVal, out subscriptRVals); + if(numSubscripts > 1) + { + // If so, put the values in an LSL_List object. + TokenRValList rValList = new TokenRValList(tokenLValArEle); + rValList.rVal = subscriptRVals; + rValList.nItems = numSubscripts; + tokenLValArEle.subRVal = rValList; + } + + // Either way, save array variable name + // and substitute whole reference for L-value + tokenLValArEle.baseRVal = operand; + operand = tokenLValArEle; + goto modifiers; + } + + // If followed by a '(', it is a function/method call. + if(token is TokenKwParOpen) + { + operand = ParseRValCall(ref token, operand); + goto modifiers; + } + + // If 'new' arraytipe '{', it is an array initializer. + if((token is TokenKwBrcOpen) && (operand is TokenLValSField) && + (((TokenLValSField)operand).fieldName.val == "$new") && + ((TokenLValSField)operand).baseType.ToString().EndsWith("]")) + { + operand = ParseRValNewArIni(ref token, (TokenLValSField)operand); + if(operand != null) + goto modifiers; + } + + return operand; + } + + /** + * @brief same as GetOperand() except doesn't check for any modifiers + */ + private TokenRVal GetOperandNoMods(ref Token token) + { + // Simple unary operators. + if((token is TokenKwSub) || + (token is TokenKwTilde) || + (token is TokenKwExclam)) + { + Token uop = token; + token = token.nextToken; + TokenRVal rVal = GetOperand(ref token); + if(rVal == null) + return null; + return PerformUnOp(uop, rVal); + } + + // Type casting. + if((token is TokenKwParOpen) && + (token.nextToken is TokenType) && + (token.nextToken.nextToken is TokenKwParClose)) + { + TokenType type = (TokenType)token.nextToken; + token = token.nextToken.nextToken.nextToken; + TokenRVal rVal = GetOperand(ref token); + if(rVal == null) + return null; + return new TokenRValCast(type, rVal); + } + + // Parenthesized expression. + if(token is TokenKwParOpen) + { + return ParseRValParen(ref token); + } + + // Constants. + if(token is TokenChar) + { + TokenRValConst rValConst = new TokenRValConst(token, ((TokenChar)token).val); + token = token.nextToken; + return rValConst; + } + if(token is TokenFloat) + { + TokenRValConst rValConst = new TokenRValConst(token, ((TokenFloat)token).val); + token = token.nextToken; + return rValConst; + } + if(token is TokenInt) + { + TokenRValConst rValConst = new TokenRValConst(token, ((TokenInt)token).val); + token = token.nextToken; + return rValConst; + } + if(token is TokenStr) + { + TokenRValConst rValConst = new TokenRValConst(token, ((TokenStr)token).val); + token = token.nextToken; + return rValConst; + } + if(token is TokenKwUndef) + { + TokenRValUndef rValUndef = new TokenRValUndef((TokenKwUndef)token); + token = token.nextToken; + return rValUndef; + } + + // '<'value,...'>', ie, rotation or vector + if(token is TokenKwCmpLT) + { + Token openBkt = token; + token = token.nextToken; + TokenRVal rValAll = ParseRVal(ref token, cmpGTOnly); + if(rValAll == null) + return null; + TokenRVal rVals; + int nVals = SplitCommaRVals(rValAll, out rVals); + switch(nVals) + { + case 3: + { + TokenRValVec rValVec = new TokenRValVec(openBkt); + rValVec.xRVal = rVals; + rValVec.yRVal = (TokenRVal)rVals.nextToken; + rValVec.zRVal = (TokenRVal)rVals.nextToken.nextToken; + return rValVec; + } + case 4: + { + TokenRValRot rValRot = new TokenRValRot(openBkt); + rValRot.xRVal = rVals; + rValRot.yRVal = (TokenRVal)rVals.nextToken; + rValRot.zRVal = (TokenRVal)rVals.nextToken.nextToken; + rValRot.wRVal = (TokenRVal)rVals.nextToken.nextToken.nextToken; + return rValRot; + } + default: + { + ErrorMsg(openBkt, "bad rotation/vector"); + token = SkipPastSemi(token); + return null; + } + } + } + + // '['value,...']', ie, list + if(token is TokenKwBrkOpen) + { + TokenRValList rValList = new TokenRValList(token); + token = token.nextToken; + if(token is TokenKwBrkClose) + { + token = token.nextToken; // empty list + } + else + { + TokenRVal rValAll = ParseRVal(ref token, brkCloseOnly); + if(rValAll == null) + return null; + rValList.nItems = SplitCommaRVals(rValAll, out rValList.rVal); + } + return rValList; + } + + // Maybe we have . referencing a static field or method of some type. + if((token is TokenType) && (token.nextToken is TokenKwDot) && (token.nextToken.nextToken is TokenName)) + { + TokenLValSField field = new TokenLValSField(token.nextToken.nextToken); + field.baseType = (TokenType)token; + field.fieldName = (TokenName)token.nextToken.nextToken; + token = token.nextToken.nextToken.nextToken; + return field; + } + + // Maybe we have 'this' referring to the object of the instance method. + if(token is TokenKwThis) + { + if((currentDeclSDType == null) || !(currentDeclSDType is TokenDeclSDTypeClass)) + { + ErrorMsg(token, "using 'this' outside class definition"); + token = SkipPastSemi(token); + return null; + } + TokenRValThis zhis = new TokenRValThis(token, (TokenDeclSDTypeClass)currentDeclSDType); + token = token.nextToken; + return zhis; + } + + // Maybe we have 'base' referring to a field/method of the extended class. + if(token is TokenKwBase) + { + if((currentDeclFunc == null) || (currentDeclFunc.sdtClass == null) || !(currentDeclFunc.sdtClass is TokenDeclSDTypeClass)) + { + ErrorMsg(token, "using 'base' outside method"); + token = SkipPastSemi(token); + return null; + } + if(!(token.nextToken is TokenKwDot) || !(token.nextToken.nextToken is TokenName)) + { + ErrorMsg(token, "base must be followed by . then field or method name"); + TokenRValThis zhis = new TokenRValThis(token, (TokenDeclSDTypeClass)currentDeclFunc.sdtClass); + token = token.nextToken; + return zhis; + } + TokenLValBaseField baseField = new TokenLValBaseField(token, + (TokenName)token.nextToken.nextToken, + (TokenDeclSDTypeClass)currentDeclFunc.sdtClass); + token = token.nextToken.nextToken.nextToken; + return baseField; + } + + // Maybe we have 'new ' saying to create an object instance. + // This ends up generating a call to static function .$new(...) + // whose CIL code is generated by GenerateNewobjBody(). + if(token is TokenKwNew) + { + if(!(token.nextToken is TokenType)) + { + ErrorMsg(token.nextToken, "new must be followed by type"); + token = SkipPastSemi(token); + return null; + } + TokenLValSField field = new TokenLValSField(token.nextToken.nextToken); + field.baseType = (TokenType)token.nextToken; + field.fieldName = new TokenName(token, "$new"); + token = token.nextToken.nextToken; + return field; + } + + // All we got left is , eg, arg, function, global or local variable reference + if(token is TokenName) + { + TokenLValName name = new TokenLValName((TokenName)token, tokenScript.variablesStack); + token = token.nextToken; + return name; + } + + // Who knows what it is supposed to be? + ErrorMsg(token, "invalid operand token"); + token = SkipPastSemi(token); + return null; + } + + /** + * @brief Parse a call expression + * @param token = points to arg list '(' + * @param meth = points to method name being called + * @returns call expression value + * token = points just past arg list ')' + */ + private TokenRValCall ParseRValCall(ref Token token, TokenRVal meth) + { + // Set up basic function call struct with function name. + TokenRValCall rValCall = new TokenRValCall(token); + rValCall.meth = meth; + + // Parse the call parameters, if any. + token = token.nextToken; + if(token is TokenKwParClose) + { + token = token.nextToken; + } + else + { + rValCall.args = ParseRVal(ref token, parCloseOnly); + if(rValCall.args == null) + return null; + rValCall.nArgs = SplitCommaRVals(rValCall.args, out rValCall.args); + } + + currentDeclFunc.unknownTrivialityCalls.AddLast(rValCall); + + return rValCall; + } + + /** + * @brief decode binary operator token + * @param token = points to token to decode + * @returns null: invalid operator token + * else: operator token and precedence + */ + private BinOp GetOperator(ref Token token) + { + BinOp binOp = new BinOp(); + if(precedence.TryGetValue(token.GetType(), out binOp.preced)) + { + binOp.token = (TokenKw)token; + token = token.nextToken; + return binOp; + } + + if((token is TokenKwSemi) || (token is TokenKwBrcOpen) || (token is TokenKwBrcClose)) + { + ErrorMsg(token, "premature expression end"); + } + else + { + ErrorMsg(token, "invalid operator"); + } + token = SkipPastSemi(token); + return null; + } + + private class BinOp + { + public BinOp pop; + public TokenKw token; + public int preced; + } + + /** + * @brief Return an R-value expression token that will be used to + * generate code to perform the operation at runtime. + * @param left = left-hand operand + * @param binOp = operator + * @param right = right-hand operand + * @returns resultant expression + */ + private TokenRVal PerformBinOp(TokenRVal left, BinOp binOp, TokenRVal right) + { + return new TokenRValOpBin(left, binOp.token, right); + } + + /** + * @brief Return an R-value expression token that will be used to + * generate code to perform the operation at runtime. + * @param unOp = operator + * @param right = right-hand operand + * @returns resultant constant or expression + */ + private TokenRVal PerformUnOp(Token unOp, TokenRVal right) + { + return new TokenRValOpUn((TokenKw)unOp, right); + } + + /** + * @brief Parse an array initialization expression. + * @param token = points to '{' on entry + * @param newCall = encapsulates a '$new' call + * @return resultant operand encapsulating '$new' call and initializers + * token = points just past terminating '}' + * ...or null if parse error + */ + private TokenRVal ParseRValNewArIni(ref Token token, TokenLValSField newCall) + { + Stack stack = new Stack(); + TokenRValNewArIni arini = new TokenRValNewArIni(token); + arini.arrayType = newCall.baseType; + TokenList values = null; + while(true) + { + + // open brace means start a (sub-)list + if(token is TokenKwBrcOpen) + { + stack.Push(values); + values = new TokenList(token); + token = token.nextToken; + continue; + } + + // close brace means end of (sub-)list + // if final '}' all done parsing + if(token is TokenKwBrcClose) + { + token = token.nextToken; // skip over the '}' + TokenList innerds = values; // save the list just closed + arini.valueList = innerds; // it's the top list if it's the last closed + values = stack.Pop(); // pop to next outer list + if(values == null) + return arini; // final '}', we are done + values.tl.Add(innerds); // put the inner list on end of outer list + if(token is TokenKwComma) + { // should have a ',' or '}' next + token = token.nextToken; // skip over the ',' + } + else if(!(token is TokenKwBrcClose)) + { + ErrorMsg(token, "expecting , or } after sublist"); + } + continue; + } + + // this is a comma that doesn't have a value expression before it + // so we take it to mean skip initializing element (leave it zeroes/null etc) + if(token is TokenKwComma) + { + values.tl.Add(token); + token = token.nextToken; + continue; + } + + // parse value expression and skip terminating ',' if any + TokenRVal append = ParseRVal(ref token, commaOrBrcClose); + if(append == null) + return null; + values.tl.Add(append); + if(token is TokenKwComma) + { + token = token.nextToken; + } + } + } + + /** + * @brief parse out a parenthesized expression. + * @param token = points to open parenthesis + * @returns null: invalid expression + * else: parenthesized expression token or constant token + * token = points past the close parenthesis + */ + private TokenRValParen ParseRValParen(ref Token token) + { + if(!(token is TokenKwParOpen)) + { + ErrorMsg(token, "expecting ("); + token = SkipPastSemi(token); + return null; + } + TokenRValParen tokenRValParen = new TokenRValParen(token); + token = token.nextToken; + tokenRValParen.rVal = ParseRVal(ref token, parCloseOnly); + if(tokenRValParen.rVal == null) + return null; + return tokenRValParen; + } + + /** + * @brief Split a comma'd RVal into separate expressions + * @param rValAll = expression containing commas + * @returns number of comma separated values + * rVals = values in a null-terminated list linked by rVals.nextToken + */ + private int SplitCommaRVals(TokenRVal rValAll, out TokenRVal rVals) + { + if(!(rValAll is TokenRValOpBin) || !(((TokenRValOpBin)rValAll).opcode is TokenKwComma)) + { + rVals = rValAll; + if(rVals.nextToken != null) + throw new Exception("expected null"); + return 1; + } + TokenRValOpBin opBin = (TokenRValOpBin)rValAll; + TokenRVal rValLeft, rValRight; + int leftCount = SplitCommaRVals(opBin.rValLeft, out rValLeft); + int rightCount = SplitCommaRVals(opBin.rValRight, out rValRight); + rVals = rValLeft; + while(rValLeft.nextToken != null) + rValLeft = (TokenRVal)rValLeft.nextToken; + rValLeft.nextToken = rValRight; + return leftCount + rightCount; + } + + /** + * @brief output error message and remember that there is an error. + * @param token = what token is associated with the error + * @param message = error message string + */ + private void ErrorMsg(Token token, string message) + { + if(!errors || (token.file != lastErrorFile) || (token.line > lastErrorLine)) + { + errors = true; + lastErrorFile = token.file; + lastErrorLine = token.line; + token.ErrorMsg(message); + } + } + + /** + * @brief Skip past the next semicolon (or matched braces) + * @param token = points to token to skip over + * @returns token just after the semicolon or close brace + */ + private Token SkipPastSemi(Token token) + { + int braceLevel = 0; + + while(!(token is TokenEnd)) + { + if((token is TokenKwSemi) && (braceLevel == 0)) + { + return token.nextToken; + } + if(token is TokenKwBrcOpen) + { + braceLevel++; + } + if((token is TokenKwBrcClose) && (--braceLevel <= 0)) + { + return token.nextToken; + } + token = token.nextToken; + } + return token; + } + } + + /** + * @brief Script-defined type declarations + */ + public abstract class TokenDeclSDType: Token + { + protected const byte CLASS = 0; + protected const byte DELEGATE = 1; + protected const byte INTERFACE = 2; + protected const byte TYPEDEF = 3; + + // stuff that gets cloned/copied/transformed when instantiating a generic + // see InstantiateGeneric() below + public TokenDeclSDType outerSDType; // null if top-level + // else points to defining script-defined type + public Dictionary innerSDTypes = new Dictionary(); + // indexed by shortName + public Token begToken; // token that begins the definition (might be this or something like 'public') + public Token endToken; // the '}' or ';' that ends the definition + + // generic instantiation assumes none of the rest needs to be cloned (well except for the shortName) + public int sdTypeIndex = -1; // index in scriptObjCode.sdObjTypesIndx[] array + public TokenDeclSDTypeClass extends; // only non-null for TokenDeclSDTypeClass's + public uint accessLevel; // SDT_PRIVATE, SDT_PROTECTED or SDT_PUBLIC + // ... all top-level types are SDT_PUBLIC + public VarDict members = new VarDict(false); // declared fields, methods, properties if any + + public Dictionary genParams; // list of parameters for generic prototypes + // null for non-generic prototypes + // eg, for 'Dictionary' + // ...genParams gives K->0; V->1 + + public bool isPartial; // was declared with 'partial' keyword + // classes only, all others always false + + /* + * Name of the type. + * shortName = doesn't include outer class type names + * eg, 'Engine' for non-generic + * 'Dictionary<,>' for generic prototype + * 'Dictionary' for generic instantiation + * longName = includes all outer class type names if any + */ + private TokenName _shortName; + private TokenName _longName; + + public TokenName shortName + { + get + { + return _shortName; + } + set + { + _shortName = value; + _longName = null; + } + } + + public TokenName longName + { + get + { + if(_longName == null) + { + _longName = _shortName; + if(outerSDType != null) + { + _longName = new TokenName(_shortName, outerSDType.longName.val + "." + _shortName.val); + } + } + return _longName; + } + } + + /* + * Dictionary used when reading from object file that holds all script-defined types. + * Not complete though until all types have been read from the object file. + */ + private Dictionary sdTypes; + + public TokenDeclSDType(Token t) : base(t) { } + protected abstract TokenDeclSDType MakeBlank(TokenName shortName); + public abstract TokenType MakeRefToken(Token t); + public abstract Type GetSysType(); + public abstract void WriteToFile(BinaryWriter objFileWriter); + public abstract void ReadFromFile(BinaryReader objFileReader, TextWriter asmFileWriter); + + /** + * @brief Given that this is a generic prototype, apply the supplied genArgs + * to create an equivalent instantiated non-generic. This basically + * makes a copy replacing all the parameter types with the actual + * argument types. + * @param this = the prototype to be instantiated, eg, 'Dictionary.Converter' + * @param name = short name with arguments, eg, 'Converter'. + * @param genArgs = argument types of just this level, eg, 'float'. + * @returns clone of this but with arguments applied and spliced in source token stream + */ + public TokenDeclSDType InstantiateGeneric(string name, TokenType[] genArgs, ScriptReduce reduce) + { + // Malloc the struct and give it a name. + TokenDeclSDType instdecl = this.MakeBlank(new TokenName(this, name)); + + // If the original had an outer type, then so does the new one. + // The outer type will never be a generic prototype, eg, if this + // is 'ValueList' it will always be inside 'Dictionary' + // not 'Dictionary' at this point. + if((this.outerSDType != null) && (this.outerSDType.genParams != null)) + throw new Exception(); + instdecl.outerSDType = this.outerSDType; + + // The generic prototype may have stuff like 'public' just before it and we need to copy that too. + Token prefix; + for(prefix = this; (prefix = prefix.prevToken) != null;) + { + if(!(prefix is TokenKwPublic) && !(prefix is TokenKwProtected) && !(prefix is TokenKwPrivate)) + break; + } + this.begToken = prefix.nextToken; + + // Splice in a copy of the prefix tokens, just before the beginning token of prototype (this.begToken). + while((prefix = prefix.nextToken) != this) + { + SpliceSourceToken(prefix.CopyToken(prefix)); + } + + // Splice instantiation (instdecl) in just before the beginning token of prototype (this.begToken). + SpliceSourceToken(instdecl); + + // Now for the fun part... Copy the rest of the prototype body to the + // instantiated body, replacing all generic parameter type tokens with + // the corresponding generic argument types. Note that the parameters + // are numbered starting with the outermost so we need the full genArgs + // array. Eg if we are doing 'Converter' from + // 'Dictionary.Converter', any V's are + // numbered [2]. Any [0]s or [1]s should be gone by now but it doesn't + // matter. + int index; + Token it, pt; + TokenDeclSDType innerProto = this; + TokenDeclSDType innerInst = instdecl; + for(pt = this; (pt = pt.nextToken) != this.endToken;) + { + // Coming across a sub-type's declaration involves a deep copy of the + // declaration token. Fortunately we are early on in parsing, so there + // really isn't much to copy: + // 1) short name is the same, eg, doing List of Dictionary.List is same short name as Dictionary.List + // if generic, eg doing Converter of Dictionary.Converter, we have to manually copy the W as well. + // 2) outerSDType is transformed from Dictionary to Dictionary. + // 3) innerSDTypes is rebuilt when/if we find classes that are inner to this one. + if(pt is TokenDeclSDType) + { + // Make a new TokenDeclSDType{Class,Delegate,Interface}. + TokenDeclSDType ptSDType = (TokenDeclSDType)pt; + TokenDeclSDType itSDType = ptSDType.MakeBlank(new TokenName(ptSDType.shortName, ptSDType.shortName.val)); + + // Set up the transformed outerSDType. + // Eg, if we are creating Enumerator of Dictionary.Enumerator, + // innerProto = Dictionary and innerInst = Dictionary. + itSDType.outerSDType = innerInst; + + // This clone is an inner type of its next outer level. + reduce.CatalogSDTypeDecl(itSDType); + + // We need to manually copy any generic parameters of the class declaration being cloned. + // eg, if we are cloning Converter, this is where the W gets copied. + // Since it is an immutable array of strings, just copy the array pointer, if any. + itSDType.genParams = ptSDType.genParams; + + // We are now processing tokens for this cloned type declaration. + innerProto = ptSDType; + innerInst = itSDType; + + // Splice this clone token in. + it = itSDType; + } + + // Check for an generic parameter to substitute out. + else if((pt is TokenName) && this.genParams.TryGetValue(((TokenName)pt).val, out index)) + { + it = genArgs[index].CopyToken(pt); + } + + // Everything else is a simple copy. + else + it = pt.CopyToken(pt); + + // Whatever we came up with, splice it into the source token stream. + SpliceSourceToken(it); + + // Maybe we just finished copying an inner type definition. + // If so, remember where it ends and pop it from the stack. + if(innerProto.endToken == pt) + { + innerInst.endToken = it; + innerProto = innerProto.outerSDType; + innerInst = innerInst.outerSDType; + } + } + + // Clone and insert the terminator, either '}' or ';' + it = pt.CopyToken(pt); + SpliceSourceToken(it); + instdecl.endToken = it; + + return instdecl; + } + + /** + * @brief Splice a source token in just before the type's beginning keyword. + */ + private void SpliceSourceToken(Token it) + { + it.nextToken = this.begToken; + (it.prevToken = this.begToken.prevToken).nextToken = it; + this.begToken.prevToken = it; + } + + /** + * @brief Read one of these in from the object file. + * @param sdTypes = dictionary of script-defined types, not yet complete + * @param name = script-visible name of this type + * @param objFileReader = reads from the object file + * @param asmFileWriter = writes to the disassembly file (might be null) + */ + public static TokenDeclSDType ReadFromFile(Dictionary sdTypes, string name, + BinaryReader objFileReader, TextWriter asmFileWriter) + { + string file = objFileReader.ReadString(); + int line = objFileReader.ReadInt32(); + int posn = objFileReader.ReadInt32(); + byte code = objFileReader.ReadByte(); + TokenName n = new TokenName(null, file, line, posn, name); + TokenDeclSDType sdt; + switch(code) + { + case CLASS: + { + sdt = new TokenDeclSDTypeClass(n, false); + break; + } + case DELEGATE: + { + sdt = new TokenDeclSDTypeDelegate(n); + break; + } + case INTERFACE: + { + sdt = new TokenDeclSDTypeInterface(n); + break; + } + case TYPEDEF: + { + sdt = new TokenDeclSDTypeTypedef(n); + break; + } + default: + throw new Exception(); + } + sdt.sdTypes = sdTypes; + sdt.sdTypeIndex = objFileReader.ReadInt32(); + sdt.ReadFromFile(objFileReader, asmFileWriter); + return sdt; + } + + /** + * @brief Convert a typename string to a type token + * @param name = script-visible name of token to create, + * either a script-defined type or an LSL-defined type + * @returns type token + */ + protected TokenType MakeTypeToken(string name) + { + TokenDeclSDType sdtdecl; + if(sdTypes.TryGetValue(name, out sdtdecl)) + return sdtdecl.MakeRefToken(this); + return TokenType.FromLSLType(this, name); + } + + // debugging - returns, eg, 'Dictionary.Enumerator.Node' + public override void DebString(StringBuilder sb) + { + // get long name broken down into segments from outermost to this + Stack declStack = new Stack(); + for(TokenDeclSDType decl = this; decl != null; decl = decl.outerSDType) + { + declStack.Push(decl); + } + + // output each segment's name followed by our args for it + // starting with outermost and ending with this + while(declStack.Count > 0) + { + TokenDeclSDType decl = declStack.Pop(); + sb.Append(decl.shortName.val); + if(decl.genParams != null) + { + sb.Append('<'); + string[] parms = new string[decl.genParams.Count]; + foreach(KeyValuePair kvp in decl.genParams) + { + parms[kvp.Value] = kvp.Key; + } + for(int j = 0; j < parms.Length;) + { + sb.Append(parms[j]); + if(++j < parms.Length) + sb.Append(','); + } + sb.Append('>'); + } + if(declStack.Count > 0) + sb.Append('.'); + } + } + } + + public class TokenDeclSDTypeClass: TokenDeclSDType + { + public List implements = new List(); + public TokenDeclVar instFieldInit; // $instfieldinit function to do instance field initializations + public TokenDeclVar staticFieldInit; // $staticfieldinit function to do static field initializations + + public Dictionary intfIndices = new Dictionary(); // longname => this.iFaces index + public TokenDeclSDTypeInterface[] iFaces; // array of implemented interfaces + // low-end entries copied from rootward classes + public TokenDeclVar[][] iImplFunc; // iImplFunc[i][j]: + // low-end [i] entries copied from rootward classes + // i = interface number from this.intfIndices[name] + // j = method of interface from iface.methods[name].vTableIndex + + public TokenType arrayOfType; // if array, it's an array of this type, else null + public int arrayOfRank; // if array, it has this number of dimensions, else zero + + public bool slotsAssigned; // set true when slots have been assigned... + public XMRInstArSizes instSizes = new XMRInstArSizes(); + // number of instance fields of various types + public int numVirtFuncs; // number of virtual functions + public int numInterfaces; // number of implemented interfaces + + private string extendsStr; + private string arrayOfTypeStr; + private List stackedMethods; + private List stackedIFaces; + + public DynamicMethod[] vDynMeths; // virtual method entrypoints + public Type[] vMethTypes; // virtual method delegate types + public DynamicMethod[][] iDynMeths; // interface method entrypoints + public Type[][] iMethTypes; // interface method types + // low-end [i] entries copied from rootward classes + // i = interface number from this.intfIndices[name] + // j = method of interface from iface.methods[name].vTableIndex + + public TokenDeclSDTypeClass(TokenName shortName, bool isPartial) : base(shortName) + { + this.shortName = shortName; + this.isPartial = isPartial; + } + + protected override TokenDeclSDType MakeBlank(TokenName shortName) + { + return new TokenDeclSDTypeClass(shortName, false); + } + + public override TokenType MakeRefToken(Token t) + { + return new TokenTypeSDTypeClass(t, this); + } + + public override Type GetSysType() + { + return typeof(XMRSDTypeClObj); + } + + /** + * @brief See if the class implements the interface. + * Do a recursive (deep) check in all rootward classes. + */ + public bool CanCastToIntf(TokenDeclSDTypeInterface intf) + { + if(this.implements.Contains(intf)) + return true; + if(this.extends == null) + return false; + return this.extends.CanCastToIntf(intf); + } + + /** + * @brief Write enough out so we can reconstruct with ReadFromFile. + */ + public override void WriteToFile(BinaryWriter objFileWriter) + { + objFileWriter.Write(this.file); + objFileWriter.Write(this.line); + objFileWriter.Write(this.posn); + objFileWriter.Write((byte)CLASS); + objFileWriter.Write(this.sdTypeIndex); + + this.instSizes.WriteToFile(objFileWriter); + objFileWriter.Write(numVirtFuncs); + + if(extends == null) + { + objFileWriter.Write(""); + } + else + { + objFileWriter.Write(extends.longName.val); + } + + objFileWriter.Write(arrayOfRank); + if(arrayOfRank > 0) + objFileWriter.Write(arrayOfType.ToString()); + + foreach(TokenDeclVar meth in members) + { + if((meth.retType != null) && (meth.vTableIndex >= 0)) + { + objFileWriter.Write(meth.vTableIndex); + objFileWriter.Write(meth.GetObjCodeName()); + objFileWriter.Write(meth.GetDelType().decl.GetWholeSig()); + } + } + objFileWriter.Write(-1); + + int numIFaces = iImplFunc.Length; + objFileWriter.Write(numIFaces); + for(int i = 0; i < numIFaces; i++) + { + objFileWriter.Write(iFaces[i].longName.val); + TokenDeclVar[] meths = iImplFunc[i]; + int numMeths = 0; + if(meths != null) + numMeths = meths.Length; + objFileWriter.Write(numMeths); + for(int j = 0; j < numMeths; j++) + { + TokenDeclVar meth = meths[j]; + objFileWriter.Write(meth.vTableIndex); + objFileWriter.Write(meth.GetObjCodeName()); + objFileWriter.Write(meth.GetDelType().decl.GetWholeSig()); + } + } + } + + /** + * @brief Reconstruct from the file. + */ + public override void ReadFromFile(BinaryReader objFileReader, TextWriter asmFileWriter) + { + instSizes.ReadFromFile(objFileReader); + numVirtFuncs = objFileReader.ReadInt32(); + + extendsStr = objFileReader.ReadString(); + arrayOfRank = objFileReader.ReadInt32(); + if(arrayOfRank > 0) + arrayOfTypeStr = objFileReader.ReadString(); + + if(asmFileWriter != null) + { + instSizes.WriteAsmFile(asmFileWriter, extendsStr + "." + shortName.val + ".numInst"); + } + + stackedMethods = new List(); + int vTableIndex; + while((vTableIndex = objFileReader.ReadInt32()) >= 0) + { + StackedMethod sm; + sm.methVTI = vTableIndex; + sm.methName = objFileReader.ReadString(); + sm.methSig = objFileReader.ReadString(); + stackedMethods.Add(sm); + } + + int numIFaces = objFileReader.ReadInt32(); + if(numIFaces > 0) + { + iDynMeths = new DynamicMethod[numIFaces][]; + iMethTypes = new Type[numIFaces][]; + stackedIFaces = new List(); + for(int i = 0; i < numIFaces; i++) + { + string iFaceName = objFileReader.ReadString(); + intfIndices[iFaceName] = i; + int numMeths = objFileReader.ReadInt32(); + iDynMeths[i] = new DynamicMethod[numMeths]; + iMethTypes[i] = new Type[numMeths]; + for(int j = 0; j < numMeths; j++) + { + StackedIFace si; + si.iFaceIndex = i; + si.methIndex = j; + si.vTableIndex = objFileReader.ReadInt32(); + si.methName = objFileReader.ReadString(); + si.methSig = objFileReader.ReadString(); + stackedIFaces.Add(si); + } + } + } + } + + private struct StackedMethod + { + public int methVTI; + public string methName; + public string methSig; + } + + private struct StackedIFace + { + public int iFaceIndex; // which implemented interface + public int methIndex; // which method of that interface + public int vTableIndex; // <0: implemented by non-virtual; else: implemented by virtual + public string methName; // object code name of implementing method (GetObjCodeName) + public string methSig; // method signature incl return type (GetWholeSig) + } + + /** + * @brief Called after all dynamic method code has been generated to fill in vDynMeths and vMethTypes + * Also fills in iDynMeths, iMethTypes. + */ + public void FillVTables(ScriptObjCode scriptObjCode) + { + if(extendsStr != null) + { + if(extendsStr != "") + { + extends = (TokenDeclSDTypeClass)scriptObjCode.sdObjTypesName[extendsStr]; + extends.FillVTables(scriptObjCode); + } + extendsStr = null; + } + if(arrayOfTypeStr != null) + { + arrayOfType = MakeTypeToken(arrayOfTypeStr); + arrayOfTypeStr = null; + } + + if((numVirtFuncs > 0) && (stackedMethods != null)) + { + // Allocate arrays big enough for mine plus type we are extending. + vDynMeths = new DynamicMethod[numVirtFuncs]; + vMethTypes = new Type[numVirtFuncs]; + + // Fill in low parts from type we are extending. + if(extends != null) + { + int n = extends.numVirtFuncs; + for(int i = 0; i < n; i++) + { + vDynMeths[i] = extends.vDynMeths[i]; + vMethTypes[i] = extends.vMethTypes[i]; + } + } + + // Fill in high parts with my own methods. + // Might also overwrite lower ones with 'override' methods. + foreach(StackedMethod sm in stackedMethods) + { + int i = sm.methVTI; + string methName = sm.methName; + DynamicMethod dm; + if(scriptObjCode.dynamicMethods.TryGetValue(methName, out dm)) + { + // method is not abstract + vDynMeths[i] = dm; + vMethTypes[i] = GetDynamicMethodDelegateType(dm, sm.methSig); + } + } + stackedMethods = null; + } + + if(stackedIFaces != null) + { + foreach(StackedIFace si in stackedIFaces) + { + int i = si.iFaceIndex; + int j = si.methIndex; + int vti = si.vTableIndex; + string methName = si.methName; + DynamicMethod dm = scriptObjCode.dynamicMethods[methName]; + iDynMeths[i][j] = (vti < 0) ? dm : vDynMeths[vti]; + iMethTypes[i][j] = GetDynamicMethodDelegateType(dm, si.methSig); + } + stackedIFaces = null; + } + } + + private Type GetDynamicMethodDelegateType(DynamicMethod dm, string methSig) + { + Type retType = dm.ReturnType; + ParameterInfo[] pi = dm.GetParameters(); + Type[] argTypes = new Type[pi.Length]; + for(int j = 0; j < pi.Length; j++) + { + argTypes[j] = pi[j].ParameterType; + } + return DelegateCommon.GetType(retType, argTypes, methSig); + } + + public override void DebString(StringBuilder sb) + { + // Don't output if array of some type. + // They will be re-instantiated as referenced by rest of script. + if(arrayOfType != null) + return; + + // This class name and extended/implemented type declaration. + sb.Append("class "); + sb.Append(shortName.val); + bool first = true; + if(extends != null) + { + sb.Append(" : "); + sb.Append(extends.longName); + first = false; + } + foreach(TokenDeclSDType impld in implements) + { + sb.Append(first ? " : " : ", "); + sb.Append(impld.longName); + first = false; + } + sb.Append(" {"); + + // Inner type definitions. + foreach(TokenDeclSDType subs in innerSDTypes.Values) + { + subs.DebString(sb); + } + + // Members (fields, methods, properties). + foreach(TokenDeclVar memb in members) + { + if((memb == instFieldInit) || (memb == staticFieldInit)) + { + memb.DebStringInitFields(sb); + } + else if(memb.retType != null) + { + memb.DebString(sb); + } + } + + sb.Append('}'); + } + } + + public class TokenDeclSDTypeDelegate: TokenDeclSDType + { + private TokenType retType; + private TokenType[] argTypes; + + private string argSig; + private string wholeSig; + private Type sysType; + private Type retSysType; + private Type[] argSysTypes; + + private string retStr; + private string[] argStrs; + + private static Dictionary inlines = new Dictionary(); + private static Dictionary inlrevs = new Dictionary(); + + public TokenDeclSDTypeDelegate(TokenName shortName) : base(shortName) + { + this.shortName = shortName; + } + public void SetRetArgTypes(TokenType retType, TokenType[] argTypes) + { + this.retType = retType; + this.argTypes = argTypes; + } + + protected override TokenDeclSDType MakeBlank(TokenName shortName) + { + return new TokenDeclSDTypeDelegate(shortName); + } + + public override TokenType MakeRefToken(Token t) + { + return new TokenTypeSDTypeDelegate(t, this); + } + + /** + * @brief Get system type for the whole delegate. + */ + public override Type GetSysType() + { + if(sysType == null) + FillInStuff(); + return sysType; + } + + /** + * @brief Get the function's return value type (TokenTypeVoid if void, never null) + */ + public TokenType GetRetType() + { + if(retType == null) + FillInStuff(); + return retType; + } + + /** + * @brief Get the function's argument types + */ + public TokenType[] GetArgTypes() + { + if(argTypes == null) + FillInStuff(); + return argTypes; + } + + /** + * @brief Get signature for the whole delegate, eg, "void(integer,list)" + */ + public string GetWholeSig() + { + if(wholeSig == null) + FillInStuff(); + return wholeSig; + } + + /** + * @brief Get signature for the arguments, eg, "(integer,list)" + */ + public string GetArgSig() + { + if(argSig == null) + FillInStuff(); + return argSig; + } + + /** + * @brief Find out how to create one of these delegates. + */ + public ConstructorInfo GetConstructorInfo() + { + if(sysType == null) + FillInStuff(); + return sysType.GetConstructor(DelegateCommon.constructorArgTypes); + } + + /** + * @brief Find out how to call what one of these delegates points to. + */ + public MethodInfo GetInvokerInfo() + { + if(sysType == null) + FillInStuff(); + return sysType.GetMethod("Invoke", argSysTypes); + } + + /** + * @brief Write enough out to a file so delegate can be reconstructed in ReadFromFile(). + */ + public override void WriteToFile(BinaryWriter objFileWriter) + { + objFileWriter.Write(this.file); + objFileWriter.Write(this.line); + objFileWriter.Write(this.posn); + objFileWriter.Write((byte)DELEGATE); + objFileWriter.Write(this.sdTypeIndex); + + objFileWriter.Write(retType.ToString()); + int nArgs = argTypes.Length; + objFileWriter.Write(nArgs); + for(int i = 0; i < nArgs; i++) + { + objFileWriter.Write(argTypes[i].ToString()); + } + } + + /** + * @brief Read that data from file so we can reconstruct. + * Don't actually reconstruct yet in case any forward-referenced types are undefined. + */ + public override void ReadFromFile(BinaryReader objFileReader, TextWriter asmFileWriter) + { + retStr = objFileReader.ReadString(); + int nArgs = objFileReader.ReadInt32(); + if(asmFileWriter != null) + { + asmFileWriter.Write(" delegate " + retStr + " " + longName.val + "("); + } + argStrs = new string[nArgs]; + for(int i = 0; i < nArgs; i++) + { + argStrs[i] = objFileReader.ReadString(); + if(asmFileWriter != null) + { + if(i > 0) + asmFileWriter.Write(","); + asmFileWriter.Write(argStrs[i]); + } + } + if(asmFileWriter != null) + { + asmFileWriter.WriteLine(");"); + } + } + + /** + * @brief Fill in missing internal data. + */ + private void FillInStuff() + { + int nArgs; + + // This happens when the node was restored via ReadFromFile(). + // It leaves the types in retStr/argStrs for resolution after + // all definitions have been read from the object file in case + // there are forward references. + if(retType == null) + { + retType = MakeTypeToken(retStr); + } + if(argTypes == null) + { + nArgs = argStrs.Length; + argTypes = new TokenType[nArgs]; + for(int i = 0; i < nArgs; i++) + { + argTypes[i] = MakeTypeToken(argStrs[i]); + } + } + + // Fill in system types from token types. + // Might as well build the signature strings too from token types. + retSysType = retType.ToSysType(); + + nArgs = argTypes.Length; + StringBuilder sb = new StringBuilder(); + argSysTypes = new Type[nArgs]; + sb.Append('('); + for(int i = 0; i < nArgs; i++) + { + if(i > 0) + sb.Append(','); + sb.Append(argTypes[i].ToString()); + argSysTypes[i] = argTypes[i].ToSysType(); + } + sb.Append(')'); + argSig = sb.ToString(); + wholeSig = retType.ToString() + argSig; + + // Now we can create a system delegate type from the given + // return and argument types. Give it an unique name using + // the whole signature string. + sysType = DelegateCommon.GetType(retSysType, argSysTypes, wholeSig); + } + + /** + * @brief create delegate reference token for inline functions. + * there is just one instance of these per inline function + * shared by all scripts, and it is just used when the + * script engine is loaded. + */ + public static TokenDeclSDTypeDelegate CreateInline(TokenType retType, TokenType[] argTypes) + { + TokenDeclSDTypeDelegate decldel; + + // Name it after the whole signature string. + StringBuilder sb = new StringBuilder("$inline"); + sb.Append(retType.ToString()); + sb.Append("("); + bool first = true; + foreach(TokenType at in argTypes) + { + if(!first) + sb.Append(","); + sb.Append(at.ToString()); + first = false; + } + sb.Append(")"); + string inlname = sb.ToString(); + if(!inlines.TryGetValue(inlname, out decldel)) + { + // Create the corresponding declaration and link to it + TokenName name = new TokenName(null, inlname); + decldel = new TokenDeclSDTypeDelegate(name); + decldel.retType = retType; + decldel.argTypes = argTypes; + inlines.Add(inlname, decldel); + inlrevs.Add(decldel.GetSysType(), inlname); + } + return decldel; + } + + public static string TryGetInlineName(Type sysType) + { + string name; + if(!inlrevs.TryGetValue(sysType, out name)) + return null; + return name; + } + + public static Type TryGetInlineSysType(string name) + { + TokenDeclSDTypeDelegate decl; + if(!inlines.TryGetValue(name, out decl)) + return null; + return decl.GetSysType(); + } + } + + public class TokenDeclSDTypeInterface: TokenDeclSDType + { + public VarDict methsNProps = new VarDict(false); + // any class that implements this interface + // must implement all of these methods & properties + + public List implements = new List(); + // any class that implements this interface + // must also implement all of the methods & properties + // of all of these interfaces + + public TokenDeclSDTypeInterface(TokenName shortName) : base(shortName) + { + this.shortName = shortName; + } + + protected override TokenDeclSDType MakeBlank(TokenName shortName) + { + return new TokenDeclSDTypeInterface(shortName); + } + + public override TokenType MakeRefToken(Token t) + { + return new TokenTypeSDTypeInterface(t, this); + } + + public override Type GetSysType() + { + // interfaces are implemented as arrays of delegates + // they are taken from iDynMeths[interfaceIndex] of a script-defined class object + return typeof(Delegate[]); + } + + public override void WriteToFile(BinaryWriter objFileWriter) + { + objFileWriter.Write(this.file); + objFileWriter.Write(this.line); + objFileWriter.Write(this.posn); + objFileWriter.Write((byte)INTERFACE); + objFileWriter.Write(this.sdTypeIndex); + } + + public override void ReadFromFile(BinaryReader objFileReader, TextWriter asmFileWriter) + { + } + + /** + * @brief Add this interface to the list of interfaces implemented by a class if not already. + * And also add this interface's implemented interfaces to the class for those not already there, + * just as if the class itself had declared to implement those interfaces. + */ + public void AddToClassDecl(TokenDeclSDTypeClass tokdeclcl) + { + if(!tokdeclcl.implements.Contains(this)) + { + tokdeclcl.implements.Add(this); + foreach(TokenDeclSDTypeInterface subimpl in this.implements) + { + subimpl.AddToClassDecl(tokdeclcl); + } + } + } + + /** + * @brief See if the 'this' interface implements the new interface. + * Do a recursive (deep) check. + */ + public bool Implements(TokenDeclSDTypeInterface newDecl) + { + foreach(TokenDeclSDTypeInterface ii in this.implements) + { + if(ii == newDecl) + return true; + if(ii.Implements(newDecl)) + return true; + } + return false; + } + + /** + * @brief Scan an interface and all its implemented interfaces for a method or property + * @param scg = script code generator (ie, which script is being compiled) + * @param fieldName = name of the member being looked for + * @param argsig = the method's argument signature + * @returns null: no such member; intf = undefined + * else: member; intf = which interface actually found in + */ + public TokenDeclVar FindIFaceMember(ScriptCodeGen scg, TokenName fieldName, TokenType[] argsig, out TokenDeclSDTypeInterface intf) + { + intf = this; + TokenDeclVar var = scg.FindSingleMember(this.methsNProps, fieldName, argsig); + if(var == null) + { + foreach(TokenDeclSDTypeInterface ii in this.implements) + { + var = ii.FindIFaceMember(scg, fieldName, argsig, out intf); + if(var != null) + break; + } + } + return var; + } + } + + public class TokenDeclSDTypeTypedef: TokenDeclSDType + { + + public TokenDeclSDTypeTypedef(TokenName shortName) : base(shortName) + { + this.shortName = shortName; + } + + protected override TokenDeclSDType MakeBlank(TokenName shortName) + { + return new TokenDeclSDTypeTypedef(shortName); + } + + public override TokenType MakeRefToken(Token t) + { + // if our body is a single type token, that is what we return + // otherwise return null saying maybe our body needs some substitutions + if(!(this.nextToken is TokenType)) + return null; + if(this.nextToken.nextToken != this.endToken) + { + this.nextToken.nextToken.ErrorMsg("extra tokens for typedef"); + return null; + } + return (TokenType)this.nextToken.CopyToken(t); + } + + public override Type GetSysType() + { + // we are just a macro + // we are asked for system type because we are cataloged + // but we don't really have one so return null + return null; + } + + public override void WriteToFile(BinaryWriter objFileWriter) + { + objFileWriter.Write(this.file); + objFileWriter.Write(this.line); + objFileWriter.Write(this.posn); + objFileWriter.Write((byte)TYPEDEF); + objFileWriter.Write(this.sdTypeIndex); + } + + public override void ReadFromFile(BinaryReader objFileReader, TextWriter asmFileWriter) + { + } + } + + /** + * @brief Script-defined type references. + * These occur in the source code wherever it specifies (eg, variable declaration) a script-defined type. + * These must be copyable via CopyToken(). + */ + public abstract class TokenTypeSDType: TokenType + { + public TokenTypeSDType(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { } + public TokenTypeSDType(Token t) : base(t) { } + public abstract TokenDeclSDType GetDecl(); + public abstract void SetDecl(TokenDeclSDType decl); + } + + public class TokenTypeSDTypeClass: TokenTypeSDType + { + private static readonly FieldInfo iarSDTClObjsFieldInfo = typeof(XMRInstArrays).GetField("iarSDTClObjs"); + + public TokenDeclSDTypeClass decl; + + public TokenTypeSDTypeClass(Token t, TokenDeclSDTypeClass decl) : base(t) + { + this.decl = decl; + } + public override TokenDeclSDType GetDecl() + { + return decl; + } + public override void SetDecl(TokenDeclSDType decl) + { + this.decl = (TokenDeclSDTypeClass)decl; + } + public override string ToString() + { + return decl.longName.val; + } + public override Type ToSysType() + { + return typeof(XMRSDTypeClObj); + } + + public override void AssignVarSlot(TokenDeclVar declVar, XMRInstArSizes ias) + { + declVar.vTableArray = iarSDTClObjsFieldInfo; + declVar.vTableIndex = ias.iasSDTClObjs++; + } + + // debugging + public override void DebString(StringBuilder sb) + { + sb.Append(decl.longName); + } + } + + public class TokenTypeSDTypeDelegate: TokenTypeSDType + { + private static readonly FieldInfo iarObjectsFieldInfo = typeof(XMRInstArrays).GetField("iarObjects"); + + public TokenDeclSDTypeDelegate decl; + + /** + * @brief create a reference to an explicitly declared delegate + * @param t = where the reference is being made in the source file + * @param decl = the explicit delegate declaration + */ + public TokenTypeSDTypeDelegate(Token t, TokenDeclSDTypeDelegate decl) : base(t) + { + this.decl = decl; + } + public override TokenDeclSDType GetDecl() + { + return decl; + } + public override void SetDecl(TokenDeclSDType decl) + { + this.decl = (TokenDeclSDTypeDelegate)decl; + } + + /** + * @brief create a reference to a possibly anonymous delegate + * @param t = where the reference is being made in the source file + * @param retType = return type (TokenTypeVoid if void, never null) + * @param argTypes = script-visible argument types + * @param tokenScript = what script this is part of + */ + public TokenTypeSDTypeDelegate(Token t, TokenType retType, TokenType[] argTypes, TokenScript tokenScript) : base(t) + { + TokenDeclSDTypeDelegate decldel; + + // See if we already have a matching declared one cataloged. + int nArgs = argTypes.Length; + foreach(TokenDeclSDType decl in tokenScript.sdSrcTypesValues) + { + if(decl is TokenDeclSDTypeDelegate) + { + decldel = (TokenDeclSDTypeDelegate)decl; + TokenType rt = decldel.GetRetType(); + TokenType[] ats = decldel.GetArgTypes(); + if((rt.ToString() == retType.ToString()) && (ats.Length == nArgs)) + { + for(int i = 0; i < nArgs; i++) + { + if(ats[i].ToString() != argTypes[i].ToString()) + goto nomatch; + } + this.decl = decldel; + return; + } + } + nomatch: + ; + } + + // No such luck, create a new anonymous declaration. + StringBuilder sb = new StringBuilder("$anondel$"); + sb.Append(retType.ToString()); + sb.Append("("); + bool first = true; + foreach(TokenType at in argTypes) + { + if(!first) + sb.Append(","); + sb.Append(at.ToString()); + first = false; + } + sb.Append(")"); + TokenName name = new TokenName(t, sb.ToString()); + decldel = new TokenDeclSDTypeDelegate(name); + decldel.SetRetArgTypes(retType, argTypes); + tokenScript.sdSrcTypesAdd(name.val, decldel); + this.decl = decldel; + } + + public override Type ToSysType() + { + return decl.GetSysType(); + } + + public override string ToString() + { + return decl.longName.val; + } + + /** + * @brief Assign slots in the gblObjects[] array because we have to typecast out in any case. + * Likewise with the sdtcObjects[] array. + */ + public override void AssignVarSlot(TokenDeclVar declVar, XMRInstArSizes ias) + { + declVar.vTableArray = iarObjectsFieldInfo; + declVar.vTableIndex = ias.iasObjects++; + } + + /** + * @brief create delegate reference token for inline functions. + */ + public TokenTypeSDTypeDelegate(TokenType retType, TokenType[] argTypes) : base(null) + { + this.decl = TokenDeclSDTypeDelegate.CreateInline(retType, argTypes); + } + + // debugging + public override void DebString(StringBuilder sb) + { + sb.Append(decl.longName); + } + } + + public class TokenTypeSDTypeInterface: TokenTypeSDType + { + private static readonly FieldInfo iarSDTIntfObjsFieldInfo = typeof(XMRInstArrays).GetField("iarSDTIntfObjs"); + + public TokenDeclSDTypeInterface decl; + + public TokenTypeSDTypeInterface(Token t, TokenDeclSDTypeInterface decl) : base(t) + { + this.decl = decl; + } + public override TokenDeclSDType GetDecl() + { + return decl; + } + public override void SetDecl(TokenDeclSDType decl) + { + this.decl = (TokenDeclSDTypeInterface)decl; + } + + public override string ToString() + { + return decl.longName.val; + } + public override Type ToSysType() + { + return typeof(Delegate[]); + } + + /** + * @brief Assign slots in the gblSDTIntfObjs[] array + * Likewise with the sdtcSDTIntfObjs[] array. + */ + public override void AssignVarSlot(TokenDeclVar declVar, XMRInstArSizes ias) + { + declVar.vTableArray = iarSDTIntfObjsFieldInfo; + declVar.vTableIndex = ias.iasSDTIntfObjs++; + } + + // debugging + public override void DebString(StringBuilder sb) + { + sb.Append(decl.longName); + } + } + + /** + * @brief function argument list declaration + */ + public class TokenArgDecl: Token + { + public VarDict varDict = new VarDict(false); + + public TokenArgDecl(Token original) : base(original) { } + + public bool AddArg(TokenType type, TokenName name) + { + TokenDeclVar var = new TokenDeclVar(name, null, null); + var.name = name; + var.type = type; + var.vTableIndex = varDict.Count; + return varDict.AddEntry(var); + } + + /** + * @brief Get an array of the argument types. + */ + private TokenType[] _types; + public TokenType[] types + { + get + { + if(_types == null) + { + _types = new TokenType[varDict.Count]; + foreach(TokenDeclVar var in varDict) + { + _types[var.vTableIndex] = var.type; + } + } + return _types; + } + } + + /** + * @brief Access the arguments as an array of variables. + */ + private TokenDeclVar[] _vars; + public TokenDeclVar[] vars + { + get + { + if(_vars == null) + { + _vars = new TokenDeclVar[varDict.Count]; + foreach(TokenDeclVar var in varDict) + { + _vars[var.vTableIndex] = var; + } + } + return _vars; + } + } + + /** + * @brief Get argument signature string, eg, "(list,vector,integer)" + */ + private string argSig = null; + public string GetArgSig() + { + if(argSig == null) + { + argSig = ScriptCodeGen.ArgSigString(types); + } + return argSig; + } + } + + /** + * @brief encapsulate a state declaration in a single token + */ + public class TokenDeclState: Token + { + + public TokenName name; // null for default state + public TokenStateBody body; + + public TokenDeclState(Token original) : base(original) { } + + public override void DebString(StringBuilder sb) + { + if(name == null) + { + sb.Append("default"); + } + else + { + sb.Append("state "); + sb.Append(name); + } + body.DebString(sb); + } + } + + /** + * @brief encapsulate the declaration of a field/function/method/property/variable. + */ + + public enum Triviality + { // function triviality: has no loops and doesn't call anything that has loops + // such a function does not need all the CheckRun() and stack serialization stuff + unknown, // function's Triviality unknown as of yet + // - it does not have any loops or backward gotos + // - nothing it calls is known to be complex + trivial, // function known to be trivial + // - it does not have any loops or backward gotos + // - everything it calls is known to be trivial + complex, // function known to be complex + // - it has loops or backward gotos + // - something it calls is known to be complex + analyzing // triviality is being analyzed (used to detect recursive loops) + }; + + public class TokenDeclVar: TokenStmt + { + public TokenName name; // vars: name; funcs: bare name, ie, no signature + public TokenRVal init; // vars: null if none; funcs: null + public bool constant; // vars: 'constant'; funcs: false + public uint sdtFlags; // SDT_<*> flags + + public CompValu location; // used by codegen to keep track of location + public FieldInfo vTableArray; + public int vTableIndex = -1; // local vars: not used (-1) + // arg vars: index in the arg list + // global vars: which slot in gbls[] array it is stored + // instance vars: which slot in insts[] array it is stored + // static vars: which slot in gbls[] array it is stored + // global funcs: not used (-1) + // virt funcs: which slot in vTable[] array it is stored + // instance func: not used (-1) + public TokenDeclVar getProp; // if property, function that reads value + public TokenDeclVar setProp; // if property, function that writes value + + public TokenScript tokenScript; // what script this function is part of + public TokenDeclSDType sdtClass; // null: script global member + // else: member is part of this script-defined type + + // function-only data: + + public TokenType retType; // vars: null; funcs: TokenTypeVoid if void + public TokenArgDecl argDecl; // vars: null; funcs: argument list prototypes + public TokenStmtBlock body; // vars: null; funcs: statements (null iff abstract) + public Dictionary labels = new Dictionary(); + // all labels defined in the function + public LinkedList localVars = new LinkedList(); + // all local variables declared by this function + // - doesn't include argument variables + public TokenIntfImpl implements; // if script-defined type method, what interface method(s) this func implements + public TokenRValCall baseCtorCall; // if script-defined type constructor, call to base constructor, if any + public Triviality triviality = Triviality.unknown; + // vars: unknown (not used for any thing); funcs: unknown/trivial/complex + public LinkedList unknownTrivialityCalls = new LinkedList(); + // reduction puts all calls here + // compilation sorts it all out + + public ScriptObjWriter ilGen; // codegen stores emitted code here + + /** + * @brief Set up a variable declaration token. + * @param original = original source token that triggered definition + * (for error messages) + * @param func = null: global variable + * else: local to the given function + */ + public TokenDeclVar(Token original, TokenDeclVar func, TokenScript ts) : base(original) + { + if(func != null) + { + func.localVars.AddLast(this); + } + tokenScript = ts; + } + + /** + * @brief Get/Set overall type + * For vars, this is the type of the location + * For funcs, this is the delegate type + */ + private TokenType _type; + public TokenType type + { + get + { + if(_type == null) + { + GetDelType(); + } + return _type; + } + set + { + _type = value; + } + } + + /** + * @brief Full name: .() + * () missing for fields/variables + * . missing for top-level functions/variables + */ + public string fullName + { + get + { + if(sdtClass == null) + { + if(retType == null) + return name.val; + return funcNameSig.val; + } + string ln = sdtClass.longName.val; + if(retType == null) + return ln + "." + name.val; + return ln + "." + funcNameSig.val; + } + } + + /** + * @brief See if reading or writing the variable is trivial. + * Note that for functions, this is reading the function itself, + * as in 'someDelegate = SomeFunction;', not calling it as such. + * The triviality of actually calling the function is IsFuncTrivial(). + */ + public bool IsVarTrivial(ScriptCodeGen scg) + { + // reading or writing a property involves a function call however + // so we need to check the triviality of the property functions + if((getProp != null) && !getProp.IsFuncTrivial(scg)) + return false; + if((setProp != null) && !setProp.IsFuncTrivial(scg)) + return false; + + // otherwise for variables it is a trivial access + // and likewise for getting a delegate that points to a function + return true; + } + + /***************************\ + * FUNCTION-only methods * + \***************************/ + + private TokenName _funcNameSig; // vars: null; funcs: function name including argumet signature, eg, "PrintStuff(list,string)" + public TokenName funcNameSig + { + get + { + if(_funcNameSig == null) + { + if(argDecl == null) + return null; + _funcNameSig = new TokenName(name, name.val + argDecl.GetArgSig()); + } + return _funcNameSig; + } + } + + /** + * @brief The bare function name, ie, without any signature info + */ + public string GetSimpleName() + { + return name.val; + } + + /** + * @brief The function name as it appears in the object code, + * ie, script-defined type name if any, + * bare function name and argument signature, + * eg, "MyClass.PrintStuff(string)" + */ + public string GetObjCodeName() + { + string objCodeName = ""; + if(sdtClass != null) + { + objCodeName += sdtClass.longName.val + "."; + } + objCodeName += funcNameSig.val; + return objCodeName; + } + + /** + * @brief Get delegate type. + * This is the function's script-visible type, + * It includes return type and all script-visible argument types. + * @returns null for vars; else delegate type for funcs + */ + public TokenTypeSDTypeDelegate GetDelType() + { + if(argDecl == null) + return null; + if(_type == null) + { + if(tokenScript == null) + { + // used during startup to define inline function delegate types + _type = new TokenTypeSDTypeDelegate(retType, argDecl.types); + } + else + { + // used for normal script processing + _type = new TokenTypeSDTypeDelegate(this, retType, argDecl.types, tokenScript); + } + } + if(!(_type is TokenTypeSDTypeDelegate)) + return null; + return (TokenTypeSDTypeDelegate)_type; + } + + /** + * @brief See if the function's code itself is trivial or not. + * If it contains any loops (calls to CheckRun()), it is not trivial. + * If it calls anything that is not trivial, it is not trivial. + * Otherwise it is trivial. + */ + public bool IsFuncTrivial(ScriptCodeGen scg) + { + // If not really a function, assume it's a delegate. + // And since we don't really know what functions it can point to, + // assume it can point to a non-trivial one. + if(retType == null) + return false; + + // All virtual functions are non-trivial because although a particular + // one might be trivial, it might be overidden with a non-trivial one. + if((sdtFlags & (ScriptReduce.SDT_ABSTRACT | ScriptReduce.SDT_OVERRIDE | + ScriptReduce.SDT_VIRTUAL)) != 0) + { + return false; + } + + // Check the triviality status of the function. + switch(triviality) + { + // Don't yet know if it is trivial. + // We know at this point it doesn't have any direct looping. + // But if it calls something that has loops, it isn't trivial. + // Otherwise it is trivial. + case Triviality.unknown: + { + // Mark that we are analyzing this function now. So if there are + // any recursive call loops, that will show that the function is + // non-trivial and the analysis will terminate at that point. + triviality = Triviality.analyzing; + + // Check out everything else this function calls. If any say they + // aren't trivial, then we say this function isn't trivial. + foreach(TokenRValCall call in unknownTrivialityCalls) + { + if(!call.IsRValTrivial(scg, null)) + { + triviality = Triviality.complex; + return false; + } + } + + // All functions called by this function are trivial, and this + // function's code doesn't have any loops, so we can mark this + // function as being trivial. + triviality = Triviality.trivial; + return true; + } + + // We already know that it is trivial. + case Triviality.trivial: + { + return true; + } + + // We either know it is complex or are trying to analyze it already. + // If we are already analyzing it, it means it has a recursive loop + // and we assume those are non-trivial. + default: + return false; + } + } + + // debugging + public override void DebString(StringBuilder sb) + { + DebStringSDTFlags(sb); + + if(retType == null) + { + sb.Append(constant ? "constant" : type.ToString()); + sb.Append(' '); + sb.Append(name.val); + if(init != null) + { + sb.Append(" = "); + init.DebString(sb); + } + sb.Append(';'); + } + else + { + if(!(retType is TokenTypeVoid)) + { + sb.Append(retType.ToString()); + sb.Append(' '); + } + string namestr = name.val; + if(namestr == "$ctor") + namestr = "constructor"; + sb.Append(namestr); + sb.Append(" ("); + for(int i = 0; i < argDecl.vars.Length; i++) + { + if(i > 0) + sb.Append(", "); + sb.Append(argDecl.vars[i].type.ToString()); + sb.Append(' '); + sb.Append(argDecl.vars[i].name.val); + } + sb.Append(')'); + if(body == null) + sb.Append(';'); + else + { + sb.Append(' '); + body.DebString(sb); + } + } + } + + // debugging + // - used to output contents of a $globalvarinit(), $instfieldinit() or $statisfieldinit() function + // as a series of variable declaration statements with initial value assignments + // so we get the initial value assignments done in same order as specified in script + public void DebStringInitFields(StringBuilder sb) + { + if((retType == null) || !(retType is TokenTypeVoid)) + throw new Exception("bad return type " + retType.GetType().Name); + if(argDecl.vars.Length != 0) + throw new Exception("has " + argDecl.vars.Length + " arg(s)"); + + for(Token stmt = body.statements; stmt != null; stmt = stmt.nextToken) + { + // Body of the function should all be arithmetic statements (not eg for loops, if statements etc). + TokenRVal rval = ((TokenStmtRVal)stmt).rVal; + + // And the opcode should be a simple assignment operator. + TokenRValOpBin rvob = (TokenRValOpBin)rval; + if(!(rvob.opcode is TokenKwAssign)) + throw new Exception("bad op type " + rvob.opcode.GetType().Name); + + // Get field or variable being assigned to. + TokenDeclVar var = null; + TokenRVal left = rvob.rValLeft; + if(left is TokenLValIField) + { + TokenLValIField ifield = (TokenLValIField)left; + TokenRValThis zhis = (TokenRValThis)ifield.baseRVal; + TokenDeclSDTypeClass sdt = zhis.sdtClass; + var = sdt.members.FindExact(ifield.fieldName.val, null); + } + if(left is TokenLValName) + { + TokenLValName global = (TokenLValName)left; + var = global.stack.FindExact(global.name.val, null); + } + if(left is TokenLValSField) + { + TokenLValSField sfield = (TokenLValSField)left; + TokenTypeSDTypeClass sdtc = (TokenTypeSDTypeClass)sfield.baseType; + TokenDeclSDTypeClass decl = sdtc.decl; + var = decl.members.FindExact(sfield.fieldName.val, null); + } + if(var == null) + throw new Exception("unknown var type " + left.GetType().Name); + + // Output flags, type name and bare variable name. + // This should look like a declaration in the 'sb' + // as it is not enclosed in a function. + var.DebStringSDTFlags(sb); + var.type.DebString(sb); + sb.Append(' '); + sb.Append(var.name.val); + + // Maybe it has a non-default initialization value. + if((var.init != null) && !(var.init is TokenRValInitDef)) + { + sb.Append(" = "); + var.init.DebString(sb); + } + + // End of declaration statement. + sb.Append(';'); + } + } + + private void DebStringSDTFlags(StringBuilder sb) + { + if((sdtFlags & ScriptReduce.SDT_PRIVATE) != 0) + sb.Append("private "); + if((sdtFlags & ScriptReduce.SDT_PROTECTED) != 0) + sb.Append("protected "); + if((sdtFlags & ScriptReduce.SDT_PUBLIC) != 0) + sb.Append("public "); + if((sdtFlags & ScriptReduce.SDT_ABSTRACT) != 0) + sb.Append("abstract "); + if((sdtFlags & ScriptReduce.SDT_FINAL) != 0) + sb.Append("final "); + if((sdtFlags & ScriptReduce.SDT_NEW) != 0) + sb.Append("new "); + if((sdtFlags & ScriptReduce.SDT_OVERRIDE) != 0) + sb.Append("override "); + if((sdtFlags & ScriptReduce.SDT_STATIC) != 0) + sb.Append("static "); + if((sdtFlags & ScriptReduce.SDT_VIRTUAL) != 0) + sb.Append("virtual "); + } + } + + /** + * @brief Indicates an interface type.method that is implemented by the function + */ + public class TokenIntfImpl: Token + { + public TokenTypeSDTypeInterface intfType; + public TokenName methName; // simple name, no arg signature + + public TokenIntfImpl(TokenTypeSDTypeInterface intfType, TokenName methName) : base(intfType) + { + this.intfType = intfType; + this.methName = methName; + } + } + + /** + * @brief any expression that can go on left side of an "=" + */ + public abstract class TokenLVal: TokenRVal + { + public TokenLVal(Token original) : base(original) { } + public abstract override TokenType GetRValType(ScriptCodeGen scg, TokenType[] argsig); + public abstract override bool IsRValTrivial(ScriptCodeGen scg, TokenType[] argsig); + } + + /** + * @brief an element of an array is an L-value + */ + public class TokenLValArEle: TokenLVal + { + public TokenRVal baseRVal; + public TokenRVal subRVal; + + public TokenLValArEle(Token original) : base(original) { } + + public override TokenType GetRValType(ScriptCodeGen scg, TokenType[] argsig) + { + TokenType baseType = baseRVal.GetRValType(scg, null); + + // Maybe referencing element of a fixed-dimension array. + if((baseType is TokenTypeSDTypeClass) && (((TokenTypeSDTypeClass)baseType).decl.arrayOfType != null)) + { + return ((TokenTypeSDTypeClass)baseType).decl.arrayOfType; + } + + // Maybe referencing $idxprop property of script-defined class or interface. + if(baseType is TokenTypeSDTypeClass) + { + TokenDeclSDTypeClass sdtDecl = ((TokenTypeSDTypeClass)baseType).decl; + TokenDeclVar idxProp = scg.FindSingleMember(sdtDecl.members, new TokenName(this, "$idxprop"), null); + if(idxProp != null) + return idxProp.type; + } + if(baseType is TokenTypeSDTypeInterface) + { + TokenDeclSDTypeInterface sdtDecl = ((TokenTypeSDTypeInterface)baseType).decl; + TokenDeclVar idxProp = sdtDecl.FindIFaceMember(scg, new TokenName(this, "$idxprop"), null, out sdtDecl); + if(idxProp != null) + return idxProp.type; + } + + // Maybe referencing single character of a string. + if((baseType is TokenTypeKey) || (baseType is TokenTypeStr)) + { + return new TokenTypeChar(this); + } + + // Assume XMR_Array element or extracting element from list. + if((baseType is TokenTypeArray) || (baseType is TokenTypeList)) + { + return new TokenTypeObject(this); + } + + scg.ErrorMsg(this, "unknown array reference"); + return new TokenTypeVoid(this); + } + + public override bool IsRValTrivial(ScriptCodeGen scg, TokenType[] argsig) + { + return baseRVal.IsRValTrivial(scg, null) && subRVal.IsRValTrivial(scg, null); + } + + public override void DebString(StringBuilder sb) + { + baseRVal.DebString(sb); + sb.Append('['); + subRVal.DebString(sb); + sb.Append(']'); + } + } + + /** + * @brief 'base.' being used to reference a field/method of the extended class. + */ + public class TokenLValBaseField: TokenLVal + { + public TokenName fieldName; + private TokenDeclSDTypeClass thisClass; + + public TokenLValBaseField(Token original, TokenName fieldName, TokenDeclSDTypeClass thisClass) : base(original) + { + this.fieldName = fieldName; + this.thisClass = thisClass; + } + + public override TokenType GetRValType(ScriptCodeGen scg, TokenType[] argsig) + { + TokenDeclVar var = scg.FindThisMember(thisClass.extends, fieldName, argsig); + if(var != null) + return var.type; + scg.ErrorMsg(fieldName, "unknown member of " + thisClass.extends.ToString()); + return new TokenTypeVoid(fieldName); + } + + public override bool IsRValTrivial(ScriptCodeGen scg, TokenType[] argsig) + { + TokenDeclVar var = scg.FindThisMember(thisClass.extends, fieldName, argsig); + return (var != null) && var.IsVarTrivial(scg); + } + + public override bool IsCallTrivial(ScriptCodeGen scg, TokenType[] argsig) + { + TokenDeclVar var = scg.FindThisMember(thisClass.extends, fieldName, argsig); + return (var != null) && var.IsFuncTrivial(scg); + } + } + + /** + * @brief a field within an struct is an L-value + */ + public class TokenLValIField: TokenLVal + { + public TokenRVal baseRVal; + public TokenName fieldName; + + public TokenLValIField(Token original) : base(original) { } + + public override TokenType GetRValType(ScriptCodeGen scg, TokenType[] argsig) + { + TokenType baseType = baseRVal.GetRValType(scg, null); + if(baseType is TokenTypeSDTypeClass) + { + TokenDeclVar var = scg.FindThisMember((TokenTypeSDTypeClass)baseType, fieldName, argsig); + if(var != null) + return var.type; + } + if(baseType is TokenTypeSDTypeInterface) + { + TokenDeclSDTypeInterface baseIntfDecl = ((TokenTypeSDTypeInterface)baseType).decl; + TokenDeclVar var = baseIntfDecl.FindIFaceMember(scg, fieldName, argsig, out baseIntfDecl); + if(var != null) + return var.type; + } + if(baseType is TokenTypeArray) + { + return XMR_Array.GetRValType(fieldName); + } + if((baseType is TokenTypeRot) || (baseType is TokenTypeVec)) + { + return new TokenTypeFloat(fieldName); + } + scg.ErrorMsg(fieldName, "unknown member of " + baseType.ToString()); + return new TokenTypeVoid(fieldName); + } + + public override bool IsRValTrivial(ScriptCodeGen scg, TokenType[] argsig) + { + // If getting pointer to instance isn't trivial, then accessing the member isn't trivial either. + if(!baseRVal.IsRValTrivial(scg, null)) + return false; + + // Accessing a member of a class depends on the member. + // In the case of a method, this is accessing it as a delegate, not calling it, and + // argsig simply serves as selecting which of possibly overloaded methods to select. + // The case of accessing a property, however, depends on the property implementation, + // as there could be looping inside the property code. + TokenType baseType = baseRVal.GetRValType(scg, null); + if(baseType is TokenTypeSDTypeClass) + { + TokenDeclVar var = scg.FindThisMember((TokenTypeSDTypeClass)baseType, fieldName, argsig); + return (var != null) && var.IsVarTrivial(scg); + } + + // Accessing the members of anything else (arrays, rotations, vectors) is always trivial. + return true; + } + + /** + * @brief Check to see if the case of calling an instance method of some object is trivial. + * @param scg = script making the call + * @param argsig = argument types of the call (used to select among overloads) + * @returns true iff we can tell at compile time that the call will always call a trivial method + */ + public override bool IsCallTrivial(ScriptCodeGen scg, TokenType[] argsig) + { + // If getting pointer to instance isn't trivial, then calling the method isn't trivial either. + if(!baseRVal.IsRValTrivial(scg, null)) + return false; + + // Calling a method of a class depends on the method. + TokenType baseType = baseRVal.GetRValType(scg, null); + if(baseType is TokenTypeSDTypeClass) + { + TokenDeclVar var = scg.FindThisMember((TokenTypeSDTypeClass)baseType, fieldName, argsig); + return (var != null) && var.IsFuncTrivial(scg); + } + + // Calling via a pointer to an interface instance is never trivial. + // (It is really a pointer to an array of delegates). + // We can't tell for this call site whether the actual method being called is trivial or not, + // so we have to assume it isn't. + // ??? We could theoretically check to see if *all* implementations of this method of + // this interface are trivial, then we could conclude that this call is trivial. + if(baseType is TokenTypeSDTypeInterface) + return false; + + // Calling a method of anything else (arrays, rotations, vectors) is always trivial. + // Even methods of delegates, such as ".GetArgTypes()" that we may someday do is trivial. + return true; + } + + // debugging + public override void DebString(StringBuilder sb) + { + baseRVal.DebString(sb); + sb.Append('.'); + sb.Append(fieldName.val); + } + } + + /** + * @brief a name is being used as an L-value + */ + public class TokenLValName: TokenLVal + { + public TokenName name; + public VarDict stack; + + public TokenLValName(TokenName name, VarDict stack) : base(name) + { + // Save name of variable/method/function/field. + this.name = name; + + // Save where in the stack it can be looked up. + // If the current stack is for locals, do not allow forward references. + // this allows idiocy like: + // list buttons = [ 1, 2, 3 ]; + // x () { + // list buttons = llList2List (buttons, 0, 1); + // llOwnerSay (llList2CSV (buttons)); + // } + // If it is not locals, allow forward references. + // this allows function X() to call Y() and Y() to call X(). + this.stack = stack.FreezeLocals(); + } + + public override TokenType GetRValType(ScriptCodeGen scg, TokenType[] argsig) + { + TokenDeclVar var = scg.FindNamedVar(this, argsig); + if(var != null) + return var.type; + scg.ErrorMsg(name, "undefined name " + name.val + ScriptCodeGen.ArgSigString(argsig)); + return new TokenTypeVoid(name); + } + + public override bool IsRValTrivial(ScriptCodeGen scg, TokenType[] argsig) + { + TokenDeclVar var = scg.FindNamedVar(this, argsig); + return (var != null) && var.IsVarTrivial(scg); + } + + /** + * @brief Check to see if the case of calling a global method is trivial. + * @param scg = script making the call + * @param argsig = argument types of the call (used to select among overloads) + * @returns true iff we can tell at compile time that the call will always call a trivial method + */ + public override bool IsCallTrivial(ScriptCodeGen scg, TokenType[] argsig) + { + TokenDeclVar var = scg.FindNamedVar(this, argsig); + return (var != null) && var.IsFuncTrivial(scg); + } + + // debugging + public override void DebString(StringBuilder sb) + { + sb.Append(name.val); + } + } + + /** + * @brief a static field within a struct is an L-value + */ + public class TokenLValSField: TokenLVal + { + public TokenType baseType; + public TokenName fieldName; + + public TokenLValSField(Token original) : base(original) { } + + public override TokenType GetRValType(ScriptCodeGen scg, TokenType[] argsig) + { + if(baseType is TokenTypeSDTypeClass) + { + TokenDeclVar var = scg.FindThisMember((TokenTypeSDTypeClass)baseType, fieldName, argsig); + if(var != null) + return var.type; + } + scg.ErrorMsg(fieldName, "unknown member of " + baseType.ToString()); + return new TokenTypeVoid(fieldName); + } + + public override bool IsRValTrivial(ScriptCodeGen scg, TokenType[] argsig) + { + // Accessing a member of a class depends on the member. + // In the case of a method, this is accessing it as a delegate, not calling it, and + // argsig simply serves as selecting which of possibly overloaded methods to select. + // The case of accessing a property, however, depends on the property implementation, + // as there could be looping inside the property code. + if(baseType is TokenTypeSDTypeClass) + { + TokenDeclVar var = scg.FindThisMember((TokenTypeSDTypeClass)baseType, fieldName, argsig); + return (var != null) && var.IsVarTrivial(scg); + } + + // Accessing the fields/methods/properties of anything else (arrays, rotations, vectors) is always trivial. + return true; + } + + /** + * @brief Check to see if the case of calling a class' static method is trivial. + * @param scg = script making the call + * @param argsig = argument types of the call (used to select among overloads) + * @returns true iff we can tell at compile time that the call will always call a trivial method + */ + public override bool IsCallTrivial(ScriptCodeGen scg, TokenType[] argsig) + { + // Calling a static method of a class depends on the method. + if(baseType is TokenTypeSDTypeClass) + { + TokenDeclVar var = scg.FindThisMember((TokenTypeSDTypeClass)baseType, fieldName, argsig); + return (var != null) && var.IsFuncTrivial(scg); + } + + // Calling a static method of anything else (arrays, rotations, vectors) is always trivial. + return true; + } + + public override void DebString(StringBuilder sb) + { + if(fieldName.val == "$new") + { + sb.Append("new "); + baseType.DebString(sb); + } + else + { + baseType.DebString(sb); + sb.Append('.'); + fieldName.DebString(sb); + } + } + } + + /** + * @brief any expression that can go on right side of "=" + */ + public delegate TokenRVal TCCLookup(TokenRVal rVal, ref bool didOne); + public abstract class TokenRVal: Token + { + public TokenRVal(Token original) : base(original) { } + + /** + * @brief Tell us the type of the expression. + */ + public abstract TokenType GetRValType(ScriptCodeGen scg, TokenType[] argsig); + + /** + * @brief Tell us if reading and writing the value is trivial. + * + * @param scg = script code generator of script making the access + * @param argsig = argument types of the call (used to select among overloads) + * @returns true: we can tell at compile time that reading/writing this location + * will always be trivial (no looping or CheckRun() calls possible). + * false: otherwise + */ + public abstract bool IsRValTrivial(ScriptCodeGen scg, TokenType[] argsig); + + /** + * @brief Tell us if calling the method is trivial. + * + * This is the default implementation that returns false. + * It is only used if the location is holding a delegate + * and the method that the delegate is pointing to is being + * called. Since we can't tell if the actual runtime method + * is trivial or not, we assume it isn't. + * + * For the more usual ways of calling functions, see the + * various overrides of IsCallTrivial(). + * + * @param scg = script code generator of script making the call + * @param argsig = argument types of the call (used to select among overloads) + * @returns true: we can tell at compile time that this call will always + * be to a trivial function/method (no looping or CheckRun() + * calls possible). + * false: otherwise + */ + public virtual bool IsCallTrivial(ScriptCodeGen scg, TokenType[] argsig) + { + return false; + } + + /** + * @brief If the result of the expression is a constant, + * create a TokenRValConst equivalent, set didOne, and return that. + * Otherwise, just return the original without changing didOne. + */ + public virtual TokenRVal TryComputeConstant(TCCLookup lookup, ref bool didOne) + { + return lookup(this, ref didOne); + } + } + + /** + * @brief a postfix operator and corresponding L-value + */ + public class TokenRValAsnPost: TokenRVal + { + public TokenLVal lVal; + public Token postfix; + + public TokenRValAsnPost(Token original) : base(original) { } + + public override TokenType GetRValType(ScriptCodeGen scg, TokenType[] argsig) + { + return lVal.GetRValType(scg, argsig); + } + + public override bool IsRValTrivial(ScriptCodeGen scg, TokenType[] argsig) + { + return lVal.IsRValTrivial(scg, null); + } + + public override void DebString(StringBuilder sb) + { + lVal.DebString(sb); + sb.Append(' '); + postfix.DebString(sb); + } + } + + /** + * @brief a prefix operator and corresponding L-value + */ + public class TokenRValAsnPre: TokenRVal + { + public Token prefix; + public TokenLVal lVal; + + public TokenRValAsnPre(Token original) : base(original) { } + + public override TokenType GetRValType(ScriptCodeGen scg, TokenType[] argsig) + { + return lVal.GetRValType(scg, argsig); + } + + public override bool IsRValTrivial(ScriptCodeGen scg, TokenType[] argsig) + { + return lVal.IsRValTrivial(scg, null); + } + + public override void DebString(StringBuilder sb) + { + prefix.DebString(sb); + sb.Append(' '); + lVal.DebString(sb); + } + } + + /** + * @brief calling a function or method, ie, may have side-effects + */ + public class TokenRValCall: TokenRVal + { + + public TokenRVal meth; // points to the function to be called + // - might be a reference to a global function (TokenLValName) + // - or an instance method of a class (TokenLValIField) + // - or a static method of a class (TokenLValSField) + // - or a delegate stored in a variable (assumption for anything else) + public TokenRVal args; // null-terminated TokenRVal list + public int nArgs; // number of elements in args + + public TokenRValCall(Token original) : base(original) { } + + private TokenType[] myArgSig; + + /** + * @brief The type of a call is the type of the return value. + */ + public override TokenType GetRValType(ScriptCodeGen scg, TokenType[] argsig) + { + // Build type signature so we select correct overloaded function. + if(myArgSig == null) + { + myArgSig = new TokenType[nArgs]; + int i = 0; + for(Token t = args; t != null; t = t.nextToken) + { + myArgSig[i++] = ((TokenRVal)t).GetRValType(scg, null); + } + } + + // Get the type of the method itself. This should get us a delegate type. + TokenType delType = meth.GetRValType(scg, myArgSig); + if(!(delType is TokenTypeSDTypeDelegate)) + { + scg.ErrorMsg(meth, "must be function or method"); + return new TokenTypeVoid(meth); + } + + // Get the return type from the delegate type. + return ((TokenTypeSDTypeDelegate)delType).decl.GetRetType(); + } + + /** + * @brief See if the call to the function/method is trivial. + * It is trivial if all the argument computations are trivial and + * the function is not being called via virtual table or delegate + * and the function body is trivial. + */ + public override bool IsRValTrivial(ScriptCodeGen scg, TokenType[] argsig) + { + // Build type signature so we select correct overloaded function. + if(myArgSig == null) + { + myArgSig = new TokenType[nArgs]; + int i = 0; + for(Token t = args; t != null; t = t.nextToken) + { + myArgSig[i++] = ((TokenRVal)t).GetRValType(scg, null); + } + } + + // Make sure all arguments can be computed trivially. + for(Token t = args; t != null; t = t.nextToken) + { + if(!((TokenRVal)t).IsRValTrivial(scg, null)) + return false; + } + + // See if the function call itself and the function body are trivial. + return meth.IsCallTrivial(scg, myArgSig); + } + + // debugging + public override void DebString(StringBuilder sb) + { + meth.DebString(sb); + sb.Append(" ("); + bool first = true; + for(Token t = args; t != null; t = t.nextToken) + { + if(!first) + sb.Append(", "); + t.DebString(sb); + first = false; + } + sb.Append(")"); + } + } + + /** + * @brief encapsulates a typecast, ie, (type) + */ + public class TokenRValCast: TokenRVal + { + public TokenType castTo; + public TokenRVal rVal; + + public TokenRValCast(TokenType type, TokenRVal value) : base(type) + { + castTo = type; + rVal = value; + } + + public override TokenType GetRValType(ScriptCodeGen scg, TokenType[] argsig) + { + return castTo; + } + + public override bool IsRValTrivial(ScriptCodeGen scg, TokenType[] argsig) + { + argsig = null; + if(castTo is TokenTypeSDTypeDelegate) + { + argsig = ((TokenTypeSDTypeDelegate)castTo).decl.GetArgTypes(); + } + return rVal.IsRValTrivial(scg, argsig); + } + + /** + * @brief If operand is constant, maybe we can say the whole thing is a constant. + */ + public override TokenRVal TryComputeConstant(TCCLookup lookup, ref bool didOne) + { + rVal = rVal.TryComputeConstant(lookup, ref didOne); + if(rVal is TokenRValConst) + { + try + { + object val = ((TokenRValConst)rVal).val; + object nval = null; + if(castTo is TokenTypeChar) + { + if(val is char) + return rVal; + if(val is int) + nval = (char)(int)val; + } + if(castTo is TokenTypeFloat) + { + if(val is double) + return rVal; + if(val is int) + nval = (double)(int)val; + if(val is string) + nval = new LSL_Float((string)val).value; + } + if(castTo is TokenTypeInt) + { + if(val is int) + return rVal; + if(val is char) + nval = (int)(char)val; + if(val is double) + nval = (int)(double)val; + if(val is string) + nval = new LSL_Integer((string)val).value; + } + if(castTo is TokenTypeRot) + { + if(val is LSL_Rotation) + return rVal; + if(val is string) + nval = new LSL_Rotation((string)val); + } + if((castTo is TokenTypeKey) || (castTo is TokenTypeStr)) + { + if(val is string) + nval = val; // in case of key/string conversion + if(val is char) + nval = TypeCast.CharToString((char)val); + if(val is double) + nval = TypeCast.FloatToString((double)val); + if(val is int) + nval = TypeCast.IntegerToString((int)val); + if(val is LSL_Rotation) + nval = TypeCast.RotationToString((LSL_Rotation)val); + if(val is LSL_Vector) + nval = TypeCast.VectorToString((LSL_Vector)val); + } + if(castTo is TokenTypeVec) + { + if(val is LSL_Vector) + return rVal; + if(val is string) + nval = new LSL_Vector((string)val); + } + if(nval != null) + { + TokenRVal rValConst = new TokenRValConst(castTo, nval); + didOne = true; + return rValConst; + } + } + catch + { + } + } + return this; + } + + public override void DebString(StringBuilder sb) + { + sb.Append('('); + castTo.DebString(sb); + sb.Append(')'); + rVal.DebString(sb); + } + } + + /** + * @brief Encapsulate a conditional expression: + * ? : + */ + public class TokenRValCondExpr: TokenRVal + { + public TokenRVal condExpr; + public TokenRVal trueExpr; + public TokenRVal falseExpr; + + public TokenRValCondExpr(Token original) : base(original) + { + } + + public override TokenType GetRValType(ScriptCodeGen scg, TokenType[] argsig) + { + TokenType trueType = trueExpr.GetRValType(scg, argsig); + TokenType falseType = falseExpr.GetRValType(scg, argsig); + if(trueType.ToString() != falseType.ToString()) + { + scg.ErrorMsg(condExpr, "true & false expr types don't match"); + } + return trueType; + } + + public override bool IsRValTrivial(ScriptCodeGen scg, TokenType[] argsig) + { + return condExpr.IsRValTrivial(scg, null) && + trueExpr.IsRValTrivial(scg, argsig) && + falseExpr.IsRValTrivial(scg, argsig); + } + + /** + * @brief If condition is constant, then the whole expression is constant + * iff the corresponding trueExpr or falseExpr is constant. + */ + public override TokenRVal TryComputeConstant(TCCLookup lookup, ref bool didOne) + { + TokenRVal rValCond = condExpr.TryComputeConstant(lookup, ref didOne); + if(rValCond is TokenRValConst) + { + didOne = true; + bool isTrue = ((TokenRValConst)rValCond).IsConstBoolTrue(); + return (isTrue ? trueExpr : falseExpr).TryComputeConstant(lookup, ref didOne); + } + return this; + } + + // debugging + public override void DebString(StringBuilder sb) + { + condExpr.DebString(sb); + sb.Append(" ? "); + trueExpr.DebString(sb); + sb.Append(" : "); + falseExpr.DebString(sb); + } + } + + /** + * @brief all constants supposed to end up here + */ + public enum TokenRValConstType: byte { CHAR = 0, FLOAT = 1, INT = 2, KEY = 3, STRING = 4 }; + public class TokenRValConst: TokenRVal + { + public object val; // always a system type (char, int, double, string), never LSL-wrapped + public TokenRValConstType type; + public TokenType tokType; + + public TokenRValConst(Token original, object value) : base(original) + { + val = value; + + TokenType tt = null; + if(val is char) + { + type = TokenRValConstType.CHAR; + tt = new TokenTypeChar(this); + } + else if(val is int) + { + type = TokenRValConstType.INT; + tt = new TokenTypeInt(this); + } + else if(val is double) + { + type = TokenRValConstType.FLOAT; + tt = new TokenTypeFloat(this); + } + else if(val is string) + { + type = TokenRValConstType.STRING; + tt = new TokenTypeStr(this); + } + else + { + throw new Exception("invalid constant type " + val.GetType()); + } + + tokType = (original is TokenType) ? (TokenType)original : tt; + if(tokType is TokenTypeKey) + { + type = TokenRValConstType.KEY; + } + } + + public override TokenType GetRValType(ScriptCodeGen scg, TokenType[] argsig) + { + return tokType; + } + + public override bool IsRValTrivial(ScriptCodeGen scg, TokenType[] argsig) + { + return true; + } + + public CompValu GetCompValu() + { + switch(type) + { + case TokenRValConstType.CHAR: + { + return new CompValuChar(tokType, (char)val); + } + case TokenRValConstType.FLOAT: + { + return new CompValuFloat(tokType, (double)val); + } + case TokenRValConstType.INT: + { + return new CompValuInteger(tokType, (int)val); + } + case TokenRValConstType.KEY: + case TokenRValConstType.STRING: + { + return new CompValuString(tokType, (string)val); + } + default: + throw new Exception("unknown type"); + } + } + + public override TokenRVal TryComputeConstant(TCCLookup lookup, ref bool didOne) + { + // gotta end somewhere + return this; + } + + public bool IsConstBoolTrue() + { + switch(type) + { + case TokenRValConstType.CHAR: + { + return (char)val != 0; + } + case TokenRValConstType.FLOAT: + { + return (double)val != 0; + } + case TokenRValConstType.INT: + { + return (int)val != 0; + } + case TokenRValConstType.KEY: + { + return (string)val != "" && (string)val != ScriptBaseClass.NULL_KEY; + } + case TokenRValConstType.STRING: + { + return (string)val != ""; + } + default: + throw new Exception("unknown type"); + } + } + + public override void DebString(StringBuilder sb) + { + if(val is char) + { + sb.Append('\''); + EscapeQuotes(sb, new string(new char[] { (char)val })); + sb.Append('\''); + } + else if(val is int) + { + sb.Append((int)val); + } + else if(val is double) + { + string str = ((double)val).ToString(); + sb.Append(str); + if((str.IndexOf('.') < 0) && + (str.IndexOf('E') < 0) && + (str.IndexOf('e') < 0)) + { + sb.Append(".0"); + } + } + else if(val is string) + { + sb.Append('"'); + EscapeQuotes(sb, (string)val); + sb.Append('"'); + } + else + { + throw new Exception("invalid constant type " + val.GetType()); + } + } + private static void EscapeQuotes(StringBuilder sb, string s) + { + foreach(char c in s) + { + switch(c) + { + case '\n': + { + sb.Append("\\n"); + break; + } + case '\t': + { + sb.Append("\\t"); + break; + } + case '\\': + { + sb.Append("\\\\"); + break; + } + case '\'': + { + sb.Append("\\'"); + break; + } + case '\"': + { + sb.Append("\\\""); + break; + } + default: + { + sb.Append(c); + break; + } + } + } + } + } + + /** + * @brief Default initialization value for the corresponding variable. + */ + public class TokenRValInitDef: TokenRVal + { + public TokenType type; + + public static TokenRValInitDef Construct(TokenDeclVar tokenDeclVar) + { + TokenRValInitDef zhis = new TokenRValInitDef(tokenDeclVar); + zhis.type = tokenDeclVar.type; + return zhis; + } + private TokenRValInitDef(Token original) : base(original) { } + + public override TokenType GetRValType(ScriptCodeGen scg, TokenType[] argsig) + { + return type; + } + + public override bool IsRValTrivial(ScriptCodeGen scg, TokenType[] argsig) + { + // it's always just a constant so it's always very trivial + return true; + } + + public override void DebString(StringBuilder sb) + { + sb.Append("'); + } + } + + /** + * @brief encapsulation of is + */ + public class TokenRValIsType: TokenRVal + { + public TokenRVal rValExp; + public TokenTypeExp typeExp; + + public TokenRValIsType(Token original) : base(original) { } + + public override TokenType GetRValType(ScriptCodeGen scg, TokenType[] argsig) + { + return new TokenTypeBool(rValExp); + } + + public override bool IsRValTrivial(ScriptCodeGen scg, TokenType[] argsig) + { + return rValExp.IsRValTrivial(scg, argsig); + } + } + + /** + * @brief an R-value enclosed in brackets is an LSLList + */ + public class TokenRValList: TokenRVal + { + + public TokenRVal rVal; // null-terminated list of TokenRVal objects + public int nItems; + + public TokenRValList(Token original) : base(original) { } + + public override TokenType GetRValType(ScriptCodeGen scg, TokenType[] argsig) + { + return new TokenTypeList(rVal); + } + + public override bool IsRValTrivial(ScriptCodeGen scg, TokenType[] argsig) + { + for(Token t = rVal; t != null; t = t.nextToken) + { + if(!((TokenRVal)t).IsRValTrivial(scg, null)) + return false; + } + return true; + } + + public override void DebString(StringBuilder sb) + { + bool first = true; + sb.Append('['); + for(Token t = rVal; t != null; t = t.nextToken) + { + if(!first) + sb.Append(','); + sb.Append(' '); + t.DebString(sb); + first = false; + } + sb.Append(" ]"); + } + } + + /** + * @brief encapsulates '$new' arraytype '{' ... '}' + */ + public class TokenRValNewArIni: TokenRVal + { + public TokenType arrayType; + public TokenList valueList; // TokenList : a sub-list + // TokenKwComma : a default value + // TokenRVal : init expression + + public TokenRValNewArIni(Token original) : base(original) + { + valueList = new TokenList(original); + } + + // type of the expression = the array type allocated by $new() + public override TokenType GetRValType(ScriptCodeGen scg, TokenType[] argsig) + { + return arrayType; + } + + // The expression is trivial if all the initializers are trivial. + // An array's constructor is always trivial (no CheckRun() calls). + public override bool IsRValTrivial(ScriptCodeGen scg, TokenType[] argsig) + { + return ListIsTrivial(scg, valueList); + } + private bool ListIsTrivial(ScriptCodeGen scg, TokenList valList) + { + foreach(Token val in valList.tl) + { + if(val is TokenRVal) + { + if(!((TokenRVal)val).IsRValTrivial(scg, null)) + return false; + } + if(val is TokenList) + { + if(!ListIsTrivial(scg, (TokenList)val)) + return false; + } + } + return true; + } + + public override void DebString(StringBuilder sb) + { + sb.Append("new "); + arrayType.DebString(sb); + sb.Append(' '); + valueList.DebString(sb); + } + } + public class TokenList: Token + { + public List tl = new List(); + public TokenList(Token original) : base(original) { } + + public override void DebString(StringBuilder sb) + { + sb.Append('{'); + bool first = true; + foreach(Token t in tl) + { + if(!first) + sb.Append(", "); + t.DebString(sb); + first = false; + } + sb.Append('}'); + } + } + + /** + * @brief a binary operator and its two operands + */ + public class TokenRValOpBin: TokenRVal + { + public TokenRVal rValLeft; + public TokenKw opcode; + public TokenRVal rValRight; + + public TokenRValOpBin(TokenRVal left, TokenKw op, TokenRVal right) : base(op) + { + rValLeft = left; + opcode = op; + rValRight = right; + } + + public override TokenType GetRValType(ScriptCodeGen scg, TokenType[] argsig) + { + // Comparisons and the like always return bool. + string opstr = opcode.ToString(); + if((opstr == "==") || (opstr == "!=") || (opstr == ">=") || (opstr == ">") || + (opstr == "&&") || (opstr == "||") || (opstr == "<=") || (opstr == "<") || + (opstr == "&&&") || (opstr == "|||")) + { + return new TokenTypeBool(opcode); + } + + // Comma is always type of right-hand operand. + if(opstr == ",") + return rValRight.GetRValType(scg, argsig); + + // Assignments are always the type of the left-hand operand, + // including stuff like "+=". + if(opstr.EndsWith("=")) + { + return rValLeft.GetRValType(scg, argsig); + } + + // string+something or something+string is always string. + // except list+something or something+list is always a list. + string lType = rValLeft.GetRValType(scg, argsig).ToString(); + string rType = rValRight.GetRValType(scg, argsig).ToString(); + if((opstr == "+") && ((lType == "list") || (rType == "list"))) + { + return new TokenTypeList(opcode); + } + if((opstr == "+") && ((lType == "key") || (lType == "string") || + (rType == "key") || (rType == "string"))) + { + return new TokenTypeStr(opcode); + } + + // Everything else depends on both operands. + string key = lType + opstr + rType; + BinOpStr binOpStr; + if(BinOpStr.defined.TryGetValue(key, out binOpStr)) + { + return TokenType.FromSysType(opcode, binOpStr.outtype); + } + + scg.ErrorMsg(opcode, "undefined operation " + key); + return new TokenTypeVoid(opcode); + } + + public override bool IsRValTrivial(ScriptCodeGen scg, TokenType[] argsig) + { + return rValLeft.IsRValTrivial(scg, null) && rValRight.IsRValTrivial(scg, null); + } + + /** + * @brief If both operands are constants, maybe we can say the whole thing is a constant. + */ + public override TokenRVal TryComputeConstant(TCCLookup lookup, ref bool didOne) + { + rValLeft = rValLeft.TryComputeConstant(lookup, ref didOne); + rValRight = rValRight.TryComputeConstant(lookup, ref didOne); + if((rValLeft is TokenRValConst) && (rValRight is TokenRValConst)) + { + try + { + object val = opcode.binOpConst(((TokenRValConst)rValLeft).val, + ((TokenRValConst)rValRight).val); + TokenRVal rValConst = new TokenRValConst(opcode, val); + didOne = true; + return rValConst; + } + catch + { + } + } + return this; + } + + // debugging + public override void DebString(StringBuilder sb) + { + rValLeft.DebString(sb); + sb.Append(' '); + sb.Append(opcode.ToString()); + sb.Append(' '); + rValRight.DebString(sb); + } + } + + /** + * @brief an unary operator and its one operand + */ + public class TokenRValOpUn: TokenRVal + { + public TokenKw opcode; + public TokenRVal rVal; + + public TokenRValOpUn(TokenKw op, TokenRVal right) : base(op) + { + opcode = op; + rVal = right; + } + + public override TokenType GetRValType(ScriptCodeGen scg, TokenType[] argsig) + { + if(opcode is TokenKwExclam) + return new TokenTypeInt(opcode); + return rVal.GetRValType(scg, null); + } + + public override bool IsRValTrivial(ScriptCodeGen scg, TokenType[] argsig) + { + return rVal.IsRValTrivial(scg, null); + } + + /** + * @brief If operand is constant, maybe we can say the whole thing is a constant. + */ + public override TokenRVal TryComputeConstant(TCCLookup lookup, ref bool didOne) + { + rVal = rVal.TryComputeConstant(lookup, ref didOne); + if(rVal is TokenRValConst) + { + try + { + object val = opcode.unOpConst(((TokenRValConst)rVal).val); + TokenRVal rValConst = new TokenRValConst(opcode, val); + didOne = true; + return rValConst; + } + catch + { + } + } + return this; + } + + /** + * @brief Serialization/Deserialization. + */ + public TokenRValOpUn(Token original) : base(original) { } + + // debugging + public override void DebString(StringBuilder sb) + { + sb.Append(opcode.ToString()); + rVal.DebString(sb); + } + } + + /** + * @brief an R-value enclosed in parentheses + */ + public class TokenRValParen: TokenRVal + { + + public TokenRVal rVal; + + public TokenRValParen(Token original) : base(original) { } + + public override TokenType GetRValType(ScriptCodeGen scg, TokenType[] argsig) + { + // pass argsig through in this simple case, ie, let + // them do something like (llOwnerSay)("blabla..."); + return rVal.GetRValType(scg, argsig); + } + + public override bool IsRValTrivial(ScriptCodeGen scg, TokenType[] argsig) + { + // pass argsig through in this simple case, ie, let + // them do something like (llOwnerSay)("blabla..."); + return rVal.IsRValTrivial(scg, argsig); + } + + /** + * @brief If operand is constant, we can say the whole thing is a constant. + */ + public override TokenRVal TryComputeConstant(TCCLookup lookup, ref bool didOne) + { + rVal = rVal.TryComputeConstant(lookup, ref didOne); + if(rVal is TokenRValConst) + { + didOne = true; + return rVal; + } + return this; + } + + public override void DebString(StringBuilder sb) + { + sb.Append('('); + rVal.DebString(sb); + sb.Append(')'); + } + } + + public class TokenRValRot: TokenRVal + { + + public TokenRVal xRVal; + public TokenRVal yRVal; + public TokenRVal zRVal; + public TokenRVal wRVal; + + public TokenRValRot(Token original) : base(original) { } + + public override TokenType GetRValType(ScriptCodeGen scg, TokenType[] argsig) + { + return new TokenTypeRot(xRVal); + } + + public override bool IsRValTrivial(ScriptCodeGen scg, TokenType[] argsig) + { + return xRVal.IsRValTrivial(scg, null) && + yRVal.IsRValTrivial(scg, null) && + zRVal.IsRValTrivial(scg, null) && + wRVal.IsRValTrivial(scg, null); + } + + public override void DebString(StringBuilder sb) + { + sb.Append('<'); + xRVal.DebString(sb); + sb.Append(','); + yRVal.DebString(sb); + sb.Append(','); + zRVal.DebString(sb); + sb.Append(','); + wRVal.DebString(sb); + sb.Append('>'); + } + } + + /** + * @brief 'this' is being used as an rval inside an instance method. + */ + public class TokenRValThis: TokenRVal + { + public Token original; + public TokenDeclSDTypeClass sdtClass; + + public TokenRValThis(Token original, TokenDeclSDTypeClass sdtClass) : base(original) + { + this.original = original; + this.sdtClass = sdtClass; + } + + public override TokenType GetRValType(ScriptCodeGen scg, TokenType[] argsig) + { + return sdtClass.MakeRefToken(original); + } + + public override bool IsRValTrivial(ScriptCodeGen scg, TokenType[] argsig) + { + return true; // ldarg.0/starg.0 can't possibly loop + } + + // debugging + public override void DebString(StringBuilder sb) + { + sb.Append("this"); + } + } + + /** + * @brief the 'undef' keyword is being used as a value in an expression. + * It is the null object pointer and has type TokenTypeUndef. + */ + public class TokenRValUndef: TokenRVal + { + Token original; + + public TokenRValUndef(Token original) : base(original) + { + this.original = original; + } + + public override TokenType GetRValType(ScriptCodeGen scg, TokenType[] argsig) + { + return new TokenTypeUndef(original); + } + + public override bool IsRValTrivial(ScriptCodeGen scg, TokenType[] argsig) + { + return true; + } + + public override void DebString(StringBuilder sb) + { + sb.Append("undef"); + } + } + + /** + * @brief put 3 RVals together as a Vector value. + */ + public class TokenRValVec: TokenRVal + { + + public TokenRVal xRVal; + public TokenRVal yRVal; + public TokenRVal zRVal; + + public TokenRValVec(Token original) : base(original) { } + + public override TokenType GetRValType(ScriptCodeGen scg, TokenType[] argsig) + { + return new TokenTypeVec(xRVal); + } + + public override bool IsRValTrivial(ScriptCodeGen scg, TokenType[] argsig) + { + return xRVal.IsRValTrivial(scg, null) && + yRVal.IsRValTrivial(scg, null) && + zRVal.IsRValTrivial(scg, null); + } + + public override void DebString(StringBuilder sb) + { + sb.Append('<'); + xRVal.DebString(sb); + sb.Append(','); + yRVal.DebString(sb); + sb.Append(','); + zRVal.DebString(sb); + sb.Append('>'); + } + } + + /** + * @brief encapsulates the whole script in a single token + */ + public class TokenScript: Token + { + public int expiryDays = Int32.MaxValue; + public TokenDeclState defaultState; + public Dictionary states = new Dictionary(); + public VarDict variablesStack = new VarDict(false); // initial one is used for global functions and variables + public TokenDeclVar globalVarInit; // $globalvarinit function + // - performs explicit global var and static field inits + + private Dictionary sdSrcTypes = new Dictionary(); + private bool sdSrcTypesSealed = false; + + public TokenScript(Token original) : base(original) { } + + /* + * Handle variable definition stack. + * Generally a '{' pushes a new frame and a '}' pops the frame. + * Function parameters are pushed in an additional frame (just outside the body's { ... } block) + */ + public void PushVarFrame(bool locals) + { + PushVarFrame(new VarDict(locals)); + } + public void PushVarFrame(VarDict newFrame) + { + newFrame.outerVarDict = variablesStack; + variablesStack = newFrame; + } + public void PopVarFrame() + { + variablesStack = variablesStack.outerVarDict; + } + public bool AddVarEntry(TokenDeclVar var) + { + return variablesStack.AddEntry(var); + } + + /* + * Handle list of script-defined types. + */ + public void sdSrcTypesSeal() + { + sdSrcTypesSealed = true; + } + public bool sdSrcTypesContainsKey(string key) + { + return sdSrcTypes.ContainsKey(key); + } + public bool sdSrcTypesTryGetValue(string key, out TokenDeclSDType value) + { + return sdSrcTypes.TryGetValue(key, out value); + } + public void sdSrcTypesAdd(string key, TokenDeclSDType value) + { + if(sdSrcTypesSealed) + throw new Exception("sdSrcTypes is sealed"); + value.sdTypeIndex = sdSrcTypes.Count; + sdSrcTypes.Add(key, value); + } + public void sdSrcTypesRep(string key, TokenDeclSDType value) + { + if(sdSrcTypesSealed) + throw new Exception("sdSrcTypes is sealed"); + value.sdTypeIndex = sdSrcTypes[key].sdTypeIndex; + sdSrcTypes[key] = value; + } + public void sdSrcTypesReplace(string key, TokenDeclSDType value) + { + if(sdSrcTypesSealed) + throw new Exception("sdSrcTypes is sealed"); + sdSrcTypes[key] = value; + } + public Dictionary.ValueCollection sdSrcTypesValues + { + get + { + return sdSrcTypes.Values; + } + } + public int sdSrcTypesCount + { + get + { + return sdSrcTypes.Count; + } + } + + /** + * @brief Debug output. + */ + public override void DebString(StringBuilder sb) + { + /* + * Script-defined types. + */ + foreach(TokenDeclSDType srcType in sdSrcTypes.Values) + { + srcType.DebString(sb); + } + + /* + * Global constants. + * Variables are handled by outputting the $globalvarinit function. + */ + foreach(TokenDeclVar var in variablesStack) + { + if(var.constant) + { + var.DebString(sb); + } + } + + /* + * Global functions. + */ + foreach(TokenDeclVar var in variablesStack) + { + if(var == globalVarInit) + { + var.DebStringInitFields(sb); + } + else if(var.retType != null) + { + var.DebString(sb); + } + } + + /* + * States and their event handler functions. + */ + defaultState.DebString(sb); + foreach(TokenDeclState st in states.Values) + { + st.DebString(sb); + } + } + } + + /** + * @brief state body declaration + */ + public class TokenStateBody: Token + { + + public TokenDeclVar eventFuncs; + + public int index = -1; // (codegen) row in ScriptHandlerEventTable (0=default) + + public TokenStateBody(Token original) : base(original) { } + + public override void DebString(StringBuilder sb) + { + sb.Append(" { "); + for(Token t = eventFuncs; t != null; t = t.nextToken) + { + t.DebString(sb); + } + sb.Append(" } "); + } + } + + /** + * @brief a single statement, such as ending on a semicolon or enclosed in braces + * TokenStmt includes the terminating semicolon or the enclosing braces + * Also includes @label; for jump targets. + * Also includes stray ; null statements. + * Also includes local variable declarations with or without initialization value. + */ + public class TokenStmt: Token + { + public TokenStmt(Token original) : base(original) { } + } + + /** + * @brief a group of statements enclosed in braces + */ + public class TokenStmtBlock: TokenStmt + { + public Token statements; // null-terminated list of statements, can also have TokenDeclVar's in here + public TokenStmtBlock outerStmtBlock; // next outer stmtBlock or null if top-level, ie, function definition + public TokenDeclVar function; // function it is part of + public bool isTry; // true iff it's a try statement block + public bool isCatch; // true iff it's a catch statement block + public bool isFinally; // true iff it's a finally statement block + public TokenStmtTry tryStmt; // set iff isTry|isCatch|isFinally is set + + public TokenStmtBlock(Token original) : base(original) { } + + // debugging + public override void DebString(StringBuilder sb) + { + sb.Append("{ "); + for(Token stmt = statements; stmt != null; stmt = stmt.nextToken) + { + stmt.DebString(sb); + } + sb.Append("} "); + } + } + + /** + * @brief definition of branch target name + */ + public class TokenStmtLabel: TokenStmt + { + public TokenName name; // the label's name + public TokenStmtBlock block; // which block it is defined in + public bool hasBkwdRefs = false; + + public bool labelTagged; // code gen: location of label + public ScriptMyLabel labelStruct; + + public TokenStmtLabel(Token original) : base(original) { } + + public override void DebString(StringBuilder sb) + { + sb.Append('@'); + name.DebString(sb); + sb.Append(';'); + } + } + + /** + * @brief those types of RVals with a semi-colon on the end + * that are allowed to stand alone as statements + */ + public class TokenStmtRVal: TokenStmt + { + public TokenRVal rVal; + + public TokenStmtRVal(Token original) : base(original) { } + + // debugging + public override void DebString(StringBuilder sb) + { + rVal.DebString(sb); + sb.Append("; "); + } + } + + public class TokenStmtBreak: TokenStmt + { + public TokenStmtBreak(Token original) : base(original) { } + + public override void DebString(StringBuilder sb) + { + sb.Append("break;"); + } + } + + public class TokenStmtCont: TokenStmt + { + public TokenStmtCont(Token original) : base(original) { } + + public override void DebString(StringBuilder sb) + { + sb.Append("continue;"); + } + } + + /** + * @brief "do" statement + */ + public class TokenStmtDo: TokenStmt + { + + public TokenStmt bodyStmt; + public TokenRValParen testRVal; + + public TokenStmtDo(Token original) : base(original) { } + + public override void DebString(StringBuilder sb) + { + sb.Append("do "); + bodyStmt.DebString(sb); + sb.Append(" while "); + testRVal.DebString(sb); + sb.Append(';'); + } + } + + /** + * @brief "for" statement + */ + public class TokenStmtFor: TokenStmt + { + + public TokenStmt initStmt; // there is always an init statement, though it may be a null statement + public TokenRVal testRVal; // there may or may not be a test (null if not) + public TokenRVal incrRVal; // there may or may not be an increment (null if not) + public TokenStmt bodyStmt; // there is always a body statement, though it may be a null statement + + public TokenStmtFor(Token original) : base(original) { } + + public override void DebString(StringBuilder sb) + { + sb.Append("for ("); + if(initStmt != null) + initStmt.DebString(sb); + else + sb.Append(';'); + if(testRVal != null) + testRVal.DebString(sb); + sb.Append(';'); + if(incrRVal != null) + incrRVal.DebString(sb); + sb.Append(") "); + bodyStmt.DebString(sb); + } + } + + /** + * @brief "foreach" statement + */ + public class TokenStmtForEach: TokenStmt + { + + public TokenLVal keyLVal; + public TokenLVal valLVal; + public TokenRVal arrayRVal; + public TokenStmt bodyStmt; // there is always a body statement, though it may be a null statement + + public TokenStmtForEach(Token original) : base(original) { } + + public override void DebString(StringBuilder sb) + { + sb.Append("foreach ("); + if(keyLVal != null) + keyLVal.DebString(sb); + sb.Append(','); + if(valLVal != null) + valLVal.DebString(sb); + sb.Append(" in "); + arrayRVal.DebString(sb); + sb.Append(')'); + bodyStmt.DebString(sb); + } + } + + public class TokenStmtIf: TokenStmt + { + + public TokenRValParen testRVal; + public TokenStmt trueStmt; + public TokenStmt elseStmt; + + public TokenStmtIf(Token original) : base(original) { } + + public override void DebString(StringBuilder sb) + { + sb.Append("if "); + testRVal.DebString(sb); + sb.Append(" "); + trueStmt.DebString(sb); + if(elseStmt != null) + { + sb.Append(" else "); + elseStmt.DebString(sb); + } + } + } + + public class TokenStmtJump: TokenStmt + { + + public TokenName label; + + public TokenStmtJump(Token original) : base(original) { } + + public override void DebString(StringBuilder sb) + { + sb.Append("jump "); + label.DebString(sb); + sb.Append(';'); + } + } + + public class TokenStmtNull: TokenStmt + { + public TokenStmtNull(Token original) : base(original) { } + + public override void DebString(StringBuilder sb) + { + sb.Append(';'); + } + } + + public class TokenStmtRet: TokenStmt + { + public TokenRVal rVal; // null if void + + public TokenStmtRet(Token original) : base(original) { } + + public override void DebString(StringBuilder sb) + { + sb.Append("return"); + if(rVal != null) + { + sb.Append(' '); + rVal.DebString(sb); + } + sb.Append(';'); + } + } + + /** + * @brief statement that changes the current state. + */ + public class TokenStmtState: TokenStmt + { + public TokenName state; // null for default + + public TokenStmtState(Token original) : base(original) { } + + public override void DebString(StringBuilder sb) + { + sb.Append("state "); + sb.Append((state == null) ? "default" : state.val); + sb.Append(';'); + } + } + + /** + * @brief Encapsulates a whole switch statement including the body and all cases. + */ + public class TokenStmtSwitch: TokenStmt + { + public TokenRValParen testRVal; // the integer index expression + public TokenSwitchCase cases = null; // list of all cases, linked by .nextCase + public TokenSwitchCase lastCase = null; // used during reduce to point to last in 'cases' list + + public TokenStmtSwitch(Token original) : base(original) { } + + public override void DebString(StringBuilder sb) + { + sb.Append("switch "); + testRVal.DebString(sb); + sb.Append('{'); + for(TokenSwitchCase kase = cases; kase != null; kase = kase.nextCase) + { + kase.DebString(sb); + } + sb.Append('}'); + } + } + + /** + * @brief Encapsulates a case/default clause from a switch statement including the + * two values and the corresponding body statements. + */ + public class TokenSwitchCase: Token + { + public TokenSwitchCase nextCase; // next case in source-code order + public TokenRVal rVal1; // null means 'default', else 'case' + public TokenRVal rVal2; // null means 'case expr:', else 'case expr ... expr:' + public TokenStmt stmts; // statements associated with the case + public TokenStmt lastStmt; // used during reduce for building statement list + + public int val1; // codegen: value of rVal1 here + public int val2; // codegen: value of rVal2 here + public ScriptMyLabel label; // codegen: target label here + public TokenSwitchCase nextSortedCase; // codegen: next case in ascending val order + + public string str1; + public string str2; + public TokenSwitchCase lowerCase; + public TokenSwitchCase higherCase; + + public TokenSwitchCase(Token original) : base(original) { } + + public override void DebString(StringBuilder sb) + { + if(rVal1 == null) + { + sb.Append("default: "); + } + else + { + sb.Append("case "); + rVal1.DebString(sb); + if(rVal2 != null) + { + sb.Append(" ... "); + rVal2.DebString(sb); + } + sb.Append(": "); + } + for(Token t = stmts; t != null; t = t.nextToken) + { + t.DebString(sb); + } + } + } + + public class TokenStmtThrow: TokenStmt + { + public TokenRVal rVal; // null if rethrow style + + public TokenStmtThrow(Token original) : base(original) { } + + public override void DebString(StringBuilder sb) + { + sb.Append("throw "); + rVal.DebString(sb); + sb.Append(';'); + } + } + + /** + * @brief Encapsulates related try, catch and finally statements. + */ + public class TokenStmtTry: TokenStmt + { + public TokenStmtBlock tryStmt; + public TokenDeclVar catchVar; // null iff catchStmt is null + public TokenStmtBlock catchStmt; // can be null + public TokenStmtBlock finallyStmt; // can be null + public Dictionary iLeaves = new Dictionary(); + + public TokenStmtTry(Token original) : base(original) { } + + public override void DebString(StringBuilder sb) + { + sb.Append("try "); + tryStmt.DebString(sb); + if(catchStmt != null) + { + sb.Append("catch ("); + sb.Append(catchVar.type.ToString()); + sb.Append(' '); + sb.Append(catchVar.name.val); + sb.Append(") "); + catchStmt.DebString(sb); + } + if(finallyStmt != null) + { + sb.Append("finally "); + finallyStmt.DebString(sb); + } + } + } + + public class IntermediateLeave + { + public ScriptMyLabel jumpIntoLabel; + public ScriptMyLabel jumpAwayLabel; + } + + public class TokenStmtVarIniDef: TokenStmt + { + public TokenLVal var; + public TokenStmtVarIniDef(Token original) : base(original) { } + } + + public class TokenStmtWhile: TokenStmt + { + public TokenRValParen testRVal; + public TokenStmt bodyStmt; + + public TokenStmtWhile(Token original) : base(original) { } + + public override void DebString(StringBuilder sb) + { + sb.Append("while "); + testRVal.DebString(sb); + sb.Append(' '); + bodyStmt.DebString(sb); + } + } + + /** + * @brief type expressions (right-hand of 'is' keyword). + */ + public class TokenTypeExp: Token + { + public TokenTypeExp(Token original) : base(original) { } + } + + public class TokenTypeExpBinOp: TokenTypeExp + { + public TokenTypeExp leftOp; + public Token binOp; + public TokenTypeExp rightOp; + + public TokenTypeExpBinOp(Token original) : base(original) { } + } + + public class TokenTypeExpNot: TokenTypeExp + { + public TokenTypeExp typeExp; + + public TokenTypeExpNot(Token original) : base(original) { } + } + + public class TokenTypeExpPar: TokenTypeExp + { + public TokenTypeExp typeExp; + + public TokenTypeExpPar(Token original) : base(original) { } + } + + public class TokenTypeExpType: TokenTypeExp + { + public TokenType typeToken; + + public TokenTypeExpType(Token original) : base(original) { } + } + + public class TokenTypeExpUndef: TokenTypeExp + { + public TokenTypeExpUndef(Token original) : base(original) { } + } +} diff --git a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptTokenize.cs b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptTokenize.cs new file mode 100644 index 0000000000..6c233bc24c --- /dev/null +++ b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptTokenize.cs @@ -0,0 +1,2948 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @brief Parse raw source file string into token list. + * + * Usage: + * + * emsg = some function to output error messages to + * source = string containing entire source file + * + * TokenBegin tokenBegin = TokenBegin.Construct (emsg, source); + * + * tokenBegin = null: tokenizing error + * else: first (dummy) token in file + * the rest are chained by nextToken,prevToken + * final token is always a (dummy) TokenEnd + */ + +using System; +using System.Collections.Generic; +using System.IO; +using System.Net; +using System.Reflection; +using System.Reflection.Emit; +using System.Text; + +using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; +using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; +using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; +using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list; +using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; +using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; +using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; + +namespace OpenSim.Region.ScriptEngine.Yengine +{ + + public delegate void TokenErrorMessage(Token token, string message); + + /** + * @brief base class for all tokens + */ + public class Token + { + public static readonly int MAX_NAME_LEN = 255; + public static readonly int MAX_STRING_LEN = 4096; + + public Token nextToken; + public Token prevToken; + public bool nr2l; + + // used for error message printing + public TokenErrorMessage emsg; + public string file = ""; + public int line; + public int posn; + public Token copiedFrom; + + /** + * @brief construct a token coming directly from a source file + * @param emsg = object that error messages get sent to + * @param file = source file name (or "" if none) + * @param line = source file line number + * @param posn = token's position within that source line + */ + public Token(TokenErrorMessage emsg, string file, int line, int posn) + { + this.emsg = emsg; + this.file = file; + this.line = line; + this.posn = posn; + } + + /** + * @brief construct a token with same error message parameters + * @param original = original token to create from + */ + public Token(Token original) + { + if(original != null) + { + this.emsg = original.emsg; + this.file = original.file; + this.line = original.line; + this.posn = original.posn; + this.nr2l = original.nr2l; + } + } + + /** + * @brief output an error message associated with this token + * sends the message to the token's error object + * @param message = error message string + */ + public void ErrorMsg(string message) + { + if(emsg != null) + { + emsg(this, message); + } + } + + /* + * Generate a unique string (for use in CIL label names, etc) + */ + public string Unique + { + get + { + return file + "_" + line + "_" + posn; + } + } + + /* + * Generate source location string (for use in error messages) + */ + public string SrcLoc + { + get + { + string loc = file + "(" + line + "," + posn + ")"; + if(copiedFrom == null) + return loc; + string fromLoc = copiedFrom.SrcLoc; + if(fromLoc.StartsWith(loc)) + return fromLoc; + return loc + ":" + fromLoc; + } + } + + /* + * Used in generic instantiation to copy token. + * Only valid for parsing tokens, not reduction tokens + * because it is a shallow copy. + */ + public Token CopyToken(Token src) + { + Token t = (Token)this.MemberwiseClone(); + t.file = src.file; + t.line = src.line; + t.posn = src.posn; + t.copiedFrom = this; + return t; + } + + /* + * Generate debugging string - should look like source code. + */ + public virtual void DebString(StringBuilder sb) + { + sb.Append(this.ToString()); + } + } + + + /** + * @brief token that begins a source file + * Along with TokenEnd, it keeps insertion/removal of intermediate tokens + * simple as the intermediate tokens always have non-null nextToken,prevToken. + */ + public class TokenBegin: Token + { + private class Options + { + public bool arrays; // has seen 'XMROption arrays;' + public bool advFlowCtl; // has seen 'XMROption advFlowCtl;' + public bool tryCatch; // has seen 'XMROption tryCatch;' + public bool objects; // has seen 'XMROption objects;' + public bool chars; // has seen 'XMROption chars;' + public bool noRightToLeft; // has seen 'XMROption noRightToLeft;' + public bool dollarsigns; // has seen 'XMROption dollarsigns;' + } + + private bool youveAnError; // there was some error tokenizing + private int bolIdx; // index in 'source' at begining of current line + private int lineNo; // current line in source file, starting at 0 + private string filNam; // current source file name + private string source; // the whole script source code + private Token lastToken; // last token created so far + private string cameFrom; // where the source came from + private TextWriter saveSource; // save copy of source here (or null) + private Options options = new Options(); + + /** + * @brief convert a source file in the form of a string + * to a list of raw tokens + * @param cameFrom = where the source came from + * @param emsg = where to output messages to + * @param source = whole source file contents + * @returns null: conversion error, message already output + * else: list of tokens, starting with TokenBegin, ending with TokenEnd. + */ + public static TokenBegin Construct(string cameFrom, TextWriter saveSource, TokenErrorMessage emsg, string source, out string sourceHash) + { + sourceHash = null; + + // Now do the tokenization. + TokenBegin tokenBegin = new TokenBegin(emsg, "", 0, 0); + tokenBegin.cameFrom = cameFrom; + tokenBegin.saveSource = saveSource; + tokenBegin.lastToken = tokenBegin; + tokenBegin.source = source; + tokenBegin.filNam = cameFrom; + if(saveSource != null) + saveSource.WriteLine(source); + tokenBegin.Tokenize(); + if(tokenBegin.youveAnError) + return null; + tokenBegin.AppendToken(new TokenEnd(emsg, tokenBegin.filNam, ++tokenBegin.lineNo, 0)); + + /* + * Return source hash so caller can know if source changes. + */ + System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create(); + byte[] hashBytes = md5.ComputeHash(new TokenStream(tokenBegin)); + int hashBytesLen = hashBytes.Length; + StringBuilder sb = new StringBuilder(hashBytesLen * 2); + for(int i = 0; i < hashBytesLen; i++) + { + sb.Append(hashBytes[i].ToString("X2")); + } + sourceHash = sb.ToString(); + if(saveSource != null) + { + saveSource.WriteLine(" "); + saveSource.WriteLine("********************************************************************************"); + saveSource.WriteLine("**** source hash: " + sourceHash); + saveSource.WriteLine("********************************************************************************"); + } + + return tokenBegin; + } + + private TokenBegin(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { } + + /* + * Stream consisting of all the tokens. + * Null delimeters between the tokens. + * Used for creating the source hash. + */ + private class TokenStream: Stream + { + private Token curTok; + private bool delim; + private byte[] curBuf; + private int curOfs; + private int curLen; + + public TokenStream(Token t) + { + curTok = t; + } + + public override bool CanRead + { + get + { + return true; + } + } + public override bool CanSeek + { + get + { + return false; + } + } + public override bool CanWrite + { + get + { + return false; + } + } + public override long Length + { + get + { + return 0; + } + } + public override long Position + { + get + { + return 0; + } + set + { + } + } + + public override void Write(byte[] buffer, int offset, int count) + { + } + public override void Flush() + { + } + public override long Seek(long offset, SeekOrigin origin) + { + return 0; + } + public override void SetLength(long value) + { + } + + public override int Read(byte[] buffer, int offset, int count) + { + int len, total; + for(total = 0; total < count; total += len) + { + while((len = curLen - curOfs) <= 0) + { + if(curTok is TokenEnd) + goto done; + curTok = curTok.nextToken; + if(curTok is TokenEnd) + goto done; + curBuf = System.Text.Encoding.UTF8.GetBytes(curTok.ToString()); + curOfs = 0; + curLen = curBuf.Length; + delim = true; + } + if(delim) + { + buffer[offset + total] = 0; + delim = false; + len = 1; + } + else + { + if(len > count - total) + len = count - total; + Array.Copy(curBuf, curOfs, buffer, offset + total, len); + curOfs += len; + } + } + done: + return total; + } + } + + /* + * Produces raw token stream: names, numbers, strings, keywords/delimeters. + * @param this.source = whole source file in one string + * @returns this.nextToken = filled in with tokens + * this.youveAnError = true: some tokenizing error + * false: successful + */ + private void Tokenize() + { + bolIdx = 0; + lineNo = 0; + for(int i = 0; i < source.Length; i++) + { + char c = source[i]; + if(c == '\n') + { + + // Increment source line number and set char index of beg of next line. + lineNo++; + bolIdx = i + 1; + + // Check for '#' lineno filename newline + // lineno is line number of next line in file + // If found, save values and remove tokens from stream + if((lastToken is TokenStr) && + (lastToken.prevToken is TokenInt) && + (lastToken.prevToken.prevToken is TokenKwHash)) + { + filNam = ((TokenStr)lastToken).val; + lineNo = ((TokenInt)lastToken.prevToken).val; + lastToken = lastToken.prevToken.prevToken.prevToken; + lastToken.nextToken = null; + } + continue; + } + + // Skip over whitespace. + if(c <= ' ') + continue; + + // Skip over comments. + if((i + 2 <= source.Length) && source.Substring(i, 2).Equals("//")) + { + while((i < source.Length) && (source[i] != '\n')) + i++; + lineNo++; + bolIdx = i + 1; + continue; + } + if((i + 2 <= source.Length) && (source.Substring(i, 2).Equals("/*"))) + { + i += 2; + while((i + 1 < source.Length) && (((c = source[i]) != '*') || (source[i + 1] != '/'))) + { + if(c == '\n') + { + lineNo++; + bolIdx = i + 1; + } + i++; + } + i++; + continue; + } + + // Check for numbers. + if((c >= '0') && (c <= '9')) + { + int j = TryParseFloat(i); + if(j == 0) + j = TryParseInt(i); + i = --j; + continue; + } + if((c == '.') && (i + 1 < source.Length) && (source[i + 1] >= '0') && (source[i + 1] <= '9')) + { + int j = TryParseFloat(i); + if(j > 0) + i = --j; + continue; + } + + // Check for quoted strings. + if(c == '"') + { + StringBuilder sb = new StringBuilder(); + bool backslash; + int j; + + backslash = false; + for(j = i; ++j < source.Length;) + { + c = source[j]; + if(c == '\\' && !backslash) + { + backslash = true; + continue; + } + if(c == '\n') + { + lineNo++; + bolIdx = j + 1; + } + else + { + if(!backslash && (c == '"')) + break; + if(backslash && (c == 'n')) + c = '\n'; + if(backslash && (c == 't')) + { + sb.Append(" "); + c = ' '; + } + } + backslash = false; + sb.Append(c); + } + if(j - i > MAX_STRING_LEN) + { + TokenError(i, "string too long, max " + MAX_STRING_LEN); + } + else + { + AppendToken(new TokenStr(emsg, filNam, lineNo, i - bolIdx, sb.ToString())); + } + i = j; + continue; + } + + // Check for quoted characters. + if(c == '\'') + { + char cb = (char)0; + bool backslash, overflow, underflow; + int j; + + backslash = false; + overflow = false; + underflow = true; + for(j = i; ++j < source.Length;) + { + c = source[j]; + if(c == '\\' && !backslash) + { + backslash = true; + continue; + } + if(c == '\n') + { + lineNo++; + bolIdx = j + 1; + } + else + { + if(!backslash && (c == '\'')) + break; + if(backslash && (c == 'n')) + c = '\n'; + if(backslash && (c == 't')) + c = '\t'; + } + backslash = false; + overflow = !underflow; + underflow = false; + cb = c; + } + if(underflow || overflow) + { + TokenError(i, "character must be exactly one character"); + } + else + { + AppendToken(new TokenChar(emsg, filNam, lineNo, i - bolIdx, cb)); + } + i = j; + continue; + } + + // Check for keywords/names. + if((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c == '_') || (c == '$' && options.dollarsigns)) + { + int j; + + for(j = i; ++j < source.Length;) + { + c = source[j]; + if(c >= 'a' && c <= 'z') + continue; + if(c >= 'A' && c <= 'Z') + continue; + if(c >= '0' && c <= '9') + continue; + if(c == '$' && options.dollarsigns) + continue; + if(c != '_') + break; + } + if(j - i > MAX_NAME_LEN) + { + TokenError(i, "name too long, max " + MAX_NAME_LEN); + } + else + { + string name = source.Substring(i, j - i); + if(name == "quaternion") + name = "rotation"; // see lslangtest1.lsl + if(keywords.ContainsKey(name)) + { + Object[] args = new Object[] { emsg, filNam, lineNo, i - bolIdx }; + AppendToken((Token)keywords[name].Invoke(args)); + } + else if(options.arrays && arrayKeywords.ContainsKey(name)) + { + Object[] args = new Object[] { emsg, filNam, lineNo, i - bolIdx }; + AppendToken((Token)arrayKeywords[name].Invoke(args)); + } + else if(options.advFlowCtl && advFlowCtlKeywords.ContainsKey(name)) + { + Object[] args = new Object[] { emsg, filNam, lineNo, i - bolIdx }; + AppendToken((Token)advFlowCtlKeywords[name].Invoke(args)); + } + else if(options.tryCatch && tryCatchKeywords.ContainsKey(name)) + { + Object[] args = new Object[] { emsg, filNam, lineNo, i - bolIdx }; + AppendToken((Token)tryCatchKeywords[name].Invoke(args)); + } + else if(options.objects && objectsKeywords.ContainsKey(name)) + { + Object[] args = new Object[] { emsg, filNam, lineNo, i - bolIdx }; + AppendToken((Token)objectsKeywords[name].Invoke(args)); + } + else if(options.chars && charsKeywords.ContainsKey(name)) + { + Object[] args = new Object[] { emsg, filNam, lineNo, i - bolIdx }; + AppendToken((Token)charsKeywords[name].Invoke(args)); + } + else + { + AppendToken(new TokenName(emsg, filNam, lineNo, i - bolIdx, name)); + } + } + i = --j; + continue; + } + + // Check for option enables. + if((c == ';') && (lastToken is TokenName) && + (lastToken.prevToken is TokenName) && + (strcasecmp(((TokenName)lastToken.prevToken).val, "yoption") == 0)) + { + string opt = ((TokenName)lastToken).val; + if(strcasecmp(opt, "allowall") == 0) + { + options.arrays = true; + options.advFlowCtl = true; + options.tryCatch = true; + options.objects = true; + options.chars = true; + // options.noRightToLeft = true; + options.dollarsigns = true; + } + else if(strcasecmp(opt, "arrays") == 0) + options.arrays = true; + else if(strcasecmp(opt, "advflowctl") == 0) + options.advFlowCtl = true; + else if(strcasecmp(opt, "trycatch") == 0) + options.tryCatch = true; + else if(strcasecmp(opt, "objects") == 0) + options.objects = true; + else if(strcasecmp(opt, "chars") == 0) + options.chars = true; + else if(strcasecmp(opt, "norighttoleft") == 0) + options.noRightToLeft = true; + else if(strcasecmp(opt, "dollarsigns") == 0) + options.dollarsigns = true; + else + lastToken.ErrorMsg("unknown YOption"); + + lastToken = lastToken.prevToken.prevToken; + lastToken.nextToken = null; + continue; + } + + // Lastly, check for delimeters. + { + int j; + int len = 0; + + for(j = 0; j < delims.Length; j++) + { + len = delims[j].str.Length; + if((i + len <= source.Length) && (source.Substring(i, len).Equals(delims[j].str))) + break; + } + if(j < delims.Length) + { + Object[] args = { emsg, filNam, lineNo, i - bolIdx }; + Token kwToken = (Token)delims[j].ctorInfo.Invoke(args); + AppendToken(kwToken); + i += --len; + continue; + } + } + + // Don't know what it is! + TokenError(i, "unknown character '" + c + "'"); + } + } + + private static int strcasecmp(String s, String t) + { + return String.Compare(s, t, StringComparison.OrdinalIgnoreCase); + } + + /** + * @brief try to parse a floating-point number from the source + * @param i = starting position within this.source of number + * @returns 0: not a floating point number, try something else + * else: position in this.source of terminating character, ie, past number + * TokenFloat appended to token list + * or error message has been output + */ + private int TryParseFloat(int i) + { + bool decimals, error, negexp, nulexp; + char c; + double f, f10; + int exponent, j, x, y; + ulong m, mantissa; + + decimals = false; + error = false; + exponent = 0; + mantissa = 0; + for(j = i; j < source.Length; j++) + { + c = source[j]; + if((c >= '0') && (c <= '9')) + { + m = mantissa * 10 + (ulong)(c - '0'); + if(m / 10 != mantissa) + { + if(!decimals) + exponent++; + } + else + { + mantissa = m; + if(decimals) + exponent--; + } + continue; + } + if(c == '.') + { + if(decimals) + { + TokenError(i, "more than one decimal point"); + return j; + } + decimals = true; + continue; + } + if((c == 'E') || (c == 'e')) + { + if(++j >= source.Length) + { + TokenError(i, "floating exponent off end of source"); + return j; + } + c = source[j]; + negexp = (c == '-'); + if(negexp || (c == '+')) + j++; + y = 0; + nulexp = true; + for(; j < source.Length; j++) + { + c = source[j]; + if((c < '0') || (c > '9')) + break; + x = y * 10 + (c - '0'); + if(x / 10 != y) + { + if(!error) + TokenError(i, "floating exponent overflow"); + error = true; + } + y = x; + nulexp = false; + } + if(nulexp) + { + TokenError(i, "bad or missing floating exponent"); + return j; + } + if(negexp) + { + x = exponent - y; + if(x > exponent) + { + if(!error) + TokenError(i, "floating exponent overflow"); + error = true; + } + } + else + { + x = exponent + y; + if(x < exponent) + { + if(!error) + TokenError(i, "floating exponent overflow"); + error = true; + } + } + exponent = x; + } + break; + } + if(!decimals) + { + return 0; + } + + f = mantissa; + if((exponent != 0) && (mantissa != 0) && !error) + { + f10 = 10.0; + if(exponent < 0) + { + exponent = -exponent; + while(exponent > 0) + { + if((exponent & 1) != 0) + { + f /= f10; + } + exponent /= 2; + f10 *= f10; + } + } + else + { + while(exponent > 0) + { + if((exponent & 1) != 0) + { + f *= f10; + } + exponent /= 2; + f10 *= f10; + } + } + } + if(!error) + { + AppendToken(new TokenFloat(emsg, filNam, lineNo, i - bolIdx, f)); + } + return j; + } + + /** + * @brief try to parse an integer number from the source + * @param i = starting position within this.source of number + * @returns 0: not an integer number, try something else + * else: position in this.source of terminating character, ie, past number + * TokenInt appended to token list + * or error message has been output + */ + private int TryParseInt(int i) + { + bool error; + char c; + int j; + uint basse, m, mantissa; + + basse = 10; + error = false; + mantissa = 0; + for(j = i; j < source.Length; j++) + { + c = source[j]; + if((c >= '0') && (c <= '9')) + { + m = mantissa * basse + (uint)(c - '0'); + if(m / basse != mantissa) + { + if(!error) + TokenError(i, "integer overflow"); + error = true; + } + mantissa = m; + continue; + } + if((basse == 16) && ((c >= 'A') && (c <= 'F'))) + { + m = mantissa * basse + (uint)(c - 'A') + 10U; + if(m / basse != mantissa) + { + if(!error) + TokenError(i, "integer overflow"); + error = true; + } + mantissa = m; + continue; + } + if((basse == 16) && ((c >= 'a') && (c <= 'f'))) + { + m = mantissa * basse + (uint)(c - 'a') + 10U; + if(m / basse != mantissa) + { + if(!error) + TokenError(i, "integer overflow"); + error = true; + } + mantissa = m; + continue; + } + if(((c == 'x') || (c == 'X')) && (mantissa == 0) && (basse == 10)) + { + basse = 16; + continue; + } + break; + } + if(!error) + { + AppendToken(new TokenInt(emsg, filNam, lineNo, i - bolIdx, (int)mantissa)); + } + return j; + } + + /** + * @brief append token on to end of list + * @param newToken = token to append + * @returns with token appended onto this.lastToken + */ + private void AppendToken(Token newToken) + { + newToken.nextToken = null; + newToken.prevToken = lastToken; + newToken.nr2l = this.options.noRightToLeft; + lastToken.nextToken = newToken; + lastToken = newToken; + } + + /** + * @brief print tokenizing error message + * and remember that we've an error + * @param i = position within source file of the error + * @param message = error message text + * @returns with this.youveAnError set + */ + private void TokenError(int i, string message) + { + Token temp = new Token(this.emsg, this.filNam, this.lineNo, i - this.bolIdx); + temp.ErrorMsg(message); + youveAnError = true; + } + + /** + * @brief get a token's constructor + * @param tokenType = token's type + * @returns token's constructor + */ + private static Type[] constrTypes = new Type[] { + typeof (TokenErrorMessage), typeof (string), typeof (int), typeof (int) + }; + + private static System.Reflection.ConstructorInfo GetTokenCtor(Type tokenType) + { + return tokenType.GetConstructor(constrTypes); + } + + /** + * @brief delimeter table + */ + private class Delim + { + public string str; + public System.Reflection.ConstructorInfo ctorInfo; + public Delim(string str, Type type) + { + this.str = str; + ctorInfo = GetTokenCtor(type); + } + } + + private static Delim[] delims = new Delim[] { + new Delim ("...", typeof (TokenKwDotDotDot)), + new Delim ("&&&", typeof (TokenKwAndAndAnd)), + new Delim ("|||", typeof (TokenKwOrOrOr)), + new Delim ("<<=", typeof (TokenKwAsnLSh)), + new Delim (">>=", typeof (TokenKwAsnRSh)), + new Delim ("<=", typeof (TokenKwCmpLE)), + new Delim (">=", typeof (TokenKwCmpGE)), + new Delim ("==", typeof (TokenKwCmpEQ)), + new Delim ("!=", typeof (TokenKwCmpNE)), + new Delim ("++", typeof (TokenKwIncr)), + new Delim ("--", typeof (TokenKwDecr)), + new Delim ("&&", typeof (TokenKwAndAnd)), + new Delim ("||", typeof (TokenKwOrOr)), + new Delim ("+=", typeof (TokenKwAsnAdd)), + new Delim ("&=", typeof (TokenKwAsnAnd)), + new Delim ("-=", typeof (TokenKwAsnSub)), + new Delim ("*=", typeof (TokenKwAsnMul)), + new Delim ("/=", typeof (TokenKwAsnDiv)), + new Delim ("%=", typeof (TokenKwAsnMod)), + new Delim ("|=", typeof (TokenKwAsnOr)), + new Delim ("^=", typeof (TokenKwAsnXor)), + new Delim ("<<", typeof (TokenKwLSh)), + new Delim (">>", typeof (TokenKwRSh)), + new Delim ("~", typeof (TokenKwTilde)), + new Delim ("!", typeof (TokenKwExclam)), + new Delim ("@", typeof (TokenKwAt)), + new Delim ("%", typeof (TokenKwMod)), + new Delim ("^", typeof (TokenKwXor)), + new Delim ("&", typeof (TokenKwAnd)), + new Delim ("*", typeof (TokenKwMul)), + new Delim ("(", typeof (TokenKwParOpen)), + new Delim (")", typeof (TokenKwParClose)), + new Delim ("-", typeof (TokenKwSub)), + new Delim ("+", typeof (TokenKwAdd)), + new Delim ("=", typeof (TokenKwAssign)), + new Delim ("{", typeof (TokenKwBrcOpen)), + new Delim ("}", typeof (TokenKwBrcClose)), + new Delim ("[", typeof (TokenKwBrkOpen)), + new Delim ("]", typeof (TokenKwBrkClose)), + new Delim (";", typeof (TokenKwSemi)), + new Delim (":", typeof (TokenKwColon)), + new Delim ("<", typeof (TokenKwCmpLT)), + new Delim (">", typeof (TokenKwCmpGT)), + new Delim (",", typeof (TokenKwComma)), + new Delim (".", typeof (TokenKwDot)), + new Delim ("?", typeof (TokenKwQMark)), + new Delim ("/", typeof (TokenKwDiv)), + new Delim ("|", typeof (TokenKwOr)), + new Delim ("#", typeof (TokenKwHash)) + }; + + /** + * @brief keyword tables + * The keyword tables translate a keyword string + * to the corresponding token constructor. + */ + private static Dictionary keywords = BuildKeywords(); + private static Dictionary arrayKeywords = BuildArrayKeywords(); + private static Dictionary advFlowCtlKeywords = BuildAdvFlowCtlKeywords(); + private static Dictionary tryCatchKeywords = BuildTryCatchKeywords(); + private static Dictionary objectsKeywords = BuildObjectsKeywords(); + private static Dictionary charsKeywords = BuildCharsKeywords(); + + private static Dictionary BuildKeywords() + { + Dictionary kws = new Dictionary(); + + kws.Add("default", GetTokenCtor(typeof(TokenKwDefault))); + kws.Add("do", GetTokenCtor(typeof(TokenKwDo))); + kws.Add("else", GetTokenCtor(typeof(TokenKwElse))); + kws.Add("float", GetTokenCtor(typeof(TokenTypeFloat))); + kws.Add("for", GetTokenCtor(typeof(TokenKwFor))); + kws.Add("if", GetTokenCtor(typeof(TokenKwIf))); + kws.Add("integer", GetTokenCtor(typeof(TokenTypeInt))); + kws.Add("list", GetTokenCtor(typeof(TokenTypeList))); + kws.Add("jump", GetTokenCtor(typeof(TokenKwJump))); + kws.Add("key", GetTokenCtor(typeof(TokenTypeKey))); + kws.Add("return", GetTokenCtor(typeof(TokenKwRet))); + kws.Add("rotation", GetTokenCtor(typeof(TokenTypeRot))); + kws.Add("state", GetTokenCtor(typeof(TokenKwState))); + kws.Add("string", GetTokenCtor(typeof(TokenTypeStr))); + kws.Add("vector", GetTokenCtor(typeof(TokenTypeVec))); + kws.Add("while", GetTokenCtor(typeof(TokenKwWhile))); + + return kws; + } + + private static Dictionary BuildArrayKeywords() + { + Dictionary kws = new Dictionary(); + + kws.Add("array", GetTokenCtor(typeof(TokenTypeArray))); + kws.Add("foreach", GetTokenCtor(typeof(TokenKwForEach))); + kws.Add("in", GetTokenCtor(typeof(TokenKwIn))); + kws.Add("is", GetTokenCtor(typeof(TokenKwIs))); + kws.Add("object", GetTokenCtor(typeof(TokenTypeObject))); + kws.Add("undef", GetTokenCtor(typeof(TokenKwUndef))); + + return kws; + } + + private static Dictionary BuildAdvFlowCtlKeywords() + { + Dictionary kws = new Dictionary(); + + kws.Add("break", GetTokenCtor(typeof(TokenKwBreak))); + kws.Add("case", GetTokenCtor(typeof(TokenKwCase))); + kws.Add("constant", GetTokenCtor(typeof(TokenKwConst))); + kws.Add("continue", GetTokenCtor(typeof(TokenKwCont))); + kws.Add("switch", GetTokenCtor(typeof(TokenKwSwitch))); + + return kws; + } + + private static Dictionary BuildTryCatchKeywords() + { + Dictionary kws = new Dictionary(); + + kws.Add("catch", GetTokenCtor(typeof(TokenKwCatch))); + kws.Add("exception", GetTokenCtor(typeof(TokenTypeExc))); + kws.Add("finally", GetTokenCtor(typeof(TokenKwFinally))); + kws.Add("throw", GetTokenCtor(typeof(TokenKwThrow))); + kws.Add("try", GetTokenCtor(typeof(TokenKwTry))); + + return kws; + } + + private static Dictionary BuildObjectsKeywords() + { + Dictionary kws = new Dictionary(); + + kws.Add("abstract", GetTokenCtor(typeof(TokenKwAbstract))); + kws.Add("base", GetTokenCtor(typeof(TokenKwBase))); + kws.Add("class", GetTokenCtor(typeof(TokenKwClass))); + kws.Add("constructor", GetTokenCtor(typeof(TokenKwConstructor))); + kws.Add("delegate", GetTokenCtor(typeof(TokenKwDelegate))); + kws.Add("destructor", GetTokenCtor(typeof(TokenKwDestructor))); + kws.Add("final", GetTokenCtor(typeof(TokenKwFinal))); + kws.Add("get", GetTokenCtor(typeof(TokenKwGet))); + kws.Add("interface", GetTokenCtor(typeof(TokenKwInterface))); + kws.Add("new", GetTokenCtor(typeof(TokenKwNew))); + kws.Add("override", GetTokenCtor(typeof(TokenKwOverride))); + kws.Add("partial", GetTokenCtor(typeof(TokenKwPartial))); + kws.Add("private", GetTokenCtor(typeof(TokenKwPrivate))); + kws.Add("protected", GetTokenCtor(typeof(TokenKwProtected))); + kws.Add("public", GetTokenCtor(typeof(TokenKwPublic))); + kws.Add("set", GetTokenCtor(typeof(TokenKwSet))); + kws.Add("static", GetTokenCtor(typeof(TokenKwStatic))); + kws.Add("this", GetTokenCtor(typeof(TokenKwThis))); + kws.Add("typedef", GetTokenCtor(typeof(TokenKwTypedef))); + kws.Add("virtual", GetTokenCtor(typeof(TokenKwVirtual))); + + return kws; + } + + private static Dictionary BuildCharsKeywords() + { + Dictionary kws = new Dictionary(); + + kws.Add("char", GetTokenCtor(typeof(TokenTypeChar))); + + return kws; + } + } + + /** + * @brief All output token types in addition to TokenBegin. + * They are all sub-types of Token. + */ + + public class TokenChar: Token + { + public char val; + public TokenChar(TokenErrorMessage emsg, string file, int line, int posn, char val) : base(emsg, file, line, posn) + { + this.val = val; + } + public TokenChar(Token original, char val) : base(original) + { + this.val = val; + } + public override string ToString() + { + switch(val) + { + case '\'': + return "'\\''"; + case '\\': + return "'\\\\'"; + case '\n': + return "'\\n'"; + case '\t': + return "'\\t'"; + default: + return "'" + val + "'"; + } + } + } + + public class TokenFloat: Token + { + public double val; + public TokenFloat(TokenErrorMessage emsg, string file, int line, int posn, double val) : base(emsg, file, line, posn) + { + this.val = val; + } + public override string ToString() + { + return val.ToString(); + } + } + + public class TokenInt: Token + { + public int val; + public TokenInt(TokenErrorMessage emsg, string file, int line, int posn, int val) : base(emsg, file, line, posn) + { + this.val = val; + } + public TokenInt(Token original, int val) : base(original) + { + this.val = val; + } + public override string ToString() + { + return val.ToString(); + } + } + + public class TokenName: Token + { + public string val; + public TokenName(TokenErrorMessage emsg, string file, int line, int posn, string val) : base(emsg, file, line, posn) + { + this.val = val; + } + public TokenName(Token original, string val) : base(original) + { + this.val = val; + } + public override string ToString() + { + return this.val; + } + } + + public class TokenStr: Token + { + public string val; + public TokenStr(TokenErrorMessage emsg, string file, int line, int posn, string val) : base(emsg, file, line, posn) + { + this.val = val; + } + public override string ToString() + { + if((val.IndexOf('"') < 0) && + (val.IndexOf('\\') < 0) && + (val.IndexOf('\n') < 0) && + (val.IndexOf('\t') < 0)) + return "\"" + val + "\""; + + int len = val.Length; + StringBuilder sb = new StringBuilder(len * 2 + 2); + sb.Append('"'); + for(int i = 0; i < len; i++) + { + char c = val[i]; + switch(c) + { + case '"': + { + sb.Append('\\'); + sb.Append('"'); + break; + } + case '\\': + { + sb.Append('\\'); + sb.Append('\\'); + break; + } + case '\n': + { + sb.Append('\\'); + sb.Append('n'); + break; + } + case '\t': + { + sb.Append('\\'); + sb.Append('t'); + break; + } + default: + { + sb.Append(c); + break; + } + } + } + return sb.ToString(); + } + } + + /* + * This one marks the end-of-file. + */ + public class TokenEnd: Token + { + public TokenEnd(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { } + } + + /* + * Various keywords and delimeters. + */ + public delegate object TokenRValConstBinOpDelegate(object left, object right); + public delegate object TokenRValConstUnOpDelegate(object right); + + public class TokenKw: Token + { + public TokenRValConstBinOpDelegate binOpConst; + public TokenRValConstUnOpDelegate unOpConst; + public bool sdtClassOp; + public TokenKw(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) + { + } + public TokenKw(Token original) : base(original) + { + } + } + + public class TokenKwDotDotDot: TokenKw + { + public TokenKwDotDotDot(TokenErrorMessage emsg, string file, + int line, int posn) : base(emsg, file, line, posn) + { + binOpConst = TokenRValConstOps.Null; + unOpConst = TokenRValConstOps.Null; + sdtClassOp = false; + } + public TokenKwDotDotDot(Token original) : base(original) + { + binOpConst = TokenRValConstOps.Null; + unOpConst = TokenRValConstOps.Null; + sdtClassOp = false; + } + public override string ToString() + { + return "..."; + } + } + public class TokenKwAndAndAnd: TokenKw + { + public TokenKwAndAndAnd(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) + { + binOpConst = TokenRValConstOps.Null; + unOpConst = TokenRValConstOps.Null; + sdtClassOp = false; + } + public TokenKwAndAndAnd(Token original) : base(original) + { + binOpConst = TokenRValConstOps.Null; + unOpConst = TokenRValConstOps.Null; + sdtClassOp = false; + } + public override string ToString() + { + return "&&&"; + } + } + public class TokenKwOrOrOr: TokenKw + { + public TokenKwOrOrOr(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) + { + binOpConst = TokenRValConstOps.Null; + unOpConst = TokenRValConstOps.Null; + sdtClassOp = false; + } + public TokenKwOrOrOr(Token original) : base(original) + { + binOpConst = TokenRValConstOps.Null; + unOpConst = TokenRValConstOps.Null; + sdtClassOp = false; + } + public override string ToString() + { + return "|||"; + } + } + public class TokenKwAsnLSh: TokenKw + { + public TokenKwAsnLSh(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) + { + binOpConst = TokenRValConstOps.Null; + unOpConst = TokenRValConstOps.Null; + sdtClassOp = true; + } + public TokenKwAsnLSh(Token original) : base(original) + { + binOpConst = TokenRValConstOps.Null; + unOpConst = TokenRValConstOps.Null; + sdtClassOp = true; + } + public override string ToString() + { + return "<<="; + } + } + public class TokenKwAsnRSh: TokenKw + { + public TokenKwAsnRSh(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = true; } + public TokenKwAsnRSh(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = true; } + public override string ToString() + { + return ">>="; + } + } + public class TokenKwCmpLE: TokenKw + { + public TokenKwCmpLE(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = true; } + public TokenKwCmpLE(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = true; } + public override string ToString() + { + return "<="; + } + } + public class TokenKwCmpGE: TokenKw + { + public TokenKwCmpGE(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = true; } + public TokenKwCmpGE(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = true; } + public override string ToString() + { + return ">="; + } + } + public class TokenKwCmpEQ: TokenKw + { + public TokenKwCmpEQ(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = true; } + public TokenKwCmpEQ(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = true; } + public override string ToString() + { + return "=="; + } + } + public class TokenKwCmpNE: TokenKw + { + public TokenKwCmpNE(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = true; } + public TokenKwCmpNE(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = true; } + public override string ToString() + { + return "!="; + } + } + public class TokenKwIncr: TokenKw + { + public TokenKwIncr(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public TokenKwIncr(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public override string ToString() + { + return "++"; + } + } + public class TokenKwDecr: TokenKw + { + public TokenKwDecr(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public TokenKwDecr(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public override string ToString() + { + return "--"; + } + } + public class TokenKwAndAnd: TokenKw + { + public TokenKwAndAnd(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = true; } + public TokenKwAndAnd(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = true; } + public override string ToString() + { + return "&&"; + } + } + public class TokenKwOrOr: TokenKw + { + public TokenKwOrOr(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = true; } + public TokenKwOrOr(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = true; } + public override string ToString() + { + return "||"; + } + } + public class TokenKwAsnAdd: TokenKw + { + public TokenKwAsnAdd(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = true; } + public TokenKwAsnAdd(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = true; } + public override string ToString() + { + return "+="; + } + } + public class TokenKwAsnAnd: TokenKw + { + public TokenKwAsnAnd(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = true; } + public TokenKwAsnAnd(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = true; } + public override string ToString() + { + return "&="; + } + } + public class TokenKwAsnSub: TokenKw + { + public TokenKwAsnSub(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = true; } + public TokenKwAsnSub(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = true; } + public override string ToString() + { + return "-="; + } + } + public class TokenKwAsnMul: TokenKw + { + public TokenKwAsnMul(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = true; } + public TokenKwAsnMul(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = true; } + public override string ToString() + { + return "*="; + } + } + public class TokenKwAsnDiv: TokenKw + { + public TokenKwAsnDiv(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = true; } + public TokenKwAsnDiv(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = true; } + public override string ToString() + { + return "/="; + } + } + public class TokenKwAsnMod: TokenKw + { + public TokenKwAsnMod(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = true; } + public TokenKwAsnMod(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = true; } + public override string ToString() + { + return "%="; + } + } + public class TokenKwAsnOr: TokenKw + { + public TokenKwAsnOr(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = true; } + public TokenKwAsnOr(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = true; } + public override string ToString() + { + return "|="; + } + } + public class TokenKwAsnXor: TokenKw + { + public TokenKwAsnXor(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = true; } + public TokenKwAsnXor(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = true; } + public override string ToString() + { + return "^="; + } + } + public class TokenKwLSh: TokenKw + { + public TokenKwLSh(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.LSh; unOpConst = TokenRValConstOps.Null; sdtClassOp = true; } + public TokenKwLSh(Token original) : base(original) { binOpConst = TokenRValConstOps.LSh; unOpConst = TokenRValConstOps.Null; sdtClassOp = true; } + public override string ToString() + { + return "<<"; + } + } + public class TokenKwRSh: TokenKw + { + public TokenKwRSh(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.RSh; unOpConst = TokenRValConstOps.Null; sdtClassOp = true; } + public TokenKwRSh(Token original) : base(original) { binOpConst = TokenRValConstOps.RSh; unOpConst = TokenRValConstOps.Null; sdtClassOp = true; } + public override string ToString() + { + return ">>"; + } + } + public class TokenKwTilde: TokenKw + { + public TokenKwTilde(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Not; sdtClassOp = true; } + public TokenKwTilde(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Not; sdtClassOp = true; } + public override string ToString() + { + return "~"; + } + } + public class TokenKwExclam: TokenKw + { + public TokenKwExclam(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = true; } + public TokenKwExclam(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = true; } + public override string ToString() + { + return "!"; + } + } + public class TokenKwAt: TokenKw + { + public TokenKwAt(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public TokenKwAt(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public override string ToString() + { + return "@"; + } + } + public class TokenKwMod: TokenKw + { + public TokenKwMod(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Mod; unOpConst = TokenRValConstOps.Null; sdtClassOp = true; } + public TokenKwMod(Token original) : base(original) { binOpConst = TokenRValConstOps.Mod; unOpConst = TokenRValConstOps.Null; sdtClassOp = true; } + public override string ToString() + { + return "%"; + } + } + public class TokenKwXor: TokenKw + { + public TokenKwXor(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Xor; unOpConst = TokenRValConstOps.Null; sdtClassOp = true; } + public TokenKwXor(Token original) : base(original) { binOpConst = TokenRValConstOps.Xor; unOpConst = TokenRValConstOps.Null; sdtClassOp = true; } + public override string ToString() + { + return "^"; + } + } + public class TokenKwAnd: TokenKw + { + public TokenKwAnd(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.And; unOpConst = TokenRValConstOps.Null; sdtClassOp = true; } + public TokenKwAnd(Token original) : base(original) { binOpConst = TokenRValConstOps.And; unOpConst = TokenRValConstOps.Null; sdtClassOp = true; } + public override string ToString() + { + return "&"; + } + } + public class TokenKwMul: TokenKw + { + public TokenKwMul(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Mul; unOpConst = TokenRValConstOps.Null; sdtClassOp = true; } + public TokenKwMul(Token original) : base(original) { binOpConst = TokenRValConstOps.Mul; unOpConst = TokenRValConstOps.Null; sdtClassOp = true; } + public override string ToString() + { + return "*"; + } + } + public class TokenKwParOpen: TokenKw + { + public TokenKwParOpen(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public TokenKwParOpen(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public override string ToString() + { + return "("; + } + } + public class TokenKwParClose: TokenKw + { + public TokenKwParClose(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public TokenKwParClose(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public override string ToString() + { + return ")"; + } + } + public class TokenKwSub: TokenKw + { + public TokenKwSub(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Sub; unOpConst = TokenRValConstOps.Neg; sdtClassOp = true; } + public TokenKwSub(Token original) : base(original) { binOpConst = TokenRValConstOps.Sub; unOpConst = TokenRValConstOps.Neg; sdtClassOp = true; } + public override string ToString() + { + return "-"; + } + } + public class TokenKwAdd: TokenKw + { + public TokenKwAdd(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Add; unOpConst = TokenRValConstOps.Null; sdtClassOp = true; } + public TokenKwAdd(Token original) : base(original) { binOpConst = TokenRValConstOps.Add; unOpConst = TokenRValConstOps.Null; sdtClassOp = true; } + public override string ToString() + { + return "+"; + } + } + public class TokenKwAssign: TokenKw + { + public TokenKwAssign(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public TokenKwAssign(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public override string ToString() + { + return "="; + } + } + public class TokenKwBrcOpen: TokenKw + { + public TokenKwBrcOpen(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public TokenKwBrcOpen(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public override string ToString() + { + return "{"; + } + } + public class TokenKwBrcClose: TokenKw + { + public TokenKwBrcClose(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public TokenKwBrcClose(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public override string ToString() + { + return "}"; + } + } + public class TokenKwBrkOpen: TokenKw + { + public TokenKwBrkOpen(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public TokenKwBrkOpen(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public override string ToString() + { + return "["; + } + } + public class TokenKwBrkClose: TokenKw + { + public TokenKwBrkClose(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public TokenKwBrkClose(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public override string ToString() + { + return "]"; + } + } + public class TokenKwSemi: TokenKw + { + public TokenKwSemi(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public TokenKwSemi(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public override string ToString() + { + return ";"; + } + } + public class TokenKwColon: TokenKw + { + public TokenKwColon(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public TokenKwColon(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public override string ToString() + { + return ":"; + } + } + public class TokenKwCmpLT: TokenKw + { + public TokenKwCmpLT(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = true; } + public TokenKwCmpLT(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = true; } + public override string ToString() + { + return "<"; + } + } + public class TokenKwCmpGT: TokenKw + { + public TokenKwCmpGT(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = true; } + public TokenKwCmpGT(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = true; } + public override string ToString() + { + return ">"; + } + } + public class TokenKwComma: TokenKw + { + public TokenKwComma(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public TokenKwComma(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public override string ToString() + { + return ","; + } + } + public class TokenKwDot: TokenKw + { + public TokenKwDot(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public TokenKwDot(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public override string ToString() + { + return "."; + } + } + public class TokenKwQMark: TokenKw + { + public TokenKwQMark(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public TokenKwQMark(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public override string ToString() + { + return "?"; + } + } + public class TokenKwDiv: TokenKw + { + public TokenKwDiv(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Div; unOpConst = TokenRValConstOps.Null; sdtClassOp = true; } + public TokenKwDiv(Token original) : base(original) { binOpConst = TokenRValConstOps.Div; unOpConst = TokenRValConstOps.Null; sdtClassOp = true; } + public override string ToString() + { + return "/"; + } + } + public class TokenKwOr: TokenKw + { + public TokenKwOr(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Or; unOpConst = TokenRValConstOps.Null; sdtClassOp = true; } + public TokenKwOr(Token original) : base(original) { binOpConst = TokenRValConstOps.Or; unOpConst = TokenRValConstOps.Null; sdtClassOp = true; } + public override string ToString() + { + return "|"; + } + } + public class TokenKwHash: TokenKw + { + public TokenKwHash(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public TokenKwHash(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public override string ToString() + { + return "#"; + } + } + + public class TokenKwAbstract: TokenKw + { + public TokenKwAbstract(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public TokenKwAbstract(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public override string ToString() + { + return "abstract"; + } + } + public class TokenKwBase: TokenKw + { + public TokenKwBase(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public TokenKwBase(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public override string ToString() + { + return "base"; + } + } + public class TokenKwBreak: TokenKw + { + public TokenKwBreak(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public TokenKwBreak(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public override string ToString() + { + return "break"; + } + } + public class TokenKwCase: TokenKw + { + public TokenKwCase(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public TokenKwCase(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public override string ToString() + { + return "case"; + } + } + public class TokenKwCatch: TokenKw + { + public TokenKwCatch(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public TokenKwCatch(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public override string ToString() + { + return "catch"; + } + } + public class TokenKwClass: TokenKw + { + public TokenKwClass(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public TokenKwClass(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public override string ToString() + { + return "class"; + } + } + public class TokenKwConst: TokenKw + { + public TokenKwConst(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public TokenKwConst(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public override string ToString() + { + return "constant"; + } + } + public class TokenKwConstructor: TokenKw + { + public TokenKwConstructor(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public TokenKwConstructor(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public override string ToString() + { + return "constructor"; + } + } + public class TokenKwCont: TokenKw + { + public TokenKwCont(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public TokenKwCont(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public override string ToString() + { + return "continue"; + } + } + public class TokenKwDelegate: TokenKw + { + public TokenKwDelegate(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public TokenKwDelegate(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public override string ToString() + { + return "delegate"; + } + } + public class TokenKwDefault: TokenKw + { + public TokenKwDefault(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public TokenKwDefault(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public override string ToString() + { + return "default"; + } + } + public class TokenKwDestructor: TokenKw + { + public TokenKwDestructor(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public TokenKwDestructor(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public override string ToString() + { + return "destructor"; + } + } + public class TokenKwDo: TokenKw + { + public TokenKwDo(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public TokenKwDo(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public override string ToString() + { + return "do"; + } + } + public class TokenKwElse: TokenKw + { + public TokenKwElse(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public TokenKwElse(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public override string ToString() + { + return "else"; + } + } + public class TokenKwFinal: TokenKw + { + public TokenKwFinal(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public TokenKwFinal(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public override string ToString() + { + return "final"; + } + } + public class TokenKwFinally: TokenKw + { + public TokenKwFinally(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public TokenKwFinally(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public override string ToString() + { + return "finally"; + } + } + public class TokenKwFor: TokenKw + { + public TokenKwFor(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public TokenKwFor(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public override string ToString() + { + return "for"; + } + } + public class TokenKwForEach: TokenKw + { + public TokenKwForEach(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public TokenKwForEach(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public override string ToString() + { + return "foreach"; + } + } + public class TokenKwGet: TokenKw + { + public TokenKwGet(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public TokenKwGet(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public override string ToString() + { + return "get"; + } + } + public class TokenKwIf: TokenKw + { + public TokenKwIf(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public TokenKwIf(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public override string ToString() + { + return "if"; + } + } + public class TokenKwIn: TokenKw + { + public TokenKwIn(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public TokenKwIn(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public override string ToString() + { + return "in"; + } + } + public class TokenKwInterface: TokenKw + { + public TokenKwInterface(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public TokenKwInterface(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public override string ToString() + { + return "interface"; + } + } + public class TokenKwIs: TokenKw + { + public TokenKwIs(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public TokenKwIs(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public override string ToString() + { + return "is"; + } + } + public class TokenKwJump: TokenKw + { + public TokenKwJump(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public TokenKwJump(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public override string ToString() + { + return "jump"; + } + } + public class TokenKwNew: TokenKw + { + public TokenKwNew(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public TokenKwNew(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public override string ToString() + { + return "new"; + } + } + public class TokenKwOverride: TokenKw + { + public TokenKwOverride(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public TokenKwOverride(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public override string ToString() + { + return "override"; + } + } + public class TokenKwPartial: TokenKw + { + public TokenKwPartial(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public TokenKwPartial(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public override string ToString() + { + return "partial"; + } + } + public class TokenKwPrivate: TokenKw + { + public TokenKwPrivate(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public TokenKwPrivate(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public override string ToString() + { + return "private"; + } + } + public class TokenKwProtected: TokenKw + { + public TokenKwProtected(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public TokenKwProtected(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public override string ToString() + { + return "protected"; + } + } + public class TokenKwPublic: TokenKw + { + public TokenKwPublic(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public TokenKwPublic(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public override string ToString() + { + return "public"; + } + } + public class TokenKwRet: TokenKw + { + public TokenKwRet(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public TokenKwRet(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public override string ToString() + { + return "return"; + } + } + public class TokenKwSet: TokenKw + { + public TokenKwSet(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public TokenKwSet(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public override string ToString() + { + return "set"; + } + } + public class TokenKwState: TokenKw + { + public TokenKwState(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public TokenKwState(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public override string ToString() + { + return "state"; + } + } + public class TokenKwStatic: TokenKw + { + public TokenKwStatic(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public TokenKwStatic(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public override string ToString() + { + return "static"; + } + } + public class TokenKwSwitch: TokenKw + { + public TokenKwSwitch(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public TokenKwSwitch(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public override string ToString() + { + return "switch"; + } + } + public class TokenKwThis: TokenKw + { + public TokenKwThis(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public TokenKwThis(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public override string ToString() + { + return "this"; + } + } + public class TokenKwThrow: TokenKw + { + public TokenKwThrow(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public TokenKwThrow(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public override string ToString() + { + return "throw"; + } + } + public class TokenKwTry: TokenKw + { + public TokenKwTry(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public TokenKwTry(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public override string ToString() + { + return "try"; + } + } + public class TokenKwTypedef: TokenKw + { + public TokenKwTypedef(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public TokenKwTypedef(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public override string ToString() + { + return "typedef"; + } + } + public class TokenKwUndef: TokenKw + { + public TokenKwUndef(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public TokenKwUndef(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public override string ToString() + { + return "undef"; + } + } + public class TokenKwVirtual: TokenKw + { + public TokenKwVirtual(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public TokenKwVirtual(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public override string ToString() + { + return "virtual"; + } + } + public class TokenKwWhile: TokenKw + { + public TokenKwWhile(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public TokenKwWhile(Token original) : base(original) { binOpConst = TokenRValConstOps.Null; unOpConst = TokenRValConstOps.Null; sdtClassOp = false; } + public override string ToString() + { + return "while"; + } + } + + /** + * @brief These static functions attempt to perform arithmetic on two constant + * operands to generate the resultant constant. + * Likewise for unary operators. + * + * @param left = left-hand value + * @param right = right-hand value + * @returns null: not able to perform computation + * else: resultant value object + * + * Note: it is ok for these to throw any exception (such as overflow or div-by-zero), + * and it will be treated as the 'not able to perform computation' case. + */ + public class TokenRValConstOps + { + public static object Null(object left, object right) + { + return null; + } + public static object Div(object left, object right) + { + if((left is int) && (right is int)) + { + return (int)left / (int)right; + } + if((left is int) && (right is double)) + { + return (int)left / (double)right; + } + if((left is double) && (right is int)) + { + return (double)left / (int)right; + } + if((left is double) && (right is double)) + { + return (double)left / (double)right; + } + return null; + } + public static object Mod(object left, object right) + { + if((left is int) && (right is int)) + { + return (int)left % (int)right; + } + if((left is int) && (right is double)) + { + return (int)left % (double)right; + } + if((left is double) && (right is int)) + { + return (double)left % (int)right; + } + if((left is double) && (right is double)) + { + return (double)left % (double)right; + } + return null; + } + public static object Mul(object left, object right) + { + if((left is int) && (right is int)) + { + return (int)left * (int)right; + } + if((left is int) && (right is double)) + { + return (int)left * (double)right; + } + if((left is double) && (right is int)) + { + return (double)left * (int)right; + } + if((left is double) && (right is double)) + { + return (double)left * (double)right; + } + return null; + } + public static object And(object left, object right) + { + if((left is int) && (right is int)) + { + return (int)left & (int)right; + } + if((left is int) && (right is double)) + { + return (int)left & (int)(double)right; + } + if((left is double) && (right is int)) + { + return (int)(double)left & (int)right; + } + if((left is double) && (right is double)) + { + return (int)(double)left & (int)(double)right; + } + return null; + } + public static object LSh(object left, object right) + { + if((left is int) && (right is int)) + { + return (int)left << (int)right; + } + if((left is int) && (right is double)) + { + return (int)left << (int)(double)right; + } + if((left is double) && (right is int)) + { + return (int)(double)left << (int)right; + } + if((left is double) && (right is double)) + { + return (int)(double)left << (int)(double)right; + } + return null; + } + public static object Or(object left, object right) + { + if((left is int) && (right is int)) + { + return (int)left | (int)right; + } + if((left is int) && (right is double)) + { + return (int)left | (int)(double)right; + } + if((left is double) && (right is int)) + { + return (int)(double)left | (int)right; + } + if((left is double) && (right is double)) + { + return (int)(double)left | (int)(double)right; + } + return null; + } + public static object RSh(object left, object right) + { + if((left is int) && (right is int)) + { + return (int)left >> (int)right; + } + if((left is int) && (right is double)) + { + return (int)left >> (int)(double)right; + } + if((left is double) && (right is int)) + { + return (int)(double)left >> (int)right; + } + if((left is double) && (right is double)) + { + return (int)(double)left >> (int)(double)right; + } + return null; + } + public static object Xor(object left, object right) + { + if((left is int) && (right is int)) + { + return (int)left ^ (int)right; + } + if((left is int) && (right is double)) + { + return (int)left ^ (int)(double)right; + } + if((left is double) && (right is int)) + { + return (int)(double)left ^ (int)right; + } + if((left is double) && (right is double)) + { + return (int)(double)left ^ (int)(double)right; + } + return null; + } + public static object Add(object left, object right) + { + if((left is char) && (right is int)) + { + return (char)((char)left + (int)right); + } + if((left is double) && (right is double)) + { + return (double)left + (double)right; + } + if((left is double) && (right is int)) + { + return (double)left + (int)right; + } + if((left is double) && (right is string)) + { + return TypeCast.FloatToString((double)left) + (string)right; + } + if((left is int) && (right is double)) + { + return (int)left + (double)right; + } + if((left is int) && (right is int)) + { + return (int)left + (int)right; + } + if((left is int) && (right is string)) + { + return TypeCast.IntegerToString((int)left) + (string)right; + } + if((left is string) && (right is char)) + { + return (string)left + (char)right; + } + if((left is string) && (right is double)) + { + return (string)left + TypeCast.FloatToString((double)right); + } + if((left is string) && (right is int)) + { + return (string)left + TypeCast.IntegerToString((int)right); + } + if((left is string) && (right is string)) + { + return (string)left + (string)right; + } + return null; + } + public static object Sub(object left, object right) + { + if((left is char) && (right is int)) + { + return (char)((char)left - (int)right); + } + if((left is int) && (right is int)) + { + return (int)left - (int)right; + } + if((left is int) && (right is double)) + { + return (int)left - (double)right; + } + if((left is double) && (right is int)) + { + return (double)left - (int)right; + } + if((left is double) && (right is double)) + { + return (double)left - (double)right; + } + return null; + } + public static object Null(object right) + { + return null; + } + public static object Neg(object right) + { + if(right is int) + { + return -(int)right; + } + if(right is double) + { + return -(double)right; + } + return null; + } + public static object Not(object right) + { + if(right is int) + { + return ~(int)right; + } + return null; + } + } + + /* + * Various datatypes. + */ + public abstract class TokenType: Token + { + + public TokenType(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { } + public TokenType(Token original) : base(original) { } + + public static TokenType FromSysType(Token original, System.Type typ) + { + if(typ == typeof(LSL_List)) + return new TokenTypeList(original); + if(typ == typeof(LSL_Rotation)) + return new TokenTypeRot(original); + if(typ == typeof(void)) + return new TokenTypeVoid(original); + if(typ == typeof(LSL_Vector)) + return new TokenTypeVec(original); + if(typ == typeof(float)) + return new TokenTypeFloat(original); + if(typ == typeof(int)) + return new TokenTypeInt(original); + if(typ == typeof(string)) + return new TokenTypeStr(original); + if(typ == typeof(double)) + return new TokenTypeFloat(original); + if(typ == typeof(bool)) + return new TokenTypeBool(original); + if(typ == typeof(object)) + return new TokenTypeObject(original); + if(typ == typeof(XMR_Array)) + return new TokenTypeArray(original); + if(typ == typeof(LSL_Integer)) + return new TokenTypeLSLInt(original); + if(typ == typeof(LSL_Float)) + return new TokenTypeLSLFloat(original); + if(typ == typeof(LSL_String)) + return new TokenTypeLSLString(original); + if(typ == typeof(char)) + return new TokenTypeChar(original); + if(typ == typeof(Exception)) + return new TokenTypeExc(original); + + throw new Exception("unknown script type " + typ.ToString()); + } + + public static TokenType FromLSLType(Token original, string typ) + { + if(typ == "list") + return new TokenTypeList(original); + if(typ == "rotation") + return new TokenTypeRot(original); + if(typ == "vector") + return new TokenTypeVec(original); + if(typ == "float") + return new TokenTypeFloat(original); + if(typ == "integer") + return new TokenTypeInt(original); + if(typ == "key") + return new TokenTypeKey(original); + if(typ == "string") + return new TokenTypeStr(original); + if(typ == "object") + return new TokenTypeObject(original); + if(typ == "array") + return new TokenTypeArray(original); + if(typ == "bool") + return new TokenTypeBool(original); + if(typ == "void") + return new TokenTypeVoid(original); + if(typ == "char") + return new TokenTypeChar(original); + if(typ == "exception") + return new TokenTypeExc(original); + + throw new Exception("unknown type " + typ); + } + + /** + * @brief Estimate the number of bytes of memory taken by one of these + * objects. For objects with widely varying size, return the + * smallest it can be. + */ + public static int StaticSize(System.Type typ) + { + if(typ == typeof(LSL_List)) + return 96; + if(typ == typeof(LSL_Rotation)) + return 80; + if(typ == typeof(void)) + return 0; + if(typ == typeof(LSL_Vector)) + return 72; + if(typ == typeof(float)) + return 8; + if(typ == typeof(int)) + return 8; + if(typ == typeof(string)) + return 40; + if(typ == typeof(double)) + return 8; + if(typ == typeof(bool)) + return 8; + if(typ == typeof(XMR_Array)) + return 96; + if(typ == typeof(object)) + return 32; + if(typ == typeof(char)) + return 2; + + if(typ == typeof(LSL_Integer)) + return 32; + if(typ == typeof(LSL_Float)) + return 32; + if(typ == typeof(LSL_String)) + return 40; + + throw new Exception("unknown type " + typ.ToString()); + } + + /** + * @brief Return the corresponding system type. + */ + public abstract Type ToSysType(); + + /** + * @brief Return the equivalent LSL wrapping type. + * + * null: normal + * else: LSL-style wrapping, ie, LSL_Integer, LSL_Float, LSL_String + * ToSysType()=System.Int32; lslWrapping=LSL_Integer + * ToSysType()=System.Float; lslWrapping=LSL_Float + * ToSysType()=System.String; lslWrapping=LSL_String + */ + public virtual Type ToLSLWrapType() + { + return null; + } + + /** + * @brief Assign slots in either the global variable arrays or the script-defined type instance arrays. + * These only need to be implemented for script-visible types, ie, those that a script writer + * can actually define a variable as. + */ + public virtual void AssignVarSlot(TokenDeclVar declVar, XMRInstArSizes arSizes) + { + throw new Exception("not implemented for " + ToString() + " (" + GetType() + ")"); + } + + /** + * @brief Get heap tracking type. + * null indicates there is no heap tracker for the type. + */ + public virtual Type ToHeapTrackerType() + { + return null; + } + public virtual ConstructorInfo GetHeapTrackerCtor() + { + throw new ApplicationException("no GetHeapTrackerCtor for " + this.GetType()); + } + public virtual void CallHeapTrackerPopMeth(Token errorAt, ScriptMyILGen ilGen) + { + throw new ApplicationException("no CallHeapTrackerPopMeth for " + this.GetType()); + } + public virtual void CallHeapTrackerPushMeth(Token errorAt, ScriptMyILGen ilGen) + { + throw new ApplicationException("no CallHeapTrackerPushMeth for " + this.GetType()); + } + } + + public class TokenTypeArray: TokenType + { + private static readonly FieldInfo iarArraysFieldInfo = typeof(XMRInstArrays).GetField("iarArrays"); + + public TokenTypeArray(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { } + public TokenTypeArray(Token original) : base(original) { } + public override Type ToSysType() + { + return typeof(XMR_Array); + } + public override string ToString() + { + return "array"; + } + public override void AssignVarSlot(TokenDeclVar declVar, XMRInstArSizes arSizes) + { + declVar.vTableArray = iarArraysFieldInfo; + declVar.vTableIndex = arSizes.iasArrays++; + } + } + public class TokenTypeBool: TokenType + { + public TokenTypeBool(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { } + public TokenTypeBool(Token original) : base(original) { } + public override Type ToSysType() + { + return typeof(bool); + } + public override string ToString() + { + return "bool"; + } + } + public class TokenTypeChar: TokenType + { + private static readonly FieldInfo iarCharsFieldInfo = typeof(XMRInstArrays).GetField("iarChars"); + + public TokenTypeChar(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { } + public TokenTypeChar(Token original) : base(original) { } + public override Type ToSysType() + { + return typeof(char); + } + public override string ToString() + { + return "char"; + } + public override void AssignVarSlot(TokenDeclVar declVar, XMRInstArSizes arSizes) + { + declVar.vTableArray = iarCharsFieldInfo; + declVar.vTableIndex = arSizes.iasChars++; + } + } + public class TokenTypeExc: TokenType + { + private static readonly FieldInfo iarObjectsFieldInfo = typeof(XMRInstArrays).GetField("iarObjects"); + + public TokenTypeExc(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { } + public TokenTypeExc(Token original) : base(original) { } + public override Type ToSysType() + { + return typeof(Exception); + } + public override string ToString() + { + return "exception"; + } + public override void AssignVarSlot(TokenDeclVar declVar, XMRInstArSizes arSizes) + { + declVar.vTableArray = iarObjectsFieldInfo; + declVar.vTableIndex = arSizes.iasObjects++; + } + } + public class TokenTypeFloat: TokenType + { + private static readonly FieldInfo iarFloatsFieldInfo = typeof(XMRInstArrays).GetField("iarFloats"); + + public TokenTypeFloat(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { } + public TokenTypeFloat(Token original) : base(original) { } + public override Type ToSysType() + { + return typeof(double); + } + public override string ToString() + { + return "float"; + } + public override void AssignVarSlot(TokenDeclVar declVar, XMRInstArSizes arSizes) + { + declVar.vTableArray = iarFloatsFieldInfo; + declVar.vTableIndex = arSizes.iasFloats++; + } + } + public class TokenTypeInt: TokenType + { + private static readonly FieldInfo iarIntegersFieldInfo = typeof(XMRInstArrays).GetField("iarIntegers"); + + public TokenTypeInt(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { } + public TokenTypeInt(Token original) : base(original) { } + public override Type ToSysType() + { + return typeof(int); + } + public override string ToString() + { + return "integer"; + } + public override void AssignVarSlot(TokenDeclVar declVar, XMRInstArSizes arSizes) + { + declVar.vTableArray = iarIntegersFieldInfo; + declVar.vTableIndex = arSizes.iasIntegers++; + } + } + public class TokenTypeKey: TokenType + { + private static readonly FieldInfo iarStringsFieldInfo = typeof(XMRInstArrays).GetField("iarStrings"); + + public TokenTypeKey(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { } + public TokenTypeKey(Token original) : base(original) { } + public override Type ToSysType() + { + return typeof(string); + } + public override string ToString() + { + return "key"; + } + public override void AssignVarSlot(TokenDeclVar declVar, XMRInstArSizes arSizes) + { + declVar.vTableArray = iarStringsFieldInfo; + declVar.vTableIndex = arSizes.iasStrings++; + } + } + public class TokenTypeList: TokenType + { + private static readonly FieldInfo iarListsFieldInfo = typeof(XMRInstArrays).GetField("iarLists"); + private static readonly ConstructorInfo htListCtor = typeof(HeapTrackerList).GetConstructor(new Type[] { typeof(XMRInstAbstract) }); + + public TokenTypeList(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { } + public TokenTypeList(Token original) : base(original) { } + public override Type ToSysType() + { + return typeof(LSL_List); + } + public override string ToString() + { + return "list"; + } + public override void AssignVarSlot(TokenDeclVar declVar, XMRInstArSizes arSizes) + { + declVar.vTableArray = iarListsFieldInfo; + declVar.vTableIndex = arSizes.iasLists++; + } + public override Type ToHeapTrackerType() + { + return typeof(HeapTrackerList); + } + public override ConstructorInfo GetHeapTrackerCtor() + { + return htListCtor; + } + public override void CallHeapTrackerPopMeth(Token errorAt, ScriptMyILGen ilGen) + { + HeapTrackerList.GenPop(errorAt, ilGen); + } + public override void CallHeapTrackerPushMeth(Token errorAt, ScriptMyILGen ilGen) + { + HeapTrackerList.GenPush(errorAt, ilGen); + } + } + public class TokenTypeObject: TokenType + { + private static readonly FieldInfo iarObjectsFieldInfo = typeof(XMRInstArrays).GetField("iarObjects"); + private static readonly ConstructorInfo htObjectCtor = typeof(HeapTrackerObject).GetConstructor(new Type[] { typeof(XMRInstAbstract) }); + + public TokenTypeObject(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { } + public TokenTypeObject(Token original) : base(original) { } + public override Type ToSysType() + { + return typeof(object); + } + public override string ToString() + { + return "object"; + } + public override void AssignVarSlot(TokenDeclVar declVar, XMRInstArSizes arSizes) + { + declVar.vTableArray = iarObjectsFieldInfo; + declVar.vTableIndex = arSizes.iasObjects++; + } + public override Type ToHeapTrackerType() + { + return typeof(HeapTrackerObject); + } + public override ConstructorInfo GetHeapTrackerCtor() + { + return htObjectCtor; + } + public override void CallHeapTrackerPopMeth(Token errorAt, ScriptMyILGen ilGen) + { + HeapTrackerObject.GenPop(errorAt, ilGen); + } + public override void CallHeapTrackerPushMeth(Token errorAt, ScriptMyILGen ilGen) + { + HeapTrackerObject.GenPush(errorAt, ilGen); + } + } + public class TokenTypeRot: TokenType + { + private static readonly FieldInfo iarRotationsFieldInfo = typeof(XMRInstArrays).GetField("iarRotations"); + + public TokenTypeRot(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { } + public TokenTypeRot(Token original) : base(original) { } + public override Type ToSysType() + { + return typeof(LSL_Rotation); + } + public override string ToString() + { + return "rotation"; + } + public override void AssignVarSlot(TokenDeclVar declVar, XMRInstArSizes arSizes) + { + declVar.vTableArray = iarRotationsFieldInfo; + declVar.vTableIndex = arSizes.iasRotations++; + } + } + public class TokenTypeStr: TokenType + { + private static readonly FieldInfo iarStringsFieldInfo = typeof(XMRInstArrays).GetField("iarStrings"); + private static readonly ConstructorInfo htStringCtor = typeof(HeapTrackerString).GetConstructor(new Type[] { typeof(XMRInstAbstract) }); + + public TokenTypeStr(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { } + public TokenTypeStr(Token original) : base(original) { } + public override Type ToSysType() + { + return typeof(string); + } + public override string ToString() + { + return "string"; + } + public override void AssignVarSlot(TokenDeclVar declVar, XMRInstArSizes arSizes) + { + declVar.vTableArray = iarStringsFieldInfo; + declVar.vTableIndex = arSizes.iasStrings++; + } + public override Type ToHeapTrackerType() + { + return typeof(HeapTrackerString); + } + public override ConstructorInfo GetHeapTrackerCtor() + { + return htStringCtor; + } + public override void CallHeapTrackerPopMeth(Token errorAt, ScriptMyILGen ilGen) + { + HeapTrackerString.GenPop(errorAt, ilGen); + } + public override void CallHeapTrackerPushMeth(Token errorAt, ScriptMyILGen ilGen) + { + HeapTrackerString.GenPush(errorAt, ilGen); + } + } + public class TokenTypeUndef: TokenType + { // for the 'undef' constant, ie, null object pointer + public TokenTypeUndef(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { } + public TokenTypeUndef(Token original) : base(original) { } + public override Type ToSysType() + { + return typeof(object); + } + public override string ToString() + { + return "undef"; + } + } + public class TokenTypeVec: TokenType + { + private static readonly FieldInfo iarVectorsFieldInfo = typeof(XMRInstArrays).GetField("iarVectors"); + + public TokenTypeVec(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { } + public TokenTypeVec(Token original) : base(original) { } + public override Type ToSysType() + { + return typeof(LSL_Vector); + } + public override string ToString() + { + return "vector"; + } + public override void AssignVarSlot(TokenDeclVar declVar, XMRInstArSizes arSizes) + { + declVar.vTableArray = iarVectorsFieldInfo; + declVar.vTableIndex = arSizes.iasVectors++; + } + } + public class TokenTypeVoid: TokenType + { // used only for function/method return types + public TokenTypeVoid(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { } + public TokenTypeVoid(Token original) : base(original) { } + public override Type ToSysType() + { + return typeof(void); + } + public override string ToString() + { + return "void"; + } + } + + public class TokenTypeLSLFloat: TokenTypeFloat + { + public TokenTypeLSLFloat(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { } + public TokenTypeLSLFloat(Token original) : base(original) { } + public override Type ToLSLWrapType() + { + return typeof(LSL_Float); + } + } + public class TokenTypeLSLInt: TokenTypeInt + { + public TokenTypeLSLInt(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { } + public TokenTypeLSLInt(Token original) : base(original) { } + public override Type ToLSLWrapType() + { + return typeof(LSL_Integer); + } + } + public class TokenTypeLSLKey: TokenTypeKey + { + public TokenTypeLSLKey(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { } + public TokenTypeLSLKey(Token original) : base(original) { } + public override Type ToLSLWrapType() + { + return typeof(LSL_Key); + } + } + public class TokenTypeLSLString: TokenTypeStr + { + public TokenTypeLSLString(TokenErrorMessage emsg, string file, int line, int posn) : base(emsg, file, line, posn) { } + public TokenTypeLSLString(Token original) : base(original) { } + public override Type ToLSLWrapType() + { + return typeof(LSL_String); + } + } +} diff --git a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptTypeCast.cs b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptTypeCast.cs new file mode 100644 index 0000000000..dd0e5e061e --- /dev/null +++ b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptTypeCast.cs @@ -0,0 +1,978 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using OpenSim.Region.ScriptEngine.Shared.ScriptBase; +using OpenSim.Region.ScriptEngine.Yengine; +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Reflection.Emit; + +using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; +using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; +using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; +using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list; +using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; +using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; +using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; + +/** + * @brief Generate script object code to perform type casting + */ + +namespace OpenSim.Region.ScriptEngine.Yengine +{ + + public class TypeCast + { + private delegate void CastDelegate(IScriptCodeGen scg, Token errorAt); + + private static ConstructorInfo floatConstructorStringInfo = typeof(LSL_Float).GetConstructor(new Type[] { typeof(string) }); + private static ConstructorInfo integerConstructorStringInfo = typeof(LSL_Integer).GetConstructor(new Type[] { typeof(string) }); + private static ConstructorInfo lslFloatConstructorInfo = typeof(LSL_Float).GetConstructor(new Type[] { typeof(double) }); + private static ConstructorInfo lslIntegerConstructorInfo = typeof(LSL_Integer).GetConstructor(new Type[] { typeof(int) }); + private static ConstructorInfo lslStringConstructorInfo = typeof(LSL_String).GetConstructor(new Type[] { typeof(string) }); + private static ConstructorInfo rotationConstrucorStringInfo = typeof(LSL_Rotation).GetConstructor(new Type[] { typeof(string) }); + private static ConstructorInfo vectorConstrucorStringInfo = typeof(LSL_Vector).GetConstructor(new Type[] { typeof(string) }); + private static FieldInfo lslFloatValueFieldInfo = typeof(LSL_Float).GetField("value"); + private static FieldInfo lslIntegerValueFieldInfo = typeof(LSL_Integer).GetField("value"); + private static FieldInfo lslStringValueFieldInfo = typeof(LSL_String).GetField("m_string"); + private static FieldInfo sdtcITableFieldInfo = typeof(XMRSDTypeClObj).GetField("sdtcITable"); + private static MethodInfo boolToListMethodInfo = typeof(TypeCast).GetMethod("BoolToList", new Type[] { typeof(bool) }); + private static MethodInfo boolToStringMethodInfo = typeof(TypeCast).GetMethod("BoolToString", new Type[] { typeof(bool) }); + private static MethodInfo charToStringMethodInfo = typeof(TypeCast).GetMethod("CharToString", new Type[] { typeof(char) }); + private static MethodInfo excToStringMethodInfo = typeof(TypeCast).GetMethod("ExceptionToString", new Type[] { typeof(Exception), typeof(XMRInstAbstract) }); + private static MethodInfo floatToStringMethodInfo = typeof(TypeCast).GetMethod("FloatToString", new Type[] { typeof(double) }); + private static MethodInfo intToStringMethodInfo = typeof(TypeCast).GetMethod("IntegerToString", new Type[] { typeof(int) }); + private static MethodInfo keyToBoolMethodInfo = typeof(TypeCast).GetMethod("KeyToBool", new Type[] { typeof(string) }); + private static MethodInfo listToBoolMethodInfo = typeof(TypeCast).GetMethod("ListToBool", new Type[] { typeof(LSL_List) }); + private static MethodInfo listToStringMethodInfo = typeof(TypeCast).GetMethod("ListToString", new Type[] { typeof(LSL_List) }); + private static MethodInfo objectToFloatMethodInfo = typeof(TypeCast).GetMethod("ObjectToFloat", new Type[] { typeof(object) }); + private static MethodInfo objectToIntegerMethodInfo = typeof(TypeCast).GetMethod("ObjectToInteger", new Type[] { typeof(object) }); + private static MethodInfo objectToListMethodInfo = typeof(TypeCast).GetMethod("ObjectToList", new Type[] { typeof(object) }); + private static MethodInfo objectToRotationMethodInfo = typeof(TypeCast).GetMethod("ObjectToRotation", new Type[] { typeof(object) }); + private static MethodInfo objectToStringMethodInfo = typeof(TypeCast).GetMethod("ObjectToString", new Type[] { typeof(object) }); + private static MethodInfo objectToVectorMethodInfo = typeof(TypeCast).GetMethod("ObjectToVector", new Type[] { typeof(object) }); + private static MethodInfo rotationToBoolMethodInfo = typeof(TypeCast).GetMethod("RotationToBool", new Type[] { typeof(LSL_Rotation) }); + private static MethodInfo rotationToStringMethodInfo = typeof(TypeCast).GetMethod("RotationToString", new Type[] { typeof(LSL_Rotation) }); + private static MethodInfo stringToBoolMethodInfo = typeof(TypeCast).GetMethod("StringToBool", new Type[] { typeof(string) }); + private static MethodInfo vectorToBoolMethodInfo = typeof(TypeCast).GetMethod("VectorToBool", new Type[] { typeof(LSL_Vector) }); + private static MethodInfo vectorToStringMethodInfo = typeof(TypeCast).GetMethod("VectorToString", new Type[] { typeof(LSL_Vector) }); + private static MethodInfo sdTypeClassCastClass2ClassMethodInfo = typeof(XMRSDTypeClObj).GetMethod("CastClass2Class", new Type[] { typeof(object), typeof(int) }); + private static MethodInfo sdTypeClassCastIFace2ClassMethodInfo = typeof(XMRSDTypeClObj).GetMethod("CastIFace2Class", new Type[] { typeof(Delegate[]), typeof(int) }); + private static MethodInfo sdTypeClassCastObj2IFaceMethodInfo = typeof(XMRSDTypeClObj).GetMethod("CastObj2IFace", new Type[] { typeof(object), typeof(string) }); + private static MethodInfo charToListMethodInfo = typeof(TypeCast).GetMethod("CharToList", new Type[] { typeof(char) }); + private static MethodInfo excToListMethodInfo = typeof(TypeCast).GetMethod("ExcToList", new Type[] { typeof(Exception) }); + private static MethodInfo vectorToListMethodInfo = typeof(TypeCast).GetMethod("VectorToList", new Type[] { typeof(LSL_Vector) }); + private static MethodInfo floatToListMethodInfo = typeof(TypeCast).GetMethod("FloatToList", new Type[] { typeof(double) }); + private static MethodInfo integerToListMethodInfo = typeof(TypeCast).GetMethod("IntegerToList", new Type[] { typeof(int) }); + private static MethodInfo rotationToListMethodInfo = typeof(TypeCast).GetMethod("RotationToList", new Type[] { typeof(LSL_Rotation) }); + private static MethodInfo stringToListMethodInfo = typeof(TypeCast).GetMethod("StringToList", new Type[] { typeof(string) }); + + /* + * List of all allowed type casts and how to perform the casting. + */ + private static Dictionary legalTypeCasts = CreateLegalTypeCasts(); + + /** + * @brief create a dictionary of legal type casts. + * Defines what EXPLICIT type casts are allowed in addition to the IMPLICIT ones. + * Key is of the form for IMPLICIT casting. + * Key is of the form * for EXPLICIT casting. + * Value is a delegate that generates code to perform the type cast. + */ + private static Dictionary CreateLegalTypeCasts() + { + Dictionary ltc = new Dictionary(); + + // IMPLICIT type casts (a space is in middle of the key) + // EXPLICIT type casts (an * is in middle of the key) + // In general, only mark explicit if it might throw an exception + ltc.Add("array object", TypeCastArray2Object); + ltc.Add("bool float", TypeCastBool2Float); + ltc.Add("bool integer", TypeCastBool2Integer); + ltc.Add("bool list", TypeCastBool2List); + ltc.Add("bool object", TypeCastBool2Object); + ltc.Add("bool string", TypeCastBool2String); + ltc.Add("char integer", TypeCastChar2Integer); + ltc.Add("char list", TypeCastChar2List); + ltc.Add("char object", TypeCastChar2Object); + ltc.Add("char string", TypeCastChar2String); + ltc.Add("exception list", TypeCastExc2List); + ltc.Add("exception object", TypeCastExc2Object); + ltc.Add("exception string", TypeCastExc2String); + ltc.Add("float bool", TypeCastFloat2Bool); + ltc.Add("float integer", TypeCastFloat2Integer); + ltc.Add("float list", TypeCastFloat2List); + ltc.Add("float object", TypeCastFloat2Object); + ltc.Add("float string", TypeCastFloat2String); + ltc.Add("integer bool", TypeCastInteger2Bool); + ltc.Add("integer char", TypeCastInteger2Char); + ltc.Add("integer float", TypeCastInteger2Float); + ltc.Add("integer list", TypeCastInteger2List); + ltc.Add("integer object", TypeCastInteger2Object); + ltc.Add("integer string", TypeCastInteger2String); + ltc.Add("list bool", TypeCastList2Bool); + ltc.Add("list object", TypeCastList2Object); + ltc.Add("list string", TypeCastList2String); + ltc.Add("object*array", TypeCastObject2Array); + ltc.Add("object*bool", TypeCastObject2Bool); + ltc.Add("object*char", TypeCastObject2Char); + ltc.Add("object*exception", TypeCastObject2Exc); + ltc.Add("object*float", TypeCastObject2Float); + ltc.Add("object*integer", TypeCastObject2Integer); + ltc.Add("object*list", TypeCastObject2List); + ltc.Add("object*rotation", TypeCastObject2Rotation); + ltc.Add("object string", TypeCastObject2String); + ltc.Add("object*vector", TypeCastObject2Vector); + ltc.Add("rotation bool", TypeCastRotation2Bool); + ltc.Add("rotation list", TypeCastRotation2List); + ltc.Add("rotation object", TypeCastRotation2Object); + ltc.Add("rotation string", TypeCastRotation2String); + ltc.Add("string bool", TypeCastString2Bool); + ltc.Add("string float", TypeCastString2Float); + ltc.Add("string integer", TypeCastString2Integer); + ltc.Add("string list", TypeCastString2List); + ltc.Add("string object", TypeCastString2Object); + ltc.Add("string rotation", TypeCastString2Rotation); + ltc.Add("string vector", TypeCastString2Vector); + ltc.Add("vector bool", TypeCastVector2Bool); + ltc.Add("vector list", TypeCastVector2List); + ltc.Add("vector object", TypeCastVector2Object); + ltc.Add("vector string", TypeCastVector2String); + + return ltc; + } + + /** + * @brief See if the given type can be cast to the other implicitly. + * @param dstType = type being cast to + * @param srcType = type being cast from + * @returns false: implicit cast not allowed + * true: implicit cast allowed + */ + public static bool IsAssignableFrom(TokenType dstType, TokenType srcType) + { + // Do a 'dry run' of the casting operation, discarding any emits and not printing any errors. + // But if the casting tries to print error(s), return false. + // Otherwise assume the cast is allowed and return true. + SCGIAF scg = new SCGIAF(); + scg.ok = true; + scg._ilGen = migiaf; + CastTopOfStack(scg, null, srcType, dstType, false); + return scg.ok; + } + + private struct SCGIAF: IScriptCodeGen + { + public bool ok; + public ScriptMyILGen _ilGen; + + // IScriptCodeGen + public ScriptMyILGen ilGen + { + get + { + return _ilGen; + } + } + public void ErrorMsg(Token token, string message) + { + ok = false; + } + public void PushDefaultValue(TokenType type) + { + } + public void PushXMRInst() + { + } + } + + private static readonly MIGIAF migiaf = new MIGIAF(); + private struct MIGIAF: ScriptMyILGen + { + // ScriptMyILGen + public string methName + { + get + { + return null; + } + } + public ScriptMyLocal DeclareLocal(Type type, string name) + { + return null; + } + public ScriptMyLabel DefineLabel(string name) + { + return null; + } + public void BeginExceptionBlock() + { + } + public void BeginCatchBlock(Type excType) + { + } + public void BeginFinallyBlock() + { + } + public void EndExceptionBlock() + { + } + public void Emit(Token errorAt, OpCode opcode) + { + } + public void Emit(Token errorAt, OpCode opcode, FieldInfo field) + { + } + public void Emit(Token errorAt, OpCode opcode, ScriptMyLocal myLocal) + { + } + public void Emit(Token errorAt, OpCode opcode, Type type) + { + } + public void Emit(Token errorAt, OpCode opcode, ScriptMyLabel myLabel) + { + } + public void Emit(Token errorAt, OpCode opcode, ScriptMyLabel[] myLabels) + { + } + public void Emit(Token errorAt, OpCode opcode, ScriptObjWriter method) + { + } + public void Emit(Token errorAt, OpCode opcode, MethodInfo method) + { + } + public void Emit(Token errorAt, OpCode opcode, ConstructorInfo ctor) + { + } + public void Emit(Token errorAt, OpCode opcode, double value) + { + } + public void Emit(Token errorAt, OpCode opcode, float value) + { + } + public void Emit(Token errorAt, OpCode opcode, int value) + { + } + public void Emit(Token errorAt, OpCode opcode, string value) + { + } + public void MarkLabel(ScriptMyLabel myLabel) + { + } + } + + /** + * @brief Emit code that converts the top stack item from 'oldType' to 'newType' + * @param scg = what script we are compiling + * @param errorAt = token used for source location for error messages + * @param oldType = type of item currently on the stack + * @param newType = type to convert it to + * @param explicitAllowed = false: only consider implicit casts + * true: consider both implicit and explicit casts + * @returns with code emitted for conversion (or error message output if not allowed, and stack left unchanged) + */ + public static void CastTopOfStack(IScriptCodeGen scg, Token errorAt, TokenType oldType, TokenType newType, bool explicitAllowed) + { + CastDelegate castDelegate; + string oldString = oldType.ToString(); + string newString = newType.ToString(); + + // 'key' -> 'bool' is the only time we care about key being different than string. + if((oldString == "key") && (newString == "bool")) + { + LSLUnwrap(scg, errorAt, oldType); + scg.ilGen.Emit(errorAt, OpCodes.Call, keyToBoolMethodInfo); + LSLWrap(scg, errorAt, newType); + return; + } + + // Treat key and string as same type for all other type casts. + if(oldString == "key") + oldString = "string"; + if(newString == "key") + newString = "string"; + + // If the types are the same, there is no conceptual casting needed. + // However, there may be wraping/unwraping to/from the LSL wrappers. + if(oldString == newString) + { + if(oldType.ToLSLWrapType() != newType.ToLSLWrapType()) + { + LSLUnwrap(scg, errorAt, oldType); + LSLWrap(scg, errorAt, newType); + } + return; + } + + // Script-defined classes can be cast up and down the tree. + if((oldType is TokenTypeSDTypeClass) && (newType is TokenTypeSDTypeClass)) + { + TokenDeclSDTypeClass oldSDTC = ((TokenTypeSDTypeClass)oldType).decl; + TokenDeclSDTypeClass newSDTC = ((TokenTypeSDTypeClass)newType).decl; + + // implicit cast allowed from leaf toward root + for(TokenDeclSDTypeClass sdtc = oldSDTC; sdtc != null; sdtc = sdtc.extends) + { + if(sdtc == newSDTC) + return; + } + + // explicit cast allowed from root toward leaf + for(TokenDeclSDTypeClass sdtc = newSDTC; sdtc != null; sdtc = sdtc.extends) + { + if(sdtc == oldSDTC) + { + ExplCheck(scg, errorAt, explicitAllowed, oldString, newString); + scg.ilGen.Emit(errorAt, OpCodes.Ldc_I4, newSDTC.sdTypeIndex); + scg.ilGen.Emit(errorAt, OpCodes.Call, sdTypeClassCastClass2ClassMethodInfo); + return; + } + } + + // not on same branch + goto illcast; + } + + // One script-defined interface type cannot be cast to another script-defined interface type, + // unless the old interface declares that it implements the new interface. That proves that + // the underlying object, no matter what type, implements the new interface. + if((oldType is TokenTypeSDTypeInterface) && (newType is TokenTypeSDTypeInterface)) + { + TokenDeclSDTypeInterface oldDecl = ((TokenTypeSDTypeInterface)oldType).decl; + TokenDeclSDTypeInterface newDecl = ((TokenTypeSDTypeInterface)newType).decl; + if(!oldDecl.Implements(newDecl)) + goto illcast; + scg.ilGen.Emit(errorAt, OpCodes.Ldstr, newType.ToString()); + scg.ilGen.Emit(errorAt, OpCodes.Call, sdTypeClassCastObj2IFaceMethodInfo); + return; + } + + // A script-defined class type can be implicitly cast to a script-defined interface type that it + // implements. The result is an array of delegates that give the class's implementation of the + // various methods defined by the interface. + if((oldType is TokenTypeSDTypeClass) && (newType is TokenTypeSDTypeInterface)) + { + TokenDeclSDTypeClass oldSDTC = ((TokenTypeSDTypeClass)oldType).decl; + int intfIndex; + if(!oldSDTC.intfIndices.TryGetValue(newType.ToString(), out intfIndex)) + goto illcast; + scg.ilGen.Emit(errorAt, OpCodes.Ldfld, sdtcITableFieldInfo); + scg.ilGen.Emit(errorAt, OpCodes.Ldc_I4, intfIndex); + scg.ilGen.Emit(errorAt, OpCodes.Ldelem, typeof(Delegate[])); + return; + } + + // A script-defined interface type can be explicitly cast to a script-defined class type by + // extracting the Target property from element 0 of the delegate array that is the interface + // object and making sure it casts to the correct script-defined class type. + // + // But then only if the class type implements the interface type. + if((oldType is TokenTypeSDTypeInterface) && (newType is TokenTypeSDTypeClass)) + { + TokenTypeSDTypeInterface oldSDTI = (TokenTypeSDTypeInterface)oldType; + TokenTypeSDTypeClass newSDTC = (TokenTypeSDTypeClass)newType; + + if(!newSDTC.decl.CanCastToIntf(oldSDTI.decl)) + goto illcast; + + ExplCheck(scg, errorAt, explicitAllowed, oldString, newString); + scg.ilGen.Emit(errorAt, OpCodes.Ldc_I4, newSDTC.decl.sdTypeIndex); + scg.ilGen.Emit(errorAt, OpCodes.Call, sdTypeClassCastIFace2ClassMethodInfo); + return; + } + + // A script-defined interface type can be implicitly cast to object. + if((oldType is TokenTypeSDTypeInterface) && (newType is TokenTypeObject)) + { + return; + } + + // An object can be explicitly cast to a script-defined interface. + if((oldType is TokenTypeObject) && (newType is TokenTypeSDTypeInterface)) + { + ExplCheck(scg, errorAt, explicitAllowed, oldString, newString); + scg.ilGen.Emit(errorAt, OpCodes.Ldstr, newString); + scg.ilGen.Emit(errorAt, OpCodes.Call, sdTypeClassCastObj2IFaceMethodInfo); + return; + } + + // Cast to void is always allowed, such as discarding value from 'i++' or function return value. + if(newType is TokenTypeVoid) + { + scg.ilGen.Emit(errorAt, OpCodes.Pop); + return; + } + + // Cast from undef to object or script-defined type is always allowed. + if((oldType is TokenTypeUndef) && + ((newType is TokenTypeObject) || + (newType is TokenTypeSDTypeClass) || + (newType is TokenTypeSDTypeInterface))) + { + return; + } + + // Script-defined classes can be implicitly cast to objects. + if((oldType is TokenTypeSDTypeClass) && (newType is TokenTypeObject)) + { + return; + } + + // Script-defined classes can be explicitly cast from objects and other script-defined classes. + // Note that we must manually check that it is the correct SDTypeClass however because as far as + // mono is concerned, all SDTypeClass's are the same. + if((oldType is TokenTypeObject) && (newType is TokenTypeSDTypeClass)) + { + ExplCheck(scg, errorAt, explicitAllowed, oldString, newString); + scg.ilGen.Emit(errorAt, OpCodes.Ldc_I4, ((TokenTypeSDTypeClass)newType).decl.sdTypeIndex); + scg.ilGen.Emit(errorAt, OpCodes.Call, sdTypeClassCastClass2ClassMethodInfo); + return; + } + + // Delegates can be implicitly cast to/from objects. + if((oldType is TokenTypeSDTypeDelegate) && (newType is TokenTypeObject)) + { + return; + } + if((oldType is TokenTypeObject) && (newType is TokenTypeSDTypeDelegate)) + { + scg.ilGen.Emit(errorAt, OpCodes.Castclass, newType.ToSysType()); + return; + } + + // Some actual conversion is needed, see if it is in table of legal casts. + string key = oldString + " " + newString; + if(!legalTypeCasts.TryGetValue(key, out castDelegate)) + { + key = oldString + "*" + newString; + if(!legalTypeCasts.TryGetValue(key, out castDelegate)) + goto illcast; + ExplCheck(scg, errorAt, explicitAllowed, oldString, newString); + } + + // Ok, output cast. But make sure it is in native form without any LSL wrapping + // before passing to our casting routine. Then if caller is expecting an LSL- + // wrapped value on the stack upon return, wrap it up after our casting. + LSLUnwrap(scg, errorAt, oldType); + castDelegate(scg, errorAt); + LSLWrap(scg, errorAt, newType); + return; + + illcast: + scg.ErrorMsg(errorAt, "illegal to cast from " + oldString + " to " + newString); + if(!(oldType is TokenTypeVoid)) + scg.ilGen.Emit(errorAt, OpCodes.Pop); + scg.PushDefaultValue(newType); + } + private static void ExplCheck(IScriptCodeGen scg, Token errorAt, bool explicitAllowed, string oldString, string newString) + { + if(!explicitAllowed) + { + scg.ErrorMsg(errorAt, "must explicitly cast from " + oldString + " to " + newString); + } + } + + /** + * @brief If value on the stack is an LSL-style wrapped value, unwrap it. + */ + public static void LSLUnwrap(IScriptCodeGen scg, Token errorAt, TokenType type) + { + if(type.ToLSLWrapType() == typeof(LSL_Float)) + { + scg.ilGen.Emit(errorAt, OpCodes.Ldfld, lslFloatValueFieldInfo); + } + if(type.ToLSLWrapType() == typeof(LSL_Integer)) + { + scg.ilGen.Emit(errorAt, OpCodes.Ldfld, lslIntegerValueFieldInfo); + } + if(type.ToLSLWrapType() == typeof(LSL_String)) + { + scg.ilGen.Emit(errorAt, OpCodes.Ldfld, lslStringValueFieldInfo); + } + } + + /** + * @brief If caller wants the unwrapped value on stack wrapped LSL-style, wrap it. + */ + private static void LSLWrap(IScriptCodeGen scg, Token errorAt, TokenType type) + { + if(type.ToLSLWrapType() == typeof(LSL_Float)) + { + scg.ilGen.Emit(errorAt, OpCodes.Newobj, lslFloatConstructorInfo); + } + if(type.ToLSLWrapType() == typeof(LSL_Integer)) + { + scg.ilGen.Emit(errorAt, OpCodes.Newobj, lslIntegerConstructorInfo); + } + if(type.ToLSLWrapType() == typeof(LSL_String)) + { + scg.ilGen.Emit(errorAt, OpCodes.Newobj, lslStringConstructorInfo); + } + } + + /** + * @brief These routines output code to perform casting. + * They can assume there are no LSL wrapped values on input + * and they should not output an LSL wrapped value. + */ + private static void TypeCastArray2Object(IScriptCodeGen scg, Token errorAt) + { + } + private static void TypeCastBool2Float(IScriptCodeGen scg, Token errorAt) + { + if(typeof(double) == typeof(float)) + { + scg.ilGen.Emit(errorAt, OpCodes.Conv_R4); + } + else if(typeof(double) == typeof(double)) + { + scg.ilGen.Emit(errorAt, OpCodes.Conv_R8); + } + else + { + throw new Exception("unknown type"); + } + } + private static void TypeCastBool2Integer(IScriptCodeGen scg, Token errorAt) + { + } + private static void TypeCastBool2Object(IScriptCodeGen scg, Token errorAt) + { + scg.ilGen.Emit(errorAt, OpCodes.Box, typeof(bool)); + } + private static void TypeCastChar2Integer(IScriptCodeGen scg, Token errorAt) + { + } + private static void TypeCastChar2List(IScriptCodeGen scg, Token errorAt) + { + scg.ilGen.Emit(errorAt, OpCodes.Call, charToListMethodInfo); + } + private static void TypeCastChar2Object(IScriptCodeGen scg, Token errorAt) + { + scg.ilGen.Emit(errorAt, OpCodes.Box, typeof(char)); + } + private static void TypeCastChar2String(IScriptCodeGen scg, Token errorAt) + { + scg.ilGen.Emit(errorAt, OpCodes.Call, charToStringMethodInfo); + } + private static void TypeCastExc2List(IScriptCodeGen scg, Token errorAt) + { + scg.ilGen.Emit(errorAt, OpCodes.Call, excToListMethodInfo); + } + private static void TypeCastExc2Object(IScriptCodeGen scg, Token errorAt) + { + } + private static void TypeCastExc2String(IScriptCodeGen scg, Token errorAt) + { + scg.PushXMRInst(); + scg.ilGen.Emit(errorAt, OpCodes.Call, excToStringMethodInfo); + } + private static void TypeCastFloat2Bool(IScriptCodeGen scg, Token errorAt) + { + scg.ilGen.Emit(errorAt, OpCodes.Ldc_R4, 0.0f); + scg.ilGen.Emit(errorAt, OpCodes.Ceq); + scg.ilGen.Emit(errorAt, OpCodes.Ldc_I4_1); + scg.ilGen.Emit(errorAt, OpCodes.Xor); + } + private static void TypeCastFloat2Integer(IScriptCodeGen scg, Token errorAt) + { + scg.ilGen.Emit(errorAt, OpCodes.Conv_I4); + } + private static void TypeCastFloat2Object(IScriptCodeGen scg, Token errorAt) + { + scg.ilGen.Emit(errorAt, OpCodes.Box, typeof(double)); + } + private static void TypeCastInteger2Bool(IScriptCodeGen scg, Token errorAt) + { + scg.ilGen.Emit(errorAt, OpCodes.Ldc_I4_0); + scg.ilGen.Emit(errorAt, OpCodes.Ceq); + scg.ilGen.Emit(errorAt, OpCodes.Ldc_I4_1); + scg.ilGen.Emit(errorAt, OpCodes.Xor); + } + private static void TypeCastInteger2Char(IScriptCodeGen scg, Token errorAt) + { + } + private static void TypeCastInteger2Float(IScriptCodeGen scg, Token errorAt) + { + if(typeof(double) == typeof(float)) + { + scg.ilGen.Emit(errorAt, OpCodes.Conv_R4); + } + else if(typeof(double) == typeof(double)) + { + scg.ilGen.Emit(errorAt, OpCodes.Conv_R8); + } + else + { + throw new Exception("unknown type"); + } + } + private static void TypeCastInteger2Object(IScriptCodeGen scg, Token errorAt) + { + scg.ilGen.Emit(errorAt, OpCodes.Box, typeof(int)); + } + private static void TypeCastList2Bool(IScriptCodeGen scg, Token errorAt) + { + scg.ilGen.Emit(errorAt, OpCodes.Call, listToBoolMethodInfo); + } + private static void TypeCastList2Object(IScriptCodeGen scg, Token errorAt) + { + if(typeof(LSL_List).IsValueType) + { + scg.ilGen.Emit(errorAt, OpCodes.Box, typeof(LSL_List)); + } + } + private static void TypeCastObject2Array(IScriptCodeGen scg, Token errorAt) + { + scg.ilGen.Emit(errorAt, OpCodes.Castclass, typeof(XMR_Array)); + } + private static void TypeCastObject2Bool(IScriptCodeGen scg, Token errorAt) + { + scg.ilGen.Emit(errorAt, OpCodes.Unbox_Any, typeof(bool)); + } + private static void TypeCastObject2Char(IScriptCodeGen scg, Token errorAt) + { + scg.ilGen.Emit(errorAt, OpCodes.Unbox_Any, typeof(char)); + } + private static void TypeCastObject2Exc(IScriptCodeGen scg, Token errorAt) + { + scg.ilGen.Emit(errorAt, OpCodes.Castclass, typeof(Exception)); + } + private static void TypeCastObject2Float(IScriptCodeGen scg, Token errorAt) + { + scg.ilGen.Emit(errorAt, OpCodes.Call, objectToFloatMethodInfo); + } + private static void TypeCastObject2Integer(IScriptCodeGen scg, Token errorAt) + { + scg.ilGen.Emit(errorAt, OpCodes.Call, objectToIntegerMethodInfo); + } + private static void TypeCastObject2List(IScriptCodeGen scg, Token errorAt) + { + if(typeof(LSL_List).IsValueType) + { + scg.ilGen.Emit(errorAt, OpCodes.Call, objectToListMethodInfo); + } + else + { + scg.ilGen.Emit(errorAt, OpCodes.Castclass, typeof(LSL_List)); + } + } + private static void TypeCastObject2Rotation(IScriptCodeGen scg, Token errorAt) + { + scg.ilGen.Emit(errorAt, OpCodes.Call, objectToRotationMethodInfo); + } + private static void TypeCastObject2Vector(IScriptCodeGen scg, Token errorAt) + { + scg.ilGen.Emit(errorAt, OpCodes.Call, objectToVectorMethodInfo); + } + private static void TypeCastRotation2Bool(IScriptCodeGen scg, Token errorAt) + { + scg.ilGen.Emit(errorAt, OpCodes.Call, rotationToBoolMethodInfo); + } + private static void TypeCastRotation2Object(IScriptCodeGen scg, Token errorAt) + { + scg.ilGen.Emit(errorAt, OpCodes.Box, typeof(LSL_Rotation)); + } + private static void TypeCastString2Bool(IScriptCodeGen scg, Token errorAt) + { + scg.ilGen.Emit(errorAt, OpCodes.Call, stringToBoolMethodInfo); + } + private static void TypeCastString2Object(IScriptCodeGen scg, Token errorAt) + { + } + private static void TypeCastString2Rotation(IScriptCodeGen scg, Token errorAt) + { + scg.ilGen.Emit(errorAt, OpCodes.Newobj, rotationConstrucorStringInfo); + } + private static void TypeCastString2Vector(IScriptCodeGen scg, Token errorAt) + { + scg.ilGen.Emit(errorAt, OpCodes.Newobj, vectorConstrucorStringInfo); + } + private static void TypeCastVector2Bool(IScriptCodeGen scg, Token errorAt) + { + scg.ilGen.Emit(errorAt, OpCodes.Call, vectorToBoolMethodInfo); + } + private static void TypeCastVector2List(IScriptCodeGen scg, Token errorAt) + { + scg.ilGen.Emit(errorAt, OpCodes.Call, vectorToListMethodInfo); + } + private static void TypeCastVector2Object(IScriptCodeGen scg, Token errorAt) + { + scg.ilGen.Emit(errorAt, OpCodes.Box, typeof(LSL_Vector)); + } + private static void TypeCastBool2List(IScriptCodeGen scg, Token errorAt) + { + scg.ilGen.Emit(errorAt, OpCodes.Call, boolToListMethodInfo); + } + private static void TypeCastBool2String(IScriptCodeGen scg, Token errorAt) + { + scg.ilGen.Emit(errorAt, OpCodes.Call, boolToStringMethodInfo); + } + private static void TypeCastFloat2List(IScriptCodeGen scg, Token errorAt) + { + scg.ilGen.Emit(errorAt, OpCodes.Call, floatToListMethodInfo); + } + private static void TypeCastFloat2String(IScriptCodeGen scg, Token errorAt) + { + scg.ilGen.Emit(errorAt, OpCodes.Call, floatToStringMethodInfo); + } + private static void TypeCastInteger2List(IScriptCodeGen scg, Token errorAt) + { + scg.ilGen.Emit(errorAt, OpCodes.Call, integerToListMethodInfo); + } + private static void TypeCastInteger2String(IScriptCodeGen scg, Token errorAt) + { + scg.ilGen.Emit(errorAt, OpCodes.Call, intToStringMethodInfo); + } + private static void TypeCastList2String(IScriptCodeGen scg, Token errorAt) + { + scg.ilGen.Emit(errorAt, OpCodes.Call, listToStringMethodInfo); + } + private static void TypeCastObject2String(IScriptCodeGen scg, Token errorAt) + { + scg.ilGen.Emit(errorAt, OpCodes.Call, objectToStringMethodInfo); + } + private static void TypeCastRotation2List(IScriptCodeGen scg, Token errorAt) + { + scg.ilGen.Emit(errorAt, OpCodes.Call, rotationToListMethodInfo); + } + private static void TypeCastRotation2String(IScriptCodeGen scg, Token errorAt) + { + scg.ilGen.Emit(errorAt, OpCodes.Call, rotationToStringMethodInfo); + } + private static void TypeCastString2Float(IScriptCodeGen scg, Token errorAt) + { + scg.ilGen.Emit(errorAt, OpCodes.Newobj, floatConstructorStringInfo); + scg.ilGen.Emit(errorAt, OpCodes.Ldfld, lslFloatValueFieldInfo); + } + private static void TypeCastString2Integer(IScriptCodeGen scg, Token errorAt) + { + scg.ilGen.Emit(errorAt, OpCodes.Newobj, integerConstructorStringInfo); + scg.ilGen.Emit(errorAt, OpCodes.Ldfld, lslIntegerValueFieldInfo); + } + private static void TypeCastString2List(IScriptCodeGen scg, Token errorAt) + { + scg.ilGen.Emit(errorAt, OpCodes.Call, stringToListMethodInfo); + } + private static void TypeCastVector2String(IScriptCodeGen scg, Token errorAt) + { + scg.ilGen.Emit(errorAt, OpCodes.Call, vectorToStringMethodInfo); + } + + /* + * Because the calls are funky, let the compiler handle them. + */ + public static bool RotationToBool(LSL_Rotation x) + { + return !x.Equals(ScriptBaseClass.ZERO_ROTATION); + } + public static bool StringToBool(string x) + { + return x.Length > 0; + } + public static bool VectorToBool(LSL_Vector x) + { + return !x.Equals(ScriptBaseClass.ZERO_VECTOR); + } + public static string BoolToString(bool x) + { + return x ? "1" : "0"; + } + public static string CharToString(char x) + { + return x.ToString(); + } + public static string FloatToString(double x) + { + return x.ToString("0.000000"); + } + public static string IntegerToString(int x) + { + return x.ToString(); + } + public static bool KeyToBool(string x) + { + return (x != "") && (x != ScriptBaseClass.NULL_KEY); + } + public static bool ListToBool(LSL_List x) + { + return x.Length != 0; + } + public static string ListToString(LSL_List x) + { + return x.ToString(); + } + public static string ObjectToString(object x) + { + return (x == null) ? null : x.ToString(); + } + public static string RotationToString(LSL_Rotation x) + { + return x.ToString(); + } + public static string VectorToString(LSL_Vector x) + { + return x.ToString(); + } + public static LSL_List BoolToList(bool b) + { + return new LSL_List(new object[] { new LSL_Integer(b ? 1 : 0) }); + } + public static LSL_List CharToList(char c) + { + return new LSL_List(new object[] { new LSL_Integer(c) }); + } + public static LSL_List ExcToList(Exception e) + { + return new LSL_List(new object[] { e }); + } + public static LSL_List VectorToList(LSL_Vector v) + { + return new LSL_List(new object[] { v }); + } + public static LSL_List FloatToList(double f) + { + return new LSL_List(new object[] { new LSL_Float(f) }); + } + public static LSL_List IntegerToList(int i) + { + return new LSL_List(new object[] { new LSL_Integer(i) }); + } + public static LSL_List RotationToList(LSL_Rotation r) + { + return new LSL_List(new object[] { r }); + } + public static LSL_List StringToList(string s) + { + return new LSL_List(new object[] { new LSL_String(s) }); + } + + public static double ObjectToFloat(object x) + { + if(x is LSL_String) + return double.Parse(((LSL_String)x).m_string); + if(x is string) + return double.Parse((string)x); + if(x is LSL_Float) + return (double)(LSL_Float)x; + if(x is LSL_Integer) + return (double)(int)(LSL_Integer)x; + if(x is int) + return (double)(int)x; + return (double)x; + } + + public static int ObjectToInteger(object x) + { + if(x is LSL_String) + return int.Parse(((LSL_String)x).m_string); + if(x is string) + return int.Parse((string)x); + if(x is LSL_Integer) + return (int)(LSL_Integer)x; + return (int)x; + } + + public static LSL_List ObjectToList(object x) + { + return (LSL_List)x; + } + + public static LSL_Rotation ObjectToRotation(object x) + { + if(x is LSL_String) + return new LSL_Rotation(((LSL_String)x).m_string); + if(x is string) + return new LSL_Rotation((string)x); + return (LSL_Rotation)x; + } + + public static LSL_Vector ObjectToVector(object x) + { + if(x is LSL_String) + return new LSL_Vector(((LSL_String)x).m_string); + if(x is string) + return new LSL_Vector((string)x); + return (LSL_Vector)x; + } + + public static string ExceptionToString(Exception x, XMRInstAbstract inst) + { + return XMRInstAbstract.xmrExceptionTypeName(x) + ": " + XMRInstAbstract.xmrExceptionMessage(x) + + "\n" + inst.xmrExceptionStackTrace(x); + } + + /* + * These are used by event handler entrypoints to remove any LSL wrapping + * from the argument list and return the unboxed/unwrapped value. + */ + public static double EHArgUnwrapFloat(object x) + { + if(x is LSL_Float) + return (double)(LSL_Float)x; + return (double)x; + } + + public static int EHArgUnwrapInteger(object x) + { + if(x is LSL_Integer) + return (int)(LSL_Integer)x; + return (int)x; + } + + public static LSL_Rotation EHArgUnwrapRotation(object x) + { + if(x is OpenMetaverse.Quaternion) + { + OpenMetaverse.Quaternion q = (OpenMetaverse.Quaternion)x; + return new LSL_Rotation(q.X, q.Y, q.Z, q.W); + } + return (LSL_Rotation)x; + } + + public static string EHArgUnwrapString(object x) + { + if(x is LSL_Key) + return (string)(LSL_Key)x; + if(x is LSL_String) + return (string)(LSL_String)x; + return (string)x; + } + + public static LSL_Vector EHArgUnwrapVector(object x) + { + if(x is OpenMetaverse.Vector3) + { + OpenMetaverse.Vector3 v = (OpenMetaverse.Vector3)x; + return new LSL_Vector(v.X, v.Y, v.Z); + } + return (LSL_Vector)x; + } + } +} diff --git a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptVarDict.cs b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptVarDict.cs new file mode 100644 index 0000000000..a0bc7ba41d --- /dev/null +++ b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptVarDict.cs @@ -0,0 +1,401 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections; +using System.Collections.Generic; + +/** + * @brief Collection of variable/function/method definitions + */ + +namespace OpenSim.Region.ScriptEngine.Yengine +{ + public class VarDict: IEnumerable + { + public VarDict outerVarDict; // next outer VarDict to search + public TokenDeclSDTypeClass thisClass; // this VarDict is for members of thisClass + + private struct ArgTypes + { + public TokenType[] argTypes; + + public bool CanBeCalledBy(TokenType[] calledBy) + { + if((argTypes == null) && (calledBy == null)) + return true; + if((argTypes == null) || (calledBy == null)) + return false; + if(argTypes.Length != calledBy.Length) + return false; + for(int i = argTypes.Length; --i >= 0;) + { + if(!TypeCast.IsAssignableFrom(argTypes[i], calledBy[i])) + return false; + } + return true; + } + + public override bool Equals(Object that) + { + if(that == null) + return false; + if(that.GetType() != typeof(ArgTypes)) + return false; + TokenType[] at = this.argTypes; + TokenType[] bt = ((ArgTypes)that).argTypes; + if((at == null) && (bt == null)) + return true; + if((at == null) || (bt == null)) + return false; + if(at.Length != bt.Length) + return false; + for(int i = at.Length; --i >= 0;) + { + if(at[i].ToString() != bt[i].ToString()) + return false; + } + return true; + } + + public override int GetHashCode() + { + TokenType[] at = this.argTypes; + if(at == null) + return -1; + int hc = 0; + for(int i = at.Length; --i >= 0;) + { + int c = (hc < 0) ? 1 : 0; + hc = hc * 2 + c; + hc ^= at[i].ToString().GetHashCode(); + } + return hc; + } + } + + private struct TDVEntry + { + public int count; + public TokenDeclVar var; + } + + private bool isFrozen = false; + private bool locals; + private Dictionary> master = new Dictionary>(); + private int count = 0; + private VarDict frozenLocals = null; + + /** + * @brief Constructor. + * @param locals = false: cannot be frozen, allows forward references + * true: can be frozen, thus forbidding forward references + */ + public VarDict(bool locals) + { + this.locals = locals; + } + + /** + * @brief Add new variable to the dictionary. + */ + public bool AddEntry(TokenDeclVar var) + { + if(isFrozen) + { + throw new Exception("var dict is frozen"); + } + + // Make sure we have a sub-dictionary based on the bare name (ie, no signature) + Dictionary typedic; + if(!master.TryGetValue(var.name.val, out typedic)) + { + typedic = new Dictionary(); + master.Add(var.name.val, typedic); + } + + // See if there is an entry in the sub-dictionary that matches the argument signature. + // Note that fields have null argument lists. + // Methods always have a non-null argument list, even if only 0 entries long. + ArgTypes types; + types.argTypes = (var.argDecl == null) ? null : KeyTypesToStringTypes(var.argDecl.types); + if(typedic.ContainsKey(types)) + return false; + + // It is unique, add to its name-specific sub-dictionary. + TDVEntry entry; + entry.count = ++count; + entry.var = var; + typedic.Add(types, entry); + return true; + } + + public int Count + { + get + { + return count; + } + } + + /** + * @brief If this is not a local variable frame, just return the frame as is. + * If this is a local variable frame, return a version that is frozen, + * ie, one that does not contain any future additions. + */ + public VarDict FreezeLocals() + { + // If not local var frame, return original frame as is. + // This will allow forward references as the future additions + // will be seen by lookups done in this dictionary. + if(!locals) + return this; + + // If local var frame, return a copy frozen at this point. + // This disallows forward referenes as those future additions + // will not be seen by lookups done in the frozen dictionary. + if((frozenLocals == null) || (frozenLocals.count != this.count)) + { + // Make a copy of the current var dictionary frame. + // We copy a reference to the dictionary, and though it may + // contain additions made after this point, those additions + // will have a count .gt. frozen count and will be ignored. + frozenLocals = new VarDict(true); + + frozenLocals.outerVarDict = this.outerVarDict; + frozenLocals.thisClass = this.thisClass; + frozenLocals.master = this.master; + frozenLocals.count = this.count; + frozenLocals.frozenLocals = frozenLocals; + + // Mark it as being frozen. + // - assert fail if any attempt is made to add to it + // - ignore any additions to the dictionary with greater count + frozenLocals.isFrozen = true; + } + return frozenLocals; + } + + /** + * @brief Find all functions/variables that are callable + * @param name = name of function/variable to look for + * @param argTypes = the argument types the function is being called with + * null to look for a variable + * @returns null: no matching function/variable found + * else: list of matching functions/variables + * for variables, always of length 1 + */ + private List found = new List(); + public TokenDeclVar[] FindCallables(string name, TokenType[] argTypes) + { + argTypes = KeyTypesToStringTypes(argTypes); + TokenDeclVar var = FindExact(name, argTypes); + if(var != null) + return new TokenDeclVar[] { var }; + + Dictionary typedic; + if(!master.TryGetValue(name, out typedic)) + return null; + + found.Clear(); + foreach(KeyValuePair kvp in typedic) + { + if((kvp.Value.count <= this.count) && kvp.Key.CanBeCalledBy(argTypes)) + { + found.Add(kvp.Value.var); + } + } + return (found.Count > 0) ? found.ToArray() : null; + } + + /** + * @brief Find exact matching function/variable + * @param name = name of function to look for + * @param argTypes = argument types the function was declared with + * null to look for a variable + * @returns null: no matching function/variable found + * else: the matching function/variable + */ + public TokenDeclVar FindExact(string name, TokenType[] argTypes) + { + // Look for list of stuff that matches the given name. + Dictionary typedic; + if(!master.TryGetValue(name, out typedic)) + return null; + + // Loop through all fields/methods declared by that name, regardless of arg signature. + foreach(TDVEntry entry in typedic.Values) + { + if(entry.count > this.count) + continue; + TokenDeclVar var = entry.var; + + // Get argument types of declaration. + // fields are always null + // methods are always non-null, though may be zero-length + TokenType[] declArgs = (var.argDecl == null) ? null : var.argDecl.types; + + // Convert any key args to string args. + declArgs = KeyTypesToStringTypes(declArgs); + + // If both are null, they are signature-less (ie, both are fields), and so match. + if((declArgs == null) && (argTypes == null)) + return var; + + // If calling a delegate, it is a match, regardless of delegate arg types. + // If it turns out the arg types do not match, the compiler will give an error + // trying to cast the arguments to the delegate arg types. + // We don't allow overloading same field name with different delegate types. + if((declArgs == null) && (argTypes != null)) + { + TokenType fieldType = var.type; + if(fieldType is TokenTypeSDTypeDelegate) + return var; + } + + // If not both null, no match, keep looking. + if((declArgs == null) || (argTypes == null)) + continue; + + // Both not null, match argument types to make sure we have correct overload. + int i = declArgs.Length; + if(i != argTypes.Length) + continue; + while(--i >= 0) + { + string da = declArgs[i].ToString(); + string ga = argTypes[i].ToString(); + if(da == "key") + da = "string"; + if(ga == "key") + ga = "string"; + if(da != ga) + break; + } + if(i < 0) + return var; + } + + // No match. + return null; + } + + /** + * @brief Replace any TokenTypeKey elements with TokenTypeStr so that + * it doesn't matter if functions are declared with key or string, + * they will accept either. + * @param argTypes = argument types as declared in source code + * @returns argTypes with any key replaced by string + */ + private static TokenType[] KeyTypesToStringTypes(TokenType[] argTypes) + { + if(argTypes != null) + { + int i; + int nats = argTypes.Length; + for(i = nats; --i >= 0;) + { + if(argTypes[i] is TokenTypeKey) + break; + } + if(i >= 0) + { + TokenType[] at = new TokenType[nats]; + for(i = nats; --i >= 0;) + { + at[i] = argTypes[i]; + if(argTypes[i] is TokenTypeKey) + { + at[i] = new TokenTypeStr(argTypes[i]); + } + } + return at; + } + } + return argTypes; + } + + // foreach goes through all the TokenDeclVars that were added + + // IEnumerable + public IEnumerator GetEnumerator() + { + return new VarDictEnumerator(this.master, this.count); + } + + private class VarDictEnumerator: IEnumerator + { + private IEnumerator masterEnum; + private IEnumerator typedicEnum; + private int count; + + public VarDictEnumerator(Dictionary> master, int count) + { + masterEnum = master.Values.GetEnumerator(); + this.count = count; + } + + // IEnumerator + public void Reset() + { + masterEnum.Reset(); + typedicEnum = null; + } + + // IEnumerator + public bool MoveNext() + { + while(true) + { + if(typedicEnum != null) + { + while(typedicEnum.MoveNext()) + { + if(((TDVEntry)typedicEnum.Current).count <= this.count) + return true; + } + typedicEnum = null; + } + if(!masterEnum.MoveNext()) + return false; + Dictionary ctd; + ctd = (Dictionary)masterEnum.Current; + typedicEnum = ctd.Values.GetEnumerator(); + } + } + + // IEnumerator + public object Current + { + get + { + return ((TDVEntry)typedicEnum.Current).var; + } + } + } + } +} diff --git a/OpenSim/Region/ScriptEngine/YEngine/XMRArray.cs b/OpenSim/Region/ScriptEngine/YEngine/XMRArray.cs new file mode 100644 index 0000000000..3d0525b7a4 --- /dev/null +++ b/OpenSim/Region/ScriptEngine/YEngine/XMRArray.cs @@ -0,0 +1,572 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; + +using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; +using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; +using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; +using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list; +using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; +using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; +using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; + +// This class exists in the main app domain +// +namespace OpenSim.Region.ScriptEngine.Yengine +{ + /** + * @brief Array objects. + */ + public class XMR_Array + { + private const int EMPTYHEAP = 64; + private const int ENTRYHEAP = 24; + + private bool enumrValid; // true: enumr set to return array[arrayValid] + // false: array[0..arrayValid-1] is all there is + private SortedDictionary dnary; + private SortedDictionary.Enumerator enumr; + // enumerator used to fill 'array' past arrayValid to end of dictionary + private int arrayValid; // number of elements in 'array' that have been filled in + private KeyValuePair[] array; // list of kvp's that have been returned by ForEach() since last modification + private XMRInstAbstract inst; // script instance debited with heap use + private int heapUse; // current heap use debit amount + + public static TokenTypeSDTypeDelegate countDelegate = new TokenTypeSDTypeDelegate(new TokenTypeInt(null), new TokenType[0]); + public static TokenTypeSDTypeDelegate clearDelegate = new TokenTypeSDTypeDelegate(new TokenTypeVoid(null), new TokenType[0]); + public static TokenTypeSDTypeDelegate indexDelegate = new TokenTypeSDTypeDelegate(new TokenTypeObject(null), new TokenType[] { new TokenTypeInt(null) }); + public static TokenTypeSDTypeDelegate valueDelegate = new TokenTypeSDTypeDelegate(new TokenTypeObject(null), new TokenType[] { new TokenTypeInt(null) }); + + public XMR_Array(XMRInstAbstract inst) + { + this.inst = inst; + dnary = new SortedDictionary(XMRArrayKeyComparer.singleton); + heapUse = inst.UpdateHeapUse(0, EMPTYHEAP); + } + + ~XMR_Array() + { + heapUse = inst.UpdateHeapUse(heapUse, 0); + } + + public static TokenType GetRValType(TokenName name) + { + if(name.val == "count") + return new TokenTypeInt(name); + if(name.val == "clear") + return clearDelegate; + if(name.val == "index") + return indexDelegate; + if(name.val == "value") + return valueDelegate; + return new TokenTypeVoid(name); + } + + /** + * @brief Handle 'array[index]' syntax to get or set an element of the dictionary. + * Get returns null if element not defined, script sees type 'undef'. + * Setting an element to null removes it. + */ + public object GetByKey(object key) + { + object val; + key = FixKey(key); + if(!dnary.TryGetValue(key, out val)) + val = null; + return val; + } + + public void SetByKey(object key, object value) + { + key = FixKey(key); + + // Update heap use throwing an exception on failure + // before making any changes to the array. + int keysize = HeapTrackerObject.Size(key); + int newheapuse = heapUse; + object oldval; + if(dnary.TryGetValue(key, out oldval)) + { + newheapuse -= keysize + HeapTrackerObject.Size(oldval); + } + if(value != null) + { + newheapuse += keysize + HeapTrackerObject.Size(value); + } + heapUse = inst.UpdateHeapUse(heapUse, newheapuse); + + // Save new value in array, replacing one of same key if there. + // null means remove the value, ie, script did array[key] = undef. + if(value != null) + { + dnary[key] = value; + } + else + { + dnary.Remove(key); + + // Shrink the enumeration array, but always leave at least one element. + if((array != null) && (dnary.Count < array.Length / 2)) + { + Array.Resize>(ref array, array.Length / 2); + } + } + + // The enumeration array is invalid because the dictionary has been modified. + // Next time a ForEach() call happens, it will repopulate 'array' as elements are retrieved. + arrayValid = 0; + } + + /** + * @brief Converts an 'object' type to array, key, list, string, but disallows null, + * as our language doesn't allow types other than 'object' to be null. + * Value types (float, rotation, etc) don't need explicit check for null as + * the C# runtime can't convert a null to a value type, and throws an exception. + * But for any reference type (array, key, etc) we must manually check for null. + */ + public static XMR_Array Obj2Array(object obj) + { + if(obj == null) + throw new NullReferenceException(); + return (XMR_Array)obj; + } + public static LSL_Key Obj2Key(object obj) + { + if(obj == null) + throw new NullReferenceException(); + return (LSL_Key)obj; + } + public static LSL_List Obj2List(object obj) + { + if(obj == null) + throw new NullReferenceException(); + return (LSL_List)obj; + } + public static LSL_String Obj2String(object obj) + { + if(obj == null) + throw new NullReferenceException(); + return obj.ToString(); + } + + /** + * @brief remove all elements from the array. + * sets everything to its 'just constructed' state. + */ + public void __pub_clear() + { + heapUse = inst.UpdateHeapUse(heapUse, EMPTYHEAP); + dnary.Clear(); + enumrValid = false; + arrayValid = 0; + array = null; + } + + /** + * @brief return number of elements in the array. + */ + public int __pub_count() + { + return dnary.Count; + } + + /** + * @brief Retrieve index (key) of an arbitrary element. + * @param number = number of the element (0 based) + * @returns null: array doesn't have that many elements + * else: index (key) for that element + */ + public object __pub_index(int number) + { + return ForEach(number) ? UnfixKey(array[number].Key) : null; + } + + /** + * @brief Retrieve value of an arbitrary element. + * @param number = number of the element (0 based) + * @returns null: array doesn't have that many elements + * else: value for that element + */ + public object __pub_value(int number) + { + return ForEach(number) ? array[number].Value : null; + } + + /** + * @brief Called in each iteration of a 'foreach' statement. + * @param number = index of element to retrieve (0 = first one) + * @returns false: element does not exist + * true: element exists + */ + private bool ForEach(int number) + { + // If we don't have any array, we can't have ever done + // any calls here before, so allocate an array big enough + // and set everything else to the beginning. + if(array == null) + { + array = new KeyValuePair[dnary.Count]; + arrayValid = 0; + } + + // If dictionary modified since last enumeration, get a new enumerator. + if(arrayValid == 0) + { + enumr = dnary.GetEnumerator(); + enumrValid = true; + } + + // Make sure we have filled the array up enough for requested element. + while((arrayValid <= number) && enumrValid && enumr.MoveNext()) + { + if(arrayValid >= array.Length) + { + Array.Resize>(ref array, dnary.Count); + } + array[arrayValid++] = enumr.Current; + } + + // If we don't have that many elements, return end-of-array status. + return number < arrayValid; + } + + /** + * @brief Transmit array out in such a way that it can be reconstructed, + * including any in-progress ForEach() enumerations. + */ + public delegate void SendArrayObjDelegate(object graph); + public void SendArrayObj(SendArrayObjDelegate sendObj) + { + // Set the count then the elements themselves. + // UnfixKey() because sendObj doesn't handle XMRArrayListKeys. + sendObj(dnary.Count); + foreach(KeyValuePair kvp in dnary) + { + sendObj(UnfixKey(kvp.Key)); + sendObj(kvp.Value); + } + } + + /** + * @brief Receive array in. Any previous contents are erased. + * Set up such that any enumeration in progress will resume + * at the exact spot and in the exact same order as they + * were in on the sending side. + */ + public delegate object RecvArrayObjDelegate(); + public void RecvArrayObj(RecvArrayObjDelegate recvObj) + { + heapUse = inst.UpdateHeapUse(heapUse, EMPTYHEAP); + + // Cause any enumeration to refill the array from the sorted dictionary. + // Since it is a sorted dictionary, any enumerations will be in the same + // order as on the sending side. + arrayValid = 0; + enumrValid = false; + + // Fill dictionary. + dnary.Clear(); + int count = (int)recvObj(); + while(--count >= 0) + { + object key = FixKey(recvObj()); + object val = recvObj(); + int htuse = HeapTrackerObject.Size(key) + HeapTrackerObject.Size(val); + heapUse = inst.UpdateHeapUse(heapUse, heapUse + htuse); + dnary.Add(key, val); + } + } + + /** + * We want our index values to be of consistent type, otherwise we get things like (LSL_Integer)1 != (int)1. + * So strip off any LSL-ness from the types. + * We also deep-strip any given lists used as keys (multi-dimensional arrays). + */ + public static object FixKey(object key) + { + if(key is LSL_Integer) + return (int)(LSL_Integer)key; + if(key is LSL_Float) + return (double)(LSL_Float)key; + if(key is LSL_Key) + return (string)(LSL_Key)key; + if(key is LSL_String) + return (string)(LSL_String)key; + if(key is LSL_List) + { + object[] data = ((LSL_List)key).Data; + if(data.Length == 1) + return FixKey(data[0]); + return new XMRArrayListKey((LSL_List)key); + } + return key; // int, double, string, LSL_Vector, LSL_Rotation, etc are ok as is + } + + /** + * @brief When returning a key, such as for array.index(), we want to return the original + * LSL_List, not the sanitized one, as the script compiler expects an LSL_List. + * Any other sanitized types can remain as is (int, string, etc). + */ + private static object UnfixKey(object key) + { + if(key is XMRArrayListKey) + key = ((XMRArrayListKey)key).GetOriginal(); + return key; + } + } + + public class XMRArrayKeyComparer: IComparer + { + + public static XMRArrayKeyComparer singleton = new XMRArrayKeyComparer(); + + /** + * @brief Compare two keys + */ + public int Compare(object x, object y) // IComparer + { + // Use short type name (eg, String, Int32, XMRArrayListKey) as most significant part of key. + string xtn = x.GetType().Name; + string ytn = y.GetType().Name; + int ctn = String.CompareOrdinal(xtn, ytn); + if(ctn != 0) + return ctn; + + ComparerDelegate cd; + if(!comparers.TryGetValue(xtn, out cd)) + { + throw new Exception("unsupported key type " + xtn); + } + return cd(x, y); + } + + private delegate int ComparerDelegate(object a, object b); + + private static Dictionary comparers = BuildComparers(); + + private static Dictionary BuildComparers() + { + Dictionary cmps = new Dictionary(); + cmps.Add(typeof(double).Name, MyFloatComparer); + cmps.Add(typeof(int).Name, MyIntComparer); + cmps.Add(typeof(XMRArrayListKey).Name, MyListKeyComparer); + cmps.Add(typeof(LSL_Rotation).Name, MyRotationComparer); + cmps.Add(typeof(string).Name, MyStringComparer); + cmps.Add(typeof(LSL_Vector).Name, MyVectorComparer); + return cmps; + } + + private static int MyFloatComparer(object a, object b) + { + double af = (double)a; + double bf = (double)b; + if(af < bf) + return -1; + if(af > bf) + return 1; + return 0; + } + private static int MyIntComparer(object a, object b) + { + return (int)a - (int)b; + } + private static int MyListKeyComparer(object a, object b) + { + XMRArrayListKey alk = (XMRArrayListKey)a; + XMRArrayListKey blk = (XMRArrayListKey)b; + return XMRArrayListKey.Compare(alk, blk); + } + private static int MyRotationComparer(object a, object b) + { + LSL_Rotation ar = (LSL_Rotation)a; + LSL_Rotation br = (LSL_Rotation)b; + if(ar.x < br.x) + return -1; + if(ar.x > br.x) + return 1; + if(ar.y < br.y) + return -1; + if(ar.y > br.y) + return 1; + if(ar.z < br.z) + return -1; + if(ar.z > br.z) + return 1; + if(ar.s < br.s) + return -1; + if(ar.s > br.s) + return 1; + return 0; + } + private static int MyStringComparer(object a, object b) + { + return String.CompareOrdinal((string)a, (string)b); + } + private static int MyVectorComparer(object a, object b) + { + LSL_Vector av = (LSL_Vector)a; + LSL_Vector bv = (LSL_Vector)b; + if(av.x < bv.x) + return -1; + if(av.x > bv.x) + return 1; + if(av.y < bv.y) + return -1; + if(av.y > bv.y) + return 1; + if(av.z < bv.z) + return -1; + if(av.z > bv.z) + return 1; + return 0; + } + } + + /** + * @brief Lists used as keys must be sanitized first. + * List gets converted to an object[] and each element is converted from LSL_ types to system types where possible. + * And we also need an equality operator that compares the values of all elements of the list, not just the lengths. + * Note that just like LSL_Lists, we consider these objects to be immutable, so they can be directly used as keys in + * the dictionary as they don't ever change. + */ + public class XMRArrayListKey + { + private LSL_List original; + private object[] cleaned; + private int length; + private int hashCode; + + /** + * @brief Construct a sanitized object[] from a list. + * Also save the original list in case we need it later. + */ + public XMRArrayListKey(LSL_List key) + { + original = key; + object[] given = key.Data; + int len = given.Length; + length = len; + cleaned = new object[len]; + int hc = len; + for(int i = 0; i < len; i++) + { + object v = XMR_Array.FixKey(given[i]); + hc += hc + ((hc < 0) ? 1 : 0); + hc ^= v.GetHashCode(); + cleaned[i] = v; + } + hashCode = hc; + } + + /** + * @brief Get heap tracking size. + */ + public int Size + { + get + { + return original.Size; + } + } + + /** + * @brief See if the given object is an XMRArrayListKey and every value is equal to our own. + */ + public override bool Equals(object o) + { + if(!(o is XMRArrayListKey)) + return false; + XMRArrayListKey a = (XMRArrayListKey)o; + int len = a.length; + if(len != length) + return false; + if(a.hashCode != hashCode) + return false; + for(int i = 0; i < len; i++) + { + if(!cleaned[i].Equals(a.cleaned[i])) + return false; + } + return true; + } + + /** + * @brief Get an hash code. + */ + public override int GetHashCode() + { + return hashCode; + } + + /** + * @brief Compare for key sorting. + */ + public static int Compare(XMRArrayListKey x, XMRArrayListKey y) + { + int j = x.length - y.length; + if(j == 0) + { + for(int i = 0; i < x.length; i++) + { + object xo = x.cleaned[i]; + object yo = y.cleaned[i]; + j = XMRArrayKeyComparer.singleton.Compare(xo, yo); + if(j != 0) + break; + } + } + return j; + } + + /** + * @brief Get the original LSL_List we were built from. + */ + public LSL_List GetOriginal() + { + return original; + } + + /** + * @brief Debugging + */ + public override string ToString() + { + StringBuilder sb = new StringBuilder(); + for(int i = 0; i < length; i++) + { + if(i > 0) + sb.Append(','); + sb.Append(cleaned[i].ToString()); + } + return sb.ToString(); + } + } +} diff --git a/OpenSim/Region/ScriptEngine/YEngine/XMREngXmrTestLs.cs b/OpenSim/Region/ScriptEngine/YEngine/XMREngXmrTestLs.cs new file mode 100644 index 0000000000..ea306c8119 --- /dev/null +++ b/OpenSim/Region/ScriptEngine/YEngine/XMREngXmrTestLs.cs @@ -0,0 +1,547 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using log4net; +using System; +using System.Collections.Generic; +using System.IO; +using System.Reflection; +using System.Text; +using System.Threading; + +using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; +using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; +using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; +using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list; +using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; +using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; +using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; + +namespace OpenSim.Region.ScriptEngine.Yengine +{ + public partial class Yengine + { + + private void XmrTestLs(string[] args, int indx) + { + bool flagFull = false; + bool flagQueues = false; + bool flagTopCPU = false; + int maxScripts = 0x7FFFFFFF; + int numScripts = 0; + string outName = null; + XMRInstance[] instances; + + // Decode command line options. + for(int i = indx; i < args.Length; i++) + { + if(args[i] == "-full") + { + flagFull = true; + continue; + } + if(args[i] == "-help") + { + m_log.Info("[YEngine]: yeng ls -full -max= -out= -queues -topcpu"); + return; + } + if(args[i].StartsWith("-max=")) + { + try + { + maxScripts = Convert.ToInt32(args[i].Substring(5)); + } + catch(Exception e) + { + m_log.Error("[YEngine]: bad max " + args[i].Substring(5) + ": " + e.Message); + return; + } + continue; + } + if(args[i].StartsWith("-out=")) + { + outName = args[i].Substring(5); + continue; + } + if(args[i] == "-queues") + { + flagQueues = true; + continue; + } + if(args[i] == "-topcpu") + { + flagTopCPU = true; + continue; + } + if(args[i][0] == '-') + { + m_log.Error("[YEngine]: unknown option " + args[i] + ", try 'yeng ls -help'"); + return; + } + } + + TextWriter outFile = null; + if(outName != null) + { + try + { + outFile = File.CreateText(outName); + } + catch(Exception e) + { + m_log.Error("[YEngine]: error creating " + outName + ": " + e.Message); + return; + } + } + else + { + outFile = new LogInfoTextWriter(m_log); + } + + try + { + // Scan instance list to find those that match selection criteria. + if(!Monitor.TryEnter(m_InstancesDict, 100)) + { + m_log.Error("[YEngine]: deadlock m_LockedDict=" + m_LockedDict); + return; + } + try + { + instances = new XMRInstance[m_InstancesDict.Count]; + foreach(XMRInstance ins in m_InstancesDict.Values) + { + if(InstanceMatchesArgs(ins, args, indx)) + { + instances[numScripts++] = ins; + } + } + } + finally + { + Monitor.Exit(m_InstancesDict); + } + + // Maybe sort by descending CPU time. + if(flagTopCPU) + { + Array.Sort(instances, CompareInstancesByCPUTime); + } + + // Print the entries. + if(!flagFull) + { + outFile.WriteLine(" ItemID" + + " CPU(ms)" + + " NumEvents" + + " Status " + + " World Position " + + " :"); + } + for(int i = 0; (i < numScripts) && (i < maxScripts); i++) + { + outFile.WriteLine(instances[i].RunTestLs(flagFull)); + } + + // Print number of scripts that match selection criteria, + // even if we were told to print fewer. + outFile.WriteLine("total of {0} script(s)", numScripts); + + // If -queues given, print out queue contents too. + if(flagQueues) + { + LsQueue(outFile, "start", m_StartQueue, args, indx); + LsQueue(outFile, "sleep", m_SleepQueue, args, indx); + LsQueue(outFile, "yield", m_YieldQueue, args, indx); + } + } + finally + { + outFile.Close(); + } + } + + private void XmrTestPev(string[] args, int indx) + { + bool flagAll = false; + int numScripts = 0; + XMRInstance[] instances; + + // Decode command line options. + int i, j; + List selargs = new List(args.Length); + MethodInfo[] eventmethods = typeof(IEventHandlers).GetMethods(); + MethodInfo eventmethod; + for(i = indx; i < args.Length; i++) + { + string arg = args[i]; + if(arg == "-all") + { + flagAll = true; + continue; + } + if(arg == "-help") + { + m_log.Info("[YEngine]: yeng pev -all | "); + return; + } + if(arg[0] == '-') + { + m_log.Error("[YEngine]: unknown option " + arg + ", try 'yeng pev -help'"); + return; + } + for(j = 0; j < eventmethods.Length; j++) + { + eventmethod = eventmethods[j]; + if(eventmethod.Name == arg) + goto gotevent; + } + selargs.Add(arg); + } + m_log.Error("[YEngine]: missing , try 'yeng pev -help'"); + return; + gotevent: + string eventname = eventmethod.Name; + StringBuilder sourcesb = new StringBuilder(); + while(++i < args.Length) + { + sourcesb.Append(' '); + sourcesb.Append(args[i]); + } + string sourcest = sourcesb.ToString(); + string sourcehash; + youveanerror = false; + Token t = TokenBegin.Construct("", null, ErrorMsg, sourcest, out sourcehash); + if(youveanerror) + return; + ParameterInfo[] paraminfos = eventmethod.GetParameters(); + object[] paramvalues = new object[paraminfos.Length]; + i = 0; + while(!((t = t.nextToken) is TokenEnd)) + { + if(i >= paramvalues.Length) + { + ErrorMsg(t, "extra parameter(s)"); + return; + } + paramvalues[i] = ParseParamValue(ref t); + if(paramvalues[i] == null) + return; + i++; + } + OpenSim.Region.ScriptEngine.Shared.EventParams eps = + new OpenSim.Region.ScriptEngine.Shared.EventParams(eventname, paramvalues, zeroDetectParams); + + // Scan instance list to find those that match selection criteria. + if(!Monitor.TryEnter(m_InstancesDict, 100)) + { + m_log.Error("[YEngine]: deadlock m_LockedDict=" + m_LockedDict); + return; + } + + try + { + instances = new XMRInstance[m_InstancesDict.Count]; + foreach(XMRInstance ins in m_InstancesDict.Values) + { + if(flagAll || InstanceMatchesArgs(ins, selargs.ToArray(), 0)) + { + instances[numScripts++] = ins; + } + } + } + finally + { + Monitor.Exit(m_InstancesDict); + } + + // Post event to the matching instances. + for(i = 0; i < numScripts; i++) + { + XMRInstance inst = instances[i]; + m_log.Info("[YEngine]: post " + eventname + " to " + inst.m_DescName); + inst.PostEvent(eps); + } + } + + private object ParseParamValue(ref Token token) + { + if(token is TokenFloat) + { + return new LSL_Float(((TokenFloat)token).val); + } + if(token is TokenInt) + { + return new LSL_Integer(((TokenInt)token).val); + } + if(token is TokenStr) + { + return new LSL_String(((TokenStr)token).val); + } + if(token is TokenKwCmpLT) + { + List valuelist = new List(); + while(!((token = token.nextToken) is TokenKwCmpGT)) + { + if(!(token is TokenKwComma)) + { + object value = ParseParamValue(ref token); + if(value == null) + return null; + if(value is int) + value = (double)(int)value; + if(!(value is double)) + { + ErrorMsg(token, "must be float or integer constant"); + return null; + } + valuelist.Add((double)value); + } + else if(token.prevToken is TokenKwComma) + { + ErrorMsg(token, "missing constant"); + return null; + } + } + double[] values = valuelist.ToArray(); + switch(values.Length) + { + case 3: + { + return new LSL_Vector(values[0], values[1], values[2]); + } + case 4: + { + return new LSL_Rotation(values[0], values[1], values[2], values[3]); + } + default: + { + ErrorMsg(token, "not rotation or vector"); + return null; + } + } + } + if(token is TokenKwBrkOpen) + { + List valuelist = new List(); + while(!((token = token.nextToken) is TokenKwBrkClose)) + { + if(!(token is TokenKwComma)) + { + object value = ParseParamValue(ref token); + if(value == null) + return null; + valuelist.Add(value); + } + else if(token.prevToken is TokenKwComma) + { + ErrorMsg(token, "missing constant"); + return null; + } + } + return new LSL_List(valuelist.ToArray()); + } + if(token is TokenName) + { + FieldInfo field = typeof(OpenSim.Region.ScriptEngine.Shared.ScriptBase.ScriptBaseClass).GetField(((TokenName)token).val); + if((field != null) && field.IsPublic && (field.IsLiteral || (field.IsStatic && field.IsInitOnly))) + { + return field.GetValue(null); + } + } + ErrorMsg(token, "invalid constant"); + return null; + } + + private bool youveanerror; + private void ErrorMsg(Token token, string message) + { + youveanerror = true; + m_log.Info("[YEngine]: " + token.posn + " " + message); + } + + private void XmrTestReset(string[] args, int indx) + { + bool flagAll = false; + int numScripts = 0; + XMRInstance[] instances; + + if(args.Length <= indx) + { + m_log.Error("[YEngine]: must specify part of script name or -all for all scripts"); + return; + } + + // Decode command line options. + for(int i = indx; i < args.Length; i++) + { + if(args[i] == "-all") + { + flagAll = true; + continue; + } + if(args[i] == "-help") + { + m_log.Info("[YEngine]: yeng reset -all | "); + return; + } + if(args[i][0] == '-') + { + m_log.Error("[YEngine]: unknown option " + args[i] + ", try 'yeng reset -help'"); + return; + } + } + + // Scan instance list to find those that match selection criteria. + if(!Monitor.TryEnter(m_InstancesDict, 100)) + { + m_log.Error("[YEngine]: deadlock m_LockedDict=" + m_LockedDict); + return; + } + + try + { + instances = new XMRInstance[m_InstancesDict.Count]; + foreach(XMRInstance ins in m_InstancesDict.Values) + { + if(flagAll || InstanceMatchesArgs(ins, args, indx)) + { + instances[numScripts++] = ins; + } + } + } + finally + { + Monitor.Exit(m_InstancesDict); + } + + // Reset the instances as if someone clicked their "Reset" button. + for(int i = 0; i < numScripts; i++) + { + XMRInstance inst = instances[i]; + m_log.Info("[YEngine]: resetting " + inst.m_DescName); + inst.Reset(); + } + } + + private static int CompareInstancesByCPUTime(XMRInstance a, XMRInstance b) + { + if(a == null) + { + return (b == null) ? 0 : 1; + } + if(b == null) + { + return -1; + } + if(b.m_CPUTime < a.m_CPUTime) + return -1; + if(b.m_CPUTime > a.m_CPUTime) + return 1; + return 0; + } + + private void LsQueue(TextWriter outFile, string name, XMRInstQueue queue, string[] args, int indx) + { + outFile.WriteLine("Queue " + name + ":"); + lock(queue) + { + for(XMRInstance inst = queue.PeekHead(); inst != null; inst = inst.m_NextInst) + { + try + { + // Try to print instance name. + if(InstanceMatchesArgs(inst, args, indx)) + { + outFile.WriteLine(" " + inst.ItemID.ToString() + " " + inst.m_DescName); + } + } + catch(Exception e) + { + // Sometimes there are instances in the queue that are disposed. + outFile.WriteLine(" " + inst.ItemID.ToString() + " " + inst.m_DescName + ": " + e.Message); + } + } + } + } + + private bool InstanceMatchesArgs(XMRInstance ins, string[] args, int indx) + { + bool hadSomethingToCompare = false; + + for(int i = indx; i < args.Length; i++) + { + if(args[i][0] != '-') + { + hadSomethingToCompare = true; + if(ins.m_DescName.Contains(args[i])) + return true; + if(ins.ItemID.ToString().Contains(args[i])) + return true; + if(ins.AssetID.ToString().Contains(args[i])) + return true; + } + } + return !hadSomethingToCompare; + } + } + + /** + * @brief Make m_log.Info look like a text writer. + */ + public class LogInfoTextWriter: TextWriter + { + private StringBuilder sb = new StringBuilder(); + private ILog m_log; + public LogInfoTextWriter(ILog m_log) + { + this.m_log = m_log; + } + public override void Write(char c) + { + if(c == '\n') + { + m_log.Info("[YEngine]: " + sb.ToString()); + sb.Remove(0, sb.Length); + } + else + { + sb.Append(c); + } + } + public override void Close() + { + } + public override Encoding Encoding + { + get + { + return Encoding.UTF8; + } + } + } +} diff --git a/OpenSim/Region/ScriptEngine/YEngine/XMREngine.cs b/OpenSim/Region/ScriptEngine/YEngine/XMREngine.cs new file mode 100644 index 0000000000..45e44691c2 --- /dev/null +++ b/OpenSim/Region/ScriptEngine/YEngine/XMREngine.cs @@ -0,0 +1,1901 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// based on YEngine from Mike Rieker (Dreamnation) and Melanie Thielker +// but with several changes to be more cross platform. + +using log4net; +using Mono.Addins; +using Nini.Config; +using OpenSim.Framework; +using OpenSim.Framework.Console; +using OpenSim.Framework.Monitoring; +using OpenSim.Region.ClientStack.Linden; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Region.ScriptEngine.Interfaces; +using OpenSim.Region.ScriptEngine.Shared; +using OpenSim.Region.ScriptEngine.Shared.Api; +using OpenMetaverse; +using System; +using System.Collections; +using System.Collections.Generic; +using System.IO; +using System.Reflection; +using System.Reflection.Emit; +using System.Text; +using System.Threading; +using System.Timers; +using System.Xml; + +using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; +using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; +using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; +using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list; +using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; +using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; +using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; + +[assembly: Addin("YEngine", OpenSim.VersionInfo.VersionNumber)] +[assembly: AddinDependency("OpenSim.Region.Framework", OpenSim.VersionInfo.VersionNumber)] + +namespace OpenSim.Region.ScriptEngine.Yengine +{ + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "YEngine")] + public partial class Yengine: INonSharedRegionModule, IScriptEngine, + IScriptModule + { + public static readonly DetectParams[] zeroDetectParams = new DetectParams[0]; + private static ArrayList noScriptErrors = new ArrayList(); + public static readonly ILog m_log = + LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private static readonly string[] scriptReferencedAssemblies = new string[0]; + + private bool m_LateInit; + private bool m_TraceCalls; + public bool m_Verbose; + public bool m_ScriptDebug; + public bool m_ScriptDebugSaveSource; + public bool m_ScriptDebugSaveIL; + public Scene m_Scene; + private IConfigSource m_ConfigSource; + private IConfig m_Config; + private string m_ScriptBasePath; + private bool m_Enabled = false; + public bool m_StartProcessing = false; + public bool m_UseSourceHashCode = false; + private Dictionary m_ScriptErrors = + new Dictionary(); + private Dictionary> m_ObjectItemList = + new Dictionary>(); + private Dictionary m_ObjectInstArray = + new Dictionary(); + public Dictionary m_XMRInstanceApiCtxFieldInfos = + new Dictionary(); + public int m_StackSize; + private int m_HeapSize; + private Thread m_SleepThread = null; + + private bool m_Exiting = false; + + private int m_MaintenanceInterval = 10; + private System.Timers.Timer m_MaintenanceTimer; + public int numThreadScriptWorkers; + + private object m_FrameUpdateLock = new object(); + private event ThreadStart m_FrameUpdateList = null; + + // Various instance lists: + // m_InstancesDict = all known instances + // find an instance given its itemID + // m_StartQueue = instances that have just had event queued to them + // m_YieldQueue = instances that are ready to run right now + // m_SleepQueue = instances that have m_SleepUntil valid + // sorted by ascending m_SleepUntil + private Dictionary m_InstancesDict = + new Dictionary(); + public Queue m_ThunkQueue = new Queue(); + public XMRInstQueue m_StartQueue = new XMRInstQueue(); + public XMRInstQueue m_YieldQueue = new XMRInstQueue(); + public XMRInstQueue m_SleepQueue = new XMRInstQueue(); + private string m_LockedDict = "nobody"; + + public Yengine() + { + } + + public string Name + { + get + { + return "YEngine"; + } + } + + public Type ReplaceableInterface + { + get + { + return null; + } + } + + public string ScriptEnginePath + { + get + { + return m_ScriptBasePath; + } + } + + public string ScriptClassName + { + get + { + return "YEngineScript"; + } + } + + public string ScriptBaseClassName + { + get + { + return typeof(XMRInstance).FullName; + } + } + + public ParameterInfo[] ScriptBaseClassParameters + { + get + { + return typeof(XMRInstance).GetConstructor(new Type[] { typeof(WaitHandle) }).GetParameters(); + } + } + + public string[] ScriptReferencedAssemblies + { + get + { + return scriptReferencedAssemblies; + } + } + + public void Initialise(IConfigSource config) + { + TraceCalls("[YEngine]: Initialize entry"); + m_ConfigSource = config; + + ////foreach (IConfig icfg in config.Configs) { + //// m_log.Debug("[YEngine]: Initialise: configs[" + icfg.Name + "]"); + //// foreach (string key in icfg.GetKeys ()) { + //// m_log.Debug("[YEngine]: Initialise: " + key + "=" + icfg.GetExpanded (key)); + //// } + ////} + + m_Enabled = false; + m_Config = config.Configs["YEngine"]; + if(m_Config == null) + { + m_log.Info("[YEngine]: no config, assuming disabled"); + return; + } + m_Enabled = m_Config.GetBoolean("Enabled", false); + m_log.InfoFormat("[YEngine]: config enabled={0}", m_Enabled); + if(!m_Enabled) + return; + + m_UseSourceHashCode = m_Config.GetBoolean("UseSourceHashCode", false); + numThreadScriptWorkers = m_Config.GetInt("NumThreadScriptWorkers", 1); + + m_TraceCalls = m_Config.GetBoolean("TraceCalls", false); + m_Verbose = m_Config.GetBoolean("Verbose", false); + m_ScriptDebug = m_Config.GetBoolean("ScriptDebug", false); + m_ScriptDebugSaveSource = m_Config.GetBoolean("ScriptDebugSaveSource", false); + m_ScriptDebugSaveIL = m_Config.GetBoolean("ScriptDebugSaveIL", false); + + m_StackSize = m_Config.GetInt("ScriptStackSize", 2048) << 10; + m_HeapSize = m_Config.GetInt("ScriptHeapSize", 1024) << 10; + + // Verify that our ScriptEventCode's match OpenSim's scriptEvent's. + bool err = false; + for(int i = 0; i < 32; i++) + { + string mycode = "undefined"; + string oscode = "undefined"; + try + { + mycode = ((ScriptEventCode)i).ToString(); + Convert.ToInt32(mycode); + mycode = "undefined"; + } + catch { } + try + { + oscode = ((OpenSim.Region.Framework.Scenes.scriptEvents)(1 << i)).ToString(); + Convert.ToInt32(oscode); + oscode = "undefined"; + } + catch { } + if(mycode != oscode) + { + m_log.ErrorFormat("[YEngine]: {0} mycode={1}, oscode={2}", i, mycode, oscode); + err = true; + } + } + if(err) + { + m_Enabled = false; + return; + } + + m_SleepThread = StartMyThread(RunSleepThread, "Yengine sleep", ThreadPriority.Normal); + for(int i = 0; i < numThreadScriptWorkers; i++) + StartThreadWorker(i); + + m_log.InfoFormat("[YEngine]: Enabled, {0}.{1} Meg (0x{2}) stacks", + (m_StackSize >> 20).ToString(), + (((m_StackSize % 0x100000) * 1000) + >> 20).ToString("D3"), + m_StackSize.ToString("X")); + + m_log.InfoFormat("[YEngine]: ... {0}.{1} Meg (0x{2}) heaps", + (m_HeapSize >> 20).ToString(), + (((m_HeapSize % 0x100000) * 1000) + >> 20).ToString("D3"), + m_HeapSize.ToString("X")); + + m_MaintenanceInterval = m_Config.GetInt("MaintenanceInterval", 10); + + if(m_MaintenanceInterval > 0) + { + m_MaintenanceTimer = new System.Timers.Timer(m_MaintenanceInterval * 60000); + m_MaintenanceTimer.Elapsed += DoMaintenance; + m_MaintenanceTimer.Start(); + } + + MainConsole.Instance.Commands.AddCommand("yeng", false, + "yeng", + "yeng [...|help|...] ...", + "Run YEngine script engine commands", + RunTest); + + TraceCalls("[YEngine]: Initialize successful"); + } + + public void AddRegion(Scene scene) + { + if(!m_Enabled) + return; + + TraceCalls("[YEngine]: YEngine.AddRegion({0})", scene.RegionInfo.RegionName); + + m_Scene = scene; + + m_Scene.RegisterModuleInterface(this); + + m_ScriptBasePath = m_Config.GetString("ScriptBasePath", "ScriptEngines"); + m_ScriptBasePath = Path.Combine(m_ScriptBasePath, "Yengine"); + m_ScriptBasePath = Path.Combine(m_ScriptBasePath, scene.RegionInfo.RegionID.ToString()); + + Directory.CreateDirectory(m_ScriptBasePath); + + m_Scene.EventManager.OnRezScript += OnRezScript; + + m_Scene.StackModuleInterface(this); + } + + private void OneTimeLateInitialization() + { + // Build list of defined APIs and their 'this' types and define a field in XMRInstanceSuperType. + ApiManager am = new ApiManager(); + Dictionary apiCtxTypes = new Dictionary(); + foreach(string api in am.GetApis()) + { + m_log.Debug("[YEngine]: adding api " + api); + IScriptApi scriptApi = am.CreateApi(api); + Type apiCtxType = scriptApi.GetType(); + if(api == "LSL") + apiCtxType = typeof(XMRLSL_Api); + apiCtxTypes[api] = apiCtxType; + } + + if(ScriptCodeGen.xmrInstSuperType == null) // Only create type once! + { + // Start creating type XMRInstanceSuperType that contains a field + // m_ApiManager_ that points to the per-instance context + // struct for that API, ie, the 'this' value passed to all methods + // in that API. It is in essence: + + // public class XMRInstanceSuperType : XMRInstance { + // public XMRLSL_Api m_ApiManager_LSL; // 'this' value for all ll...() functions + // public MOD_Api m_ApiManager_MOD; // 'this' value for all mod...() functions + // public OSSL_Api m_ApiManager_OSSL; // 'this' value for all os...() functions + // .... + // } + AssemblyName assemblyName = new AssemblyName(); + assemblyName.Name = "XMRInstanceSuperAssembly"; + AssemblyBuilder assemblyBuilder = Thread.GetDomain().DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run); + ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("XMRInstanceSuperModule"); + TypeBuilder typeBuilder = moduleBuilder.DefineType("XMRInstanceSuperType", TypeAttributes.Public | TypeAttributes.Class); + typeBuilder.SetParent(typeof(XMRInstance)); + + foreach(string apiname in apiCtxTypes.Keys) + { + string fieldName = "m_ApiManager_" + apiname; + typeBuilder.DefineField(fieldName, apiCtxTypes[apiname], FieldAttributes.Public); + } + + // Finalize definition of XMRInstanceSuperType. + // Give the compiler a short name to reference it by, + // otherwise it will try to use the AssemblyQualifiedName + // and fail miserably. + ScriptCodeGen.xmrInstSuperType = typeBuilder.CreateType(); + ScriptObjWriter.DefineInternalType("xmrsuper", ScriptCodeGen.xmrInstSuperType); + } + + // Tell the compiler about all the constants and methods for each API. + // We also tell the compiler how to get the per-instance context for each API + // by reading the corresponding m_ApiManager_ field of XMRInstanceSuperType. + foreach(KeyValuePair kvp in apiCtxTypes) + { + // get API name and the corresponding per-instance context type + string api = kvp.Key; + Type apiCtxType = kvp.Value; + + // give script compiler an abbreviated name for the API context type + ScriptObjWriter.DefineInternalType("apimanager_" + api, apiCtxType); + + // this field tells the compiled code where the per-instance API context object is + // eg, for the OSSL API, it is in ((XMRInstanceSuperType)inst).m_ApiManager_OSSL + string fieldName = "m_ApiManager_" + api; + FieldInfo fieldInfo = ScriptCodeGen.xmrInstSuperType.GetField(fieldName); + m_XMRInstanceApiCtxFieldInfos[api] = fieldInfo; + + // now tell the compiler about the constants and methods for the API + ScriptConst.AddInterfaceConstants(null, apiCtxType.GetFields()); + TokenDeclInline.AddInterfaceMethods(null, apiCtxType.GetMethods(), fieldInfo); + } + + // Add sim-specific APIs to the compiler. + IScriptModuleComms comms = m_Scene.RequestModuleInterface(); + if(comms != null) + { + // Add methods to list of built-in functions. + Delegate[] methods = comms.GetScriptInvocationList(); + foreach(Delegate m in methods) + { + MethodInfo mi = m.Method; + try + { + CommsCallCodeGen cccg = new CommsCallCodeGen(mi, comms, m_XMRInstanceApiCtxFieldInfos["MOD"]); + Verbose("[YEngine]: added comms function " + cccg.fullName); + } + catch(Exception e) + { + m_log.Error("[YEngine]: failed to add comms function " + mi.Name); + m_log.Error("[YEngine]: - " + e.ToString()); + } + } + + // Add constants to list of built-in constants. + Dictionary consts = comms.GetConstants(); + foreach(KeyValuePair kvp in consts) + { + try + { + ScriptConst sc = ScriptConst.AddConstant(kvp.Key, kvp.Value); + Verbose("[YEngine]: added comms constant " + sc.name); + } + catch(Exception e) + { + m_log.Error("[YEngine]: failed to add comms constant " + kvp.Key); + m_log.Error("[YEngine]: - " + e.Message); + } + } + } + else + { + Verbose("[YEngine]: comms not enabled"); + } + } + + /** + * @brief Generate code for the calls to the comms functions. + * It is a tRUlY EvIL interface. + * To call the function we must call an XMRInstanceSuperType.m_ApiManager_MOD.modInvoker?() + * method passing it the name of the function as a string and the script + * argument list wrapped up in an object[] array. The modInvoker?() methods + * do some sick type conversions (with corresponding mallocs) so we can't + * call the methods directly. + */ + private class CommsCallCodeGen: TokenDeclInline + { + private static Type[] modInvokerArgTypes = new Type[] { typeof(string), typeof(object[]) }; + public static FieldInfo xmrInstModApiCtxField; + + private MethodInfo modInvokerMeth; + private string methName; + + /** + * @brief Constructor + * @param mi = method to make available to scripts + * mi.Name = name that is used by scripts + * mi.GetParameters() = parameter list as defined by module + * includes the 'UUID host','UUID script' parameters that script does not see + * allowed types for script-visible parameters are as follows: + * Single -> float + * Int32 -> integer + * OpenMetaverse.UUID -> key + * Object[] -> list + * OpenMetaverse.Quaternion -> rotation + * String -> string + * OpenMetaverse.Vector3 -> vector + * mi.ReturnType = return type as defined by module + * types are same as allowed for parameters + * @param comms = comms module the method came from + * @param apictxfi = what field in XMRInstanceSuperType the 'this' value is for this method + */ + public CommsCallCodeGen(MethodInfo mi, IScriptModuleComms comms, FieldInfo apictxfi) + : base(null, false, NameArgSig(mi), RetType(mi)) + { + methName = mi.Name; + string modInvokerName = comms.LookupModInvocation(methName); + if(modInvokerName == null) + throw new Exception("cannot find comms method " + methName); + modInvokerMeth = typeof(MOD_Api).GetMethod(modInvokerName, modInvokerArgTypes); + xmrInstModApiCtxField = apictxfi; + } + + // script-visible name(argtype,...) signature string + private static string NameArgSig(MethodInfo mi) + { + StringBuilder sb = new StringBuilder(); + sb.Append(mi.Name); + sb.Append('('); + ParameterInfo[] mps = mi.GetParameters(); + for(int i = 2; i < mps.Length; i++) + { + ParameterInfo pi = mps[i]; + if(i > 2) + sb.Append(','); + sb.Append(ParamType(pi.ParameterType)); + } + sb.Append(')'); + return sb.ToString(); + } + + // script-visible return type + // note that although we support void, the comms stuff does not + private static TokenType RetType(MethodInfo mi) + { + Type rt = mi.ReturnType; + if(rt == typeof(float)) + return new TokenTypeFloat(null); + if(rt == typeof(int)) + return new TokenTypeInt(null); + if(rt == typeof(object[])) + return new TokenTypeList(null); + if(rt == typeof(OpenMetaverse.UUID)) + return new TokenTypeKey(null); + if(rt == typeof(OpenMetaverse.Quaternion)) + return new TokenTypeRot(null); + if(rt == typeof(string)) + return new TokenTypeStr(null); + if(rt == typeof(OpenMetaverse.Vector3)) + return new TokenTypeVec(null); + if(rt == null || rt == typeof(void)) + return new TokenTypeVoid(null); + throw new Exception("unsupported return type " + rt.Name); + } + + // script-visible parameter type + private static string ParamType(Type t) + { + if(t == typeof(float)) + return "float"; + if(t == typeof(int)) + return "integer"; + if(t == typeof(OpenMetaverse.UUID)) + return "key"; + if(t == typeof(object[])) + return "list"; + if(t == typeof(OpenMetaverse.Quaternion)) + return "rotation"; + if(t == typeof(string)) + return "string"; + if(t == typeof(OpenMetaverse.Vector3)) + return "vector"; + throw new Exception("unsupported parameter type " + t.Name); + } + + /** + * @brief Called by the compiler to generate a call to the comms function. + * @param scg = which script is being compiled + * @param errorAt = where in the source code the call is being made (for error messages) + * @param result = a temp location to put the return value in if any + * @param args = array of script-visible arguments being passed to the function + */ + public override void CodeGen(ScriptCodeGen scg, Token errorAt, CompValuTemp result, CompValu[] args) + { + // Set up 'this' pointer for modInvoker?() = value from ApiManager.CreateApi("MOD"). + scg.PushXMRInst(); + scg.ilGen.Emit(errorAt, OpCodes.Castclass, xmrInstModApiCtxField.DeclaringType); + scg.ilGen.Emit(errorAt, OpCodes.Ldfld, xmrInstModApiCtxField); + + // Set up 'fname' argument to modInvoker?() = name of the function to be called. + scg.ilGen.Emit(errorAt, OpCodes.Ldstr, methName); + + // Set up 'parms' argument to modInvoker?() = object[] of the script-visible parameters, + // in their LSL-wrapped form. Of course, the modInvoker?() method will malloc yet another + // object[] and type-convert these parameters one-by-one with another round of unwrapping + // and wrapping. + // Types allowed in this object[]: + // LSL_Float, LSL_Integer, LSL_Key, LSL_List, LSL_Rotation, LSL_String, LSL_Vector + int nargs = args.Length; + scg.ilGen.Emit(errorAt, OpCodes.Ldc_I4, nargs); + scg.ilGen.Emit(errorAt, OpCodes.Newarr, typeof(object)); + + for(int i = 0; i < nargs; i++) + { + scg.ilGen.Emit(errorAt, OpCodes.Dup); + scg.ilGen.Emit(errorAt, OpCodes.Ldc_I4, i); + + // get location and type of argument + CompValu arg = args[i]; + TokenType argtype = arg.type; + + // if already in a form acceptable to modInvoker?(), + // just push it to the stack and convert to object + // by boxing it if necessary + + // but if something like a double, int, string, etc + // push to stack converting to the LSL-wrapped type + // then convert to object by boxing if necessary + + Type boxit = null; + if(argtype is TokenTypeLSLFloat) + { + args[i].PushVal(scg, errorAt); + boxit = typeof(LSL_Float); + } + else if(argtype is TokenTypeLSLInt) + { + args[i].PushVal(scg, errorAt); + boxit = typeof(LSL_Integer); + } + else if(argtype is TokenTypeLSLKey) + { + args[i].PushVal(scg, errorAt); + boxit = typeof(LSL_Key); + } + else if(argtype is TokenTypeList) + { + args[i].PushVal(scg, errorAt); + boxit = typeof(LSL_List); + } + else if(argtype is TokenTypeRot) + { + args[i].PushVal(scg, errorAt); + boxit = typeof(LSL_Rotation); + } + else if(argtype is TokenTypeLSLString) + { + args[i].PushVal(scg, errorAt); + boxit = typeof(LSL_String); + } + else if(argtype is TokenTypeVec) + { + args[i].PushVal(scg, errorAt); + boxit = typeof(LSL_Vector); + } + else if(argtype is TokenTypeFloat) + { + args[i].PushVal(scg, errorAt, new TokenTypeLSLFloat(argtype)); + boxit = typeof(LSL_Float); + } + else if(argtype is TokenTypeInt) + { + args[i].PushVal(scg, errorAt, new TokenTypeLSLInt(argtype)); + boxit = typeof(LSL_Integer); + } + else if(argtype is TokenTypeKey) + { + args[i].PushVal(scg, errorAt, new TokenTypeLSLKey(argtype)); + boxit = typeof(LSL_Key); + } + else if(argtype is TokenTypeStr) + { + args[i].PushVal(scg, errorAt, new TokenTypeLSLString(argtype)); + boxit = typeof(LSL_String); + } + else + throw new Exception("unsupported arg type " + argtype.GetType().Name); + + if(boxit.IsValueType) + scg.ilGen.Emit(errorAt, OpCodes.Box, boxit); + + // pop the object into the object[] + scg.ilGen.Emit(errorAt, OpCodes.Stelem, typeof(object)); + } + + // Call the modInvoker?() method. + // It leaves an LSL-wrapped type on the stack. + if(modInvokerMeth.IsVirtual) + scg.ilGen.Emit(errorAt, OpCodes.Callvirt, modInvokerMeth); + else + scg.ilGen.Emit(errorAt, OpCodes.Call, modInvokerMeth); + + + // The 3rd arg to Pop() is the type on the stack, + // ie, what modInvoker?() actually returns. + // The Pop() method will wrap/unwrap as needed. + Type retSysType = modInvokerMeth.ReturnType; + if(retSysType == null) + retSysType = typeof(void); + TokenType retTokType = TokenType.FromSysType(errorAt, retSysType); + result.Pop(scg, errorAt, retTokType); + } + } + + /** + * @brief Called late in shutdown procedure, + * after the 'Shutting down..." message. + */ + public void RemoveRegion(Scene scene) + { + if(!m_Enabled) + return; + + TraceCalls("[YEngine]: YEngine.RemoveRegion({0})", scene.RegionInfo.RegionName); + + if(m_MaintenanceTimer != null) + { + m_MaintenanceTimer.Stop(); + m_MaintenanceTimer.Dispose(); + } + + // Write script states out to .state files so it will be + // available when the region is restarted. + DoMaintenance(null, null); + + // Stop executing script threads and wait for final + // one to finish (ie, script gets to CheckRun() call). + m_Exiting = true; + if(m_SleepThread != null) + { + lock(m_SleepQueue) + Monitor.PulseAll(m_SleepQueue); + + if(!m_SleepThread.Join(250)) + m_SleepThread.Abort(); + m_SleepThread = null; + } + + StopThreadWorkers(); + + m_Scene.EventManager.OnFrame -= OnFrame; + m_Scene.EventManager.OnRezScript -= OnRezScript; + m_Scene.EventManager.OnRemoveScript -= OnRemoveScript; + m_Scene.EventManager.OnScriptReset -= OnScriptReset; + m_Scene.EventManager.OnStartScript -= OnStartScript; + m_Scene.EventManager.OnStopScript -= OnStopScript; + m_Scene.EventManager.OnGetScriptRunning -= OnGetScriptRunning; + m_Scene.EventManager.OnShutdown -= OnShutdown; + + m_Enabled = false; + m_Scene = null; + } + + public void RegionLoaded(Scene scene) + { + if(!m_Enabled) + return; + + TraceCalls("[YEngine]: YEngine.RegionLoaded({0})", scene.RegionInfo.RegionName); + + m_Scene.EventManager.OnFrame += OnFrame; + m_Scene.EventManager.OnRemoveScript += OnRemoveScript; + m_Scene.EventManager.OnScriptReset += OnScriptReset; + m_Scene.EventManager.OnStartScript += OnStartScript; + m_Scene.EventManager.OnStopScript += OnStopScript; + m_Scene.EventManager.OnGetScriptRunning += OnGetScriptRunning; + m_Scene.EventManager.OnShutdown += OnShutdown; + + InitEvents(); + } + + public void StartProcessing() + { + m_log.Debug("[YEngine]: StartProcessing entry"); + m_StartProcessing = true; + ResumeThreads(); + m_log.Debug("[YEngine]: StartProcessing return"); + m_Scene.EventManager.TriggerEmptyScriptCompileQueue(0, ""); + } + + public void Close() + { + TraceCalls("[YEngine]: YEngine.Close()"); + } + + private void RunTest(string module, string[] args) + { + if(args.Length < 2) + { + m_log.Info("[YEngine]: missing command, try 'yeng help'"); + return; + } + + m_log.Info("[YEngine]: " + m_Scene.RegionInfo.RegionName); + + switch(args[1]) + { + case "cvv": + m_log.InfoFormat("[YEngine]: compiled version value = {0}", + ScriptCodeGen.COMPILED_VERSION_VALUE); + break; + + case "help": + case "?": + m_log.Info("[YEngine]: yeng reset [-help ...]"); + m_log.Info("[YEngine]: yeng resume - resume script processing"); + m_log.Info("[YEngine]: yeng suspend - suspend script processing"); + m_log.Info("[YEngine]: yeng ls [-help ...]"); + m_log.Info("[YEngine]: yeng cvv - show compiler version value"); + m_log.Info("[YEngine]: yeng mvv [] - show migration version value"); + m_log.Info("[YEngine]: yeng tracecalls [yes | no]"); + m_log.Info("[YEngine]: yeng verbose [yes | no]"); + m_log.Info("[YEngine]: yeng pev [-help ...] - post event"); + break; + + case "ls": + XmrTestLs(args, 2); + break; + + case "mvv": + m_log.InfoFormat("[YEngine]: migration version value = {0}", + XMRInstance.migrationVersion); + break; + + case "pev": + XmrTestPev(args, 2); + break; + + case "reset": + XmrTestReset(args, 2); + break; + + case "resume": + m_log.Info("[YEngine]: resuming scripts"); + ResumeThreads(); + break; + + case "suspend": + m_log.Info("[YEngine]: suspending scripts"); + SuspendThreads(); + break; + + case "tracecalls": + if(args.Length > 2) + m_TraceCalls = (args[2][0] & 1) != 0; + m_log.Info("[YEngine]: tracecalls " + (m_TraceCalls ? "yes" : "no")); + break; + + case "verbose": + if(args.Length > 2) + m_Verbose = (args[2][0] & 1) != 0; + m_log.Info("[YEngine]: verbose " + (m_Verbose ? "yes" : "no")); + break; + + default: + m_log.Error("[YEngine]: unknown command " + args[1] + ", try 'yeng help'"); + break; + } + } + + // Not required when not using IScriptInstance + // + public IScriptWorkItem QueueEventHandler(object parms) + { + return null; + } + + public Scene World + { + get + { + return m_Scene; + } + } + + public IScriptModule ScriptModule + { + get + { + return this; + } + } + + public void SaveAllState() + { + m_log.Error("[YEngine]: YEngine.SaveAllState() called!!"); + } + +#pragma warning disable 0067 + public event ScriptRemoved OnScriptRemoved; + public event ObjectRemoved OnObjectRemoved; +#pragma warning restore 0067 + + // Events targeted at a specific script + // ... like listen() for an llListen() call + // + public bool PostScriptEvent(UUID itemID, EventParams parms) + { + XMRInstance instance = GetInstance(itemID); + if(instance == null) + return false; + + TraceCalls("[YEngine]: YEngine.PostScriptEvent({0},{1})", itemID.ToString(), parms.EventName); + + instance.PostEvent(parms); + return true; + } + + // Events targeted at all scripts in the given prim. + // localID = which prim + // parms = event to post + // + public bool PostObjectEvent(uint localID, EventParams parms) + { + SceneObjectPart part = m_Scene.GetSceneObjectPart(localID); + + if(part == null) + return false; + + TraceCalls("[YEngine]: YEngine.PostObjectEvent({0},{1})", localID.ToString(), parms.EventName); + + // In SecondLife, attach events go to all scripts of all prims + // in a linked object. So here we duplicate that functionality, + // as all we ever get is a single attach event for the whole + // object. + if(parms.EventName == "attach") + { + bool posted = false; + foreach(SceneObjectPart primpart in part.ParentGroup.Parts) + posted |= PostPrimEvent(primpart, parms); + + return posted; + } + + // Other events go to just the scripts in that prim. + return PostPrimEvent(part, parms); + } + + private bool PostPrimEvent(SceneObjectPart part, EventParams parms) + { + UUID partUUID = part.UUID; + + // Get list of script instances running in the object. + XMRInstance[] objInstArray; + lock(m_InstancesDict) + { + if(!m_ObjectInstArray.TryGetValue(partUUID, out objInstArray)) + return false; + + if(objInstArray == null) + { + objInstArray = RebuildObjectInstArray(partUUID); + m_ObjectInstArray[partUUID] = objInstArray; + } + } + + // Post event to all script instances in the object. + if(objInstArray.Length <= 0) + return false; + foreach(XMRInstance inst in objInstArray) + inst.PostEvent(parms); + + return true; + } + + public DetectParams GetDetectParams(UUID itemID, int number) + { + XMRInstance instance = GetInstance(itemID); + if(instance == null) + return null; + return instance.GetDetectParams(number); + } + + public void SetMinEventDelay(UUID itemID, double delay) + { + } + + public int GetStartParameter(UUID itemID) + { + XMRInstance instance = GetInstance(itemID); + if(instance == null) + return 0; + return instance.StartParam; + } + + // This is the "set running" method + // + public void SetScriptState(UUID itemID, bool state, bool self) + { + SetScriptState(itemID, state); + } + public void SetScriptState(UUID itemID, bool state) + { + XMRInstance instance = GetInstance(itemID); + if(instance != null) + instance.Running = state; + } + + // Control display of the "running" checkbox + // + public bool GetScriptState(UUID itemID) + { + XMRInstance instance = GetInstance(itemID); + if(instance == null) + return false; + return instance.Running; + } + + public void SetState(UUID itemID, string newState) + { + TraceCalls("[YEngine]: YEngine.SetState({0},{1})", itemID.ToString(), newState); + } + + public void ApiResetScript(UUID itemID) + { + XMRInstance instance = GetInstance(itemID); + if(instance != null) + instance.ApiReset(); + + } + + public void ResetScript(UUID itemID) + { + XMRInstance instance = GetInstance(itemID); + if(instance != null) + { + IUrlModule urlModule = m_Scene.RequestModuleInterface(); + if(urlModule != null) + urlModule.ScriptRemoved(itemID); + + instance.Reset(); + } + } + + public IConfig Config + { + get + { + return m_Config; + } + } + + public IConfigSource ConfigSource + { + get + { + return m_ConfigSource; + } + } + + public string ScriptEngineName + { + get + { + return "YEngine"; + } + } + + public IScriptApi GetApi(UUID itemID, string name) + { + FieldInfo fi; + if(!m_XMRInstanceApiCtxFieldInfos.TryGetValue(name, out fi)) + return null; + XMRInstance inst = GetInstance(itemID); + if(inst == null) + return null; + return (IScriptApi)fi.GetValue(inst); + } + + /** + * @brief Get script's current state as an XML string + * - called by "Take", "Take Copy" and when object deleted (ie, moved to Trash) + * This includes the .state file + */ + public string GetXMLState(UUID itemID) + { + XMRInstance instance = GetInstance(itemID); + if(instance == null) + return String.Empty; + + TraceCalls("[YEngine]: YEngine.GetXMLState({0})", itemID.ToString()); + + if(!instance.m_HasRun) + return String.Empty; + + XmlDocument doc = new XmlDocument(); + + /* + * Set up tag. + */ + XmlElement stateN = doc.CreateElement("", "State", ""); + doc.AppendChild(stateN); + + XmlAttribute engineA = doc.CreateAttribute("", "Engine", ""); + engineA.Value = ScriptEngineName; + stateN.Attributes.Append(engineA); + + XmlAttribute uuidA = doc.CreateAttribute("", "UUID", ""); + uuidA.Value = itemID.ToString(); + stateN.Attributes.Append(uuidA); + + XmlAttribute assetA = doc.CreateAttribute("", "Asset", ""); + string assetID = instance.AssetID.ToString(); + assetA.Value = assetID; + stateN.Attributes.Append(assetA); + + // Get ... item that hold's script's state. + // This suspends the script if necessary then takes a snapshot. + XmlElement scriptStateN = instance.GetExecutionState(doc); + stateN.AppendChild(scriptStateN); + + return doc.OuterXml; + } + + // Set script's current state from an XML string + // - called just before a script is instantiated + // So we write the .state file so the .state file will be seen when + // the script is instantiated. + public bool SetXMLState(UUID itemID, string xml) + { + XmlDocument doc = new XmlDocument(); + + try + { + doc.LoadXml(xml); + } + catch + { + return false; + } + TraceCalls("[YEngine]: YEngine.SetXMLState({0})", itemID.ToString()); + + // Make sure so we know it is in our + // format. + XmlElement stateN = (XmlElement)doc.SelectSingleNode("State"); + if(stateN == null) + return false; + + if(stateN.GetAttribute("Engine") != ScriptEngineName) + return false; + + // ... contains contents of .state file. + XmlElement scriptStateN = (XmlElement)stateN.SelectSingleNode("ScriptState"); + if(scriptStateN == null) + return false; + + string sen = stateN.GetAttribute("Engine"); + if((sen == null) || (sen != ScriptEngineName)) + return false; + + XmlAttribute assetA = doc.CreateAttribute("", "Asset", ""); + assetA.Value = stateN.GetAttribute("Asset"); + scriptStateN.Attributes.Append(assetA); + + // Write out the .state file with the ... XML text + string statePath = XMRInstance.GetStateFileName(m_ScriptBasePath, itemID); + FileStream ss = File.Create(statePath); + StreamWriter sw = new StreamWriter(ss); + sw.Write(scriptStateN.OuterXml); + sw.Close(); + ss.Close(); + + return true; + } + + public bool PostScriptEvent(UUID itemID, string name, Object[] p) + { + if(!m_Enabled) + return false; + + TraceCalls("[YEngine]: YEngine.PostScriptEvent({0},{1})", itemID.ToString(), name); + + return PostScriptEvent(itemID, new EventParams(name, p, zeroDetectParams)); + } + + public bool PostObjectEvent(UUID itemID, string name, Object[] p) + { + if(!m_Enabled) + return false; + + TraceCalls("[YEngine]: YEngine.PostObjectEvent({0},{1})", itemID.ToString(), name); + + SceneObjectPart part = m_Scene.GetSceneObjectPart(itemID); + if(part == null) + return false; + + return PostObjectEvent(part.LocalId, new EventParams(name, p, zeroDetectParams)); + } + + // about the 3523rd entrypoint for a script to put itself to sleep + public void SleepScript(UUID itemID, int delay) + { + XMRInstance instance = GetInstance(itemID); + if(instance != null) + instance.Sleep(delay); + } + + // Get a script instance loaded, compiling it if necessary + // + // localID = the object as a whole, may contain many scripts + // itemID = this instance of the script in this object + // script = script source code + // startParam = value passed to 'on_rez' event handler + // postOnRez = true to post an 'on_rez' event to script on load + // defEngine = default script engine + // stateSource = post this event to script on load + + public void OnRezScript(uint localID, UUID itemID, string script, + int startParam, bool postOnRez, string defEngine, int stateSource) + { + SceneObjectPart part = m_Scene.GetSceneObjectPart(localID); + TaskInventoryItem item = part.Inventory.GetInventoryItem(itemID); + + if(!m_LateInit) + { + m_LateInit = true; + OneTimeLateInitialization(); + } + + TraceCalls("[YEngine]: OnRezScript(...,{0},...)", itemID.ToString()); + + // Assume script uses the default engine, whatever that is. + string engineName = defEngine; + + // Very first line might contain "//" scriptengine ":". + string firstline = ""; + if(script.StartsWith("//")) + { + int lineEnd = script.IndexOf('\n'); + if(lineEnd > 1) + firstline = script.Substring(0, lineEnd).Trim(); + int colon = firstline.IndexOf(':'); + if(colon >= 2) + { + engineName = firstline.Substring(2, colon - 2).Trim(); + if(engineName == "") + engineName = defEngine; + } + } + + // Make sure the default or requested engine is us. + if(engineName != ScriptEngineName) + { + // Not us, if requested engine exists, silently ignore script and let + // requested engine handle it. + IScriptModule[] engines = m_Scene.RequestModuleInterfaces(); + foreach(IScriptModule eng in engines) + { + if(eng.ScriptEngineName == engineName) + return; + } + + // Requested engine not defined, warn on console. + // Then we try to handle it if we're the default engine, else we ignore it. + m_log.Warn("[YEngine]: " + itemID.ToString() + " requests undefined/disabled engine " + engineName); + m_log.Info("[YEngine]: - " + part.GetWorldPosition()); + m_log.Info("[YEngine]: first line: " + firstline); + if(defEngine != ScriptEngineName) + { + m_log.Info("[YEngine]: leaving it to the default script engine (" + defEngine + ") to process it"); + return; + } + m_log.Info("[YEngine]: will attempt to processing it anyway as default script engine"); + } + + // Put on object/instance lists. + XMRInstance instance = (XMRInstance)Activator.CreateInstance(ScriptCodeGen.xmrInstSuperType); + instance.m_LocalID = localID; + instance.m_ItemID = itemID; + instance.m_SourceCode = script; + instance.m_StartParam = startParam; + instance.m_PostOnRez = postOnRez; + instance.m_StateSource = (StateSource)stateSource; + instance.m_Part = part; + instance.m_PartUUID = part.UUID; + instance.m_Item = item; + instance.m_DescName = part.Name + ":" + item.Name; + instance.m_IState = XMRInstState.CONSTRUCT; + + lock(m_InstancesDict) + { + m_LockedDict = "RegisterInstance"; + + // Insert on internal list of all scripts being handled by this engine instance. + m_InstancesDict[instance.m_ItemID] = instance; + + // Insert on internal list of all scripts being handled by this engine instance + // that are part of the object. + List itemIDList; + if(!m_ObjectItemList.TryGetValue(instance.m_PartUUID, out itemIDList)) + { + itemIDList = new List(); + m_ObjectItemList[instance.m_PartUUID] = itemIDList; + } + if(!itemIDList.Contains(instance.m_ItemID)) + { + itemIDList.Add(instance.m_ItemID); + m_ObjectInstArray[instance.m_PartUUID] = null; + } + + m_LockedDict = "~RegisterInstance"; + } + + // Compile and load it. + lock(m_ScriptErrors) + m_ScriptErrors.Remove(instance.m_ItemID); + + LoadThreadWork(instance); + } + + /** + * @brief This routine instantiates one script. + */ + private void LoadThreadWork(XMRInstance instance) + { + // Compile and load the script in memory. + ArrayList errors = new ArrayList(); + Exception initerr = null; + try + { + instance.Initialize(this, m_ScriptBasePath, m_StackSize, m_HeapSize, errors); + } + catch(Exception e1) + { + initerr = e1; + } + if(initerr != null && !instance.m_ForceRecomp && initerr is CVVMismatchException) + { + UUID itemID = instance.m_ItemID; + Verbose("[YEngine]: {0}/{2} first load failed ({1}), retrying after recompile", + itemID.ToString(), initerr.Message, instance.m_Item.AssetID.ToString()); + Verbose("[YEngine]:\n{0}", initerr.ToString()); + initerr = null; + errors = new ArrayList(); + instance.m_ForceRecomp = true; + try + { + instance.Initialize(this, m_ScriptBasePath, m_StackSize, m_HeapSize, errors); + } + catch(Exception e2) + { + initerr = e2; + } + } + if(initerr != null) + { + UUID itemID = instance.m_ItemID; + Verbose("[YEngine]: Error starting script {0}/{2}: {1}", + itemID.ToString(), initerr.Message, instance.m_Item.AssetID.ToString()); + if(initerr.Message != "compilation errors") + { + Verbose("[YEngine]: - " + instance.m_Part.GetWorldPosition() + " " + instance.m_DescName); + Verbose("[YEngine]: exception:\n{0}", initerr.ToString()); + } + + OnRemoveScript(0, itemID); + + // Post errors where GetScriptErrors() can see them. + if(errors.Count == 0) + errors.Add(initerr.Message); + else + { + foreach(Object err in errors) + { + if(m_ScriptDebug) + m_log.DebugFormat("[YEngine]: {0}", err.ToString()); + } + } + lock(m_ScriptErrors) + m_ScriptErrors[instance.m_ItemID] = errors; + + return; + } + + // Tell GetScriptErrors() that we have finished compiling/loading + // successfully (by posting a 0 element array). + lock(m_ScriptErrors) + { + if(instance.m_IState != XMRInstState.CONSTRUCT) + throw new Exception("bad state"); + m_ScriptErrors[instance.m_ItemID] = noScriptErrors; + } + + // Transition from CONSTRUCT->ONSTARTQ and give to RunScriptThread(). + // Put it on the start queue so it will run any queued event handlers, + // such as state_entry() or on_rez(). If there aren't any queued, it + // will just go to idle state when RunOne() tries to dequeue an event. + lock(instance.m_QueueLock) + { + if(instance.m_IState != XMRInstState.CONSTRUCT) + throw new Exception("bad state"); + instance.m_IState = XMRInstState.ONSTARTQ; + if(!instance.m_Running) + instance.EmptyEventQueues(); + } + QueueToStart(instance); + } + + public void OnRemoveScript(uint localID, UUID itemID) + { + TraceCalls("[YEngine]: OnRemoveScript(...,{0})", itemID.ToString()); + + // Remove from our list of known scripts. + // After this, no more events can queue because we won't be + // able to translate the itemID to an XMRInstance pointer. + XMRInstance instance = null; + lock(m_InstancesDict) + { + m_LockedDict = "OnRemoveScript:" + itemID.ToString(); + + // Tell the instance to free off everything it can. + if(!m_InstancesDict.TryGetValue(itemID, out instance)) + { + m_LockedDict = "~OnRemoveScript"; + return; + } + + // Tell it to stop executing anything. + instance.suspendOnCheckRunHold = true; + + // Remove it from our list of known script instances + // mostly so no more events can queue to it. + m_InstancesDict.Remove(itemID); + + List itemIDList; + if(m_ObjectItemList.TryGetValue(instance.m_PartUUID, out itemIDList)) + { + itemIDList.Remove(itemID); + if(itemIDList.Count == 0) + { + m_ObjectItemList.Remove(instance.m_PartUUID); + m_ObjectInstArray.Remove(instance.m_PartUUID); + } + else + m_ObjectInstArray[instance.m_PartUUID] = null; + } + + // Delete the .state file as any needed contents were fetched with GetXMLState() + // and stored on the database server. + string stateFileName = XMRInstance.GetStateFileName(m_ScriptBasePath, itemID); + File.Delete(stateFileName); + + ScriptRemoved handlerScriptRemoved = OnScriptRemoved; + if(handlerScriptRemoved != null) + handlerScriptRemoved(itemID); + + m_LockedDict = "~~OnRemoveScript"; + } + + // Free off its stack and fun things like that. + // If it is running, abort it. + instance.Dispose(); + } + + public void OnScriptReset(uint localID, UUID itemID) + { + TraceCalls("[YEngine]: YEngine.OnScriptReset({0},{1})", localID.ToString(), itemID.ToString()); + ResetScript(itemID); + } + + public void OnStartScript(uint localID, UUID itemID) + { + XMRInstance instance = GetInstance(itemID); + if(instance != null) + instance.Running = true; + } + + public void OnStopScript(uint localID, UUID itemID) + { + XMRInstance instance = GetInstance(itemID); + if(instance != null) + instance.Running = false; + } + + public void OnGetScriptRunning(IClientAPI controllingClient, + UUID objectID, UUID itemID) + { + XMRInstance instance = GetInstance(itemID); + if(instance != null) + { + TraceCalls("[YEngine]: YEngine.OnGetScriptRunning({0},{1})", objectID.ToString(), itemID.ToString()); + + IEventQueue eq = World.RequestModuleInterface(); + if(eq == null) + { + controllingClient.SendScriptRunningReply(objectID, itemID, + instance.Running); + } + else + { + eq.Enqueue(EventQueueHelper.ScriptRunningReplyEvent(objectID, + itemID, instance.Running, true), + controllingClient.AgentId); + } + } + } + + public bool HasScript(UUID itemID, out bool running) + { + XMRInstance instance = GetInstance(itemID); + if(instance == null) + { + running = true; + return false; + } + running = instance.Running; + return true; + } + + /** + * @brief Called once per frame update to see if scripts have + * any such work to do. + */ + private void OnFrame() + { + if(m_FrameUpdateList != null) + { + ThreadStart frameupdates; + lock(m_FrameUpdateLock) + { + frameupdates = m_FrameUpdateList; + m_FrameUpdateList = null; + } + frameupdates(); + } + } + + /** + * @brief Add a one-shot delegate to list of things to do + * synchronized with frame updates. + */ + public void AddOnFrameUpdate(ThreadStart thunk) + { + lock(m_FrameUpdateLock) + m_FrameUpdateList += thunk; + } + + /** + * @brief Gets called early as part of shutdown, + * right after "Persisting changed objects" message. + */ + public void OnShutdown() + { + TraceCalls("[YEngine]: YEngine.OnShutdown()"); + } + + /** + * @brief Queue an instance to the StartQueue so it will run. + * This queue is used for instances that have just had + * an event queued to them when they were previously + * idle. It must only be called by the thread that + * transitioned the thread to XMRInstState.ONSTARTQ so + * we don't get two threads trying to queue the same + * instance to the m_StartQueue at the same time. + */ + public void QueueToStart(XMRInstance inst) + { + if(inst.m_IState != XMRInstState.ONSTARTQ) + throw new Exception("bad state"); + + lock(m_StartQueue) + m_StartQueue.InsertTail(inst); + + WakeUpOne(); + } + + /** + * @brief A script may be sleeping, in which case we wake it. + */ + public void WakeFromSleep(XMRInstance inst) + { + // Remove from sleep queue unless someone else already woke it. + lock(m_SleepQueue) + { + if(inst.m_IState != XMRInstState.ONSLEEPQ) + return; + + m_SleepQueue.Remove(inst); + inst.m_IState = XMRInstState.REMDFROMSLPQ; + } + + // Put on end of list of scripts that are ready to run. + lock(m_YieldQueue) + { + inst.m_IState = XMRInstState.ONYIELDQ; + m_YieldQueue.InsertTail(inst); + } + + // Make sure the OS thread is running so it will see the script. + WakeUpOne(); + } + + /** + * @brief An instance has just finished running for now, + * figure out what to do with it next. + * @param inst = instance in question, not on any queue at the moment + * @param newIState = its new state + * @returns with instance inserted onto proper queue (if any) + */ + public void HandleNewIState(XMRInstance inst, XMRInstState newIState) + { + // RunOne() should have left the instance in RUNNING state. + if(inst.m_IState != XMRInstState.RUNNING) + throw new Exception("bad state"); + + // Now see what RunOne() wants us to do with the instance next. + switch(newIState) + { + // Instance has set m_SleepUntil to when it wants to sleep until. + // So insert instance in sleep queue by ascending wake time. + // Then wake the timer thread if this is the new first entry + // so it will reset its timer. + case XMRInstState.ONSLEEPQ: + lock(m_SleepQueue) + { + XMRInstance after; + + inst.m_IState = XMRInstState.ONSLEEPQ; + for(after = m_SleepQueue.PeekHead(); after != null; after = after.m_NextInst) + { + if(after.m_SleepUntil > inst.m_SleepUntil) + break; + } + m_SleepQueue.InsertBefore(inst, after); + if(m_SleepQueue.PeekHead() == inst) + Monitor.Pulse(m_SleepQueue); + } + break; + + // Instance just took a long time to run and got wacked by the + // slicer. So put on end of yield queue to let someone else + // run. If there is no one else, it will run again right away. + case XMRInstState.ONYIELDQ: + lock(m_YieldQueue) + { + inst.m_IState = XMRInstState.ONYIELDQ; + m_YieldQueue.InsertTail(inst); + } + break; + + // Instance finished executing an event handler. So if there is + // another event queued for it, put it on the start queue so it + // will process the new event. Otherwise, mark it idle and the + // next event to queue to it will start it up. + case XMRInstState.FINISHED: + Monitor.Enter(inst.m_QueueLock); + if(!inst.m_Suspended && (inst.m_EventQueue.Count > 0)) + { + inst.m_IState = XMRInstState.ONSTARTQ; + Monitor.Exit(inst.m_QueueLock); + lock(m_StartQueue) + m_StartQueue.InsertTail(inst); + } + else + { + inst.m_IState = XMRInstState.IDLE; + Monitor.Exit(inst.m_QueueLock); + } + break; + + // Its m_SuspendCount > 0. + // Don't put it on any queue and it won't run. + // Since it's not IDLE, even queuing an event won't start it. + case XMRInstState.SUSPENDED: + inst.m_IState = XMRInstState.SUSPENDED; + break; + + // It has been disposed of. + // Just set the new state and all refs should theoretically drop off + // as the instance is no longer in any list. + case XMRInstState.DISPOSED: + inst.m_IState = XMRInstState.DISPOSED; + break; + + // RunOne returned something bad. + default: + throw new Exception("bad new state"); + } + } + + /** + * @brief Thread that moves instances from the Sleep queue to the Yield queue. + */ + private void RunSleepThread() + { + double deltaTS; + int deltaMS; + XMRInstance inst; + + while(true) + { + lock(m_SleepQueue) + { + // Wait here until there is a script on the timer queue that has expired. + while(true) + { + UpdateMyThread(); + if(m_Exiting) + { + MyThreadExiting(); + return; + } + inst = m_SleepQueue.PeekHead(); + if(inst == null) + { + Monitor.Wait(m_SleepQueue, Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS / 2); + continue; + } + if(inst.m_IState != XMRInstState.ONSLEEPQ) + throw new Exception("bad state"); + deltaTS = (inst.m_SleepUntil - DateTime.UtcNow).TotalMilliseconds; + if(deltaTS <= 0.0) + break; + deltaMS = Int32.MaxValue; + if(deltaTS < Int32.MaxValue) + deltaMS = (int)deltaTS; + if(deltaMS > Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS / 2) + deltaMS = Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS / 2; + + Monitor.Wait(m_SleepQueue, deltaMS); + } + + // Remove the expired entry from the timer queue. + m_SleepQueue.RemoveHead(); + inst.m_IState = XMRInstState.REMDFROMSLPQ; + } + + // Post the script to the yield queue so it will run and wake a script thread to run it. + lock(m_YieldQueue) + { + inst.m_IState = XMRInstState.ONYIELDQ; + m_YieldQueue.InsertTail(inst); + } + WakeUpOne(); + } + } + + public void Suspend(UUID itemID, int ms) + { + XMRInstance instance = GetInstance(itemID); + if(instance != null) + instance.Sleep(ms); + } + + public void Die(UUID itemID) + { + XMRInstance instance = GetInstance(itemID); + if(instance != null) + { + TraceCalls("[YEngine]: YEngine.Die({0})", itemID.ToString()); + instance.Die(); + } + } + + /** + * @brief Get specific script instance for which OnRezScript() + * has been called for an YEngine script, and that + * OnRemoveScript() has not been called since. + * @param itemID = as passed to OnRezScript() identifying a specific script instance + * @returns null: not one of our scripts (maybe XEngine etc) + * else: points to the script instance + */ + public XMRInstance GetInstance(UUID itemID) + { + XMRInstance instance; + lock(m_InstancesDict) + { + if(!m_InstancesDict.TryGetValue(itemID, out instance)) + instance = null; + } + return instance; + } + + // Called occasionally to write script state to .state file so the + // script will restart from its last known state if the region crashes + // and gets restarted. + private void DoMaintenance(object source, ElapsedEventArgs e) + { + XMRInstance[] instanceArray; + + lock(m_InstancesDict) + instanceArray = System.Linq.Enumerable.ToArray(m_InstancesDict.Values); + + foreach(XMRInstance ins in instanceArray) + { + // Don't save attachments + if(ins.m_Part.ParentGroup.IsAttachment) + continue; + ins.GetExecutionState(new XmlDocument()); + } + } + + /** + * @brief Retrieve errors generated by a previous call to OnRezScript(). + * We are guaranteed this routine will not be called before the + * corresponding OnRezScript() has returned. It blocks until the + * compile has completed. + */ + public ArrayList GetScriptErrors(UUID itemID) + { + ArrayList errors; + + lock(m_ScriptErrors) + { + while(!m_ScriptErrors.TryGetValue(itemID, out errors)) + { + Monitor.Wait(m_ScriptErrors); + } + m_ScriptErrors.Remove(itemID); + } + return errors; + } + + /** + * @brief Return a list of all script execution times. + */ + public Dictionary GetObjectScriptsExecutionTimes() + { + Dictionary topScripts = new Dictionary(); + lock(m_InstancesDict) + { + foreach(XMRInstance instance in m_InstancesDict.Values) + { + uint rootLocalID = instance.m_Part.ParentGroup.LocalId; + float oldTotal; + if(!topScripts.TryGetValue(rootLocalID, out oldTotal)) + oldTotal = 0; + + topScripts[rootLocalID] = (float)instance.m_CPUTime + oldTotal; + } + } + return topScripts; + } + + /** + * @brief A float the value is a representative execution time in + * milliseconds of all scripts in the link set. + * @param itemIDs = list of scripts in the link set + * @returns milliseconds for all those scripts + */ + public float GetScriptExecutionTime(List itemIDs) + { + if((itemIDs == null) || (itemIDs.Count == 0)) + return 0; + + float time = 0; + foreach(UUID itemID in itemIDs) + { + XMRInstance instance = GetInstance(itemID); + if((instance != null) && instance.Running) + time += (float)instance.m_CPUTime; + } + return time; + } + + /** + * @brief Block script from dequeuing events. + */ + public void SuspendScript(UUID itemID) + { + XMRInstance instance = GetInstance(itemID); + if(instance != null) + { + TraceCalls("[YEngine]: YEngine.SuspendScript({0})", itemID.ToString()); + instance.SuspendIt(); + } + } + + /** + * @brief Allow script to dequeue events. + */ + public void ResumeScript(UUID itemID) + { + XMRInstance instance = GetInstance(itemID); + if(instance != null) + { + TraceCalls("[YEngine]: YEngine.ResumeScript({0})", itemID.ToString()); + instance.ResumeIt(); + } + else + { + // probably an XEngine script + } + } + + /** + * @brief Rebuild m_ObjectInstArray[partUUID] from m_ObjectItemList[partUUID] + * @param partUUID = which object in scene to rebuild for + */ + private XMRInstance[] RebuildObjectInstArray(UUID partUUID) + { + List itemIDList = m_ObjectItemList[partUUID]; + int n = 0; + foreach(UUID itemID in itemIDList) + { + if(m_InstancesDict.ContainsKey(itemID)) + n++; + } + + XMRInstance[] a = new XMRInstance[n]; + n = 0; + foreach(UUID itemID in itemIDList) + { + if(m_InstancesDict.TryGetValue(itemID, out a[n])) + n++; + } + m_ObjectInstArray[partUUID] = a; + return a; + } + + public void TraceCalls(string format, params object[] args) + { + if(m_TraceCalls) + m_log.DebugFormat(format, args); + } + public void Verbose(string format, params object[] args) + { + if(m_Verbose) + m_log.DebugFormat(format, args); + } + + /** + * @brief Manage our threads. + */ + public static Thread StartMyThread(ThreadStart start, string name, ThreadPriority priority) + { + m_log.Debug("[YEngine]: starting thread " + name); + Thread thread = WorkManager.StartThread(start, name, priority, true, false, false); + return thread; + } + + public static void UpdateMyThread() + { + Watchdog.UpdateThread(); + } + + public static void MyThreadExiting() + { + Watchdog.RemoveThread(true); + } + } +} diff --git a/OpenSim/Region/ScriptEngine/YEngine/XMREvents.cs b/OpenSim/Region/ScriptEngine/YEngine/XMREvents.cs new file mode 100644 index 0000000000..b4e92b9d1c --- /dev/null +++ b/OpenSim/Region/ScriptEngine/YEngine/XMREvents.cs @@ -0,0 +1,377 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Reflection; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.ScriptEngine.Shared; +using OpenSim.Region.ScriptEngine.Interfaces; +using log4net; + +using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; +using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; +using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; +using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list; +using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; +using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; +using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; + +namespace OpenSim.Region.ScriptEngine.Yengine +{ + /// + /// Prepares events so they can be directly executed upon a script by EventQueueManager, then queues it. + /// + public partial class Yengine + { + public static readonly object[] zeroObjectArray = new object[0]; + public static readonly object[] oneObjectArrayOne = new object[1] { 1 }; + + private void InitEvents() + { + m_log.Info("[YEngine] Hooking up to server events"); + this.World.EventManager.OnAttach += attach; + this.World.EventManager.OnObjectGrab += touch_start; + this.World.EventManager.OnObjectGrabbing += touch; + this.World.EventManager.OnObjectDeGrab += touch_end; + this.World.EventManager.OnScriptChangedEvent += changed; + this.World.EventManager.OnScriptAtTargetEvent += at_target; + this.World.EventManager.OnScriptNotAtTargetEvent += not_at_target; + this.World.EventManager.OnScriptAtRotTargetEvent += at_rot_target; + this.World.EventManager.OnScriptNotAtRotTargetEvent += not_at_rot_target; + this.World.EventManager.OnScriptMovingStartEvent += moving_start; + this.World.EventManager.OnScriptMovingEndEvent += moving_end; + this.World.EventManager.OnScriptControlEvent += control; + this.World.EventManager.OnScriptColliderStart += collision_start; + this.World.EventManager.OnScriptColliding += collision; + this.World.EventManager.OnScriptCollidingEnd += collision_end; + this.World.EventManager.OnScriptLandColliderStart += land_collision_start; + this.World.EventManager.OnScriptLandColliding += land_collision; + this.World.EventManager.OnScriptLandColliderEnd += land_collision_end; + IMoneyModule money = this.World.RequestModuleInterface(); + if(money != null) + { + money.OnObjectPaid += HandleObjectPaid; + } + } + + /// + /// When an object gets paid by an avatar and generates the paid event, + /// this will pipe it to the script engine + /// + /// Object ID that got paid + /// Agent Id that did the paying + /// Amount paid + private void HandleObjectPaid(UUID objectID, UUID agentID, + int amount) + { + // Add to queue for all scripts in ObjectID object + DetectParams[] det = new DetectParams[1]; + det[0] = new DetectParams(); + det[0].Key = agentID; + det[0].Populate(this.World); + + // Since this is an event from a shared module, all scenes will + // get it. But only one has the object in question. The others + // just ignore it. + // + SceneObjectPart part = + this.World.GetSceneObjectPart(objectID); + + if(part == null) + return; + + if((part.ScriptEvents & scriptEvents.money) == 0) + part = part.ParentGroup.RootPart; + + Verbose("Paid: " + objectID + " from " + agentID + ", amount " + amount); + + if(part != null) + { + money(part.LocalId, agentID, amount, det); + } + } + + /// + /// Handles piping the proper stuff to The script engine for touching + /// Including DetectedParams + /// + /// + /// + /// + /// + /// + public void touch_start(uint localID, uint originalID, Vector3 offsetPos, + IClientAPI remoteClient, SurfaceTouchEventArgs surfaceArgs) + { + touches(localID, originalID, offsetPos, remoteClient, surfaceArgs, "touch_start"); + } + + public void touch(uint localID, uint originalID, Vector3 offsetPos, + IClientAPI remoteClient, SurfaceTouchEventArgs surfaceArgs) + { + touches(localID, originalID, offsetPos, remoteClient, surfaceArgs, "touch"); + } + + private static Vector3 zeroVec3 = new Vector3(0, 0, 0); + public void touch_end(uint localID, uint originalID, IClientAPI remoteClient, + SurfaceTouchEventArgs surfaceArgs) + { + touches(localID, originalID, zeroVec3, remoteClient, surfaceArgs, "touch_end"); + } + + private void touches(uint localID, uint originalID, Vector3 offsetPos, + IClientAPI remoteClient, SurfaceTouchEventArgs surfaceArgs, string eventname) + { + SceneObjectPart part; + if(originalID == 0) + { + part = this.World.GetSceneObjectPart(localID); + if(part == null) + return; + } + else + { + part = this.World.GetSceneObjectPart(originalID); + } + + DetectParams det = new DetectParams(); + det.Key = remoteClient.AgentId; + det.Populate(this.World); + det.OffsetPos = new LSL_Vector(offsetPos.X, + offsetPos.Y, + offsetPos.Z); + det.LinkNum = part.LinkNum; + + if(surfaceArgs != null) + { + det.SurfaceTouchArgs = surfaceArgs; + } + + // Add to queue for all scripts in ObjectID object + this.PostObjectEvent(localID, new EventParams( + eventname, oneObjectArrayOne, + new DetectParams[] { det })); + } + + public void changed(uint localID, uint change) + { + int ch = (int)change; + // Add to queue for all scripts in localID, Object pass change. + this.PostObjectEvent(localID, new EventParams( + "changed", new object[] { ch }, + zeroDetectParams)); + } + + // state_entry: not processed here + // state_exit: not processed here + + public void money(uint localID, UUID agentID, int amount, DetectParams[] det) + { + this.PostObjectEvent(localID, new EventParams( + "money", new object[] { + agentID.ToString(), + amount }, + det)); + } + + public void collision_start(uint localID, ColliderArgs col) + { + collisions(localID, col, "collision_start"); + } + + public void collision(uint localID, ColliderArgs col) + { + collisions(localID, col, "collision"); + } + + public void collision_end(uint localID, ColliderArgs col) + { + collisions(localID, col, "collision_end"); + } + + private void collisions(uint localID, ColliderArgs col, string eventname) + { + int dc = col.Colliders.Count; + if(dc > 0) + { + DetectParams[] det = new DetectParams[dc]; + int i = 0; + foreach(DetectedObject detobj in col.Colliders) + { + DetectParams d = new DetectParams(); + det[i++] = d; + + d.Key = detobj.keyUUID; + d.Populate(this.World); + + /* not done by XEngine... + d.Position = detobj.posVector; + d.Rotation = detobj.rotQuat; + d.Velocity = detobj.velVector; + ... */ + } + + this.PostObjectEvent(localID, new EventParams( + eventname, + new Object[] { dc }, + det)); + } + } + + public void land_collision_start(uint localID, ColliderArgs col) + { + land_collisions(localID, col, "land_collision_start"); + } + + public void land_collision(uint localID, ColliderArgs col) + { + land_collisions(localID, col, "land_collision"); + } + + public void land_collision_end(uint localID, ColliderArgs col) + { + land_collisions(localID, col, "land_collision_end"); + } + + private void land_collisions(uint localID, ColliderArgs col, string eventname) + { + foreach(DetectedObject detobj in col.Colliders) + { + LSL_Vector vec = new LSL_Vector(detobj.posVector.X, + detobj.posVector.Y, + detobj.posVector.Z); + EventParams eps = new EventParams(eventname, + new Object[] { vec }, + zeroDetectParams); + this.PostObjectEvent(localID, eps); + } + } + + // timer: not handled here + // listen: not handled here + + public void control(UUID itemID, UUID agentID, uint held, uint change) + { + this.PostScriptEvent(itemID, new EventParams( + "control", new object[] { + agentID.ToString(), + (int)held, + (int)change}, + zeroDetectParams)); + } + + public void email(uint localID, UUID itemID, string timeSent, + string address, string subject, string message, int numLeft) + { + this.PostObjectEvent(localID, new EventParams( + "email", new object[] { + timeSent, + address, + subject, + message, + numLeft}, + zeroDetectParams)); + } + + public void at_target(uint localID, uint handle, Vector3 targetpos, + Vector3 atpos) + { + this.PostObjectEvent(localID, new EventParams( + "at_target", new object[] { + (int)handle, + new LSL_Vector(targetpos.X,targetpos.Y,targetpos.Z), + new LSL_Vector(atpos.X,atpos.Y,atpos.Z) }, + zeroDetectParams)); + } + + public void not_at_target(uint localID) + { + this.PostObjectEvent(localID, new EventParams( + "not_at_target", zeroObjectArray, + zeroDetectParams)); + } + + public void at_rot_target(uint localID, uint handle, OpenMetaverse.Quaternion targetrot, OpenMetaverse.Quaternion atrot) + { + this.PostObjectEvent( + localID, + new EventParams( + "at_rot_target", + new object[] { + new LSL_Integer(handle), + new LSL_Rotation(targetrot.X, targetrot.Y, targetrot.Z, targetrot.W), + new LSL_Rotation(atrot.X, atrot.Y, atrot.Z, atrot.W) + }, + zeroDetectParams + ) + ); + } + + public void not_at_rot_target(uint localID) + { + this.PostObjectEvent(localID, new EventParams( + "not_at_rot_target", zeroObjectArray, + zeroDetectParams)); + } + + // run_time_permissions: not handled here + + public void attach(uint localID, UUID itemID, UUID avatar) + { + this.PostObjectEvent(localID, new EventParams( + "attach", new object[] { + avatar.ToString() }, + zeroDetectParams)); + } + + // dataserver: not handled here + // link_message: not handled here + + public void moving_start(uint localID) + { + this.PostObjectEvent(localID, new EventParams( + "moving_start", zeroObjectArray, + zeroDetectParams)); + } + + public void moving_end(uint localID) + { + this.PostObjectEvent(localID, new EventParams( + "moving_end", zeroObjectArray, + zeroDetectParams)); + } + + // object_rez: not handled here + // remote_data: not handled here + // http_response: not handled here + } +} diff --git a/OpenSim/Region/ScriptEngine/YEngine/XMRHeapTracker.cs b/OpenSim/Region/ScriptEngine/YEngine/XMRHeapTracker.cs new file mode 100644 index 0000000000..33eb8bf5e0 --- /dev/null +++ b/OpenSim/Region/ScriptEngine/YEngine/XMRHeapTracker.cs @@ -0,0 +1,299 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Reflection; +using System.Reflection.Emit; + +using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; +using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; +using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; +using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list; +using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; +using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; +using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; + +namespace OpenSim.Region.ScriptEngine.Yengine +{ + /** + * One instance of this class for lsl base objects that take a variable + * amount of memory. They are what the script-visible list,object,string + * variables are declared as at the CIL level. Generally, temp vars used + * by the compiler get their basic type (list,object,string). + * + * Note that the xmr arrays and script-defined objects have their own + * heap tracking built in so do not need any of this stuff. + */ + public class HeapTrackerBase + { + protected int usage; // num bytes used by object + protected XMRInstAbstract instance; // what script it is in + + public HeapTrackerBase(XMRInstAbstract inst) + { + if(inst == null) + throw new ArgumentNullException("inst"); + instance = inst; + } + + ~HeapTrackerBase() + { + usage = instance.UpdateHeapUse(usage, 0); + } + } + + /** + * Wrapper around lists to keep track of how much memory they use. + */ + public class HeapTrackerList: HeapTrackerBase + { + private static FieldInfo listValueField = typeof(HeapTrackerList).GetField("value"); + private static MethodInfo listSaveMethod = typeof(HeapTrackerList).GetMethod("Save"); + + public LSL_List value; + + public HeapTrackerList(XMRInstAbstract inst) : base(inst) { } + + // generate CIL code to pop the value from the CIL stack + // input: + // 'this' pointer already pushed on CIL stack + // new value pushed on CIL stack + // output: + // 'this' pointer popped from stack + // new value popped from CIL stack + // heap usage updated + public static void GenPop(Token errorAt, ScriptMyILGen ilGen) + { + ilGen.Emit(errorAt, OpCodes.Call, listSaveMethod); + } + + // generate CIL code to push the value on the CIL stack + // input: + // 'this' pointer already pushed on CIL stack + // output: + // 'this' pointer popped from stack + // value pushed on CIL stack replacing 'this' pointer + // returns typeof value pushed on stack + public static Type GenPush(Token errorAt, ScriptMyILGen ilGen) + { + ilGen.Emit(errorAt, OpCodes.Ldfld, listValueField); + return typeof(LSL_List); + } + + public void Save(LSL_List lis) + { + int newuse = Size(lis); + usage = instance.UpdateHeapUse(usage, newuse); + value = lis; + } + + //private static int counter = 5; + public static int Size(LSL_List lis) + { + // VS2017 in debug mode seems to have a problem running this statement quickly: + //SLOW: return (!typeof(LSL_List).IsValueType && (lis == null)) ? 0 : lis.Size; + + //FAST: return 33; + //SLOW: return (lis == null) ? 0 : 99; + //FAST: return ++ counter; + + // VS2017 in debug mode seems content to run this quickly though: + + try + { + return lis.Size; + } + catch + { + return 0; + } + } + } + + /** + * Wrapper around objects to keep track of how much memory they use. + */ + public class HeapTrackerObject: HeapTrackerBase + { + private static FieldInfo objectValueField = typeof(HeapTrackerObject).GetField("value"); + private static MethodInfo objectSaveMethod = typeof(HeapTrackerObject).GetMethod("Save"); + + public const int HT_CHAR = 2; + public const int HT_DELE = 8; + public const int HT_DOUB = 8; + public const int HT_SING = 4; + public const int HT_SFLT = 4; + public const int HT_INT = 4; + public const int HT_VEC = HT_DOUB * 3; + public const int HT_ROT = HT_DOUB * 4; + + public object value; + + public HeapTrackerObject(XMRInstAbstract inst) : base(inst) { } + + // generate CIL code to pop the value from the CIL stack + // input: + // 'this' pointer already pushed on CIL stack + // new value pushed on CIL stack + // output: + // 'this' pointer popped from stack + // new value popped from CIL stack + // heap usage updated + public static void GenPop(Token errorAt, ScriptMyILGen ilGen) + { + ilGen.Emit(errorAt, OpCodes.Call, objectSaveMethod); + } + + // generate CIL code to push the value on the CIL stack + // input: + // 'this' pointer already pushed on CIL stack + // output: + // 'this' pointer popped from stack + // value pushed on CIL stack replacing 'this' pointer + // returns typeof value pushed on stack + public static Type GenPush(Token errorAt, ScriptMyILGen ilGen) + { + ilGen.Emit(errorAt, OpCodes.Ldfld, objectValueField); + return typeof(object); + } + + public void Save(object obj) + { + int newuse = Size(obj); + usage = instance.UpdateHeapUse(usage, newuse); + value = obj; + } + + // public so it can be used by XMRArray + public static int Size(object obj) + { + if(obj == null) + return 0; + + if(obj is char) + return HT_CHAR; + if(obj is Delegate) + return HT_DELE; + if(obj is double) + return HT_DOUB; + if(obj is float) + return HT_SING; + if(obj is int) + return HT_INT; + if(obj is LSL_Float) + return HT_SFLT; + if(obj is LSL_Integer) + return HT_INT; + if(obj is LSL_List) + return ((LSL_List)obj).Size; + if(obj is LSL_Rotation) + return HT_ROT; + if(obj is LSL_String) + return ((LSL_String)obj).m_string.Length * HT_CHAR; + if(obj is LSL_Vector) + return HT_VEC; + if(obj is string) + return ((string)obj).Length * HT_CHAR; + if(obj is XMR_Array) + return 0; + if(obj is XMRArrayListKey) + return ((XMRArrayListKey)obj).Size; + if(obj is XMRSDTypeClObj) + return 0; + + if(obj is Array) + { + Array ar = (Array)obj; + int len = ar.Length; + if(len == 0) + return 0; + Type et = ar.GetType().GetElementType(); + if(et.IsValueType) + return Size(ar.GetValue(0)) * len; + int size = 0; + for(int i = 0; i < len; i++) + { + size += Size(ar.GetValue(i)); + } + return size; + } + + throw new Exception("unknown size of type " + obj.GetType().Name); + } + } + + /** + * Wrapper around strings to keep track of how much memory they use. + */ + public class HeapTrackerString: HeapTrackerBase + { + private static FieldInfo stringValueField = typeof(HeapTrackerString).GetField("value"); + private static MethodInfo stringSaveMethod = typeof(HeapTrackerString).GetMethod("Save"); + + public string value; + + public HeapTrackerString(XMRInstAbstract inst) : base(inst) { } + + // generate CIL code to pop the value from the CIL stack + // input: + // 'this' pointer already pushed on CIL stack + // new value pushed on CIL stack + // output: + // 'this' pointer popped from stack + // new value popped from CIL stack + // heap usage updated + public static void GenPop(Token errorAt, ScriptMyILGen ilGen) + { + ilGen.Emit(errorAt, OpCodes.Call, stringSaveMethod); + } + + // generate CIL code to push the value on the CIL stack + // input: + // 'this' pointer already pushed on CIL stack + // output: + // 'this' pointer popped from stack + // value pushed on CIL stack replacing 'this' pointer + // returns typeof value pushed on stack + public static Type GenPush(Token errorAt, ScriptMyILGen ilGen) + { + ilGen.Emit(errorAt, OpCodes.Ldfld, stringValueField); + return typeof(string); + } + + public void Save(string str) + { + int newuse = Size(str); + usage = instance.UpdateHeapUse(usage, newuse); + value = str; + } + + public static int Size(string str) + { + return (str == null) ? 0 : str.Length * HeapTrackerObject.HT_CHAR; + } + } +} diff --git a/OpenSim/Region/ScriptEngine/YEngine/XMRInstAbstract.cs b/OpenSim/Region/ScriptEngine/YEngine/XMRInstAbstract.cs new file mode 100644 index 0000000000..b3ff76555a --- /dev/null +++ b/OpenSim/Region/ScriptEngine/YEngine/XMRInstAbstract.cs @@ -0,0 +1,2287 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using OpenSim.Region.ScriptEngine.Shared.ScriptBase; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Reflection.Emit; +using System.Runtime.Serialization; +using System.Text; +using System.Threading; + +using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; +using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; +using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; +using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list; +using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; +using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; +using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; + +namespace OpenSim.Region.ScriptEngine.Yengine +{ + public class XMRInstArrays + { + public XMR_Array[] iarArrays; + public char[] iarChars; + public double[] iarFloats; + public int[] iarIntegers; + public LSL_List[] iarLists; + public object[] iarObjects; + public LSL_Rotation[] iarRotations; + public string[] iarStrings; + public LSL_Vector[] iarVectors; + public XMRSDTypeClObj[] iarSDTClObjs; + public Delegate[][] iarSDTIntfObjs; + + private XMRInstAbstract instance; + private int heapUse; + + private static readonly XMR_Array[] noArrays = new XMR_Array[0]; + private static readonly char[] noChars = new char[0]; + private static readonly double[] noFloats = new double[0]; + private static readonly int[] noIntegers = new int[0]; + private static readonly LSL_List[] noLists = new LSL_List[0]; + private static readonly object[] noObjects = new object[0]; + private static readonly LSL_Rotation[] noRotations = new LSL_Rotation[0]; + private static readonly string[] noStrings = new string[0]; + private static readonly LSL_Vector[] noVectors = new LSL_Vector[0]; + private static readonly XMRSDTypeClObj[] noSDTClObjs = new XMRSDTypeClObj[0]; + private static readonly Delegate[][] noSDTIntfObjs = new Delegate[0][]; + + public XMRInstArrays(XMRInstAbstract inst) + { + instance = inst; + } + + ~XMRInstArrays() + { + heapUse = instance.UpdateHeapUse(heapUse, 0); + } + + public void AllocVarArrays(XMRInstArSizes ars) + { + ClearOldArrays(); + + heapUse = instance.UpdateHeapUse(heapUse, + ars.iasChars * HeapTrackerObject.HT_CHAR + + ars.iasFloats * HeapTrackerObject.HT_SFLT + + ars.iasIntegers * HeapTrackerObject.HT_INT + + ars.iasRotations * HeapTrackerObject.HT_ROT + + ars.iasVectors * HeapTrackerObject.HT_VEC + + ars.iasSDTIntfObjs * HeapTrackerObject.HT_DELE); + + iarArrays = (ars.iasArrays > 0) ? new XMR_Array[ars.iasArrays] : noArrays; + iarChars = (ars.iasChars > 0) ? new char[ars.iasChars] : noChars; + iarFloats = (ars.iasFloats > 0) ? new double[ars.iasFloats] : noFloats; + iarIntegers = (ars.iasIntegers > 0) ? new int[ars.iasIntegers] : noIntegers; + iarLists = (ars.iasLists > 0) ? new LSL_List[ars.iasLists] : noLists; + iarObjects = (ars.iasObjects > 0) ? new object[ars.iasObjects] : noObjects; + iarRotations = (ars.iasRotations > 0) ? new LSL_Rotation[ars.iasRotations] : noRotations; + iarStrings = (ars.iasStrings > 0) ? new string[ars.iasStrings] : noStrings; + iarVectors = (ars.iasVectors > 0) ? new LSL_Vector[ars.iasVectors] : noVectors; + iarSDTClObjs = (ars.iasSDTClObjs > 0) ? new XMRSDTypeClObj[ars.iasSDTClObjs] : noSDTClObjs; + iarSDTIntfObjs = (ars.iasSDTIntfObjs > 0) ? new Delegate[ars.iasSDTIntfObjs][] : noSDTIntfObjs; + } + + /** + * @brief Do not write directly to iarLists[index], rather use this method. + */ + public void PopList(int index, LSL_List lis) + { + LSL_List old = iarLists[index]; + int newheapuse = heapUse + HeapTrackerList.Size(lis) - HeapTrackerList.Size(old); + heapUse = instance.UpdateHeapUse(heapUse, newheapuse); + iarLists[index] = lis; + } + + /** + * @brief Do not write directly to iarObjects[index], rather use this method. + */ + public void PopObject(int index, object obj) + { + object old = iarObjects[index]; + int newheapuse = heapUse + HeapTrackerObject.Size(obj) - HeapTrackerObject.Size(old); + heapUse = instance.UpdateHeapUse(heapUse, newheapuse); + iarObjects[index] = obj; + } + + /** + * @brief Do not write directly to iarStrings[index], rather use this method. + */ + public void PopString(int index, string str) + { + string old = iarStrings[index]; + int newheapuse = heapUse + HeapTrackerString.Size(str) - HeapTrackerString.Size(old); + heapUse = instance.UpdateHeapUse(heapUse, newheapuse); + iarStrings[index] = str; + } + + /** + * @brief Write all arrays out to a file. + */ + public delegate void Sender(object value); + public void SendArrays(Sender sender) + { + sender(iarArrays); + sender(iarChars); + sender(iarFloats); + sender(iarIntegers); + sender(iarLists); + sender(iarObjects); + sender(iarRotations); + sender(iarStrings); + sender(iarVectors); + sender(iarSDTClObjs); + sender(iarSDTIntfObjs); + } + + /** + * @brief Read all arrays in from a file. + */ + public delegate object Recver(); + public void RecvArrays(Recver recver) + { + ClearOldArrays(); + + iarArrays = (XMR_Array[])recver(); + char[] chrs = (char[])recver(); + double[] flts = (double[])recver(); + int[] ints = (int[])recver(); + LSL_List[] liss = (LSL_List[])recver(); + object[] objs = (object[])recver(); + LSL_Rotation[] rots = (LSL_Rotation[])recver(); + string[] strs = (string[])recver(); + LSL_Vector[] vecs = (LSL_Vector[])recver(); + iarSDTClObjs = (XMRSDTypeClObj[])recver(); + Delegate[][] dels = (Delegate[][])recver(); + + int newheapuse = heapUse; + + // value types simply are the size of the value * number of values + newheapuse += chrs.Length * HeapTrackerObject.HT_CHAR; + newheapuse += flts.Length * HeapTrackerObject.HT_SFLT; + newheapuse += ints.Length * HeapTrackerObject.HT_INT; + newheapuse += rots.Length * HeapTrackerObject.HT_ROT; + newheapuse += vecs.Length * HeapTrackerObject.HT_VEC; + newheapuse += dels.Length * HeapTrackerObject.HT_DELE; + + // lists, objects, strings are the sum of the size of each element + foreach(LSL_List lis in liss) + newheapuse += HeapTrackerList.Size(lis); + + foreach(object obj in objs) + newheapuse += HeapTrackerObject.Size(obj); + + foreach(string str in strs) + newheapuse += HeapTrackerString.Size(str); + + // others (XMR_Array, XMRSDTypeClObj) keep track of their own heap usage + + // update script heap usage, throwing an exception before finalizing changes + heapUse = instance.UpdateHeapUse(heapUse, newheapuse); + + iarChars = chrs; + iarFloats = flts; + iarIntegers = ints; + iarLists = liss; + iarObjects = objs; + iarRotations = rots; + iarStrings = strs; + iarVectors = vecs; + iarSDTIntfObjs = dels; + } + + private void ClearOldArrays() + { + int newheapuse = heapUse; + + iarArrays = null; + if(iarChars != null) + { + newheapuse -= iarChars.Length * HeapTrackerObject.HT_CHAR; + iarChars = null; + } + if(iarFloats != null) + { + newheapuse -= iarFloats.Length * HeapTrackerObject.HT_SFLT; + iarFloats = null; + } + if(iarIntegers != null) + { + newheapuse -= iarIntegers.Length * HeapTrackerObject.HT_INT; + iarIntegers = null; + } + if(iarLists != null) + { + foreach(LSL_List lis in iarLists) + newheapuse -= HeapTrackerList.Size(lis); + iarLists = null; + } + if(iarObjects != null) + { + foreach(object obj in iarObjects) + newheapuse -= HeapTrackerObject.Size(obj); + iarObjects = null; + } + if(iarRotations != null) + { + newheapuse -= iarRotations.Length * HeapTrackerObject.HT_ROT; + iarRotations = null; + } + if(iarStrings != null) + { + foreach(string str in iarStrings) + newheapuse -= HeapTrackerString.Size(str); + iarStrings = null; + } + if(iarVectors != null) + { + newheapuse -= iarVectors.Length * HeapTrackerObject.HT_VEC; + iarVectors = null; + } + iarSDTClObjs = null; + if(iarSDTIntfObjs != null) + { + newheapuse -= iarSDTIntfObjs.Length * HeapTrackerObject.HT_DELE; + iarSDTIntfObjs = null; + } + + heapUse = instance.UpdateHeapUse(heapUse, newheapuse); + } + } + + public class XMRInstArSizes + { + public int iasArrays; + public int iasChars; + public int iasFloats; + public int iasIntegers; + public int iasLists; + public int iasObjects; + public int iasRotations; + public int iasStrings; + public int iasVectors; + public int iasSDTClObjs; + public int iasSDTIntfObjs; + + public void WriteAsmFile(TextWriter asmFileWriter, string label) + { + asmFileWriter.WriteLine(" {0}Arrays {1}", label, iasArrays); + asmFileWriter.WriteLine(" {0}Chars {1}", label, iasChars); + asmFileWriter.WriteLine(" {0}Floats {1}", label, iasFloats); + asmFileWriter.WriteLine(" {0}Integers {1}", label, iasIntegers); + asmFileWriter.WriteLine(" {0}Lists {1}", label, iasLists); + asmFileWriter.WriteLine(" {0}Objects {1}", label, iasObjects); + asmFileWriter.WriteLine(" {0}Rotations {1}", label, iasRotations); + asmFileWriter.WriteLine(" {0}Strings {1}", label, iasStrings); + asmFileWriter.WriteLine(" {0}Vectors {1}", label, iasVectors); + asmFileWriter.WriteLine(" {0}SDTClObjs {1}", label, iasSDTClObjs); + asmFileWriter.WriteLine(" {0}SDTIntfObjs {1}", label, iasSDTIntfObjs); + } + + public void WriteToFile(BinaryWriter objFileWriter) + { + objFileWriter.Write(iasArrays); + objFileWriter.Write(iasChars); + objFileWriter.Write(iasFloats); + objFileWriter.Write(iasIntegers); + objFileWriter.Write(iasLists); + objFileWriter.Write(iasObjects); + objFileWriter.Write(iasRotations); + objFileWriter.Write(iasStrings); + objFileWriter.Write(iasVectors); + objFileWriter.Write(iasSDTClObjs); + objFileWriter.Write(iasSDTIntfObjs); + } + + public void ReadFromFile(BinaryReader objFileReader) + { + iasArrays = objFileReader.ReadInt32(); + iasChars = objFileReader.ReadInt32(); + iasFloats = objFileReader.ReadInt32(); + iasIntegers = objFileReader.ReadInt32(); + iasLists = objFileReader.ReadInt32(); + iasObjects = objFileReader.ReadInt32(); + iasRotations = objFileReader.ReadInt32(); + iasStrings = objFileReader.ReadInt32(); + iasVectors = objFileReader.ReadInt32(); + iasSDTClObjs = objFileReader.ReadInt32(); + iasSDTIntfObjs = objFileReader.ReadInt32(); + } + } + + public class XMRStackFrame + { + public XMRStackFrame nextSF; + public string funcName; + public int callNo; + public object[] objArray; + } + + /* + * Contains only items required by the stand-alone compiler + * so the compiler doesn't need to pull in all of OpenSim. + * + * Inherit from ScriptBaseClass so we can be used as 'this' + * parameter for backend-API calls, eg llSay(). + */ + public abstract class XMRInstAbstract: ScriptBaseClass + { + public const int CallMode_NORMAL = 0; // when function is called, it proceeds normally + public const int CallMode_SAVE = 1; // StackSaveException() was thrown, push args/locals to stackFrames + public const int CallMode_RESTORE = 2; // when function is called, it pops state from stackFrames + + public bool suspendOnCheckRunHold; // suspend script execution until explicitly set false + public bool suspendOnCheckRunTemp; // suspend script execution for single step only + public int stackLimit; // stack must have at least this many bytes free on entry to functions + public int m_StackLeft; // total number of stack bytes yet to be used (init to stacksize) + + public ScriptObjCode m_ObjCode; // script object code this instance was created from + + public object[] ehArgs; // event handler argument array + public bool doGblInit = true; // default state_entry() needs to initialize global variables + public int stateCode = 0; // state the script is in (0 = 'default') + public int newStateCode = -1; // if >= 0, in the middle of exiting 'stateCode' and entering 'newStateCode' + public ScriptEventCode eventCode = ScriptEventCode.None; + // what event handler is executing (or None if not) + + public int callMode = CallMode_NORMAL; + // to capture stack frames on stackFrames: + // set to CallMode_SAVE just before throwing StackSaveException() + // from within CheckRun() and cleared to CallMode_NORMAL when + // the exception is caught + // to restore stack frames from stackFrames: + // set to CallMode_RESTORE just before calling CallSEH() and + // cleared to CallMode_NORMAL by CheckRun() + public XMRStackFrame stackFrames; // stack frames being saved/restored + + private static readonly char[] justacomma = { ',' }; + + /* + * These arrays hold the global variable values for the script instance. + * The array lengths are determined by the script compilation, + * and are found in ScriptObjCode.glblSizes. + */ + public XMRInstArrays glblVars; + + public XMRInstAbstract() + { + glblVars = new XMRInstArrays(this); + } + + /****************************************************************\ + * Abstract function prototypes. * + * These functions require access to the OpenSim environment. * + \****************************************************************/ + + public abstract void CheckRunWork(); + public abstract void StateChange(); + + [xmrMethodCallsCheckRunAttribute] // calls CheckRun() + [xmrMethodIsNoisyAttribute] // calls Stub() + public abstract LSL_List xmrEventDequeue(double timeout, int returnMask1, int returnMask2, + int backgroundMask1, int backgroundMask2); + + [xmrMethodIsNoisyAttribute] // calls Stub() + public abstract void xmrEventEnqueue(LSL_List ev); + + [xmrMethodIsNoisyAttribute] // calls Stub() + public abstract LSL_List xmrEventSaveDets(); + + [xmrMethodIsNoisyAttribute] // calls Stub() + public abstract void xmrEventLoadDets(LSL_List dpList); + + + /**************************************************\ + * Functions what don't require runtime support * + * beyond what the compiler provides. * + \**************************************************/ + + protected int heapLimit; + private int heapUsed; + + public virtual int UpdateHeapUse(int olduse, int newuse) + { + if(newuse <= olduse) + Interlocked.Add(ref heapUsed, newuse - olduse); + else + { + int newtotal, oldtotal; + do + { + oldtotal = Interlocked.Add(ref heapUsed, 0); + newtotal = oldtotal + newuse - olduse; + if(newtotal > heapLimit) + { + // System.GC.Collect (); + // System.GC.WaitForPendingFinalizers (); + oldtotal = Interlocked.Add(ref heapUsed, 0); + newtotal = oldtotal + newuse - olduse; + if(newtotal > heapLimit) + throw new OutOfHeapException(oldtotal, newtotal, heapLimit); + } + } while(Interlocked.CompareExchange(ref heapUsed, newtotal, oldtotal) != oldtotal); + } + + return newuse; + } + + public int xmrHeapLeft() + { + return heapLimit - heapUsed; + } + + public int xmrHeapUsed() + { + return heapUsed; + } + + /** + * @brief Call script's event handler function from the very beginning. + * @param instance.stateCode = which state the event is happening in + * @param instance.eventCode = which event is happening in that state + * @returns when event handler has completed or throws an exception + * with instance.eventCode = ScriptEventCode.None + */ + public void CallSEH() + { + ScriptEventHandler seh; + + // CallMode_NORMAL: run event handler from the beginning normally + // CallMode_RESTORE: restore event handler stack from stackFrames + callMode = (stackFrames == null) ? XMRInstAbstract.CallMode_NORMAL : + XMRInstAbstract.CallMode_RESTORE; + + while(true) + { + if(this.newStateCode < 0) + { + // Process event given by 'stateCode' and 'eventCode'. + // The event handler should call CheckRun() as often as convenient. + int newState = this.stateCode; + seh = this.m_ObjCode.scriptEventHandlerTable[newState, (int)this.eventCode]; + if(seh != null) + { + try + { + seh(this); + } + catch(ScriptChangeStateException scse) + { + newState = scse.newState; + } + } + this.ehArgs = null; // we are done with them and no args for + // exit_state()/enter_state() anyway + + // The usual case is no state change. + // Even a 'state ;' statement has no effect except to exit out. + // It does not execute the state_exit() or state_entry() handlers. + // See http://wiki.secondlife.com/wiki/State + if(newState == this.stateCode) + break; + + // Save new state in a more permanent location in case we + // get serialized out while in the state_exit() handler. + this.newStateCode = newState; + } + + // Call old state's state_exit() handler. + this.eventCode = ScriptEventCode.state_exit; + seh = this.m_ObjCode.scriptEventHandlerTable[this.stateCode, (int)ScriptEventCode.state_exit]; + if(seh != null) + { + try + { + seh(this); + } + catch(ScriptChangeStateException scse) + { + this.newStateCode = scse.newState; + } + } + + // Switch over to the new state's state_entry() handler. + this.stateCode = this.newStateCode; + this.eventCode = ScriptEventCode.state_entry; + this.newStateCode = -1; + + // Now that the old state can't possibly start any more activity, + // cancel any listening handlers, etc, of the old state. + this.StateChange(); + + // Loop back to execute new state's state_entry() handler. + } + + // Event no longer being processed. + this.eventCode = ScriptEventCode.None; + } + + /** + * @brief For compatibility with old code. + */ + public void CheckRun(int line) + { + CheckRunStack(); + } + + /** + * @brief Called at beginning of complex functions to see if they + * are nested too deep possibly in a recursive loop. + */ + public void CheckRunStack() + { + if(m_StackLeft < stackLimit) + throw new OutOfStackException(); + + CheckRunQuick(); + } + + /** + * @brief Called in each iteration of a loop to see if running too long. + */ + public void CheckRunQuick() + { + // if (suspendOnCheckRunHold || suspendOnCheckRunTemp) + CheckRunWork(); + } + + /** + * @brief Called during CallMode_SAVE to create a stackframe save object that saves + * local variables and calling point within the function. + * @param funcName = name of function whose frame is being saved + * @param callNo = call number (ie, return address) within function to restart at + * @param nSaves = number of variables the function will save + * @returns an object[nSaves] where function can save variables + */ + public object[] CaptureStackFrame(string funcName, int callNo, int nSaves) + { + XMRStackFrame sf = new XMRStackFrame(); + sf.nextSF = stackFrames; + sf.funcName = funcName; + sf.callNo = callNo; + sf.objArray = new object[nSaves]; + stackFrames = sf; + return sf.objArray; + } + + /** + * @brief Called during CallMode_RESTORE to pop a stackframe object to restore + * local variables and calling point within the function. + * @param funcName = name of function whose frame is being restored + * @returns the object[nSaves] where function can retrieve variables + * callNo = as passed to CaptureStackFrame() indicating restart point + */ + public object[] RestoreStackFrame(string funcName, out int callNo) + { + XMRStackFrame sf = stackFrames; + if(sf.funcName != funcName) + throw new Exception("frame mismatch " + sf.funcName + " vs " + funcName); + + callNo = sf.callNo; + stackFrames = sf.nextSF; + return sf.objArray; + } + + /** + * @brief Convert all LSL_Integers in a list to System.Int32s, + * as required by llParcelMediaQuery(). + */ + public static LSL_List FixLLParcelMediaQuery(LSL_List oldlist) + { + object[] oldarray = oldlist.Data; + int len = oldarray.Length; + object[] newarray = new object[len]; + for(int i = 0; i < len; i++) + { + object obj = oldarray[i]; + if(obj is LSL_Integer) + obj = (int)(LSL_Integer)obj; + newarray[i] = obj; + } + return new LSL_List(newarray); + } + + /** + * @brief Convert *SOME* LSL_Integers in a list to System.Int32s, + * as required by llParcelMediaCommandList(). + */ + public static LSL_List FixLLParcelMediaCommandList(LSL_List oldlist) + { + object[] oldarray = oldlist.Data; + int len = oldarray.Length; + object[] newarray = new object[len]; + int verbatim = 0; + for(int i = 0; i < len; i++) + { + object obj = oldarray[i]; + if(--verbatim < 0) + { + if(obj is LSL_Integer) + obj = (int)(LSL_Integer)obj; + if(obj is int) + { + switch((int)obj) + { + case ScriptBaseClass.PARCEL_MEDIA_COMMAND_AUTO_ALIGN: + // leave next integer as LSL_Integer + verbatim = 1; + break; + + case ScriptBaseClass.PARCEL_MEDIA_COMMAND_SIZE: + // leave next two integers as LSL_Integer + verbatim = 2; + break; + + } + } + } + newarray[i] = obj; + } + return new LSL_List(newarray); + } + + public static int xmrHashCode(int i) + { + return i.GetHashCode(); + } + + public static int xmrHashCode(double f) + { + return f.GetHashCode(); + } + + public static int xmrHashCode(object o) + { + return o.GetHashCode(); + } + + public static int xmrHashCode(string s) + { + return s.GetHashCode(); + } + + public string xmrTypeName(object o) + { + /* + * Basic types return constant strings of the script-visible type name. + */ + if(o is XMR_Array) + return "array"; + if(o is bool) + return "bool"; + if(o is char) + return "char"; + if(o is Exception) + return "exception"; + if(o is double) + return "float"; + if(o is float) + return "float"; + if(o is LSL_Float) + return "float"; + if(o is int) + return "integer"; + if(o is LSL_Integer) + return "integer"; + if(o is LSL_List) + return "list"; + if(o is LSL_Rotation) + return "rotation"; + if(o is LSL_String) + return "string"; + if(o is string) + return "string"; + if(o is LSL_Vector) + return "vector"; + + // A script-defined interface is represented as an array of delegates. + // If that is the case, convert it to the object of the script-defined + // class that is implementing the interface. This should let the next + // step get the script-defined type name of the object. + if(o is Delegate[]) + o = ((Delegate[])o)[0].Target; + + // If script-defined class instance, get the script-defined + // type name. + if(o is XMRSDTypeClObj) + return ((XMRSDTypeClObj)o).sdtcClass.longName.val; + + // If it's a delegate, maybe we can look up its script-defined type name. + Type ot = o.GetType(); + if(o is Delegate) + { + String os; + if(m_ObjCode.sdDelTypes.TryGetValue(ot, out os)) + return os; + } + + // Don't know what it is, get the C#-level type name. + return ot.ToString(); + } + + /** + * @brief Call the current state's event handler. + * @param ev = as returned by xmrEventDequeue saying which event handler to call + * and what argument list to pass to it. The llDetect...() parameters + * are as currently set for the script (use xmrEventLoadDets to set how + * you want them to be different). + */ + public void xmrEventCallHandler(LSL_List ev) + { + object[] data = ev.Data; + int evc = (int)(ev.GetLSLIntegerItem(0).value & 0xFFFFFFFF); + ScriptEventHandler seh = m_ObjCode.scriptEventHandlerTable[stateCode, evc]; + if(seh != null) + { + int nargs = data.Length - 1; + object[] args = new object[nargs]; + Array.Copy(data, 1, args, 0, nargs); + + object[] saveEHArgs = this.ehArgs; + ScriptEventCode saveEventCode = this.eventCode; + + this.ehArgs = args; + this.eventCode = (ScriptEventCode)evc; + + seh(this); + + this.ehArgs = saveEHArgs; + this.eventCode = saveEventCode; + } + } + + /** + * @brief Sane substring functions. + */ + public string xmrSubstring(string s, int offset) + { + if(offset >= s.Length) + return ""; + return s.Substring(offset); + } + + // C# style + public string xmrSubstring(string s, int offset, int length) + { + if(length <= 0) + return ""; + if(offset >= s.Length) + return ""; + if(length > s.Length - offset) + length = s.Length - offset; + return s.Substring(offset, length); + } + + // java style + public string xmrJSubstring(string s, int beg, int end) + { + if(end <= beg) + return ""; + if(beg >= s.Length) + return ""; + if(end > s.Length) + end = s.Length; + return s.Substring(beg, end - beg); + } + + /** + * @brief String begins and ends with test. + */ + public bool xmrStringStartsWith(string s, string t) + { + return s.StartsWith(t); + } + + public bool xmrStringEndsWith(string s, string t) + { + return s.EndsWith(t); + } + + /** + * @brief [Last]IndexOf with starting position (just like C#) + */ + public int xmrStringIndexOf(string haystack, string needle) + { + return haystack.IndexOf(needle); + } + + public int xmrStringIndexOf(string haystack, string needle, int startat) + { + return haystack.IndexOf(needle, startat); + } + + public int xmrStringLastIndexOf(string haystack, string needle) + { + return haystack.LastIndexOf(needle); + } + + public int xmrStringLastIndexOf(string haystack, string needle, int startat) + { + return haystack.LastIndexOf(needle, startat); + } + + /** + * @brief These conversions throw exceptions if there is anything stinky... + */ + public double xmrString2Float(string s) + { + return double.Parse(s, CultureInfo.InvariantCulture); + } + + public int xmrString2Integer(string s) + { + s = s.Trim(); + if(s.StartsWith("0x") || s.StartsWith("0X")) + return int.Parse(s.Substring(2), NumberStyles.HexNumber); + + return int.Parse(s, CultureInfo.InvariantCulture); + } + + public LSL_Rotation xmrString2Rotation(string s) + { + s = s.Trim(); + if(!s.StartsWith("<") || !s.EndsWith(">")) + throw new FormatException("doesn't begin with < and end with >"); + + s = s.Substring(1, s.Length - 2); + string[] splitup = s.Split(justacomma, 5); + if(splitup.Length != 4) + throw new FormatException("doesn't have exactly 3 commas"); + + double x = double.Parse(splitup[0], CultureInfo.InvariantCulture); + double y = double.Parse(splitup[1], CultureInfo.InvariantCulture); + double z = double.Parse(splitup[2], CultureInfo.InvariantCulture); + double w = double.Parse(splitup[3], CultureInfo.InvariantCulture); + return new LSL_Rotation(x, y, z, w); + } + + public LSL_Vector xmrString2Vector(string s) + { + s = s.Trim(); + if(!s.StartsWith("<") || !s.EndsWith(">")) + throw new FormatException("doesn't begin with < and end with >"); + + s = s.Substring(1, s.Length - 2); + string[] splitup = s.Split(justacomma, 4); + if(splitup.Length != 3) + throw new FormatException("doesn't have exactly 2 commas"); + + double x = double.Parse(splitup[0], CultureInfo.InvariantCulture); + double y = double.Parse(splitup[1], CultureInfo.InvariantCulture); + double z = double.Parse(splitup[2], CultureInfo.InvariantCulture); + return new LSL_Vector(x, y, z); + } + + /** + * @brief Access C#-style formatted numeric conversions. + */ + public string xmrFloat2String(double val, string fmt) + { + return val.ToString(fmt, CultureInfo.InvariantCulture); + } + + public string xmrInteger2String(int val, string fmt) + { + return val.ToString(fmt, CultureInfo.InvariantCulture); + } + + public string xmrRotation2String(LSL_Rotation val, string fmt) + { + return "<" + val.x.ToString(fmt, CultureInfo.InvariantCulture) + "," + + val.y.ToString(fmt, CultureInfo.InvariantCulture) + "," + + val.z.ToString(fmt, CultureInfo.InvariantCulture) + "," + + val.s.ToString(fmt, CultureInfo.InvariantCulture) + ">"; + } + + public string xmrVector2String(LSL_Vector val, string fmt) + { + return "<" + val.x.ToString(fmt, CultureInfo.InvariantCulture) + "," + + val.y.ToString(fmt, CultureInfo.InvariantCulture) + "," + + val.z.ToString(fmt, CultureInfo.InvariantCulture) + ">"; + } + + /** + * @brief Get a delegate for a script-defined function. + * @param name = name of the function including arg types, eg, + * "Verify(array,list,string)" + * @param sig = script-defined type name + * @param targ = function's 'this' pointer or null if static + * @returns delegate for the script-defined function + */ + public Delegate GetScriptMethodDelegate(string name, string sig, object targ) + { + DynamicMethod dm = m_ObjCode.dynamicMethods[name]; + TokenDeclSDTypeDelegate dt = (TokenDeclSDTypeDelegate)m_ObjCode.sdObjTypesName[sig]; + return dm.CreateDelegate(dt.GetSysType(), targ); + } + + /** + * @brief Try to cast the thrown object to the given script-defined type. + * @param thrown = what object was thrown + * @param inst = what script instance we are running in + * @param sdtypeindex = script-defined type to try to cast it to + * @returns null: thrown is not castable to sdtypename + * else: an object casted to sdtypename + */ + public static object XMRSDTypeCatchTryCastToSDType(object thrown, XMRInstAbstract inst, int sdtypeindex) + { + TokenDeclSDType sdType = inst.m_ObjCode.sdObjTypesIndx[sdtypeindex]; + + // If it is a script-defined interface object, convert to the original XMRSDTypeClObj. + if(thrown is Delegate[]) + { + thrown = ((Delegate[])thrown)[0].Target; + } + + // If it is a script-defined delegate object, make sure it is an instance of the expected type. + if(thrown is Delegate) + { + Type ot = thrown.GetType(); + Type tt = sdType.GetSysType(); + return (ot == tt) ? thrown : null; + } + + // If it is a script-defined class object, make sure it is an instance of the expected class. + if(thrown is XMRSDTypeClObj) + { + // Step from the object's actual class rootward. + // If we find the requested class along the way, the cast is valid. + // If we run off the end of the root, the cast is not valid. + for(TokenDeclSDTypeClass ac = ((XMRSDTypeClObj)thrown).sdtcClass; ac != null; ac = ac.extends) + { + if(ac == sdType) + return thrown; + } + } + + // Don't know what it is, assume it is not what caller wants. + return null; + } + + /** + * @brief Allocate and access fixed-dimension arrays. + */ + public static object xmrFixedArrayAllocC(int len) + { + return new char[len]; + } + public static object xmrFixedArrayAllocF(int len) + { + return new double[len]; + } + public static object xmrFixedArrayAllocI(int len) + { + return new int[len]; + } + public static object xmrFixedArrayAllocO(int len) + { + return new object[len]; + } + + public static char xmrFixedArrayGetC(object arr, int idx) + { + return ((char[])arr)[idx]; + } + public static double xmrFixedArrayGetF(object arr, int idx) + { + return ((double[])arr)[idx]; + } + public static int xmrFixedArrayGetI(object arr, int idx) + { + return ((int[])arr)[idx]; + } + public static object xmrFixedArrayGetO(object arr, int idx) + { + return ((object[])arr)[idx]; + } + + public static void xmrFixedArraySetC(object arr, int idx, char val) + { + ((char[])arr)[idx] = val; + } + public static void xmrFixedArraySetF(object arr, int idx, double val) + { + ((double[])arr)[idx] = val; + } + public static void xmrFixedArraySetI(object arr, int idx, int val) + { + ((int[])arr)[idx] = val; + } + public static void xmrFixedArraySetO(object arr, int idx, object val) + { + ((object[])arr)[idx] = val; + } + + /** + * @brief Copy from one script-defined array to another. + * @param srcobj = source script-defined array class object pointer + * @param srcstart = offset in source array to start copying from + * @param dstobj = destination script-defined array class object pointer + * @param dststart = offset in destination arry to start copying to + * @param count = number of elements to copy + */ + public static void xmrArrayCopy(object srcobj, int srcstart, object dstobj, int dststart, int count) + { + // The script writer should only pass us script-defined class objects. + // Throw exception otherwise. + XMRSDTypeClObj srcsdt = (XMRSDTypeClObj)srcobj; + XMRSDTypeClObj dstsdt = (XMRSDTypeClObj)dstobj; + + // Get the script-visible type name of the arrays, brackets and all. + string srctypename = srcsdt.sdtcClass.longName.val; + string dsttypename = dstsdt.sdtcClass.longName.val; + + // The part before the first '[' of each should match exactly, + // meaning the basic data type (eg, float, List) is the same. + // And there must be a '[' in each meaning that it is a script-defined array type. + int i = srctypename.IndexOf('['); + int j = dsttypename.IndexOf('['); + if((i < 0) || (j < 0)) + throw new InvalidCastException("non-array passed: " + srctypename + " and/or " + dsttypename); + if((i != j) || !srctypename.StartsWith(dsttypename.Substring(0, j))) + throw new ArrayTypeMismatchException(srctypename + " vs " + dsttypename); + + // The number of brackets must match exactly. + // This permits copying from something like a float[,][] to something like a float[][]. + // But you cannot copy from a float[][] to a float[] or wisa wersa. + // Counting either '[' or ']' would work equally well. + int srclen = srctypename.Length; + int dstlen = dsttypename.Length; + int srcjags = 0; + int dstjags = 0; + while(++i < srclen) + if(srctypename[i] == ']') + srcjags++; + while(++j < dstlen) + if(dsttypename[j] == ']') + dstjags++; + if(dstjags != srcjags) + throw new ArrayTypeMismatchException(srctypename + " vs " + dsttypename); + + // Perform the copy. + Array srcarray = (Array)srcsdt.instVars.iarObjects[0]; + Array dstarray = (Array)dstsdt.instVars.iarObjects[0]; + Array.Copy(srcarray, srcstart, dstarray, dststart, count); + } + + /** + * @brief Copy from an array to a list. + * @param srcar = the array to copy from + * @param start = where to start in the array + * @param count = number of elements + * @returns the list + */ + public static LSL_List xmrArray2List(object srcar, int start, int count) + { + // Get the script-visible type of the array. + // We only do arrays. + XMRSDTypeClObj array = (XMRSDTypeClObj)srcar; + TokenDeclSDTypeClass sdtClass = array.sdtcClass; + if(sdtClass.arrayOfRank == 0) + throw new InvalidCastException("only do arrays not " + sdtClass.longName.val); + + // Validate objects they want to put in the list. + // We can't allow anything funky that OpenSim runtime doesn't expect. + Array srcarray = (Array)array.instVars.iarObjects[0]; + object[] output = new object[count]; + for(int i = 0; i < count; i++) + { + object src = srcarray.GetValue(i + start); + if(src == null) + throw new NullReferenceException("null element " + i); + if(src is double) + { + output[i] = new LSL_Float((double)src); + continue; + } + if(src is int) + { + output[i] = new LSL_Integer((int)src); + continue; + } + if(src is LSL_Rotation) + { + output[i] = src; + continue; + } + if(src is LSL_Vector) + { + output[i] = src; + continue; + } + if(src is string) + { + output[i] = new LSL_String((string)src); + continue; + } + throw new InvalidCastException("invalid element " + i + " type " + src.GetType().Name); + } + + // Make a list out of that now immutable array. + return new LSL_List(output); + } + + /** + * @brief Copy from a list to an array. + * @param srclist = list to copy from + * @param srcstart = where to start in the list + * @param dstobj = array to copy to + * @param dststart = where to start in the array + * @param count = number of elements + */ + public static void xmrList2Array(LSL_List srclist, int srcstart, object dstobj, int dststart, int count) + { + // Get the script-visible type of the destination. + // We only do arrays. + XMRSDTypeClObj dstarray = (XMRSDTypeClObj)dstobj; + TokenDeclSDTypeClass sdtClass = dstarray.sdtcClass; + if(sdtClass.arrayOfType == null) + throw new InvalidCastException("only do arrays not " + sdtClass.longName.val); + + // Copy from the immutable array to the mutable array. + // Strip off any LSL wrappers as the script code doesn't expect any. + object[] srcarr = srclist.Data; + Array dstarr = (Array)dstarray.instVars.iarObjects[0]; + + for(int i = 0; i < count; i++) + { + object obj = srcarr[i + srcstart]; + if(obj is LSL_Float) + obj = ((LSL_Float)obj).value; + else if(obj is LSL_Integer) + obj = ((LSL_Integer)obj).value; + else if(obj is LSL_String) + obj = ((LSL_String)obj).m_string; + dstarr.SetValue(obj, i + dststart); + } + } + + /** + * @brief Copy from an array of characters to a string. + * @param srcar = the array to copy from + * @param start = where to start in the array + * @param count = number of elements + * @returns the string + */ + public static string xmrChars2String(object srcar, int start, int count) + { + // Make sure they gave us a script-defined array object. + XMRSDTypeClObj array = (XMRSDTypeClObj)srcar; + TokenDeclSDTypeClass sdtClass = array.sdtcClass; + if(sdtClass.arrayOfRank == 0) + throw new InvalidCastException("only do arrays not " + sdtClass.longName.val); + + // We get a type cast error from mono if they didn't give us a character array. + // But if it is ok, create a string from the requested characters. + char[] srcarray = (char[])array.instVars.iarObjects[0]; + return new string(srcarray, start, count); + } + + /** + * @brief Copy from a string to a character array. + * @param srcstr = string to copy from + * @param srcstart = where to start in the string + * @param dstobj = array to copy to + * @param dststart = where to start in the array + * @param count = number of elements + */ + public static void xmrString2Chars(string srcstr, int srcstart, object dstobj, int dststart, int count) + { + // Make sure they gave us a script-defined array object. + XMRSDTypeClObj dstarray = (XMRSDTypeClObj)dstobj; + TokenDeclSDTypeClass sdtClass = dstarray.sdtcClass; + if(sdtClass.arrayOfType == null) + throw new InvalidCastException("only do arrays not " + sdtClass.longName.val); + + // We get a type cast error from mono if they didn't give us a character array. + // But if it is ok, copy from the string to the character array. + char[] dstarr = (char[])dstarray.instVars.iarObjects[0]; + for(int i = 0; i < count; i++) + dstarr[i + dststart] = srcstr[i + srcstart]; + } + + /** + * @brief Implement osParseJSON() so we return an array to the script. + * No coherent example of its use in scripts on web found. + * see http://www.json.org/ for more details on JSON + */ + private static LSL_List nullList = new LSL_List(new object[0]); + public new XMR_Array osParseJSON(string json) + { + XMR_Array dict = new XMR_Array(this); + int idx = ParseJSON(dict, nullList, json, 0); + while(idx < json.Length) + { + if(json[idx] > ' ') + throw new Exception("left-over json " + json); + idx++; + } + return dict; + } + + private static int ParseJSON(XMR_Array dict, LSL_List keys, string json, int idx) + { + char c; + + while((c = json[idx++]) <= ' ') + { + } + switch(c) + { + + // '{' ':' [ ',' ':' ... ] '}' + case '{': + do + { + string key = ParseJSONString(json, ref idx); + while((c = json[idx++]) <= ' ') + { + } + if(c != ':') + throw new Exception("missing : after key"); + idx = ParseJSON(dict, ParseJSONKeyAdd(keys, key), json, idx); + while((c = json[idx++]) <= ' ') + { + } + } while(c == ','); + if(c != '}') + throw new Exception("missing , or } after value"); + break; + + + // '[' [ ',' ... ] ']' + case '[': + int index = 0; + do + { + object key = index++; + idx = ParseJSON(dict, ParseJSONKeyAdd(keys, key), json, idx); + while((c = json[idx++]) <= ' ') + { + } + } while(c == ','); + if(c != ']') + throw new Exception("missing , or ] after value"); + break; + + + // '"''"' + case '"': + { + --idx; + string val = ParseJSONString(json, ref idx); + dict.SetByKey(keys, val); + break; + } + // true false null + case 't': + if(json.Substring(idx, 3) != "rue") + throw new Exception("bad true in json"); + idx += 3; + dict.SetByKey(keys, 1); + break; + + case 'f': + if(json.Substring(idx, 4) != "alse") + throw new Exception("bad false in json"); + idx += 4; + dict.SetByKey(keys, 0); + break; + + case 'n': + if(json.Substring(idx, 3) != "ull") + throw new Exception("bad null in json"); + idx += 3; + dict.SetByKey(keys, null); + break; + + // otherwise assume it's a number + default: + { + --idx; + object val = ParseJSONNumber(json, ref idx); + dict.SetByKey(keys, val); + break; + } + } + return idx; + } + + // Given the key for a whole array, create a key for a given element of the array + private static LSL_List ParseJSONKeyAdd(LSL_List oldkeys, object key) + { + int oldkeyslen = oldkeys.Length; + object[] array = oldkeys.Data; + Array.Resize(ref array, oldkeyslen + 1); + array[oldkeyslen] = key; + return new LSL_List(array); + } + + // Parse out a JSON string + private static string ParseJSONString(string json, ref int idx) + { + char c; + + while((c = json[idx++]) <= ' ') + { + } + if(c != '"') + throw new Exception("bad start of json string"); + + StringBuilder sb = new StringBuilder(); + while((c = json[idx++]) != '"') + { + if(c == '\\') + { + c = json[idx++]; + switch(c) + { + case 'b': + c = '\b'; + break; + + case 'f': + c = '\f'; + break; + + case 'n': + c = '\n'; + break; + + case 'r': + c = '\r'; + break; + + case 't': + c = '\t'; + break; + + case 'u': + c = (char)Int32.Parse(json.Substring(idx, 4), + System.Globalization.NumberStyles.HexNumber); + idx += 4; + break; + + default: + break; + } + } + sb.Append(c); + } + return sb.ToString(); + } + + // Parse out a JSON number + private static object ParseJSONNumber(string json, ref int idx) + { + char c; + + while((c = json[idx++]) <= ' ') + { + } + + bool expneg = false; + bool isneg = false; + int decpt = -1; + int expon = 0; + int ival = 0; + double dval = 0; + + if(c == '-') + { + isneg = true; + c = json[idx++]; + } + if((c < '0') || (c > '9')) + throw new Exception("bad json number"); + + while((c >= '0') && (c <= '9')) + { + dval *= 10; + ival *= 10; + dval += c - '0'; + ival += c - '0'; + c = '\0'; + if(idx < json.Length) + c = json[idx++]; + } + if(c == '.') + { + decpt = 0; + c = '\0'; + if(idx < json.Length) + c = json[idx++]; + while((c >= '0') && (c <= '9')) + { + dval *= 10; + dval += c - '0'; + decpt++; + c = '\0'; + if(idx < json.Length) + c = json[idx++]; + } + } + if((c == 'e') || (c == 'E')) + { + if(decpt < 0) + decpt = 0; + c = json[idx++]; + if(c == '-') + expneg = true; + if((c == '-') || (c == '+')) + c = json[idx++]; + while((c >= '0') && (c <= '9')) + { + expon *= 10; + expon += c - '0'; + c = '\0'; + if(idx < json.Length) + c = json[idx++]; + } + if(expneg) + expon = -expon; + } + + if(c != 0) + --idx; + if(decpt < 0) + { + if(isneg) + ival = -ival; + return ival; + } + else + { + if(isneg) + dval = -dval; + dval *= Math.Pow(10, expon - decpt); + return dval; + } + } + + /** + * @brief Exception-related runtime calls. + */ + // Return exception message (no type information just the message) + public static string xmrExceptionMessage(Exception ex) + { + return ex.Message; + } + + // Return stack trace (no type or message, just stack trace lines: at ... \n) + public string xmrExceptionStackTrace(Exception ex) + { + return XMRExceptionStackString(ex); + } + + // Return value thrown by a throw statement + public static object xmrExceptionThrownValue(Exception ex) + { + return ((ScriptThrownException)ex).thrown; + } + + // Return exception's short type name, eg, NullReferenceException, ScriptThrownException, etc. + public static string xmrExceptionTypeName(Exception ex) + { + return ex.GetType().Name; + } + + // internal use only: converts any IL addresses in script-defined methods to source location equivalent + // Mono ex.StackTrace: + // at OpenSim.Region.ScriptEngine.YEngine.TypeCast.ObjectToInteger (System.Object x) [0x0005e] in /home/kunta/opensim-0.9/addon-modules/YEngine/Module/MMRScriptTypeCast.cs:750 + // at (wrapper dynamic-method) System.Object:default state_entry (OpenSim.Region.ScriptEngine.YEngine.XMRInstAbstract) [0x00196] + + // Microsoft ex.StackTrace: + // at OpenSim.Region.ScriptEngine.YEngine.TypeCast.ObjectToInteger(Object x) in C:\Users\mrieker\opensim-0.9-source\addon-modules\YEngine\Module\MMRScriptTypeCast.cs:line 750 + // at default state_entry (XMRInstAbstract ) + public string XMRExceptionStackString(Exception ex) + { + string stwhole = ex.StackTrace; + string[] stlines = stwhole.Split(new char[] { '\n' }); + StringBuilder sb = new StringBuilder(); + foreach(string st in stlines) + { + string stline = st.Trim(); + if(stline == "") + continue; + + // strip 'at' off the front of line + if(stline.StartsWith("at ")) + { + stline = stline.Substring(3); + } + + // strip '(wrapper ...' off front of line + if(stline.StartsWith("(wrapper dynamic-method) System.Object:")) + { + stline = stline.Substring(39); + } + + // strip the (systemargtypes...) from our dynamic method names cuz it's messy + // 'default state_entry (XMRInstAbstract )' + // => 'default state_entry' + // 'CallSomethingThatThrows(string) (OpenSim.Region.ScriptEngine.YEngine.XMRInstance,string)' + // => 'CallSomethingThatThrows(string)' + int kwin = stline.IndexOf(" in "); + int br0x = stline.IndexOf(" [0x"); + int pastCloseParen = stline.Length; + if((kwin >= 0) && (br0x >= 0)) + pastCloseParen = Math.Min(kwin, br0x); + else if(kwin >= 0) + pastCloseParen = kwin; + else if(br0x >= 0) + pastCloseParen = br0x; + else + pastCloseParen = stline.Length; + int endFuncName = pastCloseParen; + while(endFuncName > 0) + { + if(stline[--endFuncName] == '(') + break; + } + while(endFuncName > 0) + { + if(stline[endFuncName - 1] != ' ') + break; + --endFuncName; + } + string funcName = stline.Substring(0, endFuncName); + KeyValuePair[] srcLocs; + if(m_ObjCode.scriptSrcLocss.TryGetValue(funcName, out srcLocs)) + { + stline = stline.Substring(0, endFuncName) + stline.Substring(pastCloseParen); + kwin = stline.IndexOf(" in "); + br0x = stline.IndexOf(" [0x"); + } + + // keyword 'in' is just before filename:linenumber that goes to end of line + // trim up the corresponding filename (ie, remove useless path info) + if(kwin >= 0) + { + int begfn = kwin + 4; + int slash = begfn; + for(int i = begfn; i < stline.Length; i++) + { + char c = stline[i]; + if((c == '/') || (c == '\\')) + slash = i + 1; + } + stline = stline.Substring(0, begfn) + stline.Substring(slash); + } + else if(srcLocs != null) + { + + // no filename:linenumber info, try to convert IL offset + if(br0x >= 0) + { + try + { + int begiloffs = br0x + 4; + int endiloffs = stline.IndexOf("]", begiloffs); + int iloffset = int.Parse(stline.Substring(begiloffs, endiloffs - begiloffs), + System.Globalization.NumberStyles.HexNumber); + + int srcLocIdx; + int srcLocLen = srcLocs.Length; + for(srcLocIdx = 0; ++srcLocIdx < srcLocLen;) + { + if(iloffset < srcLocs[srcLocIdx].Key) + break; + } + ScriptSrcLoc srcLoc = srcLocs[--srcLocIdx].Value; + + stline = stline.Substring(0, br0x) + " <" + + srcLoc.file + '(' + srcLoc.line + ',' + srcLoc.posn + ")>"; + } + catch + { + } + } + } + + // put edited line in output string + if(sb.Length > 0) + sb.AppendLine(); + sb.Append(" at "); + sb.Append(stline); + } + return sb.ToString(); + } + + /** + * @brief List fonts available. + */ + public LSL_List xmrFontsAvailable() + { + System.Drawing.FontFamily[] families = System.Drawing.FontFamily.Families; + object[] output = new object[families.Length]; + for(int i = 0; i < families.Length; i++) + output[i] = new LSL_String(families[i].Name); + + return new LSL_List(output); + } + + /************************\ + * Used by decompiler * + \************************/ + + public bool xmrRotationToBool(LSL_Rotation x) + { + return TypeCast.RotationToBool(x); + } + public bool xmrStringToBool(string x) + { + return TypeCast.StringToBool(x); + } + public bool xmrVectorToBool(LSL_Vector x) + { + return TypeCast.VectorToBool(x); + } + public bool xmrKeyToBool(string x) + { + return TypeCast.KeyToBool(x); + } + public bool xmrListToBool(LSL_List x) + { + return TypeCast.ListToBool(x); + } + + public int xmrStringCompare(string x, string y) + { + return string.Compare(x, y); + } + + /** + * @brief types of data we serialize + */ + private enum Ser: byte + { + NULL, + EVENTCODE, + LSLFLOAT, + LSLINT, + LSLKEY, + LSLLIST, + LSLROT, + LSLSTR, + LSLVEC, + SYSARRAY, + SYSDOUB, + SYSFLOAT, + SYSINT, + SYSSTR, + XMRARRAY, + DUPREF, + SYSBOOL, + XMRINST, + DELEGATE, + SDTCLOBJ, + SYSCHAR, + SYSERIAL, + THROWNEX + } + + /** + * @brief Write state out to a stream. + * Do not change script state. + */ + public void MigrateOut(BinaryWriter mow) + { + try + { + this.migrateOutWriter = mow; + this.migrateOutObjects = new Dictionary(); + this.migrateOutLists = new Dictionary(); + this.SendObjValue(this.ehArgs); + mow.Write(this.doGblInit); + mow.Write(this.stateCode); + mow.Write((int)this.eventCode); + this.glblVars.SendArrays(this.SendObjValue); + if(this.newStateCode >= 0) + { + mow.Write("**newStateCode**"); + mow.Write(this.newStateCode); + } + for(XMRStackFrame thisSF = this.stackFrames; thisSF != null; thisSF = thisSF.nextSF) + { + mow.Write(thisSF.funcName); + mow.Write(thisSF.callNo); + this.SendObjValue(thisSF.objArray); + } + mow.Write(""); + } + finally + { + this.migrateOutWriter = null; + this.migrateOutObjects = null; + this.migrateOutLists = null; + } + } + + /** + * @brief Write an object to the output stream. + * @param graph = object to send + */ + private BinaryWriter migrateOutWriter; + private Dictionary migrateOutObjects; + private Dictionary migrateOutLists; + public void SendObjValue(object graph) + { + BinaryWriter mow = this.migrateOutWriter; + + // Value types (including nulls) are always output directly. + if(graph == null) + { + mow.Write((byte)Ser.NULL); + return; + } + if(graph is ScriptEventCode) + { + mow.Write((byte)Ser.EVENTCODE); + mow.Write((int)graph); + return; + } + if(graph is LSL_Float) + { + mow.Write((byte)Ser.LSLFLOAT); + mow.Write((double)((LSL_Float)graph).value); + return; + } + if(graph is LSL_Integer) + { + mow.Write((byte)Ser.LSLINT); + mow.Write((int)((LSL_Integer)graph).value); + return; + } + if(graph is LSL_Key) + { + mow.Write((byte)Ser.LSLKEY); + LSL_Key key = (LSL_Key)graph; + SendObjValue(key.m_string); // m_string can be null + return; + } + if(graph is LSL_Rotation) + { + mow.Write((byte)Ser.LSLROT); + mow.Write((double)((LSL_Rotation)graph).x); + mow.Write((double)((LSL_Rotation)graph).y); + mow.Write((double)((LSL_Rotation)graph).z); + mow.Write((double)((LSL_Rotation)graph).s); + return; + } + if(graph is LSL_String) + { + mow.Write((byte)Ser.LSLSTR); + LSL_String str = (LSL_String)graph; + SendObjValue(str.m_string); // m_string can be null + return; + } + if(graph is LSL_Vector) + { + mow.Write((byte)Ser.LSLVEC); + mow.Write((double)((LSL_Vector)graph).x); + mow.Write((double)((LSL_Vector)graph).y); + mow.Write((double)((LSL_Vector)graph).z); + return; + } + if(graph is bool) + { + mow.Write((byte)Ser.SYSBOOL); + mow.Write((bool)graph); + return; + } + if(graph is double) + { + mow.Write((byte)Ser.SYSDOUB); + mow.Write((double)graph); + return; + } + if(graph is float) + { + mow.Write((byte)Ser.SYSFLOAT); + mow.Write((float)graph); + return; + } + if(graph is int) + { + mow.Write((byte)Ser.SYSINT); + mow.Write((int)graph); + return; + } + if(graph is char) + { + mow.Write((byte)Ser.SYSCHAR); + mow.Write((char)graph); + return; + } + + // Script instance pointer is always just that. + if(graph == this) + { + mow.Write((byte)Ser.XMRINST); + return; + } + + // Convert lists to object type. + // This is compatible with old migration data and also + // two vars pointing to same list won't duplicate it. + if(graph is LSL_List) + { + object[] data = ((LSL_List)graph).Data; + ObjLslList oll; + if(!this.migrateOutLists.TryGetValue(data, out oll)) + { + oll = new ObjLslList(); + oll.objarray = data; + this.migrateOutLists[data] = oll; + } + graph = oll; + } + + // If this same exact object was already serialized, + // just output an index telling the receiver to use + // that same old object, rather than creating a whole + // new object with the same values. Also this prevents + // self-referencing objects (like arrays) from causing + // an infinite loop. + int ident; + if(this.migrateOutObjects.TryGetValue(graph, out ident)) + { + mow.Write((byte)Ser.DUPREF); + mow.Write(ident); + return; + } + + // Object not seen before, save its address with an unique + // ident number that the receiver can easily regenerate. + ident = this.migrateOutObjects.Count; + this.migrateOutObjects.Add(graph, ident); + + // Now output the object's value(s). + // If the object self-references, the object is alreay entered + // in the dictionary and so the self-reference will just emit + // a DUPREF tag instead of trying to output the whole object + // again. + if(graph is ObjLslList) + { + mow.Write((byte)Ser.LSLLIST); + ObjLslList oll = (ObjLslList)graph; + SendObjValue(oll.objarray); + } + else if(graph is XMR_Array) + { + mow.Write((byte)Ser.XMRARRAY); + ((XMR_Array)graph).SendArrayObj(this.SendObjValue); + } + else if(graph is Array) + { + Array array = (Array)graph; + mow.Write((byte)Ser.SYSARRAY); + mow.Write(SysType2String(array.GetType().GetElementType())); + mow.Write((int)array.Length); + for(int i = 0; i < array.Length; i++) + this.SendObjValue(array.GetValue(i)); + } + else if(graph is string) + { + mow.Write((byte)Ser.SYSSTR); + mow.Write((string)graph); + } + else if(graph is Delegate) + { + Delegate del = (Delegate)graph; + mow.Write((byte)Ser.DELEGATE); + mow.Write(del.Method.Name); + Type delType = del.GetType(); + foreach(KeyValuePair kvp in m_ObjCode.sdObjTypesName) + { + TokenDeclSDType sdt = kvp.Value; + if(sdt is TokenDeclSDTypeDelegate) + { + TokenDeclSDTypeDelegate sdtd = (TokenDeclSDTypeDelegate)sdt; + if(sdtd.GetSysType() == delType) + { + mow.Write(kvp.Key); + goto found; + } + } + } + throw new Exception("cant find script-defined delegate for " + del.Method.Name + " type " + del.GetType()); + found: + SendObjValue(del.Target); + } + else if(graph is XMRSDTypeClObj) + { + mow.Write((byte)Ser.SDTCLOBJ); + ((XMRSDTypeClObj)graph).Capture(this.SendObjValue); + } + else if(graph is ScriptThrownException) + { + MemoryStream memoryStream = new MemoryStream(); + System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bformatter = + new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(); + bformatter.Serialize(memoryStream, graph); + byte[] rawBytes = memoryStream.ToArray(); + mow.Write((byte)Ser.THROWNEX); + mow.Write((int)rawBytes.Length); + mow.Write(rawBytes); + SendObjValue(((ScriptThrownException)graph).thrown); + } + else + { + MemoryStream memoryStream = new MemoryStream(); + System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bformatter = + new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(); + bformatter.Serialize(memoryStream, graph); + byte[] rawBytes = memoryStream.ToArray(); + mow.Write((byte)Ser.SYSERIAL); + mow.Write((int)rawBytes.Length); + mow.Write(rawBytes); + } + } + + /** + * @brief Use short strings for known type names. + */ + private static string SysType2String(Type type) + { + if(type.IsArray && (type.GetArrayRank() == 1)) + { + string str = KnownSysType2String(type.GetElementType()); + if(str != null) + return str + "[]"; + } + else + { + string str = KnownSysType2String(type); + if(str != null) + return str; + } + return type.ToString(); + } + private static string KnownSysType2String(Type type) + { + if(type == typeof(bool)) + return "bo"; + if(type == typeof(char)) + return "ch"; + if(type == typeof(Delegate)) + return "de"; + if(type == typeof(double)) + return "do"; + if(type == typeof(float)) + return "fl"; + if(type == typeof(int)) + return "in"; + if(type == typeof(LSL_List)) + return "li"; + if(type == typeof(object)) + return "ob"; + if(type == typeof(LSL_Rotation)) + return "ro"; + if(type == typeof(XMRSDTypeClObj)) + return "sc"; + if(type == typeof(string)) + return "st"; + if(type == typeof(LSL_Vector)) + return "ve"; + if(type == typeof(XMR_Array)) + return "xa"; + return null; + } + private static Type String2SysType(string str) + { + if(str.EndsWith("[]")) + return String2SysType(str.Substring(0, str.Length - 2)).MakeArrayType(); + + if(str == "bo") + return typeof(bool); + if(str == "ch") + return typeof(char); + if(str == "de") + return typeof(Delegate); + if(str == "do") + return typeof(double); + if(str == "fl") + return typeof(float); + if(str == "in") + return typeof(int); + if(str == "li") + return typeof(LSL_List); + if(str == "ob") + return typeof(object); + if(str == "ro") + return typeof(LSL_Rotation); + if(str == "sc") + return typeof(XMRSDTypeClObj); + if(str == "st") + return typeof(string); + if(str == "ve") + return typeof(LSL_Vector); + if(str == "xa") + return typeof(XMR_Array); + return Type.GetType(str, true); + } + + /** + * @brief Read state in from a stream. + */ + public void MigrateIn(BinaryReader mir) + { + try + { + this.migrateInReader = mir; + this.migrateInObjects = new Dictionary(); + this.ehArgs = (object[])this.RecvObjValue(); + this.doGblInit = mir.ReadBoolean(); + this.stateCode = mir.ReadInt32(); + this.eventCode = (ScriptEventCode)mir.ReadInt32(); + this.newStateCode = -1; + this.glblVars.RecvArrays(this.RecvObjValue); + XMRStackFrame lastSF = null; + string funcName; + while((funcName = mir.ReadString()) != "") + { + if(funcName == "**newStateCode**") + { + this.newStateCode = mir.ReadInt32(); + continue; + } + XMRStackFrame thisSF = new XMRStackFrame(); + thisSF.funcName = funcName; + thisSF.callNo = mir.ReadInt32(); + thisSF.objArray = (object[])this.RecvObjValue(); + if(lastSF == null) + this.stackFrames = thisSF; + else + lastSF.nextSF = thisSF; + lastSF = thisSF; + } + } + finally + { + this.migrateInReader = null; + this.migrateInObjects = null; + } + } + + /** + * @brief Read a single value from the stream. + * @returns value (boxed as needed) + */ + private BinaryReader migrateInReader; + private Dictionary migrateInObjects; + public object RecvObjValue() + { + BinaryReader mir = this.migrateInReader; + int ident = this.migrateInObjects.Count; + Ser code = (Ser)mir.ReadByte(); + switch(code) + { + case Ser.NULL: + return null; + + case Ser.EVENTCODE: + return (ScriptEventCode)mir.ReadInt32(); + + case Ser.LSLFLOAT: + return new LSL_Float(mir.ReadDouble()); + + case Ser.LSLINT: + return new LSL_Integer(mir.ReadInt32()); + + case Ser.LSLKEY: + return new LSL_Key((string)RecvObjValue()); + + case Ser.LSLLIST: + { + this.migrateInObjects.Add(ident, null); // placeholder + object[] data = (object[])RecvObjValue(); // read data, maybe using another index + LSL_List list = new LSL_List(data); // make LSL-level list + this.migrateInObjects[ident] = list; // fill in slot + return list; + } + + case Ser.LSLROT: + { + double x = mir.ReadDouble(); + double y = mir.ReadDouble(); + double z = mir.ReadDouble(); + double w = mir.ReadDouble(); + return new LSL_Rotation(x, y, z, w); + } + case Ser.LSLSTR: + return new LSL_String((string)RecvObjValue()); + + case Ser.LSLVEC: + { + double x = mir.ReadDouble(); + double y = mir.ReadDouble(); + double z = mir.ReadDouble(); + return new LSL_Vector(x, y, z); + } + + case Ser.SYSARRAY: + { + Type eletype = String2SysType(mir.ReadString()); + int length = mir.ReadInt32(); + Array array = Array.CreateInstance(eletype, length); + this.migrateInObjects.Add(ident, array); + for(int i = 0; i < length; i++) + array.SetValue(RecvObjValue(), i); + return array; + } + + case Ser.SYSBOOL: + return mir.ReadBoolean(); + + case Ser.SYSDOUB: + return mir.ReadDouble(); + + case Ser.SYSFLOAT: + return mir.ReadSingle(); + + case Ser.SYSINT: + return mir.ReadInt32(); + + case Ser.SYSCHAR: + return mir.ReadChar(); + + case Ser.SYSSTR: + string s = mir.ReadString(); + this.migrateInObjects.Add(ident, s); + return s; + + case Ser.XMRARRAY: + { + XMR_Array array = new XMR_Array(this); + this.migrateInObjects.Add(ident, array); + array.RecvArrayObj(this.RecvObjValue); + return array; + } + + case Ser.DUPREF: + { + ident = mir.ReadInt32(); + object obj = this.migrateInObjects[ident]; + if(obj is ObjLslList) + obj = new LSL_List(((ObjLslList)obj).objarray); + return obj; + } + + case Ser.XMRINST: + return this; + + case Ser.DELEGATE: + this.migrateInObjects.Add(ident, null); // placeholder + string name = mir.ReadString(); // function name + string sig = mir.ReadString(); // delegate type + object targ = this.RecvObjValue(); // 'this' object + Delegate del = this.GetScriptMethodDelegate(name, sig, targ); + this.migrateInObjects[ident] = del; // actual value + return del; + + case Ser.SDTCLOBJ: + XMRSDTypeClObj clobj = new XMRSDTypeClObj(); + this.migrateInObjects.Add(ident, clobj); + clobj.Restore(this, this.RecvObjValue); + return clobj; + + case Ser.SYSERIAL: + { + int rawLength = mir.ReadInt32(); + byte[] rawBytes = mir.ReadBytes(rawLength); + MemoryStream memoryStream = new MemoryStream(rawBytes); + System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bformatter = + new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(); + object graph = bformatter.Deserialize(memoryStream); + this.migrateInObjects.Add(ident, graph); + return graph; + } + + case Ser.THROWNEX: + { + int rawLength = mir.ReadInt32(); + byte[] rawBytes = mir.ReadBytes(rawLength); + MemoryStream memoryStream = new MemoryStream(rawBytes); + System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bformatter = + new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(); + object graph = bformatter.Deserialize(memoryStream); + this.migrateInObjects.Add(ident, graph); + ((ScriptThrownException)graph).thrown = RecvObjValue(); + return graph; + } + + default: + throw new Exception("bad stream code " + code.ToString()); + } + } + + // wrapper around list object arrays to make sure they are always object types for migration purposes + private class ObjLslList + { + public object[] objarray; + } + } + + // Any xmr...() methods that call CheckRun() must be tagged with this attribute + // so the ScriptCodeGen will know the method is non-trivial. + public class xmrMethodCallsCheckRunAttribute: Attribute + { + } + + // Any xmr...() methods in xmrengtest that call Stub() must be + // tagged with this attribute so the -builtins option will tell the user that + // they are a stub function. + public class xmrMethodIsNoisyAttribute: Attribute + { + } + + // Any script callable methods that really return a key not a string should be + // tagged with this attribute so the compiler will know they return type key and + // not type string. + public class xmrMethodReturnsKeyAttribute: Attribute + { + } + + [SerializableAttribute] + public class OutOfHeapException: Exception + { + public OutOfHeapException(int oldtotal, int newtotal, int limit) + : base("oldtotal=" + oldtotal + ", newtotal=" + newtotal + ", limit=" + limit) + { + } + } + + [SerializableAttribute] + public class OutOfStackException: Exception + { + } +} diff --git a/OpenSim/Region/ScriptEngine/YEngine/XMRInstBackend.cs b/OpenSim/Region/ScriptEngine/YEngine/XMRInstBackend.cs new file mode 100644 index 0000000000..b6f88748bb --- /dev/null +++ b/OpenSim/Region/ScriptEngine/YEngine/XMRInstBackend.cs @@ -0,0 +1,623 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Threading; +using System.Collections.Generic; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Region.ScriptEngine.Shared; +using OpenSim.Region.ScriptEngine.Shared.Api; +using log4net; + +using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; +using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; +using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; +using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list; +using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; +using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; +using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; + +namespace OpenSim.Region.ScriptEngine.Yengine +{ + /****************************************************\ + * This file contains routines called by scripts. * + \****************************************************/ + + public class XMRLSL_Api: LSL_Api + { + public AsyncCommandManager acm; + private XMRInstance inst; + + public void InitXMRLSLApi(XMRInstance i) + { + acm = AsyncCommands; + inst = i; + } + + protected override void ScriptSleep(int ms) + { + ms = (int)(ms * m_ScriptDelayFactor); + if (ms < 10) + return; + + inst.Sleep(ms); + } + + public override void llSleep(double sec) + { + inst.Sleep((int)(sec * 1000.0)); + } + + public override void llDie() + { + inst.Die(); + } + + /** + * @brief Seat avatar on prim. + * @param owner = true: owner of prim script is running in + * false: avatar that has given ANIMATION permission on the prim + * @returns 0: successful + * -1: no permission to animate + * -2: no av granted perms + * -3: av not in region + */ + /* engines should not have own API + public int xmrSeatAvatar (bool owner) + { + // Get avatar to be seated and make sure they have given us ANIMATION permission + + UUID avuuid; + if (owner) { + avuuid = inst.m_Part.OwnerID; + } else { + if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION) == 0) { + return -1; + } + avuuid = m_item.PermsGranter; + } + if (avuuid == UUID.Zero) { + return -2; + } + + ScenePresence presence = World.GetScenePresence (avuuid); + if (presence == null) { + return -3; + } + + // remoteClient = not used by ScenePresence.HandleAgentRequestSit() + // agentID = not used by ScenePresence.HandleAgentRequestSit() + // targetID = UUID of prim to sit on + // offset = offset of sitting position + + presence.HandleAgentRequestSit (null, UUID.Zero, m_host.UUID, OpenMetaverse.Vector3.Zero); + return 0; + } + */ + /** + * @brief llTeleportAgent() is broken in that if you pass it a landmark, + * it still subjects the position to spawn points, as it always + * calls RequestTeleportLocation() with TeleportFlags.ViaLocation. + * See llTeleportAgent() and CheckAndAdjustTelehub(). + * + * @param agent = what agent to teleport + * @param landmark = inventory name or UUID of a landmark object + * @param lookat = looking direction after teleport + */ + /* engines should not have own API + public void xmrTeleportAgent2Landmark (string agent, string landmark, LSL_Vector lookat) + { + // find out about agent to be teleported + UUID agentId; + if (!UUID.TryParse (agent, out agentId)) throw new ApplicationException ("bad agent uuid"); + + ScenePresence presence = World.GetScenePresence (agentId); + if (presence == null) throw new ApplicationException ("agent not present in scene"); + if (presence.IsNPC) throw new ApplicationException ("agent is an NPC"); + if (presence.IsGod) throw new ApplicationException ("agent is a god"); + + // prim must be owned by land owner or prim must be attached to agent + if (m_host.ParentGroup.AttachmentPoint == 0) { + if (m_host.OwnerID != World.LandChannel.GetLandObject (presence.AbsolutePosition).LandData.OwnerID) { + throw new ApplicationException ("prim not owned by land's owner"); + } + } else { + if (m_host.OwnerID != presence.UUID) throw new ApplicationException ("prim not attached to agent"); + } + + // find landmark in inventory or by UUID + UUID assetID = ScriptUtils.GetAssetIdFromKeyOrItemName (m_host, landmark); + if (assetID == UUID.Zero) throw new ApplicationException ("no such landmark"); + + // read it in and make sure it is a landmark + AssetBase lma = World.AssetService.Get (assetID.ToString ()); + if ((lma == null) || (lma.Type != (sbyte)AssetType.Landmark)) throw new ApplicationException ("not a landmark"); + + // parse the record + AssetLandmark lm = new AssetLandmark (lma); + + // the regionhandle (based on region's world X,Y) might be out of date + // re-read the handle so we can pass it to RequestTeleportLocation() + var region = World.GridService.GetRegionByUUID (World.RegionInfo.ScopeID, lm.RegionID); + if (region == null) throw new ApplicationException ("no such region"); + + // finally ready to teleport + World.RequestTeleportLocation (presence.ControllingClient, + region.RegionHandle, + lm.Position, + lookat, + (uint)TeleportFlags.ViaLandmark); + } + */ + /** + * @brief Allow any member of group given by config SetParcelMusicURLGroup to set music URL. + * Code modelled after llSetParcelMusicURL(). + * @param newurl = new URL to set (or "" to leave it alone) + * @returns previous URL string + */ + /* engines should not have own API + public string xmrSetParcelMusicURLGroup (string newurl) + { + string groupname = m_ScriptEngine.Config.GetString ("SetParcelMusicURLGroup", ""); + if (groupname == "") throw new ApplicationException ("no SetParcelMusicURLGroup config param set"); + + IGroupsModule igm = World.RequestModuleInterface (); + if (igm == null) throw new ApplicationException ("no GroupsModule loaded"); + + GroupRecord grouprec = igm.GetGroupRecord (groupname); + if (grouprec == null) throw new ApplicationException ("no such group " + groupname); + + GroupMembershipData gmd = igm.GetMembershipData (grouprec.GroupID, m_host.OwnerID); + if (gmd == null) throw new ApplicationException ("not a member of group " + groupname); + + ILandObject land = World.LandChannel.GetLandObject (m_host.AbsolutePosition); + if (land == null) throw new ApplicationException ("no land at " + m_host.AbsolutePosition.ToString ()); + string oldurl = land.GetMusicUrl (); + if (oldurl == null) oldurl = ""; + if ((newurl != null) && (newurl != "")) land.SetMusicUrl (newurl); + return oldurl; + } + */ + } + + public partial class XMRInstance + { + /** + * @brief The script is calling llReset(). + * We throw an exception to unwind the script out to its main + * causing all the finally's to execute and it will also set + * eventCode = None to indicate event handler has completed. + */ + public void ApiReset() + { + ClearQueueExceptLinkMessages(); + throw new ScriptResetException(); + } + + /** + * @brief The script is calling one of the llDetected...(int number) + * functions. Return corresponding DetectParams pointer. + */ + public DetectParams GetDetectParams(int number) + { + DetectParams dp = null; + if((number >= 0) && (m_DetectParams != null) && (number < m_DetectParams.Length)) + dp = m_DetectParams[number]; + + return dp; + } + + /** + * @brief Script is calling llDie, so flag the run loop to delete script + * once we are off the microthread stack, and throw an exception + * to unwind the stack asap. + */ + public void Die() + { + // llDie doesn't work in attachments! + if(m_Part.ParentGroup.IsAttachment || m_DetachQuantum > 0) + return; + + throw new ScriptDieException(); + } + + /** + * @brief Called by script to sleep for the given number of milliseconds. + */ + public void Sleep(int ms) + { + lock(m_QueueLock) + { + // Say how long to sleep. + m_SleepUntil = DateTime.UtcNow + TimeSpan.FromMilliseconds(ms); + + // Don't wake on any events. + m_SleepEventMask1 = 0; + m_SleepEventMask2 = 0; + } + + // The compiler follows all calls to llSleep() with a call to CheckRun(). + // So tell CheckRun() to suspend the microthread. + suspendOnCheckRunTemp = true; + } + + /** + * Block script execution until an event is queued or a timeout is reached. + * @param timeout = maximum number of seconds to wait + * @param returnMask = if event is queued that matches these mask bits, + * the script is woken, that event is dequeued and + * returned to the caller. The event handler is not + * executed. + * @param backgroundMask = if any of these events are queued while waiting, + * execute their event handlers. When any such event + * handler exits, continue waiting for events or the + * timeout. + * @returns empty list: no event was queued that matched returnMask and the timeout was reached + * or a background event handler changed state (eg, via 'state' statement) + * else: list giving parameters of the event: + * [0] = event code (integer) + * [1..n] = call parameters to the event, if any + * Notes: + * 1) Scrips should use XMREVENTMASKn_ symbols for the mask arguments, + * where n is 1 or 2 for mask1 or mask2 arguments. + * The list[0] return argument can be decoded by using XMREVENTCODE_ symbols. + * 2) If all masks are zero, the call ends up acting like llSleep. + * 3) If an event is enabled in both returnMask and backgroundMask, the returnMask bit + * action takes precedence, ie, the event is returned. This allows a simple specification + * of -1 for both backgroundMask arguments to indicate that all events not listed in + * the returnMask argumetns should be handled in the background. + * 4) Any events not listed in either returnMask or backgroundMask arguments will be + * queued for later processing (subject to normal queue limits). + * 5) Background event handlers execute as calls from within xmrEventDequeue, they do + * not execute as separate threads. Thus any background event handlers must return + * before the call to xmrEventDequeue will return. + * 6) If a background event handler changes state (eg, via 'state' statement), the state + * is immediately changed and the script-level xmrEventDequeue call does not return. + * 7) For returned events, the detect parameters are overwritten by the returned event. + * For background events, the detect parameters are saved and restored. + * 8) Scripts must contain dummy event handler definitions for any event types that may + * be returned by xmrEventDequeue, to let the runtime know that the script is capable + * of processing that event type. Otherwise, the event may not be queued to the script. + */ + private static LSL_List emptyList = new LSL_List(new object[0]); + + public override LSL_List xmrEventDequeue(double timeout, int returnMask1, int returnMask2, + int backgroundMask1, int backgroundMask2) + { + DateTime sleepUntil = DateTime.UtcNow + TimeSpan.FromMilliseconds(timeout * 1000.0); + EventParams evt = null; + int callNo, evc2; + int evc1 = 0; + int mask1 = returnMask1 | backgroundMask1; // codes 00..31 + int mask2 = returnMask2 | backgroundMask2; // codes 32..63 + LinkedListNode lln = null; + object[] sv; + ScriptEventCode evc = ScriptEventCode.None; + + callNo = -1; + try + { + if(callMode == CallMode_NORMAL) + goto findevent; + + // Stack frame is being restored as saved via CheckRun...(). + // Restore necessary values then jump to __call label to resume processing. + sv = RestoreStackFrame("xmrEventDequeue", out callNo); + sleepUntil = DateTime.Parse((string)sv[0]); + returnMask1 = (int)sv[1]; + returnMask2 = (int)sv[2]; + mask1 = (int)sv[3]; + mask2 = (int)sv[4]; + switch(callNo) + { + case 0: + goto __call0; + case 1: + { + evc1 = (int)sv[5]; + evc = (ScriptEventCode)(int)sv[6]; + DetectParams[] detprms = ObjArrToDetPrms((object[])sv[7]); + object[] ehargs = (object[])sv[8]; + evt = new EventParams(evc.ToString(), ehargs, detprms); + goto __call1; + } + } + throw new ScriptBadCallNoException(callNo); + + // Find first event that matches either the return or background masks. + findevent: + Monitor.Enter(m_QueueLock); + for(lln = m_EventQueue.First; lln != null; lln = lln.Next) + { + evt = lln.Value; + evc = (ScriptEventCode)Enum.Parse(typeof(ScriptEventCode), evt.EventName); + evc1 = (int)evc; + evc2 = evc1 - 32; + if((((uint)evc1 < (uint)32) && (((mask1 >> evc1) & 1) != 0)) || + (((uint)evc2 < (uint)32) && (((mask2 >> evc2) & 1) != 0))) + goto remfromq; + } + + // Nothing found, sleep while one comes in. + m_SleepUntil = sleepUntil; + m_SleepEventMask1 = mask1; + m_SleepEventMask2 = mask2; + Monitor.Exit(m_QueueLock); + suspendOnCheckRunTemp = true; + callNo = 0; + __call0: + CheckRunQuick(); + goto checktmo; + + // Found one, remove it from queue. + remfromq: + m_EventQueue.Remove(lln); + if((uint)evc1 < (uint)m_EventCounts.Length) + m_EventCounts[evc1]--; + + Monitor.Exit(m_QueueLock); + m_InstEHEvent++; + + // See if returnable or background event. + if((((uint)evc1 < (uint)32) && (((returnMask1 >> evc1) & 1) != 0)) || + (((uint)evc2 < (uint)32) && (((returnMask2 >> evc2) & 1) != 0))) + { + // Returnable event, return its parameters in a list. + // Also set the detect parameters to what the event has. + int plen = evt.Params.Length; + object[] plist = new object[plen + 1]; + plist[0] = (LSL_Integer)evc1; + for(int i = 0; i < plen;) + { + object ob = evt.Params[i]; + if(ob is int) + ob = (LSL_Integer)(int)ob; + else if(ob is double) + ob = (LSL_Float)(double)ob; + else if(ob is string) + ob = (LSL_String)(string)ob; + plist[++i] = ob; + } + m_DetectParams = evt.DetectParams; + return new LSL_List(plist); + } + + // It is a background event, simply call its event handler, + // then check event queue again. + callNo = 1; + __call1: + ScriptEventHandler seh = m_ObjCode.scriptEventHandlerTable[stateCode, evc1]; + if(seh == null) + goto checktmo; + + DetectParams[] saveDetParams = this.m_DetectParams; + object[] saveEHArgs = this.ehArgs; + ScriptEventCode saveEventCode = this.eventCode; + + this.m_DetectParams = evt.DetectParams; + this.ehArgs = evt.Params; + this.eventCode = evc; + + try + { + seh(this); + } + finally + { + this.m_DetectParams = saveDetParams; + this.ehArgs = saveEHArgs; + this.eventCode = saveEventCode; + } + + // Keep waiting until we find a returnable event or timeout. + checktmo: + if(DateTime.UtcNow < sleepUntil) + goto findevent; + + // We timed out, return an empty list. + return emptyList; + } + finally + { + if(callMode != CallMode_NORMAL) + { + // Stack frame is being saved by CheckRun...(). + // Save everything we need at the __call labels so we can restore it + // when we need to. + sv = CaptureStackFrame("xmrEventDequeue", callNo, 9); + sv[0] = sleepUntil.ToString(); // needed at __call0,__call1 + sv[1] = returnMask1; // needed at __call0,__call1 + sv[2] = returnMask2; // needed at __call0,__call1 + sv[3] = mask1; // needed at __call0,__call1 + sv[4] = mask2; // needed at __call0,__call1 + if(callNo == 1) + { + sv[5] = evc1; // needed at __call1 + sv[6] = (int)evc; // needed at __call1 + sv[7] = DetPrmsToObjArr(evt.DetectParams); // needed at __call1 + sv[8] = evt.Params; // needed at __call1 + } + } + } + } + + /** + * @brief Enqueue an event + * @param ev = as returned by xmrEventDequeue saying which event type to queue + * and what argument list to pass to it. The llDetect...() parameters + * are as currently set for the script (use xmrEventLoadDets to set how + * you want them to be different). + */ + public override void xmrEventEnqueue(LSL_List ev) + { + object[] data = ev.Data; + ScriptEventCode evc = (ScriptEventCode)ListInt(data[0]); + + int nargs = data.Length - 1; + object[] args = new object[nargs]; + Array.Copy(data, 1, args, 0, nargs); + + PostEvent(new EventParams(evc.ToString(), args, m_DetectParams)); + } + + /** + * @brief Save current detect params into a list + * @returns a list containing current detect param values + */ + private const int saveDPVer = 1; + + public override LSL_List xmrEventSaveDets() + { + object[] obs = DetPrmsToObjArr(m_DetectParams); + return new LSL_List(obs); + } + + private static object[] DetPrmsToObjArr(DetectParams[] dps) + { + int len = dps.Length; + object[] obs = new object[len * 16 + 1]; + int j = 0; + obs[j++] = (LSL_Integer)saveDPVer; + for(int i = 0; i < len; i++) + { + DetectParams dp = dps[i]; + obs[j++] = (LSL_String)dp.Key.ToString(); // UUID + obs[j++] = dp.OffsetPos; // vector + obs[j++] = (LSL_Integer)dp.LinkNum; // integer + obs[j++] = (LSL_String)dp.Group.ToString(); // UUID + obs[j++] = (LSL_String)dp.Name; // string + obs[j++] = (LSL_String)dp.Owner.ToString(); // UUID + obs[j++] = dp.Position; // vector + obs[j++] = dp.Rotation; // rotation + obs[j++] = (LSL_Integer)dp.Type; // integer + obs[j++] = dp.Velocity; // vector + obs[j++] = dp.TouchST; // vector + obs[j++] = dp.TouchNormal; // vector + obs[j++] = dp.TouchBinormal; // vector + obs[j++] = dp.TouchPos; // vector + obs[j++] = dp.TouchUV; // vector + obs[j++] = (LSL_Integer)dp.TouchFace; // integer + } + return obs; + } + + /** + * @brief Load current detect params from a list + * @param dpList = as returned by xmrEventSaveDets() + */ + public override void xmrEventLoadDets(LSL_List dpList) + { + m_DetectParams = ObjArrToDetPrms(dpList.Data); + } + + private static DetectParams[] ObjArrToDetPrms(object[] objs) + { + int j = 0; + if((objs.Length % 16 != 1) || (ListInt(objs[j++]) != saveDPVer)) + throw new Exception("invalid detect param format"); + + int len = objs.Length / 16; + DetectParams[] dps = new DetectParams[len]; + + for(int i = 0; i < len; i++) + { + DetectParams dp = new DetectParams(); + + dp.Key = new UUID(ListStr(objs[j++])); + dp.OffsetPos = (LSL_Vector)objs[j++]; + dp.LinkNum = ListInt(objs[j++]); + dp.Group = new UUID(ListStr(objs[j++])); + dp.Name = ListStr(objs[j++]); + dp.Owner = new UUID(ListStr(objs[j++])); + dp.Position = (LSL_Vector)objs[j++]; + dp.Rotation = (LSL_Rotation)objs[j++]; + dp.Type = ListInt(objs[j++]); + dp.Velocity = (LSL_Vector)objs[j++]; + + SurfaceTouchEventArgs stea = new SurfaceTouchEventArgs(); + + stea.STCoord = LSLVec2OMVec((LSL_Vector)objs[j++]); + stea.Normal = LSLVec2OMVec((LSL_Vector)objs[j++]); + stea.Binormal = LSLVec2OMVec((LSL_Vector)objs[j++]); + stea.Position = LSLVec2OMVec((LSL_Vector)objs[j++]); + stea.UVCoord = LSLVec2OMVec((LSL_Vector)objs[j++]); + stea.FaceIndex = ListInt(objs[j++]); + + dp.SurfaceTouchArgs = stea; + + dps[i] = dp; + } + return dps; + } + + /** + * @brief The script is executing a 'state ;' command. + * Tell outer layers to cancel any event triggers, like llListen(), + * then tell outer layers which events the new state has handlers for. + * We also clear the event queue as per http://wiki.secondlife.com/wiki/State + */ + public override void StateChange() + { + // Cancel any llListen()s etc. + // But llSetTimerEvent() should persist. + object[] timers = m_XMRLSLApi.acm.TimerPlugin.GetSerializationData(m_ItemID); + AsyncCommandManager.RemoveScript(m_Engine, m_LocalID, m_ItemID); + m_XMRLSLApi.acm.TimerPlugin.CreateFromData(m_LocalID, m_ItemID, UUID.Zero, timers); + + // Tell whoever cares which event handlers the new state has. + m_Part.SetScriptEvents(m_ItemID, GetStateEventFlags(stateCode)); + + // Clear out any old events from the queue. + lock(m_QueueLock) + { + m_EventQueue.Clear(); + for(int i = m_EventCounts.Length; --i >= 0;) + m_EventCounts[i] = 0; + } + } + } + + /** + * @brief Thrown by things like llResetScript() to unconditionally + * unwind as script and reset it to the default state_entry + * handler. We don't want script-level try/catch to intercept + * these so scripts can't interfere with the behavior. + */ + public class ScriptResetException: Exception, IXMRUncatchable + { + } + + /** + * @brief Thrown by things like llDie() to unconditionally unwind as + * script. We don't want script-level try/catch to intercept + * these so scripts can't interfere with the behavior. + */ + public class ScriptDieException: Exception, IXMRUncatchable + { + } +} diff --git a/OpenSim/Region/ScriptEngine/YEngine/XMRInstCapture.cs b/OpenSim/Region/ScriptEngine/YEngine/XMRInstCapture.cs new file mode 100644 index 0000000000..e90d83bae4 --- /dev/null +++ b/OpenSim/Region/ScriptEngine/YEngine/XMRInstCapture.cs @@ -0,0 +1,309 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.IO; +using System.Xml; +using OpenSim.Region.ScriptEngine.Shared; +using OpenSim.Region.ScriptEngine.Shared.Api; +using log4net; + +using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; +using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; +using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; +using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list; +using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; +using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; +using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; + +namespace OpenSim.Region.ScriptEngine.Yengine +{ + public partial class XMRInstance + { + /********************************************************************************\ + * The only method of interest to outside this module is GetExecutionState() * + * which captures the current state of the script into an XML document. * + * * + * The rest of this module contains support routines for GetExecutionState(). * + \********************************************************************************/ + + /** + * @brief Create an XML element that gives the current state of the script. + * + * globalsandstackdump + * m_Running + * + * + * Updates the .state file while we're at it. + */ + public XmlElement GetExecutionState(XmlDocument doc) + { + // When we're detaching an attachment, we need to wait here. + + // Change this to a 5 second timeout. If things do mess up, + // we don't want to be stuck forever. + // + m_DetachReady.WaitOne(5000, false); + + XmlElement scriptStateN = doc.CreateElement("", "ScriptState", ""); + scriptStateN.SetAttribute("Engine", m_Engine.ScriptEngineName); + scriptStateN.SetAttribute("Asset", m_Item.AssetID.ToString()); + scriptStateN.SetAttribute("SourceHash", m_ObjCode.sourceHash); + + // Make sure we aren't executing part of the script so it stays + // stable. Setting suspendOnCheckRun tells CheckRun() to suspend + // and return out so RunOne() will release the lock asap. + suspendOnCheckRunHold = true; + lock(m_RunLock) + { + m_RunOnePhase = "GetExecutionState enter"; + CheckRunLockInvariants(true); + + // Get copy of script globals and stack in relocateable form. + MemoryStream snapshotStream = new MemoryStream(); + MigrateOutEventHandler(snapshotStream); + Byte[] snapshotBytes = snapshotStream.ToArray(); + snapshotStream.Close(); + string snapshotString = Convert.ToBase64String(snapshotBytes); + XmlElement snapshotN = doc.CreateElement("", "Snapshot", ""); + snapshotN.AppendChild(doc.CreateTextNode(snapshotString)); + scriptStateN.AppendChild(snapshotN); + m_RunOnePhase = "GetExecutionState B"; + CheckRunLockInvariants(true); + + // "Running" says whether or not we are accepting new events. + XmlElement runningN = doc.CreateElement("", "Running", ""); + runningN.AppendChild(doc.CreateTextNode(m_Running.ToString())); + scriptStateN.AppendChild(runningN); + m_RunOnePhase = "GetExecutionState C"; + CheckRunLockInvariants(true); + + // "DoGblInit" says whether or not default:state_entry() will init global vars. + XmlElement doGblInitN = doc.CreateElement("", "DoGblInit", ""); + doGblInitN.AppendChild(doc.CreateTextNode(doGblInit.ToString())); + scriptStateN.AppendChild(doGblInitN); + m_RunOnePhase = "GetExecutionState D"; + CheckRunLockInvariants(true); + + // More misc data. + XmlNode permissionsN = doc.CreateElement("", "Permissions", ""); + scriptStateN.AppendChild(permissionsN); + + XmlAttribute granterA = doc.CreateAttribute("", "granter", ""); + granterA.Value = m_Item.PermsGranter.ToString(); + permissionsN.Attributes.Append(granterA); + + XmlAttribute maskA = doc.CreateAttribute("", "mask", ""); + maskA.Value = m_Item.PermsMask.ToString(); + permissionsN.Attributes.Append(maskA); + m_RunOnePhase = "GetExecutionState E"; + CheckRunLockInvariants(true); + + // "DetectParams" are returned by llDetected...() script functions + // for the currently active event, if any. + if(m_DetectParams != null) + { + XmlElement detParArrayN = doc.CreateElement("", "DetectArray", ""); + AppendXMLDetectArray(doc, detParArrayN, m_DetectParams); + scriptStateN.AppendChild(detParArrayN); + } + m_RunOnePhase = "GetExecutionState F"; + CheckRunLockInvariants(true); + + // Save any events we have in the queue. + // + // + // ... ... + // ... ... + // + // ... + // + XmlElement queuedEventsN = doc.CreateElement("", "EventQueue", ""); + lock(m_QueueLock) + { + foreach(EventParams evt in m_EventQueue) + { + XmlElement singleEventN = doc.CreateElement("", "Event", ""); + singleEventN.SetAttribute("Name", evt.EventName); + AppendXMLObjectArray(doc, singleEventN, evt.Params, "param"); + AppendXMLDetectArray(doc, singleEventN, evt.DetectParams); + queuedEventsN.AppendChild(singleEventN); + } + } + scriptStateN.AppendChild(queuedEventsN); + m_RunOnePhase = "GetExecutionState G"; + CheckRunLockInvariants(true); + + // "Plugins" indicate enabled timers and listens, etc. + Object[] pluginData = + AsyncCommandManager.GetSerializationData(m_Engine, m_ItemID); + + XmlNode plugins = doc.CreateElement("", "Plugins", ""); + AppendXMLObjectArray(doc, plugins, pluginData, "plugin"); + scriptStateN.AppendChild(plugins); + m_RunOnePhase = "GetExecutionState H"; + CheckRunLockInvariants(true); + + // Let script run again. + suspendOnCheckRunHold = false; + + m_RunOnePhase = "GetExecutionState leave"; + CheckRunLockInvariants(true); + } + + // scriptStateN represents the contents of the .state file so + // write the .state file while we are here. + FileStream fs = File.Create(m_StateFileName); + StreamWriter sw = new StreamWriter(fs); + sw.Write(scriptStateN.OuterXml); + sw.Close(); + fs.Close(); + + return scriptStateN; + } + + /** + * @brief Write script state to output stream. + * Input: + * stream = stream to write event handler state information to + */ + private void MigrateOutEventHandler(Stream stream) + { + // Write script state out, frames and all, to the stream. + // Does not change script state. + stream.WriteByte(migrationVersion); + stream.WriteByte((byte)16); + this.MigrateOut(new BinaryWriter(stream)); + } + + /** + * @brief Convert an DetectParams[] to corresponding XML. + * DetectParams[] holds the values retrievable by llDetected...() for + * a given event. + */ + private static void AppendXMLDetectArray(XmlDocument doc, XmlElement parent, DetectParams[] detect) + { + foreach(DetectParams d in detect) + { + XmlElement detectParamsN = GetXMLDetect(doc, d); + parent.AppendChild(detectParamsN); + } + } + + private static XmlElement GetXMLDetect(XmlDocument doc, DetectParams d) + { + XmlElement detectParamsN = doc.CreateElement("", "DetectParams", ""); + + XmlAttribute d_key = doc.CreateAttribute("", "key", ""); + d_key.Value = d.Key.ToString(); + detectParamsN.Attributes.Append(d_key); + + XmlAttribute pos = doc.CreateAttribute("", "pos", ""); + pos.Value = d.OffsetPos.ToString(); + detectParamsN.Attributes.Append(pos); + + XmlAttribute d_linkNum = doc.CreateAttribute("", "linkNum", ""); + d_linkNum.Value = d.LinkNum.ToString(); + detectParamsN.Attributes.Append(d_linkNum); + + XmlAttribute d_group = doc.CreateAttribute("", "group", ""); + d_group.Value = d.Group.ToString(); + detectParamsN.Attributes.Append(d_group); + + XmlAttribute d_name = doc.CreateAttribute("", "name", ""); + d_name.Value = d.Name.ToString(); + detectParamsN.Attributes.Append(d_name); + + XmlAttribute d_owner = doc.CreateAttribute("", "owner", ""); + d_owner.Value = d.Owner.ToString(); + detectParamsN.Attributes.Append(d_owner); + + XmlAttribute d_position = doc.CreateAttribute("", "position", ""); + d_position.Value = d.Position.ToString(); + detectParamsN.Attributes.Append(d_position); + + XmlAttribute d_rotation = doc.CreateAttribute("", "rotation", ""); + d_rotation.Value = d.Rotation.ToString(); + detectParamsN.Attributes.Append(d_rotation); + + XmlAttribute d_type = doc.CreateAttribute("", "type", ""); + d_type.Value = d.Type.ToString(); + detectParamsN.Attributes.Append(d_type); + + XmlAttribute d_velocity = doc.CreateAttribute("", "velocity", ""); + d_velocity.Value = d.Velocity.ToString(); + detectParamsN.Attributes.Append(d_velocity); + + return detectParamsN; + } + + /** + * @brief Append elements of an array of objects to an XML parent. + * @param doc = document the parent is part of + * @param parent = parent to append the items to + * @param array = array of objects + * @param tag = ... for each element + */ + private static void AppendXMLObjectArray(XmlDocument doc, XmlNode parent, object[] array, string tag) + { + foreach(object o in array) + { + XmlElement element = GetXMLObject(doc, o, tag); + parent.AppendChild(element); + } + } + + /** + * @brief Get and XML representation of an object. + * @param doc = document the tag will be put in + * @param o = object to be represented + * @param tag = ... + */ + private static XmlElement GetXMLObject(XmlDocument doc, object o, string tag) + { + XmlAttribute typ = doc.CreateAttribute("", "type", ""); + XmlElement n = doc.CreateElement("", tag, ""); + + if(o is LSL_List) + { + typ.Value = "list"; + n.Attributes.Append(typ); + AppendXMLObjectArray(doc, n, ((LSL_List)o).Data, "item"); + } + else + { + typ.Value = o.GetType().ToString(); + n.Attributes.Append(typ); + n.AppendChild(doc.CreateTextNode(o.ToString())); + } + return n; + } + } +} diff --git a/OpenSim/Region/ScriptEngine/YEngine/XMRInstCtor.cs b/OpenSim/Region/ScriptEngine/YEngine/XMRInstCtor.cs new file mode 100644 index 0000000000..f7aad6e2d5 --- /dev/null +++ b/OpenSim/Region/ScriptEngine/YEngine/XMRInstCtor.cs @@ -0,0 +1,721 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Threading; +using System.Reflection; +using System.Collections; +using System.Collections.Generic; +using System.Runtime.Remoting.Lifetime; +using System.Security.Policy; +using System.IO; +using System.Xml; +using System.Text; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Region.ScriptEngine.Interfaces; +using OpenSim.Region.ScriptEngine.Shared; +using OpenSim.Region.ScriptEngine.Shared.Api; +using OpenSim.Region.ScriptEngine.Shared.ScriptBase; +using OpenSim.Region.ScriptEngine.Yengine; +using OpenSim.Region.Framework.Scenes; +using log4net; + +using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; +using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; +using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; +using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list; +using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; +using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; +using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; + +namespace OpenSim.Region.ScriptEngine.Yengine +{ + public partial class XMRInstance + { + /****************************************************************************\ + * The only method of interest to outside this module is the Initializer. * + * * + * The rest of this module contains support routines for the Initializer. * + \****************************************************************************/ + + /** + * @brief Initializer, loads script in memory and all ready for running. + * @param engine = YEngine instance this is part of + * @param scriptBasePath = directory name where files are + * @param stackSize = number of bytes to allocate for stacks + * @param errors = return compiler errors in this array + * @param forceRecomp = force recompile + * Throws exception if any error, so it was successful if it returns. + */ + public void Initialize(Yengine engine, string scriptBasePath, + int stackSize, int heapSize, ArrayList errors) + { + if(stackSize < 16384) + stackSize = 16384; + if(heapSize < 16384) + heapSize = 16384; + + // Save all call parameters in instance vars for easy access. + m_Engine = engine; + m_ScriptBasePath = scriptBasePath; + m_StackSize = stackSize; + m_StackLeft = stackSize; + m_HeapSize = heapSize; + m_CompilerErrors = errors; + m_StateFileName = GetStateFileName(scriptBasePath, m_ItemID); + + // Not in any XMRInstQueue. + m_NextInst = this; + m_PrevInst = this; + + // Set up list of API calls it has available. + // This also gets the API modules ready to accept setup data, such as + // active listeners being restored. + IScriptApi scriptApi; + ApiManager am = new ApiManager(); + foreach(string api in am.GetApis()) + { + // Instantiate the API for this script instance. + if(api != "LSL") + scriptApi = am.CreateApi(api); + else + scriptApi = m_XMRLSLApi = new XMRLSL_Api(); + + // Connect it up to the instance. + InitScriptApi(engine, api, scriptApi); + } + + m_XMRLSLApi.InitXMRLSLApi(this); + + // Get object loaded, compiling script and reading .state file as + // necessary to restore the state. + suspendOnCheckRunHold = true; + InstantiateScript(); + m_SourceCode = null; + if(m_ObjCode == null) + throw new ArgumentNullException("m_ObjCode"); + if(m_ObjCode.scriptEventHandlerTable == null) + throw new ArgumentNullException("m_ObjCode.scriptEventHandlerTable"); + + suspendOnCheckRunHold = false; + suspendOnCheckRunTemp = false; + + // Declare which events the script's current state can handle. + int eventMask = GetStateEventFlags(stateCode); + m_Part.SetScriptEvents(m_ItemID, eventMask); + } + + private void InitScriptApi(Yengine engine, string api, IScriptApi scriptApi) + { + // Set up m_ApiManager_ = instance pointer. + engine.m_XMRInstanceApiCtxFieldInfos[api].SetValue(this, scriptApi); + + // Initialize the API instance. + scriptApi.Initialize(m_Engine, m_Part, m_Item); + this.InitApi(api, scriptApi); + } + + + /* + * Get script object code loaded in memory and all ready to run, + * ready to resume it from where the .state file says it was last + */ + private void InstantiateScript() + { + bool compiledIt = false; + ScriptObjCode objCode; + + // If source code string is empty, use the asset ID as the object file name. + // Allow lines of // comments at the beginning (for such as engine selection). + int i, j, len; + if(m_SourceCode == null) + m_SourceCode = String.Empty; + for(len = m_SourceCode.Length; len > 0; --len) + { + if(m_SourceCode[len - 1] > ' ') + break; + } + for(i = 0; i < len; i++) + { + char c = m_SourceCode[i]; + if(c <= ' ') + continue; + if(c != '/') + break; + if((i + 1 >= len) || (m_SourceCode[i + 1] != '/')) + break; + i = m_SourceCode.IndexOf('\n', i); + if(i < 0) + i = len - 1; + } + if((i >= len) || !m_Engine.m_UseSourceHashCode) + { + // Source consists of nothing but // comments and whitespace, + // or we are being forced to use the asset-id as the key, to + // open an already existing object code file. + m_ScriptObjCodeKey = m_Item.AssetID.ToString(); + if(i >= len) + m_SourceCode = ""; + } + else + { + // Make up dictionary key for the object code. + // Use the same object code for identical source code + // regardless of asset ID, so we don't care if they + // copy scripts or not. + byte[] scbytes = System.Text.Encoding.UTF8.GetBytes(m_SourceCode); + StringBuilder sb = new StringBuilder((256 + 5) / 6); + ByteArrayToSixbitStr(sb, System.Security.Cryptography.SHA256.Create().ComputeHash(scbytes)); + m_ScriptObjCodeKey = sb.ToString(); + + // But source code can be just a sixbit string itself + // that identifies an already existing object code file. + if(len - i == m_ScriptObjCodeKey.Length) + { + for(j = len; --j >= i;) + { + if(sixbit.IndexOf(m_SourceCode[j]) < 0) + break; + } + if(j < i) + { + m_ScriptObjCodeKey = m_SourceCode.Substring(i, len - i); + m_SourceCode = ""; + } + } + } + + // There may already be an ScriptObjCode struct in memory that + // we can use. If not, try to compile it. + lock(m_CompileLock) + { + if(!m_CompiledScriptObjCode.TryGetValue(m_ScriptObjCodeKey, out objCode) || m_ForceRecomp) + { + objCode = TryToCompile(); + compiledIt = true; + } + + // Loaded successfully, increment reference count. + // If we just compiled it though, reset count to 0 first as + // this is the one-and-only existance of this objCode struct, + // and we want any old ones for this source code to be garbage + // collected. + + if(compiledIt) + { + m_CompiledScriptObjCode[m_ScriptObjCodeKey] = objCode; + objCode.refCount = 0; + } + objCode.refCount++; + + // Now set up to decrement ref count on dispose. + m_ObjCode = objCode; + } + + try + { + + // Fill in script instance from object code + // Script instance is put in a "never-ever-has-run-before" state. + LoadObjCode(); + + // Fill in script intial state + // - either as loaded from a .state file + // - or initial default state_entry() event + LoadInitialState(); + } + catch + { + + // If any error loading, decrement object code reference count. + DecObjCodeRefCount(); + throw; + } + } + + private const string sixbit = "0123456789_abcdefghijklmnopqrstuvwxyz@ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + private static void ByteArrayToSixbitStr(StringBuilder sb, byte[] bytes) + { + int bit = 0; + int val = 0; + foreach(byte b in bytes) + { + val |= (int)((uint)b << bit); + bit += 8; + while(bit >= 6) + { + sb.Append(sixbit[val & 63]); + val >>= 6; + bit -= 6; + } + } + if(bit > 0) + sb.Append(sixbit[val & 63]); + } + + // Try to create object code from source code + // If error, just throw exception + private ScriptObjCode TryToCompile() + { + m_CompilerErrors.Clear(); + + // If object file exists, create ScriptObjCode directly from that. + // Otherwise, compile the source to create object file then create + // ScriptObjCode from that. + string assetID = m_Item.AssetID.ToString(); + m_CameFrom = "asset://" + assetID; + ScriptObjCode objCode = Compile(); + if(m_CompilerErrors.Count != 0) + throw new Exception("compilation errors"); + + if(objCode == null) + throw new Exception("compilation failed"); + + return objCode; + } + + /* + * Retrieve source from asset server. + */ + private string FetchSource(string cameFrom) + { + m_log.Debug("[YEngine]: fetching source " + cameFrom); + if(!cameFrom.StartsWith("asset://")) + throw new Exception("unable to retrieve source from " + cameFrom); + + string assetID = cameFrom.Substring(8); + AssetBase asset = m_Engine.World.AssetService.Get(assetID); + if(asset == null) + throw new Exception("source not found " + cameFrom); + + string source = Encoding.UTF8.GetString(asset.Data); + if(EmptySource(source)) + throw new Exception("fetched source empty " + cameFrom); + + return source; + } + + /* + * Fill in script object initial contents. + * Set the initial state to "default". + */ + private void LoadObjCode() + { + // Script must leave this much stack remaining on calls to CheckRun(). + this.stackLimit = m_StackSize / 2; + + // This is how many total heap bytes script is allowed to use. + this.heapLimit = m_HeapSize; + + // Allocate global variable arrays. + this.glblVars.AllocVarArrays(m_ObjCode.glblSizes); + + // Script can handle these event codes. + m_HaveEventHandlers = new bool[m_ObjCode.scriptEventHandlerTable.GetLength(1)]; + for(int i = m_ObjCode.scriptEventHandlerTable.GetLength(0); --i >= 0;) + { + for(int j = m_ObjCode.scriptEventHandlerTable.GetLength(1); --j >= 0;) + { + if(m_ObjCode.scriptEventHandlerTable[i, j] != null) + { + m_HaveEventHandlers[j] = true; + } + } + } + } + + /* + * LoadInitialState() + * if no state XML file exists for the asset, + * post initial default state events + * else + * try to restore from .state file + * If any error, throw exception + */ + private void LoadInitialState() + { + // If no .state file exists, start from default state + // Otherwise, read initial state from the .state file + + if(!File.Exists(m_StateFileName)) + { + m_Running = true; // event processing is enabled + eventCode = ScriptEventCode.None; // not processing any event + + // default state_entry() must initialize global variables + doGblInit = true; + stateCode = 0; + + PostEvent(new EventParams("state_entry", + zeroObjectArray, + zeroDetectParams)); + } + else + { + FileStream fs = File.Open(m_StateFileName, + FileMode.Open, + FileAccess.Read); + StreamReader ss = new StreamReader(fs); + string xml = ss.ReadToEnd(); + ss.Close(); + fs.Close(); + + XmlDocument doc = new XmlDocument(); + doc.LoadXml(xml); + LoadScriptState(doc); + } + + // Post event(s) saying what caused the script to start. + if(m_PostOnRez) + { + PostEvent(new EventParams("on_rez", + new Object[] { m_StartParam }, + zeroDetectParams)); + } + + switch(m_StateSource) + { + case StateSource.AttachedRez: + PostEvent(new EventParams("attach", + new object[] { m_Part.ParentGroup.AttachedAvatar.ToString() }, + zeroDetectParams)); + break; + + case StateSource.PrimCrossing: + PostEvent(new EventParams("changed", + sbcCR, + zeroDetectParams)); + break; + + case StateSource.Teleporting: + PostEvent(new EventParams("changed", + sbcCR, + zeroDetectParams)); + PostEvent(new EventParams("changed", + sbcCT, + zeroDetectParams)); + break; + + case StateSource.RegionStart: + PostEvent(new EventParams("changed", + sbcCRS, + zeroDetectParams)); + break; + } + } + + private static Object[] sbcCRS = new Object[] { ScriptBaseClass.CHANGED_REGION_START }; + private static Object[] sbcCR = new Object[] { ScriptBaseClass.CHANGED_REGION }; + private static Object[] sbcCT = new Object[] { ScriptBaseClass.CHANGED_TELEPORT }; + + /** + * @brief Save compilation error messages for later retrieval + * via GetScriptErrors(). + */ + private void ErrorHandler(Token token, string message) + { + if(token != null) + { + string srcloc = token.SrcLoc; + if(srcloc.StartsWith(m_CameFrom)) + srcloc = srcloc.Substring(m_CameFrom.Length); + + m_CompilerErrors.Add(srcloc + " Error: " + message); + } + else if(message != null) + m_CompilerErrors.Add("(0,0) Error: " + message); + else + m_CompilerErrors.Add("(0,0) Error compiling, see exception in log"); + } + + /** + * @brief Load script state from the given XML doc into the script memory + * + * ... + * ... + * + * RestoreDetectParams() + * + * ExtractXMLObjectArray("plugin") + * + * + * MigrateInEventHandler() + * + * + */ + private void LoadScriptState(XmlDocument doc) + { + DetectParams[] detParams; + LinkedList eventQueue; + + // Everything we know is enclosed in ... + XmlElement scriptStateN = (XmlElement)doc.SelectSingleNode("ScriptState"); + if(scriptStateN == null) + throw new Exception("no tag"); + + string sen = scriptStateN.GetAttribute("Engine"); + if((sen == null) || (sen != m_Engine.ScriptEngineName)) + throw new Exception(" missing Engine=\"YEngine\" attribute"); + + // AssetID is unique for the script source text so make sure the + // state file was written for that source file + string assetID = scriptStateN.GetAttribute("Asset"); + if(assetID != m_Item.AssetID.ToString()) + throw new Exception(" assetID mismatch"); + + // Also match the sourceHash in case script was + // loaded via 'xmroption fetchsource' and has changed + string sourceHash = scriptStateN.GetAttribute("SourceHash"); + if((sourceHash == null) || (sourceHash != m_ObjCode.sourceHash)) + throw new Exception(" SourceHash mismatch"); + + // Get various attributes + XmlElement runningN = (XmlElement)scriptStateN.SelectSingleNode("Running"); + m_Running = bool.Parse(runningN.InnerText); + + XmlElement doGblInitN = (XmlElement)scriptStateN.SelectSingleNode("DoGblInit"); + doGblInit = bool.Parse(doGblInitN.InnerText); + + XmlElement permissionsN = (XmlElement)scriptStateN.SelectSingleNode("Permissions"); + m_Item.PermsGranter = new UUID(permissionsN.GetAttribute("granter")); + m_Item.PermsMask = Convert.ToInt32(permissionsN.GetAttribute("mask")); + m_Part.Inventory.UpdateInventoryItem(m_Item, false, false); + + // get values used by stuff like llDetectedGrab, etc. + detParams = RestoreDetectParams(scriptStateN.SelectSingleNode("DetectArray")); + + // Restore queued events + eventQueue = RestoreEventQueue(scriptStateN.SelectSingleNode("EventQueue")); + + // Restore timers and listeners + XmlElement pluginN = (XmlElement)scriptStateN.SelectSingleNode("Plugins"); + Object[] pluginData = ExtractXMLObjectArray(pluginN, "plugin"); + + // Script's global variables and stack contents + XmlElement snapshotN = + (XmlElement)scriptStateN.SelectSingleNode("Snapshot"); + + Byte[] data = Convert.FromBase64String(snapshotN.InnerText); + MemoryStream ms = new MemoryStream(); + ms.Write(data, 0, data.Length); + ms.Seek(0, SeekOrigin.Begin); + MigrateInEventHandler(ms); + ms.Close(); + + // Restore event queues, preserving any events that queued + // whilst we were restoring the state + lock(m_QueueLock) + { + m_DetectParams = detParams; + foreach(EventParams evt in m_EventQueue) + eventQueue.AddLast(evt); + + m_EventQueue = eventQueue; + for(int i = m_EventCounts.Length; --i >= 0;) + m_EventCounts[i] = 0; + foreach(EventParams evt in m_EventQueue) + { + ScriptEventCode eventCode = (ScriptEventCode)Enum.Parse(typeof(ScriptEventCode), + evt.EventName); + m_EventCounts[(int)eventCode]++; + } + } + + // Requeue timer and listeners (possibly queuing new events) + AsyncCommandManager.CreateFromData(m_Engine, + m_LocalID, m_ItemID, m_Part.UUID, + pluginData); + } + + /** + * @brief Read llDetectedGrab, etc, values from XML + * + * ... + * . + * . + * . + * + */ + private LinkedList RestoreEventQueue(XmlNode eventsN) + { + LinkedList eventQueue = new LinkedList(); + if(eventsN != null) + { + XmlNodeList eventL = eventsN.SelectNodes("Event"); + foreach(XmlNode evnt in eventL) + { + string name = ((XmlElement)evnt).GetAttribute("Name"); + object[] parms = ExtractXMLObjectArray(evnt, "param"); + DetectParams[] detects = RestoreDetectParams(evnt); + + if(parms == null) + parms = zeroObjectArray; + if(detects == null) + detects = zeroDetectParams; + + EventParams evt = new EventParams(name, parms, detects); + eventQueue.AddLast(evt); + } + } + return eventQueue; + } + + /** + * @brief Read llDetectedGrab, etc, values from XML + * + * ... + * . + * . + * . + * + */ + private DetectParams[] RestoreDetectParams(XmlNode detectedN) + { + if(detectedN == null) + return null; + + List detected = new List(); + XmlNodeList detectL = detectedN.SelectNodes("DetectParams"); + + DetectParams detprm = new DetectParams(); + foreach(XmlNode detxml in detectL) + { + try + { + detprm.Group = new UUID(detxml.Attributes.GetNamedItem("group").Value); + detprm.Key = new UUID(detxml.Attributes.GetNamedItem("key").Value); + detprm.Owner = new UUID(detxml.Attributes.GetNamedItem("owner").Value); + + detprm.LinkNum = Int32.Parse(detxml.Attributes.GetNamedItem("linkNum").Value); + detprm.Type = Int32.Parse(detxml.Attributes.GetNamedItem("type").Value); + + detprm.Name = detxml.Attributes.GetNamedItem("name").Value; + + detprm.OffsetPos = new LSL_Types.Vector3(detxml.Attributes.GetNamedItem("pos").Value); + detprm.Position = new LSL_Types.Vector3(detxml.Attributes.GetNamedItem("position").Value); + detprm.Velocity = new LSL_Types.Vector3(detxml.Attributes.GetNamedItem("velocity").Value); + + detprm.Rotation = new LSL_Types.Quaternion(detxml.Attributes.GetNamedItem("rotation").Value); + + detected.Add(detprm); + detprm = new DetectParams(); + } + catch(Exception e) + { + m_log.Warn("[YEngine]: RestoreDetectParams bad XML: " + detxml.ToString()); + m_log.Warn("[YEngine]: ... " + e.ToString()); + } + } + + return detected.ToArray(); + } + + /** + * @brief Extract elements of an array of objects from an XML parent. + * Each element is of form ... + * @param parent = XML parent to extract them from + * @param tag = what the value's tag is + * @returns object array of the values + */ + private static object[] ExtractXMLObjectArray(XmlNode parent, string tag) + { + List olist = new List(); + + XmlNodeList itemL = parent.SelectNodes(tag); + foreach(XmlNode item in itemL) + { + olist.Add(ExtractXMLObjectValue(item)); + } + + return olist.ToArray(); + } + + private static object ExtractXMLObjectValue(XmlNode item) + { + string itemType = item.Attributes.GetNamedItem("type").Value; + + if(itemType == "list") + { + return new LSL_List(ExtractXMLObjectArray(item, "item")); + } + + if(itemType == "OpenMetaverse.UUID") + { + UUID val = new UUID(); + UUID.TryParse(item.InnerText, out val); + return val; + } + + Type itemT = Type.GetType(itemType); + if(itemT == null) + { + Object[] args = new Object[] { item.InnerText }; + + string assembly = itemType + ", OpenSim.Region.ScriptEngine.Shared"; + itemT = Type.GetType(assembly); + if(itemT == null) + { + return null; + } + return Activator.CreateInstance(itemT, args); + } + + return Convert.ChangeType(item.InnerText, itemT); + } + + /* + * Migrate an event handler in from a stream. + * + * Input: + * stream = as generated by MigrateOutEventHandler() + */ + private void MigrateInEventHandler(Stream stream) + { + int mv = stream.ReadByte(); + if(mv != migrationVersion) + throw new Exception("incoming migration version " + mv + " but accept only " + migrationVersion); + + stream.ReadByte(); // ignored + + /* + * Restore script variables and stack and other state from stream. + * And it also marks us busy (by setting this.eventCode) so we can't be + * started again and this event lost. If it restores this.eventCode = + * None, the the script was idle. + */ + lock(m_RunLock) + { + BinaryReader br = new BinaryReader(stream); + this.MigrateIn(br); + + m_RunOnePhase = "MigrateInEventHandler finished"; + CheckRunLockInvariants(true); + } + } + } +} diff --git a/OpenSim/Region/ScriptEngine/YEngine/XMRInstMain.cs b/OpenSim/Region/ScriptEngine/YEngine/XMRInstMain.cs new file mode 100644 index 0000000000..9eb05f763e --- /dev/null +++ b/OpenSim/Region/ScriptEngine/YEngine/XMRInstMain.cs @@ -0,0 +1,219 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Threading; +using System.Reflection; +using System.Collections; +using System.Collections.Generic; +using System.Runtime.Remoting.Lifetime; +using System.Security.Policy; +using System.IO; +using System.Xml; +using System.Text; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Region.ScriptEngine.Interfaces; +using OpenSim.Region.ScriptEngine.Shared; +using OpenSim.Region.ScriptEngine.Shared.Api; +using OpenSim.Region.ScriptEngine.Shared.ScriptBase; +using OpenSim.Region.ScriptEngine.Yengine; +using OpenSim.Region.Framework.Scenes; +using log4net; + +using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; +using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; +using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; +using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list; +using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; +using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; +using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; + +// This class exists in the main app domain +// +namespace OpenSim.Region.ScriptEngine.Yengine +{ + /** + * @brief Which queue it is in as far as running is concerned, + * ie, m_StartQueue, m_YieldQueue, m_SleepQueue, etc. + * Allowed transitions: + * Starts in CONSTRUCT when constructed + * CONSTRUCT->ONSTARTQ : only by thread that constructed and compiled it + * IDLE->ONSTARTQ,RESETTING : by any thread but must have m_QueueLock when transitioning + * ONSTARTQ->RUNNING,RESETTING : only by thread that removed it from m_StartQueue + * ONYIELDQ->RUNNING,RESETTING : only by thread that removed it from m_YieldQueue + * ONSLEEPQ->REMDFROMSLPQ : by any thread but must have m_SleepQueue when transitioning + * REMDFROMSLPQ->ONYIELDQ,RESETTING : only by thread that removed it from m_SleepQueue + * RUNNING->whatever1 : only by thread that transitioned it to RUNNING + * whatever1 = IDLE,ONSLEEPQ,ONYIELDQ,ONSTARTQ,SUSPENDED,FINISHED + * FINSHED->whatever2 : only by thread that transitioned it to FINISHED + * whatever2 = IDLE,ONSTARTQ,DISPOSED + * SUSPENDED->ONSTARTQ : by any thread (NOT YET IMPLEMENTED, should be under some kind of lock?) + * RESETTING->ONSTARTQ : only by the thread that transitioned it to RESETTING + */ + public enum XMRInstState + { + CONSTRUCT, // it is being constructed + IDLE, // nothing happening (finished last event and m_EventQueue is empty) + ONSTARTQ, // inserted on m_Engine.m_StartQueue + RUNNING, // currently being executed by RunOne() + ONSLEEPQ, // inserted on m_Engine.m_SleepQueue + REMDFROMSLPQ, // removed from m_SleepQueue but not yet on m_YieldQueue + ONYIELDQ, // inserted on m_Engine.m_YieldQueue + FINISHED, // just finished handling an event + SUSPENDED, // m_SuspendCount > 0 + RESETTING, // being reset via external call + DISPOSED // has been disposed + } + + public partial class XMRInstance: XMRInstAbstract, IDisposable + { + /******************************************************************\ + * This module contains the instance variables for XMRInstance. * + \******************************************************************/ + + public const int MAXEVENTQUEUE = 64; + + public static readonly DetectParams[] zeroDetectParams = new DetectParams[0]; + public static readonly object[] zeroObjectArray = new object[0]; + + public static readonly ILog m_log = + LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + public XMRInstance m_NextInst; // used by XMRInstQueue + public XMRInstance m_PrevInst; + + // For a given m_Item.AssetID, do we have the compiled object code and where + // is it? + public static object m_CompileLock = new object(); + private static Dictionary m_CompiledScriptObjCode = new Dictionary(); + + public XMRInstState m_IState; + + public bool m_ForceRecomp = false; + public SceneObjectPart m_Part = null; + public uint m_LocalID = 0; + public TaskInventoryItem m_Item = null; + public UUID m_ItemID; + public UUID m_PartUUID; + private string m_CameFrom; + private string m_ScriptObjCodeKey; + + private Yengine m_Engine = null; + private string m_ScriptBasePath; + private string m_StateFileName; + public string m_SourceCode; + public bool m_PostOnRez; + private DetectParams[] m_DetectParams = null; + public int m_StartParam = 0; + public StateSource m_StateSource; + public string m_DescName; + private bool[] m_HaveEventHandlers; + public int m_StackSize; + public int m_HeapSize; + private ArrayList m_CompilerErrors; + private DateTime m_LastRanAt = DateTime.MinValue; + private string m_RunOnePhase = "hasn't run"; + private string m_CheckRunPhase = "hasn't checked"; + public int m_InstEHEvent = 0; // number of events dequeued (StartEventHandler called) + public int m_InstEHSlice = 0; // number of times handler timesliced (ResumeEx called) + public double m_CPUTime = 0; // accumulated CPU time (milliseconds) + public double m_SliceStart = 0; // when did current exec start + + // If code needs to have both m_QueueLock and m_RunLock, + // be sure to lock m_RunLock first then m_QueueLock, as + // that is the order used in RunOne(). + // These locks are currently separated to allow the script + // to call API routines that queue events back to the script. + // If we just had one lock, then the queuing would deadlock. + + // guards m_DetachQuantum, m_EventQueue, m_EventCounts, m_Running, m_Suspended + public Object m_QueueLock = new Object(); + + // true iff allowed to accept new events + public bool m_Running = true; + + // queue of events that haven't been acted upon yet + public LinkedList m_EventQueue = new LinkedList(); + + // number of events of each code currently in m_EventQueue. + private int[] m_EventCounts = new int[(int)ScriptEventCode.Size]; + + // locked whilst running on the microthread stack (or about to run on it or just ran on it) + private Object m_RunLock = new Object(); + + // script won't step while > 0. bus-atomic updates only. + private int m_SuspendCount = 0; + + // don't run any of script until this time + // or until one of these events are queued + public DateTime m_SleepUntil = DateTime.MinValue; + public int m_SleepEventMask1 = 0; + public int m_SleepEventMask2 = 0; + + private XMRLSL_Api m_XMRLSLApi; + + /* + * Makes sure migration data version is same on both ends. + */ + public static byte migrationVersion = 10; + + // Incremented each time script gets reset. + public int m_ResetCount = 0; + + // Scripts start suspended now. This means that event queues will + // accept events, but will not actually run them until the core + // tells it it's OK. This is needed to prevent loss of link messages + // in complex objects, where no event can be allowed to run until + // all possible link message receivers' queues are established. + // Guarded by m_QueueLock. + public bool m_Suspended = true; + + // We really don't want to save state for a script that hasn't had + // a chance to run, because it's state will be blank. That would + // cause attachment state loss. + public bool m_HasRun = false; + + // When llDie is executed within the attach(NULL_KEY) event of + // a script being detached to inventory, the DeleteSceneObject call + // it causes will delete the script instances before their state can + // be saved. Therefore, the instance needs to know that it's being + // detached to inventory, rather than to ground. + // Also, the attach(NULL_KEY) event needs to run with priority, and + // it also needs to have a limited quantum. + // If this is nonzero, we're detaching to inventory. + // Guarded by m_QueueLock. + private int m_DetachQuantum = 0; + + // Finally, we need to wait until the quantum is done, or the script + // suspends itself. This should be efficient, so we use an event + // for it instead of spinning busy. + // It's born ready, but will be reset when the detach is posted. + // It will then be set again on suspend/completion + private ManualResetEvent m_DetachReady = new ManualResetEvent(true); + } +} diff --git a/OpenSim/Region/ScriptEngine/YEngine/XMRInstMisc.cs b/OpenSim/Region/ScriptEngine/YEngine/XMRInstMisc.cs new file mode 100644 index 0000000000..0af3d37c3a --- /dev/null +++ b/OpenSim/Region/ScriptEngine/YEngine/XMRInstMisc.cs @@ -0,0 +1,399 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Threading; +using System.Reflection; +using System.Collections; +using System.Collections.Generic; +using System.Reflection.Emit; +using System.Runtime.Remoting.Lifetime; +using System.Security.Policy; +using System.IO; +using System.Xml; +using System.Text; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Region.ScriptEngine.Interfaces; +using OpenSim.Region.ScriptEngine.Shared; +using OpenSim.Region.ScriptEngine.Shared.Api; +using OpenSim.Region.ScriptEngine.Shared.ScriptBase; +using OpenSim.Region.ScriptEngine.Yengine; +using OpenSim.Region.Framework.Scenes; +using log4net; + +using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; +using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; +using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; +using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list; +using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; +using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; +using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; + +// This class exists in the main app domain +// +namespace OpenSim.Region.ScriptEngine.Yengine +{ + public partial class XMRInstance + { + + // In case Dispose() doesn't get called, we want to be sure to clean + // up. This makes sure we decrement m_CompiledScriptRefCount. + ~XMRInstance() + { + Dispose(); + } + + /** + * @brief Clean up stuff. + * We specifically leave m_DescName intact for 'xmr ls' command. + */ + public void Dispose() + { + // Tell script stop executing next time it calls CheckRun(). + suspendOnCheckRunHold = true; + + // Don't send us any more events. + lock(m_RunLock) + { + if(m_Part != null) + { + m_Part.RemoveScriptEvents(m_ItemID); + AsyncCommandManager.RemoveScript(m_Engine, m_LocalID, m_ItemID); + m_Part = null; + } + } + + // Let script methods get garbage collected if no one else is using + // them. + DecObjCodeRefCount(); + } + + private void DecObjCodeRefCount() + { + if(m_ObjCode != null) + { + lock(m_CompileLock) + { + ScriptObjCode objCode; + + if(m_CompiledScriptObjCode.TryGetValue(m_ScriptObjCodeKey, out objCode) && + (objCode == m_ObjCode) && + (--objCode.refCount == 0)) + { + m_CompiledScriptObjCode.Remove(m_ScriptObjCodeKey); + } + } + m_ObjCode = null; + } + } + + public void Verbose(string format, params object[] args) + { + if(m_Engine.m_Verbose) + m_log.DebugFormat(format, args); + } + + // Called by 'xmr top' console command + // to dump this script's state to console + // Sacha + public void RunTestTop() + { + if(m_InstEHSlice > 0) + { + Console.WriteLine(m_DescName); + Console.WriteLine(" m_LocalID = " + m_LocalID); + Console.WriteLine(" m_ItemID = " + m_ItemID); + Console.WriteLine(" m_Item.AssetID = " + m_Item.AssetID); + Console.WriteLine(" m_StartParam = " + m_StartParam); + Console.WriteLine(" m_PostOnRez = " + m_PostOnRez); + Console.WriteLine(" m_StateSource = " + m_StateSource); + Console.WriteLine(" m_SuspendCount = " + m_SuspendCount); + Console.WriteLine(" m_SleepUntil = " + m_SleepUntil); + Console.WriteLine(" m_IState = " + m_IState.ToString()); + Console.WriteLine(" m_StateCode = " + GetStateName(stateCode)); + Console.WriteLine(" eventCode = " + eventCode.ToString()); + Console.WriteLine(" m_LastRanAt = " + m_LastRanAt.ToString()); + Console.WriteLine(" heapUsed/Limit = " + xmrHeapUsed() + "/" + heapLimit); + Console.WriteLine(" m_InstEHEvent = " + m_InstEHEvent.ToString()); + Console.WriteLine(" m_InstEHSlice = " + m_InstEHSlice.ToString()); + } + } + + // Called by 'xmr ls' console command + // to dump this script's state to console + public string RunTestLs(bool flagFull) + { + if(flagFull) + { + StringBuilder sb = new StringBuilder(); + sb.AppendLine(m_DescName); + sb.AppendLine(" m_LocalID = " + m_LocalID); + sb.AppendLine(" m_ItemID = " + m_ItemID + " (.state file)"); + sb.AppendLine(" m_Item.AssetID = " + m_Item.AssetID); + sb.AppendLine(" m_Part.WorldPosition = " + m_Part.GetWorldPosition()); + sb.AppendLine(" m_ScriptObjCodeKey = " + m_ScriptObjCodeKey + " (source text)"); + sb.AppendLine(" m_StartParam = " + m_StartParam); + sb.AppendLine(" m_PostOnRez = " + m_PostOnRez); + sb.AppendLine(" m_StateSource = " + m_StateSource); + sb.AppendLine(" m_SuspendCount = " + m_SuspendCount); + sb.AppendLine(" m_SleepUntil = " + m_SleepUntil); + sb.AppendLine(" m_SleepEvMask1 = 0x" + m_SleepEventMask1.ToString("X")); + sb.AppendLine(" m_SleepEvMask2 = 0x" + m_SleepEventMask2.ToString("X")); + sb.AppendLine(" m_IState = " + m_IState.ToString()); + sb.AppendLine(" m_StateCode = " + GetStateName(stateCode)); + sb.AppendLine(" eventCode = " + eventCode.ToString()); + sb.AppendLine(" m_LastRanAt = " + m_LastRanAt.ToString()); + sb.AppendLine(" m_RunOnePhase = " + m_RunOnePhase); + sb.AppendLine(" suspOnCkRunHold = " + suspendOnCheckRunHold); + sb.AppendLine(" suspOnCkRunTemp = " + suspendOnCheckRunTemp); + sb.AppendLine(" m_CheckRunPhase = " + m_CheckRunPhase); + sb.AppendLine(" heapUsed/Limit = " + xmrHeapUsed() + "/" + heapLimit); + sb.AppendLine(" m_InstEHEvent = " + m_InstEHEvent.ToString()); + sb.AppendLine(" m_InstEHSlice = " + m_InstEHSlice.ToString()); + sb.AppendLine(" m_CPUTime = " + m_CPUTime); + sb.AppendLine(" callMode = " + callMode); + lock(m_QueueLock) + { + sb.AppendLine(" m_Running = " + m_Running); + foreach(EventParams evt in m_EventQueue) + { + sb.AppendLine(" evt.EventName = " + evt.EventName); + } + } + return sb.ToString(); + } + else + { + return String.Format("{0} {1} {2} {3} {4} {5}", + m_ItemID, + m_CPUTime.ToString("F3").PadLeft(9), + m_InstEHEvent.ToString().PadLeft(9), + m_IState.ToString().PadRight(10), + m_Part.GetWorldPosition().ToString().PadRight(32), + m_DescName); + } + } + + /** + * @brief For a given stateCode, get a mask of the low 32 event codes + * that the state has handlers defined for. + */ + public int GetStateEventFlags(int stateCode) + { + if((stateCode < 0) || + (stateCode >= m_ObjCode.scriptEventHandlerTable.GetLength(0))) + { + return 0; + } + + int code = 0; + for(int i = 0; i < 32; i++) + { + if(m_ObjCode.scriptEventHandlerTable[stateCode, i] != null) + { + code |= 1 << i; + } + } + + return code; + } + + /** + * @brief Get the .state file name. + */ + public static string GetStateFileName(string scriptBasePath, UUID itemID) + { + return GetScriptFileName(scriptBasePath, itemID.ToString() + ".state"); + } + + public string GetScriptFileName(string filename) + { + return GetScriptFileName(m_ScriptBasePath, filename); + } + + public static string GetScriptFileName(string scriptBasePath, string filename) + { + // Get old path, ie, all files lumped in a single huge directory. + string oldPath = Path.Combine(scriptBasePath, filename); + + // Get new path, ie, files split up based on first 2 chars of name. + // string subdir = filename.Substring (0, 2); + // filename = filename.Substring (2); + string subdir = filename.Substring(0, 1); + filename = filename.Substring(1); + scriptBasePath = Path.Combine(scriptBasePath, subdir); + Directory.CreateDirectory(scriptBasePath); + string newPath = Path.Combine(scriptBasePath, filename); + + // If file exists only in old location, move to new location. + // If file exists in both locations, delete old location. + if(File.Exists(oldPath)) + { + if(File.Exists(newPath)) + { + File.Delete(oldPath); + } + else + { + File.Move(oldPath, newPath); + } + } + + // Always return new location. + return newPath; + } + + /** + * @brief Decode state code (int) to state name (string). + */ + public string GetStateName(int stateCode) + { + try + { + return m_ObjCode.stateNames[stateCode]; + } + catch + { + return stateCode.ToString(); + } + } + + /** + * @brief various gets & sets. + */ + public int StartParam + { + get + { + return m_StartParam; + } + set + { + m_StartParam = value; + } + } + + public SceneObjectPart SceneObject + { + get + { + return m_Part; + } + } + + public DetectParams[] DetectParams + { + get + { + return m_DetectParams; + } + set + { + m_DetectParams = value; + } + } + + public UUID ItemID + { + get + { + return m_ItemID; + } + } + + public UUID AssetID + { + get + { + return m_Item.AssetID; + } + } + + public bool Running + { + get + { + return m_Running; + } + set + { + lock(m_QueueLock) + { + m_Running = value; + if(!value) + { + EmptyEventQueues(); + } + } + } + } + + /** + * @brief Empty out the event queues. + * Assumes caller has the m_QueueLock locked. + */ + public void EmptyEventQueues() + { + m_EventQueue.Clear(); + for(int i = m_EventCounts.Length; --i >= 0;) + m_EventCounts[i] = 0; + } + + /** + * @brief Convert an LSL vector to an Openmetaverse vector. + */ + public static OpenMetaverse.Vector3 LSLVec2OMVec(LSL_Vector lslVec) + { + return new OpenMetaverse.Vector3((float)lslVec.x, (float)lslVec.y, (float)lslVec.z); + } + + /** + * @brief Extract an integer from an element of an LSL_List. + */ + public static int ListInt(object element) + { + if(element is LSL_Integer) + { + return (int)(LSL_Integer)element; + } + return (int)element; + } + + /** + * @brief Extract a string from an element of an LSL_List. + */ + public static string ListStr(object element) + { + if(element is LSL_String) + { + return (string)(LSL_String)element; + } + return (string)element; + } + } +} diff --git a/OpenSim/Region/ScriptEngine/YEngine/XMRInstQueue.cs b/OpenSim/Region/ScriptEngine/YEngine/XMRInstQueue.cs new file mode 100644 index 0000000000..549fab5065 --- /dev/null +++ b/OpenSim/Region/ScriptEngine/YEngine/XMRInstQueue.cs @@ -0,0 +1,192 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; + +namespace OpenSim.Region.ScriptEngine.Yengine +{ + /** + * @brief Implements a queue of XMRInstance's. + * Do our own queue to avoid shitty little mallocs. + * + * Note: looping inst.m_NextInst and m_PrevInst back to itself + * when inst is removed from a queue is purely for debug. + */ + public class XMRInstQueue + { + private XMRInstance m_Head = null; + private XMRInstance m_Tail = null; + + /** + * @brief Insert instance at head of queue (in front of all others) + * @param inst = instance to insert + */ + public void InsertHead(XMRInstance inst) + { + if((inst.m_PrevInst != inst) || (inst.m_NextInst != inst)) + throw new Exception("already in list"); + + inst.m_PrevInst = null; + if((inst.m_NextInst = m_Head) == null) + m_Tail = inst; + else + m_Head.m_PrevInst = inst; + + m_Head = inst; + } + + /** + * @brief Insert instance at tail of queue (behind all others) + * @param inst = instance to insert + */ + public void InsertTail(XMRInstance inst) + { + if((inst.m_PrevInst != inst) || (inst.m_NextInst != inst)) + throw new Exception("already in list"); + + inst.m_NextInst = null; + if((inst.m_PrevInst = m_Tail) == null) + m_Head = inst; + else + m_Tail.m_NextInst = inst; + + m_Tail = inst; + } + + /** + * @brief Insert instance before another element in queue + * @param inst = instance to insert + * @param after = element that is to come after one being inserted + */ + public void InsertBefore(XMRInstance inst, XMRInstance after) + { + if((inst.m_PrevInst != inst) || (inst.m_NextInst != inst)) + throw new Exception("already in list"); + + if(after == null) + InsertTail(inst); + else + { + inst.m_NextInst = after; + inst.m_PrevInst = after.m_PrevInst; + if(inst.m_PrevInst == null) + m_Head = inst; + else + inst.m_PrevInst.m_NextInst = inst; + after.m_PrevInst = inst; + } + } + + /** + * @brief Peek to see if anything in queue + * @returns first XMRInstance in queue but doesn't remove it + * null if queue is empty + */ + public XMRInstance PeekHead() + { + return m_Head; + } + + /** + * @brief Remove first element from queue, if any + * @returns null if queue is empty + * else returns first element in queue and removes it + */ + public XMRInstance RemoveHead() + { + XMRInstance inst = m_Head; + if(inst != null) + { + if((m_Head = inst.m_NextInst) == null) + m_Tail = null; + else + m_Head.m_PrevInst = null; + + inst.m_NextInst = inst; + inst.m_PrevInst = inst; + } + return inst; + } + + /** + * @brief Remove last element from queue, if any + * @returns null if queue is empty + * else returns last element in queue and removes it + */ + public XMRInstance RemoveTail() + { + XMRInstance inst = m_Tail; + if(inst != null) + { + if((m_Tail = inst.m_PrevInst) == null) + m_Head = null; + else + m_Tail.m_NextInst = null; + + inst.m_NextInst = inst; + inst.m_PrevInst = inst; + } + return inst; + } + + /** + * @brief Remove arbitrary element from queue, if any + * @param inst = element to remove (assumed to be in the queue) + * @returns with element removed + */ + public void Remove(XMRInstance inst) + { + XMRInstance next = inst.m_NextInst; + XMRInstance prev = inst.m_PrevInst; + if((prev == inst) || (next == inst)) + throw new Exception("not in a list"); + + if(next == null) + { + if(m_Tail != inst) + throw new Exception("not in this list"); + + m_Tail = prev; + } + else + next.m_PrevInst = prev; + + if(prev == null) + { + if(m_Head != inst) + throw new Exception("not in this list"); + + m_Head = next; + } + else + prev.m_NextInst = next; + + inst.m_NextInst = inst; + inst.m_PrevInst = inst; + } + } +} diff --git a/OpenSim/Region/ScriptEngine/YEngine/XMRInstRun.cs b/OpenSim/Region/ScriptEngine/YEngine/XMRInstRun.cs new file mode 100644 index 0000000000..ce0823d9dd --- /dev/null +++ b/OpenSim/Region/ScriptEngine/YEngine/XMRInstRun.cs @@ -0,0 +1,915 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Threading; +using System.Collections.Generic; +using System.Text; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.ScriptEngine.Shared; +using OpenSim.Region.ScriptEngine.Shared.Api; +using OpenSim.Region.ScriptEngine.Shared.ScriptBase; +using OpenSim.Region.Framework.Scenes; +using log4net; + +using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; +using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; +using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; +using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list; +using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; +using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; +using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; + +namespace OpenSim.Region.ScriptEngine.Yengine +{ + public partial class XMRInstance + { + /************************************************************************************\ + * This module contains these externally useful methods: * + * PostEvent() - queues an event to script and wakes script thread to process it * + * RunOne() - runs script for a time slice or until it volunteers to give up cpu * + * CallSEH() - runs in the microthread to call the event handler * + \************************************************************************************/ + + /** + * @brief This can be called in any thread (including the script thread itself) + * to queue event to script for processing. + */ + public void PostEvent(EventParams evt) + { + ScriptEventCode evc = (ScriptEventCode)Enum.Parse(typeof(ScriptEventCode), + evt.EventName); + + // Put event on end of event queue. + bool startIt = false; + bool wakeIt = false; + lock(m_QueueLock) + { + bool construct = (m_IState == XMRInstState.CONSTRUCT); + + // Ignore event if we don't even have such an handler in any state. + // We can't be state-specific here because state might be different + // by the time this event is dequeued and delivered to the script. + if(!construct && // make sure m_HaveEventHandlers is filled in + ((uint)evc < (uint)m_HaveEventHandlers.Length) && + !m_HaveEventHandlers[(int)evc]) // don't bother if we don't have such a handler in any state + return; + + // Not running means we ignore any incoming events. + // But queue if still constructing because m_Running is not yet valid. + if(!m_Running && !construct) + return; + + // Only so many of each event type allowed to queue. + if((uint)evc < (uint)m_EventCounts.Length) + { + if(evc == ScriptEventCode.timer) + { + if(m_EventCounts[(int)evc] >= 1) + return; + } + else if(m_EventCounts[(int)evc] >= MAXEVENTQUEUE) + return; + + m_EventCounts[(int)evc]++; + } + + // Put event on end of instance's event queue. + LinkedListNode lln = new LinkedListNode(evt); + switch(evc) + { + // These need to go first. The only time we manually + // queue them is for the default state_entry() and we + // need to make sure they go before any attach() events + // so the heapLimit value gets properly initialized. + case ScriptEventCode.state_entry: + m_EventQueue.AddFirst(lln); + break; + + // The attach event sneaks to the front of the queue. + // This is needed for quantum limiting to work because + // we want the attach(NULL_KEY) event to come in front + // of all others so the m_DetachQuantum won't run out + // before attach(NULL_KEY) is executed. + case ScriptEventCode.attach: + if(evt.Params[0].ToString() == UUID.Zero.ToString()) + { + LinkedListNode lln2 = null; + for(lln2 = m_EventQueue.First; lln2 != null; lln2 = lln2.Next) + { + EventParams evt2 = lln2.Value; + ScriptEventCode evc2 = (ScriptEventCode)Enum.Parse(typeof(ScriptEventCode), + evt2.EventName); + if((evc2 != ScriptEventCode.state_entry) && + (evc2 != ScriptEventCode.attach)) + break; + } + if(lln2 == null) + m_EventQueue.AddLast(lln); + else + m_EventQueue.AddBefore(lln2, lln); + + // If we're detaching, limit the qantum. This will also + // cause the script to self-suspend after running this + // event + m_DetachReady.Reset(); + m_DetachQuantum = 100; + } + else + m_EventQueue.AddLast(lln); + + break; + + // All others just go on end in the order queued. + default: + m_EventQueue.AddLast(lln); + break; + } + + // If instance is idle (ie, not running or waiting to run), + // flag it to be on m_StartQueue as we are about to do so. + // Flag it now before unlocking so another thread won't try + // to do the same thing right now. + // Dont' flag it if it's still suspended! + if((m_IState == XMRInstState.IDLE) && !m_Suspended) + { + m_IState = XMRInstState.ONSTARTQ; + startIt = true; + } + + // If instance is sleeping (ie, possibly in xmrEventDequeue), + // wake it up if event is in the mask. + if((m_SleepUntil > DateTime.UtcNow) && !m_Suspended) + { + int evc1 = (int)evc; + int evc2 = evc1 - 32; + if((((uint)evc1 < (uint)32) && (((m_SleepEventMask1 >> evc1) & 1) != 0)) || + (((uint)evc2 < (uint)32) && (((m_SleepEventMask2 >> evc2) & 1) != 0))) + wakeIt = true; + } + } + + // If transitioned from IDLE->ONSTARTQ, actually go insert it + // on m_StartQueue and give the RunScriptThread() a wake-up. + if(startIt) + m_Engine.QueueToStart(this); + + // Likewise, if the event mask triggered a wake, wake it up. + if(wakeIt) + { + m_SleepUntil = DateTime.MinValue; + m_Engine.WakeFromSleep(this); + } + } + + // This is called in the script thread to step script until it calls + // CheckRun(). It returns what the instance's next state should be, + // ONSLEEPQ, ONYIELDQ, SUSPENDED or FINISHED. + public XMRInstState RunOne() + { + DateTime now = DateTime.UtcNow; + m_SliceStart = Util.GetTimeStampMS(); + + // If script has called llSleep(), don't do any more until time is up. + m_RunOnePhase = "check m_SleepUntil"; + if(m_SleepUntil > now) + { + m_RunOnePhase = "return is sleeping"; + return XMRInstState.ONSLEEPQ; + } + + // Also, someone may have called Suspend(). + m_RunOnePhase = "check m_SuspendCount"; + if(m_SuspendCount > 0) + { + m_RunOnePhase = "return is suspended"; + return XMRInstState.SUSPENDED; + } + + // Make sure we aren't being migrated in or out and prevent that + // whilst we are in here. If migration has it locked, don't call + // back right away, delay a bit so we don't get in infinite loop. + m_RunOnePhase = "lock m_RunLock"; + if(!Monitor.TryEnter(m_RunLock)) + { + m_SleepUntil = now.AddMilliseconds(3); + m_RunOnePhase = "return was locked"; + return XMRInstState.ONSLEEPQ; + } + try + { + m_RunOnePhase = "check entry invariants"; + CheckRunLockInvariants(true); + Exception e = null; + + // Maybe it has been Disposed() + if(m_Part == null) + { + m_RunOnePhase = "runone saw it disposed"; + return XMRInstState.DISPOSED; + } + + // Do some more of the last event if it didn't finish. + if(this.eventCode != ScriptEventCode.None) + { + lock(m_QueueLock) + { + if(m_DetachQuantum > 0 && --m_DetachQuantum == 0) + { + m_Suspended = true; + m_DetachReady.Set(); + m_RunOnePhase = "detach quantum went zero"; + CheckRunLockInvariants(true); + return XMRInstState.FINISHED; + } + } + + m_RunOnePhase = "resume old event handler"; + m_LastRanAt = now; + m_InstEHSlice++; + callMode = CallMode_NORMAL; + e = ResumeEx(); + } + + // Otherwise, maybe we can dequeue a new event and start + // processing it. + else + { + m_RunOnePhase = "lock event queue"; + EventParams evt = null; + ScriptEventCode evc = ScriptEventCode.None; + + lock(m_QueueLock) + { + + // We can't get here unless the script has been resumed + // after creation, then suspended again, and then had + // an event posted to it. We just pretend there is no + // event int he queue and let the normal mechanics + // carry out the suspension. A Resume will handle the + // restarting gracefully. This is taking the easy way + // out and may be improved in the future. + + if(m_Suspended) + { + m_RunOnePhase = "m_Suspended is set"; + CheckRunLockInvariants(true); + return XMRInstState.FINISHED; + } + + m_RunOnePhase = "dequeue event"; + if(m_EventQueue.First != null) + { + evt = m_EventQueue.First.Value; + if(m_DetachQuantum > 0) + { + evc = (ScriptEventCode)Enum.Parse(typeof(ScriptEventCode), + evt.EventName); + if(evc != ScriptEventCode.attach) + { + // This is the case where the attach event + // has completed and another event is queued + // Stop it from running and suspend + m_Suspended = true; + m_DetachReady.Set(); + m_DetachQuantum = 0; + m_RunOnePhase = "nothing to do #3"; + CheckRunLockInvariants(true); + return XMRInstState.FINISHED; + } + } + m_EventQueue.RemoveFirst(); + evc = (ScriptEventCode)Enum.Parse(typeof(ScriptEventCode), + evt.EventName); + if((int)evc >= 0) + m_EventCounts[(int)evc]--; + } + + // If there is no event to dequeue, don't run this script + // until another event gets queued. + if(evt == null) + { + if(m_DetachQuantum > 0) + { + // This will happen if the attach event has run + // and exited with time slice left. + m_Suspended = true; + m_DetachReady.Set(); + m_DetachQuantum = 0; + } + m_RunOnePhase = "nothing to do #4"; + CheckRunLockInvariants(true); + return XMRInstState.FINISHED; + } + } + + // Dequeued an event, so start it going until it either + // finishes or it calls CheckRun(). + m_RunOnePhase = "start event handler"; + m_DetectParams = evt.DetectParams; + m_LastRanAt = now; + m_InstEHEvent++; + e = StartEventHandler(evc, evt.Params); + } + m_RunOnePhase = "done running"; + m_CPUTime += DateTime.UtcNow.Subtract(now).TotalMilliseconds; + + // Maybe it puqued. + if(e != null) + { + m_RunOnePhase = "handling exception " + e.Message; + HandleScriptException(e); + m_RunOnePhase = "return had exception " + e.Message; + CheckRunLockInvariants(true); + return XMRInstState.FINISHED; + } + + // If event handler completed, get rid of detect params. + if(this.eventCode == ScriptEventCode.None) + m_DetectParams = null; + + } + finally + { + m_RunOnePhase += "; checking exit invariants and unlocking"; + CheckRunLockInvariants(false); + Monitor.Exit(m_RunLock); + } + + // Cycle script through the yield queue and call it back asap. + m_RunOnePhase = "last return"; + return XMRInstState.ONYIELDQ; + } + + /** + * @brief Immediately after taking m_RunLock or just before releasing it, check invariants. + */ + private ScriptEventCode lastEventCode = ScriptEventCode.None; + private bool lastActive = false; + private string lastRunPhase = ""; + + public void CheckRunLockInvariants(bool throwIt) + { + // If not executing any event handler, there shouldn't be any saved stack frames. + // If executing an event handler, there should be some saved stack frames. + bool active = (stackFrames != null); + ScriptEventCode ec = this.eventCode; + if(((ec == ScriptEventCode.None) && active) || + ((ec != ScriptEventCode.None) && !active)) + { + m_log.Error("CheckRunLockInvariants: script=" + m_DescName); + m_log.Error("CheckRunLockInvariants: eventcode=" + ec.ToString() + ", active=" + active.ToString()); + m_log.Error("CheckRunLockInvariants: m_RunOnePhase=" + m_RunOnePhase); + m_log.Error("CheckRunLockInvariants: lastec=" + lastEventCode + ", lastAct=" + lastActive + ", lastPhase=" + lastRunPhase); + if(throwIt) + throw new Exception("CheckRunLockInvariants: eventcode=" + ec.ToString() + ", active=" + active.ToString()); + } + lastEventCode = ec; + lastActive = active; + lastRunPhase = m_RunOnePhase; + } + + /* + * Start event handler. + * + * Input: + * newEventCode = code of event to be processed + * newEhArgs = arguments for the event handler + * + * Caution: + * It is up to the caller to make sure ehArgs[] is correct for + * the particular event handler being called. The first thing + * a script event handler method does is to unmarshall the args + * from ehArgs[] and will throw an array bounds or cast exception + * if it can't. + */ + private Exception StartEventHandler(ScriptEventCode newEventCode, object[] newEhArgs) + { + // We use this.eventCode == ScriptEventCode.None to indicate we are idle. + // So trying to execute ScriptEventCode.None might make a mess. + if(newEventCode == ScriptEventCode.None) + return new Exception("Can't process ScriptEventCode.None"); + + // Silly to even try if there is no handler defined for this event. + if(((int)newEventCode >= 0) && (m_ObjCode.scriptEventHandlerTable[this.stateCode, (int)newEventCode] == null)) + return null; + + // The microthread shouldn't be processing any event code. + // These are assert checks so we throw them directly as exceptions. + if(this.eventCode != ScriptEventCode.None) + throw new Exception("still processing event " + this.eventCode.ToString()); + + // Save eventCode so we know what event handler to run in the microthread. + // And it also marks us busy so we can't be started again and this event lost. + this.eventCode = newEventCode; + this.ehArgs = newEhArgs; + + // This calls ScriptUThread.Main() directly, and returns when Main() [indirectly] + // calls Suspend() or when Main() returns, whichever occurs first. + // Setting stackFrames = null means run the event handler from the beginning + // without doing any stack frame restores first. + this.stackFrames = null; + return StartEx(); + } + + /** + * @brief There was an exception whilst starting/running a script event handler. + * Maybe we handle it directly or just print an error message. + */ + private void HandleScriptException(Exception e) + { + // The script threw some kind of exception that was not caught at + // script level, so the script is no longer running an event handler. + eventCode = ScriptEventCode.None; + stackFrames = null; + + if (e is ScriptDeleteException) + { + // Script did something like llRemoveInventory(llGetScriptName()); + // ... to delete itself from the object. + m_SleepUntil = DateTime.MaxValue; + Verbose("[YEngine]: script self-delete {0}", m_ItemID); + m_Part.Inventory.RemoveInventoryItem(m_ItemID); + } + else if(e is ScriptDieException) + { + // Script did an llDie() + m_RunOnePhase = "dying..."; + m_SleepUntil = DateTime.MaxValue; + m_Engine.World.DeleteSceneObject(m_Part.ParentGroup, false); + } + else if(e is ScriptResetException) + { + // Script did an llResetScript(). + m_RunOnePhase = "resetting..."; + ResetLocked("HandleScriptResetException"); + } + else + { + // Some general script error. + SendErrorMessage(e); + } + } + + /** + * @brief There was an exception running script event handler. + * Display error message and disable script (in a way + * that the script can be reset to be restarted). + */ + private void SendErrorMessage(Exception e) + { + StringBuilder msg = new StringBuilder(); + + msg.Append("[YEngine]: Exception while running "); + msg.Append(m_ItemID); + msg.Append('\n'); + + // Add exception message. + string des = e.Message; + des = (des == null) ? "" : (": " + des); + msg.Append(e.GetType().Name + des + "\n"); + + // Tell script owner what to do. + msg.Append("Prim: <"); + msg.Append(m_Part.Name); + msg.Append(">, Script: <"); + msg.Append(m_Item.Name); + msg.Append(">, Location: "); + msg.Append(m_Engine.World.RegionInfo.RegionName); + msg.Append(" <"); + Vector3 pos = m_Part.AbsolutePosition; + msg.Append((int)Math.Floor(pos.X)); + msg.Append(','); + msg.Append((int)Math.Floor(pos.Y)); + msg.Append(','); + msg.Append((int)Math.Floor(pos.Z)); + msg.Append(">\nScript must be Reset to re-enable.\n"); + + // Display full exception message in log. + m_log.Info(msg.ToString() + XMRExceptionStackString(e), e); + + // Give script owner the stack dump. + msg.Append(XMRExceptionStackString(e)); + + // Send error message to owner. + // Suppress internal code stack trace lines. + string msgst = msg.ToString(); + if(!msgst.EndsWith("\n")) + msgst += '\n'; + int j = 0; + StringBuilder imstr = new StringBuilder(); + for(int i = 0; (i = msgst.IndexOf('\n', i)) >= 0; j = ++i) + { + string line = msgst.Substring(j, i - j); + if(line.StartsWith("at ")) + { + if(line.StartsWith("at (wrapper")) + continue; // at (wrapper ... + int k = line.LastIndexOf(".cs:"); // ... .cs:linenumber + if(Int32.TryParse(line.Substring(k + 4), out k)) + continue; + } + this.llOwnerSay(line); + imstr.Append(line); + imstr.Append('\n'); + } + + // Send as instant message in case user not online. + // Code modelled from llInstantMessage(). + IMessageTransferModule transferModule = m_Engine.World.RequestModuleInterface(); + if(transferModule != null) + { + UUID friendTransactionID = UUID.Random(); + GridInstantMessage gim = new GridInstantMessage(); + gim.fromAgentID = new Guid(m_Part.UUID.ToString()); + gim.toAgentID = new Guid(m_Part.OwnerID.ToString()); + gim.imSessionID = new Guid(friendTransactionID.ToString()); + gim.timestamp = (uint)Util.UnixTimeSinceEpoch(); + gim.message = imstr.ToString(); + gim.dialog = (byte)19; // messgage from script + gim.fromGroup = false; + gim.offline = (byte)0; + gim.ParentEstateID = 0; + gim.Position = pos; + gim.RegionID = m_Engine.World.RegionInfo.RegionID.Guid; + gim.binaryBucket = Util.StringToBytes256( + "{0}/{1}/{2}/{3}", + m_Engine.World.RegionInfo.RegionName, + (int)Math.Floor(pos.X), + (int)Math.Floor(pos.Y), + (int)Math.Floor(pos.Z)); + transferModule.SendInstantMessage(gim, delegate (bool success) + { + }); + } + + // Say script is sleeping for a very long time. + // Reset() is able to cancel this sleeping. + m_SleepUntil = DateTime.MaxValue; + } + + /** + * @brief The user clicked the Reset Script button. + * We want to reset the script to a never-has-ever-run-before state. + */ + public void Reset() + { + checkstate: + XMRInstState iState = m_IState; + switch(iState) + { + // If it's really being constructed now, that's about as reset as we get. + case XMRInstState.CONSTRUCT: + return; + + // If it's idle, that means it is ready to receive a new event. + // So we lock the event queue to prevent another thread from taking + // it out of idle, verify that it is still in idle then transition + // it to resetting so no other thread will touch it. + case XMRInstState.IDLE: + lock(m_QueueLock) + { + if(m_IState == XMRInstState.IDLE) + { + m_IState = XMRInstState.RESETTING; + break; + } + } + goto checkstate; + + // If it's on the start queue, that means it is about to dequeue an + // event and start processing it. So we lock the start queue so it + // can't be started and transition it to resetting so no other thread + // will touch it. + case XMRInstState.ONSTARTQ: + lock(m_Engine.m_StartQueue) + { + if(m_IState == XMRInstState.ONSTARTQ) + { + m_Engine.m_StartQueue.Remove(this); + m_IState = XMRInstState.RESETTING; + break; + } + } + goto checkstate; + + // If it's running, tell CheckRun() to suspend the thread then go back + // to see what it got transitioned to. + case XMRInstState.RUNNING: + suspendOnCheckRunHold = true; + lock(m_QueueLock) + { + } + goto checkstate; + + // If it's sleeping, remove it from sleep queue and transition it to + // resetting so no other thread will touch it. + case XMRInstState.ONSLEEPQ: + lock(m_Engine.m_SleepQueue) + { + if(m_IState == XMRInstState.ONSLEEPQ) + { + m_Engine.m_SleepQueue.Remove(this); + m_IState = XMRInstState.RESETTING; + break; + } + } + goto checkstate; + + // It was just removed from the sleep queue and is about to be put + // on the yield queue (ie, is being woken up). + // Let that thread complete transition and try again. + case XMRInstState.REMDFROMSLPQ: + Sleep(10); + goto checkstate; + + // If it's yielding, remove it from yield queue and transition it to + // resetting so no other thread will touch it. + case XMRInstState.ONYIELDQ: + lock(m_Engine.m_YieldQueue) + { + if(m_IState == XMRInstState.ONYIELDQ) + { + m_Engine.m_YieldQueue.Remove(this); + m_IState = XMRInstState.RESETTING; + break; + } + } + goto checkstate; + + // If it just finished running something, let that thread transition it + // to its next state then check again. + case XMRInstState.FINISHED: + Sleep(10); + goto checkstate; + + // If it's disposed, that's about as reset as it gets. + case XMRInstState.DISPOSED: + return; + + // Some other thread is already resetting it, let it finish. + + case XMRInstState.RESETTING: + return; + + default: + throw new Exception("bad state"); + } + + // This thread transitioned the instance to RESETTING so reset it. + lock(m_RunLock) + { + CheckRunLockInvariants(true); + + // No other thread should have transitioned it from RESETTING. + if(m_IState != XMRInstState.RESETTING) + throw new Exception("bad state"); + + // Mark it idle now so it can get queued to process new stuff. + m_IState = XMRInstState.IDLE; + + // Reset everything and queue up default's start_entry() event. + ClearQueue(); + ResetLocked("external Reset"); + + CheckRunLockInvariants(true); + } + } + + private void ClearQueueExceptLinkMessages() + { + lock(m_QueueLock) + { + EventParams[] linkMessages = new EventParams[m_EventQueue.Count]; + int n = 0; + foreach(EventParams evt2 in m_EventQueue) + { + if(evt2.EventName == "link_message") + linkMessages[n++] = evt2; + } + + m_EventQueue.Clear(); + for(int i = m_EventCounts.Length; --i >= 0;) + m_EventCounts[i] = 0; + + for(int i = 0; i < n; i++) + m_EventQueue.AddLast(linkMessages[i]); + + m_EventCounts[(int)ScriptEventCode.link_message] = n; + } + } + + private void ClearQueue() + { + lock(m_QueueLock) + { + m_EventQueue.Clear(); // no events queued + for(int i = m_EventCounts.Length; --i >= 0;) + m_EventCounts[i] = 0; + } + } + + /** + * @brief The script called llResetScript() while it was running and + * has suspended. We want to reset the script to a never-has- + * ever-run-before state. + * + * Caller must have m_RunLock locked so we know script isn't + * running. + */ + private void ResetLocked(string from) + { + m_RunOnePhase = "ResetLocked: releasing controls"; + ReleaseControls(); + + m_RunOnePhase = "ResetLocked: removing script"; + m_Part.Inventory.GetInventoryItem(m_ItemID).PermsMask = 0; + m_Part.Inventory.GetInventoryItem(m_ItemID).PermsGranter = UUID.Zero; + IUrlModule urlModule = m_Engine.World.RequestModuleInterface(); + if(urlModule != null) + urlModule.ScriptRemoved(m_ItemID); + + AsyncCommandManager.RemoveScript(m_Engine, m_LocalID, m_ItemID); + + m_RunOnePhase = "ResetLocked: clearing current event"; + this.eventCode = ScriptEventCode.None; // not processing an event + m_DetectParams = null; // not processing an event + m_SleepUntil = DateTime.MinValue; // not doing llSleep() + m_ResetCount++; // has been reset once more + + // Tell next call to 'default state_entry()' to reset all global + // vars to their initial values. + doGblInit = true; + + // Throw away all its stack frames. + // If the script is resetting itself, there shouldn't be any stack frames. + // If the script is being reset by something else, we throw them away cuz we want to start from the beginning of an event handler. + stackFrames = null; + + // Set script to 'default' state and queue call to its + // 'state_entry()' event handler. + m_RunOnePhase = "ResetLocked: posting default:state_entry() event"; + stateCode = 0; + m_Part.SetScriptEvents(m_ItemID, GetStateEventFlags(0)); + PostEvent(new EventParams("state_entry", + zeroObjectArray, + zeroDetectParams)); + + // Tell CheckRun() to let script run. + suspendOnCheckRunHold = false; + suspendOnCheckRunTemp = false; + m_RunOnePhase = "ResetLocked: reset complete"; + } + + private void ReleaseControls() + { + if(m_Part != null) + { + bool found; + int permsMask; + UUID permsGranter; + + try + { + permsGranter = m_Part.TaskInventory[m_ItemID].PermsGranter; + permsMask = m_Part.TaskInventory[m_ItemID].PermsMask; + found = true; + } + catch + { + permsGranter = UUID.Zero; + permsMask = 0; + found = false; + } + + if(found && ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0)) + { + ScenePresence presence = m_Engine.World.GetScenePresence(permsGranter); + if(presence != null) + presence.UnRegisterControlEventsToScript(m_LocalID, m_ItemID); + } + } + } + + /** + * @brief The script code should call this routine whenever it is + * convenient to perform a migation or switch microthreads. + */ + public override void CheckRunWork() + { + if(!suspendOnCheckRunHold && !suspendOnCheckRunTemp) + { + if(Util.GetTimeStampMS() - m_SliceStart < 60.0) + return; + suspendOnCheckRunTemp = true; + } + m_CheckRunPhase = "entered"; + + // Stay stuck in this loop as long as something wants us suspended. + while(suspendOnCheckRunHold || suspendOnCheckRunTemp) + { + m_CheckRunPhase = "top of while"; + suspendOnCheckRunTemp = false; + + switch(this.callMode) + { + // Now we are ready to suspend or resume. + case CallMode_NORMAL: + m_CheckRunPhase = "suspending"; + callMode = XMRInstance.CallMode_SAVE; + stackFrames = null; + throw new StackHibernateException(); // does not return + + // We get here when the script state has been read in by MigrateInEventHandler(). + // Since the stack is completely restored at this point, any subsequent calls + // within the functions should do their normal processing instead of trying to + // restore their state. + + // the stack has been restored as a result of calling ResumeEx() + // tell script code to process calls normally + case CallMode_RESTORE: + this.callMode = CallMode_NORMAL; + break; + + default: + throw new Exception("callMode=" + callMode); + } + + m_CheckRunPhase = "resumed"; + } + + m_CheckRunPhase = "returning"; + + // Upon return from CheckRun() it should always be the case that the script is + // going to process calls normally, neither saving nor restoring stack frame state. + if(callMode != CallMode_NORMAL) + throw new Exception("bad callMode " + callMode); + } + + /** + * @brief Allow script to dequeue events. + */ + public void ResumeIt() + { + lock(m_QueueLock) + { + m_Suspended = false; + if((m_EventQueue != null) && + (m_EventQueue.First != null) && + (m_IState == XMRInstState.IDLE)) + { + m_IState = XMRInstState.ONSTARTQ; + m_Engine.QueueToStart(this); + } + m_HasRun = true; + } + } + + /** + * @brief Block script from dequeuing events. + */ + public void SuspendIt() + { + lock(m_QueueLock) + { + m_Suspended = true; + } + } + } + + /** + * @brief Thrown by CheckRun() to unwind the script stack, capturing frames to + * instance.stackFrames as it unwinds. We don't want scripts to be able + * to intercept this exception as it would block the stack capture + * functionality. + */ + public class StackCaptureException: Exception, IXMRUncatchable + { + } +} diff --git a/OpenSim/Region/ScriptEngine/YEngine/XMRObjectTokens.cs b/OpenSim/Region/ScriptEngine/YEngine/XMRObjectTokens.cs new file mode 100644 index 0000000000..b54e14cb07 --- /dev/null +++ b/OpenSim/Region/ScriptEngine/YEngine/XMRObjectTokens.cs @@ -0,0 +1,6225 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using OpenSim.Region.ScriptEngine.Shared.ScriptBase; +using System; +using System.Collections.Generic; +using System.IO; +using System.Reflection; +using System.Reflection.Emit; +using System.Text; + +using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; +using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; +using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; +using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list; +using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; +using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; +using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; + +/** + * Contains classes that disassemble or decompile an yobj file. + * See xmrengcomp.cx utility program. + */ + +namespace OpenSim.Region.ScriptEngine.Yengine +{ + /* + * Encapsulate object code for a method. + */ + public abstract class ObjectTokens + { + public ScriptObjCode scriptObjCode; + + public ObjectTokens(ScriptObjCode scriptObjCode) + { + this.scriptObjCode = scriptObjCode; + } + + public abstract void Close(); + public abstract void BegMethod(DynamicMethod method); + public abstract void EndMethod(); + public abstract void DefineLabel(int number, string name); + public abstract void DefineLocal(int number, string name, string type, Type syType); + public abstract void DefineMethod(string methName, Type retType, Type[] argTypes, string[] argNames); + public abstract void MarkLabel(int offset, int number); + public abstract void BegExcBlk(int offset); + public abstract void BegCatBlk(int offset, Type excType); + public abstract void BegFinBlk(int offset); + public abstract void EndExcBlk(int offset); + public abstract void EmitNull(int offset, OpCode opCode); + public abstract void EmitField(int offset, OpCode opCode, FieldInfo field); + public abstract void EmitLocal(int offset, OpCode opCode, int number); + public abstract void EmitType(int offset, OpCode opCode, Type type); + public abstract void EmitLabel(int offset, OpCode opCode, int number); + public abstract void EmitLabels(int offset, OpCode opCode, int[] numbers); + public abstract void EmitMethod(int offset, OpCode opCode, MethodInfo method); + public abstract void EmitCtor(int offset, OpCode opCode, ConstructorInfo ctor); + public abstract void EmitDouble(int offset, OpCode opCode, double value); + public abstract void EmitFloat(int offset, OpCode opCode, float value); + public abstract void EmitInteger(int offset, OpCode opCode, int value); + public abstract void EmitString(int offset, OpCode opCode, string value); + } + + /******************\ + * DISASSEMBLER * + \******************/ + + public class OTDisassemble: ObjectTokens + { + private static readonly int OPCSTRWIDTH = 12; + + private Dictionary labelNames; + private Dictionary localNames; + private StringBuilder lbuf = new StringBuilder(); + private TextWriter twout; + + public OTDisassemble(ScriptObjCode scriptObjCode, TextWriter twout) : base(scriptObjCode) + { + this.twout = twout; + } + + public override void Close() + { + twout.WriteLine("TheEnd."); + } + + /** + * About to generate object code for this method. + */ + public override void BegMethod(DynamicMethod method) + { + labelNames = new Dictionary(); + localNames = new Dictionary(); + + twout.WriteLine(""); + + lbuf.Append(method.ReturnType.Name); + lbuf.Append(' '); + lbuf.Append(method.Name); + + ParameterInfo[] parms = method.GetParameters(); + int nArgs = parms.Length; + lbuf.Append(" ("); + for(int i = 0; i < nArgs; i++) + { + if(i > 0) + lbuf.Append(", "); + lbuf.Append(parms[i].ParameterType.Name); + } + lbuf.Append(')'); + FlushLine(); + + lbuf.Append('{'); + FlushLine(); + } + + /** + * Dump out reconstructed source for this method. + */ + public override void EndMethod() + { + lbuf.Append('}'); + FlushLine(); + } + + /** + * Add instructions to stream. + */ + public override void DefineLabel(int number, string name) + { + labelNames[number] = name + "$" + number; + } + + public override void DefineLocal(int number, string name, string type, Type syType) + { + localNames[number] = name + "$" + number; + + lbuf.Append(" "); + lbuf.Append(type.PadRight(OPCSTRWIDTH - 1)); + lbuf.Append(' '); + lbuf.Append(localNames[number]); + FlushLine(); + } + + public override void DefineMethod(string methName, Type retType, Type[] argTypes, string[] argNames) + { + } + + public override void MarkLabel(int offset, int number) + { + LinePrefix(offset); + lbuf.Append(labelNames[number]); + lbuf.Append(":"); + FlushLine(); + } + + public override void BegExcBlk(int offset) + { + LinePrefix(offset); + lbuf.Append(" BeginExceptionBlock"); + FlushLine(); + } + + public override void BegCatBlk(int offset, Type excType) + { + LinePrefix(offset); + lbuf.Append(" BeginCatchBlock "); + lbuf.Append(excType.Name); + FlushLine(); + } + + public override void BegFinBlk(int offset) + { + LinePrefix(offset); + lbuf.Append(" BeginFinallyBlock"); + FlushLine(); + } + + public override void EndExcBlk(int offset) + { + LinePrefix(offset); + lbuf.Append(" EndExceptionBlock"); + FlushLine(); + } + + public override void EmitNull(int offset, OpCode opCode) + { + LinePrefix(offset, opCode); + FlushLine(); + } + + public override void EmitField(int offset, OpCode opCode, FieldInfo field) + { + LinePrefix(offset, opCode); + lbuf.Append(field.DeclaringType.Name); + lbuf.Append(':'); + lbuf.Append(field.Name); + lbuf.Append(" -> "); + lbuf.Append(field.FieldType.Name); + lbuf.Append(" (field)"); + FlushLine(); + } + + public override void EmitLocal(int offset, OpCode opCode, int number) + { + LinePrefix(offset, opCode); + lbuf.Append(localNames[number]); + lbuf.Append(" (local)"); + FlushLine(); + } + + public override void EmitType(int offset, OpCode opCode, Type type) + { + LinePrefix(offset, opCode); + lbuf.Append(type.Name); + lbuf.Append(" (type)"); + FlushLine(); + } + + public override void EmitLabel(int offset, OpCode opCode, int number) + { + LinePrefix(offset, opCode); + lbuf.Append(labelNames[number]); + lbuf.Append(" (label)"); + FlushLine(); + } + + public override void EmitLabels(int offset, OpCode opCode, int[] numbers) + { + LinePrefix(offset, opCode); + + int lineLen = lbuf.Length; + int nLabels = numbers.Length; + for(int i = 0; i < nLabels; i++) + { + if(i > 0) + { + lbuf.AppendLine(); + lbuf.Append(",".PadLeft(lineLen)); + } + lbuf.Append(labelNames[numbers[i]]); + } + + FlushLine(); + } + + public override void EmitMethod(int offset, OpCode opCode, MethodInfo method) + { + LinePrefix(offset, opCode); + + ParameterInfo[] parms = method.GetParameters(); + int nArgs = parms.Length; + if(method.DeclaringType != null) + { + lbuf.Append(method.DeclaringType.Name); + lbuf.Append(':'); + } + lbuf.Append(method.Name); + lbuf.Append('('); + for(int i = 0; i < nArgs; i++) + { + if(i > 0) + lbuf.Append(","); + lbuf.Append(parms[i].ParameterType.Name); + } + lbuf.Append(") -> "); + lbuf.Append(method.ReturnType.Name); + + FlushLine(); + } + + public override void EmitCtor(int offset, OpCode opCode, ConstructorInfo ctor) + { + LinePrefix(offset, opCode); + + ParameterInfo[] parms = ctor.GetParameters(); + int nArgs = parms.Length; + lbuf.Append(ctor.DeclaringType.Name); + lbuf.Append(":("); + for(int i = 0; i < nArgs; i++) + { + if(i > 0) + lbuf.Append(","); + lbuf.Append(parms[i].ParameterType.Name); + } + lbuf.Append(")"); + + FlushLine(); + } + + public override void EmitDouble(int offset, OpCode opCode, double value) + { + LinePrefix(offset, opCode); + lbuf.Append(value.ToString()); + lbuf.Append(" (double)"); + FlushLine(); + } + + public override void EmitFloat(int offset, OpCode opCode, float value) + { + LinePrefix(offset, opCode); + lbuf.Append(value.ToString()); + lbuf.Append(" (float)"); + FlushLine(); + } + + public override void EmitInteger(int offset, OpCode opCode, int value) + { + LinePrefix(offset, opCode); + lbuf.Append(value.ToString()); + lbuf.Append(" (int)"); + FlushLine(); + } + + public override void EmitString(int offset, OpCode opCode, string value) + { + LinePrefix(offset, opCode); + lbuf.Append("\""); + lbuf.Append(value); + lbuf.Append("\" (string)"); + FlushLine(); + } + + /** + * Put offset and opcode at beginning of line. + */ + private void LinePrefix(int offset, OpCode opCode) + { + LinePrefix(offset); + lbuf.Append(" "); + lbuf.Append(opCode.ToString().PadRight(OPCSTRWIDTH - 1)); + lbuf.Append(' '); + } + + private void LinePrefix(int offset) + { + lbuf.Append(" "); + lbuf.Append(offset.ToString("X4")); + lbuf.Append(" "); + } + + /** + * Flush line buffer to output file. + */ + private void FlushLine() + { + if(lbuf.Length > 0) + { + twout.WriteLine(lbuf.ToString()); + lbuf.Remove(0, lbuf.Length); + } + } + } + + /****************\ + * DECOMPILER * + \****************/ + + /** + * Note: The decompiler does not handle any xmroption extensions + * such as &&&, |||, ? operators and switch statements, as + * they do branches with a non-empty stack, which is way + * beyond this code's ability to analyze. + */ + + public class OTDecompile: ObjectTokens + { + public const string _mainCallNo = "__mainCallNo$"; + public const string _callLabel = "__call_"; + public const string _callMode = "callMode"; + public const string _checkRunQuick = "CheckRunQuick"; + public const string _checkRunStack = "CheckRunStack"; + public const string _cmRestore = "__cmRestore"; + public const string _doBreak = "dobreak_"; + public const string _doCont = "docont_"; + public const string _doGblInit = "doGblInit"; + public const string _doLoop = "doloop_"; + public const string _ehArgs = "ehArgs"; + public const string _forBreak = "forbreak_"; + public const string _forCont = "forcont_"; + public const string _forLoop = "forloop_"; + public const string _globalvarinit = "$globalvarinit()"; + public const string _heapTrackerPop = "Pop"; + public const string _heapTrackerPush = "Push"; + public const string _ifDone = "ifdone_"; + public const string _ifElse = "ifelse_"; + public const string _llAbstemp = "llAbstemp"; + public const string _retlbl = "__retlbl"; + public const string _retval = "__retval$"; + public const string _whileBreak = "whilebreak_"; + public const string _whileCont = "whilecont_"; + public const string _whileLoop = "whileloop_"; + public const string _xmrinst = "__xmrinst"; + public const string _xmrinstlocal = "__xmrinst$"; + + private const string INDENT = " "; + private const string LABELINDENT = " "; + + private static Dictionary typeTranslator = InitTypeTranslator(); + private static Dictionary InitTypeTranslator() + { + Dictionary d = new Dictionary(); + d["Boolean"] = "integer"; + d["bool"] = "integer"; + d["Double"] = "float"; + d["double"] = "float"; + d["Int32"] = "integer"; + d["int"] = "integer"; + d["htlist"] = "list"; + d["htobject"] = "object"; + d["htstring"] = "string"; + d["lslfloat"] = "float"; + d["lslint"] = "integer"; + d["lsllist"] = "list"; + d["lslrot"] = "rotation"; + d["lslstr"] = "string"; + d["lslvec"] = "vector"; + d["Quaternion"] = "rotation"; + d["String"] = "string"; + d["Vector3"] = "vector"; + return d; + } + + private Dictionary eharglist; + private Dictionary labels; + private Dictionary locals; + private Dictionary methargnames; + private LinkedList cilinstrs; + private OTStmtBlock topBlock; + private Stack opstack; + private Stack trystack; + private Stack blockstack; + + private int dupNo; + private DynamicMethod method; + private string laststate; + private TextWriter twout; + + public OTDecompile(ScriptObjCode scriptObjCode, TextWriter twout) : base(scriptObjCode) + { + this.twout = twout; + twout.Write("xmroption dollarsigns;"); + methargnames = new Dictionary(); + } + + public override void Close() + { + if(laststate != null) + { + twout.Write("\n}"); + laststate = null; + } + twout.Write('\n'); + } + + /** + * About to generate object code for this method. + */ + public override void BegMethod(DynamicMethod method) + { + this.method = method; + + eharglist = new Dictionary(); + labels = new Dictionary(); + locals = new Dictionary(); + cilinstrs = new LinkedList(); + opstack = new Stack(); + trystack = new Stack(); + blockstack = new Stack(); + + dupNo = 0; + } + + /** + * Dump out reconstructed source for this method. + */ + public override void EndMethod() + { + // Convert CIL code to primitive statements. + // There are a bunch of labels and internal code such as call stack save restore. + topBlock = new OTStmtBlock(); + blockstack.Push(topBlock); + for(LinkedListNode link = cilinstrs.First; link != null; link = link.Next) + { + link.Value.BuildStatements(this, link); + } + + // Strip out stuff we don't want, such as references to callMode. + // This strips out stack frame capture and restore code. + topBlock.StripStuff(null); + + // including a possible final return statement + // - delete if void return value + // - delete if returning __retval cuz we converted all __retval assignments to return statements + if((topBlock.blkstmts.Last != null) && (topBlock.blkstmts.Last.Value is OTStmtRet)) + { + OTStmtRet finalret = (OTStmtRet)topBlock.blkstmts.Last.Value; + if((finalret.value == null) || + ((finalret.value is OTOpndLocal) && + ((OTOpndLocal)finalret.value).local.name.StartsWith(_retval))) + { + topBlock.blkstmts.RemoveLast(); + } + } + + // At this point, all behind-the-scenes references are removed except + // that the do/for/if/while blocks are represented by OTStmtCont-style + // if/jumps. So try to convert them to the higher-level structures. + topBlock.DetectDoForIfWhile(null); + + // Final strip to get rid of unneeded @forbreak_; labels and the like. + topBlock.StripStuff(null); + + // Build reference counts so we don't output unneeded declarations, + // especially temps and internal variables. + foreach(OTLocal local in locals.Values) + { + local.nlclreads = 0; + local.nlclwrites = 0; + } + topBlock.CountRefs(); + for(IEnumerator localenum = locals.Keys.GetEnumerator(); localenum.MoveNext();) + { + OTLocal local = locals[localenum.Current]; + if(((local.nlclreads | local.nlclwrites) == 0) || local.name.StartsWith(_xmrinstlocal)) + { + locals.Remove(localenum.Current); + localenum = locals.Keys.GetEnumerator(); + } + } + + // Strip the $n off of local vars that are not ambiguous. + // Make sure they don't mask globals and arguments as well. + Dictionary namecounts = new Dictionary(); + foreach(Dictionary varnames in scriptObjCode.globalVarNames.Values) + { + foreach(string varname in varnames.Values) + { + int count; + if(!namecounts.TryGetValue(varname, out count)) + count = 0; + namecounts[varname] = count + 1; + } + } + if(methargnames.ContainsKey(method.Name)) + { + foreach(string argname in methargnames[method.Name]) + { + int count; + if(!namecounts.TryGetValue(argname, out count)) + count = 0; + namecounts[argname] = count + 1; + } + } + foreach(OTLocal local in locals.Values) + { + int i = local.name.LastIndexOf('$'); + string name = local.name.Substring(0, i); + int count; + if(!namecounts.TryGetValue(name, out count)) + count = 0; + namecounts[name] = count + 1; + } + foreach(OTLocal local in locals.Values) + { + int i = local.name.LastIndexOf('$'); + string name = local.name.Substring(0, i); + int count = namecounts[name]; + if(count == 1) + local.name = name; + } + + // Print out result. + if(method.Name == _globalvarinit) + { + GlobalsDump(); + } + else + { + MethodDump(); + } + } + + /** + * Add instructions to stream. + */ + public override void DefineLabel(int number, string name) + { + labels.Add(number, new OTLabel(number, name)); + } + public override void DefineLocal(int number, string name, string type, Type syType) + { + locals.Add(number, new OTLocal(number, name, type)); + } + public override void DefineMethod(string methName, Type retType, Type[] argTypes, string[] argNames) + { + methargnames[methName] = argNames; + } + public override void MarkLabel(int offset, int number) + { + OTCilInstr label = labels[number]; + label.offset = offset; + cilinstrs.AddLast(label); + } + public override void BegExcBlk(int offset) + { + cilinstrs.AddLast(new OTCilBegExcBlk(offset)); + } + public override void BegCatBlk(int offset, Type excType) + { + cilinstrs.AddLast(new OTCilBegCatBlk(offset, excType)); + } + public override void BegFinBlk(int offset) + { + cilinstrs.AddLast(new OTCilBegFinBlk(offset)); + } + public override void EndExcBlk(int offset) + { + cilinstrs.AddLast(new OTCilEndExcBlk(offset)); + } + public override void EmitNull(int offset, OpCode opCode) + { + cilinstrs.AddLast(new OTCilNull(offset, opCode)); + } + public override void EmitField(int offset, OpCode opCode, FieldInfo field) + { + cilinstrs.AddLast(new OTCilField(offset, opCode, field)); + } + public override void EmitLocal(int offset, OpCode opCode, int number) + { + cilinstrs.AddLast(new OTCilLocal(offset, opCode, locals[number])); + } + public override void EmitType(int offset, OpCode opCode, Type type) + { + cilinstrs.AddLast(new OTCilType(offset, opCode, type)); + } + public override void EmitLabel(int offset, OpCode opCode, int number) + { + cilinstrs.AddLast(new OTCilLabel(offset, opCode, labels[number])); + } + public override void EmitLabels(int offset, OpCode opCode, int[] numbers) + { + OTLabel[] labelarray = new OTLabel[numbers.Length]; + for(int i = 0; i < numbers.Length; i++) + { + labelarray[i] = labels[numbers[i]]; + } + cilinstrs.AddLast(new OTCilLabels(offset, opCode, labelarray)); + } + public override void EmitMethod(int offset, OpCode opCode, MethodInfo method) + { + cilinstrs.AddLast(new OTCilMethod(offset, opCode, method)); + } + public override void EmitCtor(int offset, OpCode opCode, ConstructorInfo ctor) + { + cilinstrs.AddLast(new OTCilCtor(offset, opCode, ctor)); + } + public override void EmitDouble(int offset, OpCode opCode, double value) + { + cilinstrs.AddLast(new OTCilDouble(offset, opCode, value)); + } + public override void EmitFloat(int offset, OpCode opCode, float value) + { + cilinstrs.AddLast(new OTCilFloat(offset, opCode, value)); + } + public override void EmitInteger(int offset, OpCode opCode, int value) + { + cilinstrs.AddLast(new OTCilInteger(offset, opCode, value)); + } + public override void EmitString(int offset, OpCode opCode, string value) + { + cilinstrs.AddLast(new OTCilString(offset, opCode, value)); + } + + /** + * Add the given statement to the end of the currently open block. + */ + public void AddLastStmt(OTStmt stmt) + { + blockstack.Peek().blkstmts.AddLast(stmt); + } + + /** + * Generate output for $globalvarinit() function. + * Also outputs declarations for global variables. + */ + private void GlobalsDump() + { + // Scan $globalvarinit(). It should only have global var assignments in it. + // Also gather up list of variables it initializes. + bool badinit = false; + Dictionary inittypes = new Dictionary(); + foreach(OTStmt stmt in topBlock.blkstmts) + { + if(!(stmt is OTStmtStore)) + { + badinit = true; + break; + } + OTStmtStore store = (OTStmtStore)stmt; + if(!(store.varwr is OTOpndGlobal)) + { + badinit = true; + break; + } + OTOpndGlobal globalop = (OTOpndGlobal)store.varwr; + inittypes[globalop.PrintableString] = ""; + } + + // Scan through list of all global variables in the script. + // Output declarations for those what don't have any init statement for them. + // Save the type for those that do have init statements. + bool first = true; + foreach(string iartypename in scriptObjCode.globalVarNames.Keys) + { + Dictionary varnames = scriptObjCode.globalVarNames[iartypename]; + string typename = iartypename.ToLowerInvariant(); + if(typename.StartsWith("iar")) + typename = typename.Substring(3); + if(typename.EndsWith("s")) + typename = typename.Substring(0, typename.Length - 1); + foreach(string varname in varnames.Values) + { + if(!badinit && inittypes.ContainsKey(varname)) + { + inittypes[varname] = typename; + } + else + { + if(first) + twout.Write('\n'); + twout.Write('\n' + typename + ' ' + varname + ';'); + first = false; + } + } + } + + // If $globalvarinit() has anything bad in it, output it as a function. + // Otherwise, output it as a series of global declarations with init values. + if(badinit) + { + MethodDump(); + } + else + { + foreach(OTStmt stmt in topBlock.blkstmts) + { + OTStmtStore store = (OTStmtStore)stmt; + OTOpndGlobal globalop = (OTOpndGlobal)store.varwr; + string name = globalop.PrintableString; + if(first) + twout.Write('\n'); + twout.Write('\n' + inittypes[name] + ' '); + store.PrintStmt(twout, ""); + first = false; + } + } + } + + /** + * Generate output for other functions. + */ + private void MethodDump() + { + string indent; + + // Event handlers don't have an argument list as such in the original + // code. Instead they have a series of assignments from ehargs[] to + // local variables. So make those local variables look like they are + // an argument list. + int i = method.Name.IndexOf(' '); + if(i >= 0) + { + // Maybe we have to output the state name. + string statename = method.Name.Substring(0, i); + string eventname = method.Name.Substring(++i); + + if(laststate != statename) + { + if(laststate != null) + twout.Write("\n}"); + if(statename == "default") + { + twout.Write("\n\ndefault {"); + } + else + { + twout.Write("\n\nstate " + statename + " {"); + } + laststate = statename; + } + else + { + twout.Write('\n'); + } + + // Output event name and argument list. + // Remove from locals list so they don't print below. + twout.Write('\n' + INDENT + eventname + " ("); + MethodInfo meth = typeof(IEventHandlers).GetMethod(eventname); + i = 0; + foreach(ParameterInfo pi in meth.GetParameters()) + { + // skip the first param cuz it's the XMRInstance arg + if(i > 0) + twout.Write(", "); + OTLocal local; + if(eharglist.TryGetValue(i, out local) && locals.ContainsKey(local.number)) + { + twout.Write(local.DumpString()); + locals.Remove(local.number); + } + else + { + // maybe the assignment was removed + // eg, because the local was write-only (not referenced) + // so substitute in placeholder that won't be referenced + twout.Write(AbbrType(pi.ParameterType) + " arg$" + (i + 1)); + } + i++; + } + twout.Write(')'); + + // Indent method body by 4 spaces. + indent = INDENT; + } + else + { + // Maybe need to close out previous state. + if(laststate != null) + { + twout.Write("\n}"); + laststate = null; + } + + // Output blank line and return type (if any). + twout.Write("\n\n"); + if(method.ReturnType != typeof(void)) + { + twout.Write(AbbrType(method.ReturnType) + ' '); + } + + // Output method name and argument list. + int j = method.Name.IndexOf('('); + if(j < 0) + { + twout.Write(method.Name); + } + else + { + twout.Write(method.Name.Substring(0, j) + " ("); + bool first = true; + j = 0; + foreach(ParameterInfo pi in method.GetParameters()) + { + if(j > 0) + { // skip the XMRInstance arg$0 parameter + if(!first) + twout.Write(", "); + twout.Write(AbbrType(pi.ParameterType) + ' ' + MethArgName(j)); + first = false; + } + j++; + } + twout.Write(')'); + } + + // Don't indent method body at all. + indent = ""; + } + + // Output local variable declarations. + twout.Write('\n' + indent + '{'); + bool didOne = false; + foreach(OTLocal local in locals.Values) + { + twout.Write('\n' + indent + INDENT + local.DumpString() + "; // r:" + local.nlclreads + " w:" + local.nlclwrites); + didOne = true; + } + if(didOne) + twout.Write('\n'); + + // Output statements. + if(topBlock.blkstmts.Count == 0) + { + twout.Write(" }"); + } + else + { + topBlock.PrintBodyAndEnd(twout, indent); + } + } + + /** + * Get abbreviated type string. + */ + public static string AbbrType(Type type) + { + if(type == null) + return "null"; + return AbbrType(type.Name); + } + public static string AbbrType(string type) + { + if(type.StartsWith("OpenSim.Region.ScriptEngine.YEngine.")) + { + type = type.Substring(38); + int i = type.IndexOf(','); + if(i > 0) + type = type.Substring(0, i); + } + if(typeTranslator.ContainsKey(type)) + { + type = typeTranslator[type]; + } + return type; + } + + /** + * Get current method's argument name. + */ + public string MethArgName(int index) + { + string[] argnames; + if(methargnames.TryGetValue(method.Name, out argnames) && (index < argnames.Length)) + { + return argnames[index]; + } + return "arg$" + index; + } + + /** + * Strip svperflvovs (float) cast from rotation/vector values. + */ + public static OTOpnd StripFloatCast(OTOpnd op) + { + if(op is OTOpndCast) + { + OTOpndCast opcast = (OTOpndCast)op; + if((opcast.type == typeof(double)) && (opcast.value is OTOpndInt)) + { + return opcast.value; + } + } + return op; + } + + /** + * Strip svperflvovs Brtrues so we don't end up with stuff like 'if (!! someint) ...'. + */ + public static OTOpnd StripBrtrue(OTOpnd op) + { + if(op is OTOpndUnOp) + { + OTOpndUnOp opunop = (OTOpndUnOp)op; + if(opunop.opCode == MyOp.Brtrue) + return opunop.value; + } + return op; + } + + /* + * Local variable declaration. + */ + private class OTLocal + { + public int number; + public string name; + public string type; + + public int nlclreads; + public int nlclwrites; + + public OTLocal(int number, string name, string type) + { + this.number = number; + this.name = name.StartsWith("tmp$") ? name : name + "$" + number; + this.type = type; + } + + public string DumpString() + { + return AbbrType(type) + ' ' + name; + } + } + + /***********************************************\ + * Tokens that are one-for-one with CIL code * + \***********************************************/ + + /* + * Part of instruction stream. + */ + public abstract class OTCilInstr + { + public int offset; // cil offset + + public OTCilInstr(int offset) + { + this.offset = offset; + } + + public abstract string DumpString(); + public abstract void BuildStatements(OTDecompile decompile, LinkedListNode link); + + protected void CheckEmptyStack(OTDecompile decompile, string opMnemonic) + { + if(decompile.opstack.Count > 0) + { + Console.Error.WriteLine("CheckEmptyStack: " + decompile.method.Name + " 0x" + offset.ToString("X") + ": " + + opMnemonic + " stack depth " + decompile.opstack.Count); + } + } + } + + /* + * Label mark point. + */ + private class OTLabel: OTCilInstr + { + public int number; + public string name; + + public int lbljumps; + + public OTLabel(int number, string name) : base(-1) + { + this.number = number; + this.name = name; + } + + public string PrintableName + { + get + { + if(name.StartsWith(_doBreak)) + return _doBreak + "$" + number; + if(name.StartsWith(_doCont)) + return _doCont + "$" + number; + if(name.StartsWith(_forBreak)) + return _forBreak + "$" + number; + if(name.StartsWith(_forCont)) + return _forCont + "$" + number; + if(name.StartsWith(_whileBreak)) + return _whileBreak + "$" + number; + if(name.StartsWith(_whileCont)) + return _whileCont + "$" + number; + return name; + } + } + + public override string DumpString() + { + return name + ":"; + } + + public override void BuildStatements(OTDecompile decompile, LinkedListNode link) + { + OTStmtLabel.AddLast(decompile, this); + } + } + + /* + * 'try {' + */ + private class OTCilBegExcBlk: OTCilInstr + { + public LinkedList catches = new LinkedList(); + + public OTCilBegExcBlk(int offset) : base(offset) + { + } + + public override string DumpString() + { + return "try {"; + } + + public override void BuildStatements(OTDecompile decompile, LinkedListNode link) + { + CheckEmptyStack(decompile, "try"); + + // link the try itself onto outer block + OTStmtBegExcBlk trystmt = new OTStmtBegExcBlk(); + decompile.AddLastStmt(trystmt); + + // subsequent statements go to the try block + trystmt.tryblock = new OTStmtBlock(); + decompile.trystack.Push(trystmt); + decompile.blockstack.Push(trystmt.tryblock); + } + } + + /* + * '} catch (...) {' + */ + private class OTCilBegCatBlk: OTCilInstr + { + public Type excType; + + public OTCilBegCatBlk(int offset, Type excType) : base(offset) + { + this.excType = excType; + } + + public override string DumpString() + { + return "} catch (" + AbbrType(excType) + ") {"; + } + + public override void BuildStatements(OTDecompile decompile, LinkedListNode link) + { + CheckEmptyStack(decompile, "catch"); + + // link the catch itself onto the try statement + OTStmtBegExcBlk trystmt = decompile.trystack.Peek(); + OTStmtBegCatBlk catstmt = new OTStmtBegCatBlk(excType); + trystmt.catches.AddLast(catstmt); + + // start capturing statements into the catch block + catstmt.tryblock = trystmt; + catstmt.catchblock = new OTStmtBlock(); + decompile.blockstack.Pop(); + decompile.blockstack.Push(catstmt.catchblock); + + // fill the stack slot with something for the exception argument + OTOpndDup dup = new OTOpndDup(++decompile.dupNo); + decompile.opstack.Push(dup); + } + } + + /* + * '} finally {' + */ + private class OTCilBegFinBlk: OTCilInstr + { + public OTCilBegFinBlk(int offset) : base(offset) + { + } + + public override string DumpString() + { + return "} finally {"; + } + + public override void BuildStatements(OTDecompile decompile, LinkedListNode link) + { + CheckEmptyStack(decompile, "finally"); + + // link the finally itself to the try statement + OTStmtBegExcBlk trystmt = decompile.trystack.Peek(); + OTStmtBegFinBlk finstmt = new OTStmtBegFinBlk(); + trystmt.finblock = finstmt; + + // start capturing statements into the finally block + finstmt.tryblock = trystmt; + finstmt.finblock = new OTStmtBlock(); + decompile.blockstack.Pop(); + decompile.blockstack.Push(finstmt.finblock); + } + } + + /* + * '}' end of try + */ + private class OTCilEndExcBlk: OTCilInstr + { + public OTCilEndExcBlk(int offset) : base(offset) + { + } + + public override string DumpString() + { + return "} // end try"; + } + + public override void BuildStatements(OTDecompile decompile, LinkedListNode link) + { + CheckEmptyStack(decompile, "endtry"); + + // pop the try/catch/finally blocks from stacks + decompile.blockstack.Pop(); + decompile.trystack.Pop(); + + // subsequent statements collect following the try + } + } + + /* + * Actual opcodes (instructions). + */ + private class OTCilNull: OTCilInstr + { + public MyOp opCode; + + public OTCilNull(int offset, OpCode opCode) : base(offset) + { + this.opCode = MyOp.GetByName(opCode.Name); + } + + public override string DumpString() + { + return opCode.ToString(); + } + + public override void BuildStatements(OTDecompile decompile, LinkedListNode link) + { + switch(opCode.ToString()) + { + case "conv.i1": + case "conv.i2": + case "conv.i4": + case "conv.i8": + { + OTOpnd value = decompile.opstack.Pop(); + decompile.opstack.Push(new OTOpndCast(typeof(int), value)); + break; + } + case "conv.r4": + case "conv.r8": + { + OTOpnd value = decompile.opstack.Pop(); + decompile.opstack.Push(new OTOpndCast(typeof(double), value)); + break; + } + case "dup": + { + OTOpnd value = decompile.opstack.Pop(); + if(!(value is OTOpndDup)) + { + OTOpndDup dup = new OTOpndDup(++decompile.dupNo); + OTStmtStore.AddLast(decompile, dup, value); + value = dup; + } + decompile.opstack.Push(value); + decompile.opstack.Push(value); + break; + } + case "endfinally": + break; + case "ldarg.0": + { + decompile.opstack.Push(new OTOpndArg(0, false, decompile)); + break; + } + case "ldarg.1": + { + decompile.opstack.Push(new OTOpndArg(1, false, decompile)); + break; + } + case "ldarg.2": + { + decompile.opstack.Push(new OTOpndArg(2, false, decompile)); + break; + } + case "ldarg.3": + { + decompile.opstack.Push(new OTOpndArg(3, false, decompile)); + break; + } + case "ldc.i4.0": + { + decompile.opstack.Push(new OTOpndInt(0)); + break; + } + case "ldc.i4.1": + { + decompile.opstack.Push(new OTOpndInt(1)); + break; + } + case "ldc.i4.2": + { + decompile.opstack.Push(new OTOpndInt(2)); + break; + } + case "ldc.i4.3": + { + decompile.opstack.Push(new OTOpndInt(3)); + break; + } + case "ldc.i4.4": + { + decompile.opstack.Push(new OTOpndInt(4)); + break; + } + case "ldc.i4.5": + { + decompile.opstack.Push(new OTOpndInt(5)); + break; + } + case "ldc.i4.6": + { + decompile.opstack.Push(new OTOpndInt(6)); + break; + } + case "ldc.i4.7": + { + decompile.opstack.Push(new OTOpndInt(7)); + break; + } + case "ldc.i4.8": + { + decompile.opstack.Push(new OTOpndInt(8)); + break; + } + case "ldc.i4.m1": + { + decompile.opstack.Push(new OTOpndInt(-1)); + break; + } + case "ldelem.i4": + case "ldelem.r4": + case "ldelem.r8": + case "ldelem.ref": + { + OTOpnd index = decompile.opstack.Pop(); + OTOpnd array = decompile.opstack.Pop(); + decompile.opstack.Push(OTOpndArrayElem.Make(array, index, false, decompile)); + break; + } + case "ldnull": + { + decompile.opstack.Push(new OTOpndNull()); + break; + } + case "neg": + case "not": + { + OTOpnd value = decompile.opstack.Pop(); + decompile.opstack.Push(OTOpndUnOp.Make(opCode, value)); + break; + } + case "pop": + { + OTStmtVoid.AddLast(decompile, decompile.opstack.Pop()); + break; + } + case "ret": + { + OTOpnd value = null; + if(decompile.method.ReturnType != typeof(void)) + { + value = decompile.opstack.Pop(); + } + CheckEmptyStack(decompile); + decompile.AddLastStmt(new OTStmtRet(value)); + break; + } + case "stelem.i4": + case "stelem.r8": + case "stelem.ref": + { + OTOpnd value = decompile.opstack.Pop(); + OTOpnd index = decompile.opstack.Pop(); + OTOpnd array = decompile.opstack.Pop(); + OTStmtStore.AddLast(decompile, OTOpndArrayElem.Make(array, index, false, decompile), value); + break; + } + case "throw": + { + OTOpnd value = decompile.opstack.Pop(); + CheckEmptyStack(decompile); + decompile.AddLastStmt(new OTStmtThrow(value, decompile)); + break; + } + case "add": + case "and": + case "ceq": + case "cgt": + case "cgt.un": + case "clt": + case "clt.un": + case "div": + case "div.un": + case "mul": + case "or": + case "rem": + case "rem.un": + case "shl": + case "shr": + case "shr.un": + case "sub": + case "xor": + { + OTOpnd rite = decompile.opstack.Pop(); + OTOpnd left = decompile.opstack.Pop(); + decompile.opstack.Push(OTOpndBinOp.Make(left, opCode, rite)); + break; + } + default: + throw new Exception("unknown opcode " + opCode.ToString()); + } + } + + protected void CheckEmptyStack(OTDecompile decompile) + { + CheckEmptyStack(decompile, opCode.ToString()); + } + } + + private class OTCilField: OTCilNull + { + public FieldInfo field; + + public OTCilField(int offset, OpCode opCode, FieldInfo field) : base(offset, opCode) + { + this.field = field; + } + + public override string DumpString() + { + return opCode.ToString() + ' ' + field.Name; + } + + public override void BuildStatements(OTDecompile decompile, LinkedListNode link) + { + switch(opCode.ToString()) + { + case "ldfld": + { + OTOpnd obj = decompile.opstack.Pop(); + decompile.opstack.Push(OTOpndField.Make(obj, field)); + break; + } + case "ldsfld": + { + decompile.opstack.Push(new OTOpndSField(field)); + break; + } + case "stfld": + { + OTOpnd val = decompile.opstack.Pop(); + OTOpnd obj = decompile.opstack.Pop(); + OTStmtStore.AddLast(decompile, OTOpndField.Make(obj, field), val); + break; + } + case "stsfld": + { + OTOpnd val = decompile.opstack.Pop(); + OTStmtStore.AddLast(decompile, new OTOpndSField(field), val); + break; + } + default: + throw new Exception("unknown opcode " + opCode.ToString()); + } + } + } + + private class OTCilLocal: OTCilNull + { + public OTLocal local; + + public OTCilLocal(int offset, OpCode opCode, OTLocal local) : base(offset, opCode) + { + this.local = local; + } + + public override string DumpString() + { + return opCode.ToString() + ' ' + local.name; + } + + public override void BuildStatements(OTDecompile decompile, LinkedListNode link) + { + switch(opCode.ToString()) + { + case "ldloc": + { + decompile.opstack.Push(new OTOpndLocal(local)); + break; + } + case "ldloca": + { + decompile.opstack.Push(new OTOpndLocalRef(local)); + break; + } + case "stloc": + { + OTOpnd val = decompile.opstack.Pop(); + OTStmtStore.AddLast(decompile, new OTOpndLocal(local), val); + break; + } + default: + throw new Exception("unknown opcode " + opCode.ToString()); + } + } + } + + private class OTCilType: OTCilNull + { + public Type type; + + public OTCilType(int offset, OpCode opCode, Type type) : base(offset, opCode) + { + this.type = type; + } + + public override string DumpString() + { + return opCode.ToString() + ' ' + AbbrType(type); + } + + public override void BuildStatements(OTDecompile decompile, LinkedListNode link) + { + switch(opCode.ToString()) + { + case "box": + { + break; + } + case "castclass": + case "unbox.any": + { + OTOpnd value = decompile.opstack.Pop(); + decompile.opstack.Push(new OTOpndCast(type, value)); + break; + } + case "ldelem": + { + OTOpnd index = decompile.opstack.Pop(); + OTOpnd array = decompile.opstack.Pop(); + decompile.opstack.Push(OTOpndArrayElem.Make(array, index, false, decompile)); + break; + } + case "ldelema": + { + OTOpnd index = decompile.opstack.Pop(); + OTOpnd array = decompile.opstack.Pop(); + decompile.opstack.Push(OTOpndArrayElem.Make(array, index, true, decompile)); + break; + } + case "newarr": + { + OTOpnd index = decompile.opstack.Pop(); + decompile.opstack.Push(new OTOpndNewarr(type, index)); + break; + } + case "stelem": + { + OTOpnd value = decompile.opstack.Pop(); + OTOpnd index = decompile.opstack.Pop(); + OTOpnd array = decompile.opstack.Pop(); + OTStmtStore.AddLast(decompile, OTOpndArrayElem.Make(array, index, false, decompile), value); + break; + } + default: + throw new Exception("unknown opcode " + opCode.ToString()); + } + } + } + + private class OTCilLabel: OTCilNull + { + public OTLabel label; + + public OTCilLabel(int offset, OpCode opCode, OTLabel label) : base(offset, opCode) + { + this.label = label; + } + + public override string DumpString() + { + return opCode.ToString() + ' ' + label.name; + } + + public override void BuildStatements(OTDecompile decompile, LinkedListNode link) + { + switch(opCode.ToString()) + { + // We don't handle non-empty stack at branch points. + // + // So handle this case specially: + // + // dup + // ldc.i4.0 + // bge.s llAbstemp << we are here + // neg + // llAbstemp: + // + // becomes: + // + // call llAbs + case "bge.s": + { + OTOpnd rite = decompile.opstack.Pop(); // alleged zero + OTOpnd left = decompile.opstack.Pop(); // alleged dup + + if((label.name == _llAbstemp) && (decompile.opstack.Count > 0)) + { + LinkedListNode linkneg = link.Next; + if((left is OTOpndDup) && (rite is OTOpndInt) && + (linkneg != null) && (linkneg.Value is OTCilNull) && + (((OTCilNull)linkneg.Value).opCode == MyOp.Neg)) + { + OTOpndInt riteint = (OTOpndInt)rite; + LinkedListNode linklbl = linkneg.Next; + if((riteint.value == 0) && (linklbl != null) && (linklbl.Value is OTLabel) && + (((OTLabel)linklbl.Value) == label)) + { + linkneg.List.Remove(linkneg); + linklbl.List.Remove(linklbl); + MethodInfo method = typeof(ScriptBaseClass).GetMethod("llAbs"); + OTOpnd[] args = new OTOpnd[] { new OTOpndNull(), decompile.opstack.Pop() }; + OTOpndCall.AddLast(decompile, method, args); + break; + } + } + } + + CheckEmptyStack(decompile); + OTOpnd valu = OTOpndBinOp.Make(left, opCode, rite); + OTStmt jump = OTStmtJump.Make(label); + decompile.AddLastStmt(new OTStmtCond(valu, jump)); + break; + } + + case "beq": + case "bge": + case "bgt": + case "ble": + case "blt": + case "bne.un": + case "beq.s": + case "bgt.s": + case "ble.s": + case "blt.s": + case "bne.un.s": + { + OTOpnd rite = decompile.opstack.Pop(); + OTOpnd left = decompile.opstack.Pop(); + CheckEmptyStack(decompile); + OTOpnd valu = OTOpndBinOp.Make(left, opCode, rite); + OTStmt jump = OTStmtJump.Make(label); + decompile.AddLastStmt(new OTStmtCond(valu, jump)); + break; + } + case "brfalse": + case "brfalse.s": + case "brtrue": + case "brtrue.s": + { + OTOpnd value = decompile.opstack.Pop(); + CheckEmptyStack(decompile); + OTOpnd valu = OTOpndUnOp.Make(opCode, value); + OTStmt jump = OTStmtJump.Make(label); + decompile.AddLastStmt(new OTStmtCond(valu, jump)); + break; + } + case "br": + case "br.s": + case "leave": + { + CheckEmptyStack(decompile); + OTStmt jump = OTStmtJump.Make(label); + decompile.AddLastStmt(jump); + break; + } + default: + throw new Exception("unknown opcode " + opCode.ToString()); + } + } + } + + private class OTCilLabels: OTCilNull + { + public OTLabel[] labels; + + public OTCilLabels(int offset, OpCode opCode, OTLabel[] labels) : base(offset, opCode) + { + this.labels = labels; + } + + public override string DumpString() + { + StringBuilder sb = new StringBuilder(); + sb.Append(opCode.ToString()); + foreach(OTLabel label in labels) + { + sb.Append(' '); + sb.Append(label.name); + } + return sb.ToString(); + } + + public override void BuildStatements(OTDecompile decompile, LinkedListNode link) + { + switch(opCode.ToString()) + { + case "switch": + { + OTOpnd value = decompile.opstack.Pop(); + CheckEmptyStack(decompile); + decompile.AddLastStmt(new OTStmtSwitch(value, labels)); + break; + } + default: + throw new Exception("unknown opcode " + opCode.ToString()); + } + } + } + + private class OTCilMethod: OTCilNull + { + public MethodInfo method; + + public OTCilMethod(int offset, OpCode opCode, MethodInfo method) : base(offset, opCode) + { + this.method = method; + } + + public override string DumpString() + { + return opCode.ToString() + ' ' + method.Name; + } + + public override void BuildStatements(OTDecompile decompile, LinkedListNode link) + { + switch(opCode.ToString()) + { + case "call": + case "callvirt": + { + int nargs = method.GetParameters().Length; + if(!method.IsStatic) + nargs++; + OTOpnd[] args = new OTOpnd[nargs]; + for(int i = nargs; --i >= 0;) + { + args[i] = decompile.opstack.Pop(); + } + OTOpndCall.AddLast(decompile, method, args); + break; + } + default: + throw new Exception("unknown opcode " + opCode.ToString()); + } + } + } + + private class OTCilCtor: OTCilNull + { + public ConstructorInfo ctor; + + public OTCilCtor(int offset, OpCode opCode, ConstructorInfo ctor) : base(offset, opCode) + { + this.ctor = ctor; + } + + public override string DumpString() + { + return opCode.ToString() + ' ' + AbbrType(ctor.DeclaringType); + } + + public override void BuildStatements(OTDecompile decompile, LinkedListNode link) + { + switch(opCode.ToString()) + { + case "newobj": + { + int nargs = ctor.GetParameters().Length; + OTOpnd[] args = new OTOpnd[nargs]; + for(int i = nargs; --i >= 0;) + { + args[i] = decompile.opstack.Pop(); + } + decompile.opstack.Push(OTOpndNewobj.Make(ctor, args)); + break; + } + default: + throw new Exception("unknown opcode " + opCode.ToString()); + } + } + } + + private class OTCilDouble: OTCilNull + { + public double value; + + public OTCilDouble(int offset, OpCode opCode, double value) : base(offset, opCode) + { + this.value = value; + } + + public override string DumpString() + { + return opCode.ToString() + ' ' + value; + } + + public override void BuildStatements(OTDecompile decompile, LinkedListNode link) + { + switch(opCode.ToString()) + { + case "ldc.r8": + { + decompile.opstack.Push(new OTOpndDouble(value)); + break; + } + default: + throw new Exception("unknown opcode " + opCode.ToString()); + } + } + } + + private class OTCilFloat: OTCilNull + { + public float value; + + public OTCilFloat(int offset, OpCode opCode, float value) : base(offset, opCode) + { + this.value = value; + } + + public override string DumpString() + { + return opCode.ToString() + ' ' + value; + } + + public override void BuildStatements(OTDecompile decompile, LinkedListNode link) + { + switch(opCode.ToString()) + { + case "ldc.r4": + { + decompile.opstack.Push(new OTOpndFloat(value)); + break; + } + default: + throw new Exception("unknown opcode " + opCode.ToString()); + } + } + } + + private class OTCilInteger: OTCilNull + { + public int value; + + public OTCilInteger(int offset, OpCode opCode, int value) : base(offset, opCode) + { + this.value = value; + } + + public override string DumpString() + { + return opCode.ToString() + ' ' + value; + } + + public override void BuildStatements(OTDecompile decompile, LinkedListNode link) + { + switch(opCode.ToString()) + { + case "ldarg": + case "ldarg.s": + { + decompile.opstack.Push(new OTOpndArg(value, false, decompile)); + break; + } + case "ldarga": + case "ldarga.s": + { + decompile.opstack.Push(new OTOpndArg(value, true, decompile)); + break; + } + case "ldc.i4": + case "ldc.i4.s": + { + decompile.opstack.Push(new OTOpndInt(value)); + break; + } + case "starg": + { + OTOpnd val = decompile.opstack.Pop(); + OTStmtStore.AddLast(decompile, new OTOpndArg(value, false, decompile), val); + break; + } + default: + throw new Exception("unknown opcode " + opCode.ToString()); + } + } + } + + private class OTCilString: OTCilNull + { + public string value; + + public OTCilString(int offset, OpCode opCode, string value) : base(offset, opCode) + { + this.value = value; + } + + public override string DumpString() + { + StringBuilder sb = new StringBuilder(); + sb.Append(opCode.ToString()); + sb.Append(' '); + TokenDeclInline.PrintParamString(sb, value); + return sb.ToString(); + } + + public override void BuildStatements(OTDecompile decompile, LinkedListNode link) + { + switch(opCode.ToString()) + { + case "ldstr": + { + decompile.opstack.Push(new OTOpndString(value)); + break; + } + default: + throw new Exception("unknown opcode " + opCode.ToString()); + } + } + } + + /***************************************\ + * Tokens what are on operand stack. * + \***************************************/ + + public abstract class OTOpnd + { + + /** + * See if it possibly has any side effects. + */ + public abstract bool HasSideEffects + { + get; + } + + /** + * Increment reference counts. + */ + public virtual void CountRefs(bool writing) + { + } + + /** + * If this operand is a 'by reference' operand, + * return the corresponding 'by value' operand. + */ + public virtual OTOpnd GetNonByRefOpnd() + { + return this; + } + + /** + * If this operand is same as oldopnd, replace it with newopnd. + * + * This default just does a shallow search which is ok if this operand does not have any sub-operands. + * But it must be overridden for a deep search if this operand has any sub-operands. + */ + public virtual OTOpnd ReplaceOperand(OTOpnd oldopnd, OTOpnd newopnd, ref bool rc) + { + if(SameAs(oldopnd)) + { + rc = true; + return newopnd; + } + return this; + } + + /** + * See if the two operands are the same value. + * Note that calls might have side-effects so are never the same. + */ + public abstract bool SameAs(OTOpnd other); + + /** + * Get a printable string representation of the operand. + */ + public abstract string PrintableString + { + get; + } + } + + /** + * Argument variable. + */ + private class OTOpndArg: OTOpnd + { + public int index; + public bool byref; + + private OTDecompile decompile; + + public OTOpndArg(int index, bool byref, OTDecompile decompile) + { + this.index = index; + this.byref = byref; + this.decompile = decompile; + } + + public override bool HasSideEffects + { + get + { + return false; + } + } + + public override OTOpnd GetNonByRefOpnd() + { + if(!byref) + return this; + return new OTOpndArg(index, false, decompile); + } + + public override bool SameAs(OTOpnd other) + { + if(!(other is OTOpndArg)) + return false; + return (((OTOpndArg)other).byref == byref) && (((OTOpndArg)other).index == index); + } + + public override string PrintableString + { + get + { + string argname = decompile.MethArgName(index); + return byref ? ("ref " + argname) : argname; + } + } + } + + /** + * Element of an array. + */ + private class OTOpndArrayElem: OTOpnd + { + public bool byref; + public OTOpnd array; + public OTOpnd index; + + public static OTOpnd Make(OTOpnd array, OTOpnd index, bool byref, OTDecompile decompile) + { + // arg$0.glblVars.iar[] is a reference to a global variable + // likewise so is __xmrinst.glblVars.iar[] + if((array is OTOpndField) && (index is OTOpndInt)) + { + // arrayfield = (arg$0.glblVars).iar + // arrayfieldobj = arg$0.glblVars + // iartypename = iar + OTOpndField arrayfield = (OTOpndField)array; + OTOpnd arrayfieldobj = arrayfield.obj; + string iartypename = arrayfield.field.Name; + + // See if they are what they are supposed to be. + if((arrayfieldobj is OTOpndField) && iartypename.StartsWith("iar")) + { + // arrayfieldobjfield = arg$0.glblVars + OTOpndField arrayfieldobjfield = (OTOpndField)arrayfieldobj; + + // See if the parts are what they are supposed to be. + if(IsArg0OrXMRInst(arrayfieldobjfield.obj) && (arrayfieldobjfield.field.Name == "glblVars")) + { + // Everything matches up, make a global variable instead of an array reference. + return new OTOpndGlobal(iartypename, ((OTOpndInt)index).value, byref, decompile.scriptObjCode); + } + } + } + + // Other array reference. + OTOpndArrayElem it = new OTOpndArrayElem(); + it.array = array; + it.index = index; + it.byref = byref; + return it; + } + + private OTOpndArrayElem() + { + } + + public override bool HasSideEffects + { + get + { + return array.HasSideEffects || index.HasSideEffects; + } + } + + public override void CountRefs(bool writing) + { + array.CountRefs(false); + index.CountRefs(false); + } + + public override OTOpnd GetNonByRefOpnd() + { + if(!byref) + return this; + OTOpndArrayElem it = new OTOpndArrayElem(); + it.array = array; + it.index = index; + return it; + } + + public override OTOpnd ReplaceOperand(OTOpnd oldopnd, OTOpnd newopnd, ref bool rc) + { + if(SameAs(oldopnd)) + { + rc = true; + return newopnd; + } + array = array.ReplaceOperand(oldopnd, newopnd, ref rc); + index = index.ReplaceOperand(oldopnd, newopnd, ref rc); + return this; + } + + public override bool SameAs(OTOpnd other) + { + if(!(other is OTOpndArrayElem)) + return false; + OTOpndArrayElem otherae = (OTOpndArrayElem)other; + return array.SameAs(otherae.array) && index.SameAs(otherae.index); + } + + public override string PrintableString + { + get + { + return (byref ? "ref " : "") + array.PrintableString + "[" + index.PrintableString + "]"; + } + } + + /** + * See if the argument is a reference to arg$0 or __xmrinst + */ + public static bool IsArg0OrXMRInst(OTOpnd obj) + { + if(obj is OTOpndArg) + { + OTOpndArg objarg = (OTOpndArg)obj; + return objarg.index == 0; + } + if(obj is OTOpndLocal) + { + OTOpndLocal objlcl = (OTOpndLocal)obj; + return objlcl.local.name.StartsWith(_xmrinstlocal); + } + return false; + } + } + + /** + * Binary operator. + */ + private class OTOpndBinOp: OTOpnd + { + public OTOpnd left; + public MyOp opCode; + public OTOpnd rite; + + private static Dictionary xor1ops = InitXor1Ops(); + + private static Dictionary InitXor1Ops() + { + Dictionary d = new Dictionary(); + d["ceq"] = "cne"; + d["cge"] = "clt"; + d["cgt"] = "cle"; + d["cle"] = "cgt"; + d["clt"] = "cge"; + d["cne"] = "ceq"; + return d; + } + + public static OTOpnd Make(OTOpnd left, MyOp opCode, OTOpnd rite) + { + // ((x clt y) xor 1) => (x cge y) etc + string xor1op; + if((left is OTOpndBinOp) && xor1ops.TryGetValue(((OTOpndBinOp)left).opCode.name, out xor1op) && + (opCode == MyOp.Xor) && + (rite is OTOpndInt) && (((OTOpndInt)rite).value == 1)) + { + opCode = MyOp.GetByName(xor1op); + } + + // handle strcmp() cases (see OTOpndStrCmp) + if(left is OTOpndStrCmp) + { + OTOpnd strcmp = ((OTOpndStrCmp)left).MakeBinOp(opCode, rite); + if(strcmp != null) + return strcmp; + } + + // nothing special, make as is + OTOpndBinOp it = new OTOpndBinOp(); + it.left = left; + it.opCode = opCode; + it.rite = rite; + return it; + } + + private OTOpndBinOp() + { + } + + public override bool HasSideEffects + { + get + { + return left.HasSideEffects || rite.HasSideEffects; + } + } + + public override void CountRefs(bool writing) + { + left.CountRefs(false); + rite.CountRefs(false); + } + + public override OTOpnd ReplaceOperand(OTOpnd oldopnd, OTOpnd newopnd, ref bool rc) + { + if(SameAs(oldopnd)) + { + rc = true; + return newopnd; + } + left = left.ReplaceOperand(oldopnd, newopnd, ref rc); + rite = rite.ReplaceOperand(oldopnd, newopnd, ref rc); + return this; + } + + public override bool SameAs(OTOpnd other) + { + if(!(other is OTOpndBinOp)) + return false; + OTOpndBinOp otherbo = (OTOpndBinOp)other; + return left.SameAs(otherbo.left) && (opCode.ToString() == otherbo.opCode.ToString()) && rite.SameAs(otherbo.rite); + } + + public override string PrintableString + { + get + { + StringBuilder sb = new StringBuilder(); + + bool leftneedsparen = ItNeedsParentheses(left, true); + if(leftneedsparen) + sb.Append('('); + sb.Append(left.PrintableString); + if(leftneedsparen) + sb.Append(')'); + + sb.Append(' '); + sb.Append(opCode.source); + sb.Append(' '); + + bool riteneedsparen = ItNeedsParentheses(rite, false); + if(riteneedsparen) + sb.Append('('); + sb.Append(rite.PrintableString); + if(riteneedsparen) + sb.Append(')'); + + return sb.ToString(); + } + } + + /** + * See if source code representation requires parentheses around the given operand. + * @param it = the other operand to decide about + * @param itleft = true: 'it' is on the left of this operand (A $ B) # C + * false: 'it' is on the right of this operand A $ (B # C) + */ + private bool ItNeedsParentheses(OTOpnd it, bool itleft) + { + if(!(it is OTOpndBinOp)) + return false; + string itop = ((OTOpndBinOp)it).opCode.source; + string myop = opCode.source; + + // find them in table. higher number is for *, lower is for +. + int itpi, mypi; + if(!precedence.TryGetValue(itop, out itpi)) + return true; + if(!precedence.TryGetValue(myop, out mypi)) + return true; + int itpiabs = Math.Abs(itpi); + int mypiabs = Math.Abs(mypi); + + // if its precedence is lower (eg +) than my precedence (eg *), it needs parentheses + if(itpiabs < mypiabs) + return true; + + // if its precedence is higher (eg *) than my precedence (eg +), it doesn't needs parentheses + if(itpiabs > mypiabs) + return false; + + // if (A $ B) # C, we can safely go without the parentheses + if(itleft) + return false; + + // my it + // A $ (B # C) only works without parentheses for commutative $ + // A - (B + C) and A - (B - C) require parentheses + // A + (B - C) does not + return mypi < 0; // neg: things like -, /, etc require parentheses + // pos: things like +, *, etc do not need parens + } + + // see MMRScriptReduce.PrecedenceInit() + private static Dictionary precedence = InitPrecedence(); + private static Dictionary InitPrecedence() + { + Dictionary d = new Dictionary(); + d["|"] = 140; + d["^"] = 160; + d["&"] = 180; + d["<<"] = -260; + d[">>"] = -260; + d["+"] = 280; + d["-"] = -280; + d["*"] = 320; + d["/"] = -320; + d["%"] = -320; + return d; + } + } + + /** + * Call with or without return value. + */ + private class OTOpndCall: OTOpnd + { + private static Dictionary mathmeths = InitMathMeths(); + private static Dictionary InitMathMeths() + { + Dictionary d = new Dictionary(); + d["Acos"] = typeof(ScriptBaseClass).GetMethod("llAcos"); + d["Asin"] = typeof(ScriptBaseClass).GetMethod("llAsin"); + d["Atan"] = typeof(ScriptBaseClass).GetMethod("llAtan"); + d["Cos"] = typeof(ScriptBaseClass).GetMethod("llCos"); + d["Abs"] = typeof(ScriptBaseClass).GetMethod("llFabs"); + d["Log"] = typeof(ScriptBaseClass).GetMethod("llLog"); + d["Log10"] = typeof(ScriptBaseClass).GetMethod("llLog10"); + d["Round"] = typeof(ScriptBaseClass).GetMethod("llRound"); + d["Sin"] = typeof(ScriptBaseClass).GetMethod("llSin"); + d["Sqrt"] = typeof(ScriptBaseClass).GetMethod("llSqrt"); + d["Tan"] = typeof(ScriptBaseClass).GetMethod("llTan"); + return d; + } + + public MethodInfo method; + public OTOpnd[] args; + + // pushes on stack for return-value functions + // pushes to end of instruction stream for return-void functions + public static void AddLast(OTDecompile decompile, MethodInfo method, OTOpnd[] args) + { + int nargs = args.Length; + + // heap tracker push is just the single arg value as far as we're concerned + if((nargs == 1) && (method.Name == _heapTrackerPush) && method.DeclaringType.Name.StartsWith("HeapTracker")) + { + decompile.opstack.Push(args[0]); + return; + } + + // heap tracker pop is just a store as far as we're concerned + if((nargs == 2) && (method.Name == _heapTrackerPop) && method.DeclaringType.Name.StartsWith("HeapTracker")) + { + OTStmtStore.AddLast(decompile, args[0], args[1]); + return; + } + + // string.Compare() is its own thing cuz it has to decompile many ways + if((nargs == 2) && (method.DeclaringType == typeof(string)) && (method.Name == "Compare")) + { + decompile.opstack.Push(new OTOpndStrCmp(args[0], args[1])); + return; + } + + // ObjectToString, etc, should appear as casts + if((nargs == 1) && (method.DeclaringType == typeof(TypeCast)) && method.Name.EndsWith("ToBool")) + { + MethodInfo meth = typeof(XMRInstAbstract).GetMethod("xmr" + method.Name); + AddLast(decompile, meth, new OTOpnd[] { new OTOpndNull(), args[0] }); + return; + } + if((nargs == 1) && (method.DeclaringType == typeof(TypeCast)) && method.Name.EndsWith("ToFloat")) + { + decompile.opstack.Push(new OTOpndCast(typeof(double), args[0])); + return; + } + if((nargs == 1) && (method.DeclaringType == typeof(TypeCast)) && method.Name.EndsWith("ToInteger")) + { + decompile.opstack.Push(new OTOpndCast(typeof(int), args[0])); + return; + } + if((nargs == 1) && (method.DeclaringType == typeof(TypeCast)) && method.Name.EndsWith("ToList")) + { + decompile.opstack.Push(new OTOpndCast(typeof(LSL_List), args[0])); + return; + } + if((nargs == 1) && (method.DeclaringType == typeof(TypeCast)) && method.Name.EndsWith("ToRotation")) + { + decompile.opstack.Push(new OTOpndCast(typeof(LSL_Rotation), args[0])); + return; + } + if((nargs == 1) && (method.DeclaringType == typeof(TypeCast)) && method.Name.EndsWith("ToString")) + { + decompile.opstack.Push(new OTOpndCast(typeof(string), args[0])); + return; + } + if((nargs == 1) && (method.DeclaringType == typeof(TypeCast)) && method.Name.EndsWith("ToVector")) + { + decompile.opstack.Push(new OTOpndCast(typeof(LSL_Vector), args[0])); + return; + } + + if((method.DeclaringType == typeof(XMRInstAbstract)) && (method.Name == "xmrHeapLeft")) + { + AddLast(decompile, typeof(ScriptBaseClass).GetMethod("llGetFreeMemory"), new OTOpnd[] { new OTOpndNull() }); + return; + } + + // pop to entry in the list/object/string array + if(PopToGlobalArray(decompile, method, args)) + return; + + // strip off event handler argument unwrapper calls + if((nargs == 1) && (method.DeclaringType == typeof(TypeCast)) && method.Name.StartsWith("EHArgUnwrap")) + { + decompile.opstack.Push(args[0]); + return; + } + + // translate Math method to ll method + MethodInfo mathmeth; + if((method.DeclaringType == typeof(Math)) && mathmeths.TryGetValue(method.Name, out mathmeth)) + { + AddLast(decompile, mathmeth, new OTOpnd[] { new OTOpndNull(), args[0] }); + return; + } + if((method.DeclaringType == typeof(Math)) && (method.Name == "Atan2")) + { + AddLast(decompile, typeof(ScriptBaseClass).GetMethod("llAtan2"), new OTOpnd[] { new OTOpndNull(), args[0], args[1] }); + return; + } + if((method.DeclaringType == typeof(Math)) && (method.Name == "Pow")) + { + AddLast(decompile, typeof(ScriptBaseClass).GetMethod("llPow"), new OTOpnd[] { new OTOpndNull(), args[0], args[1] }); + return; + } + + // string concat should be a bunch of adds + if((method.Name == "Concat") && (method.DeclaringType == typeof(string))) + { + int k = args.Length; + while(k > 1) + { + int j = 0; + int i; + for(i = 0; i + 2 <= k; i += 2) + { + args[j++] = OTOpndBinOp.Make(args[i + 0], MyOp.Add, args[i + 1]); + } + while(i < k) + args[j++] = args[i++]; + k = j; + } + if(k > 0) + decompile.opstack.Push(args[0]); + return; + } + + // bunch of calls for rotation and vector arithmetic + if((method.DeclaringType == typeof(BinOpStr)) && BinOpStrCall(decompile, method, args)) + return; + if((method.DeclaringType == typeof(ScriptCodeGen)) && (method.Name == "LSLRotationNegate")) + { + decompile.opstack.Push(OTOpndUnOp.Make(MyOp.Neg, args[0])); + return; + } + if((method.DeclaringType == typeof(ScriptCodeGen)) && (method.Name == "LSLVectorNegate")) + { + decompile.opstack.Push(OTOpndUnOp.Make(MyOp.Neg, args[0])); + return; + } + + // otherwise process it as a call + OTOpndCall call = new OTOpndCall(); + call.method = method; + call.args = args; + if(method.ReturnType == typeof(void)) + { + OTStmtVoid.AddLast(decompile, call); + } + else + { + decompile.opstack.Push(call); + } + } + + public override bool HasSideEffects + { + get + { + return true; + } + } + + /** + * Handle a call to XMRInstArrays.Pop + * by converting it to a store directly into the array. + */ + private static bool PopToGlobalArray(OTDecompile decompile, MethodInfo method, OTOpnd[] args) + { + if(method.DeclaringType != typeof(XMRInstArrays)) + return false; + if(args.Length != 3) + return false; + + string array = null; + if(method.Name == "PopList") + array = "iarLists"; + if(method.Name == "PopObject") + array = "iarObjects"; + if(method.Name == "PopString") + array = "iarStrings"; + if(array == null) + return false; + + // make token that points to the iar array + FieldInfo field = typeof(XMRInstArrays).GetField(array); + OTOpnd arrayfield = OTOpndField.Make(args[0], field); + + // make token that points to the element to be popped to + OTOpnd element = OTOpndArrayElem.Make(arrayfield, args[1], false, decompile); + + // make a statement to store value in that element + OTStmtStore.AddLast(decompile, element, args[2]); + + return true; + } + + /** + * BinOpStr has a bunch of calls to do funky arithmetic. + * Instead of generating a call, put back the original source. + */ + private static bool BinOpStrCall(OTDecompile decompile, MethodInfo method, OTOpnd[] args) + { + switch(method.Name) + { + case "MethFloatAddList": + case "MethIntAddList": + case "MethKeyAddList": + case "MethListAddFloat": + case "MethListAddInt": + case "MethListAddKey": + case "MethListAddList": + case "MethListAddObj": + case "MethListAddRot": + case "MethListAddStr": + case "MethListAddVec": + case "MethObjAddList": + case "MethRotAddList": + case "MethRotAddRot": + case "MethStrAddList": + case "MethVecAddList": + case "MethVecAddVec": + { + decompile.opstack.Push(OTOpndBinOp.Make(args[0], MyOp.Add, args[1])); + return true; + } + + case "MethListEqList": + case "MethRotEqRot": + case "MethVecEqVec": + { + decompile.opstack.Push(OTOpndBinOp.Make(args[0], MyOp.Ceq, args[1])); + return true; + } + + case "MethListNeList": + case "MethRotNeRot": + case "MethVecNeVec": + { + decompile.opstack.Push(OTOpndBinOp.Make(args[0], MyOp.Cne, args[1])); + return true; + } + + case "MethRotSubRot": + case "MethVecSubVec": + { + decompile.opstack.Push(OTOpndBinOp.Make(args[0], MyOp.Sub, args[1])); + return true; + } + + case "MethFloatMulVec": + case "MethIntMulVec": + case "MethRotMulRot": + case "MethVecMulFloat": + case "MethVecMulInt": + case "MethVecMulRot": + case "MethVecMulVec": + { + decompile.opstack.Push(OTOpndBinOp.Make(args[0], MyOp.Mul, args[1])); + return true; + } + + case "MethRotDivRot": + case "MethVecDivFloat": + case "MethVecDivInt": + case "MethVecDivRot": + { + decompile.opstack.Push(OTOpndBinOp.Make(args[0], MyOp.Div, args[1])); + return true; + } + + default: + return false; + } + } + + private OTOpndCall() + { + } + + public override void CountRefs(bool writing) + { + foreach(OTOpnd arg in args) + { + arg.CountRefs(false); + } + } + + public override OTOpnd ReplaceOperand(OTOpnd oldopnd, OTOpnd newopnd, ref bool rc) + { + for(int i = 0; i < args.Length; i++) + { + args[i] = args[i].ReplaceOperand(oldopnd, newopnd, ref rc); + } + return this; + } + + public override bool SameAs(OTOpnd other) + { + return false; + } + + public override string PrintableString + { + get + { + StringBuilder sb = new StringBuilder(); + + // GetByKey(a,i) => a[i] + if((method.DeclaringType == typeof(XMR_Array)) && (method.Name == "GetByKey") && (args.Length == 2)) + { + sb.Append(args[0].PrintableString); + sb.Append('['); + sb.Append(args[1].PrintableString); + sb.Append(']'); + return sb.ToString(); + } + + // SetByKey(a,i,v) => a[i] = v + if((method.DeclaringType == typeof(XMR_Array)) && (method.Name == "SetByKey") && (args.Length == 3)) + { + sb.Append(args[0].PrintableString); + sb.Append('['); + sb.Append(args[1].PrintableString); + sb.Append("] = "); + sb.Append(args[2].PrintableString); + return sb.ToString(); + } + + // CompValuListEl.GetElementFromList accesses list elements like an array. + if((method.DeclaringType == typeof(CompValuListEl)) && (method.Name == "GetElementFromList")) + { + sb.Append(args[0].PrintableString); + sb.Append('['); + sb.Append(args[1].PrintableString); + sb.Append(']'); + return sb.ToString(); + } + + // methods that are part of ScriptBaseClass are LSL functions such as llSay() + // so we want to skip outputting "arg$0," as it is the hidden "this" argument. + // and there are also XMRInstAbstract functions such as xmrEventDequeue(). + int starti = 0; + if((method.DeclaringType == typeof(ScriptBaseClass)) && !method.IsStatic) + starti = 1; + if((method.DeclaringType == typeof(XMRInstAbstract)) && !method.IsStatic) + starti = 1; + + // likewise, method that have null as the declaring type are script-defined + // dynamic methods which have a hidden "this" argument passed as "arg$0". + if(method.DeclaringType == null) + starti = 1; + + // all others we want to show the type name (such as Math.Abs, String.Compare, etc) + if(starti == 0) + { + sb.Append(AbbrType(method.DeclaringType)); + sb.Append('.'); + } + + // script-defined functions have the param types as part of their name + // so strip them off here so they don't clutter things up + int i = method.Name.IndexOf('('); + if(i < 0) + sb.Append(method.Name); + else + sb.Append(method.Name.Substring(0, i)); + + // now add the call arguments + sb.Append(" ("); + bool first = true; + foreach(OTOpnd arg in args) + { + if(--starti < 0) + { + if(!first) + sb.Append(", "); + sb.Append(arg.PrintableString); + first = false; + } + } + sb.Append(')'); + return sb.ToString(); + } + } + } + + /** + * Cast value to the given type. + */ + private class OTOpndCast: OTOpnd + { + public Type type; + public OTOpnd value; + + public OTOpndCast(Type type, OTOpnd value) + { + this.type = type; + this.value = value; + } + + public override bool HasSideEffects + { + get + { + return value.HasSideEffects; + } + } + + public override void CountRefs(bool writing) + { + value.CountRefs(false); + } + + public override OTOpnd ReplaceOperand(OTOpnd oldopnd, OTOpnd newopnd, ref bool rc) + { + if(SameAs(oldopnd)) + { + rc = true; + return newopnd; + } + value = value.ReplaceOperand(oldopnd, newopnd, ref rc); + return this; + } + + public override bool SameAs(OTOpnd other) + { + if(!(other is OTOpndCast)) + return false; + OTOpndCast othercast = (OTOpndCast)other; + return (type == othercast.type) && value.SameAs(othercast.value); + } + + public override string PrintableString + { + get + { + StringBuilder sb = new StringBuilder(); + sb.Append('('); + sb.Append(AbbrType(type)); + sb.Append(") "); + if(value is OTOpndBinOp) + sb.Append('('); + sb.Append(value.PrintableString); + if(value is OTOpndBinOp) + sb.Append(')'); + return sb.ToString(); + } + } + } + + /** + * Duplicate stack value without re-performing computation. + * Semantics just like local var except it doesn't have a declaration. + */ + private class OTOpndDup: OTOpnd + { + public int index; + public int ndupreads; + + public OTOpndDup(int index) + { + this.index = index; + } + + public override bool HasSideEffects + { + get + { + return false; + } + } + + public override void CountRefs(bool writing) + { + if(!writing) + ndupreads++; + } + + public override bool SameAs(OTOpnd other) + { + if(!(other is OTOpndDup)) + return false; + return ((OTOpndDup)other).index == index; + } + + public override string PrintableString + { + get + { + return "dup$" + index; + } + } + } + + /** + * Field of an object. + */ + private class OTOpndField: OTOpnd + { + public OTOpnd obj; + public FieldInfo field; + + public static OTOpnd Make(OTOpnd obj, FieldInfo field) + { + // LSL_Float.value => the object itself + if((field.DeclaringType == typeof(LSL_Float)) && (field.Name == "value")) + { + return obj; + } + + // LSL_Integer.value => the object itself + if((field.DeclaringType == typeof(LSL_Integer)) && (field.Name == "value")) + { + return obj; + } + + // LSL_String.m_string => the object itself + if((field.DeclaringType == typeof(LSL_String)) && (field.Name == "m_string")) + { + return obj; + } + + // some other field, output code to access it + // sometimes the object comes as by reference (value types), so we might need to deref it first + OTOpndField it = new OTOpndField(); + it.obj = obj.GetNonByRefOpnd(); + it.field = field; + return it; + } + + private OTOpndField() + { + } + + public override bool HasSideEffects + { + get + { + return obj.HasSideEffects; + } + } + + public override void CountRefs(bool writing) + { + // the field may be getting written to, but the object is being read + obj.CountRefs(false); + } + + public override OTOpnd ReplaceOperand(OTOpnd oldopnd, OTOpnd newopnd, ref bool rc) + { + if(SameAs(oldopnd)) + { + rc = true; + return newopnd; + } + obj = obj.ReplaceOperand(oldopnd, newopnd, ref rc); + return this; + } + + public override bool SameAs(OTOpnd other) + { + if(!(other is OTOpndField)) + return false; + OTOpndField otherfield = (OTOpndField)other; + return (field.Name == otherfield.field.Name) && obj.SameAs(otherfield.obj); + } + + public override string PrintableString + { + get + { + StringBuilder sb = new StringBuilder(); + if(obj is OTOpndBinOp) + sb.Append('('); + sb.Append(obj.PrintableString); + if(obj is OTOpndBinOp) + sb.Append(')'); + sb.Append('.'); + sb.Append(field.Name); + return sb.ToString(); + } + } + } + + /** + * Script-level global variable. + */ + private class OTOpndGlobal: OTOpnd + { + public string iartypename; + public int iararrayidx; + public bool byref; + public ScriptObjCode scriptObjCode; + + public OTOpndGlobal(string iartypename, int iararrayidx, bool byref, ScriptObjCode scriptObjCode) + { + this.iartypename = iartypename; + this.iararrayidx = iararrayidx; + this.byref = byref; + this.scriptObjCode = scriptObjCode; + } + + public override bool HasSideEffects + { + get + { + return false; + } + } + + public override OTOpnd GetNonByRefOpnd() + { + if(!byref) + return this; + return new OTOpndGlobal(iartypename, iararrayidx, false, scriptObjCode); + } + + public override bool SameAs(OTOpnd other) + { + if(!(other is OTOpndGlobal)) + return false; + OTOpndGlobal otherglobal = (OTOpndGlobal)other; + return (iartypename == otherglobal.iartypename) && (iararrayidx == otherglobal.iararrayidx); + } + + public override string PrintableString + { + get + { + return (byref ? "ref " : "") + scriptObjCode.globalVarNames[iartypename][iararrayidx]; + } + } + } + + /** + * List initialization. + */ + private class OTOpndListIni: OTOpnd + { + public OTOpnd[] values; + + /** + * Try to detect list initialization building idiom: + * dup$ = newarr object[] << link points here + * dup$[0] = bla + * dup$[1] = bla + * ... + * ... newobj list (dup$) ... + */ + public static bool Detect(LinkedListNode link) + { + if(link == null) + return false; + + /* + * Check for 'dup$ = newarr object[]' and get listsize from . + */ + OTStmtStore store = (OTStmtStore)link.Value; + if(!(store.varwr is OTOpndDup)) + return false; + if(!(store.value is OTOpndNewarr)) + return false; + OTOpndDup storevar = (OTOpndDup)store.varwr; + OTOpndNewarr storeval = (OTOpndNewarr)store.value; + if(storeval.type != typeof(object)) + return false; + if(!(storeval.index is OTOpndInt)) + return false; + int listsize = ((OTOpndInt)storeval.index).value; + + // Good chance of having list initializer, malloc an object to hold it. + OTOpndListIni it = new OTOpndListIni(); + it.values = new OTOpnd[listsize]; + + // There should be exactly listsize statements following that of the form: + // dup$[] = bla + // If so, save the bla values in the values[] array. + LinkedListNode vallink = link; + for(int i = 0; i < listsize; i++) + { + vallink = vallink.Next; + if(vallink == null) + return false; + if(!(vallink.Value is OTStmtStore)) + return false; + OTStmtStore valstore = (OTStmtStore)vallink.Value; + if(!(valstore.varwr is OTOpndArrayElem)) + return false; + OTOpndArrayElem varelem = (OTOpndArrayElem)valstore.varwr; + if(varelem.array != storevar) + return false; + if(!(varelem.index is OTOpndInt)) + return false; + if(((OTOpndInt)varelem.index).value != i) + return false; + it.values[i] = valstore.value; + } + + // The next statement should have a 'newobj list (dup$)' in it somewhere + // that we want to replace with 'it'. + ConstructorInfo protoctor = typeof(LSL_List).GetConstructor(new Type[] { typeof(object[]) }); + OTOpnd[] protoargs = new OTOpnd[] { storevar }; + OTOpnd proto = OTOpndNewobj.Make(protoctor, protoargs); + + vallink = vallink.Next; + bool rc = vallink.Value.ReplaceOperand(proto, it); + + // If successful, delete 'dup$n =' and all 'dup$n[i] =' statements. + if(rc) + { + do + { + LinkedListNode nextlink = link.Next; + link.List.Remove(link); + link = nextlink; + } while(link != vallink); + } + + return rc; + } + + public override bool HasSideEffects + { + get + { + foreach(OTOpnd value in values) + { + if(value.HasSideEffects) + return true; + } + return false; + } + } + + public override void CountRefs(bool writing) + { + foreach(OTOpnd value in values) + { + value.CountRefs(false); + } + } + + public override OTOpnd ReplaceOperand(OTOpnd oldopnd, OTOpnd newopnd, ref bool rc) + { + if(SameAs(oldopnd)) + { + rc = true; + return newopnd; + } + for(int i = 0; i < values.Length; i++) + { + values[i] = values[i].ReplaceOperand(oldopnd, newopnd, ref rc); + } + return this; + } + + public override bool SameAs(OTOpnd other) + { + if(!(other is OTOpndListIni)) + return false; + OTOpndListIni otherli = (OTOpndListIni)other; + if(otherli.values.Length != values.Length) + return false; + for(int i = 0; i < values.Length; i++) + { + if(!values[i].SameAs(otherli.values[i])) + return false; + } + return true; + } + + public override string PrintableString + { + get + { + StringBuilder sb = new StringBuilder(); + sb.Append('['); + for(int i = 0; i < values.Length; i++) + { + if(i > 0) + sb.Append(','); + sb.Append(' '); + sb.Append(values[i].PrintableString); + } + sb.Append(" ]"); + return sb.ToString(); + } + } + } + + /** + * Local variable. + */ + private class OTOpndLocal: OTOpnd + { + public OTLocal local; + + public OTOpndLocal(OTLocal local) + { + this.local = local; + } + + public override bool HasSideEffects + { + get + { + return false; + } + } + + public override void CountRefs(bool writing) + { + if(writing) + local.nlclwrites++; + else + local.nlclreads++; + } + + public override bool SameAs(OTOpnd other) + { + if(!(other is OTOpndLocal)) + return false; + OTOpndLocal otherlocal = (OTOpndLocal)other; + return local == otherlocal.local; + } + + public override string PrintableString + { + get + { + return local.name; + } + } + } + private class OTOpndLocalRef: OTOpnd + { + public OTLocal local; + + public OTOpndLocalRef(OTLocal local) + { + this.local = local; + } + + public override bool HasSideEffects + { + get + { + return true; + } + } + + public override void CountRefs(bool writing) + { + local.nlclreads++; + local.nlclwrites++; + } + + public override OTOpnd GetNonByRefOpnd() + { + return new OTOpndLocal(local); + } + + public override bool SameAs(OTOpnd other) + { + if(!(other is OTOpndLocal)) + return false; + OTOpndLocal otherlocal = (OTOpndLocal)other; + return local == otherlocal.local; + } + + public override string PrintableString + { + get + { + return "ref " + local.name; + } + } + } + + /** + * New C#-level array. + */ + private class OTOpndNewarr: OTOpnd + { + public Type type; + public OTOpnd index; + + public OTOpndNewarr(Type type, OTOpnd index) + { + this.type = type; + this.index = index; + } + + public override bool HasSideEffects + { + get + { + return index.HasSideEffects; + } + } + + public override void CountRefs(bool writing) + { + index.CountRefs(false); + } + + public override OTOpnd ReplaceOperand(OTOpnd oldopnd, OTOpnd newopnd, ref bool rc) + { + if(SameAs(oldopnd)) + { + rc = true; + return newopnd; + } + index = index.ReplaceOperand(oldopnd, newopnd, ref rc); + return this; + } + + public override bool SameAs(OTOpnd other) + { + return false; + } + + public override string PrintableString + { + get + { + return "newarr " + type.Name + "[" + index.PrintableString + "]"; + } + } + } + + /** + * New C#-level object. + */ + private class OTOpndNewobj: OTOpnd + { + public ConstructorInfo ctor; + public OTOpnd[] args; + + public static OTOpnd Make(ConstructorInfo ctor, OTOpnd[] args) + { + // newobj LSL_Float (x) => x + if((ctor.DeclaringType == typeof(LSL_Float)) && (args.Length == 1)) + { + Type ptype = ctor.GetParameters()[0].ParameterType; + if(ptype == typeof(string)) + { + return new OTOpndCast(typeof(double), args[0]); + } + return args[0]; + } + + // newobj LSL_Integer (x) => x + if((ctor.DeclaringType == typeof(LSL_Integer)) && (args.Length == 1)) + { + Type ptype = ctor.GetParameters()[0].ParameterType; + if(ptype == typeof(string)) + { + return new OTOpndCast(typeof(int), args[0]); + } + return args[0]; + } + + // newobj LSL_String (x) => x + if((ctor.DeclaringType == typeof(LSL_String)) && (args.Length == 1)) + { + return args[0]; + } + + // newobj LSL_Rotation (x, y, z, w) => + if((ctor.DeclaringType == typeof(LSL_Rotation)) && (args.Length == 4)) + { + return new OTOpndRot(args[0], args[1], args[2], args[3]); + } + + // newobj LSL_Vector (x, y, z) => + if((ctor.DeclaringType == typeof(LSL_Vector)) && (args.Length == 3)) + { + return new OTOpndVec(args[0], args[1], args[2]); + } + + // newobj LSL_Rotation (string) => (rotation) string + if((ctor.DeclaringType == typeof(LSL_Rotation)) && (args.Length == 1)) + { + return new OTOpndCast(typeof(LSL_Rotation), args[0]); + } + + // newobj LSL_Vector (string) => (rotation) string + if((ctor.DeclaringType == typeof(LSL_Vector)) && (args.Length == 1)) + { + return new OTOpndCast(typeof(LSL_Vector), args[0]); + } + + // newobj LSL_List (newarr object[0]) => [ ] + if((ctor.DeclaringType == typeof(LSL_List)) && (args.Length == 1) && (args[0] is OTOpndNewarr)) + { + OTOpndNewarr arg0 = (OTOpndNewarr)args[0]; + if((arg0.type == typeof(object)) && (arg0.index is OTOpndInt) && (((OTOpndInt)arg0.index).value == 0)) + { + OTOpndListIni listini = new OTOpndListIni(); + listini.values = new OTOpnd[0]; + return listini; + } + } + + // something else, output as is + OTOpndNewobj it = new OTOpndNewobj(); + it.ctor = ctor; + it.args = args; + return it; + } + + private OTOpndNewobj() + { + } + + public override bool HasSideEffects + { + get + { + foreach(OTOpnd arg in args) + { + if(arg.HasSideEffects) + return true; + } + return false; + } + } + + public override void CountRefs(bool writing) + { + foreach(OTOpnd arg in args) + { + arg.CountRefs(false); + } + } + + public override OTOpnd ReplaceOperand(OTOpnd oldopnd, OTOpnd newopnd, ref bool rc) + { + if(SameAs(oldopnd)) + { + rc = true; + return newopnd; + } + for(int i = 0; i < args.Length; i++) + { + args[i] = args[i].ReplaceOperand(oldopnd, newopnd, ref rc); + } + return this; + } + + public override bool SameAs(OTOpnd other) + { + if(!(other is OTOpndNewobj)) + return false; + OTOpndNewobj otherno = (OTOpndNewobj)other; + if(otherno.ctor.DeclaringType != ctor.DeclaringType) + return false; + if(otherno.args.Length != args.Length) + return false; + for(int i = 0; i < args.Length; i++) + { + if(!args[i].SameAs(otherno.args[i])) + return false; + } + return true; + } + + public override string PrintableString + { + get + { + StringBuilder sb = new StringBuilder(); + sb.Append("newobj "); + sb.Append(ctor.DeclaringType.Name); + sb.Append(" ("); + bool first = true; + foreach(OTOpnd arg in args) + { + if(!first) + sb.Append(", "); + sb.Append(arg.PrintableString); + first = false; + } + sb.Append(')'); + return sb.ToString(); + } + } + } + + /** + * Rotation value. + */ + private class OTOpndRot: OTOpnd + { + private OTOpnd x, y, z, w; + + public OTOpndRot(OTOpnd x, OTOpnd y, OTOpnd z, OTOpnd w) + { + this.x = StripFloatCast(x); + this.y = StripFloatCast(y); + this.z = StripFloatCast(z); + this.w = StripFloatCast(w); + } + + public override bool HasSideEffects + { + get + { + return x.HasSideEffects || y.HasSideEffects || z.HasSideEffects || w.HasSideEffects; + } + } + + public override void CountRefs(bool writing) + { + x.CountRefs(false); + y.CountRefs(false); + z.CountRefs(false); + w.CountRefs(false); + } + + public override OTOpnd ReplaceOperand(OTOpnd oldopnd, OTOpnd newopnd, ref bool rc) + { + if(SameAs(oldopnd)) + { + rc = true; + return newopnd; + } + x = x.ReplaceOperand(oldopnd, newopnd, ref rc); + y = y.ReplaceOperand(oldopnd, newopnd, ref rc); + z = z.ReplaceOperand(oldopnd, newopnd, ref rc); + w = w.ReplaceOperand(oldopnd, newopnd, ref rc); + return this; + } + + public override bool SameAs(OTOpnd other) + { + if(!(other is OTOpndRot)) + return false; + OTOpndRot otherv = (OTOpndRot)other; + return otherv.x.SameAs(x) && otherv.y.SameAs(y) && otherv.z.SameAs(z) && otherv.w.SameAs(w); + } + + public override string PrintableString + { + get + { + return "<" + x.PrintableString + ", " + y.PrintableString + ", " + z.PrintableString + ", " + w.PrintableString + ">"; + } + } + } + + /** + * Static field. + */ + private class OTOpndSField: OTOpnd + { + private FieldInfo field; + + public OTOpndSField(FieldInfo field) + { + this.field = field; + } + + public override bool HasSideEffects + { + get + { + return false; + } + } + + public override bool SameAs(OTOpnd other) + { + if(!(other is OTOpndSField)) + return false; + OTOpndSField othersfield = (OTOpndSField)other; + return (field.Name == othersfield.field.Name) && (field.DeclaringType == othersfield.field.DeclaringType); + } + + public override string PrintableString + { + get + { + if(field.DeclaringType == typeof(ScriptBaseClass)) + return field.Name; + return field.DeclaringType.Name + "." + field.Name; + } + } + } + + /** + * Call to string.Compare(). + * See use cases in BinOpStr: + * strcmp (a, b) ceq 0 + * (strcmp (a, b) ceq 0) xor 1 => we translate to: strcmp (a, b) cne 0 + * strcmp (a, b) clt 0 + * strcmp (a, b) clt 1 // <= + * strcmp (a, b) cgt 0 + * strcmp (a, b) cgt -1 // >= + * ...but then optimized by ScriptCollector if followed by br{false,true}: + * ceq + xor 1 + brtrue => bne.un + * ceq + xor 1 + brfalse => beq + * ceq + brtrue => beq + * ceq + brfalse => bne.un + * cgt + brtrue => bgt + * cgt + brfalse => ble + * clt + brtrue => blt + * clt + brfalse => bge + * So we end up with these cases: + * strcmp (a, b) ceq 0 + * strcmp (a, b) cne 0 + * strcmp (a, b) clt 0 + * strcmp (a, b) clt 1 + * strcmp (a, b) cgt 0 + * strcmp (a, b) cgt -1 + * strcmp (a, b) beq 0 + * strcmp (a, b) bne.un 0 + * strcmp (a, b) bgt 0 + * strcmp (a, b) ble 0 + * strcmp (a, b) bgt -1 + * strcmp (a, b) ble -1 + * strcmp (a, b) blt 0 + * strcmp (a, b) bge 0 + * strcmp (a, b) blt 1 + * strcmp (a, b) bge 1 + * ... so we pretty them up in OTOpndBinOp + */ + private class OTOpndStrCmp: OTOpnd + { + private static Dictionary binops = InitBinops(); + private static Dictionary InitBinops() + { + Dictionary d = new Dictionary(); + d["ceq 0"] = "ceq"; + d["cne 0"] = "cne"; + d["clt 0"] = "clt"; + d["clt 1"] = "cle"; + d["cgt 0"] = "cgt"; + d["cgt -1"] = "cge"; + d["beq 0"] = "ceq"; + d["bne.un 0"] = "cne"; + d["bgt 0"] = "cgt"; + d["ble 0"] = "cle"; + d["bgt -1"] = "cge"; + d["ble -1"] = "clt"; + d["blt 0"] = "clt"; + d["bge 0"] = "cge"; + d["blt 1"] = "cle"; + d["bge 1"] = "cgt"; + return d; + } + + private OTOpnd arg0; + private OTOpnd arg1; + + public OTOpndStrCmp(OTOpnd arg0, OTOpnd arg1) + { + this.arg0 = arg0; + this.arg1 = arg1; + } + + /** + * Try to make something a script writer would recognize. + * If we can't, then we leave it as a call to xmrStringCompare(). + * this = some strcmp(a,b) + * opCode = hopefully some cxx or bxx from above table + * rite = hopefully some constant from above table + */ + public OTOpnd MakeBinOp(MyOp opCode, OTOpnd rite) + { + if(!(rite is OTOpndInt)) + return null; + int riteint = ((OTOpndInt)rite).value; + string key = opCode.name + ' ' + riteint; + string cxxopname; + if(!binops.TryGetValue(key, out cxxopname)) + return null; + return OTOpndBinOp.Make(arg0, MyOp.GetByName(cxxopname), arg1); + } + public OTOpnd MakeUnOp(MyOp opCode) + { + if(opCode == MyOp.Brfalse) + return OTOpndBinOp.Make(arg0, MyOp.Ceq, arg1); + if(opCode == MyOp.Brtrue) + return OTOpndBinOp.Make(arg0, MyOp.Cne, arg1); + return null; + } + + public override bool HasSideEffects + { + get + { + return false; + } + } + + public override void CountRefs(bool writing) + { + arg0.CountRefs(writing); + arg1.CountRefs(writing); + } + + public override OTOpnd ReplaceOperand(OTOpnd oldopnd, OTOpnd newopnd, ref bool rc) + { + if(SameAs(oldopnd)) + { + rc = true; + return newopnd; + } + arg0 = arg0.ReplaceOperand(oldopnd, newopnd, ref rc); + arg1 = arg1.ReplaceOperand(oldopnd, newopnd, ref rc); + return this; + } + + public override bool SameAs(OTOpnd other) + { + if(!(other is OTOpndStrCmp)) + return false; + return arg0.SameAs(((OTOpndStrCmp)other).arg0) && arg1.SameAs(((OTOpndStrCmp)other).arg1); + } + + public override string PrintableString + { + get + { + return "xmrStringCompare (" + arg0.PrintableString + ", " + arg1.PrintableString + ")"; + } + } + } + + /** + * Unary operator. + */ + private class OTOpndUnOp: OTOpnd + { + public MyOp opCode; + public OTOpnd value; + + private static Dictionary brfops = InitBrfOps(); + private static Dictionary InitBrfOps() + { + Dictionary d = new Dictionary(); + d["beq"] = "cne"; + d["bge"] = "clt"; + d["bgt"] = "cle"; + d["ble"] = "cgt"; + d["blt"] = "cge"; + d["bne.un"] = "ceq"; + d["ceq"] = "cne"; + d["cge"] = "clt"; + d["cgt"] = "cle"; + d["cle"] = "cgt"; + d["clt"] = "cge"; + d["cne"] = "ceq"; + return d; + } + + public static OTOpnd Make(MyOp opCode, OTOpnd value) + { + // (brfalse (brfalse (x))) => (brtrue (x)) + if((opCode == MyOp.Brfalse) && (value is OTOpndUnOp) && (((OTOpndUnOp)value).opCode == MyOp.Brfalse)) + { + ((OTOpndUnOp)value).opCode = MyOp.Brtrue; + return value; + } + + // (brfalse (brtrue (x))) => (brfalse (x)) + if((opCode == MyOp.Brfalse) && (value is OTOpndUnOp) && (((OTOpndUnOp)value).opCode == MyOp.Brtrue)) + { + ((OTOpndUnOp)value).opCode = MyOp.Brfalse; + return value; + } + + // (brtrue (brfalse (x))) => (brfalse (x)) + if((opCode == MyOp.Brtrue) && (value is OTOpndUnOp) && (((OTOpndUnOp)value).opCode == MyOp.Brfalse)) + { + return value; + } + + // (brtrue (brtrue (x))) => (brtrue (x)) + if((opCode == MyOp.Brtrue) && (value is OTOpndUnOp) && (((OTOpndUnOp)value).opCode == MyOp.Brtrue)) + { + return value; + } + + // (brfalse (x beq y)) => (x bne y) etc + string brfop; + if((opCode == MyOp.Brfalse) && (value is OTOpndBinOp) && brfops.TryGetValue(((OTOpndBinOp)value).opCode.name, out brfop)) + { + ((OTOpndBinOp)value).opCode = MyOp.GetByName(brfop); + return value; + } + + // (brtrue (x beq y)) => (x beq y) etc + if((opCode == MyOp.Brtrue) && (value is OTOpndBinOp) && brfops.ContainsKey(((OTOpndBinOp)value).opCode.name)) + { + return value; + } + + // strcmp() can be a special case + if(value is OTOpndStrCmp) + { + OTOpnd strcmp = ((OTOpndStrCmp)value).MakeUnOp(opCode); + if(strcmp != null) + return strcmp; + } + + // nothing special, save opcode and value + OTOpndUnOp it = new OTOpndUnOp(); + it.opCode = opCode; + it.value = value; + return it; + } + + private OTOpndUnOp() + { + } + + public override bool HasSideEffects + { + get + { + return value.HasSideEffects; + } + } + + public override void CountRefs(bool writing) + { + value.CountRefs(false); + } + + public override OTOpnd ReplaceOperand(OTOpnd oldopnd, OTOpnd newopnd, ref bool rc) + { + if(SameAs(oldopnd)) + { + rc = true; + return newopnd; + } + value = value.ReplaceOperand(oldopnd, newopnd, ref rc); + return this; + } + + public override bool SameAs(OTOpnd other) + { + if(!(other is OTOpndUnOp)) + return false; + OTOpndUnOp otherop = (OTOpndUnOp)other; + return (opCode.ToString() == otherop.opCode.ToString()) && value.SameAs(otherop.value); + } + + public override string PrintableString + { + get + { + StringBuilder sb = new StringBuilder(); + sb.Append(opCode.source); + sb.Append(' '); + if(value is OTOpndBinOp) + sb.Append('('); + sb.Append(value.PrintableString); + if(value is OTOpndBinOp) + sb.Append(')'); + return sb.ToString(); + } + } + } + + /** + * Vector value. + */ + private class OTOpndVec: OTOpnd + { + private OTOpnd x, y, z; + + public OTOpndVec(OTOpnd x, OTOpnd y, OTOpnd z) + { + this.x = StripFloatCast(x); + this.y = StripFloatCast(y); + this.z = StripFloatCast(z); + } + + public override bool HasSideEffects + { + get + { + return x.HasSideEffects || y.HasSideEffects || z.HasSideEffects; + } + } + + public override void CountRefs(bool writing) + { + x.CountRefs(false); + y.CountRefs(false); + z.CountRefs(false); + } + + public override OTOpnd ReplaceOperand(OTOpnd oldopnd, OTOpnd newopnd, ref bool rc) + { + if(SameAs(oldopnd)) + { + rc = true; + return newopnd; + } + x = x.ReplaceOperand(oldopnd, newopnd, ref rc); + y = y.ReplaceOperand(oldopnd, newopnd, ref rc); + z = z.ReplaceOperand(oldopnd, newopnd, ref rc); + return this; + } + + public override bool SameAs(OTOpnd other) + { + if(!(other is OTOpndVec)) + return false; + OTOpndVec otherv = (OTOpndVec)other; + return otherv.x.SameAs(x) && otherv.y.SameAs(y) && otherv.z.SameAs(z); + } + + public override string PrintableString + { + get + { + return "<" + x.PrintableString + ", " + y.PrintableString + ", " + z.PrintableString + ">"; + } + } + } + + /** + * Constants. + */ + private class OTOpndDouble: OTOpnd + { + public double value; + public OTOpndDouble(double value) + { + this.value = value; + } + public override bool HasSideEffects + { + get + { + return false; + } + } + public override bool SameAs(OTOpnd other) + { + if(!(other is OTOpndDouble)) + return false; + return ((OTOpndDouble)other).value == value; + } + public override string PrintableString + { + get + { + string s = value.ToString(); + long i; + if(long.TryParse(s, out i)) + { + s += ".0"; + } + return s; + } + } + } + private class OTOpndFloat: OTOpnd + { + public float value; + public OTOpndFloat(float value) + { + this.value = value; + } + public override bool HasSideEffects + { + get + { + return false; + } + } + public override bool SameAs(OTOpnd other) + { + if(!(other is OTOpndFloat)) + return false; + return ((OTOpndFloat)other).value == value; + } + public override string PrintableString + { + get + { + string s = value.ToString(); + long i; + if(long.TryParse(s, out i)) + { + s += ".0"; + } + return s; + } + } + } + private class OTOpndInt: OTOpnd + { + public int value; + public OTOpndInt(int value) + { + this.value = value; + } + public override bool HasSideEffects + { + get + { + return false; + } + } + public override bool SameAs(OTOpnd other) + { + if(!(other is OTOpndInt)) + return false; + return ((OTOpndInt)other).value == value; + } + public override string PrintableString + { + get + { + return value.ToString(); + } + } + } + private class OTOpndNull: OTOpnd + { + public override bool HasSideEffects + { + get + { + return false; + } + } + public override bool SameAs(OTOpnd other) + { + return other is OTOpndNull; + } + public override string PrintableString + { + get + { + return "undef"; + } + } + } + private class OTOpndString: OTOpnd + { + public string value; + public OTOpndString(string value) + { + this.value = value; + } + public override bool HasSideEffects + { + get + { + return false; + } + } + public override bool SameAs(OTOpnd other) + { + if(!(other is OTOpndString)) + return false; + return ((OTOpndString)other).value == value; + } + public override string PrintableString + { + get + { + StringBuilder sb = new StringBuilder(); + TokenDeclInline.PrintParamString(sb, value); + return sb.ToString(); + } + } + } + + /****************************************\ + * Tokens what are in statement list. * + \****************************************/ + + public abstract class OTStmt + { + + /** + * Increment reference counts. + */ + public abstract void CountRefs(); + + /** + * Strip out any of the behind-the-scenes code such as stack capture/restore. + * By default, there is no change. + */ + public virtual bool StripStuff(LinkedListNode link) + { + return false; + } + + /** + * Replace the oldopnd operand with the newopnd operand if it is present. + * Return whether or not it was found and replaced. + */ + public abstract bool ReplaceOperand(OTOpnd oldopnd, OTOpnd newopnd); + + /** + * Detect and modify for do/for/if/while structures. + */ + public virtual bool DetectDoForIfWhile(LinkedListNode link) + { + return false; + } + + /** + * If this statement is the old statement, replace it with the given new statement. + * Also search any sub-ordinate statements. + * **NOTE**: minimally implemented to replace a Jump with a Break or Continue + */ + public abstract OTStmt ReplaceStatement(OTStmt oldstmt, OTStmt newstmt); + + /** + * Print the statement out on the given printer with the given indenting. + * The first line is already indented, subsequent lines must be indented as given. + * This method should leave the printer at the end of the line. + */ + public abstract void PrintStmt(TextWriter twout, string indent); + + /** + * Strip all statements following this statement + * because this statement jumps somewhere. + */ + protected bool StripStuffForTerminal(LinkedListNode link) + { + // strip all statements following jump until seeing some label + bool rc = false; + if(link != null) + { + LinkedListNode nextlink; + while((nextlink = link.Next) != null) + { + if(nextlink.Value is OTStmtLabel) + break; + nextlink.List.Remove(nextlink); + rc = true; + } + } + return rc; + } + } + + /**************************\ + * Primitive statements * + \**************************/ + + /** + * Begin catch block (catch). + */ + private class OTStmtBegCatBlk: OTStmt + { + public OTStmtBegExcBlk tryblock; + public OTStmtBlock catchblock; + + private Type excType; + + public OTStmtBegCatBlk(Type excType) + { + this.excType = excType; + } + + public override void CountRefs() + { + catchblock.CountRefs(); + } + + public override bool StripStuff(LinkedListNode link) + { + return catchblock.StripStuff(null); + } + + public override bool ReplaceOperand(OTOpnd oldopnd, OTOpnd newopnd) + { + return catchblock.ReplaceOperand(oldopnd, newopnd); + } + + public override bool DetectDoForIfWhile(LinkedListNode link) + { + return catchblock.DetectDoForIfWhile(link); + } + + public override OTStmt ReplaceStatement(OTStmt oldstmt, OTStmt newstmt) + { + catchblock = (OTStmtBlock)catchblock.ReplaceStatement(oldstmt, newstmt); + return this; + } + + /** + * Print out the catch block including its enclosed statements. + */ + public override void PrintStmt(TextWriter twout, string indent) + { + twout.Write("catch (" + excType.Name + ") "); + catchblock.PrintStmt(twout, indent); + } + } + + /** + * Begin exception block (try). + */ + private class OTStmtBegExcBlk: OTStmt + { + + // statements within the try { } not including any catch or finally + public OTStmtBlock tryblock; + + // list of all catch { } blocks associated with this try { } + public LinkedList catches = new LinkedList(); + + // possible single finally { } associated with this try + public OTStmtBegFinBlk finblock; // might be null + + public override void CountRefs() + { + tryblock.CountRefs(); + foreach(OTStmtBegCatBlk catblock in catches) + { + catblock.CountRefs(); + } + if(finblock != null) + finblock.CountRefs(); + } + + /** + * Strip behind-the-scenes info from all the sub-blocks. + */ + public override bool StripStuff(LinkedListNode link) + { + // strip behind-the-scenes info from all the sub-blocks. + bool rc = tryblock.StripStuff(null); + foreach(OTStmtBegCatBlk catblk in catches) + { + rc |= catblk.StripStuff(null); + } + if(finblock != null) + rc |= finblock.StripStuff(null); + if(rc) + return true; + + // change: + // try { + // ... + // } + // to: + // { + // ... + // } + // note that an empty catch () { } has meaning so can't be stripped + // empty finally { } blocks strips itself from the try + if((catches.Count == 0) && (finblock == null) && (link != null)) + { + link.List.AddAfter(link, tryblock); + tryblock = null; + link.List.Remove(link); + return true; + } + + return false; + } + + public override bool ReplaceOperand(OTOpnd oldopnd, OTOpnd newopnd) + { + bool rc = tryblock.ReplaceOperand(oldopnd, newopnd); + foreach(OTStmtBegCatBlk catblk in catches) + { + rc |= catblk.ReplaceOperand(oldopnd, newopnd); + } + if(finblock != null) + rc |= finblock.ReplaceOperand(oldopnd, newopnd); + return rc; + } + + public override bool DetectDoForIfWhile(LinkedListNode link) + { + bool rc = tryblock.DetectDoForIfWhile(link); + foreach(OTStmtBegCatBlk catblk in catches) + { + rc |= catblk.DetectDoForIfWhile(link); + } + if(finblock != null) + rc |= finblock.DetectDoForIfWhile(link); + return rc; + } + + /** + * Assume we will never try to replace the try block itself. + * But go through all our sub-ordinates statements. + */ + public override OTStmt ReplaceStatement(OTStmt oldstmt, OTStmt newstmt) + { + tryblock = (OTStmtBlock)tryblock.ReplaceStatement(oldstmt, newstmt); + for(LinkedListNode catlink = catches.First; catlink != null; catlink = catlink.Next) + { + catlink.Value = (OTStmtBegCatBlk)catlink.Value.ReplaceStatement(oldstmt, newstmt); + } + if(finblock != null) + finblock = (OTStmtBegFinBlk)finblock.ReplaceStatement(oldstmt, newstmt); + return this; + } + + /** + * Print out the try block including its enclosed statements. + * And since the try is the only thing pushed to the outer block, + * we also print out all the catch and finally blocks. + */ + public override void PrintStmt(TextWriter twout, string indent) + { + twout.Write("try "); + tryblock.PrintStmt(twout, indent); + foreach(OTStmtBegCatBlk catblk in catches) + { + twout.Write(' '); + catblk.PrintStmt(twout, indent); + } + if(finblock != null) + { + twout.Write(' '); + finblock.PrintStmt(twout, indent); + } + } + } + + /** + * Begin finally block (finally). + */ + private class OTStmtBegFinBlk: OTStmt + { + public OTStmtBegExcBlk tryblock; + public OTStmtBlock finblock; + + public override void CountRefs() + { + finblock.CountRefs(); + } + + /** + * Strip behind-the-scene parts from the finally block. + */ + public override bool StripStuff(LinkedListNode link) + { + // strip behind-the-scenes parts from finally block itself + if(finblock.StripStuff(null)) + return true; + + // if finblock is empty, delete the finally from the try + if(finblock.blkstmts.Count == 0) + { + tryblock.finblock = null; + return true; + } + + return false; + } + + public override bool ReplaceOperand(OTOpnd oldopnd, OTOpnd newopnd) + { + return finblock.ReplaceOperand(oldopnd, newopnd); + } + + public override bool DetectDoForIfWhile(LinkedListNode link) + { + return finblock.DetectDoForIfWhile(link); + } + + /** + * Assume we will never try to replace the finally block itself. + * But go through all our sub-ordinates statements. + */ + public override OTStmt ReplaceStatement(OTStmt oldstmt, OTStmt newstmt) + { + finblock = (OTStmtBlock)finblock.ReplaceStatement(oldstmt, newstmt); + return this; + } + + /** + * Print out the finally block including its enclosed statements. + */ + public override void PrintStmt(TextWriter twout, string indent) + { + twout.Write("finally "); + finblock.PrintStmt(twout, indent); + } + } + + /** + * Simple if jump/break/continue statement. + */ + private class OTStmtCond: OTStmt + { + public OTOpnd valu; + public OTStmt stmt; // jump, break, continue only + + public OTStmtCond(OTOpnd valu, OTStmt stmt) + { + this.valu = valu; + this.stmt = stmt; + } + + public override void CountRefs() + { + valu.CountRefs(false); + stmt.CountRefs(); + } + + public override bool StripStuff(LinkedListNode link) + { + // we assume that callMode is always CallMode_NORMAL, ie, not doing a stack capture or restore + // so the 'if (arg$0.callMode bne.un 0) ...' is deleted + // and the 'if (arg$0.callMode bne.un 1) ...' becomes unconditional + // it can also be __xmrinst.callMode instead of arg$0 + if(valu is OTOpndBinOp) + { + OTOpndBinOp binop = (OTOpndBinOp)valu; + if((binop.left is OTOpndField) && (binop.opCode.ToString() == "bne.un") && (binop.rite is OTOpndInt)) + { + OTOpndField leftfield = (OTOpndField)binop.left; + if(leftfield.field.Name == _callMode) + { + bool ok = false; + if(leftfield.obj is OTOpndArg) + { + ok = ((OTOpndArg)leftfield.obj).index == 0; + } + if(leftfield.obj is OTOpndLocal) + { + ok = ((OTOpndLocal)leftfield.obj).local.name.StartsWith(_xmrinstlocal); + } + if(ok) + { + OTOpndInt riteint = (OTOpndInt)binop.rite; + + // delete 'if ((arg$0).callMode bne.un 0) ...' + if(riteint.value == XMRInstAbstract.CallMode_NORMAL) + { + link.List.Remove(link); + return true; + } + + // make 'if ((arg$0).callMode bne.un 1) ...' unconditional + if(riteint.value == XMRInstAbstract.CallMode_SAVE) + { + link.Value = stmt; + return true; + } + } + } + } + } + + // similarly we assume that doGblInit is always 0 to eliminate the code at beginning of default state_entry() + // so the 'if (brfalse __xmrinst.doGblInit) ...' is made unconditional + if(valu is OTOpndUnOp) + { + OTOpndUnOp unop = (OTOpndUnOp)valu; + if((unop.opCode == MyOp.Brfalse) && (unop.value is OTOpndField)) + { + OTOpndField valuefield = (OTOpndField)unop.value; + if(valuefield.field.Name == _doGblInit) + { + bool ok = false; + if(valuefield.obj is OTOpndLocal) + { + ok = ((OTOpndLocal)valuefield.obj).local.name.StartsWith(_xmrinstlocal); + } + if(ok) + { + + // make 'if (brfalse __xmrinst.doGblInit) ...' unconditional + link.Value = stmt; + return true; + } + } + } + } + + return false; + } + + public override bool ReplaceOperand(OTOpnd oldopnd, OTOpnd newopnd) + { + bool rc = stmt.ReplaceOperand(oldopnd, newopnd); + valu = valu.ReplaceOperand(oldopnd, newopnd, ref rc); + return rc; + } + + /** + * Maybe this simple if statement is part of a script-level if/then/else statement. + */ + public override bool DetectDoForIfWhile(LinkedListNode link) + { + return OTStmtIf.Detect(link); + } + + /** + * Assume we won't replace the if statement itself. + * But search all our sub-ordinate statements. + */ + public override OTStmt ReplaceStatement(OTStmt oldstmt, OTStmt newstmt) + { + stmt = stmt.ReplaceStatement(oldstmt, newstmt); + return this; + } + + public override void PrintStmt(TextWriter twout, string indent) + { + twout.Write("if (" + StripBrtrue(valu).PrintableString + ") "); + stmt.PrintStmt(twout, indent); + } + + /** + * Scan forward for a given label definition. + * Put intervening statements in a statement block. + * @param link = start scanning after this statement + * @param label = look for this label definition + * @param block = where to return intervening statement block + * @returns null: label definition not found + * else: label definition statement + */ + private static LinkedListNode ScanForLabel(LinkedListNode link, + OTLabel label, out OTStmtBlock block) + { + block = new OTStmtBlock(); + while((link = link.Next) != null) + { + if(link.Value is OTStmtLabel) + { + if(((OTStmtLabel)link.Value).label == label) + break; + } + block.blkstmts.AddLast(link.Value); + } + return link; + } + + /** + * Strip statements after link up to and including donelink. + */ + private static void StripInterveningStatements(LinkedListNode link, LinkedListNode donelink) + { + LinkedListNode striplink; + do + { + striplink = link.Next; + striplink.List.Remove(striplink); + } while(striplink != donelink); + } + } + + /** + * Jump to a label. + */ + private class OTStmtJump: OTStmt + { + public OTLabel label; + + public static OTStmt Make(OTLabel label) + { + // jumps to __retlbl are return statements + // note that is is safe to say it is a valueless return because + // valued returns are done with this construct: + // __retval = ....; + // jump __retlbl; + // and those __retval = statements have been changed to return statements already + if(label.name.StartsWith(_retlbl)) + return new OTStmtRet(null); + + // other jumps are really jumps + OTStmtJump it = new OTStmtJump(); + it.label = label; + return it; + } + + private OTStmtJump() + { + } + + public override void CountRefs() + { + label.lbljumps++; + } + + public override bool StripStuff(LinkedListNode link) + { + if(link == null) + return false; + + // strip statements following unconditional jump until next label + bool rc = StripStuffForTerminal(link); + + // if we (now) have: + // jump label; + // @label; + // ... delete this jump + if(link.Next != null) + { + OTStmtLabel nextlabel = (OTStmtLabel)link.Next.Value; + if(nextlabel.label == label) + { + link.List.Remove(link); + rc = true; + } + } + + return rc; + } + + public override bool ReplaceOperand(OTOpnd oldopnd, OTOpnd newopnd) + { + return false; + } + + /** + * This is actually what ReplaceStatement() is currently used for. + * It replaces a jump with a break or a continue. + */ + public override OTStmt ReplaceStatement(OTStmt oldstmt, OTStmt newstmt) + { + if((oldstmt is OTStmtJump) && (((OTStmtJump)oldstmt).label == label)) + return newstmt; + return this; + } + + public override void PrintStmt(TextWriter twout, string indent) + { + twout.Write("jump " + label.PrintableName + ';'); + } + } + + /** + * Label definition point. + */ + private class OTStmtLabel: OTStmt + { + public OTLabel label; + + private OTDecompile decompile; + + public static void AddLast(OTDecompile decompile, OTLabel label) + { + OTStmtLabel it = new OTStmtLabel(); + it.label = label; + it.decompile = decompile; + decompile.AddLastStmt(it); + } + + private OTStmtLabel() + { + } + + public override void CountRefs() + { + // don't increment label.lbljumps + // cuz we don't want the positioning + // to count as a reference, only jumps + // to the label should count + } + + public override bool StripStuff(LinkedListNode link) + { + // if label has nothing jumping to it, remove the label + if(link != null) + { + label.lbljumps = 0; + decompile.topBlock.CountRefs(); + if(label.lbljumps == 0) + { + link.List.Remove(link); + return true; + } + } + + return false; + } + + public override bool ReplaceOperand(OTOpnd oldopnd, OTOpnd newopnd) + { + return false; + } + + public override bool DetectDoForIfWhile(LinkedListNode link) + { + if(OTStmtDo.Detect(link)) + return true; + if(OTStmtFor.Detect(link, true)) + return true; + if(OTStmtFor.Detect(link, false)) + return true; + return false; + } + + public override OTStmt ReplaceStatement(OTStmt oldstmt, OTStmt newstmt) + { + return this; + } + + public override void PrintStmt(TextWriter twout, string indent) + { + twout.Write("@" + label.PrintableName + ';'); + } + } + + /** + * Return with or without value. + */ + private class OTStmtRet: OTStmt + { + public OTOpnd value; // might be null + + public OTStmtRet(OTOpnd value) + { + this.value = value; + } + + public override void CountRefs() + { + if(value != null) + value.CountRefs(false); + } + + public override bool StripStuff(LinkedListNode link) + { + return StripStuffForTerminal(link); + } + + public override bool ReplaceOperand(OTOpnd oldopnd, OTOpnd newopnd) + { + bool rc = false; + if(value != null) + value = value.ReplaceOperand(oldopnd, newopnd, ref rc); + return rc; + } + + public override OTStmt ReplaceStatement(OTStmt oldstmt, OTStmt newstmt) + { + return this; + } + + public override void PrintStmt(TextWriter twout, string indent) + { + if(value == null) + { + twout.Write("return;"); + } + else + { + twout.Write("return " + value.PrintableString + ';'); + } + } + } + + /** + * Store value in variable. + */ + private class OTStmtStore: OTStmt + { + public OTOpnd varwr; + public OTOpnd value; + + private OTDecompile decompile; + + public static void AddLast(OTDecompile decompile, OTOpnd varwr, OTOpnd value) + { + OTStmtStore it = new OTStmtStore(varwr, value, decompile); + decompile.AddLastStmt(it); + } + + public OTStmtStore(OTOpnd varwr, OTOpnd value, OTDecompile decompile) + { + this.varwr = varwr; + this.value = value; + this.decompile = decompile; + } + + public override void CountRefs() + { + varwr.CountRefs(true); + value.CountRefs(false); + } + + public override bool StripStuff(LinkedListNode link) + { + // strip out stores to __mainCallNo + if(varwr is OTOpndLocal) + { + OTOpndLocal local = (OTOpndLocal)varwr; + if(local.local.name.StartsWith(_mainCallNo)) + { + link.List.Remove(link); + return true; + } + } + + // strip out stores to local vars where the var is not read + // but convert the value to an OTStmtVoid in case it is a call + if(varwr is OTOpndLocal) + { + OTOpndLocal local = (OTOpndLocal)varwr; + local.local.nlclreads = 0; + decompile.topBlock.CountRefs(); + if(local.local.nlclreads == 0) + { + OTStmt voidstmt = OTStmtVoid.Make(value); + if(voidstmt == null) + link.List.Remove(link); + else + link.Value = voidstmt; + return true; + } + } + + // strip out bla = newobj HeapTrackerList (...); + if(value is OTOpndNewobj) + { + OTOpndNewobj valueno = (OTOpndNewobj)value; + if(valueno.ctor.DeclaringType == typeof(HeapTrackerList)) + { + link.List.Remove(link); + return true; + } + } + + // strip out bla = newobj HeapTrackerObject (...); + if(value is OTOpndNewobj) + { + OTOpndNewobj valueno = (OTOpndNewobj)value; + if(valueno.ctor.DeclaringType == typeof(HeapTrackerObject)) + { + link.List.Remove(link); + return true; + } + } + + // strip out bla = newobj HeapTrackerString (...); + if(value is OTOpndNewobj) + { + OTOpndNewobj valueno = (OTOpndNewobj)value; + if(valueno.ctor.DeclaringType == typeof(HeapTrackerString)) + { + link.List.Remove(link); + return true; + } + } + + // convert tmp$n = bla bla; + // .... tmp$n ....; + // to + // .... bla bla ....; + // gets rid of vast majority of temps + if(varwr is OTOpndLocal) + { + OTOpndLocal temp = (OTOpndLocal)varwr; + if(temp.local.name.StartsWith("tmp$")) + { + temp.local.nlclreads = 0; + temp.local.nlclwrites = 0; + decompile.topBlock.CountRefs(); + if((temp.local.nlclreads == 1) && (temp.local.nlclwrites == 1) && (link.Next != null)) + { + OTStmt nextstmt = link.Next.Value; + if(!(nextstmt is OTStmtBlock)) + { + if(nextstmt.ReplaceOperand(varwr, value)) + { + link.List.Remove(link); + return true; + } + } + } + + // also try to convert: + // tmp$n = ... asdf ... << we are here (link) + // lcl = tmp$n; << nextstore + // ... qwer tmp$n ... + // ... no further references to tmp$n + // to: + // lcl = ... asdf ... + // ... qwer lcl ... + if((temp.local.nlclreads == 2) && (temp.local.nlclwrites == 1) && + (link.Next != null) && (link.Next.Value is OTStmtStore)) + { + OTStmtStore nextstore = (OTStmtStore)link.Next.Value; + if((nextstore.varwr is OTOpndLocal) && (nextstore.value is OTOpndLocal) && (link.Next.Next != null)) + { + OTOpndLocal localopnd = (OTOpndLocal)nextstore.varwr; + OTOpndLocal tempopnd = (OTOpndLocal)nextstore.value; + if(tempopnd.local == temp.local) + { + OTStmt finalstmt = link.Next.Next.Value; + if(finalstmt.ReplaceOperand(tempopnd, localopnd)) + { + nextstore.value = value; + link.List.Remove(link); + return true; + } + } + } + } + } + } + + // convert: + // dup$n = ... asdf ... << we are here + // lcl = dup$n; + // ... qwer dup$n ... + // ... no further references to dup$n + // to: + // lcl = ... asdf ... + // ... qwer lcl ... + if((varwr is OTOpndDup) && (link != null)) + { + OTOpndDup vardup = (OTOpndDup)varwr; + LinkedListNode nextlink = link.Next; + vardup.ndupreads = 0; + decompile.topBlock.CountRefs(); + if((vardup.ndupreads == 2) && (nextlink != null) && (nextlink.Value is OTStmtStore)) + { + + // point to the supposed lcl = dup$n statement + OTStmtStore nextstore = (OTStmtStore)nextlink.Value; + LinkedListNode nextlink2 = nextlink.Next; + if((nextstore.varwr is OTOpndLocal) && (nextstore.value == vardup) && (nextlink2 != null)) + { + + // get the local var being written and point to the ... qwer dup$n ... statement + OTOpndLocal varlcl = (OTOpndLocal)nextstore.varwr; + OTStmt nextstmt2 = nextlink2.Value; + + // try to replace dup$n in qwer with lcl + if(nextstmt2.ReplaceOperand(vardup, varlcl)) + { + + // successful, replace dup$n in asdf with lcl + // and delete the lcl = dup$n statement + varwr = varlcl; + nextlink.List.Remove(nextlink); + return true; + } + } + } + } + + // convert: + // dup$n = ... asdf ... << we are here + // ... qwer dup$n ... + // ... no further references to dup$n + // to: + // ... qwer ... asdf ... ... + if((varwr is OTOpndDup) && (link != null)) + { + OTOpndDup vardup = (OTOpndDup)varwr; + LinkedListNode nextlink = link.Next; + vardup.ndupreads = 0; + decompile.topBlock.CountRefs(); + if((vardup.ndupreads == 1) && (nextlink != null)) + { + + // point to the ... qwer dup$n ... statement + OTStmt nextstmt = nextlink.Value; + + // try to replace dup$n in qwer with ... asdf ... + if(nextstmt.ReplaceOperand(vardup, value)) + { + + // successful, delete the dup$n = ... asdf ... statement + link.List.Remove(link); + return true; + } + } + } + + // look for list initialization [ ... ] + if(OTOpndListIni.Detect(link)) + return true; + + // __xmrinst = (XMRInstAbstract) arg$0 indicates this is an event handler + // so strip it out and set the flag + if((varwr is OTOpndLocal) && (value is OTOpndCast)) + { + OTOpndLocal lcl = (OTOpndLocal)varwr; + OTOpndCast cast = (OTOpndCast)value; + if(lcl.local.name.StartsWith(_xmrinstlocal) && (cast.value is OTOpndArg)) + { + link.List.Remove(link); + return true; + } + } + + // local = [ (optional cast) ] __xmrinst.ehArgs[n] is a definition of event handler arg #n + // if found, make it event handler arg list definition + OTOpnd valuenocast = value; + if(valuenocast is OTOpndCast) + valuenocast = ((OTOpndCast)value).value; + if((varwr is OTOpndLocal) && (valuenocast is OTOpndArrayElem)) + { + OTOpndArrayElem array = (OTOpndArrayElem)valuenocast; + if((array.array is OTOpndField) && (array.index is OTOpndInt)) + { + OTOpndField arrayfield = (OTOpndField)array.array; + if((arrayfield.obj is OTOpndLocal) && + ((OTOpndLocal)arrayfield.obj).local.name.StartsWith(_xmrinstlocal) && + (arrayfield.field.Name == _ehArgs)) + { + int index = ((OTOpndInt)array.index).value; + decompile.eharglist[index] = ((OTOpndLocal)varwr).local; + link.List.Remove(link); + return true; + } + } + } + + // __retval$n = ...; => return ...; + if(varwr is OTOpndLocal) + { + OTOpndLocal lcl = (OTOpndLocal)varwr; + if(lcl.local.name.StartsWith(_retval)) + { + link.Value = new OTStmtRet(value); + return true; + } + } + + return false; + } + + public override bool ReplaceOperand(OTOpnd oldopnd, OTOpnd newopnd) + { + bool rc = false; + if(value != null) + value = value.ReplaceOperand(oldopnd, newopnd, ref rc); + return rc; + } + + public override OTStmt ReplaceStatement(OTStmt oldstmt, OTStmt newstmt) + { + return this; + } + + public override void PrintStmt(TextWriter twout, string indent) + { + // print x = x + 1 as x += 1, but don't print x = x < 3 as x <= 3 + if(value is OTOpndBinOp) + { + OTOpndBinOp valuebo = (OTOpndBinOp)value; + if(varwr.SameAs(valuebo.left) && " add and div mul or rem shl shr sub xor ".Contains(' ' + valuebo.opCode.name + ' ')) + { + twout.Write(varwr.PrintableString + ' ' + valuebo.opCode.source + "= " + valuebo.rite.PrintableString + ';'); + return; + } + } + + twout.Write(varwr.PrintableString + " = " + value.PrintableString + ';'); + } + } + + /** + * Dispatch to a table of labels. + */ + private class OTStmtSwitch: OTStmt + { + private OTOpnd index; + private OTLabel[] labels; + + public OTStmtSwitch(OTOpnd index, OTLabel[] labels) + { + this.index = index; + this.labels = labels; + } + + public override void CountRefs() + { + index.CountRefs(false); + foreach(OTLabel label in labels) + { + label.lbljumps++; + } + } + + public override bool ReplaceOperand(OTOpnd oldopnd, OTOpnd newopnd) + { + bool rc = false; + if(index != null) + index = index.ReplaceOperand(oldopnd, newopnd, ref rc); + return rc; + } + + public override OTStmt ReplaceStatement(OTStmt oldstmt, OTStmt newstmt) + { + return this; + } + + public override void PrintStmt(TextWriter twout, string indent) + { + twout.Write("switch (" + index.PrintableString + ") {\n"); + for(int i = 0; i < labels.Length; i++) + { + twout.Write(indent + INDENT + "case " + i + ": jump " + labels[i].name + ";\n"); + } + twout.Write(indent + '}'); + } + } + + /** + * Throw an exception. + */ + private class OTStmtThrow: OTStmt + { + private OTOpnd value; + private OTDecompile decompile; + + public OTStmtThrow(OTOpnd value, OTDecompile decompile) + { + this.value = value; + this.decompile = decompile; + } + + public override void CountRefs() + { + value.CountRefs(false); + } + + public override bool StripStuff(LinkedListNode link) + { + return StripStuffForTerminal(link); + } + + public override bool ReplaceOperand(OTOpnd oldopnd, OTOpnd newopnd) + { + bool rc = false; + if(value != null) + value = value.ReplaceOperand(oldopnd, newopnd, ref rc); + return rc; + } + + public override OTStmt ReplaceStatement(OTStmt oldstmt, OTStmt newstmt) + { + return this; + } + + public override void PrintStmt(TextWriter twout, string indent) + { + // throw newobj ScriptUndefinedStateException ("x") => state x + if(value is OTOpndNewobj) + { + OTOpndNewobj valueno = (OTOpndNewobj)value; + if((valueno.ctor.DeclaringType == typeof(ScriptUndefinedStateException)) && + (valueno.args.Length == 1) && (valueno.args[0] is OTOpndString)) + { + OTOpndString arg0 = (OTOpndString)valueno.args[0]; + twout.Write("state " + arg0.value + "; /* throws undefined state exception */"); + return; + } + } + + // throw newobj ScriptChangeStateException (n) => state n + if(value is OTOpndNewobj) + { + OTOpndNewobj valueno = (OTOpndNewobj)value; + if((valueno.ctor.DeclaringType == typeof(ScriptChangeStateException)) && + (valueno.args.Length == 1) && (valueno.args[0] is OTOpndInt)) + { + OTOpndInt arg0 = (OTOpndInt)valueno.args[0]; + twout.Write("state " + decompile.scriptObjCode.stateNames[arg0.value] + ';'); + return; + } + } + + // throwing something else, output as is + twout.Write("throw " + value.PrintableString + ';'); + } + } + + /** + * Call with void return, or really anything that we discard the value of after computing it. + */ + private class OTStmtVoid: OTStmt + { + private OTOpnd value; + + public static void AddLast(OTDecompile decompile, OTOpnd value) + { + OTStmt it = OTStmtVoid.Make(value); + if(it != null) + decompile.AddLastStmt(it); + } + + public static OTStmt Make(OTOpnd value) + { + if(!value.HasSideEffects) + return null; + OTStmtVoid it = new OTStmtVoid(); + it.value = value; + return it; + } + + private OTStmtVoid() + { + } + + public override void CountRefs() + { + value.CountRefs(false); + } + + public override bool ReplaceOperand(OTOpnd oldopnd, OTOpnd newopnd) + { + bool rc = false; + value = value.ReplaceOperand(oldopnd, newopnd, ref rc); + return rc; + } + + public override bool StripStuff(LinkedListNode link) + { + // strip out calls to CheckRunQuick() and CheckRunStack() + if(value is OTOpndCall) + { + OTOpndCall call = (OTOpndCall)value; + MethodInfo method = call.method; + if((method.Name == _checkRunQuick) || (method.Name == _checkRunStack)) + { + link.List.Remove(link); + return true; + } + } + + return false; + } + + public override OTStmt ReplaceStatement(OTStmt oldstmt, OTStmt newstmt) + { + return this; + } + + public override void PrintStmt(TextWriter twout, string indent) + { + twout.Write(value.PrintableString + ';'); + } + } + + /***************************\ + * Structured statements * + \***************************/ + + /** + * Block of statements. + */ + private class OTStmtBlock: OTStmt + { + public LinkedList blkstmts = new LinkedList(); + + public override void CountRefs() + { + foreach(OTStmt stmt in blkstmts) + { + stmt.CountRefs(); + } + } + + /** + * Scrub out all references to behind-the-scenes parts and simplify. + */ + public override bool StripStuff(LinkedListNode link) + { + // loop through all sub-statements to strip out behind-the-scenes references + bool rc = false; + loop: + for(LinkedListNode stmtlink = blkstmts.First; stmtlink != null; stmtlink = stmtlink.Next) + { + if(stmtlink.Value.StripStuff(stmtlink)) + { + rc = true; + goto loop; + } + } + if(rc) + return true; + + // try to merge this block into outer block + // change: + // { + // ... + // { << link points here + // ... + // } + // ... + // } + // to: + // { + // ... + // ... + // ... + // } + if(link != null) + { + LinkedListNode nextlink; + while((nextlink = blkstmts.Last) != null) + { + nextlink.List.Remove(nextlink); + link.List.AddAfter(link, nextlink); + } + link.List.Remove(link); + return true; + } + + return rc; + } + + public override bool ReplaceOperand(OTOpnd oldopnd, OTOpnd newopnd) + { + bool rc = false; + foreach(OTStmt stmt in blkstmts) + { + rc |= stmt.ReplaceOperand(oldopnd, newopnd); + } + return rc; + } + + /** + * Check each statement in the block to see if it starts a do/for/if/while statement. + */ + public override bool DetectDoForIfWhile(LinkedListNode link) + { + bool rc = false; + loop: + for(link = blkstmts.First; link != null; link = link.Next) + { + if(link.Value.DetectDoForIfWhile(link)) + { + rc = true; + goto loop; + } + } + return rc; + } + + /** + * Assume we will never try to replace the block itself. + * But go through all our sub-ordinates statements. + */ + public override OTStmt ReplaceStatement(OTStmt oldstmt, OTStmt newstmt) + { + for(LinkedListNode childlink = blkstmts.First; childlink != null; childlink = childlink.Next) + { + childlink.Value = childlink.Value.ReplaceStatement(oldstmt, newstmt); + } + return this; + } + + /** + * Print out the block including its enclosed statements. + */ + public override void PrintStmt(TextWriter twout, string indent) + { + switch(blkstmts.Count) + { + case 0: + { + twout.Write("{ }"); + break; + } + ////case 1: { + //// blkstmts.First.Value.PrintStmt (twout, indent); + //// break; + ////} + default: + { + twout.Write('{'); + PrintBodyAndEnd(twout, indent); + break; + } + } + } + + public void PrintBodyAndEnd(TextWriter twout, string indent) + { + string newindent = indent + INDENT; + foreach(OTStmt stmt in blkstmts) + { + twout.Write('\n' + indent); + if(!(stmt is OTStmtLabel)) + twout.Write(INDENT); + else + twout.Write(LABELINDENT); + stmt.PrintStmt(twout, newindent); + } + twout.Write('\n' + indent + '}'); + } + } + + /** + * 'do' statement. + */ + private class OTStmtDo: OTStmt + { + private OTOpnd dotest; + private OTStmtBlock dobody; + + /** + * See if we have a do loop... + * @doloop_; << link points here + * ... ... + * [ if (dotest) ] jump doloop_; + */ + public static bool Detect(LinkedListNode link) + { + // see if we have label starting with 'doloop_' + OTLabel looplabel = ((OTStmtLabel)link.Value).label; + if(!looplabel.name.StartsWith(_doLoop)) + return false; + + // good chance we have a do loop + OTStmtDo it = new OTStmtDo(); + + // scan ahead looking for the terminating cond/jump loop + // also gather up the statements for the do body block + it.dobody = new OTStmtBlock(); + LinkedListNode nextlink; + for(nextlink = link.Next; nextlink != null; nextlink = nextlink.Next) + { + OTStmt nextstmt = nextlink.Value; + + // add statement to do body + it.dobody.blkstmts.AddLast(nextlink.Value); + + // check for something what jumps to loop label + // that gives us the end of the loop + OTStmt maybejump = nextstmt; + if(nextstmt is OTStmtCond) + { + maybejump = ((OTStmtCond)nextstmt).stmt; + } + if((maybejump is OTStmtJump) && (((OTStmtJump)maybejump).label == looplabel)) + { + break; + } + } + + // make sure we found the jump back to the loop label + if(nextlink == null) + return false; + + // remove all statements from caller's block including the continue label if any + // but leave the break label alone it will be removed later if unreferenced + // and leave the initial loop label intact for now + for(LinkedListNode remlink = null; (remlink = link.Next) != null;) + { + link.List.Remove(remlink); + if(remlink == nextlink) + break; + } + + // take test condition from last statement of body + // it should be an cond/jump or just a jump to the loop label + LinkedListNode lastlink = it.dobody.blkstmts.Last; + OTStmt laststmt = lastlink.Value; + if(laststmt is OTStmtCond) + { + it.dotest = ((OTStmtCond)laststmt).valu; + } + else + { + it.dotest = new OTOpndInt(1); + } + lastlink.List.Remove(lastlink); + + // finally replace the loop label with the whole do statement + link.Value = it; + + // tell caller we made a change + return true; + } + + public override void CountRefs() + { + if(dotest != null) + dotest.CountRefs(false); + if(dobody != null) + dobody.CountRefs(); + } + + public override bool ReplaceOperand(OTOpnd oldopnd, OTOpnd newopnd) + { + return dobody.ReplaceOperand(oldopnd, newopnd); + } + + public override bool DetectDoForIfWhile(LinkedListNode link) + { + return dobody.DetectDoForIfWhile(link); + } + + /** + * Assume we won't replace the do statement itself. + * But search all our sub-ordinate statements. + */ + public override OTStmt ReplaceStatement(OTStmt oldstmt, OTStmt newstmt) + { + dobody = (OTStmtBlock)dobody.ReplaceStatement(oldstmt, newstmt); + return this; + } + + public override void PrintStmt(TextWriter twout, string indent) + { + // output do body + twout.Write("do "); + dobody.PrintStmt(twout, indent); + + // output while part + twout.Write(" while (" + StripBrtrue(dotest).PrintableString + ");"); + } + } + + /** + * 'for' or 'while' statement. + */ + private class OTStmtFor: OTStmt + { + private bool iswhile; + private OTOpnd fortest; + private OTStmtBlock forbody; + private OTStmt forinit; + private OTStmt forstep; + + /** + * See if we have a for or while loop... + * + * @forloop_; << link points here + * [ if () jump forbreak_; ] + * ... ... + * jump forloop_; + * [ @forbreak_; ] + */ + public static bool Detect(LinkedListNode link, bool iswhile) + { + string loopname = iswhile ? _whileLoop : _forLoop; + string breakname = iswhile ? _whileBreak : _forBreak; + + // see if we have label starting with 'forloop_' + OTLabel looplabel = ((OTStmtLabel)link.Value).label; + if(!looplabel.name.StartsWith(loopname)) + return false; + + // good chance we have a for loop + OTStmtFor it = new OTStmtFor(); + it.iswhile = iswhile; + + // all labels end with this suffix + string suffix = looplabel.name.Substring(loopname.Length); + + // scan ahead looking for the 'jump forloop_;' statement + // also gather up the statements for the for body block + it.forbody = new OTStmtBlock(); + LinkedListNode lastlink; + for(lastlink = link; (lastlink = lastlink.Next) != null;) + { + + // check for jump forloop that tells us where loop ends + if(lastlink.Value is OTStmtJump) + { + OTStmtJump lastjump = (OTStmtJump)lastlink.Value; + if(lastjump.label == looplabel) + break; + } + + // add to body block + it.forbody.blkstmts.AddLast(lastlink.Value); + } + + // make sure we found the 'jump forloop' where the for loop ends + if(lastlink == null) + return false; + + // remove all statements from caller's block including final jump + // but leave the loop label in place + for(LinkedListNode nextlink = null; (nextlink = link.Next) != null;) + { + link.List.Remove(nextlink); + if(nextlink == lastlink) + break; + } + + // if statement before loop label is an assignment, use it for the init statement + if(!iswhile && (link.Previous != null) && (link.Previous.Value is OTStmtStore)) + { + it.forinit = link.Previous.Value; + link.List.Remove(link.Previous); + } + + // if first statement of for body is 'if (...) jump breaklabel' use it for the test value + if((it.forbody.blkstmts.First != null) && (it.forbody.blkstmts.First.Value is OTStmtCond)) + { + OTStmtCond condstmt = (OTStmtCond)it.forbody.blkstmts.First.Value; + if((condstmt.stmt is OTStmtJump) && (((OTStmtJump)condstmt.stmt).label.name == breakname + suffix)) + { + it.fortest = OTOpndUnOp.Make(MyOp.Brfalse, condstmt.valu); + it.forbody.blkstmts.RemoveFirst(); + } + } + + // if last statement of body is an assigment, + // use the assignment as the step statement + if(!iswhile && (it.forbody.blkstmts.Last != null) && + (it.forbody.blkstmts.Last.Value is OTStmtStore)) + { + LinkedListNode storelink = it.forbody.blkstmts.Last; + storelink.List.Remove(storelink); + it.forstep = storelink.Value; + } + + // finally replace the loop label with the whole for statement + link.Value = it; + + // tell caller we made a change + return true; + } + + public override void CountRefs() + { + if(fortest != null) + fortest.CountRefs(false); + if(forbody != null) + forbody.CountRefs(); + if(forinit != null) + forinit.CountRefs(); + if(forstep != null) + forstep.CountRefs(); + } + + public override bool ReplaceOperand(OTOpnd oldopnd, OTOpnd newopnd) + { + return forbody.ReplaceOperand(oldopnd, newopnd) | + ((forinit != null) && forinit.ReplaceOperand(oldopnd, newopnd)) | + ((forstep != null) && forstep.ReplaceOperand(oldopnd, newopnd)); + } + + public override bool DetectDoForIfWhile(LinkedListNode link) + { + return forbody.DetectDoForIfWhile(link) | + ((forinit != null) && forinit.DetectDoForIfWhile(link)) | + ((forstep != null) && forstep.DetectDoForIfWhile(link)); + } + + /** + * Assume we won't replace the for statement itself. + * But search all our sub-ordinate statements. + */ + public override OTStmt ReplaceStatement(OTStmt oldstmt, OTStmt newstmt) + { + forbody = (OTStmtBlock)forbody.ReplaceStatement(oldstmt, newstmt); + if(forinit != null) + forinit = forinit.ReplaceStatement(oldstmt, newstmt); + if(forstep != null) + forstep = forstep.ReplaceStatement(oldstmt, newstmt); + return this; + } + + public override void PrintStmt(TextWriter twout, string indent) + { + if(iswhile) + { + twout.Write("while ("); + if(fortest == null) + { + twout.Write("TRUE"); + } + else + { + twout.Write(StripBrtrue(fortest).PrintableString); + } + } + else + { + twout.Write("for ("); + if(forinit != null) + { + forinit.PrintStmt(twout, indent + INDENT); + } + else + { + twout.Write(';'); + } + if(fortest != null) + { + twout.Write(' ' + StripBrtrue(fortest).PrintableString); + } + twout.Write(';'); + if(forstep != null) + { + StringWriter sw = new StringWriter(); + sw.Write(' '); + forstep.PrintStmt(sw, indent + INDENT); + StringBuilder sb = sw.GetStringBuilder(); + int sl = sb.Length; + if((sl > 0) && (sb[sl - 1] == ';')) + sb.Remove(--sl, 1); + twout.Write(sb.ToString()); + } + } + + twout.Write(") "); + forbody.PrintStmt(twout, indent); + } + } + + /** + * if/then/else block. + */ + private class OTStmtIf: OTStmt + { + private OTOpnd testvalu; + private OTStmt thenstmt; + private OTStmt elsestmt; // might be null + + /** + * Try to detect a structured if statement. + * + * if (condition) jump ifdone_; << link points here + * ... then body ... + * @ifdone_; + * + * if (condition) jump ifelse_; + * ... then body ... + * jump ifdone_; << optional if true body doesn't fall through + * @ifelse_; + * ... else body ... + * @ifdone_; + */ + public static bool Detect(LinkedListNode link) + { + OTStmtCond condstmt = (OTStmtCond)link.Value; + if(!(condstmt.stmt is OTStmtJump)) + return false; + + OTStmtJump jumpstmt = (OTStmtJump)condstmt.stmt; + if(jumpstmt.label.name.StartsWith(_ifDone)) + { + + // then-only if + + // skip forward to find the ifdone_ label + // also save the intervening statements for the then body + OTStmtBlock thenbody; + LinkedListNode donelink = ScanForLabel(link, jumpstmt.label, out thenbody); + + // make sure we found matching label + if(donelink == null) + return false; + + // replace the jump ifdone_ with the + OTStmtIf it = new OTStmtIf(); + it.thenstmt = thenbody; + + // replace the test value with the opposite + it.testvalu = OTOpndUnOp.Make(MyOp.Brfalse, condstmt.valu); + condstmt.valu = null; + + // strip out the true body statements from the main code including the ifdone_ label + StripInterveningStatements(link, donelink); + + // replace the simple conditional with the if/then/else block + link.Value = it; + + // tell caller we changed something + return true; + } + + if(jumpstmt.label.name.StartsWith(_ifElse)) + { + string suffix = jumpstmt.label.name.Substring(_ifElse.Length); + + // if/then/else + OTStmtIf it = new OTStmtIf(); + + // skip forward to find the ifelse_ label + // also save the intervening statements for the true body + OTStmtBlock thenbody; + LinkedListNode elselink = ScanForLabel(link, jumpstmt.label, out thenbody); + + // make sure we found matching label + if(elselink != null) + { + + // the last statement of the then body might be a jump ifdone_ + LinkedListNode lastthenlink = thenbody.blkstmts.Last; + if((lastthenlink != null) && (lastthenlink.Value is OTStmtJump)) + { + OTStmtJump jumpifdone = (OTStmtJump)lastthenlink.Value; + if(jumpifdone.label.name == _ifDone + suffix) + { + + lastthenlink.List.Remove(lastthenlink); + + // skip forward to find the ifdone_ label + // also save the intervening statements for the else body + OTStmtBlock elsebody; + LinkedListNode donelink = ScanForLabel(elselink, jumpifdone.label, out elsebody); + if(donelink != null) + { + + // replace the jump ifdone_ with the + it.thenstmt = thenbody; + + // save the else body as well + it.elsestmt = elsebody; + + // replace the test value with the opposite + it.testvalu = OTOpndUnOp.Make(MyOp.Brfalse, condstmt.valu); + condstmt.valu = null; + + // strip out the true and else body statements from the main code including the ifdone_ label + StripInterveningStatements(link, donelink); + + // replace the simple conditional with the if/then/else block + link.Value = it; + + // tell caller we changed something + return true; + } + } + } + + // missing the jump _ifDone_, so make it a simple if/then + // if (condition) jump ifelse_; << link + // ... then body ... << encapsulated in block thenbody + // @ifelse_; << elselink + // ... else body ... << still inline and leave it there + // @ifdone_; << strip this out + + // replace the jump ifelse_ with the + it.thenstmt = thenbody; + + // replace the test value with the opposite + it.testvalu = OTOpndUnOp.Make(MyOp.Brfalse, condstmt.valu); + condstmt.valu = null; + + // strip out the then body statements from the main code including the ifelse_ label + StripInterveningStatements(link, elselink); + + // there's a dangling unused ifdone_ label ahead that has to be stripped + for(LinkedListNode donelink = link; (donelink = donelink.Next) != null;) + { + if((donelink.Value is OTStmtLabel) && (((OTStmtLabel)donelink.Value).label.name == _ifDone + suffix)) + { + donelink.List.Remove(donelink); + break; + } + } + + // replace the simple conditional with the if/then/else block + link.Value = it; + + // tell caller we changed something + return true; + } + } + + return false; + } + + private OTStmtIf() + { + } + + public override void CountRefs() + { + if(testvalu != null) + testvalu.CountRefs(false); + if(thenstmt != null) + thenstmt.CountRefs(); + if(elsestmt != null) + elsestmt.CountRefs(); + } + + public override bool ReplaceOperand(OTOpnd oldopnd, OTOpnd newopnd) + { + bool rc = thenstmt.ReplaceOperand(oldopnd, newopnd); + testvalu = testvalu.ReplaceOperand(oldopnd, newopnd, ref rc); + return rc; + } + + public override bool DetectDoForIfWhile(LinkedListNode link) + { + return ((thenstmt != null) && thenstmt.DetectDoForIfWhile(link)) | + ((elsestmt != null) && elsestmt.DetectDoForIfWhile(link)); + } + + /** + * Assume we won't replace the if statement itself. + * But search all our sub-ordinate statements. + */ + public override OTStmt ReplaceStatement(OTStmt oldstmt, OTStmt newstmt) + { + thenstmt = thenstmt.ReplaceStatement(oldstmt, newstmt); + if(elsestmt != null) + elsestmt = elsestmt.ReplaceStatement(oldstmt, newstmt); + return this; + } + + public override void PrintStmt(TextWriter twout, string indent) + { + twout.Write("if (" + StripBrtrue(testvalu).PrintableString + ") "); + OTStmt thenst = ReduceStmtBody(thenstmt, false); + thenst.PrintStmt(twout, indent); + if(elsestmt != null) + { + twout.Write('\n' + indent + "else "); + OTStmt elsest = ReduceStmtBody(elsestmt, true); + elsest.PrintStmt(twout, indent); + } + } + + // strip block off a single jump so it prints inline instead of with braces around it + // also, if this is part of else, strip block for ifs to make else if statement + private static OTStmt ReduceStmtBody(OTStmt statement, bool stripif) + { + OTStmt onestmt = statement; + if((onestmt is OTStmtBlock) && (((OTStmtBlock)onestmt).blkstmts.Count == 1)) + { + onestmt = ((OTStmtBlock)onestmt).blkstmts.First.Value; + if((onestmt is OTStmtJump) || (stripif && (onestmt is OTStmtIf))) + { + return onestmt; + } + } + return statement; + } + + /** + * Scan forward for a given label definition. + * Put intervening statements in a statement block. + * @param link = start scanning after this statement + * @param label = look for this label definition + * @param block = where to return intervening statement block + * @returns null: label definition not found + * else: label definition statement + */ + private static LinkedListNode ScanForLabel(LinkedListNode link, + OTLabel label, out OTStmtBlock block) + { + block = new OTStmtBlock(); + while((link = link.Next) != null) + { + if(link.Value is OTStmtLabel) + { + if(((OTStmtLabel)link.Value).label == label) + break; + } + block.blkstmts.AddLast(link.Value); + } + return link; + } + + /** + * Strip statements after link up to and including donelink. + */ + private static void StripInterveningStatements(LinkedListNode link, LinkedListNode donelink) + { + LinkedListNode striplink; + do + { + striplink = link.Next; + striplink.List.Remove(striplink); + } while(striplink != donelink); + } + } + + private class MyOp + { + public int index; + public OpCode sysop; + public string name; + public string source; + + private static Dictionary myopsbyname = new Dictionary(); + private static int nextindex = 0; + + public MyOp(OpCode sysop) + { + this.index = nextindex++; + this.sysop = sysop; + this.name = sysop.Name; + myopsbyname.Add(name, this); + } + + public MyOp(OpCode sysop, string source) + { + this.index = nextindex++; + this.sysop = sysop; + this.name = sysop.Name; + this.source = source; + myopsbyname.Add(name, this); + } + + public MyOp(string name) + { + this.index = nextindex++; + this.name = name; + myopsbyname.Add(name, this); + } + + public MyOp(string name, string source) + { + this.index = nextindex++; + this.name = name; + this.source = source; + myopsbyname.Add(name, this); + } + + public static MyOp GetByName(string name) + { + return myopsbyname[name]; + } + + public override string ToString() + { + return name; + } + + // these copied from OpCodes.cs + public static readonly MyOp Nop = new MyOp(OpCodes.Nop); + public static readonly MyOp Break = new MyOp(OpCodes.Break); + public static readonly MyOp Ldarg_0 = new MyOp(OpCodes.Ldarg_0); + public static readonly MyOp Ldarg_1 = new MyOp(OpCodes.Ldarg_1); + public static readonly MyOp Ldarg_2 = new MyOp(OpCodes.Ldarg_2); + public static readonly MyOp Ldarg_3 = new MyOp(OpCodes.Ldarg_3); + public static readonly MyOp Ldloc_0 = new MyOp(OpCodes.Ldloc_0); + public static readonly MyOp Ldloc_1 = new MyOp(OpCodes.Ldloc_1); + public static readonly MyOp Ldloc_2 = new MyOp(OpCodes.Ldloc_2); + public static readonly MyOp Ldloc_3 = new MyOp(OpCodes.Ldloc_3); + public static readonly MyOp Stloc_0 = new MyOp(OpCodes.Stloc_0); + public static readonly MyOp Stloc_1 = new MyOp(OpCodes.Stloc_1); + public static readonly MyOp Stloc_2 = new MyOp(OpCodes.Stloc_2); + public static readonly MyOp Stloc_3 = new MyOp(OpCodes.Stloc_3); + public static readonly MyOp Ldarg_S = new MyOp(OpCodes.Ldarg_S); + public static readonly MyOp Ldarga_S = new MyOp(OpCodes.Ldarga_S); + public static readonly MyOp Starg_S = new MyOp(OpCodes.Starg_S); + public static readonly MyOp Ldloc_S = new MyOp(OpCodes.Ldloc_S); + public static readonly MyOp Ldloca_S = new MyOp(OpCodes.Ldloca_S); + public static readonly MyOp Stloc_S = new MyOp(OpCodes.Stloc_S); + public static readonly MyOp Ldnull = new MyOp(OpCodes.Ldnull); + public static readonly MyOp Ldc_I4_M1 = new MyOp(OpCodes.Ldc_I4_M1); + public static readonly MyOp Ldc_I4_0 = new MyOp(OpCodes.Ldc_I4_0); + public static readonly MyOp Ldc_I4_1 = new MyOp(OpCodes.Ldc_I4_1); + public static readonly MyOp Ldc_I4_2 = new MyOp(OpCodes.Ldc_I4_2); + public static readonly MyOp Ldc_I4_3 = new MyOp(OpCodes.Ldc_I4_3); + public static readonly MyOp Ldc_I4_4 = new MyOp(OpCodes.Ldc_I4_4); + public static readonly MyOp Ldc_I4_5 = new MyOp(OpCodes.Ldc_I4_5); + public static readonly MyOp Ldc_I4_6 = new MyOp(OpCodes.Ldc_I4_6); + public static readonly MyOp Ldc_I4_7 = new MyOp(OpCodes.Ldc_I4_7); + public static readonly MyOp Ldc_I4_8 = new MyOp(OpCodes.Ldc_I4_8); + public static readonly MyOp Ldc_I4_S = new MyOp(OpCodes.Ldc_I4_S); + public static readonly MyOp Ldc_I4 = new MyOp(OpCodes.Ldc_I4); + public static readonly MyOp Ldc_I8 = new MyOp(OpCodes.Ldc_I8); + public static readonly MyOp Ldc_R4 = new MyOp(OpCodes.Ldc_R4); + public static readonly MyOp Ldc_R8 = new MyOp(OpCodes.Ldc_R8); + public static readonly MyOp Dup = new MyOp(OpCodes.Dup); + public static readonly MyOp Pop = new MyOp(OpCodes.Pop); + public static readonly MyOp Jmp = new MyOp(OpCodes.Jmp); + public static readonly MyOp Call = new MyOp(OpCodes.Call); + public static readonly MyOp Calli = new MyOp(OpCodes.Calli); + public static readonly MyOp Ret = new MyOp(OpCodes.Ret); + public static readonly MyOp Br_S = new MyOp(OpCodes.Br_S); + public static readonly MyOp Brfalse_S = new MyOp(OpCodes.Brfalse_S); + public static readonly MyOp Brtrue_S = new MyOp(OpCodes.Brtrue_S); + public static readonly MyOp Beq_S = new MyOp(OpCodes.Beq_S, "=="); + public static readonly MyOp Bge_S = new MyOp(OpCodes.Bge_S, ">="); + public static readonly MyOp Bgt_S = new MyOp(OpCodes.Bgt_S, ">"); + public static readonly MyOp Ble_S = new MyOp(OpCodes.Ble_S, "<="); + public static readonly MyOp Blt_S = new MyOp(OpCodes.Blt_S, "<"); + public static readonly MyOp Bne_Un_S = new MyOp(OpCodes.Bne_Un_S, "!="); + public static readonly MyOp Bge_Un_S = new MyOp(OpCodes.Bge_Un_S); + public static readonly MyOp Bgt_Un_S = new MyOp(OpCodes.Bgt_Un_S); + public static readonly MyOp Ble_Un_S = new MyOp(OpCodes.Ble_Un_S); + public static readonly MyOp Blt_Un_S = new MyOp(OpCodes.Blt_Un_S); + public static readonly MyOp Br = new MyOp(OpCodes.Br); + public static readonly MyOp Brfalse = new MyOp(OpCodes.Brfalse, "!"); + public static readonly MyOp Brtrue = new MyOp(OpCodes.Brtrue, "!!"); + public static readonly MyOp Beq = new MyOp(OpCodes.Beq, "=="); + public static readonly MyOp Bge = new MyOp(OpCodes.Bge, ">="); + public static readonly MyOp Bgt = new MyOp(OpCodes.Bgt, ">"); + public static readonly MyOp Ble = new MyOp(OpCodes.Ble, "<="); + public static readonly MyOp Blt = new MyOp(OpCodes.Blt, "<"); + public static readonly MyOp Bne_Un = new MyOp(OpCodes.Bne_Un, "!="); + public static readonly MyOp Bge_Un = new MyOp(OpCodes.Bge_Un); + public static readonly MyOp Bgt_Un = new MyOp(OpCodes.Bgt_Un); + public static readonly MyOp Ble_Un = new MyOp(OpCodes.Ble_Un); + public static readonly MyOp Blt_Un = new MyOp(OpCodes.Blt_Un); + public static readonly MyOp Switch = new MyOp(OpCodes.Switch); + public static readonly MyOp Ldind_I1 = new MyOp(OpCodes.Ldind_I1); + public static readonly MyOp Ldind_U1 = new MyOp(OpCodes.Ldind_U1); + public static readonly MyOp Ldind_I2 = new MyOp(OpCodes.Ldind_I2); + public static readonly MyOp Ldind_U2 = new MyOp(OpCodes.Ldind_U2); + public static readonly MyOp Ldind_I4 = new MyOp(OpCodes.Ldind_I4); + public static readonly MyOp Ldind_U4 = new MyOp(OpCodes.Ldind_U4); + public static readonly MyOp Ldind_I8 = new MyOp(OpCodes.Ldind_I8); + public static readonly MyOp Ldind_I = new MyOp(OpCodes.Ldind_I); + public static readonly MyOp Ldind_R4 = new MyOp(OpCodes.Ldind_R4); + public static readonly MyOp Ldind_R8 = new MyOp(OpCodes.Ldind_R8); + public static readonly MyOp Ldind_Ref = new MyOp(OpCodes.Ldind_Ref); + public static readonly MyOp Stind_Ref = new MyOp(OpCodes.Stind_Ref); + public static readonly MyOp Stind_I1 = new MyOp(OpCodes.Stind_I1); + public static readonly MyOp Stind_I2 = new MyOp(OpCodes.Stind_I2); + public static readonly MyOp Stind_I4 = new MyOp(OpCodes.Stind_I4); + public static readonly MyOp Stind_I8 = new MyOp(OpCodes.Stind_I8); + public static readonly MyOp Stind_R4 = new MyOp(OpCodes.Stind_R4); + public static readonly MyOp Stind_R8 = new MyOp(OpCodes.Stind_R8); + public static readonly MyOp Add = new MyOp(OpCodes.Add, "+"); + public static readonly MyOp Sub = new MyOp(OpCodes.Sub, "-"); + public static readonly MyOp Mul = new MyOp(OpCodes.Mul, "*"); + public static readonly MyOp Div = new MyOp(OpCodes.Div, "/"); + public static readonly MyOp Div_Un = new MyOp(OpCodes.Div_Un); + public static readonly MyOp Rem = new MyOp(OpCodes.Rem, "%"); + public static readonly MyOp Rem_Un = new MyOp(OpCodes.Rem_Un); + public static readonly MyOp And = new MyOp(OpCodes.And, "&"); + public static readonly MyOp Or = new MyOp(OpCodes.Or, "|"); + public static readonly MyOp Xor = new MyOp(OpCodes.Xor, "^"); + public static readonly MyOp Shl = new MyOp(OpCodes.Shl, "<<"); + public static readonly MyOp Shr = new MyOp(OpCodes.Shr, ">>"); + public static readonly MyOp Shr_Un = new MyOp(OpCodes.Shr_Un); + public static readonly MyOp Neg = new MyOp(OpCodes.Neg, "-"); + public static readonly MyOp Not = new MyOp(OpCodes.Not, "~"); + public static readonly MyOp Conv_I1 = new MyOp(OpCodes.Conv_I1); + public static readonly MyOp Conv_I2 = new MyOp(OpCodes.Conv_I2); + public static readonly MyOp Conv_I4 = new MyOp(OpCodes.Conv_I4); + public static readonly MyOp Conv_I8 = new MyOp(OpCodes.Conv_I8); + public static readonly MyOp Conv_R4 = new MyOp(OpCodes.Conv_R4); + public static readonly MyOp Conv_R8 = new MyOp(OpCodes.Conv_R8); + public static readonly MyOp Conv_U4 = new MyOp(OpCodes.Conv_U4); + public static readonly MyOp Conv_U8 = new MyOp(OpCodes.Conv_U8); + public static readonly MyOp Callvirt = new MyOp(OpCodes.Callvirt); + public static readonly MyOp Cpobj = new MyOp(OpCodes.Cpobj); + public static readonly MyOp Ldobj = new MyOp(OpCodes.Ldobj); + public static readonly MyOp Ldstr = new MyOp(OpCodes.Ldstr); + public static readonly MyOp Newobj = new MyOp(OpCodes.Newobj); + public static readonly MyOp Castclass = new MyOp(OpCodes.Castclass); + public static readonly MyOp Isinst = new MyOp(OpCodes.Isinst); + public static readonly MyOp Conv_R_Un = new MyOp(OpCodes.Conv_R_Un); + public static readonly MyOp Unbox = new MyOp(OpCodes.Unbox); + public static readonly MyOp Throw = new MyOp(OpCodes.Throw); + public static readonly MyOp Ldfld = new MyOp(OpCodes.Ldfld); + public static readonly MyOp Ldflda = new MyOp(OpCodes.Ldflda); + public static readonly MyOp Stfld = new MyOp(OpCodes.Stfld); + public static readonly MyOp Ldsfld = new MyOp(OpCodes.Ldsfld); + public static readonly MyOp Ldsflda = new MyOp(OpCodes.Ldsflda); + public static readonly MyOp Stsfld = new MyOp(OpCodes.Stsfld); + public static readonly MyOp Stobj = new MyOp(OpCodes.Stobj); + public static readonly MyOp Conv_Ovf_I1_Un = new MyOp(OpCodes.Conv_Ovf_I1_Un); + public static readonly MyOp Conv_Ovf_I2_Un = new MyOp(OpCodes.Conv_Ovf_I2_Un); + public static readonly MyOp Conv_Ovf_I4_Un = new MyOp(OpCodes.Conv_Ovf_I4_Un); + public static readonly MyOp Conv_Ovf_I8_Un = new MyOp(OpCodes.Conv_Ovf_I8_Un); + public static readonly MyOp Conv_Ovf_U1_Un = new MyOp(OpCodes.Conv_Ovf_U1_Un); + public static readonly MyOp Conv_Ovf_U2_Un = new MyOp(OpCodes.Conv_Ovf_U2_Un); + public static readonly MyOp Conv_Ovf_U4_Un = new MyOp(OpCodes.Conv_Ovf_U4_Un); + public static readonly MyOp Conv_Ovf_U8_Un = new MyOp(OpCodes.Conv_Ovf_U8_Un); + public static readonly MyOp Conv_Ovf_I_Un = new MyOp(OpCodes.Conv_Ovf_I_Un); + public static readonly MyOp Conv_Ovf_U_Un = new MyOp(OpCodes.Conv_Ovf_U_Un); + public static readonly MyOp Box = new MyOp(OpCodes.Box); + public static readonly MyOp Newarr = new MyOp(OpCodes.Newarr); + public static readonly MyOp Ldlen = new MyOp(OpCodes.Ldlen); + public static readonly MyOp Ldelema = new MyOp(OpCodes.Ldelema); + public static readonly MyOp Ldelem_I1 = new MyOp(OpCodes.Ldelem_I1); + public static readonly MyOp Ldelem_U1 = new MyOp(OpCodes.Ldelem_U1); + public static readonly MyOp Ldelem_I2 = new MyOp(OpCodes.Ldelem_I2); + public static readonly MyOp Ldelem_U2 = new MyOp(OpCodes.Ldelem_U2); + public static readonly MyOp Ldelem_I4 = new MyOp(OpCodes.Ldelem_I4); + public static readonly MyOp Ldelem_U4 = new MyOp(OpCodes.Ldelem_U4); + public static readonly MyOp Ldelem_I8 = new MyOp(OpCodes.Ldelem_I8); + public static readonly MyOp Ldelem_I = new MyOp(OpCodes.Ldelem_I); + public static readonly MyOp Ldelem_R4 = new MyOp(OpCodes.Ldelem_R4); + public static readonly MyOp Ldelem_R8 = new MyOp(OpCodes.Ldelem_R8); + public static readonly MyOp Ldelem_Ref = new MyOp(OpCodes.Ldelem_Ref); + public static readonly MyOp Stelem_I = new MyOp(OpCodes.Stelem_I); + public static readonly MyOp Stelem_I1 = new MyOp(OpCodes.Stelem_I1); + public static readonly MyOp Stelem_I2 = new MyOp(OpCodes.Stelem_I2); + public static readonly MyOp Stelem_I4 = new MyOp(OpCodes.Stelem_I4); + public static readonly MyOp Stelem_I8 = new MyOp(OpCodes.Stelem_I8); + public static readonly MyOp Stelem_R4 = new MyOp(OpCodes.Stelem_R4); + public static readonly MyOp Stelem_R8 = new MyOp(OpCodes.Stelem_R8); + public static readonly MyOp Stelem_Ref = new MyOp(OpCodes.Stelem_Ref); + public static readonly MyOp Ldelem = new MyOp(OpCodes.Ldelem); + public static readonly MyOp Stelem = new MyOp(OpCodes.Stelem); + public static readonly MyOp Unbox_Any = new MyOp(OpCodes.Unbox_Any); + public static readonly MyOp Conv_Ovf_I1 = new MyOp(OpCodes.Conv_Ovf_I1); + public static readonly MyOp Conv_Ovf_U1 = new MyOp(OpCodes.Conv_Ovf_U1); + public static readonly MyOp Conv_Ovf_I2 = new MyOp(OpCodes.Conv_Ovf_I2); + public static readonly MyOp Conv_Ovf_U2 = new MyOp(OpCodes.Conv_Ovf_U2); + public static readonly MyOp Conv_Ovf_I4 = new MyOp(OpCodes.Conv_Ovf_I4); + public static readonly MyOp Conv_Ovf_U4 = new MyOp(OpCodes.Conv_Ovf_U4); + public static readonly MyOp Conv_Ovf_I8 = new MyOp(OpCodes.Conv_Ovf_I8); + public static readonly MyOp Conv_Ovf_U8 = new MyOp(OpCodes.Conv_Ovf_U8); + public static readonly MyOp Refanyval = new MyOp(OpCodes.Refanyval); + public static readonly MyOp Ckfinite = new MyOp(OpCodes.Ckfinite); + public static readonly MyOp Mkrefany = new MyOp(OpCodes.Mkrefany); + public static readonly MyOp Ldtoken = new MyOp(OpCodes.Ldtoken); + public static readonly MyOp Conv_U2 = new MyOp(OpCodes.Conv_U2); + public static readonly MyOp Conv_U1 = new MyOp(OpCodes.Conv_U1); + public static readonly MyOp Conv_I = new MyOp(OpCodes.Conv_I); + public static readonly MyOp Conv_Ovf_I = new MyOp(OpCodes.Conv_Ovf_I); + public static readonly MyOp Conv_Ovf_U = new MyOp(OpCodes.Conv_Ovf_U); + public static readonly MyOp Add_Ovf = new MyOp(OpCodes.Add_Ovf); + public static readonly MyOp Add_Ovf_Un = new MyOp(OpCodes.Add_Ovf_Un); + public static readonly MyOp Mul_Ovf = new MyOp(OpCodes.Mul_Ovf); + public static readonly MyOp Mul_Ovf_Un = new MyOp(OpCodes.Mul_Ovf_Un); + public static readonly MyOp Sub_Ovf = new MyOp(OpCodes.Sub_Ovf); + public static readonly MyOp Sub_Ovf_Un = new MyOp(OpCodes.Sub_Ovf_Un); + public static readonly MyOp Endfinally = new MyOp(OpCodes.Endfinally); + public static readonly MyOp Leave = new MyOp(OpCodes.Leave); + public static readonly MyOp Leave_S = new MyOp(OpCodes.Leave_S); + public static readonly MyOp Stind_I = new MyOp(OpCodes.Stind_I); + public static readonly MyOp Conv_U = new MyOp(OpCodes.Conv_U); + public static readonly MyOp Prefix7 = new MyOp(OpCodes.Prefix7); + public static readonly MyOp Prefix6 = new MyOp(OpCodes.Prefix6); + public static readonly MyOp Prefix5 = new MyOp(OpCodes.Prefix5); + public static readonly MyOp Prefix4 = new MyOp(OpCodes.Prefix4); + public static readonly MyOp Prefix3 = new MyOp(OpCodes.Prefix3); + public static readonly MyOp Prefix2 = new MyOp(OpCodes.Prefix2); + public static readonly MyOp Prefix1 = new MyOp(OpCodes.Prefix1); + public static readonly MyOp Prefixref = new MyOp(OpCodes.Prefixref); + public static readonly MyOp Arglist = new MyOp(OpCodes.Arglist); + public static readonly MyOp Ceq = new MyOp(OpCodes.Ceq, "=="); + public static readonly MyOp Cgt = new MyOp(OpCodes.Cgt, ">"); + public static readonly MyOp Cgt_Un = new MyOp(OpCodes.Cgt_Un); + public static readonly MyOp Clt = new MyOp(OpCodes.Clt, "<"); + public static readonly MyOp Clt_Un = new MyOp(OpCodes.Clt_Un); + public static readonly MyOp Ldftn = new MyOp(OpCodes.Ldftn); + public static readonly MyOp Ldvirtftn = new MyOp(OpCodes.Ldvirtftn); + public static readonly MyOp Ldarg = new MyOp(OpCodes.Ldarg); + public static readonly MyOp Ldarga = new MyOp(OpCodes.Ldarga); + public static readonly MyOp Starg = new MyOp(OpCodes.Starg); + public static readonly MyOp Ldloc = new MyOp(OpCodes.Ldloc); + public static readonly MyOp Ldloca = new MyOp(OpCodes.Ldloca); + public static readonly MyOp Stloc = new MyOp(OpCodes.Stloc); + public static readonly MyOp Localloc = new MyOp(OpCodes.Localloc); + public static readonly MyOp Endfilter = new MyOp(OpCodes.Endfilter); + public static readonly MyOp Unaligned = new MyOp(OpCodes.Unaligned); + public static readonly MyOp Volatile = new MyOp(OpCodes.Volatile); + public static readonly MyOp Tailcall = new MyOp(OpCodes.Tailcall); + public static readonly MyOp Initobj = new MyOp(OpCodes.Initobj); + public static readonly MyOp Constrained = new MyOp(OpCodes.Constrained); + public static readonly MyOp Cpblk = new MyOp(OpCodes.Cpblk); + public static readonly MyOp Initblk = new MyOp(OpCodes.Initblk); + public static readonly MyOp Rethrow = new MyOp(OpCodes.Rethrow); + public static readonly MyOp Sizeof = new MyOp(OpCodes.Sizeof); + public static readonly MyOp Refanytype = new MyOp(OpCodes.Refanytype); + public static readonly MyOp Readonly = new MyOp(OpCodes.Readonly); + + // used internally + public static readonly MyOp Cge = new MyOp("cge", ">="); + public static readonly MyOp Cle = new MyOp("cle", "<="); + public static readonly MyOp Cne = new MyOp("cne", "!="); + } + } +} diff --git a/OpenSim/Region/ScriptEngine/YEngine/XMRSDTypeClObj.cs b/OpenSim/Region/ScriptEngine/YEngine/XMRSDTypeClObj.cs new file mode 100644 index 0000000000..1bdd28e851 --- /dev/null +++ b/OpenSim/Region/ScriptEngine/YEngine/XMRSDTypeClObj.cs @@ -0,0 +1,275 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Reflection.Emit; + +using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; +using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; +using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; +using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list; +using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; +using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; +using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; + +namespace OpenSim.Region.ScriptEngine.Yengine +{ + public class XMRSDTypeClObj + { + /* + * Which script instance we are part of so we can access + * the script's global variables and functions. + */ + public XMRInstAbstract xmrInst; + + /* + * What class we actually are in the hierarchy + * used for casting. + */ + public TokenDeclSDTypeClass sdtcClass; + + /* + * Our VTable array, used for calling virtual functions. + * And ITable array, used for calling our implementation of interface functions. + */ + public Delegate[] sdtcVTable; + public Delegate[][] sdtcITable; + + /* + * These arrays hold the insance variable values. + * The array lengths are determined by the script compilation, + * and are found in TokenDeclSDTypeClass.instSizes. + */ + public XMRInstArrays instVars; + + /** + * @brief Called by script's $new() to initialize a new object. + */ + public XMRSDTypeClObj(XMRInstAbstract inst, int classindex) + { + Construct(inst, classindex); + instVars.AllocVarArrays(sdtcClass.instSizes); + } + + /** + * @brief Set up everything except the instVars arrays. + * @param inst = script instance this object is part of + * @param classindex = which script-defined type class this object is an onstance of + * @returns with the vtables filled in + */ + private void Construct(XMRInstAbstract inst, int classindex) + { + Delegate[] thisMid = null; + TokenDeclSDTypeClass clas = (TokenDeclSDTypeClass)inst.m_ObjCode.sdObjTypesIndx[classindex]; + + xmrInst = inst; + sdtcClass = clas; + instVars = new XMRInstArrays(inst); + + /* + * VTable consists of delegates built from DynamicMethods and the 'this' pointer. + * Yes, yes, lots of shitty little mallocs. + */ + DynamicMethod[] vDynMeths = clas.vDynMeths; + if(vDynMeths != null) + { + int n = vDynMeths.Length; + Type[] vMethTypes = clas.vMethTypes; + sdtcVTable = new Delegate[n]; + for(int i = 0; i < n; i++) + { + sdtcVTable[i] = vDynMeths[i].CreateDelegate(vMethTypes[i], this); + } + } + + /* + * Fill in interface vtables. + * There is one array of delegates for each implemented interface. + * The array of delegates IS the interface's object, ie, the 'this' value of the interface. + * To cast from the class type to the interface type, just get the correct array from the table. + * To cast from the interface type to the class type, just get Target of entry 0. + * + * So we end up with this: + * sdtcITable[interfacenumber][methodofintfnumber] = delegate of this.ourimplementationofinterfacesmethod + */ + if(clas.iDynMeths != null) + { + int nIFaces = clas.iDynMeths.Length; + sdtcITable = new Delegate[nIFaces][]; + for(int i = 0; i < nIFaces; i++) + { + + // get vector of entrypoints of our instance methods that implement that interface + DynamicMethod[] iDynMeths = clas.iDynMeths[i]; + Type[] iMethTypes = clas.iMethTypes[i]; + + // allocate an array with a slot for each method the interface defines + int nMeths = iDynMeths.Length; + Delegate[] ivec; + if(nMeths > 0) + { + // fill in the array with delegates that reference back to this class instance + ivec = new Delegate[nMeths]; + for(int j = 0; j < nMeths; j++) + { + ivec[j] = iDynMeths[j].CreateDelegate(iMethTypes[j], this); + } + } + else + { + // just a marker interface with no methods, + // allocate a one-element array and fill + // with a dummy entry. this will allow casting + // back to the original class instance (this) + // by reading Target of entry 0. + if(thisMid == null) + { + thisMid = new Delegate[1]; + thisMid[0] = markerInterfaceDummy.CreateDelegate(typeof(MarkerInterfaceDummy), this); + } + ivec = thisMid; + } + + // save whatever we ended up allocating + sdtcITable[i] = ivec; + } + } + } + + private delegate void MarkerInterfaceDummy(); + private static DynamicMethod markerInterfaceDummy = MakeMarkerInterfaceDummy(); + private static DynamicMethod MakeMarkerInterfaceDummy() + { + DynamicMethod dm = new DynamicMethod("XMRSDTypeClObj.MarkerInterfaceDummy", null, new Type[] { typeof(XMRSDTypeClObj) }); + ILGenerator ilGen = dm.GetILGenerator(); + ilGen.Emit(OpCodes.Ret); + return dm; + } + + /** + * @brief Perform runtime casting of script-defined interface object to + * its corresponding script-defined class object. + * @param da = interface object (array of delegates pointing to class's implementations of interface's methods) + * @param classindex = what class those implementations are supposedly part of + * @returns original script-defined class object + */ + public static XMRSDTypeClObj CastIFace2Class(Delegate[] da, int classindex) + { + return CastClass2Class(da[0].Target, classindex); + } + + /** + * @brief Perform runtime casting of XMRSDTypeClObj's. + * @param ob = XMRSDTypeClObj of unknown script-defined class to cast + * @param classindex = script-defined class to cast it to + * @returns ob is a valid instance of classindex; else exception thrown + */ + public static XMRSDTypeClObj CastClass2Class(object ob, int classindex) + { + /* + * Let mono check to see if we at least have an XMRSDTypeClObj. + */ + XMRSDTypeClObj ci = (XMRSDTypeClObj)ob; + if(ci != null) + { + + /* + * This is the target class, ie, what we are hoping the object can cast to. + */ + TokenDeclSDTypeClass tc = (TokenDeclSDTypeClass)ci.xmrInst.m_ObjCode.sdObjTypesIndx[classindex]; + + /* + * Step from the object's actual class rootward. + * If we find the target class along the way, the cast is valid. + * If we run off the end of the root, the cast is not valid. + */ + for(TokenDeclSDTypeClass ac = ci.sdtcClass; ac != tc; ac = ac.extends) + { + if(ac == null) + throw new InvalidCastException("invalid cast from " + ci.sdtcClass.longName.val + + " to " + tc.longName.val); + } + + /* + * The target class is at or rootward of the actual class, + * so the cast is valid. + */ + } + return ci; + } + + /** + * @brief Cast an arbitrary object to the given interface. + * @param ob = object to be cast of unknown type + * @returns ob cast to the interface type + */ + public static Delegate[] CastObj2IFace(object ob, string ifacename) + { + if(ob == null) + return null; + + /* + * If it is already one of our interfaces, extract the script-defined class object from it. + */ + if(ob is Delegate[]) + { + Delegate[] da = (Delegate[])ob; + ob = da[0].Target; + } + + /* + * Now that we have a presumed script-defined class object, cast that to the requested interface + * by picking the array of delegates that corresponds to the requested interface. + */ + XMRSDTypeClObj ci = (XMRSDTypeClObj)ob; + int iFaceIndex = ci.sdtcClass.intfIndices[ifacename]; + return ci.sdtcITable[iFaceIndex]; + } + + /** + * @brief Write the whole thing out to a stream. + */ + public void Capture(XMRInstArrays.Sender sendValue) + { + sendValue(this.sdtcClass.sdTypeIndex); + this.instVars.SendArrays(sendValue); + } + + /** + * @brief Read the whole thing in from a stream. + */ + public XMRSDTypeClObj() + { + } + public void Restore(XMRInstAbstract inst, XMRInstArrays.Recver recvValue) + { + int classindex = (int)recvValue(); + Construct(inst, classindex); + this.instVars.RecvArrays(recvValue); + } + } +} diff --git a/OpenSim/Region/ScriptEngine/YEngine/XMRScriptThread.cs b/OpenSim/Region/ScriptEngine/YEngine/XMRScriptThread.cs new file mode 100644 index 0000000000..08c7e80c92 --- /dev/null +++ b/OpenSim/Region/ScriptEngine/YEngine/XMRScriptThread.cs @@ -0,0 +1,240 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using OpenSim.Framework.Monitoring; +using System; +using System.Collections.Generic; +using System.Threading; + +namespace OpenSim.Region.ScriptEngine.Yengine +{ + + public partial class Yengine + { + private int m_WakeUpOne = 0; + public object m_WakeUpLock = new object(); + + private Dictionary m_RunningInstances = new Dictionary(); + + private bool m_SuspendScriptThreadFlag = false; + private bool m_WakeUpThis = false; + public DateTime m_LastRanAt = DateTime.MinValue; + public long m_ScriptExecTime = 0; + + [ThreadStatic] + private static int m_ScriptThreadTID; + + public static bool IsScriptThread + { + get + { + return m_ScriptThreadTID != 0; + } + } + + public void StartThreadWorker(int i) + { + Thread thd; + if(i >= 0) + thd = Yengine.StartMyThread(RunScriptThread, "YScript" + i.ToString(), ThreadPriority.BelowNormal); + else + thd = Yengine.StartMyThread(RunScriptThread, "YScript", ThreadPriority.BelowNormal); + lock(m_WakeUpLock) + m_RunningInstances.Add(thd.ManagedThreadId, null); + } + + public void StopThreadWorkers() + { + lock(m_WakeUpLock) + { + while(m_RunningInstances.Count != 0) + { + Monitor.PulseAll(m_WakeUpLock); + Monitor.Wait(m_WakeUpLock, Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS / 2); + } + } + } + + /** + * @brief Something was just added to the Start or Yield queue so + * wake one of the RunScriptThread() instances to run it. + */ + public void WakeUpOne() + { + lock(m_WakeUpLock) + { + m_WakeUpOne++; + Monitor.Pulse(m_WakeUpLock); + } + } + + public void SuspendThreads() + { + lock(m_WakeUpLock) + { + m_SuspendScriptThreadFlag = true; + Monitor.PulseAll(m_WakeUpLock); + } + } + + public void ResumeThreads() + { + lock(m_WakeUpLock) + { + m_SuspendScriptThreadFlag = false; + Monitor.PulseAll(m_WakeUpLock); + } + } + + /** + * @brief Thread that runs the scripts. + * + * There are NUMSCRIPTHREADWKRS of these. + * Each sits in a loop checking the Start and Yield queues for + * a script to run and calls the script as a microthread. + */ + private void RunScriptThread() + { + int tid = System.Threading.Thread.CurrentThread.ManagedThreadId; + ThreadStart thunk; + XMRInstance inst; + bool didevent; + m_ScriptThreadTID = tid; + + while(!m_Exiting) + { + Yengine.UpdateMyThread(); + + lock(m_WakeUpLock) + { + // Maybe there are some scripts waiting to be migrated in or out. + thunk = null; + if(m_ThunkQueue.Count > 0) + thunk = m_ThunkQueue.Dequeue(); + + // Handle 'xmr resume/suspend' commands. + else if(m_SuspendScriptThreadFlag && !m_Exiting) + { + Monitor.Wait(m_WakeUpLock, Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS / 2); + Yengine.UpdateMyThread(); + continue; + } + } + + if(thunk != null) + { + thunk(); + continue; + } + + if(m_StartProcessing) + { + // If event just queued to any idle scripts + // start them right away. But only start so + // many so we can make some progress on yield + // queue. + int numStarts; + didevent = false; + for(numStarts = 5; numStarts >= 0; --numStarts) + { + lock(m_StartQueue) + inst = m_StartQueue.RemoveHead(); + + if(inst == null) + break; + if(inst.m_IState != XMRInstState.ONSTARTQ) + throw new Exception("bad state"); + RunInstance(inst, tid); + if(m_SuspendScriptThreadFlag || m_Exiting) + continue; + didevent = true; + } + + // If there is something to run, run it + // then rescan from the beginning in case + // a lot of things have changed meanwhile. + // + // These are considered lower priority than + // m_StartQueue as they have been taking at + // least one quantum of CPU time and event + // handlers are supposed to be quick. + lock(m_YieldQueue) + inst = m_YieldQueue.RemoveHead(); + + if(inst != null) + { + if(inst.m_IState != XMRInstState.ONYIELDQ) + throw new Exception("bad state"); + RunInstance(inst, tid); + continue; + } + + // If we left something dangling in the m_StartQueue or m_YieldQueue, go back to check it. + if(didevent) + continue; + } + + // Nothing to do, sleep. + lock(m_WakeUpLock) + { + if(!m_WakeUpThis && (m_WakeUpOne <= 0) && !m_Exiting) + Monitor.Wait(m_WakeUpLock, Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS / 2); + + m_WakeUpThis = false; + if((m_WakeUpOne > 0) && (--m_WakeUpOne > 0)) + Monitor.Pulse(m_WakeUpLock); + } + } + lock(m_WakeUpLock) + m_RunningInstances.Remove(tid); + + Yengine.MyThreadExiting(); + } + + /** + * @brief A script instance was just removed from the Start or Yield Queue. + * So run it for a little bit then stick in whatever queue it should go in. + */ + private void RunInstance(XMRInstance inst, int tid) + { + m_LastRanAt = DateTime.UtcNow; + m_ScriptExecTime -= (long)(m_LastRanAt - DateTime.MinValue).TotalMilliseconds; + inst.m_IState = XMRInstState.RUNNING; + + lock(m_WakeUpLock) + m_RunningInstances[tid] = inst; + + XMRInstState newIState = inst.RunOne(); + + lock(m_WakeUpLock) + m_RunningInstances[tid] = null; + + HandleNewIState(inst, newIState); + m_ScriptExecTime += (long)(DateTime.UtcNow - DateTime.MinValue).TotalMilliseconds; + } + } +} diff --git a/OpenSim/Region/ScriptEngine/YEngine/XMRScriptUThread.cs b/OpenSim/Region/ScriptEngine/YEngine/XMRScriptUThread.cs new file mode 100644 index 0000000000..5806d36ba2 --- /dev/null +++ b/OpenSim/Region/ScriptEngine/YEngine/XMRScriptUThread.cs @@ -0,0 +1,97 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Threading; + +namespace OpenSim.Region.ScriptEngine.Yengine +{ + + public partial class XMRInstance + { + /** + * @brief Start script event handler from the beginning. + * Return when either the script event handler completes + * or the script calls Hiber(). + * @returns null: script did not throw any exception so far + * else: script threw an exception + */ + public Exception StartEx() + { + // Start script event handler from very beginning. + callMode = XMRInstance.CallMode_NORMAL; + try + { + CallSEH(); // run script event handler + } + catch(StackHibernateException) + { + if(callMode != XMRInstance.CallMode_SAVE) + throw new Exception("callMode=" + callMode); + } + catch(Exception e) + { + return e; + } + + return null; + } + + /** + * @brief We now want to run some more script code from where it last hibernated + * until it either finishes the script event handler or until the script + * calls Hiber() again. + */ + public Exception ResumeEx() + { + // Resume script from captured stack. + callMode = XMRInstance.CallMode_RESTORE; + suspendOnCheckRunTemp = true; + try + { + CallSEH(); // run script event handler + } + catch(StackHibernateException) + { + if(callMode != XMRInstance.CallMode_SAVE) + throw new Exception("callMode=" + callMode); + } + catch(Exception e) + { + return e; + } + + return null; + } + + public class StackHibernateException: Exception, IXMRUncatchable + { + } + } +} diff --git a/OpenSim/Server/Base/ServerUtils.cs b/OpenSim/Server/Base/ServerUtils.cs index b17d7ba5c1..d0043ba7d9 100644 --- a/OpenSim/Server/Base/ServerUtils.cs +++ b/OpenSim/Server/Base/ServerUtils.cs @@ -39,7 +39,7 @@ using OpenMetaverse; using Mono.Addins; using OpenSim.Framework.Servers.HttpServer; using OpenSim.Framework.Servers; - +using OpenMetaverse.StructuredData; // LitJson is hidden on this [assembly:AddinRoot("Robust", OpenSim.VersionInfo.VersionNumber)] namespace OpenSim.Server.Base @@ -327,49 +327,62 @@ namespace OpenSim.Server.Base public static Dictionary ParseQueryString(string query) { - Dictionary result = new Dictionary(); string[] terms = query.Split(new char[] {'&'}); - if (terms.Length == 0) - return result; + int nterms = terms.Length; + if (nterms == 0) + return new Dictionary(); - foreach (string t in terms) + Dictionary result = new Dictionary(nterms); + string name; + + for(int i = 0; i < nterms; ++i) { - string[] elems = t.Split(new char[] {'='}); + string[] elems = terms[i].Split(new char[] {'='}); + if (elems.Length == 0) continue; - string name = System.Web.HttpUtility.UrlDecode(elems[0]); - string value = String.Empty; + if(String.IsNullOrWhiteSpace(elems[0])) + continue; - if (elems.Length > 1) - value = System.Web.HttpUtility.UrlDecode(elems[1]); + name = System.Web.HttpUtility.UrlDecode(elems[0]); if (name.EndsWith("[]")) { - string cleanName = name.Substring(0, name.Length - 2); - if (result.ContainsKey(cleanName)) + name = name.Substring(0, name.Length - 2); + if(String.IsNullOrWhiteSpace(name)) + continue; + if (result.ContainsKey(name)) { - if (!(result[cleanName] is List)) + if (!(result[name] is List)) continue; - List l = (List)result[cleanName]; - - l.Add(value); + List l = (List)result[name]; + if (elems.Length > 1 && !String.IsNullOrWhiteSpace(elems[1])) + l.Add(System.Web.HttpUtility.UrlDecode(elems[1])); + else + l.Add(String.Empty); } else { List newList = new List(); - - newList.Add(value); - - result[cleanName] = newList; + if (elems.Length > 1 && !String.IsNullOrWhiteSpace(elems[1])) + newList.Add(System.Web.HttpUtility.UrlDecode(elems[1])); + else + newList.Add(String.Empty); + result[name] = newList; } } else { if (!result.ContainsKey(name)) - result[name] = value; + { + if (elems.Length > 1 && !String.IsNullOrWhiteSpace(elems[1])) + result[name] = System.Web.HttpUtility.UrlDecode(elems[1]); + else + result[name] = String.Empty; + } } } @@ -378,47 +391,70 @@ namespace OpenSim.Server.Base public static string BuildQueryString(Dictionary data) { - string qstring = String.Empty; + // this is not conform to html url encoding + // can only be used on Body of POST or PUT + StringBuilder sb = new StringBuilder(4096); - string part; + string pvalue; foreach (KeyValuePair kvp in data) { if (kvp.Value is List) { List l = (List)kvp.Value; - - foreach (string s in l) + int llen = l.Count; + string nkey = System.Web.HttpUtility.UrlEncode(kvp.Key); + for(int i = 0; i < llen; ++i) { - part = System.Web.HttpUtility.UrlEncode(kvp.Key) + - "[]=" + System.Web.HttpUtility.UrlEncode(s); - - if (qstring != String.Empty) - qstring += "&"; - - qstring += part; + if (sb.Length != 0) + sb.Append("&"); + sb.Append(nkey); + sb.Append("[]="); + sb.Append(System.Web.HttpUtility.UrlEncode(l[i])); } } + else if(kvp.Value is Dictionary) + { + // encode complex structures as JSON + // needed for estate bans with the encoding used on xml + // encode can be here because object does contain the structure information + // but decode needs to be on estateSettings (or other user) + string js; + try + { + // bypass libovm, we dont need even more useless high level maps + // this should only be called once.. but no problem, i hope + // (other uses may need more..) + LitJson.JsonMapper.RegisterExporter((uuid, writer) => writer.Write(uuid.ToString()) ); + js = LitJson.JsonMapper.ToJson(kvp.Value); + } + // catch(Exception e) + catch + { + continue; + } + if (sb.Length != 0) + sb.Append("&"); + sb.Append(System.Web.HttpUtility.UrlEncode(kvp.Key)); + sb.Append("="); + sb.Append(System.Web.HttpUtility.UrlEncode(js)); + } else { - if (kvp.Value.ToString() != String.Empty) + if (sb.Length != 0) + sb.Append("&"); + sb.Append(System.Web.HttpUtility.UrlEncode(kvp.Key)); + + pvalue = kvp.Value.ToString(); + if (!String.IsNullOrEmpty(pvalue)) { - part = System.Web.HttpUtility.UrlEncode(kvp.Key) + - "=" + System.Web.HttpUtility.UrlEncode(kvp.Value.ToString()); + sb.Append("="); + sb.Append(System.Web.HttpUtility.UrlEncode(pvalue)); } - else - { - part = System.Web.HttpUtility.UrlEncode(kvp.Key); - } - - if (qstring != String.Empty) - qstring += "&"; - - qstring += part; } } - return qstring; + return sb.ToString(); } public static string BuildXmlResponse(Dictionary data) @@ -478,17 +514,22 @@ namespace OpenSim.Server.Base XmlDocument doc = new XmlDocument(); - doc.LoadXml(data); + try + { + doc.LoadXml(data); + XmlNodeList rootL = doc.GetElementsByTagName("ServerResponse"); - XmlNodeList rootL = doc.GetElementsByTagName("ServerResponse"); + if (rootL.Count != 1) + return ret; - if (rootL.Count != 1) - return ret; - - XmlNode rootNode = rootL[0]; - - ret = ParseElement(rootNode); + XmlNode rootNode = rootL[0]; + ret = ParseElement(rootNode); + } + catch (Exception e) + { + m_log.DebugFormat("[serverUtils.ParseXmlResponse]: failed error: {0} \n --- string: {1} - ",e.Message, data); + } return ret; } diff --git a/OpenSim/Server/Base/ServicesServerBase.cs b/OpenSim/Server/Base/ServicesServerBase.cs index d151de663e..900327a792 100644 --- a/OpenSim/Server/Base/ServicesServerBase.cs +++ b/OpenSim/Server/Base/ServicesServerBase.cs @@ -61,8 +61,9 @@ namespace OpenSim.Server.Base // private bool m_Running = true; +#if (_MONO) private static Mono.Unix.UnixSignal[] signals; - +#endif // Handle all the automagical stuff // @@ -186,6 +187,7 @@ namespace OpenSim.Server.Base RegisterCommonCommands(); RegisterCommonComponents(Config); +#if (_MONO) Thread signal_thread = new Thread (delegate () { while (true) @@ -209,6 +211,7 @@ namespace OpenSim.Server.Base { new Mono.Unix.UnixSignal(Mono.Unix.Native.Signum.SIGTERM) }; + ignal_thread.IsBackground = true; signal_thread.Start(); } catch (Exception e) @@ -218,6 +221,7 @@ namespace OpenSim.Server.Base m_log.Debug("Exception was: ", e); } } +#endif // Allow derived classes to perform initialization that // needs to be done after the console has opened @@ -246,6 +250,9 @@ namespace OpenSim.Server.Base } } + MemoryWatchdog.Enabled = false; + Watchdog.Enabled = false; + WorkManager.Stop(); RemovePIDFile(); return 0; @@ -253,6 +260,8 @@ namespace OpenSim.Server.Base protected override void ShutdownSpecific() { + if(!m_Running) + return; m_Running = false; m_log.Info("[CONSOLE] Quitting"); diff --git a/OpenSim/Server/Handlers/Authentication/AuthenticationServerPostHandler.cs b/OpenSim/Server/Handlers/Authentication/AuthenticationServerPostHandler.cs index d3ea7e23da..4f03cf4a28 100644 --- a/OpenSim/Server/Handlers/Authentication/AuthenticationServerPostHandler.cs +++ b/OpenSim/Server/Handlers/Authentication/AuthenticationServerPostHandler.cs @@ -82,11 +82,11 @@ namespace OpenSim.Server.Handlers.Authentication switch (p[0]) { case "plain": - StreamReader sr = new StreamReader(request); - string body = sr.ReadToEnd(); - sr.Close(); - + string body; + using(StreamReader sr = new StreamReader(request)) + body = sr.ReadToEnd(); return DoPlainMethods(body); + case "crypt": byte[] buffer = new byte[request.Length]; long length = request.Length; diff --git a/OpenSim/Server/Handlers/Authentication/OpenIdServerHandler.cs b/OpenSim/Server/Handlers/Authentication/OpenIdServerHandler.cs index a6605a113b..254b82fadd 100644 --- a/OpenSim/Server/Handlers/Authentication/OpenIdServerHandler.cs +++ b/OpenSim/Server/Handlers/Authentication/OpenIdServerHandler.cs @@ -222,7 +222,10 @@ For more information, see http://openid.net/. try { - NameValueCollection postQuery = HttpUtility.ParseQueryString(new StreamReader(httpRequest.InputStream).ReadToEnd()); + string forPost; + using(StreamReader sr = new StreamReader(httpRequest.InputStream)) + forPost = sr.ReadToEnd(); + NameValueCollection postQuery = HttpUtility.ParseQueryString(forPost); NameValueCollection getQuery = HttpUtility.ParseQueryString(httpRequest.Url.Query); NameValueCollection openIdQuery = (postQuery.GetValues("openid.mode") != null ? postQuery : getQuery); diff --git a/OpenSim/Server/Handlers/Avatar/AvatarServerPostHandler.cs b/OpenSim/Server/Handlers/Avatar/AvatarServerPostHandler.cs index 69c1a896f7..b8fdacfb60 100644 --- a/OpenSim/Server/Handlers/Avatar/AvatarServerPostHandler.cs +++ b/OpenSim/Server/Handlers/Avatar/AvatarServerPostHandler.cs @@ -60,9 +60,9 @@ namespace OpenSim.Server.Handlers.Avatar protected override byte[] ProcessRequest(string path, Stream requestData, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { - StreamReader sr = new StreamReader(requestData); - string body = sr.ReadToEnd(); - sr.Close(); + string body; + using(StreamReader sr = new StreamReader(requestData)) + body = sr.ReadToEnd(); body = body.Trim(); //m_log.DebugFormat("[XXX]: query String: {0}", body); diff --git a/OpenSim/Server/Handlers/BakedTextures/XBakesPostHandler.cs b/OpenSim/Server/Handlers/BakedTextures/XBakesPostHandler.cs index 24f63d9319..d16000d572 100644 --- a/OpenSim/Server/Handlers/BakedTextures/XBakesPostHandler.cs +++ b/OpenSim/Server/Handlers/BakedTextures/XBakesPostHandler.cs @@ -65,10 +65,8 @@ namespace OpenSim.Server.Handlers.BakedTextures return new byte[0]; } - StreamReader sr = new StreamReader(request); - - m_BakesService.Store(p[0], sr.ReadToEnd()); - sr.Close(); + using(StreamReader sr = new StreamReader(request)) + m_BakesService.Store(p[0],sr.ReadToEnd()); return new byte[0]; } diff --git a/OpenSim/Server/Handlers/Estate/EstateDataRobustConnector.cs b/OpenSim/Server/Handlers/Estate/EstateDataRobustConnector.cs index e0c281044f..b7558ec2a9 100644 --- a/OpenSim/Server/Handlers/Estate/EstateDataRobustConnector.cs +++ b/OpenSim/Server/Handlers/Estate/EstateDataRobustConnector.cs @@ -282,9 +282,10 @@ namespace OpenSim.Server.Handlers // /estates/estate/?eid=int®ion=uuid if ("estate".Equals(resource)) { - StreamReader sr = new StreamReader(request); - string body = sr.ReadToEnd(); - sr.Close(); + string body; + using(StreamReader sr = new StreamReader(request)) + body = sr.ReadToEnd(); + body = body.Trim(); Dictionary requestData = ServerUtils.ParseQueryString(body); diff --git a/OpenSim/Server/Handlers/Friends/FriendsServerPostHandler.cs b/OpenSim/Server/Handlers/Friends/FriendsServerPostHandler.cs index 3aab30b3c3..d6668abe13 100644 --- a/OpenSim/Server/Handlers/Friends/FriendsServerPostHandler.cs +++ b/OpenSim/Server/Handlers/Friends/FriendsServerPostHandler.cs @@ -61,9 +61,9 @@ namespace OpenSim.Server.Handlers.Friends protected override byte[] ProcessRequest(string path, Stream requestData, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { - StreamReader sr = new StreamReader(requestData); - string body = sr.ReadToEnd(); - sr.Close(); + string body; + using(StreamReader sr = new StreamReader(requestData)) + body = sr.ReadToEnd(); body = body.Trim(); //m_log.DebugFormat("[XXX]: query String: {0}", body); diff --git a/OpenSim/Server/Handlers/Grid/GridServerPostHandler.cs b/OpenSim/Server/Handlers/Grid/GridServerPostHandler.cs index f51c4ee48c..44d4654ceb 100644 --- a/OpenSim/Server/Handlers/Grid/GridServerPostHandler.cs +++ b/OpenSim/Server/Handlers/Grid/GridServerPostHandler.cs @@ -65,9 +65,9 @@ namespace OpenSim.Server.Handlers.Grid protected override byte[] ProcessRequest(string path, Stream requestData, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { - StreamReader sr = new StreamReader(requestData); - string body = sr.ReadToEnd(); - sr.Close(); + string body; + using(StreamReader sr = new StreamReader(requestData)) + body = sr.ReadToEnd(); body = body.Trim(); //m_log.DebugFormat("[XXX]: query String: {0}", body); diff --git a/OpenSim/Server/Handlers/GridUser/GridUserServerConnector.cs b/OpenSim/Server/Handlers/GridUser/GridUserServerConnector.cs index 1e29378c26..755272bc28 100644 --- a/OpenSim/Server/Handlers/GridUser/GridUserServerConnector.cs +++ b/OpenSim/Server/Handlers/GridUser/GridUserServerConnector.cs @@ -56,7 +56,7 @@ namespace OpenSim.Server.Handlers.GridUser Object[] args = new Object[] { config }; m_GridUserService = ServerUtils.LoadPlugin(service, args); - IServiceAuth auth = ServiceAuth.Create(config, m_ConfigName); ; + IServiceAuth auth = ServiceAuth.Create(config, m_ConfigName); server.AddStreamHandler(new GridUserServerPostHandler(m_GridUserService, auth)); } diff --git a/OpenSim/Server/Handlers/GridUser/GridUserServerPostHandler.cs b/OpenSim/Server/Handlers/GridUser/GridUserServerPostHandler.cs index 8806c2cbbd..1f691d66b2 100644 --- a/OpenSim/Server/Handlers/GridUser/GridUserServerPostHandler.cs +++ b/OpenSim/Server/Handlers/GridUser/GridUserServerPostHandler.cs @@ -60,9 +60,9 @@ namespace OpenSim.Server.Handlers.GridUser protected override byte[] ProcessRequest(string path, Stream requestData, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { - StreamReader sr = new StreamReader(requestData); - string body = sr.ReadToEnd(); - sr.Close(); + string body; + using(StreamReader sr = new StreamReader(requestData)) + body = sr.ReadToEnd(); body = body.Trim(); //m_log.DebugFormat("[XXX]: query String: {0}", body); diff --git a/OpenSim/Server/Handlers/Hypergrid/HGFriendsServerPostHandler.cs b/OpenSim/Server/Handlers/Hypergrid/HGFriendsServerPostHandler.cs index 8116050afe..fc1a77d0e1 100644 --- a/OpenSim/Server/Handlers/Hypergrid/HGFriendsServerPostHandler.cs +++ b/OpenSim/Server/Handlers/Hypergrid/HGFriendsServerPostHandler.cs @@ -71,9 +71,9 @@ namespace OpenSim.Server.Handlers.Hypergrid protected override byte[] ProcessRequest(string path, Stream requestData, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { - StreamReader sr = new StreamReader(requestData); - string body = sr.ReadToEnd(); - sr.Close(); + string body; + using(StreamReader sr = new StreamReader(requestData)) + body = sr.ReadToEnd(); body = body.Trim(); //m_log.DebugFormat("[XXX]: query String: {0}", body); diff --git a/OpenSim/Server/Handlers/Inventory/XInventoryInConnector.cs b/OpenSim/Server/Handlers/Inventory/XInventoryInConnector.cs index 4400395c30..742d1a045b 100644 --- a/OpenSim/Server/Handlers/Inventory/XInventoryInConnector.cs +++ b/OpenSim/Server/Handlers/Inventory/XInventoryInConnector.cs @@ -95,9 +95,9 @@ namespace OpenSim.Server.Handlers.Inventory protected override byte[] ProcessRequest(string path, Stream requestData, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { - StreamReader sr = new StreamReader(requestData); - string body = sr.ReadToEnd(); - sr.Close(); + string body; + using(StreamReader sr = new StreamReader(requestData)) + body = sr.ReadToEnd(); body = body.Trim(); //m_log.DebugFormat("[XXX]: query String: {0}", body); diff --git a/OpenSim/Server/Handlers/Land/LandHandlers.cs b/OpenSim/Server/Handlers/Land/LandHandlers.cs index 150eaae995..d74077a365 100644 --- a/OpenSim/Server/Handlers/Land/LandHandlers.cs +++ b/OpenSim/Server/Handlers/Land/LandHandlers.cs @@ -85,6 +85,7 @@ namespace OpenSim.Server.Handlers.Land hash["SnapshotID"] = landData.SnapshotID.ToString(); hash["UserLocation"] = landData.UserLocation.ToString(); hash["RegionAccess"] = regionAccess.ToString(); + hash["Dwell"] = landData.Dwell.ToString(); } XmlRpcResponse response = new XmlRpcResponse(); diff --git a/OpenSim/Server/Handlers/Login/LLLoginHandlers.cs b/OpenSim/Server/Handlers/Login/LLLoginHandlers.cs index 072429a8f7..4e7ab00cec 100644 --- a/OpenSim/Server/Handlers/Login/LLLoginHandlers.cs +++ b/OpenSim/Server/Handlers/Login/LLLoginHandlers.cs @@ -64,7 +64,7 @@ namespace OpenSim.Server.Handlers.Login public XmlRpcResponse HandleXMLRPCLogin(XmlRpcRequest request, IPEndPoint remoteClient) { Hashtable requestData = (Hashtable)request.Params[0]; - if (m_Proxy && request.Params[3] != null) + if (request.Params[3] != null) { IPEndPoint ep = Util.GetClientIPFromXFF((string)request.Params[3]); if (ep != null) diff --git a/OpenSim/Server/Handlers/Map/MapAddServerConnector.cs b/OpenSim/Server/Handlers/Map/MapAddServerConnector.cs index 7611f538dd..331dabf9a9 100644 --- a/OpenSim/Server/Handlers/Map/MapAddServerConnector.cs +++ b/OpenSim/Server/Handlers/Map/MapAddServerConnector.cs @@ -104,9 +104,9 @@ namespace OpenSim.Server.Handlers.MapImage protected override byte[] ProcessRequest(string path, Stream requestData, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { // m_log.DebugFormat("[MAP SERVICE IMAGE HANDLER]: Received {0}", path); - StreamReader sr = new StreamReader(requestData); - string body = sr.ReadToEnd(); - sr.Close(); + string body; + using(StreamReader sr = new StreamReader(requestData)) + body = sr.ReadToEnd(); body = body.Trim(); try @@ -225,8 +225,8 @@ namespace OpenSim.Server.Handlers.MapImage private System.Net.IPAddress GetCallerIP(IOSHttpRequest request) { - if (!m_Proxy) - return request.RemoteIPEndPoint.Address; +// if (!m_Proxy) +// return request.RemoteIPEndPoint.Address; // We're behind a proxy string xff = "X-Forwarded-For"; @@ -236,7 +236,7 @@ namespace OpenSim.Server.Handlers.MapImage if (xffValue == null || (xffValue != null && xffValue == string.Empty)) { - m_log.WarnFormat("[MAP IMAGE HANDLER]: No XFF header"); +// m_log.WarnFormat("[MAP IMAGE HANDLER]: No XFF header"); return request.RemoteIPEndPoint.Address; } diff --git a/OpenSim/Server/Handlers/Map/MapRemoveServerConnector.cs b/OpenSim/Server/Handlers/Map/MapRemoveServerConnector.cs index f292b9585d..9daeb73729 100644 --- a/OpenSim/Server/Handlers/Map/MapRemoveServerConnector.cs +++ b/OpenSim/Server/Handlers/Map/MapRemoveServerConnector.cs @@ -102,9 +102,9 @@ namespace OpenSim.Server.Handlers.MapImage public override byte[] Handle(string path, Stream requestData, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { // m_log.DebugFormat("[MAP SERVICE IMAGE HANDLER]: Received {0}", path); - StreamReader sr = new StreamReader(requestData); - string body = sr.ReadToEnd(); - sr.Close(); + string body; + using(StreamReader sr = new StreamReader(requestData)) + body = sr.ReadToEnd(); body = body.Trim(); try @@ -215,19 +215,22 @@ namespace OpenSim.Server.Handlers.MapImage private byte[] DocToBytes(XmlDocument doc) { - MemoryStream ms = new MemoryStream(); - XmlTextWriter xw = new XmlTextWriter(ms, null); - xw.Formatting = Formatting.Indented; - doc.WriteTo(xw); - xw.Flush(); - + using(MemoryStream ms = new MemoryStream()) + { + using(XmlTextWriter xw = new XmlTextWriter(ms,null)) + { + xw.Formatting = Formatting.Indented; + doc.WriteTo(xw); + xw.Flush(); + } return ms.ToArray(); + } } private System.Net.IPAddress GetCallerIP(IOSHttpRequest request) { - if (!m_Proxy) - return request.RemoteIPEndPoint.Address; +// if (!m_Proxy) +// return request.RemoteIPEndPoint.Address; // We're behind a proxy string xff = "X-Forwarded-For"; @@ -237,7 +240,7 @@ namespace OpenSim.Server.Handlers.MapImage if (xffValue == null || (xffValue != null && xffValue == string.Empty)) { - m_log.WarnFormat("[MAP IMAGE HANDLER]: No XFF header"); +// m_log.WarnFormat("[MAP IMAGE HANDLER]: No XFF header"); return request.RemoteIPEndPoint.Address; } diff --git a/OpenSim/Server/Handlers/MuteList/MuteListServerConnector.cs b/OpenSim/Server/Handlers/MuteList/MuteListServerConnector.cs new file mode 100644 index 0000000000..8d27f0704e --- /dev/null +++ b/OpenSim/Server/Handlers/MuteList/MuteListServerConnector.cs @@ -0,0 +1,63 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using Nini.Config; +using OpenSim.Server.Base; +using OpenSim.Services.Interfaces; +using OpenSim.Framework.ServiceAuth; +using OpenSim.Framework.Servers.HttpServer; +using OpenSim.Server.Handlers.Base; + +namespace OpenSim.Server.Handlers.GridUser +{ + public class MuteListServiceConnector : ServiceConnector + { + private IMuteListService m_MuteListService; + private string m_ConfigName = "MuteListService"; + + public MuteListServiceConnector(IConfigSource config, IHttpServer server, string configName) : + base(config, server, configName) + { + IConfig serverConfig = config.Configs[m_ConfigName]; + if (serverConfig == null) + throw new Exception(String.Format("No section {0} in config file", m_ConfigName)); + + string service = serverConfig.GetString("LocalServiceModule", String.Empty); + + if (service == String.Empty) + throw new Exception("LocalServiceModule not present in MuteListService config file MuteListService section"); + + Object[] args = new Object[] { config }; + m_MuteListService = ServerUtils.LoadPlugin(service, args); + + IServiceAuth auth = ServiceAuth.Create(config, m_ConfigName); + + server.AddStreamHandler(new MuteListServerPostHandler(m_MuteListService, auth)); + } + } +} diff --git a/OpenSim/Server/Handlers/MuteList/MuteListServerPostHandler.cs b/OpenSim/Server/Handlers/MuteList/MuteListServerPostHandler.cs new file mode 100644 index 0000000000..26c4093e26 --- /dev/null +++ b/OpenSim/Server/Handlers/MuteList/MuteListServerPostHandler.cs @@ -0,0 +1,240 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using Nini.Config; +using log4net; +using System; +using System.Reflection; +using System.IO; +using System.Net; +using System.Text; +using System.Text.RegularExpressions; +using System.Xml; +using System.Xml.Serialization; +using System.Collections.Generic; +using OpenSim.Server.Base; +using OpenSim.Services.Interfaces; +using OpenSim.Framework; +using OpenSim.Framework.ServiceAuth; +using OpenSim.Framework.Servers.HttpServer; +using OpenMetaverse; + +namespace OpenSim.Server.Handlers.GridUser +{ + public class MuteListServerPostHandler : BaseStreamHandler + { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private IMuteListService m_service; + + public MuteListServerPostHandler(IMuteListService service, IServiceAuth auth) : + base("POST", "/mutelist", auth) + { + m_service = service; + } + + protected override byte[] ProcessRequest(string path, Stream requestData, + IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) + { + string body; + using(StreamReader sr = new StreamReader(requestData)) + body = sr.ReadToEnd(); + body = body.Trim(); + + //m_log.DebugFormat("[XXX]: query String: {0}", body); + string method = string.Empty; + + try + { + Dictionary request = + ServerUtils.ParseQueryString(body); + + if (!request.ContainsKey("METHOD")) + return FailureResult(); + + method = request["METHOD"].ToString(); + + switch (method) + { + case "get": + return getmutes(request); + case "update": + return updatemute(request); + case "delete": + return deletemute(request); + } + m_log.DebugFormat("[MUTELIST HANDLER]: unknown method request: {0}", method); + } + catch (Exception e) + { + m_log.DebugFormat("[MUTELIST HANDLER]: Exception in method {0}: {1}", method, e); + } + + return FailureResult(); + } + + byte[] getmutes(Dictionary request) + { + if(!request.ContainsKey("agentid") || !request.ContainsKey("mutecrc")) + return FailureResult(); + + UUID agentID; + if(!UUID.TryParse(request["agentid"].ToString(), out agentID)) + return FailureResult(); + + uint mutecrc; + if(!UInt32.TryParse(request["mutecrc"].ToString(), out mutecrc)) + return FailureResult(); + + byte[] data = m_service.MuteListRequest(agentID, mutecrc); + + Dictionary result = new Dictionary(); + result["result"] = Convert.ToBase64String(data); + + string xmlString = ServerUtils.BuildXmlResponse(result); + + //m_log.DebugFormat("[GRID USER HANDLER]: resp string: {0}", xmlString); + return Util.UTF8NoBomEncoding.GetBytes(xmlString); + } + + byte[] updatemute(Dictionary request) + { + if(!request.ContainsKey("agentid") || !request.ContainsKey("muteid")) + return FailureResult(); + + MuteData mute = new MuteData(); + + if( !UUID.TryParse(request["agentid"].ToString(), out mute.AgentID)) + return FailureResult(); + + if(!UUID.TryParse(request["muteid"].ToString(), out mute.MuteID)) + return FailureResult(); + + if(request.ContainsKey("mutename")) + { + mute.MuteName = request["mutename"].ToString(); + } + else + mute.MuteName = String.Empty; + + if(request.ContainsKey("mutetype")) + { + if(!Int32.TryParse(request["mutetype"].ToString(), out mute.MuteType)) + return FailureResult(); + } + else + mute.MuteType = 0; + + if(request.ContainsKey("muteflags")) + { + if(!Int32.TryParse(request["muteflags"].ToString(), out mute.MuteFlags)) + return FailureResult(); + } + else + mute.MuteFlags = 0; + + if(request.ContainsKey("mutestamp")) + { + if(!Int32.TryParse(request["mutestamp"].ToString(), out mute.Stamp)) + return FailureResult(); + } + else + mute.Stamp = Util.UnixTimeSinceEpoch(); + + return m_service.UpdateMute(mute) ? SuccessResult() : FailureResult(); + } + + byte[] deletemute(Dictionary request) + { + if(!request.ContainsKey("agentid") || !request.ContainsKey("muteid")) + return FailureResult(); + + UUID agentID; + if( !UUID.TryParse(request["agentid"].ToString(), out agentID)) + return FailureResult(); + + UUID muteID; + if(!UUID.TryParse(request["muteid"].ToString(), out muteID)) + return FailureResult(); + + string muteName; + if(request.ContainsKey("mutename")) + { + muteName = request["mutename"].ToString(); + + } + else + muteName = String.Empty; + + return m_service.RemoveMute(agentID, muteID, muteName) ? SuccessResult() : FailureResult(); + } + + private byte[] SuccessResult() + { + XmlDocument doc = new XmlDocument(); + + XmlNode xmlnode = doc.CreateNode(XmlNodeType.XmlDeclaration, + "", ""); + + doc.AppendChild(xmlnode); + + XmlElement rootElement = doc.CreateElement("", "ServerResponse", + ""); + + doc.AppendChild(rootElement); + + XmlElement result = doc.CreateElement("", "result", ""); + result.AppendChild(doc.CreateTextNode("Success")); + + rootElement.AppendChild(result); + + return Util.DocToBytes(doc); + } + + private byte[] FailureResult() + { + XmlDocument doc = new XmlDocument(); + + XmlNode xmlnode = doc.CreateNode(XmlNodeType.XmlDeclaration, + "", ""); + + doc.AppendChild(xmlnode); + + XmlElement rootElement = doc.CreateElement("", "ServerResponse", + ""); + + doc.AppendChild(rootElement); + + XmlElement result = doc.CreateElement("", "result", ""); + result.AppendChild(doc.CreateTextNode("Failure")); + + rootElement.AppendChild(result); + + return Util.DocToBytes(doc); + } + } +} diff --git a/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs b/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs index 4e1f72edf9..c52a1ab06b 100644 --- a/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs +++ b/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs @@ -517,32 +517,30 @@ namespace OpenSim.Server.Handlers.Simulation protected string GetCallerIP(Hashtable request) { - if (!m_Proxy) - return Util.GetCallerIP(request); - - // We're behind a proxy - Hashtable headers = (Hashtable)request["headers"]; - - //// DEBUG - //foreach (object o in headers.Keys) - // m_log.DebugFormat("XXX {0} = {1}", o.ToString(), (headers[o] == null? "null" : headers[o].ToString())); - - string xff = "X-Forwarded-For"; - if (headers.ContainsKey(xff.ToLower())) - xff = xff.ToLower(); - - if (!headers.ContainsKey(xff) || headers[xff] == null) + if (request.ContainsKey("headers")) { - m_log.WarnFormat("[AGENT HANDLER]: No XFF header"); - return Util.GetCallerIP(request); + Hashtable headers = (Hashtable)request["headers"]; + + //// DEBUG + //foreach (object o in headers.Keys) + // m_log.DebugFormat("XXX {0} = {1}", o.ToString(), (headers[o] == null? "null" : headers[o].ToString())); + + string xff = "X-Forwarded-For"; + if (!headers.ContainsKey(xff)) + xff = xff.ToLower(); + + if (!headers.ContainsKey(xff) || headers[xff] == null) + { +// m_log.WarnFormat("[AGENT HANDLER]: No XFF header"); + return Util.GetCallerIP(request); + } + +// m_log.DebugFormat("[AGENT HANDLER]: XFF is {0}", headers[xff]); + + IPEndPoint ep = Util.GetClientIPFromXFF((string)headers[xff]); + if (ep != null) + return ep.Address.ToString(); } - - m_log.DebugFormat("[AGENT HANDLER]: XFF is {0}", headers[xff]); - - IPEndPoint ep = Util.GetClientIPFromXFF((string)headers[xff]); - if (ep != null) - return ep.Address.ToString(); - // Oops return Util.GetCallerIP(request); } diff --git a/OpenSim/Server/Handlers/UserAccounts/UserAccountServerPostHandler.cs b/OpenSim/Server/Handlers/UserAccounts/UserAccountServerPostHandler.cs index a02255f01d..bc12ef9b94 100644 --- a/OpenSim/Server/Handlers/UserAccounts/UserAccountServerPostHandler.cs +++ b/OpenSim/Server/Handlers/UserAccounts/UserAccountServerPostHandler.cs @@ -72,9 +72,9 @@ namespace OpenSim.Server.Handlers.UserAccounts protected override byte[] ProcessRequest(string path, Stream requestData, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { - StreamReader sr = new StreamReader(requestData); - string body = sr.ReadToEnd(); - sr.Close(); + string body; + using(StreamReader sr = new StreamReader(requestData)) + body = sr.ReadToEnd(); body = body.Trim(); // We need to check the authorization header diff --git a/OpenSim/Server/ServerMain.cs b/OpenSim/Server/ServerMain.cs index c3430440a3..4b7fd8a087 100644 --- a/OpenSim/Server/ServerMain.cs +++ b/OpenSim/Server/ServerMain.cs @@ -30,7 +30,10 @@ using log4net; using System.Reflection; using System; using System.Net; +using System.Net.Security; +using System.Security.Cryptography.X509Certificates; using System.Collections.Generic; +using OpenSim.Framework; using OpenSim.Framework.Servers; using OpenSim.Framework.Servers.HttpServer; using OpenSim.Server.Base; @@ -51,12 +54,35 @@ namespace OpenSim.Server new List(); protected static PluginLoader loader; + private static bool m_NoVerifyCertChain = false; + private static bool m_NoVerifyCertHostname = false; + + public static bool ValidateServerCertificate( + object sender, + X509Certificate certificate, + X509Chain chain, + SslPolicyErrors sslPolicyErrors) + { + if (m_NoVerifyCertChain) + sslPolicyErrors &= ~SslPolicyErrors.RemoteCertificateChainErrors; + + if (m_NoVerifyCertHostname) + sslPolicyErrors &= ~SslPolicyErrors.RemoteCertificateNameMismatch; + + if (sslPolicyErrors == SslPolicyErrors.None) + return true; + + return false; + } public static int Main(string[] args) { - // Make sure we don't get outbound connections queueing - ServicePointManager.DefaultConnectionLimit = 50; + ServicePointManager.DefaultConnectionLimit = 64; + ServicePointManager.Expect100Continue = false; ServicePointManager.UseNagleAlgorithm = false; + ServicePointManager.ServerCertificateValidationCallback = ValidateServerCertificate; + + try { ServicePointManager.DnsRefreshTimeout = 300000; } catch { } m_Server = new HttpServerBase("R.O.B.U.S.T.", args); @@ -69,6 +95,10 @@ namespace OpenSim.Server throw new Exception("Configuration error"); } + m_NoVerifyCertChain = serverConfig.GetBoolean("NoVerifyCertChain", m_NoVerifyCertChain); + m_NoVerifyCertHostname = serverConfig.GetBoolean("NoVerifyCertHostname", m_NoVerifyCertHostname); + + string connList = serverConfig.GetString("ServiceConnectors", String.Empty); registryLocation = serverConfig.GetString("RegistryLocation","."); @@ -158,6 +188,11 @@ namespace OpenSim.Server int res = m_Server.Run(); + if(m_Server != null) + m_Server.Shutdown(); + + Util.StopThreadPool(); + Environment.Exit(res); return 0; diff --git a/OpenSim/Services/AssetService/AssetService.cs b/OpenSim/Services/AssetService/AssetService.cs index 5c37c33452..ee2e56871f 100644 --- a/OpenSim/Services/AssetService/AssetService.cs +++ b/OpenSim/Services/AssetService/AssetService.cs @@ -82,7 +82,7 @@ namespace OpenSim.Services.AssetService if (existingAsset == null || Util.SHA1Hash(existingAsset.Data) != Util.SHA1Hash(a.Data)) { // m_log.DebugFormat("[ASSET]: Storing {0} {1}", a.Name, a.ID); - Store(a); + m_Database.StoreAsset(a); } }); } diff --git a/OpenSim/Services/AssetService/XAssetService.cs b/OpenSim/Services/AssetService/XAssetService.cs index 9490d55af2..de7223ba4d 100644 --- a/OpenSim/Services/AssetService/XAssetService.cs +++ b/OpenSim/Services/AssetService/XAssetService.cs @@ -80,7 +80,7 @@ namespace OpenSim.Services.AssetService if (existingAsset == null || Util.SHA1Hash(existingAsset.Data) != Util.SHA1Hash(a.Data)) { // m_log.DebugFormat("[ASSET]: Storing {0} {1}", a.Name, a.ID); - Store(a); + m_Database.StoreAsset(a); } }); } diff --git a/OpenSim/Services/Connectors/Asset/AssetServicesConnector.cs b/OpenSim/Services/Connectors/Asset/AssetServicesConnector.cs index 810da2f7cc..205426ee59 100644 --- a/OpenSim/Services/Connectors/Asset/AssetServicesConnector.cs +++ b/OpenSim/Services/Connectors/Asset/AssetServicesConnector.cs @@ -29,12 +29,13 @@ using log4net; using System; using System.Threading; using System.Collections.Generic; +using System.Collections.Concurrent; using System.IO; using System.Reflection; using System.Timers; using Nini.Config; using OpenSim.Framework; -using OpenSim.Framework.Console; +using OpenSim.Framework.Monitoring; using OpenSim.Services.Interfaces; using OpenMetaverse; @@ -135,8 +136,11 @@ namespace OpenSim.Services.Connectors for (int i = 0 ; i < 2 ; i++) { - m_fetchThreads[i] = new Thread(AssetRequestProcessor); - m_fetchThreads[i].Start(); + m_fetchThreads[i] = WorkManager.StartThread(AssetRequestProcessor, + String.Format("GetTextureWorker{0}", i), + ThreadPriority.Normal, + true, + false); } } @@ -349,8 +353,7 @@ namespace OpenSim.Services.Connectors public string id; } - private OpenMetaverse.BlockingQueue m_requestQueue = - new OpenMetaverse.BlockingQueue(); + private BlockingCollection m_requestQueue = new BlockingCollection(); private void AssetRequestProcessor() { @@ -358,8 +361,13 @@ namespace OpenSim.Services.Connectors while (true) { - r = m_requestQueue.Dequeue(); + if(!m_requestQueue.TryTake(out r, 4500) || r == null) + { + Watchdog.UpdateThread(); + continue; + } + Watchdog.UpdateThread(); string uri = r.uri; string id = r.id; @@ -427,7 +435,7 @@ namespace OpenSim.Services.Connectors QueuedAssetRequest request = new QueuedAssetRequest(); request.id = id; request.uri = uri; - m_requestQueue.Enqueue(request); + m_requestQueue.Add(request); } } else diff --git a/OpenSim/Services/Connectors/Estate/EstateDataConnector.cs b/OpenSim/Services/Connectors/Estate/EstateDataConnector.cs index b9a628160c..0971b3866a 100644 --- a/OpenSim/Services/Connectors/Estate/EstateDataConnector.cs +++ b/OpenSim/Services/Connectors/Estate/EstateDataConnector.cs @@ -195,6 +195,14 @@ namespace OpenSim.Services.Connectors string uri = m_ServerURI + string.Format("/estates/estate/?region={0}&create={1}", regionID, create); reply = MakeRequest("GET", uri, string.Empty); + if(reply == null) + { + // this is a fatal error + m_log.DebugFormat("[ESTATE CONNECTOR] connection to remote estates service failed"); + m_log.DebugFormat("[ESTATE CONNECTOR] simulator needs to terminate"); + Environment.Exit(-1); + } + if (String.IsNullOrEmpty(reply)) return null; @@ -308,7 +316,8 @@ namespace OpenSim.Services.Connectors string reply = string.Empty; try { - reply = SynchronousRestFormsRequester.MakeRequest(verb, uri, formdata, m_Auth); + reply = SynchronousRestFormsRequester.MakeRequest(verb, uri, formdata, 30, m_Auth); + return reply; } catch (WebException e) { @@ -317,14 +326,17 @@ namespace OpenSim.Services.Connectors if (hwr != null) { if (hwr.StatusCode == HttpStatusCode.NotFound) + { m_log.Error(string.Format("[ESTATE CONNECTOR]: Resource {0} not found ", uri)); + return reply; + } if (hwr.StatusCode == HttpStatusCode.Unauthorized) m_log.Error(string.Format("[ESTATE CONNECTOR]: Web request {0} requires authentication ", uri)); } else m_log.Error(string.Format( "[ESTATE CONNECTOR]: WebException for {0} {1} {2} {3}", - verb, uri, formdata, e)); + verb, uri, formdata, e.Message)); } } catch (Exception e) @@ -332,7 +344,7 @@ namespace OpenSim.Services.Connectors m_log.DebugFormat("[ESTATE CONNECTOR]: Exception when contacting estate server at {0}: {1}", uri, e.Message); } - return reply; + return null; } } } diff --git a/OpenSim/Services/Connectors/Hypergrid/GatekeeperServiceConnector.cs b/OpenSim/Services/Connectors/Hypergrid/GatekeeperServiceConnector.cs index e814c4579e..cb15fc0eff 100644 --- a/OpenSim/Services/Connectors/Hypergrid/GatekeeperServiceConnector.cs +++ b/OpenSim/Services/Connectors/Hypergrid/GatekeeperServiceConnector.cs @@ -189,7 +189,7 @@ namespace OpenSim.Services.Connectors.Hypergrid using (Bitmap bitmap = new Bitmap(filename)) { //m_log.Debug("Size: " + m.PhysicalDimension.Height + "-" + m.PhysicalDimension.Width); - imageData = OpenJPEG.EncodeFromImage(bitmap, true); + imageData = OpenJPEG.EncodeFromImage(bitmap, false); } AssetBase ass = new AssetBase(UUID.Random(), "region " + name, (sbyte)AssetType.Texture, regionID.ToString()); diff --git a/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs b/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs index b261675572..f2bb52aa4d 100644 --- a/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs +++ b/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs @@ -70,9 +70,14 @@ namespace OpenSim.Services.Connectors.Hypergrid { Uri m_Uri = new Uri(m_ServerURL); IPAddress ip = Util.GetHostFromDNS(m_Uri.Host); - m_ServerURL = m_ServerURL.Replace(m_Uri.Host, ip.ToString()); - if (!m_ServerURL.EndsWith("/")) - m_ServerURL += "/"; + if(ip != null) + { + m_ServerURL = m_ServerURL.Replace(m_Uri.Host, ip.ToString()); + if (!m_ServerURL.EndsWith("/")) + m_ServerURL += "/"; + } + else + m_log.DebugFormat("[USER AGENT CONNECTOR]: Failed to resolv address of {0}", url); } catch (Exception e) { diff --git a/OpenSim/Services/Connectors/Land/LandServicesConnector.cs b/OpenSim/Services/Connectors/Land/LandServicesConnector.cs index 047880a063..5492e83a96 100644 --- a/OpenSim/Services/Connectors/Land/LandServicesConnector.cs +++ b/OpenSim/Services/Connectors/Land/LandServicesConnector.cs @@ -117,6 +117,8 @@ namespace OpenSim.Services.Connectors landData.UserLocation = Vector3.Parse((string)hash["UserLocation"]); if (hash["RegionAccess"] != null) regionAccess = (byte)Convert.ToInt32((string)hash["RegionAccess"]); + if(hash["Dwell"] != null) + landData.Dwell = Convert.ToSingle((string)hash["Dwell"]); m_log.DebugFormat("[LAND CONNECTOR]: Got land data for parcel {0}", landData.Name); } catch (Exception e) diff --git a/OpenSim/Services/Connectors/MapImage/MapImageServicesConnector.cs b/OpenSim/Services/Connectors/MapImage/MapImageServicesConnector.cs index 84c4efe378..762d2f7c30 100644 --- a/OpenSim/Services/Connectors/MapImage/MapImageServicesConnector.cs +++ b/OpenSim/Services/Connectors/MapImage/MapImageServicesConnector.cs @@ -229,6 +229,7 @@ namespace OpenSim.Services.Connectors string reply = SynchronousRestFormsRequester.MakeRequest("POST", uri, reqString, + 30, m_Auth); if (reply != string.Empty) { @@ -271,7 +272,7 @@ namespace OpenSim.Services.Connectors { // This just dumps a warning for any operation that takes more than 100 ms int tickdiff = Util.EnvironmentTickCountSubtract(tickstart); - m_log.DebugFormat("[MAP IMAGE CONNECTOR]: map tile uploaded in {0}ms", tickdiff); + m_log.DebugFormat("[MAP IMAGE CONNECTOR]: map tile upload time {0}ms", tickdiff); } return false; diff --git a/OpenSim/Services/Connectors/MuteList/MuteListServicesConnector.cs b/OpenSim/Services/Connectors/MuteList/MuteListServicesConnector.cs new file mode 100644 index 0000000000..e574c1d741 --- /dev/null +++ b/OpenSim/Services/Connectors/MuteList/MuteListServicesConnector.cs @@ -0,0 +1,183 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using log4net; +using System; +using System.Collections.Generic; +using System.IO; +using System.Reflection; +using Nini.Config; +using OpenSim.Framework; + +using OpenSim.Framework.ServiceAuth; +using OpenSim.Services.Interfaces; +using GridRegion = OpenSim.Services.Interfaces.GridRegion; +using OpenSim.Server.Base; +using OpenMetaverse; + +namespace OpenSim.Services.Connectors +{ + public class MuteListServicesConnector : BaseServiceConnector, IMuteListService + { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private string m_ServerURI = String.Empty; + + public MuteListServicesConnector() + { + } + + public MuteListServicesConnector(string serverURI) + { + m_ServerURI = serverURI.TrimEnd('/') + "/mutelist"; + } + + public MuteListServicesConnector(IConfigSource source) + { + Initialise(source); + } + + public virtual void Initialise(IConfigSource source) + { + IConfig gridConfig = source.Configs["MuteListService"]; + if (gridConfig == null) + { + m_log.Error("[MUTELIST CONNECTOR]: MuteListService missing from configuration"); + throw new Exception("MuteList connector init error"); + } + + string serviceURI = gridConfig.GetString("MuteListServerURI", + String.Empty); + + if (serviceURI == String.Empty) + { + m_log.Error("[GRID USER CONNECTOR]: No Server URI named in section GridUserService"); + throw new Exception("GridUser connector init error"); + } + m_ServerURI = serviceURI + "/mutelist";; + base.Initialise(source, "MuteListService"); + } + + #region IMuteListService + public Byte[] MuteListRequest(UUID agentID, uint crc) + { + Dictionary sendData = new Dictionary(); + sendData["METHOD"] = "get"; + sendData["agentid"] = agentID.ToString(); + sendData["mutecrc"] = crc.ToString(); + + try + { + string reply = SynchronousRestFormsRequester.MakeRequest("POST", m_ServerURI, + ServerUtils.BuildQueryString(sendData), m_Auth); + if (reply != string.Empty) + { + Dictionary replyData = ServerUtils.ParseXmlResponse(reply); + + if (replyData.ContainsKey("result")) + { + string datastr = replyData["result"].ToString(); + if(String.IsNullOrWhiteSpace(datastr)) + return null; + return Convert.FromBase64String(datastr); + } + else + m_log.DebugFormat("[MUTELIST CONNECTOR]: get reply data does not contain result field"); + } + else + m_log.DebugFormat("[MUTELIST CONNECTOR]: get received empty reply"); + } + catch (Exception e) + { + m_log.DebugFormat("[MUTELIST CONNECTOR]: Exception when contacting server at {0}: {1}", m_ServerURI, e.Message); + } + + return null; + } + + public bool UpdateMute(MuteData mute) + { + Dictionary sendData = new Dictionary(); + sendData["METHOD"] = "update"; + sendData["agentid"] = mute.AgentID.ToString(); + sendData["muteid"] = mute.MuteID.ToString(); + if(mute.MuteType != 0) + sendData["mutetype"] = mute.MuteType.ToString(); + if(mute.MuteFlags != 0) + sendData["muteflags"] = mute.MuteFlags.ToString(); + sendData["mutestamp"] = mute.Stamp.ToString(); + if(!String.IsNullOrEmpty(mute.MuteName)) + sendData["mutename"] = mute.MuteName; + + return doSimplePost(ServerUtils.BuildQueryString(sendData), "update"); + } + + public bool RemoveMute(UUID agentID, UUID muteID, string muteName) + { + Dictionary sendData = new Dictionary(); + sendData["METHOD"] = "delete"; + sendData["agentid"] = agentID.ToString(); + sendData["muteid"] = muteID.ToString(); + if(!String.IsNullOrEmpty(muteName)) + sendData["mutename"] = muteName; + + return doSimplePost(ServerUtils.BuildQueryString(sendData), "remove"); + } + + #endregion IMuteListService + + private bool doSimplePost(string reqString, string meth) + { + try + { + string reply = SynchronousRestFormsRequester.MakeRequest("POST", m_ServerURI, reqString, m_Auth); + if (reply != string.Empty) + { + Dictionary replyData = ServerUtils.ParseXmlResponse(reply); + + if (replyData.ContainsKey("result")) + { + if (replyData["result"].ToString().ToLower() == "success") + return true; + else + return false; + } + else + m_log.DebugFormat("[MUTELIST CONNECTOR]: {0} reply data does not contain result field", meth); + } + else + m_log.DebugFormat("[MUTELIST CONNECTOR]: {0} received empty reply", meth); + } + catch (Exception e) + { + m_log.DebugFormat("[MUTELIST CONNECTOR]: Exception when contacting server at {0}: {1}", m_ServerURI, e.Message); + } + + return false; + } + } +} diff --git a/OpenSim/Services/Connectors/Neighbour/NeighbourServicesConnector.cs b/OpenSim/Services/Connectors/Neighbour/NeighbourServicesConnector.cs index 939059da71..9f3b94c78d 100644 --- a/OpenSim/Services/Connectors/Neighbour/NeighbourServicesConnector.cs +++ b/OpenSim/Services/Connectors/Neighbour/NeighbourServicesConnector.cs @@ -151,7 +151,8 @@ namespace OpenSim.Services.Connectors os.Write(buffer, 0, strBuffer.Length); //Send it //m_log.InfoFormat("[REST COMMS]: Posted HelloNeighbour request to remote sim {0}", uri); } - catch (Exception e) +// catch (Exception e) + catch { // m_log.WarnFormat( // "[NEIGHBOUR SERVICE CONNCTOR]: Unable to send HelloNeighbour from {0} to {1}. Exception {2}{3}", @@ -183,8 +184,8 @@ namespace OpenSim.Services.Connectors { using (StreamReader sr = new StreamReader(s)) { + sr.ReadToEnd(); // just try to read //reply = sr.ReadToEnd().Trim(); - sr.ReadToEnd().Trim(); //m_log.InfoFormat("[REST COMMS]: DoHelloNeighbourCall reply was {0} ", reply); } } diff --git a/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs index 9f4d89ab6f..a4ca2d3ecb 100644 --- a/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs +++ b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs @@ -295,9 +295,6 @@ namespace OpenSim.Services.Connectors.Simulation // m_log.DebugFormat("[REMOTE SIMULATION CONNECTOR]: QueryAccess start, position={0}", position); - IPEndPoint ext = destination.ExternalEndPoint; - if (ext == null) return false; - // Eventually, we want to use a caps url instead of the agentID string uri = destination.ServerURI + AgentPath() + agentID + "/" + destination.RegionID.ToString() + "/"; diff --git a/OpenSim/Services/GridService/GridService.cs b/OpenSim/Services/GridService/GridService.cs index 6153f5ea26..78fffa6f54 100644 --- a/OpenSim/Services/GridService/GridService.cs +++ b/OpenSim/Services/GridService/GridService.cs @@ -494,7 +494,7 @@ namespace OpenSim.Services.GridService { // m_log.DebugFormat("[GRID SERVICE]: GetRegionsByName {0}", name); - List rdatas = m_Database.Get(Util.EscapeForLike(name) + "%", scopeID); + List rdatas = m_Database.Get("%" + Util.EscapeForLike(name) + "%", scopeID); int count = 0; List rinfos = new List(); @@ -909,9 +909,9 @@ namespace OpenSim.Services.GridService private void OutputRegionsToConsoleSummary(List regions) { ConsoleDisplayTable dispTable = new ConsoleDisplayTable(); - dispTable.AddColumn("Name", 44); - dispTable.AddColumn("ID", 36); - dispTable.AddColumn("Position", 11); + dispTable.AddColumn("Name", ConsoleDisplayUtil.RegionNameSize); + dispTable.AddColumn("ID", ConsoleDisplayUtil.UuidSize); + dispTable.AddColumn("Position", ConsoleDisplayUtil.CoordTupleSize); dispTable.AddColumn("Size", 11); dispTable.AddColumn("Flags", 60); diff --git a/OpenSim/Services/HypergridService/GatekeeperService.cs b/OpenSim/Services/HypergridService/GatekeeperService.cs index b80700faed..1b652a02f3 100644 --- a/OpenSim/Services/HypergridService/GatekeeperService.cs +++ b/OpenSim/Services/HypergridService/GatekeeperService.cs @@ -35,8 +35,8 @@ using OpenSim.Framework; using OpenSim.Services.Interfaces; using GridRegion = OpenSim.Services.Interfaces.GridRegion; using OpenSim.Server.Base; +using OpenSim.Services.Connectors.InstantMessage; using OpenSim.Services.Connectors.Hypergrid; - using OpenMetaverse; using Nini.Config; @@ -62,6 +62,7 @@ namespace OpenSim.Services.HypergridService private static string m_AllowedClients = string.Empty; private static string m_DeniedClients = string.Empty; + private static string m_DeniedMacs = string.Empty; private static bool m_ForeignAgentsAllowed = true; private static List m_ForeignsAllowedExceptions = new List(); private static List m_ForeignsDisallowedExceptions = new List(); @@ -71,6 +72,7 @@ namespace OpenSim.Services.HypergridService private static string m_ExternalName; private static Uri m_Uri; private static GridRegion m_DefaultGatewayRegion; + private bool m_allowDuplicatePresences = false; public GatekeeperService(IConfigSource config, ISimulationService simService) { @@ -136,6 +138,8 @@ namespace OpenSim.Services.HypergridService config, "AllowedClients", possibleAccessControlConfigSections, string.Empty); m_DeniedClients = Util.GetConfigVarFromSections( config, "DeniedClients", possibleAccessControlConfigSections, string.Empty); + m_DeniedMacs = Util.GetConfigVarFromSections( + config, "DeniedMacs", possibleAccessControlConfigSections, string.Empty); m_ForeignAgentsAllowed = serverConfig.GetBoolean("ForeignAgentsAllowed", true); LoadDomainExceptionsFromConfig(serverConfig, "AllowExcept", m_ForeignsAllowedExceptions); @@ -144,6 +148,12 @@ namespace OpenSim.Services.HypergridService if (m_GridService == null || m_PresenceService == null || m_SimulationService == null) throw new Exception("Unable to load a required plugin, Gatekeeper Service cannot function."); + IConfig presenceConfig = config.Configs["PresenceService"]; + if (presenceConfig != null) + { + m_allowDuplicatePresences = presenceConfig.GetBoolean("AllowDuplicatePresences", m_allowDuplicatePresences); + } + m_log.Debug("[GATEKEEPER SERVICE]: Starting..."); } } @@ -268,11 +278,13 @@ namespace OpenSim.Services.HypergridService (source == null) ? "Unknown" : string.Format("{0} ({1}){2}", source.RegionName, source.RegionID, (source.RawServerURI == null) ? "" : " @ " + source.ServerURI)); string curViewer = Util.GetViewerName(aCircuit); + string curMac = aCircuit.Mac.ToString(); + // // Check client // - if (m_AllowedClients != string.Empty) + if (!String.IsNullOrWhiteSpace(m_AllowedClients)) { Regex arx = new Regex(m_AllowedClients); Match am = arx.Match(curViewer); @@ -285,7 +297,7 @@ namespace OpenSim.Services.HypergridService } } - if (m_DeniedClients != string.Empty) + if (!String.IsNullOrWhiteSpace(m_DeniedClients)) { Regex drx = new Regex(m_DeniedClients); Match dm = drx.Match(curViewer); @@ -298,6 +310,17 @@ namespace OpenSim.Services.HypergridService } } + if (!String.IsNullOrWhiteSpace(m_DeniedMacs)) + { + m_log.InfoFormat("[GATEKEEPER SERVICE]: Checking users Mac {0} against list of denied macs {1} ...", curMac, m_DeniedMacs); + if (m_DeniedMacs.Contains(curMac)) + { + reason = "Login failed: client with Mac " + curMac + " is denied"; + m_log.InfoFormat("[GATEKEEPER SERVICE]: Login failed, reason: client with mac {0} is denied", curMac); + return false; + } + } + // // Authenticate the user // @@ -369,6 +392,38 @@ namespace OpenSim.Services.HypergridService return false; } + UUID agentID = aCircuit.AgentID; + if(agentID == new UUID("6571e388-6218-4574-87db-f9379718315e")) + { + // really? + reason = "Invalid account ID"; + return false; + } + + if(m_GridUserService != null) + { + string PrincipalIDstr = agentID.ToString(); + GridUserInfo guinfo = m_GridUserService.GetGridUserInfo(PrincipalIDstr); + + if(!m_allowDuplicatePresences) + { + if(guinfo != null && guinfo.Online && guinfo.LastRegionID != UUID.Zero) + { + if(SendAgentGodKillToRegion(UUID.Zero, agentID, guinfo)) + { + if(account != null) + m_log.InfoFormat( + "[GATEKEEPER SERVICE]: Login failed for {0} {1}, reason: already logged in", + account.FirstName, account.LastName); + reason = "You appear to be already logged in on the destination grid " + + "Please wait a a minute or two and retry. " + + "If this takes longer than a few minutes please contact the grid owner."; + return false; + } + } + } + } + m_log.DebugFormat("[GATEKEEPER SERVICE]: User {0} is ok", aCircuit.Name); bool isFirstLogin = false; @@ -389,26 +444,6 @@ namespace OpenSim.Services.HypergridService return false; } - m_log.DebugFormat("[GATEKEEPER SERVICE]: Login presence {0} is ok", aCircuit.Name); - - // Also login foreigners with GridUser service - if (m_GridUserService != null && account == null) - { - string userId = aCircuit.AgentID.ToString(); - string first = aCircuit.firstname, last = aCircuit.lastname; - if (last.StartsWith("@")) - { - string[] parts = aCircuit.firstname.Split('.'); - if (parts.Length >= 2) - { - first = parts[0]; - last = parts[1]; - } - } - - userId += ";" + aCircuit.ServiceURLs["HomeURI"] + ";" + first + " " + last; - m_GridUserService.LoggedIn(userId); - } } // @@ -465,7 +500,33 @@ namespace OpenSim.Services.HypergridService true, aCircuit.startpos, new List(), ctx, out reason)) return false; - return m_SimulationService.CreateAgent(source, destination, aCircuit, (uint)loginFlag, ctx, out reason); + bool didit = m_SimulationService.CreateAgent(source, destination, aCircuit, (uint)loginFlag, ctx, out reason); + + if(didit) + { + m_log.DebugFormat("[GATEKEEPER SERVICE]: Login presence {0} is ok", aCircuit.Name); + + if(!isFirstLogin && m_GridUserService != null && account == null) + { + // Also login foreigners with GridUser service + string userId = aCircuit.AgentID.ToString(); + string first = aCircuit.firstname, last = aCircuit.lastname; + if (last.StartsWith("@")) + { + string[] parts = aCircuit.firstname.Split('.'); + if (parts.Length >= 2) + { + first = parts[0]; + last = parts[1]; + } + } + + userId += ";" + aCircuit.ServiceURLs["HomeURI"] + ";" + first + " " + last; + m_GridUserService.LoggedIn(userId); + } + } + + return didit; } protected bool Authenticate(AgentCircuitData aCircuit) @@ -563,6 +624,40 @@ namespace OpenSim.Services.HypergridService return exception; } + private bool SendAgentGodKillToRegion(UUID scopeID, UUID agentID , GridUserInfo guinfo) + { + UUID regionID = guinfo.LastRegionID; + GridRegion regInfo = m_GridService.GetRegionByUUID(scopeID, regionID); + if(regInfo == null) + return false; + + string regURL = regInfo.ServerURI; + if(String.IsNullOrEmpty(regURL)) + return false; + + UUID guuid = new UUID("6571e388-6218-4574-87db-f9379718315e"); + + GridInstantMessage msg = new GridInstantMessage(); + msg.imSessionID = UUID.Zero.Guid; + msg.fromAgentID = guuid.Guid; + msg.toAgentID = agentID.Guid; + msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); + msg.fromAgentName = "GRID"; + msg.message = string.Format("New login detected"); + msg.dialog = 250; // God kick + msg.fromGroup = false; + msg.offline = (byte)0; + msg.ParentEstateID = 0; + msg.Position = Vector3.Zero; + msg.RegionID = scopeID.Guid; + msg.binaryBucket = new byte[1] {0}; + InstantMessageServiceConnector.SendInstantMessage(regURL,msg); + + m_GridUserService.LoggedOut(agentID.ToString(), + UUID.Zero, guinfo.LastRegionID, guinfo.LastPosition, guinfo.LastLookAt); + + return true; + } #endregion } } diff --git a/OpenSim/Services/HypergridService/HGSuitcaseInventoryService.cs b/OpenSim/Services/HypergridService/HGSuitcaseInventoryService.cs index d1f2e7032e..9b332176bc 100644 --- a/OpenSim/Services/HypergridService/HGSuitcaseInventoryService.cs +++ b/OpenSim/Services/HypergridService/HGSuitcaseInventoryService.cs @@ -399,7 +399,7 @@ namespace OpenSim.Services.HypergridService return false; } - public new InventoryItemBase GetItem(InventoryItemBase item) + public InventoryItemBase GetItem(InventoryItemBase item) { InventoryItemBase it = base.GetItem(item.Owner, item.ID); if (it == null) diff --git a/OpenSim/Services/HypergridService/UserAgentService.cs b/OpenSim/Services/HypergridService/UserAgentService.cs index ba3cb2f72d..6f2cdd5e99 100644 --- a/OpenSim/Services/HypergridService/UserAgentService.cs +++ b/OpenSim/Services/HypergridService/UserAgentService.cs @@ -254,7 +254,6 @@ namespace OpenSim.Services.HypergridService } } - // Take the IP address + port of the gatekeeper (reg) plus the info of finalDestination GridRegion region = new GridRegion(gatekeeper); region.ServerURI = gatekeeper.ServerURI; diff --git a/OpenSim/Services/Interfaces/IAvatarService.cs b/OpenSim/Services/Interfaces/IAvatarService.cs index b4dc511109..ef8d1583c9 100644 --- a/OpenSim/Services/Interfaces/IAvatarService.cs +++ b/OpenSim/Services/Interfaces/IAvatarService.cs @@ -28,6 +28,7 @@ using System; using System.Collections; using System.Collections.Generic; +using System.Text; using OpenSim.Framework; @@ -150,7 +151,6 @@ namespace OpenSim.Services.Interfaces // Wearables Data["AvatarHeight"] = appearance.AvatarHeight.ToString(); - // TODO: With COF, is this even needed? for (int i = 0 ; i < AvatarWearable.LEGACY_VERSION_MAX_WEARABLES ; i++) { for (int j = 0 ; j < appearance.Wearables[i].Count ; j++) @@ -162,21 +162,18 @@ namespace OpenSim.Services.Interfaces } } - // Visual Params - //string[] vps = new string[AvatarAppearance.VISUALPARAM_COUNT]; - //byte[] binary = appearance.VisualParams; - - // for (int i = 0 ; i < AvatarAppearance.VISUALPARAM_COUNT ; i++) - byte[] binary = appearance.VisualParams; - string[] vps = new string[binary.Length]; + int len = binary.Length; + int last = len - 1; - for (int i = 0; i < binary.Length; i++) + StringBuilder sb = new StringBuilder(5 * len); + for (int i = 0; i < len; i++) { - vps[i] = binary[i].ToString(); + sb.Append(binary[i].ToString()); + if (i < last) + sb.Append(","); } - - Data["VisualParams"] = String.Join(",", vps); + Data["VisualParams"] = sb.ToString(); // Attachments List attachments = appearance.GetAttachments(); @@ -213,7 +210,6 @@ namespace OpenSim.Services.Interfaces if( h == 0f) h = 1.9f; appearance.SetSize(new Vector3(0.45f, 0.6f, h )); -// appearance.AvatarHeight = float.Parse(Data["AvatarHeight"]); } // Legacy Wearables @@ -285,9 +281,6 @@ namespace OpenSim.Services.Interfaces if (Data.ContainsKey("VisualParams")) { string[] vps = Data["VisualParams"].Split(new char[] {','}); - //byte[] binary = new byte[AvatarAppearance.VISUALPARAM_COUNT]; - - //for (int i = 0 ; i < vps.Length && i < binary.Length ; i++) byte[] binary = new byte[vps.Length]; for (int i = 0; i < vps.Length; i++) @@ -296,10 +289,12 @@ namespace OpenSim.Services.Interfaces appearance.VisualParams = binary; } - // New style wearables + AvatarWearable[] wearables = appearance.Wearables; + int currentLength = wearables.Length; foreach (KeyValuePair _kvp in Data) { - if (_kvp.Key.StartsWith("Wearable ")) + // New style wearables + if (_kvp.Key.StartsWith("Wearable ") && _kvp.Key.Length > 9) { string wearIndex = _kvp.Key.Substring(9); string[] wearIndices = wearIndex.Split(new char[] {':'}); @@ -308,33 +303,33 @@ namespace OpenSim.Services.Interfaces string[] ids = _kvp.Value.Split(new char[] {':'}); UUID itemID = new UUID(ids[0]); UUID assetID = new UUID(ids[1]); - - appearance.Wearables[index].Add(itemID, assetID); - } - } - - // Attachments - Dictionary attchs = new Dictionary(); - foreach (KeyValuePair _kvp in Data) - if (_kvp.Key.StartsWith("_ap_")) - attchs[_kvp.Key] = _kvp.Value; - - foreach (KeyValuePair _kvp in attchs) - { - string pointStr = _kvp.Key.Substring(4); - int point = 0; - if (!Int32.TryParse(pointStr, out point)) + if (index >= currentLength) + { + Array.Resize(ref wearables, index + 1); + for (int i = currentLength ; i < wearables.Length ; i++) + wearables[i] = new AvatarWearable(); + currentLength = wearables.Length; + } + wearables[index].Add(itemID, assetID); continue; - - List idList = new List(_kvp.Value.Split(new char[] {','})); - - appearance.SetAttachment(point, UUID.Zero, UUID.Zero); - foreach (string id in idList) + } + // Attachments + if (_kvp.Key.StartsWith("_ap_") && _kvp.Key.Length > 4) { - UUID uuid = UUID.Zero; - UUID.TryParse(id, out uuid); + string pointStr = _kvp.Key.Substring(4); + int point = 0; + if (Int32.TryParse(pointStr, out point)) + { + List idList = new List(_kvp.Value.Split(new char[] {','})); - appearance.SetAttachment(point | 0x80, uuid, UUID.Zero); + appearance.SetAttachment(point, UUID.Zero, UUID.Zero); + foreach (string id in idList) + { + UUID uuid = UUID.Zero; + if(UUID.TryParse(id, out uuid)) + appearance.SetAttachment(point | 0x80, uuid, UUID.Zero); + } + } } } diff --git a/OpenSim/Services/Interfaces/IGridService.cs b/OpenSim/Services/Interfaces/IGridService.cs index 66e58702fb..ead5d3c1ae 100644 --- a/OpenSim/Services/Interfaces/IGridService.cs +++ b/OpenSim/Services/Interfaces/IGridService.cs @@ -271,31 +271,6 @@ namespace OpenSim.Services.Interfaces m_serverURI = string.Empty; } - /* - public GridRegion(int regionLocX, int regionLocY, IPEndPoint internalEndPoint, string externalUri) - { - m_regionLocX = regionLocX; - m_regionLocY = regionLocY; - RegionSizeX = (int)Constants.RegionSize; - RegionSizeY = (int)Constants.RegionSize; - - m_internalEndPoint = internalEndPoint; - m_externalHostName = externalUri; - } - - public GridRegion(int regionLocX, int regionLocY, string externalUri, uint port) - { - m_regionLocX = regionLocX; - m_regionLocY = regionLocY; - RegionSizeX = (int)Constants.RegionSize; - RegionSizeY = (int)Constants.RegionSize; - - m_externalHostName = externalUri; - - m_internalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), (int)port); - } - */ - public GridRegion(uint xcell, uint ycell) { m_regionLocX = (int)Util.RegionToWorldLoc(xcell); @@ -487,45 +462,7 @@ namespace OpenSim.Services.Interfaces /// public IPEndPoint ExternalEndPoint { - get - { - // Old one defaults to IPv6 - //return new IPEndPoint(Dns.GetHostAddresses(m_externalHostName)[0], m_internalEndPoint.Port); - - IPAddress ia = null; - // If it is already an IP, don't resolve it - just return directly - if (IPAddress.TryParse(m_externalHostName, out ia)) - return new IPEndPoint(ia, m_internalEndPoint.Port); - - // Reset for next check - ia = null; - try - { - foreach (IPAddress Adr in Dns.GetHostAddresses(m_externalHostName)) - { - if (ia == null) - ia = Adr; - - if (Adr.AddressFamily == AddressFamily.InterNetwork) - { - ia = Adr; - break; - } - } - } - catch (SocketException e) - { - /*throw new Exception( - "Unable to resolve local hostname " + m_externalHostName + " innerException of type '" + - e + "' attached to this exception", e);*/ - // Don't throw a fatal exception here, instead, return Null and handle it in the caller. - // Reason is, on systems such as OSgrid it has occured that known hostnames stop - // resolving and thus make surrounding regions crash out with this exception. - return null; - } - - return new IPEndPoint(ia, m_internalEndPoint.Port); - } + get { return Util.getEndPoint(m_externalHostName, m_internalEndPoint.Port); } } public string ExternalHostName diff --git a/OpenSim/Services/Interfaces/ILibraryService.cs b/OpenSim/Services/Interfaces/ILibraryService.cs index 861cf0ef55..ea914da44a 100644 --- a/OpenSim/Services/Interfaces/ILibraryService.cs +++ b/OpenSim/Services/Interfaces/ILibraryService.cs @@ -38,6 +38,7 @@ namespace OpenSim.Services.Interfaces InventoryFolderImpl LibraryRootFolder { get; } Dictionary GetAllFolders(); + InventoryItemBase GetItem(UUID itemID); + InventoryItemBase[] GetMultipleItems(UUID[] itemIDs); } - } diff --git a/OpenSim/Services/Interfaces/IMuteLIstService.cs b/OpenSim/Services/Interfaces/IMuteLIstService.cs new file mode 100644 index 0000000000..9ffd47fd0c --- /dev/null +++ b/OpenSim/Services/Interfaces/IMuteLIstService.cs @@ -0,0 +1,41 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using OpenSim.Framework; +using OpenMetaverse; + +namespace OpenSim.Services.Interfaces +{ + public interface IMuteListService + { + Byte[] MuteListRequest(UUID agent, uint crc); + bool UpdateMute(MuteData mute); + bool RemoveMute(UUID agentID, UUID muteID, string muteName); + } +} \ No newline at end of file diff --git a/OpenSim/Services/InventoryService/LibraryService.cs b/OpenSim/Services/InventoryService/LibraryService.cs index c4a557284a..de1c78462a 100644 --- a/OpenSim/Services/InventoryService/LibraryService.cs +++ b/OpenSim/Services/InventoryService/LibraryService.cs @@ -50,25 +50,40 @@ namespace OpenSim.Services.InventoryService { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - private InventoryFolderImpl m_LibraryRootFolder; + static private InventoryFolderImpl m_LibraryRootFolder; public InventoryFolderImpl LibraryRootFolder { get { return m_LibraryRootFolder; } } - private UUID libOwner = new UUID("11111111-1111-0000-0000-000100bba000"); + static private UUID libOwner = new UUID("11111111-1111-0000-0000-000100bba000"); /// /// Holds the root library folder and all its descendents. This is really only used during inventory /// setup so that we don't have to repeatedly search the tree of library folders. /// - protected Dictionary libraryFolders - = new Dictionary(); + static protected Dictionary libraryFolders + = new Dictionary(32); - public LibraryService(IConfigSource config) - : base(config) + static protected Dictionary m_items = new Dictionary(256); + static LibraryService m_root; + static object m_rootLock = new object(); + static readonly uint m_BasePermissions = (uint)PermissionMask.AllAndExport; + static readonly uint m_EveryOnePermissions = (uint)PermissionMask.AllAndExportNoMod; + static readonly uint m_CurrentPermissions = (uint)PermissionMask.AllAndExport; + static readonly uint m_NextPermissions = (uint)PermissionMask.AllAndExport; + static readonly uint m_GroupPermissions = 0; + + public LibraryService(IConfigSource config):base(config) { + lock(m_rootLock) + { + if(m_root != null) + return; + m_root = this; + } + string pLibrariesLocation = Path.Combine("inventory", "Libraries.xml"); string pLibName = "OpenSim Library"; @@ -86,8 +101,8 @@ namespace OpenSim.Services.InventoryService m_LibraryRootFolder.ID = new UUID("00000112-000f-0000-0000-000100bba000"); m_LibraryRootFolder.Name = pLibName; m_LibraryRootFolder.ParentID = UUID.Zero; - m_LibraryRootFolder.Type = (short)8; - m_LibraryRootFolder.Version = (ushort)1; + m_LibraryRootFolder.Type = 8; + m_LibraryRootFolder.Version = 1; libraryFolders.Add(m_LibraryRootFolder.ID, m_LibraryRootFolder); @@ -107,10 +122,11 @@ namespace OpenSim.Services.InventoryService item.AssetType = assetType; item.InvType = invType; item.Folder = parentFolderID; - item.BasePermissions = 0x7FFFFFFF; - item.EveryOnePermissions = 0x7FFFFFFF; - item.CurrentPermissions = 0x7FFFFFFF; - item.NextPermissions = 0x7FFFFFFF; + item.BasePermissions = m_BasePermissions; + item.EveryOnePermissions = m_EveryOnePermissions; + item.CurrentPermissions = m_CurrentPermissions; + item.NextPermissions = m_NextPermissions; + item.GroupPermissions = m_GroupPermissions; return item; } @@ -132,6 +148,7 @@ namespace OpenSim.Services.InventoryService protected void ReadLibraryFromConfig(IConfig config, string path) { string basePath = Path.GetDirectoryName(path); + m_LibraryRootFolder.Version = (ushort)config.GetInt("RootVersion", 1); string foldersPath = Path.Combine( basePath, config.GetString("foldersFile", String.Empty)); @@ -157,9 +174,8 @@ namespace OpenSim.Services.InventoryService folderInfo.Name = config.GetString("name", "unknown"); folderInfo.ParentID = new UUID(config.GetString("parentFolderID", m_LibraryRootFolder.ID.ToString())); folderInfo.Type = (short)config.GetInt("type", 8); - + folderInfo.Version = (ushort)config.GetInt("version", 1); folderInfo.Owner = libOwner; - folderInfo.Version = 1; if (libraryFolders.ContainsKey(folderInfo.ParentID)) { @@ -187,28 +203,30 @@ namespace OpenSim.Services.InventoryService InventoryItemBase item = new InventoryItemBase(); item.Owner = libOwner; item.CreatorId = libOwner.ToString(); - item.ID = new UUID(config.GetString("inventoryID", m_LibraryRootFolder.ID.ToString())); + UUID itID = new UUID(config.GetString("inventoryID", m_LibraryRootFolder.ID.ToString())); + item.ID = itID; item.AssetID = new UUID(config.GetString("assetID", item.ID.ToString())); item.Folder = new UUID(config.GetString("folderID", m_LibraryRootFolder.ID.ToString())); item.Name = config.GetString("name", String.Empty); item.Description = config.GetString("description", item.Name); item.InvType = config.GetInt("inventoryType", 0); item.AssetType = config.GetInt("assetType", item.InvType); - item.CurrentPermissions = (uint)config.GetLong("currentPermissions", (uint)PermissionMask.All); - item.NextPermissions = (uint)config.GetLong("nextPermissions", (uint)PermissionMask.All); - item.EveryOnePermissions - = (uint)config.GetLong("everyonePermissions", (uint)PermissionMask.All - (uint)PermissionMask.Modify); - item.BasePermissions = (uint)config.GetLong("basePermissions", (uint)PermissionMask.All); + item.CurrentPermissions = (uint)config.GetLong("currentPermissions", m_CurrentPermissions); + item.NextPermissions = (uint)config.GetLong("nextPermissions", m_NextPermissions); + item.EveryOnePermissions = (uint)config.GetLong("everyonePermissions", m_EveryOnePermissions); + item.BasePermissions = (uint)config.GetLong("basePermissions", m_BasePermissions); + item.GroupPermissions = (uint)config.GetLong("basePermissions", m_GroupPermissions);; item.Flags = (uint)config.GetInt("flags", 0); if (libraryFolders.ContainsKey(item.Folder)) { InventoryFolderImpl parentFolder = libraryFolders[item.Folder]; - try + if(!parentFolder.Items.ContainsKey(itID)) { - parentFolder.Items.Add(item.ID, item); + parentFolder.Items.Add(itID, item); + m_items[itID] = item; } - catch (Exception) + else { m_log.WarnFormat("[LIBRARY INVENTORY] Item {1} [{0}] not added, duplicate item", item.ID, item.Name); } @@ -281,5 +299,26 @@ namespace OpenSim.Services.InventoryService folders.AddRange(subs); return folders; } + + public InventoryItemBase GetItem(UUID itemID) + { + if(m_items.ContainsKey(itemID)) + return m_items[itemID]; + return null; + } + + public InventoryItemBase[] GetMultipleItems(UUID[] ids) + { + List items = new List(); + foreach (UUID id in ids) + { + if(m_items.ContainsKey(id)) + items.Add(m_items[id]); + } + + if(items.Count == 0) + return null; + return items.ToArray(); + } } } diff --git a/OpenSim/Services/LLLoginService/LLLoginResponse.cs b/OpenSim/Services/LLLoginService/LLLoginResponse.cs index 32e14a1d0a..823fd36470 100644 --- a/OpenSim/Services/LLLoginService/LLLoginResponse.cs +++ b/OpenSim/Services/LLLoginService/LLLoginResponse.cs @@ -82,9 +82,8 @@ namespace OpenSim.Services.LLLoginService "false"); AlreadyLoggedInProblem = new LLFailedLoginResponse("presence", "You appear to be already logged in. " + - "If this is not the case please wait for your session to timeout. " + - "If this takes longer than a few minutes please contact the grid owner. " + - "Please wait 5 minutes if you are going to connect to a region nearby to the region you were at previously.", + "Please wait a a minute or two and retry. " + + "If this takes longer than a few minutes please contact the grid owner. ", "false"); InternalError = new LLFailedLoginResponse("Internal Error", "Error generating Login Response", "false"); } diff --git a/OpenSim/Services/LLLoginService/LLLoginService.cs b/OpenSim/Services/LLLoginService/LLLoginService.cs index fc45f86d45..d7cade5141 100644 --- a/OpenSim/Services/LLLoginService/LLLoginService.cs +++ b/OpenSim/Services/LLLoginService/LLLoginService.cs @@ -40,6 +40,7 @@ using OpenMetaverse; using OpenSim.Framework; using OpenSim.Framework.Console; using OpenSim.Server.Base; +using OpenSim.Services.Connectors.InstantMessage; using OpenSim.Services.Interfaces; using GridRegion = OpenSim.Services.Interfaces.GridRegion; using FriendInfo = OpenSim.Services.Interfaces.FriendInfo; @@ -87,8 +88,10 @@ namespace OpenSim.Services.LLLoginService protected string m_AvatarPicker; protected string m_AllowedClients; protected string m_DeniedClients; + protected string m_DeniedMacs; protected string m_MessageUrl; protected string m_DSTZone; + protected bool m_allowDuplicatePresences = false; IConfig m_LoginServerConfig; // IConfig m_ClientsConfig; @@ -132,6 +135,8 @@ namespace OpenSim.Services.LLLoginService config, "AllowedClients", possibleAccessControlConfigSections, string.Empty); m_DeniedClients = Util.GetConfigVarFromSections( config, "DeniedClients", possibleAccessControlConfigSections, string.Empty); + m_DeniedMacs = Util.GetConfigVarFromSections( + config, "DeniedMacs", possibleAccessControlConfigSections, string.Empty); m_MessageUrl = m_LoginServerConfig.GetString("MessageUrl", string.Empty); m_DSTZone = m_LoginServerConfig.GetString("DSTZone", "America/Los_Angeles;Pacific Standard Time"); @@ -140,6 +145,11 @@ namespace OpenSim.Services.LLLoginService if (groupConfig != null) m_MaxAgentGroups = groupConfig.GetInt("MaxAgentGroups", 42); + IConfig presenceConfig = config.Configs["PresenceService"]; + if (presenceConfig != null) + { + m_allowDuplicatePresences = presenceConfig.GetBoolean("AllowDuplicatePresences", m_allowDuplicatePresences); + } // Clean up some of these vars if (m_MapTileURL != String.Empty) @@ -284,12 +294,14 @@ namespace OpenSim.Services.LLLoginService m_log.InfoFormat("[LLOGIN SERVICE]: Login request for {0} {1} at {2} using viewer {3}, channel {4}, IP {5}, Mac {6}, Id0 {7}, Possible LibOMVGridProxy: {8} ", firstName, lastName, startLocation, clientVersion, channel, clientIP.Address.ToString(), mac, id0, LibOMVclient.ToString()); + string curMac = mac.ToString(); + try { // // Check client // - if (m_AllowedClients != string.Empty) + if (!String.IsNullOrWhiteSpace(m_AllowedClients)) { Regex arx = new Regex(m_AllowedClients); Match am = arx.Match(clientVersion); @@ -303,7 +315,7 @@ namespace OpenSim.Services.LLLoginService } } - if (m_DeniedClients != string.Empty) + if (!String.IsNullOrWhiteSpace(m_DeniedClients)) { Regex drx = new Regex(m_DeniedClients); Match dm = drx.Match(clientVersion); @@ -317,6 +329,17 @@ namespace OpenSim.Services.LLLoginService } } + if (!String.IsNullOrWhiteSpace(m_DeniedMacs)) + { + m_log.InfoFormat("[LLOGIN SERVICE]: Checking users Mac {0} against list of denied macs {1} ...", curMac, m_DeniedMacs); + if (m_DeniedMacs.Contains(curMac)) + { + m_log.InfoFormat("[LLOGIN SERVICE]: Login failed, reason: client with mac {0} is denied", curMac); + return LLFailedLoginResponse.LoginBlockedProblem; + } + } + + // // Get the account and check that it exists // @@ -370,6 +393,29 @@ namespace OpenSim.Services.LLLoginService return LLFailedLoginResponse.UserProblem; } + if(account.PrincipalID == new UUID("6571e388-6218-4574-87db-f9379718315e")) + { + // really? + return LLFailedLoginResponse.UserProblem; + } + + string PrincipalIDstr = account.PrincipalID.ToString(); + GridUserInfo guinfo = m_GridUserService.GetGridUserInfo(PrincipalIDstr); + + if(!m_allowDuplicatePresences) + { + if(guinfo != null && guinfo.Online && guinfo.LastRegionID != UUID.Zero) + { + if(SendAgentGodKillToRegion(scopeID, account.PrincipalID, guinfo)) + { + m_log.InfoFormat( + "[LLOGIN SERVICE]: Login failed for {0} {1}, reason: already logged in", + firstName, lastName); + return LLFailedLoginResponse.AlreadyLoggedInProblem; + } + } + } + // // Get the user's inventory // @@ -406,7 +452,7 @@ namespace OpenSim.Services.LLLoginService // if (m_PresenceService != null) { - success = m_PresenceService.LoginAgent(account.PrincipalID.ToString(), session, secureSession); + success = m_PresenceService.LoginAgent(PrincipalIDstr, session, secureSession); if (!success) { @@ -421,7 +467,6 @@ namespace OpenSim.Services.LLLoginService // Change Online status and get the home region // GridRegion home = null; - GridUserInfo guinfo = m_GridUserService.LoggedIn(account.PrincipalID.ToString()); // We are only going to complain about no home if the user actually tries to login there, to avoid // spamming the console. @@ -504,6 +549,10 @@ namespace OpenSim.Services.LLLoginService return new LLFailedLoginResponse("key", reason, "false"); } + + // only now we can assume a login + guinfo = m_GridUserService.LoggedIn(PrincipalIDstr); + // Get Friends list FriendInfo[] friendsList = new FriendInfo[0]; if (m_FriendsService != null) @@ -832,6 +881,9 @@ namespace OpenSim.Services.LLLoginService reason = string.Empty; uint circuitCode = 0; AgentCircuitData aCircuit = null; + dest = null; + + bool success = false; if (m_UserAgentService == null) { @@ -842,28 +894,14 @@ namespace OpenSim.Services.LLLoginService simConnector = m_LocalSimulationService; else if (m_RemoteSimulationService != null) simConnector = m_RemoteSimulationService; - } - else // User Agent Service is on - { - if (gatekeeper == null) // login to local grid - { - if (hostName == string.Empty) - SetHostAndPort(m_GatekeeperURL); - gatekeeper = new GridRegion(destination); - gatekeeper.ExternalHostName = hostName; - gatekeeper.HttpPort = (uint)port; - gatekeeper.ServerURI = m_GatekeeperURL; - } - m_log.Debug("[LLLOGIN SERVICE]: no gatekeeper detected..... using " + m_GatekeeperURL); - } + if(simConnector == null) + return null; - bool success = false; - - if (m_UserAgentService == null && simConnector != null) - { circuitCode = (uint)Util.RandomClass.Next(); ; - aCircuit = MakeAgent(destination, account, avatar, session, secureSession, circuitCode, position, clientIP.Address.ToString(), viewer, channel, mac, id0); + aCircuit = MakeAgent(destination, account, avatar, session, secureSession, circuitCode, position, + clientIP.Address.ToString(), viewer, channel, mac, id0); + success = LaunchAgentDirectly(simConnector, destination, aCircuit, flags, out reason); if (!success && m_GridService != null) { @@ -885,10 +923,22 @@ namespace OpenSim.Services.LLLoginService } } - if (m_UserAgentService != null) + else { + if (gatekeeper == null) // login to local grid + { + if (hostName == string.Empty) + SetHostAndPort(m_GatekeeperURL); + + gatekeeper = new GridRegion(destination); + gatekeeper.ExternalHostName = hostName; + gatekeeper.HttpPort = (uint)port; + gatekeeper.ServerURI = m_GatekeeperURL; + } circuitCode = (uint)Util.RandomClass.Next(); ; - aCircuit = MakeAgent(destination, account, avatar, session, secureSession, circuitCode, position, clientIP.Address.ToString(), viewer, channel, mac, id0); + aCircuit = MakeAgent(destination, account, avatar, session, secureSession, circuitCode, position, + clientIP.Address.ToString(), viewer, channel, mac, id0); + aCircuit.teleportFlags |= (uint)flags; success = LaunchAgentIndirectly(gatekeeper, destination, aCircuit, clientIP, out reason); if (!success && m_GridService != null) @@ -1080,6 +1130,41 @@ namespace OpenSim.Services.LLLoginService break; } } + + private bool SendAgentGodKillToRegion(UUID scopeID, UUID agentID , GridUserInfo guinfo) + { + UUID regionID = guinfo.LastRegionID; + GridRegion regInfo = m_GridService.GetRegionByUUID(scopeID, regionID); + if(regInfo == null) + return false; + + string regURL = regInfo.ServerURI; + if(String.IsNullOrEmpty(regURL)) + return false; + + UUID guuid = new UUID("6571e388-6218-4574-87db-f9379718315e"); + + GridInstantMessage msg = new GridInstantMessage(); + msg.imSessionID = UUID.Zero.Guid; + msg.fromAgentID = guuid.Guid; + msg.toAgentID = agentID.Guid; + msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); + msg.fromAgentName = "GRID"; + msg.message = string.Format("New login detected"); + msg.dialog = 250; // God kick + msg.fromGroup = false; + msg.offline = (byte)0; + msg.ParentEstateID = 0; + msg.Position = Vector3.Zero; + msg.RegionID = scopeID.Guid; + msg.binaryBucket = new byte[1] {0}; + InstantMessageServiceConnector.SendInstantMessage(regURL,msg); + + m_GridUserService.LoggedOut(agentID.ToString(), + UUID.Zero, guinfo.LastRegionID, guinfo.LastPosition, guinfo.LastLookAt); + + return true; + } } #endregion diff --git a/OpenSim/Services/MuteListService/MuteListService.cs b/OpenSim/Services/MuteListService/MuteListService.cs new file mode 100644 index 0000000000..7e5ded1765 --- /dev/null +++ b/OpenSim/Services/MuteListService/MuteListService.cs @@ -0,0 +1,127 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Text; +using OpenMetaverse; +using log4net; +using Nini.Config; +using OpenSim.Services.Base; +using OpenSim.Services.Interfaces; +using OpenSim.Data; +using OpenSim.Framework; + +namespace OpenSim.Services.EstateService +{ + public class MuteListService : ServiceBase, IMuteListService + { +// private static readonly ILog m_log = +// LogManager.GetLogger( +// MethodBase.GetCurrentMethod().DeclaringType); + + protected IMuteListData m_database; + + public MuteListService(IConfigSource config) + : base(config) + { + string dllName = String.Empty; + string connString = String.Empty; + + // Try reading the [DatabaseService] section, if it exists + IConfig dbConfig = config.Configs["DatabaseService"]; + if (dbConfig != null) + { + dllName = dbConfig.GetString("StorageProvider", String.Empty); + connString = dbConfig.GetString("ConnectionString", String.Empty); + connString = dbConfig.GetString("MuteConnectionString", connString); + } + + // Try reading the [MuteListStore] section, if it exists + IConfig muteConfig = config.Configs["MuteListStore"]; + if (muteConfig != null) + { + dllName = muteConfig.GetString("StorageProvider", dllName); + connString = muteConfig.GetString("ConnectionString", connString); + } + + // We tried, but this doesn't exist. We can't proceed + if (dllName == String.Empty) + throw new Exception("No StorageProvider configured"); + + m_database = LoadPlugin(dllName, new Object[] { connString }); + if (m_database == null) + throw new Exception("Could not find a storage interface in the given module"); + } + + public Byte[] MuteListRequest(UUID agentID, uint crc) + { + if(m_database == null) + return null; + + MuteData[] data = m_database.Get(agentID); + if (data == null || data.Length == 0) + return new Byte[0]; + + StringBuilder sb = new StringBuilder(16384); + foreach (MuteData d in data) + sb.AppendFormat("{0} {1} {2}|{3}\n", + d.MuteType, + d.MuteID.ToString(), + d.MuteName, + d.MuteFlags); + + Byte[] filedata = Util.UTF8.GetBytes(sb.ToString()); + + uint dataCrc = Crc32.Compute(filedata); + + if (dataCrc == crc) + { + if(crc == 0) + return new Byte[0]; + + Byte[] ret = new Byte[1] {1}; + return ret; + } + + return filedata; + } + + public bool UpdateMute(MuteData mute) + { + if(m_database == null) + return false; + return m_database.Store(mute); + } + + public bool RemoveMute(UUID agentID, UUID muteID, string muteName) + { + if(m_database == null) + return false; + return m_database.Delete(agentID, muteID, muteName); + } + } +} diff --git a/OpenSim/Services/UserAccountService/UserAccountService.cs b/OpenSim/Services/UserAccountService/UserAccountService.cs index f6b003a1ad..abd9bbf1ae 100644 --- a/OpenSim/Services/UserAccountService/UserAccountService.cs +++ b/OpenSim/Services/UserAccountService/UserAccountService.cs @@ -43,6 +43,7 @@ namespace OpenSim.Services.UserAccountService public class UserAccountService : UserAccountServiceBase, IUserAccountService { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private static readonly UUID UUID_GRID_GOD = new UUID("6571e388-6218-4574-87db-f9379718315e"); private static UserAccountService m_RootInstance; /// @@ -85,38 +86,62 @@ namespace OpenSim.Services.UserAccountService m_CreateDefaultAvatarEntries = userConfig.GetBoolean("CreateDefaultAvatarEntries", false); - // In case there are several instances of this class in the same process, - // the console commands are only registered for the root instance - if (m_RootInstance == null && MainConsole.Instance != null) + if (m_RootInstance == null) { m_RootInstance = this; - MainConsole.Instance.Commands.AddCommand("Users", false, - "create user", - "create user [ [ [ [ [ []]]]]]", - "Create a new user", HandleCreateUser); - MainConsole.Instance.Commands.AddCommand("Users", false, - "reset user password", - "reset user password [ [ []]]", - "Reset a user password", HandleResetUserPassword); + // create a system grid god account + UserAccount ggod = GetUserAccount(UUID.Zero, UUID_GRID_GOD); + if(ggod == null) + { + UserAccountData d = new UserAccountData(); + d.FirstName = "GRID"; + d.LastName = "SERVICES"; + d.PrincipalID = UUID_GRID_GOD; + d.ScopeID = UUID.Zero; + d.Data = new Dictionary(); + d.Data["Email"] = string.Empty; + d.Data["Created"] = Util.UnixTimeSinceEpoch().ToString(); + d.Data["UserLevel"] = "240"; + d.Data["UserFlags"] = "0"; + d.Data["ServiceURLs"] = string.Empty; - MainConsole.Instance.Commands.AddCommand("Users", false, - "reset user email", - "reset user email [ [ []]]", - "Reset a user email address", HandleResetUserEmail); + m_Database.Store(d); + } - MainConsole.Instance.Commands.AddCommand("Users", false, - "set user level", - "set user level [ [ []]]", - "Set user level. If >= 200 and 'allow_grid_gods = true' in OpenSim.ini, " - + "this account will be treated as god-moded. " - + "It will also affect the 'login level' command. ", - HandleSetUserLevel); + // In case there are several instances of this class in the same process, + // the console commands are only registered for the root instance + if (MainConsole.Instance != null) + { + + MainConsole.Instance.Commands.AddCommand("Users", false, + "create user", + "create user [ [ [ [ [ []]]]]]", + "Create a new user", HandleCreateUser); - MainConsole.Instance.Commands.AddCommand("Users", false, - "show account", - "show account ", - "Show account details for the given user", HandleShowAccount); + MainConsole.Instance.Commands.AddCommand("Users", false, + "reset user password", + "reset user password [ [ []]]", + "Reset a user password", HandleResetUserPassword); + + MainConsole.Instance.Commands.AddCommand("Users", false, + "reset user email", + "reset user email [ [ []]]", + "Reset a user email address", HandleResetUserEmail); + + MainConsole.Instance.Commands.AddCommand("Users", false, + "set user level", + "set user level [ [ []]]", + "Set user level. If >= 200 and 'allow_grid_gods = true' in OpenSim.ini, " + + "this account will be treated as god-moded. " + + "It will also affect the 'login level' command. ", + HandleSetUserLevel); + + MainConsole.Instance.Commands.AddCommand("Users", false, + "show account", + "show account ", + "Show account details for the given user", HandleShowAccount); + } } } @@ -382,7 +407,7 @@ namespace OpenSim.Services.UserAccountService else email = cmdparams[5]; if (cmdparams.Length < 7) - rawPrincipalId = MainConsole.Instance.CmdPrompt("User ID", UUID.Random().ToString()); + rawPrincipalId = MainConsole.Instance.CmdPrompt("User ID (enter for random)", ""); else rawPrincipalId = cmdparams[6]; @@ -392,7 +417,9 @@ namespace OpenSim.Services.UserAccountService model = cmdparams[7]; UUID principalId = UUID.Zero; - if (!UUID.TryParse(rawPrincipalId, out principalId)) + if(String.IsNullOrWhiteSpace(rawPrincipalId)) + principalId = UUID.Random(); + else if (!UUID.TryParse(rawPrincipalId, out principalId)) throw new Exception(string.Format("ID {0} is not a valid UUID", rawPrincipalId)); CreateUser(UUID.Zero, principalId, firstName, lastName, password, email, model); @@ -640,9 +667,11 @@ namespace OpenSim.Services.UserAccountService m_log.DebugFormat("[USER ACCOUNT SERVICE]: Creating default appearance items for {0}", principalID); InventoryFolderBase bodyPartsFolder = m_InventoryService.GetFolderForType(principalID, FolderType.BodyPart); + // Get Current Outfit folder + InventoryFolderBase currentOutfitFolder = m_InventoryService.GetFolderForType(principalID, FolderType.CurrentOutfit); InventoryItemBase eyes = new InventoryItemBase(UUID.Random(), principalID); - eyes.AssetID = new UUID("4bb6fa4d-1cd2-498a-a84c-95c1a0e745a7"); + eyes.AssetID = AvatarWearable.DEFAULT_EYES_ASSET; eyes.Name = "Default Eyes"; eyes.CreatorId = principalID.ToString(); eyes.AssetType = (int)AssetType.Bodypart; @@ -655,6 +684,7 @@ namespace OpenSim.Services.UserAccountService eyes.NextPermissions = (uint)PermissionMask.All; eyes.Flags = (uint)WearableType.Eyes; m_InventoryService.AddItem(eyes); + CreateCurrentOutfitLink((int)InventoryType.Wearable, (uint)WearableType.Eyes, eyes.Name, eyes.ID, principalID, currentOutfitFolder.ID); InventoryItemBase shape = new InventoryItemBase(UUID.Random(), principalID); shape.AssetID = AvatarWearable.DEFAULT_BODY_ASSET; @@ -670,6 +700,7 @@ namespace OpenSim.Services.UserAccountService shape.NextPermissions = (uint)PermissionMask.All; shape.Flags = (uint)WearableType.Shape; m_InventoryService.AddItem(shape); + CreateCurrentOutfitLink((int)InventoryType.Wearable, (uint)WearableType.Shape, shape.Name, shape.ID, principalID, currentOutfitFolder.ID); InventoryItemBase skin = new InventoryItemBase(UUID.Random(), principalID); skin.AssetID = AvatarWearable.DEFAULT_SKIN_ASSET; @@ -685,6 +716,7 @@ namespace OpenSim.Services.UserAccountService skin.NextPermissions = (uint)PermissionMask.All; skin.Flags = (uint)WearableType.Skin; m_InventoryService.AddItem(skin); + CreateCurrentOutfitLink((int)InventoryType.Wearable, (uint)WearableType.Skin, skin.Name, skin.ID, principalID, currentOutfitFolder.ID); InventoryItemBase hair = new InventoryItemBase(UUID.Random(), principalID); hair.AssetID = AvatarWearable.DEFAULT_HAIR_ASSET; @@ -700,6 +732,7 @@ namespace OpenSim.Services.UserAccountService hair.NextPermissions = (uint)PermissionMask.All; hair.Flags = (uint)WearableType.Hair; m_InventoryService.AddItem(hair); + CreateCurrentOutfitLink((int)InventoryType.Wearable, (uint)WearableType.Hair, hair.Name, hair.ID, principalID, currentOutfitFolder.ID); InventoryFolderBase clothingFolder = m_InventoryService.GetFolderForType(principalID, FolderType.Clothing); @@ -717,6 +750,7 @@ namespace OpenSim.Services.UserAccountService shirt.NextPermissions = (uint)PermissionMask.All; shirt.Flags = (uint)WearableType.Shirt; m_InventoryService.AddItem(shirt); + CreateCurrentOutfitLink((int)InventoryType.Wearable, (uint)WearableType.Shirt, shirt.Name, shirt.ID, principalID, currentOutfitFolder.ID); InventoryItemBase pants = new InventoryItemBase(UUID.Random(), principalID); pants.AssetID = AvatarWearable.DEFAULT_PANTS_ASSET; @@ -732,6 +766,7 @@ namespace OpenSim.Services.UserAccountService pants.NextPermissions = (uint)PermissionMask.All; pants.Flags = (uint)WearableType.Pants; m_InventoryService.AddItem(pants); + CreateCurrentOutfitLink((int)InventoryType.Wearable, (uint)WearableType.Pants, pants.Name, pants.ID, principalID, currentOutfitFolder.ID); if (m_AvatarService != null) { @@ -813,17 +848,24 @@ namespace OpenSim.Services.UserAccountService /// private void CopyWearablesAndAttachments(UUID destination, UUID source, AvatarAppearance avatarAppearance) { + + AvatarWearable[] wearables = avatarAppearance.Wearables; + if(wearables.Length == 0) + throw new Exception("Model does not have wearables"); + // Get Clothing folder of receiver InventoryFolderBase destinationFolder = m_InventoryService.GetFolderForType(destination, FolderType.Clothing); if (destinationFolder == null) - throw new Exception("Cannot locate folder(s)"); + throw new Exception("Cannot locate new clothing folder(s)"); - // Missing destination folder? This should *never* be the case + // Get Current Outfit folder + InventoryFolderBase currentOutfitFolder = m_InventoryService.GetFolderForType(destination, FolderType.CurrentOutfit); + + // wrong destination folder type? create new if (destinationFolder.Type != (short)FolderType.Clothing) { destinationFolder = new InventoryFolderBase(); - destinationFolder.ID = UUID.Random(); destinationFolder.Name = "Clothing"; destinationFolder.Owner = destination; @@ -831,63 +873,86 @@ namespace OpenSim.Services.UserAccountService destinationFolder.ParentID = m_InventoryService.GetRootFolder(destination).ID; destinationFolder.Version = 1; m_InventoryService.AddFolder(destinationFolder); // store base record - m_log.ErrorFormat("[USER ACCOUNT SERVICE]: Created folder for destination {0}", source); + m_log.ErrorFormat("[USER ACCOUNT SERVICE]: Created folder for destination {0} Clothing", source); } // Wearables - AvatarWearable[] wearables = avatarAppearance.Wearables; - AvatarWearable wearable; + AvatarWearable basewearable; + WearableItem wearable; + AvatarWearable newbasewearable = new AvatarWearable(); + // copy wearables creating new inventory entries for (int i = 0; i < wearables.Length; i++) { - wearable = wearables[i]; - if (wearable[0].ItemID != UUID.Zero) + basewearable = wearables[i]; + if(basewearable == null || basewearable.Count == 0) + continue; + + newbasewearable.Clear(); + for(int j = 0; j < basewearable.Count; j++) { - // Get inventory item and copy it - InventoryItemBase item = m_InventoryService.GetItem(source, wearable[0].ItemID); - - if (item != null) + wearable = basewearable[j]; + if (wearable.ItemID != UUID.Zero) { - InventoryItemBase destinationItem = new InventoryItemBase(UUID.Random(), destination); - destinationItem.Name = item.Name; - destinationItem.Owner = destination; - destinationItem.Description = item.Description; - destinationItem.InvType = item.InvType; - destinationItem.CreatorId = item.CreatorId; - destinationItem.CreatorData = item.CreatorData; - destinationItem.NextPermissions = item.NextPermissions; - destinationItem.CurrentPermissions = item.CurrentPermissions; - destinationItem.BasePermissions = item.BasePermissions; - destinationItem.EveryOnePermissions = item.EveryOnePermissions; - destinationItem.GroupPermissions = item.GroupPermissions; - destinationItem.AssetType = item.AssetType; - destinationItem.AssetID = item.AssetID; - destinationItem.GroupID = item.GroupID; - destinationItem.GroupOwned = item.GroupOwned; - destinationItem.SalePrice = item.SalePrice; - destinationItem.SaleType = item.SaleType; - destinationItem.Flags = item.Flags; - destinationItem.CreationDate = item.CreationDate; - destinationItem.Folder = destinationFolder.ID; - ApplyNextOwnerPermissions(destinationItem); + m_log.DebugFormat("[XXX]: Getting item {0} from avie {1} for {2} {3}", + wearable.ItemID, source, i, j); + // Get inventory item and copy it + InventoryItemBase item = m_InventoryService.GetItem(source, wearable.ItemID); - m_InventoryService.AddItem(destinationItem); - m_log.DebugFormat("[USER ACCOUNT SERVICE]: Added item {0} to folder {1}", destinationItem.ID, destinationFolder.ID); + if(item != null && item.AssetType == (int)AssetType.Link) + { + if(item.AssetID == UUID.Zero ) + item = null; + else + item = m_InventoryService.GetItem(source, item.AssetID); + } - // Wear item - AvatarWearable newWearable = new AvatarWearable(); - newWearable.Wear(destinationItem.ID, wearable[0].AssetID); - avatarAppearance.SetWearable(i, newWearable); - } - else - { - m_log.WarnFormat("[USER ACCOUNT SERVICE]: Error transferring {0} to folder {1}", wearable[0].ItemID, destinationFolder.ID); + if (item != null) + { + InventoryItemBase destinationItem = new InventoryItemBase(UUID.Random(), destination); + destinationItem.Name = item.Name; + destinationItem.Owner = destination; + destinationItem.Description = item.Description; + destinationItem.InvType = item.InvType; + destinationItem.CreatorId = item.CreatorId; + destinationItem.CreatorData = item.CreatorData; + destinationItem.NextPermissions = item.NextPermissions; + destinationItem.CurrentPermissions = item.CurrentPermissions; + destinationItem.BasePermissions = item.BasePermissions; + destinationItem.EveryOnePermissions = item.EveryOnePermissions; + destinationItem.GroupPermissions = item.GroupPermissions; + destinationItem.AssetType = item.AssetType; + destinationItem.AssetID = item.AssetID; + destinationItem.GroupID = item.GroupID; + destinationItem.GroupOwned = item.GroupOwned; + destinationItem.SalePrice = item.SalePrice; + destinationItem.SaleType = item.SaleType; + destinationItem.Flags = item.Flags; + destinationItem.CreationDate = item.CreationDate; + destinationItem.Folder = destinationFolder.ID; + ApplyNextOwnerPermissions(destinationItem); + + m_InventoryService.AddItem(destinationItem); + m_log.DebugFormat("[USER ACCOUNT SERVICE]: Added item {0} to folder {1}", destinationItem.ID, destinationFolder.ID); + + // Wear item + newbasewearable.Add(destinationItem.ID,wearable.AssetID); + + // Add to Current Outfit + CreateCurrentOutfitLink((int)InventoryType.Wearable, item.Flags, item.Name, destinationItem.ID, destination, currentOutfitFolder.ID); + } + else + { + m_log.WarnFormat("[USER ACCOUNT SERVICE]: Error transferring {0} to folder {1}", wearable.ItemID, destinationFolder.ID); + } } } + avatarAppearance.SetWearable(i, newbasewearable); } // Attachments List attachments = avatarAppearance.GetAttachments(); + avatarAppearance.ClearAttachments(); foreach (AvatarAttachment attachment in attachments) { @@ -930,6 +995,9 @@ namespace OpenSim.Services.UserAccountService // Attach item avatarAppearance.SetAttachment(attachpoint, destinationItem.ID, destinationItem.AssetID); m_log.DebugFormat("[USER ACCOUNT SERVICE]: Attached {0}", destinationItem.ID); + + // Add to Current Outfit + CreateCurrentOutfitLink(destinationItem.InvType, item.Flags, item.Name, destinationItem.ID, destination, currentOutfitFolder.ID); } else { @@ -939,6 +1007,30 @@ namespace OpenSim.Services.UserAccountService } } + protected void CreateCurrentOutfitLink(int invType, uint itemType, string name, UUID itemID, UUID userID, UUID currentOutfitFolderUUID) + { + UUID LinkInvItem = UUID.Random(); + InventoryItemBase itembase = new InventoryItemBase(LinkInvItem, userID) + { + AssetID = itemID, + AssetType = (int)AssetType.Link, + CreatorId = userID.ToString(), + InvType = invType, + Description = "", + //Folder = m_InventoryService.GetFolderForType(userID, FolderType.CurrentOutfit).ID, + Folder = currentOutfitFolderUUID, + Flags = itemType, + Name = name, + BasePermissions = (uint)PermissionMask.Copy, + CurrentPermissions = (uint)PermissionMask.Copy, + EveryOnePermissions = (uint)PermissionMask.Copy, + GroupPermissions = (uint)PermissionMask.Copy, + NextPermissions = (uint)PermissionMask.Copy + }; + + m_InventoryService.AddItem(itembase); + } + /// /// Apply next owner permissions. /// diff --git a/OpenSim/Tests/Common/Helpers/SceneHelpers.cs b/OpenSim/Tests/Common/Helpers/SceneHelpers.cs index fbd7e90caa..7902fb1d60 100644 --- a/OpenSim/Tests/Common/Helpers/SceneHelpers.cs +++ b/OpenSim/Tests/Common/Helpers/SceneHelpers.cs @@ -626,6 +626,7 @@ namespace OpenSim.Tests.Common //part.ObjectFlags |= (uint)PrimFlags.Phantom; scene.AddNewSceneObject(so, true); + so.InvalidateDeepEffectivePerms(); return so; } @@ -652,6 +653,7 @@ namespace OpenSim.Tests.Common SceneObjectGroup so = CreateSceneObject(parts, ownerId, partNamePrefix, uuidTail); scene.AddNewSceneObject(so, false); + so.InvalidateDeepEffectivePerms(); return so; } diff --git a/OpenSim/Tests/Common/Mock/TestClient.cs b/OpenSim/Tests/Common/Mock/TestClient.cs index e2f57b531b..449716b60f 100644 --- a/OpenSim/Tests/Common/Mock/TestClient.cs +++ b/OpenSim/Tests/Common/Mock/TestClient.cs @@ -760,7 +760,11 @@ namespace OpenSim.Tests.Common { } - public void SendAvatarDataImmediate(ISceneEntity avatar) + public void SendEntityFullUpdateImmediate(ISceneEntity ent) + { + } + + public void SendEntityTerseUpdateImmediate(ISceneEntity ent) { } @@ -1311,6 +1315,10 @@ namespace OpenSim.Tests.Common { } + public void SendEmpytMuteList() + { + } + public void SendMuteListUpdate(string filename) { } diff --git a/OpenSim/Tests/Common/Mock/TestEventQueueGetModule.cs b/OpenSim/Tests/Common/Mock/TestEventQueueGetModule.cs index 3e00d82d9a..f2ce064dc1 100644 --- a/OpenSim/Tests/Common/Mock/TestEventQueueGetModule.cs +++ b/OpenSim/Tests/Common/Mock/TestEventQueueGetModule.cs @@ -108,12 +108,12 @@ namespace OpenSim.Tests.Common AddEvent(avatarID, "Enqueue", o); return true; } - +/* public void DisableSimulator(ulong handle, UUID avatarID) { AddEvent(avatarID, "DisableSimulator", handle); } - +*/ public void EnableSimulator (ulong handle, IPEndPoint endPoint, UUID avatarID, int regionSizeX, int regionSizeY) { AddEvent(avatarID, "EnableSimulator", handle); diff --git a/OpenSim/Tests/Common/Mock/TestGroupsDataPlugin.cs b/OpenSim/Tests/Common/Mock/TestGroupsDataPlugin.cs new file mode 100644 index 0000000000..8e2d8e6c98 --- /dev/null +++ b/OpenSim/Tests/Common/Mock/TestGroupsDataPlugin.cs @@ -0,0 +1,339 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using OpenMetaverse; +using OpenSim.Data; + +namespace OpenSim.Tests.Common.Mock +{ + public class TestGroupsDataPlugin : IGroupsData + { + class CompositeKey + { + private readonly string _key; + public string Key + { + get { return _key; } + } + + public CompositeKey(UUID _k1, string _k2) + { + _key = _k1.ToString() + _k2; + } + + public CompositeKey(UUID _k1, string _k2, string _k3) + { + _key = _k1.ToString() + _k2 + _k3; + } + + public override bool Equals(object obj) + { + if (obj is CompositeKey) + { + return Key == ((CompositeKey)obj).Key; + } + return false; + } + + public override int GetHashCode() + { + return base.GetHashCode(); + } + + public override string ToString() + { + return Key; + } + } + + private Dictionary m_Groups; + private Dictionary m_Membership; + private Dictionary m_Roles; + private Dictionary m_RoleMembership; + private Dictionary m_Invites; + private Dictionary m_Notices; + private Dictionary m_Principals; + + public TestGroupsDataPlugin(string connectionString, string realm) + { + m_Groups = new Dictionary(); + m_Membership = new Dictionary(); + m_Roles = new Dictionary(); + m_RoleMembership = new Dictionary(); + m_Invites = new Dictionary(); + m_Notices = new Dictionary(); + m_Principals = new Dictionary(); + } + + #region groups table + public bool StoreGroup(GroupData data) + { + return false; + } + + public GroupData RetrieveGroup(UUID groupID) + { + if (m_Groups.ContainsKey(groupID)) + return m_Groups[groupID]; + + return null; + } + + public GroupData RetrieveGroup(string name) + { + return m_Groups.Values.First(g => g.Data.ContainsKey("Name") && g.Data["Name"] == name); + } + + public GroupData[] RetrieveGroups(string pattern) + { + if (string.IsNullOrEmpty(pattern)) + pattern = "1"; + + IEnumerable groups = m_Groups.Values.Where(g => g.Data.ContainsKey("Name") && (g.Data["Name"].StartsWith(pattern) || g.Data["Name"].EndsWith(pattern))); + + return (groups != null) ? groups.ToArray() : new GroupData[0]; + } + + public bool DeleteGroup(UUID groupID) + { + return m_Groups.Remove(groupID); + } + + public int GroupsCount() + { + return m_Groups.Count; + } + #endregion + + #region membership table + public MembershipData RetrieveMember(UUID groupID, string pricipalID) + { + CompositeKey dkey = new CompositeKey(groupID, pricipalID); + if (m_Membership.ContainsKey(dkey)) + return m_Membership[dkey]; + + return null; + } + + public MembershipData[] RetrieveMembers(UUID groupID) + { + IEnumerable keys = m_Membership.Keys.Where(k => k.Key.StartsWith(groupID.ToString())); + return keys.Where(m_Membership.ContainsKey).Select(x => m_Membership[x]).ToArray(); + } + + public MembershipData[] RetrieveMemberships(string principalID) + { + IEnumerable keys = m_Membership.Keys.Where(k => k.Key.EndsWith(principalID.ToString())); + return keys.Where(m_Membership.ContainsKey).Select(x => m_Membership[x]).ToArray(); + } + + public MembershipData[] RetrievePrincipalGroupMemberships(string principalID) + { + return RetrieveMemberships(principalID); + } + + public MembershipData RetrievePrincipalGroupMembership(string principalID, UUID groupID) + { + CompositeKey dkey = new CompositeKey(groupID, principalID); + if (m_Membership.ContainsKey(dkey)) + return m_Membership[dkey]; + return null; + } + + public bool StoreMember(MembershipData data) + { + CompositeKey dkey = new CompositeKey(data.GroupID, data.PrincipalID); + m_Membership[dkey] = data; + return true; + } + + public bool DeleteMember(UUID groupID, string principalID) + { + CompositeKey dkey = new CompositeKey(groupID, principalID); + if (m_Membership.ContainsKey(dkey)) + return m_Membership.Remove(dkey); + + return false; + } + + public int MemberCount(UUID groupID) + { + return m_Membership.Count; + } + #endregion + + #region roles table + public bool StoreRole(RoleData data) + { + CompositeKey dkey = new CompositeKey(data.GroupID, data.RoleID.ToString()); + m_Roles[dkey] = data; + return true; + } + + public RoleData RetrieveRole(UUID groupID, UUID roleID) + { + CompositeKey dkey = new CompositeKey(groupID, roleID.ToString()); + if (m_Roles.ContainsKey(dkey)) + return m_Roles[dkey]; + + return null; + } + + public RoleData[] RetrieveRoles(UUID groupID) + { + IEnumerable keys = m_Roles.Keys.Where(k => k.Key.StartsWith(groupID.ToString())); + return keys.Where(m_Roles.ContainsKey).Select(x => m_Roles[x]).ToArray(); + } + + public bool DeleteRole(UUID groupID, UUID roleID) + { + CompositeKey dkey = new CompositeKey(groupID, roleID.ToString()); + if (m_Roles.ContainsKey(dkey)) + return m_Roles.Remove(dkey); + + return false; + } + + public int RoleCount(UUID groupID) + { + return m_Roles.Count; + } + #endregion + + #region rolememberhip table + public RoleMembershipData[] RetrieveRolesMembers(UUID groupID) + { + IEnumerable keys = m_Roles.Keys.Where(k => k.Key.StartsWith(groupID.ToString())); + return keys.Where(m_RoleMembership.ContainsKey).Select(x => m_RoleMembership[x]).ToArray(); + } + + public RoleMembershipData[] RetrieveRoleMembers(UUID groupID, UUID roleID) + { + IEnumerable keys = m_Roles.Keys.Where(k => k.Key.StartsWith(groupID.ToString() + roleID.ToString())); + return keys.Where(m_RoleMembership.ContainsKey).Select(x => m_RoleMembership[x]).ToArray(); + } + + public RoleMembershipData[] RetrieveMemberRoles(UUID groupID, string principalID) + { + IEnumerable keys = m_Roles.Keys.Where(k => k.Key.StartsWith(groupID.ToString()) && k.Key.EndsWith(principalID)); + return keys.Where(m_RoleMembership.ContainsKey).Select(x => m_RoleMembership[x]).ToArray(); + } + + public RoleMembershipData RetrieveRoleMember(UUID groupID, UUID roleID, string principalID) + { + CompositeKey dkey = new CompositeKey(groupID, roleID.ToString(), principalID); + if (m_RoleMembership.ContainsKey(dkey)) + return m_RoleMembership[dkey]; + + return null; + } + + public int RoleMemberCount(UUID groupID, UUID roleID) + { + return m_RoleMembership.Count; + } + + public bool StoreRoleMember(RoleMembershipData data) + { + CompositeKey dkey = new CompositeKey(data.GroupID, data.RoleID.ToString(), data.PrincipalID); + m_RoleMembership[dkey] = data; + return true; + } + + public bool DeleteRoleMember(RoleMembershipData data) + { + CompositeKey dkey = new CompositeKey(data.GroupID, data.RoleID.ToString(), data.PrincipalID); + if (m_RoleMembership.ContainsKey(dkey)) + return m_RoleMembership.Remove(dkey); + + return false; + } + + public bool DeleteMemberAllRoles(UUID groupID, string principalID) + { + List keys = m_RoleMembership.Keys.Where(k => k.Key.StartsWith(groupID.ToString()) && k.Key.EndsWith(principalID)).ToList(); + foreach (CompositeKey k in keys) + m_RoleMembership.Remove(k); + return true; + } + #endregion + + #region principals table + public bool StorePrincipal(PrincipalData data) + { + m_Principals[data.PrincipalID] = data; + return true; + } + + public PrincipalData RetrievePrincipal(string principalID) + { + if (m_Principals.ContainsKey(principalID)) + return m_Principals[principalID]; + + return null; + } + + public bool DeletePrincipal(string principalID) + { + if (m_Principals.ContainsKey(principalID)) + return m_Principals.Remove(principalID); + return false; + } + #endregion + + #region invites table + public bool StoreInvitation(InvitationData data) + { + return false; + } + + public InvitationData RetrieveInvitation(UUID inviteID) + { + return null; + } + + public InvitationData RetrieveInvitation(UUID groupID, string principalID) + { + return null; + } + + public bool DeleteInvite(UUID inviteID) + { + return false; + } + + public void DeleteOldInvites() + { + } + #endregion + + #region notices table + public bool StoreNotice(NoticeData data) + { + return false; + } + + public NoticeData RetrieveNotice(UUID noticeID) + { + return null; + } + + public NoticeData[] RetrieveNotices(UUID groupID) + { + return new NoticeData[0]; + } + + public bool DeleteNotice(UUID noticeID) + { + return false; + } + + public void DeleteOldNotices() + { + } + #endregion + + } +} diff --git a/OpenSim/Tests/Common/Mock/TestLandChannel.cs b/OpenSim/Tests/Common/Mock/TestLandChannel.cs index 3d44a33352..cb16f55edd 100644 --- a/OpenSim/Tests/Common/Mock/TestLandChannel.cs +++ b/OpenSim/Tests/Common/Mock/TestLandChannel.cs @@ -42,6 +42,8 @@ namespace OpenSim.Tests.Common private Scene m_scene; private List m_parcels; + public float BanLineSafeHeight { get { return 100f; } } + public TestLandChannel(Scene scene) { m_scene = scene; @@ -96,6 +98,11 @@ namespace OpenSim.Tests.Common return GetNoLand(); } + public ILandObject GetLandObject(UUID ID) + { + return GetNoLand(); + } + public ILandObject GetLandObject(float x, float y) { return GetNoLand(); @@ -104,6 +111,7 @@ namespace OpenSim.Tests.Common public bool IsLandPrimCountTainted() { return false; } public bool IsForcefulBansAllowed() { return false; } public void UpdateLandObject(int localID, LandData data) {} + public void SendParcelsOverlay(IClientAPI client) {} public void ReturnObjectsInParcel(int localID, uint returnType, UUID[] agentIDs, UUID[] taskIDs, IClientAPI remoteClient) {} public void setParcelObjectMaxOverride(overrideParcelMaxPrimCountDelegate overrideDel) {} public void setSimulatorObjectMaxOverride(overrideSimulatorMaxPrimCountDelegate overrideDel) {} diff --git a/OpenSim/Tests/Common/Mock/TestOSHttpResponse.cs b/OpenSim/Tests/Common/Mock/TestOSHttpResponse.cs index 2e17f1ea79..4577ca352f 100644 --- a/OpenSim/Tests/Common/Mock/TestOSHttpResponse.cs +++ b/OpenSim/Tests/Common/Mock/TestOSHttpResponse.cs @@ -117,8 +117,6 @@ namespace OpenSim.Tests.Common /// public string StatusDescription { get; set; } - public bool ReuseContext { get; set; } - /// /// Add a header field and content to the response. /// diff --git a/OpenSim/Tests/Permissions/Common.cs b/OpenSim/Tests/Permissions/Common.cs new file mode 100644 index 0000000000..4ecce383e4 --- /dev/null +++ b/OpenSim/Tests/Permissions/Common.cs @@ -0,0 +1,374 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +using System; +using System.Collections.Generic; +using System.Threading; +using Nini.Config; +using NUnit.Framework; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Region.CoreModules.World.Permissions; +using OpenSim.Region.CoreModules.Avatar.Inventory.Transfer; +using OpenSim.Region.CoreModules.Framework.InventoryAccess; +using OpenSim.Services.Interfaces; +using OpenSim.Tests.Common; +using PermissionMask = OpenSim.Framework.PermissionMask; + +namespace OpenSim.Tests.Permissions +{ + [SetUpFixture] + public class Common : OpenSimTestCase + { + public static Common TheInstance; + + public static TestScene TheScene + { + get { return TheInstance.m_Scene; } + } + + public static ScenePresence[] TheAvatars + { + get { return TheInstance.m_Avatars; } + } + + private static string Perms = "Owner: {0}; Group: {1}; Everyone: {2}; Next: {3}"; + private TestScene m_Scene; + private ScenePresence[] m_Avatars = new ScenePresence[3]; + + [SetUp] + public override void SetUp() + { + if (TheInstance == null) + TheInstance = this; + + base.SetUp(); + TestHelpers.EnableLogging(); + + IConfigSource config = new IniConfigSource(); + config.AddConfig("Messaging"); + config.Configs["Messaging"].Set("InventoryTransferModule", "InventoryTransferModule"); + + config.AddConfig("Modules"); + config.Configs["Modules"].Set("InventoryAccessModule", "BasicInventoryAccessModule"); + + config.AddConfig("InventoryService"); + config.Configs["InventoryService"].Set("LocalServiceModule", "OpenSim.Services.InventoryService.dll:XInventoryService"); + config.Configs["InventoryService"].Set("StorageProvider", "OpenSim.Tests.Common.dll:TestXInventoryDataPlugin"); + + config.AddConfig("Groups"); + config.Configs["Groups"].Set("Enabled", "true"); + config.Configs["Groups"].Set("Module", "Groups Module V2"); + config.Configs["Groups"].Set("StorageProvider", "OpenSim.Tests.Common.dll:TestGroupsDataPlugin"); + config.Configs["Groups"].Set("ServicesConnectorModule", "Groups Local Service Connector"); + config.Configs["Groups"].Set("LocalService", "local"); + + m_Scene = new SceneHelpers().SetupScene("Test", UUID.Random(), 1000, 1000, config); + // Add modules + SceneHelpers.SetupSceneModules(m_Scene, config, new DefaultPermissionsModule(), new InventoryTransferModule(), new BasicInventoryAccessModule()); + + SetUpBasicEnvironment(); + } + + /// + /// The basic environment consists of: + /// - 3 avatars: A1, A2, A3 + /// - 6 simple boxes inworld belonging to A0 and with Next Owner perms: + /// C, CT, MC, MCT, MT, T + /// - Copies of all of these boxes in A0's inventory in the Objects folder + /// - One additional box inworld and in A0's inventory which is a copy of MCT, but + /// with C removed in inventory. This one is called MCT-C + /// + private void SetUpBasicEnvironment() + { + Console.WriteLine("===> SetUpBasicEnvironment <==="); + + // Add 3 avatars + for (int i = 0; i < 3; i++) + { + UUID id = TestHelpers.ParseTail(i + 1); + + m_Avatars[i] = AddScenePresence("Bot", "Bot_" + (i+1), id); + Assert.That(m_Avatars[i], Is.Not.Null); + Assert.That(m_Avatars[i].IsChildAgent, Is.False); + Assert.That(m_Avatars[i].UUID, Is.EqualTo(id)); + Assert.That(m_Scene.GetScenePresences().Count, Is.EqualTo(i + 1)); + } + + AddA1Object("Box C", 10, PermissionMask.Copy); + AddA1Object("Box CT", 11, PermissionMask.Copy | PermissionMask.Transfer); + AddA1Object("Box MC", 12, PermissionMask.Modify | PermissionMask.Copy); + AddA1Object("Box MCT", 13, PermissionMask.Modify | PermissionMask.Copy | PermissionMask.Transfer); + AddA1Object("Box MT", 14, PermissionMask.Modify | PermissionMask.Transfer); + AddA1Object("Box T", 15, PermissionMask.Transfer); + + // MCT-C + AddA1Object("Box MCT-C", 16, PermissionMask.Modify | PermissionMask.Copy | PermissionMask.Transfer); + + Thread.Sleep(5000); + + InventoryFolderBase objsFolder = UserInventoryHelpers.GetInventoryFolder(m_Scene.InventoryService, m_Avatars[0].UUID, "Objects"); + List items = m_Scene.InventoryService.GetFolderItems(m_Avatars[0].UUID, objsFolder.ID); + Assert.That(items.Count, Is.EqualTo(7)); + + RevokePermission(0, "Box MCT-C", PermissionMask.Copy); + } + + private ScenePresence AddScenePresence(string first, string last, UUID id) + { + UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(m_Scene, first, last, id, "pw"); + ScenePresence sp = SceneHelpers.AddScenePresence(m_Scene, id); + Assert.That(m_Scene.AuthenticateHandler.GetAgentCircuitData(id), Is.Not.Null); + + return sp; + } + + private void AddA1Object(string name, int suffix, PermissionMask nextOwnerPerms) + { + // Create a Box. Default permissions are just T + SceneObjectGroup box = AddSceneObject(name, suffix, 1, m_Avatars[0].UUID); + Assert.True((box.RootPart.NextOwnerMask & (int)PermissionMask.Copy) == 0); + Assert.True((box.RootPart.NextOwnerMask & (int)PermissionMask.Modify) == 0); + Assert.True((box.RootPart.NextOwnerMask & (int)PermissionMask.Transfer) != 0); + + // field = 16 is NextOwner + // set = 1 means add the permission; set = 0 means remove permission + + if ((nextOwnerPerms & PermissionMask.Copy) != 0) + m_Scene.HandleObjectPermissionsUpdate((IClientAPI)m_Avatars[0].ClientView, m_Avatars[0].UUID, + ((IClientAPI)(m_Avatars[0].ClientView)).SessionId, 16, box.LocalId, (uint)PermissionMask.Copy, 1); + + if ((nextOwnerPerms & PermissionMask.Modify) != 0) + m_Scene.HandleObjectPermissionsUpdate((IClientAPI)m_Avatars[0].ClientView, m_Avatars[0].UUID, + ((IClientAPI)(m_Avatars[0].ClientView)).SessionId, 16, box.LocalId, (uint)PermissionMask.Modify, 1); + + if ((nextOwnerPerms & PermissionMask.Transfer) == 0) + m_Scene.HandleObjectPermissionsUpdate((IClientAPI)m_Avatars[0].ClientView, m_Avatars[0].UUID, + ((IClientAPI)(m_Avatars[0].ClientView)).SessionId, 16, box.LocalId, (uint)PermissionMask.Transfer, 0); + + PrintPerms(box); + AssertPermissions(nextOwnerPerms, (PermissionMask)box.RootPart.NextOwnerMask, box.OwnerID.ToString().Substring(34) + " : " + box.Name); + + TakeCopyToInventory(0, box); + + } + + public void RevokePermission(int ownerIndex, string name, PermissionMask perm) + { + InventoryItemBase item = Common.TheInstance.GetItemFromInventory(m_Avatars[ownerIndex].UUID, "Objects", name); + Assert.That(item, Is.Not.Null); + + // Clone it, so to avoid aliasing -- just like the viewer does. + InventoryItemBase clone = Common.TheInstance.CloneInventoryItem(item); + // Revoke the permission in this copy + clone.NextPermissions &= ~(uint)perm; + Common.TheInstance.AssertPermissions((PermissionMask)clone.NextPermissions & ~perm, + (PermissionMask)clone.NextPermissions, Common.TheInstance.IdStr(clone)); + Assert.That(clone.ID == item.ID); + + // Update properties of the item in inventory. This should affect the original item above. + Common.TheScene.UpdateInventoryItemAsset(m_Avatars[ownerIndex].ControllingClient, UUID.Zero, clone.ID, clone); + + item = Common.TheInstance.GetItemFromInventory(m_Avatars[ownerIndex].UUID, "Objects", name); + Assert.That(item, Is.Not.Null); + Common.TheInstance.PrintPerms(item); + Common.TheInstance.AssertPermissions((PermissionMask)item.NextPermissions & ~perm, + (PermissionMask)item.NextPermissions, Common.TheInstance.IdStr(item)); + + } + + public void PrintPerms(SceneObjectGroup sog) + { + Console.WriteLine("SOG " + sog.Name + " (" + sog.OwnerID.ToString().Substring(34) + "): " + + String.Format(Perms, (PermissionMask)sog.EffectiveOwnerPerms, + (PermissionMask)sog.EffectiveGroupPerms, (PermissionMask)sog.EffectiveEveryOnePerms, (PermissionMask)sog.RootPart.NextOwnerMask)); + + } + + public void PrintPerms(InventoryItemBase item) + { + Console.WriteLine("Inv " + item.Name + " (" + item.Owner.ToString().Substring(34) + "): " + + String.Format(Perms, (PermissionMask)item.BasePermissions, + (PermissionMask)item.GroupPermissions, (PermissionMask)item.EveryOnePermissions, (PermissionMask)item.NextPermissions)); + + } + + public void AssertPermissions(PermissionMask desired, PermissionMask actual, string message) + { + if ((desired & PermissionMask.Copy) != 0) + Assert.True((actual & PermissionMask.Copy) != 0, message); + else + Assert.True((actual & PermissionMask.Copy) == 0, message); + + if ((desired & PermissionMask.Modify) != 0) + Assert.True((actual & PermissionMask.Modify) != 0, message); + else + Assert.True((actual & PermissionMask.Modify) == 0, message); + + if ((desired & PermissionMask.Transfer) != 0) + Assert.True((actual & PermissionMask.Transfer) != 0, message); + else + Assert.True((actual & PermissionMask.Transfer) == 0, message); + + } + + public SceneObjectGroup AddSceneObject(string name, int suffix, int partsToTestCount, UUID ownerID) + { + SceneObjectGroup so = SceneHelpers.CreateSceneObject(partsToTestCount, ownerID, name, suffix); + so.Name = name; + so.Description = name; + + Assert.That(m_Scene.AddNewSceneObject(so, false), Is.True); + SceneObjectGroup retrievedSo = m_Scene.GetSceneObjectGroup(so.UUID); + + // If the parts have the same UUID then we will consider them as one and the same + Assert.That(retrievedSo.PrimCount, Is.EqualTo(partsToTestCount)); + + return so; + } + + public void TakeCopyToInventory(int userIndex, SceneObjectGroup sog) + { + InventoryFolderBase objsFolder = UserInventoryHelpers.GetInventoryFolder(m_Scene.InventoryService, m_Avatars[userIndex].UUID, "Objects"); + Assert.That(objsFolder, Is.Not.Null); + + List localIds = new List(); localIds.Add(sog.LocalId); + // This is an async operation + m_Scene.DeRezObjects((IClientAPI)m_Avatars[userIndex].ClientView, localIds, m_Avatars[userIndex].UUID, DeRezAction.TakeCopy, objsFolder.ID); + } + + public InventoryItemBase GetItemFromInventory(UUID userID, string folderName, string itemName) + { + InventoryFolderBase objsFolder = UserInventoryHelpers.GetInventoryFolder(m_Scene.InventoryService, userID, folderName); + Assert.That(objsFolder, Is.Not.Null); + List items = m_Scene.InventoryService.GetFolderItems(userID, objsFolder.ID); + InventoryItemBase item = items.Find(i => i.Name == itemName); + Assert.That(item, Is.Not.Null); + + return item; + } + + public InventoryItemBase CloneInventoryItem(InventoryItemBase item) + { + InventoryItemBase clone = new InventoryItemBase(item.ID); + clone.Name = item.Name; + clone.Description = item.Description; + clone.AssetID = item.AssetID; + clone.AssetType = item.AssetType; + clone.BasePermissions = item.BasePermissions; + clone.CreatorId = item.CreatorId; + clone.CurrentPermissions = item.CurrentPermissions; + clone.EveryOnePermissions = item.EveryOnePermissions; + clone.Flags = item.Flags; + clone.Folder = item.Folder; + clone.GroupID = item.GroupID; + clone.GroupOwned = item.GroupOwned; + clone.GroupPermissions = item.GroupPermissions; + clone.InvType = item.InvType; + clone.NextPermissions = item.NextPermissions; + clone.Owner = item.Owner; + + return clone; + } + + public void DeleteObjectsFolders() + { + // Delete everything in A2 and A3's Objects folders, so we can restart + for (int i = 1; i < 3; i++) + { + InventoryFolderBase objsFolder = UserInventoryHelpers.GetInventoryFolder(Common.TheScene.InventoryService, Common.TheAvatars[i].UUID, "Objects"); + Assert.That(objsFolder, Is.Not.Null); + + List items = Common.TheScene.InventoryService.GetFolderItems(Common.TheAvatars[i].UUID, objsFolder.ID); + List ids = new List(); + foreach (InventoryItemBase it in items) + ids.Add(it.ID); + + Common.TheScene.InventoryService.DeleteItems(Common.TheAvatars[i].UUID, ids); + items = Common.TheScene.InventoryService.GetFolderItems(Common.TheAvatars[i].UUID, objsFolder.ID); + Assert.That(items.Count, Is.EqualTo(0), "A" + (i + 1)); + } + + } + + public string IdStr(InventoryItemBase item) + { + return item.Owner.ToString().Substring(34) + " : " + item.Name; + } + + public string IdStr(SceneObjectGroup sog) + { + return sog.OwnerID.ToString().Substring(34) + " : " + sog.Name; + } + + public void GiveInventoryItem(UUID itemId, ScenePresence giverSp, ScenePresence receiverSp) + { + TestClient giverClient = (TestClient)giverSp.ControllingClient; + TestClient receiverClient = (TestClient)receiverSp.ControllingClient; + + UUID initialSessionId = TestHelpers.ParseTail(0x10); + byte[] giveImBinaryBucket = new byte[17]; + byte[] itemIdBytes = itemId.GetBytes(); + Array.Copy(itemIdBytes, 0, giveImBinaryBucket, 1, itemIdBytes.Length); + + GridInstantMessage giveIm + = new GridInstantMessage( + m_Scene, + giverSp.UUID, + giverSp.Name, + receiverSp.UUID, + (byte)InstantMessageDialog.InventoryOffered, + false, + "inventory offered msg", + initialSessionId, + false, + Vector3.Zero, + giveImBinaryBucket, + true); + + giverClient.HandleImprovedInstantMessage(giveIm); + + // These details might not all be correct. + GridInstantMessage acceptIm + = new GridInstantMessage( + m_Scene, + receiverSp.UUID, + receiverSp.Name, + giverSp.UUID, + (byte)InstantMessageDialog.InventoryAccepted, + false, + "inventory accepted msg", + initialSessionId, + false, + Vector3.Zero, + null, + true); + + receiverClient.HandleImprovedInstantMessage(acceptIm); + } + } +} diff --git a/OpenSim/Tests/Permissions/DirectTransferTests.cs b/OpenSim/Tests/Permissions/DirectTransferTests.cs new file mode 100644 index 0000000000..0f251dba43 --- /dev/null +++ b/OpenSim/Tests/Permissions/DirectTransferTests.cs @@ -0,0 +1,153 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using NUnit.Framework; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Tests.Common; +using PermissionMask = OpenSim.Framework.PermissionMask; + +namespace OpenSim.Tests.Permissions +{ + /// + /// Basic scene object tests (create, read and delete but not update). + /// + [TestFixture] + public class DirectTransferTests + { + + [SetUp] + public void SetUp() + { + // In case we're dealing with some older version of nunit + if (Common.TheInstance == null) + { + Common.TheInstance = new Common(); + Common.TheInstance.SetUp(); + } + + Common.TheInstance.DeleteObjectsFolders(); + } + + /// + /// Test giving simple objecta with various combinations of next owner perms. + /// + [Test] + public void TestGiveBox() + { + TestHelpers.InMethod(); + + // C, CT, MC, MCT, MT, T + string[] names = new string[6] { "Box C", "Box CT", "Box MC", "Box MCT", "Box MT", "Box T" }; + PermissionMask[] perms = new PermissionMask[6] { + PermissionMask.Copy, + PermissionMask.Copy | PermissionMask.Transfer, + PermissionMask.Modify | PermissionMask.Copy, + PermissionMask.Modify | PermissionMask.Copy | PermissionMask.Transfer, + PermissionMask.Modify | PermissionMask.Transfer, + PermissionMask.Transfer + }; + + for (int i = 0; i < 6; i++) + TestOneBox(names[i], perms[i]); + } + + private void TestOneBox(string name, PermissionMask mask) + { + InventoryItemBase item = Common.TheInstance.GetItemFromInventory(Common.TheAvatars[0].UUID, "Objects", name); + + Common.TheInstance.GiveInventoryItem(item.ID, Common.TheAvatars[0], Common.TheAvatars[1]); + + item = Common.TheInstance.GetItemFromInventory(Common.TheAvatars[1].UUID, "Objects", name); + + // Check the receiver + Common.TheInstance.PrintPerms(item); + Common.TheInstance.AssertPermissions(mask, (PermissionMask)item.BasePermissions, item.Owner.ToString().Substring(34) + " : " + item.Name); + + int nObjects = Common.TheScene.GetSceneObjectGroups().Count; + // Rez it and check perms in scene too + Common.TheScene.RezObject(Common.TheAvatars[1].ControllingClient, item.ID, UUID.Zero, Vector3.One, Vector3.Zero, UUID.Zero, 0, false, false, false, UUID.Zero); + Assert.That(Common.TheScene.GetSceneObjectGroups().Count, Is.EqualTo(nObjects + 1)); + + SceneObjectGroup box = Common.TheScene.GetSceneObjectGroups().Find(sog => sog.OwnerID == Common.TheAvatars[1].UUID && sog.Name == name); + Common.TheInstance.PrintPerms(box); + Assert.That(box, Is.Not.Null); + + // Check Owner permissions + Common.TheInstance.AssertPermissions(mask, (PermissionMask)box.EffectiveOwnerPerms, box.OwnerID.ToString().Substring(34) + " : " + box.Name); + + // Check Next Owner permissions + Common.TheInstance.AssertPermissions(mask, (PermissionMask)box.RootPart.NextOwnerMask, box.OwnerID.ToString().Substring(34) + " : " + box.Name); + + } + + /// + /// Test giving simple objecta with variour combinations of next owner perms. + /// + [Test] + public void TestDoubleGiveWithChange() + { + TestHelpers.InMethod(); + + string name = "Box MCT-C"; + InventoryItemBase item = Common.TheInstance.GetItemFromInventory(Common.TheAvatars[0].UUID, "Objects", name); + + // Now give the item to A2. We give the original item, not a clone. + // The giving methods are supposed to duplicate it. + Common.TheInstance.GiveInventoryItem(item.ID, Common.TheAvatars[0], Common.TheAvatars[1]); + + item = Common.TheInstance.GetItemFromInventory(Common.TheAvatars[1].UUID, "Objects", name); + + // Check the receiver + Common.TheInstance.PrintPerms(item); + Common.TheInstance.AssertPermissions(PermissionMask.Modify | PermissionMask.Transfer, + (PermissionMask)item.BasePermissions, Common.TheInstance.IdStr(item)); + + // --------------------------- + // Second transfer + //---------------------------- + + // A2 revokes M + Common.TheInstance.RevokePermission(1, name, PermissionMask.Modify); + + item = Common.TheInstance.GetItemFromInventory(Common.TheAvatars[1].UUID, "Objects", name); + + // Now give the item to A3. We give the original item, not a clone. + // The giving methods are supposed to duplicate it. + Common.TheInstance.GiveInventoryItem(item.ID, Common.TheAvatars[1], Common.TheAvatars[2]); + + item = Common.TheInstance.GetItemFromInventory(Common.TheAvatars[2].UUID, "Objects", name); + + // Check the receiver + Common.TheInstance.PrintPerms(item); + Common.TheInstance.AssertPermissions(PermissionMask.Transfer, + (PermissionMask)item.BasePermissions, Common.TheInstance.IdStr(item)); + + } + } +} \ No newline at end of file diff --git a/OpenSim/Tests/Permissions/IndirectTransferTests.cs b/OpenSim/Tests/Permissions/IndirectTransferTests.cs new file mode 100644 index 0000000000..fb96b8b194 --- /dev/null +++ b/OpenSim/Tests/Permissions/IndirectTransferTests.cs @@ -0,0 +1,132 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System.Collections.Generic; +using System.Threading; +using NUnit.Framework; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Tests.Common; +using PermissionMask = OpenSim.Framework.PermissionMask; + +namespace OpenSim.Tests.Permissions +{ + /// + /// Basic scene object tests (create, read and delete but not update). + /// + [TestFixture] + public class IndirectTransferTests + { + + [SetUp] + public void SetUp() + { + // In case we're dealing with some older version of nunit + if (Common.TheInstance == null) + { + Common.TheInstance = new Common(); + Common.TheInstance.SetUp(); + } + Common.TheInstance.DeleteObjectsFolders(); + } + + /// + /// Test giving simple objecta with various combinations of next owner perms. + /// + [Test] + public void SimpleTakeCopy() + { + TestHelpers.InMethod(); + + // The Objects folder of A2 + InventoryFolderBase objsFolder = UserInventoryHelpers.GetInventoryFolder(Common.TheScene.InventoryService, Common.TheAvatars[1].UUID, "Objects"); + + // C, CT, MC, MCT, MT, T + string[] names = new string[6] { "Box C", "Box CT", "Box MC", "Box MCT", "Box MT", "Box T" }; + PermissionMask[] perms = new PermissionMask[6] { + PermissionMask.Copy, + PermissionMask.Copy | PermissionMask.Transfer, + PermissionMask.Modify | PermissionMask.Copy, + PermissionMask.Modify | PermissionMask.Copy | PermissionMask.Transfer, + PermissionMask.Modify | PermissionMask.Transfer, + PermissionMask.Transfer + }; + + // Try A2 takes copies of objects that cannot be copied. + for (int i = 0; i < 6; i++) + TakeOneBox(Common.TheScene.GetSceneObjectGroups(), names[i], perms[i]); + // Ad-hoc. Enough time to let the take work. + Thread.Sleep(5000); + + List items = Common.TheScene.InventoryService.GetFolderItems(Common.TheAvatars[1].UUID, objsFolder.ID); + Assert.That(items.Count, Is.EqualTo(0)); + + // A1 makes the objects copyable + for (int i = 0; i < 6; i++) + MakeCopyable(Common.TheScene.GetSceneObjectGroups(), names[i]); + + // Try A2 takes copies of objects that can be copied. + for (int i = 0; i < 6; i++) + TakeOneBox(Common.TheScene.GetSceneObjectGroups(), names[i], perms[i]); + // Ad-hoc. Enough time to let the take work. + Thread.Sleep(5000); + + items = Common.TheScene.InventoryService.GetFolderItems(Common.TheAvatars[1].UUID, objsFolder.ID); + Assert.That(items.Count, Is.EqualTo(6)); + + for (int i = 0; i < 6; i++) + { + InventoryItemBase item = Common.TheInstance.GetItemFromInventory(Common.TheAvatars[1].UUID, "Objects", names[i]); + Assert.That(item, Is.Not.Null); + Common.TheInstance.AssertPermissions(perms[i], (PermissionMask)item.BasePermissions, Common.TheInstance.IdStr(item)); + } + } + + private void TakeOneBox(List objs, string name, PermissionMask mask) + { + // Find the object inworld + SceneObjectGroup box = objs.Find(sog => sog.Name == name && sog.OwnerID == Common.TheAvatars[0].UUID); + Assert.That(box, Is.Not.Null, name); + + // A2's inventory (index 1) + Common.TheInstance.TakeCopyToInventory(1, box); + } + + private void MakeCopyable(List objs, string name) + { + SceneObjectGroup box = objs.Find(sog => sog.Name == name && sog.OwnerID == Common.TheAvatars[0].UUID); + Assert.That(box, Is.Not.Null, name); + + // field = 8 is Everyone + // set = 1 means add the permission; set = 0 means remove permission + Common.TheScene.HandleObjectPermissionsUpdate((IClientAPI)Common.TheAvatars[0].ClientView, Common.TheAvatars[0].UUID, + Common.TheAvatars[0].ControllingClient.SessionId, 8, box.LocalId, (uint)PermissionMask.Copy, 1); + Common.TheInstance.PrintPerms(box); + } + } +} \ No newline at end of file diff --git a/OpenSim/Tests/Stress/VectorRenderModuleStressTests.cs b/OpenSim/Tests/Stress/VectorRenderModuleStressTests.cs index 5e6a63891a..e9767f3e84 100644 --- a/OpenSim/Tests/Stress/VectorRenderModuleStressTests.cs +++ b/OpenSim/Tests/Stress/VectorRenderModuleStressTests.cs @@ -118,8 +118,7 @@ namespace OpenSim.Tests.Stress so.UUID, m_tests.Vrm.GetContentType(), string.Format("PenColour BLACK; MoveTo 40,220; FontSize 32; Text {0};", text), - "", - 0); + ""); Assert.That(originalTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID)); diff --git a/OpenSim/Tools/pCampBot/BotManager.cs b/OpenSim/Tools/pCampBot/BotManager.cs index 37dc0d9572..60e6ce3a69 100644 --- a/OpenSim/Tools/pCampBot/BotManager.cs +++ b/OpenSim/Tools/pCampBot/BotManager.cs @@ -302,7 +302,7 @@ namespace pCampBot { lock (m_bots) { - string lastName = string.Format("{0}_{1}", m_lastNameStem, i + m_fromBotNumber); + string lastName = string.Format("{0}{1}", m_lastNameStem, i + m_fromBotNumber); CreateBot( this, @@ -958,7 +958,7 @@ namespace pCampBot private string GenerateBotNameFromNumber(int botNumber) { - return string.Format("{0} {1}_{2}", m_firstName, m_lastNameStem, botNumber); + return string.Format("{0} {1}{2}", m_firstName, m_lastNameStem, botNumber); } internal void Grid_GridRegion(object o, GridRegionEventArgs args) diff --git a/Prebuild/ChangeLog b/Prebuild/ChangeLog index bb8e7b09d8..a7d06129a6 100644 --- a/Prebuild/ChangeLog +++ b/Prebuild/ChangeLog @@ -1,3 +1,22 @@ +2017, August Unit Umarov + * add Freak Tech patch for prefer32bit default to false + * fix comand line target override + * fix CSharp target assembly name + +2015, June Fly-Man- + * V2.0.7 (WhiteCore Build) + * Added the VS2012/VS2013 targets so .Net 4.5 can be used for WhiteCore + * Cleaned up the SharpDevelop2 code part + +2015, April rowan Deppeler + * V2.0.6w (WhiteCore build + * No changes to the code as it appears development has now stalled at 1.10 + - Incorporated (Rev's, I think) patches from Aurora to provide for passing the framework + and additional conditionals in the Prebuild.xml spec + - Re-built using Net 4.0 framework to provide for use on unmodified Windows 8 systems (No Net 3.5) + - Included Solution and project files to assist building if required + + 2008-12-09T02:15 D. Moonfire * src/Core/Kernel.cs - Added a /ppi target to get the results of processing but before diff --git a/Prebuild/prebuild.xml b/Prebuild/prebuild.xml index f39175b52c..f0003df01a 100644 --- a/Prebuild/prebuild.xml +++ b/Prebuild/prebuild.xml @@ -1,6 +1,6 @@ - + DEBUG;TRACE @@ -21,7 +21,6 @@ prebuild.xml - prebuild Matthew Holmes (matthew@wildfiregames.com) Dan Moorehead (dan05a@gmail.com) @@ -40,6 +39,8 @@ Rob Loach (http://robloach.net) C.J. Adams-Collier (cjac@colliertech.org) John Hurliman (john.hurliman@intel.com) + WhiteCore build (2015) Rowan Deppeler (greythan@gmail.com) + OpenSimulator build (2017) AJLDuarte The Prebuild project generator @@ -68,7 +69,9 @@ - + + + diff --git a/Prebuild/runprebuild.bat b/Prebuild/runprebuild.bat new file mode 100644 index 0000000000..5cdef31222 --- /dev/null +++ b/Prebuild/runprebuild.bat @@ -0,0 +1,127 @@ + + +rem Prebuild.exe /target VS2010 + +@ECHO OFF + +echo ========================================== +echo ==== WhiteCore Prebuild Configuration ==== +echo ========================================== +echo. +echo If you wish to customize the configuration, re-run with the switch '-p' +echo e.g. runprebuild -p +echo. + +rem ## Default "configuration" choice ((r)elease, (d)ebug) +set configuration=d + +rem ## Default Visual Studio edition +set vstudio=2010 + +rem ## Default Framework +set framework=4_0 + +rem ## Default architecture (86 (for 32bit), 64) +:CheckArch +set bits=AnyCPU +rem if exist "%PROGRAMFILES(X86)%" (set bits=x64) +rem if %bits% == x64 ( +rem echo Found 64bit architecture +rem ) +rem if %bits% == x86 ( +rem echo Found 32 bit architecture +rem ) + +rem ## Determine native framework +:CheckOS +set framework=4_5 +for /f "tokens=4-5 delims=. " %%i in ('ver') do set VERSION=%%i.%%j +if %version% == 10.0 ( + set framework=4_5 + echo Windows 10 +) +if %version% == 6.3 ( + set framework=4_5 + echo Windows 8.1 or Server 2012 R2 +) +if %version% == 6.2 ( + set framework=4_5 + echo Windows 8 or Server 2012 +) +if %version% == 6.1 ( + set framework=4_0 + echo Windows 7 or Server 2008 R2 +) +if %version% == 6.0 ( + set framework=3_5 + echo hmmm... Windows Vista or Server 2008 +) +if %version% == 5.2 ( + set framework=3_5 + echo hmmm... Windows XP x64 or Server 2003 +) +if %version% == 5.1 ( + set framework=3_5 + echo hmmm... Windows XP +) + + +rem ## If not requested, skip the prompting +if "%1" =="" goto final +if %1 == -p goto prompt +if %1 == --prompt goto prompt +goto final + +:prompt +echo I will now ask you four questions regarding your build. +echo However, if you wish to build for: +echo %bits% Architecture +echo .NET %framework% +echo Visual Studio %vstudio% + +echo. +echo Simply tap [ENTER] three times. +echo. +echo Note that you can change these defaults by opening this +echo batch file in a text editor. +echo. + +:bits +set /p bits="Choose your architecture (x86, x64, AnyCPU) [%bits%]: " +if %bits%==86 goto configuration +if %bits%==x86 goto configuration +if %bits%==64 goto configuration +if %bits%==x64 goto configuration +if %bits%==AnyCPU goto configuration +if %bits%==anycpu goto configuration +echo "%bits%" isn't a valid choice! +goto bits + +:configuration +set /p configuration="Choose your configuration ((r)elease or (d)ebug)? [%configuration%]: " +if %configuration%==r goto framework +if %configuration%==d goto framework +if %configuration%==release goto framework +if %configuration%==debug goto framework +echo "%configuration%" isn't a valid choice! +goto configuration + +:framework +set /p framework="Choose your .NET framework (4_0 or 4_5)? [%framework%]: " +if %framework%==4_0 goto final +if %framework%==4_5 goto final +echo "%framework%" isn't a valid choice! +goto framework + +:final +echo. +echo Configuring for %bits% architecture using %framework% .NET framework +echo. +echo. + + +if %framework%==4_5 set %vstudio%=2012 + +echo Calling Prebuild for target %vstudio% with framework %framework%... +Prebuild.exe /target vs%vstudio% /targetframework v%framework% /conditionals ISWIN;NET_%framework% + diff --git a/Prebuild/runprebuild.sh b/Prebuild/runprebuild.sh new file mode 100644 index 0000000000..4e701b739d --- /dev/null +++ b/Prebuild/runprebuild.sh @@ -0,0 +1,3 @@ +#!/bin/sh +#exec mono [PREFIX]/prebuild.exe "$@" +exec mono Prebuild.exe /target VS2010 diff --git a/Prebuild/src/Core/Attributes/DataNodeAttribute.cs b/Prebuild/src/Core/Attributes/DataNodeAttribute.cs index cd3cea41cd..f1938a2e20 100644 --- a/Prebuild/src/Core/Attributes/DataNodeAttribute.cs +++ b/Prebuild/src/Core/Attributes/DataNodeAttribute.cs @@ -5,16 +5,16 @@ Copyright (c) 2004-2005 Matthew Holmes (matthew@wildfiregames.com), Dan Moorehea Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: -* Redistributions of source code must retain the above copyright notice, this list of conditions - and the following disclaimer. -* Redistributions in binary form must reproduce the above copyright notice, this list of conditions - and the following disclaimer in the documentation and/or other materials provided with the - distribution. -* The name of the author may not be used to endorse or promote products derived from this software - without specific prior written permission. +* Redistributions of source code must retain the above copyright notice, this list of conditions + and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions + and the following disclaimer in the documentation and/or other materials provided with the + distribution. +* The name of the author may not be used to endorse or promote products derived from this software + without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, -BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY @@ -28,45 +28,45 @@ using System.Collections.Specialized; namespace Prebuild.Core.Attributes { - /// - /// - /// - [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple=true)] - public sealed class DataNodeAttribute : Attribute - { - #region Fields + /// + /// + /// + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple=true)] + public sealed class DataNodeAttribute : Attribute + { + #region Fields - private string m_Name = "unknown"; + private string m_Name = "unknown"; - #endregion + #endregion - #region Constructors + #region Constructors - /// - /// Initializes a new instance of the class. - /// - /// The name. - public DataNodeAttribute(string name) - { - m_Name = name; - } + /// + /// Initializes a new instance of the class. + /// + /// The name. + public DataNodeAttribute(string name) + { + m_Name = name; + } - #endregion + #endregion - #region Properties + #region Properties - /// - /// Gets the name. - /// - /// The name. - public string Name - { - get - { - return m_Name; - } - } + /// + /// Gets the name. + /// + /// The name. + public string Name + { + get + { + return m_Name; + } + } - #endregion - } + #endregion + } } diff --git a/Prebuild/src/Core/Attributes/OptionNodeAttribute.cs b/Prebuild/src/Core/Attributes/OptionNodeAttribute.cs index 8ef97a10bf..2d6a6a7bfc 100644 --- a/Prebuild/src/Core/Attributes/OptionNodeAttribute.cs +++ b/Prebuild/src/Core/Attributes/OptionNodeAttribute.cs @@ -5,16 +5,16 @@ Copyright (c) 2004-2005 Matthew Holmes (matthew@wildfiregames.com), Dan Moorehea Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: -* Redistributions of source code must retain the above copyright notice, this list of conditions - and the following disclaimer. -* Redistributions in binary form must reproduce the above copyright notice, this list of conditions - and the following disclaimer in the documentation and/or other materials provided with the - distribution. -* The name of the author may not be used to endorse or promote products derived from this software - without specific prior written permission. +* Redistributions of source code must retain the above copyright notice, this list of conditions + and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions + and the following disclaimer in the documentation and/or other materials provided with the + distribution. +* The name of the author may not be used to endorse or promote products derived from this software + without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, -BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY @@ -27,45 +27,45 @@ using System; namespace Prebuild.Core.Attributes { - /// - /// - /// - [AttributeUsage(AttributeTargets.Field)] - public sealed class OptionNodeAttribute : Attribute - { - #region Fields + /// + /// + /// + [AttributeUsage(AttributeTargets.Field)] + public sealed class OptionNodeAttribute : Attribute + { + #region Fields - private string m_NodeName; + private string m_NodeName; - #endregion + #endregion - #region Constructors + #region Constructors - /// - /// Initializes a new instance of the class. - /// - /// Name of the node. - public OptionNodeAttribute(string nodeName) - { - m_NodeName = nodeName; - } + /// + /// Initializes a new instance of the class. + /// + /// Name of the node. + public OptionNodeAttribute(string nodeName) + { + m_NodeName = nodeName; + } - #endregion + #endregion - #region Properties + #region Properties - /// - /// Gets the name of the node. - /// - /// The name of the node. - public string NodeName - { - get - { - return m_NodeName; - } - } + /// + /// Gets the name of the node. + /// + /// The name of the node. + public string NodeName + { + get + { + return m_NodeName; + } + } - #endregion - } + #endregion + } } diff --git a/Prebuild/src/Core/Attributes/TargetAttribute.cs b/Prebuild/src/Core/Attributes/TargetAttribute.cs index fb309147b8..5ad62ee033 100644 --- a/Prebuild/src/Core/Attributes/TargetAttribute.cs +++ b/Prebuild/src/Core/Attributes/TargetAttribute.cs @@ -5,16 +5,16 @@ Copyright (c) 2004-2005 Matthew Holmes (matthew@wildfiregames.com), Dan Moorehea Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: -* Redistributions of source code must retain the above copyright notice, this list of conditions - and the following disclaimer. -* Redistributions in binary form must reproduce the above copyright notice, this list of conditions - and the following disclaimer in the documentation and/or other materials provided with the - distribution. -* The name of the author may not be used to endorse or promote products derived from this software - without specific prior written permission. +* Redistributions of source code must retain the above copyright notice, this list of conditions + and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions + and the following disclaimer in the documentation and/or other materials provided with the + distribution. +* The name of the author may not be used to endorse or promote products derived from this software + without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, -BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY @@ -27,45 +27,45 @@ using System; namespace Prebuild.Core.Attributes { - /// - /// - /// - [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct)] - public sealed class TargetAttribute : Attribute - { - #region Fields + /// + /// + /// + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct)] + public sealed class TargetAttribute : Attribute + { + #region Fields - private string m_Name; + private string m_Name; - #endregion + #endregion - #region Constructors + #region Constructors - /// - /// Initializes a new instance of the class. - /// - /// The name. - public TargetAttribute(string name) - { - m_Name = name; - } + /// + /// Initializes a new instance of the class. + /// + /// The name. + public TargetAttribute(string name) + { + m_Name = name; + } - #endregion + #endregion - #region Properties + #region Properties - /// - /// Gets the name. - /// - /// The name. - public string Name - { - get - { - return m_Name; - } - } + /// + /// Gets the name. + /// + /// The name. + public string Name + { + get + { + return m_Name; + } + } - #endregion - } + #endregion + } } diff --git a/Prebuild/src/Core/FatalException.cs b/Prebuild/src/Core/FatalException.cs index 751297a907..348790568f 100644 --- a/Prebuild/src/Core/FatalException.cs +++ b/Prebuild/src/Core/FatalException.cs @@ -5,16 +5,16 @@ Copyright (c) 2004-2005 Matthew Holmes (matthew@wildfiregames.com), Dan Moorehea Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: -* Redistributions of source code must retain the above copyright notice, this list of conditions - and the following disclaimer. -* Redistributions in binary form must reproduce the above copyright notice, this list of conditions - and the following disclaimer in the documentation and/or other materials provided with the - distribution. -* The name of the author may not be used to endorse or promote products derived from this software - without specific prior written permission. +* Redistributions of source code must retain the above copyright notice, this list of conditions + and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions + and the following disclaimer in the documentation and/or other materials provided with the + distribution. +* The name of the author may not be used to endorse or promote products derived from this software + without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, -BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY @@ -28,58 +28,58 @@ using System.Runtime.Serialization; namespace Prebuild.Core { - /// - /// - /// - [Serializable()] - public class FatalException : Exception - { - #region Constructors + /// + /// + /// + [Serializable()] + public class FatalException : Exception + { + #region Constructors + + /// + /// Initializes a new instance of the class. + /// + public FatalException() + { + } - /// - /// Initializes a new instance of the class. - /// - public FatalException() - { - } + /// + /// Initializes a new instance of the class. + /// + /// The format. + /// The args. + public FatalException(string format, params object[] args) + : base(String.Format(format, args)) + { + } - /// - /// Initializes a new instance of the class. - /// - /// The format. - /// The args. - public FatalException(string format, params object[] args) - : base(String.Format(format, args)) - { - } + /// + /// Exception with specified string + /// + /// Exception message + public FatalException(string message): base(message) + { + } - /// - /// Exception with specified string - /// - /// Exception message - public FatalException(string message): base(message) - { - } + /// + /// + /// + /// + /// + public FatalException(string message, Exception exception) : base(message, exception) + { + } - /// - /// - /// - /// - /// - public FatalException(string message, Exception exception) : base(message, exception) - { - } + /// + /// + /// + /// + /// + protected FatalException(SerializationInfo info, StreamingContext context) : base( info, context ) + { + } - /// - /// - /// - /// - /// - protected FatalException(SerializationInfo info, StreamingContext context) : base( info, context ) - { - } - - #endregion - } + #endregion + } } diff --git a/Prebuild/src/Core/Interfaces/IDataNode.cs b/Prebuild/src/Core/Interfaces/IDataNode.cs index 4917b180f5..986dd2de8c 100644 --- a/Prebuild/src/Core/Interfaces/IDataNode.cs +++ b/Prebuild/src/Core/Interfaces/IDataNode.cs @@ -5,16 +5,16 @@ Copyright (c) 2004-2005 Matthew Holmes (matthew@wildfiregames.com), Dan Moorehea Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: -* Redistributions of source code must retain the above copyright notice, this list of conditions - and the following disclaimer. -* Redistributions in binary form must reproduce the above copyright notice, this list of conditions - and the following disclaimer in the documentation and/or other materials provided with the - distribution. -* The name of the author may not be used to endorse or promote products derived from this software - without specific prior written permission. +* Redistributions of source code must retain the above copyright notice, this list of conditions + and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions + and the following disclaimer in the documentation and/or other materials provided with the + distribution. +* The name of the author may not be used to endorse or promote products derived from this software + without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, -BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY @@ -26,22 +26,22 @@ IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY O using System; using System.Xml; -namespace Prebuild.Core.Interfaces +namespace Prebuild.Core.Interfaces { - /// - /// - /// - public interface IDataNode - { - /// - /// Gets or sets the parent. - /// - /// The parent. - IDataNode Parent { get; set; } - /// - /// Parses the specified node. - /// - /// The node. - void Parse(XmlNode node); - } + /// + /// + /// + public interface IDataNode + { + /// + /// Gets or sets the parent. + /// + /// The parent. + IDataNode Parent { get; set; } + /// + /// Parses the specified node. + /// + /// The node. + void Parse(XmlNode node); + } } diff --git a/Prebuild/src/Core/Interfaces/ITarget.cs b/Prebuild/src/Core/Interfaces/ITarget.cs index e4c3ea40a4..47115c658b 100644 --- a/Prebuild/src/Core/Interfaces/ITarget.cs +++ b/Prebuild/src/Core/Interfaces/ITarget.cs @@ -5,16 +5,16 @@ Copyright (c) 2004-2005 Matthew Holmes (matthew@wildfiregames.com), Dan Moorehea Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: -* Redistributions of source code must retain the above copyright notice, this list of conditions - and the following disclaimer. -* Redistributions in binary form must reproduce the above copyright notice, this list of conditions - and the following disclaimer in the documentation and/or other materials provided with the - distribution. -* The name of the author may not be used to endorse or promote products derived from this software - without specific prior written permission. +* Redistributions of source code must retain the above copyright notice, this list of conditions + and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions + and the following disclaimer in the documentation and/or other materials provided with the + distribution. +* The name of the author may not be used to endorse or promote products derived from this software + without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, -BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY @@ -25,27 +25,27 @@ IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY O using System; -namespace Prebuild.Core.Interfaces +namespace Prebuild.Core.Interfaces { - /// - /// - /// - public interface ITarget - { - /// - /// Writes the specified kern. - /// - /// The kern. - void Write(Kernel kern); - /// - /// Cleans the specified kern. - /// - /// The kern. - void Clean(Kernel kern); - /// - /// Gets the name. - /// - /// The name. - string Name { get; } - } + /// + /// + /// + public interface ITarget + { + /// + /// Writes the specified kern. + /// + /// The kern. + void Write(Kernel kern); + /// + /// Cleans the specified kern. + /// + /// The kern. + void Clean(Kernel kern); + /// + /// Gets the name. + /// + /// The name. + string Name { get; } + } } \ No newline at end of file diff --git a/Prebuild/src/Core/Kernel.cs b/Prebuild/src/Core/Kernel.cs index 454ff8b0a7..3db92efb88 100644 --- a/Prebuild/src/Core/Kernel.cs +++ b/Prebuild/src/Core/Kernel.cs @@ -49,202 +49,206 @@ using Prebuild.Core.Interfaces; using Prebuild.Core.Nodes; using Prebuild.Core.Utilities; -namespace Prebuild.Core +namespace Prebuild.Core { - /// - /// - /// - public class Kernel : IDisposable - { - #region Inner Classes + /// + /// + /// + public class Kernel : IDisposable + { + #region Inner Classes - private struct NodeEntry - { - public Type Type; - public DataNodeAttribute Attribute; - } + private struct NodeEntry + { + public Type Type; + public DataNodeAttribute Attribute; + } - #endregion + #endregion - #region Fields + #region Fields - private static readonly Kernel m_Instance = new Kernel(); + private static readonly Kernel m_Instance = new Kernel(); - /// - /// This must match the version of the schema that is embeeded - /// - private const string m_SchemaVersion = "1.10"; - private const string m_Schema = "prebuild-" + m_SchemaVersion + ".xsd"; - private const string m_SchemaURI = "http://dnpb.sourceforge.net/schemas/" + m_Schema; - bool disposed; - private Version m_Version; - private const string m_Revision = ""; - private CommandLineCollection m_CommandLine; - private Log m_Log; - private CurrentDirectory m_CurrentWorkingDirectory; - private XmlSchemaCollection m_Schemas; + /// + /// This must match the version of the schema that is embeeded + /// + private const string m_SchemaVersion = "1.10"; + private const string m_Schema = "prebuild-" + m_SchemaVersion + ".xsd"; + private const string m_SchemaURI = "http://dnpb.sourceforge.net/schemas/" + m_Schema; + bool disposed; + private Version m_Version; + private const string m_Revision = "w"; + private CommandLineCollection m_CommandLine; + private Log m_Log; + private CurrentDirectory m_CurrentWorkingDirectory; + private XmlSchemaCollection m_Schemas; private readonly Dictionary m_Targets = new Dictionary(); private readonly Dictionary m_Nodes = new Dictionary(); - readonly List m_Solutions = new List(); + readonly List m_Solutions = new List(); string m_Target; - string m_Clean; - string[] m_RemoveDirectories; - XmlDocument m_CurrentDoc; - bool m_PauseAfterFinish; - string[] m_ProjectGroups; + bool cmdlineTargetFramework; + FrameworkVersion m_TargetFramework; //Overrides all project settings + string m_Conditionals; //Adds to all project settings + public string ForcedConditionals { get { return m_Conditionals; } } + string m_Clean; + string[] m_RemoveDirectories; + XmlDocument m_CurrentDoc; + bool m_PauseAfterFinish; + string[] m_ProjectGroups; - #endregion + #endregion - #region Constructors + #region Constructors - private Kernel() - { - } + private Kernel() + { + } - #endregion + #endregion - #region Properties + #region Properties - /// - /// Gets a value indicating whether [pause after finish]. - /// - /// true if [pause after finish]; otherwise, false. - public bool PauseAfterFinish - { - get - { - return m_PauseAfterFinish; - } - } + /// + /// Gets a value indicating whether [pause after finish]. + /// + /// true if [pause after finish]; otherwise, false. + public bool PauseAfterFinish + { + get + { + return m_PauseAfterFinish; + } + } - /// - /// Gets the instance. - /// - /// The instance. - public static Kernel Instance - { - get - { - return m_Instance; - } - } + /// + /// Gets the instance. + /// + /// The instance. + public static Kernel Instance + { + get + { + return m_Instance; + } + } - /// - /// Gets the version. - /// - /// The version. - public string Version - { - get - { - return String.Format("{0}.{1}.{2}{3}", m_Version.Major, m_Version.Minor, m_Version.Build, m_Revision); - } - } + /// + /// Gets the version. + /// + /// The version. + public string Version + { + get + { + return String.Format("{0}.{1}.{2}{3}", m_Version.Major, m_Version.Minor, m_Version.Build, m_Revision); + } + } - /// - /// Gets the command line. - /// - /// The command line. - public CommandLineCollection CommandLine - { - get - { - return m_CommandLine; - } - } + /// + /// Gets the command line. + /// + /// The command line. + public CommandLineCollection CommandLine + { + get + { + return m_CommandLine; + } + } - /// - /// Gets the targets. - /// - /// The targets. - public Dictionary Targets - { - get - { - return m_Targets; - } - } + /// + /// Gets the targets. + /// + /// The targets. + public Dictionary Targets + { + get + { + return m_Targets; + } + } - /// - /// Gets the log. - /// - /// The log. - public Log Log - { - get - { - return m_Log; - } - } + /// + /// Gets the log. + /// + /// The log. + public Log Log + { + get + { + return m_Log; + } + } - /// - /// Gets the current working directory. - /// - /// The current working directory. - public CurrentDirectory CurrentWorkingDirectory - { - get - { - return m_CurrentWorkingDirectory; - } - } + /// + /// Gets the current working directory. + /// + /// The current working directory. + public CurrentDirectory CurrentWorkingDirectory + { + get + { + return m_CurrentWorkingDirectory; + } + } - /// - /// Gets the solutions. - /// - /// The solutions. - public List Solutions - { - get - { - return m_Solutions; - } - } + /// + /// Gets the solutions. + /// + /// The solutions. + public List Solutions + { + get + { + return m_Solutions; + } + } + + /// + /// Gets the XmlDocument object representing the prebuild.xml + /// being processed + /// + /// The XmlDocument object + public XmlDocument CurrentDoc + { + get + { + return m_CurrentDoc; + } + } - /// - /// Gets the XmlDocument object representing the prebuild.xml - /// being processed - /// - /// The XmlDocument object - public XmlDocument CurrentDoc - { - get - { - return m_CurrentDoc; - } - } + #endregion - #endregion + #region Private Methods - #region Private Methods + private static void RemoveDirectories(string rootDir, string[] dirNames) + { + foreach(string dir in Directory.GetDirectories(rootDir)) + { + string simpleName = Path.GetFileName(dir); - private static void RemoveDirectories(string rootDir, string[] dirNames) - { - foreach(string dir in Directory.GetDirectories(rootDir)) - { - string simpleName = Path.GetFileName(dir); + if(Array.IndexOf(dirNames, simpleName) != -1) + { + //delete if the name matches one of the directory names to delete + string fullDirPath = Path.GetFullPath(dir); + Directory.Delete(fullDirPath,true); + } + else//not a match, so check children + { + RemoveDirectories(dir,dirNames); + //recurse, checking children for them + } + } + } - if(Array.IndexOf(dirNames, simpleName) != -1) - { - //delete if the name matches one of the directory names to delete - string fullDirPath = Path.GetFullPath(dir); - Directory.Delete(fullDirPath,true); - } - else//not a match, so check children - { - RemoveDirectories(dir,dirNames); - //recurse, checking children for them - } - } - } - -// private void RemoveDirectoryMatches(string rootDir, string dirPattern) +// private void RemoveDirectoryMatches(string rootDir, string dirPattern) // { -// foreach(string dir in Directory.GetDirectories(rootDir)) +// foreach(string dir in Directory.GetDirectories(rootDir)) // { -// foreach(string match in Directory.GetDirectories(dir)) +// foreach(string match in Directory.GetDirectories(dir)) // {//delete all child directories that match // Directory.Delete(Path.GetFullPath(match),true); // } @@ -253,56 +257,56 @@ namespace Prebuild.Core // } // } - private void LoadSchema() - { - Assembly assembly = GetType().Assembly; - Stream stream = assembly.GetManifestResourceStream("Prebuild.data." + m_Schema); - if(stream == null) - { - //try without the default namespace prepending to it in case was compiled with SharpDevelop or MonoDevelop instead of Visual Studio .NET - stream = assembly.GetManifestResourceStream(m_Schema); - if(stream == null) - { - throw new System.Reflection.TargetException(string.Format("Could not find the scheme embedded resource file '{0}'.", m_Schema)); - } - } - XmlReader schema = new XmlTextReader(stream); + private void LoadSchema() + { + Assembly assembly = GetType().Assembly; + Stream stream = assembly.GetManifestResourceStream("Prebuild.data." + m_Schema); + if(stream == null) + { + //try without the default namespace prepending to it in case was compiled with SharpDevelop or MonoDevelop instead of Visual Studio .NET + stream = assembly.GetManifestResourceStream(m_Schema); + if(stream == null) + { + throw new System.Reflection.TargetException(string.Format("Could not find the scheme embedded resource file '{0}'.", m_Schema)); + } + } + XmlReader schema = new XmlTextReader(stream); + + m_Schemas = new XmlSchemaCollection(); + m_Schemas.Add(m_SchemaURI, schema); + } - m_Schemas = new XmlSchemaCollection(); - m_Schemas.Add(m_SchemaURI, schema); - } + private void CacheVersion() + { + m_Version = Assembly.GetEntryAssembly().GetName().Version; + } - private void CacheVersion() - { - m_Version = Assembly.GetEntryAssembly().GetName().Version; - } + private void CacheTargets(Assembly assm) + { + foreach(Type t in assm.GetTypes()) + { + TargetAttribute ta = (TargetAttribute)Helper.CheckType(t, typeof(TargetAttribute), typeof(ITarget)); - private void CacheTargets(Assembly assm) - { - foreach(Type t in assm.GetTypes()) - { - TargetAttribute ta = (TargetAttribute)Helper.CheckType(t, typeof(TargetAttribute), typeof(ITarget)); + if(ta == null) + continue; + + if (t.IsAbstract) + continue; + + ITarget target = (ITarget)assm.CreateInstance(t.FullName); + if (target == null) + { + throw new MissingMethodException("Could not create ITarget instance"); + } - if(ta == null) - continue; + m_Targets[ta.Name] = target; + } + } - if (t.IsAbstract) - continue; - - ITarget target = (ITarget)assm.CreateInstance(t.FullName); - if (target == null) - { - throw new MissingMethodException("Could not create ITarget instance"); - } - - m_Targets[ta.Name] = target; - } - } - - private void CacheNodeTypes(Assembly assm) - { - foreach(Type t in assm.GetTypes()) - { + private void CacheNodeTypes(Assembly assm) + { + foreach(Type t in assm.GetTypes()) + { foreach (DataNodeAttribute dna in t.GetCustomAttributes(typeof(DataNodeAttribute), true)) { NodeEntry ne = new NodeEntry(); @@ -310,11 +314,11 @@ namespace Prebuild.Core ne.Attribute = dna; m_Nodes[dna.Name] = ne; } - } - } + } + } - private void LogBanner() - { + private void LogBanner() + { m_Log.Write("Prebuild v" + Version); m_Log.Write("Copyright (c) 2004-2010"); m_Log.Write("Matthew Holmes (matthew@wildfiregames.com),"); @@ -323,10 +327,12 @@ namespace Prebuild.Core m_Log.Write("Rob Loach (http://www.robloach.net),"); m_Log.Write("C.J. Adams-Collier (cjac@colliertech.org),"); m_Log.Write("John Hurliman (john.hurliman@intel.com),"); - + m_Log.Write("WhiteCore build 2015 (greythane@gmail.com),"); + m_Log.Write("OpenSimulator build 2017 Ubit Umarov,"); + m_Log.Write (""); m_Log.Write("See 'prebuild /usage' for help"); m_Log.Write(); - } + } @@ -348,37 +354,37 @@ namespace Prebuild.Core } /// - /// + /// /// /// /// /// - public void ProcessFile(string file, IList solutions) - { - m_CurrentWorkingDirectory.Push(); + public void ProcessFile(string file, IList solutions) + { + m_CurrentWorkingDirectory.Push(); + + string path = file; + try + { + try + { + path = Helper.ResolvePath(path); + } + catch(ArgumentException) + { + m_Log.Write("Could not open Prebuild file: " + path); + m_CurrentWorkingDirectory.Pop(); + return; + } - string path = file; - try - { - try - { - path = Helper.ResolvePath(path); - } - catch(ArgumentException) - { - m_Log.Write("Could not open Prebuild file: " + path); - m_CurrentWorkingDirectory.Pop(); - return; - } - - Helper.SetCurrentDir(Path.GetDirectoryName(path)); - - XmlTextReader reader = new XmlTextReader(path); + Helper.SetCurrentDir(Path.GetDirectoryName(path)); + + XmlTextReader reader = new XmlTextReader(path); Core.Parse.Preprocessor pre = new Core.Parse.Preprocessor(); //register command line arguments as XML variables - IEnumerator> dict = m_CommandLine.GetEnumerator(); + IEnumerator> dict = m_CommandLine.GetEnumerator(); while (dict.MoveNext()) { string name = dict.Current.Key.Trim(); @@ -386,447 +392,457 @@ namespace Prebuild.Core pre.RegisterVariable(name, dict.Current.Value); } - string xml = pre.Process(reader);//remove script and evaulate pre-proccessing to get schema-conforming XML + string xml = pre.Process(reader);//remove script and evaulate pre-proccessing to get schema-conforming XML - // See if the user put into a pseudo target of "prebuild:preprocessed-input" to indicate they want to see the - // output before the system processes it. - if (m_CommandLine.WasPassed("ppi")) - { - // Get the filename if there is one, otherwise use a default. - string ppiFile = m_CommandLine["ppi"]; - if (ppiFile == null || ppiFile.Trim().Length == 0) - { - ppiFile = "preprocessed-input.xml"; - } + // See if the user put into a pseudo target of "prebuild:preprocessed-input" to indicate they want to see the + // output before the system processes it. + if (m_CommandLine.WasPassed("ppi")) + { + // Get the filename if there is one, otherwise use a default. + string ppiFile = m_CommandLine["ppi"]; + if (ppiFile == null || ppiFile.Trim().Length == 0) + { + ppiFile = "preprocessed-input.xml"; + } - // Write out the string to the given stream. - try - { - using (StreamWriter ppiWriter = new StreamWriter(ppiFile)) - { - ppiWriter.WriteLine(xml); - } - } - catch(IOException ex) - { - Console.WriteLine("Could not write PPI file '{0}': {1}", ppiFile, ex.Message); - } + // Write out the string to the given stream. + try + { + using (StreamWriter ppiWriter = new StreamWriter(ppiFile)) + { + ppiWriter.WriteLine(xml); + } + } + catch(IOException ex) + { + Console.WriteLine("Could not write PPI file '{0}': {1}", ppiFile, ex.Message); + } - // Finish processing this special tag. - return; - } - - m_CurrentDoc = new XmlDocument(); - try - { + // Finish processing this special tag. + return; + } + + m_CurrentDoc = new XmlDocument(); + try + { #if NO_VALIDATE - XmlReader validator = XmlReader.Create(new StringReader(xml)); - m_CurrentDoc.Load(validator); + XmlReader validator = XmlReader.Create(new StringReader(xml)); + m_CurrentDoc.Load(validator); #else - XmlValidatingReader validator = new XmlValidatingReader(new XmlTextReader(new StringReader(xml))); + XmlValidatingReader validator = new XmlValidatingReader(new XmlTextReader(new StringReader(xml))); - //validate while reading from string into XmlDocument DOM structure in memory - foreach(XmlSchema schema in m_Schemas) - { - validator.Schemas.Add(schema); - } - m_CurrentDoc.Load(validator); + //validate while reading from string into XmlDocument DOM structure in memory + foreach(XmlSchema schema in m_Schemas) + { + validator.Schemas.Add(schema); + } + m_CurrentDoc.Load(validator); #endif - } - catch(XmlException e) + } + catch(XmlException e) + { + throw new XmlException(e.ToString()); + } + + //is there a purpose to writing it? An syntax/schema problem would have been found during pre.Process() and reported with details + if(m_CommandLine.WasPassed("ppo")) + { + string ppoFile = m_CommandLine["ppo"]; + if(ppoFile == null || ppoFile.Trim().Length < 1) + { + ppoFile = "preprocessed.xml"; + } + + StreamWriter writer = null; + try + { + writer = new StreamWriter(ppoFile); + writer.Write(xml); + } + catch(IOException ex) + { + Console.WriteLine("Could not write PPO file '{0}': {1}", ppoFile, ex.Message); + } + finally + { + if(writer != null) + { + writer.Close(); + } + } + return; + } + //start reading the xml config file + XmlElement rootNode = m_CurrentDoc.DocumentElement; + //string suggestedVersion = Helper.AttributeValue(rootNode,"version","1.0"); + Helper.CheckForOSVariables = Helper.ParseBoolean(rootNode,"checkOsVars",false); + + foreach(XmlNode node in rootNode.ChildNodes)//solutions or if pre-proc instructions + { + IDataNode dataNode = ParseNode(node, null); + if(dataNode is ProcessNode) + { + ProcessNode proc = (ProcessNode)dataNode; + if(proc.IsValid) + { + ProcessFile(proc.Path); + } + } + else if(dataNode is SolutionNode) + { + solutions.Add((SolutionNode)dataNode); + } + } + } + catch(XmlSchemaException xse) + { + m_Log.Write("XML validation error at line {0} in {1}:\n\n{2}", + xse.LineNumber, path, xse.Message); + } + finally + { + m_CurrentWorkingDirectory.Pop(); + } + } + + #endregion + + #region Public Methods + + /// + /// Allows the project. + /// + /// The project groups flags. + /// + public bool AllowProject(string projectGroupsFlags) + { + if(m_ProjectGroups != null && m_ProjectGroups.Length > 0) + { + if(projectGroupsFlags != null && projectGroupsFlags.Length == 0) + { + foreach(string group in projectGroupsFlags.Split('|')) + { + if(Array.IndexOf(m_ProjectGroups, group) != -1) //if included in the filter list + { + return true; + } + } + } + return false;//not included in the list or no groups specified for the project + } + return true;//no filter specified in the command line args + } + + /// + /// Gets the type of the node. + /// + /// The node. + /// + public Type GetNodeType(XmlNode node) + { + if( node == null ) + { + throw new ArgumentNullException("node"); + } + if(!m_Nodes.ContainsKey(node.Name)) + { + return null; + } + + NodeEntry ne = m_Nodes[node.Name]; + return ne.Type; + } + + /// + /// + /// + /// + /// + /// + public IDataNode ParseNode(XmlNode node, IDataNode parent) + { + return ParseNode(node, parent, null); + } + + //Create an instance of the data node type that is mapped to the name of the xml DOM node + /// + /// Parses the node. + /// + /// The node. + /// The parent. + /// The pre node. + /// + public IDataNode ParseNode(XmlNode node, IDataNode parent, IDataNode preNode) + { + IDataNode dataNode; + + try + { + if( node == null ) + { + throw new ArgumentNullException("node"); + } + if(preNode == null) + { + if(!m_Nodes.ContainsKey(node.Name)) + { + Console.WriteLine("WARNING: Unknown XML node: " + node.Name); + return null; + } + + NodeEntry ne = m_Nodes[node.Name]; + Type type = ne.Type; + //DataNodeAttribute dna = ne.Attribute; + + dataNode = (IDataNode)type.Assembly.CreateInstance(type.FullName); + if(dataNode == null) + { + throw new System.Reflection.TargetException("Could not create new parser instance: " + type.FullName); + } + } + else + dataNode = preNode; + + dataNode.Parent = parent; + if (cmdlineTargetFramework && dataNode is ProjectNode) { - throw new XmlException(e.ToString()); + ((ProjectNode)dataNode).FrameworkVersion = m_TargetFramework; } + dataNode.Parse(node); + } + catch(WarningException wex) + { + m_Log.Write(LogType.Warning, wex.Message); + return null; + } + catch(FatalException fex) + { + m_Log.WriteException(LogType.Error, fex); + throw; + } + catch(Exception ex) + { + m_Log.WriteException(LogType.Error, ex); + throw; + } - //is there a purpose to writing it? An syntax/schema problem would have been found during pre.Process() and reported with details - if(m_CommandLine.WasPassed("ppo")) - { - string ppoFile = m_CommandLine["ppo"]; - if(ppoFile == null || ppoFile.Trim().Length < 1) - { - ppoFile = "preprocessed.xml"; - } + return dataNode; + } - StreamWriter writer = null; - try - { - writer = new StreamWriter(ppoFile); - writer.Write(xml); - } - catch(IOException ex) - { - Console.WriteLine("Could not write PPO file '{0}': {1}", ppoFile, ex.Message); - } - finally - { - if(writer != null) - { - writer.Close(); - } - } - return; - } - //start reading the xml config file - XmlElement rootNode = m_CurrentDoc.DocumentElement; - //string suggestedVersion = Helper.AttributeValue(rootNode,"version","1.0"); - Helper.CheckForOSVariables = Helper.ParseBoolean(rootNode,"checkOsVars",false); + /// + /// Initializes the specified target. + /// + /// The target. + /// The args. + public void Initialize(LogTargets target, string[] args) + { + CacheTargets(GetType().Assembly); + CacheNodeTypes(GetType().Assembly); + CacheVersion(); - foreach(XmlNode node in rootNode.ChildNodes)//solutions or if pre-proc instructions - { - IDataNode dataNode = ParseNode(node, null); - if(dataNode is ProcessNode) - { - ProcessNode proc = (ProcessNode)dataNode; - if(proc.IsValid) - { - ProcessFile(proc.Path); - } - } - else if(dataNode is SolutionNode) - { - solutions.Add((SolutionNode)dataNode); - } - } - } - catch(XmlSchemaException xse) - { - m_Log.Write("XML validation error at line {0} in {1}:\n\n{2}", - xse.LineNumber, path, xse.Message); - } - finally - { - m_CurrentWorkingDirectory.Pop(); - } - } + m_CommandLine = new CommandLineCollection(args); + + string logFile = null; + if(m_CommandLine.WasPassed("log")) + { + logFile = m_CommandLine["log"]; - #endregion + if(logFile != null && logFile.Length == 0) + { + logFile = "Prebuild.log"; + } + } + else + { + target = target & ~LogTargets.File; //dont output to a file + } + + m_Log = new Log(target, logFile); + LogBanner(); - #region Public Methods - - /// - /// Allows the project. - /// - /// The project groups flags. - /// - public bool AllowProject(string projectGroupsFlags) - { - if(m_ProjectGroups != null && m_ProjectGroups.Length > 0) - { - if(projectGroupsFlags != null && projectGroupsFlags.Length == 0) - { - foreach(string group in projectGroupsFlags.Split('|')) - { - if(Array.IndexOf(m_ProjectGroups, group) != -1) //if included in the filter list - { - return true; - } - } - } - return false;//not included in the list or no groups specified for the project - } - return true;//no filter specified in the command line args - } - - /// - /// Gets the type of the node. - /// - /// The node. - /// - public Type GetNodeType(XmlNode node) - { - if( node == null ) - { - throw new ArgumentNullException("node"); - } - if(!m_Nodes.ContainsKey(node.Name)) - { - return null; - } - - NodeEntry ne = m_Nodes[node.Name]; - return ne.Type; - } - - /// - /// - /// - /// - /// - /// - public IDataNode ParseNode(XmlNode node, IDataNode parent) - { - return ParseNode(node, parent, null); - } - - //Create an instance of the data node type that is mapped to the name of the xml DOM node - /// - /// Parses the node. - /// - /// The node. - /// The parent. - /// The pre node. - /// - public IDataNode ParseNode(XmlNode node, IDataNode parent, IDataNode preNode) - { - IDataNode dataNode; - - try - { - if( node == null ) - { - throw new ArgumentNullException("node"); - } - if(preNode == null) - { - if(!m_Nodes.ContainsKey(node.Name)) - { - Console.WriteLine("WARNING: Unknown XML node: " + node.Name); - return null; - } - - NodeEntry ne = m_Nodes[node.Name]; - Type type = ne.Type; - //DataNodeAttribute dna = ne.Attribute; - - dataNode = (IDataNode)type.Assembly.CreateInstance(type.FullName); - if(dataNode == null) - { - throw new System.Reflection.TargetException("Could not create new parser instance: " + type.FullName); - } - } - else - dataNode = preNode; - - dataNode.Parent = parent; - dataNode.Parse(node); - } - catch(WarningException wex) - { - m_Log.Write(LogType.Warning, wex.Message); - return null; - } - catch(FatalException fex) - { - m_Log.WriteException(LogType.Error, fex); - throw; - } - catch(Exception ex) - { - m_Log.WriteException(LogType.Error, ex); - throw; - } - - return dataNode; - } - - /// - /// Initializes the specified target. - /// - /// The target. - /// The args. - public void Initialize(LogTargets target, string[] args) - { - CacheTargets(GetType().Assembly); - CacheNodeTypes(GetType().Assembly); - CacheVersion(); - - m_CommandLine = new CommandLineCollection(args); - - string logFile = null; - if(m_CommandLine.WasPassed("log")) - { - logFile = m_CommandLine["log"]; - - if(logFile != null && logFile.Length == 0) - { - logFile = "Prebuild.log"; - } - } - else - { - target = target & ~LogTargets.File; //dont output to a file - } - - m_Log = new Log(target, logFile); - LogBanner(); - - m_CurrentWorkingDirectory = new CurrentDirectory(); + m_CurrentWorkingDirectory = new CurrentDirectory(); m_Target = m_CommandLine["target"]; - m_Clean = m_CommandLine["clean"]; - string removeDirs = m_CommandLine["removedir"]; - if(removeDirs != null && removeDirs.Length == 0) + m_Conditionals = m_CommandLine["conditionals"]; + if(m_CommandLine["targetframework"] != null) { - m_RemoveDirectories = removeDirs.Split('|'); + m_TargetFramework = (FrameworkVersion)Enum.Parse (typeof (FrameworkVersion), m_CommandLine["targetframework"]); + cmdlineTargetFramework = true; } + m_Clean = m_CommandLine["clean"]; + string removeDirs = m_CommandLine["removedir"]; + if(removeDirs != null && removeDirs.Length == 0) + { + m_RemoveDirectories = removeDirs.Split('|'); + } - string flags = m_CommandLine["allowedgroups"];//allows filtering by specifying a pipe-delimited list of groups to include - if(flags != null && flags.Length == 0) - { - m_ProjectGroups = flags.Split('|'); - } - m_PauseAfterFinish = m_CommandLine.WasPassed("pause"); + string flags = m_CommandLine["allowedgroups"];//allows filtering by specifying a pipe-delimited list of groups to include + if(flags != null && flags.Length == 0) + { + m_ProjectGroups = flags.Split('|'); + } + m_PauseAfterFinish = m_CommandLine.WasPassed("pause"); - LoadSchema(); - } + LoadSchema(); + } - /// - /// Processes this instance. - /// - public void Process() - { - bool perfomedOtherTask = false; - if(m_RemoveDirectories != null && m_RemoveDirectories.Length > 0) - { - try - { - RemoveDirectories(".",m_RemoveDirectories); - } - catch(IOException e) - { - m_Log.Write("Failed to remove directories named {0}",m_RemoveDirectories); - m_Log.WriteException(LogType.Error,e); - } - catch(UnauthorizedAccessException e) - { - m_Log.Write("Failed to remove directories named {0}",m_RemoveDirectories); - m_Log.WriteException(LogType.Error,e); - } - perfomedOtherTask = true; - } - - if(m_Target != null && m_Clean != null) - { - m_Log.Write(LogType.Error, "The options /target and /clean cannot be passed together"); - return; - } + /// + /// Processes this instance. + /// + public void Process() + { + bool perfomedOtherTask = false; + if(m_RemoveDirectories != null && m_RemoveDirectories.Length > 0) + { + try + { + RemoveDirectories(".",m_RemoveDirectories); + } + catch(IOException e) + { + m_Log.Write("Failed to remove directories named {0}",m_RemoveDirectories); + m_Log.WriteException(LogType.Error,e); + } + catch(UnauthorizedAccessException e) + { + m_Log.Write("Failed to remove directories named {0}",m_RemoveDirectories); + m_Log.WriteException(LogType.Error,e); + } + perfomedOtherTask = true; + } + if(m_Target != null && m_Clean != null) + { + m_Log.Write(LogType.Error, "The options /target and /clean cannot be passed together"); + return; + } + if(m_Target == null && m_Clean == null) - { - if(perfomedOtherTask) //finished - { - return; - } - m_Log.Write(LogType.Error, "Must pass either /target or /clean to process a Prebuild file"); - return; - } + { + if(perfomedOtherTask) //finished + { + return; + } + m_Log.Write(LogType.Error, "Must pass either /target or /clean to process a Prebuild file"); + return; + } - string file = "./prebuild.xml"; - if(m_CommandLine.WasPassed("file")) - { - file = m_CommandLine["file"]; - } + string file = "./prebuild.xml"; + if(m_CommandLine.WasPassed("file")) + { + file = m_CommandLine["file"]; + } - ProcessFile(file); + ProcessFile(file); - string target = (m_Target != null ? m_Target.ToLower() : m_Clean.ToLower()); - bool clean = (m_Target == null); - if(clean && target != null && target.Length == 0) - { - target = "all"; - } - if(clean && target == "all")//default to all if no target was specified for clean - { + string target = (m_Target != null ? m_Target.ToLower() : m_Clean.ToLower()); + bool clean = (m_Target == null); + if(clean && target != null && target.Length == 0) + { + target = "all"; + } + if(clean && target == "all")//default to all if no target was specified for clean + { //check if they passed yes if (!m_CommandLine.WasPassed("yes")) { - Console.WriteLine("WARNING: This operation will clean ALL project files for all targets, are you sure? (y/n):"); - string ret = Console.ReadLine(); - if(ret == null) - { - return; - } - ret = ret.Trim().ToLower(); - if((ret.ToLower() != "y" && ret.ToLower() != "yes")) - { - return; + Console.WriteLine("WARNING: This operation will clean ALL project files for all targets, are you sure? (y/n):"); + string ret = Console.ReadLine(); + if(ret == null) + { + return; + } + ret = ret.Trim().ToLower(); + if((ret.ToLower() != "y" && ret.ToLower() != "yes")) + { + return; } } - //clean all targets (just cleaning vs2002 target didn't clean nant) - foreach(ITarget targ in m_Targets.Values) - { - targ.Clean(this); - } - } - else - { - if (!m_Targets.ContainsKey(target)) { - m_Log.Write(LogType.Error, "Unknown Target \"{0}\"", target); - return; - } - ITarget targ = m_Targets[target]; + //clean all targets (just cleaning vs2002 target didn't clean nant) + foreach(ITarget targ in m_Targets.Values) + { + targ.Clean(this); + } + } + else + { + if (!m_Targets.ContainsKey(target)) { + m_Log.Write(LogType.Error, "Unknown Target \"{0}\"", target); + return; + } + ITarget targ = m_Targets[target]; - if(clean) - { - targ.Clean(this); - } - else - { - targ.Write(this); - } - } + if(clean) + { + targ.Clean(this); + } + else + { + targ.Write(this); + } + } - m_Log.Flush(); - } + m_Log.Flush(); + } - #endregion + #endregion - #region IDisposable Members + #region IDisposable Members - /// - /// - /// - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } + /// + /// + /// + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } - /// - /// Dispose objects - /// - /// - /// If true, it will dispose close the handle - /// - /// - /// Will dispose managed and unmanaged resources. - /// - protected virtual void Dispose(bool disposing) - { - if (!disposed) - { - if (disposing) - { + /// + /// Dispose objects + /// + /// + /// If true, it will dispose close the handle + /// + /// + /// Will dispose managed and unmanaged resources. + /// + protected virtual void Dispose(bool disposing) + { + if (!disposed) + { + if (disposing) + { GC.SuppressFinalize(this); - if (m_Log != null) - { - m_Log.Close(); - m_Log = null; - } - } - } - disposed = true; - } + if (m_Log != null) + { + m_Log.Close(); + m_Log = null; + } + } + } + disposed = true; + } - /// - /// - /// - ~Kernel() - { - Dispose(false); - } + /// + /// + /// + ~Kernel() + { + Dispose(false); + } + + /// + /// Closes and destroys this object + /// + /// + /// Same as Dispose(true) + /// + public void Close() + { + Dispose(); + } - /// - /// Closes and destroys this object - /// - /// - /// Same as Dispose(true) - /// - public void Close() - { - Dispose(); - } - - #endregion - } + #endregion + } } diff --git a/Prebuild/src/Core/Nodes/AuthorNode.cs b/Prebuild/src/Core/Nodes/AuthorNode.cs index e4b024f1f1..4c415bb6b1 100644 --- a/Prebuild/src/Core/Nodes/AuthorNode.cs +++ b/Prebuild/src/Core/Nodes/AuthorNode.cs @@ -5,16 +5,16 @@ Copyright (c) 2007 C.J. Adams-Collier (cjac@colliertech.org) Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: -* Redistributions of source code must retain the above copyright notice, this list of conditions - and the following disclaimer. -* Redistributions in binary form must reproduce the above copyright notice, this list of conditions - and the following disclaimer in the documentation and/or other materials provided with the - distribution. -* The name of the author may not be used to endorse or promote products derived from this software - without specific prior written permission. +* Redistributions of source code must retain the above copyright notice, this list of conditions + and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions + and the following disclaimer in the documentation and/or other materials provided with the + distribution. +* The name of the author may not be used to endorse or promote products derived from this software + without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, -BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY @@ -32,56 +32,56 @@ using Prebuild.Core.Utilities; namespace Prebuild.Core.Nodes { - /// - /// - /// - [DataNode("Author")] - public class AuthorNode : DataNode - { - #region Fields + /// + /// + /// + [DataNode("Author")] + public class AuthorNode : DataNode + { + #region Fields - private string m_Signature; + private string m_Signature; - #endregion + #endregion - #region Properties + #region Properties - /// - /// Gets the signature. - /// - /// The signature. - public string Signature - { - get - { - return m_Signature; - } - } + /// + /// Gets the signature. + /// + /// The signature. + public string Signature + { + get + { + return m_Signature; + } + } - #endregion + #endregion - #region Public Methods + #region Public Methods - /// - /// Parses the specified node. - /// - /// The node. - public override void Parse(XmlNode node) - { - if( node == null ) - { - throw new ArgumentNullException("node"); - } + /// + /// Parses the specified node. + /// + /// The node. + public override void Parse(XmlNode node) + { + if( node == null ) + { + throw new ArgumentNullException("node"); + } - m_Signature = Helper.InterpolateForEnvironmentVariables(node.InnerText); - if(m_Signature == null) - { - m_Signature = ""; - } + m_Signature = Helper.InterpolateForEnvironmentVariables(node.InnerText); + if(m_Signature == null) + { + m_Signature = ""; + } - m_Signature = m_Signature.Trim(); - } + m_Signature = m_Signature.Trim(); + } - #endregion - } + #endregion + } } diff --git a/Prebuild/src/Core/Nodes/CleanFilesNode.cs b/Prebuild/src/Core/Nodes/CleanFilesNode.cs index bd564d5ea1..71405f9aaa 100644 --- a/Prebuild/src/Core/Nodes/CleanFilesNode.cs +++ b/Prebuild/src/Core/Nodes/CleanFilesNode.cs @@ -5,16 +5,16 @@ Copyright (c) 2007 C.J. Adams-Collier (cjac@colliertech.org) Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: -* Redistributions of source code must retain the above copyright notice, this list of conditions - and the following disclaimer. -* Redistributions in binary form must reproduce the above copyright notice, this list of conditions - and the following disclaimer in the documentation and/or other materials provided with the - distribution. -* The name of the author may not be used to endorse or promote products derived from this software - without specific prior written permission. +* Redistributions of source code must retain the above copyright notice, this list of conditions + and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions + and the following disclaimer in the documentation and/or other materials provided with the + distribution. +* The name of the author may not be used to endorse or promote products derived from this software + without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, -BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY diff --git a/Prebuild/src/Core/Nodes/CleanupNode.cs b/Prebuild/src/Core/Nodes/CleanupNode.cs index f334ea3623..b8131b0ebb 100644 --- a/Prebuild/src/Core/Nodes/CleanupNode.cs +++ b/Prebuild/src/Core/Nodes/CleanupNode.cs @@ -5,16 +5,16 @@ Copyright (c) 2007 C.J. Adams-Collier (cjac@colliertech.org) Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: -* Redistributions of source code must retain the above copyright notice, this list of conditions - and the following disclaimer. -* Redistributions in binary form must reproduce the above copyright notice, this list of conditions - and the following disclaimer in the documentation and/or other materials provided with the - distribution. -* The name of the author may not be used to endorse or promote products derived from this software - without specific prior written permission. +* Redistributions of source code must retain the above copyright notice, this list of conditions + and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions + and the following disclaimer in the documentation and/or other materials provided with the + distribution. +* The name of the author may not be used to endorse or promote products derived from this software + without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, -BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY @@ -35,40 +35,40 @@ namespace Prebuild.Core.Nodes [DataNode("Cleanup")] public class CleanupNode : DataNode { - #region Fields + #region Fields - private List m_CleanFiles = new List(); + private List m_CleanFiles = new List(); - #endregion + #endregion - #region Properties + #region Properties - /// - /// Gets the signature. - /// - /// The signature. + /// + /// Gets the signature. + /// + /// The signature. public List CleanFiles - { - get - { - return m_CleanFiles; - } - } + { + get + { + return m_CleanFiles; + } + } - #endregion + #endregion - #region Public Methods + #region Public Methods - /// - /// Parses the specified node. - /// - /// The node. - public override void Parse(XmlNode node) - { - if( node == null ) - { - throw new ArgumentNullException("node"); - } + /// + /// Parses the specified node. + /// + /// The node. + public override void Parse(XmlNode node) + { + if( node == null ) + { + throw new ArgumentNullException("node"); + } foreach (XmlNode child in node.ChildNodes) { @@ -78,8 +78,8 @@ namespace Prebuild.Core.Nodes m_CleanFiles.Add((CleanFilesNode)dataNode); } } - } + } - #endregion + #endregion } } \ No newline at end of file diff --git a/Prebuild/src/Core/Nodes/ConfigurationNode.cs b/Prebuild/src/Core/Nodes/ConfigurationNode.cs index a101799eec..cd2f740ae7 100644 --- a/Prebuild/src/Core/Nodes/ConfigurationNode.cs +++ b/Prebuild/src/Core/Nodes/ConfigurationNode.cs @@ -5,16 +5,16 @@ Copyright (c) 2004-2005 Matthew Holmes (matthew@wildfiregames.com), Dan Moorehea Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: -* Redistributions of source code must retain the above copyright notice, this list of conditions - and the following disclaimer. -* Redistributions in binary form must reproduce the above copyright notice, this list of conditions - and the following disclaimer in the documentation and/or other materials provided with the - distribution. -* The name of the author may not be used to endorse or promote products derived from this software - without specific prior written permission. +* Redistributions of source code must retain the above copyright notice, this list of conditions + and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions + and the following disclaimer in the documentation and/or other materials provided with the + distribution. +* The name of the author may not be used to endorse or promote products derived from this software + without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, -BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY @@ -32,185 +32,185 @@ using Prebuild.Core.Utilities; namespace Prebuild.Core.Nodes { - /// - /// - /// - [DataNode("Configuration")] - public class ConfigurationNode : DataNode, ICloneable, IComparable - { - #region Fields + /// + /// + /// + [DataNode("Configuration")] + public class ConfigurationNode : DataNode, ICloneable, IComparable + { + #region Fields - private string m_Name = "unknown"; - private string m_Platform = "AnyCPU"; - private OptionsNode m_Options; + private string m_Name = "unknown"; + private string m_Platform = "AnyCPU"; + private OptionsNode m_Options; - #endregion + #endregion - #region Constructors + #region Constructors - /// - /// Initializes a new instance of the class. - /// - public ConfigurationNode() - { - m_Options = new OptionsNode(); - } + /// + /// Initializes a new instance of the class. + /// + public ConfigurationNode() + { + m_Options = new OptionsNode(); + } - #endregion + #endregion - #region Properties + #region Properties - /// - /// Gets or sets the parent. - /// - /// The parent. - public override IDataNode Parent - { - get - { - return base.Parent; - } - set - { - base.Parent = value; - if(base.Parent is SolutionNode) - { - SolutionNode node = (SolutionNode)base.Parent; - if(node != null && node.Options != null) - { - node.Options.CopyTo(m_Options); - } - } - } - } + /// + /// Gets or sets the parent. + /// + /// The parent. + public override IDataNode Parent + { + get + { + return base.Parent; + } + set + { + base.Parent = value; + if(base.Parent is SolutionNode) + { + SolutionNode node = (SolutionNode)base.Parent; + if(node != null && node.Options != null) + { + node.Options.CopyTo(m_Options); + } + } + } + } - /// - /// Identifies the platform for this specific configuration. - /// - public string Platform - { - get - { - return m_Platform; - } - set - { - switch ((value + "").ToLower()) - { - case "x86": - case "x64": - m_Platform = value; - break; - case "itanium": - m_Platform = "Itanium"; - break; - default: - m_Platform = "AnyCPU"; - break; - } - } - } + /// + /// Identifies the platform for this specific configuration. + /// + public string Platform + { + get + { + return m_Platform; + } + set + { + switch ((value + "").ToLower()) + { + case "x86": + case "x64": + m_Platform = value; + break; + case "itanium": + m_Platform = "Itanium"; + break; + default: + m_Platform = "AnyCPU"; + break; + } + } + } - /// - /// Gets the name. - /// - /// The name. - public string Name - { - get - { - return m_Name; - } - } + /// + /// Gets the name. + /// + /// The name. + public string Name + { + get + { + return m_Name; + } + } - /// - /// Gets the name and platform for the configuration. - /// - /// The name and platform. - public string NameAndPlatform - { - get - { + /// + /// Gets the name and platform for the configuration. + /// + /// The name and platform. + public string NameAndPlatform + { + get + { string platform = m_Platform; if (platform == "AnyCPU") platform = "Any CPU"; - return String.Format("{0}|{1}", m_Name, platform); - } - } + return String.Format("{0}|{1}", m_Name, platform); + } + } - /// - /// Gets or sets the options. - /// - /// The options. - public OptionsNode Options - { - get - { - return m_Options; - } - set - { - m_Options = value; - } - } + /// + /// Gets or sets the options. + /// + /// The options. + public OptionsNode Options + { + get + { + return m_Options; + } + set + { + m_Options = value; + } + } - #endregion + #endregion - #region Public Methods + #region Public Methods - /// - /// Parses the specified node. - /// - /// The node. - public override void Parse(XmlNode node) - { - m_Name = Helper.AttributeValue(node, "name", m_Name); - Platform = Helper.AttributeValue(node, "platform", m_Platform); + /// + /// Parses the specified node. + /// + /// The node. + public override void Parse(XmlNode node) + { + m_Name = Helper.AttributeValue(node, "name", m_Name); + Platform = Helper.AttributeValue(node, "platform", m_Platform); - if (node == null) - { - throw new ArgumentNullException("node"); - } - foreach(XmlNode child in node.ChildNodes) - { - IDataNode dataNode = Kernel.Instance.ParseNode(child, this); - if(dataNode is OptionsNode) - { - ((OptionsNode)dataNode).CopyTo(m_Options); - } - } - } + if (node == null) + { + throw new ArgumentNullException("node"); + } + foreach(XmlNode child in node.ChildNodes) + { + IDataNode dataNode = Kernel.Instance.ParseNode(child, this); + if(dataNode is OptionsNode) + { + ((OptionsNode)dataNode).CopyTo(m_Options); + } + } + } - /// - /// Copies to. - /// - /// The conf. - public void CopyTo(ConfigurationNode conf) - { - m_Options.CopyTo(conf.m_Options); - } + /// + /// Copies to. + /// + /// The conf. + public void CopyTo(ConfigurationNode conf) + { + m_Options.CopyTo(conf.m_Options); + } - #endregion + #endregion - #region ICloneable Members + #region ICloneable Members - /// - /// Creates a new object that is a copy of the current instance. - /// - /// - /// A new object that is a copy of this instance. - /// - public object Clone() - { - ConfigurationNode ret = new ConfigurationNode(); - ret.m_Name = m_Name; - ret.m_Platform = m_Platform; - m_Options.CopyTo(ret.m_Options); - return ret; - } + /// + /// Creates a new object that is a copy of the current instance. + /// + /// + /// A new object that is a copy of this instance. + /// + public object Clone() + { + ConfigurationNode ret = new ConfigurationNode(); + ret.m_Name = m_Name; + ret.m_Platform = m_Platform; + m_Options.CopyTo(ret.m_Options); + return ret; + } - #endregion + #endregion #region IComparable Members @@ -221,5 +221,5 @@ namespace Prebuild.Core.Nodes } #endregion - } + } } diff --git a/Prebuild/src/Core/Nodes/ConfigurationNodeCollection.cs b/Prebuild/src/Core/Nodes/ConfigurationNodeCollection.cs index eba6550203..1c38d9e443 100644 --- a/Prebuild/src/Core/Nodes/ConfigurationNodeCollection.cs +++ b/Prebuild/src/Core/Nodes/ConfigurationNodeCollection.cs @@ -5,16 +5,16 @@ Copyright (c) 2004-2005 Matthew Holmes (matthew@wildfiregames.com), Dan Moorehea Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: -* Redistributions of source code must retain the above copyright notice, this list of conditions - and the following disclaimer. -* Redistributions in binary form must reproduce the above copyright notice, this list of conditions - and the following disclaimer in the documentation and/or other materials provided with the - distribution. -* The name of the author may not be used to endorse or promote products derived from this software - without specific prior written permission. +* Redistributions of source code must retain the above copyright notice, this list of conditions + and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions + and the following disclaimer in the documentation and/or other materials provided with the + distribution. +* The name of the author may not be used to endorse or promote products derived from this software + without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, -BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY @@ -27,45 +27,45 @@ using System.Collections.Generic; namespace Prebuild.Core.Nodes { - /// - /// Implements a specialized list of configuration nodes which allows for lookup via - /// configuration name and platform. - /// - public class ConfigurationNodeCollection : List - { - #region Properties + /// + /// Implements a specialized list of configuration nodes which allows for lookup via + /// configuration name and platform. + /// + public class ConfigurationNodeCollection : List + { + #region Properties - public ConfigurationNode this[string nameAndPlatform] - { - get - { - foreach (ConfigurationNode configurationNode in this) - { - if (configurationNode.NameAndPlatform == nameAndPlatform) - { - return configurationNode; - } - } + public ConfigurationNode this[string nameAndPlatform] + { + get + { + foreach (ConfigurationNode configurationNode in this) + { + if (configurationNode.NameAndPlatform == nameAndPlatform) + { + return configurationNode; + } + } - return null; - } + return null; + } - set - { - // See if the node - ConfigurationNode configurationNode = this[nameAndPlatform]; + set + { + // See if the node + ConfigurationNode configurationNode = this[nameAndPlatform]; - if (configurationNode != null) - { - this[IndexOf(configurationNode)] = value; - } - else - { - Add(value); - } - } - } + if (configurationNode != null) + { + this[IndexOf(configurationNode)] = value; + } + else + { + Add(value); + } + } + } - #endregion - } + #endregion + } } diff --git a/Prebuild/src/Core/Nodes/DataNode.cs b/Prebuild/src/Core/Nodes/DataNode.cs index 4f20588d39..318b13ccb9 100644 --- a/Prebuild/src/Core/Nodes/DataNode.cs +++ b/Prebuild/src/Core/Nodes/DataNode.cs @@ -5,16 +5,16 @@ Copyright (c) 2004-2005 Matthew Holmes (matthew@wildfiregames.com), Dan Moorehea Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: -* Redistributions of source code must retain the above copyright notice, this list of conditions - and the following disclaimer. -* Redistributions in binary form must reproduce the above copyright notice, this list of conditions - and the following disclaimer in the documentation and/or other materials provided with the - distribution. -* The name of the author may not be used to endorse or promote products derived from this software - without specific prior written permission. +* Redistributions of source code must retain the above copyright notice, this list of conditions + and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions + and the following disclaimer in the documentation and/or other materials provided with the + distribution. +* The name of the author may not be used to endorse or promote products derived from this software + without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, -BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY @@ -32,86 +32,86 @@ using System.IO; namespace Prebuild.Core.Nodes { - /// - /// - /// - public abstract class DataNode : IDataNode - { - #region Fields + /// + /// + /// + public abstract class DataNode : IDataNode + { + #region Fields - private IDataNode parent; - string[] m_WebTypes = new string[] { "aspx", "ascx", "master", "ashx", "asmx" }; + private IDataNode parent; + string[] m_WebTypes = new string[] { "aspx", "ascx", "master", "ashx", "asmx" }; - #endregion + #endregion - #region IDataNode Members + #region IDataNode Members - /// - /// Gets or sets the parent. - /// - /// The parent. - public virtual IDataNode Parent - { - get - { - return parent; - } - set - { - parent = value; - } - } - public string[] WebTypes - { - get { return m_WebTypes; } - } - /// - /// Parses the specified node. - /// - /// The node. - public virtual void Parse(XmlNode node) - { - } - public BuildAction GetBuildActionByFileName(string fileName) - { - string extension = Path.GetExtension(fileName).ToLower(); - foreach (string type in WebTypes) - { - if (extension == type) - return BuildAction.Content; - } - return BuildAction.Compile; - } - /// - /// Parses the file type to figure out what type it is - /// - /// - public SubType GetSubTypeByFileName(string fileName) - { - string extension = System.IO.Path.GetExtension(fileName).ToLower(); - string designer = String.Format(".designer{0}", extension); - string path = fileName.ToLower(); - if (extension == ".resx") - { - return SubType.Designer; - } - else if (path.EndsWith(".settings")) - { - return SubType.Settings; - } - else - { - - foreach (string type in WebTypes) - { + /// + /// Gets or sets the parent. + /// + /// The parent. + public virtual IDataNode Parent + { + get + { + return parent; + } + set + { + parent = value; + } + } + public string[] WebTypes + { + get { return m_WebTypes; } + } + /// + /// Parses the specified node. + /// + /// The node. + public virtual void Parse(XmlNode node) + { + } + public BuildAction GetBuildActionByFileName(string fileName) + { + string extension = Path.GetExtension(fileName).ToLower(); + foreach (string type in WebTypes) + { + if (extension == type) + return BuildAction.Content; + } + return BuildAction.Compile; + } + /// + /// Parses the file type to figure out what type it is + /// + /// + public SubType GetSubTypeByFileName(string fileName) + { + string extension = System.IO.Path.GetExtension(fileName).ToLower(); + string designer = String.Format(".designer{0}", extension); + string path = fileName.ToLower(); + if (extension == ".resx") + { + return SubType.Designer; + } + else if (path.EndsWith(".settings")) + { + return SubType.Settings; + } + else + { + + foreach (string type in WebTypes) + { if (path.EndsWith(type)) - { - return SubType.CodeBehind; - } - } - } - return SubType.Code; - } - #endregion - } + { + return SubType.CodeBehind; + } + } + } + return SubType.Code; + } + #endregion + } } diff --git a/Prebuild/src/Core/Nodes/DatabaseReferenceNode.cs b/Prebuild/src/Core/Nodes/DatabaseReferenceNode.cs index 974b74e67b..845db24b12 100644 --- a/Prebuild/src/Core/Nodes/DatabaseReferenceNode.cs +++ b/Prebuild/src/Core/Nodes/DatabaseReferenceNode.cs @@ -43,18 +43,18 @@ namespace Prebuild.Core.Nodes providerId = new Guid("7F041D59-D76A-44ed-9AA2-FBF6B0548B80"); break; case "System.Data.OracleClient": providerId = new Guid("8F5C5018-AE09-42cf-B2CC-2CCCC7CFC2BB"); break; - case "System.Data.SqlClient": + case "System.Data.SqlClient": providerId = new Guid("91510608-8809-4020-8897-FBA057E22D54"); break; case "System.Data.Odbc": providerId = new Guid("C3D4F4CE-2C48-4381-B4D6-34FA50C51C86"); break; - + default: throw new ArgumentOutOfRangeException("providerName", providerName, "Could not provider name to an id."); } } else providerId = new Guid(Helper.AttributeValue(node, "providerId", Guid.Empty.ToString("B"))); - + connectionString = Helper.AttributeValue(node, "connectionString", connectionString); base.Parse(node); diff --git a/Prebuild/src/Core/Nodes/DescriptionNode.cs b/Prebuild/src/Core/Nodes/DescriptionNode.cs index 713b47c34a..d1293a0c80 100644 --- a/Prebuild/src/Core/Nodes/DescriptionNode.cs +++ b/Prebuild/src/Core/Nodes/DescriptionNode.cs @@ -5,16 +5,16 @@ Copyright (c) 2007 C.J. Adams-Collier (cjac@colliertech.org) Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: -* Redistributions of source code must retain the above copyright notice, this list of conditions - and the following disclaimer. -* Redistributions in binary form must reproduce the above copyright notice, this list of conditions - and the following disclaimer in the documentation and/or other materials provided with the - distribution. -* The name of the author may not be used to endorse or promote products derived from this software - without specific prior written permission. +* Redistributions of source code must retain the above copyright notice, this list of conditions + and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions + and the following disclaimer in the documentation and/or other materials provided with the + distribution. +* The name of the author may not be used to endorse or promote products derived from this software + without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, -BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY @@ -32,56 +32,56 @@ using Prebuild.Core.Utilities; namespace Prebuild.Core.Nodes { - /// - /// The object representing the /Prebuild/Solution/Project/Description element - /// - [DataNode("Description")] - public class DescriptionNode : DataNode - { - #region Fields + /// + /// The object representing the /Prebuild/Solution/Project/Description element + /// + [DataNode("Description")] + public class DescriptionNode : DataNode + { + #region Fields - private string m_Value; + private string m_Value; - #endregion + #endregion - #region Properties + #region Properties - /// - /// Gets the description Value. - /// - /// The description Value. - public string Value - { - get - { - return m_Value; - } - } + /// + /// Gets the description Value. + /// + /// The description Value. + public string Value + { + get + { + return m_Value; + } + } - #endregion + #endregion - #region Public Methods + #region Public Methods - /// - /// Parses the specified node. - /// - /// The node. - public override void Parse(XmlNode node) - { - if( node == null ) - { - throw new ArgumentNullException("node"); - } + /// + /// Parses the specified node. + /// + /// The node. + public override void Parse(XmlNode node) + { + if( node == null ) + { + throw new ArgumentNullException("node"); + } - m_Value = Helper.InterpolateForEnvironmentVariables(node.InnerText); - if(m_Value == null) - { - m_Value = ""; - } + m_Value = Helper.InterpolateForEnvironmentVariables(node.InnerText); + if(m_Value == null) + { + m_Value = ""; + } - m_Value = m_Value.Trim(); - } + m_Value = m_Value.Trim(); + } - #endregion - } + #endregion + } } diff --git a/Prebuild/src/Core/Nodes/ExcludeNode.cs b/Prebuild/src/Core/Nodes/ExcludeNode.cs index addbdb43d7..7f04cba72f 100644 --- a/Prebuild/src/Core/Nodes/ExcludeNode.cs +++ b/Prebuild/src/Core/Nodes/ExcludeNode.cs @@ -5,16 +5,16 @@ Copyright (c) 2004-2005 Matthew Holmes (matthew@wildfiregames.com), Dan Moorehea Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: -* Redistributions of source code must retain the above copyright notice, this list of conditions - and the following disclaimer. -* Redistributions in binary form must reproduce the above copyright notice, this list of conditions - and the following disclaimer in the documentation and/or other materials provided with the - distribution. -* The name of the author may not be used to endorse or promote products derived from this software - without specific prior written permission. +* Redistributions of source code must retain the above copyright notice, this list of conditions + and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions + and the following disclaimer in the documentation and/or other materials provided with the + distribution. +* The name of the author may not be used to endorse or promote products derived from this software + without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, -BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY @@ -32,31 +32,31 @@ using Prebuild.Core.Utilities; namespace Prebuild.Core.Nodes { - /// - /// - /// - [DataNode("Exclude")] - public class ExcludeNode : DataNode - { - #region Fields + /// + /// + /// + [DataNode("Exclude")] + public class ExcludeNode : DataNode + { + #region Fields private string m_Pattern = ""; - #endregion + #endregion - #region Properties + #region Properties - /// - /// Gets the name. - /// - /// The name. - public string Name - { - get - { - return m_Pattern; - } - } + /// + /// Gets the name. + /// + /// The name. + public string Name + { + get + { + return m_Pattern; + } + } /// /// Gets the pattern. @@ -72,18 +72,18 @@ namespace Prebuild.Core.Nodes #endregion - #region Public Methods + #region Public Methods - /// - /// Parses the specified node. - /// - /// The node. - public override void Parse(XmlNode node) - { + /// + /// Parses the specified node. + /// + /// The node. + public override void Parse(XmlNode node) + { m_Pattern = Helper.AttributeValue( node, "name", m_Pattern ); m_Pattern = Helper.AttributeValue(node, "pattern", m_Pattern ); - } + } - #endregion - } + #endregion + } } diff --git a/Prebuild/src/Core/Nodes/FileNode.cs b/Prebuild/src/Core/Nodes/FileNode.cs index c66f123315..b313ffac75 100644 --- a/Prebuild/src/Core/Nodes/FileNode.cs +++ b/Prebuild/src/Core/Nodes/FileNode.cs @@ -5,16 +5,16 @@ Copyright (c) 2004-2005 Matthew Holmes (matthew@wildfiregames.com), Dan Moorehea Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: -* Redistributions of source code must retain the above copyright notice, this list of conditions - and the following disclaimer. -* Redistributions in binary form must reproduce the above copyright notice, this list of conditions - and the following disclaimer in the documentation and/or other materials provided with the - distribution. -* The name of the author may not be used to endorse or promote products derived from this software - without specific prior written permission. +* Redistributions of source code must retain the above copyright notice, this list of conditions + and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions + and the following disclaimer in the documentation and/or other materials provided with the + distribution. +* The name of the author may not be used to endorse or promote products derived from this software + without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, -BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY @@ -34,193 +34,193 @@ using Prebuild.Core.Targets; namespace Prebuild.Core.Nodes { - /// - /// - /// - public enum BuildAction - { + /// + /// + /// + public enum BuildAction + { + /// + /// + /// + None, + /// + /// + /// + Compile, + /// + /// + /// + Content, + /// + /// + /// + EmbeddedResource, + /// + /// + /// + ApplicationDefinition, + /// + /// + /// + Page, /// - /// - /// - None, - /// - /// - /// - Compile, - /// - /// - /// - Content, - /// - /// - /// - EmbeddedResource, - /// - /// - /// - ApplicationDefinition, - /// - /// - /// - Page, - /// - /// + /// /// Copy - } + } - /// - /// - /// - public enum SubType - { + /// + /// + /// + public enum SubType + { + /// + /// + /// + Code, + /// + /// + /// + Component, /// - /// - /// - Code, - /// - /// - /// - Component, - /// - /// + /// /// Designer, - /// - /// - /// - Form, - /// - /// - /// - Settings, - /// - /// - /// - UserControl, - /// - /// - /// - CodeBehind, - } + /// + /// + /// + Form, + /// + /// + /// + Settings, + /// + /// + /// + UserControl, + /// + /// + /// + CodeBehind, + } - public enum CopyToOutput - { - Never, - Always, - PreserveNewest - } + public enum CopyToOutput + { + Never, + Always, + PreserveNewest + } - /// - /// - /// - [DataNode("File")] - public class FileNode : DataNode - { - #region Fields + /// + /// + /// + [DataNode("File")] + public class FileNode : DataNode + { + #region Fields - private string m_Path; - private string m_ResourceName = ""; - private BuildAction? m_BuildAction; - private bool m_Valid; - private SubType? m_SubType; - private CopyToOutput m_CopyToOutput = CopyToOutput.Never; - private bool m_Link = false; - private string m_LinkPath = string.Empty; + private string m_Path; + private string m_ResourceName = ""; + private BuildAction? m_BuildAction; + private bool m_Valid; + private SubType? m_SubType; + private CopyToOutput m_CopyToOutput = CopyToOutput.Never; + private bool m_Link = false; + private string m_LinkPath = string.Empty; private bool m_PreservePath = false; - #endregion + #endregion - #region Properties + #region Properties + + /// + /// + /// + public string Path + { + get + { + return m_Path; + } + } + + /// + /// + /// + public string ResourceName + { + get + { + return m_ResourceName; + } + } + + /// + /// + /// + public BuildAction BuildAction + { + get + { + if (m_BuildAction != null) + return m_BuildAction.Value; + else + return GetBuildActionByFileName(this.Path); + + } + } + + public CopyToOutput CopyToOutput + { + get + { + return this.m_CopyToOutput; + } + } + + public bool IsLink + { + get + { + return this.m_Link; + } + } + + public string LinkPath + { + get + { + return this.m_LinkPath; + } + } + /// + /// + /// + public SubType SubType + { + get + { + if (m_SubType != null) + return m_SubType.Value; + else + return GetSubTypeByFileName(this.Path); + } + } + + /// + /// + /// + public bool IsValid + { + get + { + return m_Valid; + } + } /// - /// - /// - public string Path - { - get - { - return m_Path; - } - } - - /// - /// - /// - public string ResourceName - { - get - { - return m_ResourceName; - } - } - - /// - /// - /// - public BuildAction BuildAction - { - get - { - if (m_BuildAction != null) - return m_BuildAction.Value; - else - return GetBuildActionByFileName(this.Path); - - } - } - - public CopyToOutput CopyToOutput - { - get - { - return this.m_CopyToOutput; - } - } - - public bool IsLink - { - get - { - return this.m_Link; - } - } - - public string LinkPath - { - get - { - return this.m_LinkPath; - } - } - /// - /// - /// - public SubType SubType - { - get - { - if (m_SubType != null) - return m_SubType.Value; - else - return GetSubTypeByFileName(this.Path); - } - } - - /// - /// - /// - public bool IsValid - { - get - { - return m_Valid; - } - } - - /// - /// + /// /// /// /// @@ -232,61 +232,61 @@ namespace Prebuild.Core.Nodes } } - #endregion + #endregion - #region Public Methods + #region Public Methods - /// - /// - /// - /// - public override void Parse(XmlNode node) - { - string buildAction = Helper.AttributeValue(node, "buildAction", String.Empty); - if (buildAction != string.Empty) - m_BuildAction = (BuildAction)Enum.Parse(typeof(BuildAction), buildAction); - string subType = Helper.AttributeValue(node, "subType", string.Empty); - if (subType != String.Empty) - m_SubType = (SubType)Enum.Parse(typeof(SubType), subType); + /// + /// + /// + /// + public override void Parse(XmlNode node) + { + string buildAction = Helper.AttributeValue(node, "buildAction", String.Empty); + if (buildAction != string.Empty) + m_BuildAction = (BuildAction)Enum.Parse(typeof(BuildAction), buildAction); + string subType = Helper.AttributeValue(node, "subType", string.Empty); + if (subType != String.Empty) + m_SubType = (SubType)Enum.Parse(typeof(SubType), subType); Console.WriteLine("[FileNode]:BuildAction is {0}", buildAction); - m_ResourceName = Helper.AttributeValue(node, "resourceName", m_ResourceName.ToString()); - this.m_Link = bool.Parse(Helper.AttributeValue(node, "link", bool.FalseString)); - if ( this.m_Link == true ) - { - this.m_LinkPath = Helper.AttributeValue( node, "linkPath", string.Empty ); - } - this.m_CopyToOutput = (CopyToOutput) Enum.Parse(typeof(CopyToOutput), Helper.AttributeValue(node, "copyToOutput", this.m_CopyToOutput.ToString())); + m_ResourceName = Helper.AttributeValue(node, "resourceName", m_ResourceName.ToString()); + this.m_Link = bool.Parse(Helper.AttributeValue(node, "link", bool.FalseString)); + if ( this.m_Link == true ) + { + this.m_LinkPath = Helper.AttributeValue( node, "linkPath", string.Empty ); + } + this.m_CopyToOutput = (CopyToOutput) Enum.Parse(typeof(CopyToOutput), Helper.AttributeValue(node, "copyToOutput", this.m_CopyToOutput.ToString())); this.m_PreservePath = bool.Parse( Helper.AttributeValue( node, "preservePath", bool.FalseString ) ); - if( node == null ) - { - throw new ArgumentNullException("node"); - } + if( node == null ) + { + throw new ArgumentNullException("node"); + } - m_Path = Helper.InterpolateForEnvironmentVariables(node.InnerText); - if(m_Path == null) - { - m_Path = ""; - } + m_Path = Helper.InterpolateForEnvironmentVariables(node.InnerText); + if(m_Path == null) + { + m_Path = ""; + } - m_Path = m_Path.Trim(); - m_Valid = true; - if(!File.Exists(m_Path)) - { - m_Valid = false; - Kernel.Instance.Log.Write(LogType.Warning, "File does not exist: {0}", m_Path); - } + m_Path = m_Path.Trim(); + m_Valid = true; + if(!File.Exists(m_Path)) + { + m_Valid = false; + Kernel.Instance.Log.Write(LogType.Warning, "File does not exist: {0}", m_Path); + } if (System.IO.Path.GetExtension(m_Path) == ".settings") { m_SubType = SubType.Settings; m_BuildAction = BuildAction.None; } - } + } - #endregion - } + #endregion + } } diff --git a/Prebuild/src/Core/Nodes/FilesNode.cs b/Prebuild/src/Core/Nodes/FilesNode.cs index 58b54fb6a4..16658f38f2 100644 --- a/Prebuild/src/Core/Nodes/FilesNode.cs +++ b/Prebuild/src/Core/Nodes/FilesNode.cs @@ -5,16 +5,16 @@ Copyright (c) 2004-2005 Matthew Holmes (matthew@wildfiregames.com), Dan Moorehea Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: -* Redistributions of source code must retain the above copyright notice, this list of conditions - and the following disclaimer. -* Redistributions in binary form must reproduce the above copyright notice, this list of conditions - and the following disclaimer in the documentation and/or other materials provided with the - distribution. -* The name of the author may not be used to endorse or promote products derived from this software - without specific prior written permission. +* Redistributions of source code must retain the above copyright notice, this list of conditions + and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions + and the following disclaimer in the documentation and/or other materials provided with the + distribution. +* The name of the author may not be used to endorse or promote products derived from this software + without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, -BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY @@ -34,36 +34,36 @@ using System.IO; namespace Prebuild.Core.Nodes { - /// - /// - /// - [DataNode("Files")] - public class FilesNode : DataNode - { - #region Fields + /// + /// + /// + [DataNode("Files")] + public class FilesNode : DataNode + { + #region Fields - private readonly List m_Files = new List(); - private readonly Dictionary m_BuildActions = new Dictionary(); - private readonly Dictionary m_SubTypes = new Dictionary(); - private readonly Dictionary m_ResourceNames = new Dictionary(); - private readonly Dictionary m_CopyToOutputs = new Dictionary(); - private readonly Dictionary m_Links = new Dictionary(); - private readonly Dictionary m_LinkPaths = new Dictionary(); + private readonly List m_Files = new List(); + private readonly Dictionary m_BuildActions = new Dictionary(); + private readonly Dictionary m_SubTypes = new Dictionary(); + private readonly Dictionary m_ResourceNames = new Dictionary(); + private readonly Dictionary m_CopyToOutputs = new Dictionary(); + private readonly Dictionary m_Links = new Dictionary(); + private readonly Dictionary m_LinkPaths = new Dictionary(); private readonly Dictionary m_PreservePaths = new Dictionary(); private readonly Dictionary m_DestinationPath = new Dictionary(); private readonly NameValueCollection m_CopyFiles = new NameValueCollection(); - #endregion + #endregion - #region Properties + #region Properties - public int Count - { - get - { - return m_Files.Count; - } - } + public int Count + { + get + { + return m_Files.Count; + } + } public string[] Destinations { @@ -75,19 +75,19 @@ namespace Prebuild.Core.Nodes get { return m_CopyFiles.Count; } } - #endregion + #endregion - #region Public Methods + #region Public Methods - public BuildAction GetBuildAction(string file) - { - if(!m_BuildActions.ContainsKey(file)) - { - return BuildAction.Compile; - } + public BuildAction GetBuildAction(string file) + { + if(!m_BuildActions.ContainsKey(file)) + { + return BuildAction.Compile; + } - return m_BuildActions[file]; - } + return m_BuildActions[file]; + } public string GetDestinationPath(string file) { @@ -103,57 +103,57 @@ namespace Prebuild.Core.Nodes return m_CopyFiles.GetValues(dest); } - public CopyToOutput GetCopyToOutput(string file) - { - if (!m_CopyToOutputs.ContainsKey(file)) - { - return CopyToOutput.Never; - } - return m_CopyToOutputs[file]; - } + public CopyToOutput GetCopyToOutput(string file) + { + if (!m_CopyToOutputs.ContainsKey(file)) + { + return CopyToOutput.Never; + } + return m_CopyToOutputs[file]; + } - public bool GetIsLink(string file) - { - if (!m_Links.ContainsKey(file)) - { - return false; - } - return m_Links[file]; - } + public bool GetIsLink(string file) + { + if (!m_Links.ContainsKey(file)) + { + return false; + } + return m_Links[file]; + } public bool Contains(string file) { return m_Files.Contains(file); } - public string GetLinkPath( string file ) - { - if ( !m_LinkPaths.ContainsKey( file ) ) - { - return string.Empty; - } - return m_LinkPaths[ file ]; - } + public string GetLinkPath( string file ) + { + if ( !m_LinkPaths.ContainsKey( file ) ) + { + return string.Empty; + } + return m_LinkPaths[ file ]; + } - public SubType GetSubType(string file) - { - if(!m_SubTypes.ContainsKey(file)) - { - return SubType.Code; - } + public SubType GetSubType(string file) + { + if(!m_SubTypes.ContainsKey(file)) + { + return SubType.Code; + } - return m_SubTypes[file]; - } + return m_SubTypes[file]; + } - public string GetResourceName(string file) - { - if(!m_ResourceNames.ContainsKey(file)) - { - return string.Empty; - } + public string GetResourceName(string file) + { + if(!m_ResourceNames.ContainsKey(file)) + { + return string.Empty; + } - return m_ResourceNames[file]; - } + return m_ResourceNames[file]; + } public bool GetPreservePath( string file ) { @@ -165,45 +165,45 @@ namespace Prebuild.Core.Nodes return m_PreservePaths[ file ]; } - public override void Parse(XmlNode node) - { - if( node == null ) - { - throw new ArgumentNullException("node"); - } - foreach(XmlNode child in node.ChildNodes) - { - IDataNode dataNode = Kernel.Instance.ParseNode(child, this); - if(dataNode is FileNode) - { - FileNode fileNode = (FileNode)dataNode; - if(fileNode.IsValid) - { - if (!m_Files.Contains(fileNode.Path)) - { - m_Files.Add(fileNode.Path); - m_BuildActions[fileNode.Path] = fileNode.BuildAction; - m_SubTypes[fileNode.Path] = fileNode.SubType; - m_ResourceNames[fileNode.Path] = fileNode.ResourceName; + public override void Parse(XmlNode node) + { + if( node == null ) + { + throw new ArgumentNullException("node"); + } + foreach(XmlNode child in node.ChildNodes) + { + IDataNode dataNode = Kernel.Instance.ParseNode(child, this); + if(dataNode is FileNode) + { + FileNode fileNode = (FileNode)dataNode; + if(fileNode.IsValid) + { + if (!m_Files.Contains(fileNode.Path)) + { + m_Files.Add(fileNode.Path); + m_BuildActions[fileNode.Path] = fileNode.BuildAction; + m_SubTypes[fileNode.Path] = fileNode.SubType; + m_ResourceNames[fileNode.Path] = fileNode.ResourceName; m_PreservePaths[ fileNode.Path ] = fileNode.PreservePath; m_Links[ fileNode.Path ] = fileNode.IsLink; - m_LinkPaths[ fileNode.Path ] = fileNode.LinkPath; - m_CopyToOutputs[ fileNode.Path ] = fileNode.CopyToOutput; + m_LinkPaths[ fileNode.Path ] = fileNode.LinkPath; + m_CopyToOutputs[ fileNode.Path ] = fileNode.CopyToOutput; - } - } - } - else if(dataNode is MatchNode) - { - foreach(string file in ((MatchNode)dataNode).Files) - { + } + } + } + else if(dataNode is MatchNode) + { + foreach(string file in ((MatchNode)dataNode).Files) + { MatchNode matchNode = (MatchNode)dataNode; - if (!m_Files.Contains(file)) - { - m_Files.Add(file); - if (matchNode.BuildAction == null) + if (!m_Files.Contains(file)) + { + m_Files.Add(file); + if (matchNode.BuildAction == null) m_BuildActions[file] = GetBuildActionByFileName(file); - else + else m_BuildActions[file] = matchNode.BuildAction.Value; if (matchNode.BuildAction == BuildAction.Copy) @@ -212,27 +212,27 @@ namespace Prebuild.Core.Nodes m_DestinationPath[file] = matchNode.DestinationPath; } - m_SubTypes[file] = matchNode.SubType == null ? GetSubTypeByFileName(file) : matchNode.SubType.Value; + m_SubTypes[file] = matchNode.SubType == null ? GetSubTypeByFileName(file) : matchNode.SubType.Value; m_ResourceNames[ file ] = matchNode.ResourceName; m_PreservePaths[ file ] = matchNode.PreservePath; m_Links[ file ] = matchNode.IsLink; - m_LinkPaths[ file ] = matchNode.LinkPath; - m_CopyToOutputs[ file ] = matchNode.CopyToOutput; + m_LinkPaths[ file ] = matchNode.LinkPath; + m_CopyToOutputs[ file ] = matchNode.CopyToOutput; - } - } - } - } - } + } + } + } + } + } - // TODO: Check in to why StringCollection's enumerator doesn't implement - // IEnumerator? - public IEnumerator GetEnumerator() - { - return m_Files.GetEnumerator(); - } + // TODO: Check in to why StringCollection's enumerator doesn't implement + // IEnumerator? + public IEnumerator GetEnumerator() + { + return m_Files.GetEnumerator(); + } - #endregion + #endregion } } diff --git a/Prebuild/src/Core/Nodes/MatchNode.cs b/Prebuild/src/Core/Nodes/MatchNode.cs index fe02277189..000bde93c4 100644 --- a/Prebuild/src/Core/Nodes/MatchNode.cs +++ b/Prebuild/src/Core/Nodes/MatchNode.cs @@ -5,16 +5,16 @@ Copyright (c) 2004-2005 Matthew Holmes (matthew@wildfiregames.com), Dan Moorehea Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: -* Redistributions of source code must retain the above copyright notice, this list of conditions - and the following disclaimer. -* Redistributions in binary form must reproduce the above copyright notice, this list of conditions - and the following disclaimer in the documentation and/or other materials provided with the - distribution. -* The name of the author may not be used to endorse or promote products derived from this software - without specific prior written permission. +* Redistributions of source code must retain the above copyright notice, this list of conditions + and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions + and the following disclaimer in the documentation and/or other materials provided with the + distribution. +* The name of the author may not be used to endorse or promote products derived from this software + without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, -BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY @@ -35,51 +35,51 @@ using Prebuild.Core.Utilities; namespace Prebuild.Core.Nodes { - /// - /// - /// - [DataNode("Match")] - public class MatchNode : DataNode - { - #region Fields + /// + /// + /// + [DataNode("Match")] + public class MatchNode : DataNode + { + #region Fields private readonly List m_Files = new List(); - private Regex m_Regex; - private BuildAction? m_BuildAction; - private SubType? m_SubType; - string m_ResourceName = ""; - private CopyToOutput m_CopyToOutput; - private bool m_Link; - private string m_LinkPath; + private Regex m_Regex; + private BuildAction? m_BuildAction; + private SubType? m_SubType; + string m_ResourceName = ""; + private CopyToOutput m_CopyToOutput; + private bool m_Link; + private string m_LinkPath; private bool m_PreservePath; private string m_Destination = ""; private readonly List m_Exclusions = new List(); - #endregion + #endregion - #region Properties + #region Properties - /// - /// - /// - public IEnumerable Files - { - get - { - return m_Files; - } - } + /// + /// + /// + public IEnumerable Files + { + get + { + return m_Files; + } + } - /// - /// - /// - public BuildAction? BuildAction - { - get - { - return m_BuildAction; - } - } + /// + /// + /// + public BuildAction? BuildAction + { + get + { + return m_BuildAction; + } + } public string DestinationPath { @@ -88,50 +88,50 @@ namespace Prebuild.Core.Nodes return m_Destination; } } - /// - /// - /// - public SubType? SubType - { - get - { - return m_SubType; - } - } + /// + /// + /// + public SubType? SubType + { + get + { + return m_SubType; + } + } - public CopyToOutput CopyToOutput - { - get - { - return m_CopyToOutput; - } - } + public CopyToOutput CopyToOutput + { + get + { + return m_CopyToOutput; + } + } - public bool IsLink - { - get - { - return m_Link; - } - } + public bool IsLink + { + get + { + return m_Link; + } + } - public string LinkPath - { - get - { - return m_LinkPath; - } - } - /// - /// - /// - public string ResourceName - { - get - { - return m_ResourceName; - } - } + public string LinkPath + { + get + { + return m_LinkPath; + } + } + /// + /// + /// + public string ResourceName + { + get + { + return m_ResourceName; + } + } public bool PreservePath { @@ -141,27 +141,27 @@ namespace Prebuild.Core.Nodes } } - #endregion + #endregion - #region Private Methods + #region Private Methods - /// - /// Recurses the directories. - /// - /// The path. - /// The pattern. - /// if set to true [recurse]. - /// if set to true [use regex]. - private void RecurseDirectories(string path, string pattern, bool recurse, bool useRegex, List exclusions) - { - Match match; - try - { - string[] files; + /// + /// Recurses the directories. + /// + /// The path. + /// The pattern. + /// if set to true [recurse]. + /// if set to true [use regex]. + private void RecurseDirectories(string path, string pattern, bool recurse, bool useRegex, List exclusions) + { + Match match; + try + { + string[] files; - Boolean excludeFile; - if(!useRegex) - { + Boolean excludeFile; + if(!useRegex) + { try { files = Directory.GetFiles(path, pattern); @@ -169,7 +169,7 @@ namespace Prebuild.Core.Nodes catch (IOException) { // swallow weird IOException error when running in a virtual box - // guest OS on a network share when the host OS is not Windows. + // guest OS on a network share when the host OS is not Windows. // This seems to happen on network shares // when no files match, and may be related to this report: // http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=254546 @@ -177,20 +177,20 @@ namespace Prebuild.Core.Nodes files = null; } - if(files != null) - { - foreach (string file in files) - { + if(files != null) + { + foreach (string file in files) + { excludeFile = false; - string fileTemp; - if (file.Substring(0,2) == "./" || file.Substring(0,2) == ".\\") - { - fileTemp = file.Substring(2); - } - else - { - fileTemp = file; - } + string fileTemp; + if (file.Substring(0,2) == "./" || file.Substring(0,2) == ".\\") + { + fileTemp = file.Substring(2); + } + else + { + fileTemp = file; + } // Check all excludions and set flag if there are any hits. foreach ( ExcludeNode exclude in exclusions ) @@ -205,18 +205,18 @@ namespace Prebuild.Core.Nodes m_Files.Add( fileTemp ); } - } - } + } + } // don't call return here, because we may need to recursively search directories below // this one, even if no matches were found in this directory. - } - else - { - try - { - files = Directory.GetFiles(path); - } + } + else + { + try + { + files = Directory.GetFiles(path); + } catch (IOException) { // swallow weird IOException error when running in a virtual box @@ -248,12 +248,12 @@ namespace Prebuild.Core.Nodes } } } - } - - if(recurse) - { - string[] dirs = Directory.GetDirectories(path); - if(dirs != null && dirs.Length > 0) + } + + if(recurse) + { + string[] dirs = Directory.GetDirectories(path); + if(dirs != null && dirs.Length > 0) { foreach (string str in dirs) { @@ -265,96 +265,96 @@ namespace Prebuild.Core.Nodes RecurseDirectories(Helper.NormalizePath(str), pattern, recurse, useRegex, exclusions); } } - } - } - catch(DirectoryNotFoundException) - { - return; - } - catch(ArgumentException) - { - return; - } - } + } + } + catch(DirectoryNotFoundException) + { + return; + } + catch(ArgumentException) + { + return; + } + } - #endregion + #endregion - #region Public Methods + #region Public Methods - /// - /// - /// - /// - public override void Parse(XmlNode node) - { - if( node == null ) - { - throw new ArgumentNullException("node"); - } - string path = Helper.AttributeValue(node, "path", "."); - string pattern = Helper.AttributeValue(node, "pattern", "*"); + /// + /// + /// + /// + public override void Parse(XmlNode node) + { + if( node == null ) + { + throw new ArgumentNullException("node"); + } + string path = Helper.AttributeValue(node, "path", "."); + string pattern = Helper.AttributeValue(node, "pattern", "*"); string destination = Helper.AttributeValue(node, "destination", string.Empty); - bool recurse = (bool)Helper.TranslateValue(typeof(bool), Helper.AttributeValue(node, "recurse", "false")); - bool useRegex = (bool)Helper.TranslateValue(typeof(bool), Helper.AttributeValue(node, "useRegex", "false")); - string buildAction = Helper.AttributeValue(node, "buildAction", String.Empty); - if (buildAction != string.Empty) - m_BuildAction = (BuildAction)Enum.Parse(typeof(BuildAction), buildAction); + bool recurse = (bool)Helper.TranslateValue(typeof(bool), Helper.AttributeValue(node, "recurse", "false")); + bool useRegex = (bool)Helper.TranslateValue(typeof(bool), Helper.AttributeValue(node, "useRegex", "false")); + string buildAction = Helper.AttributeValue(node, "buildAction", String.Empty); + if (buildAction != string.Empty) + m_BuildAction = (BuildAction)Enum.Parse(typeof(BuildAction), buildAction); - //TODO: Figure out where the subtype node is being assigned - //string subType = Helper.AttributeValue(node, "subType", string.Empty); - //if (subType != String.Empty) - // m_SubType = (SubType)Enum.Parse(typeof(SubType), subType); - m_ResourceName = Helper.AttributeValue(node, "resourceName", m_ResourceName); - m_CopyToOutput = (CopyToOutput) Enum.Parse(typeof(CopyToOutput), Helper.AttributeValue(node, "copyToOutput", m_CopyToOutput.ToString())); - m_Link = bool.Parse(Helper.AttributeValue(node, "link", bool.FalseString)); - if ( m_Link ) - { - m_LinkPath = Helper.AttributeValue( node, "linkPath", string.Empty ); - } + //TODO: Figure out where the subtype node is being assigned + //string subType = Helper.AttributeValue(node, "subType", string.Empty); + //if (subType != String.Empty) + // m_SubType = (SubType)Enum.Parse(typeof(SubType), subType); + m_ResourceName = Helper.AttributeValue(node, "resourceName", m_ResourceName); + m_CopyToOutput = (CopyToOutput) Enum.Parse(typeof(CopyToOutput), Helper.AttributeValue(node, "copyToOutput", m_CopyToOutput.ToString())); + m_Link = bool.Parse(Helper.AttributeValue(node, "link", bool.FalseString)); + if ( m_Link ) + { + m_LinkPath = Helper.AttributeValue( node, "linkPath", string.Empty ); + } m_PreservePath = bool.Parse( Helper.AttributeValue( node, "preservePath", bool.FalseString ) ); if ( buildAction == "Copy") m_Destination = destination; - if(path != null && path.Length == 0) - path = ".";//use current directory + if(path != null && path.Length == 0) + path = ".";//use current directory + + //throw new WarningException("Match must have a 'path' attribute"); - //throw new WarningException("Match must have a 'path' attribute"); + if(pattern == null) + { + throw new WarningException("Match must have a 'pattern' attribute"); + } - if(pattern == null) - { - throw new WarningException("Match must have a 'pattern' attribute"); - } + path = Helper.NormalizePath(path); + if(!Directory.Exists(path)) + { + throw new WarningException("Match path does not exist: {0}", path); + } - path = Helper.NormalizePath(path); - if(!Directory.Exists(path)) - { - throw new WarningException("Match path does not exist: {0}", path); - } - - try - { - if(useRegex) - { - m_Regex = new Regex(pattern); - } - } - catch(ArgumentException ex) - { - throw new WarningException("Could not compile regex pattern: {0}", ex.Message); - } + try + { + if(useRegex) + { + m_Regex = new Regex(pattern); + } + } + catch(ArgumentException ex) + { + throw new WarningException("Could not compile regex pattern: {0}", ex.Message); + } - foreach(XmlNode child in node.ChildNodes) - { - IDataNode dataNode = Kernel.Instance.ParseNode(child, this); - if(dataNode is ExcludeNode) - { - ExcludeNode excludeNode = (ExcludeNode)dataNode; + foreach(XmlNode child in node.ChildNodes) + { + IDataNode dataNode = Kernel.Instance.ParseNode(child, this); + if(dataNode is ExcludeNode) + { + ExcludeNode excludeNode = (ExcludeNode)dataNode; m_Exclusions.Add( excludeNode ); - } - } + } + } RecurseDirectories( path, pattern, recurse, useRegex, m_Exclusions ); @@ -371,8 +371,8 @@ namespace Prebuild.Core.Nodes throw new WarningException("Match" + projectName + " returned no files: {0}{1}", Helper.EndPath(path), pattern); } m_Regex = null; - } + } - #endregion - } + #endregion + } } diff --git a/Prebuild/src/Core/Nodes/OptionsNode.cs b/Prebuild/src/Core/Nodes/OptionsNode.cs index d45bd34e57..490fd6f540 100644 --- a/Prebuild/src/Core/Nodes/OptionsNode.cs +++ b/Prebuild/src/Core/Nodes/OptionsNode.cs @@ -5,16 +5,16 @@ Copyright (c) 2004-2005 Matthew Holmes (matthew@wildfiregames.com), Dan Moorehea Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: -* Redistributions of source code must retain the above copyright notice, this list of conditions - and the following disclaimer. -* Redistributions in binary form must reproduce the above copyright notice, this list of conditions - and the following disclaimer in the documentation and/or other materials provided with the - distribution. -* The name of the author may not be used to endorse or promote products derived from this software - without specific prior written permission. +* Redistributions of source code must retain the above copyright notice, this list of conditions + and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions + and the following disclaimer in the documentation and/or other materials provided with the + distribution. +* The name of the author may not be used to endorse or promote products derived from this software + without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, -BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY @@ -34,273 +34,291 @@ using Prebuild.Core.Utilities; namespace Prebuild.Core.Nodes { - /// - /// - /// - [DataNode("Options")] - public class OptionsNode : DataNode - { - #region Fields + /// + /// + /// + [DataNode("Options")] + public class OptionsNode : DataNode + { + #region Fields - private static readonly Dictionary m_OptionFields = new Dictionary(); + private static readonly Dictionary m_OptionFields = new Dictionary(); - [OptionNode("CompilerDefines")] - private string m_CompilerDefines = ""; + [OptionNode("CompilerDefines")] + private string m_CompilerDefines = ""; - /// - /// - /// - public string CompilerDefines - { - get - { - return m_CompilerDefines; - } - set - { - m_CompilerDefines = value; - } - } + /// + /// + /// + public string CompilerDefines + { + get + { + return m_CompilerDefines; + } + set + { + m_CompilerDefines = value; + } + } + + [OptionNode("OptimizeCode")] + private bool m_OptimizeCode; - [OptionNode("OptimizeCode")] - private bool m_OptimizeCode; + /// + /// + /// + public bool OptimizeCode + { + get + { + return m_OptimizeCode; + } + set + { + m_OptimizeCode = value; + } + } + + [OptionNode("CheckUnderflowOverflow")] + private bool m_CheckUnderflowOverflow; - /// - /// - /// - public bool OptimizeCode - { - get - { - return m_OptimizeCode; - } - set - { - m_OptimizeCode = value; - } - } + /// + /// + /// + public bool CheckUnderflowOverflow + { + get + { + return m_CheckUnderflowOverflow; + } + set + { + m_CheckUnderflowOverflow = value; + } + } + + [OptionNode("AllowUnsafe")] + private bool m_AllowUnsafe; - [OptionNode("CheckUnderflowOverflow")] - private bool m_CheckUnderflowOverflow; + /// + /// + /// + public bool AllowUnsafe + { + get + { + return m_AllowUnsafe; + } + set + { + m_AllowUnsafe = value; + } + } + + [OptionNode("PreBuildEvent")] + private string m_PreBuildEvent; + + /// + /// + /// + public string PreBuildEvent + { + get + { + return m_PreBuildEvent; + } + set + { + m_PreBuildEvent = value; + } + } + + [OptionNode("PostBuildEvent")] + private string m_PostBuildEvent; + + /// + /// + /// + public string PostBuildEvent + { + get + { + return m_PostBuildEvent; + } + set + { + m_PostBuildEvent = value; + } + } + + [OptionNode("PreBuildEventArgs")] + private string m_PreBuildEventArgs; + + /// + /// + /// + public string PreBuildEventArgs + { + get + { + return m_PreBuildEventArgs; + } + set + { + m_PreBuildEventArgs = value; + } + } + + [OptionNode("PostBuildEventArgs")] + private string m_PostBuildEventArgs; + + /// + /// + /// + public string PostBuildEventArgs + { + get + { + return m_PostBuildEventArgs; + } + set + { + m_PostBuildEventArgs = value; + } + } + + [OptionNode("RunPostBuildEvent")] + private string m_RunPostBuildEvent; + + /// + /// + /// + public string RunPostBuildEvent + { + get + { + return m_RunPostBuildEvent; + } + set + { + m_RunPostBuildEvent = value; + } + } + + [OptionNode("RunScript")] + private string m_RunScript; + + /// + /// + /// + public string RunScript + { + get + { + return m_RunScript; + } + set + { + m_RunScript = value; + } + } + + [OptionNode("WarningLevel")] + private int m_WarningLevel = 4; - /// - /// - /// - public bool CheckUnderflowOverflow - { - get - { - return m_CheckUnderflowOverflow; - } - set - { - m_CheckUnderflowOverflow = value; - } - } + /// + /// + /// + public int WarningLevel + { + get + { + return m_WarningLevel; + } + set + { + m_WarningLevel = value; + } + } + + [OptionNode("WarningsAsErrors")] + private bool m_WarningsAsErrors; - [OptionNode("AllowUnsafe")] - private bool m_AllowUnsafe; + /// + /// + /// + public bool WarningsAsErrors + { + get + { + return m_WarningsAsErrors; + } + set + { + m_WarningsAsErrors = value; + } + } - /// - /// - /// - public bool AllowUnsafe - { - get - { - return m_AllowUnsafe; - } - set - { - m_AllowUnsafe = value; - } - } + [OptionNode("SuppressWarnings")] + private string m_SuppressWarnings = ""; - [OptionNode("PreBuildEvent")] - private string m_PreBuildEvent; + /// + /// + /// + public string SuppressWarnings + { + get + { + return m_SuppressWarnings; + } + set + { + m_SuppressWarnings = value; + } + } - /// - /// - /// - public string PreBuildEvent - { - get - { - return m_PreBuildEvent; - } - set - { - m_PreBuildEvent = value; - } - } + [OptionNode("Prefer32Bit")] + private bool m_Prefer32Bit; - [OptionNode("PostBuildEvent")] - private string m_PostBuildEvent; + /// + /// + /// + public bool Prefer32Bit + { + get + { + return m_Prefer32Bit; + } + set + { + m_Prefer32Bit = value; + } + } + + [OptionNode("OutputPath")] + private string m_OutputPath = "bin/"; - /// - /// - /// - public string PostBuildEvent - { - get - { - return m_PostBuildEvent; - } - set - { - m_PostBuildEvent = value; - } - } - - [OptionNode("PreBuildEventArgs")] - private string m_PreBuildEventArgs; - - /// - /// - /// - public string PreBuildEventArgs - { - get - { - return m_PreBuildEventArgs; - } - set - { - m_PreBuildEventArgs = value; - } - } - - [OptionNode("PostBuildEventArgs")] - private string m_PostBuildEventArgs; - - /// - /// - /// - public string PostBuildEventArgs - { - get - { - return m_PostBuildEventArgs; - } - set - { - m_PostBuildEventArgs = value; - } - } - - [OptionNode("RunPostBuildEvent")] - private string m_RunPostBuildEvent; - - /// - /// - /// - public string RunPostBuildEvent - { - get - { - return m_RunPostBuildEvent; - } - set - { - m_RunPostBuildEvent = value; - } - } - - [OptionNode("RunScript")] - private string m_RunScript; - - /// - /// - /// - public string RunScript - { - get - { - return m_RunScript; - } - set - { - m_RunScript = value; - } - } - - [OptionNode("WarningLevel")] - private int m_WarningLevel = 4; - - /// - /// - /// - public int WarningLevel - { - get - { - return m_WarningLevel; - } - set - { - m_WarningLevel = value; - } - } - - [OptionNode("WarningsAsErrors")] - private bool m_WarningsAsErrors; - - /// - /// - /// - public bool WarningsAsErrors - { - get - { - return m_WarningsAsErrors; - } - set - { - m_WarningsAsErrors = value; - } - } - - [OptionNode("SuppressWarnings")] - private string m_SuppressWarnings = ""; - - /// - /// - /// - public string SuppressWarnings - { - get - { - return m_SuppressWarnings; - } - set - { - m_SuppressWarnings = value; - } - } - - [OptionNode("OutputPath")] - private string m_OutputPath = "bin/"; - - /// - /// - /// - public string OutputPath - { - get - { - return m_OutputPath; - } - set - { - m_OutputPath = value; - } - } + /// + /// + /// + public string OutputPath + { + get + { + return m_OutputPath; + } + set + { + m_OutputPath = value; + } + } [OptionNode("GenerateDocumentation")] private bool m_GenerateDocumentation; /// - /// + /// /// public bool GenerateDocumentation { @@ -314,321 +332,321 @@ namespace Prebuild.Core.Nodes } } - [OptionNode("GenerateXmlDocFile")] - private bool m_GenerateXmlDocFile; + [OptionNode("GenerateXmlDocFile")] + private bool m_GenerateXmlDocFile; - /// - /// - /// - public bool GenerateXmlDocFile - { - get - { - return m_GenerateXmlDocFile; - } - set - { - m_GenerateXmlDocFile = value; - } - } + /// + /// + /// + public bool GenerateXmlDocFile + { + get + { + return m_GenerateXmlDocFile; + } + set + { + m_GenerateXmlDocFile = value; + } + } + + [OptionNode("XmlDocFile")] + private string m_XmlDocFile = ""; - [OptionNode("XmlDocFile")] - private string m_XmlDocFile = ""; + /// + /// + /// + public string XmlDocFile + { + get + { + return m_XmlDocFile; + } + set + { + m_XmlDocFile = value; + } + } - /// - /// - /// - public string XmlDocFile - { - get - { - return m_XmlDocFile; - } - set - { - m_XmlDocFile = value; - } - } + [OptionNode("KeyFile")] + private string m_KeyFile = ""; - [OptionNode("KeyFile")] - private string m_KeyFile = ""; + /// + /// + /// + public string KeyFile + { + get + { + return m_KeyFile; + } + set + { + m_KeyFile = value; + } + } + + [OptionNode("DebugInformation")] + private bool m_DebugInformation; - /// - /// - /// - public string KeyFile - { - get - { - return m_KeyFile; - } - set - { - m_KeyFile = value; - } - } + /// + /// + /// + public bool DebugInformation + { + get + { + return m_DebugInformation; + } + set + { + m_DebugInformation = value; + } + } + + [OptionNode("RegisterComInterop")] + private bool m_RegisterComInterop; - [OptionNode("DebugInformation")] - private bool m_DebugInformation; + /// + /// + /// + public bool RegisterComInterop + { + get + { + return m_RegisterComInterop; + } + set + { + m_RegisterComInterop = value; + } + } - /// - /// - /// - public bool DebugInformation - { - get - { - return m_DebugInformation; - } - set - { - m_DebugInformation = value; - } - } + [OptionNode("RemoveIntegerChecks")] + private bool m_RemoveIntegerChecks; - [OptionNode("RegisterComInterop")] - private bool m_RegisterComInterop; + /// + /// + /// + public bool RemoveIntegerChecks + { + get + { + return m_RemoveIntegerChecks; + } + set + { + m_RemoveIntegerChecks = value; + } + } + + [OptionNode("IncrementalBuild")] + private bool m_IncrementalBuild; - /// - /// - /// - public bool RegisterComInterop - { - get - { - return m_RegisterComInterop; - } - set - { - m_RegisterComInterop = value; - } - } + /// + /// + /// + public bool IncrementalBuild + { + get + { + return m_IncrementalBuild; + } + set + { + m_IncrementalBuild = value; + } + } + + [OptionNode("BaseAddress")] + private string m_BaseAddress = "285212672"; - [OptionNode("RemoveIntegerChecks")] - private bool m_RemoveIntegerChecks; + /// + /// + /// + public string BaseAddress + { + get + { + return m_BaseAddress; + } + set + { + m_BaseAddress = value; + } + } + + [OptionNode("FileAlignment")] + private int m_FileAlignment = 4096; - /// - /// - /// - public bool RemoveIntegerChecks - { - get - { - return m_RemoveIntegerChecks; - } - set - { - m_RemoveIntegerChecks = value; - } - } + /// + /// + /// + public int FileAlignment + { + get + { + return m_FileAlignment; + } + set + { + m_FileAlignment = value; + } + } + + [OptionNode("NoStdLib")] + private bool m_NoStdLib; - [OptionNode("IncrementalBuild")] - private bool m_IncrementalBuild; + /// + /// + /// + public bool NoStdLib + { + get + { + return m_NoStdLib; + } + set + { + m_NoStdLib = value; + } + } - /// - /// - /// - public bool IncrementalBuild - { - get - { - return m_IncrementalBuild; - } - set - { - m_IncrementalBuild = value; - } - } + private readonly List m_FieldsDefined = new List(); - [OptionNode("BaseAddress")] - private string m_BaseAddress = "285212672"; + #endregion - /// - /// - /// - public string BaseAddress - { - get - { - return m_BaseAddress; - } - set - { - m_BaseAddress = value; - } - } + #region Constructors - [OptionNode("FileAlignment")] - private int m_FileAlignment = 4096; + /// + /// Initializes the class. + /// + static OptionsNode() + { + Type t = typeof(OptionsNode); + + foreach(FieldInfo f in t.GetFields(BindingFlags.NonPublic | BindingFlags.Instance)) + { + object[] attrs = f.GetCustomAttributes(typeof(OptionNodeAttribute), false); + if(attrs == null || attrs.Length < 1) + { + continue; + } - /// - /// - /// - public int FileAlignment - { - get - { - return m_FileAlignment; - } - set - { - m_FileAlignment = value; - } - } + OptionNodeAttribute ona = (OptionNodeAttribute)attrs[0]; + m_OptionFields[ona.NodeName] = f; + } + } - [OptionNode("NoStdLib")] - private bool m_NoStdLib; + #endregion - /// - /// - /// - public bool NoStdLib - { - get - { - return m_NoStdLib; - } - set - { - m_NoStdLib = value; - } - } + #region Properties - private readonly List m_FieldsDefined = new List(); + /// + /// Gets the at the specified index. + /// + /// + public object this[string index] + { + get + { + if(!m_OptionFields.ContainsKey(index)) + { + return null; + } - #endregion - - #region Constructors - - /// - /// Initializes the class. - /// - static OptionsNode() - { - Type t = typeof(OptionsNode); - - foreach(FieldInfo f in t.GetFields(BindingFlags.NonPublic | BindingFlags.Instance)) - { - object[] attrs = f.GetCustomAttributes(typeof(OptionNodeAttribute), false); - if(attrs == null || attrs.Length < 1) - { - continue; - } - - OptionNodeAttribute ona = (OptionNodeAttribute)attrs[0]; - m_OptionFields[ona.NodeName] = f; - } - } - - #endregion - - #region Properties - - /// - /// Gets the at the specified index. - /// - /// - public object this[string index] - { - get - { - if(!m_OptionFields.ContainsKey(index)) - { - return null; - } - - FieldInfo f = m_OptionFields[index]; - return f.GetValue(this); - } - } - - /// - /// Gets the at the specified index. - /// - /// - public object this[string index, object defaultValue] - { - get - { - object valueObject = this[index]; - if(valueObject != null && valueObject is string && ((string)valueObject).Length == 0) - { - return defaultValue; - } - return valueObject; - } - } + FieldInfo f = m_OptionFields[index]; + return f.GetValue(this); + } + } + + /// + /// Gets the at the specified index. + /// + /// + public object this[string index, object defaultValue] + { + get + { + object valueObject = this[index]; + if(valueObject != null && valueObject is string && ((string)valueObject).Length == 0) + { + return defaultValue; + } + return valueObject; + } + } - #endregion + #endregion - #region Private Methods + #region Private Methods - private void FlagDefined(string name) - { - if(!m_FieldsDefined.Contains(name)) - { - m_FieldsDefined.Add(name); - } - } + private void FlagDefined(string name) + { + if(!m_FieldsDefined.Contains(name)) + { + m_FieldsDefined.Add(name); + } + } - private void SetOption(string nodeName, string val) - { - lock(m_OptionFields) - { - if(!m_OptionFields.ContainsKey(nodeName)) - { - return; - } + private void SetOption(string nodeName, string val) + { + lock(m_OptionFields) + { + if(!m_OptionFields.ContainsKey(nodeName)) + { + return; + } - FieldInfo f = m_OptionFields[nodeName]; - f.SetValue(this, Helper.TranslateValue(f.FieldType, val)); - FlagDefined(f.Name); - } - } + FieldInfo f = m_OptionFields[nodeName]; + f.SetValue(this, Helper.TranslateValue(f.FieldType, val)); + FlagDefined(f.Name); + } + } - #endregion + #endregion - #region Public Methods + #region Public Methods - /// - /// Parses the specified node. - /// - /// The node. - public override void Parse(XmlNode node) - { - if( node == null ) - { - throw new ArgumentNullException("node"); - } + /// + /// Parses the specified node. + /// + /// The node. + public override void Parse(XmlNode node) + { + if( node == null ) + { + throw new ArgumentNullException("node"); + } - foreach(XmlNode child in node.ChildNodes) - { - SetOption(child.Name, Helper.InterpolateForEnvironmentVariables(child.InnerText)); - } - } + foreach(XmlNode child in node.ChildNodes) + { + SetOption(child.Name, Helper.InterpolateForEnvironmentVariables(child.InnerText)); + } + } - /// - /// Copies to. - /// - /// The opt. - public void CopyTo(OptionsNode opt) - { - if(opt == null) - { - return; - } + /// + /// Copies to. + /// + /// The opt. + public void CopyTo(OptionsNode opt) + { + if(opt == null) + { + return; + } - foreach(FieldInfo f in m_OptionFields.Values) - { - if(m_FieldsDefined.Contains(f.Name)) - { - f.SetValue(opt, f.GetValue(this)); - opt.m_FieldsDefined.Add(f.Name); - } - } - } + foreach(FieldInfo f in m_OptionFields.Values) + { + if(m_FieldsDefined.Contains(f.Name)) + { + f.SetValue(opt, f.GetValue(this)); + opt.m_FieldsDefined.Add(f.Name); + } + } + } - #endregion - } + #endregion + } } diff --git a/Prebuild/src/Core/Nodes/ProcessNode.cs b/Prebuild/src/Core/Nodes/ProcessNode.cs index b05ffc60f7..8ca8e493d2 100644 --- a/Prebuild/src/Core/Nodes/ProcessNode.cs +++ b/Prebuild/src/Core/Nodes/ProcessNode.cs @@ -5,16 +5,16 @@ Copyright (c) 2004-2005 Matthew Holmes (matthew@wildfiregames.com), Dan Moorehea Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: -* Redistributions of source code must retain the above copyright notice, this list of conditions - and the following disclaimer. -* Redistributions in binary form must reproduce the above copyright notice, this list of conditions - and the following disclaimer in the documentation and/or other materials provided with the - distribution. -* The name of the author may not be used to endorse or promote products derived from this software - without specific prior written permission. +* Redistributions of source code must retain the above copyright notice, this list of conditions + and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions + and the following disclaimer in the documentation and/or other materials provided with the + distribution. +* The name of the author may not be used to endorse or promote products derived from this software + without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, -BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY @@ -32,77 +32,77 @@ using Prebuild.Core.Utilities; namespace Prebuild.Core.Nodes { - /// - /// - /// - [DataNode("Process")] - public class ProcessNode : DataNode - { - #region Fields + /// + /// + /// + [DataNode("Process")] + public class ProcessNode : DataNode + { + #region Fields - private string m_Path; - private bool m_IsValid = true; + private string m_Path; + private bool m_IsValid = true; - #endregion + #endregion - #region Properties + #region Properties - /// - /// Gets the path. - /// - /// The path. - public string Path - { - get - { - return m_Path; - } - } + /// + /// Gets the path. + /// + /// The path. + public string Path + { + get + { + return m_Path; + } + } - /// - /// Gets a value indicating whether this instance is valid. - /// - /// true if this instance is valid; otherwise, false. - public bool IsValid - { - get - { - return m_IsValid; - } - } + /// + /// Gets a value indicating whether this instance is valid. + /// + /// true if this instance is valid; otherwise, false. + public bool IsValid + { + get + { + return m_IsValid; + } + } - #endregion + #endregion - #region Public Methods + #region Public Methods - /// - /// Parses the specified node. - /// - /// The node. - public override void Parse(XmlNode node) - { - if( node == null ) - { - throw new ArgumentNullException("node"); - } + /// + /// Parses the specified node. + /// + /// The node. + public override void Parse(XmlNode node) + { + if( node == null ) + { + throw new ArgumentNullException("node"); + } - m_Path = Helper.InterpolateForEnvironmentVariables(node.InnerText); - if(m_Path == null) - { - m_Path = ""; - } + m_Path = Helper.InterpolateForEnvironmentVariables(node.InnerText); + if(m_Path == null) + { + m_Path = ""; + } - try - { - m_Path = Helper.ResolvePath(m_Path); - } - catch(ArgumentException) - { - Kernel.Instance.Log.Write(LogType.Warning, "Could not find prebuild file for processing: {0}", m_Path); - m_IsValid = false; - } - } + try + { + m_Path = Helper.ResolvePath(m_Path); + } + catch(ArgumentException) + { + Kernel.Instance.Log.Write(LogType.Warning, "Could not find prebuild file for processing: {0}", m_Path); + m_IsValid = false; + } + } - #endregion - } + #endregion + } } diff --git a/Prebuild/src/Core/Nodes/ProjectNode.cs b/Prebuild/src/Core/Nodes/ProjectNode.cs index e02b11bc03..9622d896d5 100644 --- a/Prebuild/src/Core/Nodes/ProjectNode.cs +++ b/Prebuild/src/Core/Nodes/ProjectNode.cs @@ -5,16 +5,16 @@ Copyright (c) 2004-2005 Matthew Holmes (matthew@wildfiregames.com), Dan Moorehea Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: -* Redistributions of source code must retain the above copyright notice, this list of conditions - and the following disclaimer. -* Redistributions in binary form must reproduce the above copyright notice, this list of conditions - and the following disclaimer in the documentation and/or other materials provided with the - distribution. -* The name of the author may not be used to endorse or promote products derived from this software - without specific prior written permission. +* Redistributions of source code must retain the above copyright notice, this list of conditions + and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions + and the following disclaimer in the documentation and/or other materials provided with the + distribution. +* The name of the author may not be used to endorse or promote products derived from this software + without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, -BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY @@ -34,65 +34,65 @@ using Prebuild.Core.Utilities; namespace Prebuild.Core.Nodes { - /// - /// A set of values that the Project's type can be - /// - public enum ProjectType - { + /// + /// A set of values that the Project's type can be + /// + public enum ProjectType + { + /// + /// The project is a console executable + /// + Exe, + /// + /// The project is a windows executable + /// + WinExe, + /// + /// The project is a library + /// + Library, /// - /// The project is a console executable - /// - Exe, - /// - /// The project is a windows executable - /// - WinExe, - /// - /// The project is a library - /// - Library, - /// - /// The project is a website - /// - Web, - } + /// The project is a website + /// + Web, + } - /// - /// - /// - public enum ClrRuntime - { - /// - /// - /// - Microsoft, - /// - /// - /// - Mono - } - /// - /// The version of the .NET framework to use (Required for VS2008) - /// We don't need .NET 1.1 in here, it'll default when using vs2003. - /// - public enum FrameworkVersion - { - /// - /// .NET 2.0 - /// - v2_0, - /// - /// .NET 3.0 - /// - v3_0, - /// - /// .NET 3.5 - /// - v3_5, - /// - /// .NET 4.0 - /// - v4_0, + /// + /// + /// + public enum ClrRuntime + { + /// + /// + /// + Microsoft, + /// + /// + /// + Mono + } + /// + /// The version of the .NET framework to use (Required for VS2008) + /// We don't need .NET 1.1 in here, it'll default when using vs2003. + /// + public enum FrameworkVersion + { + /// + /// .NET 2.0 + /// + v2_0, + /// + /// .NET 3.0 + /// + v3_0, + /// + /// .NET 3.5 + /// + v3_5, + /// + /// .NET 4.0 + /// + v4_0, /// /// .NET 4.5 /// @@ -100,124 +100,139 @@ namespace Prebuild.Core.Nodes /// /// .NET 4.5.1 /// - v4_5_1 + v4_5_1, + /// + /// .NET 4.6 + /// + v4_6, + /// + /// .NET 4.6.1 + /// + v4_6_1 } - /// - /// The Node object representing /Prebuild/Solution/Project elements - /// - [DataNode("Project")] - public class ProjectNode : DataNode, IComparable - { - #region Fields + /// + /// The Node object representing /Prebuild/Solution/Project elements + /// + [DataNode("Project")] + public class ProjectNode : DataNode, IComparable + { + #region Fields - private string m_Name = "unknown"; - private string m_Path = ""; - private string m_FullPath = ""; - private string m_AssemblyName; - private string m_AppIcon = ""; + private string m_Name = "unknown"; + private string m_Path = ""; + private string m_FullPath = ""; + private string m_AssemblyName; + private string m_AppIcon = ""; + private string m_ApplicationManifest = ""; private string m_ConfigFile = ""; - private string m_DesignerFolder = ""; - private string m_Language = "C#"; - private ProjectType m_Type = ProjectType.Exe; - private ClrRuntime m_Runtime = ClrRuntime.Microsoft; + private string m_DesignerFolder = ""; + private string m_Language = "C#"; + private ProjectType m_Type = ProjectType.Exe; + private ClrRuntime m_Runtime = ClrRuntime.Microsoft; private FrameworkVersion m_Framework = FrameworkVersion.v2_0; - private string m_StartupObject = ""; - private string m_RootNamespace; - private string m_FilterGroups = ""; - private string m_Version = ""; - private Guid m_Guid; + private bool m_useFramework = true; + private string m_StartupObject = ""; + private string m_RootNamespace; + private string m_FilterGroups = ""; + private string m_Version = ""; + private Guid m_Guid; private string m_DebugStartParameters; private readonly Dictionary m_Configurations = new Dictionary(); private readonly List m_ReferencePaths = new List(); - private readonly List m_References = new List(); + private readonly List m_References = new List(); private readonly List m_Authors = new List(); - private FilesNode m_Files; + private FilesNode m_Files; - #endregion + #endregion - #region Properties + #region Properties - /// - /// Gets the name. - /// - /// The name. - public string Name - { - get + /// + /// Gets the name. + /// + /// The name. + public string Name + { + get + { + return m_Name; + } + } + /// + /// The version of the .NET Framework to compile under + /// + public FrameworkVersion FrameworkVersion + { + get + { + return m_Framework; + } + set { - return m_Name; + m_Framework = value; + m_useFramework = false; } - } - /// - /// The version of the .NET Framework to compile under - /// - public FrameworkVersion FrameworkVersion - { - get - { - return m_Framework; - } - } - /// - /// Gets the path. - /// - /// The path. - public string Path - { - get - { - return m_Path; - } - } + } + /// + /// Gets the path. + /// + /// The path. + public string Path + { + get + { + return m_Path; + } + } - /// - /// Gets the filter groups. - /// - /// The filter groups. - public string FilterGroups - { - get - { - return m_FilterGroups; - } - } + /// + /// Gets the filter groups. + /// + /// The filter groups. + public string FilterGroups + { + get + { + return m_FilterGroups; + } + } - /// - /// Gets the project's version - /// - /// The project's version. - public string Version - { - get - { - return m_Version; - } - } + /// + /// Gets the project's version + /// + /// The project's version. + public string Version + { + get + { + return m_Version; + } + } - /// - /// Gets the full path. - /// - /// The full path. - public string FullPath - { - get - { - return m_FullPath; - } - } + /// + /// Gets the full path. + /// + /// The full path. + public string FullPath + { + get + { + return m_FullPath; + } + } - /// - /// Gets the name of the assembly. - /// - /// The name of the assembly. - public string AssemblyName - { - get - { - return m_AssemblyName; - } - } + /// + /// Gets the name of the assembly. + /// + /// The name of the assembly. + public string AssemblyName + { + get + { + return m_AssemblyName; + } + } /// /// Gets the app icon. @@ -232,347 +247,362 @@ namespace Prebuild.Core.Nodes } /// - /// Gets the app icon. + /// Gets the Application Manifest. /// - /// The app icon. - public string ConfigFile + /// The Application Manifest. + public string ApplicationManifest { get { - return m_ConfigFile; + return m_ApplicationManifest; } } - /// - /// - /// - public string DesignerFolder - { - get - { - return m_DesignerFolder; - } - } + /// + /// Gets the app icon. + /// + /// The app icon. + public string ConfigFile + { + get + { + return m_ConfigFile; + } + } - /// - /// Gets the language. - /// - /// The language. - public string Language - { - get - { - return m_Language; - } - } + /// + /// + /// + public string DesignerFolder + { + get + { + return m_DesignerFolder; + } + } - /// - /// Gets the type. - /// - /// The type. - public ProjectType Type - { - get - { - return m_Type; - } - } + /// + /// Gets the language. + /// + /// The language. + public string Language + { + get + { + return m_Language; + } + } - /// - /// Gets the runtime. - /// - /// The runtime. - public ClrRuntime Runtime - { - get - { - return m_Runtime; - } - } + /// + /// Gets the type. + /// + /// The type. + public ProjectType Type + { + get + { + return m_Type; + } + } - private bool m_GenerateAssemblyInfoFile; + /// + /// Gets the runtime. + /// + /// The runtime. + public ClrRuntime Runtime + { + get + { + return m_Runtime; + } + } - /// - /// - /// - public bool GenerateAssemblyInfoFile - { - get - { - return m_GenerateAssemblyInfoFile; - } - set - { - m_GenerateAssemblyInfoFile = value; - } - } + private bool m_GenerateAssemblyInfoFile; + + /// + /// + /// + public bool GenerateAssemblyInfoFile + { + get + { + return m_GenerateAssemblyInfoFile; + } + set + { + m_GenerateAssemblyInfoFile = value; + } + } - /// - /// Gets the startup object. - /// - /// The startup object. - public string StartupObject - { - get - { - return m_StartupObject; - } - } + /// + /// Gets the startup object. + /// + /// The startup object. + public string StartupObject + { + get + { + return m_StartupObject; + } + } - /// - /// Gets the root namespace. - /// - /// The root namespace. - public string RootNamespace - { - get - { - return m_RootNamespace; - } - } + /// + /// Gets the root namespace. + /// + /// The root namespace. + public string RootNamespace + { + get + { + return m_RootNamespace; + } + } - /// - /// Gets the configurations. - /// - /// The configurations. + /// + /// Gets the configurations. + /// + /// The configurations. public List Configurations - { - get - { - List tmp = new List(ConfigurationsTable.Values); + { + get + { + List tmp = new List(ConfigurationsTable.Values); tmp.Sort(); return tmp; - } - } + } + } - /// - /// Gets the configurations table. - /// - /// The configurations table. - public Dictionary ConfigurationsTable - { - get - { - return m_Configurations; - } - } + /// + /// Gets the configurations table. + /// + /// The configurations table. + public Dictionary ConfigurationsTable + { + get + { + return m_Configurations; + } + } - /// - /// Gets the reference paths. - /// - /// The reference paths. - public List ReferencePaths - { - get - { + /// + /// Gets the reference paths. + /// + /// The reference paths. + public List ReferencePaths + { + get + { List tmp = new List(m_ReferencePaths); tmp.Sort(); return tmp; - } - } + } + } - /// - /// Gets the references. - /// - /// The references. + /// + /// Gets the references. + /// + /// The references. public List References - { - get - { + { + get + { List tmp = new List(m_References); tmp.Sort(); return tmp; - } - } + } + } + + /// + /// Gets the Authors list. + /// + /// The list of the project's authors. + public List Authors + { + get + { + return m_Authors; + } + } - /// - /// Gets the Authors list. - /// - /// The list of the project's authors. - public List Authors - { - get - { - return m_Authors; - } - } + /// + /// Gets the files. + /// + /// The files. + public FilesNode Files + { + get + { + return m_Files; + } + } - /// - /// Gets the files. - /// - /// The files. - public FilesNode Files - { - get - { - return m_Files; - } - } + /// + /// Gets or sets the parent. + /// + /// The parent. + public override IDataNode Parent + { + get + { + return base.Parent; + } + set + { + base.Parent = value; + if(base.Parent is SolutionNode && m_Configurations.Count < 1) + { + SolutionNode parent = (SolutionNode)base.Parent; + foreach(ConfigurationNode conf in parent.Configurations) + { + m_Configurations[conf.NameAndPlatform] = (ConfigurationNode) conf.Clone(); + } + } + } + } - /// - /// Gets or sets the parent. - /// - /// The parent. - public override IDataNode Parent - { - get - { - return base.Parent; - } - set - { - base.Parent = value; - if(base.Parent is SolutionNode && m_Configurations.Count < 1) - { - SolutionNode parent = (SolutionNode)base.Parent; - foreach(ConfigurationNode conf in parent.Configurations) - { - m_Configurations[conf.NameAndPlatform] = (ConfigurationNode) conf.Clone(); - } - } - } - } + /// + /// Gets the GUID. + /// + /// The GUID. + public Guid Guid + { + get + { + return m_Guid; + } + } - /// - /// Gets the GUID. - /// - /// The GUID. - public Guid Guid - { - get - { - return m_Guid; - } - } - - public string DebugStartParameters - { + public string DebugStartParameters + { get { return m_DebugStartParameters; } - } + } - #endregion + #endregion - #region Private Methods + #region Private Methods - private void HandleConfiguration(ConfigurationNode conf) - { - if(String.Compare(conf.Name, "all", true) == 0) //apply changes to all, this may not always be applied first, - //so it *may* override changes to the same properties for configurations defines at the project level - { - foreach(ConfigurationNode confNode in m_Configurations.Values) - { - conf.CopyTo(confNode);//update the config templates defines at the project level with the overrides - } - } - if(m_Configurations.ContainsKey(conf.NameAndPlatform)) - { - ConfigurationNode parentConf = m_Configurations[conf.NameAndPlatform]; - conf.CopyTo(parentConf);//update the config templates defines at the project level with the overrides - } - else - { - m_Configurations[conf.NameAndPlatform] = conf; - } - } + private void HandleConfiguration(ConfigurationNode conf) + { + if(String.Compare(conf.Name, "all", true) == 0) //apply changes to all, this may not always be applied first, + //so it *may* override changes to the same properties for configurations defines at the project level + { + foreach(ConfigurationNode confNode in m_Configurations.Values) + { + conf.CopyTo(confNode);//update the config templates defines at the project level with the overrides + } + } + if(m_Configurations.ContainsKey(conf.NameAndPlatform)) + { + ConfigurationNode parentConf = m_Configurations[conf.NameAndPlatform]; + conf.CopyTo(parentConf);//update the config templates defines at the project level with the overrides + } + else + { + m_Configurations[conf.NameAndPlatform] = conf; + } + } - #endregion + #endregion - #region Public Methods + #region Public Methods - /// - /// Parses the specified node. - /// - /// The node. - public override void Parse(XmlNode node) - { - m_Name = Helper.AttributeValue(node, "name", m_Name); - m_Path = Helper.AttributeValue(node, "path", m_Path); - m_FilterGroups = Helper.AttributeValue(node, "filterGroups", m_FilterGroups); + /// + /// Parses the specified node. + /// + /// The node. + public override void Parse(XmlNode node) + { + m_Name = Helper.AttributeValue(node, "name", m_Name); + m_Path = Helper.AttributeValue(node, "path", m_Path); + m_FilterGroups = Helper.AttributeValue(node, "filterGroups", m_FilterGroups); m_Version = Helper.AttributeValue(node, "version", m_Version); m_AppIcon = Helper.AttributeValue(node, "icon", m_AppIcon); + m_ApplicationManifest = Helper.AttributeValue(node, "appmanifest", m_ApplicationManifest); m_ConfigFile = Helper.AttributeValue(node, "configFile", m_ConfigFile); - m_DesignerFolder = Helper.AttributeValue(node, "designerFolder", m_DesignerFolder); - m_AssemblyName = Helper.AttributeValue(node, "assemblyName", m_AssemblyName); - m_Language = Helper.AttributeValue(node, "language", m_Language); - m_Type = (ProjectType)Helper.EnumAttributeValue(node, "type", typeof(ProjectType), m_Type); - m_Runtime = (ClrRuntime)Helper.EnumAttributeValue(node, "runtime", typeof(ClrRuntime), m_Runtime); - m_Framework = (FrameworkVersion)Helper.EnumAttributeValue(node, "frameworkVersion", typeof(FrameworkVersion), m_Framework); + m_DesignerFolder = Helper.AttributeValue(node, "designerFolder", m_DesignerFolder); + m_AssemblyName = Helper.AttributeValue(node, "assemblyName", m_AssemblyName); + m_Language = Helper.AttributeValue(node, "language", m_Language); + m_Type = (ProjectType)Helper.EnumAttributeValue(node, "type", typeof(ProjectType), m_Type); + m_Runtime = (ClrRuntime)Helper.EnumAttributeValue(node, "runtime", typeof(ClrRuntime), m_Runtime); + if(m_useFramework) + m_Framework = (FrameworkVersion)Helper.EnumAttributeValue(node, "frameworkVersion", typeof(FrameworkVersion), m_Framework); + m_StartupObject = Helper.AttributeValue(node, "startupObject", m_StartupObject); - m_RootNamespace = Helper.AttributeValue(node, "rootNamespace", m_RootNamespace); - + m_RootNamespace = Helper.AttributeValue(node, "rootNamespace", m_RootNamespace); + int hash = m_Name.GetHashCode(); - Guid guidByHash = new Guid(hash, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - string guid = Helper.AttributeValue(node, "guid", guidByHash.ToString()); - m_Guid = new Guid(guid); + Guid guidByHash = new Guid(hash, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + string guid = Helper.AttributeValue(node, "guid", guidByHash.ToString()); + m_Guid = new Guid(guid); m_GenerateAssemblyInfoFile = Helper.ParseBoolean(node, "generateAssemblyInfoFile", false); - m_DebugStartParameters = Helper.AttributeValue(node, "debugStartParameters", string.Empty); + m_DebugStartParameters = Helper.AttributeValue(node, "debugStartParameters", string.Empty); + + if(string.IsNullOrEmpty(m_AssemblyName)) + { + m_AssemblyName = m_Name; + } - if(string.IsNullOrEmpty(m_AssemblyName)) - { - m_AssemblyName = m_Name; - } + if(string.IsNullOrEmpty(m_RootNamespace)) + { + m_RootNamespace = m_Name; + } - if(string.IsNullOrEmpty(m_RootNamespace)) - { - m_RootNamespace = m_Name; - } + m_FullPath = m_Path; + try + { + m_FullPath = Helper.ResolvePath(m_FullPath); + } + catch + { + throw new WarningException("Could not resolve Solution path: {0}", m_Path); + } - m_FullPath = m_Path; - try - { - m_FullPath = Helper.ResolvePath(m_FullPath); - } - catch - { - throw new WarningException("Could not resolve Solution path: {0}", m_Path); - } + Kernel.Instance.CurrentWorkingDirectory.Push(); + try + { + Helper.SetCurrentDir(m_FullPath); - Kernel.Instance.CurrentWorkingDirectory.Push(); - try - { - Helper.SetCurrentDir(m_FullPath); + if( node == null ) + { + throw new ArgumentNullException("node"); + } - if( node == null ) - { - throw new ArgumentNullException("node"); - } - - foreach(XmlNode child in node.ChildNodes) - { - IDataNode dataNode = Kernel.Instance.ParseNode(child, this); - if(dataNode is ConfigurationNode) - { - HandleConfiguration((ConfigurationNode)dataNode); - } - else if(dataNode is ReferencePathNode) - { + foreach(XmlNode child in node.ChildNodes) + { + IDataNode dataNode = Kernel.Instance.ParseNode(child, this); + if(dataNode is ConfigurationNode) + { + HandleConfiguration((ConfigurationNode)dataNode); + } + else if(dataNode is ReferencePathNode) + { m_ReferencePaths.Add((ReferencePathNode)dataNode); - } - else if(dataNode is ReferenceNode) - { + } + else if(dataNode is ReferenceNode) + { m_References.Add((ReferenceNode)dataNode); - } - else if(dataNode is AuthorNode) - { + } + else if(dataNode is AuthorNode) + { m_Authors.Add((AuthorNode)dataNode); - } - else if(dataNode is FilesNode) - { - m_Files = (FilesNode)dataNode; - } - } - } - finally - { - Kernel.Instance.CurrentWorkingDirectory.Pop(); - } - } + } + else if(dataNode is FilesNode) + { + m_Files = (FilesNode)dataNode; + } + } + } + finally + { + Kernel.Instance.CurrentWorkingDirectory.Pop(); + } + } - #endregion + #endregion #region IComparable Members @@ -582,6 +612,6 @@ namespace Prebuild.Core.Nodes return m_Name.CompareTo(that.m_Name); } - #endregion - } + #endregion + } } diff --git a/Prebuild/src/Core/Nodes/ReferenceNode.cs b/Prebuild/src/Core/Nodes/ReferenceNode.cs index 9afb51250b..9c5d1a3491 100644 --- a/Prebuild/src/Core/Nodes/ReferenceNode.cs +++ b/Prebuild/src/Core/Nodes/ReferenceNode.cs @@ -5,16 +5,16 @@ Copyright (c) 2004-2005 Matthew Holmes (matthew@wildfiregames.com), Dan Moorehea Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: -* Redistributions of source code must retain the above copyright notice, this list of conditions - and the following disclaimer. -* Redistributions in binary form must reproduce the above copyright notice, this list of conditions - and the following disclaimer in the documentation and/or other materials provided with the - distribution. -* The name of the author may not be used to endorse or promote products derived from this software - without specific prior written permission. +* Redistributions of source code must retain the above copyright notice, this list of conditions + and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions + and the following disclaimer in the documentation and/or other materials provided with the + distribution. +* The name of the author may not be used to endorse or promote products derived from this software + without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, -BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY @@ -32,104 +32,104 @@ using Prebuild.Core.Utilities; namespace Prebuild.Core.Nodes { - /// - /// - /// - [DataNode("Reference")] - public class ReferenceNode : DataNode, IComparable - { - #region Fields + /// + /// + /// + [DataNode("Reference")] + public class ReferenceNode : DataNode, IComparable + { + #region Fields - private string m_Name = "unknown"; - private string m_Path; - private string m_LocalCopy; - private string m_Version; + private string m_Name = "unknown"; + private string m_Path; + private string m_LocalCopy; + private string m_Version; - #endregion + #endregion - #region Properties + #region Properties - /// - /// Gets the name. - /// - /// The name. - public string Name - { - get - { - return m_Name; - } - } + /// + /// Gets the name. + /// + /// The name. + public string Name + { + get + { + return m_Name; + } + } - /// - /// Gets the path. - /// - /// The path. - public string Path - { - get - { - return m_Path; - } - } + /// + /// Gets the path. + /// + /// The path. + public string Path + { + get + { + return m_Path; + } + } - /// - /// Gets a value indicating whether [local copy specified]. - /// - /// true if [local copy specified]; otherwise, false. - public bool LocalCopySpecified - { - get - { - return ( m_LocalCopy != null && m_LocalCopy.Length == 0); - } - } + /// + /// Gets a value indicating whether [local copy specified]. + /// + /// true if [local copy specified]; otherwise, false. + public bool LocalCopySpecified + { + get + { + return ( m_LocalCopy != null && m_LocalCopy.Length == 0); + } + } - /// - /// Gets a value indicating whether [local copy]. - /// - /// true if [local copy]; otherwise, false. - public bool LocalCopy - { - get - { - if( m_LocalCopy == null) - { - return false; - } - return bool.Parse(m_LocalCopy); - } - } + /// + /// Gets a value indicating whether [local copy]. + /// + /// true if [local copy]; otherwise, false. + public bool LocalCopy + { + get + { + if( m_LocalCopy == null) + { + return false; + } + return bool.Parse(m_LocalCopy); + } + } - /// - /// Gets the version. - /// - /// The version. - public string Version - { - get - { - return m_Version; - } - } + /// + /// Gets the version. + /// + /// The version. + public string Version + { + get + { + return m_Version; + } + } - #endregion + #endregion - #region Public Methods + #region Public Methods - /// - /// Parses the specified node. - /// - /// The node. - public override void Parse(XmlNode node) - { - m_Name = Helper.AttributeValue(node, "name", m_Name); - m_Path = Helper.AttributeValue(node, "path", m_Path); - m_LocalCopy = Helper.AttributeValue(node, "localCopy", m_LocalCopy); - m_Version = Helper.AttributeValue(node, "version", m_Version); - } + /// + /// Parses the specified node. + /// + /// The node. + public override void Parse(XmlNode node) + { + m_Name = Helper.AttributeValue(node, "name", m_Name); + m_Path = Helper.AttributeValue(node, "path", m_Path); + m_LocalCopy = Helper.AttributeValue(node, "localCopy", m_LocalCopy); + m_Version = Helper.AttributeValue(node, "version", m_Version); + } - #endregion + #endregion #region IComparable Members @@ -140,5 +140,5 @@ namespace Prebuild.Core.Nodes } #endregion - } + } } diff --git a/Prebuild/src/Core/Nodes/ReferencePathNode.cs b/Prebuild/src/Core/Nodes/ReferencePathNode.cs index 29c63c5f78..7331cd7b58 100644 --- a/Prebuild/src/Core/Nodes/ReferencePathNode.cs +++ b/Prebuild/src/Core/Nodes/ReferencePathNode.cs @@ -5,16 +5,16 @@ Copyright (c) 2004-2005 Matthew Holmes (matthew@wildfiregames.com), Dan Moorehea Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: -* Redistributions of source code must retain the above copyright notice, this list of conditions - and the following disclaimer. -* Redistributions in binary form must reproduce the above copyright notice, this list of conditions - and the following disclaimer in the documentation and/or other materials provided with the - distribution. -* The name of the author may not be used to endorse or promote products derived from this software - without specific prior written permission. +* Redistributions of source code must retain the above copyright notice, this list of conditions + and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions + and the following disclaimer in the documentation and/or other materials provided with the + distribution. +* The name of the author may not be used to endorse or promote products derived from this software + without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, -BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY @@ -32,57 +32,57 @@ using Prebuild.Core.Utilities; namespace Prebuild.Core.Nodes { - /// - /// - /// - [DataNode("ReferencePath")] - public class ReferencePathNode : DataNode, IComparable - { - #region Fields + /// + /// + /// + [DataNode("ReferencePath")] + public class ReferencePathNode : DataNode, IComparable + { + #region Fields - private string m_Path; + private string m_Path; - #endregion + #endregion - #region Properties + #region Properties - /// - /// Gets the path. - /// - /// The path. - public string Path - { - get - { - return m_Path; - } - } + /// + /// Gets the path. + /// + /// The path. + public string Path + { + get + { + return m_Path; + } + } - #endregion + #endregion - #region Public Methods + #region Public Methods - /// - /// Parses the specified node. - /// - /// The node. - public override void Parse(XmlNode node) - { - if( node == null ) - { - throw new ArgumentNullException("node"); - } + /// + /// Parses the specified node. + /// + /// The node. + public override void Parse(XmlNode node) + { + if( node == null ) + { + throw new ArgumentNullException("node"); + } - m_Path = Helper.InterpolateForEnvironmentVariables(node.InnerText); - if(m_Path == null) - { - m_Path = ""; - } + m_Path = Helper.InterpolateForEnvironmentVariables(node.InnerText); + if(m_Path == null) + { + m_Path = ""; + } - m_Path = m_Path.Trim(); - } + m_Path = m_Path.Trim(); + } - #endregion + #endregion #region IComparable Members @@ -93,5 +93,5 @@ namespace Prebuild.Core.Nodes } #endregion - } + } } diff --git a/Prebuild/src/Core/Nodes/SolutionNode.cs b/Prebuild/src/Core/Nodes/SolutionNode.cs index e1d5b3ba28..10c02234da 100644 --- a/Prebuild/src/Core/Nodes/SolutionNode.cs +++ b/Prebuild/src/Core/Nodes/SolutionNode.cs @@ -5,16 +5,16 @@ Copyright (c) 2004-2005 Matthew Holmes (matthew@wildfiregames.com), Dan Moorehea Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: -* Redistributions of source code must retain the above copyright notice, this list of conditions - and the following disclaimer. -* Redistributions in binary form must reproduce the above copyright notice, this list of conditions - and the following disclaimer in the documentation and/or other materials provided with the - distribution. -* The name of the author may not be used to endorse or promote products derived from this software - without specific prior written permission. +* Redistributions of source code must retain the above copyright notice, this list of conditions + and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions + and the following disclaimer in the documentation and/or other materials provided with the + distribution. +* The name of the author may not be used to endorse or promote products derived from this software + without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, -BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY @@ -34,35 +34,35 @@ using Prebuild.Core.Utilities; namespace Prebuild.Core.Nodes { - /// - /// - /// - [DataNode("Solution")] + /// + /// + /// + [DataNode("Solution")] [DataNode("EmbeddedSolution")] [DebuggerDisplay("{Name}")] - public class SolutionNode : DataNode - { - #region Fields + public class SolutionNode : DataNode + { + #region Fields private Guid m_Guid = Guid.NewGuid(); - private string m_Name = "unknown"; - private string m_Path = ""; - private string m_FullPath = ""; - private string m_ActiveConfig; + private string m_Name = "unknown"; + private string m_Path = ""; + private string m_FullPath = ""; + private string m_ActiveConfig; private string m_Version = "1.0.0"; - - private OptionsNode m_Options; - private FilesNode m_Files; + + private OptionsNode m_Options; + private FilesNode m_Files; private readonly ConfigurationNodeCollection m_Configurations = new ConfigurationNodeCollection(); private readonly Dictionary m_Projects = new Dictionary(); private readonly Dictionary m_DatabaseProjects = new Dictionary(); private readonly List m_ProjectsOrder = new List(); private readonly Dictionary m_Solutions = new Dictionary(); - private CleanupNode m_Cleanup; + private CleanupNode m_Cleanup; - #endregion + #endregion - #region Properties + #region Properties public override IDataNode Parent { get @@ -84,142 +84,142 @@ namespace Prebuild.Core.Nodes } } - public CleanupNode Cleanup - { - get - { - return m_Cleanup; - } + public CleanupNode Cleanup + { + get + { + return m_Cleanup; + } set { m_Cleanup = value; } - } + } public Guid Guid { - get - { - return m_Guid; + get + { + return m_Guid; } set { - m_Guid = value; - } - } - /// - /// Gets or sets the active config. - /// - /// The active config. - public string ActiveConfig - { - get - { - return m_ActiveConfig; - } - set - { - m_ActiveConfig = value; + m_Guid = value; } } + /// + /// Gets or sets the active config. + /// + /// The active config. + public string ActiveConfig + { + get + { + return m_ActiveConfig; + } + set + { + m_ActiveConfig = value; + } + } - /// - /// Gets the name. - /// - /// The name. - public string Name - { - get - { - return m_Name; - } - } + /// + /// Gets the name. + /// + /// The name. + public string Name + { + get + { + return m_Name; + } + } - /// - /// Gets the path. - /// - /// The path. - public string Path - { - get - { - return m_Path; - } - } + /// + /// Gets the path. + /// + /// The path. + public string Path + { + get + { + return m_Path; + } + } - /// - /// Gets the full path. - /// - /// The full path. - public string FullPath - { - get - { - return m_FullPath; - } - } + /// + /// Gets the full path. + /// + /// The full path. + public string FullPath + { + get + { + return m_FullPath; + } + } - /// - /// Gets the version. - /// - /// The version. - public string Version - { - get - { - return m_Version; - } - } + /// + /// Gets the version. + /// + /// The version. + public string Version + { + get + { + return m_Version; + } + } - /// - /// Gets the options. - /// - /// The options. - public OptionsNode Options - { - get - { - return m_Options; - } - } + /// + /// Gets the options. + /// + /// The options. + public OptionsNode Options + { + get + { + return m_Options; + } + } - /// - /// Gets the files. - /// - /// The files. - public FilesNode Files - { - get - { - return m_Files; - } - } + /// + /// Gets the files. + /// + /// The files. + public FilesNode Files + { + get + { + return m_Files; + } + } - /// - /// Gets the configurations. - /// - /// The configurations. - public ConfigurationNodeCollection Configurations - { - get - { - ConfigurationNodeCollection tmp = new ConfigurationNodeCollection(); - tmp.AddRange(ConfigurationsTable); - return tmp; - } - } + /// + /// Gets the configurations. + /// + /// The configurations. + public ConfigurationNodeCollection Configurations + { + get + { + ConfigurationNodeCollection tmp = new ConfigurationNodeCollection(); + tmp.AddRange(ConfigurationsTable); + return tmp; + } + } - /// - /// Gets the configurations table. - /// - /// The configurations table. - public ConfigurationNodeCollection ConfigurationsTable - { - get - { - return m_Configurations; - } - } + /// + /// Gets the configurations table. + /// + /// The configurations table. + public ConfigurationNodeCollection ConfigurationsTable + { + get + { + return m_Configurations; + } + } /// /// Gets the database projects. /// @@ -250,106 +250,106 @@ namespace Prebuild.Core.Nodes return m_Solutions; } } - /// - /// Gets the projects. - /// - /// The projects. - public ICollection Projects - { - get - { + /// + /// Gets the projects. + /// + /// The projects. + public ICollection Projects + { + get + { List tmp = new List(m_Projects.Values); tmp.Sort(); return tmp; - } - } + } + } - /// - /// Gets the projects table. - /// - /// The projects table. - public Dictionary ProjectsTable - { - get - { - return m_Projects; - } - } + /// + /// Gets the projects table. + /// + /// The projects table. + public Dictionary ProjectsTable + { + get + { + return m_Projects; + } + } - /// - /// Gets the projects table. - /// - /// The projects table. - public List ProjectsTableOrder - { - get - { - return m_ProjectsOrder; - } - } + /// + /// Gets the projects table. + /// + /// The projects table. + public List ProjectsTableOrder + { + get + { + return m_ProjectsOrder; + } + } - #endregion + #endregion - #region Public Methods + #region Public Methods - /// - /// Parses the specified node. - /// - /// The node. - public override void Parse(XmlNode node) - { - m_Name = Helper.AttributeValue(node, "name", m_Name); - m_ActiveConfig = Helper.AttributeValue(node, "activeConfig", m_ActiveConfig); - m_Path = Helper.AttributeValue(node, "path", m_Path); - m_Version = Helper.AttributeValue(node, "version", m_Version); + /// + /// Parses the specified node. + /// + /// The node. + public override void Parse(XmlNode node) + { + m_Name = Helper.AttributeValue(node, "name", m_Name); + m_ActiveConfig = Helper.AttributeValue(node, "activeConfig", m_ActiveConfig); + m_Path = Helper.AttributeValue(node, "path", m_Path); + m_Version = Helper.AttributeValue(node, "version", m_Version); - m_FullPath = m_Path; - try - { - m_FullPath = Helper.ResolvePath(m_FullPath); - } - catch - { - throw new WarningException("Could not resolve solution path: {0}", m_Path); - } + m_FullPath = m_Path; + try + { + m_FullPath = Helper.ResolvePath(m_FullPath); + } + catch + { + throw new WarningException("Could not resolve solution path: {0}", m_Path); + } - Kernel.Instance.CurrentWorkingDirectory.Push(); - try - { - Helper.SetCurrentDir(m_FullPath); + Kernel.Instance.CurrentWorkingDirectory.Push(); + try + { + Helper.SetCurrentDir(m_FullPath); - if( node == null ) - { - throw new ArgumentNullException("node"); - } + if( node == null ) + { + throw new ArgumentNullException("node"); + } - foreach(XmlNode child in node.ChildNodes) - { - IDataNode dataNode = Kernel.Instance.ParseNode(child, this); - if(dataNode is OptionsNode) - { - m_Options = (OptionsNode)dataNode; - } - else if(dataNode is FilesNode) - { - m_Files = (FilesNode)dataNode; - } - else if(dataNode is ConfigurationNode) - { - ConfigurationNode configurationNode = (ConfigurationNode) dataNode; - m_Configurations[configurationNode.NameAndPlatform] = configurationNode; + foreach(XmlNode child in node.ChildNodes) + { + IDataNode dataNode = Kernel.Instance.ParseNode(child, this); + if(dataNode is OptionsNode) + { + m_Options = (OptionsNode)dataNode; + } + else if(dataNode is FilesNode) + { + m_Files = (FilesNode)dataNode; + } + else if(dataNode is ConfigurationNode) + { + ConfigurationNode configurationNode = (ConfigurationNode) dataNode; + m_Configurations[configurationNode.NameAndPlatform] = configurationNode; - // If the active configuration is null, then we populate it. - if (ActiveConfig == null) - { - ActiveConfig = configurationNode.Name; - } - } - else if(dataNode is ProjectNode) - { - m_Projects[((ProjectNode)dataNode).Name] = (ProjectNode) dataNode; - m_ProjectsOrder.Add((ProjectNode)dataNode); - } + // If the active configuration is null, then we populate it. + if (ActiveConfig == null) + { + ActiveConfig = configurationNode.Name; + } + } + else if(dataNode is ProjectNode) + { + m_Projects[((ProjectNode)dataNode).Name] = (ProjectNode) dataNode; + m_ProjectsOrder.Add((ProjectNode)dataNode); + } else if(dataNode is SolutionNode) { m_Solutions[((SolutionNode)dataNode).Name] = (SolutionNode) dataNode; @@ -369,14 +369,14 @@ namespace Prebuild.Core.Nodes throw new WarningException("There can only be one Cleanup node."); m_Cleanup = (CleanupNode)dataNode; } - } - } - finally - { - Kernel.Instance.CurrentWorkingDirectory.Pop(); - } - } + } + } + finally + { + Kernel.Instance.CurrentWorkingDirectory.Pop(); + } + } - #endregion - } + #endregion + } } diff --git a/Prebuild/src/Core/Parse/IfContext.cs b/Prebuild/src/Core/Parse/IfContext.cs index 7729d3b869..3c79d38b06 100644 --- a/Prebuild/src/Core/Parse/IfContext.cs +++ b/Prebuild/src/Core/Parse/IfContext.cs @@ -5,16 +5,16 @@ Copyright (c) 2004-2005 Matthew Holmes (matthew@wildfiregames.com), Dan Moorehea Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: -* Redistributions of source code must retain the above copyright notice, this list of conditions - and the following disclaimer. -* Redistributions in binary form must reproduce the above copyright notice, this list of conditions - and the following disclaimer in the documentation and/or other materials provided with the - distribution. -* The name of the author may not be used to endorse or promote products derived from this software - without specific prior written permission. +* Redistributions of source code must retain the above copyright notice, this list of conditions + and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions + and the following disclaimer in the documentation and/or other materials provided with the + distribution. +* The name of the author may not be used to endorse or promote products derived from this software + without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, -BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY @@ -27,128 +27,128 @@ using System; namespace Prebuild.Core.Parse { - /// - /// - /// - public enum IfState - { - /// - /// - /// - None, - /// - /// - /// - If, - /// - /// - /// - ElseIf, - /// - /// - /// - Else - } + /// + /// + /// + public enum IfState + { + /// + /// + /// + None, + /// + /// + /// + If, + /// + /// + /// + ElseIf, + /// + /// + /// + Else + } - /// - /// Summary description for IfContext. - /// - // Inspired by the equivalent WiX class (see www.sourceforge.net/projects/wix/) - public class IfContext - { - #region Properties + /// + /// Summary description for IfContext. + /// + // Inspired by the equivalent WiX class (see www.sourceforge.net/projects/wix/) + public class IfContext + { + #region Properties - bool m_Active; - bool m_Keep; - bool m_EverKept; - IfState m_State = IfState.None; + bool m_Active; + bool m_Keep; + bool m_EverKept; + IfState m_State = IfState.None; - #endregion + #endregion - #region Constructors + #region Constructors - /// - /// Initializes a new instance of the class. - /// - /// if set to true [active]. - /// if set to true [keep]. - /// The state. - public IfContext(bool active, bool keep, IfState state) - { - m_Active = active; - m_Keep = keep; - m_EverKept = keep; - m_State = state; - } + /// + /// Initializes a new instance of the class. + /// + /// if set to true [active]. + /// if set to true [keep]. + /// The state. + public IfContext(bool active, bool keep, IfState state) + { + m_Active = active; + m_Keep = keep; + m_EverKept = keep; + m_State = state; + } - #endregion + #endregion - #region Properties + #region Properties - /// - /// Gets or sets a value indicating whether this is active. - /// - /// true if active; otherwise, false. - public bool Active - { - get - { - return m_Active; - } - set - { - m_Active = value; - } - } + /// + /// Gets or sets a value indicating whether this is active. + /// + /// true if active; otherwise, false. + public bool Active + { + get + { + return m_Active; + } + set + { + m_Active = value; + } + } - /// - /// Gets or sets a value indicating whether this is keep. - /// - /// true if keep; otherwise, false. - public bool Keep - { - get - { - return m_Keep; - } - set - { - m_Keep = value; - if(m_Keep) - { - m_EverKept = true; - } - } - } + /// + /// Gets or sets a value indicating whether this is keep. + /// + /// true if keep; otherwise, false. + public bool Keep + { + get + { + return m_Keep; + } + set + { + m_Keep = value; + if(m_Keep) + { + m_EverKept = true; + } + } + } - /// - /// Gets a value indicating whether [ever kept]. - /// - /// true if [ever kept]; otherwise, false. - public bool EverKept - { - get - { - return m_EverKept; - } - } + /// + /// Gets a value indicating whether [ever kept]. + /// + /// true if [ever kept]; otherwise, false. + public bool EverKept + { + get + { + return m_EverKept; + } + } - /// - /// Gets or sets the state. - /// - /// The state. - public IfState State - { - get - { - return m_State; - } - set - { - m_State = value; - } - } + /// + /// Gets or sets the state. + /// + /// The state. + public IfState State + { + get + { + return m_State; + } + set + { + m_State = value; + } + } - #endregion - } + #endregion + } } diff --git a/Prebuild/src/Core/Parse/Preprocessor.cs b/Prebuild/src/Core/Parse/Preprocessor.cs index 0cd6e82e3c..0648fad8d8 100644 --- a/Prebuild/src/Core/Parse/Preprocessor.cs +++ b/Prebuild/src/Core/Parse/Preprocessor.cs @@ -5,16 +5,16 @@ Copyright (c) 2004-2005 Matthew Holmes (matthew@wildfiregames.com), Dan Moorehea Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: -* Redistributions of source code must retain the above copyright notice, this list of conditions - and the following disclaimer. -* Redistributions in binary form must reproduce the above copyright notice, this list of conditions - and the following disclaimer in the documentation and/or other materials provided with the - distribution. -* The name of the author may not be used to endorse or promote products derived from this software - without specific prior written permission. +* Redistributions of source code must retain the above copyright notice, this list of conditions + and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions + and the following disclaimer in the documentation and/or other materials provided with the + distribution. +* The name of the author may not be used to endorse or promote products derived from this software + without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, -BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY @@ -31,336 +31,336 @@ using System.Xml; namespace Prebuild.Core.Parse { - /// - /// - /// - public enum OperatorSymbol - { - /// - /// - /// - None, - /// - /// - /// - Equal, - /// - /// - /// - NotEqual, - /// - /// - /// - LessThan, - /// - /// - /// - GreaterThan, - /// - /// - /// - LessThanEqual, - /// - /// - /// - GreaterThanEqual - } + /// + /// + /// + public enum OperatorSymbol + { + /// + /// + /// + None, + /// + /// + /// + Equal, + /// + /// + /// + NotEqual, + /// + /// + /// + LessThan, + /// + /// + /// + GreaterThan, + /// + /// + /// + LessThanEqual, + /// + /// + /// + GreaterThanEqual + } - /// - /// - /// - public class Preprocessor - { - #region Constants + /// + /// + /// + public class Preprocessor + { + #region Constants - /// - /// Includes the regex to look for file tags in the processing instruction. - /// - private static readonly Regex includeFileRegex = new Regex("file=\"(.+?)\""); + /// + /// Includes the regex to look for file tags in the processing instruction. + /// + private static readonly Regex includeFileRegex = new Regex("file=\"(.+?)\""); - #endregion + #endregion - #region Fields + #region Fields - readonly XmlDocument m_OutDoc = new XmlDocument(); - readonly Stack m_IfStack = new Stack(); - readonly Dictionary m_Variables = new Dictionary(); + readonly XmlDocument m_OutDoc = new XmlDocument(); + readonly Stack m_IfStack = new Stack(); + readonly Dictionary m_Variables = new Dictionary(); - #endregion + #endregion - #region Constructors + #region Constructors - /// - /// Initializes a new instance of the class. - /// - public Preprocessor() - { - RegisterVariable("OS", GetOS()); - RegisterVariable("RuntimeVersion", Environment.Version.Major); - RegisterVariable("RuntimeMajor", Environment.Version.Major); - RegisterVariable("RuntimeMinor", Environment.Version.Minor); - RegisterVariable("RuntimeRevision", Environment.Version.Revision); - } + /// + /// Initializes a new instance of the class. + /// + public Preprocessor() + { + RegisterVariable("OS", GetOS()); + RegisterVariable("RuntimeVersion", Environment.Version.Major); + RegisterVariable("RuntimeMajor", Environment.Version.Major); + RegisterVariable("RuntimeMinor", Environment.Version.Minor); + RegisterVariable("RuntimeRevision", Environment.Version.Revision); + } - #endregion + #endregion - #region Properties + #region Properties - /// - /// Gets the processed doc. - /// - /// The processed doc. - public XmlDocument ProcessedDoc - { - get - { - return m_OutDoc; - } - } + /// + /// Gets the processed doc. + /// + /// The processed doc. + public XmlDocument ProcessedDoc + { + get + { + return m_OutDoc; + } + } - #endregion + #endregion - #region Private Methods + #region Private Methods + + /// + /// Parts of this code were taken from NAnt and is subject to the GPL + /// as per NAnt's license. Thanks to the NAnt guys for this little gem. + /// + /// + public static string GetOS() + { + PlatformID platId = Environment.OSVersion.Platform; + if(platId == PlatformID.Win32NT || platId == PlatformID.Win32Windows) + { + return "Win32"; + } - /// - /// Parts of this code were taken from NAnt and is subject to the GPL - /// as per NAnt's license. Thanks to the NAnt guys for this little gem. - /// - /// - public static string GetOS() - { - PlatformID platId = Environment.OSVersion.Platform; - if(platId == PlatformID.Win32NT || platId == PlatformID.Win32Windows) - { - return "Win32"; - } + if (File.Exists("/System/Library/Frameworks/Cocoa.framework/Cocoa")) + { + return "MACOSX"; + } - if (File.Exists("/System/Library/Frameworks/Cocoa.framework/Cocoa")) - { - return "MACOSX"; - } + /* + * .NET 1.x, under Mono, the UNIX code is 128. Under + * .NET 2.x, Mono or MS, the UNIX code is 4 + */ + if(Environment.Version.Major == 1) + { + if((int)platId == 128) + { + return "UNIX"; + } + } + else if((int)platId == 4) + { + return "UNIX"; + } - /* - * .NET 1.x, under Mono, the UNIX code is 128. Under - * .NET 2.x, Mono or MS, the UNIX code is 4 - */ - if(Environment.Version.Major == 1) - { - if((int)platId == 128) - { - return "UNIX"; - } - } - else if((int)platId == 4) - { - return "UNIX"; - } + return "Unknown"; + } - return "Unknown"; - } + private static bool CompareNum(OperatorSymbol oper, int val1, int val2) + { + switch(oper) + { + case OperatorSymbol.Equal: + return (val1 == val2); + case OperatorSymbol.NotEqual: + return (val1 != val2); + case OperatorSymbol.LessThan: + return (val1 < val2); + case OperatorSymbol.LessThanEqual: + return (val1 <= val2); + case OperatorSymbol.GreaterThan: + return (val1 > val2); + case OperatorSymbol.GreaterThanEqual: + return (val1 >= val2); + } - private static bool CompareNum(OperatorSymbol oper, int val1, int val2) - { - switch(oper) - { - case OperatorSymbol.Equal: - return (val1 == val2); - case OperatorSymbol.NotEqual: - return (val1 != val2); - case OperatorSymbol.LessThan: - return (val1 < val2); - case OperatorSymbol.LessThanEqual: - return (val1 <= val2); - case OperatorSymbol.GreaterThan: - return (val1 > val2); - case OperatorSymbol.GreaterThanEqual: - return (val1 >= val2); - } + throw new WarningException("Unknown operator type"); + } - throw new WarningException("Unknown operator type"); - } + private static bool CompareStr(OperatorSymbol oper, string val1, string val2) + { + switch(oper) + { + case OperatorSymbol.Equal: + return (val1 == val2); + case OperatorSymbol.NotEqual: + return (val1 != val2); + case OperatorSymbol.LessThan: + return (val1.CompareTo(val2) < 0); + case OperatorSymbol.LessThanEqual: + return (val1.CompareTo(val2) <= 0); + case OperatorSymbol.GreaterThan: + return (val1.CompareTo(val2) > 0); + case OperatorSymbol.GreaterThanEqual: + return (val1.CompareTo(val2) >= 0); + } - private static bool CompareStr(OperatorSymbol oper, string val1, string val2) - { - switch(oper) - { - case OperatorSymbol.Equal: - return (val1 == val2); - case OperatorSymbol.NotEqual: - return (val1 != val2); - case OperatorSymbol.LessThan: - return (val1.CompareTo(val2) < 0); - case OperatorSymbol.LessThanEqual: - return (val1.CompareTo(val2) <= 0); - case OperatorSymbol.GreaterThan: - return (val1.CompareTo(val2) > 0); - case OperatorSymbol.GreaterThanEqual: - return (val1.CompareTo(val2) >= 0); - } + throw new WarningException("Unknown operator type"); + } - throw new WarningException("Unknown operator type"); - } + private static char NextChar(int idx, string str) + { + if((idx + 1) >= str.Length) + { + return Char.MaxValue; + } - private static char NextChar(int idx, string str) - { - if((idx + 1) >= str.Length) - { - return Char.MaxValue; - } + return str[idx + 1]; + } + // Very very simple expression parser. Can only match expressions of the form + // : + // OS = Windows + // OS != Linux + // RuntimeMinor > 0 + private bool ParseExpression(string exp) + { + if(exp == null) + { + throw new ArgumentException("Invalid expression, cannot be null"); + } - return str[idx + 1]; - } - // Very very simple expression parser. Can only match expressions of the form - // : - // OS = Windows - // OS != Linux - // RuntimeMinor > 0 - private bool ParseExpression(string exp) - { - if(exp == null) - { - throw new ArgumentException("Invalid expression, cannot be null"); - } + exp = exp.Trim(); + if(exp.Length < 1) + { + throw new ArgumentException("Invalid expression, cannot be 0 length"); + } - exp = exp.Trim(); - if(exp.Length < 1) - { - throw new ArgumentException("Invalid expression, cannot be 0 length"); - } + string id = ""; + string str = ""; + OperatorSymbol oper = OperatorSymbol.None; + bool inStr = false; - string id = ""; - string str = ""; - OperatorSymbol oper = OperatorSymbol.None; - bool inStr = false; + for(int i = 0; i < exp.Length; i++) + { + char c = exp[i]; + if(Char.IsWhiteSpace(c)) + { + continue; + } - for(int i = 0; i < exp.Length; i++) - { - char c = exp[i]; - if(Char.IsWhiteSpace(c)) - { - continue; - } + if(Char.IsLetterOrDigit(c) || c == '_') + { + if(inStr) + { + str += c; + } + else + { + id += c; + } + } + else if(c == '\"') + { + inStr = !inStr; + if(inStr) + { + str = ""; + } + } + else + { + if(inStr) + { + str += c; + } + else + { + switch(c) + { + case '=': + oper = OperatorSymbol.Equal; + break; - if(Char.IsLetterOrDigit(c) || c == '_') - { - if(inStr) - { - str += c; - } - else - { - id += c; - } - } - else if(c == '\"') - { - inStr = !inStr; - if(inStr) - { - str = ""; - } - } - else - { - if(inStr) - { - str += c; - } - else - { - switch(c) - { - case '=': - oper = OperatorSymbol.Equal; - break; + case '!': + if(NextChar(i, exp) == '=') + { + oper = OperatorSymbol.NotEqual; + } + + break; - case '!': - if(NextChar(i, exp) == '=') - { - oper = OperatorSymbol.NotEqual; - } + case '<': + if(NextChar(i, exp) == '=') + { + oper = OperatorSymbol.LessThanEqual; + } + else + { + oper = OperatorSymbol.LessThan; + } + + break; - break; + case '>': + if(NextChar(i, exp) == '=') + { + oper = OperatorSymbol.GreaterThanEqual; + } + else + { + oper = OperatorSymbol.GreaterThan; + } - case '<': - if(NextChar(i, exp) == '=') - { - oper = OperatorSymbol.LessThanEqual; - } - else - { - oper = OperatorSymbol.LessThan; - } + break; + } + } + } + } - break; + + if(inStr) + { + throw new WarningException("Expected end of string in expression"); + } - case '>': - if(NextChar(i, exp) == '=') - { - oper = OperatorSymbol.GreaterThanEqual; - } - else - { - oper = OperatorSymbol.GreaterThan; - } + if(oper == OperatorSymbol.None) + { + throw new WarningException("Expected operator in expression"); + } + if(id.Length < 1) + { + throw new WarningException("Expected identifier in expression"); + } + if(str.Length < 1) + { + throw new WarningException("Expected value in expression"); + } - break; - } - } - } - } + bool ret; + try + { + object val = m_Variables[id.ToLower()]; + if(val == null) + { + throw new WarningException("Unknown identifier '{0}'", id); + } + Type t = val.GetType(); + if(t.IsAssignableFrom(typeof(int))) + { + int numVal = (int)val; + int numVal2 = Int32.Parse(str); + ret = CompareNum(oper, numVal, numVal2); + } + else + { + string strVal = val.ToString(); + string strVal2 = str; + ret = CompareStr(oper, strVal, strVal2); + } + } + catch(ArgumentException ex) + { + ex.ToString(); + throw new WarningException("Invalid value type for system variable '{0}', expected int", id); + } - if(inStr) - { - throw new WarningException("Expected end of string in expression"); - } - - if(oper == OperatorSymbol.None) - { - throw new WarningException("Expected operator in expression"); - } - if(id.Length < 1) - { - throw new WarningException("Expected identifier in expression"); - } - if(str.Length < 1) - { - throw new WarningException("Expected value in expression"); - } - - bool ret; - try - { - object val = m_Variables[id.ToLower()]; - if(val == null) - { - throw new WarningException("Unknown identifier '{0}'", id); - } - - Type t = val.GetType(); - if(t.IsAssignableFrom(typeof(int))) - { - int numVal = (int)val; - int numVal2 = Int32.Parse(str); - ret = CompareNum(oper, numVal, numVal2); - } - else - { - string strVal = val.ToString(); - string strVal2 = str; - ret = CompareStr(oper, strVal, strVal2); - } - } - catch(ArgumentException ex) - { - ex.ToString(); - throw new WarningException("Invalid value type for system variable '{0}', expected int", id); - } - - return ret; - } + return ret; + } /// /// Taken from current Prebuild included in OpenSim 0.7.x @@ -376,13 +376,13 @@ namespace Prebuild.Core.Parse if (!include.Contains ("*")) { return; } - + // Console.WriteLine("Processing {0}", include); - + // Break up the include into pre and post wildcard sections string preWildcard = include.Substring (0, include.IndexOf ("*")); string postWildcard = include.Substring (include.IndexOf ("*") + 2); - + // If preWildcard is a directory, recurse if (Directory.Exists (preWildcard)) { string[] directories = Directory.GetDirectories (preWildcard); @@ -390,7 +390,7 @@ namespace Prebuild.Core.Parse Array.Reverse (directories); foreach (string dirPath in directories) { //Console.WriteLine ("Scanning : {0}", dirPath); - + string includeFile = Path.Combine (dirPath, postWildcard); if (includeFile.Contains ("*")) { // postWildcard included another wildcard, recurse. @@ -408,10 +408,10 @@ namespace Prebuild.Core.Parse // preWildcard is not a path to a directory, so the wildcard is in the filename string searchFilename = Path.GetFileName (preWildcard.Substring (preWildcard.IndexOf ("/") + 1) + "*" + postWildcard); Console.WriteLine ("searchFilename: {0}", searchFilename); - + string searchDirectory = Path.GetDirectoryName (preWildcard); Console.WriteLine ("searchDirectory: {0}", searchDirectory); - + string[] files = Directory.GetFiles (searchDirectory, searchFilename); Array.Sort (files); Array.Reverse (files); @@ -426,227 +426,227 @@ namespace Prebuild.Core.Parse } } - #endregion + #endregion - #region Public Methods + #region Public Methods - /// - /// - /// - /// - /// - public void RegisterVariable(string name, object variableValue) - { - if(name == null || variableValue == null) - { - return; - } + /// + /// + /// + /// + /// + public void RegisterVariable(string name, object variableValue) + { + if(name == null || variableValue == null) + { + return; + } - m_Variables[name.ToLower()] = variableValue; - } + m_Variables[name.ToLower()] = variableValue; + } - /// - /// Performs validation on the xml source as well as evaluates conditional and flow expresions - /// - /// For invalid use of conditional expressions or for invalid XML syntax. If a XmlValidatingReader is passed, then will also throw exceptions for non-schema-conforming xml + /// + /// Performs validation on the xml source as well as evaluates conditional and flow expresions + /// + /// For invalid use of conditional expressions or for invalid XML syntax. If a XmlValidatingReader is passed, then will also throw exceptions for non-schema-conforming xml /// - /// the output xml - public string Process(XmlReader initialReader) - { - if(initialReader == null) - { - throw new ArgumentException("Invalid XML reader to pre-process"); - } + /// the output xml + public string Process(XmlReader initialReader) + { + if(initialReader == null) + { + throw new ArgumentException("Invalid XML reader to pre-process"); + } - IfContext context = new IfContext(true, true, IfState.None); - StringWriter xmlText = new StringWriter(); - XmlTextWriter writer = new XmlTextWriter(xmlText); - writer.Formatting = Formatting.Indented; + IfContext context = new IfContext(true, true, IfState.None); + StringWriter xmlText = new StringWriter(); + XmlTextWriter writer = new XmlTextWriter(xmlText); + writer.Formatting = Formatting.Indented; - // Create a queue of XML readers and add the initial - // reader to it. Then we process until we run out of - // readers which lets the operation add more - // readers to generate a multi-file parser and not require - // XML fragments that a recursive version would use. - Stack readerStack = new Stack(); - readerStack.Push(initialReader); + // Create a queue of XML readers and add the initial + // reader to it. Then we process until we run out of + // readers which lets the operation add more + // readers to generate a multi-file parser and not require + // XML fragments that a recursive version would use. + Stack readerStack = new Stack(); + readerStack.Push(initialReader); + + while(readerStack.Count > 0) + { + // Pop off the next reader. + XmlReader reader = readerStack.Pop(); - while(readerStack.Count > 0) - { - // Pop off the next reader. - XmlReader reader = readerStack.Pop(); + // Process through this XML reader until it is + // completed (or it is replaced by the include + // operation). + while(reader.Read()) + { + // The prebuild file has a series of processing + // instructions which allow for specific + // inclusions based on operating system or to + // include additional files. + if(reader.NodeType == XmlNodeType.ProcessingInstruction) + { + bool ignore = false; - // Process through this XML reader until it is - // completed (or it is replaced by the include - // operation). - while(reader.Read()) - { - // The prebuild file has a series of processing - // instructions which allow for specific - // inclusions based on operating system or to - // include additional files. - if(reader.NodeType == XmlNodeType.ProcessingInstruction) - { - bool ignore = false; + switch(reader.LocalName) + { + case "include": + // use regular expressions to parse out the attributes. + MatchCollection matches = includeFileRegex.Matches(reader.Value); - switch(reader.LocalName) - { - case "include": - // use regular expressions to parse out the attributes. - MatchCollection matches = includeFileRegex.Matches(reader.Value); + // make sure there is only one file attribute. + if(matches.Count > 1) + { + throw new WarningException("An node was found, but it specified more than one file."); + } - // make sure there is only one file attribute. - if(matches.Count > 1) - { - throw new WarningException("An node was found, but it specified more than one file."); - } - - if(matches.Count == 0) - { - throw new WarningException("An node was found, but it did not specify the file attribute."); - } + if(matches.Count == 0) + { + throw new WarningException("An node was found, but it did not specify the file attribute."); + } // ***** Adding for wildcard handling // Push current reader back onto the stack. readerStack.Push (reader); - + // Pull the file out from the regex and make sure it is a valid file before using it. string filename = matches[0].Groups[1].Value; - + filename = String.Join (Path.DirectorySeparatorChar.ToString (), filename.Split (new char[] { '/', '\\' })); - + if (!filename.Contains ("*")) { - + FileInfo includeFile = new FileInfo (filename); if (!includeFile.Exists) { throw new WarningException ("Cannot include file: " + includeFile.FullName); } - + // Create a new reader object for this file. Then put the old reader back on the stack and start // processing using this new XML reader. - + XmlReader newReader = new XmlTextReader (includeFile.Open (FileMode.Open, FileAccess.Read, FileShare.Read)); reader = newReader; readerStack.Push (reader); - + } else { WildCardInclude (readerStack, filename); } - + reader = (XmlReader)readerStack.Pop (); ignore = true; break; - case "if": - m_IfStack.Push(context); - context = new IfContext(context.Keep & context.Active, ParseExpression(reader.Value), IfState.If); - ignore = true; - break; + case "if": + m_IfStack.Push(context); + context = new IfContext(context.Keep & context.Active, ParseExpression(reader.Value), IfState.If); + ignore = true; + break; - case "elseif": - if(m_IfStack.Count == 0) - { - throw new WarningException("Unexpected 'elseif' outside of 'if'"); - } - if(context.State != IfState.If && context.State != IfState.ElseIf) - { - throw new WarningException("Unexpected 'elseif' outside of 'if'"); - } + case "elseif": + if(m_IfStack.Count == 0) + { + throw new WarningException("Unexpected 'elseif' outside of 'if'"); + } + if(context.State != IfState.If && context.State != IfState.ElseIf) + { + throw new WarningException("Unexpected 'elseif' outside of 'if'"); + } - context.State = IfState.ElseIf; - if(!context.EverKept) - { - context.Keep = ParseExpression(reader.Value); - } - else - { - context.Keep = false; - } + context.State = IfState.ElseIf; + if(!context.EverKept) + { + context.Keep = ParseExpression(reader.Value); + } + else + { + context.Keep = false; + } - ignore = true; - break; + ignore = true; + break; - case "else": - if(m_IfStack.Count == 0) - { - throw new WarningException("Unexpected 'else' outside of 'if'"); - } - if(context.State != IfState.If && context.State != IfState.ElseIf) - { - throw new WarningException("Unexpected 'else' outside of 'if'"); - } + case "else": + if(m_IfStack.Count == 0) + { + throw new WarningException("Unexpected 'else' outside of 'if'"); + } + if(context.State != IfState.If && context.State != IfState.ElseIf) + { + throw new WarningException("Unexpected 'else' outside of 'if'"); + } - context.State = IfState.Else; - context.Keep = !context.EverKept; - ignore = true; - break; + context.State = IfState.Else; + context.Keep = !context.EverKept; + ignore = true; + break; - case "endif": - if(m_IfStack.Count == 0) - { - throw new WarningException("Unexpected 'endif' outside of 'if'"); - } + case "endif": + if(m_IfStack.Count == 0) + { + throw new WarningException("Unexpected 'endif' outside of 'if'"); + } - context = m_IfStack.Pop(); - ignore = true; - break; - } + context = m_IfStack.Pop(); + ignore = true; + break; + } - if(ignore) - { - continue; - } - }//end pre-proc instruction + if(ignore) + { + continue; + } + }//end pre-proc instruction - if(!context.Active || !context.Keep) - { - continue; - } + if(!context.Active || !context.Keep) + { + continue; + } - switch(reader.NodeType) - { - case XmlNodeType.Element: - bool empty = reader.IsEmptyElement; - writer.WriteStartElement(reader.Name); + switch(reader.NodeType) + { + case XmlNodeType.Element: + bool empty = reader.IsEmptyElement; + writer.WriteStartElement(reader.Name); - while (reader.MoveToNextAttribute()) - { - writer.WriteAttributeString(reader.Name, reader.Value); - } + while (reader.MoveToNextAttribute()) + { + writer.WriteAttributeString(reader.Name, reader.Value); + } - if(empty) - { - writer.WriteEndElement(); - } + if(empty) + { + writer.WriteEndElement(); + } + + break; - break; + case XmlNodeType.EndElement: + writer.WriteEndElement(); + break; - case XmlNodeType.EndElement: - writer.WriteEndElement(); - break; + case XmlNodeType.Text: + writer.WriteString(reader.Value); + break; - case XmlNodeType.Text: - writer.WriteString(reader.Value); - break; + case XmlNodeType.CDATA: + writer.WriteCData(reader.Value); + break; - case XmlNodeType.CDATA: - writer.WriteCData(reader.Value); - break; + default: + break; + } + } - default: - break; - } - } + if(m_IfStack.Count != 0) + { + throw new WarningException("Mismatched 'if', 'endif' pair"); + } + } + + return xmlText.ToString(); + } - if(m_IfStack.Count != 0) - { - throw new WarningException("Mismatched 'if', 'endif' pair"); - } - } - - return xmlText.ToString(); - } - - #endregion - } + #endregion + } } diff --git a/Prebuild/src/Core/Targets/AutotoolsTarget.cs b/Prebuild/src/Core/Targets/AutotoolsTarget.cs index c52c4f19ae..485e4dd724 100644 --- a/Prebuild/src/Core/Targets/AutotoolsTarget.cs +++ b/Prebuild/src/Core/Targets/AutotoolsTarget.cs @@ -51,10 +51,10 @@ POSSIBILITY OF SUCH DAMAGE. distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - + The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND @@ -156,7 +156,7 @@ namespace Prebuild.Core.Targets /// - /// + /// /// [Target("autotools")] public class AutotoolsTarget : ITarget @@ -650,7 +650,7 @@ namespace Prebuild.Core.Targets string tempAssemblyFile = Path.Combine(Path.GetTempPath(), project.Name + "-temp.dll"); System.CodeDom.Compiler.CompilerParameters cparam = new System.CodeDom.Compiler.CompilerParameters(args, tempAssemblyFile); - + System.CodeDom.Compiler.CompilerResults cr = cscp.CompileAssemblyFromFile(cparam, sources); @@ -673,11 +673,11 @@ namespace Prebuild.Core.Targets if (File.Exists(tempAssemblyFile)) File.Delete(tempAssemblyFile); } - catch + catch { Console.WriteLine("Error! '{0}'", e); } - + } // Tell the user if there's a problem copying the file @@ -977,7 +977,7 @@ namespace Prebuild.Core.Targets if(autotoolsStream == null) { - /* + /* * try without the default namespace prepended, in * case prebuild.exe assembly was compiled with * something other than Visual Studio .NET diff --git a/Prebuild/src/Core/Targets/DebugTarget.cs b/Prebuild/src/Core/Targets/DebugTarget.cs index be8aea9c1a..d78064f429 100644 --- a/Prebuild/src/Core/Targets/DebugTarget.cs +++ b/Prebuild/src/Core/Targets/DebugTarget.cs @@ -5,16 +5,16 @@ Copyright (c) 2004-2005 Matthew Holmes (matthew@wildfiregames.com), Dan Moorehea Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: -* Redistributions of source code must retain the above copyright notice, this list of conditions - and the following disclaimer. -* Redistributions in binary form must reproduce the above copyright notice, this list of conditions - and the following disclaimer in the documentation and/or other materials provided with the - distribution. -* The name of the author may not be used to endorse or promote products derived from this software - without specific prior written permission. +* Redistributions of source code must retain the above copyright notice, this list of conditions + and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions + and the following disclaimer in the documentation and/or other materials provided with the + distribution. +* The name of the author may not be used to endorse or promote products derived from this software + without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, -BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY @@ -41,62 +41,62 @@ using Prebuild.Core.Nodes; #if (DEBUG && _DEBUG_TARGET) namespace Prebuild.Core.Targets { - [Target("debug")] - public class DebugTarget : ITarget - { + [Target("debug")] + public class DebugTarget : ITarget + { #region Fields - private Kernel m_Kernel = null; + private Kernel m_Kernel = null; #endregion #region ITarget Members - public void Write() - { - foreach(SolutionNode s in m_Kernel.Solutions) - { - Console.WriteLine("Solution [ {0}, {1} ]", s.Name, s.Path); - foreach(string file in s.Files) + public void Write() + { + foreach(SolutionNode s in m_Kernel.Solutions) + { + Console.WriteLine("Solution [ {0}, {1} ]", s.Name, s.Path); + foreach(string file in s.Files) { - Console.WriteLine("\tFile [ {0} ]", file); + Console.WriteLine("\tFile [ {0} ]", file); } - foreach(ProjectNode proj in s.Projects) - { - Console.WriteLine("\tProject [ {0}, {1}. {2} ]", proj.Name, proj.Path, proj.Language); - foreach(string file in proj.Files) - Console.WriteLine("\t\tFile [ {0} ]", file); - } - } - } + foreach(ProjectNode proj in s.Projects) + { + Console.WriteLine("\tProject [ {0}, {1}. {2} ]", proj.Name, proj.Path, proj.Language); + foreach(string file in proj.Files) + Console.WriteLine("\t\tFile [ {0} ]", file); + } + } + } - public void Clean() - { - Console.WriteLine("Not implemented"); - } + public void Clean() + { + Console.WriteLine("Not implemented"); + } - public string Name - { - get - { - return "debug"; - } - } + public string Name + { + get + { + return "debug"; + } + } - public Kernel Kernel - { - get - { - return m_Kernel; - } - set - { - m_Kernel = value; - } - } + public Kernel Kernel + { + get + { + return m_Kernel; + } + set + { + m_Kernel = value; + } + } #endregion - } + } } #endif diff --git a/Prebuild/src/Core/Targets/MakefileTarget.cs b/Prebuild/src/Core/Targets/MakefileTarget.cs index 8fe1c444d2..54046dd9bb 100644 --- a/Prebuild/src/Core/Targets/MakefileTarget.cs +++ b/Prebuild/src/Core/Targets/MakefileTarget.cs @@ -5,16 +5,16 @@ Copyright (c) 2004 Crestez Leonard (cleonard@go.ro) Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: -* Redistributions of source code must retain the above copyright notice, this list of conditions - and the following disclaimer. -* Redistributions in binary form must reproduce the above copyright notice, this list of conditions - and the following disclaimer in the documentation and/or other materials provided with the - distribution. -* The name of the author may not be used to endorse or promote products derived from this software - without specific prior written permission. +* Redistributions of source code must retain the above copyright notice, this list of conditions + and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions + and the following disclaimer in the documentation and/or other materials provided with the + distribution. +* The name of the author may not be used to endorse or promote products derived from this software + without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, -BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY diff --git a/Prebuild/src/Core/Targets/MonoDevelopTarget.cs b/Prebuild/src/Core/Targets/MonoDevelopTarget.cs index 85fe2db922..ea6d2c2233 100644 --- a/Prebuild/src/Core/Targets/MonoDevelopTarget.cs +++ b/Prebuild/src/Core/Targets/MonoDevelopTarget.cs @@ -5,16 +5,16 @@ Copyright (c) 2004 Matthew Holmes (matthew@wildfiregames.com), Dan Moorehead (da Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: -* Redistributions of source code must retain the above copyright notice, this list of conditions - and the following disclaimer. -* Redistributions in binary form must reproduce the above copyright notice, this list of conditions - and the following disclaimer in the documentation and/or other materials provided with the - distribution. -* The name of the author may not be used to endorse or promote products derived from this software - without specific prior written permission. +* Redistributions of source code must retain the above copyright notice, this list of conditions + and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions + and the following disclaimer in the documentation and/or other materials provided with the + distribution. +* The name of the author may not be used to endorse or promote products derived from this software + without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, -BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY @@ -35,481 +35,481 @@ using Prebuild.Core.Utilities; namespace Prebuild.Core.Targets { - /// - /// - /// - [Target("monodev")] - public class MonoDevelopTarget : ITarget - { - #region Fields + /// + /// + /// + [Target("monodev")] + public class MonoDevelopTarget : ITarget + { + #region Fields - private Kernel m_Kernel; + private Kernel m_Kernel; - #endregion + #endregion - #region Private Methods + #region Private Methods - private static string PrependPath(string path) - { - string tmpPath = Helper.NormalizePath(path, '/'); - Regex regex = new Regex(@"(\w):/(\w+)"); - Match match = regex.Match(tmpPath); - if(match.Success || tmpPath[0] == '.' || tmpPath[0] == '/') - { - tmpPath = Helper.NormalizePath(tmpPath); - } - else - { - tmpPath = Helper.NormalizePath("./" + tmpPath); - } + private static string PrependPath(string path) + { + string tmpPath = Helper.NormalizePath(path, '/'); + Regex regex = new Regex(@"(\w):/(\w+)"); + Match match = regex.Match(tmpPath); + if(match.Success || tmpPath[0] == '.' || tmpPath[0] == '/') + { + tmpPath = Helper.NormalizePath(tmpPath); + } + else + { + tmpPath = Helper.NormalizePath("./" + tmpPath); + } - return tmpPath; - } + return tmpPath; + } - private static string BuildReference(SolutionNode solution, ReferenceNode refr) - { - string ret = ""; - } - else - { - ProjectNode project = (ProjectNode)refr.Parent; - string fileRef = FindFileReference(refr.Name, project); + private static string BuildReference(SolutionNode solution, ReferenceNode refr) + { + string ret = ""; + } + else + { + ProjectNode project = (ProjectNode)refr.Parent; + string fileRef = FindFileReference(refr.Name, project); - if(refr.Path != null || fileRef != null) - { - ret += "Assembly\" refto=\""; + if(refr.Path != null || fileRef != null) + { + ret += "Assembly\" refto=\""; - string finalPath = (refr.Path != null) ? Helper.MakeFilePath(refr.Path, refr.Name, "dll") : fileRef; + string finalPath = (refr.Path != null) ? Helper.MakeFilePath(refr.Path, refr.Name, "dll") : fileRef; - ret += finalPath; - ret += "\" localcopy=\"" + refr.LocalCopy.ToString() + "\" />"; - return ret; - } + ret += finalPath; + ret += "\" localcopy=\"" + refr.LocalCopy.ToString() + "\" />"; + return ret; + } - ret += "Gac\""; - ret += " localcopy=\"" + refr.LocalCopy.ToString() + "\""; - ret += " refto=\""; - try - { - /* - Day changed to 28 Mar 2007 - ... - 08:09 < cj> is there anything that replaces Assembly.LoadFromPartialName() ? - 08:09 < jonp> no - 08:10 < jonp> in their infinite wisdom [sic], microsoft decided that the - ability to load any assembly version by-name was an inherently - bad idea - 08:11 < cj> I'm thinking of a bunch of four-letter words right now... - 08:11 < cj> security through making it difficult for the developer!!! - 08:12 < jonp> just use the Obsolete API - 08:12 < jonp> it should still work - 08:12 < cj> alrighty. - 08:12 < jonp> you just get warnings when using it - */ - Assembly assem = Assembly.LoadWithPartialName(refr.Name); - ret += assem.FullName; + ret += "Gac\""; + ret += " localcopy=\"" + refr.LocalCopy.ToString() + "\""; + ret += " refto=\""; + try + { + /* + Day changed to 28 Mar 2007 + ... + 08:09 < cj> is there anything that replaces Assembly.LoadFromPartialName() ? + 08:09 < jonp> no + 08:10 < jonp> in their infinite wisdom [sic], microsoft decided that the + ability to load any assembly version by-name was an inherently + bad idea + 08:11 < cj> I'm thinking of a bunch of four-letter words right now... + 08:11 < cj> security through making it difficult for the developer!!! + 08:12 < jonp> just use the Obsolete API + 08:12 < jonp> it should still work + 08:12 < cj> alrighty. + 08:12 < jonp> you just get warnings when using it + */ + Assembly assem = Assembly.LoadWithPartialName(refr.Name); + ret += assem.FullName; //ret += refr.Name; - } - catch (System.NullReferenceException e) - { - e.ToString(); - ret += refr.Name; - } - ret += "\" />"; - } + } + catch (System.NullReferenceException e) + { + e.ToString(); + ret += refr.Name; + } + ret += "\" />"; + } - return ret; - } + return ret; + } - private static string FindFileReference(string refName, ProjectNode project) - { - foreach(ReferencePathNode refPath in project.ReferencePaths) - { - string fullPath = Helper.MakeFilePath(refPath.Path, refName, "dll"); + private static string FindFileReference(string refName, ProjectNode project) + { + foreach(ReferencePathNode refPath in project.ReferencePaths) + { + string fullPath = Helper.MakeFilePath(refPath.Path, refName, "dll"); - if(File.Exists(fullPath)) - { - return fullPath; - } - } + if(File.Exists(fullPath)) + { + return fullPath; + } + } - return null; - } + return null; + } - /// - /// Gets the XML doc file. - /// - /// The project. - /// The conf. - /// - public static string GenerateXmlDocFile(ProjectNode project, ConfigurationNode conf) - { - if( conf == null ) - { - throw new ArgumentNullException("conf"); - } - if( project == null ) - { - throw new ArgumentNullException("project"); - } - string docFile = (string)conf.Options["XmlDocFile"]; - if(docFile != null && docFile.Length == 0)//default to assembly name if not specified - { - return "False"; - } - return "True"; - } + /// + /// Gets the XML doc file. + /// + /// The project. + /// The conf. + /// + public static string GenerateXmlDocFile(ProjectNode project, ConfigurationNode conf) + { + if( conf == null ) + { + throw new ArgumentNullException("conf"); + } + if( project == null ) + { + throw new ArgumentNullException("project"); + } + string docFile = (string)conf.Options["XmlDocFile"]; + if(docFile != null && docFile.Length == 0)//default to assembly name if not specified + { + return "False"; + } + return "True"; + } - private void WriteProject(SolutionNode solution, ProjectNode project) - { - string csComp = "Mcs"; - string netRuntime = "Mono"; - if(project.Runtime == ClrRuntime.Microsoft) - { - csComp = "Csc"; - netRuntime = "MsNet"; - } + private void WriteProject(SolutionNode solution, ProjectNode project) + { + string csComp = "Mcs"; + string netRuntime = "Mono"; + if(project.Runtime == ClrRuntime.Microsoft) + { + csComp = "Csc"; + netRuntime = "MsNet"; + } - string projFile = Helper.MakeFilePath(project.FullPath, project.Name, "mdp"); - StreamWriter ss = new StreamWriter(projFile); + string projFile = Helper.MakeFilePath(project.FullPath, project.Name, "mdp"); + StreamWriter ss = new StreamWriter(projFile); - m_Kernel.CurrentWorkingDirectory.Push(); - Helper.SetCurrentDir(Path.GetDirectoryName(projFile)); + m_Kernel.CurrentWorkingDirectory.Push(); + Helper.SetCurrentDir(Path.GetDirectoryName(projFile)); - using(ss) - { - ss.WriteLine( - "", - project.Name, - project.RootNamespace - ); + using(ss) + { + ss.WriteLine( + "", + project.Name, + project.RootNamespace + ); + + int count = 0; + + ss.WriteLine(" ", solution.ActiveConfig); - int count = 0; - - ss.WriteLine(" ", solution.ActiveConfig); - - foreach(ConfigurationNode conf in project.Configurations) - { - ss.WriteLine(" ", conf.Name); - ss.Write(" "); - - ss.Write(" "); - - ss.Write(" ", conf.Name); + ss.Write(" "); + + ss.Write(" "); + + ss.Write(" "); + ss.WriteLine(" />"); + + ss.Write(" "); + ss.WriteLine(" "); - ss.Write(" "); - ss.WriteLine(" "); + count++; + } + ss.WriteLine(" "); - count++; - } - ss.WriteLine(" "); + ss.Write(" "); + ss.WriteLine(" "); + ss.WriteLine(" "); + + ss.WriteLine(" "); + foreach(string file in project.Files) + { + string buildAction; + string dependson = ""; + string resource_id = ""; + string copyToOutput = ""; + + switch(project.Files.GetBuildAction(file)) + { + case BuildAction.None: + buildAction = "Nothing"; + break; - ss.Write(" "); - ss.WriteLine(" "); - ss.WriteLine(" "); + case BuildAction.Content: + buildAction = "Exclude"; + break; - ss.WriteLine(" "); - foreach(string file in project.Files) - { - string buildAction; - string dependson = ""; - string resource_id = ""; - string copyToOutput = ""; + case BuildAction.EmbeddedResource: + buildAction = "EmbedAsResource"; + break; - switch(project.Files.GetBuildAction(file)) - { - case BuildAction.None: - buildAction = "Nothing"; - break; - - case BuildAction.Content: - buildAction = "Exclude"; - break; - - case BuildAction.EmbeddedResource: - buildAction = "EmbedAsResource"; - break; - - default: - buildAction = "Compile"; - break; - } + default: + buildAction = "Compile"; + break; + } if (project.Files.GetCopyToOutput(file) != CopyToOutput.Never) - buildAction = "FileCopy"; + buildAction = "FileCopy"; - // Sort of a hack, we try and resolve the path and make it relative, if we can. - string extension = Path.GetExtension(file); - string designer_format = string.Format(".Designer{0}", extension); + // Sort of a hack, we try and resolve the path and make it relative, if we can. + string extension = Path.GetExtension(file); + string designer_format = string.Format(".Designer{0}", extension); - if (file.EndsWith(designer_format)) - { - string basename = file.Substring(0, file.LastIndexOf(designer_format)); - string[] extensions = new string[] { ".cs", ".resx", ".settings" }; + if (file.EndsWith(designer_format)) + { + string basename = file.Substring(0, file.LastIndexOf(designer_format)); + string[] extensions = new string[] { ".cs", ".resx", ".settings" }; - foreach(string ext in extensions) - { - if (project.Files.Contains(basename + ext)) - { - dependson = string.Format(" dependson=\"{0}{1}\"", basename, ext); - break; - } - } - } - if (extension == ".resx") - { - buildAction = "EmbedAsResource"; - string basename = file.Substring(0, file.LastIndexOf(".resx")); + foreach(string ext in extensions) + { + if (project.Files.Contains(basename + ext)) + { + dependson = string.Format(" dependson=\"{0}{1}\"", basename, ext); + break; + } + } + } + if (extension == ".resx") + { + buildAction = "EmbedAsResource"; + string basename = file.Substring(0, file.LastIndexOf(".resx")); + + // Visual Studio type resx + form dependency + if (project.Files.Contains(basename + ".cs")) + { + dependson = string.Format(" dependson=\"{0}{1}\"", basename, ".cs"); + } - // Visual Studio type resx + form dependency - if (project.Files.Contains(basename + ".cs")) - { - dependson = string.Format(" dependson=\"{0}{1}\"", basename, ".cs"); - } + // We need to specify a resources file name to avoid MissingManifestResourceExceptions + // in libraries that are built. + resource_id = string.Format(" resource_id=\"{0}.{1}.resources\"", + project.AssemblyName, basename.Replace("/", ".")); + } - // We need to specify a resources file name to avoid MissingManifestResourceExceptions - // in libraries that are built. - resource_id = string.Format(" resource_id=\"{0}.{1}.resources\"", - project.AssemblyName, basename.Replace("/", ".")); - } + switch(project.Files.GetCopyToOutput(file)) + { + case CopyToOutput.Always: + copyToOutput = string.Format(" copyToOutputDirectory=\"Always\""); + break; + case CopyToOutput.PreserveNewest: + copyToOutput = string.Format(" copyToOutputDirectory=\"PreserveNewest\""); + break; + } + + // Sort of a hack, we try and resolve the path and make it relative, if we can. + string filePath = PrependPath(file); + ss.WriteLine(" ", + filePath, buildAction, dependson, resource_id, copyToOutput); + } + ss.WriteLine(" "); - switch(project.Files.GetCopyToOutput(file)) - { - case CopyToOutput.Always: - copyToOutput = string.Format(" copyToOutputDirectory=\"Always\""); - break; - case CopyToOutput.PreserveNewest: - copyToOutput = string.Format(" copyToOutputDirectory=\"PreserveNewest\""); - break; - } - - // Sort of a hack, we try and resolve the path and make it relative, if we can. - string filePath = PrependPath(file); - ss.WriteLine(" ", - filePath, buildAction, dependson, resource_id, copyToOutput); - } - ss.WriteLine(" "); - - ss.WriteLine(" "); - foreach(ReferenceNode refr in project.References) - { - ss.WriteLine(" {0}", BuildReference(solution, refr)); - } - ss.WriteLine(" "); + ss.WriteLine(" "); + foreach(ReferenceNode refr in project.References) + { + ss.WriteLine(" {0}", BuildReference(solution, refr)); + } + ss.WriteLine(" "); - ss.WriteLine(""); - } + ss.WriteLine(""); + } - m_Kernel.CurrentWorkingDirectory.Pop(); - } + m_Kernel.CurrentWorkingDirectory.Pop(); + } - private void WriteCombine(SolutionNode solution) - { - m_Kernel.Log.Write("Creating MonoDevelop combine and project files"); - foreach(ProjectNode project in solution.Projects) - { - if(m_Kernel.AllowProject(project.FilterGroups)) - { - m_Kernel.Log.Write("...Creating project: {0}", project.Name); - WriteProject(solution, project); - } - } + private void WriteCombine(SolutionNode solution) + { + m_Kernel.Log.Write("Creating MonoDevelop combine and project files"); + foreach(ProjectNode project in solution.Projects) + { + if(m_Kernel.AllowProject(project.FilterGroups)) + { + m_Kernel.Log.Write("...Creating project: {0}", project.Name); + WriteProject(solution, project); + } + } - m_Kernel.Log.Write(""); - string combFile = Helper.MakeFilePath(solution.FullPath, solution.Name, "mds"); - StreamWriter ss = new StreamWriter(combFile); - - m_Kernel.CurrentWorkingDirectory.Push(); - Helper.SetCurrentDir(Path.GetDirectoryName(combFile)); + m_Kernel.Log.Write(""); + string combFile = Helper.MakeFilePath(solution.FullPath, solution.Name, "mds"); + StreamWriter ss = new StreamWriter(combFile); + m_Kernel.CurrentWorkingDirectory.Push(); + Helper.SetCurrentDir(Path.GetDirectoryName(combFile)); + int count = 0; + + using(ss) + { + ss.WriteLine("", solution.Name); - using(ss) - { - ss.WriteLine("", solution.Name); + count = 0; + foreach(ConfigurationNode conf in solution.Configurations) + { + if(count == 0) + { + ss.WriteLine(" ", conf.Name); + } - count = 0; - foreach(ConfigurationNode conf in solution.Configurations) - { - if(count == 0) - { - ss.WriteLine(" ", conf.Name); - } + ss.WriteLine(" ", conf.Name); + foreach(ProjectNode project in solution.Projects) + { + ss.WriteLine(" ", project.Name, conf.Name); + } + ss.WriteLine(" "); - ss.WriteLine(" ", conf.Name); - foreach(ProjectNode project in solution.Projects) - { - ss.WriteLine(" ", project.Name, conf.Name); - } - ss.WriteLine(" "); + count++; + } + ss.WriteLine(" "); + + count = 0; + + foreach(ProjectNode project in solution.Projects) + { + if(count == 0) + ss.WriteLine(" ", project.Name); - count++; - } - ss.WriteLine(" "); + ss.WriteLine(" ", project.Name); + count++; + } + ss.WriteLine(" "); + + ss.WriteLine(" "); + foreach(ProjectNode project in solution.Projects) + { + string path = Helper.MakePathRelativeTo(solution.FullPath, project.FullPath); + ss.WriteLine(" ", + Helper.MakeFilePath(path, project.Name, "mdp")); + } + ss.WriteLine(" "); + + ss.WriteLine(""); + } - count = 0; + m_Kernel.CurrentWorkingDirectory.Pop(); + } - foreach(ProjectNode project in solution.Projects) - { - if(count == 0) - ss.WriteLine(" ", project.Name); + private void CleanProject(ProjectNode project) + { + m_Kernel.Log.Write("...Cleaning project: {0}", project.Name); + string projectFile = Helper.MakeFilePath(project.FullPath, project.Name, "mdp"); + Helper.DeleteIfExists(projectFile); + } - ss.WriteLine(" ", project.Name); - count++; - } - ss.WriteLine(" "); + private void CleanSolution(SolutionNode solution) + { + m_Kernel.Log.Write("Cleaning MonoDevelop combine and project files for", solution.Name); - ss.WriteLine(" "); - foreach(ProjectNode project in solution.Projects) - { - string path = Helper.MakePathRelativeTo(solution.FullPath, project.FullPath); - ss.WriteLine(" ", - Helper.MakeFilePath(path, project.Name, "mdp")); - } - ss.WriteLine(" "); + string slnFile = Helper.MakeFilePath(solution.FullPath, solution.Name, "mds"); + Helper.DeleteIfExists(slnFile); - ss.WriteLine(""); - } + foreach(ProjectNode project in solution.Projects) + { + CleanProject(project); + } + + m_Kernel.Log.Write(""); + } - m_Kernel.CurrentWorkingDirectory.Pop(); - } + #endregion - private void CleanProject(ProjectNode project) - { - m_Kernel.Log.Write("...Cleaning project: {0}", project.Name); - string projectFile = Helper.MakeFilePath(project.FullPath, project.Name, "mdp"); - Helper.DeleteIfExists(projectFile); - } + #region ITarget Members - private void CleanSolution(SolutionNode solution) - { - m_Kernel.Log.Write("Cleaning MonoDevelop combine and project files for", solution.Name); + /// + /// Writes the specified kern. + /// + /// The kern. + public void Write(Kernel kern) + { + if( kern == null ) + { + throw new ArgumentNullException("kern"); + } + m_Kernel = kern; + foreach(SolutionNode solution in kern.Solutions) + { + WriteCombine(solution); + } + m_Kernel = null; + } - string slnFile = Helper.MakeFilePath(solution.FullPath, solution.Name, "mds"); - Helper.DeleteIfExists(slnFile); + /// + /// Cleans the specified kern. + /// + /// The kern. + public virtual void Clean(Kernel kern) + { + if( kern == null ) + { + throw new ArgumentNullException("kern"); + } + m_Kernel = kern; + foreach(SolutionNode sol in kern.Solutions) + { + CleanSolution(sol); + } + m_Kernel = null; + } - foreach(ProjectNode project in solution.Projects) - { - CleanProject(project); - } + /// + /// Gets the name. + /// + /// The name. + public string Name + { + get + { + return "sharpdev"; + } + } - m_Kernel.Log.Write(""); - } - - #endregion - - #region ITarget Members - - /// - /// Writes the specified kern. - /// - /// The kern. - public void Write(Kernel kern) - { - if( kern == null ) - { - throw new ArgumentNullException("kern"); - } - m_Kernel = kern; - foreach(SolutionNode solution in kern.Solutions) - { - WriteCombine(solution); - } - m_Kernel = null; - } - - /// - /// Cleans the specified kern. - /// - /// The kern. - public virtual void Clean(Kernel kern) - { - if( kern == null ) - { - throw new ArgumentNullException("kern"); - } - m_Kernel = kern; - foreach(SolutionNode sol in kern.Solutions) - { - CleanSolution(sol); - } - m_Kernel = null; - } - - /// - /// Gets the name. - /// - /// The name. - public string Name - { - get - { - return "sharpdev"; - } - } - - #endregion - } + #endregion + } } diff --git a/Prebuild/src/Core/Targets/NAntTarget.cs b/Prebuild/src/Core/Targets/NAntTarget.cs index 21bc80ec41..925f5ca86d 100644 --- a/Prebuild/src/Core/Targets/NAntTarget.cs +++ b/Prebuild/src/Core/Targets/NAntTarget.cs @@ -47,36 +47,36 @@ using Prebuild.Core.Utilities; namespace Prebuild.Core.Targets { - /// - /// - /// - [Target("nant")] - public class NAntTarget : ITarget - { - #region Fields + /// + /// + /// + [Target("nant")] + public class NAntTarget : ITarget + { + #region Fields - private Kernel m_Kernel; + private Kernel m_Kernel; - #endregion + #endregion - #region Private Methods + #region Private Methods - private static string PrependPath(string path) - { - string tmpPath = Helper.NormalizePath(path, '/'); - Regex regex = new Regex(@"(\w):/(\w+)"); - Match match = regex.Match(tmpPath); - //if(match.Success || tmpPath[0] == '.' || tmpPath[0] == '/') - //{ - tmpPath = Helper.NormalizePath(tmpPath); - //} - // else - // { - // tmpPath = Helper.NormalizePath("./" + tmpPath); - // } + private static string PrependPath(string path) + { + string tmpPath = Helper.NormalizePath(path, '/'); + Regex regex = new Regex(@"(\w):/(\w+)"); + Match match = regex.Match(tmpPath); + //if(match.Success || tmpPath[0] == '.' || tmpPath[0] == '/') + //{ + tmpPath = Helper.NormalizePath(tmpPath); + //} + // else + // { + // tmpPath = Helper.NormalizePath("./" + tmpPath); + // } - return tmpPath; - } + return tmpPath; + } private static string BuildReference(SolutionNode solution, ProjectNode currentProject, ReferenceNode refr) { @@ -85,7 +85,7 @@ namespace Prebuild.Core.Targets { return refr.Path; } - + if (solution.ProjectsTable.ContainsKey(refr.Name)) { ProjectNode projectRef = (ProjectNode) solution.ProjectsTable[refr.Name]; @@ -113,7 +113,7 @@ namespace Prebuild.Core.Targets return refr.Name + ".dll"; } - public static string GetRefFileName(string refName) + public static string GetRefFileName(string refName) { if (ExtensionSpecified(refName)) { @@ -140,11 +140,11 @@ namespace Prebuild.Core.Targets return extension; } - private static string FindFileReference(string refName, ProjectNode project) - { - foreach (ReferencePathNode refPath in project.ReferencePaths) - { - string fullPath = Helper.MakeFilePath(refPath.Path, refName); + private static string FindFileReference(string refName, ProjectNode project) + { + foreach (ReferencePathNode refPath in project.ReferencePaths) + { + string fullPath = Helper.MakeFilePath(refPath.Path, refName); if (File.Exists(fullPath)) { @@ -153,10 +153,10 @@ namespace Prebuild.Core.Targets fullPath = Helper.MakeFilePath(refPath.Path, refName, "dll"); - if (File.Exists(fullPath)) - { - return fullPath; - } + if (File.Exists(fullPath)) + { + return fullPath; + } fullPath = Helper.MakeFilePath(refPath.Path, refName, "exe"); @@ -164,162 +164,205 @@ namespace Prebuild.Core.Targets { return fullPath; } - } + } - return null; - } + return null; + } - /// - /// Gets the XML doc file. - /// - /// The project. - /// The conf. - /// - public static string GetXmlDocFile(ProjectNode project, ConfigurationNode conf) - { - if (conf == null) - { - throw new ArgumentNullException("conf"); - } - if (project == null) - { - throw new ArgumentNullException("project"); - } - string docFile = (string)conf.Options["XmlDocFile"]; - // if(docFile != null && docFile.Length == 0)//default to assembly name if not specified - // { - // return Path.GetFileNameWithoutExtension(project.AssemblyName) + ".xml"; - // } - return docFile; - } + /// + /// Gets the XML doc file. + /// + /// The project. + /// The conf. + /// + public static string GetXmlDocFile(ProjectNode project, ConfigurationNode conf) + { + if (conf == null) + { + throw new ArgumentNullException("conf"); + } + if (project == null) + { + throw new ArgumentNullException("project"); + } + string docFile = (string)conf.Options["XmlDocFile"]; + // if(docFile != null && docFile.Length == 0)//default to assembly name if not specified + // { + // return Path.GetFileNameWithoutExtension(project.AssemblyName) + ".xml"; + // } + return docFile; + } - private void WriteProject(SolutionNode solution, ProjectNode project) - { + private void WriteProject(SolutionNode solution, ProjectNode project) + { string projFile = Helper.MakeFilePath(project.FullPath, project.Name + GetProjectExtension(project), "build"); - StreamWriter ss = new StreamWriter(projFile); + StreamWriter ss = new StreamWriter(projFile); - m_Kernel.CurrentWorkingDirectory.Push(); - Helper.SetCurrentDir(Path.GetDirectoryName(projFile)); - bool hasDoc = false; + m_Kernel.CurrentWorkingDirectory.Push(); + Helper.SetCurrentDir(Path.GetDirectoryName(projFile)); + bool hasDoc = false; - using (ss) - { - ss.WriteLine(""); - ss.WriteLine("", project.Name); - ss.WriteLine(" ", "build"); - ss.WriteLine(" "); - ss.WriteLine(" "); + using (ss) + { + ss.WriteLine(""); + ss.WriteLine("", project.Name); + ss.WriteLine(" ", "build"); + ss.WriteLine(" "); + ss.WriteLine(" "); + ss.WriteLine(" "); + ss.WriteLine(" "); + foreach (ReferenceNode refr in project.References) + { + if (refr.LocalCopy) + { + ss.WriteLine(" ", '/')); + } + } + + ss.WriteLine(" "); + ss.WriteLine(" "); + if (project.ConfigFile != null && project.ConfigFile.Length!=0) + { + ss.Write(" "); + } + + // Add the content files to just be copied + ss.WriteLine(" {0}", ""); + ss.WriteLine(" {0}", ""); + + foreach (string file in project.Files) + { + // Ignore if we aren't content + if (project.Files.GetBuildAction(file) != BuildAction.Content) + continue; + + // Create a include tag + ss.WriteLine(" {0}", ""); + } + + ss.WriteLine(" {0}", ""); + ss.WriteLine(" {0}", ""); + + ss.Write(" "); - ss.WriteLine(" ", project.RootNamespace); - foreach (string file in project.Files) - { - switch (project.Files.GetBuildAction(file)) - { - case BuildAction.EmbeddedResource: - ss.WriteLine(" {0}", ""); - break; - default: - if (project.Files.GetSubType(file) != SubType.Code && project.Files.GetSubType(file) != SubType.Settings) - { - ss.WriteLine(" ", file.Substring(0, file.LastIndexOf('.')) + ".resx"); - } - break; - } - } - //if (project.Files.GetSubType(file).ToString() != "Code") - //{ - // ps.WriteLine(" ", file.Substring(0, file.LastIndexOf('.')) + ".resx"); + ss.WriteLine(" ", project.RootNamespace); + foreach (string file in project.Files) + { + switch (project.Files.GetBuildAction(file)) + { + case BuildAction.EmbeddedResource: + ss.WriteLine(" {0}", ""); + break; + default: + if (project.Files.GetSubType(file) != SubType.Code && project.Files.GetSubType(file) != SubType.Settings) + { + ss.WriteLine(" ", file.Substring(0, file.LastIndexOf('.')) + ".resx"); + } + break; + } + } + //if (project.Files.GetSubType(file).ToString() != "Code") + //{ + // ps.WriteLine(" ", file.Substring(0, file.LastIndexOf('.')) + ".resx"); - ss.WriteLine(" "); - ss.WriteLine(" "); - foreach (string file in project.Files) - { - switch (project.Files.GetBuildAction(file)) - { - case BuildAction.Compile: - ss.WriteLine(" "); - break; - default: - break; - } - } - ss.WriteLine(" "); - ss.WriteLine(" "); - ss.WriteLine(" "); - ss.WriteLine(" "); + ss.WriteLine(" "); + ss.WriteLine(" "); + foreach (string file in project.Files) + { + switch (project.Files.GetBuildAction(file)) + { + case BuildAction.Compile: + ss.WriteLine(" "); + break; + default: + break; + } + } + ss.WriteLine(" "); + ss.WriteLine(" "); + ss.WriteLine(" "); + ss.WriteLine(" "); foreach(ReferencePathNode refPath in project.ReferencePaths) { ss.WriteLine(" "); } - ss.WriteLine(" "); - foreach (ReferenceNode refr in project.References) - { - string path = Helper.NormalizePath(Helper.MakePathRelativeTo(project.FullPath, BuildReference(solution, project, refr)), '/'); + ss.WriteLine(" "); + foreach (ReferenceNode refr in project.References) + { + string path = Helper.NormalizePath(Helper.MakePathRelativeTo(project.FullPath, BuildReference(solution, project, refr)), '/'); if (refr.Path != null) { if (ExtensionSpecified(refr.Name)) { @@ -334,12 +377,12 @@ namespace Prebuild.Core.Targets { ss.WriteLine (" "); } - } - ss.WriteLine(" "); + } + ss.WriteLine(" "); - ss.WriteLine(" "); + ss.WriteLine(" "); - foreach (ConfigurationNode conf in project.Configurations) + foreach (ConfigurationNode conf in project.Configurations) { if (!String.IsNullOrEmpty(conf.Options.OutputPath)) { @@ -361,170 +404,170 @@ namespace Prebuild.Core.Targets } } - ss.WriteLine(" "); + ss.WriteLine(" "); - ss.WriteLine(" "); - ss.WriteLine(" "); - ss.WriteLine(" "); - ss.WriteLine(" "); + ss.WriteLine(" "); + ss.WriteLine(" "); + ss.WriteLine(" "); + ss.WriteLine(" "); - ss.WriteLine(" "); - if (hasDoc) - { - ss.WriteLine(" "); - ss.WriteLine(" "); - ss.WriteLine(" "); - ss.WriteLine(" "); - ss.WriteLine(" "); - ss.WriteLine(" "); - ss.Write(" "); - } - else - { - ss.WriteLine(".exe\" />"); - } + ss.WriteLine(" "); + if (hasDoc) + { + ss.WriteLine(" "); + ss.WriteLine(" "); + ss.WriteLine(" "); + ss.WriteLine(" "); + ss.WriteLine(" "); + ss.WriteLine(" "); + ss.Write(" "); + } + else + { + ss.WriteLine(".exe\" />"); + } - ss.WriteLine(" "); - ss.WriteLine(" "); - ss.WriteLine(" "); - ss.WriteLine(" "); - ss.WriteLine(" "); - ss.WriteLine(" "); - // foreach(ReferenceNode refr in project.References) - // { - // string path = Helper.NormalizePath(Helper.MakePathRelativeTo(project.FullPath, BuildReferencePath(solution, refr)), '/'); - // if (path != "") - // { - // ss.WriteLine(" ", path); - // } - // } - ss.WriteLine(" "); - ss.WriteLine(" "); - ss.WriteLine(" "); - ss.WriteLine(" "); - ss.WriteLine(" "); - ss.WriteLine(" "); - ss.WriteLine(" "); - ss.WriteLine(" "); - ss.WriteLine(" "); - ss.WriteLine(" "); - ss.WriteLine(" "); - ss.WriteLine(" "); - ss.WriteLine(" "); - ss.WriteLine(" "); - ss.WriteLine(" "); - ss.WriteLine(" "); - ss.WriteLine(" "); - ss.WriteLine(" "); - ss.WriteLine(" "); - ss.WriteLine(" "); - ss.WriteLine(" "); - ss.WriteLine(" "); - ss.WriteLine(" "); - ss.WriteLine(" "); - ss.WriteLine(" "); - } - ss.WriteLine(" "); - ss.WriteLine(""); - } - m_Kernel.CurrentWorkingDirectory.Pop(); - } + ss.WriteLine(" "); + ss.WriteLine(" "); + ss.WriteLine(" "); + ss.WriteLine(" "); + ss.WriteLine(" "); + ss.WriteLine(" "); + // foreach(ReferenceNode refr in project.References) + // { + // string path = Helper.NormalizePath(Helper.MakePathRelativeTo(project.FullPath, BuildReferencePath(solution, refr)), '/'); + // if (path != "") + // { + // ss.WriteLine(" ", path); + // } + // } + ss.WriteLine(" "); + ss.WriteLine(" "); + ss.WriteLine(" "); + ss.WriteLine(" "); + ss.WriteLine(" "); + ss.WriteLine(" "); + ss.WriteLine(" "); + ss.WriteLine(" "); + ss.WriteLine(" "); + ss.WriteLine(" "); + ss.WriteLine(" "); + ss.WriteLine(" "); + ss.WriteLine(" "); + ss.WriteLine(" "); + ss.WriteLine(" "); + ss.WriteLine(" "); + ss.WriteLine(" "); + ss.WriteLine(" "); + ss.WriteLine(" "); + ss.WriteLine(" "); + ss.WriteLine(" "); + ss.WriteLine(" "); + ss.WriteLine(" "); + ss.WriteLine(" "); + ss.WriteLine(" "); + } + ss.WriteLine(" "); + ss.WriteLine(""); + } + m_Kernel.CurrentWorkingDirectory.Pop(); + } - private void WriteCombine(SolutionNode solution) - { - m_Kernel.Log.Write("Creating NAnt build files"); - foreach (ProjectNode project in solution.Projects) - { - if (m_Kernel.AllowProject(project.FilterGroups)) - { - m_Kernel.Log.Write("...Creating project: {0}", project.Name); - WriteProject(solution, project); - } - } + private void WriteCombine(SolutionNode solution) + { + m_Kernel.Log.Write("Creating NAnt build files"); + foreach (ProjectNode project in solution.Projects) + { + if (m_Kernel.AllowProject(project.FilterGroups)) + { + m_Kernel.Log.Write("...Creating project: {0}", project.Name); + WriteProject(solution, project); + } + } - m_Kernel.Log.Write(""); - string combFile = Helper.MakeFilePath(solution.FullPath, solution.Name, "build"); - StreamWriter ss = new StreamWriter(combFile); + m_Kernel.Log.Write(""); + string combFile = Helper.MakeFilePath(solution.FullPath, solution.Name, "build"); + StreamWriter ss = new StreamWriter(combFile); - m_Kernel.CurrentWorkingDirectory.Push(); - Helper.SetCurrentDir(Path.GetDirectoryName(combFile)); + m_Kernel.CurrentWorkingDirectory.Push(); + Helper.SetCurrentDir(Path.GetDirectoryName(combFile)); - using (ss) - { - ss.WriteLine(""); - ss.WriteLine("", solution.Name); - ss.WriteLine(" "); - ss.WriteLine(); + using (ss) + { + ss.WriteLine(""); + ss.WriteLine("", solution.Name); + ss.WriteLine(" "); + ss.WriteLine(); - //ss.WriteLine(" "); - //ss.WriteLine(" "); - ss.WriteLine(" "); - ss.WriteLine(" "); - ss.WriteLine(" "); - ss.WriteLine(" "); + //ss.WriteLine(" "); + //ss.WriteLine(" "); + ss.WriteLine(" "); + ss.WriteLine(" "); + ss.WriteLine(" "); + ss.WriteLine(" "); - // Use the active configuration, which is the first configuration name in the prebuild file. - Dictionary emittedConfigurations = new Dictionary(); + // Use the active configuration, which is the first configuration name in the prebuild file. + Dictionary emittedConfigurations = new Dictionary(); - ss.WriteLine(" ", solution.ActiveConfig); - ss.WriteLine(); + ss.WriteLine(" ", solution.ActiveConfig); + ss.WriteLine(); - foreach (ConfigurationNode conf in solution.Configurations) - { - // If the name isn't in the emitted configurations, we give a high level target to the - // platform specific on. This lets "Debug" point to "Debug-AnyCPU". - if (!emittedConfigurations.ContainsKey(conf.Name)) - { - // Add it to the dictionary so we only emit one. - emittedConfigurations.Add(conf.Name, conf.Platform); + foreach (ConfigurationNode conf in solution.Configurations) + { + // If the name isn't in the emitted configurations, we give a high level target to the + // platform specific on. This lets "Debug" point to "Debug-AnyCPU". + if (!emittedConfigurations.ContainsKey(conf.Name)) + { + // Add it to the dictionary so we only emit one. + emittedConfigurations.Add(conf.Name, conf.Platform); - // Write out the target block. - ss.WriteLine(" ", conf.Name, conf.Platform); - ss.WriteLine(" "); - ss.WriteLine(); - } + // Write out the target block. + ss.WriteLine(" ", conf.Name, conf.Platform); + ss.WriteLine(" "); + ss.WriteLine(); + } - // Write out the target for the configuration. - ss.WriteLine(" ", conf.Name, conf.Platform); - ss.WriteLine(" ", conf.Name); - ss.WriteLine(" ", conf.Options["DebugInformation"].ToString().ToLower()); - ss.WriteLine("\t\t ", conf.Platform); - ss.WriteLine(" "); - ss.WriteLine(); - } + // Write out the target for the configuration. + ss.WriteLine(" ", conf.Name, conf.Platform); + ss.WriteLine(" ", conf.Name); + ss.WriteLine(" ", conf.Options["DebugInformation"].ToString().ToLower()); + ss.WriteLine("\t\t ", conf.Platform); + ss.WriteLine(" "); + ss.WriteLine(); + } - ss.WriteLine(" "); - ss.WriteLine(" "); - ss.WriteLine(" "); - ss.WriteLine(); + ss.WriteLine(" "); + ss.WriteLine(" "); + ss.WriteLine(" "); + ss.WriteLine(); - ss.WriteLine(" "); - ss.WriteLine(" "); - ss.WriteLine(" "); - ss.WriteLine(); + ss.WriteLine(" "); + ss.WriteLine(" "); + ss.WriteLine(" "); + ss.WriteLine(); - ss.WriteLine(" "); - ss.WriteLine(" "); - ss.WriteLine(" "); - ss.WriteLine(); + ss.WriteLine(" "); + ss.WriteLine(" "); + ss.WriteLine(" "); + ss.WriteLine(); - ss.WriteLine(" "); - ss.WriteLine(" "); - ss.WriteLine(" "); - ss.WriteLine(); + ss.WriteLine(" "); + ss.WriteLine(" "); + ss.WriteLine(" "); + ss.WriteLine(); - ss.WriteLine(" "); - ss.WriteLine(" "); - ss.WriteLine(" "); - ss.WriteLine(); + ss.WriteLine(" "); + ss.WriteLine(" "); + ss.WriteLine(" "); + ss.WriteLine(); - ss.WriteLine(" "); - ss.WriteLine(" "); - ss.WriteLine(" "); - ss.WriteLine(); + ss.WriteLine(" "); + ss.WriteLine(" "); + ss.WriteLine(" "); + ss.WriteLine(); ss.WriteLine(" "); ss.WriteLine(" "); @@ -594,24 +637,6 @@ namespace Prebuild.Core.Targets ss.WriteLine(" "); ss.WriteLine(" "); //ss.WriteLine(" "); - - // justincc: FIXME FIXME FIXME - A temporary OpenSim hack to clean up files when "nant clean" is executed. - // Should be replaced with extreme prejudice once anybody finds out if the CleanFiles stuff works or there is - // another working mechanism for specifying this stuff - ss.WriteLine(" "); - ss.WriteLine(" "); - ss.WriteLine(" "); - ss.WriteLine(" "); - ss.WriteLine(" "); - ss.WriteLine(" "); - ss.WriteLine(" "); - ss.WriteLine(" "); - ss.WriteLine(" "); - ss.WriteLine(" "); - ss.WriteLine(" "); - ss.WriteLine(" "); - ss.WriteLine(" "); - if (solution.Cleanup != null && solution.Cleanup.CleanFiles.Count > 0) { foreach (CleanFilesNode cleanFile in solution.Cleanup.CleanFiles) @@ -625,7 +650,7 @@ namespace Prebuild.Core.Targets } } - ss.WriteLine(" "); + ss.WriteLine(" "); foreach (ProjectNode project in solution.Projects) { string path = Helper.MakePathRelativeTo(solution.FullPath, project.FullPath); diff --git a/Prebuild/src/Core/Targets/SharpDevelop2Target.cs b/Prebuild/src/Core/Targets/SharpDevelop2Target.cs index 40a210de55..66dd1bc6f6 100644 --- a/Prebuild/src/Core/Targets/SharpDevelop2Target.cs +++ b/Prebuild/src/Core/Targets/SharpDevelop2Target.cs @@ -5,16 +5,16 @@ Copyright (c) 2004-2005 Matthew Holmes (matthew@wildfiregames.com), Dan Moorehea Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: -* Redistributions of source code must retain the above copyright notice, this list of conditions - and the following disclaimer. -* Redistributions in binary form must reproduce the above copyright notice, this list of conditions - and the following disclaimer in the documentation and/or other materials provided with the - distribution. -* The name of the author may not be used to endorse or promote products derived from this software - without specific prior written permission. +* Redistributions of source code must retain the above copyright notice, this list of conditions + and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions + and the following disclaimer in the documentation and/or other materials provided with the + distribution. +* The name of the author may not be used to endorse or promote products derived from this software + without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, -BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY @@ -29,11 +29,11 @@ using Prebuild.Core.Attributes; namespace Prebuild.Core.Targets { - /// - /// - /// - [Target("sharpdev2")] - public class SharpDevelop2Target : VS2005Target + /// + /// + /// + [Target("sharpdev2")] + public class SharpDevelop2Target : VS2005Target { #region Properties public override string VersionName @@ -45,38 +45,38 @@ namespace Prebuild.Core.Targets } #endregion - #region Public Methods + #region Public Methods - /// - /// Writes the specified kern. - /// - /// The kern. - public override void Write(Kernel kern) - { - base.Write(kern); - } + /// + /// Writes the specified kern. + /// + /// The kern. + public override void Write(Kernel kern) + { + base.Write(kern); + } - /// - /// Cleans the specified kern. - /// - /// The kern. - public override void Clean(Kernel kern) - { - base.Clean(kern); - } + /// + /// Cleans the specified kern. + /// + /// The kern. + public override void Clean(Kernel kern) + { + base.Clean(kern); + } - /// - /// Gets the name. - /// - /// The name. - public override string Name - { - get - { - return "sharpdev2"; - } - } + /// + /// Gets the name. + /// + /// The name. + public override string Name + { + get + { + return "sharpdev2"; + } + } - #endregion - } + #endregion + } } diff --git a/Prebuild/src/Core/Targets/SharpDevelopTarget.cs b/Prebuild/src/Core/Targets/SharpDevelopTarget.cs index acab9f48bc..8e3205025f 100644 --- a/Prebuild/src/Core/Targets/SharpDevelopTarget.cs +++ b/Prebuild/src/Core/Targets/SharpDevelopTarget.cs @@ -5,16 +5,16 @@ Copyright (c) 2004 Matthew Holmes (matthew@wildfiregames.com), Dan Moorehead (da Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: -* Redistributions of source code must retain the above copyright notice, this list of conditions - and the following disclaimer. -* Redistributions in binary form must reproduce the above copyright notice, this list of conditions - and the following disclaimer in the documentation and/or other materials provided with the - distribution. -* The name of the author may not be used to endorse or promote products derived from this software - without specific prior written permission. +* Redistributions of source code must retain the above copyright notice, this list of conditions + and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions + and the following disclaimer in the documentation and/or other materials provided with the + distribution. +* The name of the author may not be used to endorse or promote products derived from this software + without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, -BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY @@ -34,392 +34,392 @@ using Prebuild.Core.Utilities; namespace Prebuild.Core.Targets { - /// - /// - /// - [Target("sharpdev")] - public class SharpDevelopTarget : ITarget - { - #region Fields + /// + /// + /// + [Target("sharpdev")] + public class SharpDevelopTarget : ITarget + { + #region Fields - private Kernel m_Kernel; + private Kernel m_Kernel; - #endregion + #endregion - #region Private Methods + #region Private Methods - private static string PrependPath(string path) - { - string tmpPath = Helper.NormalizePath(path, '/'); - Regex regex = new Regex(@"(\w):/(\w+)"); - Match match = regex.Match(tmpPath); - if(match.Success || tmpPath[0] == '.' || tmpPath[0] == '/') - { - tmpPath = Helper.NormalizePath(tmpPath); - } - else - { - tmpPath = Helper.NormalizePath("./" + tmpPath); - } + private static string PrependPath(string path) + { + string tmpPath = Helper.NormalizePath(path, '/'); + Regex regex = new Regex(@"(\w):/(\w+)"); + Match match = regex.Match(tmpPath); + if(match.Success || tmpPath[0] == '.' || tmpPath[0] == '/') + { + tmpPath = Helper.NormalizePath(tmpPath); + } + else + { + tmpPath = Helper.NormalizePath("./" + tmpPath); + } - return tmpPath; - } + return tmpPath; + } - private static string BuildReference(SolutionNode solution, ReferenceNode refr) - { - string ret = ""; - } - else - { - ProjectNode project = (ProjectNode)refr.Parent; - string fileRef = FindFileReference(refr.Name, project); + private static string BuildReference(SolutionNode solution, ReferenceNode refr) + { + string ret = ""; + } + else + { + ProjectNode project = (ProjectNode)refr.Parent; + string fileRef = FindFileReference(refr.Name, project); - if(refr.Path != null || fileRef != null) - { - ret += "Assembly\" refto=\""; + if(refr.Path != null || fileRef != null) + { + ret += "Assembly\" refto=\""; - string finalPath = (refr.Path != null) ? Helper.MakeFilePath(refr.Path, refr.Name, "dll") : fileRef; + string finalPath = (refr.Path != null) ? Helper.MakeFilePath(refr.Path, refr.Name, "dll") : fileRef; - ret += finalPath; - ret += "\" localcopy=\"" + refr.LocalCopy.ToString() + "\" />"; - return ret; - } + ret += finalPath; + ret += "\" localcopy=\"" + refr.LocalCopy.ToString() + "\" />"; + return ret; + } - ret += "Gac\" refto=\""; - try - { - //Assembly assem = Assembly.Load(refr.Name); + ret += "Gac\" refto=\""; + try + { + //Assembly assem = Assembly.Load(refr.Name); ret += refr.Name;// assem.FullName; - } - catch (System.NullReferenceException e) - { - e.ToString(); - ret += refr.Name; - } - ret += "\" localcopy=\"" + refr.LocalCopy.ToString() + "\" />"; - } + } + catch (System.NullReferenceException e) + { + e.ToString(); + ret += refr.Name; + } + ret += "\" localcopy=\"" + refr.LocalCopy.ToString() + "\" />"; + } - return ret; - } + return ret; + } - private static string FindFileReference(string refName, ProjectNode project) - { - foreach(ReferencePathNode refPath in project.ReferencePaths) - { - string fullPath = Helper.MakeFilePath(refPath.Path, refName, "dll"); + private static string FindFileReference(string refName, ProjectNode project) + { + foreach(ReferencePathNode refPath in project.ReferencePaths) + { + string fullPath = Helper.MakeFilePath(refPath.Path, refName, "dll"); - if(File.Exists(fullPath)) - { - return fullPath; - } - } + if(File.Exists(fullPath)) + { + return fullPath; + } + } - return null; - } + return null; + } - /// - /// Gets the XML doc file. - /// - /// The project. - /// The conf. - /// - public static string GenerateXmlDocFile(ProjectNode project, ConfigurationNode conf) - { - if( conf == null ) - { - throw new ArgumentNullException("conf"); - } - if( project == null ) - { - throw new ArgumentNullException("project"); - } - string docFile = (string)conf.Options["XmlDocFile"]; - if(docFile != null && docFile.Length == 0)//default to assembly name if not specified - { - return "False"; - } - return "True"; - } + /// + /// Gets the XML doc file. + /// + /// The project. + /// The conf. + /// + public static string GenerateXmlDocFile(ProjectNode project, ConfigurationNode conf) + { + if( conf == null ) + { + throw new ArgumentNullException("conf"); + } + if( project == null ) + { + throw new ArgumentNullException("project"); + } + string docFile = (string)conf.Options["XmlDocFile"]; + if(docFile != null && docFile.Length == 0)//default to assembly name if not specified + { + return "False"; + } + return "True"; + } - private void WriteProject(SolutionNode solution, ProjectNode project) - { - string csComp = "Csc"; - string netRuntime = "MsNet"; - if(project.Runtime == ClrRuntime.Mono) - { - csComp = "Mcs"; - netRuntime = "Mono"; - } + private void WriteProject(SolutionNode solution, ProjectNode project) + { + string csComp = "Csc"; + string netRuntime = "MsNet"; + if(project.Runtime == ClrRuntime.Mono) + { + csComp = "Mcs"; + netRuntime = "Mono"; + } - string projFile = Helper.MakeFilePath(project.FullPath, project.Name, "prjx"); - StreamWriter ss = new StreamWriter(projFile); + string projFile = Helper.MakeFilePath(project.FullPath, project.Name, "prjx"); + StreamWriter ss = new StreamWriter(projFile); - m_Kernel.CurrentWorkingDirectory.Push(); - Helper.SetCurrentDir(Path.GetDirectoryName(projFile)); + m_Kernel.CurrentWorkingDirectory.Push(); + Helper.SetCurrentDir(Path.GetDirectoryName(projFile)); - using(ss) - { - ss.WriteLine( - "", - project.Name, - project.RootNamespace - ); + using(ss) + { + ss.WriteLine( + "", + project.Name, + project.RootNamespace + ); - ss.WriteLine(" "); - foreach(string file in project.Files) - { - string buildAction = "Compile"; - switch(project.Files.GetBuildAction(file)) - { - case BuildAction.None: - buildAction = "Nothing"; - break; + ss.WriteLine(" "); + foreach(string file in project.Files) + { + string buildAction = "Compile"; + switch(project.Files.GetBuildAction(file)) + { + case BuildAction.None: + buildAction = "Nothing"; + break; - case BuildAction.Content: - buildAction = "Exclude"; - break; + case BuildAction.Content: + buildAction = "Exclude"; + break; - case BuildAction.EmbeddedResource: - buildAction = "EmbedAsResource"; - break; + case BuildAction.EmbeddedResource: + buildAction = "EmbedAsResource"; + break; - default: - buildAction = "Compile"; - break; - } + default: + buildAction = "Compile"; + break; + } - // Sort of a hack, we try and resolve the path and make it relative, if we can. - string filePath = PrependPath(file); - ss.WriteLine(" ", filePath, buildAction); - } - ss.WriteLine(" "); + // Sort of a hack, we try and resolve the path and make it relative, if we can. + string filePath = PrependPath(file); + ss.WriteLine(" ", filePath, buildAction); + } + ss.WriteLine(" "); - ss.WriteLine(" "); - foreach(ReferenceNode refr in project.References) - { - ss.WriteLine(" {0}", BuildReference(solution, refr)); - } - ss.WriteLine(" "); + ss.WriteLine(" "); + foreach(ReferenceNode refr in project.References) + { + ss.WriteLine(" {0}", BuildReference(solution, refr)); + } + ss.WriteLine(" "); - ss.Write(" "); + ss.Write(" "); - int count = 0; + int count = 0; + + ss.WriteLine(" ", solution.ActiveConfig); - ss.WriteLine(" ", solution.ActiveConfig); + foreach(ConfigurationNode conf in project.Configurations) + { + ss.Write(" "); + ss.Write(" "); - foreach(ConfigurationNode conf in project.Configurations) - { - ss.Write(" "); - ss.Write(" "); + ss.Write(" "); - ss.Write(" "); + ss.Write(" "); + ss.WriteLine(" "); - ss.Write(" "); - ss.WriteLine(" "); + count++; + } + ss.WriteLine(" "); + ss.WriteLine(""); + } - count++; - } - ss.WriteLine(" "); - ss.WriteLine(""); - } + m_Kernel.CurrentWorkingDirectory.Pop(); + } - m_Kernel.CurrentWorkingDirectory.Pop(); - } + private void WriteCombine(SolutionNode solution) + { + m_Kernel.Log.Write("Creating SharpDevelop combine and project files"); + foreach(ProjectNode project in solution.Projects) + { + if(m_Kernel.AllowProject(project.FilterGroups)) + { + m_Kernel.Log.Write("...Creating project: {0}", project.Name); + WriteProject(solution, project); + } + } - private void WriteCombine(SolutionNode solution) - { - m_Kernel.Log.Write("Creating SharpDevelop combine and project files"); - foreach(ProjectNode project in solution.Projects) - { - if(m_Kernel.AllowProject(project.FilterGroups)) - { - m_Kernel.Log.Write("...Creating project: {0}", project.Name); - WriteProject(solution, project); - } - } + m_Kernel.Log.Write(""); + string combFile = Helper.MakeFilePath(solution.FullPath, solution.Name, "cmbx"); + StreamWriter ss = new StreamWriter(combFile); - m_Kernel.Log.Write(""); - string combFile = Helper.MakeFilePath(solution.FullPath, solution.Name, "cmbx"); - StreamWriter ss = new StreamWriter(combFile); + m_Kernel.CurrentWorkingDirectory.Push(); + Helper.SetCurrentDir(Path.GetDirectoryName(combFile)); + + using(ss) + { + ss.WriteLine("", solution.Name); + + int count = 0; + foreach(ProjectNode project in solution.Projects) + { + if(count == 0) + ss.WriteLine(" ", project.Name); - m_Kernel.CurrentWorkingDirectory.Push(); - Helper.SetCurrentDir(Path.GetDirectoryName(combFile)); + ss.WriteLine(" ", project.Name); + count++; + } + ss.WriteLine(" "); + + ss.WriteLine(" "); + foreach(ProjectNode project in solution.Projects) + { + string path = Helper.MakePathRelativeTo(solution.FullPath, project.FullPath); + ss.WriteLine(" ", + Helper.MakeFilePath(path, project.Name, "prjx")); + } + ss.WriteLine(" "); - using(ss) - { - ss.WriteLine("", solution.Name); + count = 0; + foreach(ConfigurationNode conf in solution.Configurations) + { + if(count == 0) + { + ss.WriteLine(" ", conf.Name); + } - int count = 0; - foreach(ProjectNode project in solution.Projects) - { - if(count == 0) - ss.WriteLine(" ", project.Name); + ss.WriteLine(" ", conf.Name); + foreach(ProjectNode project in solution.Projects) + { + ss.WriteLine(" ", project.Name, conf.Name); + } + ss.WriteLine(" "); - ss.WriteLine(" ", project.Name); - count++; - } - ss.WriteLine(" "); + count++; + } + ss.WriteLine(" "); + ss.WriteLine(""); + } - ss.WriteLine(" "); - foreach(ProjectNode project in solution.Projects) - { - string path = Helper.MakePathRelativeTo(solution.FullPath, project.FullPath); - ss.WriteLine(" ", - Helper.MakeFilePath(path, project.Name, "prjx")); - } - ss.WriteLine(" "); + m_Kernel.CurrentWorkingDirectory.Pop(); + } - count = 0; - foreach(ConfigurationNode conf in solution.Configurations) - { - if(count == 0) - { - ss.WriteLine(" ", conf.Name); - } + private void CleanProject(ProjectNode project) + { + m_Kernel.Log.Write("...Cleaning project: {0}", project.Name); + string projectFile = Helper.MakeFilePath(project.FullPath, project.Name, "prjx"); + Helper.DeleteIfExists(projectFile); + } - ss.WriteLine(" ", conf.Name); - foreach(ProjectNode project in solution.Projects) - { - ss.WriteLine(" ", project.Name, conf.Name); - } - ss.WriteLine(" "); + private void CleanSolution(SolutionNode solution) + { + m_Kernel.Log.Write("Cleaning SharpDevelop combine and project files for", solution.Name); - count++; - } - ss.WriteLine(" "); - ss.WriteLine(""); - } + string slnFile = Helper.MakeFilePath(solution.FullPath, solution.Name, "cmbx"); + Helper.DeleteIfExists(slnFile); - m_Kernel.CurrentWorkingDirectory.Pop(); - } + foreach(ProjectNode project in solution.Projects) + { + CleanProject(project); + } + + m_Kernel.Log.Write(""); + } - private void CleanProject(ProjectNode project) - { - m_Kernel.Log.Write("...Cleaning project: {0}", project.Name); - string projectFile = Helper.MakeFilePath(project.FullPath, project.Name, "prjx"); - Helper.DeleteIfExists(projectFile); - } + #endregion - private void CleanSolution(SolutionNode solution) - { - m_Kernel.Log.Write("Cleaning SharpDevelop combine and project files for", solution.Name); + #region ITarget Members - string slnFile = Helper.MakeFilePath(solution.FullPath, solution.Name, "cmbx"); - Helper.DeleteIfExists(slnFile); + /// + /// Writes the specified kern. + /// + /// The kern. + public void Write(Kernel kern) + { + if( kern == null ) + { + throw new ArgumentNullException("kern"); + } + m_Kernel = kern; + foreach(SolutionNode solution in kern.Solutions) + { + WriteCombine(solution); + } + m_Kernel = null; + } - foreach(ProjectNode project in solution.Projects) - { - CleanProject(project); - } + /// + /// Cleans the specified kern. + /// + /// The kern. + public virtual void Clean(Kernel kern) + { + if( kern == null ) + { + throw new ArgumentNullException("kern"); + } + m_Kernel = kern; + foreach(SolutionNode sol in kern.Solutions) + { + CleanSolution(sol); + } + m_Kernel = null; + } - m_Kernel.Log.Write(""); - } + /// + /// Gets the name. + /// + /// The name. + public string Name + { + get + { + return "sharpdev"; + } + } - #endregion - - #region ITarget Members - - /// - /// Writes the specified kern. - /// - /// The kern. - public void Write(Kernel kern) - { - if( kern == null ) - { - throw new ArgumentNullException("kern"); - } - m_Kernel = kern; - foreach(SolutionNode solution in kern.Solutions) - { - WriteCombine(solution); - } - m_Kernel = null; - } - - /// - /// Cleans the specified kern. - /// - /// The kern. - public virtual void Clean(Kernel kern) - { - if( kern == null ) - { - throw new ArgumentNullException("kern"); - } - m_Kernel = kern; - foreach(SolutionNode sol in kern.Solutions) - { - CleanSolution(sol); - } - m_Kernel = null; - } - - /// - /// Gets the name. - /// - /// The name. - public string Name - { - get - { - return "sharpdev"; - } - } - - #endregion - } + #endregion + } } diff --git a/Prebuild/src/Core/Targets/ToolInfo.cs b/Prebuild/src/Core/Targets/ToolInfo.cs index 984d20ecbd..935c6744db 100644 --- a/Prebuild/src/Core/Targets/ToolInfo.cs +++ b/Prebuild/src/Core/Targets/ToolInfo.cs @@ -4,194 +4,194 @@ using System.Text; namespace Prebuild.Core.Targets { - /// - /// - /// - public struct ToolInfo - { - string name; - string guid; - string fileExtension; - string xmlTag; - string importProject; + /// + /// + /// + public struct ToolInfo + { + string name; + string guid; + string fileExtension; + string xmlTag; + string importProject; - /// - /// Gets or sets the name. - /// - /// The name. - public string Name - { - get - { - return name; - } - set - { - name = value; - } - } + /// + /// Gets or sets the name. + /// + /// The name. + public string Name + { + get + { + return name; + } + set + { + name = value; + } + } - /// - /// Gets or sets the GUID. - /// - /// The GUID. - public string Guid - { - get - { - return guid; - } - set - { - guid = value; - } - } + /// + /// Gets or sets the GUID. + /// + /// The GUID. + public string Guid + { + get + { + return guid; + } + set + { + guid = value; + } + } - /// - /// Gets or sets the file extension. - /// - /// The file extension. - public string FileExtension - { - get - { - return fileExtension; - } - set - { - fileExtension = value; - } - } - public string LanguageExtension - { - get - { - switch (this.Name) - { - case "C#": - return ".cs"; - case "VisualBasic": - return ".vb"; - case "Boo": - return ".boo"; - default: - return ".cs"; - } - } - } - /// - /// Gets or sets the XML tag. - /// - /// The XML tag. - public string XmlTag - { - get - { - return xmlTag; - } - set - { - xmlTag = value; - } - } + /// + /// Gets or sets the file extension. + /// + /// The file extension. + public string FileExtension + { + get + { + return fileExtension; + } + set + { + fileExtension = value; + } + } + public string LanguageExtension + { + get + { + switch (this.Name) + { + case "C#": + return ".cs"; + case "VisualBasic": + return ".vb"; + case "Boo": + return ".boo"; + default: + return ".cs"; + } + } + } + /// + /// Gets or sets the XML tag. + /// + /// The XML tag. + public string XmlTag + { + get + { + return xmlTag; + } + set + { + xmlTag = value; + } + } - /// - /// Gets or sets the import project property. - /// - /// The ImportProject tag. - public string ImportProject - { - get - { - return importProject; - } - set - { - importProject = value; - } - } + /// + /// Gets or sets the import project property. + /// + /// The ImportProject tag. + public string ImportProject + { + get + { + return importProject; + } + set + { + importProject = value; + } + } - /// - /// Initializes a new instance of the class. - /// - /// The name. - /// The GUID. - /// The file extension. - /// The XML. - /// The import project. - public ToolInfo(string name, string guid, string fileExtension, string xml, string importProject) - { - this.name = name; - this.guid = guid; - this.fileExtension = fileExtension; - this.xmlTag = xml; - this.importProject = importProject; - } + /// + /// Initializes a new instance of the class. + /// + /// The name. + /// The GUID. + /// The file extension. + /// The XML. + /// The import project. + public ToolInfo(string name, string guid, string fileExtension, string xml, string importProject) + { + this.name = name; + this.guid = guid; + this.fileExtension = fileExtension; + this.xmlTag = xml; + this.importProject = importProject; + } - /// - /// Initializes a new instance of the class. - /// - /// The name. - /// The GUID. - /// The file extension. - /// The XML. - public ToolInfo(string name, string guid, string fileExtension, string xml) - { - this.name = name; - this.guid = guid; - this.fileExtension = fileExtension; - this.xmlTag = xml; - this.importProject = "$(MSBuildBinPath)\\Microsoft." + xml + ".Targets"; - } + /// + /// Initializes a new instance of the class. + /// + /// The name. + /// The GUID. + /// The file extension. + /// The XML. + public ToolInfo(string name, string guid, string fileExtension, string xml) + { + this.name = name; + this.guid = guid; + this.fileExtension = fileExtension; + this.xmlTag = xml; + this.importProject = "$(MSBuildBinPath)\\Microsoft." + xml + ".Targets"; + } - /// - /// Equals operator - /// - /// ToolInfo to compare - /// true if toolInfos are equal - public override bool Equals(object obj) - { - if (obj == null) - { - throw new ArgumentNullException("obj"); - } - if (obj.GetType() != typeof(ToolInfo)) - return false; + /// + /// Equals operator + /// + /// ToolInfo to compare + /// true if toolInfos are equal + public override bool Equals(object obj) + { + if (obj == null) + { + throw new ArgumentNullException("obj"); + } + if (obj.GetType() != typeof(ToolInfo)) + return false; - ToolInfo c = (ToolInfo)obj; - return ((this.name == c.name) && (this.guid == c.guid) && (this.fileExtension == c.fileExtension) && (this.importProject == c.importProject)); - } + ToolInfo c = (ToolInfo)obj; + return ((this.name == c.name) && (this.guid == c.guid) && (this.fileExtension == c.fileExtension) && (this.importProject == c.importProject)); + } - /// - /// Equals operator - /// - /// ToolInfo to compare - /// ToolInfo to compare - /// True if toolInfos are equal - public static bool operator ==(ToolInfo c1, ToolInfo c2) - { - return ((c1.name == c2.name) && (c1.guid == c2.guid) && (c1.fileExtension == c2.fileExtension) && (c1.importProject == c2.importProject) && (c1.xmlTag == c2.xmlTag)); - } + /// + /// Equals operator + /// + /// ToolInfo to compare + /// ToolInfo to compare + /// True if toolInfos are equal + public static bool operator ==(ToolInfo c1, ToolInfo c2) + { + return ((c1.name == c2.name) && (c1.guid == c2.guid) && (c1.fileExtension == c2.fileExtension) && (c1.importProject == c2.importProject) && (c1.xmlTag == c2.xmlTag)); + } - /// - /// Not equals operator - /// - /// ToolInfo to compare - /// ToolInfo to compare - /// True if toolInfos are not equal - public static bool operator !=(ToolInfo c1, ToolInfo c2) - { - return !(c1 == c2); - } + /// + /// Not equals operator + /// + /// ToolInfo to compare + /// ToolInfo to compare + /// True if toolInfos are not equal + public static bool operator !=(ToolInfo c1, ToolInfo c2) + { + return !(c1 == c2); + } - /// - /// Hash Code - /// - /// Hash code - public override int GetHashCode() - { - return name.GetHashCode() ^ guid.GetHashCode() ^ this.fileExtension.GetHashCode() ^ this.importProject.GetHashCode() ^ this.xmlTag.GetHashCode(); + /// + /// Hash Code + /// + /// Hash code + public override int GetHashCode() + { + return name.GetHashCode() ^ guid.GetHashCode() ^ this.fileExtension.GetHashCode() ^ this.importProject.GetHashCode() ^ this.xmlTag.GetHashCode(); - } - } + } + } } diff --git a/Prebuild/src/Core/Targets/VS2002Target.cs b/Prebuild/src/Core/Targets/VS2002Target.cs index d7f6dd11ab..2292624473 100644 --- a/Prebuild/src/Core/Targets/VS2002Target.cs +++ b/Prebuild/src/Core/Targets/VS2002Target.cs @@ -5,16 +5,16 @@ Copyright (c) 2004-2005 Matthew Holmes (matthew@wildfiregames.com), Dan Moorehea Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: -* Redistributions of source code must retain the above copyright notice, this list of conditions - and the following disclaimer. -* Redistributions in binary form must reproduce the above copyright notice, this list of conditions - and the following disclaimer in the documentation and/or other materials provided with the - distribution. -* The name of the author may not be used to endorse or promote products derived from this software - without specific prior written permission. +* Redistributions of source code must retain the above copyright notice, this list of conditions + and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions + and the following disclaimer in the documentation and/or other materials provided with the + distribution. +* The name of the author may not be used to endorse or promote products derived from this software + without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, -BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY @@ -29,59 +29,59 @@ using Prebuild.Core.Attributes; namespace Prebuild.Core.Targets { - /// - /// - /// - [Target("vs2002")] - public class VS2002Target : VS2003Target - { - #region Private Methods + /// + /// + /// + [Target("vs2002")] + public class VS2002Target : VS2003Target + { + #region Private Methods - private void SetVS2002() - { - this.SolutionVersion = "7.00"; - this.ProductVersion = "7.0.9254"; - this.SchemaVersion = "1.0"; - this.VersionName = "2002"; - this.Version = VSVersion.VS70; - } + private void SetVS2002() + { + this.SolutionVersion = "7.00"; + this.ProductVersion = "7.0.9254"; + this.SchemaVersion = "1.0"; + this.VersionName = "2002"; + this.Version = VSVersion.VS70; + } - #endregion + #endregion - #region Public Methods + #region Public Methods - /// - /// Writes the specified kern. - /// - /// The kern. - public override void Write(Kernel kern) - { - SetVS2002(); - base.Write(kern); - } + /// + /// Writes the specified kern. + /// + /// The kern. + public override void Write(Kernel kern) + { + SetVS2002(); + base.Write(kern); + } - /// - /// Cleans the specified kern. - /// - /// The kern. - public override void Clean(Kernel kern) - { - SetVS2002(); - base.Clean(kern); - } + /// + /// Cleans the specified kern. + /// + /// The kern. + public override void Clean(Kernel kern) + { + SetVS2002(); + base.Clean(kern); + } - /// - /// Gets the name. - /// - /// The name. - public override string Name - { - get - { - return "vs2002"; - } - } + /// + /// Gets the name. + /// + /// The name. + public override string Name + { + get + { + return "vs2002"; + } + } - #endregion - } + #endregion + } } diff --git a/Prebuild/src/Core/Targets/VS2003Target.cs b/Prebuild/src/Core/Targets/VS2003Target.cs index f4b4517d14..10e2dc4a71 100644 --- a/Prebuild/src/Core/Targets/VS2003Target.cs +++ b/Prebuild/src/Core/Targets/VS2003Target.cs @@ -5,16 +5,16 @@ Copyright (c) 2004-2005 Matthew Holmes (matthew@wildfiregames.com), Dan Moorehea Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: -* Redistributions of source code must retain the above copyright notice, this list of conditions - and the following disclaimer. -* Redistributions in binary form must reproduce the above copyright notice, this list of conditions - and the following disclaimer in the documentation and/or other materials provided with the - distribution. -* The name of the author may not be used to endorse or promote products derived from this software - without specific prior written permission. +* Redistributions of source code must retain the above copyright notice, this list of conditions + and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions + and the following disclaimer in the documentation and/or other materials provided with the + distribution. +* The name of the author may not be used to endorse or promote products derived from this software + without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, -BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY @@ -34,560 +34,560 @@ using Prebuild.Core.Utilities; namespace Prebuild.Core.Targets { - [Target("vs2003")] - public class VS2003Target : ITarget - { - - #region Fields - - string solutionVersion = "8.00"; - string productVersion = "7.10.3077"; - string schemaVersion = "2.0"; - string versionName = "2003"; - VSVersion version = VSVersion.VS71; - - readonly Dictionary m_Tools = new Dictionary(); - Kernel m_Kernel; - - /// - /// Gets or sets the solution version. - /// - /// The solution version. - protected string SolutionVersion - { - get - { - return solutionVersion; - } - set - { - solutionVersion = value; - } - } - /// - /// Gets or sets the product version. - /// - /// The product version. - protected string ProductVersion - { - get - { - return productVersion; - } - set - { - productVersion = value; - } - } - /// - /// Gets or sets the schema version. - /// - /// The schema version. - protected string SchemaVersion - { - get - { - return schemaVersion; - } - set - { - schemaVersion = value; - } - } - /// - /// Gets or sets the name of the version. - /// - /// The name of the version. - protected string VersionName - { - get - { - return versionName; - } - set - { - versionName = value; - } - } - /// - /// Gets or sets the version. - /// - /// The version. - protected VSVersion Version - { - get - { - return version; - } - set - { - version = value; - } - } - - #endregion - - #region Constructors - - /// - /// Initializes a new instance of the class. - /// - public VS2003Target() - { - m_Tools["C#"] = new ToolInfo("C#", "{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}", "csproj", "CSHARP"); - m_Tools["VB.NET"] = new ToolInfo("VB.NET", "{F184B08F-C81C-45F6-A57F-5ABD9991F28F}", "vbproj", "VisualBasic"); - } - - #endregion - - #region Private Methods - - private string MakeRefPath(ProjectNode project) - { - string ret = ""; - foreach(ReferencePathNode node in project.ReferencePaths) - { - try - { - string fullPath = Helper.ResolvePath(node.Path); - if(ret.Length < 1) - { - ret = fullPath; - } - else - { - ret += ";" + fullPath; - } - } - catch(ArgumentException) - { - m_Kernel.Log.Write(LogType.Warning, "Could not resolve reference path: {0}", node.Path); - } - } - - return ret; - } - - private void WriteProject(SolutionNode solution, ProjectNode project) - { - if(!m_Tools.ContainsKey(project.Language)) - { - throw new UnknownLanguageException("Unknown .NET language: " + project.Language); - } - - ToolInfo toolInfo = m_Tools[project.Language]; - string projectFile = Helper.MakeFilePath(project.FullPath, project.Name, toolInfo.FileExtension); - StreamWriter ps = new StreamWriter(projectFile); - - m_Kernel.CurrentWorkingDirectory.Push(); - Helper.SetCurrentDir(Path.GetDirectoryName(projectFile)); - - using(ps) - { - ps.WriteLine(""); - ps.WriteLine(" <{0}", toolInfo.XmlTag); - ps.WriteLine("\t\t\t\tProjectType = \"Local\""); - ps.WriteLine("\t\t\t\tProductVersion = \"{0}\"", ProductVersion); - ps.WriteLine("\t\t\t\tSchemaVersion = \"{0}\"", SchemaVersion); - ps.WriteLine("\t\t\t\tProjectGuid = \"{{{0}}}\"", project.Guid.ToString().ToUpper()); - ps.WriteLine("\t\t>"); - - ps.WriteLine("\t\t\t\t"); - ps.WriteLine(" "); - - foreach(ConfigurationNode conf in project.Configurations) - { - ps.WriteLine("\t\t\t\t "); - } - - ps.WriteLine(" "); - - ps.WriteLine(" "); - foreach(ReferenceNode refr in project.References) - { - ps.WriteLine(" "); - } - ps.WriteLine(" "); - - ps.WriteLine(" "); - ps.WriteLine(" "); - - ps.WriteLine(" "); - - foreach(string file in project.Files) - { - string fileName = file.Replace(".\\", ""); - ps.WriteLine(" "); - - if (project.Files.GetSubType(file) != SubType.Code && project.Files.GetSubType(file) != SubType.Settings) - { - ps.WriteLine(" "); - - } - } - ps.WriteLine(" "); - - ps.WriteLine(" "); - ps.WriteLine(" ", toolInfo.XmlTag); - ps.WriteLine(""); - } - - ps = new StreamWriter(projectFile + ".user"); - using(ps) - { - ps.WriteLine(""); - ps.WriteLine(" <{0}>", toolInfo.XmlTag); - ps.WriteLine(" "); - - ps.WriteLine(" ", MakeRefPath(project)); - foreach(ConfigurationNode conf in project.Configurations) - { - ps.WriteLine(" "); - } - ps.WriteLine(" "); - - ps.WriteLine(" "); - ps.WriteLine(" ", toolInfo.XmlTag); - ps.WriteLine(""); - } - - m_Kernel.CurrentWorkingDirectory.Pop(); - } - - /// - /// Gets the XML doc file. - /// - /// The project. - /// The conf. - /// - public static string GetXmlDocFile(ProjectNode project, ConfigurationNode conf) - { - if( conf == null ) - { - throw new ArgumentNullException("conf"); - } - if( project == null ) - { - throw new ArgumentNullException("project"); - } - // if(!(bool)conf.Options["GenerateXmlDocFile"]) //default to none, if the generate option is false - // { - // return string.Empty; - // } - - //default to "AssemblyName.xml" - //string defaultValue = Path.GetFileNameWithoutExtension(project.AssemblyName) + ".xml"; - //return (string)conf.Options["XmlDocFile", defaultValue]; - - //default to no XmlDocFile file - return (string)conf.Options["XmlDocFile", ""]; - } - - private void WriteSolution(SolutionNode solution) - { - m_Kernel.Log.Write("Creating Visual Studio {0} solution and project files", VersionName); - - foreach(ProjectNode project in solution.Projects) - { - if(m_Kernel.AllowProject(project.FilterGroups)) - { - m_Kernel.Log.Write("...Creating project: {0}", project.Name); - WriteProject(solution, project); - } - } - - m_Kernel.Log.Write(""); - string solutionFile = Helper.MakeFilePath(solution.FullPath, solution.Name, "sln"); - StreamWriter ss = new StreamWriter(solutionFile); - - m_Kernel.CurrentWorkingDirectory.Push(); - Helper.SetCurrentDir(Path.GetDirectoryName(solutionFile)); - - using(ss) - { - ss.WriteLine("Microsoft Visual Studio Solution File, Format Version {0}", SolutionVersion); - foreach(ProjectNode project in solution.Projects) - { - if(!m_Tools.ContainsKey(project.Language)) - { - throw new UnknownLanguageException("Unknown .NET language: " + project.Language); - } - - ToolInfo toolInfo = m_Tools[project.Language]; - - string path = Helper.MakePathRelativeTo(solution.FullPath, project.FullPath); - ss.WriteLine("Project(\"{0}\") = \"{1}\", \"{2}\", \"{{{3}}}\"", - toolInfo.Guid, project.Name, Helper.MakeFilePath(path, project.Name, - toolInfo.FileExtension), project.Guid.ToString().ToUpper()); - - ss.WriteLine("\tProjectSection(ProjectDependencies) = postProject"); - ss.WriteLine("\tEndProjectSection"); - - ss.WriteLine("EndProject"); - } - - ss.WriteLine("Global"); - - ss.WriteLine("\tGlobalSection(SolutionConfiguration) = preSolution"); - foreach(ConfigurationNode conf in solution.Configurations) - { - ss.WriteLine("\t\t{0} = {0}", conf.Name); - } - ss.WriteLine("\tEndGlobalSection"); - - ss.WriteLine("\tGlobalSection(ProjectDependencies) = postSolution"); - foreach(ProjectNode project in solution.Projects) - { - for(int i = 0; i < project.References.Count; i++) - { - ReferenceNode refr = project.References[i]; - if(solution.ProjectsTable.ContainsKey(refr.Name)) - { - ProjectNode refProject = solution.ProjectsTable[refr.Name]; - ss.WriteLine("\t\t({{{0}}}).{1} = ({{{2}}})", - project.Guid.ToString().ToUpper() - , i, - refProject.Guid.ToString().ToUpper() - ); - } - } - } - ss.WriteLine("\tEndGlobalSection"); - - ss.WriteLine("\tGlobalSection(ProjectConfiguration) = postSolution"); - foreach(ProjectNode project in solution.Projects) - { - foreach(ConfigurationNode conf in solution.Configurations) - { - ss.WriteLine("\t\t{{{0}}}.{1}.ActiveCfg = {1}|.NET", - project.Guid.ToString().ToUpper(), - conf.Name); - - ss.WriteLine("\t\t{{{0}}}.{1}.Build.0 = {1}|.NET", - project.Guid.ToString().ToUpper(), - conf.Name); - } - } - ss.WriteLine("\tEndGlobalSection"); - - if(solution.Files != null) - { - ss.WriteLine("\tGlobalSection(SolutionItems) = postSolution"); - foreach(string file in solution.Files) - { - ss.WriteLine("\t\t{0} = {0}", file); - } - ss.WriteLine("\tEndGlobalSection"); - } - - ss.WriteLine("\tGlobalSection(ExtensibilityGlobals) = postSolution"); - ss.WriteLine("\tEndGlobalSection"); - ss.WriteLine("\tGlobalSection(ExtensibilityAddIns) = postSolution"); - ss.WriteLine("\tEndGlobalSection"); - - ss.WriteLine("EndGlobal"); - } - - m_Kernel.CurrentWorkingDirectory.Pop(); - } - - private void CleanProject(ProjectNode project) - { - m_Kernel.Log.Write("...Cleaning project: {0}", project.Name); - - ToolInfo toolInfo = m_Tools[project.Language]; - string projectFile = Helper.MakeFilePath(project.FullPath, project.Name, toolInfo.FileExtension); - string userFile = projectFile + ".user"; - - Helper.DeleteIfExists(projectFile); - Helper.DeleteIfExists(userFile); - } - - private void CleanSolution(SolutionNode solution) - { - m_Kernel.Log.Write("Cleaning Visual Studio {0} solution and project files", VersionName, solution.Name); - - string slnFile = Helper.MakeFilePath(solution.FullPath, solution.Name, "sln"); - string suoFile = Helper.MakeFilePath(solution.FullPath, solution.Name, "suo"); - - Helper.DeleteIfExists(slnFile); - Helper.DeleteIfExists(suoFile); - - foreach(ProjectNode project in solution.Projects) - { - CleanProject(project); - } - - m_Kernel.Log.Write(""); - } - - #endregion - - #region ITarget Members - - /// - /// Writes the specified kern. - /// - /// The kern. - public virtual void Write(Kernel kern) - { - if( kern == null ) - { - throw new ArgumentNullException("kern"); - } - m_Kernel = kern; - foreach(SolutionNode sol in m_Kernel.Solutions) - { - WriteSolution(sol); - } - m_Kernel = null; - } - - /// - /// Cleans the specified kern. - /// - /// The kern. - public virtual void Clean(Kernel kern) - { - if( kern == null ) - { - throw new ArgumentNullException("kern"); - } - m_Kernel = kern; - foreach(SolutionNode sol in m_Kernel.Solutions) - { - CleanSolution(sol); - } - m_Kernel = null; - } - - /// - /// Gets the name. - /// - /// The name. - public virtual string Name - { - get - { - return "vs2003"; - } - } - - #endregion - } + [Target("vs2003")] + public class VS2003Target : ITarget + { + + #region Fields + + string solutionVersion = "8.00"; + string productVersion = "7.10.3077"; + string schemaVersion = "2.0"; + string versionName = "2003"; + VSVersion version = VSVersion.VS71; + + readonly Dictionary m_Tools = new Dictionary(); + Kernel m_Kernel; + + /// + /// Gets or sets the solution version. + /// + /// The solution version. + protected string SolutionVersion + { + get + { + return solutionVersion; + } + set + { + solutionVersion = value; + } + } + /// + /// Gets or sets the product version. + /// + /// The product version. + protected string ProductVersion + { + get + { + return productVersion; + } + set + { + productVersion = value; + } + } + /// + /// Gets or sets the schema version. + /// + /// The schema version. + protected string SchemaVersion + { + get + { + return schemaVersion; + } + set + { + schemaVersion = value; + } + } + /// + /// Gets or sets the name of the version. + /// + /// The name of the version. + protected string VersionName + { + get + { + return versionName; + } + set + { + versionName = value; + } + } + /// + /// Gets or sets the version. + /// + /// The version. + protected VSVersion Version + { + get + { + return version; + } + set + { + version = value; + } + } + + #endregion + + #region Constructors + + /// + /// Initializes a new instance of the class. + /// + public VS2003Target() + { + m_Tools["C#"] = new ToolInfo("C#", "{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}", "csproj", "CSHARP"); + m_Tools["VB.NET"] = new ToolInfo("VB.NET", "{F184B08F-C81C-45F6-A57F-5ABD9991F28F}", "vbproj", "VisualBasic"); + } + + #endregion + + #region Private Methods + + private string MakeRefPath(ProjectNode project) + { + string ret = ""; + foreach(ReferencePathNode node in project.ReferencePaths) + { + try + { + string fullPath = Helper.ResolvePath(node.Path); + if(ret.Length < 1) + { + ret = fullPath; + } + else + { + ret += ";" + fullPath; + } + } + catch(ArgumentException) + { + m_Kernel.Log.Write(LogType.Warning, "Could not resolve reference path: {0}", node.Path); + } + } + + return ret; + } + + private void WriteProject(SolutionNode solution, ProjectNode project) + { + if(!m_Tools.ContainsKey(project.Language)) + { + throw new UnknownLanguageException("Unknown .NET language: " + project.Language); + } + + ToolInfo toolInfo = m_Tools[project.Language]; + string projectFile = Helper.MakeFilePath(project.FullPath, project.Name, toolInfo.FileExtension); + StreamWriter ps = new StreamWriter(projectFile); + + m_Kernel.CurrentWorkingDirectory.Push(); + Helper.SetCurrentDir(Path.GetDirectoryName(projectFile)); + + using(ps) + { + ps.WriteLine(""); + ps.WriteLine(" <{0}", toolInfo.XmlTag); + ps.WriteLine("\t\t\t\tProjectType = \"Local\""); + ps.WriteLine("\t\t\t\tProductVersion = \"{0}\"", ProductVersion); + ps.WriteLine("\t\t\t\tSchemaVersion = \"{0}\"", SchemaVersion); + ps.WriteLine("\t\t\t\tProjectGuid = \"{{{0}}}\"", project.Guid.ToString().ToUpper()); + ps.WriteLine("\t\t>"); + + ps.WriteLine("\t\t\t\t"); + ps.WriteLine(" "); + + foreach(ConfigurationNode conf in project.Configurations) + { + ps.WriteLine("\t\t\t\t "); + } + + ps.WriteLine(" "); + + ps.WriteLine(" "); + foreach(ReferenceNode refr in project.References) + { + ps.WriteLine(" "); + } + ps.WriteLine(" "); + + ps.WriteLine(" "); + ps.WriteLine(" "); + + ps.WriteLine(" "); + + foreach(string file in project.Files) + { + string fileName = file.Replace(".\\", ""); + ps.WriteLine(" "); + + if (project.Files.GetSubType(file) != SubType.Code && project.Files.GetSubType(file) != SubType.Settings) + { + ps.WriteLine(" "); + + } + } + ps.WriteLine(" "); + + ps.WriteLine(" "); + ps.WriteLine(" ", toolInfo.XmlTag); + ps.WriteLine(""); + } + + ps = new StreamWriter(projectFile + ".user"); + using(ps) + { + ps.WriteLine(""); + ps.WriteLine(" <{0}>", toolInfo.XmlTag); + ps.WriteLine(" "); + + ps.WriteLine(" ", MakeRefPath(project)); + foreach(ConfigurationNode conf in project.Configurations) + { + ps.WriteLine(" "); + } + ps.WriteLine(" "); + + ps.WriteLine(" "); + ps.WriteLine(" ", toolInfo.XmlTag); + ps.WriteLine(""); + } + + m_Kernel.CurrentWorkingDirectory.Pop(); + } + + /// + /// Gets the XML doc file. + /// + /// The project. + /// The conf. + /// + public static string GetXmlDocFile(ProjectNode project, ConfigurationNode conf) + { + if( conf == null ) + { + throw new ArgumentNullException("conf"); + } + if( project == null ) + { + throw new ArgumentNullException("project"); + } + // if(!(bool)conf.Options["GenerateXmlDocFile"]) //default to none, if the generate option is false + // { + // return string.Empty; + // } + + //default to "AssemblyName.xml" + //string defaultValue = Path.GetFileNameWithoutExtension(project.AssemblyName) + ".xml"; + //return (string)conf.Options["XmlDocFile", defaultValue]; + + //default to no XmlDocFile file + return (string)conf.Options["XmlDocFile", ""]; + } + + private void WriteSolution(SolutionNode solution) + { + m_Kernel.Log.Write("Creating Visual Studio {0} solution and project files", VersionName); + + foreach(ProjectNode project in solution.Projects) + { + if(m_Kernel.AllowProject(project.FilterGroups)) + { + m_Kernel.Log.Write("...Creating project: {0}", project.Name); + WriteProject(solution, project); + } + } + + m_Kernel.Log.Write(""); + string solutionFile = Helper.MakeFilePath(solution.FullPath, solution.Name, "sln"); + StreamWriter ss = new StreamWriter(solutionFile); + + m_Kernel.CurrentWorkingDirectory.Push(); + Helper.SetCurrentDir(Path.GetDirectoryName(solutionFile)); + + using(ss) + { + ss.WriteLine("Microsoft Visual Studio Solution File, Format Version {0}", SolutionVersion); + foreach(ProjectNode project in solution.Projects) + { + if(!m_Tools.ContainsKey(project.Language)) + { + throw new UnknownLanguageException("Unknown .NET language: " + project.Language); + } + + ToolInfo toolInfo = m_Tools[project.Language]; + + string path = Helper.MakePathRelativeTo(solution.FullPath, project.FullPath); + ss.WriteLine("Project(\"{0}\") = \"{1}\", \"{2}\", \"{{{3}}}\"", + toolInfo.Guid, project.Name, Helper.MakeFilePath(path, project.Name, + toolInfo.FileExtension), project.Guid.ToString().ToUpper()); + + ss.WriteLine("\tProjectSection(ProjectDependencies) = postProject"); + ss.WriteLine("\tEndProjectSection"); + + ss.WriteLine("EndProject"); + } + + ss.WriteLine("Global"); + + ss.WriteLine("\tGlobalSection(SolutionConfiguration) = preSolution"); + foreach(ConfigurationNode conf in solution.Configurations) + { + ss.WriteLine("\t\t{0} = {0}", conf.Name); + } + ss.WriteLine("\tEndGlobalSection"); + + ss.WriteLine("\tGlobalSection(ProjectDependencies) = postSolution"); + foreach(ProjectNode project in solution.Projects) + { + for(int i = 0; i < project.References.Count; i++) + { + ReferenceNode refr = project.References[i]; + if(solution.ProjectsTable.ContainsKey(refr.Name)) + { + ProjectNode refProject = solution.ProjectsTable[refr.Name]; + ss.WriteLine("\t\t({{{0}}}).{1} = ({{{2}}})", + project.Guid.ToString().ToUpper() + , i, + refProject.Guid.ToString().ToUpper() + ); + } + } + } + ss.WriteLine("\tEndGlobalSection"); + + ss.WriteLine("\tGlobalSection(ProjectConfiguration) = postSolution"); + foreach(ProjectNode project in solution.Projects) + { + foreach(ConfigurationNode conf in solution.Configurations) + { + ss.WriteLine("\t\t{{{0}}}.{1}.ActiveCfg = {1}|.NET", + project.Guid.ToString().ToUpper(), + conf.Name); + + ss.WriteLine("\t\t{{{0}}}.{1}.Build.0 = {1}|.NET", + project.Guid.ToString().ToUpper(), + conf.Name); + } + } + ss.WriteLine("\tEndGlobalSection"); + + if(solution.Files != null) + { + ss.WriteLine("\tGlobalSection(SolutionItems) = postSolution"); + foreach(string file in solution.Files) + { + ss.WriteLine("\t\t{0} = {0}", file); + } + ss.WriteLine("\tEndGlobalSection"); + } + + ss.WriteLine("\tGlobalSection(ExtensibilityGlobals) = postSolution"); + ss.WriteLine("\tEndGlobalSection"); + ss.WriteLine("\tGlobalSection(ExtensibilityAddIns) = postSolution"); + ss.WriteLine("\tEndGlobalSection"); + + ss.WriteLine("EndGlobal"); + } + + m_Kernel.CurrentWorkingDirectory.Pop(); + } + + private void CleanProject(ProjectNode project) + { + m_Kernel.Log.Write("...Cleaning project: {0}", project.Name); + + ToolInfo toolInfo = m_Tools[project.Language]; + string projectFile = Helper.MakeFilePath(project.FullPath, project.Name, toolInfo.FileExtension); + string userFile = projectFile + ".user"; + + Helper.DeleteIfExists(projectFile); + Helper.DeleteIfExists(userFile); + } + + private void CleanSolution(SolutionNode solution) + { + m_Kernel.Log.Write("Cleaning Visual Studio {0} solution and project files", VersionName, solution.Name); + + string slnFile = Helper.MakeFilePath(solution.FullPath, solution.Name, "sln"); + string suoFile = Helper.MakeFilePath(solution.FullPath, solution.Name, "suo"); + + Helper.DeleteIfExists(slnFile); + Helper.DeleteIfExists(suoFile); + + foreach(ProjectNode project in solution.Projects) + { + CleanProject(project); + } + + m_Kernel.Log.Write(""); + } + + #endregion + + #region ITarget Members + + /// + /// Writes the specified kern. + /// + /// The kern. + public virtual void Write(Kernel kern) + { + if( kern == null ) + { + throw new ArgumentNullException("kern"); + } + m_Kernel = kern; + foreach(SolutionNode sol in m_Kernel.Solutions) + { + WriteSolution(sol); + } + m_Kernel = null; + } + + /// + /// Cleans the specified kern. + /// + /// The kern. + public virtual void Clean(Kernel kern) + { + if( kern == null ) + { + throw new ArgumentNullException("kern"); + } + m_Kernel = kern; + foreach(SolutionNode sol in m_Kernel.Solutions) + { + CleanSolution(sol); + } + m_Kernel = null; + } + + /// + /// Gets the name. + /// + /// The name. + public virtual string Name + { + get + { + return "vs2003"; + } + } + + #endregion + } } diff --git a/Prebuild/src/Core/Targets/VS2005Target.cs b/Prebuild/src/Core/Targets/VS2005Target.cs index e5a0939e8e..9c70e26a37 100644 --- a/Prebuild/src/Core/Targets/VS2005Target.cs +++ b/Prebuild/src/Core/Targets/VS2005Target.cs @@ -5,16 +5,16 @@ Copyright (c) 2004 Matthew Holmes (matthew@wildfiregames.com) Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: -* Redistributions of source code must retain the above copyright notice, this list of conditions - and the following disclaimer. -* Redistributions in binary form must reproduce the above copyright notice, this list of conditions - and the following disclaimer in the documentation and/or other materials provided with the - distribution. -* The name of the author may not be used to endorse or promote products derived from this software - without specific prior written permission. +* Redistributions of source code must retain the above copyright notice, this list of conditions + and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions + and the following disclaimer in the documentation and/or other materials provided with the + distribution. +* The name of the author may not be used to endorse or promote products derived from this software + without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, -BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY @@ -35,7 +35,7 @@ using Prebuild.Core.Utilities; namespace Prebuild.Core.Targets { /// - /// + /// /// [Target("vs2005")] public class VS2005Target : VSGenericTarget @@ -137,9 +137,9 @@ namespace Prebuild.Core.Targets /// /// Initializes a new instance of the class. /// - public VS2005Target() + public VS2005Target() : base() - { + { } #endregion diff --git a/Prebuild/src/Core/Targets/VS2008Target.cs b/Prebuild/src/Core/Targets/VS2008Target.cs index a3f3acaf4f..fee4f7f27f 100644 --- a/Prebuild/src/Core/Targets/VS2008Target.cs +++ b/Prebuild/src/Core/Targets/VS2008Target.cs @@ -11,86 +11,86 @@ using System.CodeDom.Compiler; namespace Prebuild.Core.Targets { - /// - /// - /// - [Target("vs2008")] - public class VS2008Target : VSGenericTarget - { - #region Fields - string solutionVersion = "10.00"; - string productVersion = "9.0.21022"; - string schemaVersion = "2.0"; - string versionName = "Visual Studio 2008"; - string name = "vs2008"; - VSVersion version = VSVersion.VS90; + /// + /// + /// + [Target("vs2008")] + public class VS2008Target : VSGenericTarget + { + #region Fields + string solutionVersion = "10.00"; + string productVersion = "9.0.21022"; + string schemaVersion = "2.0"; + string versionName = "Visual Studio 2008"; + string name = "vs2008"; + VSVersion version = VSVersion.VS90; - /// - /// Gets or sets the solution version. - /// - /// The solution version. - public override string SolutionVersion - { - get - { - return solutionVersion; - } - } - /// - /// Gets or sets the product version. - /// - /// The product version. - public override string ProductVersion - { - get - { - return productVersion; - } - } - /// - /// Gets or sets the schema version. - /// - /// The schema version. - public override string SchemaVersion - { - get - { - return schemaVersion; - } - } - /// - /// Gets or sets the name of the version. - /// - /// The name of the version. - public override string VersionName - { - get - { - return versionName; - } - } - /// - /// Gets or sets the version. - /// - /// The version. - public override VSVersion Version - { - get - { - return version; - } - } - /// - /// Gets the name. - /// - /// The name. - public override string Name - { - get - { - return name; - } - } + /// + /// Gets or sets the solution version. + /// + /// The solution version. + public override string SolutionVersion + { + get + { + return solutionVersion; + } + } + /// + /// Gets or sets the product version. + /// + /// The product version. + public override string ProductVersion + { + get + { + return productVersion; + } + } + /// + /// Gets or sets the schema version. + /// + /// The schema version. + public override string SchemaVersion + { + get + { + return schemaVersion; + } + } + /// + /// Gets or sets the name of the version. + /// + /// The name of the version. + public override string VersionName + { + get + { + return versionName; + } + } + /// + /// Gets or sets the version. + /// + /// The version. + public override VSVersion Version + { + get + { + return version; + } + } + /// + /// Gets the name. + /// + /// The name. + public override string Name + { + get + { + return name; + } + } protected override string GetToolsVersionXml(FrameworkVersion frameworkVersion) { @@ -110,18 +110,18 @@ namespace Prebuild.Core.Targets get { return "# Visual Studio 2008"; } } - #endregion + #endregion - #region Constructors + #region Constructors - /// - /// Initializes a new instance of the class. - /// - public VS2008Target() - : base() - { - } + /// + /// Initializes a new instance of the class. + /// + public VS2008Target() + : base() + { + } - #endregion - } + #endregion + } } diff --git a/Prebuild/src/Core/Targets/VS2010Target.cs b/Prebuild/src/Core/Targets/VS2010Target.cs index b4c79dce99..e8aeab5b01 100644 --- a/Prebuild/src/Core/Targets/VS2010Target.cs +++ b/Prebuild/src/Core/Targets/VS2010Target.cs @@ -11,96 +11,96 @@ using System.CodeDom.Compiler; namespace Prebuild.Core.Targets { - /// - /// - /// - [Target("vs2010")] - public class VS2010Target : VSGenericTarget - { - #region Fields + /// + /// + /// + [Target("vs2010")] + public class VS2010Target : VSGenericTarget + { + #region Fields + + string solutionVersion = "11.00"; + string productVersion = "9.0.30729"; + string schemaVersion = "2.0"; + string versionName = "Visual Studio 2010"; + string name = "vs2010"; + VSVersion version = VSVersion.VS10; - string solutionVersion = "11.00"; - string productVersion = "9.0.30729"; - string schemaVersion = "2.0"; - string versionName = "Visual Studio 2010"; - string name = "vs2010"; - VSVersion version = VSVersion.VS10; - - #endregion - - #region Properties - - /// - /// Gets or sets the solution version. - /// - /// The solution version. - public override string SolutionVersion - { - get - { - return solutionVersion; - } - } - - /// - /// Gets or sets the product version. - /// - /// The product version. - public override string ProductVersion - { - get - { - return productVersion; - } - } - - /// - /// Gets or sets the schema version. - /// - /// The schema version. - public override string SchemaVersion - { - get - { - return schemaVersion; - } - } - - /// - /// Gets or sets the name of the version. - /// - /// The name of the version. - public override string VersionName - { - get - { - return versionName; - } - } - - /// - /// Gets or sets the version. - /// - /// The version. - public override VSVersion Version - { - get - { - return version; - } - } - - /// - /// Gets the name. - /// - /// The name. - public override string Name - { - get - { - return name; - } - } + #endregion + + #region Properties + + /// + /// Gets or sets the solution version. + /// + /// The solution version. + public override string SolutionVersion + { + get + { + return solutionVersion; + } + } + + /// + /// Gets or sets the product version. + /// + /// The product version. + public override string ProductVersion + { + get + { + return productVersion; + } + } + + /// + /// Gets or sets the schema version. + /// + /// The schema version. + public override string SchemaVersion + { + get + { + return schemaVersion; + } + } + + /// + /// Gets or sets the name of the version. + /// + /// The name of the version. + public override string VersionName + { + get + { + return versionName; + } + } + + /// + /// Gets or sets the version. + /// + /// The version. + public override VSVersion Version + { + get + { + return version; + } + } + + /// + /// Gets the name. + /// + /// The name. + public override string Name + { + get + { + return name; + } + } protected override string GetToolsVersionXml(FrameworkVersion frameworkVersion) { @@ -110,7 +110,7 @@ namespace Prebuild.Core.Targets case FrameworkVersion.v4_5: case FrameworkVersion.v4_0: case FrameworkVersion.v3_5: - return "ToolsVersion=\"4.0\""; + return "ToolsVersion=\"4.0\""; case FrameworkVersion.v3_0: return "ToolsVersion=\"3.0\""; default: @@ -123,18 +123,18 @@ namespace Prebuild.Core.Targets get { return "# Visual Studio 2010"; } } - #endregion + #endregion - #region Constructors + #region Constructors - /// - /// Initializes a new instance of the class. - /// - public VS2010Target() - : base() - { - } + /// + /// Initializes a new instance of the class. + /// + public VS2010Target() + : base() + { + } - #endregion - } + #endregion + } } diff --git a/Prebuild/src/Core/Targets/VS2012Target.cs b/Prebuild/src/Core/Targets/VS2012Target.cs new file mode 100644 index 0000000000..e21c97a258 --- /dev/null +++ b/Prebuild/src/Core/Targets/VS2012Target.cs @@ -0,0 +1,138 @@ +using System; + +using Prebuild.Core.Attributes; +using Prebuild.Core.Nodes; + +namespace Prebuild.Core.Targets +{ + + /// + /// + /// + [Target("vs2012")] + public class VS2012Target : VSGenericTarget + { + #region Fields + + string solutionVersion = "12.00"; + string productVersion = "11.0.61030.0"; + string schemaVersion = "2.0"; + string versionName = "Visual Studio 2012"; + string name = "vs2012"; + VSVersion version = VSVersion.VS11; + + #endregion + + #region Properties + + /// + /// Gets or sets the solution version. + /// + /// The solution version. + public override string SolutionVersion + { + get + { + return solutionVersion; + } + } + + /// + /// Gets or sets the product version. + /// + /// The product version. + public override string ProductVersion + { + get + { + return productVersion; + } + } + + /// + /// Gets or sets the schema version. + /// + /// The schema version. + public override string SchemaVersion + { + get + { + return schemaVersion; + } + } + + /// + /// Gets or sets the name of the version. + /// + /// The name of the version. + public override string VersionName + { + get + { + return versionName; + } + } + + /// + /// Gets or sets the version. + /// + /// The version. + public override VSVersion Version + { + get + { + return version; + } + } + + /// + /// Gets the name. + /// + /// The name. + public override string Name + { + get + { + return name; + } + } + + protected override string GetToolsVersionXml(FrameworkVersion frameworkVersion) + { + switch (frameworkVersion) + { + case FrameworkVersion.v4_6_1: + case FrameworkVersion.v4_6: + return "ToolsVersion=\"14.0\""; + case FrameworkVersion.v4_5_1: + case FrameworkVersion.v4_5: + case FrameworkVersion.v4_0: + case FrameworkVersion.v3_5: + return "ToolsVersion=\"4.0\""; + case FrameworkVersion.v3_0: + return "ToolsVersion=\"3.0\""; + default: + return "ToolsVersion=\"2.0\""; + } + } + + public override string SolutionTag + { + get { return "# Visual Studio 2012"; } + } + + #endregion + + #region Constructors + + /// + /// Initializes a new instance of the class. + /// + public VS2012Target() + : base() + { + } + + #endregion + } +} diff --git a/Prebuild/src/Core/Targets/VS2013Target.cs b/Prebuild/src/Core/Targets/VS2013Target.cs new file mode 100644 index 0000000000..96d8294988 --- /dev/null +++ b/Prebuild/src/Core/Targets/VS2013Target.cs @@ -0,0 +1,139 @@ +using System; + +using Prebuild.Core.Attributes; +using Prebuild.Core.Nodes; + +namespace Prebuild.Core.Targets +{ + + /// + /// + /// + [Target("vs2013")] + public class VS2013Target : VSGenericTarget + { + #region Fields + + string solutionVersion = "12.00"; + string productVersion = "12.0.31101"; + string schemaVersion = "2.0"; + string versionName = "Visual Studio 2013"; + string name = "vs2013"; + VSVersion version = VSVersion.VS12; + + #endregion + + #region Properties + + /// + /// Gets or sets the solution version. + /// + /// The solution version. + public override string SolutionVersion + { + get + { + return solutionVersion; + } + } + + /// + /// Gets or sets the product version. + /// + /// The product version. + public override string ProductVersion + { + get + { + return productVersion; + } + } + + /// + /// Gets or sets the schema version. + /// + /// The schema version. + public override string SchemaVersion + { + get + { + return schemaVersion; + } + } + + /// + /// Gets or sets the name of the version. + /// + /// The name of the version. + public override string VersionName + { + get + { + return versionName; + } + } + + /// + /// Gets or sets the version. + /// + /// The version. + public override VSVersion Version + { + get + { + return version; + } + } + + /// + /// Gets the name. + /// + /// The name. + public override string Name + { + get + { + return name; + } + } + + protected override string GetToolsVersionXml(FrameworkVersion frameworkVersion) + { + switch (frameworkVersion) + { + case FrameworkVersion.v4_6_1: + case FrameworkVersion.v4_6: + return "ToolsVersion=\"14.0\""; + case FrameworkVersion.v4_5_1: + case FrameworkVersion.v4_5: + return "ToolsVersion=\"12.0\""; + case FrameworkVersion.v4_0: + case FrameworkVersion.v3_5: + return "ToolsVersion=\"4.0\""; + case FrameworkVersion.v3_0: + return "ToolsVersion=\"3.0\""; + default: + return "ToolsVersion=\"2.0\""; + } + } + + public override string SolutionTag + { + get { return "# Visual Studio 2013"; } + } + + #endregion + + #region Constructors + + /// + /// Initializes a new instance of the class. + /// + public VS2013Target() + : base() + { + } + + #endregion + } +} diff --git a/Prebuild/src/Core/Targets/VS2015Target.cs b/Prebuild/src/Core/Targets/VS2015Target.cs new file mode 100644 index 0000000000..b487979cee --- /dev/null +++ b/Prebuild/src/Core/Targets/VS2015Target.cs @@ -0,0 +1,143 @@ +using System; +using System.IO; +using System.Text; + +using Prebuild.Core.Attributes; +using Prebuild.Core.Interfaces; +using Prebuild.Core.Nodes; +using Prebuild.Core.Utilities; +using System.CodeDom.Compiler; + +namespace Prebuild.Core.Targets +{ + + /// + /// + /// + [Target("vs2015")] + public class VS2015Target : VSGenericTarget + { + #region Fields + + string solutionVersion = "12.00"; + string productVersion = "14.0.23107.0"; + string schemaVersion = "2.0"; + string versionName = "Visual Studio 14"; + string name = "vs2015"; + VSVersion version = VSVersion.VS15; + + #endregion + + #region Properties + + /// + /// Gets or sets the solution version. + /// + /// The solution version. + public override string SolutionVersion + { + get + { + return solutionVersion; + } + } + + /// + /// Gets or sets the product version. + /// + /// The product version. + public override string ProductVersion + { + get + { + return productVersion; + } + } + + /// + /// Gets or sets the schema version. + /// + /// The schema version. + public override string SchemaVersion + { + get + { + return schemaVersion; + } + } + + /// + /// Gets or sets the name of the version. + /// + /// The name of the version. + public override string VersionName + { + get + { + return versionName; + } + } + + /// + /// Gets or sets the version. + /// + /// The version. + public override VSVersion Version + { + get + { + return version; + } + } + + /// + /// Gets the name. + /// + /// The name. + public override string Name + { + get + { + return name; + } + } + + protected override string GetToolsVersionXml(FrameworkVersion frameworkVersion) + { + switch (frameworkVersion) + { + case FrameworkVersion.v4_6_1: + case FrameworkVersion.v4_6: + return "ToolsVersion=\"14.0\""; + case FrameworkVersion.v4_5: + return "ToolsVersion=\"12.0\""; + case FrameworkVersion.v4_0: + case FrameworkVersion.v3_5: + return "ToolsVersion=\"4.0\""; + case FrameworkVersion.v3_0: + return "ToolsVersion=\"3.0\""; + default: + return "ToolsVersion=\"2.0\""; + } + } + + public override string SolutionTag + { + get { return "# Visual Studio 14"; } + } + + #endregion + + #region Constructors + + /// + /// Initializes a new instance of the class. + /// + public VS2015Target() + : base() + { + } + + #endregion + } +} \ No newline at end of file diff --git a/Prebuild/src/Core/Targets/VSGenericTarget.cs b/Prebuild/src/Core/Targets/VSGenericTarget.cs index 400788b9e2..c12120f761 100644 --- a/Prebuild/src/Core/Targets/VSGenericTarget.cs +++ b/Prebuild/src/Core/Targets/VSGenericTarget.cs @@ -35,141 +35,141 @@ using System.CodeDom.Compiler; namespace Prebuild.Core.Targets { - /// - /// - /// - public abstract class VSGenericTarget : ITarget - { - #region Fields + /// + /// + /// + public abstract class VSGenericTarget : ITarget + { + #region Fields - readonly Dictionary tools = new Dictionary(); + readonly Dictionary tools = new Dictionary(); // NameValueCollection CopyFiles = new NameValueCollection(); - Kernel kernel; - #endregion + Kernel kernel; + #endregion - #region Properties - /// - /// Gets or sets the solution version. - /// - /// The solution version. - public abstract string SolutionVersion { get; } - /// - /// Gets or sets the product version. - /// - /// The product version. - public abstract string ProductVersion { get; } - /// - /// Gets or sets the schema version. - /// - /// The schema version. - public abstract string SchemaVersion { get; } - /// - /// Gets or sets the name of the version. - /// - /// The name of the version. - public abstract string VersionName { get; } - /// - /// Gets or sets the version. - /// - /// The version. - public abstract VSVersion Version { get; } - /// - /// Gets the name. - /// - /// The name. - public abstract string Name { get; } + #region Properties + /// + /// Gets or sets the solution version. + /// + /// The solution version. + public abstract string SolutionVersion { get; } + /// + /// Gets or sets the product version. + /// + /// The product version. + public abstract string ProductVersion { get; } + /// + /// Gets or sets the schema version. + /// + /// The schema version. + public abstract string SchemaVersion { get; } + /// + /// Gets or sets the name of the version. + /// + /// The name of the version. + public abstract string VersionName { get; } + /// + /// Gets or sets the version. + /// + /// The version. + public abstract VSVersion Version { get; } + /// + /// Gets the name. + /// + /// The name. + public abstract string Name { get; } - protected abstract string GetToolsVersionXml(FrameworkVersion version); - public abstract string SolutionTag { get; } + protected abstract string GetToolsVersionXml(FrameworkVersion version); + public abstract string SolutionTag { get; } - #endregion + #endregion - #region Constructors + #region Constructors - /// - /// Initializes a new instance of the class. - /// - protected VSGenericTarget() - { - tools["C#"] = new ToolInfo("C#", "{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}", "csproj", "CSHARP", "$(MSBuildBinPath)\\Microsoft.CSHARP.Targets"); - tools["Database"] = new ToolInfo("Database", "{4F174C21-8C12-11D0-8340-0000F80270F8}", "dbp", "UNKNOWN"); - tools["Boo"] = new ToolInfo("Boo", "{45CEA7DC-C2ED-48A6-ACE0-E16144C02365}", "booproj", "Boo", "$(BooBinPath)\\Boo.Microsoft.Build.targets"); - tools["VisualBasic"] = new ToolInfo("VisualBasic", "{F184B08F-C81C-45F6-A57F-5ABD9991F28F}", "vbproj", "VisualBasic", "$(MSBuildBinPath)\\Microsoft.VisualBasic.Targets"); - tools["Folder"] = new ToolInfo("Folder", "{2150E333-8FDC-42A3-9474-1A3956D46DE8}", null, null); - } + /// + /// Initializes a new instance of the class. + /// + protected VSGenericTarget() + { + tools["C#"] = new ToolInfo("C#", "{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}", "csproj", "CSHARP", "$(MSBuildBinPath)\\Microsoft.CSharp.targets"); + tools["Database"] = new ToolInfo("Database", "{4F174C21-8C12-11D0-8340-0000F80270F8}", "dbp", "UNKNOWN"); + tools["Boo"] = new ToolInfo("Boo", "{45CEA7DC-C2ED-48A6-ACE0-E16144C02365}", "booproj", "Boo", "$(BooBinPath)\\Boo.Microsoft.Build.targets"); + tools["VisualBasic"] = new ToolInfo("VisualBasic", "{F184B08F-C81C-45F6-A57F-5ABD9991F28F}", "vbproj", "VisualBasic", "$(MSBuildBinPath)\\Microsoft.VisualBasic.Targets"); + tools["Folder"] = new ToolInfo("Folder", "{2150E333-8FDC-42A3-9474-1A3956D46DE8}", null, null); + } - #endregion + #endregion - #region Private Methods + #region Private Methods - private string MakeRefPath(ProjectNode project) - { - string ret = ""; - foreach (ReferencePathNode node in project.ReferencePaths) - { - try - { - string fullPath = Helper.ResolvePath(node.Path); - if (ret.Length < 1) - { - ret = fullPath; - } - else - { - ret += ";" + fullPath; - } - } - catch (ArgumentException) - { - kernel.Log.Write(LogType.Warning, "Could not resolve reference path: {0}", node.Path); - } - } + private string MakeRefPath(ProjectNode project) + { + string ret = ""; + foreach (ReferencePathNode node in project.ReferencePaths) + { + try + { + string fullPath = Helper.ResolvePath(node.Path); + if (ret.Length < 1) + { + ret = fullPath; + } + else + { + ret += ";" + fullPath; + } + } + catch (ArgumentException) + { + kernel.Log.Write(LogType.Warning, "Could not resolve reference path: {0}", node.Path); + } + } - return ret; - } + return ret; + } - private static ProjectNode FindProjectInSolution(string name, SolutionNode solution) - { - SolutionNode node = solution; + private static ProjectNode FindProjectInSolution(string name, SolutionNode solution) + { + SolutionNode node = solution; - while (node.Parent is SolutionNode) - node = node.Parent as SolutionNode; + while (node.Parent is SolutionNode) + node = node.Parent as SolutionNode; - return FindProjectInSolutionRecursively(name, node); - } + return FindProjectInSolutionRecursively(name, node); + } - private static ProjectNode FindProjectInSolutionRecursively(string name, SolutionNode solution) - { - if (solution.ProjectsTable.ContainsKey(name)) - return solution.ProjectsTable[name]; + private static ProjectNode FindProjectInSolutionRecursively(string name, SolutionNode solution) + { + if (solution.ProjectsTable.ContainsKey(name)) + return solution.ProjectsTable[name]; - foreach (SolutionNode child in solution.Solutions) - { - ProjectNode node = FindProjectInSolutionRecursively(name, child); - if (node != null) - return node; - } + foreach (SolutionNode child in solution.Solutions) + { + ProjectNode node = FindProjectInSolutionRecursively(name, child); + if (node != null) + return node; + } - return null; - } + return null; + } - private void WriteProject(SolutionNode solution, ProjectNode project) - { - if (!tools.ContainsKey(project.Language)) - { - throw new UnknownLanguageException("Unknown .NET language: " + project.Language); - } + private void WriteProject(SolutionNode solution, ProjectNode project) + { + if (!tools.ContainsKey(project.Language)) + { + throw new UnknownLanguageException("Unknown .NET language: " + project.Language); + } - ToolInfo toolInfo = tools[project.Language]; - string projectFile = Helper.MakeFilePath(project.FullPath, project.Name, toolInfo.FileExtension); - StreamWriter ps = new StreamWriter(projectFile); + ToolInfo toolInfo = tools[project.Language]; + string projectFile = Helper.MakeFilePath(project.FullPath, project.Name, toolInfo.FileExtension); + StreamWriter ps = new StreamWriter(projectFile); - kernel.CurrentWorkingDirectory.Push(); - Helper.SetCurrentDir(Path.GetDirectoryName(projectFile)); + kernel.CurrentWorkingDirectory.Push(); + Helper.SetCurrentDir(Path.GetDirectoryName(projectFile)); - #region Project File - using (ps) - { + #region Project File + using (ps) + { string targets = ""; if(project.Files.CopyFiles > 0) @@ -177,347 +177,354 @@ namespace Prebuild.Core.Targets else targets = "Build"; - ps.WriteLine("", targets, GetToolsVersionXml(project.FrameworkVersion)); - ps.WriteLine(" "); - ps.WriteLine(" Local"); - ps.WriteLine(" {0}", ProductVersion); - ps.WriteLine(" {0}", SchemaVersion); - ps.WriteLine(" {{{0}}}", project.Guid.ToString().ToUpper()); + ps.WriteLine("", targets, GetToolsVersionXml(project.FrameworkVersion)); + ps.WriteLine(" "); + ps.WriteLine(" Local"); + ps.WriteLine(" {0}", ProductVersion); + ps.WriteLine(" {0}", SchemaVersion); + ps.WriteLine(" {{{0}}}", project.Guid.ToString().ToUpper()); - // Visual Studio has a hard coded guid for the project type - if (project.Type == ProjectType.Web) - ps.WriteLine(" {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}"); - ps.WriteLine(" Debug"); - ps.WriteLine(" {0}", project.AppIcon); - ps.WriteLine(" "); - ps.WriteLine(" "); - ps.WriteLine(" {0}", project.AssemblyName); - foreach (ConfigurationNode conf in project.Configurations) + // Visual Studio has a hard coded guid for the project type + if (project.Type == ProjectType.Web) + ps.WriteLine(" {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}"); + ps.WriteLine(" Debug"); + ps.WriteLine(" {0}", project.AppIcon); + ps.WriteLine(" "); + ps.WriteLine(" "); + ps.WriteLine(" {0}", project.AssemblyName); + foreach (ConfigurationNode conf in project.Configurations) + { + if (conf.Options.KeyFile != "") + { + ps.WriteLine(" {0}", conf.Options.KeyFile); + ps.WriteLine(" true"); + break; + } + } + ps.WriteLine(" JScript"); + ps.WriteLine(" Grid"); + ps.WriteLine(" IE50"); + ps.WriteLine(" false"); + ps.WriteLine(" {0}", project.FrameworkVersion.ToString().Replace("_", ".")); + + ps.WriteLine(" {0}", project.Type == ProjectType.Web ? ProjectType.Library.ToString() : project.Type.ToString()); + ps.WriteLine(" {0}", project.DesignerFolder); + ps.WriteLine(" {0}", project.RootNamespace); + ps.WriteLine(" {0}", project.StartupObject); + if (string.IsNullOrEmpty(project.DebugStartParameters)) + { + ps.WriteLine(" {0}", project.DebugStartParameters); + } + ps.WriteLine(" "); + ps.WriteLine(" "); + + ps.WriteLine(" "); + if (!string.IsNullOrEmpty(project.ApplicationManifest)) { - if (conf.Options.KeyFile != "") - { - ps.WriteLine(" {0}", conf.Options.KeyFile); - ps.WriteLine(" true"); - break; - } - } - ps.WriteLine(" JScript"); - ps.WriteLine(" Grid"); - ps.WriteLine(" IE50"); - ps.WriteLine(" false"); - ps.WriteLine(" {0}", project.FrameworkVersion.ToString().Replace("_", ".")); - - ps.WriteLine(" {0}", project.Type == ProjectType.Web ? ProjectType.Library.ToString() : project.Type.ToString()); - ps.WriteLine(" {0}", project.DesignerFolder); - ps.WriteLine(" {0}", project.RootNamespace); - ps.WriteLine(" {0}", project.StartupObject); - if (string.IsNullOrEmpty(project.DebugStartParameters)) - { - ps.WriteLine(" {0}", project.DebugStartParameters); - } - ps.WriteLine(" "); - ps.WriteLine(" "); - - ps.WriteLine(" "); - - foreach (ConfigurationNode conf in project.Configurations) - { - ps.Write(" ", conf.Name, conf.Platform); - ps.WriteLine(" {0}", conf.Options["AllowUnsafe"]); - ps.WriteLine(" {0}", conf.Options["BaseAddress"]); - ps.WriteLine(" {0}", conf.Options["CheckUnderflowOverflow"]); - ps.WriteLine(" "); - ps.WriteLine(" "); - ps.WriteLine(" {0}", conf.Options["CompilerDefines"]); - ps.WriteLine(" {0}", Helper.NormalizePath(conf.Options["XmlDocFile"].ToString())); - ps.WriteLine(" {0}", conf.Options["DebugInformation"]); - ps.WriteLine(" {0}", conf.Options["FileAlignment"]); - ps.WriteLine(" {0}", conf.Options["OptimizeCode"]); - if (project.Type != ProjectType.Web) - ps.WriteLine(" {0}", - Helper.EndPath(Helper.NormalizePath(conf.Options["OutputPath"].ToString()))); - else - ps.WriteLine(" {0}", - Helper.EndPath(Helper.NormalizePath("bin\\"))); - - ps.WriteLine(" {0}", conf.Options["RegisterComInterop"]); - ps.WriteLine(" {0}", conf.Options["RemoveIntegerChecks"]); - ps.WriteLine(" {0}", conf.Options["WarningsAsErrors"]); - ps.WriteLine(" {0}", conf.Options["WarningLevel"]); - ps.WriteLine(" {0}", conf.Options["NoStdLib"]); - ps.WriteLine(" {0}", conf.Options["SuppressWarnings"]); - ps.WriteLine(" {0}", conf.Platform); + ps.WriteLine(" "); + ps.WriteLine(" " + project.ApplicationManifest + ""); ps.WriteLine(" "); } + foreach (ConfigurationNode conf in project.Configurations) + { + ps.Write(" ", conf.Name, conf.Platform); + ps.WriteLine(" {0}", conf.Options["AllowUnsafe"]); + ps.WriteLine(" {0}", conf.Options["BaseAddress"]); + ps.WriteLine(" {0}", conf.Options["CheckUnderflowOverflow"]); + ps.WriteLine(" "); + ps.WriteLine(" "); + ps.WriteLine(" {0}", + conf.Options["CompilerDefines"].ToString() == "" ? this.kernel.ForcedConditionals : conf.Options["CompilerDefines"] + ";" + kernel.ForcedConditionals); + ps.WriteLine(" {0}", Helper.NormalizePath(conf.Options["XmlDocFile"].ToString())); + ps.WriteLine(" {0}", conf.Options["DebugInformation"]); + ps.WriteLine(" {0}", conf.Options["FileAlignment"]); + ps.WriteLine(" {0}", conf.Options["OptimizeCode"]); + if (project.Type != ProjectType.Web) + ps.WriteLine(" {0}", + Helper.EndPath(Helper.NormalizePath(conf.Options["OutputPath"].ToString()))); + else + ps.WriteLine(" {0}", + Helper.EndPath(Helper.NormalizePath("bin\\"))); - //ps.WriteLine(" "); + ps.WriteLine(" {0}", conf.Options["RegisterComInterop"]); + ps.WriteLine(" {0}", conf.Options["RemoveIntegerChecks"]); + ps.WriteLine(" {0}", conf.Options["WarningsAsErrors"]); + ps.WriteLine(" {0}", conf.Options["WarningLevel"]); + ps.WriteLine(" {0}", conf.Options["NoStdLib"]); + ps.WriteLine(" {0}", conf.Options["SuppressWarnings"]); + ps.WriteLine(" {0}", conf.Platform); + ps.WriteLine(" {0}",conf.Options["Prefer32Bit"]); + ps.WriteLine(" "); + } - Dictionary projectReferences = new Dictionary(); - List otherReferences = new List(); + //ps.WriteLine(" "); - foreach (ReferenceNode refr in project.References) - { - ProjectNode projectNode = FindProjectInSolution(refr.Name, solution); + Dictionary projectReferences = new Dictionary(); + List otherReferences = new List(); - if (projectNode == null) - otherReferences.Add(refr); - else - projectReferences.Add(refr, projectNode); - } - // Assembly References - ps.WriteLine(" "); + foreach (ReferenceNode refr in project.References) + { + ProjectNode projectNode = FindProjectInSolution(refr.Name, solution); - foreach (ReferenceNode refr in otherReferences) - { - ps.Write(" "); - ps.Write(" "); - ps.Write(refr.Name); - ps.WriteLine(""); + if (projectNode == null) + otherReferences.Add(refr); + else + projectReferences.Add(refr, projectNode); + } + // Assembly References + ps.WriteLine(" "); - if(!String.IsNullOrEmpty(refr.Path)) - { - // Use absolute path to assembly (for determining assembly type) - string absolutePath = Path.Combine(project.FullPath, refr.Path); - if(File.Exists(Helper.MakeFilePath(absolutePath, refr.Name, "exe"))) { - // Assembly is an executable (exe) - ps.WriteLine(" {0}", Helper.MakeFilePath(refr.Path, refr.Name, "exe")); - } else if(File.Exists(Helper.MakeFilePath(absolutePath, refr.Name, "dll"))) { - // Assembly is an library (dll) - ps.WriteLine(" {0}", Helper.MakeFilePath(refr.Path, refr.Name, "dll")); - } else { - string referencePath = Helper.MakeFilePath(refr.Path, refr.Name, "dll"); - kernel.Log.Write(LogType.Warning, "Reference \"{0}\": The specified file doesn't exist.", referencePath); - ps.WriteLine(" {0}", Helper.MakeFilePath(refr.Path, refr.Name, "dll")); - } - } + foreach (ReferenceNode refr in otherReferences) + { + ps.Write(" "); + ps.Write(" "); + ps.Write(refr.Name); + ps.WriteLine(""); + + if(!String.IsNullOrEmpty(refr.Path)) + { + // Use absolute path to assembly (for determining assembly type) + string absolutePath = Path.Combine(project.FullPath, refr.Path); + if(File.Exists(Helper.MakeFilePath(absolutePath, refr.Name, "exe"))) { + // Assembly is an executable (exe) + ps.WriteLine(" {0}", Helper.MakeFilePath(refr.Path, refr.Name, "exe")); + } else if(File.Exists(Helper.MakeFilePath(absolutePath, refr.Name, "dll"))) { + // Assembly is an library (dll) + ps.WriteLine(" {0}", Helper.MakeFilePath(refr.Path, refr.Name, "dll")); + } else { + string referencePath = Helper.MakeFilePath(refr.Path, refr.Name, "dll"); + kernel.Log.Write(LogType.Warning, "Reference \"{0}\": The specified file doesn't exist.", referencePath); + ps.WriteLine(" {0}", Helper.MakeFilePath(refr.Path, refr.Name, "dll")); + } + } + + ps.WriteLine(" {0}", refr.LocalCopy); + ps.WriteLine(" "); + } + ps.WriteLine(" "); - ps.WriteLine(" {0}", refr.LocalCopy); - ps.WriteLine(" "); - } - ps.WriteLine(" "); + //Project References + ps.WriteLine(" "); + foreach (KeyValuePair pair in projectReferences) + { + ToolInfo tool = tools[pair.Value.Language]; + if (tools == null) + throw new UnknownLanguageException(); - //Project References - ps.WriteLine(" "); - foreach (KeyValuePair pair in projectReferences) - { - ToolInfo tool = tools[pair.Value.Language]; - if (tools == null) - throw new UnknownLanguageException(); + string path = + Helper.MakePathRelativeTo(project.FullPath, + Helper.MakeFilePath(pair.Value.FullPath, pair.Value.Name, tool.FileExtension)); + ps.WriteLine(" ", path); - string path = - Helper.MakePathRelativeTo(project.FullPath, - Helper.MakeFilePath(pair.Value.FullPath, pair.Value.Name, tool.FileExtension)); - ps.WriteLine(" ", path); + // TODO: Allow reference to visual basic projects + ps.WriteLine(" {0}", pair.Value.Name); + ps.WriteLine(" {0}", pair.Value.Guid.ToString("B").ToUpper()); + ps.WriteLine(" {0}", tool.Guid.ToUpper()); - // TODO: Allow reference to visual basic projects - ps.WriteLine(" {0}", pair.Value.Name); - ps.WriteLine(" {0}", pair.Value.Guid.ToString("B").ToUpper()); - ps.WriteLine(" {0}", tool.Guid.ToUpper()); + //This is the Copy Local flag in VS + ps.WriteLine(" {0}", pair.Key.LocalCopy); - //This is the Copy Local flag in VS - ps.WriteLine(" {0}", pair.Key.LocalCopy); + ps.WriteLine(" "); + } + ps.WriteLine(" "); - ps.WriteLine(" "); - } - ps.WriteLine(" "); + // ps.WriteLine(" "); + ps.WriteLine(" "); - // ps.WriteLine(" "); - ps.WriteLine(" "); + // ps.WriteLine(" "); + List list = new List(); - // ps.WriteLine(" "); - List list = new List(); + foreach (string path in project.Files) + { + string lower = path.ToLower(); + if (lower.EndsWith(".resx")) + { + string codebehind = String.Format("{0}.Designer{1}", path.Substring(0, path.LastIndexOf('.')), toolInfo.LanguageExtension); + if (!list.Contains(codebehind)) + list.Add(codebehind); + } - foreach (string path in project.Files) - { - string lower = path.ToLower(); - if (lower.EndsWith(".resx")) - { - string codebehind = String.Format("{0}.Designer{1}", path.Substring(0, path.LastIndexOf('.')), toolInfo.LanguageExtension); - if (!list.Contains(codebehind)) - list.Add(codebehind); - } - - } + } - foreach (string filePath in project.Files) - { + foreach (string filePath in project.Files) + { // Add the filePath with the destination as the key // will use it later to form the copy parameters with Include lists // for each destination if (project.Files.GetBuildAction(filePath) == BuildAction.Copy) continue; - // if (file == "Properties\\Bind.Designer.cs") - // { - // Console.WriteLine("Wait a minute!"); - // Console.WriteLine(project.Files.GetSubType(file).ToString()); - // } - SubType subType = project.Files.GetSubType(filePath); + // if (file == "Properties\\Bind.Designer.cs") + // { + // Console.WriteLine("Wait a minute!"); + // Console.WriteLine(project.Files.GetSubType(file).ToString()); + // } + SubType subType = project.Files.GetSubType(filePath); + + // Visual Studio chokes on file names if forward slash is used as a path separator + // instead of backslash. So we must make sure that all file paths written to the + // project file use \ as a path separator. + string file = filePath.Replace(@"/", @"\"); - // Visual Studio chokes on file names if forward slash is used as a path separator - // instead of backslash. So we must make sure that all file paths written to the - // project file use \ as a path separator. - string file = filePath.Replace(@"/", @"\"); + if (subType != SubType.Code && subType != SubType.Settings && subType != SubType.Designer + && subType != SubType.CodeBehind) + { + ps.WriteLine(" ", file.Substring(0, file.LastIndexOf('.')) + ".resx"); + ps.WriteLine(" {0}", Path.GetFileName(file)); + ps.WriteLine(" Designer"); + ps.WriteLine(" "); + // + } - if (subType != SubType.Code && subType != SubType.Settings && subType != SubType.Designer - && subType != SubType.CodeBehind) - { - ps.WriteLine(" ", file.Substring(0, file.LastIndexOf('.')) + ".resx"); - ps.WriteLine(" {0}", Path.GetFileName(file)); - ps.WriteLine(" Designer"); - ps.WriteLine(" "); - // - } + if (subType == SubType.Designer) + { + ps.WriteLine(" ", file); + + string autogen_name = file.Substring(0, file.LastIndexOf('.')) + ".Designer.cs"; + string dependent_name = filePath.Substring(0, file.LastIndexOf('.')) + ".cs"; - if (subType == SubType.Designer) - { - ps.WriteLine(" ", file); + // Check for a parent .cs file with the same name as this designer file + if (File.Exists(Helper.NormalizePath(dependent_name))) + { + ps.WriteLine(" {0}", Path.GetFileName(dependent_name)); + } + else + { + ps.WriteLine(" ResXFileCodeGenerator"); + ps.WriteLine(" {0}", Path.GetFileName(autogen_name)); + ps.WriteLine(" " + subType + ""); + } + + ps.WriteLine(" "); + if (File.Exists(Helper.NormalizePath(autogen_name))) + { + ps.WriteLine(" ", autogen_name); + //ps.WriteLine(" True"); - string autogen_name = file.Substring(0, file.LastIndexOf('.')) + ".Designer.cs"; - string dependent_name = filePath.Substring(0, file.LastIndexOf('.')) + ".cs"; + // If a parent .cs file exists, link this autogen file to it. Otherwise link + // to the designer file + if (File.Exists(dependent_name)) + { + ps.WriteLine(" {0}", Path.GetFileName(dependent_name)); + } + else + { + ps.WriteLine(" True"); + ps.WriteLine(" {0}", Path.GetFileName(filePath)); + } + + ps.WriteLine(" "); + } + list.Add(autogen_name); + } + if (subType == SubType.Settings) + { + ps.Write(" <{0} ", project.Files.GetBuildAction(filePath)); + ps.WriteLine("Include=\"{0}\">", file); + string fileName = Path.GetFileName(filePath); + if (project.Files.GetBuildAction(filePath) == BuildAction.None) + { + ps.WriteLine(" SettingsSingleFileGenerator"); + ps.WriteLine(" {0}", fileName.Substring(0, fileName.LastIndexOf('.')) + ".Designer.cs"); + } + else + { + ps.WriteLine(" Code"); + ps.WriteLine(" True"); + ps.WriteLine(" True"); + string fileNameShort = fileName.Substring(0, fileName.LastIndexOf('.')); + string fileNameShorter = fileNameShort.Substring(0, fileNameShort.LastIndexOf('.')); + ps.WriteLine(" {0}", Path.GetFileName(fileNameShorter + ".settings")); + } + ps.WriteLine(" ", project.Files.GetBuildAction(filePath)); + } + else if (subType != SubType.Designer) + { + string path = Helper.NormalizePath(file); + string path_lower = path.ToLower(); - // Check for a parent .cs file with the same name as this designer file - if (File.Exists(Helper.NormalizePath(dependent_name))) - { - ps.WriteLine(" {0}", Path.GetFileName(dependent_name)); - } - else - { - ps.WriteLine(" ResXFileCodeGenerator"); - ps.WriteLine(" {0}", Path.GetFileName(autogen_name)); - ps.WriteLine(" " + subType + ""); - } + if (!list.Contains(filePath)) + { + ps.Write(" <{0} ", project.Files.GetBuildAction(filePath)); - ps.WriteLine(" "); - if (File.Exists(Helper.NormalizePath(autogen_name))) - { - ps.WriteLine(" ", autogen_name); - //ps.WriteLine(" True"); + int startPos = 0; + if (project.Files.GetPreservePath(filePath)) + { + while ((@"./\").IndexOf(file.Substring(startPos, 1)) != -1) + startPos++; - // If a parent .cs file exists, link this autogen file to it. Otherwise link - // to the designer file - if (File.Exists(dependent_name)) - { - ps.WriteLine(" {0}", Path.GetFileName(dependent_name)); - } - else - { - ps.WriteLine(" True"); - ps.WriteLine(" {0}", Path.GetFileName(filePath)); - } + } + else + { + startPos = file.LastIndexOf(Path.GetFileName(path)); + } + + // be sure to write out the path with backslashes so VS recognizes + // the file properly. + ps.WriteLine("Include=\"{0}\">", file); - ps.WriteLine(" "); - } - list.Add(autogen_name); - } - if (subType == SubType.Settings) - { - ps.Write(" <{0} ", project.Files.GetBuildAction(filePath)); - ps.WriteLine("Include=\"{0}\">", file); - string fileName = Path.GetFileName(filePath); - if (project.Files.GetBuildAction(filePath) == BuildAction.None) - { - ps.WriteLine(" SettingsSingleFileGenerator"); - ps.WriteLine(" {0}", fileName.Substring(0, fileName.LastIndexOf('.')) + ".Designer.cs"); - } - else - { - ps.WriteLine(" Code"); - ps.WriteLine(" True"); - ps.WriteLine(" True"); - string fileNameShort = fileName.Substring(0, fileName.LastIndexOf('.')); - string fileNameShorter = fileNameShort.Substring(0, fileNameShort.LastIndexOf('.')); - ps.WriteLine(" {0}", Path.GetFileName(fileNameShorter + ".settings")); - } - ps.WriteLine(" ", project.Files.GetBuildAction(filePath)); - } - else if (subType != SubType.Designer) - { - string path = Helper.NormalizePath(file); - string path_lower = path.ToLower(); - - if (!list.Contains(filePath)) - { - ps.Write(" <{0} ", project.Files.GetBuildAction(filePath)); - - int startPos = 0; - if (project.Files.GetPreservePath(filePath)) - { - while ((@"./\").IndexOf(file.Substring(startPos, 1)) != -1) - startPos++; - - } - else - { - startPos = file.LastIndexOf(Path.GetFileName(path)); - } - - // be sure to write out the path with backslashes so VS recognizes - // the file properly. - ps.WriteLine("Include=\"{0}\">", file); - - int last_period_index = file.LastIndexOf('.'); + int last_period_index = file.LastIndexOf('.'); string short_file_name = (last_period_index >= 0) ? file.Substring(0, last_period_index) : file; - string extension = Path.GetExtension(path); - // make this upper case, so that when File.Exists tests for the - // existence of a designer file on a case-sensitive platform, - // it is correctly identified. - string designer_format = string.Format(".Designer{0}", extension); + string extension = Path.GetExtension(path); + // make this upper case, so that when File.Exists tests for the + // existence of a designer file on a case-sensitive platform, + // it is correctly identified. + string designer_format = string.Format(".Designer{0}", extension); - if (path_lower.EndsWith(designer_format.ToLowerInvariant())) - { - int designer_index = path.IndexOf(designer_format); - string file_name = path.Substring(0, designer_index); + if (path_lower.EndsWith(designer_format.ToLowerInvariant())) + { + int designer_index = path.IndexOf(designer_format); + string file_name = path.Substring(0, designer_index); - // There are two corrections to the next lines: - // 1. Fix the connection between a designer file and a form - // or usercontrol that don't have an associated resx file. - // 2. Connect settings files to associated designer files. - if (File.Exists(file_name + extension)) - ps.WriteLine(" {0}", Path.GetFileName(file_name + extension)); - else if (File.Exists(file_name + ".resx")) - ps.WriteLine(" {0}", Path.GetFileName(file_name + ".resx")); - else if (File.Exists(file_name + ".settings")) - { - ps.WriteLine(" {0}", Path.GetFileName(file_name + ".settings")); - ps.WriteLine(" True"); - ps.WriteLine(" True"); - } - } - else if (subType == SubType.CodeBehind) - { - ps.WriteLine(" {0}", Path.GetFileName(short_file_name)); - } - if (project.Files.GetIsLink(filePath)) - { - string alias = project.Files.GetLinkPath(filePath); - alias += file.Substring(startPos); - alias = Helper.NormalizePath(alias); - ps.WriteLine(" {0}", alias); - } - else if (project.Files.GetBuildAction(filePath) != BuildAction.None) - { - if (project.Files.GetBuildAction(filePath) != BuildAction.EmbeddedResource) - { - ps.WriteLine(" {0}", subType); - } - } + // There are two corrections to the next lines: + // 1. Fix the connection between a designer file and a form + // or usercontrol that don't have an associated resx file. + // 2. Connect settings files to associated designer files. + if (File.Exists(file_name + extension)) + ps.WriteLine(" {0}", Path.GetFileName(file_name + extension)); + else if (File.Exists(file_name + ".resx")) + ps.WriteLine(" {0}", Path.GetFileName(file_name + ".resx")); + else if (File.Exists(file_name + ".settings")) + { + ps.WriteLine(" {0}", Path.GetFileName(file_name + ".settings")); + ps.WriteLine(" True"); + ps.WriteLine(" True"); + } + } + else if (subType == SubType.CodeBehind) + { + ps.WriteLine(" {0}", Path.GetFileName(short_file_name)); + } + if (project.Files.GetIsLink(filePath)) + { + string alias = project.Files.GetLinkPath(filePath); + alias += file.Substring(startPos); + alias = Helper.NormalizePath(alias); + ps.WriteLine(" {0}", alias); + } + else if (project.Files.GetBuildAction(filePath) != BuildAction.None) + { + if (project.Files.GetBuildAction(filePath) != BuildAction.EmbeddedResource) + { + ps.WriteLine(" {0}", subType); + } + } - if (project.Files.GetCopyToOutput(filePath) != CopyToOutput.Never) - { - ps.WriteLine(" {0}", project.Files.GetCopyToOutput(filePath)); - } + if (project.Files.GetCopyToOutput(filePath) != CopyToOutput.Never) + { + ps.WriteLine(" {0}", project.Files.GetCopyToOutput(filePath)); + } - ps.WriteLine(" ", project.Files.GetBuildAction(filePath)); - } - } - } + ps.WriteLine(" ", project.Files.GetBuildAction(filePath)); + } + } + } ps.WriteLine(" "); /* @@ -553,420 +560,420 @@ namespace Prebuild.Core.Targets ps.WriteLine(" "); } - ps.WriteLine(" "); - ps.WriteLine(" "); - ps.WriteLine(" "); - ps.WriteLine(" "); - ps.WriteLine(" "); - ps.WriteLine(" "); - ps.WriteLine(" "); - ps.WriteLine(""); - } - #endregion - - #region User File - - ps = new StreamWriter(projectFile + ".user"); - using (ps) - { - // Get the first configuration from the project. - ConfigurationNode firstConfiguration = null; - - if (project.Configurations.Count > 0) - { - firstConfiguration = project.Configurations[0]; - } - - ps.WriteLine(""); - //ps.WriteLine( "" ); - //ps.WriteLine(" <{0}>", toolInfo.XMLTag); - //ps.WriteLine(" "); - ps.WriteLine(" "); - //ps.WriteLine(" ", MakeRefPath(project)); - - if (firstConfiguration != null) - { - ps.WriteLine(" {0}", firstConfiguration.Name); - ps.WriteLine(" {0}", firstConfiguration.Platform); - } - - ps.WriteLine(" {0}", MakeRefPath(project)); - ps.WriteLine(" {0}", ProductVersion); - ps.WriteLine(" ProjectFiles"); - ps.WriteLine(" 0"); - ps.WriteLine(" "); - foreach (ConfigurationNode conf in project.Configurations) - { - ps.Write(" "); - } - ps.WriteLine(""); - } - #endregion - - kernel.CurrentWorkingDirectory.Pop(); - } - - private void WriteSolution(SolutionNode solution, bool writeSolutionToDisk) - { - kernel.Log.Write("Creating {0} solution and project files", VersionName); - - foreach (SolutionNode child in solution.Solutions) - { - kernel.Log.Write("...Creating folder: {0}", child.Name); - WriteSolution(child, false); - } - - foreach (ProjectNode project in solution.Projects) - { - kernel.Log.Write("...Creating project: {0}", project.Name); - WriteProject(solution, project); - } - - foreach (DatabaseProjectNode project in solution.DatabaseProjects) - { - kernel.Log.Write("...Creating database project: {0}", project.Name); - WriteDatabaseProject(solution, project); - } - - if (writeSolutionToDisk) // only write main solution - { - kernel.Log.Write(""); - string solutionFile = Helper.MakeFilePath(solution.FullPath, solution.Name, "sln"); - - using (StreamWriter ss = new StreamWriter(solutionFile)) - { - kernel.CurrentWorkingDirectory.Push(); - Helper.SetCurrentDir(Path.GetDirectoryName(solutionFile)); - - ss.WriteLine("Microsoft Visual Studio Solution File, Format Version {0}", SolutionVersion); - ss.WriteLine(SolutionTag); - - WriteProjectDeclarations(ss, solution, solution); - - ss.WriteLine("Global"); - - ss.WriteLine("\tGlobalSection(SolutionConfigurationPlatforms) = preSolution"); - foreach (ConfigurationNode conf in solution.Configurations) - { - ss.WriteLine("\t\t{0} = {0}", conf.NameAndPlatform); - } - ss.WriteLine("\tEndGlobalSection"); - - ss.WriteLine("\tGlobalSection(ProjectConfigurationPlatforms) = postSolution"); - WriteConfigurationLines(solution.Configurations, solution, ss); - ss.WriteLine("\tEndGlobalSection"); - - if (solution.Solutions.Count > 0) - { - ss.WriteLine("\tGlobalSection(NestedProjects) = preSolution"); - foreach (SolutionNode embeddedSolution in solution.Solutions) - { - WriteNestedProjectMap(ss, embeddedSolution); - } - ss.WriteLine("\tEndGlobalSection"); - } - - ss.WriteLine("EndGlobal"); - } - - kernel.CurrentWorkingDirectory.Pop(); - } - } - - private void WriteProjectDeclarations(TextWriter writer, SolutionNode actualSolution, SolutionNode embeddedSolution) - { - foreach (SolutionNode childSolution in embeddedSolution.Solutions) - { - WriteEmbeddedSolution(writer, childSolution); - WriteProjectDeclarations(writer, actualSolution, childSolution); - } - - foreach (ProjectNode project in embeddedSolution.Projects) - { - WriteProject(actualSolution, writer, project); - } - - foreach (DatabaseProjectNode dbProject in embeddedSolution.DatabaseProjects) - { - WriteProject(actualSolution, writer, dbProject); - } - - if (actualSolution.Guid == embeddedSolution.Guid) - { - WriteSolutionFiles(actualSolution, writer); - } - } - - private static void WriteNestedProjectMap(TextWriter writer, SolutionNode embeddedSolution) - { - foreach (ProjectNode project in embeddedSolution.Projects) - { - WriteNestedProject(writer, embeddedSolution, project.Guid); - } - - foreach (DatabaseProjectNode dbProject in embeddedSolution.DatabaseProjects) - { - WriteNestedProject(writer, embeddedSolution, dbProject.Guid); - } - - foreach (SolutionNode child in embeddedSolution.Solutions) - { - WriteNestedProject(writer, embeddedSolution, child.Guid); - WriteNestedProjectMap(writer, child); - } - } - - private static void WriteNestedProject(TextWriter writer, SolutionNode solution, Guid projectGuid) - { - WriteNestedFolder(writer, solution.Guid, projectGuid); - } - - private static void WriteNestedFolder(TextWriter writer, Guid parentGuid, Guid childGuid) - { - writer.WriteLine("\t\t{0} = {1}", - childGuid.ToString("B").ToUpper(), - parentGuid.ToString("B").ToUpper()); - } - - private static void WriteConfigurationLines(IEnumerable configurations, SolutionNode solution, TextWriter ss) - { - foreach (ProjectNode project in solution.Projects) - { - foreach (ConfigurationNode conf in configurations) - { - ss.WriteLine("\t\t{0}.{1}.ActiveCfg = {1}", - project.Guid.ToString("B").ToUpper(), - conf.NameAndPlatform); - - ss.WriteLine("\t\t{0}.{1}.Build.0 = {1}", - project.Guid.ToString("B").ToUpper(), - conf.NameAndPlatform); - } - } - - foreach (SolutionNode child in solution.Solutions) - { - WriteConfigurationLines(configurations, child, ss); - } - } - - private void WriteSolutionFiles(SolutionNode solution, TextWriter ss) - { - if(solution.Files != null && solution.Files.Count > 0) - WriteProject(ss, "Folder", solution.Guid, "Solution Files", "Solution Files", solution.Files); - } - - private void WriteEmbeddedSolution(TextWriter writer, SolutionNode embeddedSolution) - { - WriteProject(writer, "Folder", embeddedSolution.Guid, embeddedSolution.Name, embeddedSolution.Name, embeddedSolution.Files); - } - - private void WriteProject(SolutionNode solution, TextWriter ss, ProjectNode project) - { - WriteProject(ss, solution, project.Language, project.Guid, project.Name, project.FullPath); - } - - private void WriteProject(SolutionNode solution, TextWriter ss, DatabaseProjectNode dbProject) - { - if (solution.Files != null && solution.Files.Count > 0) - WriteProject(ss, solution, "Database", dbProject.Guid, dbProject.Name, dbProject.FullPath); - } - - const string ProjectDeclarationBeginFormat = "Project(\"{0}\") = \"{1}\", \"{2}\", \"{3}\""; - const string ProjectDeclarationEndFormat = "EndProject"; - - private void WriteProject(TextWriter ss, SolutionNode solution, string language, Guid guid, string name, string projectFullPath) - { - if (!tools.ContainsKey(language)) - throw new UnknownLanguageException("Unknown .NET language: " + language); - - ToolInfo toolInfo = tools[language]; - - string path = Helper.MakePathRelativeTo(solution.FullPath, projectFullPath); - - path = Helper.MakeFilePath(path, name, toolInfo.FileExtension); - - WriteProject(ss, language, guid, name, path); - } - - private void WriteProject(TextWriter writer, string language, Guid projectGuid, string name, string location) - { - WriteProject(writer, language, projectGuid, name, location, null); - } - - private void WriteProject(TextWriter writer, string language, Guid projectGuid, string name, string location, FilesNode files) - { - if (!tools.ContainsKey(language)) - throw new UnknownLanguageException("Unknown .NET language: " + language); - - ToolInfo toolInfo = tools[language]; - - writer.WriteLine(ProjectDeclarationBeginFormat, - toolInfo.Guid, - name, - location, - projectGuid.ToString("B").ToUpper()); - - if (files != null) - { - writer.WriteLine("\tProjectSection(SolutionItems) = preProject"); - - foreach (string file in files) - writer.WriteLine("\t\t{0} = {0}", file); - - writer.WriteLine("\tEndProjectSection"); - } - - writer.WriteLine(ProjectDeclarationEndFormat); - } - - private void WriteDatabaseProject(SolutionNode solution, DatabaseProjectNode project) - { - string projectFile = Helper.MakeFilePath(project.FullPath, project.Name, "dbp"); - IndentedTextWriter ps = new IndentedTextWriter(new StreamWriter(projectFile), " "); - - kernel.CurrentWorkingDirectory.Push(); - - Helper.SetCurrentDir(Path.GetDirectoryName(projectFile)); - - using (ps) - { - ps.WriteLine("# Microsoft Developer Studio Project File - Database Project"); - ps.WriteLine("Begin DataProject = \"{0}\"", project.Name); - ps.Indent++; - ps.WriteLine("MSDTVersion = \"80\""); - // TODO: Use the project.Files property - if (ContainsSqlFiles(Path.GetDirectoryName(projectFile))) - WriteDatabaseFoldersAndFiles(ps, Path.GetDirectoryName(projectFile)); - - ps.WriteLine("Begin DBRefFolder = \"Database References\""); - ps.Indent++; - foreach (DatabaseReferenceNode reference in project.References) - { - ps.WriteLine("Begin DBRefNode = \"{0}\"", reference.Name); - ps.Indent++; - ps.WriteLine("ConnectStr = \"{0}\"", reference.ConnectionString); - ps.WriteLine("Provider = \"{0}\"", reference.ProviderId.ToString("B").ToUpper()); - //ps.WriteLine("Colorizer = 5"); - ps.Indent--; - ps.WriteLine("End"); - } - ps.Indent--; - ps.WriteLine("End"); - ps.Indent--; - ps.WriteLine("End"); - - ps.Flush(); - } - - kernel.CurrentWorkingDirectory.Pop(); - } - - private static bool ContainsSqlFiles(string folder) - { - if(Directory.GetFiles(folder, "*.sql").Length > 0) - return true; // if the folder contains 1 .sql file, that's good enough - - foreach (string child in Directory.GetDirectories(folder)) - { - if (ContainsSqlFiles(child)) - return true; // if 1 child folder contains a .sql file, still good enough - } - - return false; - } - - private static void WriteDatabaseFoldersAndFiles(IndentedTextWriter writer, string folder) - { - foreach (string child in Directory.GetDirectories(folder)) - { - if (ContainsSqlFiles(child)) - { - writer.WriteLine("Begin Folder = \"{0}\"", Path.GetFileName(child)); - writer.Indent++; - WriteDatabaseFoldersAndFiles(writer, child); - writer.Indent--; - writer.WriteLine("End"); - } - } - foreach (string file in Directory.GetFiles(folder, "*.sql")) - { - writer.WriteLine("Script = \"{0}\"", Path.GetFileName(file)); - } - } - - private void CleanProject(ProjectNode project) - { - kernel.Log.Write("...Cleaning project: {0}", project.Name); - - ToolInfo toolInfo = tools[project.Language]; - string projectFile = Helper.MakeFilePath(project.FullPath, project.Name, toolInfo.FileExtension); - string userFile = projectFile + ".user"; - - Helper.DeleteIfExists(projectFile); - Helper.DeleteIfExists(userFile); - } - - private void CleanSolution(SolutionNode solution) - { - kernel.Log.Write("Cleaning {0} solution and project files", VersionName, solution.Name); - - string slnFile = Helper.MakeFilePath(solution.FullPath, solution.Name, "sln"); - string suoFile = Helper.MakeFilePath(solution.FullPath, solution.Name, "suo"); - - Helper.DeleteIfExists(slnFile); - Helper.DeleteIfExists(suoFile); - - foreach (ProjectNode project in solution.Projects) - { - CleanProject(project); - } - - kernel.Log.Write(""); - } - - #endregion - - #region ITarget Members - - /// - /// Writes the specified kern. - /// - /// The kern. - public virtual void Write(Kernel kern) - { - if (kern == null) - { - throw new ArgumentNullException("kern"); - } - kernel = kern; - foreach (SolutionNode sol in kernel.Solutions) - { - WriteSolution(sol, true); - } - kernel = null; - } - - /// - /// Cleans the specified kern. - /// - /// The kern. - public virtual void Clean(Kernel kern) - { - if (kern == null) - { - throw new ArgumentNullException("kern"); - } - kernel = kern; - foreach (SolutionNode sol in kernel.Solutions) - { - CleanSolution(sol); - } - kernel = null; - } - - #endregion - } + ps.WriteLine(" "); + ps.WriteLine(" "); + ps.WriteLine(" "); + ps.WriteLine(" "); + ps.WriteLine(" "); + ps.WriteLine(" "); + ps.WriteLine(" "); + ps.WriteLine(""); + } + #endregion + + #region User File + + ps = new StreamWriter(projectFile + ".user"); + using (ps) + { + // Get the first configuration from the project. + ConfigurationNode firstConfiguration = null; + + if (project.Configurations.Count > 0) + { + firstConfiguration = project.Configurations[0]; + } + + ps.WriteLine(""); + //ps.WriteLine( "" ); + //ps.WriteLine(" <{0}>", toolInfo.XMLTag); + //ps.WriteLine(" "); + ps.WriteLine(" "); + //ps.WriteLine(" ", MakeRefPath(project)); + + if (firstConfiguration != null) + { + ps.WriteLine(" {0}", firstConfiguration.Name); + ps.WriteLine(" {0}", firstConfiguration.Platform); + } + + ps.WriteLine(" {0}", MakeRefPath(project)); + ps.WriteLine(" {0}", ProductVersion); + ps.WriteLine(" ProjectFiles"); + ps.WriteLine(" 0"); + ps.WriteLine(" "); + foreach (ConfigurationNode conf in project.Configurations) + { + ps.Write(" "); + } + ps.WriteLine(""); + } + #endregion + + kernel.CurrentWorkingDirectory.Pop(); + } + + private void WriteSolution(SolutionNode solution, bool writeSolutionToDisk) + { + kernel.Log.Write("Creating {0} solution and project files", VersionName); + + foreach (SolutionNode child in solution.Solutions) + { + kernel.Log.Write("...Creating folder: {0}", child.Name); + WriteSolution(child, false); + } + + foreach (ProjectNode project in solution.Projects) + { + kernel.Log.Write("...Creating project: {0}", project.Name); + WriteProject(solution, project); + } + + foreach (DatabaseProjectNode project in solution.DatabaseProjects) + { + kernel.Log.Write("...Creating database project: {0}", project.Name); + WriteDatabaseProject(solution, project); + } + + if (writeSolutionToDisk) // only write main solution + { + kernel.Log.Write(""); + string solutionFile = Helper.MakeFilePath(solution.FullPath, solution.Name, "sln"); + + using (StreamWriter ss = new StreamWriter(solutionFile)) + { + kernel.CurrentWorkingDirectory.Push(); + Helper.SetCurrentDir(Path.GetDirectoryName(solutionFile)); + + ss.WriteLine("Microsoft Visual Studio Solution File, Format Version {0}", SolutionVersion); + ss.WriteLine(SolutionTag); + + WriteProjectDeclarations(ss, solution, solution); + + ss.WriteLine("Global"); + + ss.WriteLine("\tGlobalSection(SolutionConfigurationPlatforms) = preSolution"); + foreach (ConfigurationNode conf in solution.Configurations) + { + ss.WriteLine("\t\t{0} = {0}", conf.NameAndPlatform); + } + ss.WriteLine("\tEndGlobalSection"); + + ss.WriteLine("\tGlobalSection(ProjectConfigurationPlatforms) = postSolution"); + WriteConfigurationLines(solution.Configurations, solution, ss); + ss.WriteLine("\tEndGlobalSection"); + + if (solution.Solutions.Count > 0) + { + ss.WriteLine("\tGlobalSection(NestedProjects) = preSolution"); + foreach (SolutionNode embeddedSolution in solution.Solutions) + { + WriteNestedProjectMap(ss, embeddedSolution); + } + ss.WriteLine("\tEndGlobalSection"); + } + + ss.WriteLine("EndGlobal"); + } + + kernel.CurrentWorkingDirectory.Pop(); + } + } + + private void WriteProjectDeclarations(TextWriter writer, SolutionNode actualSolution, SolutionNode embeddedSolution) + { + foreach (SolutionNode childSolution in embeddedSolution.Solutions) + { + WriteEmbeddedSolution(writer, childSolution); + WriteProjectDeclarations(writer, actualSolution, childSolution); + } + + foreach (ProjectNode project in embeddedSolution.Projects) + { + WriteProject(actualSolution, writer, project); + } + + foreach (DatabaseProjectNode dbProject in embeddedSolution.DatabaseProjects) + { + WriteProject(actualSolution, writer, dbProject); + } + + if (actualSolution.Guid == embeddedSolution.Guid) + { + WriteSolutionFiles(actualSolution, writer); + } + } + + private static void WriteNestedProjectMap(TextWriter writer, SolutionNode embeddedSolution) + { + foreach (ProjectNode project in embeddedSolution.Projects) + { + WriteNestedProject(writer, embeddedSolution, project.Guid); + } + + foreach (DatabaseProjectNode dbProject in embeddedSolution.DatabaseProjects) + { + WriteNestedProject(writer, embeddedSolution, dbProject.Guid); + } + + foreach (SolutionNode child in embeddedSolution.Solutions) + { + WriteNestedProject(writer, embeddedSolution, child.Guid); + WriteNestedProjectMap(writer, child); + } + } + + private static void WriteNestedProject(TextWriter writer, SolutionNode solution, Guid projectGuid) + { + WriteNestedFolder(writer, solution.Guid, projectGuid); + } + + private static void WriteNestedFolder(TextWriter writer, Guid parentGuid, Guid childGuid) + { + writer.WriteLine("\t\t{0} = {1}", + childGuid.ToString("B").ToUpper(), + parentGuid.ToString("B").ToUpper()); + } + + private static void WriteConfigurationLines(IEnumerable configurations, SolutionNode solution, TextWriter ss) + { + foreach (ProjectNode project in solution.Projects) + { + foreach (ConfigurationNode conf in configurations) + { + ss.WriteLine("\t\t{0}.{1}.ActiveCfg = {1}", + project.Guid.ToString("B").ToUpper(), + conf.NameAndPlatform); + + ss.WriteLine("\t\t{0}.{1}.Build.0 = {1}", + project.Guid.ToString("B").ToUpper(), + conf.NameAndPlatform); + } + } + + foreach (SolutionNode child in solution.Solutions) + { + WriteConfigurationLines(configurations, child, ss); + } + } + + private void WriteSolutionFiles(SolutionNode solution, TextWriter ss) + { + if(solution.Files != null && solution.Files.Count > 0) + WriteProject(ss, "Folder", solution.Guid, "Solution Files", "Solution Files", solution.Files); + } + + private void WriteEmbeddedSolution(TextWriter writer, SolutionNode embeddedSolution) + { + WriteProject(writer, "Folder", embeddedSolution.Guid, embeddedSolution.Name, embeddedSolution.Name, embeddedSolution.Files); + } + + private void WriteProject(SolutionNode solution, TextWriter ss, ProjectNode project) + { + WriteProject(ss, solution, project.Language, project.Guid, project.Name, project.FullPath); + } + + private void WriteProject(SolutionNode solution, TextWriter ss, DatabaseProjectNode dbProject) + { + if (solution.Files != null && solution.Files.Count > 0) + WriteProject(ss, solution, "Database", dbProject.Guid, dbProject.Name, dbProject.FullPath); + } + + const string ProjectDeclarationBeginFormat = "Project(\"{0}\") = \"{1}\", \"{2}\", \"{3}\""; + const string ProjectDeclarationEndFormat = "EndProject"; + + private void WriteProject(TextWriter ss, SolutionNode solution, string language, Guid guid, string name, string projectFullPath) + { + if (!tools.ContainsKey(language)) + throw new UnknownLanguageException("Unknown .NET language: " + language); + + ToolInfo toolInfo = tools[language]; + + string path = Helper.MakePathRelativeTo(solution.FullPath, projectFullPath); + + path = Helper.MakeFilePath(path, name, toolInfo.FileExtension); + + WriteProject(ss, language, guid, name, path); + } + + private void WriteProject(TextWriter writer, string language, Guid projectGuid, string name, string location) + { + WriteProject(writer, language, projectGuid, name, location, null); + } + + private void WriteProject(TextWriter writer, string language, Guid projectGuid, string name, string location, FilesNode files) + { + if (!tools.ContainsKey(language)) + throw new UnknownLanguageException("Unknown .NET language: " + language); + + ToolInfo toolInfo = tools[language]; + + writer.WriteLine(ProjectDeclarationBeginFormat, + toolInfo.Guid, + name, + location, + projectGuid.ToString("B").ToUpper()); + + if (files != null) + { + writer.WriteLine("\tProjectSection(SolutionItems) = preProject"); + + foreach (string file in files) + writer.WriteLine("\t\t{0} = {0}", file); + + writer.WriteLine("\tEndProjectSection"); + } + + writer.WriteLine(ProjectDeclarationEndFormat); + } + + private void WriteDatabaseProject(SolutionNode solution, DatabaseProjectNode project) + { + string projectFile = Helper.MakeFilePath(project.FullPath, project.Name, "dbp"); + IndentedTextWriter ps = new IndentedTextWriter(new StreamWriter(projectFile), " "); + + kernel.CurrentWorkingDirectory.Push(); + + Helper.SetCurrentDir(Path.GetDirectoryName(projectFile)); + + using (ps) + { + ps.WriteLine("# Microsoft Developer Studio Project File - Database Project"); + ps.WriteLine("Begin DataProject = \"{0}\"", project.Name); + ps.Indent++; + ps.WriteLine("MSDTVersion = \"80\""); + // TODO: Use the project.Files property + if (ContainsSqlFiles(Path.GetDirectoryName(projectFile))) + WriteDatabaseFoldersAndFiles(ps, Path.GetDirectoryName(projectFile)); + + ps.WriteLine("Begin DBRefFolder = \"Database References\""); + ps.Indent++; + foreach (DatabaseReferenceNode reference in project.References) + { + ps.WriteLine("Begin DBRefNode = \"{0}\"", reference.Name); + ps.Indent++; + ps.WriteLine("ConnectStr = \"{0}\"", reference.ConnectionString); + ps.WriteLine("Provider = \"{0}\"", reference.ProviderId.ToString("B").ToUpper()); + //ps.WriteLine("Colorizer = 5"); + ps.Indent--; + ps.WriteLine("End"); + } + ps.Indent--; + ps.WriteLine("End"); + ps.Indent--; + ps.WriteLine("End"); + + ps.Flush(); + } + + kernel.CurrentWorkingDirectory.Pop(); + } + + private static bool ContainsSqlFiles(string folder) + { + if(Directory.GetFiles(folder, "*.sql").Length > 0) + return true; // if the folder contains 1 .sql file, that's good enough + + foreach (string child in Directory.GetDirectories(folder)) + { + if (ContainsSqlFiles(child)) + return true; // if 1 child folder contains a .sql file, still good enough + } + + return false; + } + + private static void WriteDatabaseFoldersAndFiles(IndentedTextWriter writer, string folder) + { + foreach (string child in Directory.GetDirectories(folder)) + { + if (ContainsSqlFiles(child)) + { + writer.WriteLine("Begin Folder = \"{0}\"", Path.GetFileName(child)); + writer.Indent++; + WriteDatabaseFoldersAndFiles(writer, child); + writer.Indent--; + writer.WriteLine("End"); + } + } + foreach (string file in Directory.GetFiles(folder, "*.sql")) + { + writer.WriteLine("Script = \"{0}\"", Path.GetFileName(file)); + } + } + + private void CleanProject(ProjectNode project) + { + kernel.Log.Write("...Cleaning project: {0}", project.Name); + + ToolInfo toolInfo = tools[project.Language]; + string projectFile = Helper.MakeFilePath(project.FullPath, project.Name, toolInfo.FileExtension); + string userFile = projectFile + ".user"; + + Helper.DeleteIfExists(projectFile); + Helper.DeleteIfExists(userFile); + } + + private void CleanSolution(SolutionNode solution) + { + kernel.Log.Write("Cleaning {0} solution and project files", VersionName, solution.Name); + + string slnFile = Helper.MakeFilePath(solution.FullPath, solution.Name, "sln"); + string suoFile = Helper.MakeFilePath(solution.FullPath, solution.Name, "suo"); + + Helper.DeleteIfExists(slnFile); + Helper.DeleteIfExists(suoFile); + + foreach (ProjectNode project in solution.Projects) + { + CleanProject(project); + } + + kernel.Log.Write(""); + } + + #endregion + + #region ITarget Members + + /// + /// Writes the specified kern. + /// + /// The kern. + public virtual void Write(Kernel kern) + { + if (kern == null) + { + throw new ArgumentNullException("kern"); + } + kernel = kern; + foreach (SolutionNode sol in kernel.Solutions) + { + WriteSolution(sol, true); + } + kernel = null; + } + + /// + /// Cleans the specified kern. + /// + /// The kern. + public virtual void Clean(Kernel kern) + { + if (kern == null) + { + throw new ArgumentNullException("kern"); + } + kernel = kern; + foreach (SolutionNode sol in kernel.Solutions) + { + CleanSolution(sol); + } + kernel = null; + } + + #endregion + } } diff --git a/Prebuild/src/Core/Targets/VSVersion.cs b/Prebuild/src/Core/Targets/VSVersion.cs index a7434c677d..b917878bdc 100644 --- a/Prebuild/src/Core/Targets/VSVersion.cs +++ b/Prebuild/src/Core/Targets/VSVersion.cs @@ -5,16 +5,16 @@ Copyright (c) 2008-2009 Matthew Holmes (matthew@wildfiregames.com), Dan Moorehea Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: -* Redistributions of source code must retain the above copyright notice, this list of conditions - and the following disclaimer. -* Redistributions in binary form must reproduce the above copyright notice, this list of conditions - and the following disclaimer in the documentation and/or other materials provided with the - distribution. -* The name of the author may not be used to endorse or promote products derived from this software - without specific prior written permission. +* Redistributions of source code must retain the above copyright notice, this list of conditions + and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions + and the following disclaimer in the documentation and/or other materials provided with the + distribution. +* The name of the author may not be used to endorse or promote products derived from this software + without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, -BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY @@ -25,30 +25,43 @@ IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY O namespace Prebuild.Core.Targets { - /// - /// - /// - public enum VSVersion - { + /// + /// + /// + public enum VSVersion + { + /// + /// Visual Studio 2002 + /// + VS70, + /// + /// Visual Studio 2003 + /// + VS71, + /// + /// Visual Studio 2005 + /// + VS80, + /// + /// Visual Studio 2008 + /// + VS90, + /// + /// Visual Studio 2010 + /// + VS10, + /// + /// Visual Studio 2012 + /// + VS11, + /// + /// Visual Studio 2013 + /// + VS12, /// - /// Visual Studio 2002 + /// Visual Studio 2015 /// - VS70, - /// - /// Visual Studio 2003 - /// - VS71, - /// - /// Visual Studio 2005 - /// - VS80, - /// - /// Visual Studio 2008 - /// - VS90, - /// - /// Visual Studio 2010 - /// - VS10 - } + VS15 + + } } diff --git a/Prebuild/src/Core/Targets/XcodeTarget.cs b/Prebuild/src/Core/Targets/XcodeTarget.cs index d2c86a0d85..5393cec05f 100644 --- a/Prebuild/src/Core/Targets/XcodeTarget.cs +++ b/Prebuild/src/Core/Targets/XcodeTarget.cs @@ -5,16 +5,16 @@ Copyright (c) 2004 Matthew Holmes (matthew@wildfiregames.com), Dan Moorehead (da Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: -* Redistributions of source code must retain the above copyright notice, this list of conditions - and the following disclaimer. -* Redistributions in binary form must reproduce the above copyright notice, this list of conditions - and the following disclaimer in the documentation and/or other materials provided with the - distribution. -* The name of the author may not be used to endorse or promote products derived from this software - without specific prior written permission. +* Redistributions of source code must retain the above copyright notice, this list of conditions + and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions + and the following disclaimer in the documentation and/or other materials provided with the + distribution. +* The name of the author may not be used to endorse or promote products derived from this software + without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, -BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY @@ -36,7 +36,7 @@ using Prebuild.Core.Utilities; namespace Prebuild.Core.Targets { /// - /// + /// /// [Target("xcode")] public class XcodeTarget : ITarget @@ -282,7 +282,7 @@ namespace Prebuild.Core.Targets } //if (project.Files.GetSubType(file).ToString() != "Code") //{ - // ps.WriteLine(" ", file.Substring(0, file.LastIndexOf('.')) + ".resx"); + // ps.WriteLine(" ", file.Substring(0, file.LastIndexOf('.')) + ".resx"); ss.WriteLine(" "); ss.WriteLine(" "); diff --git a/Prebuild/src/Core/UnknownLanguageException.cs b/Prebuild/src/Core/UnknownLanguageException.cs index 71fc885699..607b66c022 100644 --- a/Prebuild/src/Core/UnknownLanguageException.cs +++ b/Prebuild/src/Core/UnknownLanguageException.cs @@ -6,12 +6,12 @@ * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA @@ -20,44 +20,44 @@ using System; using System.Runtime.Serialization; -namespace Prebuild.Core +namespace Prebuild.Core { - /// - /// - [Serializable()] - public class UnknownLanguageException : Exception - { - /// - /// Basic exception. - /// - public UnknownLanguageException() - { - } + /// + /// + [Serializable()] + public class UnknownLanguageException : Exception + { + /// + /// Basic exception. + /// + public UnknownLanguageException() + { + } - /// - /// Exception with specified string - /// - /// Exception message - public UnknownLanguageException(string message): base(message) - { - } + /// + /// Exception with specified string + /// + /// Exception message + public UnknownLanguageException(string message): base(message) + { + } - /// - /// - /// - /// - /// - public UnknownLanguageException(string message, Exception exception) : base(message, exception) - { - } + /// + /// + /// + /// + /// + public UnknownLanguageException(string message, Exception exception) : base(message, exception) + { + } - /// - /// - /// - /// - /// - protected UnknownLanguageException(SerializationInfo info, StreamingContext context) : base( info, context ) - { - } - } + /// + /// + /// + /// + /// + protected UnknownLanguageException(SerializationInfo info, StreamingContext context) : base( info, context ) + { + } + } } diff --git a/Prebuild/src/Core/Utilities/CommandLineCollection.cs b/Prebuild/src/Core/Utilities/CommandLineCollection.cs index 5e6facedbe..786fa1e49d 100644 --- a/Prebuild/src/Core/Utilities/CommandLineCollection.cs +++ b/Prebuild/src/Core/Utilities/CommandLineCollection.cs @@ -5,16 +5,16 @@ Copyright (c) 2004-2005 Matthew Holmes (matthew@wildfiregames.com), Dan Moorehea Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: -* Redistributions of source code must retain the above copyright notice, this list of conditions - and the following disclaimer. -* Redistributions in binary form must reproduce the above copyright notice, this list of conditions - and the following disclaimer in the documentation and/or other materials provided with the - distribution. -* The name of the author may not be used to endorse or promote products derived from this software - without specific prior written permission. +* Redistributions of source code must retain the above copyright notice, this list of conditions + and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions + and the following disclaimer in the documentation and/or other materials provided with the + distribution. +* The name of the author may not be used to endorse or promote products derived from this software + without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, -BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY @@ -27,126 +27,126 @@ using System.Collections; using System.Collections.Generic; namespace Prebuild.Core.Utilities -{ - /// - /// The CommandLine class parses and interprets the command-line arguments passed to - /// prebuild. - /// - public class CommandLineCollection : IEnumerable> - { - #region Fields +{ + /// + /// The CommandLine class parses and interprets the command-line arguments passed to + /// prebuild. + /// + public class CommandLineCollection : IEnumerable> + { + #region Fields - // The raw OS arguments - private readonly string[] m_RawArgs; + // The raw OS arguments + private readonly string[] m_RawArgs; - // Command-line argument storage - private readonly Dictionary m_Arguments = new Dictionary(); + // Command-line argument storage + private readonly Dictionary m_Arguments = new Dictionary(); + + #endregion + + #region Constructors + + /// + /// Create a new CommandLine instance and set some internal variables. + /// + public CommandLineCollection(string[] args) + { + m_RawArgs = args; + + Parse(); + } - #endregion + #endregion - #region Constructors + #region Private Methods - /// - /// Create a new CommandLine instance and set some internal variables. - /// - public CommandLineCollection(string[] args) - { - m_RawArgs = args; + private void Parse() + { + if(m_RawArgs.Length < 1) + return; - Parse(); - } - - #endregion - - #region Private Methods - - private void Parse() - { - if(m_RawArgs.Length < 1) - return; - - int idx = 0; + int idx = 0; string lastArg = null; - while(idx 2 && arg[0] == '/') - { - arg = arg.Substring(1); - lastArg = arg; - m_Arguments[arg] = ""; - } - else - { - if(lastArg != null) - { - m_Arguments[lastArg] = arg; - lastArg = null; - } - } + if(arg.Length > 2 && arg[0] == '/') + { + arg = arg.Substring(1); + lastArg = arg; + m_Arguments[arg] = ""; + } + else + { + if(lastArg != null) + { + m_Arguments[lastArg] = arg; + lastArg = null; + } + } - idx++; - } - } + idx++; + } + } - #endregion + #endregion - #region Public Methods + #region Public Methods - /// - /// Wases the passed. - /// - /// The arg. - /// - public bool WasPassed(string arg) - { - return (m_Arguments.ContainsKey(arg)); - } + /// + /// Wases the passed. + /// + /// The arg. + /// + public bool WasPassed(string arg) + { + return (m_Arguments.ContainsKey(arg)); + } - #endregion + #endregion - #region Properties + #region Properties - /// - /// Gets the parameter associated with the command line option - /// - /// Returns null if option was not specified, - /// null string if no parameter was specified, and the value if a parameter was specified - public string this[string index] - { - get - { - if(m_Arguments.ContainsKey(index)) - { - return (m_Arguments[index]); - } - return null; - } - } + /// + /// Gets the parameter associated with the command line option + /// + /// Returns null if option was not specified, + /// null string if no parameter was specified, and the value if a parameter was specified + public string this[string index] + { + get + { + if(m_Arguments.ContainsKey(index)) + { + return (m_Arguments[index]); + } + return null; + } + } - #endregion + #endregion - #region IEnumerable Members + #region IEnumerable Members - /// - /// Returns an enumerator that can iterate through a collection. - /// - /// - /// An - /// that can be used to iterate through the collection. - /// + /// + /// Returns an enumerator that can iterate through a collection. + /// + /// + /// An + /// that can be used to iterate through the collection. + /// public IEnumerator> GetEnumerator() - { - return m_Arguments.GetEnumerator(); - } + { + return m_Arguments.GetEnumerator(); + } - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } - #endregion - } + #endregion + } } diff --git a/Prebuild/src/Core/Utilities/CurrentDirectory.cs b/Prebuild/src/Core/Utilities/CurrentDirectory.cs index d743d83cd9..9624c35ed5 100644 --- a/Prebuild/src/Core/Utilities/CurrentDirectory.cs +++ b/Prebuild/src/Core/Utilities/CurrentDirectory.cs @@ -5,16 +5,16 @@ Copyright (c) 2004-2005 Matthew Holmes (matthew@wildfiregames.com), Dan Moorehea Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: -* Redistributions of source code must retain the above copyright notice, this list of conditions - and the following disclaimer. -* Redistributions in binary form must reproduce the above copyright notice, this list of conditions - and the following disclaimer in the documentation and/or other materials provided with the - distribution. -* The name of the author may not be used to endorse or promote products derived from this software - without specific prior written permission. +* Redistributions of source code must retain the above copyright notice, this list of conditions + and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions + and the following disclaimer in the documentation and/or other materials provided with the + distribution. +* The name of the author may not be used to endorse or promote products derived from this software + without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, -BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY @@ -28,41 +28,41 @@ using System.Collections.Generic; namespace Prebuild.Core.Utilities { - /// - /// - /// - public class CurrentDirectory - { - #region Fields + /// + /// + /// + public class CurrentDirectory + { + #region Fields - private readonly Stack m_Stack = new Stack(); + private readonly Stack m_Stack = new Stack(); - #endregion + #endregion - #region Public Methods + #region Public Methods - /// - /// Pushes this instance. - /// - public void Push() - { - m_Stack.Push(Environment.CurrentDirectory); - } + /// + /// Pushes this instance. + /// + public void Push() + { + m_Stack.Push(Environment.CurrentDirectory); + } - /// - /// Pops this instance. - /// - public void Pop() - { - if(m_Stack.Count < 1) - { - return; - } + /// + /// Pops this instance. + /// + public void Pop() + { + if(m_Stack.Count < 1) + { + return; + } + + string cwd = m_Stack.Pop(); + Helper.SetCurrentDir(cwd); + } - string cwd = m_Stack.Pop(); - Helper.SetCurrentDir(cwd); - } - - #endregion - } + #endregion + } } diff --git a/Prebuild/src/Core/Utilities/Helper.cs b/Prebuild/src/Core/Utilities/Helper.cs index a440e581df..85333407c1 100644 --- a/Prebuild/src/Core/Utilities/Helper.cs +++ b/Prebuild/src/Core/Utilities/Helper.cs @@ -5,16 +5,16 @@ Copyright (c) 2004-2005 Matthew Holmes (matthew@wildfiregames.com), Dan Moorehea Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: -* Redistributions of source code must retain the above copyright notice, this list of conditions - and the following disclaimer. -* Redistributions in binary form must reproduce the above copyright notice, this list of conditions - and the following disclaimer in the documentation and/or other materials provided with the - distribution. -* The name of the author may not be used to endorse or promote products derived from this software - without specific prior written permission. +* Redistributions of source code must retain the above copyright notice, this list of conditions + and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions + and the following disclaimer in the documentation and/or other materials provided with the + distribution. +* The name of the author may not be used to endorse or promote products derived from this software + without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, -BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY @@ -35,541 +35,541 @@ using Prebuild.Core.Nodes; namespace Prebuild.Core.Utilities { - /// - /// - /// - public class Helper - { - #region Fields + /// + /// + /// + public class Helper + { + #region Fields - static bool checkForOSVariables; + static bool checkForOSVariables; - /// - /// - /// - public static bool CheckForOSVariables - { - get - { - return checkForOSVariables; - } - set - { - checkForOSVariables = value; - } - } + /// + /// + /// + public static bool CheckForOSVariables + { + get + { + return checkForOSVariables; + } + set + { + checkForOSVariables = value; + } + } - #endregion + #endregion + + #region Public Methods - #region Public Methods + #region String Parsing - #region String Parsing + public delegate string StringLookup(string key); - public delegate string StringLookup(string key); + /// + /// Gets a collection of StringLocationPair objects that represent the matches + /// + /// The target. + /// The before group. + /// The after group. + /// if set to true [include delimiters in substrings]. + /// + public static StringCollection FindGroups(string target, string beforeGroup, string afterGroup, bool includeDelimitersInSubstrings) + { + if( beforeGroup == null ) + { + throw new ArgumentNullException("beforeGroup"); + } + if( afterGroup == null ) + { + throw new ArgumentNullException("afterGroup"); + } + StringCollection results = new StringCollection(); + if(target == null || target.Length == 0) + { + return results; + } - /// - /// Gets a collection of StringLocationPair objects that represent the matches - /// - /// The target. - /// The before group. - /// The after group. - /// if set to true [include delimiters in substrings]. - /// - public static StringCollection FindGroups(string target, string beforeGroup, string afterGroup, bool includeDelimitersInSubstrings) - { - if( beforeGroup == null ) - { - throw new ArgumentNullException("beforeGroup"); - } - if( afterGroup == null ) - { - throw new ArgumentNullException("afterGroup"); - } - StringCollection results = new StringCollection(); - if(target == null || target.Length == 0) - { - return results; - } + int beforeMod = 0; + int afterMod = 0; + if(includeDelimitersInSubstrings) + { + //be sure to not exlude the delims + beforeMod = beforeGroup.Length; + afterMod = afterGroup.Length; + } + int startIndex = 0; + while((startIndex = target.IndexOf(beforeGroup,startIndex)) != -1) { + int endIndex = target.IndexOf(afterGroup,startIndex);//the index of the char after it + if(endIndex == -1) + { + break; + } + int length = endIndex - startIndex - beforeGroup.Length;//move to the first char in the string + string substring = target.Substring(startIndex + beforeGroup.Length - beforeMod, + length - afterMod); - int beforeMod = 0; - int afterMod = 0; - if(includeDelimitersInSubstrings) - { - //be sure to not exlude the delims - beforeMod = beforeGroup.Length; - afterMod = afterGroup.Length; - } - int startIndex = 0; - while((startIndex = target.IndexOf(beforeGroup,startIndex)) != -1) { - int endIndex = target.IndexOf(afterGroup,startIndex);//the index of the char after it - if(endIndex == -1) - { - break; - } - int length = endIndex - startIndex - beforeGroup.Length;//move to the first char in the string - string substring = substring = target.Substring(startIndex + beforeGroup.Length - beforeMod, - length - afterMod); + results.Add(substring); + //results.Add(new StringLocationPair(substring,startIndex)); + startIndex = endIndex + 1; + //the Interpolate*() methods will not work if expressions are expandded inside expression due to an optimization + //so start after endIndex + + } + return results; + } - results.Add(substring); - //results.Add(new StringLocationPair(substring,startIndex)); - startIndex = endIndex + 1; - //the Interpolate*() methods will not work if expressions are expandded inside expression due to an optimization - //so start after endIndex + /// + /// Replaces the groups. + /// + /// The target. + /// The before group. + /// The after group. + /// The lookup. + /// + public static string ReplaceGroups(string target, string beforeGroup, string afterGroup, StringLookup lookup) { + if( target == null ) + { + throw new ArgumentNullException("target"); + } + //int targetLength = target.Length; + StringCollection strings = FindGroups(target,beforeGroup,afterGroup,false); + if( lookup == null ) + { + throw new ArgumentNullException("lookup"); + } + foreach(string substring in strings) + { + target = target.Replace(beforeGroup + substring + afterGroup, lookup(substring) ); + } + return target; + } - } - return results; - } + /// + /// Replaces ${var} statements in a string with the corresonding values as detirmined by the lookup delegate + /// + /// The target. + /// The lookup. + /// + public static string InterpolateForVariables(string target, StringLookup lookup) + { + return ReplaceGroups(target, "${" , "}" , lookup); + } - /// - /// Replaces the groups. - /// - /// The target. - /// The before group. - /// The after group. - /// The lookup. - /// - public static string ReplaceGroups(string target, string beforeGroup, string afterGroup, StringLookup lookup) { - if( target == null ) - { - throw new ArgumentNullException("target"); - } - //int targetLength = target.Length; - StringCollection strings = FindGroups(target,beforeGroup,afterGroup,false); - if( lookup == null ) - { - throw new ArgumentNullException("lookup"); - } - foreach(string substring in strings) - { - target = target.Replace(beforeGroup + substring + afterGroup, lookup(substring) ); - } - return target; - } + /// + /// Replaces ${var} statements in a string with the corresonding environment variable with name var + /// + /// + /// + public static string InterpolateForEnvironmentVariables(string target) + { + return InterpolateForVariables(target, new StringLookup(Environment.GetEnvironmentVariable)); + } - /// - /// Replaces ${var} statements in a string with the corresonding values as detirmined by the lookup delegate - /// - /// The target. - /// The lookup. - /// - public static string InterpolateForVariables(string target, StringLookup lookup) - { - return ReplaceGroups(target, "${" , "}" , lookup); - } + #endregion - /// - /// Replaces ${var} statements in a string with the corresonding environment variable with name var - /// - /// - /// - public static string InterpolateForEnvironmentVariables(string target) - { - return InterpolateForVariables(target, new StringLookup(Environment.GetEnvironmentVariable)); - } + /// + /// Translates the value. + /// + /// Type of the translate. + /// The translation item. + /// + public static object TranslateValue(Type translateType, string translationItem) + { + if(translationItem == null) + { + return null; + } - #endregion + try + { + string lowerVal = translationItem.ToLower(); + if(translateType == typeof(bool)) + { + return (lowerVal == "true" || lowerVal == "1" || lowerVal == "y" || lowerVal == "yes" || lowerVal == "on"); + } + else if(translateType == typeof(int)) + { + return (Int32.Parse(translationItem)); + } + else + { + return translationItem; + } + } + catch(FormatException) + { + return null; + } + } - /// - /// Translates the value. - /// - /// Type of the translate. - /// The translation item. - /// - public static object TranslateValue(Type translateType, string translationItem) - { - if(translationItem == null) - { - return null; - } + /// + /// Deletes if exists. + /// + /// The file. + /// + public static bool DeleteIfExists(string file) + { + string resFile = null; + try + { + resFile = ResolvePath(file); + } + catch(ArgumentException) + { + return false; + } - try - { - string lowerVal = translationItem.ToLower(); - if(translateType == typeof(bool)) - { - return (lowerVal == "true" || lowerVal == "1" || lowerVal == "y" || lowerVal == "yes" || lowerVal == "on"); - } - else if(translateType == typeof(int)) - { - return (Int32.Parse(translationItem)); - } - else - { - return translationItem; - } - } - catch(FormatException) - { - return null; - } - } + if(!File.Exists(resFile)) + { + return false; + } - /// - /// Deletes if exists. - /// - /// The file. - /// - public static bool DeleteIfExists(string file) - { - string resFile = null; - try - { - resFile = ResolvePath(file); - } - catch(ArgumentException) - { - return false; - } - - if(!File.Exists(resFile)) - { - return false; - } - - File.Delete(resFile); - return true; - } + File.Delete(resFile); + return true; + } static readonly char seperator = Path.DirectorySeparatorChar; - // This little gem was taken from the NeL source, thanks guys! - /// - /// Makes a relative path - /// - /// Path to start from - /// Path to end at - /// Path that will get from startPath to endPath - public static string MakePathRelativeTo(string startPath, string endPath) - { - string tmp = NormalizePath(startPath, seperator); - string src = NormalizePath(endPath, seperator); - string prefix = ""; + // This little gem was taken from the NeL source, thanks guys! + /// + /// Makes a relative path + /// + /// Path to start from + /// Path to end at + /// Path that will get from startPath to endPath + public static string MakePathRelativeTo(string startPath, string endPath) + { + string tmp = NormalizePath(startPath, seperator); + string src = NormalizePath(endPath, seperator); + string prefix = ""; - while(true) - { - if((String.Compare(tmp, 0, src, 0, tmp.Length) == 0)) - { - string ret; - int size = tmp.Length; - if(size == src.Length) - { - return "./"; - } + while(true) + { + if((String.Compare(tmp, 0, src, 0, tmp.Length) == 0)) + { + string ret; + int size = tmp.Length; + if(size == src.Length) + { + return "./"; + } if((src.Length > tmp.Length) && src[tmp.Length - 1] != seperator) - { - } - else - { - ret = prefix + endPath.Substring(size, endPath.Length - size); - ret = ret.Trim(); + { + } + else + { + ret = prefix + endPath.Substring(size, endPath.Length - size); + ret = ret.Trim(); if(ret[0] == seperator) - { - ret = "." + ret; - } + { + ret = "." + ret; + } - return NormalizePath(ret); - } + return NormalizePath(ret); + } + + } - } - - if(tmp.Length < 2) - { - break; - } + if(tmp.Length < 2) + { + break; + } int lastPos = tmp.LastIndexOf(seperator, tmp.Length - 2); int prevPos = tmp.IndexOf(seperator); - if((lastPos == prevPos) || (lastPos == -1)) - { - break; - } + if((lastPos == prevPos) || (lastPos == -1)) + { + break; + } - tmp = tmp.Substring(0, lastPos + 1); - prefix += ".." + seperator.ToString(); - } + tmp = tmp.Substring(0, lastPos + 1); + prefix += ".." + seperator.ToString(); + } - return endPath; - } + return endPath; + } - /// - /// Resolves the path. - /// - /// The path. - /// - public static string ResolvePath(string path) - { - string tmpPath = NormalizePath(path); - if(tmpPath.Length < 1) - { - tmpPath = "."; - } + /// + /// Resolves the path. + /// + /// The path. + /// + public static string ResolvePath(string path) + { + string tmpPath = NormalizePath(path); + if(tmpPath.Length < 1) + { + tmpPath = "."; + } + + tmpPath = Path.GetFullPath(tmpPath); + if(!File.Exists(tmpPath) && !Directory.Exists(tmpPath)) + { + throw new ArgumentException("Path could not be resolved: " + tmpPath); + } - tmpPath = Path.GetFullPath(tmpPath); - if(!File.Exists(tmpPath) && !Directory.Exists(tmpPath)) - { - throw new ArgumentException("Path could not be resolved: " + tmpPath); - } + return tmpPath; + } - return tmpPath; - } + /// + /// Normalizes the path. + /// + /// The path. + /// The separator character. + /// + public static string NormalizePath(string path, char separatorCharacter) + { + if(path == null || path == "" || path.Length < 1) + { + return ""; + } - /// - /// Normalizes the path. - /// - /// The path. - /// The separator character. - /// - public static string NormalizePath(string path, char separatorCharacter) - { - if(path == null || path == "" || path.Length < 1) - { - return ""; - } + string tmpPath = path.Replace('\\', '/'); + tmpPath = tmpPath.Replace('/', separatorCharacter); + return tmpPath; + } - string tmpPath = path.Replace('\\', '/'); - tmpPath = tmpPath.Replace('/', separatorCharacter); - return tmpPath; - } + /// + /// Normalizes the path. + /// + /// The path. + /// + public static string NormalizePath(string path) + { + return NormalizePath(path, Path.DirectorySeparatorChar); + } + + /// + /// Ends the path. + /// + /// The path. + /// The separator character. + /// + public static string EndPath(string path, char separatorCharacter) + { + if(path == null || path == "" || path.Length < 1) + { + return ""; + } - /// - /// Normalizes the path. - /// - /// The path. - /// - public static string NormalizePath(string path) - { - return NormalizePath(path, Path.DirectorySeparatorChar); - } + if(!path.EndsWith(separatorCharacter.ToString())) + { + return (path + separatorCharacter); + } - /// - /// Ends the path. - /// - /// The path. - /// The separator character. - /// - public static string EndPath(string path, char separatorCharacter) - { - if(path == null || path == "" || path.Length < 1) - { - return ""; - } + return path; + } - if(!path.EndsWith(separatorCharacter.ToString())) - { - return (path + separatorCharacter); - } + /// + /// Ends the path. + /// + /// The path. + /// + public static string EndPath(string path) + { + return EndPath(path, Path.DirectorySeparatorChar); + } - return path; - } - - /// - /// Ends the path. - /// - /// The path. - /// - public static string EndPath(string path) - { - return EndPath(path, Path.DirectorySeparatorChar); - } - - /// - /// Makes the file path. - /// - /// The path. - /// The name. - /// The ext. - /// - public static string MakeFilePath(string path, string name, string ext) - { - string ret = EndPath(NormalizePath(path)); - - if( name == null ) - { - throw new ArgumentNullException("name"); - } - - ret += name; - if(!name.EndsWith("." + ext)) - { - ret += "." + ext; - } + /// + /// Makes the file path. + /// + /// The path. + /// The name. + /// The ext. + /// + public static string MakeFilePath(string path, string name, string ext) + { + string ret = EndPath(NormalizePath(path)); + + if( name == null ) + { + throw new ArgumentNullException("name"); + } + ret += name; + if(!name.EndsWith("." + ext)) + { + ret += "." + ext; + } + //foreach(char c in Path.GetInvalidPathChars()) //{ // ret = ret.Replace(c, '_'); //} - return ret; - } + return ret; + } - /// - /// Makes the file path. - /// - /// The path. - /// The name. - /// - public static string MakeFilePath(string path, string name) - { - string ret = EndPath(NormalizePath(path)); + /// + /// Makes the file path. + /// + /// The path. + /// The name. + /// + public static string MakeFilePath(string path, string name) + { + string ret = EndPath(NormalizePath(path)); + + if( name == null ) + { + throw new ArgumentNullException("name"); + } - if( name == null ) - { - throw new ArgumentNullException("name"); - } - - ret += name; + ret += name; //foreach (char c in Path.GetInvalidPathChars()) //{ // ret = ret.Replace(c, '_'); //} - return ret; - } + return ret; + } - /// - /// - /// - /// - /// - public static string MakeReferencePath(string path) - { - string ret = EndPath(NormalizePath(path)); + /// + /// + /// + /// + /// + public static string MakeReferencePath(string path) + { + string ret = EndPath(NormalizePath(path)); //foreach (char c in Path.GetInvalidPathChars()) //{ // ret = ret.Replace(c, '_'); //} - return ret; - } + return ret; + } - /// - /// Sets the current dir. - /// - /// The path. - public static void SetCurrentDir(string path) - { - if( path == null ) - { - throw new ArgumentNullException("path"); - } - if(path.Length < 1) - { - return; - } + /// + /// Sets the current dir. + /// + /// The path. + public static void SetCurrentDir(string path) + { + if( path == null ) + { + throw new ArgumentNullException("path"); + } + if(path.Length < 1) + { + return; + } - Environment.CurrentDirectory = path; - } + Environment.CurrentDirectory = path; + } - /// - /// Checks the type. - /// - /// The type to check. - /// The attr. - /// The inter. - /// - public static object CheckType(Type typeToCheck, Type attr, Type inter) - { - if(typeToCheck == null || attr == null) - { - return null; - } + /// + /// Checks the type. + /// + /// The type to check. + /// The attr. + /// The inter. + /// + public static object CheckType(Type typeToCheck, Type attr, Type inter) + { + if(typeToCheck == null || attr == null) + { + return null; + } - object[] attrs = typeToCheck.GetCustomAttributes(attr, false); - if(attrs == null || attrs.Length < 1) - { - return null; - } - if( inter == null ) - { - throw new ArgumentNullException("inter"); - } + object[] attrs = typeToCheck.GetCustomAttributes(attr, false); + if(attrs == null || attrs.Length < 1) + { + return null; + } + if( inter == null ) + { + throw new ArgumentNullException("inter"); + } - if(typeToCheck.GetInterface(inter.FullName) == null) - { - return null; - } + if(typeToCheck.GetInterface(inter.FullName) == null) + { + return null; + } - return attrs[0]; - } + return attrs[0]; + } - /// - /// Attributes the value. - /// - /// The node. - /// The attr. - /// The def. - /// - public static string AttributeValue(XmlNode node, string attr, string def) - { - if( node == null ) - { - throw new ArgumentNullException("node"); - } - if(node.Attributes[attr] == null) - { - return def; - } - string val = node.Attributes[attr].Value; - if(!CheckForOSVariables) - { - return val; - } + /// + /// Attributes the value. + /// + /// The node. + /// The attr. + /// The def. + /// + public static string AttributeValue(XmlNode node, string attr, string def) + { + if( node == null ) + { + throw new ArgumentNullException("node"); + } + if(node.Attributes[attr] == null) + { + return def; + } + string val = node.Attributes[attr].Value; + if(!CheckForOSVariables) + { + return val; + } - return InterpolateForEnvironmentVariables(val); - } + return InterpolateForEnvironmentVariables(val); + } - /// - /// Parses the boolean. - /// - /// The node. - /// The attr. - /// if set to true [default value]. - /// - public static bool ParseBoolean(XmlNode node, string attr, bool defaultValue) - { - if( node == null ) - { - throw new ArgumentNullException("node"); - } - if(node.Attributes[attr] == null) - { - return defaultValue; - } - return bool.Parse(node.Attributes[attr].Value); - } + /// + /// Parses the boolean. + /// + /// The node. + /// The attr. + /// if set to true [default value]. + /// + public static bool ParseBoolean(XmlNode node, string attr, bool defaultValue) + { + if( node == null ) + { + throw new ArgumentNullException("node"); + } + if(node.Attributes[attr] == null) + { + return defaultValue; + } + return bool.Parse(node.Attributes[attr].Value); + } - /// - /// Enums the attribute value. - /// - /// The node. - /// The attr. - /// Type of the enum. - /// The def. - /// - public static object EnumAttributeValue(XmlNode node, string attr, Type enumType, object def) - { - if( def == null ) - { - throw new ArgumentNullException("def"); - } - string val = AttributeValue(node, attr, def.ToString()); - return Enum.Parse(enumType, val, true); - } + /// + /// Enums the attribute value. + /// + /// The node. + /// The attr. + /// Type of the enum. + /// The def. + /// + public static object EnumAttributeValue(XmlNode node, string attr, Type enumType, object def) + { + if( def == null ) + { + throw new ArgumentNullException("def"); + } + string val = AttributeValue(node, attr, def.ToString()); + return Enum.Parse(enumType, val, true); + } - /// - /// - /// - /// - /// - /// - public static string AssemblyFullName(string assemblyName, ProjectType projectType) - { - return assemblyName + (projectType == ProjectType.Library ? ".dll" : ".exe"); - } + /// + /// + /// + /// + /// + /// + public static string AssemblyFullName(string assemblyName, ProjectType projectType) + { + return assemblyName + (projectType == ProjectType.Library ? ".dll" : ".exe"); + } - #endregion - } + #endregion + } } diff --git a/Prebuild/src/Core/Utilities/Log.cs b/Prebuild/src/Core/Utilities/Log.cs index cd9563310a..4df3defdd0 100644 --- a/Prebuild/src/Core/Utilities/Log.cs +++ b/Prebuild/src/Core/Utilities/Log.cs @@ -5,16 +5,16 @@ Copyright (c) 2004-2005 Matthew Holmes (matthew@wildfiregames.com), Dan Moorehea Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: -* Redistributions of source code must retain the above copyright notice, this list of conditions - and the following disclaimer. -* Redistributions in binary form must reproduce the above copyright notice, this list of conditions - and the following disclaimer in the documentation and/or other materials provided with the - distribution. -* The name of the author may not be used to endorse or promote products derived from this software - without specific prior written permission. +* Redistributions of source code must retain the above copyright notice, this list of conditions + and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions + and the following disclaimer in the documentation and/or other materials provided with the + distribution. +* The name of the author may not be used to endorse or promote products derived from this software + without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, -BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY @@ -28,74 +28,74 @@ using System.IO; namespace Prebuild.Core.Utilities { - /// - /// - /// - public enum LogType - { - /// - /// - /// - None, - /// - /// - /// - Info, - /// - /// - /// - Warning, - /// - /// - /// - Error - } + /// + /// + /// + public enum LogType + { + /// + /// + /// + None, + /// + /// + /// + Info, + /// + /// + /// + Warning, + /// + /// + /// + Error + } - /// - /// - /// - [Flags] - public enum LogTargets - { - /// - /// - /// - None = 0, - /// - /// - /// - Null = 1, - /// - /// - /// - File = 2, - /// - /// - /// - Console = 4 - } + /// + /// + /// + [Flags] + public enum LogTargets + { + /// + /// + /// + None = 0, + /// + /// + /// + Null = 1, + /// + /// + /// + File = 2, + /// + /// + /// + Console = 4 + } - /// - /// Summary description for Log. - /// - public class Log : IDisposable - { - #region Fields + /// + /// Summary description for Log. + /// + public class Log : IDisposable + { + #region Fields - private TextWriter m_Writer; - private LogTargets m_Target = LogTargets.Null; - bool disposed; + private TextWriter m_Writer; + private LogTargets m_Target = LogTargets.Null; + bool disposed; - #endregion + #endregion - #region Constructors + #region Constructors - /// - /// Initializes a new instance of the class. - /// - /// The target. - /// Name of the file. - public Log(LogTargets target, string fileName) + /// + /// Initializes a new instance of the class. + /// + /// The target. + /// Name of the file. + public Log(LogTargets target, string fileName) { m_Target = target; @@ -111,166 +111,166 @@ namespace Prebuild.Core.Utilities } } - #endregion + #endregion - #region Public Methods + #region Public Methods - /// - /// Writes this instance. - /// - public void Write() - { - Write(string.Empty); - } + /// + /// Writes this instance. + /// + public void Write() + { + Write(string.Empty); + } - /// - /// Writes the specified MSG. - /// - /// The MSG. - public void Write(string msg) - { - if((m_Target & LogTargets.Null) != 0) - { - return; - } + /// + /// Writes the specified MSG. + /// + /// The MSG. + public void Write(string msg) + { + if((m_Target & LogTargets.Null) != 0) + { + return; + } - if((m_Target & LogTargets.Console) != 0) - { - Console.WriteLine(msg); - } - if((m_Target & LogTargets.File) != 0 && m_Writer != null) - { - m_Writer.WriteLine(msg); - } - } + if((m_Target & LogTargets.Console) != 0) + { + Console.WriteLine(msg); + } + if((m_Target & LogTargets.File) != 0 && m_Writer != null) + { + m_Writer.WriteLine(msg); + } + } - /// - /// Writes the specified format. - /// - /// The format. - /// The args. - public void Write(string format, params object[] args) - { - Write(string.Format(format,args)); - } + /// + /// Writes the specified format. + /// + /// The format. + /// The args. + public void Write(string format, params object[] args) + { + Write(string.Format(format,args)); + } - /// - /// Writes the specified type. - /// - /// The type. - /// The format. - /// The args. - public void Write(LogType type, string format, params object[] args) - { - if((m_Target & LogTargets.Null) != 0) - { - return; - } + /// + /// Writes the specified type. + /// + /// The type. + /// The format. + /// The args. + public void Write(LogType type, string format, params object[] args) + { + if((m_Target & LogTargets.Null) != 0) + { + return; + } - string str = ""; - switch(type) - { - case LogType.Info: - str = "[I] "; - break; - case LogType.Warning: - str = "[!] "; - break; - case LogType.Error: - str = "[X] "; - break; - } + string str = ""; + switch(type) + { + case LogType.Info: + str = "[I] "; + break; + case LogType.Warning: + str = "[!] "; + break; + case LogType.Error: + str = "[X] "; + break; + } - Write(str + format,args); - } + Write(str + format,args); + } - /// - /// Writes the exception. - /// - /// The type. - /// The ex. - public void WriteException(LogType type, Exception ex) - { - if(ex != null) - { - Write(type, ex.Message); - //#if DEBUG - m_Writer.WriteLine("Exception @{0} stack trace [[", ex.TargetSite.Name); - m_Writer.WriteLine(ex.StackTrace); - m_Writer.WriteLine("]]"); - //#endif - } - } + /// + /// Writes the exception. + /// + /// The type. + /// The ex. + public void WriteException(LogType type, Exception ex) + { + if(ex != null) + { + Write(type, ex.Message); + //#if DEBUG + m_Writer.WriteLine("Exception @{0} stack trace [[", ex.TargetSite.Name); + m_Writer.WriteLine(ex.StackTrace); + m_Writer.WriteLine("]]"); + //#endif + } + } - /// - /// Flushes this instance. - /// - public void Flush() - { - if(m_Writer != null) - { - m_Writer.Flush(); - } - } + /// + /// Flushes this instance. + /// + public void Flush() + { + if(m_Writer != null) + { + m_Writer.Flush(); + } + } - #endregion + #endregion - #region IDisposable Members + #region IDisposable Members - /// - /// Performs application-defined tasks associated with freeing, releasing, or - /// resetting unmanaged resources. - /// - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } + /// + /// Performs application-defined tasks associated with freeing, releasing, or + /// resetting unmanaged resources. + /// + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } - /// - /// Dispose objects - /// - /// - /// If true, it will dispose close the handle - /// - /// - /// Will dispose managed and unmanaged resources. - /// - protected virtual void Dispose(bool disposing) - { - if (!this.disposed) - { - if (disposing) - { - if (m_Writer != null) - { - m_Writer.Close(); - m_Writer = null; - } - } - } - this.disposed = true; - } + /// + /// Dispose objects + /// + /// + /// If true, it will dispose close the handle + /// + /// + /// Will dispose managed and unmanaged resources. + /// + protected virtual void Dispose(bool disposing) + { + if (!this.disposed) + { + if (disposing) + { + if (m_Writer != null) + { + m_Writer.Close(); + m_Writer = null; + } + } + } + this.disposed = true; + } - /// - /// - /// - ~Log() - { - this.Dispose(false); - } + /// + /// + /// + ~Log() + { + this.Dispose(false); + } + + /// + /// Closes and destroys this object + /// + /// + /// Same as Dispose(true) + /// + public void Close() + { + Dispose(); + } - /// - /// Closes and destroys this object - /// - /// - /// Same as Dispose(true) - /// - public void Close() - { - Dispose(); - } - - #endregion - } + #endregion + } } diff --git a/Prebuild/src/Core/WarningException.cs b/Prebuild/src/Core/WarningException.cs index 721f43dc60..b7c3668cce 100644 --- a/Prebuild/src/Core/WarningException.cs +++ b/Prebuild/src/Core/WarningException.cs @@ -5,16 +5,16 @@ Copyright (c) 2004-2005 Matthew Holmes (matthew@wildfiregames.com), Dan Moorehea Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: -* Redistributions of source code must retain the above copyright notice, this list of conditions - and the following disclaimer. -* Redistributions in binary form must reproduce the above copyright notice, this list of conditions - and the following disclaimer in the documentation and/or other materials provided with the - distribution. -* The name of the author may not be used to endorse or promote products derived from this software - without specific prior written permission. +* Redistributions of source code must retain the above copyright notice, this list of conditions + and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions + and the following disclaimer in the documentation and/or other materials provided with the + distribution. +* The name of the author may not be used to endorse or promote products derived from this software + without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, -BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY @@ -28,57 +28,57 @@ using System.Runtime.Serialization; namespace Prebuild.Core { - /// - /// - /// - [Serializable] - public class WarningException : Exception - { - #region Constructors + /// + /// + /// + [Serializable] + public class WarningException : Exception + { + #region Constructors - /// - /// - /// - public WarningException() - { - } + /// + /// + /// + public WarningException() + { + } - /// - /// - /// - /// - /// - public WarningException(string format, params object[] args) - : base(String.Format(format, args)) - { - } + /// + /// + /// + /// + /// + public WarningException(string format, params object[] args) + : base(String.Format(format, args)) + { + } - /// - /// Exception with specified string - /// - /// Exception message - public WarningException(string message): base(message) - { - } + /// + /// Exception with specified string + /// + /// Exception message + public WarningException(string message): base(message) + { + } - /// - /// - /// - /// - /// - public WarningException(string message, Exception exception) : base(message, exception) - { - } + /// + /// + /// + /// + /// + public WarningException(string message, Exception exception) : base(message, exception) + { + } - /// - /// - /// - /// - /// - protected WarningException(SerializationInfo info, StreamingContext context) : base( info, context ) - { - } + /// + /// + /// + /// + /// + protected WarningException(SerializationInfo info, StreamingContext context) : base( info, context ) + { + } - #endregion - } + #endregion + } } diff --git a/Prebuild/src/Prebuild.cs b/Prebuild/src/Prebuild.cs index 996dea0f3c..35a5dfaf44 100644 --- a/Prebuild/src/Prebuild.cs +++ b/Prebuild/src/Prebuild.cs @@ -5,16 +5,16 @@ Copyright (c) 2004-2005 Matthew Holmes (matthew@wildfiregames.com), Dan Moorehea Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: -* Redistributions of source code must retain the above copyright notice, this list of conditions - and the following disclaimer. -* Redistributions in binary form must reproduce the above copyright notice, this list of conditions - and the following disclaimer in the documentation and/or other materials provided with the - distribution. -* The name of the author may not be used to endorse or promote products derived from this software - without specific prior written permission. +* Redistributions of source code must retain the above copyright notice, this list of conditions + and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions + and the following disclaimer in the documentation and/or other materials provided with the + distribution. +* The name of the author may not be used to endorse or promote products derived from this software + without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, -BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY @@ -42,50 +42,50 @@ using System.EnterpriseServices.Internal; using Prebuild.Core; using Prebuild.Core.Utilities; -namespace Prebuild +namespace Prebuild { - /// - /// - /// - class Prebuild - { - #region Main + /// + /// + /// + class Prebuild + { + #region Main - [STAThread] - static void Main(string[] args) - { - Kernel kernel = null; - try - { - kernel = Kernel.Instance; - kernel.Initialize(LogTargets.File | LogTargets.Console, args); - bool exit = false; + [STAThread] + static void Main(string[] args) + { + Kernel kernel = null; + try + { + kernel = Kernel.Instance; + kernel.Initialize(LogTargets.File | LogTargets.Console, args); + bool exit = false; - if(kernel.CommandLine.WasPassed("usage")) - { - exit = true; - OutputUsage(); - } - if(kernel.CommandLine.WasPassed("showtargets")) - { - exit = true; - OutputTargets(kernel); - } - if(kernel.CommandLine.WasPassed("install")) - { - exit = true; - InstallAssembly(kernel); - } - if(kernel.CommandLine.WasPassed("remove")) - { - exit = true; - RemoveAssembly(kernel); - } + if(kernel.CommandLine.WasPassed("usage")) + { + exit = true; + OutputUsage(); + } + if(kernel.CommandLine.WasPassed("showtargets")) + { + exit = true; + OutputTargets(kernel); + } + if(kernel.CommandLine.WasPassed("install")) + { + exit = true; + InstallAssembly(kernel); + } + if(kernel.CommandLine.WasPassed("remove")) + { + exit = true; + RemoveAssembly(kernel); + } - if(!exit) - { - kernel.Process(); - } + if(!exit) + { + kernel.Process(); + } } #if !DEBUG catch (Exception ex) @@ -96,70 +96,70 @@ namespace Prebuild #endif finally { - if(kernel != null && kernel.PauseAfterFinish) - { - Console.WriteLine("\nPress enter to continue..."); - Console.ReadLine(); - } - } - } + if(kernel != null && kernel.PauseAfterFinish) + { + Console.WriteLine("\nPress enter to continue..."); + Console.ReadLine(); + } + } + } - #endregion + #endregion - #region Private Methods + #region Private Methods - private static void InstallAssembly(Kernel kernel) - { - Publish publish = new Publish(); - string file = kernel.CommandLine["install"]; + private static void InstallAssembly(Kernel kernel) + { + Publish publish = new Publish(); + string file = kernel.CommandLine["install"]; //Console.WriteLine(".."+file+".."); - publish.GacInstall(file); - } + publish.GacInstall(file); + } - private static void RemoveAssembly(Kernel kernel) - { - Publish publish = new Publish(); - string file = kernel.CommandLine["remove"]; - publish.GacRemove(file); - } + private static void RemoveAssembly(Kernel kernel) + { + Publish publish = new Publish(); + string file = kernel.CommandLine["remove"]; + publish.GacRemove(file); + } - private static void OutputUsage() - { - Console.WriteLine("Usage: prebuild /target [options]"); - Console.WriteLine("Available command-line switches:"); - Console.WriteLine(); - Console.WriteLine("/target Target for Prebuild"); - Console.WriteLine("/clean Clean the build files for the given target"); - Console.WriteLine("/file XML file to process"); - Console.WriteLine("/log Log file to write to"); - Console.WriteLine("/ppo Pre-process the file, but perform no other processing"); - Console.WriteLine("/pause Pauses the application after execution to view the output"); - Console.WriteLine("/yes Default to yes to any questions asked"); - Console.WriteLine("/install Install assembly into the GAC"); - Console.WriteLine("/remove Remove assembly from the GAC"); - Console.WriteLine(); - Console.WriteLine("See 'prebuild /showtargets for a list of available targets"); - Console.WriteLine("See readme.txt or check out http://dnpb.sourceforge.net for more information"); - Console.WriteLine(); - } + private static void OutputUsage() + { + Console.WriteLine("Usage: prebuild /target [options]"); + Console.WriteLine("Available command-line switches:"); + Console.WriteLine(); + Console.WriteLine("/target Target for Prebuild"); + Console.WriteLine("/clean Clean the build files for the given target"); + Console.WriteLine("/file XML file to process"); + Console.WriteLine("/log Log file to write to"); + Console.WriteLine("/ppo Pre-process the file, but perform no other processing"); + Console.WriteLine("/pause Pauses the application after execution to view the output"); + Console.WriteLine("/yes Default to yes to any questions asked"); + Console.WriteLine("/install Install assembly into the GAC"); + Console.WriteLine("/remove Remove assembly from the GAC"); + Console.WriteLine(); + Console.WriteLine("See 'prebuild /showtargets for a list of available targets"); + Console.WriteLine("See readme.txt or check out http://dnpb.sourceforge.net for more information"); + Console.WriteLine(); + } - private static void OutputTargets(Kernel kern) - { - Console.WriteLine("Targets available in Prebuild:"); - Console.WriteLine(""); - if(kern.Targets.Keys.Count > 0) - { - string[] targs = new string[kern.Targets.Keys.Count]; - kern.Targets.Keys.CopyTo(targs, 0); - Array.Sort(targs); - foreach(string target in targs) - { - Console.WriteLine(target); - } - } - Console.WriteLine(""); - } - - #endregion - } + private static void OutputTargets(Kernel kern) + { + Console.WriteLine("Targets available in Prebuild:"); + Console.WriteLine(""); + if(kern.Targets.Keys.Count > 0) + { + string[] targs = new string[kern.Targets.Keys.Count]; + kern.Targets.Keys.CopyTo(targs, 0); + Array.Sort(targs); + foreach(string target in targs) + { + Console.WriteLine(target); + } + } + Console.WriteLine(""); + } + + #endregion + } } diff --git a/Prebuild/src/Properties/AssemblyInfo.cs b/Prebuild/src/Properties/AssemblyInfo.cs index f9d90bbe4b..079d6a540f 100644 --- a/Prebuild/src/Properties/AssemblyInfo.cs +++ b/Prebuild/src/Properties/AssemblyInfo.cs @@ -52,7 +52,7 @@ using System.Resources; [assembly: CLSCompliant(true)] // -// General Information about an assembly is controlled through the following +// General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. // @@ -61,50 +61,52 @@ using System.Resources; [assembly: AssemblyConfiguration(".NET CLR")] [assembly: AssemblyCompany("The Prebuild Project")] [assembly: AssemblyProduct("")] -[assembly: AssemblyCopyright("Copyright 2004-2013 " + +[assembly: AssemblyCopyright("Copyright 2004-2015 " + "Matthew Holmes, " + "Dan Moorehead, " + "C.J. Adams-Collier, " + "Rob Loach, " + "David Hudson," + - "John Hurliman")] + "John Hurliman" + + "WhiteCore Development" + + "OpenSimulator developers")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] [assembly: NeutralResourcesLanguageAttribute("en-US")] -[assembly: AssemblyVersion("2.0.6.*")] +[assembly: AssemblyVersion("2.0.7.*")] // // Version information for an assembly consists of the following four values: // // Major Version -// Minor Version +// Minor Version // Build Number // Revision // -// You can specify all the values or you can default the Revision and Build Numbers +// You can specify all the values or you can default the Revision and Build Numbers // by using the '*' as shown below: // -// In order to sign your assembly you must specify a key to use. Refer to the +// In order to sign your assembly you must specify a key to use. Refer to the // Microsoft .NET Framework documentation for more information on assembly signing. // -// Use the attributes below to control which key is used for signing. +// Use the attributes below to control which key is used for signing. // -// Notes: +// Notes: // (*) If no key is specified, the assembly is not signed. // (*) KeyName refers to a key that has been installed in the Crypto Service // Provider (CSP) on your machine. KeyFile refers to a file which contains // a key. -// (*) If the KeyFile and the KeyName values are both specified, the +// (*) If the KeyFile and the KeyName values are both specified, the // following processing occurs: // (1) If the KeyName can be found in the CSP, that key is used. -// (2) If the KeyName does not exist and the KeyFile does exist, the key +// (2) If the KeyName does not exist and the KeyFile does exist, the key // in the KeyFile is installed into the CSP and used. // (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility. // When specifying the KeyFile, the location of the KeyFile should be // relative to the project output directory which is // %Project Directory%\obj\. For example, if your KeyFile is -// located in the project directory, you would specify the AssemblyKeyFile +// located in the project directory, you would specify the AssemblyKeyFile // attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")] // (*) Delay Signing is an advanced option - see the Microsoft .NET Framework // documentation for more information on this. diff --git a/Prebuild/src/data/prebuild-1.10.xsd b/Prebuild/src/data/prebuild-1.10.xsd index eee07a8f01..ddfa2c5689 100644 --- a/Prebuild/src/data/prebuild-1.10.xsd +++ b/Prebuild/src/data/prebuild-1.10.xsd @@ -186,8 +186,9 @@ - - + + + diff --git a/ThirdPartyLicenses/Axiom.txt b/ThirdPartyLicenses/Axiom.txt deleted file mode 100644 index fe97db2356..0000000000 --- a/ThirdPartyLicenses/Axiom.txt +++ /dev/null @@ -1,141 +0,0 @@ -GNU LESSER GENERAL PUBLIC LICENSE -Version 2.1, February 1999 - - -Copyright (C) 1991, 1999 Free Software Foundation, Inc. -59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -Everyone is permitted to copy and distribute verbatim copies -of this license document, but changing it is not allowed. - -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - -Preamble -The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. - -This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. - -When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. - -To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. - -For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. - -We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. - -To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. - -Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. - -Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. - -When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. - -We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. - -For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. - -In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. - -Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. - -The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. - - -TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION -0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". - -A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. - -The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) - -"Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. - -Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. - -1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. - -You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. - -2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: - - -a) The modified work must itself be a software library. -b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. -c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. -d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. -(For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. - -3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. - -Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. - -This option is useful when you wish to copy part of the code of the Library into a program that is not a library. - -4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. - -If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. - -5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. - -However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. - -When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. - -If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) - -Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. - -6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. - -You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: - - -a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) -b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. -c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. -d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. -e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. -For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. - -It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. - -7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: - - -a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. -b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. -8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. - -9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. - -10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. - -11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. - -This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. - -12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. - -13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. - -14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. - -NO WARRANTY - -15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - -16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. \ No newline at end of file diff --git a/ThirdPartyLicenses/log4net b/ThirdPartyLicenses/log4net new file mode 100644 index 0000000000..261eeb9e9f --- /dev/null +++ b/ThirdPartyLicenses/log4net @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/bin/Axiom.MathLib.dll b/bin/Axiom.MathLib.dll deleted file mode 100755 index b00cf1d1da..0000000000 Binary files a/bin/Axiom.MathLib.dll and /dev/null differ diff --git a/bin/C5.dll b/bin/C5.dll index 42093e5f84..079224cf20 100755 Binary files a/bin/C5.dll and b/bin/C5.dll differ diff --git a/bin/CSJ2K.dll b/bin/CSJ2K.dll index 238291f7e7..88347fc3aa 100755 Binary files a/bin/CSJ2K.dll and b/bin/CSJ2K.dll differ diff --git a/bin/CookComputing.XmlRpcV2.dll b/bin/CookComputing.XmlRpcV2.dll deleted file mode 100755 index 4dd869c803..0000000000 Binary files a/bin/CookComputing.XmlRpcV2.dll and /dev/null differ diff --git a/bin/DotNetOpenId.dll b/bin/DotNetOpenId.dll index aa62790a15..96279dc030 100755 Binary files a/bin/DotNetOpenId.dll and b/bin/DotNetOpenId.dll differ diff --git a/bin/HttpServer_OpenSim.dll b/bin/HttpServer_OpenSim.dll index 5db99ef2a4..4d6819eb27 100755 Binary files a/bin/HttpServer_OpenSim.dll and b/bin/HttpServer_OpenSim.dll differ diff --git a/bin/HttpServer_OpenSim.pdb b/bin/HttpServer_OpenSim.pdb deleted file mode 100644 index 25b6760a99..0000000000 Binary files a/bin/HttpServer_OpenSim.pdb and /dev/null differ diff --git a/bin/HttpServer_OpenSim.xml b/bin/HttpServer_OpenSim.xml deleted file mode 100644 index 7b6912ec5a..0000000000 --- a/bin/HttpServer_OpenSim.xml +++ /dev/null @@ -1,5574 +0,0 @@ - - - - HttpServer_OpenSim - - - - - Delegate used to let authentication modules authenticate the user name and password. - - Realm that the user want to authenticate in - User name specified by client - Can either be user password or implementation specific token. - object that will be stored in a session variable called if authentication was successful. - throw forbidden exception if too many attempts have been made. - - - Use to specify that the token is a HA1 token. (MD5 generated - string from realm, user name and password); Md5String(userName + ":" + realm + ":" + password); - - - - - - Let's you decide on a system level if authentication is required. - - HTTP request from client - true if user should be authenticated. - throw if no more attempts are allowed. - If no more attempts are allowed - - - - Authentication modules are used to implement different - kind of HTTP authentication. - - - - - Initializes a new instance of the class. - - Delegate used to provide information used during authentication. - Delegate used to determine if authentication is required (may be null). - - - - Initializes a new instance of the class. - - Delegate used to provide information used during authentication. - - - - name used in HTTP request. - - - - - Tag used for authentication. - - - - - Create a response that can be sent in the WWW-Authenticate header. - - Realm that the user should authenticate in - Array with optional options. - A correct authentication request. - If realm is empty or null. - - - - An authentication response have been received from the web browser. - Check if it's correct - - Contents from the Authorization header - Realm that should be authenticated - GET/POST/PUT/DELETE etc. - options to specific implementations - Authentication object that is stored for the request. A user class or something like that. - if is invalid - If any of the parameters is empty or null. - - - - Used to invoke the authentication delegate that is used to lookup the user name/realm. - - Realm (domain) that user want to authenticate in - User name - Password used for validation. Some implementations got password in clear text, they are then sent to client. - object that will be stored in the request to help you identify the user if authentication was successful. - true if authentication was successful - - - - Determines if authentication is required. - - HTTP request from browser - true if user should be authenticated. - throw from your delegate if no more attempts are allowed. - If no more attempts are allowed - - - - The "basic" authentication scheme is based on the model that the - client must authenticate itself with a user-ID and a password for - each realm. The realm value should be considered an opaque string - which can only be compared for equality with other realms on that - server. The server will service the request only if it can validate - the user-ID and password for the protection space of the Request-URI. - There are no optional authentication parameters. - - - - - Initializes a new instance of the class. - - Delegate used to provide information used during authentication. - Delegate used to determine if authentication is required (may be null). - - - - Initializes a new instance of the class. - - Delegate used to provide information used during authentication. - - - - Create a response that can be sent in the WWW-Authenticate header. - - Realm that the user should authenticate in - Not used in basic auth - A correct auth request. - - - - An authentication response have been received from the web browser. - Check if it's correct - - Contents from the Authorization header - Realm that should be authenticated - GET/POST/PUT/DELETE etc. - Not used in basic auth - Authentication object that is stored for the request. A user class or something like that. - if authenticationHeader is invalid - If any of the paramters is empty or null. - - - - name used in http request. - - - - - Implements HTTP Digest authentication. It's more secure than Basic auth since password is - encrypted with a "key" from the server. - - - Keep in mind that the password is encrypted with MD5. Use a combination of SSL and digest auth to be secure. - - - - - Initializes a new instance of the class. - - Delegate used to provide information used during authentication. - Delegate used to determine if authentication is required (may be null). - - - - Initializes a new instance of the class. - - Delegate used to provide information used during authentication. - - - - Used by test classes to be able to use hardcoded values - - - - - name used in http request. - - - - - An authentication response have been received from the web browser. - Check if it's correct - - Contents from the Authorization header - Realm that should be authenticated - GET/POST/PUT/DELETE etc. - First option: true if username/password is correct but not cnonce - - Authentication object that is stored for the request. A user class or something like that. - - if authenticationHeader is invalid - If any of the paramters is empty or null. - - - - Gets or sets whether the token supplied in is a - HA1 generated string. - - - - - Encrypts parameters into a Digest string - - Realm that the user want to log into. - User logging in - Users password. - HTTP method. - Uri/domain that generated the login prompt. - Quality of Protection. - "Number used ONCE" - Hexadecimal request counter. - "Client Number used ONCE" - Digest encrypted string - - - - - - Md5 hex encoded "userName:realm:password", without the quotes. - Md5 hex encoded "method:uri", without the quotes - Quality of Protection - "Number used ONCE" - Hexadecimal request counter. - Client number used once - - - - - Create a response that can be sent in the WWW-Authenticate header. - - Realm that the user should authenticate in - First options specifies if true if username/password is correct but not cnonce. - A correct auth request. - If realm is empty or null. - - - - Decodes authorization header value - - header value - Encoding that the buffer is in - All headers and their values if successful; otherwise null - - NameValueCollection header = DigestAuthentication.Decode("response=\"6629fae49393a05397450978507c4ef1\",\r\nc=00001", Encoding.ASCII); - - Can handle lots of whitespaces and new lines without failing. - - - - Gets the current nonce. - - - - - - Gets the Md5 hash bin hex2. - - To be hashed. - - - - - determines if the nonce is valid or has expired. - - nonce value (check wikipedia for info) - true if the nonce has not expired. - - - - Small design by contract implementation. - - - - - Check whether a parameter is empty. - - Parameter value - Parameter name, or error description. - value is empty. - - - - Checks whether a parameter is null. - - Parameter value - Parameter name, or error description. - value is null. - - - - Checks whether a parameter is null. - - - Parameter value - Parameter name, or error description. - value is null. - - - - Invoked when a client have been accepted by the - - - Can be used to revoke incoming connections - - - - - Initializes a new instance of the class. - - The socket. - - - - Accepted socket. - - - - - Client should be revoked. - - - - - Client may not be handled. - - - - - Add a component instance - - Interface type - Instance to add - - - - Get a component. - - Interface type - Component if registered, otherwise null. - - Component will get created if needed. - - - - If instance cannot be created. - - - - Checks if the specified component interface have been added. - - - true if found; otherwise false. - - - - Add a component. - - Type being requested. - Type being created. - Type have already been mapped. - - - - Lists content type mime types. - - - - - text/plain - - - - - text/haml - - - - - content type for javascript documents = application/javascript - - - - RFC 4329 states that text/javascript have been superseeded by - application/javascript. You might still want to check browser versions - since older ones do not support application/javascript. - - Browser support: http://krijnhoetmer.nl/stuff/javascript/mime-types/ - - - - - text/xml - - - - - A list of content types - - - - - - - Semicolon separated content types. - - - - Get this first content type. - - - - - Fetch a content type - - Part of type ("xml" would return "application/xml") - - All content types are in lower case. - - - - Returns an enumerator that iterates through a collection. - - - An object that can be used to iterate through the collection. - - - - - Searches for the specified type - - Can also be a part of a type (searching for "xml" would return true for "application/xml"). - true if type was found. - - - - Timeout Manager. Checks for dead clients. Clients with open connections that are not doing anything. Closes sessions opened with keepalive. - - - - - Use a Thread or a Timer to monitor the ugly - - - - - Causes the watcher to immediately check the connections. - - - - - Environment.TickCount is an int but it counts all 32 bits so it goes positive - and negative every 24.9 days. This trims down TickCount so it doesn't wrap - for the callers. - This trims it to a 12 day interval so don't let your frame time get too long. - - - - - - Environment.TickCount is an int but it counts all 32 bits so it goes positive - and negative every 24.9 days. Subtracts the passed value (previously fetched by - 'EnvironmentTickCount()') and accounts for any wrapping. - - - - subtraction of passed prevValue from current Environment.TickCount - - - - Environment.TickCount is an int but it counts all 32 bits so it goes positive - and negative every 24.9 days. Subtracts the passed value (previously fetched by - 'EnvironmentTickCount()') and accounts for any wrapping. - - - - subtraction of passed prevValue from current Environment.TickCount - - - - Environment.TickCount is an int but it counts all 32 bits so it goes positive - and negative every 24.9 days. Subtracts the passed value (previously fetched by - 'EnvironmentTickCount()') and accounts for any wrapping. - - subtraction of passed prevValue from current Environment.TickCount - - - - We dont want to let the server to die due to exceptions thrown in worker threads. - therefore we use this delegate to give you a change to handle uncaught exceptions. - - Class that the exception was thrown in. - Exception - - Server will throw a InternalServerException in release version if you dont - handle this delegate. - - - - - The request could not be understood by the server due to malformed syntax. - The client SHOULD NOT repeat the request without modifications. - - Text taken from: http://www.submissionchamber.com/help-guides/error-codes.php - - - - - Create a new bad request exception. - - reason to why the request was bad. - - - - Create a new bad request exception. - - reason to why the request was bad. - inner exception - - - - The server understood the request, but is refusing to fulfill it. - Authorization will not help and the request SHOULD NOT be repeated. - If the request method was not HEAD and the server wishes to make public why the request has not been fulfilled, - it SHOULD describe the reason for the refusal in the entity. If the server does not wish to make this information - available to the client, the status code 404 (Not Found) can be used instead. - - Text taken from: http://www.submissionchamber.com/help-guides/error-codes.php - - - - - Initializes a new instance of the class. - - error message - - - - All HTTP based exceptions will derive this class. - - - - - Create a new HttpException - - http status code (sent in the response) - error description - - - - Create a new HttpException - - http status code (sent in the response) - error description - inner exception - - - - status code to use in the response. - - - - - The server encountered an unexpected condition which prevented it from fulfilling the request. - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the class. - - error message. - - - - Initializes a new instance of the class. - - error message. - inner exception. - - - - The requested resource was not found in the web server. - - - - - Create a new exception - - message describing the error - inner exception - - - - Create a new exception - - message describing the error - - - - The request requires user authentication. The response MUST include a - WWW-Authenticate header field (section 14.47) containing a challenge - applicable to the requested resource. - - The client MAY repeat the request with a suitable Authorization header - field (section 14.8). If the request already included Authorization - credentials, then the 401 response indicates that authorization has been - refused for those credentials. If the 401 response contains the same challenge - as the prior response, and the user agent has already attempted authentication - at least once, then the user SHOULD be presented the entity that was given in the response, - since that entity might include relevant diagnostic information. - - HTTP access authentication is explained in rfc2617: - http://www.ietf.org/rfc/rfc2617.txt - - (description is taken from - http://www.submissionchamber.com/help-guides/error-codes.php#sec10.4.2) - - - - - Create a new unauhtorized exception. - - - - - - Create a new unauhtorized exception. - - reason to why the request was unauthorized. - inner exception - - - - Create a new unauhtorized exception. - - reason to why the request was unauthorized. - - - - This provider is used to let us implement any type of form decoding we want without - having to rewrite anything else in the server. - - - - - - - Should contain boundary and type, as in: multipart/form-data; boundary=---------------------------230051238959 - Stream containing form data. - Encoding used when decoding the stream - if no parser was found. - If stream is null or not readable. - If stream contents cannot be decoded properly. - - - - Add a decoder. - - - - - - - Number of added decoders. - - - - - Use with care. - - - - - Decoder used for unknown content types. - - - - Represents a field in a multipart form - - - - - - - - - - - - Interface for form content decoders. - - - - - - - Stream containing the content - Content type (with any additional info like boundry). Content type is always supplied in lower case - Stream enconding - A http form, or null if content could not be parsed. - If contents in the stream is not valid input data. - - - - Checks if the decoder can handle the mime type - - Content type (with any additional info like boundry). Content type is always supplied in lower case. - True if the decoder can parse the specified content type - - - - - - - http://www.faqs.org/rfcs/rfc1867.html - - - - - multipart/form-data - - - - - form-data - - - - - - - Stream containing the content - Content type (with any additional info like boundry). Content type is always supplied in lower case - Stream enconding - A http form, or null if content could not be parsed. - If contents in the stream is not valid input data. - If any parameter is null - - - - Checks if the decoder can handle the mime type - - Content type (with any additional info like boundry). Content type is always supplied in lower case. - True if the decoder can parse the specified content type - - - - Can handle application/x-www-form-urlencoded - - - - - - Stream containing the content - Content type (with any additional info like boundry). Content type is always supplied in lower case - Stream encoding - - A HTTP form, or null if content could not be parsed. - - If contents in the stream is not valid input data. - - - - Checks if the decoder can handle the mime type - - Content type (with any additional info like boundry). Content type is always supplied in lower case. - True if the decoder can parse the specified content type - - - - This decoder converts XML documents to form items. - Each element becomes a subitem in the form, and each attribute becomes an item. - - - // xml: somethingdata - // result: - // form["hello"].Value = "something" - // form["hello"]["id"].Value = 1 - // form["hello"]["world]["id"].Value = 1 - // form["hello"]["world"].Value = "data" - - - The original xml document is stored in form["__xml__"].Value. - - - - - - - Stream containing the content - Content type (with any additional info like boundry). Content type is always supplied in lower case - Stream encoding - Note: contentType and encoding are not used? - A http form, or null if content could not be parsed. - - - - - Recursive function that will go through an xml element and store it's content - to the form item. - - (parent) Item in form that content should be added to. - Node that should be parsed. - - - - Checks if the decoder can handle the mime type - - Content type (with any additional info like boundry). Content type is always supplied in lower case. - True if the decoder can parse the specified content type - - - - Helpers making it easier to work with forms. - - - - - - Used to let the website use different JavaScript libraries. - Default is - - - - - Create a <form> tag. - - name of form - action to invoke on submit - form should be posted as Ajax - HTML code - - - // without options - WebHelper.FormStart("frmLogin", "/user/login", Request.IsAjax); - - // with options - WebHelper.FormStart("frmLogin", "/user/login", Request.IsAjax, "style", "display:inline", "class", "greenForm"); - - - HTML attributes or JavaScript options. - Method will ALWAYS be POST. - options must consist of name, value, name, value - - - - Creates a select list with the values in a collection. - - Name of the SELECT-tag - collection used to generate options. - delegate used to return id and title from objects. - value that should be marked as selected. - First row should contain an empty value. - string containing a SELECT-tag. - - - - - Creates a select list with the values in a collection. - - Name of the SELECT-tag - Id of the SELECT-tag - collection used to generate options. - delegate used to return id and title from objects. - value that should be marked as selected. - First row should contain an empty value. - string containing a SELECT-tag. - - - - // Class that is going to be used in a SELECT-tag. - public class User - { - private readonly string _realName; - private readonly int _id; - public User(int id, string realName) - { - _id = id; - _realName = realName; - } - public string RealName - { - get { return _realName; } - } - - public int Id - { - get { return _id; } - } - } - - // Using an inline delegate to generate the select list - public void UserInlineDelegate() - { - List<User> items = new List<User>(); - items.Add(new User(1, "adam")); - items.Add(new User(2, "bertial")); - items.Add(new User(3, "david")); - string htmlSelect = Select("users", "users", items, delegate(object o, out object id, out object value) - { - User user = (User)o; - id = user.Id; - value = user.RealName; - }, 2, true); - } - - // Using an method as delegate to generate the select list. - public void UseExternalDelegate() - { - List<User> items = new List<User>(); - items.Add(new User(1, "adam")); - items.Add(new User(2, "bertial")); - items.Add(new User(3, "david")); - string htmlSelect = Select("users", "users", items, UserOptions, 1, true); - } - - // delegate returning id and title - public static void UserOptions(object o, out object id, out object title) - { - User user = (User)o; - id = user.Id; - value = user.RealName; - } - - - name, id, collection or getIdTitle is null. - - - - Creates a select list with the values in a collection. - - Name of the SELECT-tag - Id of the SELECT-tag - collection used to generate options. - delegate used to return id and title from objects. - value that should be marked as selected. - First row should contain an empty value. - name, value collection of extra HTML attributes. - string containing a SELECT-tag. - - name, id, collection or getIdTitle is null. - Invalid HTML attribute list. - - - - Generate a list of HTML options - - collection used to generate options. - delegate used to return id and title from objects. - value that should be marked as selected. - First row should contain an empty value. - - collection or getIdTitle is null. - - - sb is null. - - - - Creates a check box. - - element name - element value - determines if the check box is selected or not. This is done differently depending on the - type of variable. A boolean simply triggers checked or not, all other types are compared with "value" to determine if - the box is checked or not. - a list with additional attributes (name, value, name, value). - a generated radio button - - - - Creates a check box. - - element name - element id - element value - determines if the check box is selected or not. This is done differently depending on the - type of variable. A boolean simply triggers checked or not, all other types are compared with "value" to determine if - the box is checked or not. - a list with additional attributes (name, value, name, value). - a generated radio button - - value in your business object. (check box will be selected if it matches the element value) - - - - - Creates a check box. - - element name - element id - determines if the check box is selected or not. This is done differently depending on the - type of variable. A boolean simply triggers checked or not, all other types are compared with "value" to determine if - the box is checked or not. - a list with additional attributes (name, value, name, value). - a generated radio button - will set value to "1". - - - - Creates a RadioButton. - - element name - element value - determines if the radio button is selected or not. This is done differently depending on the - type of variable. A boolean simply triggers checked or not, all other types are compared with "value" to determine if - the box is checked or not. - a list with additional attributes (name, value, name, value). - a generated radio button - - - - Creates a RadioButton. - - element name - element id - element value - determines if the radio button is selected or not. This is done differently depending on the - type of variable. A boolean simply triggers checked or not, all other types are compared with "value" to determine if - the box is checked or not. - a list with additional attributes (name, value, name, value). - a generated radio button - - - - form close tag - - - - - - Delegate used by to populate select options. - - current object (for instance a User). - Text that should be displayed in the value part of a <optiongt;-tag. - Text shown in the select list. - - // Class that is going to be used in a SELECT-tag. - public class User - { - private readonly string _realName; - private readonly int _id; - public User(int id, string realName) - { - _id = id; - _realName = realName; - } - public string RealName - { - get { return _realName; } - } - - public int Id - { - get { return _id; } - } - } - - // Using an inline delegate to generate the select list - public void UserInlineDelegate() - { - List<User> items = new List<User>(); - items.Add(new User(1, "adam")); - items.Add(new User(2, "bertial")); - items.Add(new User(3, "david")); - string htmlSelect = Select("users", "users", items, delegate(object o, out object id, out object value) - { - User user = (User)o; - id = user.Id; - value = user.RealName; - }, 2, true); - } - - // Using an method as delegate to generate the select list. - public void UseExternalDelegate() - { - List<User> items = new List<User>(); - items.Add(new User(1, "adam")); - items.Add(new User(2, "bertial")); - items.Add(new User(3, "david")); - string htmlSelect = Select("users", "users", items, UserOptions, 1, true); - } - - // delegate returning id and title - public static void UserOptions(object o, out object id, out object title) - { - User user = (User)o; - id = user.Id; - value = user.RealName; - } /// - - - - PrototypeJS implementation of the javascript functions. - - - - - Requests a url through ajax - - url to fetch. Url is NOT enclosed in quotes by the implementation. You need to do that yourself. - optional options in format "key, value, key, value", used in JS request object. All keys should end with colon. - a link tag - onclick attribute is used by this method. - - - // plain text - JSHelper.AjaxRequest("'/user/show/1'"); - - // ajax request using this.href - string link = "<a href=\"/user/call/1\" onclick=\"" + JSHelper.AjaxRequest("this.href") + "/<call user</a>"; - - - - - - Determins if a list of strings contains a specific value - - options to check in - value to find - true if value was found - case insensitive - - - - Ajax requests that updates an element with - the fetched content - - URL to fetch. URL is NOT enclosed in quotes by the implementation. You need to do that yourself. - element to update - options in format "key, value, key, value". All keys should end with colon. - A link tag. - - - JSHelper.AjaxUpdater("'/user/show/1'", "user", "onsuccess:", "alert('hello');", "asynchronous:", "true"); - - - - - - A link that pop ups a Dialog (overlay div) - - URL to contents of dialog - link title - name, value, name, value - - A "a"-tag that popups a dialog when clicked - - Requires Control.Modal found here: http://livepipe.net/projects/control_modal/ - And the following JavaScript (load it in application.js): - - Event.observe(window, 'load', - function() { - document.getElementsByClassName('modal').each(function(link){ new Control.Modal(link); }); - } - ); - - - - WebHelper.DialogLink("/user/show/1", "show user", "onmouseover", "alert('booh!');"); - - - - - create a modal dialog (usually using DIVs) - - url to fetch - dialog title - javascript/html attributes. javascript options ends with colon ':'. - - - - - Close a javascript dialog window/div. - - javascript for closing a dialog. - - - - - javascript action that should be added to the "onsubmit" event in the form tag. - - remember to encapsulate strings in '' - - All javascript option names should end with colon. - - - JSHelper.AjaxRequest("/user/show/1", "onsuccess:", "$('userInfo').update(result);"); - - - - - - Will contain helper functions for javascript. - - - - - Requests a url through ajax - - url to fetch. Url is NOT enclosed in quotes by the implementation. You need to do that yourself. - optional options in format "key, value, key, value", used in JS request object. All keys should end with colon. - a link tag - onclick attribute is used by this method. - - - // plain text - JSHelper.AjaxRequest("'/user/show/1'"); - - // ajax request using this.href - string link = "<a href=\"/user/call/1\" onclick=\"" + JSHelper.AjaxRequest("this.href") + "/<call user</a>"; - - - - - - Ajax requests that updates an element with - the fetched content - - url to fetch. Url is NOT enclosed in quotes by the implementation. You need to do that yourself. - element to update - options in format "key, value, key, value". All keys should end with colon. - A link tag. - - - JSHelper.AjaxUpdater("'/user/show/1'", "user", "onsuccess:", "alert('hello');", "asynchronous:", "true"); - - - - - - Opens contents in a dialog window. - - url to contents of dialog - link title - name, value, name, value, all parameter names should end with colon. - - - - Close a javascript dialog window/div. - - javascript for closing a dialog. - - - - - The object form class takes an object and creates form items for it. - - - - - Initializes a new instance of the class. - - - form name *and* id. - action to do when form is posted. - - - - - Initializes a new instance of the class. - - form name *and* id. - action to do when form is posted. - object to get values from - - - - Initializes a new instance of the class. - - form action. - object to get values from. - - - - write out the FORM-tag. - - generated html code - - - - Writeout the form tag - - form should be posted through ajax. - generated html code - - - - Generates a text box. - - - - generated html code - - - - password box - - - - generated html code - - - - Hiddens the specified property name. - - Name of the property. - The options. - generated html code - - - - Labels the specified property name. - - property in object. - caption - generated html code - - - - Generate a checkbox - - property in object - checkbox value - additional html attributes. - generated html code - - - - Write a html select tag - - object property. - id column - The title column. - The options. - - - - - Selects the specified property name. - - Name of the property. - The items. - The id column. - The title column. - The options. - - - - - Write a submit tag. - - button caption - html submit tag - - - - html end form tag - - html - - - - Container to bind resource names to assemblies - - - - - Instantiates an instance of - - The dot seperated uri the resource maps to - The full resource name - The assembly the resource exists in - - - - Retrieves the assembly the resource resides in - - - - - Retrieves the full name/path of the assembly - - - - - Retrieves the extension of the resource - - - - Returns the Uri without extension - - - Retrieves the full path name to the resource file - - - - Retrieves a stream to the resource - - Null if the resource couldn't be located somehow - - - Class to handle loading of resource files - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the class. - - logger. - - - - Loads resources from a namespace in the given assembly to an URI - - The URI to map the resources to - The assembly in which the resources reside - The namespace from which to load the resources - - - resourceLoader.LoadResources("/user/", typeof(User).Assembly, "MyLib.Models.User.Views"); - - Will make the resource MyLib.Models.User.Views.list.Haml accessible via /user/list.haml or /user/list/ - - The amount of loaded files, giving you the possibility of making sure the resources needed gets loaded - If a resource has already been mapped to an uri - - - - Retrieves a stream for the specified resource path if loaded otherwise null - - Path to the resource to retrieve a stream for - A stream or null if the resource couldn't be found - - - - Fetch all files from the resource that matches the specified arguments. - - The path to the resource to extract - - a list of files if found; or an empty array if no files are found. - - Search path must end with an asterisk for finding arbitrary files - - - - Fetch all files from the resource that matches the specified arguments. - - Where the file should reside. - Files to check - - a list of files if found; or an empty array if no files are found. - - - - - Returns whether or not the loader has an instance of the file requested - - The name of the template/file - True if the loader can provide the file - - - - Webhelper provides helpers for common tasks in HTML. - - - - - Used to let the website use different javascript libraries. - Default is - - - - - Creates a link that invokes through ajax. - - url to fetch - link title - - optional options in format "key, value, key, value". - Javascript options starts with ':'. - - a link tag - - WebHelper.AjaxRequest("/users/add/", "Add user", "method:", "post", "onclick", "validate('this');"); - - - - - Builds a link that updates an element with the fetched ajax content. - - Url to fetch content from - link title - html element to update with the results of the ajax request. - optional options in format "key, value, key, value" - A link tag. - - - - A link that pop ups a Dialog (overlay div) - - url to contents of dialog - link title - name/value of html attributes. - A "a"-tag that popups a dialog when clicked - - WebHelper.DialogLink("/user/show/1", "show user", "onmouseover", "alert('booh!');"); - - - - - Create/Open a dialog box using ajax - - - - - - - - - Close a javascript dialog window/div. - - javascript for closing a dialog. - - - - - Create a <form> tag. - - name of form - action to invoke on submit - form should be posted as ajax - html code - - WebHelper.FormStart("frmLogin", "/user/login", Request.IsAjax); - - - - - Create a link tag. - - url to go to - link title (text that is displayed) - html attributes, name, value, name, value - html code - - WebHelper.Link("/user/show/1", "Show user", "id", "showUser", "onclick", "return confirm('Are you shure?');"); - - - - - Build a link - - url to go to. - title of link (displayed text) - extra html attributes. - a complete link - - - - Build a link - - url to go to. - title of link (displayed text) - extra html attributes. - a complete link - more options - - - - Obsolete - - Obsolete - Obsolete - Obsolete - Obsolete - Obsolete - Obsolete - - - - Obsolete - - Obsolete - Obsolete - Obsolete - Obsolete - Obsolete - Obsolete - Obsolete - - - - Render errors into a UL with class "errors" - - class used by UL-tag. - items to list - an unordered html list. - - - - Render errors into a UL with class "errors" - - class used by UL-tag. - items to list - an unordered html list. - - - - Render errors into a UL with class "errors" - - - - - - - Generates a list with html attributes. - - StringBuilder that the options should be added to. - attributes set by user. - attributes set by any of the helper classes. - - - - Generates a list with html attributes. - - StringBuilder that the options should be added to. - - - - - Purpose of this class is to create a javascript toolkit independent javascript helper. - - - - - Generates a list with JS options. - - StringBuilder that the options should be added to. - the javascript options. name, value pairs. each string value should be escaped by YOU! - true if we should start with a comma. - - - - Removes any javascript parameters from an array of parameters - - The array of parameters to remove javascript params from - An array of html parameters - - - - javascript action that should be added to the "onsubmit" event in the form tag. - - - All javascript option names should end with colon. - - - JSHelper.AjaxRequest("/user/show/1", "onsuccess:", "$('userInfo').update(result);"); - - - - - - Requests a url through ajax - - url to fetch - optional options in format "key, value, key, value", used in JS request object. - a link tag - All javascript option names should end with colon. - - - JSHelper.AjaxRequest("/user/show/1", "onsuccess:", "$('userInfo').update(result);"); - - - - - - Ajax requests that updates an element with - the fetched content - - Url to fetch content from - element to update - optional options in format "key, value, key, value", used in JS updater object. - A link tag. - All javascript option names should end with colon. - - - JSHelper.AjaxUpdater("/user/show/1", "userInfo", "onsuccess:", "alert('Successful!');"); - - - - - - A link that pop ups a Dialog (overlay div) - - url to contents of dialog - link title - A "a"-tag that popups a dialog when clicked - name/value of html attributes - - WebHelper.DialogLink("/user/show/1", "show user", "onmouseover", "alert('booh!');"); - - - - - Close a javascript dialog window/div. - - javascript for closing a dialog. - - - - - Creates a new modal dialog window - - url to open in window. - window title (may not be supported by all js implementations) - - - - - - Helpers to make XML handling easier - - - - - Serializes object to XML. - - object to serialize. - XML - - Removes name spaces and adds indentation - - - - - Create an object from a XML string - - Type of object - XML string - object - - - - Contains a connection to a browser/client. - - - Remember to after you have hooked the event. - - TODO: Maybe this class should be broken up into HttpClientChannel and HttpClientContext? - - - - This context have been cleaned, which means that it can be reused. - - - - - Context have been started (a new client have connected) - - - - - Initializes a new instance of the class. - - true if the connection is secured (SSL/TLS) - client that connected. - Stream used for communication - Used to create a . - Size of buffer to use when reading data. Must be at least 4096 bytes. - If fails - Stream must be writable and readable. - - - - Process incoming body bytes. - - - Bytes - - - - - - - - - - - Overload to specify own type. - - - Must be specified before the context is being used. - - - - - Start reading content. - - - Make sure to call base.Start() if you override this method. - - - - - Clean up context. - - - Make sure to call base.Cleanup() if you override the method. - - - - - Using SSL or other encryption method. - - - - - Using SSL or other encryption method. - - - - - Specify which logger to use. - - - - - Gets or sets the network stream. - - - - - Gets or sets IP address that the client connected from. - - - - - Gets or sets port that the client connected from. - - - - - Disconnect from client - - error to report in the event. - - - - Send a response. - - Either or - HTTP status code - reason for the status code. - HTML body contents, can be null or empty. - A content type to return the body as, i.e. 'text/html' or 'text/plain', defaults to 'text/html' if null or empty - If is invalid. - - - - Send a response. - - Either or - HTTP status code - reason for the status code. - - - - Send a response. - - - - - - send a whole buffer - - buffer to send - - - - - Send data using the stream - - Contains data to send - Start position in buffer - number of bytes to send - - - - - - The context have been disconnected. - - - Event can be used to clean up a context, or to reuse it. - - - - - A request have been received in the context. - - - - - Used to create and reuse contexts. - - - - - Initializes a new instance of the class. - - The writer. - Amount of bytes to read from the incoming socket stream. - Used to create a request parser. - - - - True if detailed trace logs should be written. - - - - - Create a new context. - - true if socket is running HTTPS. - Client that connected - Network/SSL stream. - A context. - - - - Create a new context. - - true if HTTPS is used. - Remote client - Network stream, uses . - A new context (always). - - - - Create a secure . - - Client socket (accepted by the ). - HTTPS certificate to use. - Kind of HTTPS protocol. Usually TLS or SSL. - - A created . - - - - - A request have been received from one of the contexts. - - - - - Creates a that handles a connected client. - - Client socket (accepted by the ). - - A creates . - - - - - Server is shutting down so shut down the factory - - - - - Custom network stream to mark sockets as reusable when disposing the stream. - - - - - Creates a new instance of the class for the specified . - - - The that the will use to send and receive data. - - - The parameter is null. - - - The parameter is not connected. - -or- - The property of the parameter is not . - -or- - The parameter is in a nonblocking state. - - - - - Initializes a new instance of the class for the specified with the specified ownership. - - - The that the will use to send and receive data. - - - Set to true to indicate that the will take ownership of the ; otherwise, false. - - - The parameter is null. - - - The parameter is not connected. - -or- - the value of the property of the parameter is not . - -or- - the parameter is in a nonblocking state. - - - - - Creates a new instance of the class for the specified with the specified access rights. - - - The that the will use to send and receive data. - - - A bitwise combination of the values that specify the type of access given to the over the provided . - - - The parameter is null. - - - The parameter is not connected. - -or- - the property of the parameter is not . - -or- - the parameter is in a nonblocking state. - - - - - Creates a new instance of the class for the specified with the specified access rights and the specified ownership. - - - The that the will use to send and receive data. - - - A bitwise combination of the values that specifies the type of access given to the over the provided . - - - Set to true to indicate that the will take ownership of the ; otherwise, false. - - - The parameter is null. - - - The parameter is not connected. - -or- - The property of the parameter is not . - -or- - The parameter is in a nonblocking state. - - - - - Closes the current stream and releases any resources (such as sockets and file handles) associated with the current stream. - - - - - Releases the unmanaged resources used by the and optionally releases the managed resources. - - true to release both managed and unmanaged resources; false to release only unmanaged resources. - - - - Used to create es. - - - - - Creates a that handles a connected client. - - Client socket (accepted by the ). - A creates . - - - - Create a secure . - - Client socket (accepted by the ). - HTTPS certificate to use. - Kind of HTTPS protocol. Usually TLS or SSL. - A created . - - - - A request have been received from one of the contexts. - - - - - Server is shutting down so shut down the factory - - - - - Container class for posted files - - - - - Creates a container for a posted file - - The identifier of the post field - The file path - The content type of the file - The name of the file uploaded - If any parameter is null or empty - - - - Creates a container for a posted file - - If any parameter is null or empty - - - Destructor disposing the file - - - - The name/id of the file - - - - - The full file path - - - - - The name of the uploaded file - - - - - The type of file - - - - - Deletes the temporary file - - True if manual dispose - - - - Disposing interface, cleans up managed resources (the temporary file) and suppresses finalization - - - - Container for posted form data - - - Instance to help mark a non-initialized form - - - Initializes a form container with the specified name - - - - Makes a deep copy of the input - - The input to copy - - - - Adds a file to the collection of posted files - - The file to add - If the file is already added - If file is null - If the instance is HttpForm.EmptyForm which cannot be modified - - - - Checks if the form contains a specified file - - Field name of the file parameter - True if the file exists - If the instance is HttpForm.EmptyForm which cannot be modified - - - - Retrieves a file held by by the form - - The identifier of the file - The requested file or null if the file was not found - If name is null or empty - If the instance is HttpForm.EmptyForm which cannot be modified - - - - Retrieves the number of files added to the - - 0 if no files are added - - - Disposes all held HttpFile's and resets values - - - - Generic helper functions for HTTP - - - - - Version string for HTTP v1.0 - - - - - Version string for HTTP v1.1 - - - - - An empty URI - - - - - Parses a query string. - - Query string (URI encoded) - A object if successful; otherwise - queryString is null. - If string cannot be parsed. - - - - Contains some kind of input from the browser/client. - can be QueryString, form data or any other request body content. - - - - Representation of a non-initialized class instance - - - Variable telling the class that it is non-initialized - - - - Initializes a new instance of the class. - - form name. - - - - Initializes a new instance of the class. - - form name. - if set to true all changes will be ignored. - this constructor should only be used by Empty - - - Creates a deep copy of the HttpInput class - The object to copy - The function makes a deep copy of quite a lot which can be slow - - - - Form name as lower case - - - - - Add a new element. Form array elements are parsed - and added in a correct hierarchy. - - Name is converted to lower case. - - name is null. - Cannot add stuff to . - - - - Get a form item. - - - Returns if item was not found. - - - - Returns true if the class contains a with the corresponding name. - - The field/query string name - True if the value exists - - - - Parses an item and returns it. - This function is primarily used to parse array items as in user[name]. - - - - - - - Outputs the instance representing all its values joined together - - - - Returns all items as an unescaped query string. - - - - - Extracts one parameter from an array - - Containing the string array - All but the first value - - string test1 = ExtractOne("system[user][extension][id]"); - string test2 = ExtractOne(test1); - string test3 = ExtractOne(test2); - // test1 = user[extension][id] - // test2 = extension[id] - // test3 = id - - - - Resets all data contained by class - - - - Returns an enumerator that iterates through the collection. - - - - A that can be used to iterate through the collection. - - 1 - - - - Returns an enumerator that iterates through a collection. - - - - An object that can be used to iterate through the collection. - - 2 - - - - Base class for request data containers - - - - - Adds a parameter mapped to the presented name - - The name to map the parameter to - The parameter value - - - - Returns a request parameter - - The name associated with the parameter - - - - - Returns true if the container contains the requested parameter - - Parameter id - True if parameter exists - - - - represents a HTTP input item. Each item can have multiple sub items, a sub item - is made in a HTML form by using square brackets - - - // becomes: - Console.WriteLine("Value: {0}", form["user"]["FirstName"].Value); - - - All names in a form SHOULD be in lowercase. - - - - Representation of a non-initialized . - - - - Initializes an input item setting its name/identifier and value - - Parameter name/id - Parameter value - - - Creates a deep copy of the item specified - The item to copy - The function makes a deep copy of quite a lot which can be slow - - - - Number of values - - - - - Get a sub item - - name in lower case. - if no item was found. - - - - Name of item (in lower case). - - - - - Returns the first value, or null if no value exist. - - - - - Returns the last value, or null if no value exist. - - - - - Returns the list with values. - - - - - Add another value to this item - - Value to add. - Cannot add stuff to . - - - - checks if a sub-item exists (and has a value). - - name in lower case - true if the sub-item exists and has a value; otherwise false. - - - Returns a formatted representation of the instance with the values of all contained parameters - - - - Outputs the string in a formatted manner - - A prefix to append, used internally - produce a query string - - - - - - name in lower case - - - - - Add a sub item. - - Can contain array formatting, the item is then parsed and added in multiple levels - Value to add. - Argument is null. - Cannot add stuff to . - - - - Returns an enumerator that iterates through the collection. - - - - A that can be used to iterate through the collection. - - 1 - - - - Returns an enumerator that iterates through a collection. - - - - An object that can be used to iterate through the collection. - - 2 - - - - Outputs the string in a formatted manner - - A prefix to append, used internally - - - - - New implementation of the HTTP listener. - - - Use the Create methods to create a default listener. - - - - - A client have been accepted, but not handled, by the listener. - - - - - Initializes a new instance of the class. - - IP Address to accept connections on - TCP Port to listen on, default HTTP port is 80. - Factory used to create es. - address is null. - Port must be a positive number. - - - - Initializes a new instance of the class. - - The address. - The port. - The factory. - The certificate. - - - - Initializes a new instance of the class. - - The address. - The port. - The factory. - The certificate. - The protocol. - - - - Creates a new instance with default factories. - - Address that the listener should accept connections on. - Port that listener should accept connections on. - Created HTTP listener. - - - - Creates a new instance with default factories. - - Address that the listener should accept connections on. - Port that listener should accept connections on. - Certificate to use - Created HTTP listener. - - - - Creates a new instance with default factories. - - Address that the listener should accept connections on. - Port that listener should accept connections on. - Certificate to use - which HTTPS protocol to use, default is TLS. - Created HTTP listener. - - - - Can be used to create filtering of new connections. - - Accepted socket - - true if connection can be accepted; otherwise false. - - - - - Contains a listener that doesn't do anything with the connections. - - - - - Listen for regular HTTP connections - - IP Address to accept connections on - TCP Port to listen on, default HTTP port is 80. - Factory used to create es. - address is null. - Port must be a positive number. - - - - Initializes a new instance of the class. - - IP Address to accept connections on - TCP Port to listen on, default HTTPS port is 443 - Factory used to create es. - Certificate to use - - - - Initializes a new instance of the class. - - IP Address to accept connections on - TCP Port to listen on, default HTTPS port is 443 - Factory used to create es. - Certificate to use - which HTTPS protocol to use, default is TLS. - - - - Gives you a change to receive log entries for all internals of the HTTP library. - - - You may not switch log writer after starting the listener. - - - - - True if we should turn on trace logs. - - - - Exception. - - - - Will try to accept connections one more time. - - If any exceptions is thrown. - - - - Can be used to create filtering of new connections. - - Accepted socket - true if connection can be accepted; otherwise false. - - - - Start listen for new connections - - Number of connections that can stand in a queue to be accepted. - Listener have already been started. - - - - Stop the listener - - - - - - Catch exceptions not handled by the listener. - - - Exceptions will be thrown during debug mode if this event is not used, - exceptions will be printed to console and suppressed during release mode. - - - - - A request have been received from a . - - - - - The purpose of this module is to serve files. - - - - - Initializes a new instance of the class. - - Uri to serve, for instance "/files/" - Path on hard drive where we should start looking for files - If true a Last-Modifed header will be sent upon requests urging web browser to cache files - - - - Initializes a new instance of the class. - - Uri to serve, for instance "/files/" - Path on hard drive where we should start looking for files - - - - List with all mime-type that are allowed. - - All other mime types will result in a Forbidden http status code. - - - - characters that may not exist in a path. - - - fileMod.ForbiddenChars = new string[]{ "\\", "..", ":" }; - - - - - Mimtypes that this class can handle per default - - - - - Determines if the request should be handled by this module. - Invoked by the - - - true if this module should handle it. - - - Illegal path - - - - check if source contains any of the chars. - - - - - - - - Method that process the Uri. - - Information sent by the browser about the request - Information that is being sent back to the client. - Session used to - Failed to find file extension - File type is forbidden. - - - - return a file extension from an absolute Uri path (or plain filename) - - - - - - - A HttpModule can be used to serve Uri's. The module itself - decides if it should serve a Uri or not. In this way, you can - get a very flexible http application since you can let multiple modules - serve almost similar urls. - - - Throw if you are using a and want to prompt for user name/password. - - - - - Method that process the url - - Information sent by the browser about the request - Information that is being sent back to the client. - Session used to - true if this module handled the request. - - - - Set the log writer to use. - - logwriter to use. - - - - Log something. - - importance of log message - message - - - - If true specifies that the module doesn't consume the processing of a request so that subsequent modules - can continue processing afterwards. Default is false. - - - - - Used to inform http server that - - - - - Eventarguments used when an exception is thrown by a module - - the exception - - - - Exception thrown in a module - - - - - Serves files that are stored in embedded resources. - - - - - Initializes a new instance of the class. - Runs to make sure the basic mime types are available, they can be cleared later - through the use of if desired. - - - - - Initializes a new instance of the class. - Runs to make sure the basic mime types are available, they can be cleared later - through the use of if desired. - - The log writer to use when logging events - - - - List with all mime-type that are allowed. - - All other mime types will result in a Forbidden http status code. - - - - Mimtypes that this class can handle per default - - - - - Loads resources from a namespace in the given assembly to an uri - - The uri to map the resources to - The assembly in which the resources reside - The namespace from which to load the resources - - resourceLoader.LoadResources("/user/", typeof(User).Assembly, "MyLib.Models.User.Views"); - - will make ie the resource MyLib.Models.User.Views.stylesheet.css accessible via /user/stylesheet.css - - The amount of loaded files, giving you the possibility of making sure the resources needed gets loaded - - - - Returns true if the module can handle the request - - - - - Method that process the url - - Information sent by the browser about the request - Information that is being sent back to the client. - Session used to - true if this module handled the request. - - - - A reverse proxy are used to act as a bridge between local (protected/hidden) websites - and public clients. - - A typical usage is to allow web servers on non standard ports to still be available - to the public clients, or allow web servers on private ips to be available. - - - - - - - Base url requested from browser - Base url on private web server - - // this will return contents from http://192.168.1.128/view/jonas when client requests http://www.gauffin.com/user/view/jonas - _server.Add(new ReverseProxyModule("http://www.gauffin.com/user/", "http://192.168.1.128/"); - - - - - Method that determines if an url should be handled or not by the module - - Url requested by the client. - true if module should handle the url. - - - - Method that process the url - - Information sent by the browser about the request - Information that is being sent back to the client. - Session used to - - - - The website module let's you handle multiple websites in the same server. - It uses the "Host" header to check which site you want. - - It's recommended that you do not - add any other modules to HttpServer if you are using the website module. Instead, - add all wanted modules to each website. - - - - - - domain name that should be handled. - - - - - Name of site. - - - - - Method that process the url - - Information sent by the browser about the request - Information that is being sent back to the client. - Session used to - - - - Returns item either from a form or a query string (checks them in that order) - - - - Representation of a non-initialized HttpParam - - - Initialises the class to hold a value either from a post request or a querystring request - - - - The add method is not availible for HttpParam - since HttpParam checks both Request.Form and Request.QueryString - - name identifying the value - value to add - - - - - Checks whether the form or querystring has the specified value - - Name, case sensitive - true if found; otherwise false. - - - - Fetch an item from the form or querystring (in that order). - - - Item if found; otherwise HttpInputItem.EmptyLanguageNode - - - - Returns an enumerator that iterates through the collection. - - - - A that can be used to iterate through the collection. - - 1 - - - - Returns an enumerator that iterates through a collection. - - - - An object that can be used to iterate through the collection. - - 2 - - - - Contains server side HTTP request information. - - - - - Chars used to split an URL path into multiple parts. - - - - - Gets or sets a value indicating whether this is secure. - - - - - Path and query (will be merged with the host header) and put in Uri - - - - - - Assign a form. - - - - - - Gets whether the body is complete. - - - - - Gets kind of types accepted by the client. - - - - - Gets or sets body stream. - - - - - Gets or sets kind of connection used for the session. - - - - - Gets or sets number of bytes in the body. - - - - - Gets headers sent by the client. - - - - - Gets or sets version of HTTP protocol that's used. - - - Probably or . - - - - - - Gets or sets requested method. - - - - Will always be in upper case. - - - - - - Gets variables sent in the query string - - - - - Gets or sets requested URI. - - - - - Uri absolute path splitted into parts. - - - // uri is: http://gauffin.com/code/tiny/ - Console.WriteLine(request.UriParts[0]); // result: code - Console.WriteLine(request.UriParts[1]); // result: tiny - - - If you're using controllers than the first part is controller name, - the second part is method name and the third part is Id property. - - - - - - Gets parameter from or . - - - - - Gets form parameters. - - - - - Gets whether the request was made by Ajax (Asynchronous JavaScript) - - - - - Gets cookies that was sent with the request. - - - - - Creates a new object that is a copy of the current instance. - - - - A new object that is a copy of this instance. - - 2 - - - - Decode body into a form. - - A list with form decoders. - If body contents is not valid for the chosen decoder. - If body is still being transferred. - - - - Cookies - - the cookies - - - - Create a response object. - - A new . - - - - Called during parsing of a . - - Name of the header, should not be URL encoded - Value of the header, should not be URL encoded - If a header is incorrect. - - - - Add bytes to the body - - buffer to read bytes from - where to start read - number of bytes to read - Number of bytes actually read (same as length unless we got all body bytes). - If body is not writable - bytes is null. - offset is out of range. - - - - Clear everything in the request - - - - - Response that is sent back to the web browser / client. - - - - A response can be sent if different ways. The easiest one is - to just fill the Body stream with content, everything else - will then be taken care of by the framework. The default content-type - is text/html, you should change it if you send anything else. - - The second and slightly more complex way is to send the response - as parts. Start with sending the header using the SendHeaders method and - then you can send the body using SendBody method, but do not forget - to set and before doing so. - - - - - // Example using response body. - class MyModule : HttpModule - { - public override bool Process(IHttpRequest request, IHttpResponse response, IHttpSession session) - { - StreamWriter writer = new StreamWriter(response.Body); - writer.WriteLine("Hello dear World!"); - writer.Flush(); - - // return true to tell webserver that we've handled the url - return true; - } - } - - - todo: add two examples, using SendHeaders/SendBody and just the Body stream. - - - - Initializes a new instance of the class. - - Client that send the . - Contains information of what the client want to receive. - cannot be empty. - - - - Initializes a new instance of the class. - - Client that send the . - Version of HTTP protocol that the client uses. - Type of HTTP connection used. - - - - The body stream is used to cache the body contents - before sending everything to the client. It's the simplest - way to serve documents. - - - - - The chunked encoding modifies the body of a message in order to - transfer it as a series of chunks, each with its own size indicator, - followed by an OPTIONAL trailer containing entity-header fields. This - allows dynamically produced content to be transferred along with the - information necessary for the recipient to verify that it has - received the full message. - - - - - Defines the version of the HTTP Response for applications where it's required - for this to be forced. - - - - - Kind of connection - - - - - Encoding to use when sending stuff to the client. - - Default is UTF8 - - - - Number of seconds to keep connection alive - - Only used if Connection property is set to . - - - - Status code that is sent to the client. - - Default is - - - - Information about why a specific status code was used. - - - - - Size of the body. MUST be specified before sending the header, - unless property Chunked is set to true. - - - - - Kind of content in the body - - Default type is "text/html" - - - - Headers have been sent to the client- - - You can not send any additional headers if they have already been sent. - - - - The whole response have been sent. - - - - - Cookies that should be created/changed. - - - - - Add another header to the document. - - Name of the header, case sensitive, use lower cases. - Header values can span over multiple lines as long as each line starts with a white space. New line chars should be \r\n - If headers already been sent. - If value conditions have not been met. - Adding any header will override the default ones and those specified by properties. - - - - Send headers and body to the browser. - - If content have already been sent. - - - - Make sure that you have specified and sent the headers first. - - - If headers have not been sent. - - offset of first byte to send - number of bytes to send. - - - This method can be used if you want to send body contents without caching them first. This - is recommended for larger files to keep the memory usage low. - - - - Make sure that you have specified and sent the headers first. - - - If headers have not been sent. - - - - This method can be used if you want to send body contents without caching them first. This - is recommended for larger files to keep the memory usage low. - - - - Send headers to the client. - - If headers already been sent. - - - - - - - Redirect client to somewhere else using the 302 status code. - - Destination of the redirect - If headers already been sent. - You can not do anything more with the request when a redirect have been done. This should be your last - action. - - - - redirect to somewhere - - where the redirect should go - - No body are allowed when doing redirects. - - - - - Delegate used to find a realm/domain. - - - - - Realms are used during HTTP Authentication - - - - - - - A complete HTTP server, you need to add a module to it to be able to handle incoming requests. - - - - // this small example will add two web site modules, thus handling - // two different sites. In reality you should add Controller modules or something - // two the website modules to be able to handle different requests. - HttpServer server = new HttpServer(); - server.Add(new WebSiteModule("www.gauffin.com", "Gauffin Telecom AB")); - server.Add(new WebSiteModule("www.vapadi.se", "Remote PBX")); - - // start regular http - server.Start(IPAddress.Any, 80); - - // start https - server.Start(IPAddress.Any, 443, myCertificate); - - - - - - - - - Server that is handling the current request. - - - Will be set as soon as a request arrives to the object. - - - - - Initializes a new instance of the class. - - Used to get all components used in the server.. - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the class. - - Form decoders are used to convert different types of posted data to the object types. - - - - - - Initializes a new instance of the class. - - A session store is used to save and retrieve sessions - - - - - Initializes a new instance of the class. - - The log writer. - - - - - Initializes a new instance of the class. - - Form decoders are used to convert different types of posted data to the object types. - The log writer. - - - - - - - Initializes a new instance of the class. - - Form decoders are used to convert different types of posted data to the object types. - A session store is used to save and retrieve sessions - The log writer. - - - - - - - - Modules used for authentication. The module that is is added first is used as - the default authentication module. - - Use the corresponding property - in the if you are using multiple websites. - - - - Form decoder providers are used to decode request body (which normally contains form data). - - - - - Server name sent in HTTP responses. - - - Do NOT include version in name, since it makes it - easier for hackers. - - - - - Name of cookie where session id is stored. - - - - - Specified where logging should go. - - - - - - - - Number of connections that can wait to be accepted by the server. - - Default is 10. - - - - Gets or sets maximum number of allowed simultaneous requests. - - - - This property is useful in busy systems. The HTTP server - will start queuing new requests if this limit is hit, instead - of trying to process all incoming requests directly. - - - The default number if allowed simultaneous requests are 10. - - - - - - Gets or sets maximum number of requests queuing to be handled. - - - - The WebServer will start turning requests away if response code - to indicate that the server - is too busy to be able to handle the request. - - - - - - Adds the specified rule. - - The rule. - - - - Add a to the server. - - mode to add - - - - Decodes the request body. - - The request. - Failed to decode form data. - - - - Generate a HTTP error page (that will be added to the response body). - response status code is also set. - - Response that the page will be generated in. - . - response body contents. - - - - Generate a HTTP error page (that will be added to the response body). - response status code is also set. - - Response that the page will be generated in. - exception. - - - - Realms are used by the s. - - HTTP request - domain/realm. - - - - Process an incoming request. - - connection to client - request information - response that should be filled - session information - - - - Can be overloaded to implement stuff when a client have been connected. - - - Default implementation does nothing. - - client that disconnected - disconnect reason - - - - Handle authentication - - - - - true if request can be handled; false if not. - Invalid authorization header - - - - Will request authentication. - - - Sends respond to client, nothing else can be done with the response after this. - - - - - - - - Received from a when a request have been parsed successfully. - - that received the request. - The request. - - - - To be able to track request count. - - - - - - - Start the web server using regular HTTP. - - IP Address to listen on, use IpAddress.Any to accept connections on all IP addresses/network cards. - Port to listen on. 80 can be a good idea =) - address is null. - Port must be a positive number. - - - - Accept secure connections. - - IP Address to listen on, use to accept connections on all IP Addresses / network cards. - Port to listen on. 80 can be a good idea =) - Certificate to use - address is null. - Port must be a positive number. - - - - shut down the server and listeners - - - - - write an entry to the log file - - importance of the message - log message - - - - write an entry to the log file - - object that wrote the message - importance of the message - log message - - - - Realms are used during HTTP authentication. - Default realm is same as server name. - - - - - Let's to receive unhandled exceptions from the threads. - - - Exceptions will be thrown during debug mode if this event is not used, - exceptions will be printed to console and suppressed during release mode. - - - - - Inversion of control interface. - - - - - Add a component instance - - Interface type - Instance to add - - - - Get a component. - - Interface type - Component if registered, otherwise null. - - Component will get created if needed. - - - - - Checks if the specified component interface have been added. - - - true if found; otherwise false. - - - - Add a component. - - Type being requested. - Type being created. - - - - Contains a connection to a browser/client. - - - - - Using SSL or other encryption method. - - - - - Using SSL or other encryption method. - - - - - Disconnect from client - - error to report in the event. - - - - Send a response. - - Either or - HTTP status code - reason for the status code. - HTML body contents, can be null or empty. - A content type to return the body as, i.e. 'text/html' or 'text/plain', defaults to 'text/html' if null or empty - If is invalid. - - - - Send a response. - - Either or - HTTP status code - reason for the status code. - - - - Send a response. - - - - - - send a whole buffer - - buffer to send - - - - - Send data using the stream - - Contains data to send - Start position in buffer - number of bytes to send - - - - - - Closes the streams and disposes of the unmanaged resources - - - - - The context have been disconnected. - - - Event can be used to clean up a context, or to reuse it. - - - - - A request have been received in the context. - - - - - A have been disconnected. - - - - - Gets reason to why client disconnected. - - - - - Initializes a new instance of the class. - - Reason to disconnection. - - - - - - - - - Gets received request. - - - - - Initializes a new instance of the class. - - The request. - - - - Class that receives Requests from a . - - - - - Client have been disconnected. - - Client that was disconnected. - Reason - - - - - Invoked when a client context have received a new HTTP request - - Client that received the request. - Request that was received. - - - - - Contains server side HTTP request information. - - - - - Gets kind of types accepted by the client. - - - - - Gets or sets body stream. - - - - - Gets whether the body is complete. - - - - - Gets or sets kind of connection used for the session. - - - - - Gets or sets number of bytes in the body. - - - - - Gets cookies that was sent with the request. - - - - - Gets form parameters. - - - - - Gets headers sent by the client. - - - - - Gets or sets version of HTTP protocol that's used. - - - Probably or . - - - - - - Gets whether the request was made by Ajax (Asynchronous JavaScript) - - - - - Gets or sets requested method. - - - Will always be in upper case. - - - - - - Gets parameter from or . - - - - - Gets variables sent in the query string - - - - - Gets or sets requested URI. - - - - - Gets URI absolute path divided into parts. - - - // URI is: http://gauffin.com/code/tiny/ - Console.WriteLine(request.UriParts[0]); // result: code - Console.WriteLine(request.UriParts[1]); // result: tiny - - - If you're using controllers than the first part is controller name, - the second part is method name and the third part is Id property. - - - - - - Gets or sets path and query. - - - - Are only used during request parsing. Cannot be set after "Host" header have been - added. - - - - - Called during parsing of a . - - Name of the header, should not be URL encoded - Value of the header, should not be URL encoded - If a header is incorrect. - - - - Add bytes to the body - - buffer to read bytes from - where to start read - number of bytes to read - Number of bytes actually read (same as length unless we got all body bytes). - If body is not writable - bytes is null. - offset is out of range. - - - - Clear everything in the request - - - - - Decode body into a form. - - A list with form decoders. - If body contents is not valid for the chosen decoder. - If body is still being transferred. - - - - Sets the cookies. - - The cookies. - - - - Create a response object. - - Context for the connected client. - A new . - - - - Event driven parser used to parse incoming HTTP requests. - - - The parser supports partial messages and keeps the states between - each parsed buffer. It's therefore important that the parser gets - ed if a client disconnects. - - - - - Current state in parser. - - - - - Parse partial or complete message. - - buffer containing incoming bytes - where in buffer that parsing should start - number of bytes to parse - Unparsed bytes left in buffer. - BadRequestException. - - - - A request have been successfully parsed. - - - - - More body bytes have been received. - - - - - Request line have been received. - - - - - A header have been received. - - - - - Clear parser state. - - - - - Gets or sets the log writer. - - - - - Current state in the parsing. - - - - - Should parse the request line - - - - - Searching for a complete header name - - - - - Searching for colon after header name (ignoring white spaces) - - - - - Searching for start of header value (ignoring white spaces) - - - - - Searching for a complete header value (can span over multiple lines, as long as they are prefixed with one/more whitespaces) - - - - - Adding bytes to body - - - - - Response that is sent back to the web browser / client. - - A response can be sent if different ways. The easiest one is - to just fill the Body stream with content, everything else - will then be taken care of by the framework. The default content-type - is text/html, you should change it if you send anything else. - - The second and slighty more complex way is to send the response - as parts. Start with sending the header using the SendHeaders method and - then you can send the body using SendBody method, but do not forget - to set ContentType and ContentLength before doing so. - - - public void MyHandler(IHttpRequest request, IHttpResponse response) - { - - } - - - - - The body stream is used to cache the body contents - before sending everything to the client. It's the simplest - way to serve documents. - - - - - Defines the version of the HTTP Response for applications where it's required - for this to be forced. - - - - - The chunked encoding modifies the body of a message in order to - transfer it as a series of chunks, each with its own size indicator, - followed by an OPTIONAL trailer containing entity-header fields. This - allows dynamically produced content to be transferred along with the - information necessary for the recipient to verify that it has - received the full message. - - - - - Kind of connection - - - - - Encoding to use when sending stuff to the client. - - Default is UTF8 - - - - Number of seconds to keep connection alive - - Only used if Connection property is set to ConnectionType.KeepAlive - - - - Status code that is sent to the client. - - Default is HttpStatusCode.Ok - - - - Information about why a specific status code was used. - - - - - Size of the body. MUST be specified before sending the header, - unless property Chunked is set to true. - - - - - Kind of content in the body - - Default is text/html - - - - Headers have been sent to the client- - - You can not send any additional headers if they have already been sent. - - - - The whole response have been sent. - - - - - Cookies that should be created/changed. - - - - - Add another header to the document. - - Name of the header, case sensitive, use lower cases. - Header values can span over multiple lines as long as each line starts with a white space. New line chars should be \r\n - If headers already been sent. - If value conditions have not been met. - Adding any header will override the default ones and those specified by properties. - - - - Send headers and body to the browser. - - If content have already been sent. - - - - Make sure that you have specified ContentLength and sent the headers first. - - - If headers have not been sent. - - offest of first byte to send - number of bytes to send. - - - This method can be used if you want to send body contents without caching them first. This - is recommended for larger files to keep the memory usage low. - - - - Make sure that you have specified ContentLength and sent the headers first. - - - If headers have not been sent. - - - - This method can be used if you want to send body contents without caching them first. This - is recommended for larger files to keep the memory usage low. - - - - Send headers to the client. - - If headers already been sent. - - - - - - - Redirect client to somewhere else using the 302 status code. - - Destination of the redirect - If headers already been sent. - You can not do anything more with the request when a redirect have been done. This should be your last - action. - - - - redirect to somewhere - - where the redirect should go - - No body are allowed when doing redirects. - - - - - Type of HTTP connection - - - - - Connection is closed after each request-response - - - - - Connection is kept alive for X seconds (unless another request have been made) - - - - - Priority for log entries - - - - - - Very detailed logs to be able to follow the flow of the program. - - - - - Logs to help debug errors in the application - - - - - Information to be able to keep track of state changes etc. - - - - - Something did not go as we expected, but it's no problem. - - - - - Something that should not fail failed, but we can still keep - on going. - - - - - Something failed, and we cannot handle it properly. - - - - - Interface used to write to log files. - - - - - Write an entry to the log file. - - object that is writing to the log - importance of the log message - the message - - - - This class writes to the console. It colors the output depending on the logprio and includes a 3-level stacktrace (in debug mode) - - - - - - The actual instance of this class. - - - - - Logwriters the specified source. - - object that wrote the logentry. - Importance of the log message - The message. - - - - Get color for the specified logprio - - prio for the log entry - A for the prio - - - - Default log writer, writes everything to null (nowhere). - - - - - - The logging instance. - - - - - Writes everything to null - - object that wrote the log entry. - Importance of the log message - The message. - - - - A thread-safe lockless queue that supports multiple readers and - multiple writers - - - - - Provides a node container for data in a singly linked list - - - - Pointer to the next node in list - - - The data contained by the node - - - - Constructor - - - - - Constructor - - - - Queue head - - - Queue tail - - - Queue item count - - - Gets the current number of items in the queue. Since this - is a lockless collection this value should be treated as a close - estimate - - - - Constructor - - - - - Enqueue an item - - Item to enqeue - - - - Try to dequeue an item - - Dequeued item if the dequeue was successful - True if an item was successfully deqeued, otherwise false - - - - Contains all HTTP Methods (according to the HTTP 1.1 specification) - - See: http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html - - - - - - The DELETE method requests that the origin server delete the resource identified by the Request-URI. - - - - This method MAY be overridden by human intervention (or other means) on the origin server. - The client cannot be guaranteed that the operation has been carried out, even if the status code - returned from the origin server indicates that the action has been completed successfully. - - - However, the server SHOULD NOT indicate success unless, at the time the response is given, - it intends to delete the resource or move it to an inaccessible location. - - - A successful response SHOULD be 200 (OK) if the response includes an entity describing the status, - 202 (Accepted) if the action has not yet been enacted, - or 204 (No Content) if the action has been enacted but the response does not include an entity. - - - If the request passes through a cache and the Request-URI identifies one or more currently cached entities, - those entries SHOULD be treated as stale. Responses to this method are not cacheable. - - - - - - The GET method means retrieve whatever information (in the form of an entity) is identified by the Request-URI. - - - - If the Request-URI refers to a data-producing process, it is the produced data which shall be returned as the - entity in the response and not the source text of the process, unless that text happens to be the output of the process. - - - The semantics of the GET method change to a "conditional GET" if the request message includes an - If-Modified-Since, If-Unmodified-Since, If-Match, If-None-Match, or If-Range header field. - A conditional GET method requests that the entity be transferred only under the circumstances described - by the conditional header field(s). The conditional GET method is intended to reduce unnecessary network - usage by allowing cached entities to be refreshed without requiring multiple requests or transferring - data already held by the client. - - - - - - The HEAD method is identical to GET except that the server MUST NOT return a message-body in the response. - - - The meta information contained in the HTTP headers in response to a HEAD request SHOULD be identical to the - information sent in response to a GET request. This method can be used for obtaining meta information about - the entity implied by the request without transferring the entity-body itself. - - This method is often used for testing hypertext links for validity, accessibility, and recent modification. - - - - - The OPTIONS method represents a request for information about the communication options available on the request/response chain identified by the Request-URI. - - - This method allows the client to determine the options and/or requirements associated with a resource, or the capabilities of a server, without implying a resource action or initiating a resource retrieval. - - - - - The POST method is used to request that the origin server accept the entity enclosed - in the request as a new subordinate of the resource identified by the Request-URI in the Request-Line. - - - POST is designed to allow a uniform method to cover the following functions: - - - Annotation of existing resources; - - Posting a message to a bulletin board, newsgroup, mailing list, or similar group of articles; - - Providing a block of data, such as the result of submitting a form, to a data-handling process; - - Extending a database through an append operation. - - - - If a resource has been created on the origin server, the response SHOULD be 201 (Created) and - contain an entity which describes the status of the request and refers to the new resource, and a - Location header (see section 14.30). - - - The action performed by the POST method might not result in a resource that can be identified by a URI. - In this case, either 200 (OK) or 204 (No Content) is the appropriate response status, depending on - whether or not the response includes an entity that describes the result. - - Responses to this method are not cacheable, unless the response includes appropriate Cache-Control - or Expires header fields. However, the 303 (See Other) response can be used to direct the user agent - to retrieve a cacheable resource. - - - - - - The PUT method requests that the enclosed entity be stored under the supplied Request-URI. - - - - - If the Request-URI refers to an already existing resource, the enclosed entity SHOULD be considered as a - modified version of the one residing on the origin server. - - If the Request-URI does not point to an existing resource, and that URI is capable of being defined as a new - resource by the requesting user agent, the origin server can create the resource with that URI. - - If a new resource is created, the origin server MUST inform the user agent via the 201 (Created) response. - - If an existing resource is modified, either the 200 (OK) or 204 (No Content) response codes SHOULD be sent to - indicate successful completion of the request. - - If the resource could not be created or modified with the Request-URI, an appropriate error response SHOULD be - given that reflects the nature of the problem. - - - - The recipient of the entity MUST NOT ignore any Content-* (e.g. Content-Range) headers that it does not - understand or implement and MUST return a 501 (Not Implemented) response in such cases. - - - - - - The TRACE method is used to invoke a remote, application-layer loop- back of the request message. - - - - - Contains all HTTP Methods (according to the HTTP 1.1 specification) - - See: http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html - - - - - - The DELETE method requests that the origin server delete the resource identified by the Request-URI. - - - - This method MAY be overridden by human intervention (or other means) on the origin server. - The client cannot be guaranteed that the operation has been carried out, even if the status code - returned from the origin server indicates that the action has been completed successfully. - - - However, the server SHOULD NOT indicate success unless, at the time the response is given, - it intends to delete the resource or move it to an inaccessible location. - - - A successful response SHOULD be 200 (OK) if the response includes an entity describing the status, - 202 (Accepted) if the action has not yet been enacted, - or 204 (No Content) if the action has been enacted but the response does not include an entity. - - - If the request passes through a cache and the Request-URI identifies one or more currently cached entities, - those entries SHOULD be treated as stale. Responses to this method are not cacheable. - - - - - - The GET method means retrieve whatever information (in the form of an entity) is identified by the Request-URI. - - - - If the Request-URI refers to a data-producing process, it is the produced data which shall be returned as the - entity in the response and not the source text of the process, unless that text happens to be the output of the process. - - - The semantics of the GET method change to a "conditional GET" if the request message includes an - If-Modified-Since, If-Unmodified-Since, If-Match, If-None-Match, or If-Range header field. - A conditional GET method requests that the entity be transferred only under the circumstances described - by the conditional header field(s). The conditional GET method is intended to reduce unnecessary network - usage by allowing cached entities to be refreshed without requiring multiple requests or transferring - data already held by the client. - - - - - - The HEAD method is identical to GET except that the server MUST NOT return a message-body in the response. - - - The meta information contained in the HTTP headers in response to a HEAD request SHOULD be identical to the - information sent in response to a GET request. This method can be used for obtaining meta information about - the entity implied by the request without transferring the entity-body itself. - - This method is often used for testing hypertext links for validity, accessibility, and recent modification. - - - - - The OPTIONS method represents a request for information about the communication options available on the request/response chain identified by the Request-URI. - - - This method allows the client to determine the options and/or requirements associated with a resource, or the capabilities of a server, without implying a resource action or initiating a resource retrieval. - - - - - The POST method is used to request that the origin server accept the entity enclosed - in the request as a new subordinate of the resource identified by the Request-URI in the Request-Line. - - - POST is designed to allow a uniform method to cover the following functions: - - - Annotation of existing resources; - - Posting a message to a bulletin board, newsgroup, mailing list, or similar group of articles; - - Providing a block of data, such as the result of submitting a form, to a data-handling process; - - Extending a database through an append operation. - - - - If a resource has been created on the origin server, the response SHOULD be 201 (Created) and - contain an entity which describes the status of the request and refers to the new resource, and a - Location header (see section 14.30). - - - The action performed by the POST method might not result in a resource that can be identified by a URI. - In this case, either 200 (OK) or 204 (No Content) is the appropriate response status, depending on - whether or not the response includes an entity that describes the result. - - Responses to this method are not cacheable, unless the response includes appropriate Cache-Control - or Expires header fields. However, the 303 (See Other) response can be used to direct the user agent - to retrieve a cacheable resource. - - - - - - The PUT method requests that the enclosed entity be stored under the supplied Request-URI. - - - - - If the Request-URI refers to an already existing resource, the enclosed entity SHOULD be considered as a - modified version of the one residing on the origin server. - - If the Request-URI does not point to an existing resource, and that URI is capable of being defined as a new - resource by the requesting user agent, the origin server can create the resource with that URI. - - If a new resource is created, the origin server MUST inform the user agent via the 201 (Created) response. - - If an existing resource is modified, either the 200 (OK) or 204 (No Content) response codes SHOULD be sent to - indicate successful completion of the request. - - If the resource could not be created or modified with the Request-URI, an appropriate error response SHOULD be - given that reflects the nature of the problem. - - - - The recipient of the entity MUST NOT ignore any Content-* (e.g. Content-Range) headers that it does not - understand or implement and MUST return a 501 (Not Implemented) response in such cases. - - - - - - The TRACE method is used to invoke a remote, application-layer loop- back of the request message. - - - - - Arguments used when more body bytes have come. - - - - - Initializes a new instance of the class. - - buffer that contains the received bytes. - offset in buffer where to start processing. - number of bytes from that should be parsed. - - - - Initializes a new instance of the class. - - - - - Gets or sets buffer that contains the received bytes. - - - - - Gets or sets number of bytes from that should be parsed. - - - - - Gets or sets offset in buffer where to start processing. - - - - - Event arguments used when a new header have been parsed. - - - - - Initializes a new instance of the class. - - Name of header. - Header value. - - - - Initializes a new instance of the class. - - - - - Gets or sets header name. - - - - - Gets or sets header value. - - - - - Parses a HTTP request directly from a stream - - - - - Create a new request parser - - delegate receiving log entries. - - - - Add a number of bytes to the body - - buffer containing more body bytes. - starting offset in buffer - number of bytes, from offset, to read. - offset to continue from. - - - - Remove all state information for the request. - - - - - Gets or sets the log writer. - - - - - Parse request line - - - If line is incorrect - Expects the following format: "Method SP Request-URI SP HTTP-Version CRLF" - - - - We've parsed a new header. - - Name in lower case - Value, unmodified. - If content length cannot be parsed. - - - - Current state in parser. - - - - - Parse a message - - bytes to parse. - where in buffer that parsing should start - number of bytes to parse, starting on . - offset (where to start parsing next). - BadRequestException. - - - - A request have been successfully parsed. - - - - - More body bytes have been received. - - - - - Request line have been received. - - - - - A header have been received. - - - - - Used when the request line have been successfully parsed. - - - - - Initializes a new instance of the class. - - The HTTP method. - The URI path. - The HTTP version. - - - - Initializes a new instance of the class. - - - - - Gets or sets http method. - - - Should be one of the methods declared in . - - - - - Gets or sets the version of the HTTP protocol that the client want to use. - - - - - Gets or sets requested URI path. - - - - - Creates request parsers when needed. - - - - - Create a new request parser. - - Used when logging should be enabled. - A new request parser. - - - - Creates request parsers when needed. - - - - - Create a new request parser. - - Used when logging should be enabled. - A new request parser. - - - - cookie sent by the client/browser - - - - - - Constructor. - - cookie identifier - cookie content - id or content is null - id is empty - - - - Gets the cookie HTML representation. - - cookie string - - - - Gets the cookie identifier. - - - - - Cookie value. Set to null to remove cookie. - - - - - This class is created as a wrapper, since there are two different cookie types in .Net (Cookie and HttpCookie). - The framework might switch class in the future and we dont want to have to replace all instances - - - - - Let's copy all the cookies. - - value from cookie header. - - - - Adds a cookie in the collection. - - cookie to add - cookie is null - - - - Gets the count of cookies in the collection. - - - - - Gets the cookie of a given identifier (null if not existing). - - - - - Gets a collection enumerator on the cookie list. - - collection enumerator - - - - Remove all cookies. - - - - - Returns an enumerator that iterates through the collection. - - - - A that can be used to iterate through the collection. - - 1 - - - - Remove a cookie from the collection. - - Name of cookie. - - - - Used to queue incoming requests. - - - - - Initializes a new instance of the class. - - Called when a request should be processed. - - - - Used two queue incoming requests to avoid - thread starvation. - - - - - Gets or sets maximum number of allowed simultaneous requests. - - - - - Gets or sets maximum number of requests queuing to be handled. - - - - - Specifies how many requests the HTTP server is currently processing. - - - - - Used to process queued requests. - - - - - Method used to process a queued request - - Context that the request was received from. - Request to process. - - - - cookie being sent back to the browser. - - - - - - Constructor. - - cookie identifier - cookie content - cookie expiration date. Use DateTime.MinValue for session cookie. - id or content is null - id is empty - - - - Create a new cookie - - name identifying the cookie - cookie value - when the cookie expires. Setting DateTime.MinValue will delete the cookie when the session is closed. - Path to where the cookie is valid - Domain that the cookie is valid for. - - - - Create a new cookie - - Name and value will be used - when the cookie expires. - - - - Gets the cookie HTML representation. - - cookie string - - - - When the cookie expires. - DateTime.MinValue means that the cookie expires when the session do so. - - - - - Cookie is only valid under this path. - - - - - Cookies that should be set. - - - - - Adds a cookie in the collection. - - cookie to add - cookie is null - - - - Copy a request cookie - - - When the cookie should expire - - - - Gets the count of cookies in the collection. - - - - - Gets the cookie of a given identifier (null if not existing). - - - - - Gets a collection enumerator on the cookie list. - - collection enumerator - - - - Remove all cookies - - - - - Returns an enumerator that iterates through the collection. - - - - A that can be used to iterate through the collection. - - 1 - - - - Rules are used to perform operations before a request is being handled. - Rules can be used to create routing etc. - - - - - Process the incoming request. - - incoming HTTP request - outgoing HTTP response - true if response should be sent to the browser directly (no other rules or modules will be processed). - - returning true means that no modules will get the request. Returning true is typically being done - for redirects. - - If request or response is null. - - - - redirects from one URL to another. - - - - - Initializes a new instance of the class. - - Absolute path (no server name) - Absolute path (no server name) - - server.Add(new RedirectRule("/", "/user/index")); - - - - - Initializes a new instance of the class. - - Absolute path (no server name) - Absolute path (no server name) - true if request should be redirected, false if the request URI should be replaced. - - server.Add(new RedirectRule("/", "/user/index")); - - - - - Gets string to match request URI with. - - Is compared to request.Uri.AbsolutePath - - - - Gets where to redirect. - - - - - Gets whether server should redirect client. - - - false means that the rule will replace - the current request URI with the new one from this class. - true means that a redirect response is sent to the client. - - - - - Process the incoming request. - - incoming HTTP request - outgoing HTTP response - true if response should be sent to the browser directly (no other rules or modules will be processed). - - returning true means that no modules will get the request. Returning true is typically being done - for redirects. - - - - - Class to make dynamic binding of redirects. Instead of having to specify a number of similar redirect rules - a regular expression can be used to identify redirect URLs and their targets. - - - [a-z0-9]+)", "/users/${target}?find=true", RegexOptions.IgnoreCase) - ]]> - - - - - Initializes a new instance of the class. - - Expression to match URL - Expression to generate URL - - [a-zA-Z0-9]+)", "/user/${first}")); - Result of ie. /employee1 will then be /user/employee1 - ]]> - - - - - Initializes a new instance of the class. - - Expression to match URL - Expression to generate URL - Regular expression options to use, can be null - - [a-zA-Z0-9]+)", "/user/{first}", RegexOptions.IgnoreCase)); - Result of ie. /employee1 will then be /user/employee1 - ]]> - - - - - Initializes a new instance of the class. - - Expression to match URL - Expression to generate URL - Regular expression options to apply - true if request should be redirected, false if the request URI should be replaced. - - [a-zA-Z0-9]+)", "/user/${first}", RegexOptions.None)); - Result of ie. /employee1 will then be /user/employee1 - ]]> - - Argument is null. - - - - - Process the incoming request. - - incoming HTTP request - outgoing HTTP response - true if response should be sent to the browser directly (no other rules or modules will be processed). - - returning true means that no modules will get the request. Returning true is typically being done - for redirects. - - If request or response is null - - - - Interface for sessions - - - - - Session id - - - - - Should - - Name of the session variable - null if it's not set - If the object cant be serialized. - - - - When the session was last accessed. - This property is touched by the http server each time the - session is requested. - - - - - Number of session variables. - - - - - Remove everything from the session - - - - - Remove everything from the session - - True if the session is cleared due to expiration - - - - Event triggered upon clearing the session - - - - - Arguments sent when a is cleared - - - - - Instantiates the arguments for the event - - True if the session is cleared due to expiration - - - - Returns true if the session is cleared due to expiration - - - - - Delegate for when a IHttpSession is cleared - - this is being cleared. - Arguments for the clearing - - - - A session store is used to store and load sessions on a media. - The default implementation () saves/retrieves sessions from memory. - - - - - Load a session from the store - - - null if session is not found. - - - - Number of minutes before a session expires. - - Default time is 20 minutes. - - - - Creates a new http session with a generated id. - - A object - - - - Creates a new http session with a specific id - - Id used to identify the new cookie.. - A object. - - Id should be generated by the store implementation if it's null or . - - - - - Load an existing session. - - Session id (usually retrieved from a client side cookie). - A session if found; otherwise null. - - - - Save an updated session to the store. - - Session id (usually retrieved from a client side cookie). - If Id property have not been specified. - - - - We use the flyweight pattern which reuses small objects - instead of creating new each time. - - Unused session that should be reused next time Create is called. - - - - Remove expired sessions - - - - - Remove a session - - id of the session. - - - - A session stored in memory. - - - - - - - A unique id used by the sessions store to identify the session - - - - Id - - - - - - Session id - - - - - Should - - Name of the session variable - null if it's not set - - - - when the session was last accessed. - - - Used to determine when the session should be removed. - - - - - Number of values in the session - - - - - Flag to indicate that the session have been changed - and should be saved into the session store. - - - - - Remove everything from the session - - - - - Clears the specified expire. - - True if the session is cleared due to expiration - - - - Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. - - 2 - - - - Event triggered upon clearing the session - - - - - Session store using memory for each session. - - - - - Initializes the class setting the expirationtimer to clean the session every minute - - - - - Delegate for the cleanup timer - - - - - Load a session from the store - - - null if session is not found. - - - - Creates a new http session - - - - - - Creates a new http session with a specific id - - Id used to identify the new cookie.. - A object. - - Id should be generated by the store implementation if it's null or . - - - - - Load an existing session. - - - - - - - Save an updated session to the store. - - - - - - We use the flyweight pattern which reuses small objects - instead of creating new each time. - - EmptyLanguageNode (unused) session that should be reused next time Create is called. - - - - Remove expired sessions - - - - - Remove a session - - id of the session. - - - - Number of minutes before a session expires. - Default is 20 minutes. - - - - diff --git a/bin/ICSharpCode.SharpZipLib.dll b/bin/ICSharpCode.SharpZipLib.dll index fe643ebc63..3b268b7c6e 100644 Binary files a/bin/ICSharpCode.SharpZipLib.dll and b/bin/ICSharpCode.SharpZipLib.dll differ diff --git a/bin/Ionic.Zip.dll b/bin/Ionic.Zip.dll index e37f1bdea5..ce50258752 100755 Binary files a/bin/Ionic.Zip.dll and b/bin/Ionic.Zip.dll differ diff --git a/bin/LukeSkywalker.IPNetwork.dll b/bin/LukeSkywalker.IPNetwork.dll index 25bcc2f5f3..91449390fa 100755 Binary files a/bin/LukeSkywalker.IPNetwork.dll and b/bin/LukeSkywalker.IPNetwork.dll differ diff --git a/bin/Mono.Addins.CecilReflector.dll b/bin/Mono.Addins.CecilReflector.dll index bbda91deb1..8fd9ad76fb 100755 Binary files a/bin/Mono.Addins.CecilReflector.dll and b/bin/Mono.Addins.CecilReflector.dll differ diff --git a/bin/Mono.Addins.Setup.dll b/bin/Mono.Addins.Setup.dll index 68c31211b3..a2b3598cf0 100755 Binary files a/bin/Mono.Addins.Setup.dll and b/bin/Mono.Addins.Setup.dll differ diff --git a/bin/Mono.Addins.Setup.xml b/bin/Mono.Addins.Setup.xml deleted file mode 100644 index f5ce70a0b0..0000000000 --- a/bin/Mono.Addins.Setup.xml +++ /dev/null @@ -1,1140 +0,0 @@ - - - - Mono.Addins.Setup - - - - - An IAddinInstaller implementation which interacts with the user through the console - - - - - Initializes a new instance of the class. - - - - - Gets or sets whether the installer can ask questions to the user - - - - - Log level (0:normal, 1+:verbose); - - - - - An add-in package - - - - - Creates a package object for an add-in available in an on-line repository - - - An add-in reference - - - The package - - - - - Creates a package object for a local package file - - - Package file path - - - The package - - - - - Name of the package - - - - - Returns true if the package will be installed in the shared directory, - false if it will be installed in the user directory. - - - - - A reference to an add-in available in an on-line repository - - - - - Begins downloading a support file - - - Result of the asynchronous operation, to be used when calling EndDownloadSupportFile to - get the download result. - - - Name of the file. - - - Callback to be called when the download operation ends. - - - Custom state object provided by the caller. - - - This method can be used to get the contents of a support file of an add-in. - A support file is a file referenced in the custom properties of an add-in. - - - - - Gets the result of the asynchronous download of a file - - - The downloaded file. - - - The async result object returned by BeginDownloadSupportFile. - - - - - Add-in information - - - - - Url to the add-in package - - - - - The URL of the repository - - - - - Name of the repository - - - - - An installation exception - - - - - Initializes the exception - - - Error message - - - - - Initializes the exception - - - Error message - - - Inner exception - - - - - A command line add-in manager. - - - This class can be used to provide an add-in management command line tool to applications. - - - - - Creates a new instance - - - Add-in registry to manage. - - - - - Runs the command line tool. - - - Array that contains the command line arguments - - - Index of the arguments array that has the first argument for the management tool - - - 0 if it succeeds. != 0 otherwise - - - - - Runs the command line tool. - - - Command line arguments - - - 0 if it succeeds. != 0 otherwise - - - - - Adds a custom command to the add-in manager - - - Category under which the command has to be shown in the help text - - - Name of the command - - - Short name of the command (it's an alias of the normal name) - - - Formal description of the arguments that the command accepts. For example: "[addin-id|addin-file] [--xml] [--all] [--full] [--namespace <namespace>]" - - - Short description of the command - - - Long description of the command - - - Delegate to be invoked to run the command - - - - - Prints help about the add-in management tool, or about a specific command - - - Optional command name and arguments - - - - - Display name of the host application - - - - - Default add-in namespace of the application (optional). If set, only add-ins that belong to that namespace - will be shown in add-in lists. - - - - - Enables or disables verbose output - - - - - Sets or gets the verbose output level (0: normal output, 1:verbose, 2+:extra verbose) - - - - - A command handler - - - - - A collection of packages - - - - - Initializes a new instance of the class. - - - - - Copy constructor - - - Collection where to copy from - - - - - Adds a package - - - A package - - - - - Checks if a package is present in the collection - - - The package - - - True if the package is preent - - - - - Adds a list of packages to the collection - - - The list of packages to add - - - - - Gets a package - - - Package index - - - - - Basic add-in information - - - - - Compares the versions of two add-ins - - - Another add-in - - - Result of comparison - - - - - Full identifier of the add-in - - - - - Display name of the add-in - - - - - Namespace of the add-in - - - - - Version of the add-in - - - - - Version with which this add-in is compatible - - - - - Add-in author - - - - - Add-in copyright - - - - - Web page URL with more information about the add-in - - - - - Description of the add-in - - - - - Category of the add-in - - - - - Dependencies of the add-in - - - - - Optional dependencies of the add-in - - - - - Custom properties specified in the add-in header - - - - - A registry of on-line repositories - - - This class can be used to manage on-line repository subscriptions. - - - - - Subscribes to an on-line repository - - - Progress monitor where to show progress status and log - - - URL of the repository - - - A repository reference - - - The repository index is not downloaded by default. It can be downloaded - by calling UpdateRepository. - - - - - Subscribes to an on-line repository - - - Progress monitor where to show progress status and log - - - URL of the repository - - - When set to True, the repository index will be downloaded. - - - A repository reference - - - - - Removes an on-line repository subscription. - - - URL of the repository. - - - - - Enables or disables a repository - - - URL of the repository - - - 'true' if the repository has to be enabled. - - - Disabled repositories are ignored when calling UpdateAllRepositories. - - - - - Checks if a repository is already subscribed. - - - URL of the repository - - - True if the repository is already subscribed. - - - - - Gets a list of subscribed repositories - - - A list of repositories. - - - - - Updates the add-in index of all subscribed repositories. - - - Progress monitor where to show progress status and log - - - - - Updates the add-in index of the provided repository - - - Progress monitor where to show progress status and log - - - URL of the repository - - - - - Gets a list of available add-in updates. - - - A list of add-in references. - - - The list is generated by looking at the add-ins currently installed and checking if there is any - add-in with a newer version number in any of the subscribed repositories. This method uses cached - information from on-line repositories. Make sure you call UpdateRepository or UpdateAllRepositories - before using this method to ensure that the latest information is available. - - - - - Gets a list of available add-in updates. - - - Search flags - - - A list of add-in references. - - - The list is generated by looking at the add-ins currently installed and checking if there is any - add-in with a newer version number in any of the subscribed repositories. This method uses cached - information from on-line repositories. Make sure you call UpdateRepository or UpdateAllRepositories - before using this method to ensure that the latest information is available. - - - - - Gets a list of available add-in updates in a specific repository. - - - The repository URL - - - A list of add-in references. - - - The list is generated by looking at the add-ins currently installed and checking if there is any - add-in with a newer version number in the provided repository. This method uses cached - information from on-line repositories. Make sure you call UpdateRepository or UpdateAllRepositories - before using this method to ensure that the latest information is available. - - - - - Gets a list of available updates for an add-in. - - - Identifier of the add-in. - - - List of updates for the specified add-in. - - - The list is generated by checking if there is any - add-in with a newer version number in any of the subscribed repositories. This method uses cached - information from on-line repositories. Make sure you call UpdateRepository or UpdateAllRepositories - before using this method to ensure that the latest information is available. - - - - - Gets a list of available updates for an add-in. - - - Identifier of the add-in. - - - Search flags. - - - List of updates for the specified add-in. - - - The list is generated by checking if there is any - add-in with a newer version number in any of the subscribed repositories. This method uses cached - information from on-line repositories. Make sure you call UpdateRepository or UpdateAllRepositories - before using this method to ensure that the latest information is available. - - - - - Gets a list of available updates for an add-in in a specific repository - - - Identifier of the add-in. - - - Identifier of the add-in. - - - List of updates for the specified add-in. - - - The list is generated by checking if there is any - add-in with a newer version number in the provided repository. This method uses cached - information from on-line repositories. Make sure you call UpdateRepository or UpdateAllRepositories - before using this method to ensure that the latest information is available. - - - - - Gets a list of available updates for an add-in in a specific repository - - - Identifier of the add-in. - - - Identifier of the add-in. - - - Search flags. - - - List of updates for the specified add-in. - - - The list is generated by checking if there is any - add-in with a newer version number in the provided repository. This method uses cached - information from on-line repositories. Make sure you call UpdateRepository or UpdateAllRepositories - before using this method to ensure that the latest information is available. - - - - - Gets a list of all available add-ins - - - A list of add-ins - - - This method uses cached - information from on-line repositories. Make sure you call UpdateRepository or UpdateAllRepositories - before using this method to ensure that the latest information is available. - - - - - Gets a list of all available add-ins - - - The available addins. - - - Search flags. - - - This method uses cached - information from on-line repositories. Make sure you call UpdateRepository or UpdateAllRepositories - before using this method to ensure that the latest information is available. - - - - - Gets a list of all available add-ins in a repository - - - A repository URL - - - A list of add-ins - - - This method uses cached - information from on-line repositories. Make sure you call UpdateRepository or UpdateAllRepositories - before using this method to ensure that the latest information is available. - - - - - Gets a list of all available add-ins in a repository - - - A repository URL - - - Search flags. - - - A list of add-ins - - - This method uses cached - information from on-line repositories. Make sure you call UpdateRepository or UpdateAllRepositories - before using this method to ensure that the latest information is available. - - - - - Checks if an add-in is available to be installed - - - Identifier of the add-in - - - Version of the add-in (optional, it can be null) - - - A list of add-ins - - - List of references to add-ins available in on-line repositories. This method uses cached - information from on-line repositories. Make sure you call UpdateRepository or UpdateAllRepositories - before using this method to ensure that the latest information is available. - - - - - Checks if an add-in is available to be installed from a repository - - - A repository URL - - - Identifier of the add-in - - - Version of the add-in (optional, it can be null) - - - A list of add-ins - - - List of references to add-ins available in the repository. This method uses cached - information from on-line repositories. Make sure you call UpdateRepository or UpdateAllRepositories - before using this method to ensure that the latest information is available. - - - - - Repository search flags. - - - - - No special search options - - - - - Only the latest version of every add-in is included in the search - - - - - An on-line add-in repository - - - - - Path to the cached add-in repository file - - - - - Url of the repository - - - - - Do not use. Use Title instead. - - - - - Title of the repository - - - - - Last change timestamp - - - - - Gets a value indicating whether this is enabled. - - - true if enabled; otherwise, false. - - - - - Helper for making web requests with support for authenticated proxies. - - - - - Sets a custom request handler that can handle requests for authenticated proxy servers. - - The custom request handler. - - - - Gets the web response, using the request handler to handle proxy authentication - if necessary. - - The response. - Callback for creating the request. - Callback for preparing the request, e.g. writing the request stream. - Cancellation token. - - Keeps sending requests until a response code that doesn't require authentication happens or if the request - requires authentication and the user has stopped trying to enter them (i.e. they hit cancel when they are prompted). - - - - - Gets the web response, using the request handler to handle proxy authentication - if necessary. - - The response. - Callback for creating the request. - Callback for preparing the request, e.g. writing the request stream. - Cancellation token. - - Keeps sending requests until a response code that doesn't require authentication happens or if the request - requires authentication and the user has stopped trying to enter them (i.e. they hit cancel when they are prompted). - - - - - Determines whether an error code is likely to have been caused by internet reachability problems. - - - - - Provides tools for managing add-ins - - - This class can be used to manage the add-ins of an application. It allows installing and uninstalling - add-ins, taking into account add-in dependencies. It provides methods for installing add-ins from on-line - repositories and tools for generating those repositories. - - - - - Initializes a new instance - - - If the add-in manager is initialized (AddinManager.Initialize has been called), then this instance - will manage the add-in registry of the initialized engine. - - - - - Initializes a new instance - - - Add-in registry to manage - - - - - Resolves add-in dependencies. - - - Progress monitor where to show progress status - - - List of add-ins to check - - - Packages that need to be installed. - - - Packages that need to be uninstalled. - - - Add-in dependencies that could not be resolved. - - - True if all dependencies could be resolved. - - - This method can be used to get a list of all packages that have to be installed in order to install - an add-in or set of add-ins. The list of packages to install will include the package that provides the - add-in, and all packages that provide the add-in dependencies. In some cases, packages may need to - be installed (for example, when an installed add-in needs to be upgraded). - - - - - Resolves add-in dependencies. - - - Progress monitor where to show progress status - - - Packages that need to be installed. - - - Packages that need to be uninstalled. - - - Add-in dependencies that could not be resolved. - - - True if all dependencies could be resolved. - - - This method can be used to get a list of all packages that have to be installed in order to satisfy - the dependencies of a package or set of packages. The 'packages' argument must have the list of packages - to be resolved. When resolving dependencies, if there is any additional package that needs to be installed, - it will be added to the same 'packages' collection. In some cases, packages may need to - be installed (for example, when an installed add-in needs to be upgraded). Those packages will be added - to the 'toUninstall' collection. Packages that could not be resolved are added to the 'unresolved' - collection. - - - - - Installs add-in packages - - - Progress monitor where to show progress status - - - Paths to the packages to install - - - True if the installation succeeded - - - - - Installs add-in packages from on-line repositories - - - Progress monitor where to show progress status - - - References to the add-ins to be installed - - - True if the installation succeeded - - - - - Installs add-in packages - - - Progress monitor where to show progress status - - - Packages to install - - - True if the installation succeeded - - - - - Uninstalls an add-in. - - - Progress monitor where to show progress status - - - Full identifier of the add-in to uninstall. - - - - - Uninstalls a set of add-ins - - - Progress monitor where to show progress status - - - Full identifiers of the add-ins to uninstall. - - - - - Gets information about an add-in - - - The add-in - - - Add-in header data - - - - - Gets a list of add-ins which depend on an add-in - - - Full identifier of an add-in. - - - When set to True, dependencies will be gathered recursivelly - - - List of dependent add-ins. - - - This methods returns a list of add-ins which have the add-in identified by 'id' as a direct - (or indirect if recursive=True) dependency. - - - - - Packages an add-in - - - Progress monitor where to show progress status - - - Directory where to generate the package - - - Paths to the add-ins to be packaged. Paths can be either the main assembly of an add-in, or an add-in - manifest (.addin or .addin.xml). - - - This method can be used to create a package for an add-in, which can then be pushed to an on-line - repository. The package will include the main assembly or manifest of the add-in and any external - file declared in the add-in metadata. - - - - - Generates an on-line repository - - - Progress monitor where to show progress status - - - Path to the directory that contains the add-ins and that is going to be published - - - This method generates the index files required to publish a directory as an online repository - of add-ins. - - - - - Gets a reference to an extensible application - - - Name of the application - - - The Application object. Null if not found. - - - - - Gets a reference to an extensible application - - - Name of the application - - - Custom paths where to look for the application. - - - The Application object. Null if not found. - - - - - Gets a lis of all known extensible applications - - - A list of applications. - - - - - Gets a lis of all known extensible applications - - - Custom paths where to look for applications. - - - A list of applications. - - - - - The add-in registry being managed - - - - - Default add-in namespace of the application (optional). If set, only add-ins that belong to that namespace - will be shown in add-in lists. - - - - - Directory where to install add-ins. If not specified, the 'addins' subdirectory of the - registry location is used. - - - - - Returns a RepositoryRegistry which can be used to manage on-line repository references - - - - - A registered extensible application - - - - - Add-in registry of the application - - - - - Description of the application - - - - - Name of the application - - - - - Path to the add-in registry - - - - - Path to the directory that contains the main executable assembly of the application - - - - - Command to be used to execute the application in add-in development mode. - - - - - Path to the default add-ins directory for the aplpication - - - - - Path to the add-in cache for the application - - - - diff --git a/bin/Mono.Addins.dll b/bin/Mono.Addins.dll index 969909e314..84ee01eadc 100755 Binary files a/bin/Mono.Addins.dll and b/bin/Mono.Addins.dll differ diff --git a/bin/Mono.Addins.xml b/bin/Mono.Addins.xml deleted file mode 100644 index b9bdd4cf1c..0000000000 --- a/bin/Mono.Addins.xml +++ /dev/null @@ -1,6120 +0,0 @@ - - - - Mono.Addins - - - - - An add-in localizer. - - - Add-in localizers which want to provide support for localization of plural forms - can additionally implement . - - - - - Gets a localized message. - - - The localized message. - - - The message identifier. - - - - - A collection of extension nodes - - - - - Base class for add-in description collections. - - - - - Base class for add-in description collections. - - - - - Initializes a new instance of the class. - - - - - Add an object. - - - The object. - - - - - Adds a collection of objects. - - - The objects to add. - - - - - Insert an object. - - - Insertion index. - - - The object. - - - - - Removes an object. - - - Object to remove. - - - - - Checks if an object is present in the collection. - - - Objecect to check. - - - - - A collection of NodeElement objects - - - - - Gets the at the specified index - - - Index - - - - - Initializes a new instance of the class. - - - - - Gets the at the specified index. - - - The index. - - - - - Gets the with the specified identifier. - - - Identifier. - - - - - Declares an extension point. - - - - - Initializes a new instance - - - - - Initializes a new instance - - - Extension path that identifies the extension point - - - - - Initializes a new instance - - - Extension path that identifies the extension point - - - Type of the extension node to be created for extensions - - - - - Initializes a new instance - - - Extension path that identifies the extension point - - - Element name to be used when defining an extension in an XML manifest. - - - Type of the extension node to be created for extensions - - - - - Extension path that identifies the extension point - - - - - Long description of the extension point. - - - - - Type of the extension node to be created for extensions - - - - - Expected extension object type (when nodes are of type TypeExtensionNode) - - - - - Element name to be used when defining an extension in an XML manifest. The default name is "Type". - - - - - Display name of the extension point. - - - - - Type of the custom attribute to be used to specify metadata for the extension point - - - - - Addin URL attribute. - - - - - Initializes the attribute - - - Url of the add-in - - - - - Url of the add-in - - - - - Declares allowed children of an extension node type. - - - This attribute allows declaring the type of children that an extension node can have. - - - - - Initializes a new instance - - - Name of the allowed child extension node. - - - - - Initializes a new instance - - - Type of the allowed child extension node. - - - - - Initializes a new instance - - - Type of the allowed child extension node. - - - Name of the allowed child extension node. - - - - - Name of the allowed child extension node. - - - - - Type of the allowed child extension node. - - - - - Provides access to add-in and extension model management operations. - - - - - Initializes the add-in engine. - - - The add-in engine needs to be initialized before doing any add-in operation. - When initialized with this method, it will look for add-ins in the global add-in registry. - - - - - Initializes the add-in engine. - - - Location of the add-in registry. - - - The add-in engine needs to be initialized before doing any add-in operation. - Configuration information about the add-in registry will be stored in the - provided location. The add-in engine will look for add-ins in an 'addins' - subdirectory of the provided directory. - - When specifying a path, it is possible to use a special folder name as root. - For example: [Personal]/.config/MyApp. In this case, [Personal] will be replaced - by the location of the Environment.SpecialFolder.Personal folder. Any value - of the Environment.SpecialFolder enumeration can be used (always between square - brackets) - - - - - Initializes the add-in engine. - - - Location of the add-in registry. - - - Add-ins directory. If the path is relative, it is considered to be relative - to the configDir directory. - - - The add-in engine needs to be initialized before doing any add-in operation. - Configuration information about the add-in registry will be stored in the - provided location. The add-in engine will look for add-ins in the provided - 'addinsDir' directory. - - When specifying a path, it is possible to use a special folder name as root. - For example: [Personal]/.config/MyApp. In this case, [Personal] will be replaced - by the location of the Environment.SpecialFolder.Personal folder. Any value - of the Environment.SpecialFolder enumeration can be used (always between square - brackets) - - - - - Initializes the add-in engine. - - - Location of the add-in registry. - - - Add-ins directory. If the path is relative, it is considered to be relative - to the configDir directory. - - - Location of the add-in database. If the path is relative, it is considered to be relative - to the configDir directory. - - - The add-in engine needs to be initialized before doing any add-in operation. - Configuration information about the add-in registry will be stored in the - provided location. The add-in engine will look for add-ins in the provided - 'addinsDir' directory. Cached information about add-ins will be stored in - the 'databaseDir' directory. - - When specifying a path, it is possible to use a special folder name as root. - For example: [Personal]/.config/MyApp. In this case, [Personal] will be replaced - by the location of the Environment.SpecialFolder.Personal folder. Any value - of the Environment.SpecialFolder enumeration can be used (always between square - brackets) - - - - - Finalizes an add-in engine. - - - - - Sets the default localizer to be used for this add-in engine - - - The add-in localizer - - - - - Checks if the provided add-ins are installed, and requests the installation of those - which aren't. - - - Message to show to the user when new add-ins have to be installed. - - - List of IDs of the add-ins to be checked. - - - This method checks if the specified add-ins are installed. - If some of the add-ins are not installed, it will use - the installer assigned to the DefaultAddinInstaller property - to install them. If the installation fails, or if DefaultAddinInstaller - is not set, an exception will be thrown. - - - - - Checks if an add-in has been loaded. - - - Full identifier of the add-in. - - - True if the add-in is loaded. - - - - - Forces the loading of an add-in. - - - Status monitor to keep track of the loading process. - - - Full identifier of the add-in to load. - - - This method loads all assemblies that belong to an add-in in memory. - All add-ins on which the specified add-in depends will also be loaded. - Notice that in general add-ins don't need to be explicitely loaded using - this method, since the add-in engine will load them on demand. - - - - - Creates a new extension context. - - - The new extension context. - - - Extension contexts can be used to query the extension model using particular condition values. - - - - - Returns the extension node in a path - - - Location of the node. - - - The node, or null if not found. - - - - - Returns the extension node in a path - - - Location of the node. - - - The node, or null if not found. - - - - - Gets extension nodes registered in a path. - - - An extension path.> - - - All nodes registered in the provided path. - - - - - Gets extension nodes registered in a path. - - - An extension path. - - - Expected node type. - - - A list of nodes - - - This method returns all nodes registered under the provided path. - It will throw a InvalidOperationException if the type of one of - the registered nodes is not assignable to the provided type. - - - - - Gets extension nodes registered in a path. - - - An extension path. - - - A list of nodes - - - This method returns all nodes registered under the provided path. - It will throw a InvalidOperationException if the type of one of - the registered nodes is not assignable to the provided type. - - - - - Gets extension nodes for a type extension point - - - Type defining the extension point - - - A list of nodes - - - This method returns all extension nodes bound to the provided type. - - - - - Gets extension nodes for a type extension point - - - Type defining the extension point - - - Expected extension node type - - - A list of nodes - - - This method returns all nodes registered for the provided type. - It will throw a InvalidOperationException if the type of one of - the registered nodes is not assignable to the provided node type. - - - - - Gets extension nodes for a type extension point - - - Type defining the extension point - - - A list of nodes - - - This method returns all nodes registered for the provided type. - It will throw a InvalidOperationException if the type of one of - the registered nodes is not assignable to the specified node type argument. - - - - - Gets extension objects registered for a type extension point. - - - Type defining the extension point - - - A list of objects - - - - - Gets extension objects registered for a type extension point. - - - A list of objects - - - The type argument of this generic method is the type that defines - the extension point. - - - - - Gets extension objects registered for a type extension point. - - - Type defining the extension point - - - When set to True, it will return instances created in previous calls. - - - A list of extension objects. - - - - - Gets extension objects registered for a type extension point. - - - When set to True, it will return instances created in previous calls. - - - A list of extension objects. - - - The type argument of this generic method is the type that defines - the extension point. - - - - - Gets extension objects registered in a path - - - An extension path. - - - An array of objects registered in the path. - - - This method can only be used if all nodes in the provided extension path - are of type Mono.Addins.TypeExtensionNode. The returned array is composed - by all objects created by calling the TypeExtensionNode.CreateInstance() - method for each node. - - - - - Gets extension objects registered in a path. - - - An extension path. - - - When set to True, it will return instances created in previous calls. - - - An array of objects registered in the path. - - - This method can only be used if all nodes in the provided extension path - are of type Mono.Addins.TypeExtensionNode. The returned array is composed - by all objects created by calling the TypeExtensionNode.CreateInstance() - method for each node (or TypeExtensionNode.GetInstance() if - reuseCachedInstance is set to true) - - - - - Gets extension objects registered in a path. - - - An extension path. - - - Type of the return array elements. - - - An array of objects registered in the path. - - - This method can only be used if all nodes in the provided extension path - are of type Mono.Addins.TypeExtensionNode. The returned array is composed - by all objects created by calling the TypeExtensionNode.CreateInstance() - method for each node. - - An InvalidOperationException exception is thrown if one of the found - objects is not a subclass of the provided type. - - - - - Gets extension objects registered in a path. - - - An extension path. - - - An array of objects registered in the path. - - - This method can only be used if all nodes in the provided extension path - are of type Mono.Addins.TypeExtensionNode. The returned array is composed - by all objects created by calling the TypeExtensionNode.CreateInstance() - method for each node. - - An InvalidOperationException exception is thrown if one of the found - objects is not a subclass of the provided type. - - - - - Gets extension objects registered in a path. - - - An extension path. - - - Type of the return array elements. - - - When set to True, it will return instances created in previous calls. - - - An array of objects registered in the path. - - - This method can only be used if all nodes in the provided extension path - are of type Mono.Addins.TypeExtensionNode. The returned array is composed - by all objects created by calling the TypeExtensionNode.CreateInstance() - method for each node (or TypeExtensionNode.GetInstance() if - reuseCachedInstance is set to true). - - An InvalidOperationException exception is thrown if one of the found - objects is not a subclass of the provided type. - - - - - Gets extension objects registered in a path. - - - An extension path. - - - When set to True, it will return instances created in previous calls. - - - An array of objects registered in the path. - - - This method can only be used if all nodes in the provided extension path - are of type Mono.Addins.TypeExtensionNode. The returned array is composed - by all objects created by calling the TypeExtensionNode.CreateInstance() - method for each node (or TypeExtensionNode.GetInstance() if - reuseCachedInstance is set to true). - - An InvalidOperationException exception is thrown if one of the found - objects is not a subclass of the provided type. - - - - - Register a listener of extension node changes. - - - Path of the node. - - - A handler method. - - - Hosts can call this method to be subscribed to an extension change - event for a specific path. The event will be fired once for every - individual node change. The event arguments include the change type - (Add or Remove) and the extension node added or removed. - - NOTE: The handler will be called for all nodes existing in the path at the moment of registration. - - - - - Unregister a listener of extension node changes. - - - Path of the node. - - - A handler method. - - - This method unregisters a delegate from the node change event of a path. - - - - - Register a listener of extension node changes. - - - Type defining the extension point - - - A handler method. - - - Hosts can call this method to be subscribed to an extension change - event for a specific type extension point. The event will be fired once for every - individual node change. The event arguments include the change type - (Add or Remove) and the extension node added or removed. - - NOTE: The handler will be called for all nodes existing in the path at the moment of registration. - - - - - Unregister a listener of extension node changes. - - - Type defining the extension point - - - A handler method. - - - - - Gets whether the add-in engine has been initialized. - - - - - Gets the default add-in installer - - - The default installer is used by the CheckInstalled method to request - the installation of missing add-ins. - - - - - Gets the default localizer for this add-in engine - - - - - Gets the localizer for the add-in that is invoking this property - - - - - Gets a reference to the RuntimeAddin object for the add-in that is invoking this property - - - - - Gets the default add-in engine - - - - - Gets the add-in registry bound to the default add-in engine - - - - - Extension change event. - - - This event is fired when any extension point in the add-in system changes. - The event args object provides the path of the changed extension, although - it does not provide information about what changed. Hosts subscribing to - this event should get the new list of nodes using a query method such as - AddinManager.GetExtensionNodes() and then update whatever needs to be updated. - - - - - Add-in loading error event. - - - This event is fired when there is an error when loading the extension - of an add-in, or any other kind of error that may happen when querying extension points. - - - - - Add-in loaded event. - - - Fired after loading an add-in in memory. - - - - - Add-in unload event. - - - Fired when an add-in is unloaded from memory. It may happen an add-in is disabled or uninstalled. - - - - - An extension node definition. - - - - - Base class for add-in description definitions. - - - - - Gets the parent object. - - - The parent object. - - - - - Gets the parent add-in description. - - - The parent add-in description. - - - - - An extension node element. - - - A raw representation of an extension node. Contains the basic information - needed to create ExtensionNode instances. - - - - - Gets element attributes. - - - Name of the attribute - - - The value of the attribute - - - - - Name of the node element. - - - - - Gets all attributes defined in the element. - - - - - Gets child nodes of this node - - - - - Initializes a new instance of the class. - - - Node name. - - - - - Gets the type of the node. - - - The node type. - - - This method only works when the add-in description to which the node belongs has been - loaded from an add-in registry. - - - - - Gets the extension path under which this node is registered - - - The parent path. - - - For example, if the id of the node is 'ThisNode', and the node is a child of another node with id 'ParentNode', and - that parent node is defined in an extension with the path '/Core/MainExtension', then the parent path is 'Core/MainExtension/ParentNode'. - - - - - Gets the value of an attribute. - - - The value of the attribute, or an empty string if the attribute is not defined. - - - Name of the attribute. - - - - - Sets the value of an attribute. - - - Name of the attribute - - - The value. - - - - - Removes an attribute. - - - Name of the attribute to remove. - - - - - Gets or sets the name of the node. - - - The name of the node. - - - - - Gets or sets the identifier of the node. - - - The identifier. - - - - - Gets or sets the identifier of the node after which this node has to be inserted - - - The identifier of the reference node - - - - - Gets or sets the identifier of the node before which this node has to be inserted - - - The identifier of the reference node - - - - - Gets a value indicating whether this node is a condition. - - - true if this node is a condition; otherwise, false. - - - - - Gets the attributes of the node. - - - The attributes. - - - - - Gets the child nodes. - - - The child nodes. - - - - - An extension node type definition. - - - - - An extension node set definition. - - - Node sets allow grouping a set of extension node declarations and give an identifier to that group - (the node set). Once a node set is declared, it can be referenced from several extension points - which use the same extension node structure. Extension node sets also allow declaring recursive - extension nodes, that is, extension nodes with a tree structure. - - - - - Copies data from another node set - - - Node set from which to copy - - - - - Initializes a new instance of the class. - - - - - Gets all the allowed node types. - - - The allowed node types. - - - Gets all allowed node types, including those defined in included node sets. - This method only works for descriptions loaded from a registry. - - - - - Gets or sets the identifier of the node set. - - - The identifier. - - - - - Gets the node types allowed in this node set. - - - The node types. - - - - - Gets a list of other node sets included in this node set. - - - The node sets. - - - - - Initializes a new instance of the class. - - - - - Copies data from another node set - - - - - Type that implements the extension node. - - - The full name of the type. - - - - - Element name to be used when defining an extension in an XML manifest. The default name is "Type". - - - The name of the node. - - - - - Type of the object that the extension creates (only valid for TypeNodeExtension). - - - - - Name of the custom attribute that can be used to declare nodes of this type - - - - - Long description of the node type - - - - - Attributes supported by the extension node type. - - - - - An add-in description - - - This class represent an add-in manifest. It has properties for getting - all information, and methods for loading and saving files. - - - - - Adds an extension point. - - - The extension point. - - - Path that identifies the new extension point. - - - - - Saves the add-in description. - - - File name where to save this instance - - - Saves the add-in description to the specified file and sets the FileName property. - - - - - Saves the add-in description. - - - It is thrown if FileName is not set - - - The description is saved to the file specified in the FileName property. - - - - - Generates an XML representation of the add-in description - - - An XML manifest. - - - - - Load an add-in description from a file - - - The file. - - - - - Load an add-in description from a stream - - - The stream - - - The path to be used to resolve relative file paths. - - - - - Load an add-in description from a text reader - - - The text reader - - - The path to be used to resolve relative file paths. - - - - - Verify this instance. - - - This method checks all the definitions in the description and returns a list of errors. - If the returned list is empty, it means that the description is valid. - - - - - Gets or sets the path to the main addin file. - - - The addin file. - - - The add-in file can be either the main assembly of an add-in or an xml manifest. - - - - - Gets the addin identifier. - - - The addin identifier. - - - - - Gets or sets the local identifier. - - - The local identifier. - - - - - Gets or sets the namespace. - - - The namespace. - - - - - Gets or sets the display name of the add-in. - - - The name. - - - - - Gets or sets the version. - - - The version. - - - - - Gets or sets the version of the add-in with which this add-in is backwards compatible. - - - The compat version. - - - - - Gets or sets the author. - - - The author. - - - - - Gets or sets the Url where more information about the add-in can be found. - - - The URL. - - - - - Gets or sets the copyright. - - - The copyright. - - - - - Gets or sets the description of the add-in. - - - The description. - - - - - Gets or sets the category of the add-in. - - - The category. - - - - - Gets the base path for locating external files relative to the add-in. - - - The base path. - - - - - Gets or sets a value indicating whether this instance is an add-in root. - - - true if this instance is an add-in root; otherwise, false. - - - - - Gets or sets a value indicating whether this add-in is enabled by default. - - - true if enabled by default; otherwise, false. - - - - - Gets or sets the add-in flags. - - - The flags. - - - - - Gets a value indicating whether this add-in can be disabled. - - - true if this add-in can be disabled; otherwise, false. - - - - - Gets a value indicating whether this add-in can be uninstalled. - - - true if this instance can be uninstalled; otherwise, false. - - - - - Gets a value indicating whether this add-in is hidden. - - - true if this add-in is hidden; otherwise, false. - - - - - Gets all external files - - - All files. - - - External files are data files and assemblies explicitly referenced in the Runtime section of the add-in manifest. - - - - - Gets all paths to be ignored by the add-in scanner. - - - All paths to be ignored. - - - - - Gets the main module. - - - The main module. - - - - - Gets the optional modules. - - - The optional modules. - - - Optional modules can be used to declare extensions which will be registered only if some specified - add-in dependencies can be satisfied. Dependencies specified in optional modules are 'soft dependencies', - which means that they don't need to be satisfied in order to load the add-in. - - - - - Gets all modules (including the main module and all optional modules) - - - All modules. - - - - - Gets the extension node sets. - - - The extension node sets. - - - - - Gets the extension points. - - - The extension points. - - - - - Gets the condition types. - - - The condition types. - - - - - Gets or sets the add-in localizer. - - - The description of the add-in localizer for this add-in. - - - - - Custom properties specified in the add-in header - - - - - Gets or sets file where this description is stored - - - The file path. - - - - - Addin flags attribute. - - - - - Initializes the attribute - - - Add-in flags - - - - - Add-in flags - - - - - Delegate to be used in add-in engine events - - - - - Provides information about an add-in engine event. - - - - - Initializes a new instance of the class. - - - Add-in identifier. - - - - - Identifier of the add-in that generated the event. - - - - - Attribute of a NodeElement. - - - - - Name of the attribute. - - - - - Value of the attribute. - - - - - Allows finding assemblies in the file system - - - - - Locates an assembly - - - The full path to the assembly, or null if not found - - - Full name of the assembly - - - - - An add-in property. - - - - - Name of the property - - - - - Locale of the property. It is null if the property is not localized. - - - - - Value of the property. - - - - - A localizer factory. - - - - - Creates a localizer for an add-in. - - - The localizer. - - - The add-in for which to create the localizer. - - - Localizer parameters. - - - - - Definition of an add-in dependency. - - - - - Gets the display name of the dependency. - - - The name. - - - - - A collection of node sets. - - - - - Initializes a new instance of the class. - - - - - Gets the at the specified index. - - - The index. - - - - - Gets the with the specified id. - - - Identifier. - - - - - An add-in engine. - - - This class allows hosting several independent add-in engines in a single application domain. - In general, applications use the AddinManager class to query and manage extensions. This class is static, - so the API is easily accessible. However, some kind applications may need to use several isolated - add-in engines, and in this case the AddinManager class can't be used, because it is bound to a single - add-in engine. Those applications can instead create several instances of the AddinEngine class. Each - add-in engine can be independently initialized with different add-in registries and extension models. - - - - - An extension context. - - - Extension contexts can be used to query the extension tree - using particular condition values. Extension points which - declare the availability of a condition type can only be - queryed using an extension context which provides an - evaluator for that condition. - - - - - Registers a new condition in the extension context. - - - Identifier of the condition. - - - Condition evaluator. - - - The registered condition will be particular to this extension context. - Any event that might be fired as a result of changes in the condition will - only be fired in this context. - - - - - Registers a new condition in the extension context. - - - Identifier of the condition. - - - Type of the condition evaluator. Must be a subclass of Mono.Addins.ConditionType. - - - The registered condition will be particular to this extension context. Any event - that might be fired as a result of changes in the condition will only be fired in this context. - - - - - Returns the extension node in a path - - - Location of the node. - - - The node, or null if not found. - - - - - Returns the extension node in a path - - - Location of the node. - - - The node, or null if not found. - - - - - Gets extension nodes registered in a path. - - - An extension path.> - - - All nodes registered in the provided path. - - - - - Gets extension nodes registered in a path. - - - An extension path. - - - A list of nodes - - - This method returns all nodes registered under the provided path. - It will throw a InvalidOperationException if the type of one of - the registered nodes is not assignable to the provided type. - - - - - Gets extension nodes for a type extension point - - - Type defining the extension point - - - A list of nodes - - - This method returns all extension nodes bound to the provided type. - - - - - Gets extension nodes for a type extension point - - - Type defining the extension point - - - Expected extension node type - - - A list of nodes - - - This method returns all nodes registered for the provided type. - It will throw a InvalidOperationException if the type of one of - the registered nodes is not assignable to the provided node type. - - - - - Gets extension nodes for a type extension point - - - Type defining the extension point - - - A list of nodes - - - This method returns all nodes registered for the provided type. - It will throw a InvalidOperationException if the type of one of - the registered nodes is not assignable to the specified node type argument. - - - - - Gets extension nodes registered in a path. - - - An extension path. - - - Expected node type. - - - A list of nodes - - - This method returns all nodes registered under the provided path. - It will throw a InvalidOperationException if the type of one of - the registered nodes is not assignable to the provided type. - - - - - Gets extension objects registered for a type extension point. - - - Type defining the extension point - - - A list of objects - - - - - Gets extension objects registered for a type extension point. - - - A list of objects - - - The type argument of this generic method is the type that defines - the extension point. - - - - - Gets extension objects registered for a type extension point. - - - Type defining the extension point - - - When set to True, it will return instances created in previous calls. - - - A list of extension objects. - - - - - Gets extension objects registered for a type extension point. - - - When set to True, it will return instances created in previous calls. - - - A list of extension objects. - - - The type argument of this generic method is the type that defines - the extension point. - - - - - Gets extension objects registered in a path - - - An extension path. - - - An array of objects registered in the path. - - - This method can only be used if all nodes in the provided extension path - are of type Mono.Addins.TypeExtensionNode. The returned array is composed - by all objects created by calling the TypeExtensionNode.CreateInstance() - method for each node. - - - - - Gets extension objects registered in a path. - - - An extension path. - - - When set to True, it will return instances created in previous calls. - - - An array of objects registered in the path. - - - This method can only be used if all nodes in the provided extension path - are of type Mono.Addins.TypeExtensionNode. The returned array is composed - by all objects created by calling the TypeExtensionNode.CreateInstance() - method for each node (or TypeExtensionNode.GetInstance() if - reuseCachedInstance is set to true) - - - - - Gets extension objects registered in a path. - - - An extension path. - - - Type of the return array elements. - - - An array of objects registered in the path. - - - This method can only be used if all nodes in the provided extension path - are of type Mono.Addins.TypeExtensionNode. The returned array is composed - by all objects created by calling the TypeExtensionNode.CreateInstance() - method for each node. - - An InvalidOperationException exception is thrown if one of the found - objects is not a subclass of the provided type. - - - - - Gets extension objects registered in a path. - - - An extension path. - - - An array of objects registered in the path. - - - This method can only be used if all nodes in the provided extension path - are of type Mono.Addins.TypeExtensionNode. The returned array is composed - by all objects created by calling the TypeExtensionNode.CreateInstance() - method for each node. - - An InvalidOperationException exception is thrown if one of the found - objects is not a subclass of the provided type. - - - - - Gets extension objects registered in a path. - - - An extension path. - - - When set to True, it will return instances created in previous calls. - - - An array of objects registered in the path. - - - This method can only be used if all nodes in the provided extension path - are of type Mono.Addins.TypeExtensionNode. The returned array is composed - by all objects created by calling the TypeExtensionNode.CreateInstance() - method for each node (or TypeExtensionNode.GetInstance() if - reuseCachedInstance is set to true). - - An InvalidOperationException exception is thrown if one of the found - objects is not a subclass of the provided type. - - - - - Gets extension objects registered in a path. - - - An extension path. - - - Type of the return array elements. - - - When set to True, it will return instances created in previous calls. - - - An array of objects registered in the path. - - - This method can only be used if all nodes in the provided extension path - are of type Mono.Addins.TypeExtensionNode. The returned array is composed - by all objects created by calling the TypeExtensionNode.CreateInstance() - method for each node (or TypeExtensionNode.GetInstance() if - reuseCachedInstance is set to true). - - An InvalidOperationException exception is thrown if one of the found - objects is not a subclass of the provided type. - - - - - Register a listener of extension node changes. - - - Path of the node. - - - A handler method. - - - Hosts can call this method to be subscribed to an extension change - event for a specific path. The event will be fired once for every - individual node change. The event arguments include the change type - (Add or Remove) and the extension node added or removed. - - NOTE: The handler will be called for all nodes existing in the path at the moment of registration. - - - - - Unregister a listener of extension node changes. - - - Path of the node. - - - A handler method. - - - This method unregisters a delegate from the node change event of a path. - - - - - Register a listener of extension node changes. - - - Type defining the extension point - - - A handler method. - - - Hosts can call this method to be subscribed to an extension change - event for a specific type extension point. The event will be fired once for every - individual node change. The event arguments include the change type - (Add or Remove) and the extension node added or removed. - - NOTE: The handler will be called for all nodes existing in the path at the moment of registration. - - - - - Unregister a listener of extension node changes. - - - Type defining the extension point - - - A handler method. - - - - - Extension change event. - - - This event is fired when any extension point in the add-in system changes. - The event args object provides the path of the changed extension, although - it does not provide information about what changed. Hosts subscribing to - this event should get the new list of nodes using a query method such as - AddinManager.GetExtensionNodes() and then update whatever needs to be updated. - - - - - Initializes a new instance of the class. - - - - - Initializes the add-in engine - - - Location of the add-in registry. - - The add-in engine needs to be initialized before doing any add-in operation. - When initialized with this method, it will look for add-in in the add-in registry - located in the specified path. - - - - - Initializes the add-in engine. - - - Location of the add-in registry. - - - Add-ins directory. If the path is relative, it is considered to be relative - to the configDir directory. - - - The add-in engine needs to be initialized before doing any add-in operation. - Configuration information about the add-in registry will be stored in the - provided location. The add-in engine will look for add-ins in the provided - 'addinsDir' directory. - - When specifying a path, it is possible to use a special folder name as root. - For example: [Personal]/.config/MyApp. In this case, [Personal] will be replaced - by the location of the Environment.SpecialFolder.Personal folder. Any value - of the Environment.SpecialFolder enumeration can be used (always between square - brackets) - - - - - Initializes the add-in engine. - - - Location of the add-in registry. - - - Add-ins directory. If the path is relative, it is considered to be relative - to the configDir directory. - - - Location of the add-in database. If the path is relative, it is considered to be relative - to the configDir directory. - - - The add-in engine needs to be initialized before doing any add-in operation. - Configuration information about the add-in registry will be stored in the - provided location. The add-in engine will look for add-ins in the provided - 'addinsDir' directory. Cached information about add-ins will be stored in - the 'databaseDir' directory. - - When specifying a path, it is possible to use a special folder name as root. - For example: [Personal]/.config/MyApp. In this case, [Personal] will be replaced - by the location of the Environment.SpecialFolder.Personal folder. Any value - of the Environment.SpecialFolder enumeration can be used (always between square - brackets) - - - - - Finalizes the add-in engine. - - - - - Sets the default localizer to be used for this add-in engine - - - The add-in localizer - - - - - Checks if the provided add-ins are installed, and requests the installation of those - which aren't. - - - Message to show to the user when new add-ins have to be installed. - - - List of IDs of the add-ins to be checked. - - - This method checks if the specified add-ins are installed. - If some of the add-ins are not installed, it will use - the installer assigned to the DefaultAddinInstaller property - to install them. If the installation fails, or if DefaultAddinInstaller - is not set, an exception will be thrown. - - - - - Checks if an add-in has been loaded. - - - Full identifier of the add-in. - - - True if the add-in is loaded. - - - - - Forces the loading of an add-in. - - - Status monitor to keep track of the loading process. - - - Full identifier of the add-in to load. - - - This method loads all assemblies that belong to an add-in in memory. - All add-ins on which the specified add-in depends will also be loaded. - Notice that in general add-ins don't need to be explicitely loaded using - this method, since the add-in engine will load them on demand. - - - - - Creates a new extension context. - - - The new extension context. - - - Extension contexts can be used to query the extension model using particular condition values. - - - - - Raised when there is an error while loading an add-in - - - - - Raised when an add-in is loaded - - - - - Raised when an add-in is unloaded - - - - - Gets whether the add-in engine has been initialized. - - - - - Gets the default add-in installer - - - The default installer is used by the CheckInstalled method to request - the installation of missing add-ins. - - - - - Gets the default localizer for this add-in engine - - - - - Gets the localizer for the add-in that is invoking this property - - - - - Gets a reference to the RuntimeAddin object for the add-in that is invoking this property - - - - - Gets the add-in registry bound to this add-in engine - - - - - An assembly reflector - - - This interface can be implemented to provide a custom method for getting information about assemblies. - - - - - Called to initialize the assembly reflector - - - IAssemblyLocator instance which can be used to locate referenced assemblies. - - - - - Gets a list of custom attributes - - - The custom attributes. - - - An assembly, class or class member - - - Type of the attribute to be returned. It will always be one of the attribute types - defined in Mono.Addins. - - - 'true' if inherited attributes must be returned - - - - - Gets a list of custom attributes - - - The attributes. - - - An assembly, class or class member - - - Base type of the attribute to be returned - - - 'true' if inherited attributes must be returned - - - - - Loads an assembly. - - - The loaded assembly - - - Path of the assembly. - - - - - Loads the assembly specified in an assembly reference - - - The assembly - - - An assembly reference - - - - - Gets the names of all resources embedded in an assembly - - - The names of the resources - - - An assembly - - - - - Gets the data stream of a resource - - - The stream. - - - An assembly - - - The name of a resource - - - - - Gets all types defined in an assembly - - - The types - - - An assembly - - - - - Gets all assembly references of an assembly - - - A list of assembly references - - - An assembly - - - - - Looks for a type in an assembly - - - The type. - - - An assembly - - - Name of the type - - - - - Gets a custom attribute - - - The custom attribute. - - - An assembly, class or class member - - - Base type of the attribute to be returned. It will always be one of the attribute types - defined in Mono.Addins. - - - 'true' if inherited attributes must be returned - - - - - Gets the name of a type (not including namespace) - - - The type name. - - - A type - - - - - Gets the full name of a type (including namespace) - - - The full name of the type - - - A type - - - - - Gets the assembly qualified name of a type - - - The assembly qualified type name - - - A type - - - - - Gets a list of all base types (including interfaces) of a type - - - An enumeration of the full name of all base types of the type - - - A type - - - - - Checks if a type is assignable to another type - - - 'true' if the type is assignable - - - Expected base type. - - - A type. - - - - - Gets the fields of a type - - - The fields. - - - A type - - - - - Gets the name of a field. - - - The field name. - - - A field. - - - - - Gets the full name of the type of a field - - - The full type name - - - A field. - - - - - A custom attribute - - - - - Full name of the type of the custom attribute - - - - - Declares an extension point bound to a type - - - - - Initializes a new instance - - - - - Initializes a new instance - - - Path that identifies the extension point - - - - - Path that identifies the extension point - - - - - Description of the extension point. - - - - - Element name to be used when defining an extension in an XML manifest. The default name is "Type". - - - - - Display name of the extension point. - - - - - Type of the extension node to be created for extensions - - - - - Type of the custom attribute to be used to specify metadata for the extension point - - - - - Add-in flags - - - - - No flags - - - - - The add-in can't be uninstalled - - - - - The add-in can't be disabled - - - - - The add-in is not visible to end users - - - - - A collection of extensions - - - - - Initializes a new instance of the class. - - - - - Gets the at the specified index. - - - The index. - - - - - Base class for extension nodes which create extension objects - - - - - A node of the extension model. - - - An extension node is an element registered by an add-in in an extension point. - A host can get nodes registered in an extension point using methods such as - AddinManager.GetExtensionNodes(string), which returns a collection of ExtensionNode objects. - - ExtensionNode will normally be used as a base class of more complex extension point types. - The most common subclass is Mono.Addins.TypeExtensionNode, which allows registering a class - implemented in an add-in. - - - - - Returns the child objects of a node. - - - An array of child objects. - - - This method only works if all children of this node are of type Mono.Addins.TypeExtensionNode. - The returned array is composed by all objects created by calling the - TypeExtensionNode.GetInstance() method for each node. - - - - - Returns the child objects of a node. - - - True if the method can reuse instances created in previous calls. - - - An array of child objects. - - - This method only works if all children of this node are of type Mono.Addins.TypeExtensionNode. - The returned array is composed by all objects created by calling the TypeExtensionNode.CreateInstance() - method for each node (or TypeExtensionNode.GetInstance() if reuseCachedInstance is set to true). - - - - - Returns the child objects of a node (with type check). - - - Type of the return array elements. - - - An array of child objects. - - - This method only works if all children of this node are of type Mono.Addins.TypeExtensionNode. - The returned array is composed by all objects created by calling the - TypeExtensionNode.GetInstance(Type) method for each node. - - An InvalidOperationException exception is thrown if one of the found child objects is not a - subclass of the provided type. - - - - - Returns the child objects of a node (casting to the specified type) - - - An array of child objects. - - - This method only works if all children of this node are of type Mono.Addins.TypeExtensionNode. - The returned array is composed by all objects created by calling the - TypeExtensionNode.GetInstance() method for each node. - - - - - Returns the child objects of a node (with type check). - - - Type of the return array elements. - - - True if the method can reuse instances created in previous calls. - - - An array of child objects. - - - This method only works if all children of this node are of type Mono.Addins.TypeExtensionNode. - The returned array is composed by all objects created by calling the TypeExtensionNode.CreateInstance(Type) - method for each node (or TypeExtensionNode.GetInstance(Type) if reuseCachedInstance is set to true). - - An InvalidOperationException exception will be thrown if one of the found child objects is not a subclass - of the provided type. - - - - - Returns the child objects of a node (casting to the specified type). - - - True if the method can reuse instances created in previous calls. - - - An array of child objects. - - - This method only works if all children of this node are of type Mono.Addins.TypeExtensionNode. - The returned array is composed by all objects created by calling the TypeExtensionNode.CreateInstance() - method for each node (or TypeExtensionNode.GetInstance() if reuseCachedInstance is set to true). - - - - - Reads the extension node data - - - The element containing the extension data - - - This method can be overriden to provide a custom method for reading extension node data from an element. - The default implementation reads the attributes if the element and assigns the values to the fields - and properties of the extension node that have the corresponding [NodeAttribute] decoration. - - - - - Called when the add-in that defined this extension node is actually loaded in memory. - - - - - Called when the add-in that defined this extension node is being - unloaded from memory. - - - - - Called when the children list of this node has changed. It may be due to add-ins - being loaded/unloaded, or to conditions being changed. - - - - - Called when a child node is added - - - Added node. - - - - - Called when a child node is removed - - - Removed node. - - - - - Identifier of the node. - - - It is not mandatory to specify an 'id' for a node. When none is provided, - the add-in manager will automatically generate an unique id for the node. - The ExtensionNode.HasId property can be used to know if the 'id' has been - specified by the developer or not. - - - - - Location of this node in the extension tree. - - - The node path is composed by the path of the extension point where it is defined, - the identifiers of its parent nodes, and its own identifier. - - - - - Parent node of this node. - - - - - Extension context to which this node belongs - - - - - Specifies whether the extension node has as an Id or not. - - - It is not mandatory to specify an 'id' for a node. When none is provided, - the add-in manager will automatically generate an unique id for the node. - This property will return true if an 'id' was provided for the node, and - false if the id was assigned by the add-in manager. - - - - - The add-in that registered this extension node. - - - This property provides access to the resources and types of the add-in that created this extension node. - - - - - Notifies that a child node of this node has been added or removed. - - - The first time the event is subscribed, the handler will be called for each existing node. - - - - - Child nodes of this extension node. - - - - - Gets the extension object declared by this node - - - Expected object type. An exception will be thrown if the object is not an instance of the specified type. - - - The extension object - - - The extension object is cached and the same instance will be returned at every call. - - - - - Gets the extension object declared by this node - - - The extension object - - - The extension object is cached and the same instance will be returned at every call. - - - - - Creates a new extension object - - - Expected object type. An exception will be thrown if the object is not an instance of the specified type. - - - The extension object - - - - - Creates a new extension object - - - The extension object - - - - - Declares a dependency on an add-in or add-in host - - - - - Initializes the attribute - - - Identifier of the add-in - - - Version of the add-in - - - - - Identifier of the add-in - - - - - Version of the add-in - - - - - An extension node with custom metadata - - - This is the default type for extension nodes bound to a custom extension attribute. - - - - - An extension node with custom metadata provided by an attribute - - - This interface is implemented by ExtensionNode<T> to provide non-generic access to the attribute instance. - - - - - The custom attribute containing the extension metadata - - - - - The custom attribute containing the extension metadata - - - - - Defines an add-in property - - - - - Initializes a new instance of the class. - - - Name of the property - - - Value of the property - - - - - Initializes a new instance of the class. - - - Name of the property - - - Locale of the property. It can be null if the property is not bound to a locale. - - - Value of the property - - - - - Name of the property - - - - - Locale of the property. It can be null if the property is not bound to a locale. - - - - - Value of the property - - - - - Base class for custon extension attributes. - - - Custom extension attributes can be used to declare extensions with custom metadata. - All custom extension attributes must subclass CustomExtensionAttribute. - - - - - Identifier of the node - - - - - Identifier of the node before which this node has to be placed - - - - - Identifier of the node after which this node has to be placed - - - - - Path of the extension point being extended. - - - This property is optional and useful only when there are several extension points which allow - using this custom attribute to define extensions. - - - - - The extension node bound to this attribute - - - - - The add-in that registered this extension node. - - - This property provides access to the resources and types of the add-in that created this extension node. - - - - - A localizer that supports localization of plural forms. - - - This interface can be implemented by add-in localizers which want to provide - support plural forms. - - - - - Gets a localized message which may contain plural forms. - - - The localized message. - - - Message identifier to use when the specified count is 1. - - - Default message identifier to use when the specified count is not 1. - - - The count that determines which plural form to use. - - - - - Converts message identifiers to localized messages. - - - - - Gets a localized message - - - Message identifier - - - The localized message - - - - - Gets a formatted and localized message - - - Message identifier (can contain string format placeholders) - - - Arguments for the string format operation - - - The formatted and localized string - - - - - Gets a formatted and localized message - - - Message identifier (can contain string format placeholders) - - - Arguments for the string format operation - - - The formatted and localized string - - - - - Gets a localized plural form for a message identifier - - - Message identifier for the singular form - - - Default result message for the plural form - - - Value count. Determines wether to use singular or plural form. - - - The localized message - - - - - Gets a localized and formatted plural form for a message identifier - - - Message identifier for the singular form (can contain string format placeholders) - - - Default result message for the plural form (can contain string format placeholders) - - - Value count. Determines whether to use singular or plural form. - - - Arguments for the string format operation - - - The localized message - - - - - Gets a localized and formatted plural form for a message identifier - - - Message identifier for the singular form (can contain string format placeholders) - - - Default result message for the plural form (can contain string format placeholders) - - - Value count. Determines whether to use singular or plural form. - - - Arguments for the string format operation - - - The localized message - - - - - A collection of extension point definitions. - - - - - Initializes a new instance of the class. - - - - - Gets the at the specified index. - - - The index. - - - - - Gets the with the specified path. - - - Path. - - - - - Declares a Gettext-based localizer for an add-in - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the class. - - - Name of the catalog which contains the strings. - - - - - Initializes a new instance of the class. - - - Name of the catalog which contains the strings. - - - Relative path to the location of the catalog. This path must be relative to the add-in location. - - - The location path must contain a directory structure like this: - - {language-id}/LC_MESSAGES/{Catalog}.mo - - For example, the catalog for spanish strings would be located at: - - locale/es/LC_MESSAGES/some-addin.mo - - - - - Name of the catalog which contains the strings. - - - - - Relative path to the location of the catalog. This path must be relative to the add-in location. - - - When not specified, the default value of this property is 'locale'. - The location path must contain a directory structure like this: - - {language-id}/LC_MESSAGES/{Catalog}.mo - - For example, the catalog for spanish strings would be located at: - - locale/es/LC_MESSAGES/some-addin.mo - - - - - Declares an author of the add-in - - - - - Initializes the attribute - - - Name of the author - - - - - Author name - - - - - A condition type definition. - - - - - Initializes a new instance of the class. - - - - - Copies data from another condition type definition - - - Condition from which to copy - - - - - Gets or sets the identifier of the condition type - - - The identifier. - - - - - Gets or sets the name of the type that implements the condition - - - The name of the type. - - - - - Gets or sets the description of the condition. - - - The description. - - - - - An extension point definition. - - - - - Initializes a new instance of the class. - - - - - Copies another extension point. - - - Extension point from which to copy. - - - - - Adds an extension node type. - - - The extension node type. - - - Name of the node - - - Name of the type that implements the extension node. - - - This method can be used to register a new allowed node type for the extension point. - - - - - Gets or sets the path that identifies the extension point. - - - The path. - - - - - Gets or sets the display name of the extension point. - - - The name. - - - - - Gets or sets the description of the extension point. - - - The description. - - - - - Gets a list of add-ins that extend this extension point. - - - This value is only available when the add-in description is loaded from an add-in registry. - - - - - A node set which specifies the node types allowed in this extension point. - - - The node set. - - - - - Gets the conditions available in this node set. - - - The conditions. - - - - - A condition evaluator. - - - Add-ins may use conditions to register nodes in an extension point which - are only visible under some contexts. For example, an add-in registering - a custom menu option to the main menu of a sample text editor might want - to make that option visible only for some kind of files. To allow add-ins - to do this kind of check, the host application needs to define a new condition. - - - - - Evaluates the condition. - - - Condition node information. - - - 'true' if the condition is satisfied. - - - - - Notifies that the condition has changed, and that it has to be re-evaluated. - - This method must be called when there is a change in the state that determines - the result of the evaluation. When this method is called, all node conditions - depending on it are reevaluated and the corresponding events for adding or - removing extension nodes are fired. - - - - - - A list of extension nodes. - - - - - Gets an enumerator which enumerates all nodes in the list - - - - - Copies all nodes to an array - - - The target array - - - Initial index where to copy to - - - - - Returns the node in the specified index. - - - The index. - - - - - Returns the node with the specified ID. - - - An id. - - - - - Number of nodes of the collection. - - - - - A list of extension nodes. - - - - - Gets an enumerator which enumerates all nodes in the list - - - - - Copies all nodes to an array - - - The target array - - - Initial index where to copy to - - - - - Returns the node in the specified index. - - - The index. - - - - - Returns the node with the specified ID. - - - An id. - - - - - Number of nodes of the collection. - - - - - Exception thrown when the add-in engine can't find a required add-in dependency - - - - - An extension node which specifies a type. - - - This class is a kind of Mono.Addins.ExtensionNode which can be used to register - types in an extension point. This is a very common case: a host application - defines an interface, and add-ins create classes that implement that interface. - The host will define an extension point which will use TypeExtensionNode as nodetext - type. Add-ins will register the classes they implement in that extension point. - - When the nodes of an extension point are of type TypeExtensionNode it is then - possible to use query methods such as AddinManager.GetExtensionObjects(string), - which will get all nodes in the provided extension path and will create an object - for each node. - - When declaring extension nodes in an add-in manifest, the class names can be - specified using the 'class' or 'type' attribute. If none of those attributes is - provided, the class name will be taken from the 'id' attribute. - - TypeExtensionNode is the default extension type used when no type is provided - in the definition of an extension point. - - - - - Reads the extension node data - - - The element containing the extension data - - - This method can be overriden to provide a custom method for reading extension node data from an element. - The default implementation reads the attributes if the element and assigns the values to the fields - and properties of the extension node that have the corresponding [NodeAttribute] decoration. - - - - - Creates a new extension object - - - The extension object - - - - - Type of the object that this node creates - - - - - Name of the type of the object that this node creates - - The name of the type. - - - - An extension node which specifies a type with custom extension metadata - - - This is the default type for type extension nodes bound to a custom extension attribute. - - - - - The custom attribute containing the extension metadata - - - - - Describes the purpose of an add-in or add-in root - - - - - Initializes a new instance of the class. - - - Description of the add-in - - - - - Initializes a new instance of the class. - - - Description of the add-in - - - Locale of the description (for example, 'en-US', or 'en') - - - - - Description of the add-in - - - - - Locale of the description (for example, 'en-US', or 'en') - - - - - Marks an assembly as being an add-in root. - - - An add-in root is an assemly which can be extended by add-ins. - - - - - Marks an assembly as being an add-in. - - - - - Initializes an add-in marker attribute - - - - - Initializes an add-in marker attribute - - - Identifier of the add-in - - - - - Initializes an add-in marker attribute - - - Identifier of the add-in - - - Version of the add-in - - - - - Identifier of the add-in. - - - - - Version of the add-in. - - - - - Version of the add-in with which this add-in is backwards compatible. - - - - - Namespace of the add-in - - - - - Category of the add-in - - - - - Url to a web page with more information about the add-in - - - - - When set to True, the add-in will be automatically enabled after installing. - It's True by default. - - - - - Add-in flags - - - - - Initializes a new instance - - - - - Initializes a new instance - - - Identifier of the add-in root - - - - - Initializes a new instance - - - Identifier of the add-in root - - - Version of the add-in root - - - - - An extension definition. - - - An Extension is a collection of nodes which have to be registered in an extension point. - The target extension point is specified in the .Path property. - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the class. - - - Path that identifies the extension point being extended - - - - - Gets the object extended by this extension - - - The extended object can be an or - an . - - - This method only works when the add-in description to which the extension belongs has been - loaded from an add-in registry. - - - - - Gets the node types allowed in this extension. - - - The allowed node types. - - - This method only works when the add-in description to which the extension belongs has been - loaded from an add-in registry. - - - - - Initializes a new instance of the class. - - - XML that describes the extension. - - - - - Gets or sets the path that identifies the extension point being extended. - - - The path. - - - - - Gets the extension nodes. - - - The extension nodes. - - - - - Delegate to be used in extension point subscriptions - - - - - Delegate to be used in extension point subscriptions - - - - - Arguments for extension events. - - - - - Creates a new instance. - - - Path of the extension node that has changed. - - - - - Checks if a path has changed. - - - An extension path. - - - 'true' if the path is affected by the extension change event. - - - Checks if the specified path or any of its children paths is affected by the extension change event. - - - - - Path of the extension node that has changed. - - - - - Arguments for extension node events. - - - - - Creates a new instance - - - Type of change. - - - Node that has been added or removed. - - - - - Path of the extension that changed. - - - - - Type of change. - - - - - Node that has been added or removed. - - - - - Extension object that has been added or removed. - - - - - Type of change in an extension change event. - - - - - An extension node has been added. - - - - - An extension node has been removed. - - - - - Sets the display name of an add-in - - - - - Initializes a new instance of the class. - - - Name of the add-in - - - - - Initializes a new instance of the class. - - - Name of the add-in - - - Locale of the name (for example, 'en-US', or 'en') - - - - - Name of the add-in - - - - - Locale of the name (for example, 'en-US', or 'en') - - - - - Type of the content of a string extension node attribute - - - - - Plain text - - - - - A class name - - - - - A resource name - - - - - A file name - - - - - An add-in file system extension. - - - File system extensions can override the behavior of the add-in scanner and provide custom rules for - locating and scanning assemblies. - - - - - Called when the add-in scan is about to start - - - - - Called when the add-in scan has finished - - - - - Checks if a directory exists - - - 'true' if the directory exists - - - Directory path - - - - - Checks if a file exists - - - 'true' if the file exists - - - Path to the file - - - - - Gets the files in a directory - - - The full path of the files in the directory - - - Directory path - - - - - Gets the subdirectories of a directory - - - The subdirectories. - - - The directory - - - - - Gets the last write time of a file - - - The last write time. - - - File path. - - - - - Opens a text file - - - The text file stream - - - File path. - - - - - Opens a file. - - - The file stream. - - - The file path. - - - - - Gets an assembly reflector for a file. - - - The reflector for the file. - - - An assembly locator - - - A file path - - - - - Gets a value indicating whether this needs to be isolated from the main execution process - - - true if requires isolation; otherwise, false. - - - - - Assigns an attribute value to an extension - - - This attribute can be used together with the [Extenion] attribute to specify - a value for an attribute of the extension. - - - - - Initializes a new instance of the class. - - - Name of the attribute - - - Value of the attribute - - - - - Initializes a new instance of the class. - - - Type of the extension for which the attribute value is being set - - - Name of the attribute - - - Value of the attribute - - - - - Initializes a new instance of the class. - - - Path of the extension for which the attribute value is being set - - - Name of the attribute - - - Value of the attribute - - - - - Name of the attribute - - - - - Value of the attribute - - - - - Path of the extension for which the attribute value is being set - - - - - Type of the extension for which the attribute value is being set - - - - - An add-in installation handler - - - - - Installs a set of add-ins - - - Registry where to install - - - Message to show to the user when new add-ins have to be installed. - - - List of IDs of the add-ins to be installed. - - - - - This attribute can be applied to an ExtensionNode subclass to specify the default name and description. - - - This information will be used when an extension point does not define a name or description for a node type. - - - - - Initializes the attribute - - - - - Initializes the attribute - - - Name of the node - - - - - Initializes the attribute - - - Name of the node - - - Description of the node - - - - - Default name of the extension node - - - - - Default description of the extension node type - - - - - Type of a custom attribute which can be used to specify metadata for this extension node type - - - - - A collection of dependency definitions. - - - - - Initializes a new instance of the class. - - - - - Adds a dependency to the collection - - - The dependency to add. - - - - - Remove the specified dependency. - - - Dependency to remove. - - - - - Gets the at the specified index. - - - The idnex. - - - - - Declares a type extension. - - - When applied to a class, specifies that the class is an extension - class to be registered in a matching extension point. - - - - - Initializes a new instance of the ExtensionAttribute class. - - - - - Initializes a new instance - - - Path of the extension point. - - The path is only required if there are several extension points defined for the same type. - - - - Initializes a new instance - - - Type defining the extension point being extended - - - This constructor can be used to explicitly specify the type that defines the extension point - to be extended. By default, Mono.Addins will try to find any extension point defined in any - of the base classes or interfaces. The type parameter can be used when there is more than one - base type providing an extension point. - - - - - Path of the extension point being extended - - - The path is only required if there are several extension points defined for the same type. - - - - - Name of the extension node - - - Extension points may require extensions to use a specific node name. - This is needed when an extension point may contain several different types of nodes. - - - - - Identifier of the extension node. - - - The ExtensionAttribute.InsertAfter and ExtensionAttribute.InsertBefore - properties can be used to specify the relative location of a node. The nodes - referenced in those properties must be defined either in the add-in host - being extended, or in any add-in on which this add-in depends. - - - - - Identifier of the extension node before which this node has to be added in the extension point. - - - The ExtensionAttribute.InsertAfter and ExtensionAttribute.InsertBefore - properties can be used to specify the relative location of a node. The nodes - referenced in those properties must be defined either in the add-in host - being extended, or in any add-in on which this add-in depends. - - - - - Identifier of the extension node after which this node has to be added in the extension point. - - - - - Type defining the extension point being extended - - - This property can be used to explicitly specify the type that defines the extension point - to be extended. By default, Mono.Addins will try to find any extension point defined in any - of the base classes or interfaces. This property can be used when there is more than one - base type providing an extension point. - - - - - Run-time representation of an add-in. - - - - - Returns a string that represents the current RuntimeAddin. - - - A string that represents the current RuntimeAddin. - - - - - Gets a resource string - - - Name of the resource - - - The value of the resource string, or null if the resource can't be found. - - - The add-in engine will look for resources in the main add-in assembly and in all included add-in assemblies. - - - - - Gets a resource string - - - Name of the resource - - - When set to true, an exception will be thrown if the resource is not found. - - - The value of the resource string - - - The add-in engine will look for resources in the main add-in assembly and in all included add-in assemblies. - - - - - Gets a resource string - - - Name of the resource - - - When set to true, an exception will be thrown if the resource is not found. - - - Culture of the resource - - - The value of the resource string - - - The add-in engine will look for resources in the main add-in assembly and in all included add-in assemblies. - - - - - Gets a resource object - - - Name of the resource - - - Value of the resource - - - The add-in engine will look for resources in the main add-in assembly and in all included add-in assemblies. - - - - - Gets a resource object - - - Name of the resource - - - When set to true, an exception will be thrown if the resource is not found. - - - Value of the resource - - - The add-in engine will look for resources in the main add-in assembly and in all included add-in assemblies. - - - - - Gets a resource object - - - Name of the resource - - - When set to true, an exception will be thrown if the resource is not found. - - - Culture of the resource - - - Value of the resource - - - The add-in engine will look for resources in the main add-in assembly and in all included add-in assemblies. - - - - - Gets a type defined in the add-in - - - Full name of the type - - - A type. - - - The type will be looked up in the assemblies that implement the add-in, - and recursivelly in all add-ins on which it depends. - - This method throws an InvalidOperationException if the type can't be found. - - - - - Gets a type defined in the add-in - - - Full name of the type - - - Indicates whether the method should throw an exception if the type can't be found. - - - A - - - The type will be looked up in the assemblies that implement the add-in, - and recursivelly in all add-ins on which it depends. - - If the type can't be found, this method throw a InvalidOperationException if - 'throwIfNotFound' is 'true', or 'null' otherwise. - - - - - Creates an instance of a type defined in the add-in - - - Name of the type. - - - A new instance of the type - - - The type will be looked up in the assemblies that implement the add-in, - and recursivelly in all add-ins on which it depends. - - This method throws an InvalidOperationException if the type can't be found. - - The specified type must have a default constructor. - - - - - Creates an instance of a type defined in the add-in - - - Name of the type. - - - Indicates whether the method should throw an exception if the type can't be found. - - - A new instance of the type - - - The type will be looked up in the assemblies that implement the add-in, - and recursivelly in all add-ins on which it depends. - - If the type can't be found, this method throw a InvalidOperationException if - 'throwIfNotFound' is 'true', or 'null' otherwise. - - The specified type must have a default constructor. - - - - - Gets the path of an add-in file - - - Relative path of the file - - - Full path of the file - - - This method can be used to get the full path of a data file deployed together with the add-in. - - - - - Gets the path of an add-in file - - - Components of the file path - - - Full path of the file - - - This method can be used to get the full path of a data file deployed together with the add-in. - - - - - Gets the content of a resource - - - Name of the resource - - - Content of the resource, or null if not found - - - The add-in engine will look for resources in the main add-in assembly and in all included add-in assemblies. - - - - - Gets the content of a resource - - - Name of the resource - - - When set to true, an exception will be thrown if the resource is not found. - - - Content of the resource. - - - The add-in engine will look for resources in the main add-in assembly and in all included add-in assemblies. - - - - - Identifier of the add-in. - - - - - Version of the add-in. - - - - - Path to a directory where add-ins can store private configuration or status data - - - - - Localizer which can be used to localize strings defined in this add-in - - - - - Declares an add-in assembly import - - - An add-in may be composed by several assemblies and data files. - Assemblies must be declared in the main assembly using this attribute, or in the XML manifest. - - It is important to properly declare all files used by an add-in. - For example, when a type from the add-in is required (e.g. an ICommand implementation), - only properly declared assemblies will be checked. - This information is also used by setup tools to know exactly what needs to be packaged when creating - an add-in package, or to know what needs to be deleted when removing an add-in. - - - - - Initializes a new instance - - - Path to the assembly. Must be relative to the assembly declaring this attribute. - - - - - Path to the assembly. Must be relative to the assembly declaring this attribute. - - - - - When set to true (the default), the included assembly will be scanned - looking for extension point declarations. - - - - - Delegate to be used in add-in error subscriptions - - - - - Provides information about an add-in loading error. - - - - - Initializes a new instance of the class. - - - Error message - - - Add-in identifier. - - - Exception that caused the error. - - - - - Exception that caused the error. - - - - - Error message - - - - - An add-in. - - - - - Checks version compatibility. - - - An add-in version. - - - True if the provided version is compatible with this add-in. - - - This method checks the CompatVersion property to know if the provided version is compatible with the version of this add-in. - - - - - Returns a that represents the current . - - - A that represents the current . - - - - - Compares two add-in versions - - - -1 if v1 is greater than v2, 0 if v1 == v2, 1 if v1 less than v2 - - - A version - - - A version - - - - - Returns the identifier of an add-in - - - The full identifier. - - - Namespace of the add-in - - - Name of the add-in - - - Version of the add-in - - - - - Given a full add-in identifier, returns the namespace and name of the add-in (it removes the version number) - - - Add-in identifier. - - - - - Given a full add-in identifier, returns the version the add-in - - - The version. - - - - - Splits a full add-in identifier in name and version - - - Add-in identifier. - - - The resulting name - - - The resulting version - - - - - Full identifier of the add-in, including namespace and version. - - - - - Namespace of the add-in. - - - - - Identifier of the add-in (without namespace) - - - - - Version of the add-in - - - - - Display name of the add-in - - - - - Custom properties specified in the add-in header - - - - - Gets or sets the enabled status of the add-in. - - - This property can be used to enable or disable an add-in. - The enabled status of an add-in is stored in the add-in registry, - so when an add-in is disabled, it will be disabled for all applications - sharing the same registry. - When an add-in is enabled or disabled, the extension points currently loaded - in memory will be properly updated to include or exclude extensions from the add-in. - - - - - Returns 'true' if the add-in is installed in the user's personal folder - - - - - Path to the add-in file (it can be an assembly or a standalone XML manifest) - - - - - Description of the add-in - - - - - A collection of condition types - - - - - Initializes a new instance of the class. - - - - - Gets the at the specified index. - - - Index. - - - The condition. - - - - - A collection of module descriptions - - - - - Initializes a new instance of the class. - - - - - Gets the at the specified index. - - - The index. - - - - - A collection of node attributes - - - - - Initializes a new instance of the class. - - - - - Gets the at the specified index. - - - The index. - - - - - Definition of a dependency of an add-in on an assembly. - - - - - Initializes a new instance of the class. - - - - - Gets or sets the full name of the assembly - - - The full name of the assembly. - - - - - Gets or sets the name of the package that provides the assembly. - - - The name of the package that provides the assembly. - - - - - Display name of the dependency - - - The name. - - - - - Declares an optional add-in module - - - - - Initializes the instance. - - - Relative path to the assembly that implements the optional module - - - - - Relative path to the assembly that implements the optional module - - - - - An add-in registry. - - - An add-in registry is a data structure used by the add-in engine to locate add-ins to load. - - A registry can be configured to look for add-ins in several directories. However, add-ins - copied to those directories won't be detected until an explicit add-in scan is requested. - The registry can be updated by an application by calling Registry.Update(), or by a user by - running the 'mautil' add-in setup tool. - - The registry has information about the location of every add-in and a timestamp of the last - check, so the Update method will only scan new or modified add-ins. An application can - add a call to Registry.Update() in the Main method to detect all new add-ins every time the - app is started. - - Every add-in added to the registry is parsed and validated, and if there is any error it - will be rejected. The registry is also in charge of scanning the add-in assemblies and look - for extensions and other information declared using custom attributes. That information is - merged with the manifest information (if there is one) to create a complete add-in - description ready to be used at run-time. - - Mono.Addins allows sharing an add-in registry among several applications. In this context, - all applications sharing the registry share the same extension point model, and it is - possible to implement add-ins which extend several hosts. - - - - - Initializes a new instance. - - - Location of the add-in registry. - - - Creates a new add-in registry located in the provided path. - The add-in registry will look for add-ins in an 'addins' - subdirectory of the provided registryPath. - - When specifying a path, it is possible to use a special folder name as root. - For example: [Personal]/.config/MyApp. In this case, [Personal] will be replaced - by the location of the Environment.SpecialFolder.Personal folder. Any value - of the Environment.SpecialFolder enumeration can be used (always between square - brackets) - - - - - Initializes a new instance. - - - Location of the add-in registry. - - - Location of the application. - - - Creates a new add-in registry located in the provided path. - The add-in registry will look for add-ins in an 'addins' - subdirectory of the provided registryPath. - - When specifying a path, it is possible to use a special folder name as root. - For example: [Personal]/.config/MyApp. In this case, [Personal] will be replaced - by the location of the Environment.SpecialFolder.Personal folder. Any value - of the Environment.SpecialFolder enumeration can be used (always between square - brackets) - - - - - Initializes a new instance of the class. - - - Location of the add-in registry. - - - Location of the application. - - - Add-ins directory. If the path is relative, it is considered to be relative - to the configDir directory. - - - Creates a new add-in registry located in the provided path. - Configuration information about the add-in registry will be stored in - 'registryPath'. The add-in registry will look for add-ins in the provided - 'addinsDir' directory. - - When specifying a path, it is possible to use a special folder name as root. - For example: [Personal]/.config/MyApp. In this case, [Personal] will be replaced - by the location of the Environment.SpecialFolder.Personal folder. Any value - of the Environment.SpecialFolder enumeration can be used (always between square - brackets) - - - - - Initializes a new instance of the class. - - - Location of the add-in registry. - - - Location of the application. - - - Add-ins directory. If the path is relative, it is considered to be relative - to the configDir directory. - - - Location of the add-in database. If the path is relative, it is considered to be relative - to the configDir directory. - - - Creates a new add-in registry located in the provided path. - Configuration information about the add-in registry will be stored in - 'registryPath'. The add-in registry will look for add-ins in the provided - 'addinsDir' directory. Cached information about add-ins will be stored in - the 'databaseDir' directory. - - When specifying a path, it is possible to use a special folder name as root. - For example: [Personal]/.config/MyApp. In this case, [Personal] will be replaced - by the location of the Environment.SpecialFolder.Personal folder. Any value - of the Environment.SpecialFolder enumeration can be used (always between square - brackets) - - - - - Gets the global registry. - - - The global registry - - - The global add-in registry is created in "~/.config/mono.addins", - and it is the default registry used when none is specified. - - - - - Disposes the add-in engine. - - - - - Returns an add-in from the registry. - - - Identifier of the add-in. - - - The add-in, or 'null' if not found. - - - The add-in identifier may optionally include a version number, for example: "TextEditor.Xml,1.2" - - - - - Returns an add-in from the registry. - - - Identifier of the add-in. - - - 'true' if the exact add-in version must be found. - - - The add-in, or 'null' if not found. - - - The add-in identifier may optionally include a version number, for example: "TextEditor.Xml,1.2". - In this case, if the exact version is not found and exactVersionMatch is 'false', it will - return one than is compatible with the required version. - - - - - Gets all add-ins or add-in roots registered in the registry. - - - The addins. - - - Flags. - - - - - Gets all add-ins registered in the registry. - - - Add-ins registered in the registry. - - - - - Gets all add-in roots registered in the registry. - - - Descriptions of all add-in roots. - - - - - Loads an add-in description - - - Progress tracker. - - - Name of the file to load - - - An add-in description - - - This method loads an add-in description from a file. The file can be an XML manifest or an - assembly that implements an add-in. - - - - - Reads an XML add-in manifest - - - Path to the XML file - - - An add-in description - - - - - Reads an XML add-in manifest - - - Reader that contains the XML - - - Base path to use to discover add-in files - - - An add-in description - - - - - Checks whether an add-in is enabled. - - - Identifier of the add-in. - - - 'true' if the add-in is enabled. - - - - - Enables an add-in. - - - Identifier of the add-in - - - If the enabled add-in depends on other add-ins which are disabled, - those will automatically be enabled too. - - - - - Disables an add-in. - - - Identifier of the add-in. - - - When an add-in is disabled, all extension points it defines will be ignored - by the add-in engine. Other add-ins which depend on the disabled add-in will - also automatically be disabled. - - - - - Registers a set of add-ins for uninstallation. - - - Identifier of the add-in - - - Files to be uninstalled - - - This method can be used to instruct the add-in manager to uninstall - an add-in the next time the registry is updated. This is useful - when an add-in manager can't delete an add-in because if it is - loaded. - - - - - Determines whether an add-in is registered for uninstallation - - - true if the add-in is registered for uninstallation - - - Identifier of the add-in - - - - - Internal use only - - - - - Resets the configuration files of the registry - - - - - Updates the add-in registry. - - - This method must be called after modifying, installing or uninstalling add-ins. - - When calling Update, every add-in added to the registry is parsed and validated, - and if there is any error it will be rejected. It will also cache add-in information - needed at run-time. - - If during the update operation the registry finds new add-ins or detects that some - add-ins have been deleted, the loaded extension points will be updated to include - or exclude extension nodes from those add-ins. - - - - - Updates the add-in registry. - - - Progress monitor to keep track of the update operation. - - - This method must be called after modifying, installing or uninstalling add-ins. - - When calling Update, every add-in added to the registry is parsed and validated, - and if there is any error it will be rejected. It will also cache add-in information - needed at run-time. - - If during the update operation the registry finds new add-ins or detects that some - add-ins have been deleted, the loaded extension points will be updated to include - or exclude extension nodes from those add-ins. - - - - - Regenerates the cached data of the add-in registry. - - - Progress monitor to keep track of the rebuild operation. - - - - - Registers an extension. Only AddinFileSystemExtension extensions are supported right now. - - - The extension to register - - - - - Unregisters an extension. - - - The extension to unregister - - - - - Location of the add-in registry. - - - - - Gets a value indicating whether there are pending add-ins to be uninstalled installed - - - - - Gets the default add-ins folder of the registry. - - - For every add-in registry there is an add-in folder where the registry will look for add-ins by default. - This folder is an "addins" subdirectory of the directory where the repository is located. In most cases, - this folder will only contain .addins files referencing other more convenient locations for add-ins. - - - - - Addin search flags. - - - - - Add-ins are included in the search - - - - - Add-in roots are included in the search - - - - - Both add-in and add-in roots are included in the search - - - - - Only the latest version of every add-in or add-in root is included in the search - - - - - An IProgressStatus class which writes output to the console. - - - - - Progress status listener. - - - - - Sets the description of the current operation. - - - A message - - - This method is called by the add-in engine to show a description of the operation being monitorized. - - - - - Sets the progress of the operation. - - - A number between 0 and 1. 0 means no progress, 1 means operation completed. - - - This method is called by the add-in engine to show the progress of the operation being monitorized. - - - - - Writes text to the log. - - - Message to write - - - - - Reports a warning. - - - Warning message - - - This method is called by the add-in engine to report a warning in the operation being monitorized. - - - - - Reports an error. - - - Error message - - - Exception that caused the error. It can be null. - - - This method is called by the add-in engine to report an error occurred while executing the operation being monitorized. - - - - - Cancels the operation being montorized. - - - - - Log level requested by the user: 0: no log, 1: normal log, >1 verbose log - - - - - Returns True when the user requested to cancel this operation - - - - - Initializes a new instance - - - Set to true to enabled verbose log - - - - - Initializes a new instance - - - Verbosity level. 0: not verbose, 1: normal, >1 extra verbose - - - - - Sets the description of the current operation. - - - A message - - - This method is called by the add-in engine to show a description of the operation being monitorized. - - - - - Sets the progress of the operation. - - - A number between 0 and 1. 0 means no progress, 1 means operation completed. - - - This method is called by the add-in engine to show the progress of the operation being monitorized. - - - - - Writes text to the log. - - - Message to write - - - - - Reports a warning. - - - Warning message - - - This method is called by the add-in engine to report a warning in the operation being monitorized. - - - - - Reports an error. - - - Error message - - - Exception that caused the error. It can be null. - - - This method is called by the add-in engine to report an error occurred while executing the operation being monitorized. - - - - - Cancels the operation being montorized. - - - - - Returns True when the user requested to cancel this operation - - - - - Log level requested by the user: 0: no log, 1: normal log, >1 verbose log - - - - - Definition of a dependency of an add-in on another add-in. - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the class. - - - Full identifier of the add-in (includes version) - - - - - Initializes a new instance of the class. - - - Identifier of the add-in. - - - Version of the add-in. - - - - - Gets the full addin identifier. - - - The full addin identifier. - - - Includes namespace and version number. For example: MonoDevelop.TextEditor,1.0 - - - - - Gets or sets the addin identifier. - - - The addin identifier. - - - - - Gets or sets the version. - - - The version. - - - - - Display name of the dependency. - - - The name. - - - - - Indicates that a field or property is bound to a node attribute - - - - - Initializes a new instance - - - - - Initializes a new instance - - - XML name of the attribute. - - - - - Initializes a new instance - - - XML name of the attribute. - - - Description of the attribute. - - - - - Initializes a new instance - - - XML name of the attribute. - - - Indicates whether the attribute is required or not. - - - - - Initializes a new instance - - - XML name of the attribute. - - - Indicates whether the attribute is required or not. - - - Description of the attribute. - - - - - Initializes a new instance - - - XML name of the attribute. - - - Type of the extension node attribute. - - - The type of the attribute is only required when applying this attribute at class level. - It is not required when it is applied to a field, since the attribute type will be the type of the field. - - - - - Initializes a new instance - - - XML name of the attribute. - - - Type of the extension node attribute. - - - Description of the attribute. - - - The type of the attribute is only required when applying this attribute at class level. - It is not required when it is applied to a field, since the attribute type will be the type of the field. - - - - - Initializes a new instance - - - XML name of the attribute. - - - Type of the extension node attribute. - - - Indicates whether the attribute is required or not. - - - The type of the attribute is only required when applying this attribute at class level. - It is not required when it is applied to a field, since the attribute type will be the type of the field. - - - - - Initializes a new instance - - - XML name of the attribute. - - - Type of the extension node attribute. - - - Indicates whether the attribute is required or not. - - - Description of the attribute. - - - The type of the attribute is only required when applying this attribute at class level. - It is not required when it is applied to a field, since the attribute type will be the type of the field. - - - - - XML name of the attribute. - - - If the name is not specified, the field name to which the [NodeAttribute] - is applied will be used as name. Providing a name is mandatory when applying - [NodeAttribute] at class level. - - - - - Indicates whether the attribute is required or not. - - - - - Type of the extension node attribute. - - - To be used only when applying [NodeAttribute] at class level. It is not required when it - is applied to a field, since the attribute type will be the type of the field. - - - - - Description of the attribute. - - - To be used in the extension point documentation. - - - - - When set to True, the value of the field or property is expected to be a string id which - will be localized by the add-in engine - - - - - Gets or sets the type of the content. - - - Allows specifying the type of the content of a string attribute. - This value is for documentation purposes only. - - - - - A collection of add-in properties - - - - - Gets the value of a property - - - The property value. - - - Name of the property. - - - If the property is localized, it will return the value for the current language if exists, or the - default value if it doesn't. - - - - - Gets the value of a property - - - The property value. - - - Name of the property. - - - Locale for which the value must be returned. - - - - - Sets the value of a property - - - Name of the property - - - New value. - - - - - Sets the value of a property for a specific locale - - - Name of the property. - - - New value. - - - Locale of the property to be set. - - - - - Removes a property. - - - Name of the property. - - - This method only removes properties which have no locale set. - - - - - Removes a property with a specified locale - - - Name of the property - - - Locale of the property - - - - - Declares an add-in file import - - - An add-in may be composed by several assemblies and data files. - Data files must be declared in the main assembly using this attribute, or in the XML manifest. - - It is important to properly declare all files used by an add-in. - This information is used by setup tools to know exactly what needs to be packaged when creating - an add-in package, or to know what needs to be deleted when removing an add-in. - - - - - Initializes a new instance - - - Path to the file. Must be relative to the assembly declaring this attribute. - - - - - Path to the file. Must be relative to the assembly declaring this attribute. - - - - - A collection of node set identifiers - - - - - Gets the collection enumerator. - - - The enumerator. - - - - - Add the specified node set identifier. - - - Node set identifier. - - - - - Remove a node set identifier - - - Node set identifier. - - - - - Clears the collection - - - - - Checks if the specified identifier is present in the collection - - - true if the node set identifier is present. - - - - - Returns the index of the specified node set identifier - - - The index. - - - A node set identifier. - - - - - Gets the node set identifier at the specified index. - - - An index. - - - - - Gets the item count. - - - The count. - - - - - A module definition. - - - Optional modules can be used to declare extensions which will be registered only if some - specified add-in dependencies can be satisfied. - - - - - Initializes a new instance of the class. - - - - - Checks if this module depends on the specified add-in. - - - true if there is a dependency. - - - Identifier of the add-in - - - - - Adds an extension node to the module. - - - The extension node. - - - Path that identifies the extension point. - - - Node name. - - - This method creates a new Extension object for the provided path if none exist. - - - - - Gets an extension instance. - - - The extension instance. - - - Path that identifies the extension point that the extension extends. - - - This method creates a new Extension object for the provided path if none exist. - - - - - Adds an add-in reference (there is a typo in the method name) - - - Identifier of the add-in. - - - Version of the add-in. - - - - - Gets the list of paths to be ignored by the add-in scanner. - - - - - Gets all external files - - - All files. - - - External files are data files and assemblies explicitly referenced in the Runtime section of the add-in manifest. - - - - - Gets the list of external assemblies used by this module. - - - - - Gets the list of external data files used by this module - - - - - Gets the dependencies of this module - - - - - Gets the extensions of this module - - - - - Addin category attribute. - - - - - Initializes the attribute - - - The category to which the add-in belongs - - - - - The category to which the add-in belongs - - - - - A collection of node types. - - - - - Initializes a new instance of the class. - - - - - Gets the at the specified index. - - - The index. - - - - - Gets the with the specified id. - - - Identifier. - - - - - Description of the attribute of a node type. - - - - - Initializes a new instance of the class. - - - - - Copies data from another node attribute. - - - The attribute from which to copy. - - - - - Gets or sets the name of the attribute. - - - The name. - - - - - Gets or sets a value indicating whether this is required. - - - true if required; otherwise, false. - - - - - Gets or sets a value indicating whether this is localizable. - - - true if localizable; otherwise, false. - - - - - Gets or sets the type of the attribute. - - - The type. - - - - - Gets or sets the description of the attribute. - - - The description. - - - - - Gets or sets the type of the content. - - - Allows specifying the type of the content of a string attribute. - The value of this property is only informative, and it doesn't - have any effect on how add-ins are packaged or loaded. - - - - diff --git a/bin/Mono.Cecil.dll b/bin/Mono.Cecil.dll new file mode 100644 index 0000000000..122b0ec4ba Binary files /dev/null and b/bin/Mono.Cecil.dll differ diff --git a/bin/Mono.Posix.dll b/bin/Mono.Posix.dll deleted file mode 100755 index 97ec8bf3f2..0000000000 Binary files a/bin/Mono.Posix.dll and /dev/null differ diff --git a/bin/MySql.Data.dll b/bin/MySql.Data.dll index 992aa5621c..c9f344a56c 100755 Binary files a/bin/MySql.Data.dll and b/bin/MySql.Data.dll differ diff --git a/bin/NDesk.Options.dll b/bin/NDesk.Options.dll index df45878957..23912c22cb 100755 Binary files a/bin/NDesk.Options.dll and b/bin/NDesk.Options.dll differ diff --git a/bin/Newtonsoft.Json.dll b/bin/Newtonsoft.Json.dll index 5931de1693..2f28437aad 100644 Binary files a/bin/Newtonsoft.Json.dll and b/bin/Newtonsoft.Json.dll differ diff --git a/bin/Newtonsoft.Json.xml b/bin/Newtonsoft.Json.xml deleted file mode 100644 index 2a75b4481a..0000000000 --- a/bin/Newtonsoft.Json.xml +++ /dev/null @@ -1,8626 +0,0 @@ - - - - Newtonsoft.Json - - - - - Represents a reader that provides fast, non-cached, forward-only access to serialized Json data. - - - - - Represents a reader that provides fast, non-cached, forward-only access to serialized Json data. - - - - - Initializes a new instance of the class with the specified . - - - - - Reads the next JSON token from the stream. - - true if the next token was read successfully; false if there are no more tokens to read. - - - - Reads the next JSON token from the stream as a . - - A . This method will return null at the end of an array. - - - - Reads the next JSON token from the stream as a . - - A . This method will return null at the end of an array. - - - - Reads the next JSON token from the stream as a . - - A or a null reference if the next JSON token is null. This method will return null at the end of an array. - - - - Reads the next JSON token from the stream as a . - - A . This method will return null at the end of an array. - - - - Reads the next JSON token from the stream as a . - - A . This method will return null at the end of an array. - - - - Reads the next JSON token from the stream as a . - - A . This method will return null at the end of an array. - - - - Skips the children of the current token. - - - - - Sets the current token. - - The new token. - - - - Sets the current token and value. - - The new token. - The value. - - - - Sets the state based on current token type. - - - - - Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. - - - - - Releases unmanaged and - optionally - managed resources - - true to release both managed and unmanaged resources; false to release only unmanaged resources. - - - - Changes the to Closed. - - - - - Gets the current reader state. - - The current reader state. - - - - Gets or sets a value indicating whether the underlying stream or - should be closed when the reader is closed. - - - true to close the underlying stream or when - the reader is closed; otherwise false. The default is true. - - - - - Gets or sets a value indicating whether multiple pieces of JSON content can - be read from a continuous stream without erroring. - - - true to support reading multiple pieces of JSON content; otherwise false. The default is false. - - - - - Gets the quotation mark character used to enclose the value of a string. - - - - - Get or set how time zones are handling when reading JSON. - - - - - Get or set how date formatted strings, e.g. "\/Date(1198908717056)\/" and "2012-03-21T05:40Z", are parsed when reading JSON. - - - - - Get or set how floating point numbers, e.g. 1.0 and 9.9, are parsed when reading JSON text. - - - - - Get or set how custom date formatted strings are parsed when reading JSON. - - - - - Gets or sets the maximum depth allowed when reading JSON. Reading past this depth will throw a . - - - - - Gets the type of the current JSON token. - - - - - Gets the text value of the current JSON token. - - - - - Gets The Common Language Runtime (CLR) type for the current JSON token. - - - - - Gets the depth of the current token in the JSON document. - - The depth of the current token in the JSON document. - - - - Gets the path of the current JSON token. - - - - - Gets or sets the culture used when reading JSON. Defaults to . - - - - - Specifies the state of the reader. - - - - - The Read method has not been called. - - - - - The end of the file has been reached successfully. - - - - - Reader is at a property. - - - - - Reader is at the start of an object. - - - - - Reader is in an object. - - - - - Reader is at the start of an array. - - - - - Reader is in an array. - - - - - The Close method has been called. - - - - - Reader has just read a value. - - - - - Reader is at the start of a constructor. - - - - - Reader in a constructor. - - - - - An error occurred that prevents the read operation from continuing. - - - - - The end of the file has been reached successfully. - - - - - Initializes a new instance of the class. - - The stream. - - - - Initializes a new instance of the class. - - The reader. - - - - Initializes a new instance of the class. - - The stream. - if set to true the root object will be read as a JSON array. - The used when reading values from BSON. - - - - Initializes a new instance of the class. - - The reader. - if set to true the root object will be read as a JSON array. - The used when reading values from BSON. - - - - Reads the next JSON token from the stream as a . - - - A or a null reference if the next JSON token is null. This method will return null at the end of an array. - - - - - Reads the next JSON token from the stream as a . - - A . This method will return null at the end of an array. - - - - Reads the next JSON token from the stream as a . - - A . This method will return null at the end of an array. - - - - Reads the next JSON token from the stream as a . - - A . This method will return null at the end of an array. - - - - Reads the next JSON token from the stream as a . - - A . This method will return null at the end of an array. - - - - Reads the next JSON token from the stream as a . - - - A . This method will return null at the end of an array. - - - - - Reads the next JSON token from the stream. - - - true if the next token was read successfully; false if there are no more tokens to read. - - - - - Changes the to Closed. - - - - - Gets or sets a value indicating whether binary data reading should compatible with incorrect Json.NET 3.5 written binary. - - - true if binary data reading will be compatible with incorrect Json.NET 3.5 written binary; otherwise, false. - - - - - Gets or sets a value indicating whether the root object will be read as a JSON array. - - - true if the root object will be read as a JSON array; otherwise, false. - - - - - Gets or sets the used when reading values from BSON. - - The used when reading values from BSON. - - - - Represents a writer that provides a fast, non-cached, forward-only way of generating JSON data. - - - - - Represents a writer that provides a fast, non-cached, forward-only way of generating Json data. - - - - - Creates an instance of the JsonWriter class. - - - - - Flushes whatever is in the buffer to the underlying streams and also flushes the underlying stream. - - - - - Closes this stream and the underlying stream. - - - - - Writes the beginning of a Json object. - - - - - Writes the end of a Json object. - - - - - Writes the beginning of a Json array. - - - - - Writes the end of an array. - - - - - Writes the start of a constructor with the given name. - - The name of the constructor. - - - - Writes the end constructor. - - - - - Writes the property name of a name/value pair on a JSON object. - - The name of the property. - - - - Writes the property name of a name/value pair on a JSON object. - - The name of the property. - A flag to indicate whether the text should be escaped when it is written as a JSON property name. - - - - Writes the end of the current Json object or array. - - - - - Writes the current token and its children. - - The to read the token from. - - - - Writes the current token. - - The to read the token from. - A flag indicating whether the current token's children should be written. - - - - Writes the specified end token. - - The end token to write. - - - - Writes indent characters. - - - - - Writes the JSON value delimiter. - - - - - Writes an indent space. - - - - - Writes a null value. - - - - - Writes an undefined value. - - - - - Writes raw JSON without changing the writer's state. - - The raw JSON to write. - - - - Writes raw JSON where a value is expected and updates the writer's state. - - The raw JSON to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - An error will raised if the value cannot be written as a single JSON token. - - The value to write. - - - - Writes out a comment /*...*/ containing the specified text. - - Text to place inside the comment. - - - - Writes out the given white space. - - The string of white space characters. - - - - Sets the state of the JsonWriter, - - The JsonToken being written. - The value being written. - - - - Gets or sets a value indicating whether the underlying stream or - should be closed when the writer is closed. - - - true to close the underlying stream or when - the writer is closed; otherwise false. The default is true. - - - - - Gets the top. - - The top. - - - - Gets the state of the writer. - - - - - Gets the path of the writer. - - - - - Indicates how JSON text output is formatted. - - - - - Get or set how dates are written to JSON text. - - - - - Get or set how time zones are handling when writing JSON text. - - - - - Get or set how strings are escaped when writing JSON text. - - - - - Get or set how special floating point numbers, e.g. , - and , - are written to JSON text. - - - - - Get or set how and values are formatting when writing JSON text. - - - - - Gets or sets the culture used when writing JSON. Defaults to . - - - - - Initializes a new instance of the class. - - The stream. - - - - Initializes a new instance of the class. - - The writer. - - - - Flushes whatever is in the buffer to the underlying streams and also flushes the underlying stream. - - - - - Writes the end. - - The token. - - - - Writes out a comment /*...*/ containing the specified text. - - Text to place inside the comment. - - - - Writes the start of a constructor with the given name. - - The name of the constructor. - - - - Writes raw JSON. - - The raw JSON to write. - - - - Writes raw JSON where a value is expected and updates the writer's state. - - The raw JSON to write. - - - - Writes the beginning of a Json array. - - - - - Writes the beginning of a Json object. - - - - - Writes the property name of a name/value pair on a Json object. - - The name of the property. - - - - Closes this stream and the underlying stream. - - - - - Writes a value. - An error will raised if the value cannot be written as a single JSON token. - - The value to write. - - - - Writes a null value. - - - - - Writes an undefined value. - - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value that represents a BSON object id. - - The Object ID value to write. - - - - Writes a BSON regex. - - The regex pattern. - The regex options. - - - - Gets or sets the used when writing values to BSON. - When set to no conversion will occur. - - The used when writing values to BSON. - - - - Represents a BSON Oid (object id). - - - - - Initializes a new instance of the class. - - The Oid value. - - - - Gets or sets the value of the Oid. - - The value of the Oid. - - - - Converts a binary value to and from a base 64 string value. - - - - - Converts an object to and from JSON. - - - - - Writes the JSON representation of the object. - - The to write to. - The value. - The calling serializer. - - - - Reads the JSON representation of the object. - - The to read from. - Type of the object. - The existing value of object being read. - The calling serializer. - The object value. - - - - Determines whether this instance can convert the specified object type. - - Type of the object. - - true if this instance can convert the specified object type; otherwise, false. - - - - - Gets the of the JSON produced by the JsonConverter. - - The of the JSON produced by the JsonConverter. - - - - Gets a value indicating whether this can read JSON. - - true if this can read JSON; otherwise, false. - - - - Gets a value indicating whether this can write JSON. - - true if this can write JSON; otherwise, false. - - - - Writes the JSON representation of the object. - - The to write to. - The value. - The calling serializer. - - - - Reads the JSON representation of the object. - - The to read from. - Type of the object. - The existing value of object being read. - The calling serializer. - The object value. - - - - Determines whether this instance can convert the specified object type. - - Type of the object. - - true if this instance can convert the specified object type; otherwise, false. - - - - - Converts a to and from JSON. - - - - - Writes the JSON representation of the object. - - The to write to. - The value. - The calling serializer. - - - - Reads the JSON representation of the object. - - The to read from. - Type of the object. - The existing value of object being read. - The calling serializer. - The object value. - - - - Determines whether this instance can convert the specified value type. - - Type of the value. - - true if this instance can convert the specified value type; otherwise, false. - - - - - Converts a to and from JSON. - - - - - Writes the JSON representation of the object. - - The to write to. - The value. - The calling serializer. - - - - Reads the JSON representation of the object. - - The to read from. - Type of the object. - The existing value of object being read. - The calling serializer. - The object value. - - - - Determines whether this instance can convert the specified value type. - - Type of the value. - - true if this instance can convert the specified value type; otherwise, false. - - - - - Create a custom object - - The object type to convert. - - - - Writes the JSON representation of the object. - - The to write to. - The value. - The calling serializer. - - - - Reads the JSON representation of the object. - - The to read from. - Type of the object. - The existing value of object being read. - The calling serializer. - The object value. - - - - Creates an object which will then be populated by the serializer. - - Type of the object. - The created object. - - - - Determines whether this instance can convert the specified object type. - - Type of the object. - - true if this instance can convert the specified object type; otherwise, false. - - - - - Gets a value indicating whether this can write JSON. - - - true if this can write JSON; otherwise, false. - - - - - Provides a base class for converting a to and from JSON. - - - - - Determines whether this instance can convert the specified object type. - - Type of the object. - - true if this instance can convert the specified object type; otherwise, false. - - - - - Converts a F# discriminated union type to and from JSON. - - - - - Writes the JSON representation of the object. - - The to write to. - The value. - The calling serializer. - - - - Reads the JSON representation of the object. - - The to read from. - Type of the object. - The existing value of object being read. - The calling serializer. - The object value. - - - - Determines whether this instance can convert the specified object type. - - Type of the object. - - true if this instance can convert the specified object type; otherwise, false. - - - - - Converts an Entity Framework EntityKey to and from JSON. - - - - - Writes the JSON representation of the object. - - The to write to. - The value. - The calling serializer. - - - - Reads the JSON representation of the object. - - The to read from. - Type of the object. - The existing value of object being read. - The calling serializer. - The object value. - - - - Determines whether this instance can convert the specified object type. - - Type of the object. - - true if this instance can convert the specified object type; otherwise, false. - - - - - Converts an ExpandoObject to and from JSON. - - - - - Writes the JSON representation of the object. - - The to write to. - The value. - The calling serializer. - - - - Reads the JSON representation of the object. - - The to read from. - Type of the object. - The existing value of object being read. - The calling serializer. - The object value. - - - - Determines whether this instance can convert the specified object type. - - Type of the object. - - true if this instance can convert the specified object type; otherwise, false. - - - - - Gets a value indicating whether this can write JSON. - - - true if this can write JSON; otherwise, false. - - - - - Converts a to and from JSON. - - - - - Writes the JSON representation of the object. - - The to write to. - The value. - The calling serializer. - - - - Reads the JSON representation of the object. - - The to read from. - Type of the object. - The existing value of object being read. - The calling serializer. - The object value. - - - - Determines whether this instance can convert the specified object type. - - Type of the object. - - true if this instance can convert the specified object type; otherwise, false. - - - - - Converts a to and from JSON and BSON. - - - - - Writes the JSON representation of the object. - - The to write to. - The value. - The calling serializer. - - - - Reads the JSON representation of the object. - - The to read from. - Type of the object. - The existing value of object being read. - The calling serializer. - The object value. - - - - Determines whether this instance can convert the specified object type. - - Type of the object. - - true if this instance can convert the specified object type; otherwise, false. - - - - - Converts a to and from JSON and BSON. - - - - - Writes the JSON representation of the object. - - The to write to. - The value. - The calling serializer. - - - - Reads the JSON representation of the object. - - The to read from. - Type of the object. - The existing value of object being read. - The calling serializer. - The object value. - - - - Determines whether this instance can convert the specified object type. - - Type of the object. - - true if this instance can convert the specified object type; otherwise, false. - - - - - Converts an to and from its name string value. - - - - - Initializes a new instance of the class. - - - - - Writes the JSON representation of the object. - - The to write to. - The value. - The calling serializer. - - - - Reads the JSON representation of the object. - - The to read from. - Type of the object. - The existing value of object being read. - The calling serializer. - The object value. - - - - Determines whether this instance can convert the specified object type. - - Type of the object. - - true if this instance can convert the specified object type; otherwise, false. - - - - - Gets or sets a value indicating whether the written enum text should be camel case. - - true if the written enum text will be camel case; otherwise, false. - - - - Gets or sets a value indicating whether integer values are allowed. - - true if integers are allowed; otherwise, false. - - - - Specifies how constructors are used when initializing objects during deserialization by the . - - - - - First attempt to use the public default constructor, then fall back to single paramatized constructor, then the non-public default constructor. - - - - - Json.NET will use a non-public default constructor before falling back to a paramatized constructor. - - - - - Converts a to and from a string (e.g. "1.2.3.4"). - - - - - Writes the JSON representation of the object. - - The to write to. - The value. - The calling serializer. - - - - Reads the JSON representation of the object. - - The to read from. - Type of the object. - The existing property value of the JSON that is being converted. - The calling serializer. - The object value. - - - - Determines whether this instance can convert the specified object type. - - Type of the object. - - true if this instance can convert the specified object type; otherwise, false. - - - - - Specifies float format handling options when writing special floating point numbers, e.g. , - and with . - - - - - Write special floating point values as strings in JSON, e.g. "NaN", "Infinity", "-Infinity". - - - - - Write special floating point values as symbols in JSON, e.g. NaN, Infinity, -Infinity. - Note that this will produce non-valid JSON. - - - - - Write special floating point values as the property's default value in JSON, e.g. 0.0 for a property, null for a property. - - - - - Specifies how floating point numbers, e.g. 1.0 and 9.9, are parsed when reading JSON text. - - - - - Floating point numbers are parsed to . - - - - - Floating point numbers are parsed to . - - - - - Instructs the how to serialize the collection. - - - - - Instructs the how to serialize the object. - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the class with the specified container Id. - - The container Id. - - - - Gets or sets the id. - - The id. - - - - Gets or sets the title. - - The title. - - - - Gets or sets the description. - - The description. - - - - Gets the collection's items converter. - - The collection's items converter. - - - - The parameter list to use when constructing the JsonConverter described by ItemConverterType. - If null, the default constructor is used. - When non-null, there must be a constructor defined in the JsonConverter that exactly matches the number, - order, and type of these parameters. - - - [JsonContainer(ItemConverterType = typeof(MyContainerConverter), ItemConverterParameters = new object[] { 123, "Four" })] - - - - - Gets or sets a value that indicates whether to preserve object references. - - - true to keep object reference; otherwise, false. The default is false. - - - - - Gets or sets a value that indicates whether to preserve collection's items references. - - - true to keep collection's items object references; otherwise, false. The default is false. - - - - - Gets or sets the reference loop handling used when serializing the collection's items. - - The reference loop handling. - - - - Gets or sets the type name handling used when serializing the collection's items. - - The type name handling. - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the class with the specified container Id. - - The container Id. - - - - The exception thrown when an error occurs during Json serialization or deserialization. - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the class - with a specified error message. - - The error message that explains the reason for the exception. - - - - Initializes a new instance of the class - with a specified error message and a reference to the inner exception that is the cause of this exception. - - The error message that explains the reason for the exception. - The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. - - - - Initializes a new instance of the class. - - The that holds the serialized object data about the exception being thrown. - The that contains contextual information about the source or destination. - The parameter is null. - The class name is null or is zero (0). - - - - Specifies how dates are formatted when writing JSON text. - - - - - Dates are written in the ISO 8601 format, e.g. "2012-03-21T05:40Z". - - - - - Dates are written in the Microsoft JSON format, e.g. "\/Date(1198908717056)\/". - - - - - Specifies how date formatted strings, e.g. "\/Date(1198908717056)\/" and "2012-03-21T05:40Z", are parsed when reading JSON text. - - - - - Date formatted strings are not parsed to a date type and are read as strings. - - - - - Date formatted strings, e.g. "\/Date(1198908717056)\/" and "2012-03-21T05:40Z", are parsed to . - - - - - Date formatted strings, e.g. "\/Date(1198908717056)\/" and "2012-03-21T05:40Z", are parsed to . - - - - - Specifies how to treat the time value when converting between string and . - - - - - Treat as local time. If the object represents a Coordinated Universal Time (UTC), it is converted to the local time. - - - - - Treat as a UTC. If the object represents a local time, it is converted to a UTC. - - - - - Treat as a local time if a is being converted to a string. - If a string is being converted to , convert to a local time if a time zone is specified. - - - - - Time zone information should be preserved when converting. - - - - - Specifies formatting options for the . - - - - - No special formatting is applied. This is the default. - - - - - Causes child objects to be indented according to the and settings. - - - - - Instructs the to use the specified constructor when deserializing that object. - - - - - Instructs the to deserialize properties with no matching class member into the specified collection - and write values during serialization. - - - - - Initializes a new instance of the class. - - - - - Gets or sets a value that indicates whether to write extension data when serializing the object. - - - true to write extension data when serializing the object; otherwise, false. The default is true. - - - - - Gets or sets a value that indicates whether to read extension data when deserializing the object. - - - true to read extension data when deserializing the object; otherwise, false. The default is true. - - - - - Specifies the settings used when merging JSON. - - - - - Gets or sets the method used when merging JSON arrays. - - The method used when merging JSON arrays. - - - - Specifies how JSON arrays are merged together. - - - - Concatenate arrays. - - - Union arrays, skipping items that already exist. - - - Replace all array items. - - - Merge array items together, matched by index. - - - - Specifies metadata property handling options for the . - - - - - Read metadata properties located at the start of a JSON object. - - - - - Read metadata properties located anywhere in a JSON object. Note that this setting will impact performance. - - - - - Do not try to read metadata properties. - - - - - Represents a trace writer that writes to the application's instances. - - - - - Represents a trace writer. - - - - - Writes the specified trace level, message and optional exception. - - The at which to write this trace. - The trace message. - The trace exception. This parameter is optional. - - - - Gets the that will be used to filter the trace messages passed to the writer. - For example a filter level of Info will exclude Verbose messages and include Info, - Warning and Error messages. - - The that will be used to filter the trace messages passed to the writer. - - - - Writes the specified trace level, message and optional exception. - - The at which to write this trace. - The trace message. - The trace exception. This parameter is optional. - - - - Gets the that will be used to filter the trace messages passed to the writer. - For example a filter level of Info will exclude Verbose messages and include Info, - Warning and Error messages. - - - The that will be used to filter the trace messages passed to the writer. - - - - - Get and set values for a using dynamic methods. - - - - - Provides methods to get and set values. - - - - - Sets the value. - - The target to set the value on. - The value to set on the target. - - - - Gets the value. - - The target to get the value from. - The value. - - - - Initializes a new instance of the class. - - The member info. - - - - Sets the value. - - The target to set the value on. - The value to set on the target. - - - - Gets the value. - - The target to get the value from. - The value. - - - - Contract details for a used by the . - - - - - Contract details for a used by the . - - - - - Gets the underlying type for the contract. - - The underlying type for the contract. - - - - Gets or sets the type created during deserialization. - - The type created during deserialization. - - - - Gets or sets whether this type contract is serialized as a reference. - - Whether this type contract is serialized as a reference. - - - - Gets or sets the default for this contract. - - The converter. - - - - Gets or sets all methods called immediately after deserialization of the object. - - The methods called immediately after deserialization of the object. - - - - Gets or sets all methods called during deserialization of the object. - - The methods called during deserialization of the object. - - - - Gets or sets all methods called after serialization of the object graph. - - The methods called after serialization of the object graph. - - - - Gets or sets all methods called before serialization of the object. - - The methods called before serialization of the object. - - - - Gets or sets all method called when an error is thrown during the serialization of the object. - - The methods called when an error is thrown during the serialization of the object. - - - - Gets or sets the method called immediately after deserialization of the object. - - The method called immediately after deserialization of the object. - - - - Gets or sets the method called during deserialization of the object. - - The method called during deserialization of the object. - - - - Gets or sets the method called after serialization of the object graph. - - The method called after serialization of the object graph. - - - - Gets or sets the method called before serialization of the object. - - The method called before serialization of the object. - - - - Gets or sets the method called when an error is thrown during the serialization of the object. - - The method called when an error is thrown during the serialization of the object. - - - - Gets or sets the default creator method used to create the object. - - The default creator method used to create the object. - - - - Gets or sets a value indicating whether the default creator is non public. - - true if the default object creator is non-public; otherwise, false. - - - - Initializes a new instance of the class. - - The underlying type for the contract. - - - - Gets or sets the default collection items . - - The converter. - - - - Gets or sets a value indicating whether the collection items preserve object references. - - true if collection items preserve object references; otherwise, false. - - - - Gets or sets the collection item reference loop handling. - - The reference loop handling. - - - - Gets or sets the collection item type name handling. - - The type name handling. - - - - Represents a trace writer that writes to memory. When the trace message limit is - reached then old trace messages will be removed as new messages are added. - - - - - Initializes a new instance of the class. - - - - - Writes the specified trace level, message and optional exception. - - The at which to write this trace. - The trace message. - The trace exception. This parameter is optional. - - - - Returns an enumeration of the most recent trace messages. - - An enumeration of the most recent trace messages. - - - - Returns a of the most recent trace messages. - - - A of the most recent trace messages. - - - - - Gets the that will be used to filter the trace messages passed to the writer. - For example a filter level of Info will exclude Verbose messages and include Info, - Warning and Error messages. - - - The that will be used to filter the trace messages passed to the writer. - - - - - Provides an interface to enable a class to return line and position information. - - - - - Gets a value indicating whether the class can return line information. - - - true if LineNumber and LinePosition can be provided; otherwise, false. - - - - - Gets the current line number. - - The current line number or 0 if no line information is available (for example, HasLineInfo returns false). - - - - Gets the current line position. - - The current line position or 0 if no line information is available (for example, HasLineInfo returns false). - - - - Specifies how strings are escaped when writing JSON text. - - - - - Only control characters (e.g. newline) are escaped. - - - - - All non-ASCII and control characters (e.g. newline) are escaped. - - - - - HTML (<, >, &, ', ") and control characters (e.g. newline) are escaped. - - - - - Represents a raw JSON string. - - - - - Represents a value in JSON (string, integer, date, etc). - - - - - Represents an abstract JSON token. - - - - - Represents a collection of objects. - - The type of token - - - - Gets the with the specified key. - - - - - - Compares the values of two tokens, including the values of all descendant tokens. - - The first to compare. - The second to compare. - true if the tokens are equal; otherwise false. - - - - Adds the specified content immediately after this token. - - A content object that contains simple content or a collection of content objects to be added after this token. - - - - Adds the specified content immediately before this token. - - A content object that contains simple content or a collection of content objects to be added before this token. - - - - Returns a collection of the ancestor tokens of this token. - - A collection of the ancestor tokens of this token. - - - - Returns a collection of the sibling tokens after this token, in document order. - - A collection of the sibling tokens after this tokens, in document order. - - - - Returns a collection of the sibling tokens before this token, in document order. - - A collection of the sibling tokens before this token, in document order. - - - - Gets the with the specified key converted to the specified type. - - The type to convert the token to. - The token key. - The converted token value. - - - - Returns a collection of the child tokens of this token, in document order. - - An of containing the child tokens of this , in document order. - - - - Returns a collection of the child tokens of this token, in document order, filtered by the specified type. - - The type to filter the child tokens on. - A containing the child tokens of this , in document order. - - - - Returns a collection of the child values of this token, in document order. - - The type to convert the values to. - A containing the child values of this , in document order. - - - - Removes this token from its parent. - - - - - Replaces this token with the specified token. - - The value. - - - - Writes this token to a . - - A into which this method will write. - A collection of which will be used when writing the token. - - - - Returns the indented JSON for this token. - - - The indented JSON for this token. - - - - - Returns the JSON for this token using the given formatting and converters. - - Indicates how the output is formatted. - A collection of which will be used when writing the token. - The JSON for this token using the given formatting and converters. - - - - Performs an explicit conversion from to . - - The value. - The result of the conversion. - - - - Performs an explicit conversion from to . - - The value. - The result of the conversion. - - - - Performs an explicit conversion from to . - - The value. - The result of the conversion. - - - - Performs an explicit conversion from to . - - The value. - The result of the conversion. - - - - Performs an explicit conversion from to . - - The value. - The result of the conversion. - - - - Performs an explicit conversion from to . - - The value. - The result of the conversion. - - - - Performs an explicit conversion from to . - - The value. - The result of the conversion. - - - - Performs an explicit conversion from to . - - The value. - The result of the conversion. - - - - Performs an explicit conversion from to . - - The value. - The result of the conversion. - - - - Performs an explicit conversion from to . - - The value. - The result of the conversion. - - - - Performs an explicit conversion from to . - - The value. - The result of the conversion. - - - - Performs an explicit conversion from to . - - The value. - The result of the conversion. - - - - Performs an explicit conversion from to . - - The value. - The result of the conversion. - - - - Performs an explicit conversion from to . - - The value. - The result of the conversion. - - - - Performs an explicit conversion from to . - - The value. - The result of the conversion. - - - - Performs an explicit conversion from to . - - The value. - The result of the conversion. - - - - Performs an explicit conversion from to . - - The value. - The result of the conversion. - - - - Performs an explicit conversion from to . - - The value. - The result of the conversion. - - - - Performs an explicit conversion from to . - - The value. - The result of the conversion. - - - - Performs an explicit conversion from to . - - The value. - The result of the conversion. - - - - Performs an explicit conversion from to . - - The value. - The result of the conversion. - - - - Performs an explicit conversion from to . - - The value. - The result of the conversion. - - - - Performs an explicit conversion from to . - - The value. - The result of the conversion. - - - - Performs an explicit conversion from to . - - The value. - The result of the conversion. - - - - Performs an explicit conversion from to . - - The value. - The result of the conversion. - - - - Performs an explicit conversion from to . - - The value. - The result of the conversion. - - - - Performs an explicit conversion from to . - - The value. - The result of the conversion. - - - - Performs an explicit conversion from to . - - The value. - The result of the conversion. - - - - Performs an explicit conversion from to . - - The value. - The result of the conversion. - - - - Performs an explicit conversion from to . - - The value. - The result of the conversion. - - - - Performs an explicit conversion from to . - - The value. - The result of the conversion. - - - - Performs an explicit conversion from to . - - The value. - The result of the conversion. - - - - Performs an explicit conversion from to . - - The value. - The result of the conversion. - - - - Performs an explicit conversion from to . - - The value. - The result of the conversion. - - - - Performs an explicit conversion from to . - - The value. - The result of the conversion. - - - - Performs an explicit conversion from to . - - The value. - The result of the conversion. - - - - Performs an explicit conversion from to . - - The value. - The result of the conversion. - - - - Performs an implicit conversion from to . - - The value to create a from. - The initialized with the specified value. - - - - Performs an implicit conversion from to . - - The value to create a from. - The initialized with the specified value. - - - - Performs an implicit conversion from to . - - The value to create a from. - The initialized with the specified value. - - - - Performs an implicit conversion from to . - - The value to create a from. - The initialized with the specified value. - - - - Performs an implicit conversion from to . - - The value to create a from. - The initialized with the specified value. - - - - Performs an implicit conversion from to . - - The value to create a from. - The initialized with the specified value. - - - - Performs an implicit conversion from to . - - The value to create a from. - The initialized with the specified value. - - - - Performs an implicit conversion from to . - - The value to create a from. - The initialized with the specified value. - - - - Performs an implicit conversion from to . - - The value to create a from. - The initialized with the specified value. - - - - Performs an implicit conversion from to . - - The value to create a from. - The initialized with the specified value. - - - - Performs an implicit conversion from to . - - The value to create a from. - The initialized with the specified value. - - - - Performs an implicit conversion from to . - - The value to create a from. - The initialized with the specified value. - - - - Performs an implicit conversion from to . - - The value to create a from. - The initialized with the specified value. - - - - Performs an implicit conversion from to . - - The value to create a from. - The initialized with the specified value. - - - - Performs an implicit conversion from to . - - The value to create a from. - The initialized with the specified value. - - - - Performs an implicit conversion from to . - - The value to create a from. - The initialized with the specified value. - - - - Performs an implicit conversion from to . - - The value to create a from. - The initialized with the specified value. - - - - Performs an implicit conversion from to . - - The value to create a from. - The initialized with the specified value. - - - - Performs an implicit conversion from to . - - The value to create a from. - The initialized with the specified value. - - - - Performs an implicit conversion from to . - - The value to create a from. - The initialized with the specified value. - - - - Performs an implicit conversion from to . - - The value to create a from. - The initialized with the specified value. - - - - Performs an implicit conversion from to . - - The value to create a from. - The initialized with the specified value. - - - - Performs an implicit conversion from to . - - The value to create a from. - The initialized with the specified value. - - - - Performs an implicit conversion from to . - - The value to create a from. - The initialized with the specified value. - - - - Performs an implicit conversion from to . - - The value to create a from. - The initialized with the specified value. - - - - Performs an implicit conversion from to . - - The value to create a from. - The initialized with the specified value. - - - - Performs an implicit conversion from to . - - The value to create a from. - The initialized with the specified value. - - - - Performs an implicit conversion from to . - - The value to create a from. - The initialized with the specified value. - - - - Performs an implicit conversion from to . - - The value to create a from. - The initialized with the specified value. - - - - Performs an implicit conversion from to . - - The value to create a from. - The initialized with the specified value. - - - - Performs an implicit conversion from to . - - The value to create a from. - The initialized with the specified value. - - - - Performs an implicit conversion from to . - - The value to create a from. - The initialized with the specified value. - - - - Performs an implicit conversion from to . - - The value to create a from. - The initialized with the specified value. - - - - Performs an implicit conversion from to . - - The value to create a from. - The initialized with the specified value. - - - - Performs an implicit conversion from to . - - The value to create a from. - The initialized with the specified value. - - - - Creates an for this token. - - An that can be used to read this token and its descendants. - - - - Creates a from an object. - - The object that will be used to create . - A with the value of the specified object - - - - Creates a from an object using the specified . - - The object that will be used to create . - The that will be used when reading the object. - A with the value of the specified object - - - - Creates the specified .NET type from the . - - The object type that the token will be deserialized to. - The new object created from the JSON value. - - - - Creates the specified .NET type from the . - - The object type that the token will be deserialized to. - The new object created from the JSON value. - - - - Creates the specified .NET type from the using the specified . - - The object type that the token will be deserialized to. - The that will be used when creating the object. - The new object created from the JSON value. - - - - Creates the specified .NET type from the using the specified . - - The object type that the token will be deserialized to. - The that will be used when creating the object. - The new object created from the JSON value. - - - - Creates a from a . - - An positioned at the token to read into this . - - An that contains the token and its descendant tokens - that were read from the reader. The runtime type of the token is determined - by the token type of the first token encountered in the reader. - - - - - Load a from a string that contains JSON. - - A that contains JSON. - A populated from the string that contains JSON. - - - - Creates a from a . - - An positioned at the token to read into this . - - An that contains the token and its descendant tokens - that were read from the reader. The runtime type of the token is determined - by the token type of the first token encountered in the reader. - - - - - Selects a using a JPath expression. Selects the token that matches the object path. - - - A that contains a JPath expression. - - A , or null. - - - - Selects a using a JPath expression. Selects the token that matches the object path. - - - A that contains a JPath expression. - - A flag to indicate whether an error should be thrown if no tokens are found when evaluating part of the expression. - A . - - - - Selects a collection of elements using a JPath expression. - - - A that contains a JPath expression. - - An that contains the selected elements. - - - - Selects a collection of elements using a JPath expression. - - - A that contains a JPath expression. - - A flag to indicate whether an error should be thrown if no tokens are found when evaluating part of the expression. - An that contains the selected elements. - - - - Returns the responsible for binding operations performed on this object. - - The expression tree representation of the runtime value. - - The to bind this object. - - - - - Returns the responsible for binding operations performed on this object. - - The expression tree representation of the runtime value. - - The to bind this object. - - - - - Creates a new instance of the . All child tokens are recursively cloned. - - A new instance of the . - - - - Gets a comparer that can compare two tokens for value equality. - - A that can compare two nodes for value equality. - - - - Gets or sets the parent. - - The parent. - - - - Gets the root of this . - - The root of this . - - - - Gets the node type for this . - - The type. - - - - Gets a value indicating whether this token has child tokens. - - - true if this token has child values; otherwise, false. - - - - - Gets the next sibling token of this node. - - The that contains the next sibling token. - - - - Gets the previous sibling token of this node. - - The that contains the previous sibling token. - - - - Gets the path of the JSON token. - - - - - Gets the with the specified key. - - The with the specified key. - - - - Get the first child token of this token. - - A containing the first child token of the . - - - - Get the last child token of this token. - - A containing the last child token of the . - - - - Initializes a new instance of the class from another object. - - A object to copy from. - - - - Initializes a new instance of the class with the given value. - - The value. - - - - Initializes a new instance of the class with the given value. - - The value. - - - - Initializes a new instance of the class with the given value. - - The value. - - - - Initializes a new instance of the class with the given value. - - The value. - - - - Initializes a new instance of the class with the given value. - - The value. - - - - Initializes a new instance of the class with the given value. - - The value. - - - - Initializes a new instance of the class with the given value. - - The value. - - - - Initializes a new instance of the class with the given value. - - The value. - - - - Initializes a new instance of the class with the given value. - - The value. - - - - Initializes a new instance of the class with the given value. - - The value. - - - - Initializes a new instance of the class with the given value. - - The value. - - - - Initializes a new instance of the class with the given value. - - The value. - - - - Initializes a new instance of the class with the given value. - - The value. - - - - Initializes a new instance of the class with the given value. - - The value. - - - - Creates a comment with the given value. - - The value. - A comment with the given value. - - - - Creates a string with the given value. - - The value. - A string with the given value. - - - - Creates a null value. - - A null value. - - - - Creates a null value. - - A null value. - - - - Writes this token to a . - - A into which this method will write. - A collection of which will be used when writing the token. - - - - Indicates whether the current object is equal to another object of the same type. - - - true if the current object is equal to the parameter; otherwise, false. - - An object to compare with this object. - - - - Determines whether the specified is equal to the current . - - The to compare with the current . - - true if the specified is equal to the current ; otherwise, false. - - - The parameter is null. - - - - - Serves as a hash function for a particular type. - - - A hash code for the current . - - - - - Returns a that represents this instance. - - - A that represents this instance. - - - - - Returns a that represents this instance. - - The format. - - A that represents this instance. - - - - - Returns a that represents this instance. - - The format provider. - - A that represents this instance. - - - - - Returns a that represents this instance. - - The format. - The format provider. - - A that represents this instance. - - - - - Returns the responsible for binding operations performed on this object. - - The expression tree representation of the runtime value. - - The to bind this object. - - - - - Compares the current instance with another object of the same type and returns an integer that indicates whether the current instance precedes, follows, or occurs in the same position in the sort order as the other object. - - An object to compare with this instance. - - A 32-bit signed integer that indicates the relative order of the objects being compared. The return value has these meanings: - Value - Meaning - Less than zero - This instance is less than . - Zero - This instance is equal to . - Greater than zero - This instance is greater than . - - - is not the same type as this instance. - - - - - Gets a value indicating whether this token has child tokens. - - - true if this token has child values; otherwise, false. - - - - - Gets the node type for this . - - The type. - - - - Gets or sets the underlying token value. - - The underlying token value. - - - - Initializes a new instance of the class from another object. - - A object to copy from. - - - - Initializes a new instance of the class. - - The raw json. - - - - Creates an instance of with the content of the reader's current token. - - The reader. - An instance of with the content of the reader's current token. - - - - Indicating whether a property is required. - - - - - The property is not required. The default state. - - - - - The property must be defined in JSON but can be a null value. - - - - - The property must be defined in JSON and cannot be a null value. - - - - - Contract details for a used by the . - - - - - Initializes a new instance of the class. - - The underlying type for the contract. - - - - Gets the object's properties. - - The object's properties. - - - - Gets or sets the property name resolver. - - The property name resolver. - - - - Contract details for a used by the . - - - - - Initializes a new instance of the class. - - The underlying type for the contract. - - - - Gets or sets the ISerializable object constructor. - - The ISerializable object constructor. - - - - Contract details for a used by the . - - - - - Initializes a new instance of the class. - - The underlying type for the contract. - - - - Contract details for a used by the . - - - - - Initializes a new instance of the class. - - The underlying type for the contract. - - - - Get and set values for a using dynamic methods. - - - - - Initializes a new instance of the class. - - The member info. - - - - Sets the value. - - The target to set the value on. - The value to set on the target. - - - - Gets the value. - - The target to get the value from. - The value. - - - - Provides data for the Error event. - - - - - Initializes a new instance of the class. - - The current object. - The error context. - - - - Gets the current object the error event is being raised against. - - The current object the error event is being raised against. - - - - Gets the error context. - - The error context. - - - - Represents a view of a . - - - - - Initializes a new instance of the class. - - The name. - - - - When overridden in a derived class, returns whether resetting an object changes its value. - - - true if resetting the component changes its value; otherwise, false. - - The component to test for reset capability. - - - - - When overridden in a derived class, gets the current value of the property on a component. - - - The value of a property for a given component. - - The component with the property for which to retrieve the value. - - - - - When overridden in a derived class, resets the value for this property of the component to the default value. - - The component with the property value that is to be reset to the default value. - - - - - When overridden in a derived class, sets the value of the component to a different value. - - The component with the property value that is to be set. - The new value. - - - - - When overridden in a derived class, determines a value indicating whether the value of this property needs to be persisted. - - - true if the property should be persisted; otherwise, false. - - The component with the property to be examined for persistence. - - - - - When overridden in a derived class, gets the type of the component this property is bound to. - - - A that represents the type of component this property is bound to. When the or methods are invoked, the object specified might be an instance of this type. - - - - - When overridden in a derived class, gets a value indicating whether this property is read-only. - - - true if the property is read-only; otherwise, false. - - - - - When overridden in a derived class, gets the type of the property. - - - A that represents the type of the property. - - - - - Gets the hash code for the name of the member. - - - - The hash code for the name of the member. - - - - - Used to resolve references when serializing and deserializing JSON by the . - - - - - Resolves a reference to its object. - - The serialization context. - The reference to resolve. - The object that - - - - Gets the reference for the sepecified object. - - The serialization context. - The object to get a reference for. - The reference to the object. - - - - Determines whether the specified object is referenced. - - The serialization context. - The object to test for a reference. - - true if the specified object is referenced; otherwise, false. - - - - - Adds a reference to the specified object. - - The serialization context. - The reference. - The object to reference. - - - - Specifies reference handling options for the . - Note that references cannot be preserved when a value is set via a non-default constructor such as types that implement ISerializable. - - - - - - - - Do not preserve references when serializing types. - - - - - Preserve references when serializing into a JSON object structure. - - - - - Preserve references when serializing into a JSON array structure. - - - - - Preserve references when serializing. - - - - - Instructs the how to serialize the collection. - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the class with a flag indicating whether the array can contain null items - - A flag indicating whether the array can contain null items. - - - - Initializes a new instance of the class with the specified container Id. - - The container Id. - - - - Gets or sets a value indicating whether null items are allowed in the collection. - - true if null items are allowed in the collection; otherwise, false. - - - - Specifies default value handling options for the . - - - - - - - - - Include members where the member value is the same as the member's default value when serializing objects. - Included members are written to JSON. Has no effect when deserializing. - - - - - Ignore members where the member value is the same as the member's default value when serializing objects - so that is is not written to JSON. - This option will ignore all default values (e.g. null for objects and nullable types; 0 for integers, - decimals and floating point numbers; and false for booleans). The default value ignored can be changed by - placing the on the property. - - - - - Members with a default value but no JSON will be set to their default value when deserializing. - - - - - Ignore members where the member value is the same as the member's default value when serializing objects - and sets members to their default value when deserializing. - - - - - Instructs the to use the specified when serializing the member or class. - - - - - Initializes a new instance of the class. - - Type of the converter. - - - - Initializes a new instance of the class. - - Type of the converter. - Parameter list to use when constructing the JsonConverter. Can be null. - - - - Gets the type of the converter. - - The type of the converter. - - - - The parameter list to use when constructing the JsonConverter described by ConverterType. - If null, the default constructor is used. - - - - - Instructs the how to serialize the object. - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the class with the specified member serialization. - - The member serialization. - - - - Initializes a new instance of the class with the specified container Id. - - The container Id. - - - - Gets or sets the member serialization. - - The member serialization. - - - - Gets or sets a value that indicates whether the object's properties are required. - - - A value indicating whether the object's properties are required. - - - - - Specifies the settings on a object. - - - - - Initializes a new instance of the class. - - - - - Gets or sets how reference loops (e.g. a class referencing itself) is handled. - - Reference loop handling. - - - - Gets or sets how missing members (e.g. JSON contains a property that isn't a member on the object) are handled during deserialization. - - Missing member handling. - - - - Gets or sets how objects are created during deserialization. - - The object creation handling. - - - - Gets or sets how null values are handled during serialization and deserialization. - - Null value handling. - - - - Gets or sets how null default are handled during serialization and deserialization. - - The default value handling. - - - - Gets or sets a collection that will be used during serialization. - - The converters. - - - - Gets or sets how object references are preserved by the serializer. - - The preserve references handling. - - - - Gets or sets how type name writing and reading is handled by the serializer. - - The type name handling. - - - - Gets or sets how metadata properties are used during deserialization. - - The metadata properties handling. - - - - Gets or sets how a type name assembly is written and resolved by the serializer. - - The type name assembly format. - - - - Gets or sets how constructors are used during deserialization. - - The constructor handling. - - - - Gets or sets the contract resolver used by the serializer when - serializing .NET objects to JSON and vice versa. - - The contract resolver. - - - - Gets or sets the used by the serializer when resolving references. - - The reference resolver. - - - - Gets or sets the used by the serializer when writing trace messages. - - The trace writer. - - - - Gets or sets the used by the serializer when resolving type names. - - The binder. - - - - Gets or sets the error handler called during serialization and deserialization. - - The error handler called during serialization and deserialization. - - - - Gets or sets the used by the serializer when invoking serialization callback methods. - - The context. - - - - Get or set how and values are formatting when writing JSON text. - - - - - Gets or sets the maximum depth allowed when reading JSON. Reading past this depth will throw a . - - - - - Indicates how JSON text output is formatted. - - - - - Get or set how dates are written to JSON text. - - - - - Get or set how time zones are handling during serialization and deserialization. - - - - - Get or set how date formatted strings, e.g. "\/Date(1198908717056)\/" and "2012-03-21T05:40Z", are parsed when reading JSON. - - - - - Get or set how special floating point numbers, e.g. , - and , - are written as JSON. - - - - - Get or set how floating point numbers, e.g. 1.0 and 9.9, are parsed when reading JSON text. - - - - - Get or set how strings are escaped when writing JSON text. - - - - - Gets or sets the culture used when reading JSON. Defaults to . - - - - - Gets a value indicating whether there will be a check for additional content after deserializing an object. - - - true if there will be a check for additional content after deserializing an object; otherwise, false. - - - - - Represents a reader that provides validation. - - - - - Initializes a new instance of the class that - validates the content returned from the given . - - The to read from while validating. - - - - Reads the next JSON token from the stream as a . - - A . - - - - Reads the next JSON token from the stream as a . - - - A or a null reference if the next JSON token is null. - - - - - Reads the next JSON token from the stream as a . - - A . - - - - Reads the next JSON token from the stream as a . - - A . This method will return null at the end of an array. - - - - Reads the next JSON token from the stream as a . - - A . This method will return null at the end of an array. - - - - Reads the next JSON token from the stream as a . - - A . - - - - Reads the next JSON token from the stream. - - - true if the next token was read successfully; false if there are no more tokens to read. - - - - - Sets an event handler for receiving schema validation errors. - - - - - Gets the text value of the current JSON token. - - - - - - Gets the depth of the current token in the JSON document. - - The depth of the current token in the JSON document. - - - - Gets the path of the current JSON token. - - - - - Gets the quotation mark character used to enclose the value of a string. - - - - - - Gets the type of the current JSON token. - - - - - - Gets the Common Language Runtime (CLR) type for the current JSON token. - - - - - - Gets or sets the schema. - - The schema. - - - - Gets the used to construct this . - - The specified in the constructor. - - - - Compares tokens to determine whether they are equal. - - - - - Determines whether the specified objects are equal. - - The first object of type to compare. - The second object of type to compare. - - true if the specified objects are equal; otherwise, false. - - - - - Returns a hash code for the specified object. - - The for which a hash code is to be returned. - A hash code for the specified object. - The type of is a reference type and is null. - - - - Specifies the member serialization options for the . - - - - - All public members are serialized by default. Members can be excluded using or . - This is the default member serialization mode. - - - - - Only members must be marked with or are serialized. - This member serialization mode can also be set by marking the class with . - - - - - All public and private fields are serialized. Members can be excluded using or . - This member serialization mode can also be set by marking the class with - and setting IgnoreSerializableAttribute on to false. - - - - - Specifies how object creation is handled by the . - - - - - Reuse existing objects, create new objects when needed. - - - - - Only reuse existing objects. - - - - - Always create new objects. - - - - - Converts a to and from the ISO 8601 date format (e.g. 2008-04-12T12:53Z). - - - - - Writes the JSON representation of the object. - - The to write to. - The value. - The calling serializer. - - - - Reads the JSON representation of the object. - - The to read from. - Type of the object. - The existing value of object being read. - The calling serializer. - The object value. - - - - Gets or sets the date time styles used when converting a date to and from JSON. - - The date time styles used when converting a date to and from JSON. - - - - Gets or sets the date time format used when converting a date to and from JSON. - - The date time format used when converting a date to and from JSON. - - - - Gets or sets the culture used when converting a date to and from JSON. - - The culture used when converting a date to and from JSON. - - - - Converts a to and from a JavaScript date constructor (e.g. new Date(52231943)). - - - - - Writes the JSON representation of the object. - - The to write to. - The value. - The calling serializer. - - - - Reads the JSON representation of the object. - - The to read from. - Type of the object. - The existing property value of the JSON that is being converted. - The calling serializer. - The object value. - - - - Converts XML to and from JSON. - - - - - Writes the JSON representation of the object. - - The to write to. - The calling serializer. - The value. - - - - Reads the JSON representation of the object. - - The to read from. - Type of the object. - The existing value of object being read. - The calling serializer. - The object value. - - - - Checks if the attributeName is a namespace attribute. - - Attribute name to test. - The attribute name prefix if it has one, otherwise an empty string. - True if attribute name is for a namespace attribute, otherwise false. - - - - Determines whether this instance can convert the specified value type. - - Type of the value. - - true if this instance can convert the specified value type; otherwise, false. - - - - - Gets or sets the name of the root element to insert when deserializing to XML if the JSON structure has produces multiple root elements. - - The name of the deserialize root element. - - - - Gets or sets a flag to indicate whether to write the Json.NET array attribute. - This attribute helps preserve arrays when converting the written XML back to JSON. - - true if the array attibute is written to the XML; otherwise, false. - - - - Gets or sets a value indicating whether to write the root JSON object. - - true if the JSON root object is omitted; otherwise, false. - - - - Represents a reader that provides fast, non-cached, forward-only access to JSON text data. - - - - - Initializes a new instance of the class with the specified . - - The TextReader containing the XML data to read. - - - - Reads the next JSON token from the stream. - - - true if the next token was read successfully; false if there are no more tokens to read. - - - - - Reads the next JSON token from the stream as a . - - - A or a null reference if the next JSON token is null. This method will return null at the end of an array. - - - - - Reads the next JSON token from the stream as a . - - A . This method will return null at the end of an array. - - - - Reads the next JSON token from the stream as a . - - A . This method will return null at the end of an array. - - - - Reads the next JSON token from the stream as a . - - A . This method will return null at the end of an array. - - - - Reads the next JSON token from the stream as a . - - A . This method will return null at the end of an array. - - - - Reads the next JSON token from the stream as a . - - A . This method will return null at the end of an array. - - - - Changes the state to closed. - - - - - Gets a value indicating whether the class can return line information. - - - true if LineNumber and LinePosition can be provided; otherwise, false. - - - - - Gets the current line number. - - - The current line number or 0 if no line information is available (for example, HasLineInfo returns false). - - - - - Gets the current line position. - - - The current line position or 0 if no line information is available (for example, HasLineInfo returns false). - - - - - Instructs the to always serialize the member with the specified name. - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the class with the specified name. - - Name of the property. - - - - Gets or sets the converter used when serializing the property's collection items. - - The collection's items converter. - - - - The parameter list to use when constructing the JsonConverter described by ItemConverterType. - If null, the default constructor is used. - When non-null, there must be a constructor defined in the JsonConverter that exactly matches the number, - order, and type of these parameters. - - - [JsonProperty(ItemConverterType = typeof(MyContainerConverter), ItemConverterParameters = new object[] { 123, "Four" })] - - - - - Gets or sets the null value handling used when serializing this property. - - The null value handling. - - - - Gets or sets the default value handling used when serializing this property. - - The default value handling. - - - - Gets or sets the reference loop handling used when serializing this property. - - The reference loop handling. - - - - Gets or sets the object creation handling used when deserializing this property. - - The object creation handling. - - - - Gets or sets the type name handling used when serializing this property. - - The type name handling. - - - - Gets or sets whether this property's value is serialized as a reference. - - Whether this property's value is serialized as a reference. - - - - Gets or sets the order of serialization and deserialization of a member. - - The numeric order of serialization or deserialization. - - - - Gets or sets a value indicating whether this property is required. - - - A value indicating whether this property is required. - - - - - Gets or sets the name of the property. - - The name of the property. - - - - Gets or sets the the reference loop handling used when serializing the property's collection items. - - The collection's items reference loop handling. - - - - Gets or sets the the type name handling used when serializing the property's collection items. - - The collection's items type name handling. - - - - Gets or sets whether this property's collection items are serialized as a reference. - - Whether this property's collection items are serialized as a reference. - - - - Instructs the not to serialize the public field or public read/write property value. - - - - - Represents a writer that provides a fast, non-cached, forward-only way of generating Json data. - - - - - Creates an instance of the JsonWriter class using the specified . - - The TextWriter to write to. - - - - Flushes whatever is in the buffer to the underlying streams and also flushes the underlying stream. - - - - - Closes this stream and the underlying stream. - - - - - Writes the beginning of a Json object. - - - - - Writes the beginning of a Json array. - - - - - Writes the start of a constructor with the given name. - - The name of the constructor. - - - - Writes the specified end token. - - The end token to write. - - - - Writes the property name of a name/value pair on a Json object. - - The name of the property. - - - - Writes the property name of a name/value pair on a JSON object. - - The name of the property. - A flag to indicate whether the text should be escaped when it is written as a JSON property name. - - - - Writes indent characters. - - - - - Writes the JSON value delimiter. - - - - - Writes an indent space. - - - - - Writes a value. - An error will raised if the value cannot be written as a single JSON token. - - The value to write. - - - - Writes a null value. - - - - - Writes an undefined value. - - - - - Writes raw JSON. - - The raw JSON to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes out a comment /*...*/ containing the specified text. - - Text to place inside the comment. - - - - Writes out the given white space. - - The string of white space characters. - - - - Gets or sets how many IndentChars to write for each level in the hierarchy when is set to Formatting.Indented. - - - - - Gets or sets which character to use to quote attribute values. - - - - - Gets or sets which character to use for indenting when is set to Formatting.Indented. - - - - - Gets or sets a value indicating whether object names will be surrounded with quotes. - - - - - The exception thrown when an error occurs while reading Json text. - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the class - with a specified error message. - - The error message that explains the reason for the exception. - - - - Initializes a new instance of the class - with a specified error message and a reference to the inner exception that is the cause of this exception. - - The error message that explains the reason for the exception. - The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. - - - - Initializes a new instance of the class. - - The that holds the serialized object data about the exception being thrown. - The that contains contextual information about the source or destination. - The parameter is null. - The class name is null or is zero (0). - - - - Gets the path to the JSON where the error occurred. - - The path to the JSON where the error occurred. - - - - The exception thrown when an error occurs while reading Json text. - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the class - with a specified error message. - - The error message that explains the reason for the exception. - - - - Initializes a new instance of the class - with a specified error message and a reference to the inner exception that is the cause of this exception. - - The error message that explains the reason for the exception. - The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. - - - - Initializes a new instance of the class. - - The that holds the serialized object data about the exception being thrown. - The that contains contextual information about the source or destination. - The parameter is null. - The class name is null or is zero (0). - - - - Gets the line number indicating where the error occurred. - - The line number indicating where the error occurred. - - - - Gets the line position indicating where the error occurred. - - The line position indicating where the error occurred. - - - - Gets the path to the JSON where the error occurred. - - The path to the JSON where the error occurred. - - - - Represents a collection of . - - - - - Provides methods for converting between common language runtime types and JSON types. - - - - - - - - Represents JavaScript's boolean value true as a string. This field is read-only. - - - - - Represents JavaScript's boolean value false as a string. This field is read-only. - - - - - Represents JavaScript's null as a string. This field is read-only. - - - - - Represents JavaScript's undefined as a string. This field is read-only. - - - - - Represents JavaScript's positive infinity as a string. This field is read-only. - - - - - Represents JavaScript's negative infinity as a string. This field is read-only. - - - - - Represents JavaScript's NaN as a string. This field is read-only. - - - - - Converts the to its JSON string representation. - - The value to convert. - A JSON string representation of the . - - - - Converts the to its JSON string representation using the specified. - - The value to convert. - The format the date will be converted to. - The time zone handling when the date is converted to a string. - A JSON string representation of the . - - - - Converts the to its JSON string representation. - - The value to convert. - A JSON string representation of the . - - - - Converts the to its JSON string representation using the specified. - - The value to convert. - The format the date will be converted to. - A JSON string representation of the . - - - - Converts the to its JSON string representation. - - The value to convert. - A JSON string representation of the . - - - - Converts the to its JSON string representation. - - The value to convert. - A JSON string representation of the . - - - - Converts the to its JSON string representation. - - The value to convert. - A JSON string representation of the . - - - - Converts the to its JSON string representation. - - The value to convert. - A JSON string representation of the . - - - - Converts the to its JSON string representation. - - The value to convert. - A JSON string representation of the . - - - - Converts the to its JSON string representation. - - The value to convert. - A JSON string representation of the . - - - - Converts the to its JSON string representation. - - The value to convert. - A JSON string representation of the . - - - - Converts the to its JSON string representation. - - The value to convert. - A JSON string representation of the . - - - - Converts the to its JSON string representation. - - The value to convert. - A JSON string representation of the . - - - - Converts the to its JSON string representation. - - The value to convert. - A JSON string representation of the . - - - - Converts the to its JSON string representation. - - The value to convert. - A JSON string representation of the . - - - - Converts the to its JSON string representation. - - The value to convert. - A JSON string representation of the . - - - - Converts the to its JSON string representation. - - The value to convert. - A JSON string representation of the . - - - - Converts the to its JSON string representation. - - The value to convert. - A JSON string representation of the . - - - - Converts the to its JSON string representation. - - The value to convert. - A JSON string representation of the . - - - - Converts the to its JSON string representation. - - The value to convert. - A JSON string representation of the . - - - - Converts the to its JSON string representation. - - The value to convert. - A JSON string representation of the . - - - - Converts the to its JSON string representation. - - The value to convert. - A JSON string representation of the . - - - - Converts the to its JSON string representation. - - The value to convert. - The string delimiter character. - A JSON string representation of the . - - - - Converts the to its JSON string representation. - - The value to convert. - The string delimiter character. - The string escape handling. - A JSON string representation of the . - - - - Converts the to its JSON string representation. - - The value to convert. - A JSON string representation of the . - - - - Serializes the specified object to a JSON string. - - The object to serialize. - A JSON string representation of the object. - - - - Serializes the specified object to a JSON string using formatting. - - The object to serialize. - Indicates how the output is formatted. - - A JSON string representation of the object. - - - - - Serializes the specified object to a JSON string using a collection of . - - The object to serialize. - A collection converters used while serializing. - A JSON string representation of the object. - - - - Serializes the specified object to a JSON string using formatting and a collection of . - - The object to serialize. - Indicates how the output is formatted. - A collection converters used while serializing. - A JSON string representation of the object. - - - - Serializes the specified object to a JSON string using . - - The object to serialize. - The used to serialize the object. - If this is null, default serialization settings will be used. - - A JSON string representation of the object. - - - - - Serializes the specified object to a JSON string using a type, formatting and . - - The object to serialize. - The used to serialize the object. - If this is null, default serialization settings will be used. - - The type of the value being serialized. - This parameter is used when is Auto to write out the type name if the type of the value does not match. - Specifing the type is optional. - - - A JSON string representation of the object. - - - - - Serializes the specified object to a JSON string using formatting and . - - The object to serialize. - Indicates how the output is formatted. - The used to serialize the object. - If this is null, default serialization settings will be used. - - A JSON string representation of the object. - - - - - Serializes the specified object to a JSON string using a type, formatting and . - - The object to serialize. - Indicates how the output is formatted. - The used to serialize the object. - If this is null, default serialization settings will be used. - - The type of the value being serialized. - This parameter is used when is Auto to write out the type name if the type of the value does not match. - Specifing the type is optional. - - - A JSON string representation of the object. - - - - - Asynchronously serializes the specified object to a JSON string. - Serialization will happen on a new thread. - - The object to serialize. - - A task that represents the asynchronous serialize operation. The value of the TResult parameter contains a JSON string representation of the object. - - - - - Asynchronously serializes the specified object to a JSON string using formatting. - Serialization will happen on a new thread. - - The object to serialize. - Indicates how the output is formatted. - - A task that represents the asynchronous serialize operation. The value of the TResult parameter contains a JSON string representation of the object. - - - - - Asynchronously serializes the specified object to a JSON string using formatting and a collection of . - Serialization will happen on a new thread. - - The object to serialize. - Indicates how the output is formatted. - The used to serialize the object. - If this is null, default serialization settings will be used. - - A task that represents the asynchronous serialize operation. The value of the TResult parameter contains a JSON string representation of the object. - - - - - Deserializes the JSON to a .NET object. - - The JSON to deserialize. - The deserialized object from the JSON string. - - - - Deserializes the JSON to a .NET object using . - - The JSON to deserialize. - - The used to deserialize the object. - If this is null, default serialization settings will be used. - - The deserialized object from the JSON string. - - - - Deserializes the JSON to the specified .NET type. - - The JSON to deserialize. - The of object being deserialized. - The deserialized object from the JSON string. - - - - Deserializes the JSON to the specified .NET type. - - The type of the object to deserialize to. - The JSON to deserialize. - The deserialized object from the JSON string. - - - - Deserializes the JSON to the given anonymous type. - - - The anonymous type to deserialize to. This can't be specified - traditionally and must be infered from the anonymous type passed - as a parameter. - - The JSON to deserialize. - The anonymous type object. - The deserialized anonymous type from the JSON string. - - - - Deserializes the JSON to the given anonymous type using . - - - The anonymous type to deserialize to. This can't be specified - traditionally and must be infered from the anonymous type passed - as a parameter. - - The JSON to deserialize. - The anonymous type object. - - The used to deserialize the object. - If this is null, default serialization settings will be used. - - The deserialized anonymous type from the JSON string. - - - - Deserializes the JSON to the specified .NET type using a collection of . - - The type of the object to deserialize to. - The JSON to deserialize. - Converters to use while deserializing. - The deserialized object from the JSON string. - - - - Deserializes the JSON to the specified .NET type using . - - The type of the object to deserialize to. - The object to deserialize. - - The used to deserialize the object. - If this is null, default serialization settings will be used. - - The deserialized object from the JSON string. - - - - Deserializes the JSON to the specified .NET type using a collection of . - - The JSON to deserialize. - The type of the object to deserialize. - Converters to use while deserializing. - The deserialized object from the JSON string. - - - - Deserializes the JSON to the specified .NET type using . - - The JSON to deserialize. - The type of the object to deserialize to. - - The used to deserialize the object. - If this is null, default serialization settings will be used. - - The deserialized object from the JSON string. - - - - Asynchronously deserializes the JSON to the specified .NET type. - Deserialization will happen on a new thread. - - The type of the object to deserialize to. - The JSON to deserialize. - - A task that represents the asynchronous deserialize operation. The value of the TResult parameter contains the deserialized object from the JSON string. - - - - - Asynchronously deserializes the JSON to the specified .NET type using . - Deserialization will happen on a new thread. - - The type of the object to deserialize to. - The JSON to deserialize. - - The used to deserialize the object. - If this is null, default serialization settings will be used. - - - A task that represents the asynchronous deserialize operation. The value of the TResult parameter contains the deserialized object from the JSON string. - - - - - Asynchronously deserializes the JSON to the specified .NET type. - Deserialization will happen on a new thread. - - The JSON to deserialize. - - A task that represents the asynchronous deserialize operation. The value of the TResult parameter contains the deserialized object from the JSON string. - - - - - Asynchronously deserializes the JSON to the specified .NET type using . - Deserialization will happen on a new thread. - - The JSON to deserialize. - The type of the object to deserialize to. - - The used to deserialize the object. - If this is null, default serialization settings will be used. - - - A task that represents the asynchronous deserialize operation. The value of the TResult parameter contains the deserialized object from the JSON string. - - - - - Populates the object with values from the JSON string. - - The JSON to populate values from. - The target object to populate values onto. - - - - Populates the object with values from the JSON string using . - - The JSON to populate values from. - The target object to populate values onto. - - The used to deserialize the object. - If this is null, default serialization settings will be used. - - - - - Asynchronously populates the object with values from the JSON string using . - - The JSON to populate values from. - The target object to populate values onto. - - The used to deserialize the object. - If this is null, default serialization settings will be used. - - - A task that represents the asynchronous populate operation. - - - - - Serializes the XML node to a JSON string. - - The node to serialize. - A JSON string of the XmlNode. - - - - Serializes the XML node to a JSON string using formatting. - - The node to serialize. - Indicates how the output is formatted. - A JSON string of the XmlNode. - - - - Serializes the XML node to a JSON string using formatting and omits the root object if is true. - - The node to serialize. - Indicates how the output is formatted. - Omits writing the root object. - A JSON string of the XmlNode. - - - - Deserializes the XmlNode from a JSON string. - - The JSON string. - The deserialized XmlNode - - - - Deserializes the XmlNode from a JSON string nested in a root elment specified by . - - The JSON string. - The name of the root element to append when deserializing. - The deserialized XmlNode - - - - Deserializes the XmlNode from a JSON string nested in a root elment specified by - and writes a .NET array attribute for collections. - - The JSON string. - The name of the root element to append when deserializing. - - A flag to indicate whether to write the Json.NET array attribute. - This attribute helps preserve arrays when converting the written XML back to JSON. - - The deserialized XmlNode - - - - Serializes the to a JSON string. - - The node to convert to JSON. - A JSON string of the XNode. - - - - Serializes the to a JSON string using formatting. - - The node to convert to JSON. - Indicates how the output is formatted. - A JSON string of the XNode. - - - - Serializes the to a JSON string using formatting and omits the root object if is true. - - The node to serialize. - Indicates how the output is formatted. - Omits writing the root object. - A JSON string of the XNode. - - - - Deserializes the from a JSON string. - - The JSON string. - The deserialized XNode - - - - Deserializes the from a JSON string nested in a root elment specified by . - - The JSON string. - The name of the root element to append when deserializing. - The deserialized XNode - - - - Deserializes the from a JSON string nested in a root elment specified by - and writes a .NET array attribute for collections. - - The JSON string. - The name of the root element to append when deserializing. - - A flag to indicate whether to write the Json.NET array attribute. - This attribute helps preserve arrays when converting the written XML back to JSON. - - The deserialized XNode - - - - Gets or sets a function that creates default . - Default settings are automatically used by serialization methods on , - and and on . - To serialize without using any default settings create a with - . - - - - - The exception thrown when an error occurs during Json serialization or deserialization. - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the class - with a specified error message. - - The error message that explains the reason for the exception. - - - - Initializes a new instance of the class - with a specified error message and a reference to the inner exception that is the cause of this exception. - - The error message that explains the reason for the exception. - The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. - - - - Initializes a new instance of the class. - - The that holds the serialized object data about the exception being thrown. - The that contains contextual information about the source or destination. - The parameter is null. - The class name is null or is zero (0). - - - - Serializes and deserializes objects into and from the JSON format. - The enables you to control how objects are encoded into JSON. - - - - - Initializes a new instance of the class. - - - - - Creates a new instance. - The will not use default settings. - - - A new instance. - The will not use default settings. - - - - - Creates a new instance using the specified . - The will not use default settings. - - The settings to be applied to the . - - A new instance using the specified . - The will not use default settings. - - - - - Creates a new instance. - The will use default settings. - - - A new instance. - The will use default settings. - - - - - Creates a new instance using the specified . - The will use default settings. - - The settings to be applied to the . - - A new instance using the specified . - The will use default settings. - - - - - Populates the JSON values onto the target object. - - The that contains the JSON structure to reader values from. - The target object to populate values onto. - - - - Populates the JSON values onto the target object. - - The that contains the JSON structure to reader values from. - The target object to populate values onto. - - - - Deserializes the Json structure contained by the specified . - - The that contains the JSON structure to deserialize. - The being deserialized. - - - - Deserializes the Json structure contained by the specified - into an instance of the specified type. - - The containing the object. - The of object being deserialized. - The instance of being deserialized. - - - - Deserializes the Json structure contained by the specified - into an instance of the specified type. - - The containing the object. - The type of the object to deserialize. - The instance of being deserialized. - - - - Deserializes the Json structure contained by the specified - into an instance of the specified type. - - The containing the object. - The of object being deserialized. - The instance of being deserialized. - - - - Serializes the specified and writes the Json structure - to a Stream using the specified . - - The used to write the Json structure. - The to serialize. - - - - Serializes the specified and writes the Json structure - to a Stream using the specified . - - The used to write the Json structure. - The to serialize. - - The type of the value being serialized. - This parameter is used when is Auto to write out the type name if the type of the value does not match. - Specifing the type is optional. - - - - - Serializes the specified and writes the Json structure - to a Stream using the specified . - - The used to write the Json structure. - The to serialize. - - The type of the value being serialized. - This parameter is used when is Auto to write out the type name if the type of the value does not match. - Specifing the type is optional. - - - - - Serializes the specified and writes the Json structure - to a Stream using the specified . - - The used to write the Json structure. - The to serialize. - - - - Occurs when the errors during serialization and deserialization. - - - - - Gets or sets the used by the serializer when resolving references. - - - - - Gets or sets the used by the serializer when resolving type names. - - - - - Gets or sets the used by the serializer when writing trace messages. - - The trace writer. - - - - Gets or sets how type name writing and reading is handled by the serializer. - - - - - Gets or sets how a type name assembly is written and resolved by the serializer. - - The type name assembly format. - - - - Gets or sets how object references are preserved by the serializer. - - - - - Get or set how reference loops (e.g. a class referencing itself) is handled. - - - - - Get or set how missing members (e.g. JSON contains a property that isn't a member on the object) are handled during deserialization. - - - - - Get or set how null values are handled during serialization and deserialization. - - - - - Get or set how null default are handled during serialization and deserialization. - - - - - Gets or sets how objects are created during deserialization. - - The object creation handling. - - - - Gets or sets how constructors are used during deserialization. - - The constructor handling. - - - - Gets or sets how metadata properties are used during deserialization. - - The metadata properties handling. - - - - Gets a collection that will be used during serialization. - - Collection that will be used during serialization. - - - - Gets or sets the contract resolver used by the serializer when - serializing .NET objects to JSON and vice versa. - - - - - Gets or sets the used by the serializer when invoking serialization callback methods. - - The context. - - - - Indicates how JSON text output is formatted. - - - - - Get or set how dates are written to JSON text. - - - - - Get or set how time zones are handling during serialization and deserialization. - - - - - Get or set how date formatted strings, e.g. "\/Date(1198908717056)\/" and "2012-03-21T05:40Z", are parsed when reading JSON. - - - - - Get or set how floating point numbers, e.g. 1.0 and 9.9, are parsed when reading JSON text. - - - - - Get or set how special floating point numbers, e.g. , - and , - are written as JSON text. - - - - - Get or set how strings are escaped when writing JSON text. - - - - - Get or set how and values are formatting when writing JSON text. - - - - - Gets or sets the culture used when reading JSON. Defaults to . - - - - - Gets or sets the maximum depth allowed when reading JSON. Reading past this depth will throw a . - - - - - Gets a value indicating whether there will be a check for additional JSON content after deserializing an object. - - - true if there will be a check for additional JSON content after deserializing an object; otherwise, false. - - - - - Contains the LINQ to JSON extension methods. - - - - - Returns a collection of tokens that contains the ancestors of every token in the source collection. - - The type of the objects in source, constrained to . - An of that contains the source collection. - An of that contains the ancestors of every node in the source collection. - - - - Returns a collection of tokens that contains the descendants of every token in the source collection. - - The type of the objects in source, constrained to . - An of that contains the source collection. - An of that contains the descendants of every node in the source collection. - - - - Returns a collection of child properties of every object in the source collection. - - An of that contains the source collection. - An of that contains the properties of every object in the source collection. - - - - Returns a collection of child values of every object in the source collection with the given key. - - An of that contains the source collection. - The token key. - An of that contains the values of every node in the source collection with the given key. - - - - Returns a collection of child values of every object in the source collection. - - An of that contains the source collection. - An of that contains the values of every node in the source collection. - - - - Returns a collection of converted child values of every object in the source collection with the given key. - - The type to convert the values to. - An of that contains the source collection. - The token key. - An that contains the converted values of every node in the source collection with the given key. - - - - Returns a collection of converted child values of every object in the source collection. - - The type to convert the values to. - An of that contains the source collection. - An that contains the converted values of every node in the source collection. - - - - Converts the value. - - The type to convert the value to. - A cast as a of . - A converted value. - - - - Converts the value. - - The source collection type. - The type to convert the value to. - A cast as a of . - A converted value. - - - - Returns a collection of child tokens of every array in the source collection. - - The source collection type. - An of that contains the source collection. - An of that contains the values of every node in the source collection. - - - - Returns a collection of converted child tokens of every array in the source collection. - - An of that contains the source collection. - The type to convert the values to. - The source collection type. - An that contains the converted values of every node in the source collection. - - - - Returns the input typed as . - - An of that contains the source collection. - The input typed as . - - - - Returns the input typed as . - - The source collection type. - An of that contains the source collection. - The input typed as . - - - - Represents a JSON constructor. - - - - - Represents a token that can contain other tokens. - - - - - Raises the event. - - The instance containing the event data. - - - - Raises the event. - - The instance containing the event data. - - - - Raises the event. - - The instance containing the event data. - - - - Returns a collection of the child tokens of this token, in document order. - - - An of containing the child tokens of this , in document order. - - - - - Returns a collection of the child values of this token, in document order. - - The type to convert the values to. - - A containing the child values of this , in document order. - - - - - Returns a collection of the descendant tokens for this token in document order. - - An containing the descendant tokens of the . - - - - Adds the specified content as children of this . - - The content to be added. - - - - Adds the specified content as the first children of this . - - The content to be added. - - - - Creates an that can be used to add tokens to the . - - An that is ready to have content written to it. - - - - Replaces the children nodes of this token with the specified content. - - The content. - - - - Removes the child nodes from this token. - - - - - Merge the specified content into this . - - The content to be merged. - - - - Merge the specified content into this using . - - The content to be merged. - The used to merge the content. - - - - Occurs when the list changes or an item in the list changes. - - - - - Occurs before an item is added to the collection. - - - - - Occurs when the items list of the collection has changed, or the collection is reset. - - - - - Gets the container's children tokens. - - The container's children tokens. - - - - Gets a value indicating whether this token has child tokens. - - - true if this token has child values; otherwise, false. - - - - - Get the first child token of this token. - - - A containing the first child token of the . - - - - - Get the last child token of this token. - - - A containing the last child token of the . - - - - - Gets the count of child JSON tokens. - - The count of child JSON tokens - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the class from another object. - - A object to copy from. - - - - Initializes a new instance of the class with the specified name and content. - - The constructor name. - The contents of the constructor. - - - - Initializes a new instance of the class with the specified name and content. - - The constructor name. - The contents of the constructor. - - - - Initializes a new instance of the class with the specified name. - - The constructor name. - - - - Writes this token to a . - - A into which this method will write. - A collection of which will be used when writing the token. - - - - Loads an from a . - - A that will be read for the content of the . - A that contains the JSON that was read from the specified . - - - - Gets the container's children tokens. - - The container's children tokens. - - - - Gets or sets the name of this constructor. - - The constructor name. - - - - Gets the node type for this . - - The type. - - - - Gets the with the specified key. - - The with the specified key. - - - - Represents a collection of objects. - - The type of token - - - - An empty collection of objects. - - - - - Initializes a new instance of the struct. - - The enumerable. - - - - Returns an enumerator that iterates through the collection. - - - A that can be used to iterate through the collection. - - - - - Returns an enumerator that iterates through a collection. - - - An object that can be used to iterate through the collection. - - - - - Determines whether the specified is equal to this instance. - - The to compare with this instance. - - true if the specified is equal to this instance; otherwise, false. - - - - - Determines whether the specified is equal to this instance. - - The to compare with this instance. - - true if the specified is equal to this instance; otherwise, false. - - - - - Returns a hash code for this instance. - - - A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. - - - - - Gets the with the specified key. - - - - - - Represents a JSON object. - - - - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the class from another object. - - A object to copy from. - - - - Initializes a new instance of the class with the specified content. - - The contents of the object. - - - - Initializes a new instance of the class with the specified content. - - The contents of the object. - - - - Gets an of this object's properties. - - An of this object's properties. - - - - Gets a the specified name. - - The property name. - A with the specified name or null. - - - - Gets an of this object's property values. - - An of this object's property values. - - - - Loads an from a . - - A that will be read for the content of the . - A that contains the JSON that was read from the specified . - - - - Load a from a string that contains JSON. - - A that contains JSON. - A populated from the string that contains JSON. - - - - - - - Creates a from an object. - - The object that will be used to create . - A with the values of the specified object - - - - Creates a from an object. - - The object that will be used to create . - The that will be used to read the object. - A with the values of the specified object - - - - Writes this token to a . - - A into which this method will write. - A collection of which will be used when writing the token. - - - - Gets the with the specified property name. - - Name of the property. - The with the specified property name. - - - - Gets the with the specified property name. - The exact property name will be searched for first and if no matching property is found then - the will be used to match a property. - - Name of the property. - One of the enumeration values that specifies how the strings will be compared. - The with the specified property name. - - - - Tries to get the with the specified property name. - The exact property name will be searched for first and if no matching property is found then - the will be used to match a property. - - Name of the property. - The value. - One of the enumeration values that specifies how the strings will be compared. - true if a value was successfully retrieved; otherwise, false. - - - - Adds the specified property name. - - Name of the property. - The value. - - - - Removes the property with the specified name. - - Name of the property. - true if item was successfully removed; otherwise, false. - - - - Tries the get value. - - Name of the property. - The value. - true if a value was successfully retrieved; otherwise, false. - - - - Returns an enumerator that iterates through the collection. - - - A that can be used to iterate through the collection. - - - - - Raises the event with the provided arguments. - - Name of the property. - - - - Raises the event with the provided arguments. - - Name of the property. - - - - Returns the properties for this instance of a component. - - - A that represents the properties for this component instance. - - - - - Returns the properties for this instance of a component using the attribute array as a filter. - - An array of type that is used as a filter. - - A that represents the filtered properties for this component instance. - - - - - Returns a collection of custom attributes for this instance of a component. - - - An containing the attributes for this object. - - - - - Returns the class name of this instance of a component. - - - The class name of the object, or null if the class does not have a name. - - - - - Returns the name of this instance of a component. - - - The name of the object, or null if the object does not have a name. - - - - - Returns a type converter for this instance of a component. - - - A that is the converter for this object, or null if there is no for this object. - - - - - Returns the default event for this instance of a component. - - - An that represents the default event for this object, or null if this object does not have events. - - - - - Returns the default property for this instance of a component. - - - A that represents the default property for this object, or null if this object does not have properties. - - - - - Returns an editor of the specified type for this instance of a component. - - A that represents the editor for this object. - - An of the specified type that is the editor for this object, or null if the editor cannot be found. - - - - - Returns the events for this instance of a component using the specified attribute array as a filter. - - An array of type that is used as a filter. - - An that represents the filtered events for this component instance. - - - - - Returns the events for this instance of a component. - - - An that represents the events for this component instance. - - - - - Returns an object that contains the property described by the specified property descriptor. - - A that represents the property whose owner is to be found. - - An that represents the owner of the specified property. - - - - - Returns the responsible for binding operations performed on this object. - - The expression tree representation of the runtime value. - - The to bind this object. - - - - - Gets the container's children tokens. - - The container's children tokens. - - - - Occurs when a property value changes. - - - - - Occurs when a property value is changing. - - - - - Gets the node type for this . - - The type. - - - - Gets the with the specified key. - - The with the specified key. - - - - Gets or sets the with the specified property name. - - - - - - Represents a JSON array. - - - - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the class from another object. - - A object to copy from. - - - - Initializes a new instance of the class with the specified content. - - The contents of the array. - - - - Initializes a new instance of the class with the specified content. - - The contents of the array. - - - - Loads an from a . - - A that will be read for the content of the . - A that contains the JSON that was read from the specified . - - - - Load a from a string that contains JSON. - - A that contains JSON. - A populated from the string that contains JSON. - - - - - - - Creates a from an object. - - The object that will be used to create . - A with the values of the specified object - - - - Creates a from an object. - - The object that will be used to create . - The that will be used to read the object. - A with the values of the specified object - - - - Writes this token to a . - - A into which this method will write. - A collection of which will be used when writing the token. - - - - Determines the index of a specific item in the . - - The object to locate in the . - - The index of if found in the list; otherwise, -1. - - - - - Inserts an item to the at the specified index. - - The zero-based index at which should be inserted. - The object to insert into the . - - is not a valid index in the . - The is read-only. - - - - Removes the item at the specified index. - - The zero-based index of the item to remove. - - is not a valid index in the . - The is read-only. - - - - Returns an enumerator that iterates through the collection. - - - A that can be used to iterate through the collection. - - - - - Adds an item to the . - - The object to add to the . - The is read-only. - - - - Removes all items from the . - - The is read-only. - - - - Determines whether the contains a specific value. - - The object to locate in the . - - true if is found in the ; otherwise, false. - - - - - Copies to. - - The array. - Index of the array. - - - - Removes the first occurrence of a specific object from the . - - The object to remove from the . - - true if was successfully removed from the ; otherwise, false. This method also returns false if is not found in the original . - - The is read-only. - - - - Gets the container's children tokens. - - The container's children tokens. - - - - Gets the node type for this . - - The type. - - - - Gets the with the specified key. - - The with the specified key. - - - - Gets or sets the at the specified index. - - - - - - Gets a value indicating whether the is read-only. - - true if the is read-only; otherwise, false. - - - - Represents a reader that provides fast, non-cached, forward-only access to serialized Json data. - - - - - Initializes a new instance of the class. - - The token to read from. - - - - Reads the next JSON token from the stream as a . - - - A or a null reference if the next JSON token is null. This method will return null at the end of an array. - - - - - Reads the next JSON token from the stream as a . - - A . This method will return null at the end of an array. - - - - Reads the next JSON token from the stream as a . - - A . This method will return null at the end of an array. - - - - Reads the next JSON token from the stream as a . - - A . This method will return null at the end of an array. - - - - Reads the next JSON token from the stream as a . - - A . This method will return null at the end of an array. - - - - Reads the next JSON token from the stream as a . - - A . This method will return null at the end of an array. - - - - Reads the next JSON token from the stream. - - - true if the next token was read successfully; false if there are no more tokens to read. - - - - - Gets the path of the current JSON token. - - - - - Represents a writer that provides a fast, non-cached, forward-only way of generating Json data. - - - - - Initializes a new instance of the class writing to the given . - - The container being written to. - - - - Initializes a new instance of the class. - - - - - Flushes whatever is in the buffer to the underlying streams and also flushes the underlying stream. - - - - - Closes this stream and the underlying stream. - - - - - Writes the beginning of a Json object. - - - - - Writes the beginning of a Json array. - - - - - Writes the start of a constructor with the given name. - - The name of the constructor. - - - - Writes the end. - - The token. - - - - Writes the property name of a name/value pair on a Json object. - - The name of the property. - - - - Writes a value. - An error will raised if the value cannot be written as a single JSON token. - - The value to write. - - - - Writes a null value. - - - - - Writes an undefined value. - - - - - Writes raw JSON. - - The raw JSON to write. - - - - Writes out a comment /*...*/ containing the specified text. - - Text to place inside the comment. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Writes a value. - - The value to write. - - - - Gets the token being writen. - - The token being writen. - - - - Represents a JSON property. - - - - - Initializes a new instance of the class from another object. - - A object to copy from. - - - - Initializes a new instance of the class. - - The property name. - The property content. - - - - Initializes a new instance of the class. - - The property name. - The property content. - - - - Writes this token to a . - - A into which this method will write. - A collection of which will be used when writing the token. - - - - Loads an from a . - - A that will be read for the content of the . - A that contains the JSON that was read from the specified . - - - - Gets the container's children tokens. - - The container's children tokens. - - - - Gets the property name. - - The property name. - - - - Gets or sets the property value. - - The property value. - - - - Gets the node type for this . - - The type. - - - - Specifies the type of token. - - - - - No token type has been set. - - - - - A JSON object. - - - - - A JSON array. - - - - - A JSON constructor. - - - - - A JSON object property. - - - - - A comment. - - - - - An integer value. - - - - - A float value. - - - - - A string value. - - - - - A boolean value. - - - - - A null value. - - - - - An undefined value. - - - - - A date value. - - - - - A raw JSON value. - - - - - A collection of bytes value. - - - - - A Guid value. - - - - - A Uri value. - - - - - A TimeSpan value. - - - - - Contains the JSON schema extension methods. - - - - - Determines whether the is valid. - - The source to test. - The schema to test with. - - true if the specified is valid; otherwise, false. - - - - - Determines whether the is valid. - - The source to test. - The schema to test with. - When this method returns, contains any error messages generated while validating. - - true if the specified is valid; otherwise, false. - - - - - Validates the specified . - - The source to test. - The schema to test with. - - - - Validates the specified . - - The source to test. - The schema to test with. - The validation event handler. - - - - Returns detailed information about the schema exception. - - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the class - with a specified error message. - - The error message that explains the reason for the exception. - - - - Initializes a new instance of the class - with a specified error message and a reference to the inner exception that is the cause of this exception. - - The error message that explains the reason for the exception. - The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. - - - - Initializes a new instance of the class. - - The that holds the serialized object data about the exception being thrown. - The that contains contextual information about the source or destination. - The parameter is null. - The class name is null or is zero (0). - - - - Gets the line number indicating where the error occurred. - - The line number indicating where the error occurred. - - - - Gets the line position indicating where the error occurred. - - The line position indicating where the error occurred. - - - - Gets the path to the JSON where the error occurred. - - The path to the JSON where the error occurred. - - - - Resolves from an id. - - - - - Initializes a new instance of the class. - - - - - Gets a for the specified reference. - - The id. - A for the specified reference. - - - - Gets or sets the loaded schemas. - - The loaded schemas. - - - - Specifies undefined schema Id handling options for the . - - - - - Do not infer a schema Id. - - - - - Use the .NET type name as the schema Id. - - - - - Use the assembly qualified .NET type name as the schema Id. - - - - - Returns detailed information related to the . - - - - - Gets the associated with the validation error. - - The JsonSchemaException associated with the validation error. - - - - Gets the path of the JSON location where the validation error occurred. - - The path of the JSON location where the validation error occurred. - - - - Gets the text description corresponding to the validation error. - - The text description. - - - - Represents the callback method that will handle JSON schema validation events and the . - - - - - Resolves member mappings for a type, camel casing property names. - - - - - Used by to resolves a for a given . - - - - - Used by to resolves a for a given . - - - - - - - - - Resolves the contract for a given type. - - The type to resolve a contract for. - The contract for a given type. - - - - Initializes a new instance of the class. - - - - - Initializes a new instance of the class. - - - If set to true the will use a cached shared with other resolvers of the same type. - Sharing the cache will significantly improve performance with multiple resolver instances because expensive reflection will only - happen once. This setting can cause unexpected behavior if different instances of the resolver are suppose to produce different - results. When set to false it is highly recommended to reuse instances with the . - - - - - Resolves the contract for a given type. - - The type to resolve a contract for. - The contract for a given type. - - - - Gets the serializable members for the type. - - The type to get serializable members for. - The serializable members for the type. - - - - Creates a for the given type. - - Type of the object. - A for the given type. - - - - Creates the constructor parameters. - - The constructor to create properties for. - The type's member properties. - Properties for the given . - - - - Creates a for the given . - - The matching member property. - The constructor parameter. - A created for the given . - - - - Resolves the default for the contract. - - Type of the object. - The contract's default . - - - - Creates a for the given type. - - Type of the object. - A for the given type. - - - - Creates a for the given type. - - Type of the object. - A for the given type. - - - - Creates a for the given type. - - Type of the object. - A for the given type. - - - - Creates a for the given type. - - Type of the object. - A for the given type. - - - - Creates a for the given type. - - Type of the object. - A for the given type. - - - - Creates a for the given type. - - Type of the object. - A for the given type. - - - - Creates a for the given type. - - Type of the object. - A for the given type. - - - - Determines which contract type is created for the given type. - - Type of the object. - A for the given type. - - - - Creates properties for the given . - - The type to create properties for. - /// The member serialization mode for the type. - Properties for the given . - - - - Creates the used by the serializer to get and set values from a member. - - The member. - The used by the serializer to get and set values from a member. - - - - Creates a for the given . - - The member's parent . - The member to create a for. - A created for the given . - - - - Resolves the name of the property. - - Name of the property. - Name of the property. - - - - Gets the resolved name of the property. - - Name of the property. - Name of the property. - - - - Gets a value indicating whether members are being get and set using dynamic code generation. - This value is determined by the runtime permissions available. - - - true if using dynamic code generation; otherwise, false. - - - - - Gets or sets the default members search flags. - - The default members search flags. - - - - Gets or sets a value indicating whether compiler generated members should be serialized. - - - true if serialized compiler generated members; otherwise, false. - - - - - Gets or sets a value indicating whether to ignore the interface when serializing and deserializing types. - - - true if the interface will be ignored when serializing and deserializing types; otherwise, false. - - - - - Gets or sets a value indicating whether to ignore the attribute when serializing and deserializing types. - - - true if the attribute will be ignored when serializing and deserializing types; otherwise, false. - - - - - Initializes a new instance of the class. - - - - - Resolves the name of the property. - - Name of the property. - The property name camel cased. - - - - The default serialization binder used when resolving and loading classes from type names. - - - - - When overridden in a derived class, controls the binding of a serialized object to a type. - - Specifies the name of the serialized object. - Specifies the name of the serialized object. - - The type of the object the formatter creates a new instance of. - - - - - When overridden in a derived class, controls the binding of a serialized object to a type. - - The type of the object the formatter creates a new instance of. - Specifies the name of the serialized object. - Specifies the name of the serialized object. - - - - Provides information surrounding an error. - - - - - Gets the error. - - The error. - - - - Gets the original object that caused the error. - - The original object that caused the error. - - - - Gets the member that caused the error. - - The member that caused the error. - - - - Gets the path of the JSON location where the error occurred. - - The path of the JSON location where the error occurred. - - - - Gets or sets a value indicating whether this is handled. - - true if handled; otherwise, false. - - - - Contract details for a used by the . - - - - - Initializes a new instance of the class. - - The underlying type for the contract. - - - - Gets the of the collection items. - - The of the collection items. - - - - Gets a value indicating whether the collection type is a multidimensional array. - - true if the collection type is a multidimensional array; otherwise, false. - - - - Handles serialization callback events. - - The object that raised the callback event. - The streaming context. - - - - Handles serialization error callback events. - - The object that raised the callback event. - The streaming context. - The error context. - - - - Sets extension data for an object during deserialization. - - The object to set extension data on. - The extension data key. - The extension data value. - - - - Gets extension data for an object during serialization. - - The object to set extension data on. - - - - Contract details for a used by the . - - - - - Initializes a new instance of the class. - - The underlying type for the contract. - - - - Gets or sets the property name resolver. - - The property name resolver. - - - - Gets the of the dictionary keys. - - The of the dictionary keys. - - - - Gets the of the dictionary values. - - The of the dictionary values. - - - - Maps a JSON property to a .NET member or constructor parameter. - - - - - Returns a that represents this instance. - - - A that represents this instance. - - - - - Gets or sets the name of the property. - - The name of the property. - - - - Gets or sets the type that declared this property. - - The type that declared this property. - - - - Gets or sets the order of serialization and deserialization of a member. - - The numeric order of serialization or deserialization. - - - - Gets or sets the name of the underlying member or parameter. - - The name of the underlying member or parameter. - - - - Gets the that will get and set the during serialization. - - The that will get and set the during serialization. - - - - Gets or sets the type of the property. - - The type of the property. - - - - Gets or sets the for the property. - If set this converter takes presidence over the contract converter for the property type. - - The converter. - - - - Gets or sets the member converter. - - The member converter. - - - - Gets or sets a value indicating whether this is ignored. - - true if ignored; otherwise, false. - - - - Gets or sets a value indicating whether this is readable. - - true if readable; otherwise, false. - - - - Gets or sets a value indicating whether this is writable. - - true if writable; otherwise, false. - - - - Gets or sets a value indicating whether this has a member attribute. - - true if has a member attribute; otherwise, false. - - - - Gets the default value. - - The default value. - - - - Gets or sets a value indicating whether this is required. - - A value indicating whether this is required. - - - - Gets or sets a value indicating whether this property preserves object references. - - - true if this instance is reference; otherwise, false. - - - - - Gets or sets the property null value handling. - - The null value handling. - - - - Gets or sets the property default value handling. - - The default value handling. - - - - Gets or sets the property reference loop handling. - - The reference loop handling. - - - - Gets or sets the property object creation handling. - - The object creation handling. - - - - Gets or sets or sets the type name handling. - - The type name handling. - - - - Gets or sets a predicate used to determine whether the property should be serialize. - - A predicate used to determine whether the property should be serialize. - - - - Gets or sets a predicate used to determine whether the property should be serialized. - - A predicate used to determine whether the property should be serialized. - - - - Gets or sets an action used to set whether the property has been deserialized. - - An action used to set whether the property has been deserialized. - - - - Gets or sets the converter used when serializing the property's collection items. - - The collection's items converter. - - - - Gets or sets whether this property's collection items are serialized as a reference. - - Whether this property's collection items are serialized as a reference. - - - - Gets or sets the the type name handling used when serializing the property's collection items. - - The collection's items type name handling. - - - - Gets or sets the the reference loop handling used when serializing the property's collection items. - - The collection's items reference loop handling. - - - - A collection of objects. - - - - - Initializes a new instance of the class. - - The type. - - - - When implemented in a derived class, extracts the key from the specified element. - - The element from which to extract the key. - The key for the specified element. - - - - Adds a object. - - The property to add to the collection. - - - - Gets the closest matching object. - First attempts to get an exact case match of propertyName and then - a case insensitive match. - - Name of the property. - A matching property if found. - - - - Gets a property by property name. - - The name of the property to get. - Type property name string comparison. - A matching property if found. - - - - Specifies missing member handling options for the . - - - - - Ignore a missing member and do not attempt to deserialize it. - - - - - Throw a when a missing member is encountered during deserialization. - - - - - Specifies null value handling options for the . - - - - - - - - - Include null values when serializing and deserializing objects. - - - - - Ignore null values when serializing and deserializing objects. - - - - - Specifies reference loop handling options for the . - - - - - Throw a when a loop is encountered. - - - - - Ignore loop references and do not serialize. - - - - - Serialize loop references. - - - - - An in-memory representation of a JSON Schema. - - - - - Initializes a new instance of the class. - - - - - Reads a from the specified . - - The containing the JSON Schema to read. - The object representing the JSON Schema. - - - - Reads a from the specified . - - The containing the JSON Schema to read. - The to use when resolving schema references. - The object representing the JSON Schema. - - - - Load a from a string that contains schema JSON. - - A that contains JSON. - A populated from the string that contains JSON. - - - - Parses the specified json. - - The json. - The resolver. - A populated from the string that contains JSON. - - - - Writes this schema to a . - - A into which this method will write. - - - - Writes this schema to a using the specified . - - A into which this method will write. - The resolver used. - - - - Returns a that represents the current . - - - A that represents the current . - - - - - Gets or sets the id. - - - - - Gets or sets the title. - - - - - Gets or sets whether the object is required. - - - - - Gets or sets whether the object is read only. - - - - - Gets or sets whether the object is visible to users. - - - - - Gets or sets whether the object is transient. - - - - - Gets or sets the description of the object. - - - - - Gets or sets the types of values allowed by the object. - - The type. - - - - Gets or sets the pattern. - - The pattern. - - - - Gets or sets the minimum length. - - The minimum length. - - - - Gets or sets the maximum length. - - The maximum length. - - - - Gets or sets a number that the value should be divisble by. - - A number that the value should be divisble by. - - - - Gets or sets the minimum. - - The minimum. - - - - Gets or sets the maximum. - - The maximum. - - - - Gets or sets a flag indicating whether the value can not equal the number defined by the "minimum" attribute. - - A flag indicating whether the value can not equal the number defined by the "minimum" attribute. - - - - Gets or sets a flag indicating whether the value can not equal the number defined by the "maximum" attribute. - - A flag indicating whether the value can not equal the number defined by the "maximum" attribute. - - - - Gets or sets the minimum number of items. - - The minimum number of items. - - - - Gets or sets the maximum number of items. - - The maximum number of items. - - - - Gets or sets the of items. - - The of items. - - - - Gets or sets a value indicating whether items in an array are validated using the instance at their array position from . - - - true if items are validated using their array position; otherwise, false. - - - - - Gets or sets the of additional items. - - The of additional items. - - - - Gets or sets a value indicating whether additional items are allowed. - - - true if additional items are allowed; otherwise, false. - - - - - Gets or sets whether the array items must be unique. - - - - - Gets or sets the of properties. - - The of properties. - - - - Gets or sets the of additional properties. - - The of additional properties. - - - - Gets or sets the pattern properties. - - The pattern properties. - - - - Gets or sets a value indicating whether additional properties are allowed. - - - true if additional properties are allowed; otherwise, false. - - - - - Gets or sets the required property if this property is present. - - The required property if this property is present. - - - - Gets or sets the a collection of valid enum values allowed. - - A collection of valid enum values allowed. - - - - Gets or sets disallowed types. - - The disallow types. - - - - Gets or sets the default value. - - The default value. - - - - Gets or sets the collection of that this schema extends. - - The collection of that this schema extends. - - - - Gets or sets the format. - - The format. - - - - Generates a from a specified . - - - - - Generate a from the specified type. - - The type to generate a from. - A generated from the specified type. - - - - Generate a from the specified type. - - The type to generate a from. - The used to resolve schema references. - A generated from the specified type. - - - - Generate a from the specified type. - - The type to generate a from. - Specify whether the generated root will be nullable. - A generated from the specified type. - - - - Generate a from the specified type. - - The type to generate a from. - The used to resolve schema references. - Specify whether the generated root will be nullable. - A generated from the specified type. - - - - Gets or sets how undefined schemas are handled by the serializer. - - - - - Gets or sets the contract resolver. - - The contract resolver. - - - - The value types allowed by the . - - - - - No type specified. - - - - - String type. - - - - - Float type. - - - - - Integer type. - - - - - Boolean type. - - - - - Object type. - - - - - Array type. - - - - - Null type. - - - - - Any type. - - - - - Contract details for a used by the . - - - - - Initializes a new instance of the class. - - The underlying type for the contract. - - - - Gets or sets the object member serialization. - - The member object serialization. - - - - Gets or sets a value that indicates whether the object's properties are required. - - - A value indicating whether the object's properties are required. - - - - - Gets the object's properties. - - The object's properties. - - - - Gets the constructor parameters required for any non-default constructor - - - - - Gets a collection of instances that define the parameters used with . - - - - - Gets or sets the override constructor used to create the object. - This is set when a constructor is marked up using the - JsonConstructor attribute. - - The override constructor. - - - - Gets or sets the parametrized constructor used to create the object. - - The parametrized constructor. - - - - Gets or sets the function used to create the object. When set this function will override . - This function is called with a collection of arguments which are defined by the collection. - - The function used to create the object. - - - - Gets or sets the extension data setter. - - - - - Gets or sets the extension data getter. - - - - - Contract details for a used by the . - - - - - Initializes a new instance of the class. - - The underlying type for the contract. - - - - Lookup and create an instance of the JsonConverter type described by the argument. - - The JsonConverter type to create. - Optional arguments to pass to an initializing constructor of the JsonConverter. - If null, the default constructor is used. - - - - Create a factory function that can be used to create instances of a JsonConverter described by the - argument type. The returned function can then be used to either invoke the converter's default ctor, or any - parameterized constructors by way of an object array. - - - - - Get and set values for a using reflection. - - - - - Initializes a new instance of the class. - - The member info. - - - - Sets the value. - - The target to set the value on. - The value to set on the target. - - - - Gets the value. - - The target to get the value from. - The value. - - - - When applied to a method, specifies that the method is called when an error occurs serializing an object. - - - - - Helper method for generating a MetaObject which calls a - specific method on Dynamic that returns a result - - - - - Helper method for generating a MetaObject which calls a - specific method on Dynamic, but uses one of the arguments for - the result. - - - - - Helper method for generating a MetaObject which calls a - specific method on Dynamic, but uses one of the arguments for - the result. - - - - - Returns a Restrictions object which includes our current restrictions merged - with a restriction limiting our type - - - - - Represents a method that constructs an object. - - The object type to create. - - - - Specifies type name handling options for the . - - - - - Do not include the .NET type name when serializing types. - - - - - Include the .NET type name when serializing into a JSON object structure. - - - - - Include the .NET type name when serializing into a JSON array structure. - - - - - Always include the .NET type name when serializing. - - - - - Include the .NET type name when the type of the object being serialized is not the same as its declared type. - - - - - Converts the value to the specified type. If the value is unable to be converted, the - value is checked whether it assignable to the specified type. - - The value to convert. - The culture to use when converting. - The type to convert or cast the value to. - - The converted type. If conversion was unsuccessful, the initial value - is returned if assignable to the target type. - - - - - Gets a dictionary of the names and values of an Enum type. - - - - - - Gets a dictionary of the names and values of an Enum type. - - The enum type to get names and values for. - - - - - Specifies the type of Json token. - - - - - This is returned by the if a method has not been called. - - - - - An object start token. - - - - - An array start token. - - - - - A constructor start token. - - - - - An object property name. - - - - - A comment. - - - - - Raw JSON. - - - - - An integer. - - - - - A float. - - - - - A string. - - - - - A boolean. - - - - - A null token. - - - - - An undefined token. - - - - - An object end token. - - - - - An array end token. - - - - - A constructor end token. - - - - - A Date. - - - - - Byte data. - - - - - Builds a string. Unlike StringBuilder this class lets you reuse it's internal buffer. - - - - - Determines whether the collection is null or empty. - - The collection. - - true if the collection is null or empty; otherwise, false. - - - - - Adds the elements of the specified collection to the specified generic IList. - - The list to add to. - The collection of elements to add. - - - - Returns the index of the first occurrence in a sequence by using a specified IEqualityComparer. - - The type of the elements of source. - A sequence in which to locate a value. - The object to locate in the sequence - An equality comparer to compare values. - The zero-based index of the first occurrence of value within the entire sequence, if found; otherwise, –1. - - - - Gets the type of the typed collection's items. - - The type. - The type of the typed collection's items. - - - - Gets the member's underlying type. - - The member. - The underlying type of the member. - - - - Determines whether the member is an indexed property. - - The member. - - true if the member is an indexed property; otherwise, false. - - - - - Determines whether the property is an indexed property. - - The property. - - true if the property is an indexed property; otherwise, false. - - - - - Gets the member's value on the object. - - The member. - The target object. - The member's value on the object. - - - - Sets the member's value on the target object. - - The member. - The target. - The value. - - - - Determines whether the specified MemberInfo can be read. - - The MemberInfo to determine whether can be read. - /// if set to true then allow the member to be gotten non-publicly. - - true if the specified MemberInfo can be read; otherwise, false. - - - - - Determines whether the specified MemberInfo can be set. - - The MemberInfo to determine whether can be set. - if set to true then allow the member to be set non-publicly. - if set to true then allow the member to be set if read-only. - - true if the specified MemberInfo can be set; otherwise, false. - - - - - Determines whether the string is all white space. Empty string will return false. - - The string to test whether it is all white space. - - true if the string is all white space; otherwise, false. - - - - - Nulls an empty string. - - The string. - Null if the string was null, otherwise the string unchanged. - - - - Specifies the state of the . - - - - - An exception has been thrown, which has left the in an invalid state. - You may call the method to put the in the Closed state. - Any other method calls results in an being thrown. - - - - - The method has been called. - - - - - An object is being written. - - - - - A array is being written. - - - - - A constructor is being written. - - - - - A property is being written. - - - - - A write method has not been called. - - - - diff --git a/bin/Nini.dll b/bin/Nini.dll index 2d16d95aca..aa4d431216 100755 Binary files a/bin/Nini.dll and b/bin/Nini.dll differ diff --git a/bin/Npgsql.dll b/bin/Npgsql.dll old mode 100755 new mode 100644 index 24ca4bde64..693cccb425 Binary files a/bin/Npgsql.dll and b/bin/Npgsql.dll differ diff --git a/bin/Npgsql.xml b/bin/Npgsql.xml index a51252d119..81334301da 100644 --- a/bin/Npgsql.xml +++ b/bin/Npgsql.xml @@ -4,1379 +4,6 @@ Npgsql - - - This class represents a parameter to a command that will be sent to server - - - - - Initializes a new instance of the NpgsqlParameter class. - - - - - Initializes a new instance of the NpgsqlParameter - class with the parameter m_Name and a value of the new NpgsqlParameter. - - The m_Name of the parameter to map. - An Object that is the value of the NpgsqlParameter. - -

When you specify an Object - in the value parameter, the DbType is - inferred from the .NET Framework type of the Object.

-

When using this constructor, you must be aware of a possible misuse of the constructor which takes a DbType parameter. - This happens when calling this constructor passing an int 0 and the compiler thinks you are passing a value of DbType. - Use Convert.ToInt32(value) for example to have compiler calling the correct constructor.

-
-
- - - Initializes a new instance of the NpgsqlParameter - class with the parameter m_Name and the data type. - - The m_Name of the parameter to map. - One of the DbType values. - - - - Initializes a new instance of the NpgsqlParameter - class with the parameter m_Name, the DbType, and the size. - - The m_Name of the parameter to map. - One of the DbType values. - The length of the parameter. - - - - Initializes a new instance of the NpgsqlParameter - class with the parameter m_Name, the DbType, the size, - and the source column m_Name. - - The m_Name of the parameter to map. - One of the DbType values. - The length of the parameter. - The m_Name of the source column. - - - - Initializes a new instance of the NpgsqlParameter - class with the parameter m_Name, the DbType, the size, - the source column m_Name, a ParameterDirection, - the precision of the parameter, the scale of the parameter, a - DataRowVersion to use, and the - value of the parameter. - - The m_Name of the parameter to map. - One of the DbType values. - The length of the parameter. - The m_Name of the source column. - One of the ParameterDirection values. - true if the value of the field can be null, otherwise false. - The total number of digits to the left and right of the decimal point to which - Value is resolved. - The total number of decimal places to which - Value is resolved. - One of the DataRowVersion values. - An Object that is the value - of the NpgsqlParameter. - - - - Creates a new NpgsqlParameter that - is a copy of the current instance. - - A new NpgsqlParameter that is a copy of this instance. - - - - Gets or sets the maximum number of digits used to represent the - Value property. - - The maximum number of digits used to represent the - Value property. - The default value is 0, which indicates that the data provider - sets the precision for Value. - - - - Gets or sets the number of decimal places to which - Value is resolved. - - The number of decimal places to which - Value is resolved. The default is 0. - - - - Gets or sets the maximum size, in bytes, of the data within the column. - - The maximum size, in bytes, of the data within the column. - The default value is inferred from the parameter value. - - - - Gets or sets the DbType of the parameter. - - One of the DbType values. The default is String. - - - - Gets or sets the DbType of the parameter. - - One of the DbType values. The default is String. - - - - Gets or sets a value indicating whether the parameter is input-only, - output-only, bidirectional, or a stored procedure return value parameter. - - One of the ParameterDirection - values. The default is Input. - - - - Gets or sets a value indicating whether the parameter accepts null values. - - true if null values are accepted; otherwise, false. The default is false. - - - - Gets or sets the m_Name of the NpgsqlParameter. - - The m_Name of the NpgsqlParameter. - The default is an empty string. - - - - The m_Name scrubbed of any optional marker - - - - - Gets or sets the m_Name of the source column that is mapped to the - DataSet and used for loading or - returning the Value. - - The m_Name of the source column that is mapped to the - DataSet. The default is an empty string. - - - - Gets or sets the DataRowVersion - to use when loading Value. - - One of the DataRowVersion values. - The default is Current. - - - - Gets or sets the value of the parameter. - - An Object that is the value of the parameter. - The default value is null. - - - - Gets or sets the value of the parameter. - - An Object that is the value of the parameter. - The default value is null. - - - - This class represents the Parse message sent to PostgreSQL - server. - - - - - - For classes representing messages sent from the client to the server. - - - - - Writes given objects into a stream for PostgreSQL COPY in default copy format (not CSV or BINARY). - - - - - Return an exact copy of this NpgsqlConnectionString. - - - - - This function will set value for known key, both private member and base[key]. - - - - - - - The function will modify private member only, not base[key]. - - - - - - - Clear the member and assign them to the default value. - - - - - Compatibilty version. When possible, behaviour caused by breaking changes will be preserved - if this version is less than that where the breaking change was introduced. - - - - - Case insensative accessor for indivual connection string values. - - - - - Common base class for all derived MD5 implementations. - - - - - Called from constructor of derived class. - - - - - Finalizer for HashAlgorithm - - - - - Computes the entire hash of all the bytes in the byte array. - - - - - When overridden in a derived class, drives the hashing function. - - - - - - - - When overridden in a derived class, this pads and hashes whatever data might be left in the buffers and then returns the hash created. - - - - - When overridden in a derived class, initializes the object to prepare for hashing. - - - - - Used for stream chaining. Computes hash as data passes through it. - - The buffer from which to grab the data to be copied. - The offset into the input buffer to start reading at. - The number of bytes to be copied. - The buffer to write the copied data to. - At what point in the outputBuffer to write the data at. - - - - Used for stream chaining. Computes hash as data passes through it. Finishes off the hash. - - The buffer from which to grab the data to be copied. - The offset into the input buffer to start reading at. - The number of bytes to be copied. - - - - Get whether or not the hash can transform multiple blocks at a time. - Note: MUST be overriden if descendant can transform multiple block - on a single call! - - - - - Gets the previously computed hash. - - - - - Returns the size in bits of the hash. - - - - - Must be overriden if not 1 - - - - - Must be overriden if not 1 - - - - - Called from constructor of derived class. - - - - - Creates the default derived class. - - - - - Given a join expression and a projection, fetch all columns in the projection - that reference columns in the join. - - - - - Given an InputExpression append all from names (including nested joins) to the list. - - - - - Get new ColumnExpression that will be used in projection that had it's existing columns moved. - These should be simple references to the inner column - - - - - Every property accessed in the list of columns must be adjusted for a new scope - - - - - This class provides many util methods to handle - reading and writing of PostgreSQL protocol messages. - - - - - This method takes a ProtocolVersion and returns an integer - version number that the Postgres backend will recognize in a - startup packet. - - - - - This method takes a version string as returned by SELECT VERSION() and returns - a valid version string ("7.2.2" for example). - This is only needed when running protocol version 2. - This does not do any validity checks. - - - - - This method gets a C NULL terminated string from the network stream. - It keeps reading a byte in each time until a NULL byte is returned. - It returns the resultant string of bytes read. - This string is sent from backend. - - - - - Reads requested number of bytes from stream with retries until Stream.Read returns 0 or count is reached. - - Stream to read - byte buffer to fill - starting position to fill the buffer - number of bytes to read - The number of bytes read. May be less than count if no more bytes are available. - - - - This method writes a C NULL terminated string to the network stream. - It appends a NULL terminator to the end of the String. - - - This method writes a C NULL terminated string to the network stream. - It appends a NULL terminator to the end of the String. - - - - - This method writes a set of bytes to the stream. It also enables logging of them. - - - - - This method writes a C NULL terminated string limited in length to the - backend server. - It pads the string with null bytes to the size specified. - - - - - Write a 32-bit integer to the given stream in the correct byte order. - - - - - Read a 32-bit integer from the given stream in the correct byte order. - - - - - Write a 16-bit integer to the given stream in the correct byte order. - - - - - Read a 16-bit integer from the given stream in the correct byte order. - - - - - Represent the frontend/backend protocol version. - - - - - Represent the backend server version. - As this class offers no functionality beyond that offered by it has been - deprecated in favour of that class. - - - - - - Returns the string representation of this version in three place dot notation (Major.Minor.Patch). - - - - - Server version major number. - - - - - Server version minor number. - - - - - Server version patch level number. - - - - - Represents a PostgreSQL COPY TO STDOUT operation with a corresponding SQL statement - to execute against a PostgreSQL database - and an associated stream used to write results to (if provided by user) - or for reading the results (when generated by driver). - Eg. new NpgsqlCopyOut("COPY (SELECT * FROM mytable) TO STDOUT", connection, streamToWrite).Start(); - - - - - Creates NpgsqlCommand to run given query upon Start(), after which CopyStream provides data from database as requested in the query. - - - - - Given command is run upon Start(), after which CopyStream provides data from database as requested in the query. - - - - - Given command is executed upon Start() and all requested copy data is written to toStream immediately. - - - - - Returns true if this operation is currently active and field at given location is in binary format. - - - - - Command specified upon creation is executed as a non-query. - If CopyStream is set upon creation, all copy data from server will be written to it, and operation will be finished immediately. - Otherwise the CopyStream member can be used for reading copy data from server until no more data is available. - - - - - Flush generated CopyStream at once. Effectively reads and discard all the rest of copy data from server. - - - - - Returns true if the connection is currently reserved for this operation. - - - - - The stream provided by user or generated upon Start() - - - - - The Command used to execute this copy operation. - - - - - Returns true if this operation is currently active and in binary format. - - - - - Returns number of fields if this operation is currently active, otherwise -1 - - - - - Faster alternative to using the generated CopyStream. - - - - - This class manages all connector objects, pooled AND non-pooled. - - - - Unique static instance of the connector pool - mamager. - - - Map of index to unused pooled connectors, avaliable to the - next RequestConnector() call. - This hashmap will be indexed by connection string. - This key will hold a list of queues of pooled connectors available to be used. - - - Timer for tracking unused connections in pools. - - - - Searches the shared and pooled connector lists for a - matching connector object or creates a new one. - - The NpgsqlConnection that is requesting - the connector. Its ConnectionString will be used to search the - pool for available connectors. - A connector object. - - - - Find a pooled connector. Handle locking and timeout here. - - - - - Find a pooled connector. Handle shared/non-shared here. - - - - - Releases a connector, possibly back to the pool for future use. - - - Pooled connectors will be put back into the pool if there is room. - Shared connectors should just have their use count decremented - since they always stay in the shared pool. - - The connector to release. - - - - Release a pooled connector. Handle locking here. - - - - - Release a pooled connector. Handle shared/non-shared here. - - - - - Create a connector without any pooling functionality. - - - - - Find an available pooled connector in the non-shared pool, or create - a new one if none found. - - - - - This method is only called when NpgsqlConnection.Dispose(false) is called which means a - finalization. This also means, an NpgsqlConnection was leak. We clear pool count so that - client doesn't end running out of connections from pool. When the connection is finalized, its underlying - socket is closed. - - - - - Close the connector. - - - Connector to release - - - - Put a pooled connector into the pool queue. - - Connector to pool - - - - A queue with an extra Int32 for keeping track of busy connections. - - - - - Connections available to the end user - - - - - Connections currently in use - - - - - This class represents a BackEndKeyData message received - from PostgreSQL - - - - - Used when a connection is closed - - - - - Summary description for NpgsqlQuery - - - - - Represents the method that handles the Notice events. - - A NpgsqlNoticeEventArgs that contains the event data. - - - - Represents the method that handles the Notification events. - - The source of the event. - A NpgsqlNotificationEventArgs that contains the event data. - - - - This class represents a connection to a - PostgreSQL server. - - - - - Initializes a new instance of the - NpgsqlConnection class. - - - - - Initializes a new instance of the - NpgsqlConnection class - and sets the ConnectionString. - - The connection used to open the PostgreSQL database. - - - - Begins a database transaction with the specified isolation level. - - The isolation level under which the transaction should run. - An DbTransaction - object representing the new transaction. - - Currently the IsolationLevel ReadCommitted and Serializable are supported by the PostgreSQL backend. - There's no support for nested transactions. - - - - - Begins a database transaction. - - A NpgsqlTransaction - object representing the new transaction. - - Currently there's no support for nested transactions. - - - - - Begins a database transaction with the specified isolation level. - - The isolation level under which the transaction should run. - A NpgsqlTransaction - object representing the new transaction. - - Currently the IsolationLevel ReadCommitted and Serializable are supported by the PostgreSQL backend. - There's no support for nested transactions. - - - - - Opens a database connection with the property settings specified by the - ConnectionString. - - - - - This method changes the current database by disconnecting from the actual - database and connecting to the specified. - - The name of the database to use in place of the current database. - - - - Releases the connection to the database. If the connection is pooled, it will be - made available for re-use. If it is non-pooled, the actual connection will be shutdown. - - - - - Creates and returns a DbCommand - object associated with the IDbConnection. - - A DbCommand object. - - - - Creates and returns a NpgsqlCommand - object associated with the NpgsqlConnection. - - A NpgsqlCommand object. - - - - Releases all resources used by the - NpgsqlConnection. - - true when called from Dispose(); - false when being called from the finalizer. - - - - Create a new connection based on this one. - - A new NpgsqlConnection object. - - - - Create a new connection based on this one. - - A new NpgsqlConnection object. - - - - Default SSL CertificateSelectionCallback implementation. - - - - - Default SSL CertificateValidationCallback implementation. - - - - - Default SSL PrivateKeySelectionCallback implementation. - - - - - Default SSL ProvideClientCertificatesCallback implementation. - - - - - Write each key/value pair in the connection string to the log. - - - - - Returns the supported collections - - - - - Returns the schema collection specified by the collection name. - - The collection name. - The collection specified. - - - - Returns the schema collection specified by the collection name filtered by the restrictions. - - The collection name. - - The restriction values to filter the results. A description of the restrictions is contained - in the Restrictions collection. - - The collection specified. - - - - Occurs on NoticeResponses from the PostgreSQL backend. - - - - - Occurs on NotificationResponses from the PostgreSQL backend. - - - - - Called to provide client certificates for SSL handshake. - - - - - Mono.Security.Protocol.Tls.CertificateSelectionCallback delegate. - - - - - Mono.Security.Protocol.Tls.CertificateValidationCallback delegate. - - - - - Mono.Security.Protocol.Tls.PrivateKeySelectionCallback delegate. - - - - - Gets or sets the string used to connect to a PostgreSQL database. - Valid values are: -
    -
  • - Server: Address/Name of Postgresql Server; -
  • -
  • - Port: Port to connect to; -
  • -
  • - Protocol: Protocol version to use, instead of automatic; Integer 2 or 3; -
  • -
  • - Database: Database name. Defaults to user name if not specified; -
  • -
  • - User Id: User name; -
  • -
  • - Password: Password for clear text authentication; -
  • -
  • - SSL: True or False. Controls whether to attempt a secure connection. Default = False; -
  • -
  • - Pooling: True or False. Controls whether connection pooling is used. Default = True; -
  • -
  • - MinPoolSize: Min size of connection pool; -
  • -
  • - MaxPoolSize: Max size of connection pool; -
  • -
  • - Timeout: Time to wait for connection open in seconds. Default is 15. -
  • -
  • - CommandTimeout: Time to wait for command to finish execution before throw an exception. In seconds. Default is 20. -
  • -
  • - Sslmode: Mode for ssl connection control. Can be Prefer, Require, Allow or Disable. Default is Disable. Check user manual for explanation of values. -
  • -
  • - ConnectionLifeTime: Time to wait before closing unused connections in the pool in seconds. Default is 15. -
  • -
  • - SyncNotification: Specifies if Npgsql should use synchronous notifications. -
  • -
  • - SearchPath: Changes search path to specified and public schemas. -
  • -
-
- The connection string that includes the server name, - the database name, and other parameters needed to establish - the initial connection. The default value is an empty string. - -
- - - Backend server host name. - - - - - Backend server port. - - - - - If true, the connection will attempt to use SSL. - - - - - Gets the time to wait while trying to establish a connection - before terminating the attempt and generating an error. - - The time (in seconds) to wait for a connection to open. The default value is 15 seconds. - - - - Gets the time to wait while trying to execute a command - before terminating the attempt and generating an error. - - The time (in seconds) to wait for a command to complete. The default value is 20 seconds. - - - - Gets the time to wait before closing unused connections in the pool if the count - of all connections exeeds MinPoolSize. - - - If connection pool contains unused connections for ConnectionLifeTime seconds, - the half of them will be closed. If there will be unused connections in a second - later then again the half of them will be closed and so on. - This strategy provide smooth change of connection count in the pool. - - The time (in seconds) to wait. The default value is 15 seconds. - - - - Gets the name of the current database or the database to be used after a connection is opened. - - The name of the current database or the name of the database to be - used after a connection is opened. The default value is the empty string. - - - - Whether datareaders are loaded in their entirety (for compatibility with earlier code). - - - - - Gets the database server name. - - - - - Gets flag indicating if we are using Synchronous notification or not. - The default value is false. - - - - - Gets the current state of the connection. - - A bitwise combination of the ConnectionState values. The default is Closed. - - - - Gets whether the current state of the connection is Open or Closed - - ConnectionState.Open or ConnectionState.Closed - - - - Version of the PostgreSQL backend. - This can only be called when there is an active connection. - - - - - Protocol version in use. - This can only be called when there is an active connection. - - - - - Process id of backend server. - This can only be called when there is an active connection. - - - - - The connector object connected to the backend. - - - - - Gets the NpgsqlConnectionStringBuilder containing the parsed connection string values. - - - - - User name. - - - - - Password. - - - - - Determine if connection pooling will be used for this connection. - - - - - This class represents the CancelRequest message sent to PostgreSQL - server. - - - - - - - - - - - - - - - - - - - A time period expressed in 100ns units. - - - A time period expressed in a - - - Number of 100ns units. - - - Number of seconds. - - - Number of milliseconds. - - - Number of milliseconds. - - - Number of milliseconds. - - - A d with the given number of ticks. - - - A d with the given number of microseconds. - - - A d with the given number of milliseconds. - - - A d with the given number of seconds. - - - A d with the given number of minutes. - - - A d with the given number of hours. - - - A d with the given number of days. - - - A d with the given number of months. - - - An whose values are the sums of the two instances. - - - An whose values are the differences of the two instances. - - - An whose value is the negated value of this instance. - - - An whose value is the absolute value of this instance. - - - - An based on this one, but with any days converted to multiples of ±24hours. - - - - An based on this one, but with any months converted to multiples of ±30days. - - - - An based on this one, but with any months converted to multiples of ±30days and then any days converted to multiples of ±24hours; - - - - An eqivalent, canonical, . - - - An equivalent . - - - - - - An signed integer. - - - - The argument is not an . - - - The string was not in a format that could be parsed to produce an . - - - true if the parsing succeeded, false otherwise. - - - The representation. - - - An whose values are the sum of the arguments. - - - An whose values are the difference of the arguments - - - true if the two arguments are exactly the same, false otherwise. - - - false if the two arguments are exactly the same, true otherwise. - - - true if the first is less than second, false otherwise. - - - true if the first is less than or equivalent to second, false otherwise. - - - true if the first is greater than second, false otherwise. - - - true if the first is greater than or equivalent to the second, false otherwise. - - - The argument. - - - The negation of the argument. - - - - - - - - - - - - - - - - - - - - This time, normalised - - - - - - - - - This time, normalised - - - An integer which is 0 if they are equal, < 0 if this is the smaller and > 0 if this is the larger. - - - - - - - - - A class to handle everything associated with SSPI authentication - - - - - Simplified SecBufferDesc struct with only one SecBuffer - - - - - This class represents the Parse message sent to PostgreSQL - server. - - - - - - EventArgs class to send Notice parameters, which are just NpgsqlError's in a lighter context. - - - - - Notice information. - - - - - This class represents the ErrorResponse and NoticeResponse - message sent from PostgreSQL server. - - - - - Return a string representation of this error object. - - - - - Severity code. All versions. - - - - - Error code. PostgreSQL 7.4 and up. - - - - - Terse error message. All versions. - - - - - Detailed error message. PostgreSQL 7.4 and up. - - - - - Suggestion to help resolve the error. PostgreSQL 7.4 and up. - - - - - Position (one based) within the query string where the error was encounterd. PostgreSQL 7.4 and up. - - - - - Position (one based) within the query string where the error was encounterd. This position refers to an internal command executed for example inside a PL/pgSQL function. PostgreSQL 7.4 and up. - - - - - Internal query string where the error was encounterd. This position refers to an internal command executed for example inside a PL/pgSQL function. PostgreSQL 7.4 and up. - - - - - Trace back information. PostgreSQL 7.4 and up. - - - - - Source file (in backend) reporting the error. PostgreSQL 7.4 and up. - - - - - Source file line number (in backend) reporting the error. PostgreSQL 7.4 and up. - - - - - Source routine (in backend) reporting the error. PostgreSQL 7.4 and up. - - - - - String containing the sql sent which produced this error. - - - - - Backend protocol version in use. - - - - - Represents an ongoing COPY TO STDOUT operation. - Provides methods to read data from server or end the operation. - - - - This class represents the base class for the state pattern design pattern - implementation. - - - - - - This method is used by the states to change the state of the context. - - - - - This method is responsible to handle all protocol messages sent from the backend. - It holds all the logic to do it. - To exchange data, it uses a Mediator object from which it reads/writes information - to handle backend requests. - - - - - - This method is responsible to handle all protocol messages sent from the backend. - It holds all the logic to do it. - To exchange data, it uses a Mediator object from which it reads/writes information - to handle backend requests. - - - - - - Called from NpgsqlState.ProcessBackendResponses upon CopyOutResponse. - If CopyStream is already set, it is used to write data received from server, after which the copy ends. - Otherwise CopyStream is set to a readable NpgsqlCopyOutStream that receives data from server. - - - - - Called from NpgsqlOutStream.Read to read copy data from server. - - - - - Copy format information returned from server. - - Handles serialisation of .NET array or IEnumeration to pg format. @@ -1394,11 +21,22 @@ The that would be used to serialise the element type. - + Serialise the enumeration or array. + + + Convert a System.Array to PG binary format. + Write the array header and prepare to write array data to the stream. + + + + + Append all array data to the binary stream. + + Handles parsing of pg arrays into .NET arrays. @@ -1434,9 +72,9 @@ for the element type. - + - Creates an array from pg representation. + Creates an array from pg text representation. @@ -1448,1692 +86,33 @@ Creates an n-dimensional array from an ArrayList of ArrayLists or - a 1-dimensional array from something else. + a 1-dimensional array from something else. to convert + Type of the elements in the list produced. + + + Creates an n-dimensional System.Array from PG binary representation. + This function reads the array header and sets up an n-dimensional System.Array object to hold its data. + PopulateArrayFromBinaryArray() is then called to carry out array population. + + + + + Recursively populates an array from PB binary data representation. + + - - Takes an array of ints and treats them like the limits of a set of counters. - Retains a matching set of ints that is set to all zeros on the first ++ - On a ++ it increments the "right-most" int. If that int reaches it's - limit it is set to zero and the one before it is incremented, and so on. - - Making this a more general purpose class is pretty straight-forward, but we'll just put what we need here. - - - - This class represents the ParameterStatus message sent from PostgreSQL - server. - + Takes an array of ints and treats them like the limits of a set of counters. + Retains a matching set of ints that is set to all zeros on the first ++ + On a ++ it increments the "right-most" int. If that int reaches it's + limit it is set to zero and the one before it is incremented, and so on. - - - - This class is responsible for serving as bridge between the backend - protocol handling and the core classes. It is used as the mediator for - exchanging data generated/sent from/to backend. + Making this a more general purpose class is pretty straight-forward, but we'll just put what we need here. - - - - - This class is responsible to create database commands for automatic insert, update and delete operations. - - - - - - This method is reponsible to derive the command parameter list with values obtained from function definition. - It clears the Parameters collection of command. Also, if there is any parameter type which is not supported by Npgsql, an InvalidOperationException will be thrown. - Parameters name will be parameter1, parameter2, ... - For while, only parameter name and NpgsqlDbType are obtained. - - NpgsqlCommand whose function parameters will be obtained. - - - - Represents a completed response message. - - - - - - Marker interface which identifies a class which may take possession of a stream for the duration of - it's lifetime (possibly temporarily giving that possession to another class for part of that time. - - It inherits from IDisposable, since any such class must make sure it leaves the stream in a valid state. - - The most important such class is that compiler-generated from ProcessBackendResponsesEnum. Of course - we can't make that inherit from this interface, alas. - - - - - The exception that is thrown when the PostgreSQL backend reports errors. - - - - - Construct a backend error exception based on a list of one or more - backend errors. The basic Exception.Message will be built from the - first (usually the only) error in the list. - - - - - Format a .NET style exception string. - Include all errors in the list, including any hints. - - - - - Append a line to the given Stream, first checking for zero-length. - - - - - Provide access to the entire list of errors provided by the PostgreSQL backend. - - - - - Severity code. All versions. - - - - - Error code. PostgreSQL 7.4 and up. - - - - - Basic error message. All versions. - - - - - Detailed error message. PostgreSQL 7.4 and up. - - - - - Suggestion to help resolve the error. PostgreSQL 7.4 and up. - - - - - Position (one based) within the query string where the error was encounterd. PostgreSQL 7.4 and up. - - - - - Trace back information. PostgreSQL 7.4 and up. - - - - - Source file (in backend) reporting the error. PostgreSQL 7.4 and up. - - - - - Source file line number (in backend) reporting the error. PostgreSQL 7.4 and up. - - - - - Source routine (in backend) reporting the error. PostgreSQL 7.4 and up. - - - - - String containing the sql sent which produced this error. - - - - - Returns the entire list of errors provided by the PostgreSQL backend. - - - - - The level of verbosity of the NpgsqlEventLog - - - - - Don't log at all - - - - - Only log the most common issues - - - - - Log everything - - - - - This class handles all the Npgsql event and debug logging - - - - - Writes a string to the Npgsql event log if msglevel is bigger then NpgsqlEventLog.Level - - - This method is obsolete and should no longer be used. - It is likely to be removed in future versions of Npgsql - - The message to write to the event log - The minimum LogLevel for which this message should be logged. - - - - Writes a string to the Npgsql event log if msglevel is bigger then NpgsqlEventLog.Level - - The ResourceManager to get the localized resources - The name of the resource that should be fetched by the ResourceManager - The minimum LogLevel for which this message should be logged. - The additional parameters that shall be included into the log-message (must be compatible with the string in the resource): - - - - Writes the default log-message for the action of calling the Get-part of an Indexer to the log file. - - The minimum LogLevel for which this message should be logged. - The name of the class that contains the Indexer - The parameter given to the Indexer - - - - Writes the default log-message for the action of calling the Set-part of an Indexer to the logfile. - - The minimum LogLevel for which this message should be logged. - The name of the class that contains the Indexer - The parameter given to the Indexer - The value the Indexer is set to - - - - Writes the default log-message for the action of calling the Get-part of a Property to the logfile. - - The minimum LogLevel for which this message should be logged. - The name of the class that contains the Property - The name of the Property - - - - Writes the default log-message for the action of calling the Set-part of a Property to the logfile. - - The minimum LogLevel for which this message should be logged. - The name of the class that contains the Property - The name of the Property - The value the Property is set to - - - - Writes the default log-message for the action of calling a Method without Arguments to the logfile. - - The minimum LogLevel for which this message should be logged. - The name of the class that contains the Method - The name of the Method - - - - Writes the default log-message for the action of calling a Method with one Argument to the logfile. - - The minimum LogLevel for which this message should be logged. - The name of the class that contains the Method - The name of the Method - The value of the Argument of the Method - - - - Writes the default log-message for the action of calling a Method with two Arguments to the logfile. - - The minimum LogLevel for which this message should be logged. - The name of the class that contains the Method - The name of the Method - The value of the first Argument of the Method - The value of the second Argument of the Method - - - - Writes the default log-message for the action of calling a Method with three Arguments to the logfile. - - The minimum LogLevel for which this message should be logged. - The name of the class that contains the Method - The name of the Method - The value of the first Argument of the Method - The value of the second Argument of the Method - The value of the third Argument of the Method - - - - Writes the default log-message for the action of calling a Method with more than three Arguments to the logfile. - - The minimum LogLevel for which this message should be logged. - The name of the class that contains the Method - The name of the Method - A Object-Array with zero or more Ojects that are Arguments of the Method. - - - - Sets/Returns the level of information to log to the logfile. - - The current LogLevel - - - - Sets/Returns the filename to use for logging. - - The filename of the current Log file. - - - - Sets/Returns whether Log messages should be echoed to the console - - true if Log messages are echoed to the console, otherwise false - - - - This class represents the Parse message sent to PostgreSQL - server. - - - - - - Represents a PostgreSQL COPY FROM STDIN operation with a corresponding SQL statement - to execute against a PostgreSQL database - and an associated stream used to read data from (if provided by user) - or for writing it (when generated by driver). - Eg. new NpgsqlCopyIn("COPY mytable FROM STDIN", connection, streamToRead).Start(); - - - - - Creates NpgsqlCommand to run given query upon Start(). Data for the requested COPY IN operation can then be written to CopyData stream followed by a call to End() or Cancel(). - - - - - Given command is run upon Start(). Data for the requested COPY IN operation can then be written to CopyData stream followed by a call to End() or Cancel(). - - - - - Given command is executed upon Start() and all data from fromStream is passed to it as copy data. - - - - - Returns true if this operation is currently active and field at given location is in binary format. - - - - - Command specified upon creation is executed as a non-query. - If CopyStream is set upon creation, it will be flushed to server as copy data, and operation will be finished immediately. - Otherwise the CopyStream member can be used for writing copy data to server and operation finished with a call to End() or Cancel(). - - - - - Called after writing all data to CopyStream to successfully complete this copy operation. - - - - - Withdraws an already started copy operation. The operation will fail with given error message. - Will do nothing if current operation is not active. - - - - - Returns true if the connection is currently reserved for this operation. - - - - - The stream provided by user or generated upon Start(). - User may provide a stream to constructor; it is used to pass to server all data read from it. - Otherwise, call to Start() sets this to a writable NpgsqlCopyInStream that passes all data written to it to server. - In latter case this is only available while the copy operation is active and null otherwise. - - - - - Returns true if this operation is currently active and in binary format. - - - - - Returns number of fields expected on each input row if this operation is currently active, otherwise -1 - - - - - The Command used to execute this copy operation. - - - - - Set before a COPY IN query to define size of internal buffer for reading from given CopyStream. - - - - - Represents information about COPY operation data transfer format as returned by server. - - - - - Only created when a CopyInResponse or CopyOutResponse is received by NpgsqlState.ProcessBackendResponses() - - - - - Returns true if this operation is currently active and field at given location is in binary format. - - - - - Returns true if this operation is currently active and in binary format. - - - - - Returns number of fields if this operation is currently active, otherwise -1 - - - - - - - - - Provide event handlers to convert all native supported basic data types from their backend - text representation to a .NET object. - - - - - Binary data. - - - - - Convert a postgresql boolean to a System.Boolean. - - - - - Convert a postgresql bit to a System.Boolean. - - - - - Convert a postgresql datetime to a System.DateTime. - - - - - Convert a postgresql date to a System.DateTime. - - - - - Convert a postgresql time to a System.DateTime. - - - - - Convert a postgresql money to a System.Decimal. - - - - - Provide event handlers to convert the basic native supported data types from - native form to backend representation. - - - - - Binary data. - - - - - Convert to a postgresql boolean. - - - - - Convert to a postgresql bit. - - - - - Convert to a postgresql timestamp. - - - - - Convert to a postgresql date. - - - - - Convert to a postgresql time. - - - - - Convert to a postgres money. - - - - - Convert to a postgres double with maximum precision. - - - - - Provide event handlers to convert extended native supported data types from their backend - text representation to a .NET object. - - - - - Convert a postgresql point to a System.NpgsqlPoint. - - - - - Convert a postgresql point to a System.RectangleF. - - - - - LDeg. - - - - - Path. - - - - - Polygon. - - - - - Circle. - - - - - Inet. - - - - - MAC Address. - - - - - interval - - - - - Provide event handlers to convert extended native supported data types from - native form to backend representation. - - - - - Point. - - - - - Box. - - - - - LSeg. - - - - - Open path. - - - - - Polygon. - - - - - Convert to a postgres MAC Address. - - - - - Circle. - - - - - Convert to a postgres inet. - - - - - Convert to a postgres interval - - - - - EventArgs class to send Notification parameters. - - - - - Process ID of the PostgreSQL backend that sent this notification. - - - - - Condition that triggered that notification. - - - - - Additional Information From Notifiying Process (for future use, currently postgres always sets this to an empty string) - - - - - Resolve a host name or IP address. - This is needed because if you call Dns.Resolve() with an IP address, it will attempt - to resolve it as a host name, when it should just convert it to an IP address. - - - - - - This class represents a RowDescription message sent from - the PostgreSQL. - - - - - - This struct represents the internal data of the RowDescription message. - - - - - This class represents the Parse message sent to PostgreSQL - server. - - - - - - A factory to create instances of various Npgsql objects. - - - - - Creates an NpgsqlCommand object. - - - - - This class represents the Parse message sent to PostgreSQL - server. - - - - - - Represents the method that handles the RowUpdated events. - - The source of the event. - A NpgsqlRowUpdatedEventArgs that contains the event data. - - - - Represents the method that handles the RowUpdating events. - - The source of the event. - A NpgsqlRowUpdatingEventArgs that contains the event data. - - - - This class represents an adapter from many commands: select, update, insert and delete to fill Datasets. - - - - - Stream for reading data from a table or select on a PostgreSQL version 7.4 or newer database during an active COPY TO STDOUT operation. - Passes data exactly as provided by the server. - - - - - Created only by NpgsqlCopyOutState.StartCopy() - - - - - Discards copy data as long as server pushes it. Returns after operation is finished. - Does nothing if this stream is not the active copy operation reader. - - - - - Not writable. - - - - - Not flushable. - - - - - Copies data read from server to given byte buffer. - Since server returns data row by row, length will differ each time, but it is only zero once the operation ends. - Can be mixed with calls to the more efficient NpgsqlCopyOutStream.Read() : byte[] though that would not make much sense. - - - - - Not seekable - - - - - Not supported - - - - - Returns a whole row of data from server without extra work. - If standard Stream.Read(...) has been called before, it's internal buffers remains are returned. - - - - - True while this stream can be used to read copy data from server - - - - - True - - - - - False - - - - - False - - - - - Number of bytes read so far - - - - - Number of bytes read so far; can not be set. - - - - - This class represents the Bind message sent to PostgreSQL - server. - - - - - - Summary description for LargeObjectManager. - - - - - Represents a transaction to be made in a PostgreSQL database. This class cannot be inherited. - - - - - Commits the database transaction. - - - - - Rolls back a transaction from a pending state. - - - - - Rolls back a transaction from a pending savepoint state. - - - - - Creates a transaction save point. - - - - - Cancel the transaction without telling the backend about it. This is - used to make the transaction go away when closing a connection. - - - - - Gets the NpgsqlConnection - object associated with the transaction, or a null reference if the - transaction is no longer valid. - - The NpgsqlConnection - object associated with the transaction. - - - - Specifies the IsolationLevel for this transaction. - - The IsolationLevel for this transaction. - The default is ReadCommitted. - - - - This class represents a StartupPacket message of PostgreSQL - protocol. - - - - - - Provides a means of reading a forward-only stream of rows from a PostgreSQL backend. This class cannot be inherited. - - - - - Return the data type name of the column at index . - - - - - Return the data type of the column at index . - - - - - Return the Npgsql specific data type of the column at requested ordinal. - - column position - Appropriate Npgsql type for column. - - - - Return the column name of the column at index . - - - - - Return the data type OID of the column at index . - - FIXME: Why this method returns String? - - - - Return the column name of the column named . - - - - - Return the data DbType of the column at index . - - - - - Return the data NpgsqlDbType of the column at index . - - - - - Get the value of a column as a . - If the differences between and - in handling of days and months is not important to your application, use - instead. - - Index of the field to find. - value of the field. - - - - Gets the value of a column converted to a Guid. - - - - - Gets the value of a column as Int16. - - - - - Gets the value of a column as Int32. - - - - - Gets the value of a column as Int64. - - - - - Gets the value of a column as Single. - - - - - Gets the value of a column as Double. - - - - - Gets the value of a column as String. - - - - - Gets the value of a column as Decimal. - - - - - Gets the value of a column as TimeSpan. - - - - - Copy values from each column in the current row into . - - The number of column values copied. - - - - Copy values from each column in the current row into . - - An array appropriately sized to store values from all columns. - The number of column values copied. - - - - Gets the value of a column as Boolean. - - - - - Gets the value of a column as Byte. Not implemented. - - - - - Gets the value of a column as Char. - - - - - Gets the value of a column as DateTime. - - - - - Returns a System.Data.DataTable that describes the column metadata of the DataReader. - - - - - This methods parses the command text and tries to get the tablename - from it. - - - - - Is raised whenever Close() is called. - - - - - Gets the number of columns in the current row. - - - - - Gets the value of a column in its native format. - - - - - Gets the value of a column in its native format. - - - - - Gets a value indicating the depth of nesting for the current row. Always returns zero. - - - - - Gets a value indicating whether the data reader is closed. - - - - - Contains the column names as the keys - - - - - Contains all unique columns - - - - - This is the primary implementation of NpgsqlDataReader. It is the one used in normal cases (where the - preload-reader option is not set in the connection string to resolve some potential backwards-compatibility - issues), the only implementation used internally, and in cases where CachingDataReader is used, it is still - used to do the actual "leg-work" of turning a response stream from the server into a datareader-style - object - with CachingDataReader then filling it's cache from here. - - - - - Iterate through the objects returned through from the server. - If it's a CompletedResponse the rowsaffected count is updated appropriately, - and we iterate again, otherwise we return it (perhaps updating our cache of pending - rows if appropriate). - - The next we will deal with. - - - - Advances the data reader to the next result, when multiple result sets were returned by the PostgreSQL backend. - - True if the reader was advanced, otherwise false. - - - - Releases the resources used by the NpgsqlCommand. - - - - - Closes the data reader object. - - - - - Advances the data reader to the next result, when multiple result sets were returned by the PostgreSQL backend. - - True if the reader was advanced, otherwise false. - - - - Advances the data reader to the next row. - - True if the reader was advanced, otherwise false. - - - - Return the value of the column at index . - - - - - Gets raw data from a column. - - - - - Gets raw data from a column. - - - - - Report whether the value in a column is DBNull. - - - - - Gets the number of rows changed, inserted, or deleted by execution of the SQL statement. - - - - - Indicates if NpgsqlDatareader has rows to be read. - - - - - Provides an implementation of NpgsqlDataReader in which all data is pre-loaded into memory. - This operates by first creating a ForwardsOnlyDataReader as usual, and then loading all of it's - Rows into memory. There is a general principle that when there is a trade-off between a class design that - is more efficient and/or scalable on the one hand and one that is less efficient but has more functionality - (in this case the internal-only functionality of caching results) that one can build the less efficent class - from the most efficient without significant extra loss in efficiency, but not the other way around. The relationship - between ForwardsOnlyDataReader and CachingDataReader is an example of this). - Since the interface presented to the user is still forwards-only, queues are used to - store this information, so that dequeueing as we go we give the garbage collector the best opportunity - possible to reclaim any memory that is no longer in use. - ForwardsOnlyDataReader being used to actually - obtain the information from the server means that the "leg-work" is still only done (and need only be - maintained) in one place. - This class exists to allow for certain potential backwards-compatibility issues to be resolved - with little effort on the part of affected users. It is considerably less efficient than ForwardsOnlyDataReader - and hence never used internally. - - - - - Represents the method that allows the application to provide a certificate collection to be used for SSL clien authentication - - A X509CertificateCollection to be filled with one or more client certificates. - - - - !!! Helper class, for compilation only. - Connector implements the logic for the Connection Objects to - access the physical connection to the database, and isolate - the application developer from connection pooling internals. - - - - - Constructor. - - Controls whether the connector can be shared. - - - - This method checks if the connector is still ok. - We try to send a simple query text, select 1 as ConnectionTest; - - - - - This method is responsible for releasing all resources associated with this Connector. - - - - - This method is responsible to release all portals used by this Connector. - - - - - Default SSL CertificateSelectionCallback implementation. - - - - - Default SSL CertificateValidationCallback implementation. - - - - - Default SSL PrivateKeySelectionCallback implementation. - - - - - Default SSL ProvideClientCertificatesCallback implementation. - - - - - This method is required to set all the version dependent features flags. - SupportsPrepare means the server can use prepared query plans (7.3+) - - - - - Opens the physical connection to the server. - - Usually called by the RequestConnector - Method of the connection pool manager. - - - - Closes the physical connection to the server. - - - - - Returns next portal index. - - - - - Returns next plan index. - - - - - Occurs on NoticeResponses from the PostgreSQL backend. - - - - - Occurs on NotificationResponses from the PostgreSQL backend. - - - - - Called to provide client certificates for SSL handshake. - - - - - Mono.Security.Protocol.Tls.CertificateSelectionCallback delegate. - - - - - Mono.Security.Protocol.Tls.CertificateValidationCallback delegate. - - - - - Mono.Security.Protocol.Tls.PrivateKeySelectionCallback delegate. - - - - - Gets the current state of the connection. - - - - - Return Connection String. - - - - - Version of backend server this connector is connected to. - - - - - Backend protocol version in use by this connector. - - - - - The physical connection stream to the backend. - - - - - The physical connection socket to the backend. - - - - - Reports if this connector is fully connected. - - - - - The connection mediator. - - - - - Report if the connection is in a transaction. - - - - - Report whether the current connection can support prepare functionality. - - - - - This class contains helper methods for type conversion between - the .Net type system and postgresql. - - - - - A cache of basic datatype mappings keyed by server version. This way we don't - have to load the basic type mappings for every connection. - - - - - Find a NpgsqlNativeTypeInfo in the default types map that can handle objects - of the given NpgsqlDbType. - - - - - Find a NpgsqlNativeTypeInfo in the default types map that can handle objects - of the given NpgsqlDbType. - - - - - Find a NpgsqlNativeTypeInfo in the default types map that can handle objects - of the given DbType. - - - - - Find a NpgsqlNativeTypeInfo in the default types map that can handle objects - of the given System.Type. - - - - - This method is responsible to convert the string received from the backend - to the corresponding NpgsqlType. - The given TypeInfo is called upon to do the conversion. - If no TypeInfo object is provided, no conversion is performed. - - - - - Create the one and only native to backend type map. - This map is used when formatting native data - types to backend representations. - - - - - This method creates (or retrieves from cache) a mapping between type and OID - of all natively supported postgresql data types. - This is needed as from one version to another, this mapping can be changed and - so we avoid hardcoding them. - - NpgsqlTypeMapping containing all known data types. The mapping must be - cloned before it is modified because it is cached; changes made by one connection may - effect another connection. - - - - Attempt to map types by issuing a query against pg_type. - This function takes a list of NpgsqlTypeInfo and attempts to resolve the OID field - of each by querying pg_type. If the mapping is found, the type info object is - updated (OID) and added to the provided NpgsqlTypeMapping object. - - NpgsqlConnector to send query through. - Mapping object to add types too. - List of types that need to have OID's mapped. - - - - Delegate called to convert the given backend data to its native representation. - - - - - Delegate called to convert the given native data to its backand representation. - - - - - Represents a backend data type. - This class can be called upon to convert a backend field representation to a native object. - - - - - Construct a new NpgsqlTypeInfo with the given attributes and conversion handlers. - - Type OID provided by the backend server. - Type name provided by the backend server. - NpgsqlDbType - System type to convert fields of this type to. - Data conversion handler. - - - - Perform a data conversion from a backend representation to - a native object. - - Data sent from the backend. - Type modifier field sent from the backend. - - - - Type OID provided by the backend server. - - - - - Type name provided by the backend server. - - - - - NpgsqlDbType. - - - - - NpgsqlDbType. - - - - - Provider type to convert fields of this type to. - - - - - System type to convert fields of this type to. - - - - - Represents a backend data type. - This class can be called upon to convert a native object to its backend field representation, - - - - - Returns an NpgsqlNativeTypeInfo for an array where the elements are of the type - described by the NpgsqlNativeTypeInfo supplied. - - - - - Construct a new NpgsqlTypeInfo with the given attributes and conversion handlers. - - Type name provided by the backend server. - NpgsqlDbType - Data conversion handler. - - - - Perform a data conversion from a native object to - a backend representation. - DBNull and null values are handled differently depending if a plain query is used - When - - Native .NET object to be converted. - Flag indicating if the conversion has to be done for - plain queries or extended queries - - - - Type name provided by the backend server. - - - - - NpgsqlDbType. - - - - - DbType. - - - - - Apply quoting. - - - - - Use parameter size information. - - - - - Provide mapping between type OID, type name, and a NpgsqlBackendTypeInfo object that represents it. - - - - - Construct an empty mapping. - - - - - Copy constuctor. - - - - - Add the given NpgsqlBackendTypeInfo to this mapping. - - - - - Add a new NpgsqlBackendTypeInfo with the given attributes and conversion handlers to this mapping. - - Type OID provided by the backend server. - Type name provided by the backend server. - NpgsqlDbType - System type to convert fields of this type to. - Data conversion handler. - - - - Make a shallow copy of this type mapping. - - - - - Determine if a NpgsqlBackendTypeInfo with the given backend type OID exists in this mapping. - - - - - Determine if a NpgsqlBackendTypeInfo with the given backend type name exists in this mapping. - - - - - Get the number of type infos held. - - - - - Retrieve the NpgsqlBackendTypeInfo with the given backend type OID, or null if none found. - - - - - Retrieve the NpgsqlBackendTypeInfo with the given backend type name, or null if none found. - - - - - Provide mapping between type Type, NpgsqlDbType and a NpgsqlNativeTypeInfo object that represents it. - - - - - Add the given NpgsqlNativeTypeInfo to this mapping. - - - - - Add a new NpgsqlNativeTypeInfo with the given attributes and conversion handlers to this mapping. - - Type name provided by the backend server. - NpgsqlDbType - Data conversion handler. - - - - Retrieve the NpgsqlNativeTypeInfo with the given NpgsqlDbType. - - - - - Retrieve the NpgsqlNativeTypeInfo with the given DbType. - - - - - Retrieve the NpgsqlNativeTypeInfo with the given Type. - - - - - Determine if a NpgsqlNativeTypeInfo with the given backend type name exists in this mapping. - - - - - Determine if a NpgsqlNativeTypeInfo with the given NpgsqlDbType exists in this mapping. - - - - - Determine if a NpgsqlNativeTypeInfo with the given Type name exists in this mapping. - - - - - Get the number of type infos held. - - - - - Implements for version 3 of the protocol. - - - - - Reads a row, field by field, allowing a DataRow to be built appropriately. - - - - - Reads part of a field, as needed (for - and - - - - - Adds further functionality to stream that is dependant upon the type of data read. - - - - - Completes the implementation of Streamer for char data. - - - - - Completes the implementation of Streamer for byte data. - - - - - Implements for version 2 of the protocol. - - - - - Encapsulates the null mapping bytes sent at the start of a version 2 - datarow message, and the process of identifying the nullity of the data - at a particular index - - - - - Provides the underlying mechanism for reading schema information. - - - - - Creates an NpgsqlSchema that can read schema information from the database. - - An open database connection for reading metadata. - - - - Returns the MetaDataCollections that lists all possible collections. - - The MetaDataCollections - - - - Returns the Restrictions that contains the meaning and position of the values in the restrictions array. - - The Restrictions - - - - Returns the Databases that contains a list of all accessable databases. - - The restrictions to filter the collection. - The Databases - - - - Returns the Tables that contains table and view names and the database and schema they come from. - - The restrictions to filter the collection. - The Tables - - - - Returns the Columns that contains information about columns in tables. - - The restrictions to filter the collection. - The Columns. - - - - Returns the Views that contains view names and the database and schema they come from. - - The restrictions to filter the collection. - The Views - - - - Returns the Users containing user names and the sysid of those users. - - The restrictions to filter the collection. - The Users. - - - - This is the abstract base class for NpgsqlAsciiRow and NpgsqlBinaryRow. - @@ -3166,7 +145,7 @@ Creats a bitstring from a string. The string to copy from. - + @@ -3322,7 +301,7 @@ The object to compare with. If the object is null then this string is considered greater. If the object is another BitString - then they are compared as in the explicit comparison for BitStrings + then they are compared as in the explicit comparison for BitStrings in any other case a is thrown. @@ -3534,6 +513,1605 @@ Retrieves the value of the bit at the given index.
+ + + Represents the PostgreSQL interval datatype. + PostgreSQL differs from .NET in how it's interval type doesn't assume 24 hours in a day + (to deal with 23- and 25-hour days caused by daylight savings adjustments) and has a concept + of months that doesn't exist in .NET's class. (Neither datatype + has any concessions for leap-seconds). + For most uses just casting to and from TimeSpan will work correctly — in particular, + the results of subtracting one or the PostgreSQL date, time and + timestamp types from another should be the same whether you do so in .NET or PostgreSQL — + but if the handling of days and months in PostgreSQL is important to your application then you + should use this class instead of . + If you don't know whether these differences are important to your application, they + probably arent! Just use and do not use this class directly ☺ + To avoid forcing unnecessary provider-specific concerns on users who need not be concerned + with them a call to on a field containing an + value will return a rather than an + . If you need the extra functionality of + then use . + + + + + + + + + + Represents the number of ticks (100ns periods) in one microsecond. This field is constant. + + + + + Represents the number of ticks (100ns periods) in one millisecond. This field is constant. + + + + + Represents the number of ticks (100ns periods) in one second. This field is constant. + + + + + Represents the number of ticks (100ns periods) in one minute. This field is constant. + + + + + Represents the number of ticks (100ns periods) in one hour. This field is constant. + + + + + Represents the number of ticks (100ns periods) in one day. This field is constant. + + + + + Represents the number of hours in one day (assuming no daylight savings adjustments). This field is constant. + + + + + Represents the number of days assumed in one month if month justification or unjustifcation is performed. + This is set to 30 for consistency with PostgreSQL. Note that this is means that month adjustments cause + a year to be taken as 30 × 12 = 360 rather than 356/366 days. + + + + + Represents the number of ticks (100ns periods) in one day, assuming 30 days per month. + + + + + Represents the number of months in a year. This field is constant. + + + + + Represents the maximum . This field is read-only. + + + + + Represents the minimum . This field is read-only. + + + + + Represents the zero . This field is read-only. + + + + + Initializes a new to the specified number of ticks. + + A time period expressed in 100ns units. + + + + Initializes a new to hold the same time as a + + A time period expressed in a + + + + Initializes a new to the specified number of months, days + & ticks. + + Number of months. + Number of days. + Number of 100ns units. + + + + Initializes a new to the specified number of + days, hours, minutes & seconds. + + Number of days. + Number of hours. + Number of minutes. + Number of seconds. + + + + Initializes a new to the specified number of + days, hours, minutes, seconds & milliseconds. + + Number of days. + Number of hours. + Number of minutes. + Number of seconds. + Number of milliseconds. + + + + Initializes a new to the specified number of + months, days, hours, minutes, seconds & milliseconds. + + Number of months. + Number of days. + Number of hours. + Number of minutes. + Number of seconds. + Number of milliseconds. + + + + Initializes a new to the specified number of + years, months, days, hours, minutes, seconds & milliseconds. + Years are calculated exactly equivalent to 12 months. + + Number of years. + Number of months. + Number of days. + Number of hours. + Number of minutes. + Number of seconds. + Number of milliseconds. + + + + Creates an from a number of ticks. + + The number of ticks (100ns units) in the interval. + A d with the given number of ticks. + + + + Creates an from a number of microseconds. + + The number of microseconds in the interval. + A d with the given number of microseconds. + + + + Creates an from a number of milliseconds. + + The number of milliseconds in the interval. + A d with the given number of milliseconds. + + + + Creates an from a number of seconds. + + The number of seconds in the interval. + A d with the given number of seconds. + + + + Creates an from a number of minutes. + + The number of minutes in the interval. + A d with the given number of minutes. + + + + Creates an from a number of hours. + + The number of hours in the interval. + A d with the given number of hours. + + + + Creates an from a number of days. + + The number of days in the interval. + A d with the given number of days. + + + + Creates an from a number of months. + + The number of months in the interval. + A d with the given number of months. + + + + Adds another interval to this instance and returns the result. + + An to add to this instance. + An whose values are the sums of the two instances. + + + + Subtracts another interval from this instance and returns the result. + + An to subtract from this instance. + An whose values are the differences of the two instances. + + + + Returns an whose value is the negated value of this instance. + + An whose value is the negated value of this instance. + + + + This absolute value of this instance. In the case of some, but not all, components being negative, + the rules used for justification are used to determine if the instance is positive or negative. + + An whose value is the absolute value of this instance. + + + + Equivalent to PostgreSQL's justify_days function. + + An based on this one, but with any hours outside of the range [-23, 23] + converted into days. + + + + Opposite to PostgreSQL's justify_days function. + + An based on this one, but with any days converted to multiples of ±24hours. + + + + Equivalent to PostgreSQL's justify_months function. + + An based on this one, but with any days outside of the range [-30, 30] + converted into months. + + + + Opposite to PostgreSQL's justify_months function. + + An based on this one, but with any months converted to multiples of ±30days. + + + + Equivalent to PostgreSQL's justify_interval function. + + An based on this one, + but with any months converted to multiples of ±30days + and then with any days converted to multiples of ±24hours + + + + Opposite to PostgreSQL's justify_interval function. + + An based on this one, but with any months converted to multiples of ±30days and then any days converted to multiples of ±24hours; + + + + Produces a canonical NpgslInterval with 0 months and hours in the range of [-23, 23]. + + + While the fact that for many purposes, two different instances could be considered + equivalent (e.g. one with 2days, 3hours and one with 1day 27hours) there are different possible canonical forms. + + E.g. we could move all excess hours into days and all excess days into months and have the most readable form, + or we could move everything into the ticks and have the form that allows for the easiest arithmetic) the form + chosen has two important properties that make it the best choice. + First, it is closest two how + objects are most often represented. Second, it is compatible with results of many + PostgreSQL functions, particularly with age() and the results of subtracting one date, time or timestamp from + another. + + Note that the results of casting a to is + canonicalised. + + + An based on this one, but with months converted to multiples of ±30days and with any hours outside of the range [-23, 23] + converted into days. + + + + Implicit cast of a to an + + A + An eqivalent, canonical, . + + + + Implicit cast of an to a . + + A . + An equivalent . + + + + Returns true if another is exactly the same as this instance. + + An for comparison. + true if the two instances are exactly the same, + false otherwise. + + + + Returns true if another object is an , that is exactly the same as + this instance + + An for comparison. + true if the argument is an and is exactly the same + as this one, false otherwise. + + + + Compares two instances. + + The first . + The second . + 0 if the two are equal or equivalent. A value greater than zero if x is greater than y, + a value less than zero if x is less than y. + + + + A hash code suitable for uses with hashing algorithms. + + An signed integer. + + + + Compares this instance with another/ + + An to compare this with. + 0 if the instances are equal or equivalent. A value less than zero if + this instance is less than the argument. A value greater than zero if this instance + is greater than the instance. + + + + Compares this instance with another/ + + An object to compare this with. + 0 if the argument is an and the instances are equal or equivalent. + A value less than zero if the argument is an and + this instance is less than the argument. + A value greater than zero if the argument is an and this instance + is greater than the instance. + A value greater than zero if the argument is null. + The argument is not an . + + + + Parses a and returns a instance. + Designed to use the formats generally returned by PostgreSQL. + + The to parse. + An represented by the argument. + The string was null. + A value obtained from parsing the string exceeded the values allowed for the relevant component. + The string was not in a format that could be parsed to produce an . + + + + Attempt to parse a to produce an . + + The to parse. + (out) The produced, or if the parsing failed. + true if the parsing succeeded, false otherwise. + + + + Create a representation of the instance. + The format returned is of the form: + [M mon[s]] [d day[s]] [HH:mm:ss[.f[f[f[f[f[f[f[f[f]]]]]]]]]] + A zero is represented as 00:00:00 + + Ticks are 100ns, Postgress resolution is only to 1µs at most. Hence we lose 1 or more decimal + precision in storing values in the database. Despite this, this method will output that extra + digit of precision. It's forward-compatible with any future increases in resolution up to 100ns, + and also makes this ToString() more applicable to any other use-case. + + + The representation. + + + + Adds two together. + + The first to add. + The second to add. + An whose values are the sum of the arguments. + + + + Subtracts one from another. + + The to subtract the other from. + The to subtract from the other. + An whose values are the difference of the arguments + + + + Returns true if two are exactly the same. + + The first to compare. + The second to compare. + true if the two arguments are exactly the same, false otherwise. + + + + Returns false if two are exactly the same. + + The first to compare. + The second to compare. + false if the two arguments are exactly the same, true otherwise. + + + + Compares two instances to see if the first is less than the second + + The first to compare. + The second to compare. + true if the first is less than second, false otherwise. + + + + Compares two instances to see if the first is less than or equivalent to the second + + The first to compare. + The second to compare. + true if the first is less than or equivalent to second, false otherwise. + + + + Compares two instances to see if the first is greater than the second + + The first to compare. + The second to compare. + true if the first is greater than second, false otherwise. + + + + Compares two instances to see if the first is greater than or equivalent the second + + The first to compare. + The second to compare. + true if the first is greater than or equivalent to the second, false otherwise. + + + + Returns the instance. + + An . + The argument. + + + + Negates an instance. + + An . + The negation of the argument. + + + + The total number of ticks(100ns units) contained. This is the resolution of the + type. This ignores the number of days and + months held. If you want them included use first. + The resolution of the PostgreSQL + interval type is by default 1µs = 1,000 ns. It may be smaller as follows: + + + interval(0) + resolution of 1s (1 second) + + + interval(1) + resolution of 100ms = 0.1s (100 milliseconds) + + + interval(2) + resolution of 10ms = 0.01s (10 milliseconds) + + + interval(3) + resolution of 1ms = 0.001s (1 millisecond) + + + interval(4) + resolution of 100µs = 0.0001s (100 microseconds) + + + interval(5) + resolution of 10µs = 0.00001s (10 microseconds) + + + interval(6) or interval + resolution of 1µs = 0.000001s (1 microsecond) + + + As such, if the 100-nanosecond resolution is significant to an application, a PostgreSQL interval will + not suffice for those purposes. + In more frequent cases though, the resolution of the interval suffices. + will always suffice to handle the resolution of any interval value, and upon + writing to the database, will be rounded to the resolution used. + + The number of ticks in the instance. + + + + + Gets the number of whole microseconds held in the instance. + An in the range [-999999, 999999]. + + + + + Gets the number of whole milliseconds held in the instance. + An in the range [-999, 999]. + + + + + Gets the number of whole seconds held in the instance. + An in the range [-59, 59]. + + + + + Gets the number of whole minutes held in the instance. + An in the range [-59, 59]. + + + + + Gets the number of whole hours held in the instance. + Note that this can be less than -23 or greater than 23 unless + has been used to produce this instance. + + + + + Gets the number of days held in the instance. + Note that this does not pay attention to a time component with -24 or less hours or + 24 or more hours, unless has been called to produce this instance. + + + + + Gets the number of months held in the instance. + Note that this does not pay attention to a day component with -30 or less days or + 30 or more days, unless has been called to produce this instance. + + + + + Returns a representing the time component of the instance. + Note that this may have a value beyond the range ±23:59:59.9999999 unless + has been called to produce this instance. + + + + + The total number of ticks (100ns units) in the instance, assuming 24 hours in each day and + 30 days in a month. + + + + + The total number of microseconds in the instance, assuming 24 hours in each day and + 30 days in a month. + + + + + The total number of milliseconds in the instance, assuming 24 hours in each day and + 30 days in a month. + + + + + The total number of seconds in the instance, assuming 24 hours in each day and + 30 days in a month. + + + + + The total number of minutes in the instance, assuming 24 hours in each day and + 30 days in a month. + + + + + The total number of hours in the instance, assuming 24 hours in each day and + 30 days in a month. + + + + + The total number of days in the instance, assuming 24 hours in each day and + 30 days in a month. + + + + + The total number of months in the instance, assuming 24 hours in each day and + 30 days in a month. + + + + + Normalise this time; if it is 24:00:00, convert it to 00:00:00 + + This time, normalised + + + + The total number of ticks(100ns units) contained. This is the resolution of the + type. + The resolution of the PostgreSQL + interval type is by default 1µs = 1,000 ns. It may be smaller as follows: + + + time(0) + resolution of 1s (1 second) + + + time(1) + resolution of 100ms = 0.1s (100 milliseconds) + + + time(2) + resolution of 10ms = 0.01s (10 milliseconds) + + + time(3) + resolution of 1ms = 0.001s (1 millisecond) + + + time(4) + resolution of 100µs = 0.0001s (100 microseconds) + + + time(5) + resolution of 10µs = 0.00001s (10 microseconds) + + + time(6) or interval + resolution of 1µs = 0.000001s (1 microsecond) + + + As such, if the 100-nanosecond resolution is significant to an application, a PostgreSQL time will + not suffice for those purposes. + In more frequent cases though, the resolution of time suffices. + will always suffice to handle the resolution of any time value, and upon + writing to the database, will be rounded to the resolution used. + + The number of ticks in the instance. + + + + + Gets the number of whole microseconds held in the instance. + An integer in the range [0, 999999]. + + + + + Gets the number of whole milliseconds held in the instance. + An integer in the range [0, 999]. + + + + + Gets the number of whole seconds held in the instance. + An interger in the range [0, 59]. + + + + + Gets the number of whole minutes held in the instance. + An integer in the range [0, 59]. + + + + + Gets the number of whole hours held in the instance. + Note that the time 24:00:00 can be stored for roundtrip compatibility. Any calculations on such a + value will normalised it to 00:00:00. + + + + + Normalise this time; if it is 24:00:00, convert it to 00:00:00 + + This time, normalised + + + + Compares this with another . As per postgres' rules, + first the times are compared as if they were both in the same timezone. If they are equal then + then timezones are compared (+01:00 being "smaller" than -01:00). + + the to compare with. + An integer which is 0 if they are equal, < 0 if this is the smaller and > 0 if this is the larger. + + + + Gets the number of whole microseconds held in the instance. + An integer in the range [0, 999999]. + + + + + Gets the number of whole milliseconds held in the instance. + An integer in the range [0, 999]. + + + + + Gets the number of whole seconds held in the instance. + An interger in the range [0, 59]. + + + + + Gets the number of whole minutes held in the instance. + An integer in the range [0, 59]. + + + + + Gets the number of whole hours held in the instance. + Note that the time 24:00:00 can be stored for roundtrip compatibility. Any calculations on such a + value will normalised it to 00:00:00. + + + + + Summary description for LargeObjectManager. + + + + + Options that control certain aspects of native to backend conversions that depend + on backend version and status. + + + + + Clone the current object. + + A new NativeToBackendTypeConverterOptions object. + + + + Clone the current object with a different OID/Name mapping. + + OID/Name mapping object to use in the new instance. + A new NativeToBackendTypeConverterOptions object. + + + + Provide event handlers to convert all native supported basic data types from their backend + text representation to a .NET object. + + + + + Convert UTF8 encoded text a string. + + + + + Byte array from bytea encoded as ASCII text, escaped or hex format. + + + + + Byte array from bytea encoded as binary. + + + + + Convert a postgresql boolean to a System.Boolean. + + + + + Convert a postgresql boolean to a System.Boolean. + + + + + Convert a postgresql bit to a System.Boolean. + + + + + Convert a postgresql datetime to a System.DateTime. + + + + + Convert a postgresql date to a System.DateTime. + + + + + Convert a postgresql time to a System.DateTime. + + + + + Convert a postgresql money to a System.Decimal. + + + + + Convert a postgresql float4 or float8 to a System.Float or System.Double respectively. + + + + + Provide event handlers to convert extended native supported data types from their backend + text representation to a .NET object. + + + + + Convert a postgresql point to a System.NpgsqlPoint. + + + + + Convert a postgresql point to a System.RectangleF. + + + + + LDeg. + + + + + Path. + + + + + Polygon. + + + + + Circle. + + + + + Inet. + + + + + MAC Address. + + + + + interval + + + + + Provide event handlers to convert the basic native supported data types from + native form to backend representation. + + + + + Convert a string to UTF8 encoded text, escaped and quoted as required. + + + + + Convert a string to UTF8 encoded text. + + + + + Binary data, escaped and quoted as required. + + + + + Binary data with possible older style octal escapes, quoted. + + + + + Binary data in the new hex format (>= 9.0), quoted. + + + + + Binary data, raw. + + + + + Convert to a postgresql boolean text format. + + + + + Convert to a postgresql boolean binary format. + + + + + Convert to a postgresql binary int2. + + + + + Convert to a postgresql binary int4. + + + + + Convert to a postgresql binary int8. + + + + + Convert to a postgresql bit. + + + + + Convert to a postgresql timestamp. + + + + + Convert to a postgresql date. + + + + + Convert to a postgresql time. + + + + + Convert to a postgres money. + + + + + Convert to a postgres double with maximum precision. + + + + + Convert a System.Float to a postgres float4. + + + + + Convert a System.Double to a postgres float8. + + + + + Provide event handlers to convert extended native supported data types from + native form to backend representation. + + + + + Point. + + + + + Box. + + + + + LSeg. + + + + + Open path. + + + + + Polygon. + + + + + Convert to a postgres MAC Address. + + + + + Circle. + + + + + Convert to a postgres inet. + + + + + Convert to a postgres interval + + + + + Delegate called to convert the given backend text data to its native representation. + + + + + Delegate called to convert the given backend binary data to its native representation. + + + + + Represents a backend data type. + This class can be called upon to convert a backend field representation to a native object. + + + + + Construct a new NpgsqlTypeInfo with the given attributes and conversion handlers. + + Type OID provided by the backend server. + Type name provided by the backend server. + NpgsqlDbType + DbType + System type to convert fields of this type to. + Data conversion handler for text encoding. + Data conversion handler for binary data. + + + + Perform a data conversion from a backend representation to + a native object. + + Data sent from the backend. + fieldValueSize + Type modifier field sent from the backend. + + + + Perform a data conversion from a backend representation to + a native object. + + Data sent from the backend. + TypeSize + Type modifier field sent from the backend. + + + + Type OID provided by the backend server. + + + + + Type name provided by the backend server. + + + + + NpgsqlDbType. + + + + + NpgsqlDbType. + + + + + Provider type to convert fields of this type to. + + + + + System type to convert fields of this type to. + + + + + Reports whether a backend binary to native decoder is available for this type. + + + + + Delegate called to convert the given native data to its backand representation. + + + + + Represents a backend data type. + This class can be called upon to convert a native object to its backend field representation, + + + + + Returns an NpgsqlNativeTypeInfo for an array where the elements are of the type + described by the NpgsqlNativeTypeInfo supplied. + + + + + Construct a new NpgsqlTypeInfo with the given attributes and conversion handlers. + + Type name provided by the backend server. + DbType + Quote + NpgsqlDbType + Data conversion handler for text backend encoding. + Data conversion handler for binary backend encoding (for extended queries). + + + + Perform a data conversion from a native object to + a backend representation. + DBNull and null values are handled differently depending if a plain query is used + When + + Native .NET object to be converted. + Specifies that the value should be formatted for the extended query syntax. + Options to guide serialization. If null, a default options set is used. + Specifies that the value should be formatted as an extended query array element. + + + + Type name provided by the backend server. + + + + + NpgsqlDbType. + + + + + DbType. + + + + + Apply quoting. + + + + + Use parameter size information. + + + + + Reports whether a native to backend binary encoder is available for this type. + + + + + Provide mapping between type OID, type name, and a NpgsqlBackendTypeInfo object that represents it. + + + + + Construct an empty mapping. + + + + + Copy constuctor. + + + + + Add the given NpgsqlBackendTypeInfo to this mapping. + + + + + Add a new NpgsqlBackendTypeInfo with the given attributes and conversion handlers to this mapping. + + Type OID provided by the backend server. + Type name provided by the backend server. + NpgsqlDbType + DbType + System type to convert fields of this type to. + Data conversion handler for text encoding. + Data conversion handler for binary data. + + + + Make a shallow copy of this type mapping. + + + + + Determine if a NpgsqlBackendTypeInfo with the given backend type OID exists in this mapping. + + + + + Determine if a NpgsqlBackendTypeInfo with the given backend type name exists in this mapping. + + + + + Get the number of type infos held. + + + + + Retrieve the NpgsqlBackendTypeInfo with the given backend type OID, or null if none found. + + + + + Retrieve the NpgsqlBackendTypeInfo with the given backend type name, or null if none found. + + + + + Provide mapping between type Type, NpgsqlDbType and a NpgsqlNativeTypeInfo object that represents it. + + + + + Add the given NpgsqlNativeTypeInfo to this mapping. + + + + + Add a new NpgsqlNativeTypeInfo with the given attributes and conversion handlers to this mapping. + + Type name provided by the backend server. + NpgsqlDbType + DbType + Quote + Data conversion handler for text backend encoding. + Data conversion handler for binary backend encoding (for extended query). + + + + Retrieve the NpgsqlNativeTypeInfo with the given NpgsqlDbType. + + + + + Retrieve the NpgsqlNativeTypeInfo with the given DbType. + + + + + Retrieve the NpgsqlNativeTypeInfo with the given Type. + + + + + Determine if a NpgsqlNativeTypeInfo with the given backend type name exists in this mapping. + + + + + Determine if a NpgsqlNativeTypeInfo with the given NpgsqlDbType exists in this mapping. + + + + + Determine if a NpgsqlNativeTypeInfo with the given Type name exists in this mapping. + + + + + Get the number of type infos held. + + + + + Represents a PostgreSQL Point type + + + + + Represents a PostgreSQL Line Segment type. + + + + + Represents a PostgreSQL Path type. + + + + + Represents a PostgreSQL Polygon type. + + + + + Represents a PostgreSQL Circle type. + + + + + Represents a PostgreSQL inet type. + + + + + Represents a PostgreSQL MacAddress type. + + + + + + + The macAddr parameter must contain a string that can only consist of numbers + and upper-case letters as hexadecimal digits. (See PhysicalAddress.Parse method on MSDN) + + + + This class contains helper methods for type conversion between + the .Net type system and postgresql. + + + + + A cache of basic datatype mappings keyed by server version. This way we don't + have to load the basic type mappings for every connection. + + + + + Find a NpgsqlNativeTypeInfo in the default types map that can handle objects + of the given NpgsqlDbType. + + + + + Find a NpgsqlNativeTypeInfo in the default types map that can handle objects + of the given NpgsqlDbType. + + + + + Find a NpgsqlNativeTypeInfo in the default types map that can handle objects + of the given DbType. + + + + + Find a NpgsqlNativeTypeInfo in the default types map that can handle objects + of the given System.Type. + + + + + This method is responsible to convert the byte[] received from the backend + to the corresponding NpgsqlType. + The given TypeInfo is called upon to do the conversion. + If no TypeInfo object is provided, no conversion is performed. + + + + + This method is responsible to convert the string received from the backend + to the corresponding NpgsqlType. + The given TypeInfo is called upon to do the conversion. + If no TypeInfo object is provided, no conversion is performed. + + + + + Create the one and only native to backend type map. + This map is used when formatting native data + types to backend representations. + + + + + This method creates (or retrieves from cache) a mapping between type and OID + of all natively supported postgresql data types. + This is needed as from one version to another, this mapping can be changed and + so we avoid hardcoding them. + + NpgsqlTypeMapping containing all known data types. The mapping must be + cloned before it is modified because it is cached; changes made by one connection may + effect another connection. + + + + + Attempt to map types by issuing a query against pg_type. + This function takes a list of NpgsqlTypeInfo and attempts to resolve the OID field + of each by querying pg_type. If the mapping is found, the type info object is + updated (OID) and added to the provided NpgsqlTypeMapping object. + + NpgsqlConnector to send query through. + Mapping object to add types too. + List of types that need to have OID's mapped. + + + + Set Cache Size. The default value is 20. + + + + + Lookup cached entity. null will returned if not match. + For both get{} and set{} apply LRU rule. + + key + + + + + The globally available text encoding used for frontend/backend communication. + + + + This class represents the base class for the state pattern design pattern + implementation. + + + This class represents the base class for the state pattern design pattern + implementation. + + + This class represents the base class for the state pattern design pattern + implementation. + + + + + + This method is used by the states to change the state of the context. + + + + + Call ProcessBackendResponsesEnum(), and scan and discard all results. + + + + + This method is responsible to handle all protocol messages sent from the backend. + It holds all the logic to do it. + To exchange data, it uses a Mediator object from which it reads/writes information + to handle backend requests. + + + + + + Checks for context socket availability. + Socket.Poll supports integer as microseconds parameter. + This limits the usable command timeout value + to 2,147 seconds: (2,147 x 1,000,000 less than max_int). + In order to bypass this limit, the availability of + the socket is checked in 2,147 seconds cycles + + true, if for context socket availability was checked, false otherwise. + Context. + Select mode. + + + + Called from constructor of derived class. + + + + + Finalizer for HashAlgorithm + + + + + Computes the entire hash of all the bytes in the byte array. + + + + + When overridden in a derived class, drives the hashing function. + + + + + + + + When overridden in a derived class, this pads and hashes whatever data might be left in the buffers and then returns the hash created. + + + + + When overridden in a derived class, initializes the object to prepare for hashing. + + + + + Used for stream chaining. Computes hash as data passes through it. + + The buffer from which to grab the data to be copied. + The offset into the input buffer to start reading at. + The number of bytes to be copied. + The buffer to write the copied data to. + At what point in the outputBuffer to write the data at. + + + + Used for stream chaining. Computes hash as data passes through it. Finishes off the hash. + + The buffer from which to grab the data to be copied. + The offset into the input buffer to start reading at. + The number of bytes to be copied. + + + + Get whether or not the hash can transform multiple blocks at a time. + Note: MUST be overriden if descendant can transform multiple block + on a single call! + + + + + Gets the previously computed hash. + + + + + Returns the size in bits of the hash. + + + + + Must be overriden if not 1 + + + + + Must be overriden if not 1 + + + + + Common base class for all derived MD5 implementations. + + + + + Called from constructor of derived class. + + + + + Creates the default derived class. + + C# implementation of the MD5 cryptographic hash function. @@ -3577,6 +2155,1570 @@ Position in buffer in bytes to get data from. How much data in bytes in the buffer to use. + + + Implements for version 3 of the protocol. + + + + + Reads a row, field by field, allowing a DataRow to be built appropriately. + + + + + Marker interface which identifies a class which may take possession of a stream for the duration of + it's lifetime (possibly temporarily giving that possession to another class for part of that time. + + It inherits from IDisposable, since any such class must make sure it leaves the stream in a valid state. + + The most important such class is that compiler-generated from ProcessBackendResponsesEnum. Of course + we can't make that inherit from this interface, alas. + + + + + Marker interface which identifies a class which represents part of + a response from the server. + + + + + Reads part of a field, as needed (for + and + + + + + Adds further functionality to stream that is dependant upon the type of data read. + + + + + Completes the implementation of Streamer for char data. + + + + + Completes the implementation of Streamer for byte data. + + + + + Implements for version 2 of the protocol. + + + + + Encapsulates the null mapping bytes sent at the start of a version 2 + datarow message, and the process of identifying the nullity of the data + at a particular index + + + + + This class represents a BackEndKeyData message received + from PostgreSQL + + + + + This class represents the Bind message sent to PostgreSQL + server. + + + + + + For classes representing messages sent from the client to the server. + + + + + This class represents the CancelRequest message sent to PostgreSQL + server. + + + + + + Represents a SQL statement or function (stored procedure) to execute + against a PostgreSQL database. This class cannot be inherited. + + + Represents a SQL statement or function (stored procedure) to execute + against a PostgreSQL database. This class cannot be inherited. + + + Represents a SQL statement or function (stored procedure) to execute + against a PostgreSQL database. This class cannot be inherited. + + + + + Initializes a new instance of the NpgsqlCommand class. + + + + + Initializes a new instance of the NpgsqlCommand class with the text of the query. + + The text of the query. + + + + Initializes a new instance of the NpgsqlCommand class with the text of the query and a NpgsqlConnection. + + The text of the query. + A NpgsqlConnection that represents the connection to a PostgreSQL server. + + + + Initializes a new instance of the NpgsqlCommand class with the text of the query, a NpgsqlConnection, and the NpgsqlTransaction. + + The text of the query. + A NpgsqlConnection that represents the connection to a PostgreSQL server. + The NpgsqlTransaction in which the NpgsqlCommand executes. + + + + Used to execute internal commands. + + + + + Attempts to cancel the execution of a NpgsqlCommand. + + This Method isn't implemented yet. + + + + Create a new command based on this one. + + A new NpgsqlCommand object. + + + + Create a new command based on this one. + + A new NpgsqlCommand object. + + + + Creates a new instance of an DbParameter object. + + An DbParameter object. + + + + Creates a new instance of a NpgsqlParameter object. + + A NpgsqlParameter object. + + + + Slightly optimised version of ExecuteNonQuery() for internal use in cases where the number + of affected rows is of no interest. + This function must not be called with a query that returns result rows, after calling Prepare(), or. + with a query that requires parameter substitution of any kind. + + + + + Executes a SQL statement against the connection and returns the number of rows affected. + + The number of rows affected if known; -1 otherwise. + + + + Sends the CommandText to + the Connection and builds a + NpgsqlDataReader + using one of the CommandBehavior values. + + One of the CommandBehavior values. + A NpgsqlDataReader object. + + + + Sends the CommandText to + the Connection and builds a + NpgsqlDataReader. + + A NpgsqlDataReader object. + + + + Sends the CommandText to + the Connection and builds a + NpgsqlDataReader + using one of the CommandBehavior values. + + One of the CommandBehavior values. + A NpgsqlDataReader object. + Currently the CommandBehavior parameter is ignored. + + + + This method binds the parameters from parameters collection to the bind + message. + + + + + Executes the query, and returns the first column of the first row + in the result set returned by the query. Extra columns or rows are ignored. + + The first column of the first row in the result set, + or a null reference if the result set is empty. + + + + Creates a prepared version of the command on a PostgreSQL server. + + + + + This method checks the connection state to see if the connection + is set or it is open. If one of this conditions is not met, throws + an InvalidOperationException + + + + + This method substitutes the Parameters, if exist, in the command + to their actual values. + The parameter name format is :ParameterName. + + A version of CommandText with the Parameters inserted. + + + + Process this.commandText, trimming each distinct command and substituting paramater + tokens. + + + + UTF8 encoded command ready to be sent to the backend. + + + + Find the beginning and end of each distinct SQL command and produce + a list of descriptors, one for each command. Commands described are trimmed of + leading and trailing white space and their terminating semi-colons. + + Raw command text. + List of chunk descriptors. + + + + Append a region of a source command text to an output command, performing parameter token + substitutions. + + Stream to which to append output. + Command text. + Starting index within src. + Length of region to be processed. + + + + + + Gets or sets the SQL statement or function (stored procedure) to execute at the data source. + + The Transact-SQL statement or stored procedure to execute. The default is an empty string. + + + + Gets or sets the wait time before terminating the attempt + to execute a command and generating an error. + + The time (in seconds) to wait for the command to execute. + The default is 20 seconds. + + + + Gets or sets a value indicating how the + CommandText property is to be interpreted. + + One of the CommandType values. The default is CommandType.Text. + + + + Gets or sets the NpgsqlConnection + used by this instance of the NpgsqlCommand. + + The connection to a data source. The default value is a null reference. + + + + Gets the NpgsqlParameterCollection. + + The parameters of the SQL statement or function (stored procedure). The default is an empty collection. + + + + Gets or sets the NpgsqlTransaction + within which the NpgsqlCommand executes. + + The NpgsqlTransaction. + The default value is a null reference. + + + + Gets or sets how command results are applied to the DataRow + when used by the Update + method of the DbDataAdapter. + + One of the UpdateRowSource values. + + + + Returns oid of inserted row. This is only updated when using executenonQuery and when command inserts just a single row. If table is created without oids, this will always be 0. + + + + + This class is responsible to create database commands for automatic insert, update and delete operations. + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class. + + The adapter. + + + + + This method is reponsible to derive the command parameter list with values obtained from function definition. + It clears the Parameters collection of command. Also, if there is any parameter type which is not supported by Npgsql, an InvalidOperationException will be thrown. + Parameters name will be parameter1, parameter2, ... + + NpgsqlCommand whose function parameters will be obtained. + + + + Gets the automatically generated object required + to perform insertions at the data source. + + + The automatically generated object required to perform insertions. + + + + + Gets the automatically generated object required to perform insertions + at the data source, optionally using columns for parameter names. + + + If true, generate parameter names matching column names, if possible. + If false, generate @p1, @p2, and so on. + + + The automatically generated object required to perform insertions. + + + + + Gets the automatically generated System.Data.Common.DbCommand object required + to perform updates at the data source. + + + The automatically generated System.Data.Common.DbCommand object required to perform updates. + + + + + Gets the automatically generated object required to perform updates + at the data source, optionally using columns for parameter names. + + + If true, generate parameter names matching column names, if possible. + If false, generate @p1, @p2, and so on. + + + The automatically generated object required to perform updates. + + + + + Gets the automatically generated System.Data.Common.DbCommand object required + to perform deletions at the data source. + + + The automatically generated System.Data.Common.DbCommand object required to perform deletions. + + + + + Gets the automatically generated object required to perform deletions + at the data source, optionally using columns for parameter names. + + + If true, generate parameter names matching column names, if possible. + If false, generate @p1, @p2, and so on. + + + The automatically generated object required to perform deletions. + + + + + Applies the parameter information. + + The parameter. + The row. + Type of the statement. + if set to true [where clause]. + + + + Returns the name of the specified parameter in the format of @p#. + + The number to be included as part of the parameter's name.. + + The name of the parameter with the specified number appended as part of the parameter name. + + + + + Returns the full parameter name, given the partial parameter name. + + The partial name of the parameter. + + The full parameter name corresponding to the partial parameter name requested. + + + + + Returns the placeholder for the parameter in the associated SQL statement. + + The number to be included as part of the parameter's name. + + The name of the parameter with the specified number appended. + + + + + Registers the to handle the event for a . + + The to be used for the update. + + + + Adds an event handler for the event. + + The sender + A instance containing information about the event. + + + + Given an unquoted identifier in the correct catalog case, returns the correct quoted form of that identifier, including properly escaping any embedded quotes in the identifier. + + The original unquoted identifier. + + The quoted version of the identifier. Embedded quotes within the identifier are properly escaped. + + + + + Unquoted identifier parameter cannot be null + + + + Given a quoted identifier, returns the correct unquoted form of that identifier, including properly un-escaping any embedded quotes in the identifier. + + The identifier that will have its embedded quotes removed. + + The unquoted identifier, with embedded quotes properly un-escaped. + + + + + Quoted identifier parameter cannot be null + + + + Gets or sets the beginning character or characters to use when specifying database objects (for example, tables or columns) whose names contain characters such as spaces or reserved tokens. + + + The beginning character or characters to use. The default is an empty string. + + + + + + + + Gets or sets the ending character or characters to use when specifying database objects (for example, tables or columns) whose names contain characters such as spaces or reserved tokens. + + + The ending character or characters to use. The default is an empty string. + + + + + + + + Represents the method that handles the Notice events. + + The source of the event. + A NpgsqlNoticeEventArgs that contains the event data. + + + + Represents the method that handles the Notification events. + + The source of the event. + A NpgsqlNotificationEventArgs that contains the event data. + + + + This class represents a connection to a + PostgreSQL server. + + + + + Initializes a new instance of the + NpgsqlConnection class. + + + + + Initializes a new instance of the + NpgsqlConnection class + and sets the ConnectionString. + + The connection used to open the PostgreSQL database. + + + + Initializes a new instance of the + NpgsqlConnection class + and sets the ConnectionString. + + The connection used to open the PostgreSQL database. + + + + Begins a database transaction with the specified isolation level. + + The isolation level under which the transaction should run. + An DbTransaction + object representing the new transaction. + + Currently the IsolationLevel ReadCommitted and Serializable are supported by the PostgreSQL backend. + There's no support for nested transactions. + + + + + Begins a database transaction. + + A NpgsqlTransaction + object representing the new transaction. + + Currently there's no support for nested transactions. + + + + + Begins a database transaction with the specified isolation level. + + The isolation level under which the transaction should run. + A NpgsqlTransaction + object representing the new transaction. + + Currently the IsolationLevel ReadCommitted and Serializable are supported by the PostgreSQL backend. + There's no support for nested transactions. + + + + + Opens a database connection with the property settings specified by the + ConnectionString. + + + + + This method changes the current database by disconnecting from the actual + database and connecting to the specified. + + The name of the database to use in place of the current database. + + + + Releases the connection to the database. If the connection is pooled, it will be + made available for re-use. If it is non-pooled, the actual connection will be shutdown. + + + + + When a connection is closed within an enclosing TransactionScope and the transaction + hasn't been promoted, we defer the actual closing until the scope ends. + + + + + Creates and returns a DbCommand + object associated with the IDbConnection. + + A DbCommand object. + + + + Creates and returns a NpgsqlCommand + object associated with the NpgsqlConnection. + + A NpgsqlCommand object. + + + + Releases all resources used by the + NpgsqlConnection. + + true when called from Dispose(); + false when being called from the finalizer. + + + + Create a new connection based on this one. + + A new NpgsqlConnection object. + + + + Create a new connection based on this one. + + A new NpgsqlConnection object. + + + + Returns a copy of the NpgsqlConnectionStringBuilder that contains the parsed connection string values. + + + + + Default SSL CertificateSelectionCallback implementation. + + + + + Default SSL CertificateValidationCallback implementation. + + + + + Default SSL PrivateKeySelectionCallback implementation. + + + + + Default SSL ProvideClientCertificatesCallback implementation. + + + + + Default SSL ValidateRemoteCertificateCallback implementation. + + + + + Write each key/value pair in the connection string to the log. + + + + + Sets the `settings` ConnectionStringBuilder based on the given `connectionString` + + The connection string to load the builder from + + + + Sets the `settings` ConnectionStringBuilder based on the given `connectionString` + + The connection string to load the builder from + + + + Refresh the cached _connectionString whenever the builder settings change + + + + + Returns the supported collections + + + + + Returns the schema collection specified by the collection name. + + The collection name. + The collection specified. + + + + Returns the schema collection specified by the collection name filtered by the restrictions. + + The collection name. + + The restriction values to filter the results. A description of the restrictions is contained + in the Restrictions collection. + + The collection specified. + + + + Occurs on NoticeResponses from the PostgreSQL backend. + + + + + Occurs on NotificationResponses from the PostgreSQL backend. + + + + + Called to provide client certificates for SSL handshake. + + + + + Mono.Security.Protocol.Tls.CertificateSelectionCallback delegate. + + + + + Mono.Security.Protocol.Tls.CertificateValidationCallback delegate. + + + + + Mono.Security.Protocol.Tls.PrivateKeySelectionCallback delegate. + + + + + Called to validate server's certificate during SSL handshake + + + + + Gets or sets the string used to connect to a PostgreSQL database. + Valid values are: +
    +
  • + Server: Address/Name of Postgresql Server; +
  • +
  • + Port: Port to connect to; +
  • +
  • + Protocol: Protocol version to use, instead of automatic; Integer 2 or 3; +
  • +
  • + Database: Database name. Defaults to user name if not specified; +
  • +
  • + User Id: User name; +
  • +
  • + Password: Password for clear text authentication; +
  • +
  • + SSL: True or False. Controls whether to attempt a secure connection. Default = False; +
  • +
  • + Pooling: True or False. Controls whether connection pooling is used. Default = True; +
  • +
  • + MinPoolSize: Min size of connection pool; +
  • +
  • + MaxPoolSize: Max size of connection pool; +
  • +
  • + Timeout: Time to wait for connection open in seconds. Default is 15. +
  • +
  • + CommandTimeout: Time to wait for command to finish execution before throw an exception. In seconds. Default is 20. +
  • +
  • + Sslmode: Mode for ssl connection control. Can be Prefer, Require, Allow or Disable. Default is Disable. Check user manual for explanation of values. +
  • +
  • + ConnectionLifeTime: Time to wait before closing unused connections in the pool in seconds. Default is 15. +
  • +
  • + SyncNotification: Specifies if Npgsql should use synchronous notifications. +
  • +
  • + SearchPath: Changes search path to specified and public schemas. +
  • +
+
+ The connection string that includes the server name, + the database name, and other parameters needed to establish + the initial connection. The default value is an empty string. + +
+ + + Backend server host name. + + + + + Backend server port. + + + + + If true, the connection will attempt to use SSL. + + + + + Gets the time to wait while trying to establish a connection + before terminating the attempt and generating an error. + + The time (in seconds) to wait for a connection to open. The default value is 15 seconds. + + + + Gets the time to wait while trying to execute a command + before terminating the attempt and generating an error. + + The time (in seconds) to wait for a command to complete. The default value is 20 seconds. + + + + Gets the time to wait before closing unused connections in the pool if the count + of all connections exeeds MinPoolSize. + + + If connection pool contains unused connections for ConnectionLifeTime seconds, + the half of them will be closed. If there will be unused connections in a second + later then again the half of them will be closed and so on. + This strategy provide smooth change of connection count in the pool. + + The time (in seconds) to wait. The default value is 15 seconds. + + + + Gets the name of the current database or the database to be used after a connection is opened. + + The name of the current database or the name of the database to be + used after a connection is opened. The default value is the empty string. + + + + Whether datareaders are loaded in their entirety (for compatibility with earlier code). + + + + + Gets the database server name. + + + + + Gets flag indicating if we are using Synchronous notification or not. + The default value is false. + + + + + Gets the current state of the connection. + + A bitwise combination of the ConnectionState values. The default is Closed. + + + + Gets whether the current state of the connection is Open or Closed + + ConnectionState.Open or ConnectionState.Closed + + + + Version of the PostgreSQL backend. + This can only be called when there is an active connection. + + + + + Protocol version in use. + This can only be called when there is an active connection. + + + + + Process id of backend server. + This can only be called when there is an active connection. + + + + + Report whether the backend is expecting standard conformant strings. + In version 8.1, Postgres began reporting this value (false), but did not actually support standard conformant strings. + In version 8.2, Postgres began supporting standard conformant strings, but defaulted this flag to false. + As of version 9.1, this flag defaults to true. + + + + + Report whether the backend understands the string literal E prefix (>= 8.1). + + + + + Report whether the backend understands the hex byte format (>= 9.0). + + + + + The connector object connected to the backend. + + + + + Gets the NpgsqlConnectionStringBuilder containing the parsed connection string values. + + + + + User name. + + + + + Password. + + + + + Determine if connection pooling will be used for this connection. + + + + + Return an exact copy of this NpgsqlConnectionString. + + + + + No integrated security if we're on mono and .NET 4.5 because of ClaimsIdentity, + see https://github.com/npgsql/Npgsql/issues/133 + + + + + This function will set value for known key, both private member and base[key]. + + + + + value, coerced as needed to the stored type. + + + + The function will modify private member only, not base[key]. + + + + value, coerced as needed to the stored type. + + + + The function will access private member only, not base[key]. + + + value. + + + + Clear the member and assign them to the default value. + + + + + Gets or sets the backend server host name. + + + + + Gets or sets the backend server port. + + + + + Gets or sets the specified backend communication protocol version. + + + + + Gets or sets the name of the database to be used after a connection is opened. + + The name of the database to be + used after a connection is opened. + + + + Gets or sets the login user name. + + + + + This is a pretty horrible hack to fix https://github.com/npgsql/Npgsql/issues/133 + In a nutshell, starting with .NET 4.5 WindowsIdentity inherits from ClaimsIdentity + which doesn't exist in mono, and calling UserName getter above bombs. + The workaround is that the function that actually deals with WindowsIdentity never + gets called on mono, so never gets JITted and the problem goes away. + + + + + Gets or sets the login password as a UTF8 encoded byte array. + + + + + Sets the login password as a string. + + + + + Gets or sets a value indicating whether to attempt to use SSL. + + + + + Gets or sets a value indicating whether to attempt to use SSL. + + + + + Gets the backend encoding. Always returns "UTF8". + + + + + Gets or sets the time to wait while trying to establish a connection + before terminating the attempt and generating an error. + + The time (in seconds) to wait for a connection to open. The default value is 15 seconds. + + + + Gets or sets the schema search path. + + + + + Gets or sets a value indicating whether connection pooling should be used. + + + + + Gets or sets the time to wait before closing unused connections in the pool if the count + of all connections exeeds MinPoolSize. + + + If connection pool contains unused connections for ConnectionLifeTime seconds, + the half of them will be closed. If there will be unused connections in a second + later then again the half of them will be closed and so on. + This strategy provide smooth change of connection count in the pool. + + The time (in seconds) to wait. The default value is 15 seconds. + + + + Gets or sets the minimum connection pool size. + + + + + Gets or sets the maximum connection pool size. + + + + + Gets or sets a value indicating whether to listen for notifications and report them between command activity. + + + + + Gets the time to wait while trying to execute a command + before terminating the attempt and generating an error. + + The time (in seconds) to wait for a command to complete. The default value is 20 seconds. + + + + Gets or sets a value indicating whether datareaders are loaded in their entirety (for compatibility with earlier code). + + + + + Compatibilty version. When possible, behaviour caused by breaking changes will be preserved + if this version is less than that where the breaking change was introduced. + + + + + Gets or sets the ootional application name parameter to be sent to the backend during connection initiation. + + + + + Gets or sets a value indicating whether to silently Prepare() all commands before execution. + + + + + Case insensative accessor for indivual connection string values. + + + + + Set both ImplicitDefault and ExplicitDefault to the 's default value. + + + + + + + + Set ImplicitDefault to the default value of 's type, + and ExplicitDefault to . + + + + + + + + Represents the method that allows the application to provide a certificate collection to be used for SSL clien authentication + + A X509CertificateCollection to be filled with one or more client certificates. + + + + Represents the method that is called to validate the certificate provided by the server during an SSL handshake + + The server's certificate + The certificate chain containing the certificate's CA and any intermediate authorities + Any errors that were detected + + + + !!! Helper class, for compilation only. + Connector implements the logic for the Connection Objects to + access the physical connection to the database, and isolate + the application developer from connection pooling internals. + + + + + Constructor. + + Connection string. + Pooled + Controls whether the connector can be shared. + + + + This method checks if the connector is still ok. + We try to send a simple query text, select 1 as ConnectionTest; + + + + + This method is responsible for releasing all resources associated with this Connector. + + + + + This method is responsible to release all portals used by this Connector. + + + + + Default SSL CertificateSelectionCallback implementation. + + + + + Default SSL CertificateValidationCallback implementation. + + + + + Default SSL PrivateKeySelectionCallback implementation. + + + + + Default SSL ProvideClientCertificatesCallback implementation. + + + + + Default SSL ValidateRemoteCertificateCallback implementation. + + + + + This method is required to set all the version dependent features flags. + SupportsPrepare means the server can use prepared query plans (7.3+) + + + + + Opens the physical connection to the server. + + Usually called by the RequestConnector + Method of the connection pool manager. + + + + Closes the physical connection to the server. + + + + + Returns next portal index. + + + + + Returns next plan index. + + + + + Occurs on NoticeResponses from the PostgreSQL backend. + + + + + Occurs on NotificationResponses from the PostgreSQL backend. + + + + + Called to provide client certificates for SSL handshake. + + + + + Mono.Security.Protocol.Tls.CertificateSelectionCallback delegate. + + + + + Mono.Security.Protocol.Tls.CertificateValidationCallback delegate. + + + + + Mono.Security.Protocol.Tls.PrivateKeySelectionCallback delegate. + + + + + Called to validate server's certificate during SSL handshake + + + + + Gets the current state of the connection. + + + + + Return Connection String. + + + + + Version of backend server this connector is connected to. + + + + + Backend protocol version in use by this connector. + + + + + The physical connection socket to the backend. + + + + + The physical connection stream to the backend. + + + + + The top level stream to the backend. + + + + + Reports if this connector is fully connected. + + + + + The connection mediator. + + + + + Report if the connection is in a transaction. + + + + + Report whether the current connection can support prepare functionality. + + + + + Options that control certain aspects of native to backend conversions that depend + on backend version and status. + + + + + This class manages all connector objects, pooled AND non-pooled. + + + + Unique static instance of the connector pool + mamager. + + + Map of index to unused pooled connectors, avaliable to the + next RequestConnector() call. + This hashmap will be indexed by connection string. + This key will hold a list of queues of pooled connectors available to be used. + + + Timer for tracking unused connections in pools. + + + + Searches the shared and pooled connector lists for a + matching connector object or creates a new one. + + The NpgsqlConnection that is requesting + the connector. Its ConnectionString will be used to search the + pool for available connectors. + A connector object. + + + + Find a pooled connector. Handle shared/non-shared here. + + + + + Releases a connector, possibly back to the pool for future use. + + + Pooled connectors will be put back into the pool if there is room. + Shared connectors should just have their use count decremented + since they always stay in the shared pool. + + Connection to which the connector is leased. + The connector to release. + + + + Release a pooled connector. Handle shared/non-shared here. + + + + + Find an available pooled connector in the non-shared pool, or create + a new one if none found. + + + + + Put a pooled connector into the pool queue. + + Connection is leased to. + Connector to pool + + + + A queue with an extra Int32 for keeping track of busy connections. + + + + + Connections available to the end user + + + + + Connections currently in use + + + + + Represents information about COPY operation data transfer format as returned by server. + + + + + Only created when a CopyInResponse or CopyOutResponse is received by NpgsqlState.ProcessBackendResponses() + + + + + Returns true if this operation is currently active and field at given location is in binary format. + + + + + Returns true if this operation is currently active and in binary format. + + + + + Returns number of fields if this operation is currently active, otherwise -1 + + + + + Represents a PostgreSQL COPY FROM STDIN operation with a corresponding SQL statement + to execute against a PostgreSQL database + and an associated stream used to read data from (if provided by user) + or for writing it (when generated by driver). + Eg. new NpgsqlCopyIn("COPY mytable FROM STDIN", connection, streamToRead).Start(); + + + + + Creates NpgsqlCommand to run given query upon Start(). Data for the requested COPY IN operation can then be written to CopyData stream followed by a call to End() or Cancel(). + + + + + Given command is run upon Start(). Data for the requested COPY IN operation can then be written to CopyData stream followed by a call to End() or Cancel(). + + + + + Given command is executed upon Start() and all data from fromStream is passed to it as copy data. + + + + + Returns true if this operation is currently active and field at given location is in binary format. + + + + + Command specified upon creation is executed as a non-query. + If CopyStream is set upon creation, it will be flushed to server as copy data, and operation will be finished immediately. + Otherwise the CopyStream member can be used for writing copy data to server and operation finished with a call to End() or Cancel(). + + + + + Called after writing all data to CopyStream to successfully complete this copy operation. + + + + + Withdraws an already started copy operation. The operation will fail with given error message. + Will do nothing if current operation is not active. + + + + + Returns true if the connection is currently reserved for this operation. + + + + + The stream provided by user or generated upon Start(). + User may provide a stream to constructor; it is used to pass to server all data read from it. + Otherwise, call to Start() sets this to a writable NpgsqlCopyInStream that passes all data written to it to server. + In latter case this is only available while the copy operation is active and null otherwise. + + + + + Returns true if this operation is currently active and in binary format. + + + + + Returns number of fields expected on each input row if this operation is currently active, otherwise -1 + + + + + The Command used to execute this copy operation. + + + + + Set before a COPY IN query to define size of internal buffer for reading from given CopyStream. + + + + + Represents an ongoing COPY FROM STDIN operation. + Provides methods to push data to server and end or cancel the operation. + + + + + Called from NpgsqlState.ProcessBackendResponses upon CopyInResponse. + If CopyStream is already set, it is used to read data to push to server, after which the copy is completed. + Otherwise CopyStream is set to a writable NpgsqlCopyInStream that calls SendCopyData each time it is written to. + + + + + Sends given packet to server as a CopyData message. + Does not check for notifications! Use another thread for that. + + + + + Sends CopyDone message to server. Handles responses, ie. may throw an exception. + + + + + Sends CopyFail message to server. Handles responses, ie. should always throw an exception: + in CopyIn state the server responds to CopyFail with an error response; + outside of a CopyIn state the server responds to CopyFail with an error response; + without network connection or whatever, there's going to eventually be a failure, timeout or user intervention. + + + + + Copy format information returned from server. + + Stream for writing data to a table on a PostgreSQL version 7.4 or newer database during an active COPY FROM STDIN operation. @@ -3657,203 +3799,1233 @@ Number of bytes written so far; not settable - + - Represents a SQL statement or function (stored procedure) to execute - against a PostgreSQL database. This class cannot be inherited. + Represents a PostgreSQL COPY TO STDOUT operation with a corresponding SQL statement + to execute against a PostgreSQL database + and an associated stream used to write results to (if provided by user) + or for reading the results (when generated by driver). + Eg. new NpgsqlCopyOut("COPY (SELECT * FROM mytable) TO STDOUT", connection, streamToWrite).Start(); - + - Initializes a new instance of the NpgsqlCommand class. + Creates NpgsqlCommand to run given query upon Start(), after which CopyStream provides data from database as requested in the query. - + - Initializes a new instance of the NpgsqlCommand class with the text of the query. - - The text of the query. - - - - Initializes a new instance of the NpgsqlCommand class with the text of the query and a NpgsqlConnection. - - The text of the query. - A NpgsqlConnection that represents the connection to a PostgreSQL server. - - - - Initializes a new instance of the NpgsqlCommand class with the text of the query, a NpgsqlConnection, and the NpgsqlTransaction. - - The text of the query. - A NpgsqlConnection that represents the connection to a PostgreSQL server. - The NpgsqlTransaction in which the NpgsqlCommand executes. - - - - Used to execute internal commands. + Given command is run upon Start(), after which CopyStream provides data from database as requested in the query. - + - Attempts to cancel the execution of a NpgsqlCommand. - - This Method isn't implemented yet. - - - - Create a new command based on this one. - - A new NpgsqlCommand object. - - - - Create a new command based on this one. - - A new NpgsqlCommand object. - - - - Creates a new instance of an DbParameter object. - - An DbParameter object. - - - - Creates a new instance of a NpgsqlParameter object. - - A NpgsqlParameter object. - - - - Slightly optimised version of ExecuteNonQuery() for internal ues in cases where the number - of affected rows is of no interest. + Given command is executed upon Start() and all requested copy data is written to toStream immediately. - + - Executes a SQL statement against the connection and returns the number of rows affected. + Returns true if this operation is currently active and field at given location is in binary format. - The number of rows affected if known; -1 otherwise. - + - Sends the CommandText to - the Connection and builds a - NpgsqlDataReader - using one of the CommandBehavior values. + Command specified upon creation is executed as a non-query. + If CopyStream is set upon creation, all copy data from server will be written to it, and operation will be finished immediately. + Otherwise the CopyStream member can be used for reading copy data from server until no more data is available. - One of the CommandBehavior values. - A NpgsqlDataReader object. - + - Sends the CommandText to - the Connection and builds a - NpgsqlDataReader. + Flush generated CopyStream at once. Effectively reads and discard all the rest of copy data from server. - A NpgsqlDataReader object. - + - Sends the CommandText to - the Connection and builds a - NpgsqlDataReader - using one of the CommandBehavior values. + Returns true if the connection is currently reserved for this operation. - One of the CommandBehavior values. - A NpgsqlDataReader object. - Currently the CommandBehavior parameter is ignored. - + - This method binds the parameters from parameters collection to the bind - message. + The stream provided by user or generated upon Start() + + + + + The Command used to execute this copy operation. + + + + + Returns true if this operation is currently active and in binary format. + + + + + Returns number of fields if this operation is currently active, otherwise -1 + + + + + Faster alternative to using the generated CopyStream. + + + + + Represents an ongoing COPY TO STDOUT operation. + Provides methods to read data from server or end the operation. + + + + + Called from NpgsqlState.ProcessBackendResponses upon CopyOutResponse. + If CopyStream is already set, it is used to write data received from server, after which the copy ends. + Otherwise CopyStream is set to a readable NpgsqlCopyOutStream that receives data from server. + + + + + Called from NpgsqlOutStream.Read to read copy data from server. + + + + + Copy format information returned from server. + + + + + Stream for reading data from a table or select on a PostgreSQL version 7.4 or newer database during an active COPY TO STDOUT operation. + Passes data exactly as provided by the server. + + + + + Created only by NpgsqlCopyOutState.StartCopy() + + + + + Discards copy data as long as server pushes it. Returns after operation is finished. + Does nothing if this stream is not the active copy operation reader. + + + + + Not writable. + + + + + Not flushable. + + + + + Copies data read from server to given byte buffer. + Since server returns data row by row, length will differ each time, but it is only zero once the operation ends. + Can be mixed with calls to the more efficient NpgsqlCopyOutStream.Read() : byte[] though that would not make much sense. + + + + + Not seekable + + + + + Not supported + + + + + Returns a whole row of data from server without extra work. + If standard Stream.Read(...) has been called before, it's internal buffers remains are returned. + + + + + True while this stream can be used to read copy data from server + + + + + True + + + + + False + + + + + False + + + + + Number of bytes read so far + + + + + Number of bytes read so far; can not be set. + + + + + Writes given objects into a stream for PostgreSQL COPY in default copy format (not CSV or BINARY). + + + + + Represents the method that handles the RowUpdated events. + + The source of the event. + A NpgsqlRowUpdatedEventArgs that contains the event data. + + + + Represents the method that handles the RowUpdating events. + + The source of the event. + A NpgsqlRowUpdatingEventArgs that contains the event data. + + + + This class represents an adapter from many commands: select, update, insert and delete to fill Datasets. + + + + + Provides a means of reading a forward-only stream of rows from a PostgreSQL backend. This class cannot be inherited. + + + + + Return the data type name of the column at index . + + + + + Return the data type of the column at index . + + + + + Return the Npgsql specific data type of the column at requested ordinal. + + column position + Appropriate Npgsql type for column. + + + + Return the column name of the column at index . + + + + + Return the data type OID of the column at index . + + FIXME: Why this method returns String? + + + + Return the column name of the column named . + + + + + Return the data DbType of the column at index . + + + + + Return the data NpgsqlDbType of the column at index . + + + + + Get the value of a column as a . + If the differences between and + in handling of days and months is not important to your application, use + instead. + + Index of the field to find. + value of the field. + + + + Gets the value of a column converted to a Guid. + + + + + Gets the value of a column as Int16. + + + + + Gets the value of a column as Int32. + + + + + Gets the value of a column as Int64. + + + + + Gets the value of a column as Single. + + + + + Gets the value of a column as Double. + + + + + Gets the value of a column as String. + + + + + Gets the value of a column as Decimal. + + + + + Gets the value of a column as TimeSpan. + + + + + Copy values from each column in the current row into . + + Destination for column values. + The number of column values copied. + + + + Copy values from each column in the current row into . + + An array appropriately sized to store values from all columns. + The number of column values copied. + + + + Gets the value of a column as Boolean. + + + + + Gets the value of a column as Byte. Not implemented. + + + + + Gets the value of a column as Char. + + + + + Gets the value of a column as DateTime. + + + + + Returns a System.Data.DataTable that describes the column metadata of the DataReader. + + + + + This methods parses the command text and tries to get the tablename + from it. + + + + + Is raised whenever Close() is called. + + + + + Gets the number of columns in the current row. + + + + + Gets the value of a column in its native format. + + + + + Gets the value of a column in its native format. + + + + + Gets a value indicating the depth of nesting for the current row. Always returns zero. + + + + + Gets a value indicating whether the data reader is closed. + + + + + Contains the column names as the keys + + + + + Contains all unique columns + + + + + This is the primary implementation of NpgsqlDataReader. It is the one used in normal cases (where the + preload-reader option is not set in the connection string to resolve some potential backwards-compatibility + issues), the only implementation used internally, and in cases where CachingDataReader is used, it is still + used to do the actual "leg-work" of turning a response stream from the server into a datareader-style + object - with CachingDataReader then filling it's cache from here. + + + + + Iterate through the objects returned through from the server. + If it's a CompletedResponse the rowsaffected count is updated appropriately, + and we iterate again, otherwise we return it (perhaps updating our cache of pending + rows if appropriate). + + The next we will deal with. + + + + Advances the data reader to the next result, when multiple result sets were returned by the PostgreSQL backend. + + True if the reader was advanced, otherwise false. + + + + Releases the resources used by the NpgsqlCommand. + + + + + Closes the data reader object. + + + + + Advances the data reader to the next result, when multiple result sets were returned by the PostgreSQL backend. + + True if the reader was advanced, otherwise false. + + + + Advances the data reader to the next row. + + True if the reader was advanced, otherwise false. + + + + Return the value of the column at index . + + + + + Gets raw data from a column. + + + + + Gets raw data from a column. + + + + + Report whether the value in a column is DBNull. + + + + + Gets the number of rows changed, inserted, or deleted by execution of the SQL statement. + + + + + Indicates if NpgsqlDatareader has rows to be read. + + + + + Provides an implementation of NpgsqlDataReader in which all data is pre-loaded into memory. + This operates by first creating a ForwardsOnlyDataReader as usual, and then loading all of it's + Rows into memory. There is a general principle that when there is a trade-off between a class design that + is more efficient and/or scalable on the one hand and one that is less efficient but has more functionality + (in this case the internal-only functionality of caching results) that one can build the less efficent class + from the most efficient without significant extra loss in efficiency, but not the other way around. The relationship + between ForwardsOnlyDataReader and CachingDataReader is an example of this). + Since the interface presented to the user is still forwards-only, queues are used to + store this information, so that dequeueing as we go we give the garbage collector the best opportunity + possible to reclaim any memory that is no longer in use. + ForwardsOnlyDataReader being used to actually + obtain the information from the server means that the "leg-work" is still only done (and need only be + maintained) in one place. + This class exists to allow for certain potential backwards-compatibility issues to be resolved + with little effort on the part of affected users. It is considerably less efficient than ForwardsOnlyDataReader + and hence never used internally. + + + + + This is the base class for NpgsqlDescribeStatement and NpgsqlDescribePortal. + - - - Executes the query, and returns the first column of the first row - in the result set returned by the query. Extra columns or rows are ignored. - - The first column of the first row in the result set, - or a null reference if the result set is empty. + + + This class represents the Statement Describe message sent to PostgreSQL + server. + + - + + + This class represents the Portal Describe message sent to PostgreSQL + server. + + + + - Creates a prepared version of the command on a PostgreSQL server. + EventArgs class to send Notice parameters, which are just NpgsqlError's in a lighter context. - + - This method checks the connection state to see if the connection - is set or it is open. If one of this conditions is not met, throws - an InvalidOperationException + Notice information. - + - This method substitutes the Parameters, if exist, in the command - to their actual values. - The parameter name format is :ParameterName. + This class represents the ErrorResponse and NoticeResponse + message sent from PostgreSQL server. - A version of CommandText with the Parameters inserted. - + - Gets or sets the SQL statement or function (stored procedure) to execute at the data source. + Return a string representation of this error object. - The Transact-SQL statement or stored procedure to execute. The default is an empty string. - + - Gets or sets the wait time before terminating the attempt - to execute a command and generating an error. + Severity code. All versions. - The time (in seconds) to wait for the command to execute. - The default is 20 seconds. - + - Gets or sets a value indicating how the - CommandText property is to be interpreted. + Error code. PostgreSQL 7.4 and up. - One of the CommandType values. The default is CommandType.Text. - + - Gets or sets the NpgsqlConnection - used by this instance of the NpgsqlCommand. + Terse error message. All versions. - The connection to a data source. The default value is a null reference. - + - Gets the NpgsqlParameterCollection. + Detailed error message. PostgreSQL 7.4 and up. - The parameters of the SQL statement or function (stored procedure). The default is an empty collection. - + - Gets or sets the NpgsqlTransaction - within which the NpgsqlCommand executes. + Suggestion to help resolve the error. PostgreSQL 7.4 and up. - The NpgsqlTransaction. - The default value is a null reference. - + - Gets or sets how command results are applied to the DataRow - when used by the Update - method of the DbDataAdapter. + Position (one based) within the query string where the error was encounterd. PostgreSQL 7.4 and up. - One of the UpdateRowSource values. - + - Returns oid of inserted row. This is only updated when using executenonQuery and when command inserts just a single row. If table is created without oids, this will always be 0. + Position (one based) within the query string where the error was encounterd. This position refers to an internal command executed for example inside a PL/pgSQL function. PostgreSQL 7.4 and up. + + + Internal query string where the error was encounterd. This position refers to an internal command executed for example inside a PL/pgSQL function. PostgreSQL 7.4 and up. + + + + + Trace back information. PostgreSQL 7.4 and up. + + + + + Source file (in backend) reporting the error. PostgreSQL 7.4 and up. + + + + + Source file line number (in backend) reporting the error. PostgreSQL 7.4 and up. + + + + + Source routine (in backend) reporting the error. PostgreSQL 7.4 and up. + + + + + Schema name which relates to the error. PostgreSQL 9.3 and up. + + + + + Table name which relates to the error. PostgreSQL 9.3 and up. + + + + + Column name which relates to the error. PostgreSQL 9.3 and up. + + + + + Data type of column which relates to the error. PostgreSQL 9.3 and up. + + + + + Constraint name which relates to the error. PostgreSQL 9.3 and up. + + + + + String containing the sql sent which produced this error. + + + + + Backend protocol version in use. + + + + + Error and notice message field codes + + + + + Severity: the field contents are ERROR, FATAL, or PANIC (in an error message), + or WARNING, NOTICE, DEBUG, INFO, or LOG (in a notice message), or a localized + translation of one of these. Always present. + + + + + Code: the SQLSTATE code for the error (see Appendix A). Not localizable. Always present. + + + + + Message: the primary human-readable error message. This should be accurate + but terse (typically one line). Always present. + + + + + Detail: an optional secondary error message carrying more detail about the problem. + Might run to multiple lines. + + + + + Hint: an optional suggestion what to do about the problem. This is intended to differ + from Detail in that it offers advice (potentially inappropriate) rather than hard facts. + Might run to multiple lines. + + + + + Position: the field value is a decimal ASCII integer, indicating an error cursor + position as an index into the original query string. The first character has index 1, + and positions are measured in characters not bytes. + + + + + Internal position: this is defined the same as the P field, but it is used when the + cursor position refers to an internally generated command rather than the one submitted + by the client. + The q field will always appear when this field appears. + + + + + Internal query: the text of a failed internally-generated command. + This could be, for example, a SQL query issued by a PL/pgSQL function. + + + + + Where: an indication of the context in which the error occurred. + Presently this includes a call stack traceback of active procedural language functions + and internally-generated queries. The trace is one entry per line, most recent first. + + + + + Schema name: if the error was associated with a specific database object, + the name of the schema containing that object, if any. + + + + + Table name: if the error was associated with a specific table, the name of the table. + (Refer to the schema name field for the name of the table's schema.) + + + + + Column name: if the error was associated with a specific table column, the name of the column. + (Refer to the schema and table name fields to identify the table.) + + + + + Data type name: if the error was associated with a specific data type, the name of the data type. + (Refer to the schema name field for the name of the data type's schema.) + + + + + Constraint name: if the error was associated with a specific constraint, the name of the constraint. + Refer to fields listed above for the associated table or domain. + (For this purpose, indexes are treated as constraints, even if they weren't created with constraint syntax.) + + + + + File: the file name of the source-code location where the error was reported. + + + + + Line: the line number of the source-code location where the error was reported. + + + + + Routine: the name of the source-code routine reporting the error. + + + + + The level of verbosity of the NpgsqlEventLog + + + + + Don't log at all + + + + + Only log the most common issues + + + + + Log everything + + + + + This class handles all the Npgsql event and debug logging + + + + + Writes a string to the Npgsql event log if msglevel is bigger then NpgsqlEventLog.Level + + + This method is obsolete and should no longer be used. + It is likely to be removed in future versions of Npgsql + + The message to write to the event log + The minimum LogLevel for which this message should be logged. + + + + Writes a string to the Npgsql event log if msglevel is bigger then NpgsqlEventLog.Level + + The ResourceManager to get the localized resources + The name of the resource that should be fetched by the ResourceManager + The minimum LogLevel for which this message should be logged. + The additional parameters that shall be included into the log-message (must be compatible with the string in the resource): + + + + Writes the default log-message for the action of calling the Get-part of an Indexer to the log file. + + The minimum LogLevel for which this message should be logged. + The name of the class that contains the Indexer + The parameter given to the Indexer + + + + Writes the default log-message for the action of calling the Set-part of an Indexer to the logfile. + + The minimum LogLevel for which this message should be logged. + The name of the class that contains the Indexer + The parameter given to the Indexer + The value the Indexer is set to + + + + Writes the default log-message for the action of calling the Get-part of a Property to the logfile. + + The minimum LogLevel for which this message should be logged. + The name of the class that contains the Property + The name of the Property + + + + Writes the default log-message for the action of calling the Set-part of a Property to the logfile. + + The minimum LogLevel for which this message should be logged. + The name of the class that contains the Property + The name of the Property + The value the Property is set to + + + + Writes the default log-message for the action of calling a Method without Arguments to the logfile. + + The minimum LogLevel for which this message should be logged. + The name of the class that contains the Method + The name of the Method + + + + Writes the default log-message for the action of calling a Method with one Argument to the logfile. + + The minimum LogLevel for which this message should be logged. + The name of the class that contains the Method + The name of the Method + The value of the Argument of the Method + + + + Writes the default log-message for the action of calling a Method with two Arguments to the logfile. + + The minimum LogLevel for which this message should be logged. + The name of the class that contains the Method + The name of the Method + The value of the first Argument of the Method + The value of the second Argument of the Method + + + + Writes the default log-message for the action of calling a Method with three Arguments to the logfile. + + The minimum LogLevel for which this message should be logged. + The name of the class that contains the Method + The name of the Method + The value of the first Argument of the Method + The value of the second Argument of the Method + The value of the third Argument of the Method + + + + Writes the default log-message for the action of calling a Method with more than three Arguments to the logfile. + + The minimum LogLevel for which this message should be logged. + The name of the class that contains the Method + The name of the Method + A Object-Array with zero or more Ojects that are Arguments of the Method. + + + + Sets/Returns the level of information to log to the logfile. + + The current LogLevel + + + + Sets/Returns the filename to use for logging. + + The filename of the current Log file. + + + + Sets/Returns whether Log messages should be echoed to the console + + true if Log messages are echoed to the console, otherwise false + + + + The exception that is thrown when the PostgreSQL backend reports errors. + + + + + Construct a backend error exception based on a list of one or more + backend errors. The basic Exception.Message will be built from the + first (usually the only) error in the list. + + + + + Format a .NET style exception string. + Include all errors in the list, including any hints. + + + + + Append a line to the given Stream, first checking for zero-length. + + + + + Provide access to the entire list of errors provided by the PostgreSQL backend. + + + + + Severity code. All versions. + + + + + Error code. PostgreSQL 7.4 and up. + + + + + Basic error message. All versions. + + + + + Detailed error message. PostgreSQL 7.4 and up. + + + + + Suggestion to help resolve the error. PostgreSQL 7.4 and up. + + + + + Position (one based) within the query string where the error was encounterd. PostgreSQL 7.4 and up. + + + + + Trace back information. PostgreSQL 7.4 and up. + + + + + Source file (in backend) reporting the error. PostgreSQL 7.4 and up. + + + + + Source file line number (in backend) reporting the error. PostgreSQL 7.4 and up. + + + + + Source routine (in backend) reporting the error. PostgreSQL 7.4 and up. + + + + + Schema name which relates to the error. PostgreSQL 9.3 and up. + + + + + Table name which relates to the error. PostgreSQL 9.3 and up. + + + + + Column name which relates to the error. PostgreSQL 9.3 and up. + + + + + Data type of column which relates to the error. PostgreSQL 9.3 and up. + + + + + Constraint name which relates to the error. PostgreSQL 9.3 and up. + + + + + String containing the sql sent which produced this error. + + + + + Returns the entire list of errors provided by the PostgreSQL backend. + + + + + This class represents the Execute message sent to PostgreSQL + server. + + + + + + A factory to create instances of various Npgsql objects. + + + + + Creates an NpgsqlCommand object. + + + + + This class represents the Flush message sent to PostgreSQL + server. + + + + + + For classes representing simple messages, + consisting only of a message code and length identifier, + sent from the client to the server. + + + + + This class is responsible for serving as bridge between the backend + protocol handling and the core classes. It is used as the mediator for + exchanging data generated/sent from/to backend. + + + + + + EventArgs class to send Notification parameters. + + + + + Process ID of the PostgreSQL backend that sent this notification. + + + + + Condition that triggered that notification. + + + + + Additional Information From Notifiying Process (for future use, currently postgres always sets this to an empty string) + + + + + This class represents a parameter to a command that will be sent to server + + + + + Initializes a new instance of the NpgsqlParameter class. + + + + + Initializes a new instance of the NpgsqlParameter + class with the parameter m_Name and a value of the new NpgsqlParameter. + + The m_Name of the parameter to map. + An Object that is the value of the NpgsqlParameter. + +

When you specify an Object + in the value parameter, the DbType is + inferred from the .NET Framework type of the Object.

+

When using this constructor, you must be aware of a possible misuse of the constructor which takes a DbType parameter. + This happens when calling this constructor passing an int 0 and the compiler thinks you are passing a value of DbType. + Use Convert.ToInt32(value) for example to have compiler calling the correct constructor.

+
+
+ + + Initializes a new instance of the NpgsqlParameter + class with the parameter m_Name and the data type. + + The m_Name of the parameter to map. + One of the DbType values. + + + + Initializes a new instance of the NpgsqlParameter + class with the parameter m_Name, the DbType, and the size. + + The m_Name of the parameter to map. + One of the DbType values. + The length of the parameter. + + + + Initializes a new instance of the NpgsqlParameter + class with the parameter m_Name, the DbType, the size, + and the source column m_Name. + + The m_Name of the parameter to map. + One of the DbType values. + The length of the parameter. + The m_Name of the source column. + + + + Initializes a new instance of the NpgsqlParameter + class with the parameter m_Name, the DbType, the size, + the source column m_Name, a ParameterDirection, + the precision of the parameter, the scale of the parameter, a + DataRowVersion to use, and the + value of the parameter. + + The m_Name of the parameter to map. + One of the DbType values. + The length of the parameter. + The m_Name of the source column. + One of the ParameterDirection values. + true if the value of the field can be null, otherwise false. + The total number of digits to the left and right of the decimal point to which + Value is resolved. + The total number of decimal places to which + Value is resolved. + One of the DataRowVersion values. + An Object that is the value + of the NpgsqlParameter. + + + + Creates a new NpgsqlParameter that + is a copy of the current instance. + + A new NpgsqlParameter that is a copy of this instance. + + + + The collection to which this parameter belongs, if any. + + + + + Gets or sets the maximum number of digits used to represent the + Value property. + + The maximum number of digits used to represent the + Value property. + The default value is 0, which indicates that the data provider + sets the precision for Value. + + + + Gets or sets the number of decimal places to which + Value is resolved. + + The number of decimal places to which + Value is resolved. The default is 0. + + + + Gets or sets the maximum size, in bytes, of the data within the column. + + The maximum size, in bytes, of the data within the column. + The default value is inferred from the parameter value. + + + + Gets or sets the DbType of the parameter. + + One of the DbType values. The default is String. + + + + Gets or sets the DbType of the parameter. + + One of the DbType values. The default is String. + + + + Gets or sets a value indicating whether the parameter is input-only, + output-only, bidirectional, or a stored procedure return value parameter. + + One of the ParameterDirection + values. The default is Input. + + + + Gets or sets a value indicating whether the parameter accepts null values. + + true if null values are accepted; otherwise, false. The default is false. + + + + Gets or sets the m_Name of the NpgsqlParameter. + + The m_Name of the NpgsqlParameter. + The default is an empty string. + + + + The m_Name scrubbed of any optional marker + + + + + Gets or sets the m_Name of the source column that is mapped to the + DataSet and used for loading or + returning the Value. + + The m_Name of the source column that is mapped to the + DataSet. The default is an empty string. + + + + Gets or sets the DataRowVersion + to use when loading Value. + + One of the DataRowVersion values. + The default is Current. + + + + Gets or sets the value of the parameter. + + An Object that is the value of the parameter. + The default value is null. + + + + Gets or sets the value of the parameter. + + An Object that is the value of the parameter. + The default value is null. + Represents a collection of parameters relevant to a NpgsqlCommand @@ -3866,6 +5038,12 @@ Initializes a new instance of the NpgsqlParameterCollection class. + + + Invalidate the hash lookup tables. This should be done any time a change + may throw the lookups out of sync with the list. + + Adds the specified NpgsqlParameter object to the NpgsqlParameterCollection. @@ -3875,11 +5053,8 @@ - Adds a NpgsqlParameter to the NpgsqlParameterCollection given the specified parameter name and value. + Obsolete. Use AddWithValue instead. - The name of the NpgsqlParameter. - The Value of the NpgsqlParameter to add to the collection. - The index of the new NpgsqlParameter object. Use caution when using this overload of the Add method to specify integer parameter values. @@ -3891,6 +5066,44 @@ are attempting to call the NpgsqlParameterCollection.Add(string, DbType) overload. + + + Adds a NpgsqlParameter to the NpgsqlParameterCollection given the specified parameter name and value. + + The name of the NpgsqlParameter. + The Value of the NpgsqlParameter to add to the collection. + The paramater that was added. + + + + Adds a NpgsqlParameter to the NpgsqlParameterCollection given the specified parameter name and value. + + The name of the NpgsqlParameter. + The Value of the NpgsqlParameter to add to the collection. + One of the NpgsqlDbType values. + The paramater that was added. + + + + Adds a NpgsqlParameter to the NpgsqlParameterCollection given the specified parameter name and value. + + The name of the NpgsqlParameter. + The Value of the NpgsqlParameter to add to the collection. + One of the NpgsqlDbType values. + The length of the column. + The paramater that was added. + + + + Adds a NpgsqlParameter to the NpgsqlParameterCollection given the specified parameter name and value. + + The name of the NpgsqlParameter. + The Value of the NpgsqlParameter to add to the collection. + One of the NpgsqlDbType values. + The length of the column. + The name of the source column. + The paramater that was added. + Adds a NpgsqlParameter to the NpgsqlParameterCollection given the parameter name and the data type. @@ -3949,13 +5162,19 @@ Inserts a NpgsqlParameter into the collection at the specified index. The zero-based index where the parameter is to be inserted within the collection. - The NpgsqlParameter to add to the collection. + The NpgsqlParameter to add to the collection. + + + + Removes the specified NpgsqlParameter from the collection. + + The name of the NpgsqlParameter to remove from the collection. Removes the specified NpgsqlParameter from the collection. - The NpgsqlParameter to remove from the collection. + The NpgsqlParameter to remove from the collection. @@ -4031,84 +5250,19 @@ The number of NpgsqlParameter objects in the collection. - - - Represents an ongoing COPY FROM STDIN operation. - Provides methods to push data to server and end or cancel the operation. - - - - - Called from NpgsqlState.ProcessBackendResponses upon CopyInResponse. - If CopyStream is already set, it is used to read data to push to server, after which the copy is completed. - Otherwise CopyStream is set to a writable NpgsqlCopyInStream that calls SendCopyData each time it is written to. - - - - - Sends given packet to server as a CopyData message. - Does not check for notifications! Use another thread for that. - - - - - Sends CopyDone message to server. Handles responses, ie. may throw an exception. - - - - - Sends CopyFail message to server. Handles responses, ie. should always throw an exception: - in CopyIn state the server responds to CopyFail with an error response; - outside of a CopyIn state the server responds to CopyFail with an error response; - without network connection or whatever, there's going to eventually be a failure, timeout or user intervention. - - - - - Copy format information returned from server. - - - - - Represents a PostgreSQL Point type - - - - - Represents a PostgreSQL Line Segment type. - - - - - Represents a PostgreSQL Path type. - - - - - Represents a PostgreSQL Polygon type. - - - - - Represents a PostgreSQL Circle type. - - - - - Represents a PostgreSQL inet type. - - - - - Represents a PostgreSQL MacAddress type. - - - - + + + This class represents the ParameterStatus message sent from PostgreSQL + server. + + + + + + This class represents the Parse message sent to PostgreSQL + server. + - - The macAddr parameter must contain a string that can only consist of numbers - and upper-case letters as hexadecimal digits. (See PhysicalAddress.Parse method on MSDN) @@ -4116,5 +5270,351 @@ PostgreSQL. + + + Used when a connection is closed + + + + + Summary description for NpgsqlQuery + + + + + This is the abstract base class for NpgsqlAsciiRow and NpgsqlBinaryRow. + + + + + This class represents a RowDescription message sent from + the PostgreSQL. + + + + + + This struct represents the internal data of the RowDescription message. + + + + + Provides the underlying mechanism for reading schema information. + + + + + Returns the MetaDataCollections that lists all possible collections. + + The MetaDataCollections + + + + Returns the Restrictions that contains the meaning and position of the values in the restrictions array. + + The Restrictions + + + + Returns the Databases that contains a list of all accessable databases. + + The database connection on which to run the metadataquery. + The restrictions to filter the collection. + The Databases + + + + Returns the Tables that contains table and view names and the database and schema they come from. + + The database connection on which to run the metadataquery. + The restrictions to filter the collection. + The Tables + + + + Returns the Columns that contains information about columns in tables. + + The database connection on which to run the metadataquery. + The restrictions to filter the collection. + The Columns. + + + + Returns the Views that contains view names and the database and schema they come from. + + The database connection on which to run the metadataquery. + The restrictions to filter the collection. + The Views + + + + Returns the Users containing user names and the sysid of those users. + + The database connection on which to run the metadataquery. + The restrictions to filter the collection. + The Users. + + + + This class represents a StartupPacket message of PostgreSQL + protocol. + + + + + + Represents a completed response message. + + + + + This class represents the Sync message sent to PostgreSQL + server. + + + + + + Represents a transaction to be made in a PostgreSQL database. This class cannot be inherited. + + + + + Commits the database transaction. + + + + + Rolls back a transaction from a pending state. + + + + + Rolls back a transaction from a pending savepoint state. + + + + + Creates a transaction save point. + + + + + Cancel the transaction without telling the backend about it. This is + used to make the transaction go away when closing a connection. + + + + + Gets the NpgsqlConnection + object associated with the transaction, or a null reference if the + transaction is no longer valid. + + The NpgsqlConnection + object associated with the transaction. + + + + Specifies the IsolationLevel for this transaction. + + The IsolationLevel for this transaction. + The default is ReadCommitted. + + + + This class provides many util methods to handle + reading and writing of PostgreSQL protocol messages. + + + + + This method takes a ProtocolVersion and returns an integer + version number that the Postgres backend will recognize in a + startup packet. + + + + + This method takes a version string as returned by SELECT VERSION() and returns + a valid version string ("7.2.2" for example). + This is only needed when running protocol version 2. + This does not do any validity checks. + + + + + This method gets a C NULL terminated string from the network stream. + It keeps reading a byte in each time until a NULL byte is returned. + It returns the resultant string of bytes read. + This string is sent from backend. + + + + + Reads requested number of bytes from stream with retries until Stream.Read returns 0 or count is reached. + + Stream to read + byte buffer to fill + starting position to fill the buffer + number of bytes to read + The number of bytes read. May be less than count if no more bytes are available. + + + + Reads requested number of bytes from . If output matches exactly, and == false, is returned directly. + + Source array. + Starting position to read from + Number of bytes to read + Force a copy, even if the output is an exact copy of . + byte[] containing data requested. + + + + This method writes a string to the network stream. + + + + + This method writes a string to the network stream. + + + + + This method writes a C NULL terminated string to the network stream. + It appends a NULL terminator to the end of the String. + + + + + This method writes a C NULL terminated string to the network stream. + It appends a NULL terminator to the end of the String. + + + + + This method writes a byte to the stream. It also enables logging of them. + + + + + This method writes a byte to the stream. It also enables logging of them. + + + + + This method writes a set of bytes to the stream. It also enables logging of them. + + + + + This method writes a set of bytes to the stream. It also enables logging of them. + + + + + This method writes a C NULL terminated string limited in length to the + backend server. + It pads the string with null bytes to the size specified. + + + + + This method writes a C NULL terminated byte[] limited in length to the + backend server. + It pads the string with null bytes to the size specified. + + + + + Write a 32-bit integer to the given stream in the correct byte order. + + + + + Read a 32-bit integer from the given stream in the correct byte order. + + + + + Read a 32-bit integer from the given array in the correct byte order. + + + + + Write a 16-bit integer to the given stream in the correct byte order. + + + + + Read a 16-bit integer from the given stream in the correct byte order. + + + + + Read a 16-bit integer from the given array in the correct byte order. + + + + + Copy and possibly reverse a byte array, depending on host architecture endienness. + + Source byte array. + Force a copy even if no swap is performed. + , reversed if on a little-endian architecture, copied if required. + + + + Copy and possibly reverse a byte array, depending on host architecture endienness. + + Source byte array. + Starting offset in source array. + Number of bytes to copy. + Force a copy even if no swap is performed. + , reversed if on a little-endian architecture, copied if required. + + + + Represent the frontend/backend protocol version. + + + + + Represent the backend server version. + As this class offers no functionality beyond that offered by it has been + deprecated in favour of that class. + + + + + + Returns the string representation of this version in three place dot notation (Major.Minor.Patch). + + + + + Server version major number. + + + + + Server version minor number. + + + + + Server version patch level number. + + + + + A class to handle everything associated with SSPI authentication + + + + + Simplified SecBufferDesc struct with only one SecBuffer + + diff --git a/bin/OpenMetaverse.Rendering.Meshmerizer.dll b/bin/OpenMetaverse.Rendering.Meshmerizer.dll index 1a12a1e774..f047f58df6 100755 Binary files a/bin/OpenMetaverse.Rendering.Meshmerizer.dll and b/bin/OpenMetaverse.Rendering.Meshmerizer.dll differ diff --git a/bin/OpenMetaverse.StructuredData.XML b/bin/OpenMetaverse.StructuredData.XML deleted file mode 100644 index 8f0dd817a3..0000000000 --- a/bin/OpenMetaverse.StructuredData.XML +++ /dev/null @@ -1,349 +0,0 @@ - - - - OpenMetaverse.StructuredData - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Uses reflection to create an SDMap from all of the SD - serializable types in an object - - Class or struct containing serializable types - An SDMap holding the serialized values from the - container object - - - - Uses reflection to deserialize member variables in an object from - an SDMap - - Reference to an object to fill with deserialized - values - Serialized values to put in the target - object - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Deserializes binary LLSD - - Serialized data - OSD containting deserialized data - - - - Deserializes binary LLSD - - Stream to read the data from - OSD containting deserialized data - - - - Serializes OSD to binary format. It does no prepend header - - OSD to serialize - Serialized data - - - - Serializes OSD to binary format - - OSD to serialize - - Serialized data - - - - Serializes OSD to binary format. It does no prepend header - - OSD to serialize - Serialized data - - - - Serializes OSD to binary format - - OSD to serialize - - Serialized data - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/bin/OpenMetaverse.StructuredData.dll b/bin/OpenMetaverse.StructuredData.dll index 7aeb0894f2..62aecd4144 100755 Binary files a/bin/OpenMetaverse.StructuredData.dll and b/bin/OpenMetaverse.StructuredData.dll differ diff --git a/bin/OpenMetaverse.XML b/bin/OpenMetaverse.XML deleted file mode 100644 index ce8ca8678a..0000000000 --- a/bin/OpenMetaverse.XML +++ /dev/null @@ -1,36656 +0,0 @@ - - - - OpenMetaverse - - - - - Permission request flags, asked when a script wants to control an Avatar - - - - Placeholder for empty values, shouldn't ever see this - - - Script wants ability to take money from you - - - Script wants to take camera controls for you - - - Script wants to remap avatars controls - - - Script wants to trigger avatar animations - This function is not implemented on the grid - - - Script wants to attach or detach the prim or primset to your avatar - - - Script wants permission to release ownership - This function is not implemented on the grid - The concept of "public" objects does not exist anymore. - - - Script wants ability to link/delink with other prims - - - Script wants permission to change joints - This function is not implemented on the grid - - - Script wants permissions to change permissions - This function is not implemented on the grid - - - Script wants to track avatars camera position and rotation - - - Script wants to control your camera - - - Script wants the ability to teleport you - - - - Special commands used in Instant Messages - - - - Indicates a regular IM from another agent - - - Simple notification box with an OK button - - - You've been invited to join a group. - - - Inventory offer - - - Accepted inventory offer - - - Declined inventory offer - - - Group vote - - - An object is offering its inventory - - - Accept an inventory offer from an object - - - Decline an inventory offer from an object - - - Unknown - - - Start a session, or add users to a session - - - Start a session, but don't prune offline users - - - Start a session with your group - - - Start a session without a calling card (finder or objects) - - - Send a message to a session - - - Leave a session - - - Indicates that the IM is from an object - - - Sent an IM to a busy user, this is the auto response - - - Shows the message in the console and chat history - - - Send a teleport lure - - - Response sent to the agent which inititiated a teleport invitation - - - Response sent to the agent which inititiated a teleport invitation - - - Only useful if you have Linden permissions - - - Request a teleport lure - - - IM to tell the user to go to an URL - - - IM for help - - - IM sent automatically on call for help, sends a lure - to each Helper reached - - - Like an IM but won't go to email - - - IM from a group officer to all group members - - - Unknown - - - Unknown - - - Accept a group invitation - - - Decline a group invitation - - - Unknown - - - An avatar is offering you friendship - - - An avatar has accepted your friendship offer - - - An avatar has declined your friendship offer - - - Indicates that a user has started typing - - - Indicates that a user has stopped typing - - - - Flag in Instant Messages, whether the IM should be delivered to - offline avatars as well - - - - Only deliver to online avatars - - - If the avatar is offline the message will be held until - they login next, and possibly forwarded to their e-mail account - - - - Conversion type to denote Chat Packet types in an easier-to-understand format - - - - Whisper (5m radius) - - - Normal chat (10/20m radius), what the official viewer typically sends - - - Shouting! (100m radius) - - - Event message when an Avatar has begun to type - - - Event message when an Avatar has stopped typing - - - Send the message to the debug channel - - - Event message when an object uses llOwnerSay - - - Event message when an object uses llRegionSayTo - - - Special value to support llRegionSay, never sent to the client - - - - Identifies the source of a chat message - - - - Chat from the grid or simulator - - - Chat from another avatar - - - Chat from an object - - - - - - - - - - - - - - - - - - Effect type used in ViewerEffect packets - - - - - - - - - - - - - - - - - - - - - - - - - Project a beam from a source to a destination, such as - the one used when editing an object - - - - - - - - - - - - Create a swirl of particles around an object - - - - - - - - - Cause an avatar to look at an object - - - Cause an avatar to point at an object - - - - The action an avatar is doing when looking at something, used in - ViewerEffect packets for the LookAt effect - - - - - - - - - - - - - - - - - - - - - - Deprecated - - - - - - - - - - - - - - - - The action an avatar is doing when pointing at something, used in - ViewerEffect packets for the PointAt effect - - - - - - - - - - - - - - - - - Money transaction types - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Flags sent when a script takes or releases a control - - NOTE: (need to verify) These might be a subset of the ControlFlags enum in Movement, - - - No Flags set - - - Forward (W or up Arrow) - - - Back (S or down arrow) - - - Move left (shift+A or left arrow) - - - Move right (shift+D or right arrow) - - - Up (E or PgUp) - - - Down (C or PgDown) - - - Rotate left (A or left arrow) - - - Rotate right (D or right arrow) - - - Left Mouse Button - - - Left Mouse button in MouseLook - - - - Currently only used to hide your group title - - - - No flags set - - - Hide your group title - - - - Action state of the avatar, which can currently be typing and - editing - - - - - - - - - - - - - - Current teleport status - - - - Unknown status - - - Teleport initialized - - - Teleport in progress - - - Teleport failed - - - Teleport completed - - - Teleport cancelled - - - - - - - - No flags set, or teleport failed - - - Set when newbie leaves help island for first time - - - - - - Via Lure - - - Via Landmark - - - Via Location - - - Via Home - - - Via Telehub - - - Via Login - - - Linden Summoned - - - Linden Forced me - - - - - - Agent Teleported Home via Script - - - - - - - - - - - - forced to new location for example when avatar is banned or ejected - - - Teleport Finished via a Lure - - - Finished, Sim Changed - - - Finished, Same Sim - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Type of mute entry - - - - Object muted by name - - - Muted residet - - - Object muted by UUID - - - Muted group - - - Muted external entry - - - - Flags of mute entry - - - - No exceptions - - - Don't mute text chat - - - Don't mute voice chat - - - Don't mute particles - - - Don't mute sounds - - - Don't mute - - - - Instant Message - - - - Key of sender - - - Name of sender - - - Key of destination avatar - - - ID of originating estate - - - Key of originating region - - - Coordinates in originating region - - - Instant message type - - - Group IM session toggle - - - Key of IM session, for Group Messages, the groups UUID - - - Timestamp of the instant message - - - Instant message text - - - Whether this message is held for offline avatars - - - Context specific packed data - - - Print the struct data as a string - A string containing the field name, and field value - - - Represents muted object or resident - - - Type of the mute entry - - - UUID of the mute etnry - - - Mute entry name - - - Mute flags - - - Transaction detail sent with MoneyBalanceReply message - - - Type of the transaction - - - UUID of the transaction source - - - Is the transaction source a group - - - UUID of the transaction destination - - - Is transaction destination a group - - - Transaction amount - - - Transaction description - - - - Manager class for our own avatar - - - - - Called once attachment resource usage information has been collected - - Indicates if operation was successfull - Attachment resource usage information - - - The event subscribers. null if no subcribers - - - Raises the ChatFromSimulator event - A ChatEventArgs object containing the - data returned from the data server - - - Thread sync lock object - - - Raised when a scripted object or agent within range sends a public message - - - The event subscribers. null if no subcribers - - - Raises the ScriptDialog event - A SctriptDialogEventArgs object containing the - data returned from the data server - - - Thread sync lock object - - - Raised when a scripted object sends a dialog box containing possible - options an agent can respond to - - - The event subscribers. null if no subcribers - - - Raises the ScriptQuestion event - A ScriptQuestionEventArgs object containing the - data returned from the data server - - - Thread sync lock object - - - Raised when an object requests a change in the permissions an agent has permitted - - - The event subscribers. null if no subcribers - - - Raises the LoadURL event - A LoadUrlEventArgs object containing the - data returned from the data server - - - Thread sync lock object - - - Raised when a script requests an agent open the specified URL - - - The event subscribers. null if no subcribers - - - Raises the MoneyBalance event - A BalanceEventArgs object containing the - data returned from the data server - - - Thread sync lock object - - - Raised when an agents currency balance is updated - - - The event subscribers. null if no subcribers - - - Raises the MoneyBalanceReply event - A MoneyBalanceReplyEventArgs object containing the - data returned from the data server - - - Thread sync lock object - - - Raised when a transaction occurs involving currency such as a land purchase - - - The event subscribers. null if no subcribers - - - Raises the IM event - A InstantMessageEventArgs object containing the - data returned from the data server - - - Thread sync lock object - - - Raised when an ImprovedInstantMessage packet is recieved from the simulator, this is used for everything from - private messaging to friendship offers. The Dialog field defines what type of message has arrived - - - The event subscribers. null if no subcribers - - - Raises the TeleportProgress event - A TeleportEventArgs object containing the - data returned from the data server - - - Thread sync lock object - - - Raised when an agent has requested a teleport to another location, or when responding to a lure. Raised multiple times - for each teleport indicating the progress of the request - - - The event subscribers. null if no subcribers - - - Raises the AgentDataReply event - A AgentDataReplyEventArgs object containing the - data returned from the data server - - - Thread sync lock object - - - Raised when a simulator sends agent specific information for our avatar. - - - The event subscribers. null if no subcribers - - - Raises the AnimationsChanged event - A AnimationsChangedEventArgs object containing the - data returned from the data server - - - Thread sync lock object - - - Raised when our agents animation playlist changes - - - The event subscribers. null if no subcribers - - - Raises the MeanCollision event - A MeanCollisionEventArgs object containing the - data returned from the data server - - - Thread sync lock object - - - Raised when an object or avatar forcefully collides with our agent - - - The event subscribers. null if no subcribers - - - Raises the RegionCrossed event - A RegionCrossedEventArgs object containing the - data returned from the data server - - - Thread sync lock object - - - Raised when our agent crosses a region border into another region - - - The event subscribers. null if no subcribers - - - Raises the GroupChatJoined event - A GroupChatJoinedEventArgs object containing the - data returned from the data server - - - Thread sync lock object - - - Raised when our agent succeeds or fails to join a group chat session - - - The event subscribers. null if no subcribers - - - Raises the AlertMessage event - A AlertMessageEventArgs object containing the - data returned from the data server - - - Thread sync lock object - - - Raised when a simulator sends an urgent message usually indication the recent failure of - another action we have attempted to take such as an attempt to enter a parcel where we are denied access - - - The event subscribers. null if no subcribers - - - Raises the ScriptControlChange event - A ScriptControlEventArgs object containing the - data returned from the data server - - - Thread sync lock object - - - Raised when a script attempts to take or release specified controls for our agent - - - The event subscribers. null if no subcribers - - - Raises the CameraConstraint event - A CameraConstraintEventArgs object containing the - data returned from the data server - - - Thread sync lock object - - - Raised when the simulator detects our agent is trying to view something - beyond its limits - - - The event subscribers. null if no subcribers - - - Raises the ScriptSensorReply event - A ScriptSensorReplyEventArgs object containing the - data returned from the data server - - - Thread sync lock object - - - Raised when a script sensor reply is received from a simulator - - - The event subscribers. null if no subcribers - - - Raises the AvatarSitResponse event - A AvatarSitResponseEventArgs object containing the - data returned from the data server - - - Thread sync lock object - - - Raised in response to a request - - - The event subscribers. null if no subcribers - - - Raises the ChatSessionMemberAdded event - A ChatSessionMemberAddedEventArgs object containing the - data returned from the data server - - - Thread sync lock object - - - Raised when an avatar enters a group chat session we are participating in - - - The event subscribers. null if no subcribers - - - Raises the ChatSessionMemberLeft event - A ChatSessionMemberLeftEventArgs object containing the - data returned from the data server - - - Thread sync lock object - - - Raised when an agent exits a group chat session we are participating in - - - The event subscribers, null of no subscribers - - - Raises the SetDisplayNameReply Event - A SetDisplayNameReplyEventArgs object containing - the data sent from the simulator - - - Thread sync lock object - - - Raised when the simulator sends us data containing - the details of display name change - - - The event subscribers. null if no subcribers - - - Raises the MuteListUpdated event - A EventArgs object containing the - data returned from the data server - - - Thread sync lock object - - - Raised when a scripted object or agent within range sends a public message - - - Reference to the GridClient instance - - - Used for movement and camera tracking - - - Currently playing animations for the agent. Can be used to - check the current movement status such as walking, hovering, aiming, - etc. by checking against system animations found in the Animations class - - - Dictionary containing current Group Chat sessions and members - - - Dictionary containing mute list keyead on mute name and key - - - Your (client) avatars - "client", "agent", and "avatar" all represent the same thing - - - Temporary assigned to this session, used for - verifying our identity in packets - - - Shared secret that is never sent over the wire - - - Your (client) avatar ID, local to the current region/sim - - - Where the avatar started at login. Can be "last", "home" - or a login - - - The access level of this agent, usually M, PG or A - - - The CollisionPlane of Agent - - - An representing the velocity of our agent - - - An representing the acceleration of our agent - - - A which specifies the angular speed, and axis about which an Avatar is rotating. - - - Position avatar client will goto when login to 'home' or during - teleport request to 'home' region. - - - LookAt point saved/restored with HomePosition - - - Avatar First Name (i.e. Philip) - - - Avatar Last Name (i.e. Linden) - - - LookAt point received with the login response message - - - Avatar Full Name (i.e. Philip Linden) - - - Gets the health of the agent - - - Gets the current balance of the agent - - - Gets the local ID of the prim the agent is sitting on, - zero if the avatar is not currently sitting - - - Gets the of the agents active group. - - - Gets the Agents powers in the currently active group - - - Current status message for teleporting - - - Current position of the agent as a relative offset from - the simulator, or the parent object if we are sitting on something - - - Current rotation of the agent as a relative rotation from - the simulator, or the parent object if we are sitting on something - - - Current position of the agent in the simulator - - - - A representing the agents current rotation - - - - Returns the global grid position of the avatar - - - Various abilities and preferences sent by the grid - - - - Constructor, setup callbacks for packets related to our avatar - - A reference to the Class - - - - Send a text message from the Agent to the Simulator - - A containing the message - The channel to send the message on, 0 is the public channel. Channels above 0 - can be used however only scripts listening on the specified channel will see the message - Denotes the type of message being sent, shout, whisper, etc. - - - - Request any instant messages sent while the client was offline to be resent. - - - - - Send an Instant Message to another Avatar - - The recipients - A containing the message to send - - - - Send an Instant Message to an existing group chat or conference chat - - The recipients - A containing the message to send - IM session ID (to differentiate between IM windows) - - - - Send an Instant Message - - The name this IM will show up as being from - Key of Avatar - Text message being sent - IM session ID (to differentiate between IM windows) - IDs of sessions for a conference - - - - Send an Instant Message - - The name this IM will show up as being from - Key of Avatar - Text message being sent - IM session ID (to differentiate between IM windows) - Type of instant message to send - Whether to IM offline avatars as well - Senders Position - RegionID Sender is In - Packed binary data that is specific to - the dialog type - - - - Send an Instant Message to a group - - of the group to send message to - Text Message being sent. - - - - Send an Instant Message to a group the agent is a member of - - The name this IM will show up as being from - of the group to send message to - Text message being sent - - - - Send a request to join a group chat session - - of Group to leave - - - - Exit a group chat session. This will stop further Group chat messages - from being sent until session is rejoined. - - of Group chat session to leave - - - - Reply to script dialog questions. - - Channel initial request came on - Index of button you're "clicking" - Label of button you're "clicking" - of Object that sent the dialog request - - - - - Accept invite for to a chatterbox session - - of session to accept invite to - - - - Start a friends conference - - List of UUIDs to start a conference with - the temportary session ID returned in the callback> - - - - Start a particle stream between an agent and an object - - Key of the source agent - Key of the target object - - The type from the enum - A unique for this effect - - - - Start a particle stream between an agent and an object - - Key of the source agent - Key of the target object - A representing the beams offset from the source - A which sets the avatars lookat animation - of the Effect - - - - Create a particle beam between an avatar and an primitive - - The ID of source avatar - The ID of the target primitive - global offset - A object containing the combined red, green, blue and alpha - color values of particle beam - a float representing the duration the parcicle beam will last - A Unique ID for the beam - - - - - Create a particle swirl around a target position using a packet - - global offset - A object containing the combined red, green, blue and alpha - color values of particle beam - a float representing the duration the parcicle beam will last - A Unique ID for the beam - - - - Sends a request to sit on the specified object - - of the object to sit on - Sit at offset - - - - Follows a call to to actually sit on the object - - - - Stands up from sitting on a prim or the ground - true of AgentUpdate was sent - - - - Does a "ground sit" at the avatar's current position - - - - - Starts or stops flying - - True to start flying, false to stop flying - - - - Starts or stops crouching - - True to start crouching, false to stop crouching - - - - Starts a jump (begin holding the jump key) - - - - - Use the autopilot sim function to move the avatar to a new - position. Uses double precision to get precise movements - - The z value is currently not handled properly by the simulator - Global X coordinate to move to - Global Y coordinate to move to - Z coordinate to move to - - - - Use the autopilot sim function to move the avatar to a new position - - The z value is currently not handled properly by the simulator - Integer value for the global X coordinate to move to - Integer value for the global Y coordinate to move to - Floating-point value for the Z coordinate to move to - - - - Use the autopilot sim function to move the avatar to a new position - - The z value is currently not handled properly by the simulator - Integer value for the local X coordinate to move to - Integer value for the local Y coordinate to move to - Floating-point value for the Z coordinate to move to - - - Macro to cancel autopilot sim function - Not certain if this is how it is really done - true if control flags were set and AgentUpdate was sent to the simulator - - - - Grabs an object - - an unsigned integer of the objects ID within the simulator - - - - - Overload: Grab a simulated object - - an unsigned integer of the objects ID within the simulator - - The texture coordinates to grab - The surface coordinates to grab - The face of the position to grab - The region coordinates of the position to grab - The surface normal of the position to grab (A normal is a vector perpindicular to the surface) - The surface binormal of the position to grab (A binormal is a vector tangen to the surface - pointing along the U direction of the tangent space - - - - Drag an object - - of the object to drag - Drag target in region coordinates - - - - Overload: Drag an object - - of the object to drag - Drag target in region coordinates - - The texture coordinates to grab - The surface coordinates to grab - The face of the position to grab - The region coordinates of the position to grab - The surface normal of the position to grab (A normal is a vector perpindicular to the surface) - The surface binormal of the position to grab (A binormal is a vector tangen to the surface - pointing along the U direction of the tangent space - - - - Release a grabbed object - - The Objects Simulator Local ID - - - - - - - Release a grabbed object - - The Objects Simulator Local ID - The texture coordinates to grab - The surface coordinates to grab - The face of the position to grab - The region coordinates of the position to grab - The surface normal of the position to grab (A normal is a vector perpindicular to the surface) - The surface binormal of the position to grab (A binormal is a vector tangen to the surface - pointing along the U direction of the tangent space - - - - Touches an object - - an unsigned integer of the objects ID within the simulator - - - - - Request the current L$ balance - - - - - Give Money to destination Avatar - - UUID of the Target Avatar - Amount in L$ - - - - Give Money to destination Avatar - - UUID of the Target Avatar - Amount in L$ - Description that will show up in the - recipients transaction history - - - - Give L$ to an object - - object to give money to - amount of L$ to give - name of object - - - - Give L$ to a group - - group to give money to - amount of L$ to give - - - - Give L$ to a group - - group to give money to - amount of L$ to give - description of transaction - - - - Pay texture/animation upload fee - - - - - Pay texture/animation upload fee - - description of the transaction - - - - Give Money to destination Object or Avatar - - UUID of the Target Object/Avatar - Amount in L$ - Reason (Optional normally) - The type of transaction - Transaction flags, mostly for identifying group - transactions - - - - Plays a gesture - - Asset of the gesture - - - - Mark gesture active - - Inventory of the gesture - Asset of the gesture - - - - Mark gesture inactive - - Inventory of the gesture - - - - Send an AgentAnimation packet that toggles a single animation on - - The of the animation to start playing - Whether to ensure delivery of this packet or not - - - - Send an AgentAnimation packet that toggles a single animation off - - The of a - currently playing animation to stop playing - Whether to ensure delivery of this packet or not - - - - Send an AgentAnimation packet that will toggle animations on or off - - A list of animation s, and whether to - turn that animation on or off - Whether to ensure delivery of this packet or not - - - - Teleports agent to their stored home location - - true on successful teleport to home location - - - - Teleport agent to a landmark - - of the landmark to teleport agent to - true on success, false on failure - - - - Attempt to look up a simulator name and teleport to the discovered - destination - - Region name to look up - Position to teleport to - True if the lookup and teleport were successful, otherwise - false - - - - Attempt to look up a simulator name and teleport to the discovered - destination - - Region name to look up - Position to teleport to - Target to look at - True if the lookup and teleport were successful, otherwise - false - - - - Teleport agent to another region - - handle of region to teleport agent to - position in destination sim to teleport to - true on success, false on failure - This call is blocking - - - - Teleport agent to another region - - handle of region to teleport agent to - position in destination sim to teleport to - direction in destination sim agent will look at - true on success, false on failure - This call is blocking - - - - Request teleport to a another simulator - - handle of region to teleport agent to - position in destination sim to teleport to - - - - Request teleport to a another simulator - - handle of region to teleport agent to - position in destination sim to teleport to - direction in destination sim agent will look at - - - - Teleport agent to a landmark - - of the landmark to teleport agent to - - - - Send a teleport lure to another avatar with default "Join me in ..." invitation message - - target avatars to lure - - - - Send a teleport lure to another avatar with custom invitation message - - target avatars to lure - custom message to send with invitation - - - - Respond to a teleport lure by either accepting it and initiating - the teleport, or denying it - - of the avatar sending the lure - IM session of the incoming lure request - true to accept the lure, false to decline it - - - - Update agent profile - - struct containing updated - profile information - - - - Update agents profile interests - - selection of interests from struct - - - - Set the height and the width of the client window. This is used - by the server to build a virtual camera frustum for our avatar - - New height of the viewer window - New width of the viewer window - - - - Request the list of muted objects and avatars for this agent - - - - - Mute an object, resident, etc. - - Mute type - Mute UUID - Mute name - - - - Mute an object, resident, etc. - - Mute type - Mute UUID - Mute name - Mute flags - - - - Unmute an object, resident, etc. - - Mute UUID - Mute name - - - - Sets home location to agents current position - - will fire an AlertMessage () with - success or failure message - - - - Move an agent in to a simulator. This packet is the last packet - needed to complete the transition in to a new simulator - - Object - - - - Reply to script permissions request - - Object - of the itemID requesting permissions - of the taskID requesting permissions - list of permissions to allow - - - - Respond to a group invitation by either accepting or denying it - - UUID of the group (sent in the AgentID field of the invite message) - IM Session ID from the group invitation message - Accept the group invitation or deny it - - - - Requests script detection of objects and avatars - - name of the object/avatar to search for - UUID of the object or avatar to search for - Type of search from ScriptSensorTypeFlags - range of scan (96 max?) - the arc in radians to search within - an user generated ID to correlate replies with - Simulator to perform search in - - - - Create or update profile pick - - UUID of the pick to update, or random UUID to create a new pick - Is this a top pick? (typically false) - UUID of the parcel (UUID.Zero for the current parcel) - Name of the pick - Global position of the pick landmark - UUID of the image displayed with the pick - Long description of the pick - - - - Delete profile pick - - UUID of the pick to delete - - - - Create or update profile Classified - - UUID of the classified to update, or random UUID to create a new classified - Defines what catagory the classified is in - UUID of the image displayed with the classified - Price that the classified will cost to place for a week - Global position of the classified landmark - Name of the classified - Long description of the classified - if true, auto renew classified after expiration - - - - Create or update profile Classified - - UUID of the classified to update, or random UUID to create a new classified - Defines what catagory the classified is in - UUID of the image displayed with the classified - Price that the classified will cost to place for a week - Name of the classified - Long description of the classified - if true, auto renew classified after expiration - - - - Delete a classified ad - - The classified ads ID - - - - Fetches resource usage by agents attachmetns - - Called when the requested information is collected - - - - Initates request to set a new display name - - Previous display name - Desired new display name - - - - Tells the sim what UI language is used, and if it's ok to share that with scripts - - Two letter language code - Share language info with scripts - - - - Sets agents maturity access level - - PG, M or A - - - - Sets agents maturity access level - - PG, M or A - Callback function - - - - Take an incoming ImprovedInstantMessage packet, auto-parse, and if - OnInstantMessage is defined call that with the appropriate arguments - - The sender - The EventArgs object containing the packet data - - - - Take an incoming Chat packet, auto-parse, and if OnChat is defined call - that with the appropriate arguments. - - The sender - The EventArgs object containing the packet data - - - - Used for parsing llDialogs - - The sender - The EventArgs object containing the packet data - - - - Used for parsing llRequestPermissions dialogs - - The sender - The EventArgs object containing the packet data - - - - Handles Script Control changes when Script with permissions releases or takes a control - - The sender - The EventArgs object containing the packet data - - - - Used for parsing llLoadURL Dialogs - - The sender - The EventArgs object containing the packet data - - - - Update client's Position, LookAt and region handle from incoming packet - - The sender - The EventArgs object containing the packet data - This occurs when after an avatar moves into a new sim - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - - EQ Message fired with the result of SetDisplayName request - - The message key - the IMessage object containing the deserialized data sent from the simulator - The which originated the packet - - - - Process TeleportFailed message sent via EventQueue, informs agent its last teleport has failed and why. - - The Message Key - An IMessage object Deserialized from the recieved message event - The simulator originating the event message - - - - Process TeleportFinish from Event Queue and pass it onto our TeleportHandler - - The message system key for this event - IMessage object containing decoded data from OSD - The simulator originating the event message - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - - Crossed region handler for message that comes across the EventQueue. Sent to an agent - when the agent crosses a sim border into a new region. - - The message key - the IMessage object containing the deserialized data sent from the simulator - The which originated the packet - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - This packet is now being sent via the EventQueue - - - - Group Chat event handler - - The capability Key - IMessage object containing decoded data from OSD - - - - - Response from request to join a group chat - - - IMessage object containing decoded data from OSD - - - - - Someone joined or left group chat - - - IMessage object containing decoded data from OSD - - - - - Handle a group chat Invitation - - Caps Key - IMessage object containing decoded data from OSD - Originating Simulator - - - - Moderate a chat session - - the of the session to moderate, for group chats this will be the groups UUID - the of the avatar to moderate - Either "voice" to moderate users voice, or "text" to moderate users text session - true to moderate (silence user), false to allow avatar to speak - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - - Agent movement and camera control - - Agent movement is controlled by setting specific - After the control flags are set, An AgentUpdate is required to update the simulator of the specified flags - This is most easily accomplished by setting one or more of the AgentMovement properties - - Movement of an avatar is always based on a compass direction, for example AtPos will move the - agent from West to East or forward on the X Axis, AtNeg will of course move agent from - East to West or backward on the X Axis, LeftPos will be South to North or forward on the Y Axis - The Z axis is Up, finer grained control of movements can be done using the Nudge properties - - - - - Camera controls for the agent, mostly a thin wrapper around - CoordinateFrame. This class is only responsible for state - tracking and math, it does not send any packets - - - - - - - The camera is a local frame of reference inside of - the larger grid space. This is where the math happens - - - - - - - - - - - - - - - - Default constructor - - - - Move agent positive along the X axis - - - Move agent negative along the X axis - - - Move agent positive along the Y axis - - - Move agent negative along the Y axis - - - Move agent positive along the Z axis - - - Move agent negative along the Z axis - - - - - - - - - - - - - - - - - - - - - - - - Causes simulator to make agent fly - - - Stop movement - - - Finish animation - - - Stand up from a sit - - - Tells simulator to sit agent on ground - - - Place agent into mouselook mode - - - Nudge agent positive along the X axis - - - Nudge agent negative along the X axis - - - Nudge agent positive along the Y axis - - - Nudge agent negative along the Y axis - - - Nudge agent positive along the Z axis - - - Nudge agent negative along the Z axis - - - - - - - - - Tell simulator to mark agent as away - - - - - - - - - - - - - - - - Returns "always run" value, or changes it by sending a SetAlwaysRunPacket - - - - The current value of the agent control flags - - - Gets or sets the interval in milliseconds at which - AgentUpdate packets are sent to the current simulator. Setting - this to a non-zero value will also enable the packet sending if - it was previously off, and setting it to zero will disable - - - Gets or sets whether AgentUpdate packets are sent to - the current simulator - - - Reset movement controls every time we send an update - - - Agent camera controls - - - Currently only used for hiding your group title - - - Action state of the avatar, which can currently be - typing and editing - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Timer for sending AgentUpdate packets - - - Default constructor - - - - Send an AgentUpdate with the camera set at the current agent - position and pointing towards the heading specified - - Camera rotation in radians - Whether to send the AgentUpdate reliable - or not - - - - Rotates the avatar body and camera toward a target position. - This will also anchor the camera position on the avatar - - Region coordinates to turn toward - - - - Rotates the avatar body and camera toward a target position. - This will also anchor the camera position on the avatar - - Region coordinates to turn toward - whether to send update or not - - - - Send new AgentUpdate packet to update our current camera - position and rotation - - - - - Send new AgentUpdate packet to update our current camera - position and rotation - - Whether to require server acknowledgement - of this packet - - - - Send new AgentUpdate packet to update our current camera - position and rotation - - Whether to require server acknowledgement - of this packet - Simulator to send the update to - - - - Builds an AgentUpdate packet entirely from parameters. This - will not touch the state of Self.Movement or - Self.Movement.Camera in any way - - - - - - - - - - - - - - - - Sends update of Field of Vision vertical angle to the simulator - - Angle in radians - - - - Used to specify movement actions for your agent - - - - Empty flag - - - Move Forward (SL Keybinding: W/Up Arrow) - - - Move Backward (SL Keybinding: S/Down Arrow) - - - Move Left (SL Keybinding: Shift-(A/Left Arrow)) - - - Move Right (SL Keybinding: Shift-(D/Right Arrow)) - - - Not Flying: Jump/Flying: Move Up (SL Keybinding: E) - - - Not Flying: Croutch/Flying: Move Down (SL Keybinding: C) - - - Unused - - - Unused - - - Unused - - - Unused - - - ORed with AGENT_CONTROL_AT_* if the keyboard is being used - - - ORed with AGENT_CONTROL_LEFT_* if the keyboard is being used - - - ORed with AGENT_CONTROL_UP_* if the keyboard is being used - - - Fly - - - - - - Finish our current animation - - - Stand up from the ground or a prim seat - - - Sit on the ground at our current location - - - Whether mouselook is currently enabled - - - Legacy, used if a key was pressed for less than a certain amount of time - - - Legacy, used if a key was pressed for less than a certain amount of time - - - Legacy, used if a key was pressed for less than a certain amount of time - - - Legacy, used if a key was pressed for less than a certain amount of time - - - Legacy, used if a key was pressed for less than a certain amount of time - - - Legacy, used if a key was pressed for less than a certain amount of time - - - - - - - - - Set when the avatar is idled or set to away. Note that the away animation is - activated separately from setting this flag - - - - - - - - - - - - - - - - Class for sending info on the success of the opration - of setting the maturity access level - - - - - New maturity accesss level returned from the sim - - - - - True if setting the new maturity access level has succedded - - - - - Creates new instance of the EventArgs class - - Has setting new maturty access level succeeded - New maturity access level as returned by the simulator - - - - - - - - Get the simulator sending the message - - - Get the message sent - - - Get the audible level of the message - - - Get the type of message sent: whisper, shout, etc - - - Get the source type of the message sender - - - Get the name of the agent or object sending the message - - - Get the ID of the agent or object sending the message - - - Get the ID of the object owner, or the agent ID sending the message - - - Get the position of the agent or object sending the message - - - - Construct a new instance of the ChatEventArgs object - - Sim from which the message originates - The message sent - The audible level of the message - The type of message sent: whisper, shout, etc - The source type of the message sender - The name of the agent or object sending the message - The ID of the agent or object sending the message - The ID of the object owner, or the agent ID sending the message - The position of the agent or object sending the message - - - Contains the data sent when a primitive opens a dialog with this agent - - - Get the dialog message - - - Get the name of the object that sent the dialog request - - - Get the ID of the image to be displayed - - - Get the ID of the primitive sending the dialog - - - Get the first name of the senders owner - - - Get the last name of the senders owner - - - Get the communication channel the dialog was sent on, responses - should also send responses on this same channel - - - Get the string labels containing the options presented in this dialog - - - UUID of the scritped object owner - - - - Construct a new instance of the ScriptDialogEventArgs - - The dialog message - The name of the object that sent the dialog request - The ID of the image to be displayed - The ID of the primitive sending the dialog - The first name of the senders owner - The last name of the senders owner - The communication channel the dialog was sent on - The string labels containing the options presented in this dialog - UUID of the scritped object owner - - - Contains the data sent when a primitive requests debit or other permissions - requesting a YES or NO answer - - - Get the simulator containing the object sending the request - - - Get the ID of the script making the request - - - Get the ID of the primitive containing the script making the request - - - Get the name of the primitive making the request - - - Get the name of the owner of the object making the request - - - Get the permissions being requested - - - - Construct a new instance of the ScriptQuestionEventArgs - - The simulator containing the object sending the request - The ID of the script making the request - The ID of the primitive containing the script making the request - The name of the primitive making the request - The name of the owner of the object making the request - The permissions being requested - - - Contains the data sent when a primitive sends a request - to an agent to open the specified URL - - - Get the name of the object sending the request - - - Get the ID of the object sending the request - - - Get the ID of the owner of the object sending the request - - - True if the object is owned by a group - - - Get the message sent with the request - - - Get the URL the object sent - - - - Construct a new instance of the LoadUrlEventArgs - - The name of the object sending the request - The ID of the object sending the request - The ID of the owner of the object sending the request - True if the object is owned by a group - The message sent with the request - The URL the object sent - - - The date received from an ImprovedInstantMessage - - - Get the InstantMessage object - - - Get the simulator where the InstantMessage origniated - - - - Construct a new instance of the InstantMessageEventArgs object - - the InstantMessage object - the simulator where the InstantMessage origniated - - - Contains the currency balance - - - - Get the currenct balance - - - - - Construct a new BalanceEventArgs object - - The currenct balance - - - Contains the transaction summary when an item is purchased, - money is given, or land is purchased - - - Get the ID of the transaction - - - True of the transaction was successful - - - Get the remaining currency balance - - - Get the meters credited - - - Get the meters comitted - - - Get the description of the transaction - - - Detailed transaction information - - - - Construct a new instance of the MoneyBalanceReplyEventArgs object - - The ID of the transaction - True of the transaction was successful - The current currency balance - The meters credited - The meters comitted - A brief description of the transaction - Transaction info - - - Data sent from the simulator containing information about your agent and active group information - - - Get the agents first name - - - Get the agents last name - - - Get the active group ID of your agent - - - Get the active groups title of your agent - - - Get the combined group powers of your agent - - - Get the active group name of your agent - - - - Construct a new instance of the AgentDataReplyEventArgs object - - The agents first name - The agents last name - The agents active group ID - The group title of the agents active group - The combined group powers the agent has in the active group - The name of the group the agent has currently active - - - Data sent by the simulator to indicate the active/changed animations - applied to your agent - - - Get the dictionary that contains the changed animations - - - - Construct a new instance of the AnimationsChangedEventArgs class - - The dictionary that contains the changed animations - - - - Data sent from a simulator indicating a collision with your agent - - - - Get the Type of collision - - - Get the ID of the agent or object that collided with your agent - - - Get the ID of the agent that was attacked - - - A value indicating the strength of the collision - - - Get the time the collision occurred - - - - Construct a new instance of the MeanCollisionEventArgs class - - The type of collision that occurred - The ID of the agent or object that perpetrated the agression - The ID of the Victim - The strength of the collision - The Time the collision occurred - - - Data sent to your agent when it crosses region boundaries - - - Get the simulator your agent just left - - - Get the simulator your agent is now in - - - - Construct a new instance of the RegionCrossedEventArgs class - - The simulator your agent just left - The simulator your agent is now in - - - Data sent from the simulator when your agent joins a group chat session - - - Get the ID of the group chat session - - - Get the name of the session - - - Get the temporary session ID used for establishing new sessions - - - True if your agent successfully joined the session - - - - Construct a new instance of the GroupChatJoinedEventArgs class - - The ID of the session - The name of the session - A temporary session id used for establishing new sessions - True of your agent successfully joined the session - - - Data sent by the simulator containing urgent messages - - - Get the alert message - - - - Construct a new instance of the AlertMessageEventArgs class - - The alert message - - - Data sent by a script requesting to take or release specified controls to your agent - - - Get the controls the script is attempting to take or release to the agent - - - True if the script is passing controls back to the agent - - - True if the script is requesting controls be released to the script - - - - Construct a new instance of the ScriptControlEventArgs class - - The controls the script is attempting to take or release to the agent - True if the script is passing controls back to the agent - True if the script is requesting controls be released to the script - - - - Data sent from the simulator to an agent to indicate its view limits - - - - Get the collision plane - - - - Construct a new instance of the CameraConstraintEventArgs class - - The collision plane - - - - Data containing script sensor requests which allow an agent to know the specific details - of a primitive sending script sensor requests - - - - Get the ID of the primitive sending the sensor - - - Get the ID of the group associated with the primitive - - - Get the name of the primitive sending the sensor - - - Get the ID of the primitive sending the sensor - - - Get the ID of the owner of the primitive sending the sensor - - - Get the position of the primitive sending the sensor - - - Get the range the primitive specified to scan - - - Get the rotation of the primitive sending the sensor - - - Get the type of sensor the primitive sent - - - Get the velocity of the primitive sending the sensor - - - - Construct a new instance of the ScriptSensorReplyEventArgs - - The ID of the primitive sending the sensor - The ID of the group associated with the primitive - The name of the primitive sending the sensor - The ID of the primitive sending the sensor - The ID of the owner of the primitive sending the sensor - The position of the primitive sending the sensor - The range the primitive specified to scan - The rotation of the primitive sending the sensor - The type of sensor the primitive sent - The velocity of the primitive sending the sensor - - - Contains the response data returned from the simulator in response to a - - - Get the ID of the primitive the agent will be sitting on - - - True if the simulator Autopilot functions were involved - - - Get the camera offset of the agent when seated - - - Get the camera eye offset of the agent when seated - - - True of the agent will be in mouselook mode when seated - - - Get the position of the agent when seated - - - Get the rotation of the agent when seated - - - Construct a new instance of the AvatarSitResponseEventArgs object - - - Data sent when an agent joins a chat session your agent is currently participating in - - - Get the ID of the chat session - - - Get the ID of the agent that joined - - - - Construct a new instance of the ChatSessionMemberAddedEventArgs object - - The ID of the chat session - The ID of the agent joining - - - Data sent when an agent exits a chat session your agent is currently participating in - - - Get the ID of the chat session - - - Get the ID of the agent that left - - - - Construct a new instance of the ChatSessionMemberLeftEventArgs object - - The ID of the chat session - The ID of the Agent that left - - - Event arguments with the result of setting display name operation - - - Status code, 200 indicates settign display name was successful - - - Textual description of the status - - - Details of the newly set display name - - - Default constructor - - - - Throttles the network traffic for various different traffic types. - Access this class through GridClient.Throttle - - - - Maximum bits per second for resending unacknowledged packets - - - Maximum bits per second for LayerData terrain - - - Maximum bits per second for LayerData wind data - - - Maximum bits per second for LayerData clouds - - - Unknown, includes object data - - - Maximum bits per second for textures - - - Maximum bits per second for downloaded assets - - - Maximum bits per second the entire connection, divided up - between invidiual streams using default multipliers - - - - Default constructor, uses a default high total of 1500 KBps (1536000) - - - - - Constructor that decodes an existing AgentThrottle packet in to - individual values - - Reference to the throttle data in an AgentThrottle - packet - Offset position to start reading at in the - throttle data - This is generally not needed in clients as the server will - never send a throttle packet to the client - - - - Send an AgentThrottle packet to the current server using the - current values - - - - - Send an AgentThrottle packet to the specified server using the - current values - - - - - Convert the current throttle values to a byte array that can be put - in an AgentThrottle packet - - Byte array containing all the throttle values - - - - Static pre-defined animations available to all agents - - - - Agent with afraid expression on face - - - Agent aiming a bazooka (right handed) - - - Agent aiming a bow (left handed) - - - Agent aiming a hand gun (right handed) - - - Agent aiming a rifle (right handed) - - - Agent with angry expression on face - - - Agent hunched over (away) - - - Agent doing a backflip - - - Agent laughing while holding belly - - - Agent blowing a kiss - - - Agent with bored expression on face - - - Agent bowing to audience - - - Agent brushing himself/herself off - - - Agent in busy mode - - - Agent clapping hands - - - Agent doing a curtsey bow - - - Agent crouching - - - Agent crouching while walking - - - Agent crying - - - Agent unanimated with arms out (e.g. setting appearance) - - - Agent re-animated after set appearance finished - - - Agent dancing - - - Agent dancing - - - Agent dancing - - - Agent dancing - - - Agent dancing - - - Agent dancing - - - Agent dancing - - - Agent dancing - - - Agent on ground unanimated - - - Agent boozing it up - - - Agent with embarassed expression on face - - - Agent with afraid expression on face - - - Agent with angry expression on face - - - Agent with bored expression on face - - - Agent crying - - - Agent showing disdain (dislike) for something - - - Agent with embarassed expression on face - - - Agent with frowning expression on face - - - Agent with kissy face - - - Agent expressing laughgter - - - Agent with open mouth - - - Agent with repulsed expression on face - - - Agent expressing sadness - - - Agent shrugging shoulders - - - Agent with a smile - - - Agent expressing surprise - - - Agent sticking tongue out - - - Agent with big toothy smile - - - Agent winking - - - Agent expressing worry - - - Agent falling down - - - Agent walking (feminine version) - - - Agent wagging finger (disapproval) - - - I'm not sure I want to know - - - Agent in superman position - - - Agent in superman position - - - Agent greeting another - - - Agent holding bazooka (right handed) - - - Agent holding a bow (left handed) - - - Agent holding a handgun (right handed) - - - Agent holding a rifle (right handed) - - - Agent throwing an object (right handed) - - - Agent in static hover - - - Agent hovering downward - - - Agent hovering upward - - - Agent being impatient - - - Agent jumping - - - Agent jumping with fervor - - - Agent point to lips then rear end - - - Agent landing from jump, finished flight, etc - - - Agent laughing - - - Agent landing from jump, finished flight, etc - - - Agent sitting on a motorcycle - - - - - - Agent moving head side to side - - - Agent moving head side to side with unhappy expression - - - Agent taunting another - - - - - - Agent giving peace sign - - - Agent pointing at self - - - Agent pointing at another - - - Agent preparing for jump (bending knees) - - - Agent punching with left hand - - - Agent punching with right hand - - - Agent acting repulsed - - - Agent trying to be Chuck Norris - - - Rocks, Paper, Scissors 1, 2, 3 - - - Agent with hand flat over other hand - - - Agent with fist over other hand - - - Agent with two fingers spread over other hand - - - Agent running - - - Agent appearing sad - - - Agent saluting - - - Agent shooting bow (left handed) - - - Agent cupping mouth as if shouting - - - Agent shrugging shoulders - - - Agent in sit position - - - Agent in sit position (feminine) - - - Agent in sit position (generic) - - - Agent sitting on ground - - - Agent sitting on ground - - - - - - Agent sleeping on side - - - Agent smoking - - - Agent inhaling smoke - - - - - - Agent taking a picture - - - Agent standing - - - Agent standing up - - - Agent standing - - - Agent standing - - - Agent standing - - - Agent standing - - - Agent stretching - - - Agent in stride (fast walk) - - - Agent surfing - - - Agent acting surprised - - - Agent striking with a sword - - - Agent talking (lips moving) - - - Agent throwing a tantrum - - - Agent throwing an object (right handed) - - - Agent trying on a shirt - - - Agent turning to the left - - - Agent turning to the right - - - Agent typing - - - Agent walking - - - Agent whispering - - - Agent whispering with fingers in mouth - - - Agent winking - - - Agent winking - - - Agent worried - - - Agent nodding yes - - - Agent nodding yes with happy face - - - Agent floating with legs and arms crossed - - - - A dictionary containing all pre-defined animations - - A dictionary containing the pre-defined animations, - where the key is the animations ID, and the value is a string - containing a name to identify the purpose of the animation - - - - Index of TextureEntry slots for avatar appearances - - - - - Bake layers for avatar appearance - - - - - Appearance Flags, introdued with server side baking, currently unused - - - - Mask for multiple attachments - - - Mapping between BakeType and AvatarTextureIndex - - - Maximum number of concurrent downloads for wearable assets and textures - - - Maximum number of concurrent uploads for baked textures - - - Timeout for fetching inventory listings - - - Timeout for fetching a single wearable, or receiving a single packet response - - - Timeout for fetching a single texture - - - Timeout for uploading a single baked texture - - - Number of times to retry bake upload - - - When changing outfit, kick off rebake after - 20 seconds has passed since the last change - - - Total number of wearables for each avatar - - - Total number of baked textures on each avatar - - - Total number of wearables per bake layer - - - Map of what wearables are included in each bake - - - Magic values to finalize the cache check hashes for each - bake - - - Default avatar texture, used to detect when a custom - texture is not set for a face - - - - Contains information about a wearable inventory item - - - - Inventory ItemID of the wearable - - - AssetID of the wearable asset - - - WearableType of the wearable - - - AssetType of the wearable - - - Asset data for the wearable - - - - Data collected from visual params for each wearable - needed for the calculation of the color - - - - - Holds a texture assetID and the data needed to bake this layer into - an outfit texture. Used to keep track of currently worn textures - and baking data - - - - A texture AssetID - - - Asset data for the texture - - - Collection of alpha masks that needs applying - - - Tint that should be applied to the texture - - - Where on avatar does this texture belong - - - The event subscribers. null if no subcribers - - - Raises the AgentWearablesReply event - An AgentWearablesReplyEventArgs object containing the - data returned from the data server - - - Thread sync lock object - - - Triggered when an AgentWearablesUpdate packet is received, - telling us what our avatar is currently wearing - request. - - - The event subscribers. null if no subcribers - - - Raises the CachedBakesReply event - An AgentCachedBakesReplyEventArgs object containing the - data returned from the data server AgentCachedTextureResponse - - - Thread sync lock object - - - Raised when an AgentCachedTextureResponse packet is - received, giving a list of cached bakes that were found on the - simulator - request. - - - The event subscribers. null if no subcribers - - - Raises the AppearanceSet event - An AppearanceSetEventArgs object indicating if the operatin was successfull - - - Thread sync lock object - - - - Raised when appearance data is sent to the simulator, also indicates - the main appearance thread is finished. - - request. - - - The event subscribers. null if no subcribers - - - Raises the RebakeAvatarRequested event - An RebakeAvatarTexturesEventArgs object containing the - data returned from the data server - - - Thread sync lock object - - - - Triggered when the simulator requests the agent rebake its appearance. - - - - - - Returns true if AppearanceManager is busy and trying to set or change appearance will fail - - - - Visual parameters last sent to the sim - - - Textures about this client sent to the sim - - - A cache of wearables currently being worn - - - A cache of textures currently being worn - - - Incrementing serial number for AgentCachedTexture packets - - - Incrementing serial number for AgentSetAppearance packets - - - Indicates if WearablesRequest succeeded - - - Indicates whether or not the appearance thread is currently - running, to prevent multiple appearance threads from running - simultaneously - - - Reference to our agent - - - - Timer used for delaying rebake on changing outfit - - - - - Main appearance thread - - - - - Is server baking complete. It needs doing only once - - - - - Default constructor - - A reference to our agent - - - - Obsolete method for setting appearance. This function no longer does anything. - Use RequestSetAppearance() to manually start the appearance thread - - - - - Obsolete method for setting appearance. This function no longer does anything. - Use RequestSetAppearance() to manually start the appearance thread - - Unused parameter - - - - Starts the appearance setting thread - - - - - Starts the appearance setting thread - - True to force rebaking, otherwise false - - - - Check if current region supports server side baking - - True if server side baking support is detected - - - - Ask the server what textures our agent is currently wearing - - - - - Build hashes out of the texture assetIDs for each baking layer to - ask the simulator whether it has cached copies of each baked texture - - - - - Returns the AssetID of the asset that is currently being worn in a - given WearableType slot - - WearableType slot to get the AssetID for - The UUID of the asset being worn in the given slot, or - UUID.Zero if no wearable is attached to the given slot or wearables - have not been downloaded yet - - - - Add a wearable to the current outfit and set appearance - - Wearable to be added to the outfit - - - - Add a wearable to the current outfit and set appearance - - Wearable to be added to the outfit - Should existing item on the same point or of the same type be replaced - - - - Add a list of wearables to the current outfit and set appearance - - List of wearable inventory items to - be added to the outfit - Should existing item on the same point or of the same type be replaced - - - - Add a list of wearables to the current outfit and set appearance - - List of wearable inventory items to - be added to the outfit - Should existing item on the same point or of the same type be replaced - - - - Remove a wearable from the current outfit and set appearance - - Wearable to be removed from the outfit - - - - Removes a list of wearables from the current outfit and set appearance - - List of wearable inventory items to - be removed from the outfit - - - - Replace the current outfit with a list of wearables and set appearance - - List of wearable inventory items that - define a new outfit - - - - Replace the current outfit with a list of wearables and set appearance - - List of wearable inventory items that - define a new outfit - Check if we have all body parts, set this to false only - if you know what you're doing - - - - Checks if an inventory item is currently being worn - - The inventory item to check against the agent - wearables - The WearableType slot that the item is being worn in, - or WearbleType.Invalid if it is not currently being worn - - - - Returns a copy of the agents currently worn wearables - - A copy of the agents currently worn wearables - Avoid calling this function multiple times as it will make - a copy of all of the wearable data each time - - - - Calls either or - depending on the value of - replaceItems - - List of wearable inventory items to add - to the outfit or become a new outfit - True to replace existing items with the - new list of items, false to add these items to the existing outfit - - - - Adds a list of attachments to our agent - - A List containing the attachments to add - If true, tells simulator to remove existing attachment - first - - - - Adds a list of attachments to our agent - - A List containing the attachments to add - If true, tells simulator to remove existing attachment - If true replace existing attachment on this attachment point, otherwise add to it (multi-attachments) - first - - - - Attach an item to our agent at a specific attach point - - A to attach - the on the avatar - to attach the item to - - - - Attach an item to our agent at a specific attach point - - A to attach - the on the avatar - If true replace existing attachment on this attachment point, otherwise add to it (multi-attachments) - to attach the item to - - - - Attach an item to our agent specifying attachment details - - The of the item to attach - The attachments owner - The name of the attachment - The description of the attahment - The to apply when attached - The of the attachment - The on the agent - to attach the item to - - - - Attach an item to our agent specifying attachment details - - The of the item to attach - The attachments owner - The name of the attachment - The description of the attahment - The to apply when attached - The of the attachment - The on the agent - If true replace existing attachment on this attachment point, otherwise add to it (multi-attachments) - to attach the item to - - - - Detach an item from our agent using an object - - An object - - - - Detach an item from our agent - - The inventory itemID of the item to detach - - - - Inform the sim which wearables are part of our current outfit - - - - - Replaces the Wearables collection with a list of new wearable items - - Wearable items to replace the Wearables collection with - - - - Calculates base color/tint for a specific wearable - based on its params - - All the color info gathered from wearable's VisualParams - passed as list of ColorParamInfo tuples - Base color/tint for the wearable - - - - Blocking method to populate the Wearables dictionary - - True on success, otherwise false - - - - Blocking method to populate the Textures array with cached bakes - - True on success, otherwise false - - - - Populates textures and visual params from a decoded asset - - Wearable to decode - - Populates textures and visual params from a decoded asset - - Wearable to decode - - - - Blocking method to download and parse currently worn wearable assets - - True on success, otherwise false - - - - Get a list of all of the textures that need to be downloaded for a - single bake layer - - Bake layer to get texture AssetIDs for - A list of texture AssetIDs to download - - - - Helper method to lookup the TextureID for a single layer and add it - to a list if it is not already present - - - - - - - Blocking method to download all of the textures needed for baking - the given bake layers - - A list of layers that need baking - No return value is given because the baking will happen - whether or not all textures are successfully downloaded - - - - Blocking method to create and upload baked textures for all of the - missing bakes - - True on success, otherwise false - - - - Blocking method to create and upload a baked texture for a single - bake layer - - Layer to bake - True on success, otherwise false - - - - Blocking method to upload a baked texture - - Five channel JPEG2000 texture data to upload - UUID of the newly created asset on success, otherwise UUID.Zero - - - - Creates a dictionary of visual param values from the downloaded wearables - - A dictionary of visual param indices mapping to visual param - values for our agent that can be fed to the Baker class - - - - Initate server baking process - - True if the server baking was successful - - - - Get the latest version of COF - - Current Outfit Folder (or null if getting the data failed) - - - - Create an AgentSetAppearance packet from Wearables data and the - Textures array and send it - - - - - Converts a WearableType to a bodypart or clothing WearableType - - A WearableType - AssetType.Bodypart or AssetType.Clothing or AssetType.Unknown - - - - Converts a BakeType to the corresponding baked texture slot in AvatarTextureIndex - - A BakeType - The AvatarTextureIndex slot that holds the given BakeType - - - - Gives the layer number that is used for morph mask - - >A BakeType - Which layer number as defined in BakeTypeToTextures is used for morph mask - - - - Converts a BakeType to a list of the texture slots that make up that bake - - A BakeType - A list of texture slots that are inputs for the given bake - - - Contains the Event data returned from the data server from an AgentWearablesRequest - - - Construct a new instance of the AgentWearablesReplyEventArgs class - - - Contains the Event data returned from the data server from an AgentCachedTextureResponse - - - Construct a new instance of the AgentCachedBakesReplyEventArgs class - - - Contains the Event data returned from an AppearanceSetRequest - - - Indicates whether appearance setting was successful - - - - Triggered when appearance data is sent to the sim and - the main appearance thread is done. - Indicates whether appearance setting was successful - - - Contains the Event data returned from the data server from an RebakeAvatarTextures - - - The ID of the Texture Layer to bake - - - - Triggered when the simulator sends a request for this agent to rebake - its appearance - - The ID of the Texture Layer to bake - - - - Class that handles the local asset cache - - - - - Allows setting weather to periodicale prune the cache if it grows too big - Default is enabled, when caching is enabled - - - - - How long (in ms) between cache checks (default is 5 min.) - - - - - Default constructor - - A reference to the GridClient object - - - - Disposes cleanup timer - - - - - Only create timer when needed - - - - - Return bytes read from the local asset cache, null if it does not exist - - UUID of the asset we want to get - Raw bytes of the asset, or null on failure - - - - Returns ImageDownload object of the - image from the local image cache, null if it does not exist - - UUID of the image we want to get - ImageDownload object containing the image, or null on failure - - - - Constructs a file name of the cached asset - - UUID of the asset - String with the file name of the cahced asset - - - - Constructs a file name of the static cached asset - - UUID of the asset - String with the file name of the static cached asset - - - - Saves an asset to the local cache - - UUID of the asset - Raw bytes the asset consists of - Weather the operation was successfull - - - - Get the file name of the asset stored with gived UUID - - UUID of the asset - Null if we don't have that UUID cached on disk, file name if found in the cache folder - - - - Checks if the asset exists in the local cache - - UUID of the asset - True is the asset is stored in the cache, otherwise false - - - - Wipes out entire cache - - - - - Brings cache size to the 90% of the max size - - - - - Asynchronously brings cache size to the 90% of the max size - - - - - Adds up file sizes passes in a FileInfo array - - - - - Checks whether caching is enabled - - - - - Periodically prune the cache - - - - - Nicely formats file sizes - - Byte size we want to output - String with humanly readable file size - - - - Helper class for sorting files by their last accessed time - - - - - - - - - OK - - - Transfer completed - - - - - - - - - Unknown error occurred - - - Equivalent to a 404 error - - - Client does not have permission for that resource - - - Unknown status - - - - - - - - - - - Unknown - - - Virtually all asset transfers use this channel - - - - - - - - - - - Asset from the asset server - - - Inventory item - - - Estate asset, such as an estate covenant - - - - - - - - - - - - - - - - - - When requesting image download, type of the image requested - - - - Normal in-world object texture - - - Avatar texture - - - Server baked avatar texture - - - - Image file format - - - - - - - - - Number of milliseconds passed since the last transfer - packet was received - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Number of milliseconds to wait for a transfer header packet if out of order data was received - - - - Callback used for various asset download requests - - Transfer information - Downloaded asset, null on fail - - - - Callback used upon competition of baked texture upload - - Asset UUID of the newly uploaded baked texture - - - - A callback that fires upon the completition of the RequestMesh call - - Was the download successfull - Resulting mesh or null on problems - - - The event subscribers. null if no subcribers - - - Raises the XferReceived event - A XferReceivedEventArgs object containing the - data returned from the simulator - - - Thread sync lock object - - - Raised when the simulator responds sends - - - The event subscribers. null if no subcribers - - - Raises the AssetUploaded event - A AssetUploadedEventArgs object containing the - data returned from the simulator - - - Thread sync lock object - - - Raised during upload completes - - - The event subscribers. null if no subcribers - - - Raises the UploadProgress event - A UploadProgressEventArgs object containing the - data returned from the simulator - - - Thread sync lock object - - - Raised during upload with progres update - - - The event subscribers. null if no subcribers - - - Raises the InitiateDownload event - A InitiateDownloadEventArgs object containing the - data returned from the simulator - - - Thread sync lock object - - - Fired when the simulator sends an InitiateDownloadPacket, used to download terrain .raw files - - - The event subscribers. null if no subcribers - - - Raises the ImageReceiveProgress event - A ImageReceiveProgressEventArgs object containing the - data returned from the simulator - - - Thread sync lock object - - - Fired when a texture is in the process of being downloaded by the TexturePipeline class - - - Texture download cache - - - - Default constructor - - A reference to the GridClient object - - - - Request an asset download - - Asset UUID - Asset type, must be correct for the transfer to succeed - Whether to give this transfer an elevated priority - The callback to fire when the simulator responds with the asset data - - - - Request an asset download - - Asset UUID - Asset type, must be correct for the transfer to succeed - Whether to give this transfer an elevated priority - Source location of the requested asset - The callback to fire when the simulator responds with the asset data - - - - Request an asset download - - Asset UUID - Asset type, must be correct for the transfer to succeed - Whether to give this transfer an elevated priority - Source location of the requested asset - UUID of the transaction - The callback to fire when the simulator responds with the asset data - - - - Request an asset download - - Asset UUID - Asset type, must be correct for the transfer to succeed - Whether to give this transfer an elevated priority - Source location of the requested asset - UUID of the transaction - The callback to fire when the simulator responds with the asset data - - - - Request an asset download through the almost deprecated Xfer system - - Filename of the asset to request - Whether or not to delete the asset - off the server after it is retrieved - Use large transfer packets or not - UUID of the file to request, if filename is - left empty - Asset type of vFileID, or - AssetType.Unknown if filename is not empty - Sets the FilePath in the request to Cache - (4) if true, otherwise Unknown (0) is used - - - - - - - Use UUID.Zero if you do not have the - asset ID but have all the necessary permissions - The item ID of this asset in the inventory - Use UUID.Zero if you are not requesting an - asset from an object inventory - The owner of this asset - Asset type - Whether to prioritize this asset download or not - - - - - Used to force asset data into the PendingUpload property, ie: for raw terrain uploads - - An AssetUpload object containing the data to upload to the simulator - - - - Request an asset be uploaded to the simulator - - The Object containing the asset data - If True, the asset once uploaded will be stored on the simulator - in which the client was connected in addition to being stored on the asset server - The of the transfer, can be used to correlate the upload with - events being fired - - - - Request an asset be uploaded to the simulator - - The of the asset being uploaded - A byte array containing the encoded asset data - If True, the asset once uploaded will be stored on the simulator - in which the client was connected in addition to being stored on the asset server - The of the transfer, can be used to correlate the upload with - events being fired - - - - Request an asset be uploaded to the simulator - - - Asset type to upload this data as - A byte array containing the encoded asset data - If True, the asset once uploaded will be stored on the simulator - in which the client was connected in addition to being stored on the asset server - The of the transfer, can be used to correlate the upload with - events being fired - - - - Initiate an asset upload - - The ID this asset will have if the - upload succeeds - Asset type to upload this data as - Raw asset data to upload - Whether to store this asset on the local - simulator or the grid-wide asset server - The tranaction id for the upload - The transaction ID of this transfer - - - - Request a texture asset from the simulator using the system to - manage the requests and re-assemble the image from the packets received from the simulator - - The of the texture asset to download - The of the texture asset. - Use for most textures, or for baked layer texture assets - A float indicating the requested priority for the transfer. Higher priority values tell the simulator - to prioritize the request before lower valued requests. An image already being transferred using the can have - its priority changed by resending the request with the new priority value - Number of quality layers to discard. - This controls the end marker of the data sent. Sending with value -1 combined with priority of 0 cancels an in-progress - transfer. - A bug exists in the Linden Simulator where a -1 will occasionally be sent with a non-zero priority - indicating an off-by-one error. - The packet number to begin the request at. A value of 0 begins the request - from the start of the asset texture - The callback to fire when the image is retrieved. The callback - will contain the result of the request and the texture asset data - If true, the callback will be fired for each chunk of the downloaded image. - The callback asset parameter will contain all previously received chunks of the texture asset starting - from the beginning of the request - - Request an image and fire a callback when the request is complete - - Client.Assets.RequestImage(UUID.Parse("c307629f-e3a1-4487-5e88-0d96ac9d4965"), ImageType.Normal, TextureDownloader_OnDownloadFinished); - - private void TextureDownloader_OnDownloadFinished(TextureRequestState state, AssetTexture asset) - { - if(state == TextureRequestState.Finished) - { - Console.WriteLine("Texture {0} ({1} bytes) has been successfully downloaded", - asset.AssetID, - asset.AssetData.Length); - } - } - - Request an image and use an inline anonymous method to handle the downloaded texture data - - Client.Assets.RequestImage(UUID.Parse("c307629f-e3a1-4487-5e88-0d96ac9d4965"), ImageType.Normal, delegate(TextureRequestState state, AssetTexture asset) - { - if(state == TextureRequestState.Finished) - { - Console.WriteLine("Texture {0} ({1} bytes) has been successfully downloaded", - asset.AssetID, - asset.AssetData.Length); - } - } - ); - - Request a texture, decode the texture to a bitmap image and apply it to a imagebox - - Client.Assets.RequestImage(UUID.Parse("c307629f-e3a1-4487-5e88-0d96ac9d4965"), ImageType.Normal, TextureDownloader_OnDownloadFinished); - - private void TextureDownloader_OnDownloadFinished(TextureRequestState state, AssetTexture asset) - { - if(state == TextureRequestState.Finished) - { - ManagedImage imgData; - Image bitmap; - - if (state == TextureRequestState.Finished) - { - OpenJPEG.DecodeToImage(assetTexture.AssetData, out imgData, out bitmap); - picInsignia.Image = bitmap; - } - } - } - - - - - - Overload: Request a texture asset from the simulator using the system to - manage the requests and re-assemble the image from the packets received from the simulator - - The of the texture asset to download - The callback to fire when the image is retrieved. The callback - will contain the result of the request and the texture asset data - - - - Overload: Request a texture asset from the simulator using the system to - manage the requests and re-assemble the image from the packets received from the simulator - - The of the texture asset to download - The of the texture asset. - Use for most textures, or for baked layer texture assets - The callback to fire when the image is retrieved. The callback - will contain the result of the request and the texture asset data - - - - Overload: Request a texture asset from the simulator using the system to - manage the requests and re-assemble the image from the packets received from the simulator - - The of the texture asset to download - The of the texture asset. - Use for most textures, or for baked layer texture assets - The callback to fire when the image is retrieved. The callback - will contain the result of the request and the texture asset data - If true, the callback will be fired for each chunk of the downloaded image. - The callback asset parameter will contain all previously received chunks of the texture asset starting - from the beginning of the request - - - - Cancel a texture request - - The texture assets - - - - Requests download of a mesh asset - - UUID of the mesh asset - Callback when the request completes - - - - Fetach avatar texture on a grid capable of server side baking - - ID of the avatar - ID of the texture - Name of the part of the avatar texture applies to - Callback invoked on operation completion - - - - Lets TexturePipeline class fire the progress event - - The texture ID currently being downloaded - the number of bytes transferred - the total number of bytes expected - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Xfer data - - - Upload data - - - Filename used on the simulator - - - Filename used by the client - - - UUID of the image that is in progress - - - Number of bytes received so far - - - Image size in bytes - - - - Avatar profile flags - - - - - Represents an avatar (other than your own) - - - - - Positive and negative ratings - - - - Positive ratings for Behavior - - - Negative ratings for Behavior - - - Positive ratings for Appearance - - - Negative ratings for Appearance - - - Positive ratings for Building - - - Negative ratings for Building - - - Positive ratings given by this avatar - - - Negative ratings given by this avatar - - - - Avatar properties including about text, profile URL, image IDs and - publishing settings - - - - First Life about text - - - First Life image ID - - - - - - - - - - - - - - - Profile image ID - - - Flags of the profile - - - Web URL for this profile - - - Should this profile be published on the web - - - Avatar Online Status - - - Is this a mature profile - - - - - - - - - - Avatar interests including spoken languages, skills, and "want to" - choices - - - - Languages profile field - - - - - - - - - - - - - - - Groups that this avatar is a member of - - - Positive and negative ratings - - - Avatar properties including about text, profile URL, image IDs and - publishing settings - - - Avatar interests including spoken languages, skills, and "want to" - choices - - - Movement control flags for avatars. Typically not set or used by - clients. To move your avatar, use Client.Self.Movement instead - - - - Contains the visual parameters describing the deformation of the avatar - - - - - Appearance version. Value greater than 0 indicates using server side baking - - - - - Version of the Current Outfit Folder that the appearance is based on - - - - - Appearance flags. Introduced with server side baking, currently unused. - - - - - List of current avatar animations - - - - First name - - - Last name - - - Full name - - - Active group - - - - Default constructor - - - - Information about agents display name - - - Agent UUID - - - Username - - - Display name - - - First name (legacy) - - - Last name (legacy) - - - Full name (legacy) - - - Is display name default display name - - - Cache display name until - - - Last updated timestamp - - - - Creates AgentDisplayName object from OSD - - Incoming OSD data - AgentDisplayName object - - - - Return object as OSD map - - OSD containing agent's display name data - - - - Holds group information for Avatars such as those you might find in a profile - - - - true of Avatar accepts group notices - - - Groups Key - - - Texture Key for groups insignia - - - Name of the group - - - Powers avatar has in the group - - - Avatars Currently selected title - - - true of Avatar has chosen to list this in their profile - - - - Contains an animation currently being played by an agent - - - - The ID of the animation asset - - - A number to indicate start order of currently playing animations - On Linden Grids this number is unique per region, with OpenSim it is per client - - - - - - - Holds group information on an individual profile pick - - - - - Retrieve friend status notifications, and retrieve avatar names and - profiles - - - - The event subscribers, null of no subscribers - - - Raises the AvatarAnimation Event - An AvatarAnimationEventArgs object containing - the data sent from the simulator - - - Thread sync lock object - - - Raised when the simulator sends us data containing - an agents animation playlist - - - The event subscribers, null of no subscribers - - - Raises the AvatarAppearance Event - A AvatarAppearanceEventArgs object containing - the data sent from the simulator - - - Thread sync lock object - - - Raised when the simulator sends us data containing - the appearance information for an agent - - - The event subscribers, null of no subscribers - - - Raises the UUIDNameReply Event - A UUIDNameReplyEventArgs object containing - the data sent from the simulator - - - Thread sync lock object - - - Raised when the simulator sends us data containing - agent names/id values - - - The event subscribers, null of no subscribers - - - Raises the AvatarInterestsReply Event - A AvatarInterestsReplyEventArgs object containing - the data sent from the simulator - - - Thread sync lock object - - - Raised when the simulator sends us data containing - the interests listed in an agents profile - - - The event subscribers, null of no subscribers - - - Raises the AvatarPropertiesReply Event - A AvatarPropertiesReplyEventArgs object containing - the data sent from the simulator - - - Thread sync lock object - - - Raised when the simulator sends us data containing - profile property information for an agent - - - The event subscribers, null of no subscribers - - - Raises the AvatarGroupsReply Event - A AvatarGroupsReplyEventArgs object containing - the data sent from the simulator - - - Thread sync lock object - - - Raised when the simulator sends us data containing - the group membership an agent is a member of - - - The event subscribers, null of no subscribers - - - Raises the AvatarPickerReply Event - A AvatarPickerReplyEventArgs object containing - the data sent from the simulator - - - Thread sync lock object - - - Raised when the simulator sends us data containing - name/id pair - - - The event subscribers, null of no subscribers - - - Raises the ViewerEffectPointAt Event - A ViewerEffectPointAtEventArgs object containing - the data sent from the simulator - - - Thread sync lock object - - - Raised when the simulator sends us data containing - the objects and effect when an agent is pointing at - - - The event subscribers, null of no subscribers - - - Raises the ViewerEffectLookAt Event - A ViewerEffectLookAtEventArgs object containing - the data sent from the simulator - - - Thread sync lock object - - - Raised when the simulator sends us data containing - the objects and effect when an agent is looking at - - - The event subscribers, null of no subscribers - - - Raises the ViewerEffect Event - A ViewerEffectEventArgs object containing - the data sent from the simulator - - - Thread sync lock object - - - Raised when the simulator sends us data containing - an agents viewer effect information - - - The event subscribers, null of no subscribers - - - Raises the AvatarPicksReply Event - A AvatarPicksReplyEventArgs object containing - the data sent from the simulator - - - Thread sync lock object - - - Raised when the simulator sends us data containing - the top picks from an agents profile - - - The event subscribers, null of no subscribers - - - Raises the PickInfoReply Event - A PickInfoReplyEventArgs object containing - the data sent from the simulator - - - Thread sync lock object - - - Raised when the simulator sends us data containing - the Pick details - - - The event subscribers, null of no subscribers - - - Raises the AvatarClassifiedReply Event - A AvatarClassifiedReplyEventArgs object containing - the data sent from the simulator - - - Thread sync lock object - - - Raised when the simulator sends us data containing - the classified ads an agent has placed - - - The event subscribers, null of no subscribers - - - Raises the ClassifiedInfoReply Event - A ClassifiedInfoReplyEventArgs object containing - the data sent from the simulator - - - Thread sync lock object - - - Raised when the simulator sends us data containing - the details of a classified ad - - - The event subscribers, null of no subscribers - - - Raises the DisplayNameUpdate Event - A DisplayNameUpdateEventArgs object containing - the data sent from the simulator - - - Thread sync lock object - - - Raised when the simulator sends us data containing - the details of display name change - - - - Callback giving results when fetching display names - - If the request was successful - Array of display names - Array of UUIDs that could not be fetched - - - - Represents other avatars - - - - - Tracks the specified avatar on your map - Avatar ID to track - - - - Request a single avatar name - - The avatar key to retrieve a name for - - - - Request a list of avatar names - - The avatar keys to retrieve names for - - - - Check if Display Names functionality is available - - True if Display name functionality is available - - - - Request retrieval of display names (max 90 names per request) - - List of UUIDs to lookup - Callback to report result of the operation - - - - Start a request for Avatar Properties - - - - - - Search for an avatar (first name, last name) - - The name to search for - An ID to associate with this query - - - - Start a request for Avatar Picks - - UUID of the avatar - - - - Start a request for Avatar Classifieds - - UUID of the avatar - - - - Start a request for details of a specific profile pick - - UUID of the avatar - UUID of the profile pick - - - - Start a request for details of a specific profile classified - - UUID of the avatar - UUID of the profile classified - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - - EQ Message fired when someone nearby changes their display name - - The message key - the IMessage object containing the deserialized data sent from the simulator - The which originated the packet - - - - Crossed region handler for message that comes across the EventQueue. Sent to an agent - when the agent crosses a sim border into a new region. - - The message key - the IMessage object containing the deserialized data sent from the simulator - The which originated the packet - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Provides data for the event - The event occurs when the simulator sends - the animation playlist for an agent - - The following code example uses the and - properties to display the animation playlist of an avatar on the window. - - // subscribe to the event - Client.Avatars.AvatarAnimation += Avatars_AvatarAnimation; - - private void Avatars_AvatarAnimation(object sender, AvatarAnimationEventArgs e) - { - // create a dictionary of "known" animations from the Animations class using System.Reflection - Dictionary<UUID, string> systemAnimations = new Dictionary<UUID, string>(); - Type type = typeof(Animations); - System.Reflection.FieldInfo[] fields = type.GetFields(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static); - foreach (System.Reflection.FieldInfo field in fields) - { - systemAnimations.Add((UUID)field.GetValue(type), field.Name); - } - - // find out which animations being played are known animations and which are assets - foreach (Animation animation in e.Animations) - { - if (systemAnimations.ContainsKey(animation.AnimationID)) - { - Console.WriteLine("{0} is playing {1} ({2}) sequence {3}", e.AvatarID, - systemAnimations[animation.AnimationID], animation.AnimationSequence); - } - else - { - Console.WriteLine("{0} is playing {1} (Asset) sequence {2}", e.AvatarID, - animation.AnimationID, animation.AnimationSequence); - } - } - } - - - - - Get the ID of the agent - - - Get the list of animations to start - - - - Construct a new instance of the AvatarAnimationEventArgs class - - The ID of the agent - The list of animations to start - - - Provides data for the event - The event occurs when the simulator sends - the appearance data for an avatar - - The following code example uses the and - properties to display the selected shape of an avatar on the window. - - // subscribe to the event - Client.Avatars.AvatarAppearance += Avatars_AvatarAppearance; - - // handle the data when the event is raised - void Avatars_AvatarAppearance(object sender, AvatarAppearanceEventArgs e) - { - Console.WriteLine("The Agent {0} is using a {1} shape.", e.AvatarID, (e.VisualParams[31] > 0) : "male" ? "female") - } - - - - - Get the Simulator this request is from of the agent - - - Get the ID of the agent - - - true if the agent is a trial account - - - Get the default agent texture - - - Get the agents appearance layer textures - - - Get the for the agent - - - Version of the appearance system used. - Value greater than 0 indicates that server side baking is used - - - Version of the Current Outfit Folder the appearance is based on - - - Appearance flags, introduced with server side baking, currently unused - - - - Construct a new instance of the AvatarAppearanceEventArgs class - - The simulator request was from - The ID of the agent - true of the agent is a trial account - The default agent texture - The agents appearance layer textures - The for the agent - - - Represents the interests from the profile of an agent - - - Get the ID of the agent - - - The properties of an agent - - - Get the ID of the agent - - - Get the ID of the agent - - - Get the ID of the agent - - - Get the ID of the avatar - - - - Event args class for display name notification messages - - - - - Wrapper around a byte array that allows bit to be packed and unpacked - one at a time or by a variable amount. Useful for very tightly packed - data like LayerData packets - - - - - - - - - - - - - - Default constructor, initialize the bit packer / bit unpacker - with a byte array and starting position - - Byte array to pack bits in to or unpack from - Starting position in the byte array - - - - Pack a floating point value in to the data - - Floating point value to pack - - - - Pack part or all of an integer in to the data - - Integer containing the data to pack - Number of bits of the integer to pack - - - - Pack part or all of an unsigned integer in to the data - - Unsigned integer containing the data to pack - Number of bits of the integer to pack - - - - Pack a single bit in to the data - - Bit to pack - - - - - - - - - - - - - - - - - - - - - - - - - Unpacking a floating point value from the data - - Unpacked floating point value - - - - Unpack a variable number of bits from the data in to integer format - - Number of bits to unpack - An integer containing the unpacked bits - This function is only useful up to 32 bits - - - - Unpack a variable number of bits from the data in to unsigned - integer format - - Number of bits to unpack - An unsigned integer containing the unpacked bits - This function is only useful up to 32 bits - - - - Unpack a 16-bit signed integer - - 16-bit signed integer - - - - Unpack a 16-bit unsigned integer - - 16-bit unsigned integer - - - - Unpack a 32-bit signed integer - - 32-bit signed integer - - - - Unpack a 32-bit unsigned integer - - 32-bit unsigned integer - - - - Reads in a byte array of an Animation Asset created by the SecondLife(tm) client. - - - - - Rotation Keyframe count (used internally) - - - - - Position Keyframe count (used internally) - - - - - Animation Priority - - - - - The animation length in seconds. - - - - - Expression set in the client. Null if [None] is selected - - - - - The time in seconds to start the animation - - - - - The time in seconds to end the animation - - - - - Loop the animation - - - - - Meta data. Ease in Seconds. - - - - - Meta data. Ease out seconds. - - - - - Meta Data for the Hand Pose - - - - - Number of joints defined in the animation - - - - - Contains an array of joints - - - - - Searialize an animation asset into it's joints/keyframes/meta data - - - - - - Variable length strings seem to be null terminated in the animation asset.. but.. - use with caution, home grown. - advances the index. - - The animation asset byte array - The offset to start reading - a string - - - - Read in a Joint from an animation asset byte array - Variable length Joint fields, yay! - Advances the index - - animation asset byte array - Byte Offset of the start of the joint - The Joint data serialized into the binBVHJoint structure - - - - Read Keyframes of a certain type - advance i - - Animation Byte array - Offset in the Byte Array. Will be advanced - Number of Keyframes - Scaling Min to pass to the Uint16ToFloat method - Scaling Max to pass to the Uint16ToFloat method - - - - - Determines whether the specified is equal to the current . - - - true if the specified is equal to the current ; otherwise, false. - - The to compare with the current . - The parameter is null. - 2 - - - - Serves as a hash function for a particular type. - - - A hash code for the current . - - 2 - - - - A Joint and it's associated meta data and keyframes - - - - - Indicates whether this instance and a specified object are equal. - - - true if and this instance are the same type and represent the same value; otherwise, false. - - Another object to compare to. - 2 - - - - Returns the hash code for this instance. - - - A 32-bit signed integer that is the hash code for this instance. - - 2 - - - - Name of the Joint. Matches the avatar_skeleton.xml in client distros - - - - - Joint Animation Override? Was the same as the Priority in testing.. - - - - - Array of Rotation Keyframes in order from earliest to latest - - - - - Array of Position Keyframes in order from earliest to latest - This seems to only be for the Pelvis? - - - - - Custom application data that can be attached to a joint - - - - - A Joint Keyframe. This is either a position or a rotation. - - - - - Either a Vector3 position or a Vector3 Euler rotation - - - - - Poses set in the animation metadata for the hands. - - - - - Capabilities is the name of the bi-directional HTTP REST protocol - used to communicate non real-time transactions such as teleporting or - group messaging - - - - - Triggered when an event is received via the EventQueueGet - capability - - Event name - Decoded event data - The simulator that generated the event - - - Reference to the simulator this system is connected to - - - Capabilities URI this system was initialized with - - - Whether the capabilities event queue is connected and - listening for incoming events - - - - Default constructor - - - - - - - Request the URI of a named capability - - Name of the capability to request - The URI of the requested capability, or String.Empty if - the capability does not exist - - - - Process any incoming events, check to see if we have a message created for the event, - - - - - - - Attempts to convert an LLSD structure to a known Packet type - - Event name, this must match an actual - packet name for a Packet to be successfully built - LLSD to convert to a Packet - A Packet on success, otherwise null - - - - A custom decoder callback - - The key of the object - the data to decode - A string represending the fieldData - - - - Add a custom decoder callback - - The key of the field to decode - The custom decode handler - - - - Remove a custom decoder callback - - The key of the field to decode - The custom decode handler - - - - Creates a formatted string containing the values of a Packet - - The Packet - A formatted string of values of the nested items in the Packet object - - - - Decode an IMessage object into a beautifully formatted string - - The IMessage object - Recursion level (used for indenting) - A formatted string containing the names and values of the source object - - - - Thrown when a packet could not be successfully deserialized - - - - - Default constructor - - - - - Constructor that takes an additional error message - - An error message to attach to this exception - - - - The header of a message template packet. Holds packet flags, sequence - number, packet ID, and any ACKs that will be appended at the end of - the packet - - - - - Convert the AckList to a byte array, used for packet serializing - - Reference to the target byte array - Beginning position to start writing to in the byte - array, will be updated with the ending position of the ACK list - - - - - - - - - - - - - - - - - - - - - A block of data in a packet. Packets are composed of one or more blocks, - each block containing one or more fields - - - - Current length of the data in this packet - - - - Create a block from a byte array - - Byte array containing the serialized block - Starting position of the block in the byte array. - This will point to the data after the end of the block when the - call returns - - - - Serialize this block into a byte array - - Byte array to serialize this block into - Starting position in the byte array to serialize to. - This will point to the position directly after the end of the - serialized block when the call returns - - - A generic value, not an actual packet type - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Origin position of this coordinate frame - - - X axis of this coordinate frame, or Forward/At in grid terms - - - Y axis of this coordinate frame, or Left in grid terms - - - Z axis of this coordinate frame, or Up in grid terms - - - - - - Looking direction, must be a normalized vector - Up direction, must be a normalized vector - - - - Align the coordinate frame X and Y axis with a given rotation - around the Z axis in radians - - Absolute rotation around the Z axis in - radians - - - - Access to the data server which allows searching for land, events, people, etc - - - - Classified Ad categories - - - Classified is listed in the Any category - - - Classified is shopping related - - - Classified is - - - - - - - - - - - - - - - - - - - - - - - - Event Categories - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Query Flags used in many of the DirectoryManager methods to specify which query to execute and how to return the results. - - Flags can be combined using the | (pipe) character, not all flags are available in all queries - - - - Query the People database - - - - - - - - - Query the Groups database - - - Query the Events database - - - Query the land holdings database for land owned by the currently connected agent - - - - - - Query the land holdings database for land which is owned by a Group - - - Specifies the query should pre sort the results based upon traffic - when searching the Places database - - - - - - - - - - - - - - - Specifies the query should pre sort the results in an ascending order when searching the land sales database. - This flag is only used when searching the land sales database - - - Specifies the query should pre sort the results using the SalePrice field when searching the land sales database. - This flag is only used when searching the land sales database - - - Specifies the query should pre sort the results by calculating the average price/sq.m (SalePrice / Area) when searching the land sales database. - This flag is only used when searching the land sales database - - - Specifies the query should pre sort the results using the ParcelSize field when searching the land sales database. - This flag is only used when searching the land sales database - - - Specifies the query should pre sort the results using the Name field when searching the land sales database. - This flag is only used when searching the land sales database - - - When set, only parcels less than the specified Price will be included when searching the land sales database. - This flag is only used when searching the land sales database - - - When set, only parcels greater than the specified Size will be included when searching the land sales database. - This flag is only used when searching the land sales database - - - - - - - - - Include PG land in results. This flag is used when searching both the Groups, Events and Land sales databases - - - Include Mature land in results. This flag is used when searching both the Groups, Events and Land sales databases - - - Include Adult land in results. This flag is used when searching both the Groups, Events and Land sales databases - - - - - - - Land types to search dataserver for - - - - Search Auction, Mainland and Estate - - - Land which is currently up for auction - - - Parcels which are on the mainland (Linden owned) continents - - - Parcels which are on privately owned simulators - - - - The content rating of the event - - - - Event is PG - - - Event is Mature - - - Event is Adult - - - - Classified Ad Options - - There appear to be two formats the flags are packed in. - This set of flags is for the newer style - - - - - - - - - - - - - - - - - - - Classified ad query options - - - - Include all ads in results - - - Include PG ads in results - - - Include Mature ads in results - - - Include Adult ads in results - - - - The For Sale flag in PlacesReplyData - - - - Parcel is not listed for sale - - - Parcel is For Sale - - - - A classified ad on the grid - - - - UUID for this ad, useful for looking up detailed - information about it - - - The title of this classified ad - - - Flags that show certain options applied to the classified - - - Creation date of the ad - - - Expiration date of the ad - - - Price that was paid for this ad - - - Print the struct data as a string - A string containing the field name, and field value - - - - A parcel retrieved from the dataserver such as results from the - "For-Sale" listings or "Places" Search - - - - The unique dataserver parcel ID - This id is used to obtain additional information from the entry - by using the method - - - A string containing the name of the parcel - - - The size of the parcel - This field is not returned for Places searches - - - The price of the parcel - This field is not returned for Places searches - - - If True, this parcel is flagged to be auctioned - - - If true, this parcel is currently set for sale - - - Parcel traffic - - - Print the struct data as a string - A string containing the field name, and field value - - - - An Avatar returned from the dataserver - - - - Online status of agent - This field appears to be obsolete and always returns false - - - The agents first name - - - The agents last name - - - The agents - - - Print the struct data as a string - A string containing the field name, and field value - - - - Response to a "Groups" Search - - - - The Group ID - - - The name of the group - - - The current number of members - - - Print the struct data as a string - A string containing the field name, and field value - - - - Parcel information returned from a request - - Represents one of the following: - A parcel of land on the grid that has its Show In Search flag set - A parcel of land owned by the agent making the request - A parcel of land owned by a group the agent making the request is a member of - - - In a request for Group Land, the First record will contain an empty record - - Note: This is not the same as searching the land for sale data source - - - - The ID of the Agent of Group that owns the parcel - - - The name - - - The description - - - The Size of the parcel - - - The billable Size of the parcel, for mainland - parcels this will match the ActualArea field. For Group owned land this will be 10 percent smaller - than the ActualArea. For Estate land this will always be 0 - - - Indicates the ForSale status of the parcel - - - The Gridwide X position - - - The Gridwide Y position - - - The Z position of the parcel, or 0 if no landing point set - - - The name of the Region the parcel is located in - - - The Asset ID of the parcels Snapshot texture - - - The calculated visitor traffic - - - The billing product SKU - Known values are: - - 023Mainland / Full Region - 024Estate / Full Region - 027Estate / Openspace - 029Estate / Homestead - 129Mainland / Homestead (Linden Owned) - - - - - No longer used, will always be 0 - - - Get a SL URL for the parcel - A string, containing a standard SLURL - - - Print the struct data as a string - A string containing the field name, and field value - - - - An "Event" Listing summary - - - - The ID of the event creator - - - The name of the event - - - The events ID - - - A string containing the short date/time the event will begin - - - The event start time in Unixtime (seconds since epoch) - - - The events maturity rating - - - Print the struct data as a string - A string containing the field name, and field value - - - - The details of an "Event" - - - - The events ID - - - The ID of the event creator - - - The name of the event - - - The category - - - The events description - - - The short date/time the event will begin - - - The event start time in Unixtime (seconds since epoch) UTC adjusted - - - The length of the event in minutes - - - 0 if no cover charge applies - - - The cover charge amount in L$ if applicable - - - The name of the region where the event is being held - - - The gridwide location of the event - - - The maturity rating - - - Get a SL URL for the parcel where the event is hosted - A string, containing a standard SLURL - - - Print the struct data as a string - A string containing the field name, and field value - - - The event subscribers. null if no subcribers - - - Raises the EventInfoReply event - An EventInfoReplyEventArgs object containing the - data returned from the data server - - - Thread sync lock object - - - Raised when the data server responds to a request. - - - The event subscribers. null if no subcribers - - - Raises the DirEventsReply event - An DirEventsReplyEventArgs object containing the - data returned from the data server - - - Thread sync lock object - - - Raised when the data server responds to a request. - - - The event subscribers. null if no subcribers - - - Raises the PlacesReply event - A PlacesReplyEventArgs object containing the - data returned from the data server - - - Thread sync lock object - - - Raised when the data server responds to a request. - - - The event subscribers. null if no subcribers - - - Raises the DirPlacesReply event - A DirPlacesReplyEventArgs object containing the - data returned from the data server - - - Thread sync lock object - - - Raised when the data server responds to a request. - - - The event subscribers. null if no subcribers - - - Raises the DirClassifiedsReply event - A DirClassifiedsReplyEventArgs object containing the - data returned from the data server - - - Thread sync lock object - - - Raised when the data server responds to a request. - - - The event subscribers. null if no subcribers - - - Raises the DirGroupsReply event - A DirGroupsReplyEventArgs object containing the - data returned from the data server - - - Thread sync lock object - - - Raised when the data server responds to a request. - - - The event subscribers. null if no subcribers - - - Raises the DirPeopleReply event - A DirPeopleReplyEventArgs object containing the - data returned from the data server - - - Thread sync lock object - - - Raised when the data server responds to a request. - - - The event subscribers. null if no subcribers - - - Raises the DirLandReply event - A DirLandReplyEventArgs object containing the - data returned from the data server - - - Thread sync lock object - - - Raised when the data server responds to a request. - - - - Constructs a new instance of the DirectoryManager class - - An instance of GridClient - - - - Query the data server for a list of classified ads containing the specified string. - Defaults to searching for classified placed in any category, and includes PG, Adult and Mature - results. - - Responses are sent 16 per response packet, there is no way to know how many results a query reply will contain however assuming - the reply packets arrived ordered, a response with less than 16 entries would indicate all results have been received - - The event is raised when a response is received from the simulator - - A string containing a list of keywords to search for - A UUID to correlate the results when the event is raised - - - - Query the data server for a list of classified ads which contain specified keywords (Overload) - - The event is raised when a response is received from the simulator - - A string containing a list of keywords to search for - The category to search - A set of flags which can be ORed to modify query options - such as classified maturity rating. - A UUID to correlate the results when the event is raised - - Search classified ads containing the key words "foo" and "bar" in the "Any" category that are either PG or Mature - - UUID searchID = StartClassifiedSearch("foo bar", ClassifiedCategories.Any, ClassifiedQueryFlags.PG | ClassifiedQueryFlags.Mature); - - - - Responses are sent 16 at a time, there is no way to know how many results a query reply will contain however assuming - the reply packets arrived ordered, a response with less than 16 entries would indicate all results have been received - - - - - Starts search for places (Overloaded) - - The event is raised when a response is received from the simulator - - Search text - Each request is limited to 100 places - being returned. To get the first 100 result entries of a request use 0, - from 100-199 use 1, 200-299 use 2, etc. - A UUID to correlate the results when the event is raised - - - - Queries the dataserver for parcels of land which are flagged to be shown in search - - The event is raised when a response is received from the simulator - - A string containing a list of keywords to search for separated by a space character - A set of flags which can be ORed to modify query options - such as classified maturity rating. - The category to search - Each request is limited to 100 places - being returned. To get the first 100 result entries of a request use 0, - from 100-199 use 1, 200-299 use 2, etc. - A UUID to correlate the results when the event is raised - - Search places containing the key words "foo" and "bar" in the "Any" category that are either PG or Adult - - UUID searchID = StartDirPlacesSearch("foo bar", DirFindFlags.DwellSort | DirFindFlags.IncludePG | DirFindFlags.IncludeAdult, ParcelCategory.Any, 0); - - - - Additional information on the results can be obtained by using the ParcelManager.InfoRequest method - - - - - Starts a search for land sales using the directory - - The event is raised when a response is received from the simulator - - What type of land to search for. Auction, - estate, mainland, "first land", etc - The OnDirLandReply event handler must be registered before - calling this function. There is no way to determine how many - results will be returned, or how many times the callback will be - fired other than you won't get more than 100 total parcels from - each query. - - - - Starts a search for land sales using the directory - - The event is raised when a response is received from the simulator - - What type of land to search for. Auction, - estate, mainland, "first land", etc - Maximum price to search for - Maximum area to search for - Each request is limited to 100 parcels - being returned. To get the first 100 parcels of a request use 0, - from 100-199 use 1, 200-299 use 2, etc. - The OnDirLandReply event handler must be registered before - calling this function. There is no way to determine how many - results will be returned, or how many times the callback will be - fired other than you won't get more than 100 total parcels from - each query. - - - - Send a request to the data server for land sales listings - - - Flags sent to specify query options - - Available flags: - Specify the parcel rating with one or more of the following: - IncludePG IncludeMature IncludeAdult - - Specify the field to pre sort the results with ONLY ONE of the following: - PerMeterSort NameSort AreaSort PricesSort - - Specify the order the results are returned in, if not specified the results are pre sorted in a Descending Order - SortAsc - - Specify additional filters to limit the results with one or both of the following: - LimitByPrice LimitByArea - - Flags can be combined by separating them with the | (pipe) character - - Additional details can be found in - - What type of land to search for. Auction, - Estate or Mainland - Maximum price to search for when the - DirFindFlags.LimitByPrice flag is specified in findFlags - Maximum area to search for when the - DirFindFlags.LimitByArea flag is specified in findFlags - Each request is limited to 100 parcels - being returned. To get the first 100 parcels of a request use 0, - from 100-199 use 100, 200-299 use 200, etc. - The event will be raised with the response from the simulator - - There is no way to determine how many results will be returned, or how many times the callback will be - fired other than you won't get more than 100 total parcels from - each reply. - - Any land set for sale to either anybody or specific to the connected agent will be included in the - results if the land is included in the query - - - // request all mainland, any maturity rating that is larger than 512 sq.m - StartLandSearch(DirFindFlags.SortAsc | DirFindFlags.PerMeterSort | DirFindFlags.LimitByArea | DirFindFlags.IncludePG | DirFindFlags.IncludeMature | DirFindFlags.IncludeAdult, SearchTypeFlags.Mainland, 0, 512, 0); - - - - - Search for Groups - - The name or portion of the name of the group you wish to search for - Start from the match number - - - - - Search for Groups - - The name or portion of the name of the group you wish to search for - Start from the match number - Search flags - - - - - Search the People directory for other avatars - - The name or portion of the name of the avatar you wish to search for - - - - - - Search Places for parcels of land you personally own - - - - - Searches Places for land owned by the specified group - - ID of the group you want to recieve land list for (You must be a member of the group) - Transaction (Query) ID which can be associated with results from your request. - - - - Search the Places directory for parcels that are listed in search and contain the specified keywords - - A string containing the keywords to search for - Transaction (Query) ID which can be associated with results from your request. - - - - Search Places - All Options - - One of the Values from the DirFindFlags struct, ie: AgentOwned, GroupOwned, etc. - One of the values from the SearchCategory Struct, ie: Any, Linden, Newcomer - A string containing a list of keywords to search for separated by a space character - String Simulator Name to search in - LLUID of group you want to recieve results for - Transaction (Query) ID which can be associated with results from your request. - Transaction (Query) ID which can be associated with results from your request. - - - - Search All Events with specifid searchText in all categories, includes PG, Mature and Adult - - A string containing a list of keywords to search for separated by a space character - Each request is limited to 100 entries - being returned. To get the first group of entries of a request use 0, - from 100-199 use 100, 200-299 use 200, etc. - UUID of query to correlate results in callback. - - - - Search Events - - A string containing a list of keywords to search for separated by a space character - One or more of the following flags: DateEvents, IncludePG, IncludeMature, IncludeAdult - from the Enum - - Multiple flags can be combined by separating the flags with the | (pipe) character - "u" for in-progress and upcoming events, -or- number of days since/until event is scheduled - For example "0" = Today, "1" = tomorrow, "2" = following day, "-1" = yesterday, etc. - Each request is limited to 100 entries - being returned. To get the first group of entries of a request use 0, - from 100-199 use 100, 200-299 use 200, etc. - EventCategory event is listed under. - UUID of query to correlate results in callback. - - - Requests Event Details - ID of Event returned from the method - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming event message - The Unique Capabilities Key - The event message containing the data - The simulator the message originated from - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming event message - The Unique Capabilities Key - The event message containing the data - The simulator the message originated from - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Contains the Event data returned from the data server from an EventInfoRequest - - - - A single EventInfo object containing the details of an event - - - - Construct a new instance of the EventInfoReplyEventArgs class - A single EventInfo object containing the details of an event - - - Contains the "Event" detail data returned from the data server - - - The ID returned by - - - A list of "Events" returned by the data server - - - Construct a new instance of the DirEventsReplyEventArgs class - The ID of the query returned by the data server. - This will correlate to the ID returned by the method - A list containing the "Events" returned by the search query - - - Contains the "Event" list data returned from the data server - - - The ID returned by - - - A list of "Places" returned by the data server - - - Construct a new instance of PlacesReplyEventArgs class - The ID of the query returned by the data server. - This will correlate to the ID returned by the method - A list containing the "Places" returned by the data server query - - - Contains the places data returned from the data server - - - The ID returned by - - - A list containing Places data returned by the data server - - - Construct a new instance of the DirPlacesReplyEventArgs class - The ID of the query returned by the data server. - This will correlate to the ID returned by the method - A list containing land data returned by the data server - - - Contains the classified data returned from the data server - - - A list containing Classified Ads returned by the data server - - - Construct a new instance of the DirClassifiedsReplyEventArgs class - A list of classified ad data returned from the data server - - - Contains the group data returned from the data server - - - The ID returned by - - - A list containing Groups data returned by the data server - - - Construct a new instance of the DirGroupsReplyEventArgs class - The ID of the query returned by the data server. - This will correlate to the ID returned by the method - A list of groups data returned by the data server - - - Contains the people data returned from the data server - - - The ID returned by - - - A list containing People data returned by the data server - - - Construct a new instance of the DirPeopleReplyEventArgs class - The ID of the query returned by the data server. - This will correlate to the ID returned by the method - A list of people data returned by the data server - - - Contains the land sales data returned from the data server - - - A list containing land forsale data returned by the data server - - - Construct a new instance of the DirLandReplyEventArgs class - A list of parcels for sale returned by the data server - - - - Represends individual HTTP Download request - - - - URI of the item to fetch - - - Timout specified in milliseconds - - - Download progress callback - - - Download completed callback - - - Accept the following content type - - - How many times will this request be retried - - - Current fetch attempt - - - Default constructor - - - Constructor - - - - Manages async HTTP downloads with a limit on maximum - concurrent downloads - - - - Maximum number of parallel downloads from a single endpoint - - - Client certificate - - - Default constructor - - - Cleanup method - - - Setup http download request - - - Check the queue for pending work - - - Enqueue a new HTTP download - - - Describes tasks returned in LandStatReply - - - - Estate level administration and utilities - - - - Textures for each of the four terrain height levels - - - Upper/lower texture boundaries for each corner of the sim - - - - Constructor for EstateTools class - - - - - Used in the ReportType field of a LandStatRequest - - - Used by EstateOwnerMessage packets - - - Used by EstateOwnerMessage packets - - - - - - - - No flags set - - - Only return targets scripted objects - - - Only return targets objects if on others land - - - Returns target's scripted objects and objects on other parcels - - - Ground texture settings for each corner of the region - - - Used by GroundTextureHeightSettings - - - The high and low texture thresholds for each corner of the sim - - - The event subscribers. null if no subcribers - - - Raises the TopCollidersReply event - A TopCollidersReplyEventArgs object containing the - data returned from the data server - - - Thread sync lock object - - - Raised when the data server responds to a request. - - - The event subscribers. null if no subcribers - - - Raises the TopScriptsReply event - A TopScriptsReplyEventArgs object containing the - data returned from the data server - - - Thread sync lock object - - - Raised when the data server responds to a request. - - - The event subscribers. null if no subcribers - - - Raises the EstateUsersReply event - A EstateUsersReplyEventArgs object containing the - data returned from the data server - - - Thread sync lock object - - - Raised when the data server responds to a request. - - - The event subscribers. null if no subcribers - - - Raises the EstateGroupsReply event - A EstateGroupsReplyEventArgs object containing the - data returned from the data server - - - Thread sync lock object - - - Raised when the data server responds to a request. - - - The event subscribers. null if no subcribers - - - Raises the EstateManagersReply event - A EstateManagersReplyEventArgs object containing the - data returned from the data server - - - Thread sync lock object - - - Raised when the data server responds to a request. - - - The event subscribers. null if no subcribers - - - Raises the EstateBansReply event - A EstateBansReplyEventArgs object containing the - data returned from the data server - - - Thread sync lock object - - - Raised when the data server responds to a request. - - - The event subscribers. null if no subcribers - - - Raises the EstateCovenantReply event - A EstateCovenantReplyEventArgs object containing the - data returned from the data server - - - Thread sync lock object - - - Raised when the data server responds to a request. - - - The event subscribers. null if no subcribers - - - Raises the EstateUpdateInfoReply event - A EstateUpdateInfoReplyEventArgs object containing the - data returned from the data server - - - Thread sync lock object - - - Raised when the data server responds to a request. - - - - Requests estate information such as top scripts and colliders - - - - - - - - Requests estate settings, including estate manager and access/ban lists - - - Requests the "Top Scripts" list for the current region - - - Requests the "Top Colliders" list for the current region - - - - Set several estate specific configuration variables - - The Height of the waterlevel over the entire estate. Defaults to 20 - The maximum height change allowed above the baked terrain. Defaults to 4 - The minimum height change allowed below the baked terrain. Defaults to -4 - true to use - if True forces the sun position to the position in SunPosition - The current position of the sun on the estate, or when FixedSun is true the static position - the sun will remain. 6.0 = Sunrise, 30.0 = Sunset - - - - Request return of objects owned by specified avatar - - The Agents owning the primitives to return - specify the coverage and type of objects to be included in the return - true to perform return on entire estate - - - - - - - - - Used for setting and retrieving various estate panel settings - - EstateOwnerMessage Method field - List of parameters to include - - - - Kick an avatar from an estate - - Key of Agent to remove - - - - Ban an avatar from an estate - Key of Agent to remove - Ban user from this estate and all others owned by the estate owner - - - Unban an avatar from an estate - Key of Agent to remove - /// Unban user from this estate and all others owned by the estate owner - - - - Send a message dialog to everyone in an entire estate - - Message to send all users in the estate - - - - Send a message dialog to everyone in a simulator - - Message to send all users in the simulator - - - - Send an avatar back to their home location - - Key of avatar to send home - - - - Begin the region restart process - - - - - Cancels a region restart - - - - Estate panel "Region" tab settings - - - Estate panel "Debug" tab settings - - - Used for setting the region's terrain textures for its four height levels - - - - - - - Used for setting sim terrain texture heights - - - Requests the estate covenant - - - - Upload a terrain RAW file - - A byte array containing the encoded terrain data - The name of the file being uploaded - The Id of the transfer request - - - - Teleports all users home in current Estate - - - - - Remove estate manager - Key of Agent to Remove - removes manager to this estate and all others owned by the estate owner - - - - Add estate manager - Key of Agent to Add - Add agent as manager to this estate and all others owned by the estate owner - - - - Add's an agent to the estate Allowed list - Key of Agent to Add - Add agent as an allowed reisdent to All estates if true - - - - Removes an agent from the estate Allowed list - Key of Agent to Remove - Removes agent as an allowed reisdent from All estates if true - - - - - Add's a group to the estate Allowed list - Key of Group to Add - Add Group as an allowed group to All estates if true - - - - - Removes a group from the estate Allowed list - Key of Group to Remove - Removes Group as an allowed Group from All estates if true - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Raised on LandStatReply when the report type is for "top colliders" - - - - The number of returned items in LandStatReply - - - - - A Dictionary of Object UUIDs to tasks returned in LandStatReply - - - - Construct a new instance of the TopCollidersReplyEventArgs class - The number of returned items in LandStatReply - Dictionary of Object UUIDs to tasks returned in LandStatReply - - - Raised on LandStatReply when the report type is for "top Scripts" - - - - The number of scripts returned in LandStatReply - - - - - A Dictionary of Object UUIDs to tasks returned in LandStatReply - - - - Construct a new instance of the TopScriptsReplyEventArgs class - The number of returned items in LandStatReply - Dictionary of Object UUIDs to tasks returned in LandStatReply - - - Returned, along with other info, upon a successful .RequestInfo() - - - - The identifier of the estate - - - - - The number of returned itmes - - - - - List of UUIDs of Banned Users - - - - Construct a new instance of the EstateBansReplyEventArgs class - The estate's identifier on the grid - The number of returned items in LandStatReply - User UUIDs banned - - - Returned, along with other info, upon a successful .RequestInfo() - - - - The identifier of the estate - - - - - The number of returned items - - - - - List of UUIDs of Allowed Users - - - - Construct a new instance of the EstateUsersReplyEventArgs class - The estate's identifier on the grid - The number of users - Allowed users UUIDs - - - Returned, along with other info, upon a successful .RequestInfo() - - - - The identifier of the estate - - - - - The number of returned items - - - - - List of UUIDs of Allowed Groups - - - - Construct a new instance of the EstateGroupsReplyEventArgs class - The estate's identifier on the grid - The number of Groups - Allowed Groups UUIDs - - - Returned, along with other info, upon a successful .RequestInfo() - - - - The identifier of the estate - - - - - The number of returned items - - - - - List of UUIDs of the Estate's Managers - - - - Construct a new instance of the EstateManagersReplyEventArgs class - The estate's identifier on the grid - The number of Managers - Managers UUIDs - - - Returned, along with other info, upon a successful .RequestInfo() - - - - The Covenant - - - - - The timestamp - - - - - The Estate name - - - - - The Estate Owner's ID (can be a GroupID) - - - - Construct a new instance of the EstateCovenantReplyEventArgs class - The Covenant ID - The timestamp - The estate's name - The Estate Owner's ID (can be a GroupID) - - - Returned, along with other info, upon a successful .RequestInfo() - - - - The estate's name - - - - - The Estate Owner's ID (can be a GroupID) - - - - - The identifier of the estate on the grid - - - - - - - Construct a new instance of the EstateUpdateInfoReplyEventArgs class - The estate's name - The Estate Owners ID (can be a GroupID) - The estate's identifier on the grid - - - - - Registers, unregisters, and fires events generated by incoming packets - - - - - Object that is passed to worker threads in the ThreadPool for - firing packet callbacks - - - - Callback to fire for this packet - - - Reference to the simulator that this packet came from - - - The packet that needs to be processed - - - Reference to the GridClient object - - - - Default constructor - - - - - - Register an event handler - - Use PacketType.Default to fire this event on every - incoming packet - Packet type to register the handler for - Callback to be fired - True if this callback should be ran - asynchronously, false to run it synchronous - - - - Unregister an event handler - - Packet type to unregister the handler for - Callback to be unregistered - - - - Fire the events registered for this packet type - - Incoming packet type - Incoming packet - Simulator this packet was received from - - - - Registers, unregisters, and fires events generated by the Capabilities - event queue - - - - - Object that is passed to worker threads in the ThreadPool for - firing CAPS callbacks - - - - Callback to fire for this packet - - - Name of the CAPS event - - - Strongly typed decoded data - - - Reference to the simulator that generated this event - - - Reference to the GridClient object - - - - Default constructor - - Reference to the GridClient object - - - - Register an new event handler for a capabilities event sent via the EventQueue - - Use String.Empty to fire this event on every CAPS event - Capability event name to register the - handler for - Callback to fire - - - - Unregister a previously registered capabilities handler - - Capability event name unregister the - handler for - Callback to unregister - - - - Fire the events registered for this event type synchronously - - Capability name - Decoded event body - Reference to the simulator that - generated this event - - - - Fire the events registered for this event type asynchronously - - Capability name - Decoded event body - Reference to the simulator that - generated this event - - - - - - - - The avatar has no rights - - - The avatar can see the online status of the target avatar - - - The avatar can see the location of the target avatar on the map - - - The avatar can modify the ojects of the target avatar - - - - 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 bitflag properties, - TheirFriendsRights and MyFriendsRights - - - - - System ID of the avatar - - - - - full name of the avatar - - - - - True if the avatar is online - - - - - True if the friend can see if I am online - - - - - True if the friend can see me on the map - - - - - True if the freind can modify my objects - - - - - True if I can see if my friend is online - - - - - True if I can see if my friend is on the map - - - - - True if I can modify my friend's objects - - - - - My friend's rights represented as bitmapped flags - - - - - My rights represented as bitmapped flags - - - - - Used internally when building the initial list of friends at login time - - 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 - - - - FriendInfo represented as a string - - A string reprentation of both my rights and my friends rights - - - - This class is used to add and remove avatars from your friends list and to manage their permission. - - - - The event subscribers. null if no subcribers - - - Raises the FriendOnline event - A FriendInfoEventArgs object containing the - data returned from the data server - - - Thread sync lock object - - - Raised when the simulator sends notification one of the members in our friends list comes online - - - The event subscribers. null if no subcribers - - - Raises the FriendOffline event - A FriendInfoEventArgs object containing the - data returned from the data server - - - Thread sync lock object - - - Raised when the simulator sends notification one of the members in our friends list goes offline - - - The event subscribers. null if no subcribers - - - Raises the FriendRightsUpdate event - A FriendInfoEventArgs object containing the - data returned from the data server - - - Thread sync lock object - - - Raised when the simulator sends notification one of the members in our friends list grants or revokes permissions - - - The event subscribers. null if no subcribers - - - Raises the FriendNames event - A FriendNamesEventArgs object containing the - data returned from the data server - - - Thread sync lock object - - - Raised when the simulator sends us the names on our friends list - - - The event subscribers. null if no subcribers - - - Raises the FriendshipOffered event - A FriendshipOfferedEventArgs object containing the - data returned from the data server - - - Thread sync lock object - - - Raised when the simulator sends notification another agent is offering us friendship - - - The event subscribers. null if no subcribers - - - Raises the FriendshipResponse event - A FriendshipResponseEventArgs object containing the - data returned from the data server - - - Thread sync lock object - - - Raised when a request we sent to friend another agent is accepted or declined - - - The event subscribers. null if no subcribers - - - Raises the FriendshipTerminated event - A FriendshipTerminatedEventArgs object containing the - data returned from the data server - - - Thread sync lock object - - - Raised when the simulator sends notification one of the members in our friends list has terminated - our friendship - - - The event subscribers. null if no subcribers - - - Raises the FriendFoundReply event - A FriendFoundReplyEventArgs object containing the - data returned from the data server - - - Thread sync lock object - - - Raised when the simulator sends the location of a friend we have - requested map location info for - - - - A dictionary of key/value pairs containing known friends of this avatar. - - The Key is the of the friend, the value is a - object that contains detailed information including permissions you have and have given to the friend - - - - - A Dictionary of key/value pairs containing current pending frienship offers. - - The key is the of the avatar making the request, - the value is the of the request which is used to accept - or decline the friendship offer - - - - - Internal constructor - - A reference to the GridClient Object - - - - Accept a friendship request - - agentID of avatatar to form friendship with - imSessionID of the friendship request message - - - - Decline a friendship request - - of friend - imSessionID of the friendship request message - - - - Overload: Offer friendship to an avatar. - - System ID of the avatar you are offering friendship to - - - - Offer friendship to an avatar. - - System ID of the avatar you are offering friendship to - A message to send with the request - - - - Terminate a friendship with an avatar - - System ID of the avatar you are terminating the friendship with - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - - Change the rights of a friend avatar. - - the of the friend - the new rights to give the friend - This method will implicitly set the rights to those passed in the rights parameter. - - - - Use to map a friends location on the grid. - - Friends UUID to find - - - - - Use to track a friends movement on the grid - - Friends Key - - - - Ask for a notification of friend's online status - - Friend's UUID - - - - This handles the asynchronous response of a RequestAvatarNames call. - - - names cooresponding to the the list of IDs sent the the RequestAvatarNames call. - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - - Populate FriendList with data from the login reply - - true if login was successful - true if login request is requiring a redirect - A string containing the response to the login request - A string containing the reason for the request - A object containing the decoded - reply from the login server - - - Contains information on a member of our friends list - - - Get the FriendInfo - - - - Construct a new instance of the FriendInfoEventArgs class - - The FriendInfo - - - Contains Friend Names - - - A dictionary where the Key is the ID of the Agent, - and the Value is a string containing their name - - - - Construct a new instance of the FriendNamesEventArgs class - - A dictionary where the Key is the ID of the Agent, - and the Value is a string containing their name - - - Sent when another agent requests a friendship with our agent - - - Get the ID of the agent requesting friendship - - - Get the name of the agent requesting friendship - - - Get the ID of the session, used in accepting or declining the - friendship offer - - - - Construct a new instance of the FriendshipOfferedEventArgs class - - The ID of the agent requesting friendship - The name of the agent requesting friendship - The ID of the session, used in accepting or declining the - friendship offer - - - A response containing the results of our request to form a friendship with another agent - - - Get the ID of the agent we requested a friendship with - - - Get the name of the agent we requested a friendship with - - - true if the agent accepted our friendship offer - - - - Construct a new instance of the FriendShipResponseEventArgs class - - The ID of the agent we requested a friendship with - The name of the agent we requested a friendship with - true if the agent accepted our friendship offer - - - Contains data sent when a friend terminates a friendship with us - - - Get the ID of the agent that terminated the friendship with us - - - Get the name of the agent that terminated the friendship with us - - - - Construct a new instance of the FrindshipTerminatedEventArgs class - - The ID of the friend who terminated the friendship with us - The name of the friend who terminated the friendship with us - - - - Data sent in response to a request which contains the information to allow us to map the friends location - - - - Get the ID of the agent we have received location information for - - - Get the region handle where our mapped friend is located - - - Get the simulator local position where our friend is located - - - - Construct a new instance of the FriendFoundReplyEventArgs class - - The ID of the agent we have requested location information for - The region handle where our friend is located - The simulator local position our friend is located - - - - Main class to expose grid functionality to clients. All of the - classes needed for sending and receiving data are accessible through - this class. - - - - // Example minimum code required to instantiate class and - // connect to a simulator. - using System; - using System.Collections.Generic; - using System.Text; - using OpenMetaverse; - - namespace FirstBot - { - class Bot - { - public static GridClient Client; - static void Main(string[] args) - { - Client = new GridClient(); // instantiates the GridClient class - // to the global Client object - // Login to Simulator - Client.Network.Login("FirstName", "LastName", "Password", "FirstBot", "1.0"); - // Wait for a Keypress - Console.ReadLine(); - // Logout of simulator - Client.Network.Logout(); - } - } - } - - - - - Networking subsystem - - - Settings class including constant values and changeable - parameters for everything - - - Parcel (subdivided simulator lots) subsystem - - - Our own avatars subsystem - - - Other avatars subsystem - - - Estate subsystem - - - Friends list subsystem - - - Grid (aka simulator group) subsystem - - - Object subsystem - - - Group subsystem - - - Asset subsystem - - - Appearance subsystem - - - Inventory subsystem - - - Directory searches including classifieds, people, land - sales, etc - - - Handles land, wind, and cloud heightmaps - - - Handles sound-related networking - - - Throttling total bandwidth usage, or allocating bandwidth - for specific data stream types - - - - Default constructor - - - - - Return the full name of this instance - - Client avatars full name - - - - Map layer request type - - - - Objects and terrain are shown - - - Only the terrain is shown, no objects - - - Overlay showing land for sale and for auction - - - - Type of grid item, such as telehub, event, populator location, etc. - - - - Telehub - - - PG rated event - - - Mature rated event - - - Popular location - - - Locations of avatar groups in a region - - - Land for sale - - - Classified ad - - - Adult rated event - - - Adult land for sale - - - - Information about a region on the grid map - - - - Sim X position on World Map - - - Sim Y position on World Map - - - Sim Name (NOTE: In lowercase!) - - - - - - Appears to always be zero (None) - - - Sim's defined Water Height - - - - - - UUID of the World Map image - - - Unique identifier for this region, a combination of the X - and Y position - - - - - - - - - - - - - - - - - - - - - - - Visual chunk of the grid map - - - - - Base class for Map Items - - - - The Global X position of the item - - - The Global Y position of the item - - - Get the Local X position of the item - - - Get the Local Y position of the item - - - Get the Handle of the region - - - - Represents an agent or group of agents location - - - - - Represents a Telehub location - - - - - Represents a non-adult parcel of land for sale - - - - - Represents an Adult parcel of land for sale - - - - - Represents a PG Event - - - - - Represents a Mature event - - - - - Represents an Adult event - - - - - Manages grid-wide tasks such as the world map - - - - The event subscribers. null if no subcribers - - - Raises the CoarseLocationUpdate event - A CoarseLocationUpdateEventArgs object containing the - data sent by simulator - - - Thread sync lock object - - - Raised when the simulator sends a - containing the location of agents in the simulator - - - The event subscribers. null if no subcribers - - - Raises the GridRegion event - A GridRegionEventArgs object containing the - data sent by simulator - - - Thread sync lock object - - - Raised when the simulator sends a Region Data in response to - a Map request - - - The event subscribers. null if no subcribers - - - Raises the GridLayer event - A GridLayerEventArgs object containing the - data sent by simulator - - - Thread sync lock object - - - Raised when the simulator sends GridLayer object containing - a map tile coordinates and texture information - - - The event subscribers. null if no subcribers - - - Raises the GridItems event - A GridItemEventArgs object containing the - data sent by simulator - - - Thread sync lock object - - - Raised when the simulator sends GridItems object containing - details on events, land sales at a specific location - - - The event subscribers. null if no subcribers - - - Raises the RegionHandleReply event - A RegionHandleReplyEventArgs object containing the - data sent by simulator - - - Thread sync lock object - - - Raised in response to a Region lookup - - - Unknown - - - Current direction of the sun - - - Current angular velocity of the sun - - - Microseconds since the start of SL 4-hour day - - - A dictionary of all the regions, indexed by region name - - - A dictionary of all the regions, indexed by region handle - - - - Constructor - - Instance of GridClient object to associate with this GridManager instance - - - - - - - - - - Request a map layer - - The name of the region - The type of layer - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Request data for all mainland (Linden managed) simulators - - - - - Request the region handle for the specified region UUID - - UUID of the region to look up - - - - Get grid region information using the region name, this function - will block until it can find the region or gives up - - Name of sim you're looking for - Layer that you are requesting - Will contain a GridRegion for the sim you're - looking for if successful, otherwise an empty structure - True if the GridRegion was successfully fetched, otherwise - false - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - - Avatar group management - - - - Key of Group Member - - - Total land contribution - - - Online status information - - - Abilities that the Group Member has - - - Current group title - - - Is a group owner - - - - Role manager for a group - - - - Key of the group - - - Key of Role - - - Name of Role - - - Group Title associated with Role - - - Description of Role - - - Abilities Associated with Role - - - Returns the role's title - The role's title - - - - Class to represent Group Title - - - - Key of the group - - - ID of the role title belongs to - - - Group Title - - - Whether title is Active - - - Returns group title - - - - Represents a group on the grid - - - - Key of Group - - - Key of Group Insignia - - - Key of Group Founder - - - Key of Group Role for Owners - - - Name of Group - - - Text of Group Charter - - - Title of "everyone" role - - - Is the group open for enrolement to everyone - - - Will group show up in search - - - - - - - - - - - - Is the group Mature - - - Cost of group membership - - - - - - - - - The total number of current members this group has - - - The number of roles this group has configured - - - Show this group in agent's profile - - - Returns the name of the group - A string containing the name of the group - - - - A group Vote - - - - Key of Avatar who created Vote - - - Text of the Vote proposal - - - Total number of votes - - - - A group proposal - - - - The Text of the proposal - - - The minimum number of members that must vote before proposal passes or failes - - - The required ration of yes/no votes required for vote to pass - The three options are Simple Majority, 2/3 Majority, and Unanimous - TODO: this should be an enum - - - The duration in days votes are accepted - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Struct representing a group notice - - - - - - - - - - - - - - - - - - - - - - - Struct representing a group notice list entry - - - - Notice ID - - - Creation timestamp of notice - - - Agent name who created notice - - - Notice subject - - - Is there an attachment? - - - Attachment Type - - - - Struct representing a member of a group chat session and their settings - - - - The of the Avatar - - - True if user has voice chat enabled - - - True of Avatar has moderator abilities - - - True if a moderator has muted this avatars chat - - - True if a moderator has muted this avatars voice - - - - Role update flags - - - - - - - - - - - - - - - - - - - - - - - - - Can send invitations to groups default role - - - Can eject members from group - - - Can toggle 'Open Enrollment' and change 'Signup fee' - - - Member is visible in the public member list - - - Can create new roles - - - Can delete existing roles - - - Can change Role names, titles and descriptions - - - Can assign other members to assigners role - - - Can assign other members to any role - - - Can remove members from roles - - - Can assign and remove abilities in roles - - - Can change group Charter, Insignia, 'Publish on the web' and which - members are publicly visible in group member listings - - - Can buy land or deed land to group - - - Can abandon group owned land to Governor Linden on mainland, or Estate owner for - private estates - - - Can set land for-sale information on group owned parcels - - - Can subdivide and join parcels - - - Can change music and media settings - - - Can toggle 'Edit Terrain' option in Land settings - - - Can toggle various About Land > Options settings - - - Can toggle "Show in Find Places" and set search category - - - Can change parcel name, description, and 'Publish on web' settings - - - Can set the landing point and teleport routing on group land - - - Can always terraform land, even if parcel settings have it turned off - - - Can always fly while over group owned land - - - Can always rez objects on group owned land - - - Can always create landmarks for group owned parcels - - - Can set home location on any group owned parcel - - - Allowed to hold events on group-owned land - - - Can modify public access settings for group owned parcels - - - Can manager parcel ban lists on group owned land - - - Can manage pass list sales information - - - Can eject and freeze other avatars on group owned land - - - Can return objects set to group - - - Can return non-group owned/set objects - - - Can return group owned objects - - - Can landscape using Linden plants - - - Can deed objects to group - - - Can move group owned objects - - - Can set group owned objects for-sale - - - Pay group liabilities and receive group dividends - - - Can send group notices - - - Can receive group notices - - - Can create group proposals - - - Can vote on group proposals - - - Can join group chat sessions - - - Can use voice chat in Group Chat sessions - - - Can moderate group chat sessions - - - Has admin rights to any experiences owned by this group - - - Can sign scripts for experiences owned by this group - - - Allows access to ban / un-ban agents from a group - - - - Ban actions available for group members - - - - Ban agent from joining a group - - - Remove restriction on agent jointing a group - - - - Handles all network traffic related to reading and writing group - information - - - - The event subscribers. null if no subcribers - - - Raises the CurrentGroups event - A CurrentGroupsEventArgs object containing the - data sent from the simulator - - - Thread sync lock object - - - Raised when the simulator sends us data containing - our current group membership - - - The event subscribers. null if no subcribers - - - Raises the GroupNamesReply event - A GroupNamesEventArgs object containing the - data response from the simulator - - - Thread sync lock object - - - Raised when the simulator responds to a RequestGroupName - or RequestGroupNames request - - - The event subscribers. null if no subcribers - - - Raises the GroupProfile event - An GroupProfileEventArgs object containing the - data returned from the simulator - - - Thread sync lock object - - - Raised when the simulator responds to a request - - - The event subscribers. null if no subcribers - - - Raises the GroupMembers event - A GroupMembersEventArgs object containing the - data returned from the simulator - - - Thread sync lock object - - - Raised when the simulator responds to a request - - - The event subscribers. null if no subcribers - - - Raises the GroupRolesDataReply event - A GroupRolesDataReplyEventArgs object containing the - data returned from the simulator - - - Thread sync lock object - - - Raised when the simulator responds to a request - - - The event subscribers. null if no subcribers - - - Raises the GroupRoleMembersReply event - A GroupRolesRoleMembersReplyEventArgs object containing the - data returned from the simulator - - - Thread sync lock object - - - Raised when the simulator responds to a request - - - The event subscribers. null if no subcribers - - - Raises the GroupTitlesReply event - A GroupTitlesReplyEventArgs object containing the - data returned from the simulator - - - Thread sync lock object - - - Raised when the simulator responds to a request - - - The event subscribers. null if no subcribers - - - Raises the GroupAccountSummary event - A GroupAccountSummaryReplyEventArgs object containing the - data returned from the simulator - - - Thread sync lock object - - - Raised when a response to a RequestGroupAccountSummary is returned - by the simulator - - - The event subscribers. null if no subcribers - - - Raises the GroupCreated event - An GroupCreatedEventArgs object containing the - data returned from the simulator - - - Thread sync lock object - - - Raised when a request to create a group is successful - - - The event subscribers. null if no subcribers - - - Raises the GroupJoined event - A GroupOperationEventArgs object containing the - result of the operation returned from the simulator - - - Thread sync lock object - - - Raised when a request to join a group either - fails or succeeds - - - The event subscribers. null if no subcribers - - - Raises the GroupLeft event - A GroupOperationEventArgs object containing the - result of the operation returned from the simulator - - - Thread sync lock object - - - Raised when a request to leave a group either - fails or succeeds - - - The event subscribers. null if no subcribers - - - Raises the GroupDropped event - An GroupDroppedEventArgs object containing the - the group your agent left - - - Thread sync lock object - - - Raised when A group is removed from the group server - - - The event subscribers. null if no subcribers - - - Raises the GroupMemberEjected event - An GroupMemberEjectedEventArgs object containing the - data returned from the simulator - - - Thread sync lock object - - - Raised when a request to eject a member from a group either - fails or succeeds - - - The event subscribers. null if no subcribers - - - Raises the GroupNoticesListReply event - An GroupNoticesListReplyEventArgs object containing the - data returned from the simulator - - - Thread sync lock object - - - Raised when the simulator sends us group notices - - - - The event subscribers. null if no subcribers - - - Raises the GroupInvitation event - An GroupInvitationEventArgs object containing the - data returned from the simulator - - - Thread sync lock object - - - Raised when another agent invites our avatar to join a group - - - The event subscribers. null if no subcribers - - - Raises the BannedAgents event - An BannedAgentsEventArgs object containing the - data returned from the simulator - - - Thread sync lock object - - - Raised when another agent invites our avatar to join a group - - - A reference to the current instance - - - Currently-active group members requests - - - Currently-active group roles requests - - - Currently-active group role-member requests - - - Dictionary keeping group members while request is in progress - - - Dictionary keeping mebmer/role mapping while request is in progress - - - Dictionary keeping GroupRole information while request is in progress - - - Caches group name lookups - - - - Construct a new instance of the GroupManager class - - A reference to the current instance - - - - Request a current list of groups the avatar is a member of. - - CAPS Event Queue must be running for this to work since the results - come across CAPS. - - - - Lookup name of group based on groupID - - groupID of group to lookup name for. - - - - Request lookup of multiple group names - - List of group IDs to request. - - - Lookup group profile data such as name, enrollment, founder, logo, etc - Subscribe to OnGroupProfile event to receive the results. - group ID (UUID) - - - Request a list of group members. - Subscribe to OnGroupMembers event to receive the results. - group ID (UUID) - UUID of the request, use to index into cache - - - Request group roles - Subscribe to OnGroupRoles event to receive the results. - group ID (UUID) - UUID of the request, use to index into cache - - - Request members (members,role) role mapping for a group. - Subscribe to OnGroupRolesMembers event to receive the results. - group ID (UUID) - UUID of the request, use to index into cache - - - Request a groups Titles - Subscribe to OnGroupTitles event to receive the results. - group ID (UUID) - UUID of the request, use to index into cache - - - Begin to get the group account summary - Subscribe to the OnGroupAccountSummary event to receive the results. - group ID (UUID) - How long of an interval - Which interval (0 for current, 1 for last) - - - Invites a user to a group - The group to invite to - A list of roles to invite a person to - Key of person to invite - - - Set a group as the current active group - group ID (UUID) - - - Change the role that determines your active title - Group ID to use - Role ID to change to - - - Set this avatar's tier contribution - Group ID to change tier in - amount of tier to donate - - - - Save wheather agent wants to accept group notices and list this group in their profile - - Group - Accept notices from this group - List this group in the profile - - - Request to join a group - Subscribe to OnGroupJoined event for confirmation. - group ID (UUID) to join. - - - - Request to create a new group. If the group is successfully - created, L$100 will automatically be deducted - - Subscribe to OnGroupCreated event to receive confirmation. - Group struct containing the new group info - - - Update a group's profile and other information - Groups ID (UUID) to update. - Group struct to update. - - - Eject a user from a group - Group ID to eject the user from - Avatar's key to eject - - - Update role information - Modified role to be updated - - - Create a new group role - Group ID to update - Role to create - - - Delete a group role - Group ID to update - Role to delete - - - Remove an avatar from a role - Group ID to update - Role ID to be removed from - Avatar's Key to remove - - - Assign an avatar to a role - Group ID to update - Role ID to assign to - Avatar's ID to assign to role - - - Request the group notices list - Group ID to fetch notices for - - - Request a group notice by key - ID of group notice - - - Send out a group notice - Group ID to update - GroupNotice structure containing notice data - - - Start a group proposal (vote) - The Group ID to send proposal to - GroupProposal structure containing the proposal - - - Request to leave a group - Subscribe to OnGroupLeft event to receive confirmation - The group to leave - - - - Gets the URI of the cpability for handling group bans - - Group ID - null, if the feature is not supported, or URI of the capability - - - - Request a list of residents banned from joining a group - - UUID of the group - - - - Request a list of residents banned from joining a group - - UUID of the group - Callback on request completition - - - - Request that group of agents be banned or unbanned from the group - - Group ID - Ban/Unban action - Array of agents UUIDs to ban - - - - Request that group of agents be banned or unbanned from the group - - Group ID - Ban/Unban action - Array of agents UUIDs to ban - Callback - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Contains the current groups your agent is a member of - - - Get the current groups your agent is a member of - - - Construct a new instance of the CurrentGroupsEventArgs class - The current groups your agent is a member of - - - A Dictionary of group names, where the Key is the groups ID and the value is the groups name - - - Get the Group Names dictionary - - - Construct a new instance of the GroupNamesEventArgs class - The Group names dictionary - - - Represents the members of a group - - - Get the ID as returned by the request to correlate - this result set and the request - - - Get the ID of the group - - - Get the dictionary of members - - - - Construct a new instance of the GroupMembersReplyEventArgs class - - The ID of the request - The ID of the group - The membership list of the group - - - Represents the roles associated with a group - - - Get the ID as returned by the request to correlate - this result set and the request - - - Get the ID of the group - - - Get the dictionary containing the roles - - - Construct a new instance of the GroupRolesDataReplyEventArgs class - The ID as returned by the request to correlate - this result set and the request - The ID of the group - The dictionary containing the roles - - - Represents the Role to Member mappings for a group - - - Get the ID as returned by the request to correlate - this result set and the request - - - Get the ID of the group - - - Get the member to roles map - - - Construct a new instance of the GroupRolesMembersReplyEventArgs class - The ID as returned by the request to correlate - this result set and the request - The ID of the group - The member to roles map - - - Represents the titles for a group - - - Get the ID as returned by the request to correlate - this result set and the request - - - Get the ID of the group - - - Get the titles - - - Construct a new instance of the GroupTitlesReplyEventArgs class - The ID as returned by the request to correlate - this result set and the request - The ID of the group - The titles - - - Represents the summary data for a group - - - Get the ID of the group - - - Get the summary data - - - Construct a new instance of the GroupAccountSummaryReplyEventArgs class - The ID of the group - The summary data - - - A response to a group create request - - - Get the ID of the group - - - true of the group was created successfully - - - A string containing the message - - - Construct a new instance of the GroupCreatedReplyEventArgs class - The ID of the group - the success or faulure of the request - A string containing additional information - - - Represents a response to a request - - - Get the ID of the group - - - true of the request was successful - - - Construct a new instance of the GroupOperationEventArgs class - The ID of the group - true of the request was successful - - - Represents your agent leaving a group - - - Get the ID of the group - - - Construct a new instance of the GroupDroppedEventArgs class - The ID of the group - - - Represents a list of active group notices - - - Get the ID of the group - - - Get the notices list - - - Construct a new instance of the GroupNoticesListReplyEventArgs class - The ID of the group - The list containing active notices - - - Represents the profile of a group - - - Get the group profile - - - Construct a new instance of the GroupProfileEventArgs class - The group profile - - - - Provides notification of a group invitation request sent by another Avatar - - The invitation is raised when another avatar makes an offer for our avatar - to join a group. - - - The ID of the Avatar sending the group invitation - - - The name of the Avatar sending the group invitation - - - A message containing the request information which includes - the name of the group, the groups charter and the fee to join details - - - The Simulator - - - Set to true to accept invitation, false to decline - - - - Result of the request for list of agents banned from a group - - - - Indicates if list of banned agents for a group was successfully retrieved - - - Indicates if list of banned agents for a group was successfully retrieved - - - Array containing a list of UUIDs of the agents banned from a group - - - - Static helper functions and global variables - - - - This header flag signals that ACKs are appended to the packet - - - This header flag signals that this packet has been sent before - - - This header flags signals that an ACK is expected for this packet - - - This header flag signals that the message is compressed using zerocoding - - - - Passed to Logger.Log() to identify the severity of a log entry - - - - No logging information will be output - - - Non-noisy useful information, may be helpful in - debugging a problem - - - A non-critical error occurred. A warning will not - prevent the rest of the library from operating as usual, - although it may be indicative of an underlying issue - - - A critical error has occurred. Generally this will - be followed by the network layer shutting down, although the - stability of the library after an error is uncertain - - - Used for internal testing, this logging level can - generate very noisy (long and/or repetitive) messages. Don't - pass this to the Log() function, use DebugLog() instead. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Given an X/Y location in absolute (grid-relative) terms, a region - handle is returned along with the local X/Y location in that region - - The absolute X location, a number such as - 255360.35 - The absolute Y location, a number such as - 255360.35 - The sim-local X position of the global X - position, a value from 0.0 to 256.0 - The sim-local Y position of the global Y - position, a value from 0.0 to 256.0 - A 64-bit region handle that can be used to teleport to - - - - Converts a floating point number to a terse string format used for - transmitting numbers in wearable asset files - - Floating point number to convert to a string - A terse string representation of the input number - - - - Convert a variable length field (byte array) to a string, with a - field name prepended to each line of the output - - If the byte array has unprintable characters in it, a - hex dump will be written instead - The StringBuilder object to write to - The byte array to convert to a string - A field name to prepend to each line of output - - - - Decode a zerocoded byte array, used to decompress packets marked - with the zerocoded flag - - Any time a zero is encountered, the next byte is a count - of how many zeroes to expand. One zero is encoded with 0x00 0x01, - two zeroes is 0x00 0x02, three zeroes is 0x00 0x03, etc. The - first four bytes are copied directly to the output buffer. - - The byte array to decode - The length of the byte array to decode. This - would be the length of the packet up to (but not including) any - appended ACKs - The output byte array to decode to - The length of the output buffer - - - - Encode a byte array with zerocoding. Used to compress packets marked - with the zerocoded flag. Any zeroes in the array are compressed down - to a single zero byte followed by a count of how many zeroes to expand - out. A single zero becomes 0x00 0x01, two zeroes becomes 0x00 0x02, - three zeroes becomes 0x00 0x03, etc. The first four bytes are copied - directly to the output buffer. - - The byte array to encode - The length of the byte array to encode - The output byte array to encode to - The length of the output buffer - - - - Calculates the CRC (cyclic redundancy check) needed to upload inventory. - - Creation date - Sale type - Inventory type - Type - Asset ID - Group ID - Sale price - Owner ID - Creator ID - Item ID - Folder ID - Everyone mask (permissions) - Flags - Next owner mask (permissions) - Group mask (permissions) - Owner mask (permissions) - The calculated CRC - - - - Attempts to load a file embedded in the assembly - - The filename of the resource to load - A Stream for the requested file, or null if the resource - was not successfully loaded - - - - Attempts to load a file either embedded in the assembly or found in - a given search path - - The filename of the resource to load - An optional path that will be searched if - the asset is not found embedded in the assembly - A Stream for the requested file, or null if the resource - was not successfully loaded - - - - Converts a list of primitives to an object that can be serialized - with the LLSD system - - Primitives to convert to a serializable object - An object that can be serialized with LLSD - - - - Deserializes OSD in to a list of primitives - - Structure holding the serialized primitive list, - must be of the SDMap type - A list of deserialized primitives - - - - Converts a struct or class object containing fields only into a key value separated string - - The struct object - A string containing the struct fields as the keys, and the field value as the value separated - - - // Add the following code to any struct or class containing only fields to override the ToString() - // method to display the values of the passed object - - /// Print the struct data as a string - ///A string containing the field name, and field value - public override string ToString() - { - return Helpers.StructToString(this); - } - - - - - - The InternalDictionary class is used through the library for storing key/value pairs. - It is intended to be a replacement for the generic Dictionary class and should - be used in its place. It contains several methods for allowing access to the data from - outside the library that are read only and thread safe. - - - Key - Value - - - Internal dictionary that this class wraps around. Do not - modify or enumerate the contents of this dictionary without locking - on this member - - - - Gets the number of Key/Value pairs contained in the - - - - - Initializes a new instance of the Class - with the specified key/value, has the default initial capacity. - - - - // initialize a new InternalDictionary named testDict with a string as the key and an int as the value. - public InternalDictionary<string, int> testDict = new InternalDictionary<string, int>(); - - - - - - Initializes a new instance of the Class - with the specified key/value, has its initial valies copied from the specified - - - - to copy initial values from - - - // initialize a new InternalDictionary named testAvName with a UUID as the key and an string as the value. - // populates with copied values from example KeyNameCache Dictionary. - - // create source dictionary - Dictionary<UUID, string> KeyNameCache = new Dictionary<UUID, string>(); - KeyNameCache.Add("8300f94a-7970-7810-cf2c-fc9aa6cdda24", "Jack Avatar"); - KeyNameCache.Add("27ba1e40-13f7-0708-3e98-5819d780bd62", "Jill Avatar"); - - // Initialize new dictionary. - public InternalDictionary<UUID, string> testAvName = new InternalDictionary<UUID, string>(KeyNameCache); - - - - - - Initializes a new instance of the Class - with the specified key/value, With its initial capacity specified. - - Initial size of dictionary - - - // initialize a new InternalDictionary named testDict with a string as the key and an int as the value, - // initially allocated room for 10 entries. - public InternalDictionary<string, int> testDict = new InternalDictionary<string, int>(10); - - - - - - Try to get entry from with specified key - - Key to use for lookup - Value returned - if specified key exists, if not found - - - // find your avatar using the Simulator.ObjectsAvatars InternalDictionary: - Avatar av; - if (Client.Network.CurrentSim.ObjectsAvatars.TryGetValue(Client.Self.AgentID, out av)) - Console.WriteLine("Found Avatar {0}", av.Name); - - - - - - - Finds the specified match. - - The match. - Matched value - - - // use a delegate to find a prim in the ObjectsPrimitives InternalDictionary - // with the ID 95683496 - uint findID = 95683496; - Primitive findPrim = sim.ObjectsPrimitives.Find( - delegate(Primitive prim) { return prim.ID == findID; }); - - - - - Find All items in an - return matching items. - a containing found items. - - Find All prims within 20 meters and store them in a List - - int radius = 20; - List<Primitive> prims = Client.Network.CurrentSim.ObjectsPrimitives.FindAll( - delegate(Primitive prim) { - Vector3 pos = prim.Position; - return ((prim.ParentID == 0) && (pos != Vector3.Zero) && (Vector3.Distance(pos, location) < radius)); - } - ); - - - - - Find All items in an - return matching keys. - a containing found keys. - - Find All keys which also exist in another dictionary - - List<UUID> matches = myDict.FindAll( - delegate(UUID id) { - return myOtherDict.ContainsKey(id); - } - ); - - - - - Perform an on each entry in an - to perform - - - // Iterates over the ObjectsPrimitives InternalDictionary and prints out some information. - Client.Network.CurrentSim.ObjectsPrimitives.ForEach( - delegate(Primitive prim) - { - if (prim.Text != null) - { - Console.WriteLine("NAME={0} ID = {1} TEXT = '{2}'", - prim.PropertiesFamily.Name, prim.ID, prim.Text); - } - }); - - - - - Perform an on each key of an - to perform - - - - Perform an on each KeyValuePair of an - - to perform - - - Check if Key exists in Dictionary - Key to check for - if found, otherwise - - - Check if Value exists in Dictionary - Value to check for - if found, otherwise - - - - Adds the specified key to the dictionary, dictionary locking is not performed, - - - The key - The value - - - - Removes the specified key, dictionary locking is not performed - - The key. - if successful, otherwise - - - - Indexer for the dictionary - - The key - The value - - - - Exception class to identify inventory exceptions - - - - - Responsible for maintaining inventory structure. Inventory constructs nodes - and manages node children as is necessary to maintain a coherant hirarchy. - Other classes should not manipulate or create InventoryNodes explicitly. When - A node's parent changes (when a folder is moved, for example) simply pass - Inventory the updated InventoryFolder and it will make the appropriate changes - to its internal representation. - - - - The event subscribers, null of no subscribers - - - Raises the InventoryObjectUpdated Event - A InventoryObjectUpdatedEventArgs object containing - the data sent from the simulator - - - Thread sync lock object - - - Raised when the simulator sends us data containing - ... - - - The event subscribers, null of no subscribers - - - Raises the InventoryObjectRemoved Event - A InventoryObjectRemovedEventArgs object containing - the data sent from the simulator - - - Thread sync lock object - - - Raised when the simulator sends us data containing - ... - - - The event subscribers, null of no subscribers - - - Raises the InventoryObjectAdded Event - A InventoryObjectAddedEventArgs object containing - the data sent from the simulator - - - Thread sync lock object - - - Raised when the simulator sends us data containing - ... - - - - The root folder of this avatars inventory - - - - - The default shared library folder - - - - - The root node of the avatars inventory - - - - - The root node of the default shared library - - - - - Returns the contents of the specified folder - - A folder's UUID - The contents of the folder corresponding to folder - When folder does not exist in the inventory - - - - Updates the state of the InventoryNode and inventory data structure that - is responsible for the InventoryObject. If the item was previously not added to inventory, - it adds the item, and updates structure accordingly. If it was, it updates the - InventoryNode, changing the parent node if item.parentUUID does - not match node.Parent.Data.UUID. - - You can not set the inventory root folder using this method - - The InventoryObject to store - - - - Removes the InventoryObject and all related node data from Inventory. - - The InventoryObject to remove. - - - - Used to find out if Inventory contains the InventoryObject - specified by uuid. - - The UUID to check. - true if inventory contains uuid, false otherwise - - - - Saves the current inventory structure to a cache file - - Name of the cache file to save to - - - - Loads in inventory cache file into the inventory structure. Note only valid to call after login has been successful. - - Name of the cache file to load - The number of inventory items sucessfully reconstructed into the inventory node tree - - - - By using the bracket operator on this class, the program can get the - InventoryObject designated by the specified uuid. If the value for the corresponding - UUID is null, the call is equivelant to a call to RemoveNodeFor(this[uuid]). - If the value is non-null, it is equivelant to a call to UpdateNodeFor(value), - the uuid parameter is ignored. - - The UUID of the InventoryObject to get or set, ignored if set to non-null value. - The InventoryObject corresponding to uuid. - - - Sort by name - - - Sort by date - - - Sort folders by name, regardless of whether items are - sorted by name or date - - - Place system folders at the top - - - - Possible destinations for DeRezObject request - - - - - - - Copy from in-world to agent inventory - - - Derez to TaskInventory - - - - - - Take Object - - - - - - Delete Object - - - Put an avatar attachment into agent inventory - - - - - - Return an object back to the owner's inventory - - - Return a deeded object back to the last owner's inventory - - - - Upper half of the Flags field for inventory items - - - - Indicates that the NextOwner permission will be set to the - most restrictive set of permissions found in the object set - (including linkset items and object inventory items) on next rez - - - Indicates that the object sale information has been - changed - - - If set, and a slam bit is set, indicates BaseMask will be overwritten on Rez - - - If set, and a slam bit is set, indicates OwnerMask will be overwritten on Rez - - - If set, and a slam bit is set, indicates GroupMask will be overwritten on Rez - - - If set, and a slam bit is set, indicates EveryoneMask will be overwritten on Rez - - - If set, and a slam bit is set, indicates NextOwnerMask will be overwritten on Rez - - - Indicates whether this object is composed of multiple - items or not - - - Indicates that the asset is only referenced by this - inventory item. If this item is deleted or updated to reference a - new assetID, the asset can be deleted - - - - Base Class for Inventory Items - - - - of item/folder - - - of parent folder - - - Name of item/folder - - - Item/Folder Owners - - - - Constructor, takes an itemID as a parameter - - The of the item - - - - - - - - - - - - - - - - Generates a number corresponding to the value of the object to support the use of a hash table, - suitable for use in hashing algorithms and data structures such as a hash table - - A Hashcode of all the combined InventoryBase fields - - - - Determine whether the specified object is equal to the current object - - InventoryBase object to compare against - true if objects are the same - - - - Determine whether the specified object is equal to the current object - - InventoryBase object to compare against - true if objects are the same - - - - Convert inventory to OSD - - OSD representation - - - - An Item in Inventory - - - - The of this item - - - The combined of this item - - - The type of item from - - - The type of item from the enum - - - The of the creator of this item - - - A Description of this item - - - The s this item is set to or owned by - - - If true, item is owned by a group - - - The price this item can be purchased for - - - The type of sale from the enum - - - Combined flags from - - - Time and date this inventory item was created, stored as - UTC (Coordinated Universal Time) - - - Used to update the AssetID in requests sent to the server - - - The of the previous owner of the item - - - - Construct a new InventoryItem object - - The of the item - - - - Construct a new InventoryItem object of a specific Type - - The type of item from - of the item - - - - Indicates inventory item is a link - - True if inventory item is a link to another inventory item - - - - - - - - - - - - - - - - Generates a number corresponding to the value of the object to support the use of a hash table. - Suitable for use in hashing algorithms and data structures such as a hash table - - A Hashcode of all the combined InventoryItem fields - - - - Compares an object - - The object to compare - true if comparison object matches - - - - Determine whether the specified object is equal to the current object - - The object to compare against - true if objects are the same - - - - Determine whether the specified object is equal to the current object - - The object to compare against - true if objects are the same - - - - Create InventoryItem from OSD - - OSD Data that makes up InventoryItem - Inventory item created - - - - Convert InventoryItem to OSD - - OSD representation of InventoryItem - - - - InventoryTexture Class representing a graphical image - - - - - - Construct an InventoryTexture object - - A which becomes the - objects AssetUUID - - - - Construct an InventoryTexture object from a serialization stream - - - - - InventorySound Class representing a playable sound - - - - - Construct an InventorySound object - - A which becomes the - objects AssetUUID - - - - Construct an InventorySound object from a serialization stream - - - - - InventoryCallingCard Class, contains information on another avatar - - - - - Construct an InventoryCallingCard object - - A which becomes the - objects AssetUUID - - - - Construct an InventoryCallingCard object from a serialization stream - - - - - InventoryLandmark Class, contains details on a specific location - - - - - Construct an InventoryLandmark object - - A which becomes the - objects AssetUUID - - - - Construct an InventoryLandmark object from a serialization stream - - - - - Landmarks use the InventoryItemFlags struct and will have a flag of 1 set if they have been visited - - - - - InventoryObject Class contains details on a primitive or coalesced set of primitives - - - - - Construct an InventoryObject object - - A which becomes the - objects AssetUUID - - - - Construct an InventoryObject object from a serialization stream - - - - - Gets or sets the upper byte of the Flags value - - - - - Gets or sets the object attachment point, the lower byte of the Flags value - - - - - InventoryNotecard Class, contains details on an encoded text document - - - - - Construct an InventoryNotecard object - - A which becomes the - objects AssetUUID - - - - Construct an InventoryNotecard object from a serialization stream - - - - - InventoryCategory Class - - TODO: Is this even used for anything? - - - - Construct an InventoryCategory object - - A which becomes the - objects AssetUUID - - - - Construct an InventoryCategory object from a serialization stream - - - - - InventoryLSL Class, represents a Linden Scripting Language object - - - - - Construct an InventoryLSL object - - A which becomes the - objects AssetUUID - - - - Construct an InventoryLSL object from a serialization stream - - - - - InventorySnapshot Class, an image taken with the viewer - - - - - Construct an InventorySnapshot object - - A which becomes the - objects AssetUUID - - - - Construct an InventorySnapshot object from a serialization stream - - - - - InventoryAttachment Class, contains details on an attachable object - - - - - Construct an InventoryAttachment object - - A which becomes the - objects AssetUUID - - - - Construct an InventoryAttachment object from a serialization stream - - - - - Get the last AttachmentPoint this object was attached to - - - - - InventoryWearable Class, details on a clothing item or body part - - - - - Construct an InventoryWearable object - - A which becomes the - objects AssetUUID - - - - Construct an InventoryWearable object from a serialization stream - - - - - The , Skin, Shape, Skirt, Etc - - - - - InventoryAnimation Class, A bvh encoded object which animates an avatar - - - - - Construct an InventoryAnimation object - - A which becomes the - objects AssetUUID - - - - Construct an InventoryAnimation object from a serialization stream - - - - - InventoryGesture Class, details on a series of animations, sounds, and actions - - - - - Construct an InventoryGesture object - - A which becomes the - objects AssetUUID - - - - Construct an InventoryGesture object from a serialization stream - - - - - A folder contains s and has certain attributes specific - to itself - - - - The Preferred for a folder. - - - The Version of this folder - - - Number of child items this folder contains. - - - - Constructor - - UUID of the folder - - - - - - - - - - Get Serilization data for this InventoryFolder object - - - - - Construct an InventoryFolder object from a serialization stream - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create InventoryFolder from OSD - - OSD Data that makes up InventoryFolder - Inventory folder created - - - - Convert InventoryItem to OSD - - OSD representation of InventoryItem - - - - Tools for dealing with agents inventory - - - - Used for converting shadow_id to asset_id - - - - Callback for inventory item creation finishing - - Whether the request to create an inventory - item succeeded or not - Inventory item being created. If success is - false this will be null - - - - Callback for an inventory item being create from an uploaded asset - - true if inventory item creation was successful - - - - - - - - - - - - The event subscribers, null of no subscribers - - - Raises the ItemReceived Event - A ItemReceivedEventArgs object containing - the data sent from the simulator - - - Thread sync lock object - - - Raised when the simulator sends us data containing - ... - - - The event subscribers, null of no subscribers - - - Raises the FolderUpdated Event - A FolderUpdatedEventArgs object containing - the data sent from the simulator - - - Thread sync lock object - - - Raised when the simulator sends us data containing - ... - - - The event subscribers, null of no subscribers - - - Raises the InventoryObjectOffered Event - A InventoryObjectOfferedEventArgs object containing - the data sent from the simulator - - - Thread sync lock object - - - Raised when the simulator sends us data containing - an inventory object sent by another avatar or primitive - - - The event subscribers, null of no subscribers - - - Raises the TaskItemReceived Event - A TaskItemReceivedEventArgs object containing - the data sent from the simulator - - - Thread sync lock object - - - Raised when the simulator sends us data containing - ... - - - The event subscribers, null of no subscribers - - - Raises the FindObjectByPath Event - A FindObjectByPathEventArgs object containing - the data sent from the simulator - - - Thread sync lock object - - - Raised when the simulator sends us data containing - ... - - - The event subscribers, null of no subscribers - - - Raises the TaskInventoryReply Event - A TaskInventoryReplyEventArgs object containing - the data sent from the simulator - - - Thread sync lock object - - - Raised when the simulator sends us data containing - ... - - - - Reply received when uploading an inventory asset - - Has upload been successful - Error message if upload failed - Inventory asset UUID - New asset UUID - - - The event subscribers, null of no subscribers - - - Raises the SaveAssetToInventory Event - A SaveAssetToInventoryEventArgs object containing - the data sent from the simulator - - - Thread sync lock object - - - Raised when the simulator sends us data containing - ... - - - - Delegate that is invoked when script upload is completed - - Has upload succeded (note, there still might be compile errors) - Upload status message - Is compilation successful - If compilation failed, list of error messages, null on compilation success - Script inventory UUID - Script's new asset UUID - - - The event subscribers, null of no subscribers - - - Raises the ScriptRunningReply Event - A ScriptRunningReplyEventArgs object containing - the data sent from the simulator - - - Thread sync lock object - - - Raised when the simulator sends us data containing - ... - - - Partial mapping of FolderTypes to folder names - - - - Get this agents Inventory data - - - - - Default constructor - - Reference to the GridClient object - - - - Fetch an inventory item from the dataserver - - The items - The item Owners - a integer representing the number of milliseconds to wait for results - An object on success, or null if no item was found - Items will also be sent to the event - - - - Request A single inventory item - - The items - The item Owners - - - - - Request inventory items - - Inventory items to request - Owners of the inventory items - - - - - Request inventory items via Capabilities - - Inventory items to request - Owners of the inventory items - - - - - Get contents of a folder - - The of the folder to search - The of the folders owner - true to retrieve folders - true to retrieve items - sort order to return results in - a integer representing the number of milliseconds to wait for results - A list of inventory items matching search criteria within folder - - InventoryFolder.DescendentCount will only be accurate if both folders and items are - requested - - - - Request the contents of an inventory folder - - The folder to search - The folder owners - true to return s contained in folder - true to return s containd in folder - the sort order to return items in - - - - - Request the contents of an inventory folder using HTTP capabilities - - The folder to search - The folder owners - true to return s contained in folder - true to return s containd in folder - the sort order to return items in - - - - - Returns the UUID of the folder (category) that defaults to - containing 'type'. The folder is not necessarily only for that - type - - This will return the root folder if one does not exist - - The UUID of the desired folder if found, the UUID of the RootFolder - if not found, or UUID.Zero on failure - - - - Find an object in inventory using a specific path to search - - The folder to begin the search in - The object owners - A string path to search - milliseconds to wait for a reply - Found items or if - timeout occurs or item is not found - - - - Find inventory items by path - - The folder to begin the search in - The object owners - A string path to search, folders/objects separated by a '/' - Results are sent to the event - - - - Search inventory Store object for an item or folder - - The folder to begin the search in - An array which creates a path to search - Number of levels below baseFolder to conduct searches - if True, will stop searching after first match is found - A list of inventory items found - - - - Move an inventory item or folder to a new location - - The item or folder to move - The to move item or folder to - - - - Move an inventory item or folder to a new location and change its name - - The item or folder to move - The to move item or folder to - The name to change the item or folder to - - - - Move and rename a folder - - The source folders - The destination folders - The name to change the folder to - - - - Update folder properties - - of the folder to update - Sets folder's parent to - Folder name - Folder type - - - - Move a folder - - The source folders - The destination folders - - - - Move multiple folders, the keys in the Dictionary parameter, - to a new parents, the value of that folder's key. - - A Dictionary containing the - of the source as the key, and the - of the destination as the value - - - - Move an inventory item to a new folder - - The of the source item to move - The of the destination folder - - - - Move and rename an inventory item - - The of the source item to move - The of the destination folder - The name to change the folder to - - - - Move multiple inventory items to new locations - - A Dictionary containing the - of the source item as the key, and the - of the destination folder as the value - - - - Remove descendants of a folder - - The of the folder - - - - Remove a single item from inventory - - The of the inventory item to remove - - - - Remove a folder from inventory - - The of the folder to remove - - - - Remove multiple items or folders from inventory - - A List containing the s of items to remove - A List containing the s of the folders to remove - - - - Empty the Lost and Found folder - - - - - Empty the Trash folder - - - - - - - - - - - Proper use is to upload the inventory's asset first, then provide the Asset's TransactionID here. - - - - - - - - - - - - - Proper use is to upload the inventory's asset first, then provide the Asset's TransactionID here. - - - - - - - - Creates a new inventory folder - - ID of the folder to put this folder in - Name of the folder to create - The UUID of the newly created folder - - - - Creates a new inventory folder - - ID of the folder to put this folder in - Name of the folder to create - Sets this folder as the default folder - for new assets of the specified type. Use FolderType.None - to create a normal folder, otherwise it will likely create a - duplicate of an existing folder type - The UUID of the newly created folder - If you specify a preferred type of AsseType.Folder - it will create a new root folder which may likely cause all sorts - of strange problems - - - - Create an inventory item and upload asset data - - Asset data - Inventory item name - Inventory item description - Asset type - Inventory type - Put newly created inventory in this folder - Delegate that will receive feedback on success or failure - - - - Create an inventory item and upload asset data - - Asset data - Inventory item name - Inventory item description - Asset type - Inventory type - Put newly created inventory in this folder - Permission of the newly created item - (EveryoneMask, GroupMask, and NextOwnerMask of Permissions struct are supported) - Delegate that will receive feedback on success or failure - - - - Creates inventory link to another inventory item or folder - - Put newly created link in folder with this UUID - Inventory item or folder - Method to call upon creation of the link - - - - Creates inventory link to another inventory item - - Put newly created link in folder with this UUID - Original inventory item - Method to call upon creation of the link - - - - Creates inventory link to another inventory folder - - Put newly created link in folder with this UUID - Original inventory folder - Method to call upon creation of the link - - - - Creates inventory link to another inventory item or folder - - Put newly created link in folder with this UUID - Original item's UUID - Name - Description - Asset Type - Inventory Type - Transaction UUID - Method to call upon creation of the link - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Request a copy of an asset embedded within a notecard - - Usually UUID.Zero for copying an asset from a notecard - UUID of the notecard to request an asset from - Target folder for asset to go to in your inventory - UUID of the embedded asset - callback to run when item is copied to inventory - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Save changes to notecard embedded in object contents - - Encoded notecard asset data - Notecard UUID - Object's UUID - Called upon finish of the upload with status information - - - - Upload new gesture asset for an inventory gesture item - - Encoded gesture asset - Gesture inventory UUID - Callback whick will be called when upload is complete - - - - Update an existing script in an agents Inventory - - A byte[] array containing the encoded scripts contents - the itemID of the script - if true, sets the script content to run on the mono interpreter - - - - - Update an existing script in an task Inventory - - A byte[] array containing the encoded scripts contents - the itemID of the script - UUID of the prim containting the script - if true, sets the script content to run on the mono interpreter - if true, sets the script to running - - - - - Rez an object from inventory - - Simulator to place object in - Rotation of the object when rezzed - Vector of where to place object - InventoryItem object containing item details - - - - Rez an object from inventory - - Simulator to place object in - Rotation of the object when rezzed - Vector of where to place object - InventoryItem object containing item details - UUID of group to own the object - - - - Rez an object from inventory - - Simulator to place object in - Rotation of the object when rezzed - Vector of where to place object - InventoryItem object containing item details - UUID of group to own the object - User defined queryID to correlate replies - If set to true, the CreateSelected flag - will be set on the rezzed object - - - - Rez an object from inventory - - Simulator to place object in - TaskID object when rezzed - Rotation of the object when rezzed - Vector of where to place object - InventoryItem object containing item details - UUID of group to own the object - User defined queryID to correlate replies - If set to true, the CreateSelected flag - will be set on the rezzed object - - - - DeRez an object from the simulator to the agents Objects folder in the agents Inventory - - The simulator Local ID of the object - If objectLocalID is a child primitive in a linkset, the entire linkset will be derezzed - - - - DeRez an object from the simulator and return to inventory - - The simulator Local ID of the object - The type of destination from the enum - The destination inventory folders -or- - if DeRezzing object to a tasks Inventory, the Tasks - The transaction ID for this request which - can be used to correlate this request with other packets - If objectLocalID is a child primitive in a linkset, the entire linkset will be derezzed - - - - Rez an item from inventory to its previous simulator location - - - - - - - - - Give an inventory item to another avatar - - The of the item to give - The name of the item - The type of the item from the enum - The of the recipient - true to generate a beameffect during transfer - - - - Give an inventory Folder with contents to another avatar - - The of the Folder to give - The name of the folder - The type of the item from the enum - The of the recipient - true to generate a beameffect during transfer - - - - Copy or move an from agent inventory to a task (primitive) inventory - - The target object - The item to copy or move from inventory - - For items with copy permissions a copy of the item is placed in the tasks inventory, - for no-copy items the object is moved to the tasks inventory - - - - Retrieve a listing of the items contained in a task (Primitive) - - The tasks - The tasks simulator local ID - milliseconds to wait for reply from simulator - A list containing the inventory items inside the task or null - if a timeout occurs - This request blocks until the response from the simulator arrives - or timeoutMS is exceeded - - - - Request the contents of a tasks (primitives) inventory from the - current simulator - - The LocalID of the object - - - - - Request the contents of a tasks (primitives) inventory - - The simulator Local ID of the object - A reference to the simulator object that contains the object - - - - - Move an item from a tasks (Primitive) inventory to the specified folder in the avatars inventory - - LocalID of the object in the simulator - UUID of the task item to move - The ID of the destination folder in this agents inventory - Simulator Object - Raises the event - - - - Remove an item from an objects (Prim) Inventory - - LocalID of the object in the simulator - UUID of the task item to remove - Simulator Object - You can confirm the removal by comparing the tasks inventory serial before and after the - request with the request combined with - the event - - - - Copy an InventoryScript item from the Agents Inventory into a primitives task inventory - - An unsigned integer representing a primitive being simulated - An which represents a script object from the agents inventory - true to set the scripts running state to enabled - A Unique Transaction ID - - The following example shows the basic steps necessary to copy a script from the agents inventory into a tasks inventory - and assumes the script exists in the agents inventory. - - uint primID = 95899503; // Fake prim ID - UUID scriptID = UUID.Parse("92a7fe8a-e949-dd39-a8d8-1681d8673232"); // Fake Script UUID in Inventory - - Client.Inventory.FolderContents(Client.Inventory.FindFolderForType(AssetType.LSLText), Client.Self.AgentID, - false, true, InventorySortOrder.ByName, 10000); - - Client.Inventory.RezScript(primID, (InventoryItem)Client.Inventory.Store[scriptID]); - - - - - - Request the running status of a script contained in a task (primitive) inventory - - The ID of the primitive containing the script - The ID of the script - The event can be used to obtain the results of the - request - - - - - Send a request to set the running state of a script contained in a task (primitive) inventory - - The ID of the primitive containing the script - The ID of the script - true to set the script running, false to stop a running script - To verify the change you can use the method combined - with the event - - - - Create a CRC from an InventoryItem - - The source InventoryItem - A uint representing the source InventoryItem as a CRC - - - - Reverses a cheesy XORing with a fixed UUID to convert a shadow_id to an asset_id - - Obfuscated shadow_id value - Deobfuscated asset_id value - - - - Does a cheesy XORing with a fixed UUID to convert an asset_id to a shadow_id - - asset_id value to obfuscate - Obfuscated shadow_id value - - - - Wrapper for creating a new object - - The type of item from the enum - The of the newly created object - An object with the type and id passed - - - - Parse the results of a RequestTaskInventory() response - - A string which contains the data from the task reply - A List containing the items contained within the tasks inventory - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - - UpdateCreateInventoryItem packets are received when a new inventory item - is created. This may occur when an object that's rezzed in world is - taken into inventory, when an item is created using the CreateInventoryItem - packet, or when an object is purchased - - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Set to true to accept offer, false to decline it - - - The folder to accept the inventory into, if null default folder for will be used - - - - Callback when an inventory object is accepted and received from a - task inventory. This is the callback in which you actually get - the ItemID, as in ObjectOfferedCallback it is null when received - from a task. - - - - - - - User data - - - - - - - - - - - - - For inventory folder nodes specifies weather the folder needs to be - refreshed from the server - - - - - - - - - - - - - - - - De-serialization constructor for the InventoryNode Class - - - - - Serialization handler for the InventoryNode Class - - - - - De-serialization handler for the InventoryNode Class - - - - - - - - - - - Singleton logging class for the entire library - - - - - Callback used for client apps to receive log messages from - the library - - Data being logged - The severity of the log entry from - - - Triggered whenever a message is logged. If this is left - null, log messages will go to the console - - - log4net logging engine - - - - Default constructor - - - - - Send a log message to the logging engine - - The log message - The severity of the log entry - - - - Send a log message to the logging engine - - The log message - The severity of the log entry - Instance of the client - - - - Send a log message to the logging engine - - The log message - The severity of the log entry - Exception that was raised - - - - Send a log message to the logging engine - - The log message - The severity of the log entry - Instance of the client - Exception that was raised - - - - If the library is compiled with DEBUG defined, an event will be - fired if an OnLogMessage handler is registered and the - message will be sent to the logging engine - - The message to log at the DEBUG level to the - current logging engine - - - - If the library is compiled with DEBUG defined and - GridClient.Settings.DEBUG is true, an event will be - fired if an OnLogMessage handler is registered and the - message will be sent to the logging engine - - The message to log at the DEBUG level to the - current logging engine - Instance of the client - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Status of the last application run. - Used for error reporting to the grid login service for statistical purposes. - - - - Application exited normally - - - Application froze - - - Application detected error and exited abnormally - - - Other crash - - - Application froze during logout - - - Application crashed during logout - - - - Login Request Parameters - - - - The URL of the Login Server - - - The number of milliseconds to wait before a login is considered - failed due to timeout - - - The request method - login_to_simulator is currently the only supported method - - - The Agents First name - - - The Agents Last name - - - A md5 hashed password - plaintext password will be automatically hashed - - - The agents starting location once logged in - Either "last", "home", or a string encoded URI - containing the simulator name and x/y/z coordinates e.g: uri:hooper&128&152&17 - - - A string containing the client software channel information - Second Life Release - - - The client software version information - The official viewer uses: Second Life Release n.n.n.n - where n is replaced with the current version of the viewer - - - A string containing the platform information the agent is running on - - - A string containing version number for OS the agent is running on - - - A string hash of the network cards Mac Address - - - Unknown or deprecated - - - A string hash of the first disk drives ID used to identify this clients uniqueness - - - A string containing the viewers Software, this is not directly sent to the login server but - instead is used to generate the Version string - - - A string representing the software creator. This is not directly sent to the login server but - is used by the library to generate the Version information - - - If true, this agent agrees to the Terms of Service of the grid its connecting to - - - Unknown - - - Status of the last application run sent to the grid login server for statistical purposes - - - An array of string sent to the login server to enable various options - - - A randomly generated ID to distinguish between login attempts. This value is only used - internally in the library and is never sent over the wire - - - - Default constuctor, initializes sane default values - - - - - Instantiates new LoginParams object and fills in the values - - Instance of GridClient to read settings from - Login first name - Login last name - Password - Login channnel (application name) - Client version, should be application name + version number - - - - Instantiates new LoginParams object and fills in the values - - Instance of GridClient to read settings from - Login first name - Login last name - Password - Login channnel (application name) - Client version, should be application name + version number - URI of the login server - - - - The decoded data returned from the login server after a successful login - - - - true, false, indeterminate - - - Login message of the day - - - M or PG, also agent_region_access and agent_access_max - - - - Parse LLSD Login Reply Data - - An - contaning the login response data - XML-RPC logins do not require this as XML-RPC.NET - automatically populates the struct properly using attributes - - - - Login Routines - - - NetworkManager is responsible for managing the network layer of - OpenMetaverse. It tracks all the server connections, serializes - outgoing traffic and deserializes incoming traffic, and provides - instances of delegates for network-related events. - - - - The event subscribers, null of no subscribers - - - Raises the LoginProgress Event - A LoginProgressEventArgs object containing - the data sent from the simulator - - - Thread sync lock object - - - Raised when the simulator sends us data containing - ... - - - - - - - - - - - - - Called when a reply is received from the login server, the - login sequence will block until this event returns - - - Seed CAPS URL returned from the login server - - - Current state of logging in - - - Upon login failure, contains a short string key for the - type of login error that occurred - - - The raw XML-RPC reply from the login server, exactly as it - was received (minus the HTTP header) - - - During login this contains a descriptive version of - LoginStatusCode. After a successful login this will contain the - message of the day, and after a failed login a descriptive error - message will be returned - - - Maximum number of groups an agent can belong to, -1 for unlimited - - - Server side baking service URL - - - Parsed login response data - - - A list of packets obtained during the login process which - networkmanager will log but not process - - - - Generate sane default values for a login request - - Account first name - Account last name - Account password - Client application name (channel) - Client application name + version - A populated struct containing - sane defaults - - - - Simplified login that takes the most common and required fields - - Account first name - Account last name - Account password - Client application name (channel) - Client application name + version - Whether the login was successful or not. On failure the - LoginErrorKey string will contain the error code and LoginMessage - will contain a description of the error - - - - Simplified login that takes the most common fields along with a - starting location URI, and can accept an MD5 string instead of a - plaintext password - - Account first name - Account last name - Account password or MD5 hash of the password - such as $1$1682a1e45e9f957dcdf0bb56eb43319c - Client application name (channel) - Starting location URI that can be built with - StartLocation() - Client application name + version - Whether the login was successful or not. On failure the - LoginErrorKey string will contain the error code and LoginMessage - will contain a description of the error - - - - Login that takes a struct of all the values that will be passed to - the login server - - The values that will be passed to the login - server, all fields must be set even if they are String.Empty - Whether the login was successful or not. On failure the - LoginErrorKey string will contain the error code and LoginMessage - will contain a description of the error - - - - Build a start location URI for passing to the Login function - - Name of the simulator to start in - X coordinate to start at - Y coordinate to start at - Z coordinate to start at - String with a URI that can be used to login to a specified - location - - - - LoginParams and the initial login XmlRpcRequest were made on a remote machine. - This method now initializes libomv with the results. - - - - - Handles response from XML-RPC login replies - - - - - Handles response from XML-RPC login replies with already parsed LoginResponseData - - - - - Handle response from LLSD login replies - - - - - - - - Get current OS - - Either "Win" or "Linux" - - - - Gets the current OS version number - - The platform version. - - - - Get clients default Mac Address - - A string containing the first found Mac Address - - - - Explains why a simulator or the grid disconnected from us - - - - The client requested the logout or simulator disconnect - - - The server notified us that it is disconnecting - - - Either a socket was closed or network traffic timed out - - - The last active simulator shut down - - - - Holds a simulator reference and a decoded packet, these structs are put in - the packet inbox for event handling - - - - Reference to the simulator that this packet came from - - - Packet that needs to be processed - - - - Holds a simulator reference and a serialized packet, these structs are put in - the packet outbox for sending - - - - Reference to the simulator this packet is destined for - - - Packet that needs to be sent - - - Sequence number of the wrapped packet - - - Number of times this packet has been resent - - - Environment.TickCount when this packet was last sent over the wire - - - Type of the packet - - - The event subscribers, null of no subscribers - - - Raises the PacketSent Event - A PacketSentEventArgs object containing - the data sent from the simulator - - - Thread sync lock object - - - Raised when the simulator sends us data containing - ... - - - The event subscribers, null of no subscribers - - - Raises the LoggedOut Event - A LoggedOutEventArgs object containing - the data sent from the simulator - - - Thread sync lock object - - - Raised when the simulator sends us data containing - ... - - - The event subscribers, null of no subscribers - - - Raises the SimConnecting Event - A SimConnectingEventArgs object containing - the data sent from the simulator - - - Thread sync lock object - - - Raised when the simulator sends us data containing - ... - - - The event subscribers, null of no subscribers - - - Raises the SimConnected Event - A SimConnectedEventArgs object containing - the data sent from the simulator - - - Thread sync lock object - - - Raised when the simulator sends us data containing - ... - - - The event subscribers, null of no subscribers - - - Raises the SimDisconnected Event - A SimDisconnectedEventArgs object containing - the data sent from the simulator - - - Thread sync lock object - - - Raised when the simulator sends us data containing - ... - - - The event subscribers, null of no subscribers - - - Raises the Disconnected Event - A DisconnectedEventArgs object containing - the data sent from the simulator - - - Thread sync lock object - - - Raised when the simulator sends us data containing - ... - - - The event subscribers, null of no subscribers - - - Raises the SimChanged Event - A SimChangedEventArgs object containing - the data sent from the simulator - - - Thread sync lock object - - - Raised when the simulator sends us data containing - ... - - - The event subscribers, null of no subscribers - - - Raises the EventQueueRunning Event - A EventQueueRunningEventArgs object containing - the data sent from the simulator - - - Thread sync lock object - - - Raised when the simulator sends us data containing - ... - - - Unique identifier associated with our connections to - simulators - - - The simulator that the logged in avatar is currently - occupying - - - Shows whether the network layer is logged in to the - grid or not - - - Number of packets in the incoming queue - - - Number of packets in the outgoing queue - - - All of the simulators we are currently connected to - - - Handlers for incoming capability events - - - Handlers for incoming packets - - - Incoming packets that are awaiting handling - - - Outgoing packets that are awaiting handling - - - - Default constructor - - Reference to the GridClient object - - - - Register an event handler for a packet. This is a low level event - interface and should only be used if you are doing something not - supported in the library - - Packet type to trigger events for - Callback to fire when a packet of this type - is received - - - - Register an event handler for a packet. This is a low level event - interface and should only be used if you are doing something not - supported in the library - - Packet type to trigger events for - Callback to fire when a packet of this type - is received - True if the callback should be ran - asynchronously. Only set this to false (synchronous for callbacks - that will always complete quickly) - If any callback for a packet type is marked as - asynchronous, all callbacks for that packet type will be fired - asynchronously - - - - Unregister an event handler for a packet. This is a low level event - interface and should only be used if you are doing something not - supported in the library - - Packet type this callback is registered with - Callback to stop firing events for - - - - Register a CAPS event handler. This is a low level event interface - and should only be used if you are doing something not supported in - the library - - Name of the CAPS event to register a handler for - Callback to fire when a CAPS event is received - - - - Unregister a CAPS event handler. This is a low level event interface - and should only be used if you are doing something not supported in - the library - - Name of the CAPS event this callback is - registered with - Callback to stop firing events for - - - - Send a packet to the simulator the avatar is currently occupying - - Packet to send - - - - Send a packet to a specified simulator - - Packet to send - Simulator to send the packet to - - - - Connect to a simulator - - IP address to connect to - Port to connect to - Handle for this simulator, to identify its - location in the grid - Whether to set CurrentSim to this new - connection, use this if the avatar is moving in to this simulator - URL of the capabilities server to use for - this sim connection - A Simulator object on success, otherwise null - - - - Connect to a simulator - - IP address and port to connect to - Handle for this simulator, to identify its - location in the grid - Whether to set CurrentSim to this new - connection, use this if the avatar is moving in to this simulator - URL of the capabilities server to use for - this sim connection - A Simulator object on success, otherwise null - - - - Begins the non-blocking logout. Makes sure that the LoggedOut event is - called even if the server does not send a logout reply, and Shutdown() - is properly called. - - - - - Initiate a blocking logout request. This will return when the logout - handshake has completed or when Settings.LOGOUT_TIMEOUT - has expired and the network layer is manually shut down - - - - - Initiate the logout process. The Shutdown() function - needs to be manually called. - - - - - Close a connection to the given simulator - - - - - - - Shutdown will disconnect all the sims except for the current sim - first, and then kill the connection to CurrentSim. This should only - be called if the logout process times out on RequestLogout - - Type of shutdown - - - - Shutdown will disconnect all the sims except for the current sim - first, and then kill the connection to CurrentSim. This should only - be called if the logout process times out on RequestLogout - - Type of shutdown - Shutdown message - - - - Searches through the list of currently connected simulators to find - one attached to the given IPEndPoint - - IPEndPoint of the Simulator to search for - A Simulator reference on success, otherwise null - - - - Fire an event when an event queue connects for capabilities - - Simulator the event queue is attached to - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - - A Name Value pair with additional settings, used in the protocol - primarily to transmit avatar names and active group in object packets - - - - Type of the value - - - Unknown - - - String value - - - - - - - - - - - - - - - Deprecated - - - String value, but designated as an asset - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Constructor that takes all the fields as parameters - - - - - - - - - - Constructor that takes a single line from a NameValue field - - - - - - - - - - No report - - - Unknown report type - - - Bug report - - - Complaint report - - - Customer service report - - - - Bitflag field for ObjectUpdateCompressed data blocks, describing - which options are present for each object - - - - Unknown - - - Whether the object has a TreeSpecies - - - Whether the object has floating text ala llSetText - - - Whether the object has an active particle system - - - Whether the object has sound attached to it - - - Whether the object is attached to a root object or not - - - Whether the object has texture animation settings - - - Whether the object has an angular velocity - - - Whether the object has a name value pairs string - - - Whether the object has a Media URL set - - - - Specific Flags for MultipleObjectUpdate requests - - - - None - - - Change position of prims - - - Change rotation of prims - - - Change size of prims - - - Perform operation on link set - - - Scale prims uniformly, same as selecing ctrl+shift in the - viewer. Used in conjunction with Scale - - - - Special values in PayPriceReply. If the price is not one of these - literal value of the price should be use - - - - - Indicates that this pay option should be hidden - - - - - Indicates that this pay option should have the default value - - - - - Contains the variables sent in an object update packet for objects. - Used to track position and movement of prims and avatars - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Handles all network traffic related to prims and avatar positions and - movement. - - - - The event subscribers, null of no subscribers - - - Thread sync lock object - - - Raised when the simulator sends us data containing - A , Foliage or Attachment - - - - - The event subscribers, null of no subscribers - - - Raises the ObjectProperties Event - A ObjectPropertiesEventArgs object containing - the data sent from the simulator - - - Thread sync lock object - - - Raised when the simulator sends us data containing - additional information - - - - - The event subscribers, null of no subscribers - - - Raises the ObjectPropertiesUpdated Event - A ObjectPropertiesUpdatedEventArgs object containing - the data sent from the simulator - - - Thread sync lock object - - - Raised when the simulator sends us data containing - Primitive.ObjectProperties for an object we are currently tracking - - - The event subscribers, null of no subscribers - - - Raises the ObjectPropertiesFamily Event - A ObjectPropertiesFamilyEventArgs object containing - the data sent from the simulator - - - Thread sync lock object - - - Raised when the simulator sends us data containing - additional and details - - - - The event subscribers, null of no subscribers - - - Raises the AvatarUpdate Event - A AvatarUpdateEventArgs object containing - the data sent from the simulator - - - - Raises the ParticleUpdate Event - - A ParticleUpdateEventArgs object containing - the data sent from the simulator - - - Thread sync lock object - - - Raised when the simulator sends us data containing - updated information for an - - - The event subscribers, null of no subscribers - - - Thread sync lock object - - - Raised when the simulator sends us data containing - and movement changes - - - The event subscribers, null of no subscribers - - - Raises the ObjectDataBlockUpdate Event - A ObjectDataBlockUpdateEventArgs object containing - the data sent from the simulator - - - Thread sync lock object - - - Raised when the simulator sends us data containing - updates to an Objects DataBlock - - - The event subscribers, null of no subscribers - - - Raises the KillObject Event - A KillObjectEventArgs object containing - the data sent from the simulator - - - Thread sync lock object - - - Raised when the simulator informs us an - or is no longer within view - - - The event subscribers, null of no subscribers - - - Raises the KillObjects Event - A KillObjectsEventArgs object containing - the data sent from the simulator - - - Thread sync lock object - - - Raised when the simulator informs us when a group of - or is no longer within view - - - The event subscribers, null of no subscribers - - - Raises the AvatarSitChanged Event - A AvatarSitChangedEventArgs object containing - the data sent from the simulator - - - Thread sync lock object - - - Raised when the simulator sends us data containing - updated sit information for our - - - The event subscribers, null of no subscribers - - - Raises the PayPriceReply Event - A PayPriceReplyEventArgs object containing - the data sent from the simulator - - - Thread sync lock object - - - Raised when the simulator sends us data containing - purchase price information for a - - - - Callback for getting object media data via CAP - - Indicates if the operation was succesfull - Object media version string - Array indexed on prim face of media entry data - - - The event subscribers, null of no subscribers - - - Raises the PhysicsProperties Event - A PhysicsPropertiesEventArgs object containing - the data sent from the simulator - - - Thread sync lock object - - - Raised when the simulator sends us data containing - additional information - - - - - Reference to the GridClient object - - - Does periodic dead reckoning calculation to convert - velocity and acceleration to new positions for objects - - - - Construct a new instance of the ObjectManager class - - A reference to the instance - - - - Request information for a single object from a - you are currently connected to - - The the object is located - The Local ID of the object - - - - Request information for multiple objects contained in - the same simulator - - The the objects are located - An array containing the Local IDs of the objects - - - - Attempt to purchase an original object, a copy, or the contents of - an object - - The the object is located - The Local ID of the object - Whether the original, a copy, or the object - contents are on sale. This is used for verification, if the this - sale type is not valid for the object the purchase will fail - Price of the object. This is used for - verification, if it does not match the actual price the purchase - will fail - Group ID that will be associated with the new - purchase - Inventory folder UUID where the object or objects - purchased should be placed - - - BuyObject(Client.Network.CurrentSim, 500, SaleType.Copy, - 100, UUID.Zero, Client.Self.InventoryRootFolderUUID); - - - - - - Request prices that should be displayed in pay dialog. This will triggger the simulator - to send us back a PayPriceReply which can be handled by OnPayPriceReply event - - The the object is located - The ID of the object - The result is raised in the event - - - - Select a single object. This will cause the to send us - an which will raise the event - - The the object is located - The Local ID of the object - - - - - Select a single object. This will cause the to send us - an which will raise the event - - The the object is located - The Local ID of the object - if true, a call to is - made immediately following the request - - - - - Select multiple objects. This will cause the to send us - an which will raise the event - - The the objects are located - An array containing the Local IDs of the objects - Should objects be deselected immediately after selection - - - - - Select multiple objects. This will cause the to send us - an which will raise the event - - The the objects are located - An array containing the Local IDs of the objects - - - - - Update the properties of an object - - The the object is located - The Local ID of the object - true to turn the objects physical property on - true to turn the objects temporary property on - true to turn the objects phantom property on - true to turn the objects cast shadows property on - - - - Update the properties of an object - - The the object is located - The Local ID of the object - true to turn the objects physical property on - true to turn the objects temporary property on - true to turn the objects phantom property on - true to turn the objects cast shadows property on - Type of the represetnation prim will have in the physics engine - Density - normal value 1000 - Friction - normal value 0.6 - Restitution - standard value 0.5 - Gravity multiplier - standar value 1.0 - - - - Sets the sale properties of a single object - - The the object is located - The Local ID of the object - One of the options from the enum - The price of the object - - - - Sets the sale properties of multiple objects - - The the objects are located - An array containing the Local IDs of the objects - One of the options from the enum - The price of the object - - - - Deselect a single object - - The the object is located - The Local ID of the object - - - - Deselect multiple objects. - - The the objects are located - An array containing the Local IDs of the objects - - - - Perform a click action on an object - - The the object is located - The Local ID of the object - - - - Perform a click action (Grab) on a single object - - The the object is located - The Local ID of the object - The texture coordinates to touch - The surface coordinates to touch - The face of the position to touch - The region coordinates of the position to touch - The surface normal of the position to touch (A normal is a vector perpindicular to the surface) - The surface binormal of the position to touch (A binormal is a vector tangen to the surface - pointing along the U direction of the tangent space - - - - Create (rez) a new prim object in a simulator - - A reference to the object to place the object in - Data describing the prim object to rez - Group ID that this prim will be set to, or UUID.Zero if you - do not want the object to be associated with a specific group - An approximation of the position at which to rez the prim - Scale vector to size this prim - Rotation quaternion to rotate this prim - Due to the way client prim rezzing is done on the server, - the requested position for an object is only close to where the prim - actually ends up. If you desire exact placement you'll need to - follow up by moving the object after it has been created. This - function will not set textures, light and flexible data, or other - extended primitive properties - - - - Create (rez) a new prim object in a simulator - - A reference to the object to place the object in - Data describing the prim object to rez - Group ID that this prim will be set to, or UUID.Zero if you - do not want the object to be associated with a specific group - An approximation of the position at which to rez the prim - Scale vector to size this prim - Rotation quaternion to rotate this prim - Specify the - Due to the way client prim rezzing is done on the server, - the requested position for an object is only close to where the prim - actually ends up. If you desire exact placement you'll need to - follow up by moving the object after it has been created. This - function will not set textures, light and flexible data, or other - extended primitive properties - - - - Rez a Linden tree - - A reference to the object where the object resides - The size of the tree - The rotation of the tree - The position of the tree - The Type of tree - The of the group to set the tree to, - or UUID.Zero if no group is to be set - true to use the "new" Linden trees, false to use the old - - - - Rez grass and ground cover - - A reference to the object where the object resides - The size of the grass - The rotation of the grass - The position of the grass - The type of grass from the enum - The of the group to set the tree to, - or UUID.Zero if no group is to be set - - - - Set the textures to apply to the faces of an object - - A reference to the object where the object resides - The objects ID which is local to the simulator the object is in - The texture data to apply - - - - Set the textures to apply to the faces of an object - - A reference to the object where the object resides - The objects ID which is local to the simulator the object is in - The texture data to apply - A media URL (not used) - - - - Set the Light data on an object - - A reference to the object where the object resides - The objects ID which is local to the simulator the object is in - A object containing the data to set - - - - Set the flexible data on an object - - A reference to the object where the object resides - The objects ID which is local to the simulator the object is in - A object containing the data to set - - - - Set the sculptie texture and data on an object - - A reference to the object where the object resides - The objects ID which is local to the simulator the object is in - A object containing the data to set - - - - Unset additional primitive parameters on an object - - A reference to the object where the object resides - The objects ID which is local to the simulator the object is in - The extra parameters to set - - - - Link multiple prims into a linkset - - A reference to the object where the objects reside - An array which contains the IDs of the objects to link - The last object in the array will be the root object of the linkset TODO: Is this true? - - - - Delink/Unlink multiple prims from a linkset - - A reference to the object where the objects reside - An array which contains the IDs of the objects to delink - - - - Change the rotation of an object - - A reference to the object where the object resides - The objects ID which is local to the simulator the object is in - The new rotation of the object - - - - Set the name of an object - - A reference to the object where the object resides - The objects ID which is local to the simulator the object is in - A string containing the new name of the object - - - - Set the name of multiple objects - - A reference to the object where the objects reside - An array which contains the IDs of the objects to change the name of - An array which contains the new names of the objects - - - - Set the description of an object - - A reference to the object where the object resides - The objects ID which is local to the simulator the object is in - A string containing the new description of the object - - - - Set the descriptions of multiple objects - - A reference to the object where the objects reside - An array which contains the IDs of the objects to change the description of - An array which contains the new descriptions of the objects - - - - Attach an object to this avatar - - A reference to the object where the object resides - The objects ID which is local to the simulator the object is in - The point on the avatar the object will be attached - The rotation of the attached object - - - - Drop an attached object from this avatar - - A reference to the - object where the objects reside. This will always be the simulator the avatar is currently in - - The object's ID which is local to the simulator the object is in - - - - Detach an object from yourself - - A reference to the - object where the objects reside - - This will always be the simulator the avatar is currently in - - An array which contains the IDs of the objects to detach - - - - Change the position of an object, Will change position of entire linkset - - A reference to the object where the object resides - The objects ID which is local to the simulator the object is in - The new position of the object - - - - Change the position of an object - - A reference to the object where the object resides - The objects ID which is local to the simulator the object is in - The new position of the object - if true, will change position of (this) child prim only, not entire linkset - - - - Change the Scale (size) of an object - - A reference to the object where the object resides - The objects ID which is local to the simulator the object is in - The new scale of the object - If true, will change scale of this prim only, not entire linkset - True to resize prims uniformly - - - - Change the Rotation of an object that is either a child or a whole linkset - - A reference to the object where the object resides - The objects ID which is local to the simulator the object is in - The new scale of the object - If true, will change rotation of this prim only, not entire linkset - - - - Send a Multiple Object Update packet to change the size, scale or rotation of a primitive - - A reference to the object where the object resides - The objects ID which is local to the simulator the object is in - The new rotation, size, or position of the target object - The flags from the Enum - - - - Deed an object (prim) to a group, Object must be shared with group which - can be accomplished with SetPermissions() - - A reference to the object where the object resides - The objects ID which is local to the simulator the object is in - The of the group to deed the object to - - - - Deed multiple objects (prims) to a group, Objects must be shared with group which - can be accomplished with SetPermissions() - - A reference to the object where the object resides - An array which contains the IDs of the objects to deed - The of the group to deed the object to - - - - Set the permissions on multiple objects - - A reference to the object where the objects reside - An array which contains the IDs of the objects to set the permissions on - The new Who mask to set - Which permission to modify - The new state of permission - - - - Request additional properties for an object - - A reference to the object where the object resides - - - - - Request additional properties for an object - - A reference to the object where the object resides - Absolute UUID of the object - Whether to require server acknowledgement of this request - - - - Set the ownership of a list of objects to the specified group - - A reference to the object where the objects reside - An array which contains the IDs of the objects to set the group id on - The Groups ID - - - - Update current URL of the previously set prim media - - UUID of the prim - Set current URL to this - Prim face number - Simulator in which prim is located - - - - Set object media - - UUID of the prim - Array the length of prims number of faces. Null on face indexes where there is - no media, on faces which contain the media - Simulatior in which prim is located - - - - Retrieve information about object media - - UUID of the primitive - Simulator where prim is located - Call this callback when done - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - - A terse object update, used when a transformation matrix or - velocity/acceleration for an object changes but nothing else - (scale/position/rotation/acceleration/velocity) - - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - - - - - - - - - - Setup construction data for a basic primitive shape - - Primitive shape to construct - Construction data that can be plugged into a - - - - - - - - - - - - - - - - - - - - Set the Shape data of an object - - A reference to the object where the object resides - The objects ID which is local to the simulator the object is in - Data describing the prim shape - - - - Set the Material data of an object - - A reference to the object where the object resides - The objects ID which is local to the simulator the object is in - The new material of the object - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Provides data for the event - The event occurs when the simulator sends - an containing a Primitive, Foliage or Attachment data - Note 1: The event will not be raised when the object is an Avatar - Note 2: It is possible for the to be - raised twice for the same object if for example the primitive moved to a new simulator, then returned to the current simulator or - if an Avatar crosses the border into a new simulator and returns to the current simulator - - - The following code example uses the , , and - properties to display new Primitives and Attachments on the window. - - // Subscribe to the event that gives us prim and foliage information - Client.Objects.ObjectUpdate += Objects_ObjectUpdate; - - - private void Objects_ObjectUpdate(object sender, PrimEventArgs e) - { - Console.WriteLine("Primitive {0} {1} in {2} is an attachment {3}", e.Prim.ID, e.Prim.LocalID, e.Simulator.Name, e.IsAttachment); - } - - - - - - - - Get the simulator the originated from - - - Get the details - - - true if the did not exist in the dictionary before this update (always true if object tracking has been disabled) - - - true if the is attached to an - - - Get the simulator Time Dilation - - - - Construct a new instance of the PrimEventArgs class - - The simulator the object originated from - The Primitive - The simulator time dilation - The prim was not in the dictionary before this update - true if the primitive represents an attachment to an agent - - - Provides data for the event - The event occurs when the simulator sends - an containing Avatar data - Note 1: The event will not be raised when the object is an Avatar - Note 2: It is possible for the to be - raised twice for the same avatar if for example the avatar moved to a new simulator, then returned to the current simulator - - - The following code example uses the property to make a request for the top picks - using the method in the class to display the names - of our own agents picks listings on the window. - - // subscribe to the AvatarUpdate event to get our information - Client.Objects.AvatarUpdate += Objects_AvatarUpdate; - Client.Avatars.AvatarPicksReply += Avatars_AvatarPicksReply; - - private void Objects_AvatarUpdate(object sender, AvatarUpdateEventArgs e) - { - // we only want our own data - if (e.Avatar.LocalID == Client.Self.LocalID) - { - // Unsubscribe from the avatar update event to prevent a loop - // where we continually request the picks every time we get an update for ourselves - Client.Objects.AvatarUpdate -= Objects_AvatarUpdate; - // make the top picks request through AvatarManager - Client.Avatars.RequestAvatarPicks(e.Avatar.ID); - } - } - - private void Avatars_AvatarPicksReply(object sender, AvatarPicksReplyEventArgs e) - { - // we'll unsubscribe from the AvatarPicksReply event since we now have the data - // we were looking for - Client.Avatars.AvatarPicksReply -= Avatars_AvatarPicksReply; - // loop through the dictionary and extract the names of the top picks from our profile - foreach (var pickName in e.Picks.Values) - { - Console.WriteLine(pickName); - } - } - - - - - - - Get the simulator the object originated from - - - Get the data - - - Get the simulator time dilation - - - true if the did not exist in the dictionary before this update (always true if avatar tracking has been disabled) - - - - Construct a new instance of the AvatarUpdateEventArgs class - - The simulator the packet originated from - The data - The simulator time dilation - The avatar was not in the dictionary before this update - - - Get the simulator the object originated from - - - Get the data - - - Get source - - - - Construct a new instance of the ParticleUpdateEventArgs class - - The simulator the packet originated from - The ParticleSystem data - The Primitive source - - - Provides additional primitive data for the event - The event occurs when the simulator sends - an containing additional details for a Primitive, Foliage data or Attachment data - The event is also raised when a request is - made. - - - The following code example uses the , and - - properties to display new attachments and send a request for additional properties containing the name of the - attachment then display it on the window. - - // Subscribe to the event that provides additional primitive details - Client.Objects.ObjectProperties += Objects_ObjectProperties; - - // handle the properties data that arrives - private void Objects_ObjectProperties(object sender, ObjectPropertiesEventArgs e) - { - Console.WriteLine("Primitive Properties: {0} Name is {1}", e.Properties.ObjectID, e.Properties.Name); - } - - - - - Get the simulator the object is located - - - Get the primitive properties - - - - Construct a new instance of the ObjectPropertiesEventArgs class - - The simulator the object is located - The primitive Properties - - - Provides additional primitive data for the event - The event occurs when the simulator sends - an containing additional details for a Primitive or Foliage data that is currently - being tracked in the dictionary - The event is also raised when a request is - made and is enabled - - - - Get the primitive details - - - - Construct a new instance of the ObjectPropertiesUpdatedEvenrArgs class - - The simulator the object is located - The Primitive - The primitive Properties - - - Provides additional primitive data, permissions and sale info for the event - The event occurs when the simulator sends - an containing additional details for a Primitive, Foliage data or Attachment. This includes - Permissions, Sale info, and other basic details on an object - The event is also raised when a request is - made, the viewer equivalent is hovering the mouse cursor over an object - - - - Get the simulator the object is located - - - - - - - - - Provides primitive data containing updated location, velocity, rotation, textures for the event - The event occurs when the simulator sends updated location, velocity, rotation, etc - - - - Get the simulator the object is located - - - Get the primitive details - - - - - - - - - - - - - - Get the simulator the object is located - - - Get the primitive details - - - - - - - - - - - - - - - Provides notification when an Avatar, Object or Attachment is DeRezzed or moves out of the avatars view for the - event - - - Get the simulator the object is located - - - The LocalID of the object - - - Provides notification when an Avatar, Object or Attachment is DeRezzed or moves out of the avatars view for the - event - - - Get the simulator the object is located - - - The LocalID of the object - - - - Provides updates sit position data - - - - Get the simulator the object is located - - - - - - - - - - - - - - - - - Get the simulator the object is located - - - - - - - - - - - - - Indicates if the operation was successful - - - - - Media version string - - - - - Array of media entries indexed by face number - - - - - Set when simulator sends us infomation on primitive's physical properties - - - - Simulator where the message originated - - - Updated physical properties - - - - Constructor - - Simulator where the message originated - Updated physical properties - - - Size of the byte array used to store raw packet data - - - Raw packet data buffer - - - Length of the data to transmit - - - EndPoint of the remote host - - - - Create an allocated UDP packet buffer for receiving a packet - - - - - Create an allocated UDP packet buffer for sending a packet - - EndPoint of the remote host - - - - Create an allocated UDP packet buffer for sending a packet - - EndPoint of the remote host - Size of the buffer to allocate for packet data - - - - Object pool for packet buffers. This is used to allocate memory for all - incoming and outgoing packets, and zerocoding buffers for those packets - - - - - Initialize the object pool in client mode - - Server to connect to - - - - - - Initialize the object pool in server mode - - - - - - - Returns a packet buffer with EndPoint set if the buffer is in - client mode, or with EndPoint set to null in server mode - - Initialized UDPPacketBuffer object - - - - Default constructor - - - - - Check a packet buffer out of the pool - - A packet buffer object - - - - Returns an instance of the class that has been checked out of the Object Pool. - - - - - Checks the instance back into the object pool - - - - - Creates a new instance of the ObjectPoolBase class. Initialize MUST be called - after using this constructor. - - - - - Creates a new instance of the ObjectPool Base class. - - The object pool is composed of segments, which - are allocated whenever the size of the pool is exceeded. The number of items - in a segment should be large enough that allocating a new segmeng is a rare - thing. For example, on a server that will have 10k people logged in at once, - the receive buffer object pool should have segment sizes of at least 1000 - byte arrays per segment. - - The minimun number of segments that may exist. - Perform a full GC.Collect whenever a segment is allocated, and then again after allocation to compact the heap. - The frequency which segments are checked to see if they're eligible for cleanup. - - - - Forces the segment cleanup algorithm to be run. This method is intended - primarly for use from the Unit Test libraries. - - - - - Responsible for allocate 1 instance of an object that will be stored in a segment. - - An instance of whatever objec the pool is pooling. - - - - Checks in an instance of T owned by the object pool. This method is only intended to be called - by the WrappedObject class. - - The segment from which the instance is checked out. - The instance of T to check back into the segment. - - - - Checks an instance of T from the pool. If the pool is not sufficient to - allow the checkout, a new segment is created. - - A WrappedObject around the instance of T. To check - the instance back into the segment, be sureto dispose the WrappedObject - when finished. - - - - The total number of segments created. Intended to be used by the Unit Tests. - - - - - The number of items that are in a segment. Items in a segment - are all allocated at the same time, and are hopefully close to - each other in the managed heap. - - - - - The minimum number of segments. When segments are reclaimed, - this number of segments will always be left alone. These - segments are allocated at startup. - - - - - The age a segment must be before it's eligible for cleanup. - This is used to prevent thrash, and typical values are in - the 5 minute range. - - - - - The frequence which the cleanup thread runs. This is typically - expected to be in the 5 minute range. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - The ObservableDictionary class is used for storing key/value pairs. It has methods for firing - events to subscribers when items are added, removed, or changed. - - Key - Value - - - - A dictionary of callbacks to fire when specified action occurs - - - - - Register a callback to be fired when an action occurs - - The action - The callback to fire - - - - Unregister a callback - - The action - The callback to fire - - - - - - - - - - Internal dictionary that this class wraps around. Do not - modify or enumerate the contents of this dictionary without locking - - - - Gets the number of Key/Value pairs contained in the - - - - - Initializes a new instance of the Class - with the specified key/value, has the default initial capacity. - - - - // initialize a new ObservableDictionary named testDict with a string as the key and an int as the value. - public ObservableDictionary<string, int> testDict = new ObservableDictionary<string, int>(); - - - - - - Initializes a new instance of the Class - with the specified key/value, With its initial capacity specified. - - Initial size of dictionary - - - // initialize a new ObservableDictionary named testDict with a string as the key and an int as the value, - // initially allocated room for 10 entries. - public ObservableDictionary<string, int> testDict = new ObservableDictionary<string, int>(10); - - - - - - Try to get entry from the with specified key - - Key to use for lookup - Value returned - if specified key exists, if not found - - - // find your avatar using the Simulator.ObjectsAvatars ObservableDictionary: - Avatar av; - if (Client.Network.CurrentSim.ObjectsAvatars.TryGetValue(Client.Self.AgentID, out av)) - Console.WriteLine("Found Avatar {0}", av.Name); - - - - - - - Finds the specified match. - - The match. - Matched value - - - // use a delegate to find a prim in the ObjectsPrimitives ObservableDictionary - // with the ID 95683496 - uint findID = 95683496; - Primitive findPrim = sim.ObjectsPrimitives.Find( - delegate(Primitive prim) { return prim.ID == findID; }); - - - - - Find All items in an - return matching items. - a containing found items. - - Find All prims within 20 meters and store them in a List - - int radius = 20; - List<Primitive> prims = Client.Network.CurrentSim.ObjectsPrimitives.FindAll( - delegate(Primitive prim) { - Vector3 pos = prim.Position; - return ((prim.ParentID == 0) && (pos != Vector3.Zero) && (Vector3.Distance(pos, location) < radius)); - } - ); - - - - - Find All items in an - return matching keys. - a containing found keys. - - Find All keys which also exist in another dictionary - - List<UUID> matches = myDict.FindAll( - delegate(UUID id) { - return myOtherDict.ContainsKey(id); - } - ); - - - - - Check if Key exists in Dictionary - Key to check for - if found, otherwise - - - Check if Value exists in Dictionary - Value to check for - if found, otherwise - - - - Adds the specified key to the dictionary, dictionary locking is not performed, - - - The key - The value - - - - Removes the specified key, dictionary locking is not performed - - The key. - if successful, otherwise - - - - Indexer for the dictionary - - The key - The value - - - - Clear the contents of the dictionary - - - - - Enumerator for iterating dictionary entries - - - - - - Provides helper methods for parallelizing loops - - - - - Executes a for loop in which iterations may run in parallel - - The loop will be started at this index - The loop will be terminated before this index is reached - Method body to run for each iteration of the loop - - - - Executes a for loop in which iterations may run in parallel - - The number of concurrent execution threads to run - The loop will be started at this index - The loop will be terminated before this index is reached - Method body to run for each iteration of the loop - - - - Executes a foreach loop in which iterations may run in parallel - - Object type that the collection wraps - An enumerable collection to iterate over - Method body to run for each object in the collection - - - - Executes a foreach loop in which iterations may run in parallel - - Object type that the collection wraps - The number of concurrent execution threads to run - An enumerable collection to iterate over - Method body to run for each object in the collection - - - - Executes a series of tasks in parallel - - A series of method bodies to execute - - - - Executes a series of tasks in parallel - - The number of concurrent execution threads to run - A series of method bodies to execute - - - - Type of return to use when returning objects from a parcel - - - - - - - Return objects owned by parcel owner - - - Return objects set to group - - - Return objects not owned by parcel owner or set to group - - - Return a specific list of objects on parcel - - - Return objects that are marked for-sale - - - - Blacklist/Whitelist flags used in parcels Access List - - - - Agent is denied access - - - Agent is granted access - - - - The result of a request for parcel properties - - - - No matches were found for the request - - - Request matched a single parcel - - - Request matched multiple parcels - - - - Flags used in the ParcelAccessListRequest packet to specify whether - we want the access list (whitelist), ban list (blacklist), or both - - - - Request the access list - - - Request the ban list - - - Request both White and Black lists - - - - Sequence ID in ParcelPropertiesReply packets (sent when avatar - tries to cross a parcel border) - - - - Parcel is currently selected - - - Parcel restricted to a group the avatar is not a - member of - - - Avatar is banned from the parcel - - - Parcel is restricted to an access list that the - avatar is not on - - - Response to hovering over a parcel - - - - The tool to use when modifying terrain levels - - - - Level the terrain - - - Raise the terrain - - - Lower the terrain - - - Smooth the terrain - - - Add random noise to the terrain - - - Revert terrain to simulator default - - - - The tool size to use when changing terrain levels - - - - Small - - - Medium - - - Large - - - - Reasons agent is denied access to a parcel on the simulator - - - - Agent is not denied, access is granted - - - Agent is not a member of the group set for the parcel, or which owns the parcel - - - Agent is not on the parcels specific allow list - - - Agent is on the parcels ban list - - - Unknown - - - Agent is not age verified and parcel settings deny access to non age verified avatars - - - - Parcel overlay type. This is used primarily for highlighting and - coloring which is why it is a single integer instead of a set of - flags - - These values seem to be poorly thought out. The first three - bits represent a single value, not flags. For example Auction (0x05) is - not a combination of OwnedByOther (0x01) and ForSale(0x04). However, - the BorderWest and BorderSouth values are bit flags that get attached - to the value stored in the first three bits. Bits four, five, and six - are unused - - - Public land - - - Land is owned by another avatar - - - Land is owned by a group - - - Land is owned by the current avatar - - - Land is for sale - - - Land is being auctioned - - - Land is private - - - To the west of this area is a parcel border - - - To the south of this area is a parcel border - - - - Various parcel properties - - - - No flags set - - - Allow avatars to fly (a client-side only restriction) - - - Allow foreign scripts to run - - - This parcel is for sale - - - Allow avatars to create a landmark on this parcel - - - Allows all avatars to edit the terrain on this parcel - - - Avatars have health and can take damage on this parcel. - If set, avatars can be killed and sent home here - - - Foreign avatars can create objects here - - - All objects on this parcel can be purchased - - - Access is restricted to a group - - - Access is restricted to a whitelist - - - Ban blacklist is enabled - - - Unknown - - - List this parcel in the search directory - - - Allow personally owned parcels to be deeded to group - - - If Deeded, owner contributes required tier to group parcel is deeded to - - - Restrict sounds originating on this parcel to the - parcel boundaries - - - Objects on this parcel are sold when the land is - purchsaed - - - Allow this parcel to be published on the web - - - The information for this parcel is mature content - - - The media URL is an HTML page - - - The media URL is a raw HTML string - - - Restrict foreign object pushes - - - Ban all non identified/transacted avatars - - - Allow group-owned scripts to run - - - Allow object creation by group members or group - objects - - - Allow all objects to enter this parcel - - - Only allow group and owner objects to enter this parcel - - - Voice Enabled on this parcel - - - Use Estate Voice channel for Voice on this parcel - - - Deny Age Unverified Users - - - - Parcel ownership status - - - - Placeholder - - - Parcel is leased (owned) by an avatar or group - - - Parcel is in process of being leased (purchased) by an avatar or group - - - Parcel has been abandoned back to Governor Linden - - - - Category parcel is listed in under search - - - - No assigned category - - - Linden Infohub or public area - - - Adult themed area - - - Arts and Culture - - - Business - - - Educational - - - Gaming - - - Hangout or Club - - - Newcomer friendly - - - Parks and Nature - - - Residential - - - Shopping - - - Not Used? - - - Other - - - Not an actual category, only used for queries - - - - Type of teleport landing for a parcel - - - - Unset, simulator default - - - Specific landing point set for this parcel - - - No landing point set, direct teleports enabled for - this parcel - - - - Parcel Media Command used in ParcelMediaCommandMessage - - - - Stop the media stream and go back to the first frame - - - Pause the media stream (stop playing but stay on current frame) - - - Start the current media stream playing and stop when the end is reached - - - Start the current media stream playing, - loop to the beginning when the end is reached and continue to play - - - Specifies the texture to replace with video - If passing the key of a texture, it must be explicitly typecast as a key, - not just passed within double quotes. - - - Specifies the movie URL (254 characters max) - - - Specifies the time index at which to begin playing - - - Specifies a single agent to apply the media command to - - - Unloads the stream. While the stop command sets the texture to the first frame of the movie, - unload resets it to the real texture that the movie was replacing. - - - Turn on/off the auto align feature, similar to the auto align checkbox in the parcel media properties - (NOT to be confused with the "align" function in the textures view of the editor!) Takes TRUE or FALSE as parameter. - - - Allows a Web page or image to be placed on a prim (1.19.1 RC0 and later only). - Use "text/html" for HTML. - - - Resizes a Web page to fit on x, y pixels (1.19.1 RC0 and later only). - This might still not be working - - - Sets a description for the media being displayed (1.19.1 RC0 and later only). - - - - Some information about a parcel of land returned from a DirectoryManager search - - - - Global Key of record - - - Parcel Owners - - - Name field of parcel, limited to 128 characters - - - Description field of parcel, limited to 256 characters - - - Total Square meters of parcel - - - Total area billable as Tier, for group owned land this will be 10% less than ActualArea - - - True of parcel is in Mature simulator - - - Grid global X position of parcel - - - Grid global Y position of parcel - - - Grid global Z position of parcel (not used) - - - Name of simulator parcel is located in - - - Texture of parcels display picture - - - Float representing calculated traffic based on time spent on parcel by avatars - - - Sale price of parcel (not used) - - - Auction ID of parcel - - - - Parcel Media Information - - - - A byte, if 0x1 viewer should auto scale media to fit object - - - A boolean, if true the viewer should loop the media - - - The Asset UUID of the Texture which when applied to a - primitive will display the media - - - A URL which points to any Quicktime supported media type - - - A description of the media - - - An Integer which represents the height of the media - - - An integer which represents the width of the media - - - A string which contains the mime type of the media - - - - Parcel of land, a portion of virtual real estate in a simulator - - - - The total number of contiguous 4x4 meter blocks your agent owns within this parcel - - - The total number of contiguous 4x4 meter blocks contained in this parcel owned by a group or agent other than your own - - - Deprecated, Value appears to always be 0 - - - Simulator-local ID of this parcel - - - UUID of the owner of this parcel - - - Whether the land is deeded to a group or not - - - - - - Date land was claimed - - - Appears to always be zero - - - This field is no longer used - - - Minimum corner of the axis-aligned bounding box for this - parcel - - - Maximum corner of the axis-aligned bounding box for this - parcel - - - Bitmap describing land layout in 4x4m squares across the - entire region - - - Total parcel land area - - - - - - Maximum primitives across the entire simulator owned by the same agent or group that owns this parcel that can be used - - - Total primitives across the entire simulator calculated by combining the allowed prim counts for each parcel - owned by the agent or group that owns this parcel - - - Maximum number of primitives this parcel supports - - - Total number of primitives on this parcel - - - For group-owned parcels this indicates the total number of prims deeded to the group, - for parcels owned by an individual this inicates the number of prims owned by the individual - - - Total number of primitives owned by the parcel group on - this parcel, or for parcels owned by an individual with a group set the - total number of prims set to that group. - - - Total number of prims owned by other avatars that are not set to group, or not the parcel owner - - - A bonus multiplier which allows parcel prim counts to go over times this amount, this does not affect - the max prims per simulator. e.g: 117 prim parcel limit x 1.5 bonus = 175 allowed - - - Autoreturn value in minutes for others' objects - - - - - - Sale price of the parcel, only useful if ForSale is set - The SalePrice will remain the same after an ownership - transfer (sale), so it can be used to see the purchase price after - a sale if the new owner has not changed it - - - Parcel Name - - - Parcel Description - - - URL For Music Stream - - - - - - Price for a temporary pass - - - How long is pass valid for - - - - - - Key of authorized buyer - - - Key of parcel snapshot - - - The landing point location - - - The landing point LookAt - - - The type of landing enforced from the enum - - - - - - - - - - - - Access list of who is whitelisted on this - parcel - - - Access list of who is blacklisted on this - parcel - - - TRUE of region denies access to age unverified users - - - true to obscure (hide) media url - - - true to obscure (hide) music url - - - A struct containing media details - - - - Displays a parcel object in string format - - string containing key=value pairs of a parcel object - - - - Defalt constructor - - Local ID of this parcel - - - - Update the simulator with any local changes to this Parcel object - - Simulator to send updates to - Whether we want the simulator to confirm - the update with a reply packet or not - - - - Set Autoreturn time - - Simulator to send the update to - - - - Parcel (subdivided simulator lots) subsystem - - - - - Parcel Accesslist - - - - Agents - - - - - - Flags for specific entry in white/black lists - - - - Owners of primitives on parcel - - - - Prim Owners - - - True of owner is group - - - Total count of prims owned by OwnerID - - - true of OwnerID is currently online and is not a group - - - The date of the most recent prim left by OwnerID - - - - Called once parcel resource usage information has been collected - - Indicates if operation was successfull - Parcel resource usage information - - - The event subscribers. null if no subcribers - - - Raises the ParcelDwellReply event - A ParcelDwellReplyEventArgs object containing the - data returned from the simulator - - - Thread sync lock object - - - Raised when the simulator responds to a request - - - The event subscribers. null if no subcribers - - - Raises the ParcelInfoReply event - A ParcelInfoReplyEventArgs object containing the - data returned from the simulator - - - Thread sync lock object - - - Raised when the simulator responds to a request - - - The event subscribers. null if no subcribers - - - Raises the ParcelProperties event - A ParcelPropertiesEventArgs object containing the - data returned from the simulator - - - Thread sync lock object - - - Raised when the simulator responds to a request - - - The event subscribers. null if no subcribers - - - Raises the ParcelAccessListReply event - A ParcelAccessListReplyEventArgs object containing the - data returned from the simulator - - - Thread sync lock object - - - Raised when the simulator responds to a request - - - The event subscribers. null if no subcribers - - - Raises the ParcelObjectOwnersReply event - A ParcelObjectOwnersReplyEventArgs object containing the - data returned from the simulator - - - Thread sync lock object - - - Raised when the simulator responds to a request - - - The event subscribers. null if no subcribers - - - Raises the SimParcelsDownloaded event - A SimParcelsDownloadedEventArgs object containing the - data returned from the simulator - - - Thread sync lock object - - - Raised when the simulator responds to a request - - - The event subscribers. null if no subcribers - - - Raises the ForceSelectObjectsReply event - A ForceSelectObjectsReplyEventArgs object containing the - data returned from the simulator - - - Thread sync lock object - - - Raised when the simulator responds to a request - - - The event subscribers. null if no subcribers - - - Raises the ParcelMediaUpdateReply event - A ParcelMediaUpdateReplyEventArgs object containing the - data returned from the simulator - - - Thread sync lock object - - - Raised when the simulator responds to a Parcel Update request - - - The event subscribers. null if no subcribers - - - Raises the ParcelMediaCommand event - A ParcelMediaCommandEventArgs object containing the - data returned from the simulator - - - Thread sync lock object - - - Raised when the parcel your agent is located sends a ParcelMediaCommand - - - - Default constructor - - A reference to the GridClient object - - - - Request basic information for a single parcel - - Simulator-local ID of the parcel - - - - Request properties of a single parcel - - Simulator containing the parcel - Simulator-local ID of the parcel - An arbitrary integer that will be returned - with the ParcelProperties reply, useful for distinguishing between - multiple simultaneous requests - - - - Request the access list for a single parcel - - Simulator containing the parcel - Simulator-local ID of the parcel - An arbitrary integer that will be returned - with the ParcelAccessList reply, useful for distinguishing between - multiple simultaneous requests - - - - - Request properties of parcels using a bounding box selection - - Simulator containing the parcel - Northern boundary of the parcel selection - Eastern boundary of the parcel selection - Southern boundary of the parcel selection - Western boundary of the parcel selection - An arbitrary integer that will be returned - with the ParcelProperties reply, useful for distinguishing between - different types of parcel property requests - A boolean that is returned with the - ParcelProperties reply, useful for snapping focus to a single - parcel - - - - Request all simulator parcel properties (used for populating the Simulator.Parcels - dictionary) - - Simulator to request parcels from (must be connected) - - - - Request all simulator parcel properties (used for populating the Simulator.Parcels - dictionary) - - Simulator to request parcels from (must be connected) - If TRUE, will force a full refresh - Number of milliseconds to pause in between each request - - - - Request the dwell value for a parcel - - Simulator containing the parcel - Simulator-local ID of the parcel - - - - Send a request to Purchase a parcel of land - - The Simulator the parcel is located in - The parcels region specific local ID - true if this parcel is being purchased by a group - The groups - true to remove tier contribution if purchase is successful - The parcels size - The purchase price of the parcel - - - - - Reclaim a parcel of land - - The simulator the parcel is in - The parcels region specific local ID - - - - Deed a parcel to a group - - The simulator the parcel is in - The parcels region specific local ID - The groups - - - - Request prim owners of a parcel of land. - - Simulator parcel is in - The parcels region specific local ID - - - - Return objects from a parcel - - Simulator parcel is in - The parcels region specific local ID - the type of objects to return, - A list containing object owners s to return - - - - Subdivide (split) a parcel - - - - - - - - - - Join two parcels of land creating a single parcel - - - - - - - - - - Get a parcels LocalID - - Simulator parcel is in - Vector3 position in simulator (Z not used) - 0 on failure, or parcel LocalID on success. - A call to Parcels.RequestAllSimParcels is required to populate map and - dictionary. - - - - Terraform (raise, lower, etc) an area or whole parcel of land - - Simulator land area is in. - LocalID of parcel, or -1 if using bounding box - From Enum, Raise, Lower, Level, Smooth, Etc. - Size of area to modify - true on successful request sent. - Settings.STORE_LAND_PATCHES must be true, - Parcel information must be downloaded using RequestAllSimParcels() - - - - Terraform (raise, lower, etc) an area or whole parcel of land - - Simulator land area is in. - west border of area to modify - south border of area to modify - east border of area to modify - north border of area to modify - From Enum, Raise, Lower, Level, Smooth, Etc. - Size of area to modify - true on successful request sent. - Settings.STORE_LAND_PATCHES must be true, - Parcel information must be downloaded using RequestAllSimParcels() - - - - Terraform (raise, lower, etc) an area or whole parcel of land - - Simulator land area is in. - LocalID of parcel, or -1 if using bounding box - west border of area to modify - south border of area to modify - east border of area to modify - north border of area to modify - From Enum, Raise, Lower, Level, Smooth, Etc. - Size of area to modify - How many meters + or - to lower, 1 = 1 meter - true on successful request sent. - Settings.STORE_LAND_PATCHES must be true, - Parcel information must be downloaded using RequestAllSimParcels() - - - - Terraform (raise, lower, etc) an area or whole parcel of land - - Simulator land area is in. - LocalID of parcel, or -1 if using bounding box - west border of area to modify - south border of area to modify - east border of area to modify - north border of area to modify - From Enum, Raise, Lower, Level, Smooth, Etc. - Size of area to modify - How many meters + or - to lower, 1 = 1 meter - Height at which the terraform operation is acting at - - - - Sends a request to the simulator to return a list of objects owned by specific owners - - Simulator local ID of parcel - Owners, Others, Etc - List containing keys of avatars objects to select; - if List is null will return Objects of type selectType - Response data is returned in the event - - - - Eject and optionally ban a user from a parcel - - target key of avatar to eject - true to also ban target - - - - Freeze or unfreeze an avatar over your land - - target key to freeze - true to freeze, false to unfreeze - - - - Abandon a parcel of land - - Simulator parcel is in - Simulator local ID of parcel - - - - Requests the UUID of the parcel in a remote region at a specified location - - Location of the parcel in the remote region - Remote region handle - Remote region UUID - If successful UUID of the remote parcel, UUID.Zero otherwise - - - - Retrieves information on resources used by the parcel - - UUID of the parcel - Should per object resource usage be requested - Callback invoked when the request is complete - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - Raises the event - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - Raises the event - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - Raises the event - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - Raises the event - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - Raises the event - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - Raises the event - - - Contains a parcels dwell data returned from the simulator in response to an - - - Get the global ID of the parcel - - - Get the simulator specific ID of the parcel - - - Get the calculated dwell - - - - Construct a new instance of the ParcelDwellReplyEventArgs class - - The global ID of the parcel - The simulator specific ID of the parcel - The calculated dwell for the parcel - - - Contains basic parcel information data returned from the - simulator in response to an request - - - Get the object containing basic parcel info - - - - Construct a new instance of the ParcelInfoReplyEventArgs class - - The object containing basic parcel info - - - Contains basic parcel information data returned from the simulator in response to an request - - - Get the simulator the parcel is located in - - - Get the object containing the details - If Result is NoData, this object will not contain valid data - - - Get the result of the request - - - Get the number of primitieves your agent is - currently selecting and or sitting on in this parcel - - - Get the user assigned ID used to correlate a request with - these results - - - TODO: - - - - Construct a new instance of the ParcelPropertiesEventArgs class - - The object containing the details - The object containing the details - The result of the request - The number of primitieves your agent is - currently selecting and or sitting on in this parcel - The user assigned ID used to correlate a request with - these results - TODO: - - - Contains blacklist and whitelist data returned from the simulator in response to an request - - - Get the simulator the parcel is located in - - - Get the user assigned ID used to correlate a request with - these results - - - Get the simulator specific ID of the parcel - - - TODO: - - - Get the list containing the white/blacklisted agents for the parcel - - - - Construct a new instance of the ParcelAccessListReplyEventArgs class - - The simulator the parcel is located in - The user assigned ID used to correlate a request with - these results - The simulator specific ID of the parcel - TODO: - The list containing the white/blacklisted agents for the parcel - - - Contains blacklist and whitelist data returned from the - simulator in response to an request - - - Get the simulator the parcel is located in - - - Get the list containing prim ownership counts - - - - Construct a new instance of the ParcelObjectOwnersReplyEventArgs class - - The simulator the parcel is located in - The list containing prim ownership counts - - - Contains the data returned when all parcel data has been retrieved from a simulator - - - Get the simulator the parcel data was retrieved from - - - A dictionary containing the parcel data where the key correlates to the ParcelMap entry - - - Get the multidimensional array containing a x,y grid mapped - to each 64x64 parcel's LocalID. - - - - Construct a new instance of the SimParcelsDownloadedEventArgs class - - The simulator the parcel data was retrieved from - The dictionary containing the parcel data - The multidimensional array containing a x,y grid mapped - to each 64x64 parcel's LocalID. - - - Contains the data returned when a request - - - Get the simulator the parcel data was retrieved from - - - Get the list of primitive IDs - - - true if the list is clean and contains the information - only for a given request - - - - Construct a new instance of the ForceSelectObjectsReplyEventArgs class - - The simulator the parcel data was retrieved from - The list of primitive IDs - true if the list is clean and contains the information - only for a given request - - - Contains data when the media data for a parcel the avatar is on changes - - - Get the simulator the parcel media data was updated in - - - Get the updated media information - - - - Construct a new instance of the ParcelMediaUpdateReplyEventArgs class - - the simulator the parcel media data was updated in - The updated media information - - - Contains the media command for a parcel the agent is currently on - - - Get the simulator the parcel media command was issued in - - - - - - - - - Get the media command that was sent - - - - - - - Construct a new instance of the ParcelMediaCommandEventArgs class - - The simulator the parcel media command was issued in - - - The media command that was sent - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Class for controlling various system settings. - - Some values are readonly because they affect things that - happen when the GridClient object is initialized, so changing them at - runtime won't do any good. Non-readonly values may affect things that - happen at login or dynamically - - - Main grid login server - - - Beta grid login server - - - The relative directory where external resources are kept - - - Login server to connect to - - - IP Address the client will bind to - - - Use XML-RPC Login or LLSD Login, default is XML-RPC Login - - - - Maximum number of HTTP connections to open to a particular endpoint. - - - An endpoint is defined as a commbination of network address and port. This is used for Caps. - This is a static variable which applies to all instances. - - - - - InventoryManager requests inventory information on login, - GridClient initializes an Inventory store for main inventory. - - - - - InventoryManager requests library information on login, - GridClient initializes an Inventory store for the library. - - - - - Use Caps for fetching inventory where available - - - - Number of milliseconds before an asset transfer will time - out - - - Number of milliseconds before a teleport attempt will time - out - - - Number of milliseconds before NetworkManager.Logout() will - time out - - - Number of milliseconds before a CAPS call will time out - Setting this too low will cause web requests time out and - possibly retry repeatedly - - - Number of milliseconds for xml-rpc to timeout - - - Milliseconds before a packet is assumed lost and resent - - - Milliseconds without receiving a packet before the - connection to a simulator is assumed lost - - - Milliseconds to wait for a simulator info request through - the grid interface - - - Number of milliseconds between sending pings to each sim - - - Number of milliseconds between sending camera updates - - - Number of milliseconds between updating the current - positions of moving, non-accelerating and non-colliding objects - - - Millisecond interval between ticks, where all ACKs are - sent out and the age of unACKed packets is checked - - - The initial size of the packet inbox, where packets are - stored before processing - - - Maximum size of packet that we want to send over the wire - - - The maximum value of a packet sequence number before it - rolls over back to one - - - The maximum size of the sequence number archive, used to - check for resent and/or duplicate packets - - - Maximum number of queued ACKs to be sent before SendAcks() - is forced - - - Network stats queue length (seconds) - - - - Primitives will be reused when falling in/out of interest list (and shared between clients) - prims returning to interest list do not need re-requested - Helps also in not re-requesting prim.Properties for code that checks for a Properties == null per client - - - - - Pool parcel data between clients (saves on requesting multiple times when all clients may need it) - - - - - How long to preserve cached data when no client is connected to a simulator - The reason for setting it to something like 2 minutes is in case a client - is running back and forth between region edges or a sim is comming and going - - - - Enable/disable storing terrain heightmaps in the - TerrainManager - - - Enable/disable sending periodic camera updates - - - Enable/disable automatically setting agent appearance at - login and after sim crossing - - - Enable/disable automatically setting the bandwidth throttle - after connecting to each simulator - The default throttle uses the equivalent of the maximum - bandwidth setting in the official client. If you do not set a - throttle your connection will by default be throttled well below - the minimum values and you may experience connection problems - - - Enable/disable the sending of pings to monitor lag and - packet loss - - - Should we connect to multiple sims? This will allow - viewing in to neighboring simulators and sim crossings - (Experimental) - - - If true, all object update packets will be decoded in to - native objects. If false, only updates for our own agent will be - decoded. Registering an event handler will force objects for that - type to always be decoded. If this is disabled the object tracking - will have missing or partial prim and avatar information - - - If true, when a cached object check is received from the - server the full object info will automatically be requested - - - Whether to establish connections to HTTP capabilities - servers for simulators - - - Whether to decode sim stats - - - The capabilities servers are currently designed to - periodically return a 502 error which signals for the client to - re-establish a connection. Set this to true to log those 502 errors - - - If true, any reference received for a folder or item - the library is not aware of will automatically be fetched - - - If true, and SEND_AGENT_UPDATES is true, - AgentUpdate packets will continuously be sent out to give the bot - smoother movement and autopiloting - - - If true, currently visible avatars will be stored - in dictionaries inside Simulator.ObjectAvatars. - If false, a new Avatar or Primitive object will be created - each time an object update packet is received - - - If true, currently visible avatars will be stored - in dictionaries inside Simulator.ObjectPrimitives. - If false, a new Avatar or Primitive object will be created - each time an object update packet is received - - - If true, position and velocity will periodically be - interpolated (extrapolated, technically) for objects and - avatars that are being tracked by the library. This is - necessary to increase the accuracy of speed and position - estimates for simulated objects - - - - If true, utilization statistics will be tracked. There is a minor penalty - in CPU time for enabling this option. - - - - If true, parcel details will be stored in the - Simulator.Parcels dictionary as they are received - - - - If true, an incoming parcel properties reply will automatically send - a request for the parcel access list - - - - - if true, an incoming parcel properties reply will automatically send - a request for the traffic count. - - - - - If true, images, and other assets downloaded from the server - will be cached in a local directory - - - - Path to store cached texture data - - - Maximum size cached files are allowed to take on disk (bytes) - - - Default color used for viewer particle effects - - - Cost of uploading an asset - Read-only since this value is dynamically fetched at login - - - Maximum number of times to resend a failed packet - - - Throttle outgoing packet rate - - - UUID of a texture used by some viewers to indentify type of client used - - - - Download textures using GetTexture capability when available - - - - The maximum number of concurrent texture downloads allowed - Increasing this number will not necessarily increase texture retrieval times due to - simulator throttles - - - - The Refresh timer inteval is used to set the delay between checks for stalled texture downloads - - This is a static variable which applies to all instances - - - - Textures taking longer than this value will be flagged as timed out and removed from the pipeline - - - - - Get or set the minimum log level to output to the console by default - - If the library is not compiled with DEBUG defined and this level is set to DEBUG - You will get no output on the console. This behavior can be overriden by creating - a logger configuration file for log4net - - - - Attach avatar names to log messages - - - Log packet retransmission info - - - Log disk cache misses and other info - - - Constructor - Reference to a GridClient object - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - - Simulator (region) properties - - - - No flags set - - - Agents can take damage and be killed - - - Landmarks can be created here - - - Home position can be set in this sim - - - Home position is reset when an agent teleports away - - - Sun does not move - - - No object, land, etc. taxes - - - Disable heightmap alterations (agents can still plant - foliage) - - - Land cannot be released, sold, or purchased - - - All content is wiped nightly - - - Unknown: Related to the availability of an overview world map tile.(Think mainland images when zoomed out.) - - - Unknown: Related to region debug flags. Possibly to skip processing of agent interaction with world. - - - Region does not update agent prim interest lists. Internal debugging option. - - - No collision detection for non-agent objects - - - No scripts are ran - - - All physics processing is turned off - - - Region can be seen from other regions on world map. (Legacy world map option?) - - - Region can be seen from mainland on world map. (Legacy world map option?) - - - Agents not explicitly on the access list can visit the region. - - - Traffic calculations are not run across entire region, overrides parcel settings. - - - Flight is disabled (not currently enforced by the sim) - - - Allow direct (p2p) teleporting - - - Estate owner has temporarily disabled scripting - - - Restricts the usage of the LSL llPushObject function, applies to whole region. - - - Deny agents with no payment info on file - - - Deny agents with payment info on file - - - Deny agents who have made a monetary transaction - - - Parcels within the region may be joined or divided by anyone, not just estate owners/managers. - - - Abuse reports sent from within this region are sent to the estate owner defined email. - - - Region is Voice Enabled - - - Removes the ability from parcel owners to set their parcels to show in search. - - - Deny agents who have not been age verified from entering the region. - - - - Region protocol flags - - - - Nothing special - - - Region supports Server side Appearance - - - Viewer supports Server side Appearance - - - - Access level for a simulator - - - - Unknown or invalid access level - - - Trial accounts allowed - - - PG rating - - - Mature rating - - - Adult rating - - - Simulator is offline - - - Simulator does not exist - - - - - - - - - Simulator Statistics - - - - Total number of packets sent by this simulator to this agent - - - Total number of packets received by this simulator to this agent - - - Total number of bytes sent by this simulator to this agent - - - Total number of bytes received by this simulator to this agent - - - Time in seconds agent has been connected to simulator - - - Total number of packets that have been resent - - - Total number of resent packets recieved - - - Total number of pings sent to this simulator by this agent - - - Total number of ping replies sent to this agent by this simulator - - - - Incoming bytes per second - - It would be nice to have this claculated on the fly, but - this is far, far easier - - - - Outgoing bytes per second - - It would be nice to have this claculated on the fly, but - this is far, far easier - - - Time last ping was sent - - - ID of last Ping sent - - - - - - - - - Current time dilation of this simulator - - - Current Frames per second of simulator - - - Current Physics frames per second of simulator - - - - - - - - - - - - - - - - - - - - - - - - - - - Total number of objects Simulator is simulating - - - Total number of Active (Scripted) objects running - - - Number of agents currently in this simulator - - - Number of agents in neighbor simulators - - - Number of Active scripts running in this simulator - - - - - - - - - - - - Number of downloads pending - - - Number of uploads pending - - - - - - - - - Number of local uploads pending - - - Unacknowledged bytes in queue - - - A public reference to the client that this Simulator object - is attached to - - - A Unique Cache identifier for this simulator - - - The capabilities for this simulator - - - - - - The current version of software this simulator is running - - - - - - A 64x64 grid of parcel coloring values. The values stored - in this array are of the type - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - true if your agent has Estate Manager rights on this region - - - - - - - - - - - - Statistics information for this simulator and the - connection to the simulator, calculated by the simulator itself - and the library - - - The regions Unique ID - - - The physical data center the simulator is located - Known values are: - - Dallas - Chandler - SF - - - - - The CPU Class of the simulator - Most full mainland/estate sims appear to be 5, - Homesteads and Openspace appear to be 501 - - - The number of regions sharing the same CPU as this one - "Full Sims" appear to be 1, Homesteads appear to be 4 - - - The billing product name - Known values are: - - Mainland / Full Region (Sku: 023) - Estate / Full Region (Sku: 024) - Estate / Openspace (Sku: 027) - Estate / Homestead (Sku: 029) - Mainland / Homestead (Sku: 129) (Linden Owned) - Mainland / Linden Homes (Sku: 131) - - - - - The billing product SKU - Known values are: - - 023 Mainland / Full Region - 024 Estate / Full Region - 027 Estate / Openspace - 029 Estate / Homestead - 129 Mainland / Homestead (Linden Owned) - 131 Linden Homes / Full Region - - - - - - Flags indicating which protocols this region supports - - - - The current sequence number for packets sent to this - simulator. Must be Interlocked before modifying. Only - useful for applications manipulating sequence numbers - - - - A thread-safe dictionary containing avatars in a simulator - - - - - A thread-safe dictionary containing primitives in a simulator - - - - - Provides access to an internal thread-safe dictionary containing parcel - information found in this simulator - - - - - Provides access to an internal thread-safe multidimensional array containing a x,y grid mapped - to each 64x64 parcel's LocalID. - - - - - Checks simulator parcel map to make sure it has downloaded all data successfully - - true if map is full (contains no 0's) - - - - Is it safe to send agent updates to this sim - AgentMovementComplete message received - - - - The IP address and port of the server - - - Whether there is a working connection to the simulator or - not - - - Coarse locations of avatars in this simulator - - - AvatarPositions key representing TrackAgent target - - - Indicates if UDP connection to the sim is fully established - - - Used internally to track sim disconnections - - - Event that is triggered when the simulator successfully - establishes a connection - - - Whether this sim is currently connected or not. Hooked up - to the property Connected - - - Coarse locations of avatars in this simulator - - - AvatarPositions key representing TrackAgent target - - - Sequence numbers of packets we've received - (for duplicate checking) - - - Packets we sent out that need ACKs from the simulator - - - Sequence number for pause/resume - - - Indicates if UDP connection to the sim is fully established - - - - - - Reference to the GridClient object - IPEndPoint of the simulator - handle of the simulator - - - - Called when this Simulator object is being destroyed - - - - - Attempt to connect to this simulator - - Whether to move our agent in to this sim or not - True if the connection succeeded or connection status is - unknown, false if there was a failure - - - - Initiates connection to the simulator - - Should we block until ack for this packet is recieved - - - - Disconnect from this simulator - - - - - Instructs the simulator to stop sending update (and possibly other) packets - - - - - Instructs the simulator to resume sending update packets (unpause) - - - - - Retrieve the terrain height at a given coordinate - - Sim X coordinate, valid range is from 0 to 255 - Sim Y coordinate, valid range is from 0 to 255 - The terrain height at the given point if the - lookup was successful, otherwise 0.0f - True if the lookup was successful, otherwise false - - - - Sends a packet - - Packet to be sent - - - - - - - - - Returns Simulator Name as a String - - - - - - - - - - - - - - - - - - - Sends out pending acknowledgements - - Number of ACKs sent - - - - Resend unacknowledged packets - - - - - Simulator handle - - - - - Number of GridClients using this datapool - - - - - Time that the last client disconnected from the simulator - - - - - The cache of prims used and unused in this simulator - - - - - Shared parcel info only when POOL_PARCEL_DATA == true - - - - - - - - - The event subscribers, null of no subscribers - - - Raises the AttachedSound Event - A AttachedSoundEventArgs object containing - the data sent from the simulator - - - Thread sync lock object - - - Raised when the simulator sends us data containing - sound - - - The event subscribers, null of no subscribers - - - Raises the AttachedSoundGainChange Event - A AttachedSoundGainChangeEventArgs object containing - the data sent from the simulator - - - Thread sync lock object - - - Raised when the simulator sends us data containing - ... - - - The event subscribers, null of no subscribers - - - Raises the SoundTrigger Event - A SoundTriggerEventArgs object containing - the data sent from the simulator - - - Thread sync lock object - - - Raised when the simulator sends us data containing - ... - - - The event subscribers, null of no subscribers - - - Raises the PreloadSound Event - A PreloadSoundEventArgs object containing - the data sent from the simulator - - - Thread sync lock object - - - Raised when the simulator sends us data containing - ... - - - - Construct a new instance of the SoundManager class, used for playing and receiving - sound assets - - A reference to the current GridClient instance - - - - Plays a sound in the current region at full volume from avatar position - - UUID of the sound to be played - - - - Plays a sound in the current region at full volume - - UUID of the sound to be played. - position for the sound to be played at. Normally the avatar. - - - - Plays a sound in the current region - - UUID of the sound to be played. - position for the sound to be played at. Normally the avatar. - volume of the sound, from 0.0 to 1.0 - - - - Plays a sound in the specified sim - - UUID of the sound to be played. - UUID of the sound to be played. - position for the sound to be played at. Normally the avatar. - volume of the sound, from 0.0 to 1.0 - - - - Play a sound asset - - UUID of the sound to be played. - handle id for the sim to be played in. - position for the sound to be played at. Normally the avatar. - volume of the sound, from 0.0 to 1.0 - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Process an incoming packet and raise the appropriate events - The sender - The EventArgs object containing the packet data - - - Provides data for the event - The event occurs when the simulator sends - the sound data which emits from an agents attachment - - The following code example shows the process to subscribe to the event - and a stub to handle the data passed from the simulator - - // Subscribe to the AttachedSound event - Client.Sound.AttachedSound += Sound_AttachedSound; - - // process the data raised in the event here - private void Sound_AttachedSound(object sender, AttachedSoundEventArgs e) - { - // ... Process AttachedSoundEventArgs here ... - } - - - - - Simulator where the event originated - - - Get the sound asset id - - - Get the ID of the owner - - - Get the ID of the Object - - - Get the volume level - - - Get the - - - - Construct a new instance of the SoundTriggerEventArgs class - - Simulator where the event originated - The sound asset id - The ID of the owner - The ID of the object - The volume level - The - - - Provides data for the event - The event occurs when an attached sound - changes its volume level - - - Simulator where the event originated - - - Get the ID of the Object - - - Get the volume level - - - - Construct a new instance of the AttachedSoundGainChangedEventArgs class - - Simulator where the event originated - The ID of the Object - The new volume level - - - Provides data for the event - The event occurs when the simulator forwards - a request made by yourself or another agent to play either an asset sound or a built in sound - - Requests to play sounds where the is not one of the built-in - will require sending a request to download the sound asset before it can be played - - - The following code example uses the , - and - properties to display some information on a sound request on the window. - - // subscribe to the event - Client.Sound.SoundTrigger += Sound_SoundTrigger; - - // play the pre-defined BELL_TING sound - Client.Sound.SendSoundTrigger(Sounds.BELL_TING); - - // handle the response data - private void Sound_SoundTrigger(object sender, SoundTriggerEventArgs e) - { - Console.WriteLine("{0} played the sound {1} at volume {2}", - e.OwnerID, e.SoundID, e.Gain); - } - - - - - Simulator where the event originated - - - Get the sound asset id - - - Get the ID of the owner - - - Get the ID of the Object - - - Get the ID of the objects parent - - - Get the volume level - - - Get the regionhandle - - - Get the source position - - - - Construct a new instance of the SoundTriggerEventArgs class - - Simulator where the event originated - The sound asset id - The ID of the owner - The ID of the object - The ID of the objects parent - The volume level - The regionhandle - The source position - - - Provides data for the event - The event occurs when the simulator sends - the appearance data for an avatar - - The following code example uses the and - properties to display the selected shape of an avatar on the window. - - // subscribe to the event - Client.Avatars.AvatarAppearance += Avatars_AvatarAppearance; - - // handle the data when the event is raised - void Avatars_AvatarAppearance(object sender, AvatarAppearanceEventArgs e) - { - Console.WriteLine("The Agent {0} is using a {1} shape.", e.AvatarID, (e.VisualParams[31] > 0) : "male" ? "female") - } - - - - - Simulator where the event originated - - - Get the sound asset id - - - Get the ID of the owner - - - Get the ID of the Object - - - - Construct a new instance of the PreloadSoundEventArgs class - - Simulator where the event originated - The sound asset id - The ID of the owner - The ID of the object - - - - pre-defined built in sounds - - - - - - - - - - - - - - - - - - - - - - - - - - - - coins - - - cash register bell - - - - - - - - - rubber - - - plastic - - - flesh - - - wood splintering? - - - glass break - - - metal clunk - - - whoosh - - - shake - - - - - - ding - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - A dictionary containing all pre-defined sounds - - A dictionary containing the pre-defined sounds, - where the key is the sounds ID, and the value is a string - containing a name to identify the purpose of the sound - - - X position of this patch - - - Y position of this patch - - - A 16x16 array of floats holding decompressed layer data - - - - Creates a LayerData packet for compressed land data given a full - simulator heightmap and an array of indices of patches to compress - - A 256 * 256 array of floating point values - specifying the height at each meter in the simulator - Array of indexes in the 16x16 grid of patches - for this simulator. For example if 1 and 17 are specified, patches - x=1,y=0 and x=1,y=1 are sent - - - - - Add a patch of terrain to a BitPacker - - BitPacker to write the patch to - Heightmap of the simulator, must be a 256 * - 256 float array - X offset of the patch to create, valid values are - from 0 to 15 - Y offset of the patch to create, valid values are - from 0 to 15 - - - The event subscribers. null if no subcribers - - - Raises the LandPatchReceived event - A LandPatchReceivedEventArgs object containing the - data returned from the simulator - - - Thread sync lock object - - - Raised when the simulator responds sends - - - - Default constructor - - - - - Simulator from that sent tha data - - - Sim coordinate of the patch - - - Sim coordinate of the patch - - - Size of tha patch - - - Heightmap for the patch - - - - The current status of a texture request as it moves through the pipeline or final result of a texture request. - - - - The initial state given to a request. Requests in this state - are waiting for an available slot in the pipeline - - - A request that has been added to the pipeline and the request packet - has been sent to the simulator - - - A request that has received one or more packets back from the simulator - - - A request that has received all packets back from the simulator - - - A request that has taken longer than - to download OR the initial packet containing the packet information was never received - - - The texture request was aborted by request of the agent - - - The simulator replied to the request that it was not able to find the requested texture - - - - A callback fired to indicate the status or final state of the requested texture. For progressive - downloads this will fire each time new asset data is returned from the simulator. - - The indicating either Progress for textures not fully downloaded, - or the final result of the request after it has been processed through the TexturePipeline - The object containing the Assets ID, raw data - and other information. For progressive rendering the will contain - the data from the beginning of the file. For failed, aborted and timed out requests it will contain - an empty byte array. - - - - Texture request download handler, allows a configurable number of download slots which manage multiple - concurrent texture downloads from the - - This class makes full use of the internal - system for full texture downloads. - - - - A request task containing information and status of a request as it is processed through the - - - - The current which identifies the current status of the request - - - The Unique Request ID, This is also the Asset ID of the texture being requested - - - The slot this request is occupying in the threadpoolSlots array - - - The ImageType of the request. - - - The callback to fire when the request is complete, will include - the and the - object containing the result data - - - If true, indicates the callback will be fired whenever new data is returned from the simulator. - This is used to progressively render textures as portions of the texture are received. - - - An object that maintains the data of an request thats in-process. - - - A dictionary containing all pending and in-process transfer requests where the Key is both the RequestID - and also the Asset Texture ID, and the value is an object containing the current state of the request and also - the asset data as it is being re-assembled - - - Holds the reference to the client object - - - Maximum concurrent texture requests allowed at a time - - - An array of objects used to manage worker request threads - - - An array of worker slots which shows the availablity status of the slot - - - The primary thread which manages the requests. - - - true if the TexturePipeline is currently running - - - A synchronization object used by the primary thread - - - A refresh timer used to increase the priority of stalled requests - - - Current number of pending and in-process transfers - - - - Default constructor, Instantiates a new copy of the TexturePipeline class - - Reference to the instantiated object - - - - Initialize callbacks required for the TexturePipeline to operate - - - - - Shutdown the TexturePipeline and cleanup any callbacks or transfers - - - - - Request a texture asset from the simulator using the system to - manage the requests and re-assemble the image from the packets received from the simulator - - The of the texture asset to download - The of the texture asset. - Use for most textures, or for baked layer texture assets - A float indicating the requested priority for the transfer. Higher priority values tell the simulator - to prioritize the request before lower valued requests. An image already being transferred using the can have - its priority changed by resending the request with the new priority value - Number of quality layers to discard. - This controls the end marker of the data sent - The packet number to begin the request at. A value of 0 begins the request - from the start of the asset texture - The callback to fire when the image is retrieved. The callback - will contain the result of the request and the texture asset data - If true, the callback will be fired for each chunk of the downloaded image. - The callback asset parameter will contain all previously received chunks of the texture asset starting - from the beginning of the request - - - - Sends the actual request packet to the simulator - - The image to download - Type of the image to download, either a baked - avatar texture or a normal texture - Priority level of the download. Default is - 1,013,000.0f - Number of quality layers to discard. - This controls the end marker of the data sent - Packet number to start the download at. - This controls the start marker of the data sent - Sending a priority of 0 and a discardlevel of -1 aborts - download - - - - Cancel a pending or in process texture request - - The texture assets unique ID - - - - Master Download Thread, Queues up downloads in the threadpool - - - - - The worker thread that sends the request and handles timeouts - - A object containing the request details - - - - Handle responses from the simulator that tell us a texture we have requested is unable to be located - or no longer exists. This will remove the request from the pipeline and free up a slot if one is in use - - The sender - The EventArgs object containing the packet data - - - - Handles the remaining Image data that did not fit in the initial ImageData packet - - The sender - The EventArgs object containing the packet data - - - - Handle the initial ImageDataPacket sent from the simulator - - The sender - The EventArgs object containing the packet data - - - - - - - - - Initialize the UDP packet handler in server mode - - Port to listening for incoming UDP packets on - - - - Initialize the UDP packet handler in client mode - - Remote UDP server to connect to - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Operation to apply when applying color to texture - - - - - Information needed to translate visual param value to RGBA color - - - - - Construct VisualColorParam - - Operation to apply when applying color to texture - Colors - - - - Represents alpha blending and bump infor for a visual parameter - such as sleive length - - - - Stregth of the alpha to apply - - - File containing the alpha channel - - - Skip blending if parameter value is 0 - - - Use miltiply insted of alpha blending - - - - Create new alhpa information for a visual param - - Stregth of the alpha to apply - File containing the alpha channel - Skip blending if parameter value is 0 - Use miltiply insted of alpha blending - - - - A single visual characteristic of an avatar mesh, such as eyebrow height - - - - Index of this visual param - - - Internal name - - - Group ID this parameter belongs to - - - Name of the wearable this parameter belongs to - - - Displayable label of this characteristic - - - Displayable label for the minimum value of this characteristic - - - Displayable label for the maximum value of this characteristic - - - Default value - - - Minimum value - - - Maximum value - - - Is this param used for creation of bump layer? - - - Alpha blending/bump info - - - Color information - - - Array of param IDs that are drivers for this parameter - - - - Set all the values through the constructor - - Index of this visual param - Internal name - - - Displayable label of this characteristic - Displayable label for the minimum value of this characteristic - Displayable label for the maximum value of this characteristic - Default value - Minimum value - Maximum value - Is this param used for creation of bump layer? - Array of param IDs that are drivers for this parameter - Alpha blending/bump info - Color information - - - - Holds the Params array of all the avatar appearance parameters - - - - - Base class for all Asset types - - - - A byte array containing the raw asset data - - - True if the asset it only stored on the server temporarily - - - A unique ID - - - The assets unique ID - - - - The "type" of asset, Notecard, Animation, etc - - - - - Construct a new Asset object - - - - - Construct a new Asset object - - A unique specific to this asset - A byte array containing the raw asset data - - - - Regenerates the AssetData byte array from the properties - of the derived class. - - - - - Decodes the AssetData, placing it in appropriate properties of the derived - class. - - True if the asset decoding succeeded, otherwise false - - - - Constants for the archiving module - - - - - The location of the archive control file - - - - - Path for the assets held in an archive - - - - - Path for the prims file - - - - - Path for terrains. Technically these may be assets, but I think it's quite nice to split them out. - - - - - Path for region settings. - - - - - Path for region settings. - - - - - The character the separates the uuid from extension information in an archived asset filename - - - - - Extensions used for asset types in the archive - - - - - Archives assets - - - - - Archive assets - - - - - Archive the assets given to this archiver to the given archive. - - - - - - Write an assets metadata file to the given archive - - - - - - Write asset data files to the given archive - - - - - - Temporary code to do the bare minimum required to read a tar archive for our purposes - - - - - Binary reader for the underlying stream - - - - - Used to trim off null chars - - - - - Used to trim off space chars - - - - - Generate a tar reader which reads from the given stream. - - - - - - Read the next entry in the tar file. - - - - the data for the entry. Returns null if there are no more entries - - - - Read the next 512 byte chunk of data as a tar header. - - A tar header struct. null if we have reached the end of the archive. - - - - Read data following a header - - - - - - - Convert octal bytes to a decimal representation - - - - - - - - - Temporary code to produce a tar archive in tar v7 format - - - - - Binary writer for the underlying stream - - - - - Write a directory entry to the tar archive. We can only handle one path level right now! - - - - - - Write a file to the tar archive - - - - - - - Write a file to the tar archive - - - - - - - Finish writing the raw tar archive data to a stream. The stream will be closed on completion. - - - - - Write a particular entry - - - - - - - - Represents an Animation - - - - Override the base classes AssetType - - - Default Constructor - - - - Construct an Asset object of type Animation - - A unique specific to this asset - A byte array containing the raw asset data - - - - Represents an that represents an avatars body ie: Hair, Etc. - - - - Override the base classes AssetType - - - Initializes a new instance of an AssetBodyPart object - - - Initializes a new instance of an AssetBodyPart object with parameters - A unique specific to this asset - A byte array containing the raw asset data - - - - Represents a Callingcard with AvatarID and Position vector - - - - Override the base classes AssetType - - - UUID of the Callingcard target avatar - - - Construct an Asset of type Callingcard - - - - Construct an Asset object of type Callingcard - - A unique specific to this asset - A byte array containing the raw asset data - - - - Constuct an asset of type Callingcard - - UUID of the target avatar - - - - Encode the raw contents of a string with the specific Callingcard format - - - - - Decode the raw asset data, populating the AvatarID and Position - - true if the AssetData was successfully decoded to a UUID and Vector - - - - Represents an that can be worn on an avatar - such as a Shirt, Pants, etc. - - - - Override the base classes AssetType - - - Initializes a new instance of an AssetScriptBinary object - - - Initializes a new instance of an AssetScriptBinary object with parameters - A unique specific to this asset - A byte array containing the raw asset data - - - - Type of gesture step - - - - - Base class for gesture steps - - - - - Retururns what kind of gesture step this is - - - - - Describes animation step of a gesture - - - - - Returns what kind of gesture step this is - - - - - If true, this step represents start of animation, otherwise animation stop - - - - - Animation asset - - - - - Animation inventory name - - - - - Describes sound step of a gesture - - - - - Returns what kind of gesture step this is - - - - - Sound asset - - - - - Sound inventory name - - - - - Describes sound step of a gesture - - - - - Returns what kind of gesture step this is - - - - - Text to output in chat - - - - - Describes sound step of a gesture - - - - - Returns what kind of gesture step this is - - - - - If true in this step we wait for all animations to finish - - - - - If true gesture player should wait for the specified amount of time - - - - - Time in seconds to wait if WaitForAnimation is false - - - - - Describes the final step of a gesture - - - - - Returns what kind of gesture step this is - - - - - Represents a sequence of animations, sounds, and chat actions - - - - - Returns asset type - - - - - Keyboard key that triggers the gestyre - - - - - Modifier to the trigger key - - - - - String that triggers playing of the gesture sequence - - - - - Text that replaces trigger in chat once gesture is triggered - - - - - Sequence of gesture steps - - - - - Constructs guesture asset - - - - - Constructs guesture asset - - A unique specific to this asset - A byte array containing the raw asset data - - - - Encodes gesture asset suitable for uplaod - - - - - Decodes gesture assset into play sequence - - true if the asset data was decoded successfully - - - - Represents a Landmark with RegionID and Position vector - - - - Override the base classes AssetType - - - UUID of the Landmark target region - - - Local position of the target - - - Construct an Asset of type Landmark - - - - Construct an Asset object of type Landmark - - A unique specific to this asset - A byte array containing the raw asset data - - - - Encode the raw contents of a string with the specific Landmark format - - - - - Decode the raw asset data, populating the RegionID and Position - - true if the AssetData was successfully decoded to a UUID and Vector - - - - Represents Mesh asset - - - - Override the base classes AssetType - - - - Decoded mesh data - - - - Initializes a new instance of an AssetMesh object - - - Initializes a new instance of an AssetMesh object with parameters - A unique specific to this asset - A byte array containing the raw asset data - - - - TODO: Encodes Collada file into LLMesh format - - - - - Decodes mesh asset. See - to furter decode it for rendering - true - - - - Represents an Animation - - - - Override the base classes AssetType - - - Default Constructor - - - - Construct an Asset object of type Animation - - Asset type - A unique specific to this asset - A byte array containing the raw asset data - - - - Represents a string of characters encoded with specific formatting properties - - - - Override the base classes AssetType - - - A text string containing main text of the notecard - - - List of s embedded on the notecard - - - Construct an Asset of type Notecard - - - - Construct an Asset object of type Notecard - - A unique specific to this asset - A byte array containing the raw asset data - - - - Encode the raw contents of a string with the specific Linden Text properties - - - - - Decode the raw asset data including the Linden Text properties - - true if the AssetData was successfully decoded - - - - A linkset asset, containing a parent primitive and zero or more children - - - - - Only used internally for XML serialization/deserialization - - - - Override the base classes AssetType - - - Initializes a new instance of an AssetPrim object - - - - Initializes a new instance of an AssetPrim object - - A unique specific to this asset - A byte array containing the raw asset data - - - - - - - - - - - - - - - The deserialized form of a single primitive in a linkset asset - - - - - Represents an AssetScriptBinary object containing the - LSO compiled bytecode of an LSL script - - - - Override the base classes AssetType - - - Initializes a new instance of an AssetScriptBinary object - - - Initializes a new instance of an AssetScriptBinary object with parameters - A unique specific to this asset - A byte array containing the raw asset data - - - - TODO: Encodes a scripts contents into a LSO Bytecode file - - - - - TODO: Decode LSO Bytecode into a string - - true - - - - Represents an LSL Text object containing a string of UTF encoded characters - - - - Override the base classes AssetType - - - A string of characters represting the script contents - - - Initializes a new AssetScriptText object - - - - Initializes a new AssetScriptText object with parameters - - A unique specific to this asset - A byte array containing the raw asset data - - - - Encode a string containing the scripts contents into byte encoded AssetData - - - - - Decode a byte array containing the scripts contents into a string - - true if decoding is successful - - - - Represents a Sound Asset - - - - Override the base classes AssetType - - - Initializes a new instance of an AssetSound object - - - Initializes a new instance of an AssetSound object with parameters - A unique specific to this asset - A byte array containing the raw asset data - - - - TODO: Encodes a sound file - - - - - TODO: Decode a sound file - - true - - - - Represents a texture - - - - Override the base classes AssetType - - - A object containing image data - - - - - - - - - Initializes a new instance of an AssetTexture object - - - - Initializes a new instance of an AssetTexture object - - A unique specific to this asset - A byte array containing the raw asset data - - - - Initializes a new instance of an AssetTexture object - - A object containing texture data - - - - Populates the byte array with a JPEG2000 - encoded image created from the data in - - - - - Decodes the JPEG2000 data in AssetData to the - object - - True if the decoding was successful, otherwise false - - - - Decodes the begin and end byte positions for each quality layer in - the image - - - - - - Represents a Wearable Asset, Clothing, Hair, Skin, Etc - - - - A string containing the name of the asset - - - A string containing a short description of the asset - - - The Assets WearableType - - - The For-Sale status of the object - - - An Integer representing the purchase price of the asset - - - The of the assets creator - - - The of the assets current owner - - - The of the assets prior owner - - - The of the Group this asset is set to - - - True if the asset is owned by a - - - The Permissions mask of the asset - - - A Dictionary containing Key/Value pairs of the objects parameters - - - A Dictionary containing Key/Value pairs where the Key is the textures Index and the Value is the Textures - - - Initializes a new instance of an AssetWearable object - - - Initializes a new instance of an AssetWearable object with parameters - A unique specific to this asset - A byte array containing the raw asset data - - - - Decode an assets byte encoded data to a string - - true if the asset data was decoded successfully - - - - Encode the assets string represantion into a format consumable by the asset server - - - - = - - - Number of times we've received an unknown CAPS exception in series. - - - For exponential backoff on error. - - - - A set of textures that are layered on texture of each other and "baked" - in to a single texture, for avatar appearances - - - - Final baked texture - - - Component layers - - - Width of the final baked image and scratchpad - - - Height of the final baked image and scratchpad - - - Bake type - - - Is this one of the 3 skin bakes - - - Final baked texture - - - Component layers - - - Width of the final baked image and scratchpad - - - Height of the final baked image and scratchpad - - - Bake type - - - - Default constructor - - Bake type - - - - Adds layer for baking - - TexturaData struct that contains texture and its params - - - - Converts avatar texture index (face) to Bake type - - Face number (AvatarTextureIndex) - BakeType, layer to which this texture belongs to - - - - Make sure images exist, resize source if needed to match the destination - - Destination image - Source image - Sanitization was succefull - - - - Fills a baked layer as a solid *appearing* color. The colors are - subtly dithered on a 16x16 grid to prevent the JPEG2000 stage from - compressing it too far since it seems to cause upload failures if - the image is a pure solid color - - Color of the base of this layer - - - - Fills a baked layer as a solid *appearing* color. The colors are - subtly dithered on a 16x16 grid to prevent the JPEG2000 stage from - compressing it too far since it seems to cause upload failures if - the image is a pure solid color - - Red value - Green value - Blue value - - - - Image width - - - - - Image height - - - - - Image channel flags - - - - - Red channel data - - - - - Green channel data - - - - - Blue channel data - - - - - Alpha channel data - - - - - Bump channel data - - - - - Create a new blank image - - width - height - channel flags - - - - - - - - - - Convert the channels in the image. Channels are created or destroyed as required. - - new channel flags - - - - Resize or stretch the image using nearest neighbor (ugly) resampling - - new width - new height - - - - Create a byte array containing 32-bit RGBA data with a bottom-left - origin, suitable for feeding directly into OpenGL - - A byte array containing raw texture data - - - - Create a byte array containing 32-bit RGBA data with a bottom-left - origin, suitable for feeding directly into OpenGL - - A byte array containing raw texture data - - - - A Wrapper around openjpeg to encode and decode images to and from byte arrays - - - - TGA Header size - - - - Defines the beginning and ending file positions of a layer in an - LRCP-progression JPEG2000 file - - - - - This structure is used to marshal both encoded and decoded images. - MUST MATCH THE STRUCT IN dotnet.h! - - - - - Information about a single packet in a JPEG2000 stream - - - - Packet start position - - - Packet header end position - - - Packet end position - - - OpenJPEG is not threadsafe, so this object is used to lock - during calls into unmanaged code - - - - Encode a object into a byte array - - The object to encode - true to enable lossless conversion, only useful for small images ie: sculptmaps - A byte array containing the encoded Image object - - - - Encode a object into a byte array - - The object to encode - a byte array of the encoded image - - - - Decode JPEG2000 data to an and - - - JPEG2000 encoded data - ManagedImage object to decode to - Image object to decode to - True if the decode succeeds, otherwise false - - - - - - - - - - - - - - - - - - - - - Encode a object into a byte array - - The source object to encode - true to enable lossless decoding - A byte array containing the source Bitmap object - - - - Capability to load TGAs to Bitmap - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Parsing Collada model files into data structures - - - - - Parses Collada document - - Load .dae model from this file - Load and decode images for uploading with model - A list of mesh prims that were parsed from the collada file - - - - Implements mesh upload communications with the simulator - - - - - Inlcude stub convex hull physics, required for uploading to Second Life - - - - - Use the same mesh used for geometry as the physical mesh upload - - - - - Callback for mesh upload operations - - null on failure, result from server on success - - - - Creates instance of the mesh uploader - - GridClient instance to communicate with the simulator - List of ModelPrimitive objects to upload as a linkset - Inventory name for newly uploaded object - Inventory description for newly upload object - - - - Performs model upload in one go, without first checking for the price - - - - - Performs model upload in one go, without first checking for the price - - Callback that will be invoke upon completion of the upload. Null is sent on request failure - - - - Ask server for details of cost and impact of the mesh upload - - Callback that will be invoke upon completion of the upload. Null is sent on request failure - - - - Performas actual mesh and image upload - - Uri recieved in the upload prepare stage - Callback that will be invoke upon completion of the upload. Null is sent on request failure - - - - Interface requirements for Messaging system - - - - - Abstract base for rendering plugins - - - - - Generates a basic mesh structure from a primitive - - Primitive to generate the mesh from - Level of detail to generate the mesh at - The generated mesh - - - - Generates a basic mesh structure from a sculpted primitive and - texture - - Sculpted primitive to generate the mesh from - Sculpt texture - Level of detail to generate the mesh at - The generated mesh - - - - Generates a series of faces, each face containing a mesh and - metadata - - Primitive to generate the mesh from - Level of detail to generate the mesh at - The generated mesh - - - - Generates a series of faces for a sculpted prim, each face - containing a mesh and metadata - - Sculpted primitive to generate the mesh from - Sculpt texture - Level of detail to generate the mesh at - The generated mesh - - - - Apply texture coordinate modifications from a - to a list of vertices - - Vertex list to modify texture coordinates for - Center-point of the face - Face texture parameters - Scale of the prim - - - - Binary reader, which is endian aware - - - - What is the format of the source file - - - - Construct a reader from a stream - - The stream to read from - - - - Construct a reader from a stream - - The stream to read from - What is the format of the file, assumes PC and similar architecture - - - - Read a 32 bit integer - - A 32 bit integer in the system's endianness - - - - Read a 16 bit integer - - A 16 bit integer in the system's endianness - - - - Read a 64 bit integer - - A 64 bit integer in the system's endianness - - - - Read an unsigned 32 bit integer - - A 32 bit unsigned integer in the system's endianness - - - - Read a single precision floating point value - - A single precision floating point value in the system's endianness - - - - Read a double precision floating point value - - A double precision floating point value in the system's endianness - - - - Read a UTF-8 string - - A standard system string - - - - Read a UTF-8 string - - length of string to read - A standard system string - - - - Load and handle Linden Lab binary meshes. - - - The exact definition of this file is a bit sketchy, especially concerning skin weights. - A good starting point is on the - second life wiki - - - - - Defines a polygon - - - - - Structure of a vertex, No surprises there, except for the Detail tex coord - - - The skinweights are a tad unconventional. The best explanation found is: - >Each weight actually contains two pieces of information. The number to the - >left of the decimal point is the index of the joint and also implicitly - >indexes to the following joint. The actual weight is to the right of the - >decimal point and interpolates between these two joints. The index is into - >an "expanded" list of joints, not just a linear array of the joints as - >defined in the skeleton file. In particular, any joint that has more than - >one child will be repeated in the list for each of its children. - - Maybe I'm dense, but that description seems to be a bit hard to build an - algorithm on. - - Esentially the weights are compressed into one floating point value. - 1. The whole number part is an index into an array of joints - 2. The fractional part is the weight that joint has - 3. If the fractional part is 0 (x.0000) then the vertex is 100% influenced by the specified joint - - - - - Provide a nice format for debugging - - Vertex definition as a string - - - - Describes deltas to apply to a vertex in order to morph a vertex - - - - - Provide a nice format for debugging - - MorphVertex definition as a string - - - - Describes a named mesh morph, essentially a named list of MorphVertices - - - - - Provide a nice format for debugging - - The name of the morph - - - - Don't really know what this does - - - - - Provide a nice format for debugging - - Human friendly format - - - - A reference mesh is one way to implement level of detail - - - Reference meshes are supplemental meshes to full meshes. For all practical - purposes almost all lod meshes are implemented as reference meshes, except for - 'avatar_eye_1.llm' which for some reason is implemented as a full mesh. - - - - - Load a mesh from a stream - - Filename and path of the file containing the reference mesh - - - - Level of Detail mesh - - - - - Construct a linden mesh with the given name - - the name of the mesh - - - - Construct a linden mesh with the given name - - the name of the mesh - The skeleton governing mesh deformation - - - - Load the mesh from a stream - - The filename and path of the file containing the mesh data - - - - Layout of one skinweight element - - - - List of skinweights, in the same order as the mesh vertices - - - - Decompress the skinweights - - the expanded joint list, used to index which bones should influece the vertex - - - - Load a reference mesh from a given stream - - The lod level of this reference mesh - the name and path of the file containing the mesh data - the loaded reference mesh - - - - Trim a string at the first occurence of NUL - - - The llm file uses null terminated strings (C/C++ style), this is where - the conversion is made. - - The string to trim - A standard .Net string - - - - load the 'avatar_skeleton.xml' - - - Partial class which extends the auto-generated 'LindenSkeleton.Xsd.cs'.eton.xsd - - - - - - Load a skeleton from a given file. - - - We use xml scema validation on top of the xml de-serializer, since the schema has - some stricter checks than the de-serializer provides. E.g. the vector attributes - are guaranteed to hold only 3 float values. This reduces the need for error checking - while working with the loaded skeleton. - - A valid recursive skeleton - - - - Load a skeleton from a given file. - - - We use xml scema validation on top of the xml de-serializer, since the schema has - some stricter checks than the de-serializer provides. E.g. the vector attributes - are guaranteed to hold only 3 float values. This reduces the need for error checking - while working with the loaded skeleton. - - The path to the skeleton definition file - A valid recursive skeleton - - - - Build and "expanded" list of joints - - - The algorithm is based on this description: - - >An "expanded" list of joints, not just a - >linear array of the joints as defined in the skeleton file. - >In particular, any joint that has more than one child will - >be repeated in the list for each of its children. - - The list should only take these joint names in consideration - An "expanded" joints list as a flat list of bone names - - - - Expand one joint - - The parent of the joint we are operating on - The joint we are supposed to expand - Joint list that we will extend upon - The expanded list should only contain these joints - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Contains all mesh faces that belong to a prim - - - - List of primitive faces - - - - Decodes mesh asset into FacetedMesh - - Mesh primitive - Asset retrieved from the asset server - Level of detail - Resulting decoded FacetedMesh - True if mesh asset decoding was successful - - - - Sent to the client to indicate a teleport request has completed - - - - The of the agent - - - - - - The simulators handle the agent teleported to - - - A Uri which contains a list of Capabilities the simulator supports - - - Indicates the level of access required - to access the simulator, or the content rating, or the simulators - map status - - - The IP Address of the simulator - - - The UDP Port the simulator will listen for UDP traffic on - - - Status flags indicating the state of the Agent upon arrival, Flying, etc. - - - - Serialize the object - - An containing the objects data - - - - Deserialize the message - - An containing the data - - - - Sent to the viewer when a neighboring simulator is requesting the agent make a connection to it. - - - - - Serialize the object - - An containing the objects data - - - - Deserialize the message - - An containing the data - - - - Serialize the object - - An containing the objects data - - - - Deserialize the message - - An containing the data - - - - Serialize the object - - An containing the objects data - - - - Deserialize the message - - An containing the data - - - - A message sent to the client which indicates a teleport request has failed - and contains some information on why it failed - - - - - - - A string key of the reason the teleport failed e.g. CouldntTPCloser - Which could be used to look up a value in a dictionary or enum - - - The of the Agent - - - A string human readable message containing the reason - An example: Could not teleport closer to destination - - - - Serialize the object - - An containing the objects data - - - - Deserialize the message - - An containing the data - - - - Serialize the object - - An containing the objects data - - - - Deserialize the message - - An containing the data - - - - Contains a list of prim owner information for a specific parcel in a simulator - - - A Simulator will always return at least 1 entry - If agent does not have proper permission the OwnerID will be UUID.Zero - If agent does not have proper permission OR there are no primitives on parcel - the DataBlocksExtended map will not be sent from the simulator - - - - - Prim ownership information for a specified owner on a single parcel - - - - The of the prim owner, - UUID.Zero if agent has no permission to view prim owner information - - - The total number of prims - - - True if the OwnerID is a - - - True if the owner is online - This is no longer used by the LL Simulators - - - The date the most recent prim was rezzed - - - An Array of objects - - - - Serialize the object - - An containing the objects data - - - - Deserialize the message - - An containing the data - - - - The details of a single parcel in a region, also contains some regionwide globals - - - - Simulator-local ID of this parcel - - - Maximum corner of the axis-aligned bounding box for this - parcel - - - Minimum corner of the axis-aligned bounding box for this - parcel - - - Total parcel land area - - - - - - Key of authorized buyer - - - Bitmap describing land layout in 4x4m squares across the - entire region - - - - - - Date land was claimed - - - Appears to always be zero - - - Parcel Description - - - - - - - - - Total number of primitives owned by the parcel group on - this parcel - - - Whether the land is deeded to a group or not - - - - - - Maximum number of primitives this parcel supports - - - The Asset UUID of the Texture which when applied to a - primitive will display the media - - - A URL which points to any Quicktime supported media type - - - A byte, if 0x1 viewer should auto scale media to fit object - - - URL For Music Stream - - - Parcel Name - - - Autoreturn value in minutes for others' objects - - - - - - Total number of other primitives on this parcel - - - UUID of the owner of this parcel - - - Total number of primitives owned by the parcel owner on - this parcel - - - - - - How long is pass valid for - - - Price for a temporary pass - - - - - - Disallows people outside the parcel from being able to see in - - - - - - - - - - - - True if the region denies access to age unverified users - - - - - - This field is no longer used - - - The result of a request for parcel properties - - - Sale price of the parcel, only useful if ForSale is set - The SalePrice will remain the same after an ownership - transfer (sale), so it can be used to see the purchase price after - a sale if the new owner has not changed it - - - - Number of primitives your avatar is currently - selecting and sitting on in this parcel - - - - - - - - A number which increments by 1, starting at 0 for each ParcelProperties request. - Can be overriden by specifying the sequenceID with the ParcelPropertiesRequest being sent. - a Negative number indicates the action in has occurred. - - - - Maximum primitives across the entire simulator - - - Total primitives across the entire simulator - - - - - - Key of parcel snapshot - - - Parcel ownership status - - - Total number of primitives on this parcel - - - - - - - - - A description of the media - - - An Integer which represents the height of the media - - - An integer which represents the width of the media - - - A boolean, if true the viewer should loop the media - - - A string which contains the mime type of the media - - - true to obscure (hide) media url - - - true to obscure (hide) music url - - - true if avatars in this parcel should be invisible to people outside - - - true if avatars outside can hear any sounds avatars inside play - - - true if group members outside can hear any sounds avatars inside play - - - - Serialize the object - - An containing the objects data - - - - Deserialize the message - - An containing the data - - - A message sent from the viewer to the simulator to updated a specific parcels settings - - - The of the agent authorized to purchase this - parcel of land or a NULL if the sale is authorized to anyone - - - true to enable auto scaling of the parcel media - - - The category of this parcel used when search is enabled to restrict - search results - - - A string containing the description to set - - - The of the which allows for additional - powers and restrictions. - - - The which specifies how avatars which teleport - to this parcel are handled - - - The LocalID of the parcel to update settings on - - - A string containing the description of the media which can be played - to visitors - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - true if avatars in this parcel should be invisible to people outside - - - true if avatars outside can hear any sounds avatars inside play - - - true if group members outside can hear any sounds avatars inside play - - - - Deserialize the message - - An containing the data - - - - Serialize the object - - An containing the objects data - - - Base class used for the RemoteParcelRequest message - - - - A message sent from the viewer to the simulator to request information - on a remote parcel - - - - Local sim position of the parcel we are looking up - - - Region handle of the parcel we are looking up - - - Region of the parcel we are looking up - - - - Serialize the object - - An containing the objects data - - - - Deserialize the message - - An containing the data - - - - A message sent from the simulator to the viewer in response to a - which will contain parcel information - - - - The grid-wide unique parcel ID - - - - Serialize the object - - An containing the objects data - - - - Deserialize the message - - An containing the data - - - - A message containing a request for a remote parcel from a viewer, or a response - from the simulator to that request - - - - The request or response details block - - - - Serialize the object - - An containing the objects data - - - - Deserialize the message - - An containing the data - - - - Serialize the object - - An containing the objects data - - - - Deserialize the message - - An containing the data - - - - Serialize the object - - An containing the objects data - - - - Deserialize the message - - An containing the data - - - - A message sent from the simulator to an agent which contains - the groups the agent is in - - - - The Agent receiving the message - - - Group Details specific to the agent - - - true of the agent accepts group notices - - - The agents tier contribution to the group - - - The Groups - - - The of the groups insignia - - - The name of the group - - - The aggregate permissions the agent has in the group for all roles the agent - is assigned - - - An optional block containing additional agent specific information - - - true of the agent allows this group to be - listed in their profile - - - An array containing information - for each the agent is a member of - - - An array containing information - for each the agent is a member of - - - - Serialize the object - - An containing the objects data - - - - Deserialize the message - - An containing the data - - - - A message sent from the viewer to the simulator which - specifies the language and permissions for others to detect - the language specified - - - - A string containng the default language - to use for the agent - - - true of others are allowed to - know the language setting - - - - Serialize the object - - An containing the objects data - - - - Deserialize the message - - An containing the data - - - - An EventQueue message sent from the simulator to an agent when the agent - leaves a group - - - - An object containing the Agents UUID, and the Groups UUID - - - The ID of the Agent leaving the group - - - The GroupID the Agent is leaving - - - - An Array containing the AgentID and GroupID - - - - - Serialize the object - - An containing the objects data - - - - Deserialize the message - - An containing the data - - - Base class for Asset uploads/results via Capabilities - - - - The request state - - - - - Serialize the object - - An containing the objects data - - - - Deserialize the message - - An containing the data - - - - A message sent from the viewer to the simulator to request a temporary upload capability - which allows an asset to be uploaded - - - - The Capability URL sent by the simulator to upload the baked texture to - - - - A message sent from the simulator that will inform the agent the upload is complete, - and the UUID of the uploaded asset - - - - The uploaded texture asset ID - - - - A message sent from the viewer to the simulator to request a temporary - capability URI which is used to upload an agents baked appearance textures - - - - Object containing request or response - - - - Serialize the object - - An containing the objects data - - - - Deserialize the message - - An containing the data - - - - A message sent from the simulator which indicates the minimum version required for - using voice chat - - - - Major Version Required - - - Minor version required - - - The name of the region sending the version requrements - - - - Serialize the object - - An containing the objects data - - - - Deserialize the message - - An containing the data - - - - A message sent from the simulator to the viewer containing the - voice server URI - - - - The Parcel ID which the voice server URI applies - - - The name of the region - - - A uri containing the server/channel information - which the viewer can utilize to participate in voice conversations - - - - Serialize the object - - An containing the objects data - - - - Deserialize the message - - An containing the data - - - - - - - - - - - - - - - Serialize the object - - An containing the objects data - - - - Deserialize the message - - An containing the data - - - - A message sent by the viewer to the simulator to request a temporary - capability for a script contained with in a Tasks inventory to be updated - - - - Object containing request or response - - - - Serialize the object - - An containing the objects data - - - - Deserialize the message - - An containing the data - - - - A message sent from the simulator to the viewer to indicate - a Tasks scripts status. - - - - The Asset ID of the script - - - True of the script is compiled/ran using the mono interpreter, false indicates it - uses the older less efficient lsl2 interprter - - - The Task containing the scripts - - - true of the script is in a running state - - - - Serialize the object - - An containing the objects data - - - - Deserialize the message - - An containing the data - - - - A message containing the request/response used for updating a gesture - contained with an agents inventory - - - - Object containing request or response - - - - Serialize the object - - An containing the objects data - - - - Deserialize the message - - An containing the data - - - - A message request/response which is used to update a notecard contained within - a tasks inventory - - - - The of the Task containing the notecard asset to update - - - The notecard assets contained in the tasks inventory - - - - Serialize the object - - An containing the objects data - - - - Deserialize the message - - An containing the data - - - - A reusable class containing a message sent from the viewer to the simulator to request a temporary uploader capability - which is used to update an asset in an agents inventory - - - - - The Notecard AssetID to replace - - - - - Serialize the object - - An containing the objects data - - - - Deserialize the message - - An containing the data - - - - A message containing the request/response used for updating a notecard - contained with an agents inventory - - - - Object containing request or response - - - - Serialize the object - - An containing the objects data - - - - Deserialize the message - - An containing the data - - - - Serialize the object - - An containing the objects data - - - - Deserialize the message - - An containing the data - - - - A message sent from the simulator to the viewer which indicates - an error occurred while attempting to update a script in an agents or tasks - inventory - - - - true of the script was successfully compiled by the simulator - - - A string containing the error which occured while trying - to update the script - - - A new AssetID assigned to the script - - - - A message sent from the viewer to the simulator - requesting the update of an existing script contained - within a tasks inventory - - - - if true, set the script mode to running - - - The scripts InventoryItem ItemID to update - - - A lowercase string containing either "mono" or "lsl2" which - specifies the script is compiled and ran on the mono runtime, or the older - lsl runtime - - - The tasks which contains the script to update - - - - Serialize the object - - An containing the objects data - - - - Deserialize the message - - An containing the data - - - - A message containing either the request or response used in updating a script inside - a tasks inventory - - - - Object containing request or response - - - - Serialize the object - - An containing the objects data - - - - Deserialize the message - - An containing the data - - - - Response from the simulator to notify the viewer the upload is completed, and - the UUID of the script asset and its compiled status - - - - The uploaded texture asset ID - - - true of the script was compiled successfully - - - - A message sent from a viewer to the simulator requesting a temporary uploader capability - used to update a script contained in an agents inventory - - - - The existing asset if of the script in the agents inventory to replace - - - The language of the script - Defaults to lsl version 2, "mono" might be another possible option - - - - Serialize the object - - An containing the objects data - - - - Deserialize the message - - An containing the data - - - - A message containing either the request or response used in updating a script inside - an agents inventory - - - - Object containing request or response - - - - Serialize the object - - An containing the objects data - - - - Deserialize the message - - An containing the data - - - - Serialize the object - - An containing the objects data - - - - Deserialize the message - - An containing the data - - - Base class for Map Layers via Capabilities - - - - - - - Serialize the object - - An containing the objects data - - - - Deserialize the message - - An containing the data - - - - Sent by an agent to the capabilities server to request map layers - - - - - A message sent from the simulator to the viewer which contains an array of map images and their grid coordinates - - - - - An object containing map location details - - - - The Asset ID of the regions tile overlay - - - The grid location of the southern border of the map tile - - - The grid location of the western border of the map tile - - - The grid location of the eastern border of the map tile - - - The grid location of the northern border of the map tile - - - An array containing LayerData items - - - - Serialize the object - - An containing the objects data - - - - Deserialize the message - - An containing the data - - - Object containing request or response - - - - Serialize the object - - An containing the objects data - - - - Deserialize the message - - An containing the data - - - - New as of 1.23 RC1, no details yet. - - - - - Serialize the object - - An containing the objects data - - - - Deserialize the message - - An containing the data - - - - Serialize the object - - An containing the objects data - - - - Deserialize the message - - An containing the data - - - A string containing the method used - - - - A request sent from an agent to the Simulator to begin a new conference. - Contains a list of Agents which will be included in the conference - - - - An array containing the of the agents invited to this conference - - - The conferences Session ID - - - - Serialize the object - - An containing the objects data - - - - Deserialize the message - - An containing the data - - - - A moderation request sent from a conference moderator - Contains an agent and an optional action to take - - - - The Session ID - - - - - - A list containing Key/Value pairs, known valid values: - key: text value: true/false - allow/disallow specified agents ability to use text in session - key: voice value: true/false - allow/disallow specified agents ability to use voice in session - - "text" or "voice" - - - - - - - Serialize the object - - An containing the objects data - - - - Deserialize the message - - An containing the data - - - - A message sent from the agent to the simulator which tells the - simulator we've accepted a conference invitation - - - - The conference SessionID - - - - Serialize the object - - An containing the objects data - - - - Deserialize the message - - An containing the data - - - - Serialize the object - - An containing the objects data - - - - Deserialize the message - - An containing the data - - - - Serialize the object - - An containing the objects data - - - - Deserialize the message - - An containing the data - - - - Serialize the object - - An containing the objects data - - - - Deserialize the message - - An containing the data - - - Key of sender - - - Name of sender - - - Key of destination avatar - - - ID of originating estate - - - Key of originating region - - - Coordinates in originating region - - - Instant message type - - - Group IM session toggle - - - Key of IM session, for Group Messages, the groups UUID - - - Timestamp of the instant message - - - Instant message text - - - Whether this message is held for offline avatars - - - Context specific packed data - - - Is this invitation for voice group/conference chat - - - - Serialize the object - - An containing the objects data - - - - Deserialize the message - - An containing the data - - - - Sent from the simulator to the viewer. - - When an agent initially joins a session the AgentUpdatesBlock object will contain a list of session members including - a boolean indicating they can use voice chat in this session, a boolean indicating they are allowed to moderate - this session, and lastly a string which indicates another agent is entering the session with the Transition set to "ENTER" - - During the session lifetime updates on individuals are sent. During the update the booleans sent during the initial join are - excluded with the exception of the Transition field. This indicates a new user entering or exiting the session with - the string "ENTER" or "LEAVE" respectively. - - - - - Serialize the object - - An containing the objects data - - - - Deserialize the message - - An containing the data - - - - An EventQueue message sent when the agent is forcibly removed from a chatterbox session - - - - - A string containing the reason the agent was removed - - - - - The ChatterBoxSession's SessionID - - - - - Serialize the object - - An containing the objects data - - - - Deserialize the message - - An containing the data - - - - Serialize the object - - An containing the objects data - - - - Deserialize the message - - An containing the data - - - - Serialize the object - - An containing the objects data - - - - Deserialize the message - - An containing the data - - - - Serialize the object - - An containing the objects data - - - - Deserialize the message - - An containing the data - - - - Serialize the object - - An containing the objects data - - - - Deserialize the message - - An containing the data - - - - - - - - - Serialize the object - - An containing the objects data - - - - Deserialize the message - - An containing the data - - - - Serialize the object - - An containing the objects data - - - - Deserialize the message - - An containing the data - - - - Serialize the object - - An containing the objects data - - - - Deserialize the message - - An containing the data - - - - Event Queue message describing physics engine attributes of a list of objects - Sim sends these when object is selected - - - - Array with the list of physics properties - - - - Serializes the message - - Serialized OSD - - - - Deserializes the message - - Incoming data to deserialize - - - - Deserializes the message - - Incoming data to deserialize - - - - Serializes the message - - Serialized OSD - - - - - Deserializes the message - - Incoming data to deserialize - - - - Serializes the message - - Serialized OSD - - - - Deserializes the message - - Incoming data to deserialize - - - - Serializes the message - - Serialized OSD - - - - Detects which class handles deserialization of this message - - An containing the data - Object capable of decoding this message - - - - A message sent from the viewer to the simulator which - specifies that the user has changed current URL - of the specific media on a prim face - - - - - New URL - - - - - Prim UUID where navigation occured - - - - - Face index - - - - - Serialize the object - - An containing the objects data - - - - Deserialize the message - - An containing the data - - - Base class used for the ObjectMedia message - - - - Message used to retrive prim media data - - - - - Prim UUID - - - - - Requested operation, either GET or UPDATE - - - - - Serialize object - - Serialized object as OSDMap - - - - Deserialize the message - - An containing the data - - - - Message used to update prim media data - - - - - Prim UUID - - - - - Array of media entries indexed by face number - - - - - Media version string - - - - - Serialize object - - Serialized object as OSDMap - - - - Deserialize the message - - An containing the data - - - - Message used to update prim media data - - - - - Prim UUID - - - - - Array of media entries indexed by face number - - - - - Requested operation, either GET or UPDATE - - - - - Serialize object - - Serialized object as OSDMap - - - - Deserialize the message - - An containing the data - - - - Message for setting or getting per face MediaEntry - - - - The request or response details block - - - - Serialize the object - - An containing the objects data - - - - Deserialize the message - - An containing the data - - - Details about object resource usage - - - Object UUID - - - Object name - - - Indicates if object is group owned - - - Locatio of the object - - - Object owner - - - Resource usage, keys are resource names, values are resource usage for that specific resource - - - - Deserializes object from OSD - - An containing the data - - - - Makes an instance based on deserialized data - - serialized data - Instance containg deserialized data - - - Details about parcel resource usage - - - Parcel UUID - - - Parcel local ID - - - Parcel name - - - Indicates if parcel is group owned - - - Parcel owner - - - Array of containing per object resource usage - - - - Deserializes object from OSD - - An containing the data - - - - Makes an instance based on deserialized data - - serialized data - Instance containg deserialized data - - - Resource usage base class, both agent and parcel resource - usage contains summary information - - - Summary of available resources, keys are resource names, - values are resource usage for that specific resource - - - Summary resource usage, keys are resource names, - values are resource usage for that specific resource - - - - Serializes object - - serialized data - - - - Deserializes object from OSD - - An containing the data - - - Agent resource usage - - - Per attachment point object resource usage - - - - Deserializes object from OSD - - An containing the data - - - - Makes an instance based on deserialized data - - serialized data - Instance containg deserialized data - - - - Detects which class handles deserialization of this message - - An containing the data - Object capable of decoding this message - - - Request message for parcel resource usage - - - UUID of the parel to request resource usage info - - - - Serializes object - - serialized data - - - - Deserializes object from OSD - - An containing the data - - - Response message for parcel resource usage - - - URL where parcel resource usage details can be retrieved - - - URL where parcel resource usage summary can be retrieved - - - - Serializes object - - serialized data - - - - Deserializes object from OSD - - An containing the data - - - - Detects which class handles deserialization of this message - - An containing the data - Object capable of decoding this message - - - Parcel resource usage - - - Array of containing per percal resource usage - - - - Deserializes object from OSD - - An containing the data - - - - Reply to request for bunch if display names - - - - Current display name - - - Following UUIDs failed to return a valid display name - - - - Serializes the message - - OSD containting the messaage - - - - Message sent when requesting change of the display name - - - - Current display name - - - Desired new display name - - - - Serializes the message - - OSD containting the messaage - - - - Message recieved in response to request to change display name - - - - New display name - - - String message indicating the result of the operation - - - Numerical code of the result, 200 indicates success - - - - Serializes the message - - OSD containting the messaage - - - - Message recieved when someone nearby changes their display name - - - - Previous display name, empty string if default - - - New display name - - - - Serializes the message - - OSD containting the messaage - - - - Return a decoded capabilities message as a strongly typed object - - A string containing the name of the capabilities message key - An to decode - A strongly typed object containing the decoded information from the capabilities message, or null - if no existing Message object exists for the specified event - - - - Permissions for control of object media - - - - - Style of cotrols that shold be displayed to the user - - - - - Class representing media data for a single face - - - - Is display of the alternative image enabled - - - Should media auto loop - - - Shoule media be auto played - - - Auto scale media to prim face - - - Should viewer automatically zoom in on the face when clicked - - - Should viewer interpret first click as interaction with the media - or when false should the first click be treated as zoom in commadn - - - Style of controls viewer should display when - viewer media on this face - - - Starting URL for the media - - - Currently navigated URL - - - Media height in pixes - - - Media width in pixels - - - Who can controls the media - - - Who can interact with the media - - - Is URL whitelist enabled - - - Array of URLs that are whitelisted - - - - Serialize to OSD - - OSDMap with the serialized data - - - - Deserialize from OSD data - - Serialized OSD data - Deserialized object - - - - Particle system specific enumerators, flags and methods. - - - - - Current version of the media data for the prim - - - - - Array of media entries indexed by face number - - - - - Complete structure for the particle system - - - - - Particle source pattern - - - - None - - - Drop particles from source position with no force - - - "Explode" particles in all directions - - - Particles shoot across a 2D area - - - Particles shoot across a 3D Cone - - - Inverse of AngleCone (shoot particles everywhere except the 3D cone defined - - - - Particle Data Flags - - - - None - - - Interpolate color and alpha from start to end - - - Interpolate scale from start to end - - - Bounce particles off particle sources Z height - - - velocity of particles is dampened toward the simulators wind - - - Particles follow the source - - - Particles point towards the direction of source's velocity - - - Target of the particles - - - Particles are sent in a straight line - - - Particles emit a glow - - - used for point/grab/touch - - - continuous ribbon particle - - - particle data contains glow - - - particle data contains blend functions - - - - Particle Flags Enum - - - - None - - - Acceleration and velocity for particles are - relative to the object rotation - - - Particles use new 'correct' angle parameters - - - Particle Flags - There appears to be more data packed in to this area - for many particle systems. It doesn't appear to be flag values - and serialization breaks unless there is a flag for every - possible bit so it is left as an unsigned integer - - - pattern of particles - - - A representing the maximimum age (in seconds) particle will be displayed - Maximum value is 30 seconds - - - A representing the number of seconds, - from when the particle source comes into view, - or the particle system's creation, that the object will emits particles; - after this time period no more particles are emitted - - - A in radians that specifies where particles will not be created - - - A in radians that specifies where particles will be created - - - A representing the number of seconds between burts. - - - A representing the number of meters - around the center of the source where particles will be created. - - - A representing in seconds, the minimum speed between bursts of new particles - being emitted - - - A representing in seconds the maximum speed of new particles being emitted. - - - A representing the maximum number of particles emitted per burst - - - A which represents the velocity (speed) from the source which particles are emitted - - - A which represents the Acceleration from the source which particles are emitted - - - The Key of the texture displayed on the particle - - - The Key of the specified target object or avatar particles will follow - - - Flags of particle from - - - Max Age particle system will emit particles for - - - The the particle has at the beginning of its lifecycle - - - The the particle has at the ending of its lifecycle - - - A that represents the starting X size of the particle - Minimum value is 0, maximum value is 4 - - - A that represents the starting Y size of the particle - Minimum value is 0, maximum value is 4 - - - A that represents the ending X size of the particle - Minimum value is 0, maximum value is 4 - - - A that represents the ending Y size of the particle - Minimum value is 0, maximum value is 4 - - - A that represents the start glow value - Minimum value is 0, maximum value is 1 - - - A that represents the end glow value - Minimum value is 0, maximum value is 1 - - - OpenGL blend function to use at particle source - - - OpenGL blend function to use at particle destination - - - - Can this particle system be packed in a legacy compatible way - - True if the particle system doesn't use new particle system features - - - - Decodes a byte[] array into a ParticleSystem Object - - ParticleSystem object - Start position for BitPacker - - - - Generate byte[] array from particle data - - Byte array - - - - - - - Parameters used to construct a visual representation of a primitive - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Attachment point to an avatar - - - - - - - - - - - - - - - - Calculdates hash code for prim construction data - - The has - - - - Information on the flexible properties of a primitive - - - - - - - - - - - - - - - - - - - - - - - Default constructor - - - - - - - - - - - - - - - - - - - - - - - - Information on the light properties of a primitive - - - - - - - - - - - - - - - - - - - - Default constructor - - - - - - - - - - - - - - - - - - - - - - - - Information on the light properties of a primitive as texture map - - - - - - - - - - - Default constructor - - - - - - - - - - - - - - - - - - - - - - - - Information on the sculpt properties of a sculpted primitive - - - - - Render inside out (inverts the normals). - - - - - Render an X axis mirror of the sculpty. - - - - - Default constructor - - - - - - - - - - - - Extended properties to describe an object - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Default constructor - - - - - Set the properties that are set in an ObjectPropertiesFamily packet - - that has - been partially filled by an ObjectPropertiesFamily packet - - - - Describes physics attributes of the prim - - - - Primitive's local ID - - - Density (1000 for normal density) - - - Friction - - - Gravity multiplier (1 for normal gravity) - - - Type of physics representation of this primitive in the simulator - - - Restitution - - - - Creates PhysicsProperties from OSD - - OSDMap with incoming data - Deserialized PhysicsProperties object - - - - Serializes PhysicsProperties to OSD - - OSDMap with serialized PhysicsProperties data - - - - - - - - - - - - - - - - - - - - - Foliage type for this primitive. Only applicable if this - primitive is foliage - - - Unknown - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Identifies the owner if audio or a particle system is - active - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Objects physics engine propertis - - - Extra data about primitive - - - Indicates if prim is attached to an avatar - - - Number of clients referencing this prim - - - Uses basic heuristics to estimate the primitive shape - - - - Default constructor - - - - - Packs PathTwist, PathTwistBegin, PathRadiusOffset, and PathSkew - parameters in to signed eight bit values - - Floating point parameter to pack - Signed eight bit value containing the packed parameter - - - - Unpacks PathTwist, PathTwistBegin, PathRadiusOffset, and PathSkew - parameters from signed eight bit integers to floating point values - - Signed eight bit value to unpack - Unpacked floating point value - - - - Texture animation mode - - - - Disable texture animation - - - Enable texture animation - - - Loop when animating textures - - - Animate in reverse direction - - - Animate forward then reverse - - - Slide texture smoothly instead of frame-stepping - - - Rotate texture instead of using frames - - - Scale texture instead of using frames - - - - A single textured face. Don't instantiate this class yourself, use the - methods in TextureEntry - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - In the future this will specify whether a webpage is - attached to this face - - - - - - - - - - Contains the definition for individual faces - - - - - - - - - - - - Represents all of the texturable faces for an object - - Grid objects have infinite faces, with each face - using the properties of the default face unless set otherwise. So if - you have a TextureEntry with a default texture uuid of X, and face 18 - has a texture UUID of Y, every face would be textured with X except for - face 18 that uses Y. In practice however, primitives utilize a maximum - of nine faces - - - - - - - - - - Constructor that takes a default texture UUID - - Texture UUID to use as the default texture - - - - Constructor that takes a TextureEntryFace for the - default face - - Face to use as the default face - - - - Constructor that creates the TextureEntry class from a byte array - - Byte array containing the TextureEntry field - Starting position of the TextureEntry field in - the byte array - Length of the TextureEntry field, in bytes - - - - This will either create a new face if a custom face for the given - index is not defined, or return the custom face for that index if - it already exists - - The index number of the face to create or - retrieve - A TextureEntryFace containing all the properties for that - face - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Controls the texture animation of a particular prim - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - The type of bump-mapping applied to a face - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - The level of shininess applied to a face - - - - - - - - - - - - - - - - - The texture mapping style used for a face - - - - - - - - - - - - - - - - - Flags in the TextureEntry block that describe which properties are - set - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - This is used to login a specific user account(s). It may only be called after - Connector initialization has completed successfully - - Handle returned from successful Connector ‘create’ request - User's account name - User's account password - Values may be “AutoAnswer” or “VerifyAnswer” - "" - This is an integer that specifies how often - the daemon will send participant property events while in a channel. If this is not set - the default will be “on state change”, which means that the events will be sent when - the participant starts talking, stops talking, is muted, is unmuted. - The valid values are: - 0 – Never - 5 – 10 times per second - 10 – 5 times per second - 50 – 1 time per second - 100 – on participant state change (this is the default) - false - - - - - This is used to logout a user session. It should only be called with a valid AccountHandle. - - Handle returned from successful Connector ‘login’ request - - - - - This is used to get a list of audio devices that can be used for capture (input) of voice. - - - - - - This is used to get a list of audio devices that can be used for render (playback) of voice. - - - - - This command is used to select the render device. - - The name of the device as returned by the Aux.GetRenderDevices command. - - - - This command is used to select the capture device. - - The name of the device as returned by the Aux.GetCaptureDevices command. - - - - This command is used to start the audio capture process which will cause - AuxAudioProperty Events to be raised. These events can be used to display a - microphone VU meter for the currently selected capture device. This command - should not be issued if the user is on a call. - - (unused but required) - - - - - This command is used to stop the audio capture process. - - - - - - This command is used to set the mic volume while in the audio tuning process. - Once an acceptable mic level is attained, the application must issue a - connector set mic volume command to have that level be used while on voice - calls. - - the microphone volume (-100 to 100 inclusive) - - - - - This command is used to set the speaker volume while in the audio tuning - process. Once an acceptable speaker level is attained, the application must - issue a connector set speaker volume command to have that level be used while - on voice calls. - - the speaker volume (-100 to 100 inclusive) - - - - - This is used to initialize and stop the Connector as a whole. The Connector - Create call must be completed successfully before any other requests are made - (typically during application initialization). The shutdown should be called - when the application is shutting down to gracefully release resources - - A string value indicting the Application name - URL for the management server - LoggingSettings - - - - - - Shutdown Connector -- Should be called when the application is shutting down - to gracefully release resources - - Handle returned from successful Connector ‘create’ request - - - - Mute or unmute the microphone - - Handle returned from successful Connector ‘create’ request - true (mute) or false (unmute) - - - - Mute or unmute the speaker - - Handle returned from successful Connector ‘create’ request - true (mute) or false (unmute) - - - - Set microphone volume - - Handle returned from successful Connector ‘create’ request - The level of the audio, a number between -100 and 100 where - 0 represents ‘normal’ speaking volume - - - - Set local speaker volume - - Handle returned from successful Connector ‘create’ request - The level of the audio, a number between -100 and 100 where - 0 represents ‘normal’ speaking volume - - - - List of audio input devices - - - - - List of audio output devices - - - - - Start up the Voice service. - - - - - Handle miscellaneous request status - - - - ///If something goes wrong, we log it. - - - - Cleanup oject resources - - - - - Request voice cap when changing regions - - - - - Handle a change in session state - - - - - Close a voice session - - - - - - Locate a Session context from its handle - - Creates the session context if it does not exist. - - - - Handle completion of main voice cap request. - - - - - - - - Daemon has started so connect to it. - - - - - The daemon TCP connection is open. - - - - - Handle creation of the Connector. - - - - - Handle response to audio output device query - - - - - Handle response to audio input device query - - - - - Set audio test mode - - - - - Set voice channel for new parcel - - - - - - Request info from a parcel capability Uri. - - - - - - Receive parcel voice cap - - - - - - - - Tell Vivox where we are standing - - This has to be called when we move or turn. - - - - Start and stop updating out position. - - - - - Enable logging - - - The folder where any logs will be created - - - This will be prepended to beginning of each log file - - - The suffix or extension to be appended to each log file - - - - 0: NONE - No logging - 1: ERROR - Log errors only - 2: WARNING - Log errors and warnings - 3: INFO - Log errors, warnings and info - 4: DEBUG - Log errors, warnings, info and debug - - - - - Constructor for default logging settings - - - - Audio Properties Events are sent after audio capture is started. These events are used to display a microphone VU meter - - - - Event for most mundane request reposnses. - - - - Response to Connector.Create request - - - Response to Aux.GetCaptureDevices request - - - Response to Aux.GetRenderDevices request - - - Audio Properties Events are sent after audio capture is started. - These events are used to display a microphone VU meter - - - Response to Account.Login request - - - This event message is sent whenever the login state of the - particular Account has transitioned from one value to another - - - - Starts a thread that keeps the daemon running - - - - - - - Stops the daemon and the thread keeping it running - - - - - - - - - - - - - Create a Session - Sessions typically represent a connection to a media session with one or more - participants. This is used to generate an ‘outbound’ call to another user or - channel. The specifics depend on the media types involved. A session handle is - required to control the local user functions within the session (or remote - users if the current account has rights to do so). Currently creating a - session automatically connects to the audio media, there is no need to call - Session.Connect at this time, this is reserved for future use. - - Handle returned from successful Connector ‘create’ request - This is the URI of the terminating point of the session (ie who/what is being called) - This is the display name of the entity being called (user or channel) - Only needs to be supplied when the target URI is password protected - This indicates the format of the password as passed in. This can either be - “ClearText” or “SHA1UserName”. If this element does not exist, it is assumed to be “ClearText”. If it is - “SHA1UserName”, the password as passed in is the SHA1 hash of the password and username concatenated together, - then base64 encoded, with the final “=” character stripped off. - - - - - - - Used to accept a call - - SessionHandle such as received from SessionNewEvent - "default" - - - - - This command is used to start the audio render process, which will then play - the passed in file through the selected audio render device. This command - should not be issued if the user is on a call. - - The fully qualified path to the sound file. - True if the file is to be played continuously and false if it is should be played once. - - - - - This command is used to stop the audio render process. - - The fully qualified path to the sound file issued in the start render command. - - - - - This is used to ‘end’ an established session (i.e. hang-up or disconnect). - - Handle returned from successful Session ‘create’ request or a SessionNewEvent - - - - - Set the combined speaking and listening position in 3D space. - - Handle returned from successful Session ‘create’ request or a SessionNewEvent - Speaking position - Listening position - - - - - Set User Volume for a particular user. Does not affect how other users hear that user. - - Handle returned from successful Session ‘create’ request or a SessionNewEvent - - The level of the audio, a number between -100 and 100 where 0 represents ‘normal’ speaking volume - - - - Positional vector of the users position - - - Velocity vector of the position - - - At Orientation (X axis) of the position - - - Up Orientation (Y axis) of the position - - - Left Orientation (Z axis) of the position - - - - Extract the avatar UUID encoded in a SIP URI - - - - - - - Represents a single Voice Session to the Vivox service. - - - - - Close this session. - - - - - Look up an existing Participants in this session - - - - - - - - - - - - Delegate to wrap another delegate and its arguments - - - - - - - An instance of DelegateWrapper which calls InvokeWrappedDelegate, - which in turn calls the DynamicInvoke method of the wrapped - delegate - - - - - Callback used to call EndInvoke on the asynchronously - invoked DelegateWrapper - - - - - Executes the specified delegate with the specified arguments - asynchronously on a thread pool thread - - - - - - - Invokes the wrapped delegate synchronously - - - - - - - Calls EndInvoke on the wrapper and Close on the resulting WaitHandle - to prevent resource leaks - - - - - diff --git a/bin/OpenMetaverse.dll b/bin/OpenMetaverse.dll index 5c576a7a6f..64f79c2e46 100755 Binary files a/bin/OpenMetaverse.dll and b/bin/OpenMetaverse.dll differ diff --git a/bin/OpenMetaverse.dll.config b/bin/OpenMetaverse.dll.config index 6b7b99930c..73514c3894 100644 --- a/bin/OpenMetaverse.dll.config +++ b/bin/OpenMetaverse.dll.config @@ -1,5 +1,6 @@ + diff --git a/bin/OpenMetaverseTypes.XML b/bin/OpenMetaverseTypes.XML deleted file mode 100644 index 3da5955b02..0000000000 --- a/bin/OpenMetaverseTypes.XML +++ /dev/null @@ -1,2667 +0,0 @@ - - - - OpenMetaverseTypes - - - - - Same as Queue except Dequeue function blocks until there is an object to return. - Note: This class does not need to be synchronized - - - - - Create new BlockingQueue. - - The System.Collections.ICollection to copy elements from - - - - Create new BlockingQueue. - - The initial number of elements that the queue can contain - - - - Create new BlockingQueue. - - - - - BlockingQueue Destructor (Close queue, resume any waiting thread). - - - - - Remove all objects from the Queue. - - - - - Remove all objects from the Queue, resume all dequeue threads. - - - - - Removes and returns the object at the beginning of the Queue. - - Object in queue. - - - - Removes and returns the object at the beginning of the Queue. - - time to wait before returning - Object in queue. - - - - Removes and returns the object at the beginning of the Queue. - - time to wait before returning (in milliseconds) - Object in queue. - - - - Adds an object to the end of the Queue - - Object to put in queue - - - - Open Queue. - - - - - Gets flag indicating if queue has been closed. - - - - - Copy constructor - - Circular queue to copy - - - - An 8-bit color structure including an alpha channel - - - - Red - - - Green - - - Blue - - - Alpha - - - - - - - - - - - - - Builds a color from a byte array - - Byte array containing a 16 byte color - Beginning position in the byte array - True if the byte array stores inverted values, - otherwise false. For example the color black (fully opaque) inverted - would be 0xFF 0xFF 0xFF 0x00 - - - - Returns the raw bytes for this vector - - Byte array containing a 16 byte color - Beginning position in the byte array - True if the byte array stores inverted values, - otherwise false. For example the color black (fully opaque) inverted - would be 0xFF 0xFF 0xFF 0x00 - True if the alpha value is inverted in - addition to whatever the inverted parameter is. Setting inverted true - and alphaInverted true will flip the alpha value back to non-inverted, - but keep the other color bytes inverted - A 16 byte array containing R, G, B, and A - - - - Copy constructor - - Color to copy - - - - IComparable.CompareTo implementation - - Sorting ends up like this: |--Grayscale--||--Color--|. - Alpha is only used when the colors are otherwise equivalent - - - - Builds a color from a byte array - - Byte array containing a 16 byte color - Beginning position in the byte array - True if the byte array stores inverted values, - otherwise false. For example the color black (fully opaque) inverted - would be 0xFF 0xFF 0xFF 0x00 - True if the alpha value is inverted in - addition to whatever the inverted parameter is. Setting inverted true - and alphaInverted true will flip the alpha value back to non-inverted, - but keep the other color bytes inverted - - - - Writes the raw bytes for this color to a byte array - - Destination byte array - Position in the destination array to start - writing. Must be at least 16 bytes before the end of the array - - - - Serializes this color into four bytes in a byte array - - Destination byte array - Position in the destination array to start - writing. Must be at least 4 bytes before the end of the array - True to invert the output (1.0 becomes 0 - instead of 255) - - - - Writes the raw bytes for this color to a byte array - - Destination byte array - Position in the destination array to start - writing. Must be at least 16 bytes before the end of the array - - - - Ensures that values are in range 0-1 - - - - - Create an RGB color from a hue, saturation, value combination - - Hue - Saturation - Value - An fully opaque RGB color (alpha is 1.0) - - - - Performs linear interpolation between two colors - - Color to start at - Color to end at - Amount to interpolate - The interpolated color - - - A Color4 with zero RGB values and fully opaque (alpha 1.0) - - - A Color4 with full RGB values (1.0) and fully opaque (alpha 1.0) - - - - Attribute class that allows extra attributes to be attached to ENUMs - - - - Text used when presenting ENUM to user - - - Default initializer - - - Text used when presenting ENUM to user - - - - The different types of grid assets - - - - Unknown asset type - - - Texture asset, stores in JPEG2000 J2C stream format - - - Sound asset - - - Calling card for another avatar - - - Link to a location in world - - - Collection of textures and parameters that can be worn by an avatar - - - Primitive that can contain textures, sounds, - scripts and more - - - Notecard asset - - - Holds a collection of inventory items. "Category" in the Linden viewer - - - Linden scripting language script - - - LSO bytecode for a script - - - Uncompressed TGA texture - - - Collection of textures and shape parameters that can be worn - - - Uncompressed sound - - - Uncompressed TGA non-square image, not to be used as a - texture - - - Compressed JPEG non-square image, not to be used as a - texture - - - Animation - - - Sequence of animations, sounds, chat, and pauses - - - Simstate file - - - Asset is a link to another inventory item - - - Asset is a link to another inventory folder - - - Marketplace Folder. Same as an Category but different display methods. - - - Linden mesh format - - - - The different types of folder. - - - - None folder type - - - Texture folder type - - - Sound folder type - - - Calling card folder type - - - Landmark folder type - - - Clothing folder type - - - Object folder type - - - Notecard folder type - - - The root folder type - - - LSLText folder - - - Bodyparts folder - - - Trash folder - - - Snapshot folder - - - Lost And Found folder - - - Animation folder - - - Gesture folder - - - Favorites folder - - - Ensemble beginning range - - - Ensemble ending range - - - Current outfit folder - - - Outfit folder - - - My outfits folder - - - Mesh folder - - - Marketplace direct delivery inbox ("Received Items") - - - Marketplace direct delivery outbox - - - Basic root folder - - - Marketplace listings folder - - - Marketplace stock folder - - - Hypergrid Suitcase folder - - - - Inventory Item Types, eg Script, Notecard, Folder, etc - - - - Unknown - - - Texture - - - Sound - - - Calling Card - - - Landmark - - - Notecard - - - - - - Folder - - - - - - an LSL Script - - - - - - - - - - - - - - - - - - - - - - Item Sale Status - - - - Not for sale - - - The original is for sale - - - Copies are for sale - - - The contents of the object are for sale - - - - Types of wearable assets - - - - Body shape - - - Skin textures and attributes - - - Hair - - - Eyes - - - Shirt - - - Pants - - - Shoes - - - Socks - - - Jacket - - - Gloves - - - Undershirt - - - Underpants - - - Skirt - - - Alpha mask to hide parts of the avatar - - - Tattoo - - - Physics - - - Invalid wearable asset - - - - Identifier code for primitive types - - - - None - - - A Primitive - - - A Avatar - - - Linden grass - - - Linden tree - - - A primitive that acts as the source for a particle stream - - - A Linden tree - - - - Primary parameters for primitives such as Physics Enabled or Phantom - - - - Deprecated - - - Whether physics are enabled for this object - - - - - - - - - - - - - - - - - - - - - Whether this object contains an active touch script - - - - - - Whether this object can receive payments - - - Whether this object is phantom (no collisions) - - - - - - - - - - - - - - - Deprecated - - - - - - - - - - - - Deprecated - - - - - - - - - - - - - - - Server flag, will not be sent to clients. Specifies that - the object is destroyed when it touches a simulator edge - - - Server flag, will not be sent to clients. Specifies that - the object will be returned to the owner's inventory when it - touches a simulator edge - - - Server flag, will not be sent to clients. - - - Server flag, will not be sent to client. Specifies that - the object is hovering/flying - - - - - - - - - - - - - - - - Sound flags for sounds attached to primitives - - - - - - - - - - - - - - - - - - - - - - - - - - Material type for a primitive - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Used in a helper function to roughly determine prim shape - - - - - Extra parameters for primitives, these flags are for features that have - been added after the original ObjectFlags that has all eight bits - reserved already - - - - Whether this object has flexible parameters - - - Whether this object has light parameters - - - Whether this object is a sculpted prim - - - Whether this object is a light image map - - - Whether this object is a mesh - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Attachment points for objects on avatar bodies - - - Both InventoryObject and InventoryAttachment types can be attached - - - - Right hand if object was not previously attached - - - Chest - - - Skull - - - Left shoulder - - - Right shoulder - - - Left hand - - - Right hand - - - Left foot - - - Right foot - - - Spine - - - Pelvis - - - Mouth - - - Chin - - - Left ear - - - Right ear - - - Left eyeball - - - Right eyeball - - - Nose - - - Right upper arm - - - Right forearm - - - Left upper arm - - - Left forearm - - - Right hip - - - Right upper leg - - - Right lower leg - - - Left hip - - - Left upper leg - - - Left lower leg - - - Stomach - - - Left pectoral - - - Right pectoral - - - HUD Center position 2 - - - HUD Top-right - - - HUD Top - - - HUD Top-left - - - HUD Center - - - HUD Bottom-left - - - HUD Bottom - - - HUD Bottom-right - - - Neck - - - Avatar Center - - - - Tree foliage types - - - - Pine1 tree - - - Oak tree - - - Tropical Bush1 - - - Palm1 tree - - - Dogwood tree - - - Tropical Bush2 - - - Palm2 tree - - - Cypress1 tree - - - Cypress2 tree - - - Pine2 tree - - - Plumeria - - - Winter pinetree1 - - - Winter Aspen tree - - - Winter pinetree2 - - - Eucalyptus tree - - - Fern - - - Eelgrass - - - Sea Sword - - - Kelp1 plant - - - Beach grass - - - Kelp2 plant - - - - Grass foliage types - - - - - - - - - - - - - - - - - - - - - - - Action associated with clicking on an object - - - - Touch object - - - Sit on object - - - Purchase object or contents - - - Pay the object - - - Open task inventory - - - Play parcel media - - - Open parcel media - - - - Type of physics representation used for this prim in the simulator - - - - Use prim physics form this object - - - No physics, prim doesn't collide - - - Use convex hull represantion of this prim - - - For thread safety - - - For thread safety - - - - Purges expired objects from the cache. Called automatically by the purge timer. - - - - - A thread-safe lockless queue that supports multiple readers and - multiple writers - - - - - Provides a node container for data in a singly linked list - - - - Pointer to the next node in list - - - The data contained by the node - - - - Constructor - - - - - Constructor - - - - Queue head - - - Queue tail - - - Queue item count - - - Gets the current number of items in the queue. Since this - is a lockless collection this value should be treated as a close - estimate - - - - Constructor - - - - - Enqueue an item - - Item to enqeue - - - - Try to dequeue an item - - Dequeued item if the dequeue was successful - True if an item was successfully deqeued, otherwise false - - - - Convert this matrix to euler rotations - - X euler angle - Y euler angle - Z euler angle - - - - Convert this matrix to a quaternion rotation - - A quaternion representation of this rotation matrix - - - - Construct a matrix from euler rotation values in radians - - X euler angle in radians - Y euler angle in radians - Z euler angle in radians - - - - Get a formatted string representation of the vector - - A string representation of the vector - - - A 4x4 matrix containing all zeroes - - - A 4x4 identity matrix - - - X value - - - Y value - - - Z value - - - W value - - - - Build a quaternion from normalized float values - - X value from -1.0 to 1.0 - Y value from -1.0 to 1.0 - Z value from -1.0 to 1.0 - - - - Constructor, builds a quaternion object from a byte array - - Byte array containing four four-byte floats - Offset in the byte array to start reading at - Whether the source data is normalized or - not. If this is true 12 bytes will be read, otherwise 16 bytes will - be read. - - - - Normalizes the quaternion - - - - - Builds a quaternion object from a byte array - - The source byte array - Offset in the byte array to start reading at - Whether the source data is normalized or - not. If this is true 12 bytes will be read, otherwise 16 bytes will - be read. - - - - Normalize this quaternion and serialize it to a byte array - - A 12 byte array containing normalized X, Y, and Z floating - point values in order using little endian byte ordering - - - - Writes the raw bytes for this quaternion to a byte array - - Destination byte array - Position in the destination array to start - writing. Must be at least 12 bytes before the end of the array - - - - Convert this quaternion to euler angles - - X euler angle - Y euler angle - Z euler angle - - - - Convert this quaternion to an angle around an axis - - Unit vector describing the axis - Angle around the axis, in radians - - - - Returns the conjugate (spatial inverse) of a quaternion - - - - - Build a quaternion from an axis and an angle of rotation around - that axis - - - - - Build a quaternion from an axis and an angle of rotation around - that axis - - Axis of rotation - Angle of rotation - - - - Creates a quaternion from a vector containing roll, pitch, and yaw - in radians - - Vector representation of the euler angles in - radians - Quaternion representation of the euler angles - - - - Creates a quaternion from roll, pitch, and yaw euler angles in - radians - - X angle in radians - Y angle in radians - Z angle in radians - Quaternion representation of the euler angles - - - - Conjugates and renormalizes a vector - - - - - Spherical linear interpolation between two quaternions - - - - - Get a string representation of the quaternion elements with up to three - decimal digits and separated by spaces only - - Raw string representation of the quaternion - - - A quaternion with a value of 0,0,0,1 - - - - Determines the appropriate events to set, leaves the locks, and sets the events. - - - - - A routine for lazily creating a event outside the lock (so if errors - happen they are outside the lock and that we don't do much work - while holding a spin lock). If all goes well, reenter the lock and - set 'waitEvent' - - - - - Waits on 'waitEvent' with a timeout of 'millisceondsTimeout. - Before the wait 'numWaiters' is incremented and is restored before leaving this routine. - - - - - A hierarchical token bucket for bandwidth throttling. See - http://en.wikipedia.org/wiki/Token_bucket for more information - - - - Parent bucket to this bucket, or null if this is a root - bucket - - - Size of the bucket in bytes. If zero, the bucket has - infinite capacity - - - Rate that the bucket fills, in bytes per millisecond. If - zero, the bucket always remains full - - - Number of tokens currently in the bucket - - - Time of the last drip, in system ticks - - - - The parent bucket of this bucket, or null if this bucket has no - parent. The parent bucket will limit the aggregate bandwidth of all - of its children buckets - - - - - Maximum burst rate in bytes per second. This is the maximum number - of tokens that can accumulate in the bucket at any one time - - - - - The speed limit of this bucket in bytes per second. This is the - number of tokens that are added to the bucket per second - - Tokens are added to the bucket any time - is called, at the granularity of - the system tick interval (typically around 15-22ms) - - - - The number of bytes that can be sent at this moment. This is the - current number of tokens in the bucket - If this bucket has a parent bucket that does not have - enough tokens for a request, will - return false regardless of the content of this bucket - - - - - Default constructor - - Parent bucket if this is a child bucket, or - null if this is a root bucket - Maximum size of the bucket in bytes, or - zero if this bucket has no maximum capacity - Rate that the bucket fills, in bytes per - second. If zero, the bucket always remains full - - - - Remove a given number of tokens from the bucket - - Number of tokens to remove from the bucket - True if the requested number of tokens were removed from - the bucket, otherwise false - - - - Remove a given number of tokens from the bucket - - Number of tokens to remove from the bucket - True if tokens were added to the bucket - during this call, otherwise false - True if the requested number of tokens were removed from - the bucket, otherwise false - - - - Add tokens to the bucket over time. The number of tokens added each - call depends on the length of time that has passed since the last - call to Drip - - True if tokens were added to the bucket, otherwise false - - - - Operating system - - - - Unknown - - - Microsoft Windows - - - Microsoft Windows CE - - - Linux - - - Apple OSX - - - - Runtime platform - - - - .NET runtime - - - Mono runtime: http://www.mono-project.com/ - - - Used for converting degrees to radians - - - Used for converting radians to degrees - - - Provide a single instance of the CultureInfo class to - help parsing in situations where the grid assumes an en-us - culture - - - UNIX epoch in DateTime format - - - Provide a single instance of the MD5 class to avoid making - duplicate copies and handle thread safety - - - Provide a single instance of the SHA-1 class to avoid - making duplicate copies and handle thread safety - - - Provide a single instance of a random number generator - to avoid making duplicate copies and handle thread safety - - - - Clamp a given value between a range - - Value to clamp - Minimum allowable value - Maximum allowable value - A value inclusively between lower and upper - - - - Clamp a given value between a range - - Value to clamp - Minimum allowable value - Maximum allowable value - A value inclusively between lower and upper - - - - Clamp a given value between a range - - Value to clamp - Minimum allowable value - Maximum allowable value - A value inclusively between lower and upper - - - - Round a floating-point value to the nearest integer - - Floating point number to round - Integer - - - - Test if a single precision float is a finite number - - - - - Test if a double precision float is a finite number - - - - - Get the distance between two floating-point values - - First value - Second value - The distance between the two values - - - - Compute the MD5 hash for a byte array - - Byte array to compute the hash for - MD5 hash of the input data - - - - Compute the SHA1 hash for a byte array - - Byte array to compute the hash for - SHA1 hash of the input data - - - - Calculate the SHA1 hash of a given string - - The string to hash - The SHA1 hash as a string - - - - Compute the SHA256 hash for a byte array - - Byte array to compute the hash for - SHA256 hash of the input data - - - - Calculate the SHA256 hash of a given string - - The string to hash - The SHA256 hash as a string - - - - Calculate the MD5 hash of a given string - - The password to hash - An MD5 hash in string format, with $1$ prepended - - - - Calculate the MD5 hash of a given string - - The string to hash - The MD5 hash as a string - - - - Generate a random double precision floating point value - - Random value of type double - - - - Get the current running platform - - Enumeration of the current platform we are running on - - - - Get the current running runtime - - Enumeration of the current runtime we are running on - - - - Convert the first two bytes starting in the byte array in - little endian ordering to a signed short integer - - An array two bytes or longer - A signed short integer, will be zero if a short can't be - read at the given position - - - - Convert the first two bytes starting at the given position in - little endian ordering to a signed short integer - - An array two bytes or longer - Position in the array to start reading - A signed short integer, will be zero if a short can't be - read at the given position - - - - Convert the first four bytes starting at the given position in - little endian ordering to a signed integer - - An array four bytes or longer - Position to start reading the int from - A signed integer, will be zero if an int can't be read - at the given position - - - - Convert the first four bytes of the given array in little endian - ordering to a signed integer - - An array four bytes or longer - A signed integer, will be zero if the array contains - less than four bytes - - - - Convert the first eight bytes of the given array in little endian - ordering to a signed long integer - - An array eight bytes or longer - A signed long integer, will be zero if the array contains - less than eight bytes - - - - Convert the first eight bytes starting at the given position in - little endian ordering to a signed long integer - - An array eight bytes or longer - Position to start reading the long from - A signed long integer, will be zero if a long can't be read - at the given position - - - - Convert the first two bytes starting at the given position in - little endian ordering to an unsigned short - - Byte array containing the ushort - Position to start reading the ushort from - An unsigned short, will be zero if a ushort can't be read - at the given position - - - - Convert two bytes in little endian ordering to an unsigned short - - Byte array containing the ushort - An unsigned short, will be zero if a ushort can't be - read - - - - Convert the first four bytes starting at the given position in - little endian ordering to an unsigned integer - - Byte array containing the uint - Position to start reading the uint from - An unsigned integer, will be zero if a uint can't be read - at the given position - - - - Convert the first four bytes of the given array in little endian - ordering to an unsigned integer - - An array four bytes or longer - An unsigned integer, will be zero if the array contains - less than four bytes - - - - Convert the first eight bytes of the given array in little endian - ordering to an unsigned 64-bit integer - - An array eight bytes or longer - An unsigned 64-bit integer, will be zero if the array - contains less than eight bytes - - - - Convert four bytes in little endian ordering to a floating point - value - - Byte array containing a little ending floating - point value - Starting position of the floating point value in - the byte array - Single precision value - - - - Convert an integer to a byte array in little endian format - - The integer to convert - A four byte little endian array - - - - Convert an integer to a byte array in big endian format - - The integer to convert - A four byte big endian array - - - - Convert a 64-bit integer to a byte array in little endian format - - The value to convert - An 8 byte little endian array - - - - Convert a 64-bit unsigned integer to a byte array in little endian - format - - The value to convert - An 8 byte little endian array - - - - Convert a floating point value to four bytes in little endian - ordering - - A floating point value - A four byte array containing the value in little endian - ordering - - - - Converts an unsigned integer to a hexadecimal string - - An unsigned integer to convert to a string - A hexadecimal string 10 characters long - 0x7fffffff - - - - Convert a variable length UTF8 byte array to a string - - The UTF8 encoded byte array to convert - The decoded string - - - - Converts a byte array to a string containing hexadecimal characters - - The byte array to convert to a string - The name of the field to prepend to each - line of the string - A string containing hexadecimal characters on multiple - lines. Each line is prepended with the field name - - - - Converts a byte array to a string containing hexadecimal characters - - The byte array to convert to a string - Number of bytes in the array to parse - A string to prepend to each line of the hex - dump - A string containing hexadecimal characters on multiple - lines. Each line is prepended with the field name - - - - Convert a string to a UTF8 encoded byte array - - The string to convert - A null-terminated UTF8 byte array - - - - Converts a string containing hexadecimal characters to a byte array - - String containing hexadecimal characters - If true, gracefully handles null, empty and - uneven strings as well as stripping unconvertable characters - The converted byte array - - - - Returns true is c is a hexadecimal digit (A-F, a-f, 0-9) - - Character to test - true if hex digit, false if not - - - - Converts 1 or 2 character string into equivalant byte value - - 1 or 2 character string - byte - - - - Convert a float value to a byte given a minimum and maximum range - - Value to convert to a byte - Minimum value range - Maximum value range - A single byte representing the original float value - - - - Convert a byte to a float value given a minimum and maximum range - - Byte array to get the byte from - Position in the byte array the desired byte is at - Minimum value range - Maximum value range - A float value inclusively between lower and upper - - - - Convert a byte to a float value given a minimum and maximum range - - Byte to convert to a float value - Minimum value range - Maximum value range - A float value inclusively between lower and upper - - - - Attempts to parse a floating point value from a string, using an - EN-US number format - - String to parse - Resulting floating point number - True if the parse was successful, otherwise false - - - - Attempts to parse a floating point value from a string, using an - EN-US number format - - String to parse - Resulting floating point number - True if the parse was successful, otherwise false - - - - Tries to parse an unsigned 32-bit integer from a hexadecimal string - - String to parse - Resulting integer - True if the parse was successful, otherwise false - - - - Returns text specified in EnumInfo attribute of the enumerator - To add the text use [EnumInfo(Text = "Some nice text here")] before declaration - of enum values - - Enum value - Text representation of the enum - - - - Takes an AssetType and returns the string representation - - The source - The string version of the AssetType - - - - Translate a string name of an AssetType into the proper Type - - A string containing the AssetType name - The AssetType which matches the string name, or AssetType.Unknown if no match was found - - - - Takes a FolderType and returns the string representation - - The source - The string version of the FolderType - - - - Translate a string name of an FolderType into the proper Type - - A string containing the FolderType name - The FolderType which matches the string name, or FolderType. None if no match was found - - - - Convert an InventoryType to a string - - The to convert - A string representation of the source - - - - Convert a string into a valid InventoryType - - A string representation of the InventoryType to convert - A InventoryType object which matched the type - - - - Convert a SaleType to a string - - The to convert - A string representation of the source - - - - Convert a string into a valid SaleType - - A string representation of the SaleType to convert - A SaleType object which matched the type - - - - Converts a string used in LLSD to AttachmentPoint type - - String representation of AttachmentPoint to convert - AttachmentPoint enum - - - - Copy a byte array - - Byte array to copy - A copy of the given byte array - - - - Packs to 32-bit unsigned integers in to a 64-bit unsigned integer - - The left-hand (or X) value - The right-hand (or Y) value - A 64-bit integer containing the two 32-bit input values - - - - Unpacks two 32-bit unsigned integers from a 64-bit unsigned integer - - The 64-bit input integer - The left-hand (or X) output value - The right-hand (or Y) output value - - - - Convert an IP address object to an unsigned 32-bit integer - - IP address to convert - 32-bit unsigned integer holding the IP address bits - - - - Gets a unix timestamp for the current time - - An unsigned integer representing a unix timestamp for now - - - - Convert a UNIX timestamp to a native DateTime object - - An unsigned integer representing a UNIX - timestamp - A DateTime object containing the same time specified in - the given timestamp - - - - Convert a UNIX timestamp to a native DateTime object - - A signed integer representing a UNIX - timestamp - A DateTime object containing the same time specified in - the given timestamp - - - - Convert a native DateTime object to a UNIX timestamp - - A DateTime object you want to convert to a - timestamp - An unsigned integer representing a UNIX timestamp - - - - Swap two values - - Type of the values to swap - First value - Second value - - - - Try to parse an enumeration value from a string - - Enumeration type - String value to parse - Enumeration value on success - True if the parsing succeeded, otherwise false - - - - Swaps the high and low words in a byte. Converts aaaabbbb to bbbbaaaa - - Byte to swap the words in - Byte value with the words swapped - - - - Attempts to convert a string representation of a hostname or IP - address to a - - Hostname to convert to an IPAddress - Converted IP address object, or null if the conversion - failed - - - - A 128-bit Universally Unique Identifier, used throughout the Second - Life networking protocol - - - - The System.Guid object this struct wraps around - - - - Constructor that takes a string UUID representation - - A string representation of a UUID, case - insensitive and can either be hyphenated or non-hyphenated - UUID("11f8aa9c-b071-4242-836b-13b7abe0d489") - - - - Constructor that takes a System.Guid object - - A Guid object that contains the unique identifier - to be represented by this UUID - - - - Constructor that takes a byte array containing a UUID - - Byte array containing a 16 byte UUID - Beginning offset in the array - - - - Constructor that takes an unsigned 64-bit unsigned integer to - convert to a UUID - - 64-bit unsigned integer to convert to a UUID - - - - Copy constructor - - UUID to copy - - - - IComparable.CompareTo implementation - - - - - Assigns this UUID from 16 bytes out of a byte array - - Byte array containing the UUID to assign this UUID to - Starting position of the UUID in the byte array - - - - Returns a copy of the raw bytes for this UUID - - A 16 byte array containing this UUID - - - - Writes the raw bytes for this UUID to a byte array - - Destination byte array - Position in the destination array to start - writing. Must be at least 16 bytes before the end of the array - - - - Calculate an LLCRC (cyclic redundancy check) for this UUID - - The CRC checksum for this UUID - - - - Create a 64-bit integer representation from the second half of this UUID - - An integer created from the last eight bytes of this UUID - - - - Generate a UUID from a string - - A string representation of a UUID, case - insensitive and can either be hyphenated or non-hyphenated - UUID.Parse("11f8aa9c-b071-4242-836b-13b7abe0d489") - - - - Generate a UUID from a string - - A string representation of a UUID, case - insensitive and can either be hyphenated or non-hyphenated - Will contain the parsed UUID if successful, - otherwise null - True if the string was successfully parse, otherwise false - UUID.TryParse("11f8aa9c-b071-4242-836b-13b7abe0d489", result) - - - - Combine two UUIDs together by taking the MD5 hash of a byte array - containing both UUIDs - - First UUID to combine - Second UUID to combine - The UUID product of the combination - - - - - - - - - - Return a hash code for this UUID, used by .NET for hash tables - - An integer composed of all the UUID bytes XORed together - - - - Comparison function - - An object to compare to this UUID - True if the object is a UUID and both UUIDs are equal - - - - Comparison function - - UUID to compare to - True if the UUIDs are equal, otherwise false - - - - Get a hyphenated string representation of this UUID - - A string representation of this UUID, lowercase and - with hyphens - 11f8aa9c-b071-4242-836b-13b7abe0d489 - - - - Equals operator - - First UUID for comparison - Second UUID for comparison - True if the UUIDs are byte for byte equal, otherwise false - - - - Not equals operator - - First UUID for comparison - Second UUID for comparison - True if the UUIDs are not equal, otherwise true - - - - XOR operator - - First UUID - Second UUID - A UUID that is a XOR combination of the two input UUIDs - - - - String typecasting operator - - A UUID in string form. Case insensitive, - hyphenated or non-hyphenated - A UUID built from the string representation - - - An UUID with a value of all zeroes - - - A cache of UUID.Zero as a string to optimize a common path - - - - A two-dimensional vector with floating-point values - - - - X value - - - Y value - - - - Test if this vector is equal to another vector, within a given - tolerance range - - Vector to test against - The acceptable magnitude of difference - between the two vectors - True if the magnitude of difference between the two vectors - is less than the given tolerance, otherwise false - - - - Test if this vector is composed of all finite numbers - - - - - IComparable.CompareTo implementation - - - - - Builds a vector from a byte array - - Byte array containing two four-byte floats - Beginning position in the byte array - - - - Returns the raw bytes for this vector - - An eight-byte array containing X and Y - - - - Writes the raw bytes for this vector to a byte array - - Destination byte array - Position in the destination array to start - writing. Must be at least 8 bytes before the end of the array - - - - Parse a vector from a string - - A string representation of a 2D vector, enclosed - in arrow brackets and separated by commas - - - - Interpolates between two vectors using a cubic equation - - - - - Get a formatted string representation of the vector - - A string representation of the vector - - - - Get a string representation of the vector elements with up to three - decimal digits and separated by spaces only - - Raw string representation of the vector - - - A vector with a value of 0,0 - - - A vector with a value of 1,1 - - - A vector with a value of 1,0 - - - A vector with a value of 0,1 - - - - A three-dimensional vector with floating-point values - - - - X value - - - Y value - - - Z value - - - - Constructor, builds a vector from a byte array - - Byte array containing three four-byte floats - Beginning position in the byte array - - - - Test if this vector is equal to another vector, within a given - tolerance range - - Vector to test against - The acceptable magnitude of difference - between the two vectors - True if the magnitude of difference between the two vectors - is less than the given tolerance, otherwise false - - - - IComparable.CompareTo implementation - - - - - Test if this vector is composed of all finite numbers - - - - - Builds a vector from a byte array - - Byte array containing a 12 byte vector - Beginning position in the byte array - - - - Returns the raw bytes for this vector - - A 12 byte array containing X, Y, and Z - - - - Writes the raw bytes for this vector to a byte array - - Destination byte array - Position in the destination array to start - writing. Must be at least 12 bytes before the end of the array - - - - Parse a vector from a string - - A string representation of a 3D vector, enclosed - in arrow brackets and separated by commas - - - - Calculate the rotation between two vectors - - Normalized directional vector (such as 1,0,0 for forward facing) - Normalized target vector - - - - Interpolates between two vectors using a cubic equation - - - - - Get a formatted string representation of the vector - - A string representation of the vector - - - - Get a string representation of the vector elements with up to three - decimal digits and separated by spaces only - - Raw string representation of the vector - - - - Cross product between two vectors - - - - - Explicit casting for Vector3d > Vector3 - - - - - - A vector with a value of 0,0,0 - - - A vector with a value of 1,1,1 - - - A unit vector facing forward (X axis), value 1,0,0 - - - A unit vector facing left (Y axis), value 0,1,0 - - - A unit vector facing up (Z axis), value 0,0,1 - - - - A three-dimensional vector with doubleing-point values - - - - X value - - - Y value - - - Z value - - - - Constructor, builds a vector from a byte array - - Byte array containing three eight-byte doubles - Beginning position in the byte array - - - - Test if this vector is equal to another vector, within a given - tolerance range - - Vector to test against - The acceptable magnitude of difference - between the two vectors - True if the magnitude of difference between the two vectors - is less than the given tolerance, otherwise false - - - - IComparable.CompareTo implementation - - - - - Test if this vector is composed of all finite numbers - - - - - Builds a vector from a byte array - - Byte array containing a 24 byte vector - Beginning position in the byte array - - - - Returns the raw bytes for this vector - - A 24 byte array containing X, Y, and Z - - - - Writes the raw bytes for this vector to a byte array - - Destination byte array - Position in the destination array to start - writing. Must be at least 24 bytes before the end of the array - - - - Parse a vector from a string - - A string representation of a 3D vector, enclosed - in arrow brackets and separated by commas - - - - Interpolates between two vectors using a cubic equation - - - - - Get a formatted string representation of the vector - - A string representation of the vector - - - - Get a string representation of the vector elements with up to three - decimal digits and separated by spaces only - - Raw string representation of the vector - - - - Cross product between two vectors - - - - - Implicit casting for Vector3 > Vector3d - - - - - - A vector with a value of 0,0,0 - - - A vector with a value of 1,1,1 - - - A unit vector facing forward (X axis), value of 1,0,0 - - - A unit vector facing left (Y axis), value of 0,1,0 - - - A unit vector facing up (Z axis), value of 0,0,1 - - - X value - - - Y value - - - Z value - - - W value - - - - Constructor, builds a vector from a byte array - - Byte array containing four four-byte floats - Beginning position in the byte array - - - - Test if this vector is equal to another vector, within a given - tolerance range - - Vector to test against - The acceptable magnitude of difference - between the two vectors - True if the magnitude of difference between the two vectors - is less than the given tolerance, otherwise false - - - - IComparable.CompareTo implementation - - - - - Test if this vector is composed of all finite numbers - - - - - Builds a vector from a byte array - - Byte array containing a 16 byte vector - Beginning position in the byte array - - - - Returns the raw bytes for this vector - - A 16 byte array containing X, Y, Z, and W - - - - Writes the raw bytes for this vector to a byte array - - Destination byte array - Position in the destination array to start - writing. Must be at least 16 bytes before the end of the array - - - - Get a string representation of the vector elements with up to three - decimal digits and separated by spaces only - - Raw string representation of the vector - - - A vector with a value of 0,0,0,0 - - - A vector with a value of 1,1,1,1 - - - A vector with a value of 1,0,0,0 - - - A vector with a value of 0,1,0,0 - - - A vector with a value of 0,0,1,0 - - - A vector with a value of 0,0,0,1 - - - diff --git a/bin/OpenMetaverseTypes.dll b/bin/OpenMetaverseTypes.dll index a07cc1daa0..135b5b0f77 100755 Binary files a/bin/OpenMetaverseTypes.dll and b/bin/OpenMetaverseTypes.dll differ diff --git a/bin/OpenSim.exe.config b/bin/OpenSim.exe.config index f1bf8a050a..5be6989918 100755 --- a/bin/OpenSim.exe.config +++ b/bin/OpenSim.exe.config @@ -5,11 +5,10 @@ - - + diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example index b0777d7657..2b241f5e1c 100644 --- a/bin/OpenSim.ini.example +++ b/bin/OpenSim.ini.example @@ -1,6 +1,6 @@ ;; This is the main configuration file for OpenSimulator. ;; If it's named OpenSim.ini then it will be loaded by OpenSimulator. -;; If it's named OpenSim.ini.example then you will need to copy it to +;; If it's named OpenSim.ini.example then you will need to copy it to ;; OpenSim.ini first (if that file does not already exist) ;; ;; Once you have copied OpenSim.ini.example to OpenSim.ini you will at least @@ -10,19 +10,19 @@ ;; StandaloneCommon.ini or GridCommon.ini which you can copy and modify from the ;; available .example files. ;; -;; The settings in this file are in the form " = ". For example, +;; The settings in this file are in the form " = ". For example, ;; save_crashes = false in the [Startup] section below. ;; -;; All settings are initially commented out and the default value used, as -;; found in OpenSimDefaults.ini. To change a setting, first uncomment it by +;; All settings are initially commented out and the default value used, as +;; found in OpenSimDefaults.ini. To change a setting, first uncomment it by ;; deleting the initial semicolon (;) and then change the value. This will ;; override the value in OpenSimDefaults.ini -;; +;; ;; If you want to find out what configuration OpenSimulator has finished with ;; once all the configuration files are loaded then type "config show" on the ;; region console command line. ;; -;; +;; ;; NOTES FOR DEVELOPERS REGARDING THE FORMAT OF THIS FILE ;; ;; All leading white space is ignored, but preserved. @@ -41,30 +41,30 @@ ;; satisfied. ;; ;; ; denotes a commented out option. -;; Any options added to OpenSim.ini.example should be initially commented +;; Any options added to OpenSim.ini.example should be initially commented ;; out. [Const] - ; For a grid these will usually be the externally accessible IP/DNS - ; name and use default public port 8002 and default private port 8003 - ; For a standalone this will usually be the externally accessible IP/DNS - ; name and use default public port 9000. The private port is not used - ; in the configuration for a standalone. + ; this section defines constants for grid services + ; to simplify other configuration files default settings + + ;# {BaseHostname} {} {BaseHostname} {"example.com" "127.0.0.1"} "127.0.0.1" + BaseHostname = "127.0.0.1" + + ;# {BaseURL} {} {BaseURL} {"http://${Const|BaseHostname}} "http://${Const|BaseHostname}" + BaseURL = http://${Const|BaseHostname} - ;# {BaseURL} {} {BaseURL} {"http://example.com" "http://127.0.0.1"} "http://127.0.0.1" - BaseURL = http://127.0.0.1 - ;# {PublicPort} {} {PublicPort} {8002 9000} "8002" PublicPort = "8002" + ;grid default private port 8003, not used in standalone ;# {PrivatePort} {} {PrivatePort} {8003} "8003" ; port to access private grid services. ; grids that run all their regions should deny access to this port ; from outside their networks, using firewalls PrivatePort = "8003" - [Startup] ;# {ConsolePrompt} {} {ConsolePrompt} {} "Region (\R) " ;; Console prompt @@ -87,6 +87,10 @@ ;; How many lines of command history should we keep? (default is 100) ; ConsoleHistoryFileLines = 100 + ;# {ConsoleHistoryTimeStamp} {} {Time stamp commands in history file} {} false + ;; Time stamp commands in history file (default false) + ; ConsoleHistoryTimeStamp = false + ;# {save_crashes} {} {Save crashes to disk?} {true false} false ;; Set this to true if you want to log crashes to disk ;; this can be useful when submitting bug reports. @@ -108,14 +112,14 @@ ; PIDFile = "/tmp/OpenSim.exe.pid" ;# {RegistryLocation} {} {Addins Registry Location} {} - ; Set path to directory for addin registry if you want addins outside of bin. - ; Information about the registered repositories and installed plugins will + ; Set path to directory for addin registry if you want addins outside of bin. + ; Information about the registered repositories and installed plugins will ; be stored here. The OpenSim.exe process must have R/W access to the location. ; RegistryLocation = "." ;# {ConfigDirectory} {} {Set path to directory for modular ini files} {} ; Used by region module addins. You can set this to outside bin, so that addin - ; configurations will survive updates. The OpenSim.exe process must have R/W access + ; configurations will survive updates. The OpenSim.exe process must have R/W access ; to the location. ; ConfigDirectory = "." @@ -125,7 +129,7 @@ ;; Default is "filesystem" ; region_info_source = "filesystem" ; region_info_source = "web" - + ;# {regionload_regionsdir} {region_info_source} {Location of file?} {} Regions ;; Determines where the region XML files are stored if you are loading ;; these from the filesystem. @@ -138,7 +142,7 @@ ;; The XML here has the same format as it does on the filesystem ;; (including the tag), except that everything is also enclosed ;; in a tag. - ; regionload_webserver_url = "http://example.com/regions.xml"; + ; regionload_webserver_url = "http://example.com/regions.xml" ;# {allow_regionless} {} {Allow simulator to start up with no regions configured.} {true false} false ;; Allow the simulator to start up if there are no region configuration available @@ -146,14 +150,14 @@ ; allow_regionless = false ;# {NonPhysicalPrimMin} {} {Minimum size of nonphysical prims?} {} 0.001 - ;; Minimum size for non-physical prims. Affects resizing of existing - ;; prims. This can be overridden in the region config file (as + ;; Minimum size for non-physical prims. Affects resizing of existing + ;; prims. This can be overridden in the region config file (as ;; NonPhysicalPrimMin!). ; NonPhysicalPrimMin = 0.001 ;# {NonPhysicalPrimMax} {} {Maximum size of nonphysical prims?} {} 256 ;; Maximum size for non-physical prims. Affects resizing of existing - ;; prims. This can be overridden in the region config file (as + ;; prims. This can be overridden in the region config file (as ;; NonPhysicalPrimMax!). ; NonPhysicalPrimMax = 256 @@ -183,7 +187,7 @@ ;; Allow scripts to keep running when they cross region boundaries, rather ;; than being restarted. State is reloaded on the destination region. ;; This only applies when crossing to a region running in a different - ;; simulator. + ;; simulator. ;; For crossings where the regions are on the same simulator the script is ;; always kept running. ; AllowScriptCrossing = true @@ -240,14 +244,14 @@ ; meshing = ZeroMesher ;; select ubODEMeshmerizer only with ubOde physics engine ; meshing = ubODEMeshmerizer - + ;; Choose one of the physics engines below ;# {physics} {} {Select physics engine} {OpenDynamicsEngine BulletSim basicphysics POS} BulletSim ;; BulletSim is the default physics engine. It provides the best performance and most functionality. ;; BulletSim supports varregions. - ;; OpenDynamicsEngine was the previous default physics engine in OpenSimulator 0.7.6.1 and before. + ;; OpenDynamicsEngine was the previous default physics engine in OpenSimulator 0.7.6.1 and before. ;; It continues to provide a workable physics implementation. It does not currently support varregions. - ;; basicphysics effectively does not model physics at all, making all objects phantom. + ;; basicphysics effectively does not model physics at all, making all objects phantom. ;; Default is BulletSim ; physics = OpenDynamicsEngine ; physics = BulletSim @@ -256,10 +260,18 @@ ;; alternative OpenDynamicsEngine engine. ubODEMeshmerizer meshing above MUST be selected also ; physics = ubODE - ;# {DefaultScriptEngine} {} {Default script engine} {XEngine} XEngine - ;; Default script engine to use. Currently, we only have XEngine - ; DefaultScriptEngine = "XEngine" + ; ubODE and OpenDynamicsEngine does allocate a lot of memory on stack. On linux you may need to increase its limit + ; script opensim-ode-sh starts opensim setting that limit. You may need to increase it even more on large regions + ; edit the line ulimit -s 262144, and change this last value + ;# {DefaultScriptEngine} {} {Default script engine} {XEngine} XEngine + ;; Default script engine to use (Xengine if all commented) + ; DefaultScriptEngine = "XEngine" + ;; ***DANGER***DANGER*** + ;; experimental engine + ;; see section [YEngine} below + ; DefaultScriptEngine = "YEngine" + ;# {HttpProxy} {} {Proxy URL for llHTTPRequest and dynamic texture loading} {} http://proxy.com:8080 ;; Http proxy setting for llHTTPRequest and dynamic texture loading, if ;; required @@ -282,8 +294,8 @@ ;; SpawnPointRouting adjusts the landing for incoming avatars. ;; "closest" will place the avatar at the SpawnPoint located in the closest ;; available spot to the destination (typically map click/landmark). - ;; "random" will place the avatar on a randomly selected spawnpoint; - ;; "sequence" will place the avatar on the next sequential SpawnPoint + ;; "random" will place the avatar on a randomly selected spawnpoint. + ;; "sequence" will place the avatar on the next sequential SpawnPoint. ; SpawnPointRouting = closest ;# {TelehubAllowLandmark} {} {Allow users with landmarks to override telehub routing} {true false} false @@ -292,7 +304,18 @@ ;; default is false ; TelehubAllowLandmark = false + + ;; SSL certificate validation options + ;; you can allow selfsigned certificates or no official CA with next option set to true + ;# {NoVerifyCertChain} {} {do not verify SSL Cert Chain} {true false} true + ; NoVerifyCertChain = true + ;; you can also bypass the hostname or domain verification + ;# {NoVerifyCertHostname} {} {do not verify SSL Cert name versus peer name} {true false} true + ; NoVerifyCertHostname = true + ;; having both options true does provide encryption but with low security + ;; set both true if you don't care to use SSL, they are needed to contact regions or grids that do use it. + [AccessControl] ;# {AllowedClients} {} {Bar (|) separated list of allowed clients} {} ;; Bar (|) separated list of viewers which may gain access to the regions. @@ -318,16 +341,16 @@ [Map] ;# {GenerateMaptiles} {} {Generate map tiles?} {true false} true - ;; Map tile options. + ;; Map tile options. ;; If true, then maptiles are generated using the MapImageModule below. ;; If false then the texture referenced by MaptileStaticUUID is used instead, which can also be overridden - ;; in individual region config file(s). If you do not want to upload map tiles at all, then you will need + ;; in individual region config file(s). If you do not want to upload map tiles at all, then you will need ;; both to set this to false and comment out the [Modules] MapImageServiceModule setting in config-include/ ; GenerateMaptiles = true ;# {MapImageModule} {} {The map image module to use} {MapImageModule Warp3DImageModule} MapImageModule ;; The module to use in order to generate map images. - ;; MapImageModule is the default. Warp3DImageModule is an alternative experimental module that can + ;; MapImageModule is the default. Warp3DImageModule is an alternative experimental module that can ;; generate better images. ;MapImageModule = "MapImageModule" @@ -360,8 +383,23 @@ ; TexturePrimSize = 48 ;# {RenderMeshes} {} {Render meshes and sculpties on map tiles?} {true false} false - ;; Attempt to render meshes and sculpties on the map - ; RenderMeshes = false; + ;; Attempt to render meshes and sculpties on the map. + ; RenderMeshes = false + + ;# {MapColorWater} {} {Water color for textured and shaded maps} {"#1D475F"} + ; MapColorWater = "#3399FF" + + ;# {MapColor1} {} {Terrain color 1 for textured maps} {"#A58976"} + ; MapColor1 = "#A58976" + + ;# {MapColor2} {} {Terrain color 2 for textured maps} {"#455931"} + ; MapColor2 = "#455931" + + ;# {MapColor3} {} {Terrain color 3 for textured maps} {"#A29A8D"} + ; MapColor3 = "#A29A8D" + + ;# {MapColor4} {} {Terrain color 4 for textured maps} {"#C8C8C8"} + ; MapColor4 = "#C8C8C8" [Permissions] @@ -399,7 +437,7 @@ ;; This is definitely not SL! ;; Provides a simple control for land owners to give build rights to ;; specific avatars in publicly accessible parcels that disallow object - ;; creation in general. + ;; creation in general. ;; Owners specific avatars by adding them to the Access List of the parcel ;; without having to use the Groups feature ; simple_build_permissions = false @@ -420,12 +458,12 @@ ; ** Standalone Estate Settings ** - ; The following parameters will only be used on a standalone system to + ; The following parameters will only be used on a standalone system to ; create an estate owner that does not already exist ;# {DefaultEstateOwnerUUID} {} {Default estate owner UUID?} {} 00000000-0000-0000-0000-000000000000 - ;; If DefaultEstateOwnerUUID is left at UUID.Zero (as below) then a random - ;; UUID will be assigned. This is normally what you want + ;; If DefaultEstateOwnerUUID is left at UUID.Zero (as below) then a random + ;; UUID will be assigned. This is normally what you want ; DefaultEstateOwnerUUID = 00000000-0000-0000-0000-000000000000 ;# {DefaultEstateOwnerEMail} {} {Default estate owner email?} {} @@ -436,7 +474,6 @@ ;; Password for the default estate owner ; DefaultEstateOwnerPassword = password - [SMTP] ;; The SMTP server enabled the email module to send email to external ;; destinations. @@ -469,7 +506,6 @@ ;# {SMTP_SERVER_PASSWORD} {[Startup]emailmodule:DefaultEmailModule enabled:true} {SMTP server password} {} ; SMTP_SERVER_PASSWORD = "" - [Network] ;# {ConsoleUser} {} {User name for console account} {} ;; Configure the remote console user here. This will not actually be used @@ -486,19 +522,48 @@ ;; the region ports use UDP. ; http_listener_port = 9000 + ; optional main server secure http (ssl) + ; to use ssl you need a ssl certificate in PKCS12 format that validates the ExternalHostnames + ; or their domains + ; some viewers by default only accept certificates signed by a oficial CA + ; to use others like self signed certificates with those viewers, + ; their debug option NoVerifySSLCert needs to be set true, You need to inform users about this + ; the main unsecure port will still open for some services. this may change in future. + + ; set http_listener_ssl to enable main server ssl. it will replace unsecure port on most functions + ;# {http_listener_ssl}{} {enable main server ssl port)} {} false + ;http_listener_ssl = false + + ; Set port for main SSL connections + ;# {http_listener_sslport}{} {main server ssl port)} {} 9001 + ;http_listener_sslport = 9001 ; + + ; currently if using ssl, regions ExternalHostName must the the same and equal to http_listener_cn + ; this may be removed in future + ;# {http_listener_cn}{} {main server ssl externalHostName)} {} "" + ;http_listener_cn = "myRegionsExternalHostName" + + ; the path for the certificate path + ;# {http_listener_cert_path}{} {main server ssl certificate file path)} {} "" + ;http_listener_cert_path = "mycert.p12" + + ;# {http_listener_cert_pass}{} {main server ssl certificate password)} {} "" + ;http_listener_cert_pass = "mycertpass" ; the cert passwork + ; By default, OpenSimulator does not allow scripts to make HTTP calls to addresses on the simulator's LAN. ; See the OutboundDisallowForUserScripts parameter in OpenSimDefaults.ini for more information on this filter. ; If you need to allow scripts to make some LAN calls use the OutboundDisallowForUserScriptsExcept parameter below. ; We recommend that you do not override OutboundDisallowForUserScripts directly unless you are very sure about what you're doing. + ; this HTTP calls can also use ssl see opensimDefaults.ini ; ; You can whitelist individual endpoints by IP or FQDN, e.g. ; ; OutboundDisallowForUserScriptsExcept = 192.168.1.3:8003 - ; + ; ; You can specify multiple addresses by separating them with a bar. For example, ; ; OutboundDisallowForUserScriptsExcept = 192.168.1.3:8003|myinternalserver:8000 - ; + ; ; If an address if given without a port number then port 80 is assumed ; ; You can also specify a network range in CIDR notation to whitelist, e.g. @@ -515,7 +580,7 @@ ;# {HttpBodyMaxLenMAX} {} {Maximum bytes allowed for HTTP_BODY_MAXLENGTH} {} 16384 ;; By default, llHTTPRequest limits the response body to 2048 bytes. ;; This limit can be extended using HTTP_BODY_MAXLENGTH to a maximum - ;; of HttpBodyMaxLenMAX bytes. + ;; of HttpBodyMaxLenMAX bytes. ;; Please be aware that the limit can be set to insanely high values, ;; effectively removing any limitation. This will expose your sim to a ;; known attack. It is not recommended to set this limit higher than @@ -525,9 +590,8 @@ ;# {ExternalHostNameForLSL} {} {Hostname to use for HTTP-IN URLs. This should be reachable from the internet.} {} ;; Hostname to use in llRequestURL/llRequestSecureURL - ;; if not defined - default machine name is being used - ;; (on Windows this mean NETBIOS name - useably only inside local network) - ; ExternalHostNameForLSL = "127.0.0.1" + ;; if not defined - llRequestURL/llRequestSecureURL are disabled + ExternalHostNameForLSL = ${Const|BaseHostname} ;# {shard} {} {Name to use for X-Secondlife-Shard header? (press enter if unsure)} {} OpenSim ;; What is reported as the "X-Secondlife-Shard" @@ -540,11 +604,11 @@ ;; What is reported as the "User-Agent" when using llHTTPRequest ;; Defaults to not sent if not set here. See the notes section in the wiki ;; at http://wiki.secondlife.com/wiki/LlHTTPRequest for comments on adding - ;; " (Mozilla Compatible)" to the text where there are problems with a + ;; " (Mozilla Compatible)" to the text where there are problems with a ;; web server ; user_agent = "OpenSim LSL (Mozilla Compatible)" - ;; The follow 3 variables are for HTTP Basic Authentication for the Robust services. + ;; The following 3 variables are for HTTP Basic Authentication for the Robust services. ;; Use this if your central services in port 8003 need to be accessible on the Internet ;; but you want to protect them from unauthorized access. The username and password ;; here need to match the ones in the Robust service configuration. @@ -557,9 +621,9 @@ [XMLRPC] ;# {XmlRpcRouterModule} {} {Module used to route incoming llRemoteData calls} {XmlRpcRouterModule XmlRpcGridRouterModule} XmlRpcRouterModule - ;; If enabled and set to XmlRpcRouterModule, this will post an event, - ;; "xmlrpc_uri(string)" to the script concurrently with the first - ;; remote_data event. This will contain the fully qualified URI an + ;; If enabled and set to XmlRpcRouterModule, this will post an event, + ;; "xmlrpc_uri(string)" to the script concurrently with the first + ;; remote_data event. This will contain the fully qualified URI an ;; external site needs to use to send XMLRPC requests to that script ;; ;; If enabled and set to XmlRpcGridRouterModule, newly created channels @@ -572,7 +636,7 @@ ;# {XmlRpcHubURI} {XmlRpcRouterModule} {URI for external service used to register xmlrpc channels created in the simulator. This depends on XmlRpcRouterModule being set to XmlRpcGridRouterModule} {} http://example.com ;; If XmlRpcRouterModule is set to XmlRpcGridRouterModule, the simulator ;; will use this address to register xmlrpc channels on the external - ;; service + ;; service ; XmlRpcHubURI = http://example.com @@ -609,7 +673,6 @@ [SimulatorFeatures] - ;# {SearchServerURI} {} {URL of the search server} {} ;; Optional. If given this serves the same purpose as the grid wide ;; [LoginServices] SearchURL setting and will override that where @@ -666,14 +729,18 @@ ;; For standalones, this is the storage dll. ; StorageProvider = OpenSim.Data.MySQL.dll - ;# {MuteListModule} {OfflineMessageModule:OfflineMessageModule} {} {} MuteListModule - ;; Mute list handler (not yet implemented). MUST BE SET to allow offline - ;; messages to work + ; Mute list handler + ; the provided MuteListModule is just a Dummy + ; you will need a external module for proper suport. + ; if you keep both 2 following settings comment, viewers will use mutes in their caches + ; if you uncoment both (url is ignored) the mutes will be deleted at login on this instance regions + ; WARNING: viewers mutes cache seems to shared by all grids, including SL + ; this may cause some confusion. + + ;# {MuteListModule} {MuteListModule:MuteListModule} {} {} None ; MuteListModule = MuteListModule - ;# {MuteListURL} {OfflineMessageModule:OfflineMessageModule} {} {} http://yourserver/Mute.php - ;; URL of the web service that serves mute lists. Not currently used, but - ;; must be set to allow offline messaging to work. + ;# {MuteListURL} {MuteListModule:MuteListModule} {} {} http://yourserver/Mute.php ; MuteListURL = http://yourserver/Mute.php ;; Control whether group invites and notices are stored for offline users. @@ -690,7 +757,7 @@ [ODEPhysicsSettings] ;# {mesh_sculpted_prim} {[Startup]physics:OpenDynamicsEngine} {Mesh sculpties so they collide as they look?} {true false} true ;; Do we want to mesh sculpted prim to collide like they look? - ;; If you are seeing sculpt texture decode problems + ;; If you are seeing sculpt texture decode problems ;; (messages such as "Decoded image with unhandled number of components: 0 shortly followed by a physcs exception") ;; then you might want to try setting this to false. ; mesh_sculpted_prim = true @@ -840,6 +907,10 @@ ;DATA_SRV_MISearch = "http://metaverseink.com/cgi-bin/register.py" [Economy] + ; the economy module in use + ; To use other modules you need to override this setting + ; economymodule = BetaGridLikeMoneyModule + ;# {SellEnabled} {} {Enable selling for 0?} {true false} true ; The default economy module only implements just enough to allow free actions (transfer of objects, etc). ; There is no intention to implement anything further in core OpenSimulator. @@ -856,6 +927,22 @@ ;; Money Unit fee to create groups. Default is 0. ; PriceGroupCreate = 0 +[YEngine] + ;; experimental engine + ;; ONLY SUPORTS ONE REGION PER INSTANCE at this point + ;; implements non preemptive microthreading, so fixing problems like llSleep or long events handlers + ;; but those will suffer from timeslicing, so will be slower. + ;; compiles LSL directly to IL, so only suports LSL scripting (no C# etc) + ;; shares the Xengine APIs like LSL, OSSL, etc. + ;; DANGER, do not use with HG, don't leave regions running alone with it. + ;; TPs or crossings to/from Xengine will full recompile scripts losing state. + ;; attachment scripts may misbehave, cars will stop on crossings, etc. + Enabled = false + ScriptStackSize = 256 + ScriptHeapSize = 256 + UseSourceHashCode = true + MinTimerInterval = 0.1 + ;ScriptBasePath="ScriptEngines" [XEngine] ;# {Enabled} {} {Enable the XEngine scripting engine?} {true false} true @@ -873,7 +960,7 @@ ;; llSetTimerEvent minimum value. Default 0.5s, 0.05s whould be more resonable ; MinTimerInterval = 0.5 - + ;# {Priority} {Enabled:true} {Priority for script engine threads?} {Lowest BelowNormal Normal AboveNormal Highest} BelowNormal ;; Thread priority ("Lowest", "BelowNormal", "Normal", "AboveNormal", ;; "Highest") @@ -888,7 +975,7 @@ ; ThreadStackSize = 262144 ;; Set this to true to load each script into a separate - ;; AppDomain. + ;; AppDomain. ;; ;; Setting this to false will load all script assemblies into the ;; current AppDomain, which will significantly improve script loading times. @@ -899,17 +986,17 @@ ;; at this time some mono versions seem to have problems with the true option ;; so default is now false until a fix is found, to simply life of less technical skilled users. ;; this should only be a issue if regions stay alive for a long time with lots of scripts added or edited. - ; AppDomainLoading = false + AppDomainLoading = false - ;; Controls whether scripts are stopped by aborting their threads externally (abort) or by co-operative checks from the compiled script (co-op) + ;; Controls whether scripts are stopped by aborting their threads externally (abort) or by co-operative checks from the compiled script (co-op) ;; co-op will be more stable but this option is currently experimental. ;; If moving from co-op to abort, existing script DLLs will need to be recompiled. - ;; This currently can only be done manually, either by setting DeleteScriptsOnStartup = true for one run + ;; This currently can only be done manually, either by setting DeleteScriptsOnStartup = true for one run ;; or by deleting the script DLL* files in bin/ScriptEngines// ;; One can move from co-op back to abort without recompilation, but reverting back to co-op again will need script recompile ;; Current valid values are "abort" and "co-op" ; ScriptStopStrategy = co-op - + ;# {DeleteScriptsOnStartup} {} {Delete previously compiled script DLLs on startup?} {true false} true ;; Controls whether previously compiled scripts DLLs are deleted on sim restart. If you set this to false @@ -924,17 +1011,6 @@ ;; But this costs a lot of time, so region load will take a lot longer. ;; it is more usefull if there are no previously compiled scripts DLLs (as with DeleteScriptsOnStartup = true) ;CompactMemOnLoad = false - - ;# {DefaultCompileLanguage} {Enabled:true} {Default script language?} {lsl vb cs} lsl - ;; Default language for scripts - ; DefaultCompileLanguage = "lsl" - - ;# {AllowedCompilers} {Enabled:true} {Languages to allow (comma separated)?} {} lsl - ;; List of allowed languages (lsl,vb,cs) - ;; AllowedCompilers=lsl,cs,vb - ;; *warning*, non lsl languages have access to static methods such as - ;; System.IO.File. Enable at your own risk. - ; AllowedCompilers = "lsl" ;; Compile debug info (line numbers) into the script assemblies ; CompileWithDebugInformation = true @@ -1043,7 +1119,7 @@ ;; or... use Groups Module V2, which works for standalones and robust grids ; Module = "Groups Module V2" - ;# {StorageProvider} {Module:Groups Module V2} {The DLL that provides the storage for V2} {OpenSim.Data.MySQL.dll} + ;# {StorageProvider} {Module:Groups Module V2} {The DLL that provides the storage for V2} {OpenSim.Data.MySQL.dll} ; StorageProvider = OpenSim.Data.MySQL.dll ;# {ServicesConnectorModule} {Module:GroupsModule Module:Groups Module V2} {Service connector to use for groups} {XmlRpcGroupsServicesConnector SimianGroupsServicesConnector "Groups Local Service Connector" "Groups Remote Service Connector" "Groups HG Service Connector"} XmlRpcGroupsServicesConnector @@ -1061,7 +1137,7 @@ ; LocalService = local ;# {SecretKey} {ServicesConnectorModule:Groups Remote Service Connector} {Secret key between sim and remote group service} {} "" - ;; Used for V2 in Remote only. + ;; Used for V2 in Remote only. ; SecretKey = "" ;# {GroupsServerURI} {Module:GroupsModule (ServicesConnectorModule:Groups Remote Service Connector or (ServicesConnectorModule:Groups HG Service Connector and LocalService:remote))} {Groups Server URI} {} @@ -1072,11 +1148,11 @@ ;; Leave it commented for standalones, V2 ; GroupsServerURI = "" - ;# {HomeURI} {ServicesConnectorModule:Groups HG Service Connector} {What's the home address of this world?} {} + ;# {HomeURI} {ServicesConnectorModule:Groups HG Service Connector} {What's the home address of this world?} {} ;; Used for V2 in HG only. For example ;; http://mygridserver.com:9000 or http://mygridserver.com:8002 ;; If you have this set under [Startup], no need to set it here, leave it commented - ; HomeURI = "" + ; HomeURI = "" ;# {MessagingEnabled} {Module:GroupsModule Module:Groups Module V2} {Is groups messaging enabled?} {true false} true ; MessagingEnabled = true @@ -1117,35 +1193,35 @@ ; TEST OPTION KEEP AS FALSE ; if true, don't send object updates if outside view range - ; ObjectsCullingByDistance = false + ; ObjectsCullingByDistance = false [MediaOnAPrim] ;# {Enabled} {} {Enable Media-on-a-Prim (MOAP)} {true false} true ;; Enable media on a prim facilities - ; Enabled = true; + ; Enabled = true [NPC] ;# {Enabled} {} {Enable Non Player Character (NPC) facilities} {true false} false ; Enabled = false - + ;; several options to control NPCs creation - + ;# {AllowNotOwned} {} {allow NPCs to be created not Owned} {true false} true ;; allow NPCs to be created not Owned {true false} default: true ; AllowNotOwned = true - + ;# {AllowSenseAsAvatar} {} {allow NPCs to set to be sensed as Avatars} {true false} true ;; allow NPCs to set to be sensed as Avatars {true false} default: true ; AllowSenseAsAvatar = true - + ;# {AllowCloneOtherAvatars} {} {allow NPCs to created cloning any avatar in region} {true false} true ;; allow NPCs to created cloning any avatar in region {true false} default: true ; AllowCloneOtherAvatars = true - + ;# {NoNPCGroup} {} {if true NPCs will have no group title, if false display "- NPC -"} {true false} true ;; if true NPCs will have no group title, if false display "- NPC -" for easy identification {true false} default: true - ; NoNPCGroup = true + ; NoNPCGroup = true [Terrain] @@ -1155,13 +1231,13 @@ [LandManagement] ;; set this to false to not display parcel ban lines ;ShowParcelBansLines = true - + [UserProfiles] ;# {ProfileServiceURL} {} {Set url to UserProfilesService} {} ;; Set the value of the url to your UserProfilesService ;; If un-set / "" the module is disabled ;; ProfileServiceURL = ${Const|BaseURL}:${Const|PublicPort} - + ;# {AllowUserProfileWebURLs} {} {allow user profiles web urls} {true false} true ;; set this to false to prevent your users to be sent to unknown ;; web sites by other users on their profiles @@ -1186,15 +1262,15 @@ ;# {Include-Architecture} {} {Choose one of the following architectures} {config-include/Standalone.ini config-include/StandaloneHypergrid.ini config-include/Grid.ini config-include/GridHypergrid.ini config-include/SimianGrid.ini config-include/HyperSimianGrid.ini} config-include/Standalone.ini ;; Uncomment one of the following includes as required. For instance, to create a standalone OpenSim, ;; uncomment Include-Architecture = "config-include/Standalone.ini" - ;; + ;; ;; Then you will need to copy and edit the corresponding *Common.example file in config-include/ ;; that the referenced .ini file goes on to include. ;; - ;; For instance, if you chose "config-include/Standalone.ini" then you will need to copy + ;; For instance, if you chose "config-include/Standalone.ini" then you will need to copy ;; "config-include/StandaloneCommon.ini.example" to "config-include/StandaloneCommon.ini" before ;; editing it to set the database and backend services that OpenSim will use. ;; - ; Include-Architecture = "config-include/Standalone.ini" + Include-Architecture = "config-include/Standalone.ini" ; Include-Architecture = "config-include/StandaloneHypergrid.ini" ; Include-Architecture = "config-include/Grid.ini" ; Include-Architecture = "config-include/GridHypergrid.ini" diff --git a/bin/OpenSim32.exe b/bin/OpenSim32.exe new file mode 100644 index 0000000000..74477c0b68 Binary files /dev/null and b/bin/OpenSim32.exe differ diff --git a/bin/OpenSim32.exe.config b/bin/OpenSim32.exe.config new file mode 100644 index 0000000000..a3b2026962 --- /dev/null +++ b/bin/OpenSim32.exe.config @@ -0,0 +1,76 @@ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/bin/OpenSim.32BitLaunch.pdb b/bin/OpenSim32.pdb similarity index 71% rename from bin/OpenSim.32BitLaunch.pdb rename to bin/OpenSim32.pdb index 5083dd5df5..86d3058531 100644 Binary files a/bin/OpenSim.32BitLaunch.pdb and b/bin/OpenSim32.pdb differ diff --git a/bin/OpenSimDefaults.ini b/bin/OpenSimDefaults.ini index f70f7dbe57..834a770d2a 100644 --- a/bin/OpenSimDefaults.ini +++ b/bin/OpenSimDefaults.ini @@ -4,7 +4,7 @@ [Startup] ; Console prompt ; Certain special characters can be used to customize the prompt - ; Currently, these are + ; Currently, these are ; \R - substitute region name ; \\ - substtitue \ ConsolePrompt = "Region (\R) " @@ -22,6 +22,9 @@ ; How many lines of command history should we keep? (default is 100) ConsoleHistoryFileLines = 100 + ; Time stamp commands in history file (default false) + ; ConsoleHistoryTimeStamp = false + ; Set this to true if you want to log crashes to disk ; this can be useful when submitting bug reports. ; However, this will only log crashes within OpenSimulator that cause the entire program to exit @@ -61,7 +64,7 @@ ; UnsafeQueueUserWorkItem has been benchmarked with better ; performance on .NET/Windows ; - ; UnsafeQueueUserWorkItem refers to the fact that the code creating the event could elevate its security + ; UnsafeQueueUserWorkItem refers to the fact that the code creating the event could elevate its security ; privileges. However, as calling code is trusted anyway this is safe (if you set ; TrustedBinaries = true in the [XEngine] section then you already have to trust that incoming code for other reasons). async_call_method = SmartThreadPool @@ -75,13 +78,13 @@ JobEngineEnabled = true ; Plugin Registry Location - ; Set path to directory for plugin registry. Information about the + ; Set path to directory for plugin registry. Information about the ; registered repositories and installed plugins will be stored here. ; The OpenSim.exe process must have R/W access to the location. RegistryLocation = "." ; Used by region module addins. You can set this to outside bin, so that addin - ; configurations will survive updates. The OpenSim.exe process must have R/W access + ; configurations will survive updates. The OpenSim.exe process must have R/W access ; to the location. ConfigDirectory = "." @@ -108,7 +111,7 @@ ; Determines the page from which regions xml is retrieved if you are loading these from the web ; The XML here has the same format as it does on the filesystem (including the tag), ; except that everything is also enclosed in a tag. - ; regionload_webserver_url = "http://example.com/regions.xml"; + ; regionload_webserver_url = "http://example.com/regions.xml" ;; Allow the simulator to start up if there are no region configuration available ;; from the selected region_info_source. @@ -122,13 +125,13 @@ ;; keep it true if you have many old objects with sits set by scripts. ;; the offset in question is added to the SitTarget to find the sitting avatar position. ;; acording to its size, etc. - ; LegacySitOffsets = true; - + ; LegacySitOffsets = true + ; Maximum number of position, rotation and scale changes for each prim that the simulator will store for later undos ; Increasing this number will increase memory usage. MaxPrimUndos = 20 - ; Minimum size for non-physical prims.This can be overridden in the region config file (as + ; Minimum size for non-physical prims.This can be overridden in the region config file (as ; NonPhysicalPrimMin!). ; NonPhysicalPrimMin = 0.001 @@ -137,7 +140,7 @@ ; Minimum size where a prim can be physical. This can be overridden in the region config file. ; PhysicalPrimMin = 0.01 - + ; Maximum size of physical prims. Affects resizing of existing prims. This can be overridden in the region config file. PhysicalPrimMax = 64 @@ -153,7 +156,7 @@ LinksetPrims = 0 ; Allow scripts to keep running when they cross region boundaries, rather than being restarted. State is reloaded on the destination region. - ; This only applies when crossing to a region running in a different simulator. + ; This only applies when crossing to a region running in a different simulator. ; For crossings where the regions are on the same simulator the script is always kept running. AllowScriptCrossing = true @@ -164,18 +167,21 @@ TrustBinaries = false ; the default view range. Viewers override this ( no major effect still ) - DefaultDrawDistance = 255.0 + ;DefaultDrawDistance = 255.0 ; limit the maximum view range ( no effect still (does limit MaxRegionsViewDistance) ) - MaxDrawDistance = 512 - + ;MaxDrawDistance = 512 + ; the maximum distance to tell a viewer to connect to a neighbour region, so it can be seen ; (it is limited by MaxDrawDistance above) - ; less than 256 shows imediate neighbours; 512 also second imediate neighbours etc - ; more than 512m can cause viewers problems specially in case of dense regions. + ; less than 256 shows immediate neighbours; 256 to 511 also second imediate neighbours etc + ; more than 511m can cause viewers problems specially in case of dense regions. ; curretly this distance is from current region borders. - MaxRegionsViewDistance = 255 - + ; Warning: if relevant regions have different setting you may notice strange + ; effects due to that asymmetry + ; ***** + ;MaxRegionsViewDistance = 255 + ; If you have only one region in an instance, or to avoid the many bugs ; that you can trigger in modules by restarting a region, set this to ; true to make the entire instance exit instead of restarting the region. @@ -193,7 +199,7 @@ ; The scale factor it 55 * FrameTime, corresponding to 5 with default configuration ; You can choose to show the true physics FPS to viewers by setting Normalized55FPS to false. ; Normalized55FPS = true - + ; Main Frame time ; This defines the rate of several simulation events. ; Default value should meet most needs. @@ -208,44 +214,44 @@ ; Less than 60% of FPS is amber by default, less then 40% is red. ; These values are advisory. Viewers may choose to not use them but it is ; encouraged that they do. - ; FrameTimeWarnPercent = 60; - ; FrameTimeCritPercent = 40; + ; FrameTimeWarnPercent = 60 + ; FrameTimeCritPercent = 40 ; Send scheduled updates to objects in the scene - ; This must be a whole number - UpdateObjectsEveryNFrames = 1; + ; This must be a whole number + UpdateObjectsEveryNFrames = 1 ; Send position/velocity, etc. updates to agents in the scene - ; This must be a whole number - UpdateAgentsEveryNFrames = 1; + ; This must be a whole number + UpdateAgentsEveryNFrames = 1 ; Apply pending forces from physics calculations to an entity. - ; This must be a whole number - UpdateEntityMovementEveryNFrames = 1; + ; This must be a whole number + UpdateEntityMovementEveryNFrames = 1 ; Send coarse location updates to viewers. In a classic viewer, this updates the minimap. ; This must be a whole number - UpdateCoarseLocationsEveryNFrames = 50; + UpdateCoarseLocationsEveryNFrames = 50 ; Physics simulation execution or syncronization, acording to engine. Should be 1 ; This must be a whole number - UpdatePhysicsEveryNFrames = 1; + UpdatePhysicsEveryNFrames = 1 ; Send out the on frame event to modules and other listeners. This should probably never deviate from 1. ; This must be a whole number - UpdateEventsEveryNFrames = 1; + UpdateEventsEveryNFrames = 1 ; Send terrain updates to viewers ; This must be a whole number - UpdateTerrainEveryNFrames = 50; + UpdateTerrainEveryNFrames = 50 ; Persitently store any objects which meet the PRIM STORAGE criteria ; This must be a whole number - UpdateStorageEveryNFrames = 200; + UpdateStorageEveryNFrames = 200 ; Clean up temp on rez objects. ; This must be a whole number - UpdateTempCleaningEveryNSeconds = 180; + UpdateTempCleaningEveryNSeconds = 180 ; ## ; ## PRIM STORAGE @@ -283,23 +289,23 @@ meshing = Meshmerizer ;meshing = ZeroMesher - + ; Path to decoded sculpty maps ; Defaults to "j2kDecodeCache ;DecodedSculptMapPath = "j2kDecodeCache" - + ; if you use Meshmerizer and want sculpt map collisions, setting this to ; to true will store decoded sculpt maps in a special folder in your bin ; folder, which can reduce startup times by reducing asset requests. Some ; versions of mono dont work well when reading the cache files, so set this ; to false if you have compatibility problems. ;CacheSculptMaps = true - + ;; BulletSim is the default physics engine. It provides the best performance and most functionality. ;; BulletSim supports varregions. - ;; OpenDynamicsEngine was the previous default physics engine in OpenSimulator 0.7.6.1 and before. + ;; OpenDynamicsEngine was the previous default physics engine in OpenSimulator 0.7.6.1 and before. ;; It continues to provide a workable physics implementation. It does not currently support varregions. - ;; basicphysics effectively does not model physics at all, making all objects phantom. + ;; basicphysics effectively does not model physics at all, making all objects phantom. ;; Default is BulletSim physics = BulletSim ;physics = modified_BulletX @@ -324,14 +330,14 @@ ; For example, servers inside your firewall. ; Separate patterns with a ';' ; HttpProxyExceptions = ".mydomain.com;localhost" - + ; ## ; ## EMAIL MODULE ; ## ;; The email module requires some configuration. It needs an SMTP ;; server to send mail through. ;emailmodule = DefaultEmailModule - + ; ## ; ## ANIMATIONS ; ## @@ -343,11 +349,11 @@ ; PreJump is an additional animation state, but it probably ; won't look right until the physics engine supports it ; (i.e delays takeoff for a moment) - + ; # ; # statistics - ; # - + ; # + ; Simulator statistics are output to the console periodically at debug level INFO. ; Setting this to zero disables this output. ; LogShowStatsSeconds = 3600 @@ -401,21 +407,32 @@ ; routing and land at the landmark coordinates when set to true ; default is false ; TelehubAllowLandmark = false - + + ; # + ; # SSL certificates validation options + ; # + ; SSL certificate validation options + ; you can allow selfsigned certificates or no official CA with next option set to true + ; NoVerifyCertChain = true + ; you can also bypass the hostname or domain verification + ; NoVerifyCertHostname = true + ; having both options true does provide encryption but with low security + ; set both true if you don't care to use SSL, they are needed to contact regions or grids that do use it. + [Map] - ; Map tile options. + ; Map tile options. ; If true, then maptiles are generated using the MapImageModule below. ; If false then the texture referenced by MaptileStaticUUID is used instead, which can also be overridden - ; in individual region config file(s). If you do not want to upload map tiles at all, then you will need + ; in individual region config file(s). If you do not want to upload map tiles at all, then you will need ; both to set this to false and comment out the [Modules] MapImageServiceModule setting in config-include/ ;GenerateMaptiles = true ;WorldMapModule = "WorldMap" ; The module to use in order to generate map images. - ; MapImageModule is the default. Warp3DImageModule is an alternative experimental module that can - ; generate better images. + ; MapImageModule is the default. Warp3DImageModule is an alternative experimental module that can + ; generate better images. ;MapImageModule = "MapImageModule" ; World map blacklist timeout in seconds @@ -441,7 +458,7 @@ TexturePrimSize = 48 ; Attempt to render meshes and sculpties on the map - RenderMeshes = false; + RenderMeshes = false [Permissions] ; ## @@ -458,14 +475,14 @@ ; Default is true serverside_object_permissions = true - + ; This allows some control over permissions ; please note that this still doesn't duplicate SL, and is not intended to - + ; This allows grid users with a UserLevel of 200 or more to assume god - ; powers in the regions in this simulator. + ; powers in the regions in this simulator. allow_grid_gods = false - + ; Allow region owners to assume god powers in their regions ;region_owner_is_god = true @@ -501,7 +518,7 @@ ; allowed_script_editors = all ; Provides a simple control for land owners to give build rights to specific avatars - ; in publicly accessible parcels that disallow object creation in general. + ; in publicly accessible parcels that disallow object creation in general. ; Owners specific avatars by adding them to the Access List of the parcel ; without having to use the Groups feature ; Disabled by default @@ -542,12 +559,12 @@ ;; Set the value of the url to your UserProfilesService ;; If un-set / "" the module is disabled ;; If the ProfileURL is not set, then very BASIC - ;; profile support will be configured. If the ProfileURL is set to a - ;; valid URL, then full profile support will be configured. The URL + ;; profile support will be configured. If the ProfileURL is set to a + ;; valid URL, then full profile support will be configured. The URL ;; points to your grid's Robust user profiles service - ;; + ;; ; ProfileURL = http://127.0.0.1:9000 - + ;; set this to false to prevent your users to be sent to unknown ;; web sites by other users on their profiles ; AllowUserProfileWebURLs = true @@ -571,16 +588,18 @@ http_listener_port = 9000 console_port = 0 - ; ssl config: Experimental! The auto https config only really works definately on windows XP now - ; you need a Cert Request/Signed pair installed in the MY store with the CN specified below - ; you can use https on other platforms, but you'll need to configure the httpapi yourself for now - http_listener_ssl = false ; Also create a SSL server - http_listener_cn = "localhost" ; Use the cert with the common name + ; ssl config: Experimental! + http_listener_ssl = false ; if set to true main server is replaced by a ssl one http_listener_sslport = 9001 ; Use this port for SSL connections - http_listener_ssl_cert = "" ; Currently unused, but will be used for OSHttpServer + ; currently if using ssl, regions ExternalHostName must the the same and equal to http_listener_cn + ; this will change is future + http_listener_cn = "myRegionsExternalHostName" + ; if the cert doesnt have a oficial CA or is selfsigned viewers option NoVerifySSLCert need to be set true + http_listener_cert_path = "mycert.p12" ; path for the cert file that is valid for the ExternalHostName + http_listener_cert_pass = "mycertpass" ; the cert passwork - ; HTTPS for "Out of band" management applications such as the remote - ; admin module + ; addicional HTTPS for "Out of band" management applications such as the remote + ; admin module or scripts ; ; Create https_listener = "True" will create a listener on the port ; specified. Provide the path to your server certificate along with it's @@ -588,7 +607,7 @@ ; https_listener = False ; Set our listener to this port ; https_port = 0 - ; Path to X509 certificate + ; Path to X509 certificate, can be the same as main or another ; cert_path = "path/to/cert.p12" ; Password for cert ; cert_pass = "password" @@ -596,12 +615,12 @@ ; Maximum bytes allowed for HTTP_BODY_MAXLENGTH. ; By default, llHTTPRequest limits the response body to 2048 bytes. ; This limit can be extended using HTTP_BODY_MAXLENGTH to a maximum - ; of HttpBodyMaxLenMAX bytes. + ; of HttpBodyMaxLenMAX bytes. ; HttpBodyMaxLenMAX=16384 ; Hostname to use in llRequestURL/llRequestSecureURL - ; if not defined - default machine name is being used - ; (on Windows this mean NETBIOS name - useably only inside local network) + ; must be a valid hostname for the ssl cert. + ; if not defined - llRequestURL/llRequestSecureURL are disabled ; ExternalHostNameForLSL=127.0.0.1 ; Disallow the following address ranges for user scripting calls (e.g. llHttpRequest()) @@ -623,7 +642,7 @@ ; You can also disable the blacklist entirely with an empty entry ; ; OutboundDisallowForUserScripts = "" - + ; What is reported as the "X-Secondlife-Shard" ; Defaults to the user server url if not set ; The old default is "OpenSim", set here for compatibility @@ -644,20 +663,12 @@ ; Viewer-based access control. |-separated list of allowed viewers. ; AllowedClients = "" - ; Viewer-based access control. |-separated list of denied viewers. + ; Viewer-based access control. |-separated list of denied viewers. ; No restrictions by default. ; DeniedClients = "" [ClientStack.LindenUDP] - ; Set this to true to process incoming packets asynchronously. Networking is - ; already separated from packet handling with a queue, so this will only - ; affect whether networking internals such as packet decoding and - ; acknowledgement accounting are done synchronously or asynchronously - ; Default is true. - ; - ;async_packet_handling = true - ; The client socket receive buffer size determines how many ; incoming requests we can process; the default on .NET is 8192 ; which is about 2 4k-sized UDP datagrams. On mono this is @@ -690,7 +701,7 @@ ;client_throttle_max_bps = 187500 ; Minimum bytes per second to send to any single client as a result of - ; adaptive throttling. Viewer preferences set to a lower number will + ; adaptive throttling. Viewer preferences set to a lower number will ; override the settin. The example given here ensures that adaptive ; throttling will never decrease per client bandwidth below 256 kbps. ; @@ -767,7 +778,7 @@ [ClientStack.LindenCaps] - ;; Long list of capabilities taken from + ;; Long list of capabilities taken from ;; http://wiki.secondlife.com/wiki/Current_Sim_Capabilities ;; Not all are supported by OpenSim. The ones supported are ;; set to localhost. These defaults can be overwritten @@ -842,10 +853,10 @@ ; Capability for searching for people Cap_AvatarPickerSearch = "localhost" - + [Chat] ; Controls whether the chat module is enabled. Default is true. - enabled = true; + enabled = true ; Distance in meters that whispers should travel. Default is 10m whisper_distance = 10 @@ -857,8 +868,8 @@ shout_distance = 100 [EntityTransfer] - ; The maximum distance in regions that an agent is allowed to teleport - ; along the x or y axis. This is set to 65535 because current viewers + ; The maximum distance in regions that an agent is allowed to teleport + ; along the x or y axis. This is set to 65535 because current viewers ; can't handle teleports that are greater than this distance ; Setting to 0 will allow teleports of any distance ; @@ -868,7 +879,7 @@ AllowAvatarCrossing = true ; This disables border transfers for objects. When true, objects can be placed outside - ; the region's border without being transferred to another simulator. + ; the region's border without being transferred to another simulator. DisableObjectTransfer = false ; Minimum user level required for HyperGrid teleports @@ -908,7 +919,7 @@ [Appearance] ; Persist avatar baked textures - ; Persisting baked textures can speed up login and region border + ; Persisting baked textures can speed up login and region border ; crossings especially with large numbers of users, though it ; will store potentially large numbers of textures in your asset ; database @@ -922,11 +933,11 @@ DelayBeforeAppearanceSend = 2 ; If true, avatar appearance information is resent to other avatars in the simulator every 60 seconds. - ; This may help with some situations where avatars are persistently grey, though it will not help + ; This may help with some situations where avatars are persistently grey, though it will not help ; in other situations (e.g. appearance baking failures where the avatar only appears as a cloud to others). ResendAppearanceUpdates = false - ; Turning this on responds to CachedTexture packets to possibly avoid rebaking the avatar + ; Turning this on responds to CachedTexture packets to possibly avoid rebaking the avatar ; on every login ReuseTextures = false @@ -940,22 +951,39 @@ ; Experimental setting to control CPU spiking when avatars with many attachments login/change outfit ; or when multiple avatars with medium level attachments login/change outfit simultaneously. ; If 0 then no throttling is performed. - ThrottlePer100PrimsRezzed = 0; + ThrottlePer100PrimsRezzed = 0 [Mesh] - ; enable / disable Collada mesh support + ; enable / disable mesh asset uploads + ; mesh asset must conform to standard mesh format, with OpenSim extensions ; default is true AllowMeshUpload = true - ; if you use Meshmerizer and want collisions for meshies, setting this to true - ; will cause OpenSim to attempt to decode meshies assets, extract the physics - ; mesh, and use it for collisions. - UseMeshiesPhysicsMesh = true - ; Minimum user level required to upload meshes ;LevelUpload = 0 + ; support meshes on physics + ;UseMeshiesPhysicsMesh = true + + ;support convex shape type on normal prims + ; (ubOde only) + ;ConvexPrims = true + + ;support convex shape type on sculpts + ; (ubOde only) + ;ConvexSculpts = true + + ; mesh cache settings: + ; (ubOde only) + ; do cache (keep true) + ;MeshFileCache = true + ; cache folder name relative to bin/ or absolute path + ;MeshFileCachePath = MeshCache + ;MeshFileCacheDoExpire = true + ;MeshFileCacheExpireHours = 48 + + [Textures] ; If true, textures generated dynamically (i.e. through osSetDynamicTextureData() and similar OSSL functions) are reused where possible @@ -976,8 +1004,8 @@ [ODEPhysicsSettings] - ; ## - ; ## Physics stats settings + ; ## + ; ## Physics stats settings ( most ignored by ubOde ) ; ; If collect_stats is enabled, then extra stat information is collected which is accessible via the MonitorModule @@ -1009,7 +1037,7 @@ ; Max value is 255, min value is 0 avatar_terminal_velocity = 54 - ; World Step size. + ; World Step size. ; with legacy ODE this value needs to be close to 0.02s ; with ubOde this value can be reduced to improve simulation quality with the cost of higher cpu load ; you will need to test acording to you needs @@ -1026,7 +1054,7 @@ world_hashSpace_level_high = 12 meters_in_small_space = 29.9 - + ; ## ; ## Contact properties. (the stuff that happens when things come in contact with each other) @@ -1066,7 +1094,7 @@ ; See http://en.wikipedia.org/wiki/PID_controller av_pid_derivative = 2200.0 - av_pid_proportional = 900.0; + av_pid_proportional = 900.0 ;girth of the avatar. Adds radius to the height also av_capsule_radius = 0.37 @@ -1099,8 +1127,8 @@ minimum_ground_flight_offset = 3.0 ; Plant avatar. This reduces the effect of physical contacts with the avatar. - ; If you have a group of unruly and rude visitors that bump each other, turn this on to make that less attractive. - ; The avatar still allows a small movement based on the PID settings above. Stronger PID settings AND this active + ; If you have a group of unruly and rude visitors that bump each other, turn this on to make that less attractive. + ; The avatar still allows a small movement based on the PID settings above. Stronger PID settings AND this active ; will lock the avatar in place av_planted = false @@ -1150,12 +1178,14 @@ ; ## additional meshing options ; ## - ; Physical collision mesh proxies are normally created for complex prim shapes, - ; and collisions for simple boxes and spheres are computed algorithmically. - ; If you would rather have mesh proxies for simple prims, you can set this to - ; true. Note that this will increase memory usage and region startup time. - ; Default is false. - ;force_simple_prim_meshing = false + ; Physics needs to create internal meshs (or convert the object meshs or scultps) + ; for all prims except simple boxes and spheres. + + ; collisions of small objects againts larger ones can have a increased CPU load cost + ; so this are represented by a simple BOX + ; if all their scale dimensions are lower or equal to this option. Default is 0.1m + ; (ubOde only) + ; MinSizeToMeshmerize = 0.1 [BulletSim] @@ -1239,7 +1269,7 @@ PhysicsLoggingEnabled = False PhysicsLoggingDir = "." VehicleLoggingEnabled = False - + [RemoteAdmin] enabled = false @@ -1301,7 +1331,7 @@ ;copy_folders = false ; path to default appearance XML file that specifies the look of the default avatars - ;default_appearance = default_appearance.xml + ;default_appearance = default_appearance.xml ; RestPlugins are not currently operational. @@ -1459,13 +1489,21 @@ [Trees] - ; Enable this to allow the tree module to manage your sim trees, including growing, reproducing and dying - ; default is false + ; enable the trees module. default true + enabled = true + + ; active_trees allows module to change its trees in time. + ; some will be deleted, others created and rest may grow + ; default is false. You can change it with console command tree active true | false later active_trees = false + ; the trees change execution time rate (in ms) + update_rate = 1000 - ; Density of tree population - tree_density = 1000.0 - + ; allow the trees to grow. + ; DANGER + ; this option causes high network use on the order of + ; NumberOfTrees * NumberAvatars * 1000 / update_rate udp packets per second + allowGrow = false [VectorRender] ; the font to use for rendering text (default: Arial) @@ -1493,7 +1531,7 @@ ; Maximum number of llListen events we allow per script ; Set this to 0 to have no limit imposed. max_listens_per_script = 64 - + ; Maximum number of external urls that scripts can set up in this simulator (e.g. via llRequestURL()) max_external_urls_per_simulator = 100 @@ -1693,38 +1731,46 @@ [Economy] + ; the economy module in use + ; default is the provided BetaGridLikeMoneyModule + ; - This module is for demonstration only - + ; The default economy module only implements just enough to allow free actions (transfer of objects, etc). + ; There is no intention to implement anything further in core OpenSimulator. + ; This functionality has to be provided by third party modules. + ; To use other modules you need to override this setting on OpenSim.ini Economy (or startup) section + ; economymodule = BetaGridLikeMoneyModule + ; These economy values get used in the BetaGridLikeMoneyModule. - This module is for demonstration only - ; The default economy module only implements just enough to allow free actions (transfer of objects, etc). ; There is no intention to implement anything further in core OpenSimulator. ; This functionality has to be provided by third party modules. ;; Enables selling things for $0. Default is true. - SellEnabled = true + ; SellEnabled = true ;; Money Unit fee to upload textures, animations etc. Default is 0. - PriceUpload = 0 + ;PriceUpload = 0 ;; Money Unit fee to create groups. Default is 0. - PriceGroupCreate = 0 + ;PriceGroupCreate = 0 ; We don't really know what the rest of these values do. These get sent to the client ; These taken from Agni at a Public Telehub. Change at your own risk. - ObjectCount = 0 - PriceEnergyUnit = 100 - PriceObjectClaim = 10 - PricePublicObjectDecay = 4 - PricePublicObjectDelete = 4 - PriceParcelClaim = 1 - PriceParcelClaimFactor = 1 - - PriceRentLight = 5 - TeleportMinPrice = 2 - TeleportPriceExponent = 2 - EnergyEfficiency = 1 - PriceObjectRent = 1 - PriceObjectScaleFactor = 10 - PriceParcelRent = 1 + ;ObjectCount = 0 + ;PriceEnergyUnit = 0 + ;PriceObjectClaim = 0 + ;PricePublicObjectDecay = 0 + ;PricePublicObjectDelete = 0 + ;PriceParcelClaim = 0 + ;PriceParcelClaimFactor = 1 + ;PriceRentLight = 0 + ;TeleportMinPrice = 0 + ;TeleportPriceExponent = 2 + ;EnergyEfficiency = 1 + ;PriceObjectRent = 0 + ;PriceObjectScaleFactor = 10 + ;PriceParcelRent = 0 [XEngine] ; Enable this engine in this OpenSim instance @@ -1770,8 +1816,8 @@ ; But this costs a lot of time, so region load will take a lot longer. ; it is more usefull if there are no previously compiled scripts DLLs (or DeleteScriptsOnStartup = true) ; CompactMemOnLoad = false - - ; Controls whether scripts are stopped by aborting their threads externally (abort) + + ; Controls whether scripts are stopped by aborting their threads externally (abort) ; or by co-operative checks inserted by OpenSimulator into compiled script (co-op). ; co-op will be more stable as aborting threads can cause instability. ; abort was the default option in OpenSimulator 0.8 and before. @@ -1787,14 +1833,6 @@ ; Save the source of all compiled scripts WriteScriptSourceToDebugFile = false - ; Default language for scripts - DefaultCompileLanguage = lsl - - ; List of allowed languages (lsl,vb,cs) - ; AllowedCompilers=lsl,cs,vb - ; *warning*, non lsl languages have access to static methods such as System.IO.File. Enable at your own risk. - AllowedCompilers=lsl - ; Compile debug info (line numbers) into the script assemblies CompileWithDebugInformation = true @@ -1805,7 +1843,7 @@ ; Allow the use of os* functions (some are dangerous) AllowOSFunctions = false - + ; Allow the user of LightShare functions AllowLightShareFunctions = false @@ -1824,7 +1862,7 @@ ; Comma separated list of UUIDS allows the function for that list of UUIDS ; Allow_osSetRegionWaterHeight = 888760cb-a3cf-43ac-8ea4-8732fd3ee2bb - + ; Comma separated list of owner classes that allow the function for a particular class of owners. Choices are ; - PARCEL_GROUP_MEMBER: allow if objectgroup is the same group as the parcel ; - PARCEL_OWNER: allow if the objectowner is parcelowner @@ -1852,7 +1890,7 @@ ; Amount of time in milliseconds we will wait for an event to completely normally when a script stop is requested ; before aborting the thread (such as when an object containing scripts is taken into inventory). - WaitForEventCompletionOnScriptStop = 1000; + WaitForEventCompletionOnScriptStop = 1000 ; Sets the multiplier for the scripting delays ScriptDelayFactor = 1.0 @@ -1882,7 +1920,7 @@ ; prims ; DisableUndergroundMovement = true - ;; Path to script assemblies + ;; Path to script assemblies ; ScriptEnginesPath = "ScriptEngines" @@ -1899,7 +1937,8 @@ ; regex specifying for which regions concierge service is desired; if ; empty, then for all - regions = "^MeetingSpace-" + ;regions = "^MeetingSpace-" + regions = "" ; for each region that matches the regions regexp you can provide ; (optionally) a welcome template using format substitution: @@ -1907,14 +1946,14 @@ ; {1} is replaced with the name of the region ; {2} is replaced with the name of the concierge (whoami variable above) - welcomes = /path/to/welcome/template/directory + ;welcomes = /path/to/welcome/template/directory ; Concierge can send attendee lists to an event broker whenever an ; avatar enters or leaves a concierged region. the URL is subject ; to format substitution: ; {0} is replaced with the region's name ; {1} is replaced with the region's UUID - broker = "http://broker.place.com/{1}" + ;broker = "http://broker.place.com/{1}" [MRM] @@ -2018,7 +2057,7 @@ ;Module = GroupsModule ; Enable Group Notices - ;NoticesEnabled = true + ;NoticesEnabled = true ; This makes the Group module very chatty on the console. DebugEnabled = false @@ -2033,15 +2072,15 @@ ; Specify which messaging module to use for groups messaging and if it's enabled ;MessagingModule = GroupsMessagingModule - ;MessagingEnabled = true + ;MessagingEnabled = true ; Experimental option to only message cached online users rather than all users - ; Should make large group with few online members messaging faster, as the expense of more calls to ROBUST presence service + ; Should make large group with few online members messaging faster, at the expense of more calls to ROBUST presence service ; (Flotsam groups only; in V2 this is always on) MessageOnlineUsersOnly = false ; Service connectors to the Groups Service. Select one depending on whether you're using a Flotsam XmlRpc backend or a SimianGrid backend - + ; SimianGrid Service for Groups ;ServicesConnectorModule = SimianGroupsServicesConnector ;GroupsServerURI = http://mygridserver.com:82/Grid/ @@ -2051,11 +2090,11 @@ ;GroupsServerURI = http://yourxmlrpcserver.com/xmlrpc.php ; XmlRpc Security settings. These must match those set on your backend groups service if the service is using these keys - ;XmlRpcServiceReadKey = 1234 - ;XmlRpcServiceWriteKey = 1234 + ;XmlRpcServiceReadKey = 1234 + ;XmlRpcServiceWriteKey = 1234 ; Disables HTTP Keep-Alive for XmlRpcGroupsServicesConnector HTTP Requests, - ; only set to false it if you absolute sure regions and groups server suport it. + ; only set to false it if you absolute sure regions and groups server support it. ; XmlRpcDisableKeepAlive = true ; Minimum user level required to create groups @@ -2063,8 +2102,8 @@ [PacketPool] - ;RecyclePackets = true; - ;RecycleDataBlocks = true; + ;RecyclePackets = true + ;RecycleDataBlocks = true ; If true, then the basic packet objects used to receive data are also recycled, not just the LLUDP packets. ; This reduces data churn @@ -2080,7 +2119,7 @@ ReprioritizationInterval = 2000.0 RootReprioritizationDistance = 10.0 ChildReprioritizationDistance = 20.0 - + ; TEST OPTION KEEP AS FALSE ; if true, don't send object updates if outside view range ObjectsCullingByDistance = false @@ -2093,7 +2132,7 @@ ; If n > 1, only every n UDP terse updates will be sent to observers of an avatar that are in another region ; n > 1 will reduce UDP traffic but may lead to laggier movement observed in other avatars, though values up to 4 may not generate a noticeable effect. ChildTerseUpdatePeriod = 0 - + ; Send an update to clients if the difference from the last sent avatar position is greater than this tolerance RootPositionUpdateTolerance = 0.05 @@ -2108,6 +2147,8 @@ ; If true, this will print out an error if more than a minute has passed since the last simulator frame ; Also is another source of region statistics provided via the regionstats URL Enabled = true + ; next option may still use framework performance monitors designed for debug only, so avoid it + ;ServerStatsEnabled = false [WebStats] @@ -2118,31 +2159,31 @@ ; enabled=false [Statistics] - ; NumberOfFrames is used in a moving average calculation, where NumberOfFrames is the number of frames + ; NumberOfFrames is used in a moving average calculation, where NumberOfFrames is the number of frames ; to include in the averaging calculations NumberOfFrames=10 [MediaOnAPrim] ; Enable media on a prim facilities - Enabled = true; + Enabled = true [NPC] ;; Enable Non Player Character (NPC) facilities Enabled = false ;; several options to control NPCs creation - + ;; allow NPCs to be created not Owned {true false} default: true ; AllowNotOwned = true - + ;; allow NPCs to set to be sensed as Avatars {true false} default: true ; AllowSenseAsAvatar = true - + ;; allow NPCs to created cloning any avatar in region {true false} default: true ; AllowCloneOtherAvatars = true - + ;; if true NPCs will have no group title, if false display "- NPC -" for easy identification {true false} default: true - ; NoNPCGroup = true + ; NoNPCGroup = true [Terrain] ; Values can be "pinhead-island" or "flat" @@ -2163,11 +2204,15 @@ ; whole region. LimitParcelLayerUpdateDistance = true ParcelLayerViewDistance = 128 - + ; set this to false to not display parcel ban lines ShowParcelBansLines = true + + ; Parcel Bans max height above ground. Default 100m + ; range 20m to 5000m + ; BanLineSafeHeight = 100 -;; +;; ;; If you are using a simian grid frontend you can enable ;; this module to upload tile images for the mapping fn ;; @@ -2178,8 +2223,8 @@ ;; -;; JsonStore module provides structured store for scripts -;; +;; JsonStore module provides structured store for scripts +;; [JsonStore] Enabled = False diff --git a/bin/Prebuild.exe b/bin/Prebuild.exe index 05deb1f551..aeecaccb1d 100755 Binary files a/bin/Prebuild.exe and b/bin/Prebuild.exe differ diff --git a/bin/PrimMesher.dll b/bin/PrimMesher.dll index 87022b7cfc..1f7b1b9670 100755 Binary files a/bin/PrimMesher.dll and b/bin/PrimMesher.dll differ diff --git a/bin/Robust.HG.ini.example b/bin/Robust.HG.ini.example index 7d13d4382f..0f9bb4b27b 100644 --- a/bin/Robust.HG.ini.example +++ b/bin/Robust.HG.ini.example @@ -3,30 +3,30 @@ ; * ; * Configurations for enabling HG1.5 -; * +; * ; * HG1.5 handlers are: OpenSim.Server.Handlers.dll:GatekeeperService ; * OpenSim.Server.Handlers.dll:UserAgentService -; * Additional OpenSim.Server.Handlers.dll:AssetServiceConnector and -; * OpenSim.Server.Handlers.dll:XInventoryInConnector +; * Additional OpenSim.Server.Handlers.dll:AssetServiceConnector and +; * OpenSim.Server.Handlers.dll:XInventoryInConnector ; * are started in port 8002, outside the firewall ; * ; ** ; * ; * The Const section allows us to define some basic information that we -; * will use throughout our configuration. We will provide examples for +; * will use throughout our configuration. We will provide examples for ; * setting the base url of the Robust server and the public and private ports ; * it uses. Changing the values of the constants will set the operating ; * parameters thoughout the configuration. Other constants that may prove -; * to be useful may be added to the followin section. They may be +; * to be useful may be added to the followin section. They may be ; * referenced anywhere in the configuration by using ${Const|Name}. One ; * such use is providing a base path for setting locations that Robust ; * uses to write data. -; * +; * [Const] ; The URL of the Robust server BaseURL = "http://127.0.0.1" - + ; The public port of the Robust server PublicPort = "8002" @@ -52,12 +52,12 @@ ; Set path to directory for plugin registry. Information ; about the registered repositories and installed plugins ; will be stored here - ; The Robust.exe process must have R/W access to the location + ; The Robust.exe process must have R/W access to the location RegistryLocation = "." ; Modular configurations ; Set path to directory for modular ini files... - ; The Robust.exe process must have R/W access to the location + ; The Robust.exe process must have R/W access to the location ConfigDirectory = "robust-include" ; Console commands can be saved to a file, so the command history persists after a restart. (default is true) @@ -70,6 +70,17 @@ ; How many lines of command history should we keep? (default is 100) ConsoleHistoryFileLines = 100 + ; Time stamp commands in history file (default false) + ; ConsoleHistoryTimeStamp = false + + ; peers SSL certificate validation options + ; you can allow selfsigned certificates or no official CA with next option set to true + NoVerifyCertChain = true + ; you can also bypass the hostname or domain verification + NoVerifyCertHostname = true + ; having both options true does provide encryption but with low security + ; set both true if you don't care to use SSL, they are needed to contact regions or grids that do use it. + [ServiceList] AssetServiceConnector = "${Const|PrivatePort}/OpenSim.Server.Handlers.dll:AssetServiceConnector" @@ -102,6 +113,8 @@ ;; Uncomment if you want to have centralized estate data ; EstateDataService = "${Const|PrivatePort}/OpenSim.Server.Handlers.dll:EstateDataRobustConnector" + MuteListConnector = "${Const|PrivatePort}/OpenSim.Server.Handlers.dll:MuteListServiceConnector" + ;; Additions for Hypergrid GatekeeperServiceInConnector = "${Const|PublicPort}/OpenSim.Server.Handlers.dll:GatekeeperServiceInConnector" @@ -151,7 +164,7 @@ ;; This is useful in cases where you want to protect most of the services, ;; but unprotect individual services. Username and Password can also be ;; overriden if you want to use different credentials for the different services. - ;; Hypergrid services are not affected by this; they are publicly available + ;; Hypergrid services are not affected by this; they are publicly available ;; by design. ;; By default, scripts are not allowed to call private services via llHttpRequest() @@ -229,27 +242,27 @@ ;; Choose an asset service (Only one option should be enabled) LocalServiceModule = "OpenSim.Services.AssetService.dll:AssetService" ;LocalServiceModule = "OpenSim.Services.FSAssetService.dll:FSAssetConnector" - + ;; FSAsset Directories. Base directory, where final asset files are stored and Spool directory for temp files ;; These directories must be on the same physical filesystem ;BaseDirectory = "./fsassets/data" ;SpoolDirectory = "./fsassets/tmp" - + ;; Original service can be checked if FSAssets can not find an asset ;FallbackService = "OpenSim.Services.AssetService.dll:AssetService"; - + ;; How many days since last updating the access time before its updated again by FSAssets when accessing an asset ;; Reduces DB calls if asset is requested often. Default value 0 will always update access time ;DaysBetweenAccessTimeUpdates = 30 - + ;; Should FSAssets print read/write stats to the robust console, default is true ;ShowConsoleStats = true - + ;; FSAssets Custom Database Config (Leave blank to use grids default database configuration) ;StorageProvider = "" ;ConnectionString = "" ;Realm = "fsassets" - + ;; The following are common to both the default asset service and FSAsset service ;; Common asset service options @@ -288,7 +301,7 @@ LocalServiceModule = "OpenSim.Services.GridService.dll:GridService" ; Realm = "regions" - ; AllowDuplicateNames = "True" + ; AllowDuplicateNames = "" ;; Perform distance check for the creation of a linked region ; Check4096 = "True" @@ -298,25 +311,25 @@ ;; Directory for map tile images of linked regions ; MapTileDirectory = "./maptiles" - + ;; Next, we can specify properties of regions, including default and fallback regions ;; The syntax is: Region_ = "" ;; or: Region_ = "" ;; where can be DefaultRegion, DefaultHGRegion, FallbackRegion, NoDirectLogin, Persistent, LockedOut, Reservation, NoMove, Authenticate - ;; + ;; ;; DefaultRegion If a local login cannot be placed in the required region (e.g. home region does not exist, avatar is not allowed entry, etc.) ;; then this region becomes the destination. Only the first online default region will be used. If no DefaultHGRegion ;; is specified then this will also be used as the region for hypergrid connections that require it (commonly because they have not specified ;; an explicit region. - ;; + ;; ;; DefaultHGRegion If an avatar connecting via the hypergrid does not specify a region, then they are placed here. Only the first online ;; region will be used. - ;; - ;; FallbackRegion If the DefaultRegion is not available for a local login, then any FallbackRegions are tried instead. These are tried in the + ;; + ;; FallbackRegion If the DefaultRegion is not available for a local login, then any FallbackRegions are tried instead. These are tried in the ;; order specified. This only applies to local logins at this time, not Hypergrid connections. - ;; + ;; ;; NoDirectLogin A hypergrid user cannot directly connect to this region. This does not apply to local logins. - ;; + ;; ;; Persistent When the simulator is shutdown, the region is signalled as offline but left registered on the grid. ;; ;; Example specification: @@ -365,19 +378,19 @@ ;; The following parameters are for STUN = Simple Traversal of UDP through NATs ;; See http://wiki.freeswitch.org/wiki/NAT_Traversal ;; stun.freeswitch.org is not guaranteed to be running so use it in - ;; production at your own risk + ;; production at your own risk ; EchoServer = 127.0.0.1 ; EchoPort = 50505 ; AttemptSTUN = false ; * This is the new style authentication service. Currently, only MySQL -; * is implemented. +; * is implemented. ; * [AuthenticationService] ; for the server connector LocalServiceModule = "OpenSim.Services.AuthenticationService.dll:PasswordAuthenticationService" - ; Realm = "useraccounts" + ; Realm = "auth" ;; Allow the service to process HTTP getauthinfo calls. ;; Default is false. @@ -400,13 +413,13 @@ ; * This is the new style user service. ; * "Realm" is the table that is used for user lookup. -; * It defaults to "useraccounts", which uses the new style. +; * It defaults to "UserAccounts", which uses the new style. ; * Realm = "users" will use the legacy tables as an authentication source ; * [UserAccountService] ; for the server connector LocalServiceModule = "OpenSim.Services.UserAccountService.dll:UserAccountService" - ; Realm = "useraccounts" + ; Realm = "UserAccounts" ; These are for creating new accounts by the service AuthenticationService = "OpenSim.Services.AuthenticationService.dll:PasswordAuthenticationService" @@ -416,7 +429,7 @@ AvatarService = "OpenSim.Services.AvatarService.dll:AvatarService" GridUserService = "OpenSim.Services.UserAccountService.dll:GridUserService" - ;; This switch creates the minimum set of body parts and avatar entries for a viewer 2 + ;; This switch creates the minimum set of body parts and avatar entries for a viewer 2 ;; to show a default "Ruth" avatar rather than a cloud for a newly created user. ;; Default is false CreateDefaultAvatarEntries = true @@ -444,10 +457,6 @@ ; for the server connector LocalServiceModule = "OpenSim.Services.PresenceService.dll:PresenceService" - ; Set this to true to allow the use of advanced web services and multiple - ; bots using one account - AllowDuplicatePresences = false; - [AvatarService] ; for the server connector LocalServiceModule = "OpenSim.Services.AvatarService.dll:AvatarService" @@ -516,7 +525,7 @@ ; If you run this login server behind a proxy, set this to true ; HasProxy = false - + ; Defaults for the users, if none is specified in the useraccounts table entry (ServiceURLs) ;; If you have GatekeeperURI set under [Hypergrid], no need to set it here, leave it commented ; GatekeeperURI = "${Const|BaseURL}:${Const|PublicPort}" @@ -534,8 +543,8 @@ ;; However, they do rely on the server to tell them whether it's Daylight Saving Time or not. ;; Hence, calculating DST based on a different timezone can result in a misleading viewer display and inconsistencies between grids. ;; By default, this setting uses various timezone names to calculate DST with regards to the viewer's standard PST. - ;; Options are - ;; "none" no DST + ;; Options are + ;; "none" no DST ;; "local" use the server's only timezone to calculate DST. This is previous OpenSimulator behaviour. ;; "America/Los_Angeles;Pacific Standard Time" use these timezone names to look up Daylight savings. ;; 'America/Los_Angeles' is used on Linux/Mac systems whilst 'Pacific Standard Time' is used on Windows @@ -556,7 +565,7 @@ ;; ;; The amount of time that a specific endpoint is blocked. Default 2 minutes. ;DOSForgiveClientAfterMS = 120000 - ;; + ;; ;; To turn off basic dos protection, set the DOSMaxRequestsInTimeFrame to 0. @@ -636,10 +645,10 @@ ;; If you have GatekeeperURI set under [Hypergrid], no need to set it here, leave it commented ; ExternalName = "${Const|BaseURL}:${Const|PublicPort}" - ; Does this grid allow incoming links to any region in it? + ; Does this grid allow incoming links to any region in it? ; If false, HG TPs happen only to the Default regions specified in [GridService] section AllowTeleportsToAnyRegion = true - + ; If you run this gatekeeper server behind a proxy, set this to true ; HasProxy = false @@ -701,10 +710,10 @@ ; * The interface that local users get when they are in other grids. ; * This restricts the inventory operations while in other grids. -; * Still not completely safe, especially if users perform inventory operations +; * Still not completely safe, especially if users perform inventory operations ; * while in those grids. The more the user accesses his/her inventory, the more ; * those simulators will know about the user's inventory. -; * +; * [HGInventoryService] ; For the InventoryServiceInConnector LocalServiceModule = "OpenSim.Services.HypergridService.dll:HGSuitcaseInventoryService" @@ -717,7 +726,7 @@ UserAccountsService = "OpenSim.Services.UserAccountService.dll:UserAccountService" AvatarService = "OpenSim.Services.AvatarService.dll:AvatarService" - ; HGInventoryService is a public-facing inventory service that allows users to + ; HGInventoryService is a public-facing inventory service that allows users to ; interact with their suitcase folder when on a foreign grid. This reuses the general inventory service connector. ; Hence, if the user has set up authentication in [Network] to protect their private services ; make sure it is not set here. @@ -730,15 +739,15 @@ ; * The interface that local users get when they are in other grids. ; * This restricts the access that the rest of the world has to ; * the assets of this world. -; * +; * [HGAssetService] ;; Use the second option if you have FSAsset service enabled LocalServiceModule = "OpenSim.Services.HypergridService.dll:HGAssetService" ;LocalServiceModule = "OpenSim.Services.HypergridService.dll:HGFSAssetService" - + UserAccountsService = "OpenSim.Services.UserAccountService.dll:UserAccountService" - ; HGAssetService is a public-facing service that allows users to + ; HGAssetService is a public-facing service that allows users to ; read and create assets when on another grid. This reuses the general asset service connector. ; Hence, if the user has set up authentication in [Network] to protect their private services ; make sure it is overriden for this public service. @@ -750,11 +759,11 @@ ;; The asset types that this grid can export to / import from other grids. ;; Comma separated. ;; Valid values are all the asset types in OpenMetaverse.AssetType, namely: - ;; Unknown, Texture, Sound, CallingCard, Landmark, Clothing, Object, Notecard, LSLText, - ;; LSLBytecode, TextureTGA, Bodypart, SoundWAV, ImageTGA, ImageJPEG, Animation, Gesture, Mesh + ;; Unknown, Texture, Sound, CallingCard, Landmark, Clothing, Object, Notecard, LSLText, + ;; LSLBytecode, TextureTGA, Bodypart, SoundWAV, ImageTGA, ImageJPEG, Animation, Gesture, Mesh ;; ;; Leave blank or commented if you don't want to apply any restrictions. - ;; A more strict, but still reasonable, policy may be to disallow the exchange + ;; A more strict, but still reasonable, policy may be to disallow the exchange ;; of scripts, like so: ; DisallowExport ="LSLText" ; DisallowImport ="LSLBytecode" @@ -811,3 +820,6 @@ LocalServiceModule = "OpenSim.Server.Handlers.dll:XBakes" ;; This directory must be writable by the user ROBUST runs as. It will be created automatically. BaseDirectory = "./bakes" + +[MuteListService] + LocalServiceModule = "OpenSim.Services.MuteListService.dll:MuteListService" diff --git a/bin/Robust.Tests.ini b/bin/Robust.Tests.ini index c25e39b646..bf7263304d 100644 --- a/bin/Robust.Tests.ini +++ b/bin/Robust.Tests.ini @@ -3,7 +3,7 @@ ; The URL of the Robust server BaseURL = "http://127.0.0.1" - + ; The public port of the Robust server PublicPort = "8888" @@ -30,14 +30,14 @@ ; Set path to directory for plugin registry. Information ; about the registered repositories and installed plugins ; will be stored here - ; The Robust.exe process must have R/W access to the location + ; The Robust.exe process must have R/W access to the location RegistryLocation = "." ; Modular configurations ; Set path to directory for modular ini files... - ; The Robust.exe process must have R/W access to the location + ; The Robust.exe process must have R/W access to the location ConfigDirectory = "." - + console = "rest" ; Console commands can be saved to a file, so the command history persists after a restart. (default is true) @@ -49,7 +49,7 @@ ; How many lines of command history should we keep? (default is 100) ConsoleHistoryFileLines = 100 - + [ServiceList] GridServiceConnector = "${Const|PrivatePort}/OpenSim.Server.Handlers.dll:GridServiceConnector" PresenceServiceConnector = "${Const|PrivatePort}/OpenSim.Server.Handlers.dll:PresenceServiceConnector" @@ -92,7 +92,7 @@ ;; This is useful in cases where you want to protect most of the services, ;; but unprotect individual services. Username and Password can also be ;; overriden if you want to use different credentials for the different services. - + ;; By default, scripts are not allowed to call private services via llHttpRequest() ;; Such calls are detected by the X-SecondLife-Shared HTTP header ;; If you allow such calls you must be sure that they are restricted to very trusted scripters @@ -181,7 +181,7 @@ ;; DefaultHGRegion If an avatar connecting via the hypergrid does not specify a region, then they are placed here. Only the first online ;; region will be used. ;; - ;; FallbackRegion If the DefaultRegion is not available for a local login, then any FallbackRegions are tried instead. These are tried in the + ;; FallbackRegion If the DefaultRegion is not available for a local login, then any FallbackRegions are tried instead. These are tried in the ;; order specified. This only applies to local logins at this time, not Hypergrid connections. ;; ;; NoDirectLogin A hypergrid user cannot directly connect to this region. This does not apply to local logins. @@ -200,7 +200,7 @@ ; * This is the new style authentication service. Currently, only MySQL -; * is implemented. +; * is implemented. ; * [AuthenticationService] ; for the server connector @@ -240,7 +240,7 @@ ;AvatarService = "OpenSim.Services.AvatarService.dll:AvatarService" ;GridUserService = "OpenSim.Services.UserAccountService.dll:GridUserService" - ;; This switch creates the minimum set of body parts and avatar entries for a viewer 2 + ;; This switch creates the minimum set of body parts and avatar entries for a viewer 2 ;; to show a default "Ruth" avatar rather than a cloud for a newly created user. ;; Default is false CreateDefaultAvatarEntries = true @@ -360,7 +360,7 @@ ;; Hence, calculating DST based on a different timezone can result in a misleading viewer display and inconsistencies between grids. ;; By default, this setting uses various timezone names to calculate DST with regards to the viewer's standard PST. ;; Options are - ;; "none" no DST + ;; "none" no DST ;; "local" use the server's only timezone to calculate DST. This is previous OpenSimulator behaviour. ;; "America/Los_Angeles;Pacific Standard Time" use these timezone names to look up Daylight savings. ;; 'America/Los_Angeles' is used on Linux/Mac systems whilst 'Pacific Standard Time' is used on Windows @@ -381,7 +381,7 @@ ;; ;; The amount of time that a specific endpoint is blocked. Default 2 minutes. ;DOSForgiveClientAfterMS = 120000 - ;; + ;; ;; To turn off basic dos protection, set the DOSMaxRequestsInTimeFrame to 0. diff --git a/bin/Robust.exe.config b/bin/Robust.exe.config index 7db6458d26..3ad5f31732 100644 --- a/bin/Robust.exe.config +++ b/bin/Robust.exe.config @@ -5,11 +5,10 @@ - - + diff --git a/bin/Robust.ini.example b/bin/Robust.ini.example index d33178c461..3222a94ad1 100644 --- a/bin/Robust.ini.example +++ b/bin/Robust.ini.example @@ -4,20 +4,20 @@ ; ** ; * ; * The Const section allows us to define some basic information that we -; * will use throughout our configuration. We will provide examples for +; * will use throughout our configuration. We will provide examples for ; * setting the base url of the Robust server and the public and private ports ; * it uses. Changing the values of the constants will set the operating ; * parameters thoughout the configuration. Other constants that may prove -; * to be useful may be added to the followin section. They may be +; * to be useful may be added to the followin section. They may be ; * referenced anywhere in the configuration by using ${Const|Name}. One ; * such use is providing a base path for setting locations that Robust ; * uses to write data. -; * +; * [Const] ; The URL of the Robust server BaseURL = "http://127.0.0.1" - + ; The public port of the Robust server PublicPort = "8002" @@ -44,14 +44,14 @@ ; Set path to directory for plugin registry. Information ; about the registered repositories and installed plugins ; will be stored here - ; The Robust.exe process must have R/W access to the location + ; The Robust.exe process must have R/W access to the location RegistryLocation = "." ; Modular configurations ; Set path to directory for modular ini files... - ; The Robust.exe process must have R/W access to the location + ; The Robust.exe process must have R/W access to the location ConfigDirectory = "robust-include" - + ; Console commands can be saved to a file, so the command history persists after a restart. (default is true) ConsoleHistoryFileEnabled = true @@ -61,7 +61,18 @@ ; How many lines of command history should we keep? (default is 100) ConsoleHistoryFileLines = 100 - + + ; Time stamp commands in history file (default false) + ; ConsoleHistoryTimeStamp = false + + ; peers SSL certificate validation options + ; you can allow selfsigned certificates or no official CA with next option set to true + NoVerifyCertChain = true + ; you can also bypass the hostname or domain verification + NoVerifyCertHostname = true + ; having both options true does provide encryption but with low security + ; set both true if you don't care to use SSL, they are needed to contact regions or grids that do use it. + [ServiceList] AssetServiceConnector = "${Const|PrivatePort}/OpenSim.Server.Handlers.dll:AssetServiceConnector" InventoryInConnector = "${Const|PrivatePort}/OpenSim.Server.Handlers.dll:XInventoryInConnector" @@ -93,6 +104,8 @@ ;; Uncomment if you want to have centralized estate data ; EstateDataService = "${Const|PrivatePort}/OpenSim.Server.Handlers.dll:EstateDataRobustConnector" + MuteListConnector = "${Const|PrivatePort}/OpenSim.Server.Handlers.dll:MuteListServiceConnector" + ; * This is common for all services, it's the network setup for the entire ; * server instance, if none is specified above ; * @@ -130,7 +143,7 @@ ;; This is useful in cases where you want to protect most of the services, ;; but unprotect individual services. Username and Password can also be ;; overriden if you want to use different credentials for the different services. - + ;; By default, scripts are not allowed to call private services via llHttpRequest() ;; Such calls are detected by the X-SecondLife-Shared HTTP header ;; If you allow such calls you must be sure that they are restricted to very trusted scripters @@ -191,29 +204,29 @@ ;; Choose an asset service (Only one option should be enabled) LocalServiceModule = "OpenSim.Services.AssetService.dll:AssetService" ;LocalServiceModule = "OpenSim.Services.FSAssetService.dll:FSAssetConnector" - + ;; FSAsset Directories. Base directory, where final asset files are stored and Spool directory for temp files ;; These directories must be on the same physical filesystem ;BaseDirectory = "./fsassets/data" ;SpoolDirectory = "./fsassets/tmp" - + ;; Original service can be checked if FSAssets can not find an asset ;FallbackService = "OpenSim.Services.AssetService.dll:AssetService"; - + ;; How many days since last updating the access time before its updated again by FSAssets when accessing an asset ;; Reduces DB calls if asset is requested often. Default value 0 will always update access time ;DaysBetweenAccessTimeUpdates = 30 - + ;; Should FSAssets print read/write stats to the robust console, default is true ;ShowConsoleStats = true - + ;; FSAssets Custom Database Config (Leave blank to use grids default database configuration) ;StorageProvider = "" ;ConnectionString = "" ;Realm = "fsassets" - + ;; The following are common to both the default asset service and FSAsset service - + ;; Common asset service options DefaultAssetLoader = "OpenSim.Framework.AssetLoader.Filesystem.dll" AssetLoaderArgs = "./assets/AssetSets.xml" @@ -265,7 +278,7 @@ ;; DefaultHGRegion If an avatar connecting via the hypergrid does not specify a region, then they are placed here. Only the first online ;; region will be used. ;; - ;; FallbackRegion If the DefaultRegion is not available for a local login, then any FallbackRegions are tried instead. These are tried in the + ;; FallbackRegion If the DefaultRegion is not available for a local login, then any FallbackRegions are tried instead. These are tried in the ;; order specified. This only applies to local logins at this time, not Hypergrid connections. ;; ;; NoDirectLogin A hypergrid user cannot directly connect to this region. This does not apply to local logins. @@ -312,19 +325,19 @@ ;; The following parameters are for STUN = Simple Traversal of UDP through NATs ;; See http://wiki.freeswitch.org/wiki/NAT_Traversal ;; stun.freeswitch.org is not guaranteed to be running so use it in - ;; production at your own risk + ;; production at your own risk ; EchoServer = 127.0.0.1 ; EchoPort = 50505 ; AttemptSTUN = false ; * This is the new style authentication service. Currently, only MySQL -; * is implemented. +; * is implemented. ; * [AuthenticationService] ; for the server connector LocalServiceModule = "OpenSim.Services.AuthenticationService.dll:PasswordAuthenticationService" - ; Realm = "useraccounts" + ; Realm = "auth" ;; Allow the service to process HTTP getauthinfo calls. ;; Default is false. @@ -353,7 +366,7 @@ [UserAccountService] ; for the server connector LocalServiceModule = "OpenSim.Services.UserAccountService.dll:UserAccountService" - ; Realm = "useraccounts" + ; Realm = "UserAccounts" ; These are for creating new accounts by the service AuthenticationService = "OpenSim.Services.AuthenticationService.dll:PasswordAuthenticationService" @@ -363,7 +376,7 @@ AvatarService = "OpenSim.Services.AvatarService.dll:AvatarService" GridUserService = "OpenSim.Services.UserAccountService.dll:GridUserService" - ;; This switch creates the minimum set of body parts and avatar entries for a viewer 2 + ;; This switch creates the minimum set of body parts and avatar entries for a viewer 2 ;; to show a default "Ruth" avatar rather than a cloud for a newly created user. ;; Default is false CreateDefaultAvatarEntries = true @@ -390,10 +403,6 @@ [PresenceService] ; for the server connector LocalServiceModule = "OpenSim.Services.PresenceService.dll:PresenceService" - ; Set this to true to allow the use of advanced web services and multiple - ; bots using one account - AllowDuplicatePresences = false; - [AvatarService] ; for the server connector @@ -462,7 +471,7 @@ ;; Hence, calculating DST based on a different timezone can result in a misleading viewer display and inconsistencies between grids. ;; By default, this setting uses various timezone names to calculate DST with regards to the viewer's standard PST. ;; Options are - ;; "none" no DST + ;; "none" no DST ;; "local" use the server's only timezone to calculate DST. This is previous OpenSimulator behaviour. ;; "America/Los_Angeles;Pacific Standard Time" use these timezone names to look up Daylight savings. ;; 'America/Los_Angeles' is used on Linux/Mac systems whilst 'Pacific Standard Time' is used on Windows @@ -483,7 +492,7 @@ ;; ;; The amount of time that a specific endpoint is blocked. Default 2 minutes. ;DOSForgiveClientAfterMS = 120000 - ;; + ;; ;; To turn off basic dos protection, set the DOSMaxRequestsInTimeFrame to 0. @@ -565,3 +574,6 @@ LocalServiceModule = "OpenSim.Server.Handlers.dll:XBakes" ;; This directory must be writable by the user ROBUST runs as. It will be created automatically. BaseDirectory = "./bakes" + +[MuteListService] + LocalServiceModule = "OpenSim.Services.MuteListService.dll:MuteListService" diff --git a/bin/Robust32.exe b/bin/Robust32.exe new file mode 100644 index 0000000000..e5e4674337 Binary files /dev/null and b/bin/Robust32.exe differ diff --git a/bin/Robust.32BitLaunch.exe.config b/bin/Robust32.exe.config similarity index 55% rename from bin/Robust.32BitLaunch.exe.config rename to bin/Robust32.exe.config index 0399a1bd34..a27f22a117 100644 --- a/bin/Robust.32BitLaunch.exe.config +++ b/bin/Robust32.exe.config @@ -1,63 +1,69 @@ - +
- - + - - + + - - - - + - - + + - - + - - - + - + + + + + + + + + + + + + \ No newline at end of file diff --git a/bin/Robust32.pdb b/bin/Robust32.pdb new file mode 100644 index 0000000000..15a0d7544e Binary files /dev/null and b/bin/Robust32.pdb differ diff --git a/bin/Robust32.vshost.exe b/bin/Robust32.vshost.exe new file mode 100644 index 0000000000..681ab771eb Binary files /dev/null and b/bin/Robust32.vshost.exe differ diff --git a/bin/OpenSim.32BitLaunch.exe.config b/bin/Robust32.vshost.exe.config similarity index 55% rename from bin/OpenSim.32BitLaunch.exe.config rename to bin/Robust32.vshost.exe.config index 5b7807a8e3..a27f22a117 100644 --- a/bin/OpenSim.32BitLaunch.exe.config +++ b/bin/Robust32.vshost.exe.config @@ -1,75 +1,69 @@ - +
- - + - - + + - - - - - - + - - + + - - + - - - - - - - - - - - - - + - + + + + + + + + + + + + + \ No newline at end of file diff --git a/bin/Tools.dll b/bin/Tools.dll index 08dcf42fde..2c9079c371 100755 Binary files a/bin/Tools.dll and b/bin/Tools.dll differ diff --git a/bin/Warp3D.dll b/bin/Warp3D.dll index 4c5519d364..7d662d92fa 100755 Binary files a/bin/Warp3D.dll and b/bin/Warp3D.dll differ diff --git a/bin/XMLRPC.dll b/bin/XMLRPC.dll index 1559a73146..8d135093c2 100755 Binary files a/bin/XMLRPC.dll and b/bin/XMLRPC.dll differ diff --git a/bin/assets/TexturesAssetSet/TexturesAssetSet.xml b/bin/assets/TexturesAssetSet/TexturesAssetSet.xml index f7e4367a18..6994822013 100644 --- a/bin/assets/TexturesAssetSet/TexturesAssetSet.xml +++ b/bin/assets/TexturesAssetSet/TexturesAssetSet.xml @@ -763,5 +763,12 @@
+ +
+ + + + +
diff --git a/bin/assets/TexturesAssetSet/b4ba225c-373f-446d-9f7e-6cb7b5cf9b3d.j2c b/bin/assets/TexturesAssetSet/b4ba225c-373f-446d-9f7e-6cb7b5cf9b3d.j2c new file mode 100644 index 0000000000..0e5279f5d2 Binary files /dev/null and b/bin/assets/TexturesAssetSet/b4ba225c-373f-446d-9f7e-6cb7b5cf9b3d.j2c differ diff --git a/bin/config-include/Grid.ini b/bin/config-include/Grid.ini index fc988792b4..ab8f25d72e 100644 --- a/bin/config-include/Grid.ini +++ b/bin/config-include/Grid.ini @@ -12,7 +12,7 @@ InventoryServices = "RemoteXInventoryServicesConnector" GridServices = "RemoteGridServicesConnector" AvatarServices = "RemoteAvatarServicesConnector" - NeighbourServices = "RemoteNeighbourServicesConnector" + NeighbourServices = "NeighbourServicesOutConnector" AuthenticationServices = "RemoteAuthenticationServicesConnector" AuthorizationServices = "LocalAuthorizationServicesConnector" PresenceServices = "RemotePresenceServicesConnector" @@ -25,7 +25,8 @@ LandServices = "RemoteLandServicesConnector" MapImageService = "MapImageServiceModule" SearchModule = "BasicSearchModule" - + MuteListService = "RemoteMuteListServicesConnector" + LandServiceInConnector = true NeighbourServiceInConnector = true SimulationServiceInConnector = true @@ -46,7 +47,7 @@ ; Because LocalGridServicesConnector starts this service, in grid mode we need to suppress ; the inappropriate console commands that it registers. SuppressConsoleCommands = true - + [LibraryService] LocalServiceModule = "OpenSim.Services.InventoryService.dll:LibraryService" LibraryName = "OpenSim Library" diff --git a/bin/config-include/GridCommon.ini.example b/bin/config-include/GridCommon.ini.example index 10a5b474d9..e93ce3c7f3 100644 --- a/bin/config-include/GridCommon.ini.example +++ b/bin/config-include/GridCommon.ini.example @@ -105,7 +105,7 @@ ; === HG ONLY === ;; Change this to the address of your Gatekeeper service - ;; (usually bundled with the rest of the services in one + ;; (usually bundled with the rest of the services in one ;; Robust server in port ${Const|PublicPort}, but not always) Gatekeeper="${Const|BaseURL}:${Const|PublicPort}" @@ -122,7 +122,7 @@ [Messaging] ; === HG ONLY === ;; Change this to the address of your Gatekeeper service - ;; (usually bundled with the rest of the services in one + ;; (usually bundled with the rest of the services in one ;; Robust server in port ${Const|PublicPort}, but not always) Gatekeeper = "${Const|BaseURL}:${Const|PublicPort}" @@ -171,7 +171,7 @@ [HGInventoryAccessModule] ; ; === HG ONLY === - ; Change this to your server + ; Change this to your server ; accessible from other grids ; HomeURI = "${Const|BaseURL}:${Const|PublicPort}" @@ -187,7 +187,7 @@ ;; Warning: advanced and unusual. Default is false. ;; Enables configurations where grids share user services, including inventory, - ;; while separating regions' assets from users' assets. Asset transfer between + ;; while separating regions' assets from users' assets. Asset transfer between ;; the users' asset server and the regions' asset server is done in HG-like manner. ; CheckSeparateAssets = false ; RegionHGAssetServerURI = ${Const|BaseURL}:${Const|PublicPort} @@ -196,7 +196,7 @@ [HGAssetService] ; ; === HG ONLY === - ; Change this to your server + ; Change this to your server ; accessible from other grids ; HomeURI = "${Const|BaseURL}:${Const|PublicPort}" @@ -204,11 +204,11 @@ ;; The asset types that this grid can export to / import from other grids. ;; Comma separated. ;; Valid values are all the asset types in OpenMetaverse.AssetType, namely: - ;; Unknown, Texture, Sound, CallingCard, Landmark, Clothing, Object, Notecard, LSLText, - ;; LSLBytecode, TextureTGA, Bodypart, SoundWAV, ImageTGA, ImageJPEG, Animation, Gesture, Mesh + ;; Unknown, Texture, Sound, CallingCard, Landmark, Clothing, Object, Notecard, LSLText, + ;; LSLBytecode, TextureTGA, Bodypart, SoundWAV, ImageTGA, ImageJPEG, Animation, Gesture, Mesh ;; ;; Leave blank or commented if you don't want to apply any restrictions. - ;; A more strict, but still reasonable, policy may be to disallow the exchange + ;; A more strict, but still reasonable, policy may be to disallow the exchange ;; of scripts, like so: ; DisallowExport ="LSLText" ; DisallowImport ="LSLBytecode" @@ -244,3 +244,6 @@ ;; Capability assigned by the grid administrator for the simulator ;; SimulatorCapability = "00000000-0000-0000-0000-000000000000" + +[MuteListService] + MuteListServerURI = "${Const|BaseURL}:${Const|PrivatePort}" diff --git a/bin/config-include/GridHypergrid.ini b/bin/config-include/GridHypergrid.ini index f5f4c8755f..78bcd73c88 100644 --- a/bin/config-include/GridHypergrid.ini +++ b/bin/config-include/GridHypergrid.ini @@ -15,7 +15,7 @@ InventoryServices = "HGInventoryBroker" GridServices = "RemoteGridServicesConnector" AvatarServices = "RemoteAvatarServicesConnector" - NeighbourServices = "RemoteNeighbourServicesConnector" + NeighbourServices = "NeighbourServicesOutConnector" AuthenticationServices = "RemoteAuthenticationServicesConnector" AuthorizationServices = "LocalAuthorizationServicesConnector" PresenceServices = "RemotePresenceServicesConnector" @@ -30,15 +30,13 @@ MapImageService = "MapImageServiceModule" UserManagementModule = "HGUserManagementModule" SearchModule = "BasicSearchModule" - + MuteListService = "RemoteMuteListServicesConnector" + LandServiceInConnector = true NeighbourServiceInConnector = true SimulationServiceInConnector = true LibraryModule = true -[Profile] - Module = "BasicProfileModule" - [SimulationDataStore] LocalServiceModule = "OpenSim.Services.SimulationService.dll:SimulationDataService" diff --git a/bin/config-include/HyperSimianGrid.ini b/bin/config-include/HyperSimianGrid.ini index efad5772a3..24f9813c6b 100644 --- a/bin/config-include/HyperSimianGrid.ini +++ b/bin/config-include/HyperSimianGrid.ini @@ -5,7 +5,7 @@ ;; ;; -;; In GridCommon.ini, these are the URLs you would use if SimianGrid is +;; In GridCommon.ini, these are the URLs you would use if SimianGrid is ;; installed at http://www.mygrid.com/Grid/ ;; ; AssetServerURI = "http://www.mygrid.com/Grid/?id=" @@ -28,17 +28,17 @@ AssetServices = "HGAssetBroker" InventoryServices = "HGInventoryBroker" AvatarServices = "SimianAvatarServiceConnector" - - NeighbourServices = "RemoteNeighbourServicesConnector" + + NeighbourServices = "NeighbourServicesOutConnector" SimulationServices = "RemoteSimulationConnectorModule" EntityTransferModule = "HGEntityTransferModule" InventoryAccessModule = "HGInventoryAccessModule" - + LandServiceInConnector = true NeighbourServiceInConnector = true SimulationServiceInConnector = true LibraryModule = false - + AssetCaching = "FlotsamAssetCache" [SimulationDataStore] @@ -87,7 +87,7 @@ [HGInventoryAccessModule] ; ; === HG ONLY === - ; Change this to your profile server + ; Change this to your profile server ; accessible from other grids ; ProfileServerURI = "http://mygridserver.com:8002/user" diff --git a/bin/config-include/SimianGrid.ini b/bin/config-include/SimianGrid.ini index 5749656231..fdf7ca23f4 100644 --- a/bin/config-include/SimianGrid.ini +++ b/bin/config-include/SimianGrid.ini @@ -5,7 +5,7 @@ ;; ;; -;; In GridCommon.ini, these are the URLs you would use if SimianGrid is +;; In GridCommon.ini, these are the URLs you would use if SimianGrid is ;; installed at http://www.mygrid.com/Grid/ ;; ; AssetServerURI = "http://www.mygrid.com/Grid/?id=" @@ -28,17 +28,17 @@ AssetServices = "SimianAssetServiceConnector" InventoryServices = "SimianInventoryServiceConnector" AvatarServices = "SimianAvatarServiceConnector" - - NeighbourServices = "RemoteNeighbourServicesConnector" + + NeighbourServices = "NeighbourServicesOutConnector" SimulationServices = "RemoteSimulationConnectorModule" EntityTransferModule = "BasicEntityTransferModule" InventoryAccessModule = "BasicInventoryAccessModule" - + LandServiceInConnector = true NeighbourServiceInConnector = true SimulationServiceInConnector = true LibraryModule = false - + AssetCaching = "FlotsamAssetCache" [SimulationDataStore] diff --git a/bin/config-include/Standalone.ini b/bin/config-include/Standalone.ini index 78ada2b7c3..127b073f0c 100644 --- a/bin/config-include/Standalone.ini +++ b/bin/config-include/Standalone.ini @@ -7,7 +7,7 @@ [Modules] AssetServices = "LocalAssetServicesConnector" InventoryServices = "LocalInventoryServicesConnector" - NeighbourServices = "LocalNeighbourServicesConnector" + NeighbourServices = "NeighbourServicesOutConnector" AuthenticationServices = "LocalAuthenticationServicesConnector" AuthorizationServices = "LocalAuthorizationServicesConnector" GridServices = "LocalGridServicesConnector" @@ -22,6 +22,7 @@ InventoryAccessModule = "BasicInventoryAccessModule" MapImageService = "MapImageServiceModule" SearchModule = "BasicSearchModule" + MuteListService = "LocalMuteListServicesConnector" LibraryModule = true LLLoginServiceInConnector = true @@ -103,8 +104,8 @@ ;; However, they do rely on the server to tell them whether it's Daylight Saving Time or not. ;; Hence, calculating DST based on a different timezone can result in a misleading viewer display and inconsistencies between grids. ;; By default, this setting uses various timezone names to calculate DST with regards to the viewer's standard PST. - ;; Options are - ;; "none" no DST + ;; Options are + ;; "none" no DST ;; "local" use the server's only timezone to calculate DST. This is previous OpenSimulator behaviour. ;; "America/Los_Angeles;Pacific Standard Time" use these timezone names to look up Daylight savings. ;; 'America/Los_Angeles' is used on Linux/Mac systems whilst 'Pacific Standard Time' is used on Windows @@ -113,6 +114,9 @@ [MapImageService] LocalServiceModule = "OpenSim.Services.MapImageService.dll:MapImageService" +[MuteListService] + LocalServiceModule = "OpenSim.Services.MuteListService.dll:MuteListService" + ;; This should always be the very last thing on this file [Includes] Include-Common = "config-include/StandaloneCommon.ini" diff --git a/bin/config-include/StandaloneCommon.ini.example b/bin/config-include/StandaloneCommon.ini.example index d0b152c6b6..89315572b9 100644 --- a/bin/config-include/StandaloneCommon.ini.example +++ b/bin/config-include/StandaloneCommon.ini.example @@ -85,20 +85,20 @@ ;; Next, we can specify properties of regions, including default and fallback regions ;; The syntax is: Region_ = "" ;; where can be DefaultRegion, FallbackRegion, NoDirectLogin, Persistent, LockedOut - ;; + ;; ;; DefaultRegion If a local login cannot be placed in the required region (e.g. home region does not exist, avatar is not allowed entry, etc.) ;; then this region becomes the destination. Only the first online default region will be used. If no DefaultHGRegion ;; is specified then this will also be used as the region for hypergrid connections that require it (commonly because they have not specified ;; an explicit region. - ;; + ;; ;; DefaultHGRegion If an avatar connecting via the hypergrid does not specify a region, then they are placed here. Only the first online ;; region will be used. - ;; - ;; FallbackRegion If the DefaultRegion is not available for a local login, then any FallbackRegions are tried instead. These are tried in the + ;; + ;; FallbackRegion If the DefaultRegion is not available for a local login, then any FallbackRegions are tried instead. These are tried in the ;; order specified. This only applies to local logins at this time, not Hypergrid connections. - ;; + ;; ;; NoDirectLogin A hypergrid user cannot directly connect to this region. This does not apply to local logins. - ;; + ;; ;; Persistent When the simulator is shutdown, the region is signalled as offline but left registered on the grid. ;; ;; For example: @@ -121,7 +121,7 @@ ;; If you have Gatekeeper set under [Hypergrid], no need to set it here, leave it commented ; GatekeeperURI = "${Const|BaseURL}:${Const|PublicPort}" - SRV_HomeURI = "${Const|BaseURL}:${Const|PublicPort}" + SRV_HomeURI = "${Const|BaseURL}:${Const|PublicPort}" SRV_InventoryServerURI = "${Const|BaseURL}:${Const|PublicPort}" SRV_AssetServerURI = "${Const|BaseURL}:${Const|PublicPort}" SRV_ProfileServerURI = "${Const|BaseURL}:${Const|PublicPort}" @@ -163,7 +163,7 @@ ; ; ; ; The amount of time that a specific endpoint is blocked. Default 2 minutes. ; DOSForgiveClientAfterMS = 120000 - ; ; + ; ; ; ; To turn off basic dos protection, set the DOSMaxRequestsInTimeFrame to 0. [FreeswitchService] @@ -197,7 +197,7 @@ ;; The following parameters are for STUN = Simple Traversal of UDP through NATs ;; See http://wiki.freeswitch.org/wiki/NAT_Traversal ;; stun.freeswitch.org is not guaranteed to be running so use it in - ;; production at your own risk + ;; production at your own risk ; EchoServer = 127.0.0.1 ; EchoPort = 50505 ; AttemptSTUN = false @@ -341,11 +341,11 @@ ;; The asset types that this grid can export to / import from other grids. ;; Comma separated. ;; Valid values are all the asset types in OpenMetaverse.AssetType, namely: - ;; Unknown, Texture, Sound, CallingCard, Landmark, Clothing, Object, Notecard, LSLText, - ;; LSLBytecode, TextureTGA, Bodypart, SoundWAV, ImageTGA, ImageJPEG, Animation, Gesture, Mesh + ;; Unknown, Texture, Sound, CallingCard, Landmark, Clothing, Object, Notecard, LSLText, + ;; LSLBytecode, TextureTGA, Bodypart, SoundWAV, ImageTGA, ImageJPEG, Animation, Gesture, Mesh ;; ;; Leave blank or commented if you don't want to apply any restrictions. - ;; A more strict, but still reasonable, policy may be to disallow the exchange + ;; A more strict, but still reasonable, policy may be to disallow the exchange ;; of scripts, like so: ; DisallowExport ="LSLText" ; DisallowImport ="LSLBytecode" diff --git a/bin/config-include/StandaloneHypergrid.ini b/bin/config-include/StandaloneHypergrid.ini index eaacfff36a..e305972af7 100644 --- a/bin/config-include/StandaloneHypergrid.ini +++ b/bin/config-include/StandaloneHypergrid.ini @@ -10,7 +10,7 @@ [Modules] AssetServices = "HGAssetBroker" InventoryServices = "HGInventoryBroker" - NeighbourServices = "LocalNeighbourServicesConnector" + NeighbourServices = "NeighbourServicesOutConnector" AuthenticationServices = "LocalAuthenticationServicesConnector" AuthorizationServices = "LocalAuthorizationServicesConnector" GridServices = "LocalGridServicesConnector" @@ -27,7 +27,8 @@ FriendsModule = "HGFriendsModule" UserManagementModule = "HGUserManagementModule" SearchModule = "BasicSearchModule" - + MuteListService = "LocalMuteListServicesConnector" + InventoryServiceInConnector = true AssetServiceInConnector = true HypergridServiceInConnector = true @@ -79,7 +80,7 @@ ; Needed to display non-default map tile images for remote regions AssetService = "OpenSim.Services.AssetService.dll:AssetService" - + HypergridLinker = true AllowHypergridMapSearch = true @@ -123,7 +124,7 @@ GridService = "OpenSim.Services.GridService.dll:GridService" AvatarService = "OpenSim.Services.AvatarService.dll:AvatarService" FriendsService = "OpenSim.Services.FriendsService.dll:FriendsService" - + ; This inventory service will be used to initialize the user's inventory HGInventoryServicePlugin = "OpenSim.Services.HypergridService.dll:HGSuitcaseInventoryService" HGInventoryServiceConstructorArg = "HGInventoryService" @@ -190,6 +191,9 @@ UserAgentService = "OpenSim.Services.HypergridService.dll:UserAgentService" InGatekeeper = True +[MuteListService] + LocalServiceModule = "OpenSim.Services.MuteListService.dll:MuteListService" + ;; This should always be the very last thing on this file [Includes] Include-Common = "config-include/StandaloneCommon.ini" diff --git a/bin/config-include/osslEnable.ini b/bin/config-include/osslEnable.ini index 45eddf748e..4726502fdc 100644 --- a/bin/config-include/osslEnable.ini +++ b/bin/config-include/osslEnable.ini @@ -1,6 +1,6 @@ ; Enable OSSL functions. ; Including this file in a region's set of INI files, causes the OpenSimulator -; specific functions to be enabled. +; specific functions to be enabled. ; See http://opensimulator.org/wiki/OSSL for a description of OSSL functions and ; refer to http://opensimulator.org/wiki/OSSL_Implemented for a list of functions. @@ -9,7 +9,7 @@ ; mis-used so the permission to execute a function can be limited. Ability to ; execute a function is based on the owner of the prim holding the script. -[XEngine] +[OSSL] ; Allow the use of os* functions (some are dangerous) AllowOSFunctions = true @@ -31,7 +31,7 @@ ; higher threat level OSSL functions, as detailed later on. OSFunctionThreatLevel = VeryLow - ; Each of the OSSL functions can be enabled or disabled individually. + ; Some of the OSSL functions can be enabled or disabled individually. ; To disable, set the value to 'false'. ; To enable for everyone, set the value to 'true'. ; To enable for individuals or groups, set it to a comma separated list. This checks @@ -45,12 +45,10 @@ ; "PARCEL_OWNER" -- enable for parcel owner ; "PARCEL_GROUP_MEMBER" -- enable for any member of the parcel group ; uuid -- enable for specified ID (may be avatar or group ID) + ; from this we can also create macros that can be include in the list as + ; ${OSSL|macroname} see examples below - ; The OSSL function name is prepended with "Allow_" and it checks against - ; the owners of the containing prim. There can also be entries beginning with - ; 'Creators_". The 'Creators_" parameters can only be a list of UUIDs and it is - ; checked against the creator of the script itself. - + ; parcel macros ; Allowing ossl functions for anyone owning a parcel can be dangerous especially if ; a region is selling or otherwise giving away parcel ownership. By default, parcel ; ownership or group membership does not enable OSSL functions. Uncomment the @@ -62,155 +60,138 @@ ; osslParcelO = "PARCEL_OWNER," ; osslParcelOG = "PARCEL_GROUP_MEMBER,PARCEL_OWNER," - ; There are a block of functions for creating and controlling NPCs. + ; NPC macros ; These can be mis-used so limit use to those you can trust. - osslNPC = ${XEngine|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER - + osslNPC = ${OSSL|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER + + ; The OSSL function name is prepended with "Allow_" and it checks against + ; the owners of the containing prim. There can also be entries beginning with + ; 'Creators_". The 'Creators_" parameters can only be a list of UUIDs and it is + ; checked against the creator of the script itself. + +; ************************************************* + ; ThreatLevel None - Allow_osDrawEllipse = true - Allow_osDrawFilledPolygon = true - Allow_osDrawFilledRectangle = true - Allow_osDrawImage = true - Allow_osDrawLine = true - Allow_osDrawPolygon = true - Allow_osDrawRectangle = true - Allow_osDrawText = true - Allow_osGetAgents = ${XEngine|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER - Allow_osGetAvatarList = ${XEngine|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER - Allow_osGetCurrentSunHour = true + Allow_osGetAgents = ${OSSL|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER + Allow_osGetAvatarList = ${OSSL|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER Allow_osGetGender = true Allow_osGetHealth = true Allow_osGetHealRate = true - Allow_osGetInventoryDesc = true - Allow_osGetMapTexture = true - Allow_osGetRegionSize = true + Allow_osGetNPCList = ${OSSL|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER Allow_osGetRezzingObject = true - Allow_osGetSunParam = true - Allow_osGetTerrainHeight = true - Allow_osIsNpc = true - Allow_osIsUUID = true - Allow_osList2Double = true - Allow_osMax = true - Allow_osMin = true - Allow_osMovePen = true - Allow_osNpcGetOwner = ${XEngine|osslNPC} + Allow_osNpcGetOwner = ${OSSL|osslNPC} Allow_osParseJSON = true Allow_osParseJSONNew = true - Allow_osSetFontName = true - Allow_osSetFontSize = true - Allow_osSetPenCap = true - Allow_osSetPenColor = true - Allow_osSetPenSize = true - Allow_osSetSunParam = ${XEngine|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER - Allow_osTeleportOwner = ${XEngine|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER + Allow_osSetSunParam = ${OSSL|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER + Allow_osTeleportOwner = ${OSSL|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER Allow_osWindActiveModelPluginName = true - Allow_osCheckODE = true ; Here for completeness. This function cannot be turned off - + ; ThreatLevel Nuisance Allow_osSetEstateSunSettings = ESTATE_MANAGER,ESTATE_OWNER Allow_osSetRegionSunSettings = ESTATE_MANAGER,ESTATE_OWNER - + ; ThreatLevel VeryLow - Allow_osEjectFromGroup = ${XEngine|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER - Allow_osForceBreakAllLinks = ${XEngine|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER - Allow_osForceBreakLink = ${XEngine|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER - Allow_osGetDrawStringSize = true + Allow_osEjectFromGroup = ${OSSL|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER + Allow_osForceBreakAllLinks = ${OSSL|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER + Allow_osForceBreakLink = ${OSSL|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER Allow_osGetWindParam = true - Allow_osInviteToGroup = ${XEngine|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER + Allow_osInviteToGroup = ${OSSL|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER Allow_osReplaceString = true - Allow_osSetDynamicTextureData = ${XEngine|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER - Allow_osSetDynamicTextureDataBlend = ${XEngine|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER - Allow_osSetDynamicTextureDataBlendFace = ${XEngine|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER - Allow_osSetDynamicTextureURL = ${XEngine|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER - Allow_osSetDynamicTextureURLBlend = ${XEngine|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER - Allow_osSetDynamicTextureURLBlendFace = ${XEngine|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER - Allow_osSetParcelMediaURL = ${XEngine|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER - Allow_osSetParcelSIPAddress = ${XEngine|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER + Allow_osSetDynamicTextureData = ${OSSL|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER + Allow_osSetDynamicTextureDataFace = ${OSSL|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER + Allow_osSetDynamicTextureDataBlend = ${OSSL|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER + Allow_osSetDynamicTextureDataBlendFace = ${OSSL|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER + Allow_osSetDynamicTextureURL = ${OSSL|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER + Allow_osSetDynamicTextureURLBlend = ${OSSL|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER + Allow_osSetDynamicTextureURLBlendFace = ${OSSL|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER + Allow_osSetParcelMediaURL = ${OSSL|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER + Allow_osSetParcelSIPAddress = ${OSSL|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER Allow_osSetPrimFloatOnWater = true - Allow_osSetWindParam = ${XEngine|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER + Allow_osSetWindParam = ${OSSL|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER Allow_osTerrainFlush = ESTATE_MANAGER,ESTATE_OWNER Allow_osUnixTimeToTimestamp = true - + ; ThreatLevel Low - Allow_osAvatarName2Key = ${XEngine|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER + Allow_osAvatarName2Key = ${OSSL|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER Allow_osFormatString = true - Allow_osKey2Name = ${XEngine|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER + Allow_osKey2Name = ${OSSL|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER Allow_osListenRegex = true - Allow_osLoadedCreationDate = ${XEngine|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER - Allow_osLoadedCreationID = ${XEngine|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER - Allow_osLoadedCreationTime = ${XEngine|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER - Allow_osMessageObject = ${XEngine|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER + Allow_osLoadedCreationDate = ${OSSL|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER + Allow_osLoadedCreationID = ${OSSL|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER + Allow_osLoadedCreationTime = ${OSSL|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER + Allow_osMessageObject = ${OSSL|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER Allow_osRegexIsMatch = true - Allow_osGetAvatarHomeURI = ${XEngine|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER - Allow_osNpcSetProfileAbout = ${XEngine|osslNPC} - Allow_osNpcSetProfileImage = ${XEngine|osslNPC} - Allow_osDie = ${XEngine|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER - + Allow_osGetAvatarHomeURI = ${OSSL|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER + Allow_osNpcSetProfileAbout = ${OSSL|osslNPC} + Allow_osNpcSetProfileImage = ${OSSL|osslNPC} + Allow_osDie = ${OSSL|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER + ; ThreatLevel Moderate - Allow_osDropAttachment = ${XEngine|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER - Allow_osDropAttachmentAt = ${XEngine|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER - Allow_osGetGridCustom = ${XEngine|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER - Allow_osGetGridGatekeeperURI = ${XEngine|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER - Allow_osGetGridHomeURI = ${XEngine|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER - Allow_osGetGridLoginURI = ${XEngine|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER + Allow_osDropAttachment = ${OSSL|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER + Allow_osDropAttachmentAt = ${OSSL|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER + Allow_osGetGridCustom = ${OSSL|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER + Allow_osGetGridGatekeeperURI = ${OSSL|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER + Allow_osGetGridHomeURI = ${OSSL|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER + Allow_osGetGridLoginURI = ${OSSL|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER Allow_osGetGridName = true Allow_osGetGridNick = true - Allow_osGetNumberOfAttachments = ${XEngine|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER - Allow_osGetRegionStats = ${XEngine|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER - Allow_osGetSimulatorMemory = ${XEngine|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER - Allow_osMessageAttachments = ${XEngine|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER - Allow_osSetSpeed = ${XEngine|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER - + Allow_osGetNumberOfAttachments = ${OSSL|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER + Allow_osGetRegionStats = ${OSSL|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER + Allow_osGetSimulatorMemory = ${OSSL|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER + Allow_osGetSimulatorMemoryKB = ${OSSL|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER + Allow_osMessageAttachments = ${OSSL|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER + Allow_osSetSpeed = ${OSSL|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER + ; ThreatLevel High - Allow_osCauseDamage = ${XEngine|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER - Allow_osCauseHealing = ${XEngine|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER - Allow_osSetHealth = ${XEngine|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER - Allow_osSetHealRate = ${XEngine|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER - Allow_osForceAttachToAvatar = ${XEngine|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER - Allow_osForceAttachToAvatarFromInventory = ${XEngine|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER - Allow_osForceCreateLink = ${XEngine|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER - Allow_osForceDropAttachment = ${XEngine|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER - Allow_osForceDropAttachmentAt = ${XEngine|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER - Allow_osGetAgentIP = ${XEngine|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER - Allow_osGetLinkPrimitiveParams = ${XEngine|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER + Allow_osCauseDamage = ${OSSL|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER + Allow_osCauseHealing = ${OSSL|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER + Allow_osSetHealth = ${OSSL|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER + Allow_osSetHealRate = ${OSSL|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER + Allow_osForceAttachToAvatar = ${OSSL|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER + Allow_osForceAttachToAvatarFromInventory = ${OSSL|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER + Allow_osForceCreateLink = ${OSSL|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER + Allow_osForceDropAttachment = ${OSSL|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER + Allow_osForceDropAttachmentAt = ${OSSL|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER + Allow_osGetLinkPrimitiveParams = ${OSSL|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER Allow_osGetPhysicsEngineType = true - Allow_osGetPrimitiveParams = ${XEngine|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER - Allow_osGetRegionMapTexture = ${XEngine|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER + Allow_osGetPrimitiveParams = ${OSSL|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER + Allow_osGetRegionMapTexture = ${OSSL|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER Allow_osGetScriptEngineName = true Allow_osGetSimulatorVersion = true - Allow_osMakeNotecard = ${XEngine|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER + Allow_osMakeNotecard = ${OSSL|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER Allow_osMatchString = true - Allow_osNpcCreate = ${XEngine|osslNPC} - Allow_osNpcGetPos = ${XEngine|osslNPC} - Allow_osNpcGetRot = ${XEngine|osslNPC} - Allow_osNpcLoadAppearance = ${XEngine|osslNPC} - Allow_osNpcMoveTo = ${XEngine|osslNPC} - Allow_osNpcMoveToTarget = ${XEngine|osslNPC} - Allow_osNpcPlayAnimation = ${XEngine|osslNPC} - Allow_osNpcRemove = ${XEngine|osslNPC} - Allow_osNpcSaveAppearance = ${XEngine|osslNPC} - Allow_osNpcSay = ${XEngine|osslNPC} - Allow_osNpcSetRot = ${XEngine|osslNPC} - Allow_osNpcShout = ${XEngine|osslNPC} - Allow_osNpcSit = ${XEngine|osslNPC} - Allow_osNpcStand = ${XEngine|osslNPC} - Allow_osNpcStopAnimation = ${XEngine|osslNPC} - Allow_osNpcStopMoveToTarget = ${XEngine|osslNPC} - Allow_osNpcTouch = ${XEngine|osslNPC} - Allow_osNpcWhisper = ${XEngine|osslNPC} - Allow_osOwnerSaveAppearance = ${XEngine|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER + Allow_osNpcCreate = ${OSSL|osslNPC} + Allow_osNpcGetPos = ${OSSL|osslNPC} + Allow_osNpcGetRot = ${OSSL|osslNPC} + Allow_osNpcLoadAppearance = ${OSSL|osslNPC} + Allow_osNpcMoveTo = ${OSSL|osslNPC} + Allow_osNpcMoveToTarget = ${OSSL|osslNPC} + Allow_osNpcPlayAnimation = ${OSSL|osslNPC} + Allow_osNpcRemove = ${OSSL|osslNPC} + Allow_osNpcSaveAppearance = ${OSSL|osslNPC} + Allow_osNpcSay = ${OSSL|osslNPC} + Allow_osNpcSetRot = ${OSSL|osslNPC} + Allow_osNpcShout = ${OSSL|osslNPC} + Allow_osNpcSit = ${OSSL|osslNPC} + Allow_osNpcStand = ${OSSL|osslNPC} + Allow_osNpcStopAnimation = ${OSSL|osslNPC} + Allow_osNpcStopMoveToTarget = ${OSSL|osslNPC} + Allow_osNpcTouch = ${OSSL|osslNPC} + Allow_osNpcWhisper = ${OSSL|osslNPC} + Allow_osOwnerSaveAppearance = ${OSSL|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER Allow_osParcelJoin = ESTATE_MANAGER,ESTATE_OWNER Allow_osParcelSubdivide = ESTATE_MANAGER,ESTATE_OWNER Allow_osRegionRestart = ESTATE_MANAGER,ESTATE_OWNER - Allow_osSetContentType = ${XEngine|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER + Allow_osRegionNotice = ESTATE_MANAGER,ESTATE_OWNER + Allow_osSetContentType = ${OSSL|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER Allow_osSetPrimitiveParams = false - Allow_osSetProjectionParams = ${XEngine|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER + Allow_osSetProjectionParams = ${OSSL|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER Allow_osSetRegionWaterHeight = ESTATE_MANAGER,ESTATE_OWNER Allow_osSetStateEvents = false ; deprecated Allow_osSetTerrainHeight = ESTATE_MANAGER,ESTATE_OWNER Allow_osSetTerrainTexture = ESTATE_MANAGER,ESTATE_OWNER Allow_osSetTerrainTextureHeight = ESTATE_MANAGER,ESTATE_OWNER - + ; ThreatLevel VeryHigh Allow_osAgentSaveAppearance = ESTATE_MANAGER,ESTATE_OWNER ; Warning: The next function allows scripts to force animations on avatars without the user giving permission. @@ -223,17 +204,79 @@ Allow_osForceDetachFromAvatar = false Allow_osForceOtherSit = false ; The notecard functions can cause a lot of load on the region if over used - Allow_osGetNotecard = ${XEngine|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER - Allow_osGetNotecardLine = ${XEngine|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER - Allow_osGetNumberOfNotecardLines = ${XEngine|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER - Allow_osRegionNotice = ESTATE_MANAGER,ESTATE_OWNER + Allow_osGetNotecard = ${OSSL|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER + Allow_osGetNotecardLine = ${OSSL|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER + Allow_osGetNumberOfNotecardLines = ${OSSL|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER Allow_osSetRot = false - Allow_osSetParcelDetails = ${XEngine|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER - + Allow_osSetParcelDetails = ${OSSL|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER + ; ThreatLevel Severe Allow_osConsoleCommand = false Allow_osGrantScriptPermissions = false - Allow_osKickAvatar = ${XEngine|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER + Allow_osKickAvatar = ${OSSL|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER Allow_osRevokeScriptPermissions = false - Allow_osTeleportAgent = ${XEngine|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER - + Allow_osTeleportAgent = ${OSSL|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER + Allow_osTeleportObject = ${OSSL|osslParcelO}ESTATE_MANAGER,ESTATE_OWNER + + ; ThreatLevel Severe with additional internal restrictions + Allow_osGetAgentIP = true ; always restricted to Administrators (true or false to disable) + + +; available functions out of Threat level control (for reference only) +; Allow_osAdjustSoundVolume = true +; Allow_osAngleBetween = true +; Allow_osCheckODE = true +; Allow_osClearInertia = true +; Allow_osCollisionSound = true +; Allow_osDrawEllipse = true +; Allow_osDrawFilledEllipse = true +; Allow_osDrawFilledPolygon = true +; Allow_osDrawFilledRectangle = true +; Allow_osDrawImage = true +; Allow_osDrawLine = true +; Allow_osDrawPolygon = true +; Allow_osDrawRectangle = true +; Allow_osDrawResetTransform = true +; Allow_osDrawRotationTransform = true +; Allow_osDrawScaleTransform = true +; Allow_osDrawText = true +; Allow_osDrawTranslationTransform = true +; Allow_osGetCurrentSunHour = true +; Allow_osGetInertiaData = true +; Allow_osGetInventoryDesc = true +; Allow_osGetLinkNumber = true +; Allow_osGetMapTexture = true +; Allow_osGetPhysicsEngineName = true +; Allow_osGetRegionSize = true +; Allow_osGetSunParam = true +; Allow_osGetTerrainHeight = true +; Allow_osGetDrawStringSize = true +; Allow_osIsNpc = true +; Allow_osIsUUID = true +; Allow_osList2Double = true +; Allow_osLoopSound = true +; Allow_osLoopSoundMaster = true +; Allow_osLoopSoundSlave = true +; Allow_osMax = true +; Allow_osMin = true +; Allow_osMovePen = true +; Allow_osPlaySound = true +; Allow_osPlaySoundSlave = true +; Allow_osPreloadSound = true +; Allow_osRound = true +; Allow_osSetFontName = true +; Allow_osSetFontSize = true +; Allow_osSetInertia = true +; Allow_osSetInertiaAsBox = true +; Allow_osSetInertiaAsSphere = true +; Allow_osSetInertiaAsCylinder = true +; Allow_osSetPenCap = true +; Allow_osSetPenColor = true +; Allow_osSetPenSize = true +; Allow_osSetSoundRadius = true +; Allow_osStopSound = true +; Allow_osTriggerSound = true +; Allow_osTriggerSoundLimited = true +; Allow_osVecDistSquare = true +; Allow_osVecMagSquare = true +; Allow_osVolumeDetect = true diff --git a/bin/inventory/TexturesLibrary/TexturesLibraryItems.xml b/bin/inventory/TexturesLibrary/TexturesLibraryItems.xml index adab5d81b2..b146c2111b 100644 --- a/bin/inventory/TexturesLibrary/TexturesLibraryItems.xml +++ b/bin/inventory/TexturesLibrary/TexturesLibraryItems.xml @@ -464,6 +464,16 @@
+
+ + + + + + + +
+
diff --git a/bin/lib/NET/Mono.Security.dll b/bin/lib/NET/Mono.Security.dll index 6accde7911..1371f5cb63 100644 Binary files a/bin/lib/NET/Mono.Security.dll and b/bin/lib/NET/Mono.Security.dll differ diff --git a/bin/lib32/BulletSim.dll b/bin/lib32/BulletSim.dll index 6d006bf593..c7138a4472 100755 Binary files a/bin/lib32/BulletSim.dll and b/bin/lib32/BulletSim.dll differ diff --git a/bin/lib32/libBulletSim.dylib b/bin/lib32/libBulletSim.dylib index b7a42e374b..e4508e6dbc 100755 Binary files a/bin/lib32/libBulletSim.dylib and b/bin/lib32/libBulletSim.dylib differ diff --git a/bin/lib32/libBulletSim.so b/bin/lib32/libBulletSim.so index ec29f58f61..4fb7e3eb11 100755 Binary files a/bin/lib32/libBulletSim.so and b/bin/lib32/libBulletSim.so differ diff --git a/bin/lib32/libode.dylib b/bin/lib32/libode.dylib old mode 100644 new mode 100755 index ce0d5d0be6..49e205e261 Binary files a/bin/lib32/libode.dylib and b/bin/lib32/libode.dylib differ diff --git a/bin/lib32/libode.so b/bin/lib32/libode.so index daf6a4d1b0..35cb027f51 100755 Binary files a/bin/lib32/libode.so and b/bin/lib32/libode.so differ diff --git a/bin/lib32/ode.dll b/bin/lib32/ode.dll index 62aa4df9c4..6d02b53ac2 100755 Binary files a/bin/lib32/ode.dll and b/bin/lib32/ode.dll differ diff --git a/bin/lib64/BulletSim.dll b/bin/lib64/BulletSim.dll index 82774a22f0..58fe6b62a1 100755 Binary files a/bin/lib64/BulletSim.dll and b/bin/lib64/BulletSim.dll differ diff --git a/bin/lib64/libBulletSim.dylib b/bin/lib64/libBulletSim.dylib new file mode 100755 index 0000000000..e4508e6dbc Binary files /dev/null and b/bin/lib64/libBulletSim.dylib differ diff --git a/bin/lib64/libBulletSim.so b/bin/lib64/libBulletSim.so index 8b092751d7..2bf11596fe 100755 Binary files a/bin/lib64/libBulletSim.so and b/bin/lib64/libBulletSim.so differ diff --git a/bin/lib64/libode-x86_64.so b/bin/lib64/libode-x86_64.so index d8f3c20ec4..663ff5d664 100755 Binary files a/bin/lib64/libode-x86_64.so and b/bin/lib64/libode-x86_64.so differ diff --git a/bin/lib64/libode.dylib b/bin/lib64/libode.dylib old mode 100644 new mode 100755 index ce0d5d0be6..49e205e261 Binary files a/bin/lib64/libode.dylib and b/bin/lib64/libode.dylib differ diff --git a/bin/lib64/ode.dll b/bin/lib64/ode.dll index 543b900026..b8e34145b8 100755 Binary files a/bin/lib64/ode.dll and b/bin/lib64/ode.dll differ diff --git a/bin/libopenjpeg-dotnet-2-1.5.0-dotnet-1.dylib b/bin/libopenjpeg-dotnet-2-1.5.0-dotnet-1.dylib index 91f7264fdb..cb4aea1761 100644 Binary files a/bin/libopenjpeg-dotnet-2-1.5.0-dotnet-1.dylib and b/bin/libopenjpeg-dotnet-2-1.5.0-dotnet-1.dylib differ diff --git a/bin/log4net.dll b/bin/log4net.dll index ffc57e1125..7740fbd94d 100755 Binary files a/bin/log4net.dll and b/bin/log4net.dll differ diff --git a/bin/mautil.exe b/bin/mautil.exe index 534df1964b..022ca5ada0 100755 Binary files a/bin/mautil.exe and b/bin/mautil.exe differ diff --git a/bin/opensim-ode.sh b/bin/opensim-ode.sh deleted file mode 100755 index b901425fc1..0000000000 --- a/bin/opensim-ode.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh -echo "Starting OpenSimulator with ODE. If you get an error saying limit: Operation not permitted. Then you will need to chmod 0600 /etc/limits" -ulimit -s 262144 -mono OpenSim.exe -physics=OpenDynamicsEngine diff --git a/bin/opensim.sh b/bin/opensim.sh new file mode 100755 index 0000000000..508d925665 --- /dev/null +++ b/bin/opensim.sh @@ -0,0 +1,5 @@ +#!/bin/sh +ulimit -s 1048576 +# next option may improve SGen gc (for opensim only) you may also need to increase nursery size on large regions +#export MONO_GC_PARAMS="minor=split,promotion-age=14" +mono --desktop OpenSim.exe diff --git a/bin/pCampBot.ini.example b/bin/pCampBot.ini.example index 2952bb002e..138e4ec237 100644 --- a/bin/pCampBot.ini.example +++ b/bin/pCampBot.ini.example @@ -7,13 +7,13 @@ [Bot] ; Control whether bots should regularly send agent updates - ; Not doing this will reduce CPU requirements for pCampbot but greatly + ; Not doing this will reduce CPU requirements for pCampbot but greatly ; reduce the realism compared to viewers which are constantly sending AgentUpdates UDP packets. ; Defaults to true. SendAgentUpdates = true ; Control whether bots will requests textures when receiving object information - ; Not doing this will reduce CPU requirements for pCampbot but greatly + ; Not doing this will reduce CPU requirements for pCampbot but greatly ; reduce the realism compared to viewers which requests such texture data if not already cached. ; Defaults to true. RequestObjectTextures = true diff --git a/bin/zlib.net.dll b/bin/zlib.net.dll index 9d156547f3..1ce10afe68 100755 Binary files a/bin/zlib.net.dll and b/bin/zlib.net.dll differ diff --git a/prebuild.xml b/prebuild.xml index c087def826..f0721c4df2 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -1,7 +1,7 @@ - + TRACE;DEBUG false @@ -14,6 +14,7 @@ true true false + false @@ -29,12 +30,13 @@ false true false + false - + - + ../../bin/ @@ -73,11 +75,13 @@ - + + + - + ../../bin/ @@ -97,7 +101,8 @@ - + + @@ -111,12 +116,16 @@ - - + + + + + + - + ../../../bin/ @@ -141,11 +150,14 @@ - + + + + - + ../../../bin/ @@ -168,11 +180,13 @@ - + + + - + ../../../../bin/ @@ -200,8 +214,8 @@ + - @@ -213,7 +227,7 @@ - + ../../../bin/ @@ -236,11 +250,13 @@ - + + + - + ../../../bin/ @@ -264,12 +280,13 @@ + - + ../../bin/ @@ -300,7 +317,7 @@ - + ../../../../bin/ @@ -321,11 +338,13 @@ - + + + - + ../../../bin/ @@ -354,12 +373,11 @@ - - + - + ../../bin/ @@ -387,14 +405,15 @@ - + + - + ../../../../bin/ @@ -421,7 +440,7 @@ - + ../../../bin/ @@ -462,6 +481,7 @@ + @@ -470,7 +490,7 @@ - + ../../../bin/ @@ -497,16 +517,17 @@ - - + + + - + ../../../bin/ @@ -529,11 +550,13 @@ - + + + - + ../../../bin/ @@ -560,11 +583,13 @@ - + + + - + ../../../bin/ @@ -591,11 +616,13 @@ - + + + - + ../../../bin/ @@ -632,11 +659,13 @@ - + + + - + ../../../bin/ @@ -666,11 +695,13 @@ - + + + - + ../../../bin/ @@ -698,11 +729,13 @@ - + + + - + ../../../bin/ @@ -732,11 +765,13 @@ - + + + - + ../../../bin/ @@ -763,11 +798,13 @@ - + + + - + ../../../bin/ @@ -795,11 +832,13 @@ - + + + - + ../../../bin/ @@ -828,11 +867,13 @@ - + + + - + ../../../bin/ @@ -862,11 +903,13 @@ - + + + - + ../../../bin/ @@ -891,11 +934,13 @@ - + + + - + ../../../bin/ @@ -922,11 +967,13 @@ - + + + - + ../../../bin/ @@ -953,11 +1000,13 @@ - + + + - + ../../../bin/ @@ -986,13 +1035,14 @@ + - + ../../../bin/ @@ -1021,11 +1071,13 @@ - + + + - + ../../../bin/ @@ -1060,11 +1112,13 @@ - + + + - + ../../../bin/ @@ -1090,11 +1144,43 @@ - + + + - + + + + ../../../bin/ + + + + + ../../../bin/ + + + + ../../../bin/ + + + + + + + + + + + + + + + + + + ../../../bin/ @@ -1125,11 +1211,13 @@ - + + + - - + + ../../../bin/ @@ -1163,13 +1251,14 @@ + - + ../../../bin/ @@ -1204,13 +1293,14 @@ + - + ../../bin/ @@ -1241,12 +1331,13 @@ - + + - + ../../bin/ @@ -1274,13 +1365,14 @@ - + + - + ../../../../../bin/ @@ -1318,14 +1410,13 @@ + - - - + ../../../../../bin/ @@ -1346,11 +1437,8 @@ - - - - + @@ -1367,13 +1455,134 @@ + + + + + + + ../../../bin/ + + + + + ../../../bin/ + + - + ../../../bin/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ../../../bin/ + + + + + ../../../bin/ + + + + ../../../bin/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ../../../bin/ + + + + + ../../../bin/ + + + + ../../../bin/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ../../../bin/ @@ -1394,6 +1603,7 @@ + @@ -1402,7 +1612,6 @@ - @@ -1417,7 +1626,10 @@ + + + @@ -1434,13 +1646,14 @@ + - + ../../../bin/ @@ -1466,18 +1679,16 @@ - + + - - - @@ -1494,6 +1705,7 @@ + @@ -1501,7 +1713,7 @@ - + ../../../bin/ @@ -1525,11 +1737,13 @@ - + + + - + ../../../../bin/ @@ -1551,12 +1765,13 @@ + - + ../../../../bin/ @@ -1584,12 +1799,14 @@ - + + + - + ../../../../bin/ @@ -1610,11 +1827,13 @@ - + + + - + ../../../../bin/ @@ -1635,11 +1854,13 @@ - + + + - + ../../../../bin/ @@ -1665,12 +1886,13 @@ + - + ../../../../bin/ @@ -1698,12 +1920,13 @@ + - + ../../../../bin/ @@ -1732,11 +1955,13 @@ - + + + - + ../../../../bin/ @@ -1769,13 +1994,14 @@ + - + ../../../bin/ @@ -1792,7 +2018,6 @@ - @@ -1815,11 +2040,13 @@ - + + + - + ../../../bin/ @@ -1847,12 +2074,14 @@ - + + + - + ../../../bin/ @@ -1876,12 +2105,14 @@ - + + + - + ../../../bin/ @@ -1914,130 +2145,16 @@ - + + + - - - - - ../../../bin/ - - - - - ../../../bin/ - - - - ../../../bin/ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ../../../bin/ - - - - - ../../../bin/ - - - - ../../../bin/ - - - - - - - - - - - - - - - - - - - - - - - - - - - ../../../bin/ - - - - - ../../../bin/ - - - - ../../../bin/ - - - - - - - - - - - - - - - - - - - - - - - - - - - - + ../../../../bin/ @@ -2073,7 +2190,7 @@ - + ../../../../../../bin/ @@ -2101,11 +2218,13 @@ - + + + - + ../../../../../../bin/ @@ -2142,11 +2261,13 @@ - + + + - + ../../../../../bin/ @@ -2171,12 +2292,13 @@ + - + ../../../../../bin/ @@ -2204,18 +2326,18 @@ - + - + ../../../../../../bin/ @@ -2244,11 +2366,13 @@ - + + + - + ../../../../bin/ @@ -2287,15 +2411,62 @@ + + + + + + ../../../../bin/ + + + + + ../../../../bin/ + + + + ../../../../bin/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + ../../../bin/ @@ -2336,13 +2507,14 @@ + - + ../../../bin/ @@ -2384,6 +2556,7 @@ + @@ -2394,7 +2567,7 @@ - + ../../../bin/ @@ -2418,11 +2591,13 @@ - + + + - + ../../../bin/ @@ -2445,11 +2620,13 @@ - + + + - + ../../../bin/ @@ -2469,12 +2646,14 @@ - + + + - + ../../../../bin/ @@ -2497,12 +2676,14 @@ - + + + - + ../../../bin/ @@ -2547,11 +2728,13 @@ - + + + - + ../../bin/ @@ -2574,7 +2757,7 @@ - + ../../../../bin/ @@ -2612,11 +2795,12 @@ + - + ../../../bin/ @@ -2647,12 +2831,14 @@ - + + + - + ../../../bin/ @@ -2697,13 +2883,17 @@ --> - - + + + + + + - + ../../../bin/ @@ -2739,12 +2929,14 @@ - + + + - + ../../../bin/ @@ -2775,7 +2967,7 @@ - + ../../../../bin/ @@ -2802,11 +2994,12 @@ + - + ../../../../bin/ @@ -2832,11 +3025,12 @@ + - + ../../../bin/ @@ -2891,31 +3085,69 @@ --> - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - + + + + + + + + + + + + + + + + + + + + + - + ../../../bin/ @@ -2977,7 +3209,7 @@ - + ../../../../../bin/ @@ -3018,7 +3250,7 @@ - + ../../../../../../bin/ @@ -3052,7 +3284,7 @@ - + ../../../bin/ @@ -3099,10 +3331,18 @@ --> - - - - + + + + + + + + + + + + @@ -3110,7 +3350,7 @@ TODO: this is kind of lame, we basically build a duplicate assembly but with tests added in, just because we can't resolve cross-bin-dir-refs. --> - + ../../../../../bin/ @@ -3137,11 +3377,13 @@ - + + + - + ../../../../../bin/ @@ -3175,7 +3417,7 @@ - + ../../../bin/ @@ -3217,11 +3459,13 @@ --> - + + + - + ../../../bin/ @@ -3261,7 +3505,7 @@ - + ../../../bin/ @@ -3300,7 +3544,46 @@ - + + + + ../../../bin/ + + + + + ../../../bin/ + + + + ../../../bin/ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/runprebuild.bat b/runprebuild.bat index ed2def1d57..af56ee8d24 100755 --- a/runprebuild.bat +++ b/runprebuild.bat @@ -1,7 +1,7 @@ @echo OFF bin\Prebuild.exe /target nant -bin\Prebuild.exe /target vs2010 +bin\Prebuild.exe /target vs2015 setlocal ENABLEEXTENSIONS set KEY_NAME="HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSBuild\ToolsVersions\4.0" diff --git a/runprebuild.sh b/runprebuild.sh index 8c18db6867..011936e3b5 100755 --- a/runprebuild.sh +++ b/runprebuild.sh @@ -18,14 +18,14 @@ case "$1" in 'vs2010') - mono bin/Prebuild.exe /target vs2010 + mono bin/Prebuild.exe /target vs2015 ;; *) mono bin/Prebuild.exe /target nant - mono bin/Prebuild.exe /target vs2010 + mono bin/Prebuild.exe /target vs2015 ;; diff --git a/share/32BitLaunch/OpenSim.32BitLaunch.exe b/share/32BitLaunch/OpenSim.32BitLaunch.exe deleted file mode 100755 index 62c14af416..0000000000 Binary files a/share/32BitLaunch/OpenSim.32BitLaunch.exe and /dev/null differ diff --git a/share/32BitLaunch/OpenSim.32BitLaunch/OpenSim32.csproj b/share/32BitLaunch/OpenSim.32BitLaunch/OpenSim32.csproj new file mode 100644 index 0000000000..c9a03e129b --- /dev/null +++ b/share/32BitLaunch/OpenSim.32BitLaunch/OpenSim32.csproj @@ -0,0 +1,94 @@ + + + + Debug + x86 + {968B4C73-280D-4FF5-9F73-DD3D10160C2E} + Exe + false + OpenSim32 + v4.0 + + + 512 + false + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + x86 + + + pdbonly + true + ..\..\..\bin\ + TRACE + prompt + 4 + x86 + true + false + + + OpenSim32 + + + + ..\..\..\bin\log4net.dll + + + + ..\..\..\bin\OpenSim.exe + + + + + + + + + + + + + + + False + Microsoft .NET Framework 4 %28x86 and x64%29 + true + + + False + .NET Framework 3.5 SP1 + false + + + False + Windows Installer 4.5 + true + + + + + + + \ No newline at end of file diff --git a/share/32BitLaunch/OpenSim.32BitLaunch/OpenSim32.csproj.user b/share/32BitLaunch/OpenSim.32BitLaunch/OpenSim32.csproj.user new file mode 100644 index 0000000000..2f100f7ba6 --- /dev/null +++ b/share/32BitLaunch/OpenSim.32BitLaunch/OpenSim32.csproj.user @@ -0,0 +1,16 @@ + + + + publish\ + + + + + + en-US + false + + + C:\Avination\testsim\bin\ + + \ No newline at end of file diff --git a/share/32BitLaunch/OpenSim.32BitLaunch/OpenSim32.sln b/share/32BitLaunch/OpenSim.32BitLaunch/OpenSim32.sln new file mode 100644 index 0000000000..93522eabdc --- /dev/null +++ b/share/32BitLaunch/OpenSim.32BitLaunch/OpenSim32.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.25420.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenSim32", "OpenSim32.csproj", "{968B4C73-280D-4FF5-9F73-DD3D10160C2E}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x86 = Debug|x86 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {968B4C73-280D-4FF5-9F73-DD3D10160C2E}.Debug|x86.ActiveCfg = Release|x86 + {968B4C73-280D-4FF5-9F73-DD3D10160C2E}.Debug|x86.Build.0 = Release|x86 + {968B4C73-280D-4FF5-9F73-DD3D10160C2E}.Release|x86.ActiveCfg = Release|x86 + {968B4C73-280D-4FF5-9F73-DD3D10160C2E}.Release|x86.Build.0 = Release|x86 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/share/32BitLaunch/OpenSim.32BitLaunch/Program.cs b/share/32BitLaunch/OpenSim.32BitLaunch/Program.cs index 52806b81bf..ca6c359d40 100644 --- a/share/32BitLaunch/OpenSim.32BitLaunch/Program.cs +++ b/share/32BitLaunch/OpenSim.32BitLaunch/Program.cs @@ -27,33 +27,13 @@ using System; -namespace OpenSim._32BitLaunch +namespace OpenSim32 { class Program { static void Main(string[] args) { - log4net.Config.XmlConfigurator.Configure(); - - System.Console.WriteLine("32-bit OpenSim executor"); - System.Console.WriteLine("-----------------------"); - System.Console.WriteLine(""); - System.Console.WriteLine("This application is compiled for 32-bit CPU and will run under WOW32 or similar."); - System.Console.WriteLine("All 64-bit incompatibilities should be gone."); - System.Console.WriteLine(""); - System.Threading.Thread.Sleep(300); - try - { - global::OpenSim.Application.Main(args); - } - catch (Exception ex) - { - System.Console.WriteLine("OpenSim threw an exception:"); - System.Console.WriteLine(ex.ToString()); - System.Console.WriteLine(""); - System.Console.WriteLine("Application will now terminate!"); - System.Console.WriteLine(""); - } + global::OpenSim.Application.Main(args); } } } diff --git a/share/32BitLaunch/OpenSim.32BitLaunch/Properties/AssemblyInfo.cs b/share/32BitLaunch/OpenSim.32BitLaunch/Properties/AssemblyInfo.cs index e81870f92f..bda1a79493 100644 --- a/share/32BitLaunch/OpenSim.32BitLaunch/Properties/AssemblyInfo.cs +++ b/share/32BitLaunch/OpenSim.32BitLaunch/Properties/AssemblyInfo.cs @@ -32,11 +32,11 @@ using System.Runtime.InteropServices; // General information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. -[assembly: AssemblyTitle("OpenSim.32BitLaunch")] -[assembly: AssemblyDescription("")] +[assembly: AssemblyTitle("OpenSim32")] +[assembly: AssemblyDescription("OpenSim 32Bit Launcher")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("http://opensimulator.org")] -[assembly: AssemblyProduct("OpenSim.32BitLaunch")] +[assembly: AssemblyProduct("OpenSim 32BitLauncher")] [assembly: AssemblyCopyright("Copyright (c) 2008")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] @@ -59,5 +59,5 @@ using System.Runtime.InteropServices; // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("0.6.3.*")] -[assembly: AssemblyVersion("0.6.3.*")] +[assembly: AssemblyVersion("0.9.1.*")] [assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/share/32BitLaunch/OpenSim.32BitLaunch/app.config b/share/32BitLaunch/OpenSim.32BitLaunch/app.config new file mode 100644 index 0000000000..92242406f1 --- /dev/null +++ b/share/32BitLaunch/OpenSim.32BitLaunch/app.config @@ -0,0 +1,75 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/share/32BitLaunch/README b/share/32BitLaunch/README deleted file mode 100644 index 443cde0ab9..0000000000 --- a/share/32BitLaunch/README +++ /dev/null @@ -1,5 +0,0 @@ -Many issues appear in the support channels because of a misunderstanding of the use of these utilities. And through discussion at OpenSimulator Office Hours it was determined that these tools probably serve no useful purpose anymore. - -Instead of removing them immediately, we move them here, for a time, in case there is a useful purpose that has escaped us during conversations. - -If a need to compile these arises, the OpenSim.32BitLaunch and Robust.32BitLaunch directories may be placed under the ./OpenSim/Tools sources subdirectory, run the prebuild script and compile. diff --git a/share/32BitLaunch/Robust.32BitLaunch.exe b/share/32BitLaunch/Robust.32BitLaunch.exe deleted file mode 100755 index affedb4bca..0000000000 Binary files a/share/32BitLaunch/Robust.32BitLaunch.exe and /dev/null differ diff --git a/share/32BitLaunch/Robust.32BitLaunch/Program.cs b/share/32BitLaunch/Robust.32BitLaunch/Program.cs index 490414c456..ec5943e4ca 100644 --- a/share/32BitLaunch/Robust.32BitLaunch/Program.cs +++ b/share/32BitLaunch/Robust.32BitLaunch/Program.cs @@ -26,35 +26,14 @@ */ using System; -using log4net; -namespace Robust._32BitLaunch +namespace Robust32 { class Program { static void Main(string[] args) { - log4net.Config.XmlConfigurator.Configure(); - - System.Console.WriteLine("32-bit OpenSim executor"); - System.Console.WriteLine("-----------------------"); - System.Console.WriteLine(""); - System.Console.WriteLine("This application is compiled for 32-bit CPU and will run under WOW32 or similar."); - System.Console.WriteLine("All 64-bit incompatibilities should be gone."); - System.Console.WriteLine(""); - System.Threading.Thread.Sleep(300); - try - { global::OpenSim.Server.OpenSimServer.Main(args); - } - catch (Exception ex) - { - System.Console.WriteLine("OpenSim threw an exception:"); - System.Console.WriteLine(ex.ToString()); - System.Console.WriteLine(""); - System.Console.WriteLine("Application will now terminate!"); - System.Console.WriteLine(""); - } } } } diff --git a/share/32BitLaunch/Robust.32BitLaunch/Robust32.csproj b/share/32BitLaunch/Robust.32BitLaunch/Robust32.csproj new file mode 100644 index 0000000000..a6dae90c3a --- /dev/null +++ b/share/32BitLaunch/Robust.32BitLaunch/Robust32.csproj @@ -0,0 +1,92 @@ + + + + Debug + x86 + {A159489E-6552-4734-8EFA-8E031F63C7F6} + Exe + false + Robust32 + v4.0 + + + 512 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + true + full + false + ..\..\..\bin\ + DEBUG;TRACE + prompt + 4 + x86 + + + pdbonly + true + ..\..\..\bin\ + TRACE + prompt + 4 + x86 + true + Off + + + Robust32 + + + Robust32.Program + + + + + False + ..\..\..\bin\Robust.exe + + + + + + + + + + + + False + Microsoft .NET Framework 4 %28x86 and x64%29 + true + + + False + .NET Framework 3.5 SP1 + false + + + False + Windows Installer 4.5 + true + + + + + + + \ No newline at end of file diff --git a/share/32BitLaunch/Robust.32BitLaunch/Robust32.csproj.user b/share/32BitLaunch/Robust.32BitLaunch/Robust32.csproj.user new file mode 100644 index 0000000000..8221333555 --- /dev/null +++ b/share/32BitLaunch/Robust.32BitLaunch/Robust32.csproj.user @@ -0,0 +1,13 @@ + + + + publish\ + + + + + + en-US + false + + \ No newline at end of file diff --git a/share/32BitLaunch/Robust.32BitLaunch/Robust32.sln b/share/32BitLaunch/Robust.32BitLaunch/Robust32.sln new file mode 100644 index 0000000000..368b3ca50b --- /dev/null +++ b/share/32BitLaunch/Robust.32BitLaunch/Robust32.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.25420.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Robust32", "Robust32.csproj", "{A159489E-6552-4734-8EFA-8E031F63C7F6}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x86 = Debug|x86 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {A159489E-6552-4734-8EFA-8E031F63C7F6}.Debug|x86.ActiveCfg = Debug|x86 + {A159489E-6552-4734-8EFA-8E031F63C7F6}.Debug|x86.Build.0 = Debug|x86 + {A159489E-6552-4734-8EFA-8E031F63C7F6}.Release|x86.ActiveCfg = Release|x86 + {A159489E-6552-4734-8EFA-8E031F63C7F6}.Release|x86.Build.0 = Release|x86 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/share/32BitLaunch/Robust.32BitLaunch/app.config b/share/32BitLaunch/Robust.32BitLaunch/app.config new file mode 100644 index 0000000000..ca3ee0e0cf --- /dev/null +++ b/share/32BitLaunch/Robust.32BitLaunch/app.config @@ -0,0 +1,72 @@ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/share/RegionLoading/example_web.xml b/share/RegionLoading/example_web.xml index f7ed25e3b0..39e8023e11 100644 --- a/share/RegionLoading/example_web.xml +++ b/share/RegionLoading/example_web.xml @@ -1,8 +1,26 @@ - - - - - - - - \ No newline at end of file + +
+ + + + + + + + + + +
+
+ + + + + + + + + + +
+
\ No newline at end of file