From a9a24062a5622350cd26203f58f14a209d3b6e72 Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 31 Oct 2011 10:18:25 +0100 Subject: [PATCH 01/17] Plug a security hole in the inventory service --- OpenSim/Data/MySQL/MySQLInventoryData.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/OpenSim/Data/MySQL/MySQLInventoryData.cs b/OpenSim/Data/MySQL/MySQLInventoryData.cs index 9d70acbeeb..1a634e5eb6 100644 --- a/OpenSim/Data/MySQL/MySQLInventoryData.cs +++ b/OpenSim/Data/MySQL/MySQLInventoryData.cs @@ -794,7 +794,8 @@ namespace OpenSim.Data.MySQL { dbcon.Open(); - using (MySqlCommand cmd = new MySqlCommand("DELETE FROM inventoryfolders WHERE folderID=?uuid", dbcon)) + // System folders can never be deleted. Period. + using (MySqlCommand cmd = new MySqlCommand("DELETE FROM inventoryfolders WHERE folderID=?uuid and type=-1", dbcon)) { cmd.Parameters.AddWithValue("?uuid", folderID.ToString()); From e3f51df3c27c5bc74bc69789d18015c538220935 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Mon, 31 Oct 2011 21:33:25 +0000 Subject: [PATCH 02/17] Stop pCampbot from firing connected event twice, which results in double counting. --- OpenSim/Tools/pCampBot/BotManager.cs | 16 ++++++++-------- OpenSim/Tools/pCampBot/PhysicsBot.cs | 5 +++-- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/OpenSim/Tools/pCampBot/BotManager.cs b/OpenSim/Tools/pCampBot/BotManager.cs index 614b350011..c9d144697b 100644 --- a/OpenSim/Tools/pCampBot/BotManager.cs +++ b/OpenSim/Tools/pCampBot/BotManager.cs @@ -81,16 +81,16 @@ namespace pCampBot m_console.Commands.AddCommand("bot", false, "shutdown", "shutdown", - "Gracefully shut down bots", HandleShutdown); + "Shutdown bots and exit", HandleShutdown); m_console.Commands.AddCommand("bot", false, "quit", "quit", - "Force quit (DANGEROUS, try shutdown first)", + "Shutdown bots and exit", HandleShutdown); - m_console.Commands.AddCommand("bot", false, "add bots", - "add bots ", - "Add more bots", HandleAddBots); +// m_console.Commands.AddCommand("bot", false, "add bots", +// "add bots ", +// "Add more bots", HandleAddBots); m_lBot = new List(); } @@ -177,14 +177,14 @@ namespace pCampBot switch (eventt) { case EventType.CONNECTED: - m_log.Info("[ " + callbot.firstname + " " + callbot.lastname + "]: Connected"); + m_log.Info("[" + callbot.firstname + " " + callbot.lastname + "]: Connected"); numbots++; break; case EventType.DISCONNECTED: - m_log.Info("[ " + callbot.firstname + " " + callbot.lastname + "]: Disconnected"); + m_log.Info("[" + callbot.firstname + " " + callbot.lastname + "]: Disconnected"); m_td[m_lBot.IndexOf(callbot)].Abort(); numbots--; - if (numbots >1) + if (numbots <= 0) Environment.Exit(0); break; } diff --git a/OpenSim/Tools/pCampBot/PhysicsBot.cs b/OpenSim/Tools/pCampBot/PhysicsBot.cs index 5d4af3144c..de54836a09 100644 --- a/OpenSim/Tools/pCampBot/PhysicsBot.cs +++ b/OpenSim/Tools/pCampBot/PhysicsBot.cs @@ -165,7 +165,7 @@ namespace pCampBot m_action.AutoReset = false; m_action.Elapsed += new ElapsedEventHandler(m_action_Elapsed); m_action.Start(); - OnConnected(this, EventType.CONNECTED); +// OnConnected(this, EventType.CONNECTED); if (wear == "save") { client.Appearance.SetPreviousAppearance(); @@ -384,6 +384,7 @@ namespace pCampBot { client.Assets.RequestImage(prim.Textures.DefaultTexture.TextureID, ImageType.Normal, Asset_TextureCallback_Texture); } + for (int i = 0; i < prim.Textures.FaceTextures.Length; i++) { if (prim.Textures.FaceTextures[i] != null) @@ -392,10 +393,10 @@ namespace pCampBot { client.Assets.RequestImage(prim.Textures.FaceTextures[i].TextureID, ImageType.Normal, Asset_TextureCallback_Texture); } - } } } + if (prim.Sculpt.SculptTexture != UUID.Zero) { client.Assets.RequestImage(prim.Sculpt.SculptTexture, ImageType.Normal, Asset_TextureCallback_Texture); From 74cc834fec3a9043f042b74a74fdbcd15c8b6411 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Mon, 31 Oct 2011 21:37:35 +0000 Subject: [PATCH 03/17] Remove unused PumaCode.SvnDotNet library --- bin/PumaCode.SvnDotNet.dll | Bin 183808 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100755 bin/PumaCode.SvnDotNet.dll diff --git a/bin/PumaCode.SvnDotNet.dll b/bin/PumaCode.SvnDotNet.dll deleted file mode 100755 index ff91789f3d88b33967562cbdc03e67dc369e6337..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 183808 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 EKkZ`L@&Et; From b1647f6d045a4ec0559d0f49d09f17f6e4cf2930 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Mon, 31 Oct 2011 22:14:49 +0000 Subject: [PATCH 04/17] adjust pCampbot so it starts up bots with the name format " _" e.g. starting up two bots called "Ima Bot" will give them the names "Ima Bot_0" and "Ima Bot_1" This is necessary since bots with random names can no longer be created, as there's no easy way to turn off account authentication --- OpenSim/Tools/pCampBot/BotManager.cs | 107 +++++++++++++-------------- OpenSim/Tools/pCampBot/PhysicsBot.cs | 45 ++++++----- OpenSim/Tools/pCampBot/README.txt | 25 ++----- OpenSim/Tools/pCampBot/pCampBot.cs | 6 +- 4 files changed, 89 insertions(+), 94 deletions(-) diff --git a/OpenSim/Tools/pCampBot/BotManager.cs b/OpenSim/Tools/pCampBot/BotManager.cs index c9d144697b..0aaa226bcb 100644 --- a/OpenSim/Tools/pCampBot/BotManager.cs +++ b/OpenSim/Tools/pCampBot/BotManager.cs @@ -53,7 +53,7 @@ namespace pCampBot protected bool m_verbose = true; protected Random somthing = new Random(Environment.TickCount); protected int numbots = 0; - protected IConfig Previous_config; + private IConfig Config; /// /// Constructor Creates MainConsole.Instance to take commands and provide the place to write data @@ -102,71 +102,64 @@ namespace pCampBot /// The configuration for the bots to use public void dobotStartup(int botcount, IConfig cs) { - Previous_config = cs; + Config = cs; m_td = new Thread[botcount]; + + string firstName = cs.GetString("firstname"); + string lastNameStem = cs.GetString("lastname"); + string password = cs.GetString("password"); + string loginUri = cs.GetString("loginuri"); + for (int i = 0; i < botcount; i++) { - startupBot(i, cs); + string lastName = string.Format("{0}_{1}", lastNameStem, i); + startupBot(i, cs, firstName, lastName, password, loginUri); } } - /// - /// Add additional bots (and threads) to our bot pool - /// - /// How Many of them to add - public void addbots(int botcount) - { - int len = m_td.Length; - Thread[] m_td2 = new Thread[len + botcount]; - for (int i = 0; i < len; i++) - { - m_td2[i] = m_td[i]; - } - m_td = m_td2; - int newlen = len + botcount; - for (int i = len; i < newlen; i++) - { - startupBot(i, Previous_config); - } - } +// /// +// /// Add additional bots (and threads) to our bot pool +// /// +// /// How Many of them to add +// public void addbots(int botcount) +// { +// int len = m_td.Length; +// Thread[] m_td2 = new Thread[len + botcount]; +// for (int i = 0; i < len; i++) +// { +// m_td2[i] = m_td[i]; +// } +// m_td = m_td2; +// int newlen = len + botcount; +// for (int i = len; i < newlen; i++) +// { +// startupBot(i, Config); +// } +// } /// /// This starts up the bot and stores the thread for the bot in the thread array /// /// The position in the thread array to stick the bot's thread /// Configuration of the bot - public void startupBot(int pos, IConfig cs) + /// First name + /// Last name + /// Password + /// Login URI + public void startupBot(int pos, IConfig cs, string firstName, string lastName, string password, string loginUri) { - PhysicsBot pb = new PhysicsBot(cs); + PhysicsBot pb = new PhysicsBot(cs, firstName, lastName, password, loginUri); pb.OnConnected += handlebotEvent; pb.OnDisconnected += handlebotEvent; - if (cs.GetString("firstname", "random") == "random") pb.firstname = CreateRandomName(); - if (cs.GetString("lastname", "random") == "random") pb.lastname = CreateRandomName(); m_td[pos] = new Thread(pb.startup); - m_td[pos].Name = "CampBot_" + pos; + m_td[pos].Name = pb.Name; m_td[pos].IsBackground = true; m_td[pos].Start(); m_lBot.Add(pb); } - /// - /// Creates a random name for the bot - /// - /// - private string CreateRandomName() - { - string returnstring = ""; - string chars = "abcdefghijklmnopqrstuvwxyz0123456789"; - - for (int i = 0; i < 7; i++) - { - returnstring += chars.Substring(somthing.Next(chars.Length),1); - } - return returnstring; - } - /// /// High level connnected/disconnected events so we can keep track of our threads by proxy /// @@ -177,11 +170,11 @@ namespace pCampBot switch (eventt) { case EventType.CONNECTED: - m_log.Info("[" + callbot.firstname + " " + callbot.lastname + "]: Connected"); + m_log.Info("[" + callbot.FirstName + " " + callbot.LastName + "]: Connected"); numbots++; break; case EventType.DISCONNECTED: - m_log.Info("[" + callbot.firstname + " " + callbot.lastname + "]: Disconnected"); + m_log.Info("[" + callbot.FirstName + " " + callbot.LastName + "]: Disconnected"); m_td[m_lBot.IndexOf(callbot)].Abort(); numbots--; if (numbots <= 0) @@ -223,17 +216,17 @@ namespace pCampBot Environment.Exit(0); } */ - - private void HandleAddBots(string module, string[] cmd) - { - int newbots = 0; - - if (cmd.Length > 2) - { - Int32.TryParse(cmd[2], out newbots); - } - if (newbots > 0) - addbots(newbots); - } +// +// private void HandleAddBots(string module, string[] cmd) +// { +// int newbots = 0; +// +// if (cmd.Length > 2) +// { +// Int32.TryParse(cmd[2], out newbots); +// } +// if (newbots > 0) +// addbots(newbots); +// } } } diff --git a/OpenSim/Tools/pCampBot/PhysicsBot.cs b/OpenSim/Tools/pCampBot/PhysicsBot.cs index de54836a09..1531b27f40 100644 --- a/OpenSim/Tools/pCampBot/PhysicsBot.cs +++ b/OpenSim/Tools/pCampBot/PhysicsBot.cs @@ -45,10 +45,11 @@ namespace pCampBot public delegate void AnEvent(PhysicsBot callbot, EventType someevent); // event delegate for bot events public IConfig startupConfig; // bot config, passed from BotManager - public string firstname; - public string lastname; - public string password; - public string loginURI; + public string FirstName { get; private set; } + public string LastName { get; private set; } + public string Name { get; private set; } + public string Password { get; private set; } + public string LoginUri { get; private set; } public string saveDir; public string wear; @@ -60,16 +61,28 @@ namespace pCampBot protected Random somthing = new Random(Environment.TickCount);// We do stuff randomly here - //New instance of a SecondLife client + /// + /// New instance of a SecondLife client + /// public GridClient client = new GridClient(); protected string[] talkarray; + /// - /// + /// Constructor /// - /// nini config for the bot - public PhysicsBot(IConfig bsconfig) + /// + /// + /// + /// + /// + public PhysicsBot(IConfig bsconfig, string firstName, string lastName, string password, string loginUri) { + FirstName = firstName; + LastName = lastName; + Name = string.Format("{0} {1}", FirstName, LastName); + Password = password; + LoginUri = loginUri; startupConfig = bsconfig; readconfig(); talkarray = readexcuses(); @@ -116,10 +129,6 @@ namespace pCampBot /// public void readconfig() { - firstname = startupConfig.GetString("firstname", "random"); - lastname = startupConfig.GetString("lastname", "random"); - password = startupConfig.GetString("password", "12345"); - loginURI = startupConfig.GetString("loginuri"); wear = startupConfig.GetString("wear","no"); } @@ -136,7 +145,7 @@ namespace pCampBot /// public void startup() { - client.Settings.LOGIN_SERVER = loginURI; + client.Settings.LOGIN_SERVER = LoginUri; client.Settings.ALWAYS_DECODE_OBJECTS = false; client.Settings.AVATAR_TRACKING = false; client.Settings.OBJECT_TRACKING = false; @@ -153,10 +162,10 @@ namespace pCampBot client.Throttle.Total = 400000; client.Network.LoginProgress += this.Network_LoginProgress; client.Network.SimConnected += this.Network_SimConnected; - client.Network.Disconnected += this.Network_OnDisconnected; +// client.Network.Disconnected += this.Network_OnDisconnected; client.Objects.ObjectUpdate += Objects_NewPrim; //client.Assets.OnAssetReceived += Asset_ReceivedCallback; - if (client.Network.Login(firstname, lastname, password, "pCampBot", "Your name")) + if (client.Network.Login(FirstName, LastName, Password, "pCampBot", "Your name")) { if (OnConnected != null) { @@ -180,7 +189,9 @@ namespace pCampBot } else { - MainConsole.Instance.Output(firstname + " " + lastname + " Can't login: " + client.Network.LoginMessage); + MainConsole.Instance.OutputFormat( + "{0} {1} cannot login: {2}", FirstName, LastName, client.Network.LoginMessage); + if (OnDisconnected != null) { OnDisconnected(this, EventType.DISCONNECTED); @@ -190,7 +201,7 @@ namespace pCampBot public void SaveDefaultAppearance() { - saveDir = "MyAppearance/" + firstname + "_" + lastname; + saveDir = "MyAppearance/" + FirstName + "_" + LastName; if (!Directory.Exists(saveDir)) { Directory.CreateDirectory(saveDir); diff --git a/OpenSim/Tools/pCampBot/README.txt b/OpenSim/Tools/pCampBot/README.txt index 7ecbde1ba9..c4fcf3393a 100644 --- a/OpenSim/Tools/pCampBot/README.txt +++ b/OpenSim/Tools/pCampBot/README.txt @@ -1,10 +1,13 @@ This is the PhysicsCamperbot libslBot tester. -This is designed to be run in standalone mode with authorize accounts -turned off as a way to stress test the simulator. It creates -clients that log in, randomly jump/walk around, and say excuses from +This is designed to stress test the simulator. It creates +clients that log in, randomly jump/walk around, and can say excuses from the BOFH. +Bots must have accounts already created. Each bot will have the same firstname and password +but their lastname will be appended with _ starting from 0. So if you have two bots called ima bot, their +first names will be ima_bot_0 and ima_bot_1. + *** WARNING *** Using this bot on a public grid could get you banned permanently, so just say No! to griefing! @@ -21,19 +24,8 @@ pCampBot.exe will end up in the regular opensim/bin folder ----- Running the bot ----- -windows: pCampBot.exe -botcount -loginuri -*nix: mono pCampBot.exe -botcount -loginuri - -The names it produces are random by default, however, you can specify -either a firstname or a lastname in the command line also. - -ex: pCampBot.exe -botcount -loginuri -lastname - -If you specify both a firstname *and* a lastname, you'll likely run -into trouble unless you're only running a single bot. In that case, -there's also a password option. - -pCampBot.exe -botcount 1 -loginuri http://somegrid.com:8002 -firstname SomeDude -lastname SomeDude -password GobbleDeGook +windows: pCampBot.exe -botcount -loginuri -firstname -lastname -password +*nix: mono pCampBot.exe -botcount -loginuri -firstname -lastname -password ----- Commands ----- @@ -41,4 +33,3 @@ The bot has console commands: help - lists the console commands and what they do shutdown - gracefully shuts down the bots quit - forcefully shuts things down leaving stuff unclean - addbots N - adds N number of random bots. (replace 'N' with a number) diff --git a/OpenSim/Tools/pCampBot/pCampBot.cs b/OpenSim/Tools/pCampBot/pCampBot.cs index 77110bf6b8..a69fbf03c9 100644 --- a/OpenSim/Tools/pCampBot/pCampBot.cs +++ b/OpenSim/Tools/pCampBot/pCampBot.cs @@ -95,9 +95,9 @@ namespace pCampBot "Spawns a set of bots to test an OpenSim region\n\n" + " -l, -loginuri loginuri for sim to log into (required)\n" + " -n, -botcount number of bots to start (default: 1)\n" + - " -firstname first name for the bot(s) (default: random string)\n" + - " -lastname lastname for the bot(s) (default: random string)\n" + - " -password password for the bots(s) (default: random string)\n" + + " -firstname first name for the bots\n" + + " -lastname lastname for the bots. Each lastname will have _ appended, e.g. Ima Bot_0\n" + + " -password password for the bots\n" + " -wear set appearance folder to load from (default: no)\n" + " -h, -help show this message" ); From d3153f47fa3faebc139e6e58161dc46049d323f1 Mon Sep 17 00:00:00 2001 From: Dan Lake Date: Mon, 31 Oct 2011 15:20:57 -0700 Subject: [PATCH 05/17] Adding green dots to map response should be for root agents only --- OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs index 509c0d8e46..00d7d55425 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs @@ -1180,7 +1180,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap else { OSDArray responsearr = new OSDArray(m_scene.GetRootAgentCount()); - m_scene.ForEachScenePresence(delegate(ScenePresence sp) + m_scene.ForEachRootScenePresence(delegate(ScenePresence sp) { OSDMap responsemapdata = new OSDMap(); responsemapdata["X"] = OSD.FromInteger((int)(xstart + sp.AbsolutePosition.X)); From 43e07efbc843ba1edd0c0369c50da331b5a1b2d6 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Mon, 31 Oct 2011 22:27:12 +0000 Subject: [PATCH 06/17] Fix bot disconnection --- OpenSim/Tools/pCampBot/PhysicsBot.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Tools/pCampBot/PhysicsBot.cs b/OpenSim/Tools/pCampBot/PhysicsBot.cs index 1531b27f40..03c6f850f4 100644 --- a/OpenSim/Tools/pCampBot/PhysicsBot.cs +++ b/OpenSim/Tools/pCampBot/PhysicsBot.cs @@ -162,7 +162,7 @@ namespace pCampBot client.Throttle.Total = 400000; client.Network.LoginProgress += this.Network_LoginProgress; client.Network.SimConnected += this.Network_SimConnected; -// client.Network.Disconnected += this.Network_OnDisconnected; + client.Network.Disconnected += this.Network_OnDisconnected; client.Objects.ObjectUpdate += Objects_NewPrim; //client.Assets.OnAssetReceived += Asset_ReceivedCallback; if (client.Network.Login(FirstName, LastName, Password, "pCampBot", "Your name")) From d366a08ebbc861a9db8ab27dd7f375a349d297ff Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Mon, 31 Oct 2011 22:52:49 +0000 Subject: [PATCH 07/17] Stop individual bots attempting to download the same asset more than once --- OpenSim/Tools/pCampBot/PhysicsBot.cs | 50 ++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 14 deletions(-) diff --git a/OpenSim/Tools/pCampBot/PhysicsBot.cs b/OpenSim/Tools/pCampBot/PhysicsBot.cs index 03c6f850f4..0344a829f3 100644 --- a/OpenSim/Tools/pCampBot/PhysicsBot.cs +++ b/OpenSim/Tools/pCampBot/PhysicsBot.cs @@ -56,6 +56,11 @@ namespace pCampBot public event AnEvent OnConnected; public event AnEvent OnDisconnected; + /// + /// Track the assets we have and have not received so we don't endlessly repeat requests. + /// + public Dictionary AssetsReceived { get; private set; } + protected Timer m_action; // Action Timer protected List objectIDs = new List(); @@ -86,6 +91,8 @@ namespace pCampBot startupConfig = bsconfig; readconfig(); talkarray = readexcuses(); + + AssetsReceived = new Dictionary(); } //We do our actions here. This is where one would @@ -164,7 +171,7 @@ namespace pCampBot client.Network.SimConnected += this.Network_SimConnected; client.Network.Disconnected += this.Network_OnDisconnected; client.Objects.ObjectUpdate += Objects_NewPrim; - //client.Assets.OnAssetReceived += Asset_ReceivedCallback; + if (client.Network.Login(FirstName, LastName, Password, "pCampBot", "Your name")) { if (OnConnected != null) @@ -227,7 +234,7 @@ namespace pCampBot { if (asset.Decode()) { - File.WriteAllBytes(Path.Combine(saveDir, String.Format("{1}.{0}", + File.WriteAllBytes(Path.Combine(saveDir, String.Format("{1}.{0}", asset.AssetType.ToString().ToLower(), asset.WearableType)), asset.AssetData); } @@ -393,40 +400,55 @@ namespace pCampBot { if (prim.Textures.DefaultTexture.TextureID != UUID.Zero) { - client.Assets.RequestImage(prim.Textures.DefaultTexture.TextureID, ImageType.Normal, Asset_TextureCallback_Texture); + GetTexture(prim.Textures.DefaultTexture.TextureID); } for (int i = 0; i < prim.Textures.FaceTextures.Length; i++) { - if (prim.Textures.FaceTextures[i] != null) + UUID textureID = prim.Textures.FaceTextures[i].TextureID; + + if (textureID != null && textureID != UUID.Zero) { - if (prim.Textures.FaceTextures[i].TextureID != UUID.Zero) - { - client.Assets.RequestImage(prim.Textures.FaceTextures[i].TextureID, ImageType.Normal, Asset_TextureCallback_Texture); - } + GetTexture(textureID); } } } if (prim.Sculpt.SculptTexture != UUID.Zero) { - client.Assets.RequestImage(prim.Sculpt.SculptTexture, ImageType.Normal, Asset_TextureCallback_Texture); + GetTexture(prim.Sculpt.SculptTexture); } } } + private void GetTexture(UUID textureID) + { + lock (AssetsReceived) + { + // Don't request assets more than once. + if (AssetsReceived.ContainsKey(textureID)) + return; + + AssetsReceived[textureID] = false; + client.Assets.RequestImage(textureID, ImageType.Normal, Asset_TextureCallback_Texture); + } + } + public void Asset_TextureCallback_Texture(TextureRequestState state, AssetTexture assetTexture) { //TODO: Implement texture saving and applying } - public void Asset_ReceivedCallback(AssetDownload transfer,Asset asset) + public void Asset_ReceivedCallback(AssetDownload transfer, Asset asset) { - if (wear == "save") - { - SaveAsset((AssetWearable) asset); - } + lock (AssetsReceived) + AssetsReceived[asset.AssetID] = true; + +// if (wear == "save") +// { +// SaveAsset((AssetWearable) asset); +// } } public string[] readexcuses() From 210868a832439bb226dfcf153ca66563300dc2cf Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Mon, 31 Oct 2011 23:10:10 +0000 Subject: [PATCH 08/17] Remove OpenSim.TestSuite Hasn't been touched since 2009 and wasn't more than another copy of pCampBot --- OpenSim/TestSuite/BotManager.cs | 170 ----------------------- OpenSim/TestSuite/Main.cs | 98 -------------- OpenSim/TestSuite/PhysicsBot.cs | 196 --------------------------- OpenSim/TestSuite/README.txt | 25 ---- OpenSim/TestSuite/Util.cs | 81 ----------- OpenSim/Tools/pCampBot/BotManager.cs | 4 +- OpenSim/Tools/pCampBot/PhysicsBot.cs | 7 +- prebuild.xml | 28 ---- 8 files changed, 9 insertions(+), 600 deletions(-) delete mode 100644 OpenSim/TestSuite/BotManager.cs delete mode 100644 OpenSim/TestSuite/Main.cs delete mode 100644 OpenSim/TestSuite/PhysicsBot.cs delete mode 100644 OpenSim/TestSuite/README.txt delete mode 100644 OpenSim/TestSuite/Util.cs diff --git a/OpenSim/TestSuite/BotManager.cs b/OpenSim/TestSuite/BotManager.cs deleted file mode 100644 index 55ba687290..0000000000 --- a/OpenSim/TestSuite/BotManager.cs +++ /dev/null @@ -1,170 +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.Collections.Generic; -using System.Reflection; -using System.Threading; -using OpenMetaverse; -using log4net; -using Nini.Config; -using OpenSim.Framework; -using OpenSim.Framework.Console; - -namespace OpenSim.TestSuite -{ - /// - /// Thread/Bot manager for the application - /// - public class BotManager - { - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - - protected CommandConsole m_console; - protected List m_lBot; - protected Thread[] m_td; - protected bool m_verbose = true; - protected Random somthing = new Random(Environment.TickCount); - protected int numbots = 0; - protected IConfig Previous_config; - - /// - /// Constructor Creates MainConsole.Instance to take commands and provide the place to write data - /// - public BotManager() - { - m_log.Info("In bot manager"); - m_lBot = new List(); - } - - /// - /// Startup number of bots specified in the starting arguments - /// - /// How many bots to start up - /// The configuration for the bots to use - public void dobotStartup(int botcount, IConfig cs) - { - Previous_config = cs; - m_td = new Thread[botcount]; - for (int i = 0; i < botcount; i++) - { - startupBot(i, cs); - } - } - - /// - /// Add additional bots (and threads) to our bot pool - /// - /// How Many of them to add - public void addbots(int botcount) - { - int len = m_td.Length; - Thread[] m_td2 = new Thread[len + botcount]; - for (int i = 0; i < len; i++) - { - m_td2[i] = m_td[i]; - } - m_td = m_td2; - int newlen = len + botcount; - for (int i = len; i < newlen; i++) - { - startupBot(i, Previous_config); - } - } - - /// - /// This starts up the bot and stores the thread for the bot in the thread array - /// - /// The position in the thread array to stick the bot's thread - /// Configuration of the bot - public void startupBot(int pos, IConfig cs) - { - PhysicsBot pb = new PhysicsBot(cs); - - pb.OnConnected += handlebotEvent; - pb.OnDisconnected += handlebotEvent; - if (cs.GetString("firstname", "random") == "random") pb.firstname = CreateRandomName(); - if (cs.GetString("lastname", "random") == "random") pb.lastname = CreateRandomName(); - - m_td[pos] = new Thread(pb.startup); - m_td[pos].Name = "CampBot_" + pos; - m_td[pos].IsBackground = true; - m_td[pos].Start(); - m_lBot.Add(pb); - } - - /// - /// Creates a random name for the bot - /// - /// - private string CreateRandomName() - { - string returnstring = ""; - string chars = "abcdefghijklmnopqrstuvwxyz0123456789"; - - for (int i = 0; i < 7; i++) - { - returnstring += chars.Substring(somthing.Next(chars.Length),1); - } - return returnstring; - } - - /// - /// High level connnected/disconnected events so we can keep track of our threads by proxy - /// - /// - /// - public void handlebotEvent(PhysicsBot callbot, EventType eventt) - { - switch (eventt) - { - case EventType.CONNECTED: - m_log.Info("[ " + callbot.firstname + " " + callbot.lastname + "]: Connected"); - numbots++; - break; - case EventType.DISCONNECTED: - m_log.Info("[ " + callbot.firstname + " " + callbot.lastname + "]: Disconnected"); - m_td[m_lBot.IndexOf(callbot)].Abort(); - numbots--; - if (numbots > 1) - Environment.Exit(0); - break; - } - } - - /// - /// Shutting down all bots - /// - public void doBotShutdown() - { - foreach (PhysicsBot pb in m_lBot) - { - pb.shutdown(); - } - } - } -} diff --git a/OpenSim/TestSuite/Main.cs b/OpenSim/TestSuite/Main.cs deleted file mode 100644 index ee75bf5fab..0000000000 --- a/OpenSim/TestSuite/Main.cs +++ /dev/null @@ -1,98 +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 Nini.Config; - -namespace OpenSim.TestSuite -{ - /// - /// Event Types from the BOT. Add new events here - /// - public enum EventType : int - { - NONE = 0, - CONNECTED = 1, - DISCONNECTED = 2 - } - - public class TestSuite - { - public static void Main(string[] args) - { - // TODO: config parser - - // TODO: load tests from addings - - // TODO: create base bot cloud for use in tests - - IConfig config = ParseConfig(args); - if (config.Get("help") != null || config.Get("loginuri") == null) - { - Help(); - } - else - { - // TODO: unused: int botcount = config.GetInt("botcount", 1); - - // BotManager bm = new BotManager(); - - Utils.TestPass("Completed Startup"); - } - } - - private static IConfig ParseConfig(String[] args) - { - //Set up our nifty config.. thanks to nini - ArgvConfigSource cs = new ArgvConfigSource(args); - - // TODO: unused: cs.AddSwitch("Startup", "botcount","n"); - cs.AddSwitch("Startup", "loginuri","l"); - cs.AddSwitch("Startup", "firstname"); - cs.AddSwitch("Startup", "lastname"); - cs.AddSwitch("Startup", "password"); - cs.AddSwitch("Startup", "help","h"); - - IConfig ol = cs.Configs["Startup"]; - return ol; - } - - private static void Help() - { - Console.WriteLine( - "usage: pCampBot <-loginuri loginuri> [OPTIONS]\n" + - "Spawns a set of bots to test an OpenSim region\n\n" + - " -l, -loginuri loginuri for sim to log into (required)\n" + - // TODO: unused: " -n, -botcount number of bots to start (default: 1)\n" + - " -firstname first name for the bot(s) (default: random string)\n" + - " -lastname lastname for the bot(s) (default: random string)\n" + - " -password password for the bots(s) (default: random string)\n" + - " -h, -help show this message" - ); - } - } -} diff --git a/OpenSim/TestSuite/PhysicsBot.cs b/OpenSim/TestSuite/PhysicsBot.cs deleted file mode 100644 index fac42756a8..0000000000 --- a/OpenSim/TestSuite/PhysicsBot.cs +++ /dev/null @@ -1,196 +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.IO; -using System.Threading; -using System.Timers; -using OpenMetaverse; -using Nini.Config; -using OpenSim.Framework; -using OpenSim.Framework.Console; -using Timer=System.Timers.Timer; - -namespace OpenSim.TestSuite -{ - public class PhysicsBot - { - public delegate void AnEvent(PhysicsBot callbot, EventType someevent); // event delegate for bot events - public IConfig startupConfig; // bot config, passed from BotManager - - public string firstname; - public string lastname; - public string password; - public string loginURI; - - public event AnEvent OnConnected; - public event AnEvent OnDisconnected; - - protected Timer m_action; // Action Timer - - protected Random somthing = new Random(Environment.TickCount);// We do stuff randomly here - - //New instance of a SecondLife client - public GridClient client = new GridClient(); - - protected string[] talkarray; - /// - /// - /// - /// nini config for the bot - public PhysicsBot(IConfig bsconfig) - { - startupConfig = bsconfig; - readconfig(); - talkarray = readexcuses(); - } - - //We do our actions here. This is where one would - //add additional steps and/or things the bot should do - - void m_action_Elapsed(object sender, ElapsedEventArgs e) - { - //client.Throttle.Task = 500000f; - //client.Throttle.Set(); - int walkorrun = somthing.Next(4); // Randomize between walking and running. The greater this number, - // the greater the bot's chances to walk instead of run. - if (walkorrun == 0) - { - client.Self.Movement.AlwaysRun = true; - } - else - { - client.Self.Movement.AlwaysRun = false; - } - - // TODO: unused: Vector3 pos = client.Self.SimPosition; - Vector3 newpos = new Vector3(somthing.Next(255), somthing.Next(255), somthing.Next(255)); - client.Self.Movement.TurnToward(newpos); - - for (int i = 0; i < 2000; i++) - { - client.Self.Movement.AtPos = true; - Thread.Sleep(somthing.Next(25, 75)); // Makes sure the bots keep walking for this time. - } - client.Self.Jump(true); - - string randomf = talkarray[somthing.Next(talkarray.Length)]; - if (talkarray.Length > 1 && randomf.Length > 1) - client.Self.Chat(randomf, 0, ChatType.Normal); - - //Thread.Sleep(somthing.Next(1, 10)); // Apparently its better without it right now. - } - - /// - /// Read the Nini config and initialize - /// - public void readconfig() - { - firstname = startupConfig.GetString("firstname", "random"); - lastname = startupConfig.GetString("lastname", "random"); - password = startupConfig.GetString("password", "12345"); - loginURI = startupConfig.GetString("loginuri"); - } - - /// - /// Tells LibSecondLife to logout and disconnect. Raises the disconnect events once it finishes. - /// - public void shutdown() - { - client.Network.Logout(); - } - - /// - /// This is the bot startup loop. - /// - public void startup() - { - client.Settings.LOGIN_SERVER = loginURI; - client.Network.LoginProgress += this.Network_LoginProgress; - client.Network.SimConnected += this.Network_SimConnected; - client.Network.Disconnected += this.Network_OnDisconnected; - if (client.Network.Login(firstname, lastname, password, "pCampBot", "Your name")) - { - - if (OnConnected != null) - { - m_action = new Timer(somthing.Next(1000, 10000)); - m_action.Elapsed += new ElapsedEventHandler(m_action_Elapsed); - m_action.Start(); - OnConnected(this, EventType.CONNECTED); - client.Self.Jump(true); - } - } - else - { - MainConsole.Instance.Output(firstname + " " + lastname + "Can't login: " + client.Network.LoginMessage); - if (OnDisconnected != null) - { - OnDisconnected(this, EventType.DISCONNECTED); - } - } - } - - public void Network_LoginProgress(object sender, LoginProgressEventArgs args) - { - if (args.Status == LoginStatus.Success) - { - if (OnConnected != null) - { - OnConnected(this, EventType.CONNECTED); - } - } - } - - public void Network_SimConnected(object sender, SimConnectedEventArgs args) - { - } - - public void Network_OnDisconnected(object sender, DisconnectedEventArgs args) - { - if (OnDisconnected != null) - { - OnDisconnected(this, EventType.DISCONNECTED); - } - } - - public string[] readexcuses() - { - string allexcuses = ""; - - string file = Path.Combine(Util.configDir(), "pCampBotSentences.txt"); - if (File.Exists(file)) - { - StreamReader csr = File.OpenText(file); - allexcuses = csr.ReadToEnd(); - csr.Close(); - } - - return allexcuses.Split(Environment.NewLine.ToCharArray()); - } - } -} diff --git a/OpenSim/TestSuite/README.txt b/OpenSim/TestSuite/README.txt deleted file mode 100644 index cdfa4a7840..0000000000 --- a/OpenSim/TestSuite/README.txt +++ /dev/null @@ -1,25 +0,0 @@ -OpenSim Test Suite ------------------------------------------------------------- - -The eventual goal of the OpenSim Test Suite is to provide a framework -and a set of tests to do system level regression testing of OpenSim. -In short: - -OpenSim Test Suite will have Test Modules (Mono Addins?) that will -verify certain paths in the code. Some early modules may be (subject -to change): - - * Login Tests - - Attempt to Log in 1, 5, 20 bots. - * Basic Walk Tests - - Attempt to Log in and move about in well known tracks - - Repeat with 5, 20 bots - * Basic Construct Tests - - Construct Simple Objects in World - - Ensure bots can see other objects constructed - * Basic Asset Tests - - Construct Simple Objects in World with Textures - - Pull Objects and Textures - - - \ No newline at end of file diff --git a/OpenSim/TestSuite/Util.cs b/OpenSim/TestSuite/Util.cs deleted file mode 100644 index e050c0709b..0000000000 --- a/OpenSim/TestSuite/Util.cs +++ /dev/null @@ -1,81 +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; - -namespace OpenSim.TestSuite -{ - public class Utils - { - enum Result - { - Fail = 0, - Pass = 1, - Skip = 3 - } - - private static String ResultToString(Result r) - { - if (r == Result.Pass) - { - return "PASS"; - } - else if (r == Result.Fail) - { - return "FAIL"; - } - else if (r == Result.Skip) - { - return "SKIP"; - } - else - { - return "UNKNOWN"; - } - } - - private static void TestResult(Result r, String msg) - { - Console.WriteLine("[{0}]: {1}", ResultToString(r), msg); - } - - public static void TestFail(String msg) - { - TestResult(Result.Fail, msg); - } - - public static void TestPass(String msg) - { - TestResult(Result.Pass, msg); - } - - public static void TestSkip(String msg) - { - TestResult(Result.Skip, msg); - } - } -} diff --git a/OpenSim/Tools/pCampBot/BotManager.cs b/OpenSim/Tools/pCampBot/BotManager.cs index 0aaa226bcb..a4b7f16d9f 100644 --- a/OpenSim/Tools/pCampBot/BotManager.cs +++ b/OpenSim/Tools/pCampBot/BotManager.cs @@ -165,18 +165,20 @@ namespace pCampBot /// /// /// - public void handlebotEvent(PhysicsBot callbot, EventType eventt) + private void handlebotEvent(PhysicsBot callbot, EventType eventt) { switch (eventt) { case EventType.CONNECTED: m_log.Info("[" + callbot.FirstName + " " + callbot.LastName + "]: Connected"); numbots++; +// m_log.InfoFormat("NUMBOTS {0}", numbots); break; case EventType.DISCONNECTED: m_log.Info("[" + callbot.FirstName + " " + callbot.LastName + "]: Disconnected"); m_td[m_lBot.IndexOf(callbot)].Abort(); numbots--; +// m_log.InfoFormat("NUMBOTS {0}", numbots); if (numbots <= 0) Environment.Exit(0); break; diff --git a/OpenSim/Tools/pCampBot/PhysicsBot.cs b/OpenSim/Tools/pCampBot/PhysicsBot.cs index 0344a829f3..0c399e355f 100644 --- a/OpenSim/Tools/pCampBot/PhysicsBot.cs +++ b/OpenSim/Tools/pCampBot/PhysicsBot.cs @@ -29,19 +29,23 @@ using System; using System.Collections.Generic; using System.Text; using System.IO; +using System.Reflection; using System.Threading; using System.Timers; +using log4net; using OpenMetaverse; using OpenMetaverse.Assets; using Nini.Config; using OpenSim.Framework; using OpenSim.Framework.Console; -using Timer=System.Timers.Timer; +using Timer = System.Timers.Timer; namespace pCampBot { public class PhysicsBot { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + public delegate void AnEvent(PhysicsBot callbot, EventType someevent); // event delegate for bot events public IConfig startupConfig; // bot config, passed from BotManager @@ -384,6 +388,7 @@ namespace pCampBot public void Network_OnDisconnected(object sender, DisconnectedEventArgs args) { +// m_log.ErrorFormat("Fired Network_OnDisconnected"); if (OnDisconnected != null) { OnDisconnected(this, EventType.DISCONNECTED); diff --git a/prebuild.xml b/prebuild.xml index b9201f7606..bf11b0ffda 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -2549,34 +2549,6 @@ - - - - - ../../bin/ - - - - - ../../bin/ - - - - ../../bin/ - - - - - - - - - - - - - - From b951c7fb1e5a284a9bf95054cb168e64ebfe717d Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Mon, 31 Oct 2011 23:22:55 +0000 Subject: [PATCH 09/17] Make bots share a cache so that asset downloads attempts are only made once instead of once for each bot --- OpenSim/Tools/pCampBot/BotManager.cs | 15 ++++++++++---- OpenSim/Tools/pCampBot/PhysicsBot.cs | 29 +++++++++++++--------------- 2 files changed, 24 insertions(+), 20 deletions(-) diff --git a/OpenSim/Tools/pCampBot/BotManager.cs b/OpenSim/Tools/pCampBot/BotManager.cs index a4b7f16d9f..03bb820e73 100644 --- a/OpenSim/Tools/pCampBot/BotManager.cs +++ b/OpenSim/Tools/pCampBot/BotManager.cs @@ -53,13 +53,20 @@ namespace pCampBot protected bool m_verbose = true; protected Random somthing = new Random(Environment.TickCount); protected int numbots = 0; - private IConfig Config; + public IConfig Config { get; private set; } + + /// + /// Track the assets we have and have not received so we don't endlessly repeat requests. + /// + public Dictionary AssetsReceived { get; private set; } /// /// Constructor Creates MainConsole.Instance to take commands and provide the place to write data /// public BotManager() { + AssetsReceived = new Dictionary(); + m_console = CreateConsole(); MainConsole.Instance = m_console; @@ -113,7 +120,7 @@ namespace pCampBot for (int i = 0; i < botcount; i++) { string lastName = string.Format("{0}_{1}", lastNameStem, i); - startupBot(i, cs, firstName, lastName, password, loginUri); + startupBot(i, this, firstName, lastName, password, loginUri); } } @@ -146,9 +153,9 @@ namespace pCampBot /// Last name /// Password /// Login URI - public void startupBot(int pos, IConfig cs, string firstName, string lastName, string password, string loginUri) + public void startupBot(int pos, BotManager bm, string firstName, string lastName, string password, string loginUri) { - PhysicsBot pb = new PhysicsBot(cs, firstName, lastName, password, loginUri); + PhysicsBot pb = new PhysicsBot(bm, firstName, lastName, password, loginUri); pb.OnConnected += handlebotEvent; pb.OnDisconnected += handlebotEvent; diff --git a/OpenSim/Tools/pCampBot/PhysicsBot.cs b/OpenSim/Tools/pCampBot/PhysicsBot.cs index 0c399e355f..2070bfd784 100644 --- a/OpenSim/Tools/pCampBot/PhysicsBot.cs +++ b/OpenSim/Tools/pCampBot/PhysicsBot.cs @@ -47,7 +47,9 @@ namespace pCampBot private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); public delegate void AnEvent(PhysicsBot callbot, EventType someevent); // event delegate for bot events - public IConfig startupConfig; // bot config, passed from BotManager + + public BotManager BotManager { get; private set; } + private IConfig startupConfig; // bot config, passed from BotManager public string FirstName { get; private set; } public string LastName { get; private set; } @@ -60,11 +62,6 @@ namespace pCampBot public event AnEvent OnConnected; public event AnEvent OnDisconnected; - /// - /// Track the assets we have and have not received so we don't endlessly repeat requests. - /// - public Dictionary AssetsReceived { get; private set; } - protected Timer m_action; // Action Timer protected List objectIDs = new List(); @@ -80,23 +77,23 @@ namespace pCampBot /// /// Constructor /// - /// + /// /// /// /// /// - public PhysicsBot(IConfig bsconfig, string firstName, string lastName, string password, string loginUri) + public PhysicsBot(BotManager bm, string firstName, string lastName, string password, string loginUri) { FirstName = firstName; LastName = lastName; Name = string.Format("{0} {1}", FirstName, LastName); Password = password; LoginUri = loginUri; - startupConfig = bsconfig; + + BotManager = bm; + startupConfig = bm.Config; readconfig(); talkarray = readexcuses(); - - AssetsReceived = new Dictionary(); } //We do our actions here. This is where one would @@ -428,13 +425,13 @@ namespace pCampBot private void GetTexture(UUID textureID) { - lock (AssetsReceived) + lock (BotManager.AssetsReceived) { // Don't request assets more than once. - if (AssetsReceived.ContainsKey(textureID)) + if (BotManager.AssetsReceived.ContainsKey(textureID)) return; - AssetsReceived[textureID] = false; + BotManager.AssetsReceived[textureID] = false; client.Assets.RequestImage(textureID, ImageType.Normal, Asset_TextureCallback_Texture); } } @@ -447,8 +444,8 @@ namespace pCampBot public void Asset_ReceivedCallback(AssetDownload transfer, Asset asset) { - lock (AssetsReceived) - AssetsReceived[asset.AssetID] = true; + lock (BotManager.AssetsReceived) + BotManager.AssetsReceived[asset.AssetID] = true; // if (wear == "save") // { From 3c55f3015f5c9bffa3580abf310fc52598fd7d6f Mon Sep 17 00:00:00 2001 From: Dan Lake Date: Mon, 31 Oct 2011 16:42:28 -0700 Subject: [PATCH 10/17] Removed unused show commands from Scene.cs and SceneBase.cs. The show modules command in OpenSim.cs now shows both shared modules and region modules. --- OpenSim/Region/Application/OpenSim.cs | 13 ++++++++++ OpenSim/Region/Framework/Scenes/Scene.cs | 27 -------------------- OpenSim/Region/Framework/Scenes/SceneBase.cs | 21 --------------- 3 files changed, 13 insertions(+), 48 deletions(-) diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs index 7087cb0009..60c130f3a5 100644 --- a/OpenSim/Region/Application/OpenSim.cs +++ b/OpenSim/Region/Application/OpenSim.cs @@ -1045,6 +1045,19 @@ namespace OpenSim MainConsole.Instance.Output("Shared Module: " + module.Name); } + m_sceneManager.ForEachScene( + delegate(Scene scene) + { + m_log.Error("The currently loaded modules in " + scene.RegionInfo.RegionName + " are:"); + foreach (IRegionModule module in scene.Modules.Values) + { + if (!module.IsSharedModule) + { + m_log.Error("Region Module: " + module.Name); + } + } + }); + MainConsole.Instance.Output(""); break; diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 7a5160c6c3..e054f1b9b6 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -4028,33 +4028,6 @@ namespace OpenSim.Region.Framework.Scenes } } - public override void Show(string[] showParams) - { - base.Show(showParams); - - switch (showParams[0]) - { - case "users": - m_log.Error("Current Region: " + RegionInfo.RegionName); - m_log.ErrorFormat("{0,-16}{1,-16}{2,-25}{3,-25}{4,-16}{5,-16}{6,-16}", "Firstname", "Lastname", - "Agent ID", "Session ID", "Circuit", "IP", "World"); - - ForEachScenePresence(delegate(ScenePresence sp) - { - m_log.ErrorFormat("{0,-16}{1,-16}{2,-25}{3,-25}{4,-16},{5,-16}{6,-16}", - sp.Firstname, - sp.Lastname, - sp.UUID, - sp.ControllingClient.AgentId, - "Unknown", - "Unknown", - RegionInfo.RegionName); - }); - - break; - } - } - #region Script Handling Methods /// diff --git a/OpenSim/Region/Framework/Scenes/SceneBase.cs b/OpenSim/Region/Framework/Scenes/SceneBase.cs index ec94f105cf..dee2ecb291 100644 --- a/OpenSim/Region/Framework/Scenes/SceneBase.cs +++ b/OpenSim/Region/Framework/Scenes/SceneBase.cs @@ -455,27 +455,6 @@ namespace OpenSim.Region.Framework.Scenes #endregion - /// - /// Shows various details about the sim based on the parameters supplied by the console command in openSimMain. - /// - /// What to show - public virtual void Show(string[] showParams) - { - switch (showParams[0]) - { - case "modules": - m_log.Error("The currently loaded modules in " + RegionInfo.RegionName + " are:"); - foreach (IRegionModule module in Modules.Values) - { - if (!module.IsSharedModule) - { - m_log.Error("Region Module: " + module.Name); - } - } - break; - } - } - /// /// Call this from a region module to add a command to the OpenSim console. /// From 87ec8a4ecbafca79841117ba03cced0aa9f82193 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Tue, 1 Nov 2011 18:36:29 +0000 Subject: [PATCH 11/17] Retain a reference to an action thread rather than starting an infinite loop via a timer, so that we can actually abort the action thread on shutdown --- OpenSim/Tools/pCampBot/PhysicsBot.cs | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/OpenSim/Tools/pCampBot/PhysicsBot.cs b/OpenSim/Tools/pCampBot/PhysicsBot.cs index 2070bfd784..945697b57b 100644 --- a/OpenSim/Tools/pCampBot/PhysicsBot.cs +++ b/OpenSim/Tools/pCampBot/PhysicsBot.cs @@ -62,7 +62,11 @@ namespace pCampBot public event AnEvent OnConnected; public event AnEvent OnDisconnected; - protected Timer m_action; // Action Timer + /// + /// Keep a track of the continuously acting thread so that we can abort it. + /// + private Thread m_actionThread; + protected List objectIDs = new List(); protected Random somthing = new Random(Environment.TickCount);// We do stuff randomly here @@ -98,8 +102,7 @@ namespace pCampBot //We do our actions here. This is where one would //add additional steps and/or things the bot should do - - void m_action_Elapsed(object sender, ElapsedEventArgs e) + private void Action() { while (true) { @@ -145,6 +148,9 @@ namespace pCampBot /// public void shutdown() { + if (m_actionThread != null) + m_actionThread.Abort(); + client.Network.Logout(); } @@ -177,11 +183,10 @@ namespace pCampBot { if (OnConnected != null) { - m_action = new Timer(somthing.Next(1000, 10000)); - m_action.Enabled = true; - m_action.AutoReset = false; - m_action.Elapsed += new ElapsedEventHandler(m_action_Elapsed); - m_action.Start(); + Thread.Sleep(somthing.Next(1000, 10000)); + m_actionThread = new Thread(Action); + m_actionThread.Start(); + // OnConnected(this, EventType.CONNECTED); if (wear == "save") { @@ -386,6 +391,13 @@ namespace pCampBot public void Network_OnDisconnected(object sender, DisconnectedEventArgs args) { // m_log.ErrorFormat("Fired Network_OnDisconnected"); + + // Only pass on the disconnect message when we receive a SimShutdown type shutdown. We have to ignore + // the earlier ClientInitiated shutdown callback. +// if ( +// (args.Reason == NetworkManager.DisconnectType.SimShutdown +// || args.Reason == NetworkManager.DisconnectType.NetworkTimeout) +// && OnDisconnected != null) if (OnDisconnected != null) { OnDisconnected(this, EventType.DISCONNECTED); From 12bd0ebd3416a60faeec77bfcd3cb48c33ed5cce Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Tue, 1 Nov 2011 21:15:47 +0000 Subject: [PATCH 12/17] stop recording the threads on which we happen to start bots. These are pointless since they terminate quickly --- OpenSim/Tools/pCampBot/BotManager.cs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/OpenSim/Tools/pCampBot/BotManager.cs b/OpenSim/Tools/pCampBot/BotManager.cs index 03bb820e73..bfb664ff1c 100644 --- a/OpenSim/Tools/pCampBot/BotManager.cs +++ b/OpenSim/Tools/pCampBot/BotManager.cs @@ -49,7 +49,6 @@ namespace pCampBot protected CommandConsole m_console; protected List m_lBot; - protected Thread[] m_td; protected bool m_verbose = true; protected Random somthing = new Random(Environment.TickCount); protected int numbots = 0; @@ -110,7 +109,6 @@ namespace pCampBot public void dobotStartup(int botcount, IConfig cs) { Config = cs; - m_td = new Thread[botcount]; string firstName = cs.GetString("firstname"); string lastNameStem = cs.GetString("lastname"); @@ -160,11 +158,12 @@ namespace pCampBot pb.OnConnected += handlebotEvent; pb.OnDisconnected += handlebotEvent; - m_td[pos] = new Thread(pb.startup); - m_td[pos].Name = pb.Name; - m_td[pos].IsBackground = true; - m_td[pos].Start(); m_lBot.Add(pb); + + Thread pbThread = new Thread(pb.startup); + pbThread.Name = pb.Name; + pbThread.IsBackground = true; + pbThread.Start(); } /// @@ -183,7 +182,6 @@ namespace pCampBot break; case EventType.DISCONNECTED: m_log.Info("[" + callbot.FirstName + " " + callbot.LastName + "]: Disconnected"); - m_td[m_lBot.IndexOf(callbot)].Abort(); numbots--; // m_log.InfoFormat("NUMBOTS {0}", numbots); if (numbots <= 0) From 53f3b76a84e6fb90b1f197977054a16ec86ccc7f Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Tue, 1 Nov 2011 21:18:28 +0000 Subject: [PATCH 13/17] get rid of unused m_verbose field --- OpenSim/Tools/pCampBot/BotManager.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/OpenSim/Tools/pCampBot/BotManager.cs b/OpenSim/Tools/pCampBot/BotManager.cs index bfb664ff1c..d2b7ded9df 100644 --- a/OpenSim/Tools/pCampBot/BotManager.cs +++ b/OpenSim/Tools/pCampBot/BotManager.cs @@ -49,7 +49,6 @@ namespace pCampBot protected CommandConsole m_console; protected List m_lBot; - protected bool m_verbose = true; protected Random somthing = new Random(Environment.TickCount); protected int numbots = 0; public IConfig Config { get; private set; } From 40750b44a09c9970497657c3a847af2d92c8b385 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Tue, 1 Nov 2011 21:47:14 +0000 Subject: [PATCH 14/17] Listen only for non SimShutdown Network.Disconnect firing so that we don't quite the program before all bots have actually logged off. --- OpenSim/Tools/pCampBot/PhysicsBot.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/OpenSim/Tools/pCampBot/PhysicsBot.cs b/OpenSim/Tools/pCampBot/PhysicsBot.cs index 945697b57b..5bcd35d01a 100644 --- a/OpenSim/Tools/pCampBot/PhysicsBot.cs +++ b/OpenSim/Tools/pCampBot/PhysicsBot.cs @@ -398,7 +398,13 @@ namespace pCampBot // (args.Reason == NetworkManager.DisconnectType.SimShutdown // || args.Reason == NetworkManager.DisconnectType.NetworkTimeout) // && OnDisconnected != null) - if (OnDisconnected != null) + + if ( + (args.Reason == NetworkManager.DisconnectType.ClientInitiated + || args.Reason == NetworkManager.DisconnectType.ServerInitiated + || args.Reason == NetworkManager.DisconnectType.NetworkTimeout) + && OnDisconnected != null) +// if (OnDisconnected != null) { OnDisconnected(this, EventType.DISCONNECTED); } From 8e2e4c47d95728ba25694a85454488074360445e Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Tue, 1 Nov 2011 22:09:21 +0000 Subject: [PATCH 15/17] Add "show status" command to pCambot --- OpenSim/Tools/pCampBot/BotManager.cs | 30 ++++++++++++++++++---- OpenSim/Tools/pCampBot/PhysicsBot.cs | 37 +++++++++++++++------------- 2 files changed, 45 insertions(+), 22 deletions(-) diff --git a/OpenSim/Tools/pCampBot/BotManager.cs b/OpenSim/Tools/pCampBot/BotManager.cs index d2b7ded9df..b05bd6d958 100644 --- a/OpenSim/Tools/pCampBot/BotManager.cs +++ b/OpenSim/Tools/pCampBot/BotManager.cs @@ -93,6 +93,11 @@ namespace pCampBot "Shutdown bots and exit", HandleShutdown); + m_console.Commands.AddCommand("bot", false, "show status", + "show status", + "Shows the status of all bots", + HandleShowStatus); + // m_console.Commands.AddCommand("bot", false, "add bots", // "add bots ", // "Add more bots", HandleAddBots); @@ -157,7 +162,8 @@ namespace pCampBot pb.OnConnected += handlebotEvent; pb.OnDisconnected += handlebotEvent; - m_lBot.Add(pb); + lock (m_lBot) + m_lBot.Add(pb); Thread pbThread = new Thread(pb.startup); pbThread.Name = pb.Name; @@ -194,10 +200,9 @@ namespace pCampBot /// public void doBotShutdown() { - foreach (PhysicsBot pb in m_lBot) - { - pb.shutdown(); - } + lock (m_lBot) + foreach (PhysicsBot pb in m_lBot) + pb.shutdown(); } /// @@ -215,6 +220,21 @@ namespace pCampBot doBotShutdown(); } + private void HandleShowStatus(string module, string[] cmd) + { + string outputFormat = "{0,-30} {1,-14}"; + MainConsole.Instance.OutputFormat(outputFormat, "Name", "Status"); + + lock (m_lBot) + { + foreach (PhysicsBot pb in m_lBot) + { + MainConsole.Instance.OutputFormat( + outputFormat, pb.Name, (pb.IsConnected ? "Connected" : "Disconnected")); + } + } + } + /* private void HandleQuit(string module, string[] cmd) { diff --git a/OpenSim/Tools/pCampBot/PhysicsBot.cs b/OpenSim/Tools/pCampBot/PhysicsBot.cs index 5bcd35d01a..14e9cca58d 100644 --- a/OpenSim/Tools/pCampBot/PhysicsBot.cs +++ b/OpenSim/Tools/pCampBot/PhysicsBot.cs @@ -51,6 +51,11 @@ namespace pCampBot public BotManager BotManager { get; private set; } private IConfig startupConfig; // bot config, passed from BotManager + /// + /// Is this bot connected to the grid? + /// + public bool IsConnected { get; private set; } + public string FirstName { get; private set; } public string LastName { get; private set; } public string Name { get; private set; } @@ -181,24 +186,23 @@ namespace pCampBot if (client.Network.Login(FirstName, LastName, Password, "pCampBot", "Your name")) { - if (OnConnected != null) - { - Thread.Sleep(somthing.Next(1000, 10000)); - m_actionThread = new Thread(Action); - m_actionThread.Start(); + IsConnected = true; + + Thread.Sleep(somthing.Next(1000, 10000)); + m_actionThread = new Thread(Action); + m_actionThread.Start(); // OnConnected(this, EventType.CONNECTED); - if (wear == "save") - { - client.Appearance.SetPreviousAppearance(); - SaveDefaultAppearance(); - } - else if (wear != "no") - { - MakeDefaultAppearance(wear); - } - client.Self.Jump(true); + if (wear == "save") + { + client.Appearance.SetPreviousAppearance(); + SaveDefaultAppearance(); } + else if (wear != "no") + { + MakeDefaultAppearance(wear); + } + client.Self.Jump(true); } else { @@ -392,8 +396,6 @@ namespace pCampBot { // m_log.ErrorFormat("Fired Network_OnDisconnected"); - // Only pass on the disconnect message when we receive a SimShutdown type shutdown. We have to ignore - // the earlier ClientInitiated shutdown callback. // if ( // (args.Reason == NetworkManager.DisconnectType.SimShutdown // || args.Reason == NetworkManager.DisconnectType.NetworkTimeout) @@ -406,6 +408,7 @@ namespace pCampBot && OnDisconnected != null) // if (OnDisconnected != null) { + IsConnected = false; OnDisconnected(this, EventType.DISCONNECTED); } } From 9456a540c50b90d2c2cdb1b556e9d6190f817426 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Tue, 1 Nov 2011 23:23:45 +0000 Subject: [PATCH 16/17] Add "appearance send" command to allow manual sending of appearance. --- .../Region/Framework/Scenes/ScenePresence.cs | 6 +++--- .../Avatar/Appearance/AppearanceInfoModule.cs | 19 ++++++++++++++++++- OpenSim/Tools/pCampBot/PhysicsBot.cs | 4 ++-- 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index bb820aa733..29966f9722 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -2575,7 +2575,7 @@ namespace OpenSim.Region.Framework.Scenes // only send update from root agents to other clients; children are only "listening posts" if (IsChildAgent) { - m_log.Warn("[SCENE PRESENCE] attempt to send avatar data from a child agent"); + m_log.Warn("[SCENE PRESENCE]: Attempt to send avatar data from a child agent"); return; } @@ -2632,10 +2632,10 @@ namespace OpenSim.Region.Framework.Scenes // only send update from root agents to other clients; children are only "listening posts" if (IsChildAgent) { - m_log.Warn("[SCENE PRESENCE] attempt to send avatar data from a child agent"); + m_log.Warn("[SCENE PRESENCE]: Attempt to send avatar data from a child agent"); return; } - + int count = 0; m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence) { diff --git a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs index 2cef8a9f8b..f8120aaa39 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs @@ -98,7 +98,24 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance "Show appearance information for each avatar in the simulator.", "At the moment this actually just checks that we have all the required baked textures. If not, then appearance is 'corrupt' and other avatars will continue to see a cloud.", ShowAppearanceInfo); - } + + scene.AddCommand( + this, "appearance send", + "appearance send", + "Send appearance data for each avatar in the simulator to viewers.", + SendAppearance); + } + + private void SendAppearance(string module, string[] cmd) + { + lock (m_scenes) + { + foreach (Scene scene in m_scenes.Values) + { + scene.ForEachRootScenePresence(sp => scene.AvatarFactory.SendAppearance(sp.UUID)); + } + } + } protected void ShowAppearanceInfo(string module, string[] cmd) { diff --git a/OpenSim/Tools/pCampBot/PhysicsBot.cs b/OpenSim/Tools/pCampBot/PhysicsBot.cs index 14e9cca58d..a8b24266a2 100644 --- a/OpenSim/Tools/pCampBot/PhysicsBot.cs +++ b/OpenSim/Tools/pCampBot/PhysicsBot.cs @@ -124,11 +124,11 @@ namespace pCampBot } // TODO: unused: Vector3 pos = client.Self.SimPosition; - Vector3 newpos = new Vector3(somthing.Next(255), somthing.Next(255), somthing.Next(255)); + Vector3 newpos = new Vector3(somthing.Next(1, 254), somthing.Next(1, 254), somthing.Next(1, 254)); client.Self.Movement.TurnToward(newpos); client.Self.Movement.AtPos = true; - Thread.Sleep(somthing.Next(3000,13000)); + Thread.Sleep(somthing.Next(3000, 13000)); client.Self.Movement.AtPos = false; client.Self.Jump(true); From 4b58d4ff95891e5d0f15801c8a48c57309925738 Mon Sep 17 00:00:00 2001 From: Dan Lake Date: Tue, 1 Nov 2011 16:51:14 -0700 Subject: [PATCH 17/17] Removed see_into_this_sim_from_neighbor configuration option. --- OpenSim/Region/Framework/Scenes/Scene.cs | 10 ---------- OpenSim/Region/Framework/Scenes/SceneViewer.cs | 2 +- bin/OpenSimDefaults.ini | 3 --- 3 files changed, 1 insertion(+), 14 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index e054f1b9b6..086de53103 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -86,7 +86,6 @@ namespace OpenSim.Region.Framework.Scenes public bool m_allowScriptCrossings; public bool m_useFlySlow; public bool m_usePreJump; - public bool m_seeIntoRegionFromNeighbor; protected float m_defaultDrawDistance = 255.0f; public float DefaultDrawDistance @@ -638,14 +637,6 @@ namespace OpenSim.Region.Framework.Scenes m_physics_enabled = !RegionInfo.RegionSettings.DisablePhysics; - // Old - /* - m_simulatorVersion = simulatorVersion - + " (OS " + Util.GetOperatingSystemInformation() + ")" - + " ChilTasks:" + m_seeIntoRegionFromNeighbor.ToString() - + " PhysPrim:" + m_physicalPrim.ToString(); - */ - m_simulatorVersion = simulatorVersion + " (" + Util.GetRuntimeInformation() + ")"; #region Region Config @@ -690,7 +681,6 @@ namespace OpenSim.Region.Framework.Scenes m_clampPrimSize = true; } - m_seeIntoRegionFromNeighbor = startupConfig.GetBoolean("see_into_this_sim_from_neighbor", true); m_trustBinaries = startupConfig.GetBoolean("TrustBinaries", m_trustBinaries); m_allowScriptCrossings = startupConfig.GetBoolean("AllowScriptCrossing", m_allowScriptCrossings); m_dontPersistBefore = diff --git a/OpenSim/Region/Framework/Scenes/SceneViewer.cs b/OpenSim/Region/Framework/Scenes/SceneViewer.cs index 50e1e39afe..ded90a3735 100644 --- a/OpenSim/Region/Framework/Scenes/SceneViewer.cs +++ b/OpenSim/Region/Framework/Scenes/SceneViewer.cs @@ -84,7 +84,7 @@ namespace OpenSim.Region.Framework.Scenes { if (m_pendingObjects == null) { - if (!m_presence.IsChildAgent || (m_presence.Scene.m_seeIntoRegionFromNeighbor)) + if (!m_presence.IsChildAgent) { m_pendingObjects = new Queue(); diff --git a/bin/OpenSimDefaults.ini b/bin/OpenSimDefaults.ini index db2a551b27..d79cb1e3ca 100644 --- a/bin/OpenSimDefaults.ini +++ b/bin/OpenSimDefaults.ini @@ -170,9 +170,6 @@ ; Objects will always be considered for persistance in the next sweep if the first change occurred this number of seconds ago MaximumTimeBeforePersistenceConsidered = 600 - ; Should avatars in neighbor sims see objects in this sim? - see_into_this_sim_from_neighbor = true - ; ## ; ## PHYSICS ; ##