LLUDPServerCommands.cs 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844
  1. /*
  2. * Copyright (c) Contributors, http://opensimulator.org/
  3. * See CONTRIBUTORS.TXT for a full list of copyright holders.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are met:
  7. * * Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * * Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. * * Neither the name of the OpenSimulator Project nor the
  13. * names of its contributors may be used to endorse or promote products
  14. * derived from this software without specific prior written permission.
  15. *
  16. * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
  17. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  18. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  19. * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
  20. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  21. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  22. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  23. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  24. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  25. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26. */
  27. using System;
  28. using System.Collections.Generic;
  29. using System.Text;
  30. using NDesk.Options;
  31. using OpenSim.Framework;
  32. using OpenSim.Framework.Console;
  33. using OpenSim.Region.Framework.Scenes;
  34. namespace OpenSim.Region.ClientStack.LindenUDP
  35. {
  36. public class LLUDPServerCommands
  37. {
  38. private readonly ICommandConsole m_console;
  39. private readonly LLUDPServer m_udpServer;
  40. public LLUDPServerCommands(ICommandConsole console, LLUDPServer udpServer)
  41. {
  42. m_console = console;
  43. m_udpServer = udpServer;
  44. }
  45. public void Register()
  46. {
  47. /*
  48. m_console.Commands.AddCommand(
  49. "Comms", false, "show server throttles",
  50. "show server throttles",
  51. "Show information about server throttles",
  52. HandleShowServerThrottlesCommand);
  53. m_console.Commands.AddCommand(
  54. "Debug", false, "debug lludp packet",
  55. "debug lludp packet [--default | --all] <level> [<avatar-first-name> <avatar-last-name>]",
  56. "Turn on packet debugging. This logs information when the client stack hands a processed packet off to downstream code or when upstream code first requests that a certain packet be sent.",
  57. "If level > 255 then all incoming and outgoing packets are logged.\n"
  58. + "If level <= 255 then incoming AgentUpdate and outgoing SimStats and SimulatorViewerTimeMessage packets are not logged.\n"
  59. + "If level <= 200 then incoming RequestImage and outgoing ImagePacket, ImageData, LayerData and CoarseLocationUpdate packets are not logged.\n"
  60. + "If level <= 100 then incoming ViewerEffect and AgentAnimation and outgoing ViewerEffect and AvatarAnimation packets are not logged.\n"
  61. + "If level <= 50 then outgoing ImprovedTerseObjectUpdate packets are not logged.\n"
  62. + "If level <= 0 then no packets are logged.\n"
  63. + "If --default is specified then the level becomes the default logging level for all subsequent agents.\n"
  64. + "If --all is specified then the level becomes the default logging level for all current and subsequent agents.\n"
  65. + "In these cases, you cannot also specify an avatar name.\n"
  66. + "If an avatar name is given then only packets from that avatar are logged.",
  67. HandlePacketCommand);
  68. m_console.Commands.AddCommand(
  69. "Debug", false, "debug lludp data out",
  70. "debug lludp data out <level> <avatar-first-name> <avatar-last-name>\"",
  71. "Turn on debugging for final outgoing data to the given user's client.",
  72. "This operates at a much lower level than the packet command and prints out available details when the data is actually sent.\n"
  73. + "If level > 0 then information about all outgoing UDP data for this avatar is logged.\n"
  74. + "If level <= 0 then no information about outgoing UDP data for this avatar is logged.",
  75. HandleDataCommand);
  76. m_console.Commands.AddCommand(
  77. "Debug", false, "debug lludp drop",
  78. "debug lludp drop <in|out> <add|remove> <packet-name>",
  79. "Drop all in or outbound packets that match the given name",
  80. "For test purposes.",
  81. HandleDropCommand);
  82. m_console.Commands.AddCommand(
  83. "Debug",
  84. false,
  85. "debug lludp start",
  86. "debug lludp start <in|out|all>",
  87. "Control LLUDP packet processing.",
  88. "No effect if packet processing has already started.\n"
  89. + "in - start inbound processing.\n"
  90. + "out - start outbound processing.\n"
  91. + "all - start in and outbound processing.\n",
  92. HandleStartCommand);
  93. m_console.Commands.AddCommand(
  94. "Debug",
  95. false,
  96. "debug lludp stop",
  97. "debug lludp stop <in|out|all>",
  98. "Stop LLUDP packet processing.",
  99. "No effect if packet processing has already stopped.\n"
  100. + "in - stop inbound processing.\n"
  101. + "out - stop outbound processing.\n"
  102. + "all - stop in and outbound processing.\n",
  103. HandleStopCommand);
  104. m_console.Commands.AddCommand(
  105. "Debug",
  106. false,
  107. "debug lludp pool",
  108. "debug lludp pool <on|off>",
  109. "Turn object pooling within the lludp component on or off.",
  110. HandlePoolCommand);
  111. m_console.Commands.AddCommand(
  112. "Debug",
  113. false,
  114. "debug lludp status",
  115. "debug lludp status",
  116. "Return status of LLUDP packet processing.",
  117. HandleStatusCommand);
  118. m_console.Commands.AddCommand(
  119. "Debug",
  120. false,
  121. "debug lludp throttles log",
  122. "debug lludp throttles log <level> [<avatar-first-name> <avatar-last-name>]",
  123. "Change debug logging level for throttles.",
  124. "If level >= 0 then throttle debug logging is performed.\n"
  125. + "If level <= 0 then no throttle debug logging is performed.",
  126. HandleThrottleCommand);
  127. m_console.Commands.AddCommand(
  128. "Debug",
  129. false,
  130. "debug lludp throttles get",
  131. "debug lludp throttles get [<avatar-first-name> <avatar-last-name>]",
  132. "Return debug settings for throttles.",
  133. "adaptive - true/false, controls adaptive throttle setting.\n"
  134. + "request - request drip rate in kbps.\n"
  135. + "max - the max kbps throttle allowed for the specified existing clients. Use 'debug lludp get new-client-throttle-max' to see the setting for new clients.\n",
  136. HandleThrottleGetCommand);
  137. m_console.Commands.AddCommand(
  138. "Debug",
  139. false,
  140. "debug lludp throttles set",
  141. "debug lludp throttles set <param> <value> [<avatar-first-name> <avatar-last-name>]",
  142. "Set a throttle parameter for the given client.",
  143. "adaptive - true/false, controls adaptive throttle setting.\n"
  144. + "current - current drip rate in kbps.\n"
  145. + "request - requested drip rate in kbps.\n"
  146. + "max - the max kbps throttle allowed for the specified existing clients. Use 'debug lludp set new-client-throttle-max' to change the settings for new clients.\n",
  147. HandleThrottleSetCommand);
  148. m_console.Commands.AddCommand(
  149. "Debug",
  150. false,
  151. "debug lludp get",
  152. "debug lludp get",
  153. "Get debug parameters for the server.",
  154. "max-scene-throttle - the current max cumulative kbps provided for this scene to clients.\n"
  155. + "max-new-client-throttle - the max kbps throttle allowed to new clients. Use 'debug lludp throttles get max' to see the settings for existing clients.",
  156. HandleGetCommand);
  157. m_console.Commands.AddCommand(
  158. "Debug",
  159. false,
  160. "debug lludp set",
  161. "debug lludp set <param> <value>",
  162. "Set a parameter for the server.",
  163. "max-scene-throttle - the current max cumulative kbps provided for this scene to clients.\n"
  164. + "max-new-client-throttle - the max kbps throttle allowed to each new client. Use 'debug lludp throttles set max' to set for existing clients.",
  165. HandleSetCommand);
  166. m_console.Commands.AddCommand(
  167. "Debug",
  168. false,
  169. "debug lludp toggle agentupdate",
  170. "debug lludp toggle agentupdate",
  171. "Toggle whether agentupdate packets are processed or simply discarded.",
  172. HandleAgentUpdateCommand);
  173. MainConsole.Instance.Commands.AddCommand(
  174. "Debug",
  175. false,
  176. "debug lludp oqre",
  177. "debug lludp oqre <start|stop|status>",
  178. "Start, stop or get status of OutgoingQueueRefillEngine.",
  179. "If stopped then refill requests are processed directly via the threadpool.",
  180. HandleOqreCommand);
  181. m_console.Commands.AddCommand(
  182. "Debug",
  183. false,
  184. "debug lludp client get",
  185. "debug lludp client get [<avatar-first-name> <avatar-last-name>]",
  186. "Get debug parameters for the client. If no name is given then all client information is returned.",
  187. "process-unacked-sends - Do we take action if a sent reliable packet has not been acked.",
  188. HandleClientGetCommand);
  189. m_console.Commands.AddCommand(
  190. "Debug",
  191. false,
  192. "debug lludp client set",
  193. "debug lludp client set <param> <value> [<avatar-first-name> <avatar-last-name>]",
  194. "Set a debug parameter for a particular client. If no name is given then the value is set on all clients.",
  195. "process-unacked-sends - Do we take action if a sent reliable packet has not been acked.",
  196. HandleClientSetCommand);
  197. */
  198. }
  199. private void HandleShowServerThrottlesCommand(string module, string[] args)
  200. {
  201. if (SceneManager.Instance.CurrentScene is not null &&
  202. SceneManager.Instance.CurrentScene != m_udpServer.Scene)
  203. return;
  204. m_console.Output("Throttles for {0}", m_udpServer.Scene.Name);
  205. ConsoleDisplayList cdl = new();
  206. cdl.AddRow("Adaptive throttles", m_udpServer.ThrottleRates.AdaptiveThrottlesEnabled);
  207. long maxSceneDripRate = (long)m_udpServer.Throttle.MaxDripRate;
  208. cdl.AddRow(
  209. "Max scene throttle",
  210. maxSceneDripRate != 0 ? string.Format("{0} kbps", maxSceneDripRate * 8 / 1000) : "unset");
  211. int maxClientDripRate = m_udpServer.ThrottleRates.Total;
  212. cdl.AddRow(
  213. "Max new client throttle",
  214. maxClientDripRate != 0 ? string.Format("{0} kbps", maxClientDripRate * 8 / 1000) : "unset");
  215. m_console.Output(cdl.ToString());
  216. m_console.Output("{0}\n", GetServerThrottlesReport(m_udpServer));
  217. }
  218. private string GetServerThrottlesReport(LLUDPServer udpServer)
  219. {
  220. StringBuilder report = new();
  221. report.AppendFormat(
  222. "{0,7} {1,8} {2,7} {3,7} {4,7} {5,7} {6,9} {7,7}\n",
  223. "Total",
  224. "Resend",
  225. "Land",
  226. "Wind",
  227. "Cloud",
  228. "Task",
  229. "Texture",
  230. "Asset");
  231. report.AppendFormat(
  232. "{0,7} {1,8} {2,7} {3,7} {4,7} {5,7} {6,9} {7,7}\n",
  233. "kb/s",
  234. "kb/s",
  235. "kb/s",
  236. "kb/s",
  237. "kb/s",
  238. "kb/s",
  239. "kb/s",
  240. "kb/s");
  241. ThrottleRates throttleRates = udpServer.ThrottleRates;
  242. report.AppendFormat(
  243. "{0,7} {1,8} {2,7} {3,7} {4,7} {5,7} {6,9} {7,7}",
  244. (throttleRates.Total * 8) / 1000,
  245. (throttleRates.Resend * 8) / 1000,
  246. (throttleRates.Land * 8) / 1000,
  247. (throttleRates.Wind * 8) / 1000,
  248. (throttleRates.Cloud * 8) / 1000,
  249. (throttleRates.Task * 8) / 1000,
  250. (throttleRates.Texture * 8) / 1000,
  251. (throttleRates.Asset * 8) / 1000);
  252. return report.ToString();
  253. }
  254. protected string GetColumnEntry(string entry, int maxLength, int columnPadding)
  255. {
  256. return string.Format(
  257. "{0,-" + maxLength + "}{1,-" + columnPadding + "}",
  258. entry.Length > maxLength ? entry.Substring(0, maxLength) : entry,
  259. "");
  260. }
  261. private void HandleDataCommand(string module, string[] args)
  262. {
  263. if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene)
  264. return;
  265. if (args.Length != 7)
  266. {
  267. MainConsole.Instance.Output("Usage: debug lludp data out <true|false> <avatar-first-name> <avatar-last-name>");
  268. return;
  269. }
  270. if (!ConsoleUtil.TryParseConsoleInt(MainConsole.Instance, args[4], out int level))
  271. return;
  272. string firstName = args[5];
  273. string lastName = args[6];
  274. m_udpServer.Scene.ForEachScenePresence(sp =>
  275. {
  276. if (sp.Firstname == firstName && sp.Lastname == lastName)
  277. {
  278. MainConsole.Instance.Output(
  279. "Data debug for {0} ({1}) set to {2} in {3}",
  280. sp.Name, sp.IsChildAgent ? "child" : "root", level, m_udpServer.Scene.Name);
  281. ((LLClientView)sp.ControllingClient).UDPClient.DebugDataOutLevel = level;
  282. }
  283. });
  284. }
  285. private void HandleThrottleCommand(string module, string[] args)
  286. {
  287. if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene)
  288. return;
  289. bool all = args.Length == 5;
  290. bool one = args.Length == 7;
  291. if (!all && !one)
  292. {
  293. MainConsole.Instance.Output(
  294. "Usage: debug lludp throttles log <level> [<avatar-first-name> <avatar-last-name>]");
  295. return;
  296. }
  297. if (!ConsoleUtil.TryParseConsoleInt(MainConsole.Instance, args[4], out int level))
  298. return;
  299. string firstName = null;
  300. string lastName = null;
  301. if (one)
  302. {
  303. firstName = args[5];
  304. lastName = args[6];
  305. }
  306. m_udpServer.Scene.ForEachScenePresence(sp =>
  307. {
  308. if (all || (sp.Firstname == firstName && sp.Lastname == lastName))
  309. {
  310. MainConsole.Instance.Output(
  311. "Throttle log level for {0} ({1}) set to {2} in {3}",
  312. sp.Name, sp.IsChildAgent ? "child" : "root", level, m_udpServer.Scene.Name);
  313. ((LLClientView)sp.ControllingClient).UDPClient.ThrottleDebugLevel = level;
  314. }
  315. });
  316. }
  317. private void HandleThrottleSetCommand(string module, string[] args)
  318. {
  319. if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene)
  320. return;
  321. bool all = args.Length == 6;
  322. bool one = args.Length == 8;
  323. if (!all && !one)
  324. {
  325. MainConsole.Instance.Output(
  326. "Usage: debug lludp throttles set <param> <value> [<avatar-first-name> <avatar-last-name>]");
  327. return;
  328. }
  329. string param = args[4];
  330. string rawValue = args[5];
  331. string firstName = null;
  332. string lastName = null;
  333. if (one)
  334. {
  335. firstName = args[6];
  336. lastName = args[7];
  337. }
  338. if (param == "adaptive")
  339. {
  340. if (!ConsoleUtil.TryParseConsoleBool(MainConsole.Instance, rawValue, out bool newValue))
  341. return;
  342. m_udpServer.Scene.ForEachScenePresence(sp =>
  343. {
  344. if (all || (sp.Firstname == firstName && sp.Lastname == lastName))
  345. {
  346. MainConsole.Instance.Output(
  347. "Setting param {0} to {1} for {2} ({3}) in {4}",
  348. param, newValue, sp.Name, sp.IsChildAgent ? "child" : "root", m_udpServer.Scene.Name);
  349. LLUDPClient udpClient = ((LLClientView)sp.ControllingClient).UDPClient;
  350. udpClient.FlowThrottle.AdaptiveEnabled = newValue;
  351. //udpClient.FlowThrottle.MaxDripRate = 0;
  352. //udpClient.FlowThrottle.AdjustedDripRate = 0;
  353. }
  354. });
  355. }
  356. else if (param == "request")
  357. {
  358. if (!ConsoleUtil.TryParseConsoleInt(MainConsole.Instance, rawValue, out int newValue))
  359. return;
  360. int newCurrentThrottleKbps = newValue * 1000 / 8;
  361. m_udpServer.Scene.ForEachScenePresence(sp =>
  362. {
  363. if (all || (sp.Firstname == firstName && sp.Lastname == lastName))
  364. {
  365. MainConsole.Instance.Output(
  366. "Setting param {0} to {1} for {2} ({3}) in {4}",
  367. param, newValue, sp.Name, sp.IsChildAgent ? "child" : "root", m_udpServer.Scene.Name);
  368. LLUDPClient udpClient = ((LLClientView)sp.ControllingClient).UDPClient;
  369. udpClient.FlowThrottle.RequestedDripRate = newCurrentThrottleKbps;
  370. }
  371. });
  372. }
  373. else if (param == "max")
  374. {
  375. if (!ConsoleUtil.TryParseConsoleInt(MainConsole.Instance, rawValue, out int newValue))
  376. return;
  377. int newThrottleMaxKbps = newValue * 1000 / 8;
  378. m_udpServer.Scene.ForEachScenePresence(sp =>
  379. {
  380. if (all || (sp.Firstname == firstName && sp.Lastname == lastName))
  381. {
  382. MainConsole.Instance.Output(
  383. "Setting param {0} to {1} for {2} ({3}) in {4}",
  384. param, newValue, sp.Name, sp.IsChildAgent ? "child" : "root", m_udpServer.Scene.Name);
  385. LLUDPClient udpClient = ((LLClientView)sp.ControllingClient).UDPClient;
  386. udpClient.FlowThrottle.MaxDripRate = newThrottleMaxKbps;
  387. }
  388. });
  389. }
  390. }
  391. private void HandleThrottleGetCommand(string module, string[] args)
  392. {
  393. if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene)
  394. return;
  395. bool all = args.Length == 4;
  396. bool one = args.Length == 6;
  397. if (!all && !one)
  398. {
  399. MainConsole.Instance.Output(
  400. "Usage: debug lludp throttles get [<avatar-first-name> <avatar-last-name>]");
  401. return;
  402. }
  403. string firstName = null;
  404. string lastName = null;
  405. if (one)
  406. {
  407. firstName = args[4];
  408. lastName = args[5];
  409. }
  410. m_udpServer.Scene.ForEachScenePresence(sp =>
  411. {
  412. if (all || (sp.Firstname == firstName && sp.Lastname == lastName))
  413. {
  414. m_console.Output(
  415. "Status for {0} ({1}) in {2}",
  416. sp.Name, sp.IsChildAgent ? "child" : "root", m_udpServer.Scene.Name);
  417. LLUDPClient udpClient = ((LLClientView)sp.ControllingClient).UDPClient;
  418. ConsoleDisplayList cdl = new();
  419. cdl.AddRow("adaptive", udpClient.FlowThrottle.AdaptiveEnabled);
  420. cdl.AddRow("current", string.Format("{0} kbps", udpClient.FlowThrottle.DripRate * 8 / 1000));
  421. cdl.AddRow("request", string.Format("{0} kbps", udpClient.FlowThrottle.RequestedDripRate * 8 / 1000));
  422. cdl.AddRow("max", string.Format("{0} kbps", udpClient.FlowThrottle.MaxDripRate * 8 / 1000));
  423. m_console.Output(cdl.ToString());
  424. }
  425. });
  426. }
  427. private void HandleGetCommand(string module, string[] args)
  428. {
  429. if (SceneManager.Instance.CurrentScene is not null &&
  430. SceneManager.Instance.CurrentScene != m_udpServer.Scene)
  431. return;
  432. m_console.Output("Debug settings for {0}", m_udpServer.Scene.Name);
  433. ConsoleDisplayList cdl = new();
  434. long maxSceneDripRate = (long)m_udpServer.Throttle.MaxDripRate;
  435. cdl.AddRow(
  436. "max-scene-throttle",
  437. maxSceneDripRate != 0 ? string.Format("{0} kbps", maxSceneDripRate * 8 / 1000) : "unset");
  438. int maxClientDripRate = m_udpServer.ThrottleRates.Total;
  439. cdl.AddRow(
  440. "max-new-client-throttle",
  441. maxClientDripRate != 0 ? string.Format("{0} kbps", maxClientDripRate * 8 / 1000) : "unset");
  442. m_console.Output(cdl.ToString());
  443. }
  444. private void HandleSetCommand(string module, string[] args)
  445. {
  446. if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene)
  447. return;
  448. if (args.Length != 5)
  449. {
  450. MainConsole.Instance.Output("Usage: debug lludp set <param> <value>");
  451. return;
  452. }
  453. string param = args[3];
  454. string rawValue = args[4];
  455. int newValue;
  456. if (param == "max-scene-throttle")
  457. {
  458. if (!ConsoleUtil.TryParseConsoleInt(MainConsole.Instance, rawValue, out newValue))
  459. return;
  460. m_udpServer.Throttle.MaxDripRate = newValue * 1000 / 8;
  461. }
  462. else if (param == "max-new-client-throttle")
  463. {
  464. if (!ConsoleUtil.TryParseConsoleInt(MainConsole.Instance, rawValue, out newValue))
  465. return;
  466. m_udpServer.ThrottleRates.Total = newValue * 1000 / 8;
  467. }
  468. else
  469. {
  470. return;
  471. }
  472. m_console.Output("{0} set to {1} in {2}", param, rawValue, m_udpServer.Scene.Name);
  473. }
  474. /* not in use, nothing to set/get from lludp
  475. private void HandleClientGetCommand(string module, string[] args)
  476. {
  477. if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene)
  478. return;
  479. if (args.Length != 4 && args.Length != 6)
  480. {
  481. MainConsole.Instance.OutputFormat("Usage: debug lludp client get [<avatar-first-name> <avatar-last-name>]");
  482. return;
  483. }
  484. string name = null;
  485. if (args.Length == 6)
  486. name = string.Format("{0} {1}", args[4], args[5]);
  487. m_udpServer.Scene.ForEachScenePresence(
  488. sp =>
  489. {
  490. if ((name == null || sp.Name == name) && sp.ControllingClient is LLClientView)
  491. {
  492. LLUDPClient udpClient = ((LLClientView)sp.ControllingClient).UDPClient;
  493. m_console.OutputFormat(
  494. "Client debug parameters for {0} ({1}) in {2}",
  495. sp.Name, sp.IsChildAgent ? "child" : "root", m_udpServer.Scene.Name);
  496. }
  497. });
  498. }
  499. private void HandleClientSetCommand(string module, string[] args)
  500. {
  501. if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene)
  502. return;
  503. if (args.Length != 6 && args.Length != 8)
  504. {
  505. MainConsole.Instance.OutputFormat("Usage: debug lludp client set <param> <value> [<avatar-first-name> <avatar-last-name>]");
  506. return;
  507. }
  508. string param = args[4];
  509. string rawValue = args[5];
  510. string name = null;
  511. if (args.Length == 8)
  512. name = string.Format("{0} {1}", args[6], args[7]);
  513. // nothing here now
  514. }
  515. */
  516. private void HandlePacketCommand(string module, string[] args)
  517. {
  518. if (SceneManager.Instance.CurrentScene is not null &&
  519. SceneManager.Instance.CurrentScene != m_udpServer.Scene)
  520. return;
  521. bool setAsDefaultLevel = false;
  522. bool setAll = false;
  523. OptionSet optionSet = new OptionSet()
  524. .Add("default", o => setAsDefaultLevel = (o is not null))
  525. .Add("all", o => setAll = (o is not null));
  526. List<string> filteredArgs = optionSet.Parse(args);
  527. string name = null;
  528. if (filteredArgs.Count == 6)
  529. {
  530. if (!(setAsDefaultLevel || setAll))
  531. {
  532. name = string.Format("{0} {1}", filteredArgs[4], filteredArgs[5]);
  533. }
  534. else
  535. {
  536. MainConsole.Instance.Output("ERROR: Cannot specify a user name when setting default/all logging level");
  537. return;
  538. }
  539. }
  540. if (filteredArgs.Count > 3)
  541. {
  542. if (int.TryParse(filteredArgs[3], out int newDebug))
  543. {
  544. if (setAsDefaultLevel || setAll)
  545. {
  546. m_udpServer.DefaultClientPacketDebugLevel = newDebug;
  547. MainConsole.Instance.Output(
  548. "Packet debug for {0} clients set to {1} in {2}",
  549. (setAll ? "all" : "future"), m_udpServer.DefaultClientPacketDebugLevel, m_udpServer.Scene.Name);
  550. if (setAll)
  551. {
  552. m_udpServer.Scene.ForEachScenePresence(sp =>
  553. {
  554. MainConsole.Instance.Output(
  555. "Packet debug for {0} ({1}) set to {2} in {3}",
  556. sp.Name, sp.IsChildAgent ? "child" : "root", newDebug, m_udpServer.Scene.Name);
  557. sp.ControllingClient.DebugPacketLevel = newDebug;
  558. });
  559. }
  560. }
  561. else
  562. {
  563. m_udpServer.Scene.ForEachScenePresence(sp =>
  564. {
  565. if (name is null || sp.Name == name)
  566. {
  567. MainConsole.Instance.Output(
  568. "Packet debug for {0} ({1}) set to {2} in {3}",
  569. sp.Name, sp.IsChildAgent ? "child" : "root", newDebug, m_udpServer.Scene.Name);
  570. sp.ControllingClient.DebugPacketLevel = newDebug;
  571. }
  572. });
  573. }
  574. }
  575. else
  576. {
  577. MainConsole.Instance.Output("Usage: debug lludp packet [--default | --all] 0..255 [<first-name> <last-name>]");
  578. }
  579. }
  580. }
  581. private void HandleDropCommand(string module, string[] args)
  582. {
  583. if (SceneManager.Instance.CurrentScene is not null &&
  584. SceneManager.Instance.CurrentScene != m_udpServer.Scene)
  585. return;
  586. if (args.Length != 6)
  587. {
  588. MainConsole.Instance.Output("Usage: debug lludp drop <in|out> <add|remove> <packet-name>");
  589. return;
  590. }
  591. string direction = args[3];
  592. string subCommand = args[4];
  593. string packetName = args[5];
  594. if (subCommand == "add")
  595. {
  596. MainConsole.Instance.Output(
  597. "Adding packet {0} to {1} drop list for all connections in {2}",
  598. direction, packetName, m_udpServer.Scene.Name);
  599. m_udpServer.Scene.ForEachScenePresence(
  600. sp =>
  601. {
  602. LLClientView llcv = (LLClientView)sp.ControllingClient;
  603. if (direction == "in")
  604. llcv.AddInPacketToDropSet(packetName);
  605. else if (direction == "out")
  606. llcv.AddOutPacketToDropSet(packetName);
  607. }
  608. );
  609. }
  610. else if (subCommand == "remove")
  611. {
  612. MainConsole.Instance.Output(
  613. "Removing packet {0} from {1} drop list for all connections in {2}",
  614. direction, packetName, m_udpServer.Scene.Name);
  615. m_udpServer.Scene.ForEachScenePresence(
  616. sp =>
  617. {
  618. LLClientView llcv = (LLClientView)sp.ControllingClient;
  619. if (direction == "in")
  620. llcv.RemoveInPacketFromDropSet(packetName);
  621. else if (direction == "out")
  622. llcv.RemoveOutPacketFromDropSet(packetName);
  623. }
  624. );
  625. }
  626. }
  627. private void HandleStartCommand(string module, string[] args)
  628. {
  629. if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_udpServer.Scene)
  630. return;
  631. if (args.Length != 4)
  632. {
  633. MainConsole.Instance.Output("Usage: debug lludp start <in|out|all>");
  634. return;
  635. }
  636. string subCommand = args[3];
  637. if (subCommand == "in" || subCommand == "all")
  638. m_udpServer.StartInbound();
  639. if (subCommand == "out" || subCommand == "all")
  640. m_udpServer.StartOutbound();
  641. }
  642. private void HandleStopCommand(string module, string[] args)
  643. {
  644. if (SceneManager.Instance.CurrentScene is not null &&
  645. SceneManager.Instance.CurrentScene != m_udpServer.Scene)
  646. return;
  647. if (args.Length != 4)
  648. {
  649. MainConsole.Instance.Output("Usage: debug lludp stop <in|out|all>");
  650. return;
  651. }
  652. string subCommand = args[3];
  653. if (subCommand == "in" || subCommand == "all")
  654. m_udpServer.StopInbound();
  655. if (subCommand == "out" || subCommand == "all")
  656. m_udpServer.StopOutbound();
  657. }
  658. private void HandleAgentUpdateCommand(string module, string[] args)
  659. {
  660. if (SceneManager.Instance.CurrentScene is not null &&
  661. SceneManager.Instance.CurrentScene != m_udpServer.Scene)
  662. return;
  663. m_udpServer.DiscardInboundAgentUpdates = !m_udpServer.DiscardInboundAgentUpdates;
  664. MainConsole.Instance.Output(
  665. "Discard AgentUpdates now {0} for {1}", null, m_udpServer.DiscardInboundAgentUpdates, m_udpServer.Scene.Name);
  666. }
  667. private void HandleStatusCommand(string module, string[] args)
  668. {
  669. if (SceneManager.Instance.CurrentScene is not null &&
  670. SceneManager.Instance.CurrentScene != m_udpServer.Scene)
  671. return;
  672. MainConsole.Instance.Output(
  673. "IN LLUDP packet processing for {0} is {1}", m_udpServer.Scene.Name, m_udpServer.IsRunningInbound ? "enabled" : "disabled");
  674. MainConsole.Instance.Output(
  675. "OUT LLUDP packet processing for {0} is {1}", m_udpServer.Scene.Name, m_udpServer.IsRunningOutbound ? "enabled" : "disabled");
  676. MainConsole.Instance.Output(
  677. "Packet debug level for new clients is {0}", m_udpServer.DefaultClientPacketDebugLevel);
  678. }
  679. private void HandleOqreCommand(string module, string[] args)
  680. {
  681. if (SceneManager.Instance.CurrentScene is not null &&
  682. SceneManager.Instance.CurrentScene != m_udpServer.Scene)
  683. return;
  684. if (args.Length != 4)
  685. {
  686. MainConsole.Instance.Output("Usage: debug lludp oqre <stop|start|status>");
  687. return;
  688. }
  689. string subCommand = args[3];
  690. if (subCommand == "stop")
  691. {
  692. m_udpServer.OqrEngine.Stop();
  693. MainConsole.Instance.Output("Stopped OQRE for {0}", m_udpServer.Scene.Name);
  694. }
  695. else if (subCommand == "start")
  696. {
  697. m_udpServer.OqrEngine.Start();
  698. MainConsole.Instance.Output("Started OQRE for {0}", m_udpServer.Scene.Name);
  699. }
  700. else if (subCommand == "status")
  701. {
  702. MainConsole.Instance.Output("OQRE in {0}", m_udpServer.Scene.Name);
  703. MainConsole.Instance.Output("Running: {0}", m_udpServer.OqrEngine.IsRunning);
  704. MainConsole.Instance.Output(
  705. "Requests waiting: {0}",
  706. m_udpServer.OqrEngine.IsRunning ? m_udpServer.OqrEngine.JobsWaiting.ToString() : "n/a");
  707. }
  708. else
  709. {
  710. MainConsole.Instance.Output("Unrecognized OQRE subcommand {0}", subCommand);
  711. }
  712. }
  713. }
  714. }