diff options
author | Armin Weatherwax | 2009-07-01 23:22:56 +0200 |
---|---|---|
committer | Armin Weatherwax | 2009-07-11 13:43:22 +0200 |
commit | 0b661f028e446ab4f19959129f3209f1a29fd63e (patch) | |
tree | 2f1ab27163104727ed972ab55c0680b0a37a8637 | |
parent | BROKEN logoff/relog crashing inconsistently on various startup states. (diff) | |
download | meta-impy-0b661f028e446ab4f19959129f3209f1a29fd63e.zip meta-impy-0b661f028e446ab4f19959129f3209f1a29fd63e.tar.gz meta-impy-0b661f028e446ab4f19959129f3209f1a29fd63e.tar.bz2 meta-impy-0b661f028e446ab4f19959129f3209f1a29fd63e.tar.xz |
BROKEN now consistantly crashes at startup STATE_PRECACHE
-rw-r--r-- | Imprudence.log | 581 | ||||
-rw-r--r-- | linden/indra/newview/llworld.cpp | 1 | ||||
-rw-r--r-- | mAttachedObject.diff.txt | 16 | ||||
-rw-r--r-- | meerkat-llmenugl.diff.txt | 534 | ||||
-rw-r--r-- | meerkat-message.diff.txt | 1319 | ||||
-rw-r--r-- | meerkat-pipeline.cpp.diff.txt | 22 | ||||
-rw-r--r-- | meerkat-voice.diff.txt | 7282 | ||||
-rw-r--r-- | stack_trace.log | 32 |
8 files changed, 9787 insertions, 0 deletions
diff --git a/Imprudence.log b/Imprudence.log new file mode 100644 index 0000000..3bc56eb --- /dev/null +++ b/Imprudence.log | |||
@@ -0,0 +1,581 @@ | |||
1 | 2009-07-01T20:58:49Z INFO: initConfiguration: Loading settings file list/home/aw/src/aaamyimprudence/linden/indra/viewer-linux-i686-relwithdebinfo/newview/packaged/app_settings/settings_files.xml | ||
2 | 2009-07-01T20:58:49Z INFO: loadSettingsFromDirectory: Loaded settings file /home/aw/src/aaamyimprudence/linden/indra/viewer-linux-i686-relwithdebinfo/newview/packaged/app_settings/settings_crash_behavior.xml | ||
3 | 2009-07-01T20:58:49Z INFO: loadSettingsFromDirectory: Loaded settings file /home/aw/src/aaamyimprudence/linden/indra/viewer-linux-i686-relwithdebinfo/newview/packaged/app_settings/settings.xml | ||
4 | 2009-07-01T20:58:49Z INFO: loadSettingsFromDirectory: Loaded settings file /home/aw/src/aaamyimprudence/linden/indra/viewer-linux-i686-relwithdebinfo/newview/packaged/app_settings/settings_per_account.xml | ||
5 | 2009-07-01T20:58:49Z INFO: initParseCommandLine: Language de | ||
6 | 2009-07-01T20:58:49Z INFO: initParseCommandLine: Location DE | ||
7 | 2009-07-01T20:58:49Z INFO: initParseCommandLine: Variant UTF-8 | ||
8 | 2009-07-01T20:58:49Z INFO: initConfiguration: Using command line specified settings filename: /home/aw/.imprudence/user_settings/settings_imprudence.xml | ||
9 | 2009-07-01T20:58:49Z INFO: loadSettingsFromDirectory: Loaded settings file /home/aw/.imprudence/user_settings/settings_crash_behavior.xml | ||
10 | 2009-07-01T20:58:49Z INFO: loadSettingsFromDirectory: Loaded settings file /home/aw/.imprudence/user_settings/settings_imprudence.xml | ||
11 | 2009-07-01T20:58:49Z WARNING: loadFromFile: Cannot find file /home/aw/.imprudence/user_settings/settings_per_account.xml to load. | ||
12 | 2009-07-01T20:58:49Z WARNING: loadSettingsFromDirectory: Cannot load /home/aw/.imprudence/user_settings/settings_per_account.xml - No settings found. | ||
13 | 2009-07-01T20:58:49Z INFO: getFontListSans: Getting system font list from FontConfig... | ||
14 | 2009-07-01T20:58:49Z INFO: getFontListSans: Language de | ||
15 | 2009-07-01T20:58:49Z INFO: getFontListSans: Location DE | ||
16 | 2009-07-01T20:58:49Z INFO: getFontListSans: Variant UTF-8 | ||
17 | 2009-07-01T20:58:49Z INFO: getFontListSans: Preferring fonts of language: de | ||
18 | 2009-07-01T20:58:49Z INFO: getFontListSans: Using 31 system font(s). | ||
19 | 2009-07-01T20:58:49Z INFO: parseFile: Loading grid info file /home/aw/.imprudence/user_settings/grid_info.xml. | ||
20 | 2009-07-01T20:58:49Z INFO: parseData: Loading grid data. | ||
21 | 2009-07-01T20:58:49Z WARNING: setPlatform: Unknown platform 'Other'. | ||
22 | 2009-07-01T20:58:49Z INFO: parseFile: Loading grid info file /home/aw/src/aaamyimprudence/linden/indra/viewer-linux-i686-relwithdebinfo/newview/packaged/app_settings/default_grids.xml. | ||
23 | 2009-07-01T20:58:49Z INFO: parseUrl: Loading grid info from 'http://opensim-viewer.sourceforge.net/db/grids.php'. | ||
24 | 2009-07-01T20:58:49Z INFO: blockingGet: blockingGet of http://opensim-viewer.sourceforge.net/db/grids.php | ||
25 | 2009-07-01T20:58:51Z WARNING: setCurrentGrid: Unknown grid ''. Setting to default grid. | ||
26 | 2009-07-01T20:58:51Z INFO: initMarkerFile: Last exec LLError crashed, setting LastExecEvent to 2 | ||
27 | 2009-07-01T20:58:51Z INFO: initMarkerFile: Last exec crashed, setting LastExecEvent to 3 | ||
28 | 2009-07-01T20:58:51Z INFO: writeSystemInfo: | ||
29 | 2009-07-01T20:58:51Z INFO: writeSystemInfo: Local time: 2009-07-01T22:58:51 CEST | ||
30 | 2009-07-01T20:58:51Z INFO: writeSystemInfo: CPU info: | ||
31 | processor : 0 vendor_id : GenuineIntel cpu family : 6 model : 14 model name : Intel(R) Core(TM) Duo CPU T2450 @ 2.00GHz stepping : 12 cpu MHz : 798.000 cache size : 2048 KB physical id : 0 siblings : 2 core id : 0 cpu cores : 2 apicid : 0 initial apicid : 0 fdiv_bug : no hlt_bug : no f00f_bug : no coma_bug : no fpu : yes fpu_exception : yes cpuid level : 10 wp : yes flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe constant_tsc arch_perfmon bts pni monitor est tm2 xtpr pdcm bogomips : 3990.13 clflush size : 64 power management: processor : 1 vendor_id : GenuineIntel cpu family : 6 model : 14 model name : Intel(R) Core(TM) Duo CPU T2450 @ 2.00GHz stepping : 12 cpu MHz : 798.000 cache size : 2048 KB physical id : 0 siblings : 2 core id : 1 cpu cores : 2 apicid : 1 initial apicid : 1 fdiv_bug : no hlt_bug : no f00f_bug : no coma_bug : no fpu : yes fpu_exception : yes cpuid level : 10 wp : yes flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe constant_tsc arch_perfmon bts pni monitor est tm2 xtpr pdcm bogomips : 3990.49 clflush size : 64 power management: | ||
32 | ->mHasSSE: 1 | ||
33 | ->mHasSSE2: 1 | ||
34 | ->mHasAltivec: 0 | ||
35 | ->mCPUMhz: 798 | ||
36 | ->mCPUString: Intel(R) Core(TM) Duo CPU T2450 @ 2.00GHz | ||
37 | |||
38 | 2009-07-01T20:58:51Z INFO: writeSystemInfo: Memory info: | ||
39 | MemTotal: 1945568 kB MemFree: 593720 kB Buffers: 13392 kB Cached: 580556 kB SwapCached: 2340 kB Active: 79892 kB Inactive: 810692 kB Active(anon): 17656 kB Inactive(anon): 280332 kB Active(file): 62236 kB Inactive(file): 530360 kB Unevictable: 0 kB Mlocked: 0 kB HighTotal: 1056424 kB HighFree: 133548 kB LowTotal: 889144 kB LowFree: 460172 kB SwapTotal: 995988 kB SwapFree: 959280 kB Dirty: 100 kB Writeback: 0 kB AnonPages: 294600 kB Mapped: 61736 kB Slab: 26508 kB SReclaimable: 17520 kB SUnreclaim: 8988 kB PageTables: 2868 kB NFS_Unstable: 0 kB Bounce: 0 kB WritebackTmp: 0 kB CommitLimit: 1968772 kB Committed_AS: 504844 kB VmallocTotal: 122880 kB VmallocUsed: 18444 kB VmallocChunk: 103592 kB HugePages_Total: 0 HugePages_Free: 0 HugePages_Rsvd: 0 HugePages_Surp: 0 Hugepagesize: 4096 kB DirectMap4k: 876536 kB DirectMap4M: 32768 kB | ||
40 | 2009-07-01T20:58:51Z INFO: writeSystemInfo: OS: Linux 2.6 | ||
41 | 2009-07-01T20:58:51Z INFO: writeSystemInfo: OS info: Linux 2.6.29.3 #1 SMP Fri May 15 17:03:02 CEST 2009 i686 | ||
42 | 2009-07-01T20:58:51Z INFO: writeDebugInfo: Opening debug file /home/aw/.imprudence/logs/debug_info.log | ||
43 | 2009-07-01T20:58:51Z INFO: init: J2C Engine is: OpenJPEG: 1.2.0, Runtime: 1.3.0 | ||
44 | 2009-07-01T20:58:51Z INFO: init: libcurl version is: libcurl/7.16.4 OpenSSL/0.9.7c zlib/1.2.3.3 c-ares/1.4.0 | ||
45 | 2009-07-01T20:58:51Z INFO: updateVectorize: Vectorization : DISABLED | ||
46 | 2009-07-01T20:58:51Z INFO: updateVectorize: Vector Processor : COMPILER DEFAULT | ||
47 | 2009-07-01T20:58:51Z INFO: updateVectorize: Vectorized Skinning : DISABLED | ||
48 | 2009-07-01T20:58:51Z WARNING: isFeatureAvailable: Feature RenderCubeMap not on feature list! | ||
49 | 2009-07-01T20:58:51Z INFO: grab_dbus_syms: Found DSO: libdbus-glib-1.so.2 | ||
50 | 2009-07-01T20:58:51Z INFO: initCache: Headers: 139810 Textures size: 320 MB | ||
51 | 2009-07-01T20:58:51Z INFO: purgeTextures: TEXTURE CACHE: PURGED: 0 ENTRIES: 2650 CACHE SIZE: 65 MB | ||
52 | 2009-07-01T20:58:51Z INFO: initCache: VFS CACHE SIZE: 100 MB | ||
53 | 2009-07-01T20:58:51Z WARNING: LLVFS: Using index file /home/aw/.imprudence/cache/index.db2.x.1 | ||
54 | 2009-07-01T20:58:51Z WARNING: LLVFS: Using data file /home/aw/.imprudence/cache/data.db2.x.1 | ||
55 | 2009-07-01T20:58:51Z WARNING: LLVFS: Using index file /home/aw/src/aaamyimprudence/linden/indra/viewer-linux-i686-relwithdebinfo/newview/packaged/app_settings/static_index.db2 | ||
56 | 2009-07-01T20:58:51Z WARNING: LLVFS: Using data file /home/aw/src/aaamyimprudence/linden/indra/viewer-linux-i686-relwithdebinfo/newview/packaged/app_settings/static_data.db2 | ||
57 | 2009-07-01T20:58:51Z INFO: initWindow: Initializing window... | ||
58 | 2009-07-01T20:58:51Z INFO: ll_try_gtk_init: Starting GTK Initialization. | ||
59 | 2009-07-01T20:58:51Z INFO: ll_try_gtk_init: GTK Initialized. | ||
60 | 2009-07-01T20:58:51Z INFO: ll_try_gtk_init: - Compiled against GTK version 2.4.14 | ||
61 | 2009-07-01T20:58:51Z INFO: ll_try_gtk_init: - Running against GTK version 2.16.1 | ||
62 | 2009-07-01T20:58:51Z INFO: createContext: createContext, fullscreen=0 size=1118x722 | ||
63 | 2009-07-01T20:58:52Z INFO: createContext: Compiled against SDL 1.2.5 | ||
64 | 2009-07-01T20:58:52Z INFO: createContext: Running against SDL 1.2.12 | ||
65 | 2009-07-01T20:58:52Z INFO: createContext: createContext: creating window 1118x722x32 | ||
66 | 2009-07-01T20:58:54Z INFO: x11_detect_VRAM_kb: Looking in /var/log/Xorg.0.log for VRAM info... | ||
67 | 2009-07-01T20:58:54Z INFO: createContext: GL buffer: | ||
68 | 2009-07-01T20:58:54Z INFO: createContext: Red Bits 8 | ||
69 | 2009-07-01T20:58:54Z INFO: createContext: Green Bits 8 | ||
70 | 2009-07-01T20:58:54Z INFO: createContext: Blue Bits 8 | ||
71 | 2009-07-01T20:58:54Z INFO: createContext: Alpha Bits 8 | ||
72 | 2009-07-01T20:58:54Z INFO: createContext: Depth Bits 24 | ||
73 | 2009-07-01T20:58:54Z INFO: createContext: Stencil Bits 8 | ||
74 | 2009-07-01T20:58:54Z INFO: initExtensions: Couldn't initialize GL_ARB_point_parameters | ||
75 | 2009-07-01T20:58:54Z INFO: initExtensions: Disabling mip-map generation for ATI GPUs (performance opt) | ||
76 | 2009-07-01T20:58:54Z WARNING: addFeature: LLFeatureList::Attempting to add preexisting feature Disregard128DefaultDrawDistance | ||
77 | 2009-07-01T20:58:54Z INFO: loadGPUClass: GPU is ATI Radeon Xpress | ||
78 | 2009-07-01T20:58:54Z INFO: applyBaseMasks: Setting GPU Class to Class0 | ||
79 | 2009-07-01T20:58:54Z WARNING: LLViewerImageList::getMaxVideoRamSetting: VRAM amount not detected, defaulting to 128 MB | ||
80 | 2009-07-01T20:58:54Z WARNING: LLViewerImageList::getMaxVideoRamSetting: VRAM amount not detected, defaulting to 512 MB | ||
81 | 2009-07-01T20:58:54Z INFO: LLViewerImageList::updateMaxResidentTexMem: Total Video Memory set to: 128 MB | ||
82 | 2009-07-01T20:58:54Z INFO: LLViewerImageList::updateMaxResidentTexMem: Available Texture Memory set to: 96 MB | ||
83 | 2009-07-01T20:58:55Z INFO: restoreGL: Loading bumpmap: <blahblah> from viewerart | ||
84 | 2009-07-01T20:58:56Z INFO: saveToFile: Saved to /home/aw/.imprudence/user_settings/settings_imprudence.xml | ||
85 | 2009-07-01T20:58:56Z INFO: setShaders: | ||
86 | ~~~~~~~~~~~~~~~~~~ | ||
87 | Loading Shaders: | ||
88 | ~~~~~~~~~~~~~~~~~~ | ||
89 | 2009-07-01T20:58:56Z INFO: saveToFile: Saved to /home/aw/.imprudence/user_settings/settings_imprudence.xml | ||
90 | 2009-07-01T20:58:57Z INFO: printGLInfoString: GL_VENDOR: ATI Technologies Inc. | ||
91 | 2009-07-01T20:58:57Z INFO: printGLInfoString: GL_RENDERER: ATI Radeon Xpress Series | ||
92 | 2009-07-01T20:58:57Z INFO: printGLInfoString: GL_VERSION: 2.1.8543 Release | ||
93 | 2009-07-01T20:58:57Z WARNING: init: ndof_init_first FAILED | ||
94 | 2009-07-01T20:58:57Z INFO: init: ndof: mDriverState=0; mNdofDev=0x9c2c1740; libinit=1 | ||
95 | 2009-07-01T20:58:57Z INFO: LLTemplateParser: ### Message template version 2 ### | ||
96 | 2009-07-01T20:58:57Z INFO: start_net: startNet - receive buffer size : 262142 | ||
97 | 2009-07-01T20:58:57Z INFO: start_net: startNet - send buffer size : 262142 | ||
98 | 2009-07-01T20:58:57Z INFO: idle_startup: Message System Initialized. | ||
99 | 2009-07-01T20:58:57Z INFO: init: LLAudioEngine::init() AudioEngine successfully initialized | ||
100 | 2009-07-01T20:58:57Z INFO: init: LLAudioEngine_OpenAL::init() OpenAL successfully initialized | ||
101 | 2009-07-01T20:58:57Z INFO: init: OpenAL version: 1.1 | ||
102 | 2009-07-01T20:58:57Z INFO: init: OpenAL vendor: OpenAL Community | ||
103 | 2009-07-01T20:58:57Z INFO: init: OpenAL renderer: OpenAL Soft | ||
104 | 2009-07-01T20:58:57Z INFO: init: ALUT version: 1.1 | ||
105 | 2009-07-01T20:58:57Z INFO: init: ALC version: 1.1 | ||
106 | 2009-07-01T20:58:57Z INFO: init: ALC default device: ALSA Software on default | ||
107 | 2009-07-01T20:58:57Z INFO: idle_startup: Audio Engine Initialized. | ||
108 | 2009-07-01T20:58:57Z INFO: setStartupState: Startup state changing from STATE_FIRST to (state #1) | ||
109 | 2009-07-01T20:58:59Z INFO: updateBrowserUserAgent: SecondLife/1.22.11.0 (Imprudence; default skin) | ||
110 | 2009-07-01T20:58:59Z INFO: setStartupState: Startup state changing from (state #1) to STATE_LOGIN_SHOW | ||
111 | 2009-07-01T20:58:59Z INFO: login_show: Initializing Login Screen | ||
112 | 2009-07-01T20:59:00Z INFO: setStartupState: Startup state changing from STATE_LOGIN_SHOW to STATE_LOGIN_WAIT | ||
113 | 2009-07-01T20:59:00Z WARNING: getChild: Found child named Say but of wrong type | ||
114 | 2009-07-01T20:59:00Z WARNING: createDummyWidget: Making dummy button named Say in chat_bar | ||
115 | 2009-07-01T20:59:00Z WARNING: createDummyWidget: Making dummy button named end_call_btn in voice_remote | ||
116 | 2009-07-01T20:59:00Z WARNING: createDummyWidget: Making dummy text named channel_label in voice_remote | ||
117 | 2009-07-01T20:59:00Z WARNING: createDummyWidget: Making dummy button named voice_channel_bg in voice_remote | ||
118 | 2009-07-01T20:59:00Z WARNING: createDummyWidget: Making dummy button named appearance_btn in toolbar | ||
119 | 2009-07-01T20:59:00Z WARNING: createDummyWidget: Making dummy button named clothing_btn in toolbar | ||
120 | 2009-07-01T20:59:00Z WARNING: createDummyWidget: Making dummy button named sit_btn in toolbar | ||
121 | 2009-07-01T20:59:00Z WARNING: createDummyWidget: Making dummy button named History in chat_panel | ||
122 | 2009-07-01T20:59:00Z WARNING: createDummyWidget: Making dummy combo_box named Gesture in chat_panel | ||
123 | 2009-07-01T20:59:00Z WARNING: getChild: Found child named Say but of wrong type | ||
124 | 2009-07-01T20:59:00Z WARNING: createDummyWidget: Making dummy button named Say in chat_panel | ||
125 | 2009-07-01T20:59:00Z WARNING: createDummyWidget: Making dummy button named Chat in chat floater | ||
126 | 2009-07-01T20:59:00Z WARNING: createDummyWidget: Making dummy view named bandwidth_tooltip in status | ||
127 | 2009-07-01T20:59:00Z WARNING: createDummyWidget: Making dummy view named packet_loss_tooltip in status | ||
128 | 2009-07-01T20:59:00Z WARNING: createDummyWidget: Making dummy view named friend_name_label in friends | ||
129 | 2009-07-01T20:59:00Z WARNING: createDummyWidget: Making dummy view named friend_rights in friends | ||
130 | 2009-07-01T20:59:00Z WARNING: createDummyWidget: Making dummy text named process_rights_label in friends | ||
131 | 2009-07-01T20:59:01Z WARNING: createDummyWidget: Making dummy view named Shout in chat_bar | ||
132 | 2009-07-01T20:59:03Z INFO: setStartupState: Startup state changing from STATE_LOGIN_WAIT to STATE_LOGIN_CLEANUP | ||
133 | 2009-07-01T20:59:04Z INFO: idle_startup: Attempting login as: Armin Weatherwax <uuid> | ||
134 | 2009-07-01T20:59:04Z WARNING: loadFromFile: Cannot find file /home/aw/.imprudence/armin_weatherwax/settings_crash_behavior.xml to load. | ||
135 | 2009-07-01T20:59:04Z WARNING: loadSettingsFromDirectory: Cannot load /home/aw/.imprudence/armin_weatherwax/settings_crash_behavior.xml - No settings found. | ||
136 | 2009-07-01T20:59:04Z WARNING: loadFromFile: Cannot find file /home/aw/.imprudence/armin_weatherwax/settings.xml to load. | ||
137 | 2009-07-01T20:59:04Z WARNING: loadSettingsFromDirectory: Cannot load /home/aw/.imprudence/armin_weatherwax/settings.xml - No settings found. | ||
138 | 2009-07-01T20:59:04Z INFO: loadSettingsFromDirectory: Loaded settings file /home/aw/.imprudence/armin_weatherwax/settings_per_account.xml | ||
139 | 2009-07-01T20:59:04Z INFO: loadFile: Loading history.xml file at url_history.xml | ||
140 | 2009-07-01T20:59:04Z INFO: loadFile: file missing, ill-formed, or simply undefined; not changing the file | ||
141 | 2009-07-01T20:59:05Z INFO: setStartupState: Startup state changing from STATE_LOGIN_CLEANUP to STATE_LOGIN_AUTH_INIT | ||
142 | 2009-07-01T20:59:05Z INFO: rewriteURI: Rewriting http://127.0.0.1:9000/ | ||
143 | 2009-07-01T20:59:05Z INFO: rewriteResult: [0] http://127.0.0.1:9000/ | ||
144 | 2009-07-01T20:59:05Z INFO: setStartupState: Startup state changing from STATE_LOGIN_AUTH_INIT to STATE_LOGIN_AUTHENTICATE | ||
145 | 2009-07-01T20:59:05Z INFO: authenticate: Authenticating: Armin Weatherwax, | ||
146 | 2009-07-01T20:59:05Z INFO: authenticate: Options: inventory-root, inventory-skeleton, inventory-lib-root, inventory-lib-owner, inventory-skel-lib, initial-outfit, gestures, event_categories, event_notifications, classified_categories, buddy-list, ui-config, tutorial_setting, login-flags, global-textures, END | ||
147 | 2009-07-01T20:59:05Z INFO: authenticate: LLUserAuth::authenticate: uri=http://127.0.0.1:9000/ | ||
148 | 2009-07-01T20:59:05Z INFO: setStartupState: Startup state changing from STATE_LOGIN_AUTHENTICATE to STATE_LOGIN_NO_DATA_YET | ||
149 | 2009-07-01T20:59:05Z INFO: transferRate: Buffer size: 105394 B | ||
150 | 2009-07-01T20:59:05Z INFO: transferRate: Transfer rate: 2041.61 Kb/s | ||
151 | 2009-07-01T20:59:05Z INFO: authResponse: Processed response: 0 | ||
152 | 2009-07-01T20:59:05Z INFO: setStartupState: Startup state changing from STATE_LOGIN_NO_DATA_YET to STATE_LOGIN_DOWNLOADING | ||
153 | 2009-07-01T20:59:05Z INFO: setStartupState: Startup state changing from STATE_LOGIN_DOWNLOADING to STATE_LOGIN_PROCESS_RESPONSE | ||
154 | 2009-07-01T20:59:05Z INFO: addCircuitData: LLCircuit::addCircuitData for 127.0.0.1:9000 | ||
155 | 2009-07-01T20:59:05Z INFO: saveFile: Saved grids to /home/aw/.imprudence/user_settings/grid_info.xml | ||
156 | 2009-07-01T20:59:05Z INFO: setStartupState: Startup state changing from STATE_LOGIN_PROCESS_RESPONSE to STATE_WORLD_INIT | ||
157 | 2009-07-01T20:59:05Z INFO: LLVoiceClient::userAuthorized: name "Armin Weatherwax" , ID <uuid> | ||
158 | 2009-07-01T20:59:05Z INFO: saveToFile: Saved to /home/aw/.imprudence/user_settings/settings_imprudence.xml | ||
159 | 2009-07-01T20:59:05Z INFO: loadPresets: Loading Default WindLight settings from /home/aw/src/aaamyimprudence/linden/indra/viewer-linux-i686-relwithdebinfo/newview/packaged/app_settings/windlight/skies/ | ||
160 | 2009-07-01T20:59:05Z INFO: loadPreset: Loading WindLight sky setting from /home/aw/src/aaamyimprudence/linden/indra/viewer-linux-i686-relwithdebinfo/newview/packaged/app_settings/windlight/skies/Blue%20Midday.xml | ||
161 | 2009-07-01T20:59:05Z INFO: loadPreset: Loading WindLight sky setting from /home/aw/src/aaamyimprudence/linden/indra/viewer-linux-i686-relwithdebinfo/newview/packaged/app_settings/windlight/skies/A%2D9AM.xml | ||
162 | 2009-07-01T20:59:05Z INFO: loadPreset: Loading WindLight sky setting from /home/aw/src/aaamyimprudence/linden/indra/viewer-linux-i686-relwithdebinfo/newview/packaged/app_settings/windlight/skies/Sheer%20Surreality.xml | ||
163 | 2009-07-01T20:59:05Z INFO: loadPreset: Loading WindLight sky setting from /home/aw/src/aaamyimprudence/linden/indra/viewer-linux-i686-relwithdebinfo/newview/packaged/app_settings/windlight/skies/A%2D12PM.xml | ||
164 | 2009-07-01T20:59:05Z INFO: loadPreset: Loading WindLight sky setting from /home/aw/src/aaamyimprudence/linden/indra/viewer-linux-i686-relwithdebinfo/newview/packaged/app_settings/windlight/skies/Funky%20Funky%20Funky.xml | ||
165 | 2009-07-01T20:59:05Z INFO: loadPreset: Loading WindLight sky setting from /home/aw/src/aaamyimprudence/linden/indra/viewer-linux-i686-relwithdebinfo/newview/packaged/app_settings/windlight/skies/Fine%20Day.xml | ||
166 | 2009-07-01T20:59:05Z INFO: loadPreset: Loading WindLight sky setting from /home/aw/src/aaamyimprudence/linden/indra/viewer-linux-i686-relwithdebinfo/newview/packaged/app_settings/windlight/skies/A%2D3PM.xml | ||
167 | 2009-07-01T20:59:05Z INFO: loadPreset: Loading WindLight sky setting from /home/aw/src/aaamyimprudence/linden/indra/viewer-linux-i686-relwithdebinfo/newview/packaged/app_settings/windlight/skies/Midday%203.xml | ||
168 | 2009-07-01T20:59:05Z INFO: loadPreset: Loading WindLight sky setting from /home/aw/src/aaamyimprudence/linden/indra/viewer-linux-i686-relwithdebinfo/newview/packaged/app_settings/windlight/skies/Funky%20Funky.xml | ||
169 | 2009-07-01T20:59:05Z INFO: loadPreset: Loading WindLight sky setting from /home/aw/src/aaamyimprudence/linden/indra/viewer-linux-i686-relwithdebinfo/newview/packaged/app_settings/windlight/skies/Night.xml | ||
170 | 2009-07-01T20:59:05Z INFO: loadPreset: Loading WindLight sky setting from /home/aw/src/aaamyimprudence/linden/indra/viewer-linux-i686-relwithdebinfo/newview/packaged/app_settings/windlight/skies/Coastal%20Sunset.xml | ||
171 | 2009-07-01T20:59:05Z INFO: loadPreset: Loading WindLight sky setting from /home/aw/src/aaamyimprudence/linden/indra/viewer-linux-i686-relwithdebinfo/newview/packaged/app_settings/windlight/skies/A%2D9PM.xml | ||
172 | 2009-07-01T20:59:05Z INFO: loadPreset: Loading WindLight sky setting from /home/aw/src/aaamyimprudence/linden/indra/viewer-linux-i686-relwithdebinfo/newview/packaged/app_settings/windlight/skies/Barcelona.xml | ||
173 | 2009-07-01T20:59:05Z INFO: loadPreset: Loading WindLight sky setting from /home/aw/src/aaamyimprudence/linden/indra/viewer-linux-i686-relwithdebinfo/newview/packaged/app_settings/windlight/skies/A%2D6AM.xml | ||
174 | 2009-07-01T20:59:05Z INFO: loadPreset: Loading WindLight sky setting from /home/aw/src/aaamyimprudence/linden/indra/viewer-linux-i686-relwithdebinfo/newview/packaged/app_settings/windlight/skies/Purple.xml | ||
175 | 2009-07-01T20:59:05Z INFO: loadPreset: Loading WindLight sky setting from /home/aw/src/aaamyimprudence/linden/indra/viewer-linux-i686-relwithdebinfo/newview/packaged/app_settings/windlight/skies/A%2D6PM.xml | ||
176 | 2009-07-01T20:59:05Z INFO: loadPreset: Loading WindLight sky setting from /home/aw/src/aaamyimprudence/linden/indra/viewer-linux-i686-relwithdebinfo/newview/packaged/app_settings/windlight/skies/Gelatto.xml | ||
177 | 2009-07-01T20:59:05Z INFO: loadPreset: Loading WindLight sky setting from /home/aw/src/aaamyimprudence/linden/indra/viewer-linux-i686-relwithdebinfo/newview/packaged/app_settings/windlight/skies/Incongruent%20Truths.xml | ||
178 | 2009-07-01T20:59:05Z INFO: loadPreset: Loading WindLight sky setting from /home/aw/src/aaamyimprudence/linden/indra/viewer-linux-i686-relwithdebinfo/newview/packaged/app_settings/windlight/skies/Fluffy%20Big%20Clouds.xml | ||
179 | 2009-07-01T20:59:05Z INFO: loadPreset: Loading WindLight sky setting from /home/aw/src/aaamyimprudence/linden/indra/viewer-linux-i686-relwithdebinfo/newview/packaged/app_settings/windlight/skies/Midday%202.xml | ||
180 | 2009-07-01T20:59:05Z INFO: loadPreset: Loading WindLight sky setting from /home/aw/src/aaamyimprudence/linden/indra/viewer-linux-i686-relwithdebinfo/newview/packaged/app_settings/windlight/skies/Ghost.xml | ||
181 | 2009-07-01T20:59:05Z INFO: loadPreset: Loading WindLight sky setting from /home/aw/src/aaamyimprudence/linden/indra/viewer-linux-i686-relwithdebinfo/newview/packaged/app_settings/windlight/skies/Desert%20Sunset.xml | ||
182 | 2009-07-01T20:59:05Z INFO: loadPreset: Loading WindLight sky setting from /home/aw/src/aaamyimprudence/linden/indra/viewer-linux-i686-relwithdebinfo/newview/packaged/app_settings/windlight/skies/Default.xml | ||
183 | 2009-07-01T20:59:05Z INFO: loadPreset: Loading WindLight sky setting from /home/aw/src/aaamyimprudence/linden/indra/viewer-linux-i686-relwithdebinfo/newview/packaged/app_settings/windlight/skies/Midday%204.xml | ||
184 | 2009-07-01T20:59:05Z INFO: loadPreset: Loading WindLight sky setting from /home/aw/src/aaamyimprudence/linden/indra/viewer-linux-i686-relwithdebinfo/newview/packaged/app_settings/windlight/skies/Blizzard.xml | ||
185 | 2009-07-01T20:59:05Z INFO: loadPreset: Loading WindLight sky setting from /home/aw/src/aaamyimprudence/linden/indra/viewer-linux-i686-relwithdebinfo/newview/packaged/app_settings/windlight/skies/Coastal%20Afternoon.xml | ||
186 | 2009-07-01T20:59:05Z INFO: loadPreset: Loading WindLight sky setting from /home/aw/src/aaamyimprudence/linden/indra/viewer-linux-i686-relwithdebinfo/newview/packaged/app_settings/windlight/skies/Foggy.xml | ||
187 | 2009-07-01T20:59:05Z INFO: loadPreset: Loading WindLight sky setting from /home/aw/src/aaamyimprudence/linden/indra/viewer-linux-i686-relwithdebinfo/newview/packaged/app_settings/windlight/skies/Sailor%27s%20Delight.xml | ||
188 | 2009-07-01T20:59:05Z INFO: loadPreset: Loading WindLight sky setting from /home/aw/src/aaamyimprudence/linden/indra/viewer-linux-i686-relwithdebinfo/newview/packaged/app_settings/windlight/skies/Pirate.xml | ||
189 | 2009-07-01T20:59:05Z INFO: loadPreset: Loading WindLight sky setting from /home/aw/src/aaamyimprudence/linden/indra/viewer-linux-i686-relwithdebinfo/newview/packaged/app_settings/windlight/skies/A%2D3AM.xml | ||
190 | 2009-07-01T20:59:05Z INFO: loadPreset: Loading WindLight sky setting from /home/aw/src/aaamyimprudence/linden/indra/viewer-linux-i686-relwithdebinfo/newview/packaged/app_settings/windlight/skies/Midday%201.xml | ||
191 | 2009-07-01T20:59:05Z INFO: loadPreset: Loading WindLight sky setting from /home/aw/src/aaamyimprudence/linden/indra/viewer-linux-i686-relwithdebinfo/newview/packaged/app_settings/windlight/skies/A%2D12AM.xml | ||
192 | 2009-07-01T20:59:05Z INFO: loadPresets: Loading User WindLight settings from /home/aw/.imprudence/user_settings/windlight/skies/ | ||
193 | 2009-07-01T20:59:05Z INFO: loadDayCycle: Loading DayCycle settings from /home/aw/src/aaamyimprudence/linden/indra/viewer-linux-i686-relwithdebinfo/newview/packaged/app_settings/windlight/days/Default.xml | ||
194 | 2009-07-01T20:59:05Z INFO: loadAllPresets: Loading Default water settings from /home/aw/src/aaamyimprudence/linden/indra/viewer-linux-i686-relwithdebinfo/newview/packaged/app_settings/windlight/water/ | ||
195 | 2009-07-01T20:59:05Z INFO: loadPreset: Loading water settings from /home/aw/src/aaamyimprudence/linden/indra/viewer-linux-i686-relwithdebinfo/newview/packaged/app_settings/windlight/water/Murky.xml | ||
196 | 2009-07-01T20:59:05Z INFO: loadPreset: Loading water settings from /home/aw/src/aaamyimprudence/linden/indra/viewer-linux-i686-relwithdebinfo/newview/packaged/app_settings/windlight/water/Pond.xml | ||
197 | 2009-07-01T20:59:05Z INFO: loadPreset: Loading water settings from /home/aw/src/aaamyimprudence/linden/indra/viewer-linux-i686-relwithdebinfo/newview/packaged/app_settings/windlight/water/Valdez.xml | ||
198 | 2009-07-01T20:59:05Z INFO: loadPreset: Loading water settings from /home/aw/src/aaamyimprudence/linden/indra/viewer-linux-i686-relwithdebinfo/newview/packaged/app_settings/windlight/water/Default.xml | ||
199 | 2009-07-01T20:59:05Z INFO: loadPreset: Loading water settings from /home/aw/src/aaamyimprudence/linden/indra/viewer-linux-i686-relwithdebinfo/newview/packaged/app_settings/windlight/water/Glassy.xml | ||
200 | 2009-07-01T20:59:05Z INFO: loadPreset: Loading water settings from /home/aw/src/aaamyimprudence/linden/indra/viewer-linux-i686-relwithdebinfo/newview/packaged/app_settings/windlight/water/Second%20Plague.xml | ||
201 | 2009-07-01T20:59:05Z INFO: loadPreset: Loading water settings from /home/aw/src/aaamyimprudence/linden/indra/viewer-linux-i686-relwithdebinfo/newview/packaged/app_settings/windlight/water/SNAKE%21%21%21.xml | ||
202 | 2009-07-01T20:59:05Z INFO: loadAllPresets: Loading User water settings from /home/aw/.imprudence/user_settings/windlight/water/ | ||
203 | 2009-07-01T20:59:05Z INFO: initVOClasses: Viewer Object size: 444 | ||
204 | 2009-07-01T20:59:05Z INFO: addRegion: Adding new region (1000:1000) | ||
205 | 2009-07-01T20:59:05Z INFO: addRegion: Host: 127.0.0.1:9000 | ||
206 | 2009-07-01T20:59:05Z INFO: idle_startup: Adding initial simulator { 256000, 256000, 0 } | ||
207 | 2009-07-01T20:59:05Z INFO: setSeedCapability: posting to seed http://127.0.0.1:9000/CAPS/<uuid>/ | ||
208 | 2009-07-01T20:59:05Z INFO: LLAgent::setRegion: Moving agent into region: located at 127.0.0.1:9000 | ||
209 | 2009-07-01T20:59:05Z INFO: setStartupState: Startup state changing from STATE_WORLD_INIT to (state #12) | ||
210 | 2009-07-01T20:59:05Z INFO: LLVoiceClient::stateMachine: /home/aw/src/aaamyimprudence/linden/indra/viewer-linux-i686-relwithdebinfo/newview/packaged/bin/SLVoice not found. | ||
211 | 2009-07-01T20:59:06Z DEBUG: startup: Found GStreamer plugins: | ||
212 | 2009-07-01T20:59:06Z DEBUG: startup: private-slvideoplugin, loaded? Yes | ||
213 | 2009-07-01T20:59:06Z DEBUG: startup: wavparse, loaded? No | ||
214 | 2009-07-01T20:59:06Z DEBUG: startup: mpegdemux2, loaded? No | ||
215 | 2009-07-01T20:59:06Z DEBUG: startup: uridecodebin, loaded? No | ||
216 | 2009-07-01T20:59:06Z DEBUG: startup: esdsink, loaded? No | ||
217 | 2009-07-01T20:59:06Z DEBUG: startup: ogg, loaded? No | ||
218 | 2009-07-01T20:59:06Z DEBUG: startup: ffmpeg, loaded? No | ||
219 | 2009-07-01T20:59:06Z DEBUG: startup: theora, loaded? No | ||
220 | 2009-07-01T20:59:06Z DEBUG: startup: gnomevfs, loaded? No | ||
221 | 2009-07-01T20:59:06Z DEBUG: startup: asf, loaded? No | ||
222 | 2009-07-01T20:59:06Z DEBUG: startup: coreelements, loaded? No | ||
223 | 2009-07-01T20:59:06Z DEBUG: startup: ossaudio, loaded? No | ||
224 | 2009-07-01T20:59:06Z DEBUG: startup: pulseaudio, loaded? No | ||
225 | 2009-07-01T20:59:06Z DEBUG: startup: coreindexers, loaded? No | ||
226 | 2009-07-01T20:59:06Z DEBUG: startup: typefindfunctions, loaded? No | ||
227 | 2009-07-01T20:59:06Z DEBUG: startup: autodetect, loaded? No | ||
228 | 2009-07-01T20:59:06Z DEBUG: startup: multifile, loaded? No | ||
229 | 2009-07-01T20:59:06Z DEBUG: startup: multipart, loaded? No | ||
230 | 2009-07-01T20:59:06Z DEBUG: startup: quicktime, loaded? No | ||
231 | 2009-07-01T20:59:06Z DEBUG: startup: id3demux, loaded? No | ||
232 | 2009-07-01T20:59:06Z DEBUG: startup: ffmpegcolorspace, loaded? No | ||
233 | 2009-07-01T20:59:06Z DEBUG: startup: audioconvert, loaded? No | ||
234 | 2009-07-01T20:59:06Z DEBUG: startup: tcp, loaded? No | ||
235 | 2009-07-01T20:59:06Z DEBUG: startup: audioresample, loaded? No | ||
236 | 2009-07-01T20:59:06Z DEBUG: startup: videoscale, loaded? No | ||
237 | 2009-07-01T20:59:06Z DEBUG: startup: avi, loaded? No | ||
238 | 2009-07-01T20:59:06Z DEBUG: startup: icydemux, loaded? No | ||
239 | 2009-07-01T20:59:06Z DEBUG: startup: vorbis, loaded? No | ||
240 | 2009-07-01T20:59:06Z DEBUG: startup: volume, loaded? No | ||
241 | 2009-07-01T20:59:06Z DEBUG: startup: playback, loaded? No | ||
242 | 2009-07-01T20:59:06Z DEBUG: startup: decodebin, loaded? No | ||
243 | 2009-07-01T20:59:06Z DEBUG: startup: alsa, loaded? No | ||
244 | 2009-07-01T20:59:06Z DEBUG: startup: udp, loaded? No | ||
245 | 2009-07-01T20:59:06Z DEBUG: startup: queue2, loaded? No | ||
246 | 2009-07-01T20:59:06Z DEBUG: startup: dvdsub, loaded? No | ||
247 | 2009-07-01T20:59:06Z DEBUG: startup: musicbrainz, loaded? No | ||
248 | 2009-07-01T20:59:06Z DEBUG: startup: wildmidi, loaded? No | ||
249 | 2009-07-01T20:59:06Z DEBUG: startup: rfbsrc, loaded? No | ||
250 | 2009-07-01T20:59:06Z DEBUG: startup: dvdlpcmdec, loaded? No | ||
251 | 2009-07-01T20:59:06Z DEBUG: startup: ofa, loaded? No | ||
252 | 2009-07-01T20:59:06Z DEBUG: startup: gstrtpmanager, loaded? No | ||
253 | 2009-07-01T20:59:06Z DEBUG: startup: dfbvideosink, loaded? No | ||
254 | 2009-07-01T20:59:06Z DEBUG: startup: fbdevsink, loaded? No | ||
255 | 2009-07-01T20:59:06Z DEBUG: startup: siddec, loaded? No | ||
256 | 2009-07-01T20:59:06Z DEBUG: startup: mpeg4videoparse, loaded? No | ||
257 | 2009-07-01T20:59:06Z DEBUG: startup: mpegvideoparse, loaded? No | ||
258 | 2009-07-01T20:59:06Z DEBUG: startup: nsfdec, loaded? No | ||
259 | 2009-07-01T20:59:06Z DEBUG: startup: festival, loaded? No | ||
260 | 2009-07-01T20:59:06Z DEBUG: startup: alsaspdif, loaded? No | ||
261 | 2009-07-01T20:59:06Z DEBUG: startup: mpegtsparse, loaded? No | ||
262 | 2009-07-01T20:59:06Z DEBUG: startup: a52dec, loaded? No | ||
263 | 2009-07-01T20:59:06Z DEBUG: startup: realmedia, loaded? No | ||
264 | 2009-07-01T20:59:06Z DEBUG: startup: dvdread, loaded? No | ||
265 | 2009-07-01T20:59:06Z DEBUG: startup: flvdemux, loaded? No | ||
266 | 2009-07-01T20:59:06Z DEBUG: startup: videosignal, loaded? No | ||
267 | 2009-07-01T20:59:06Z DEBUG: startup: sdp, loaded? No | ||
268 | 2009-07-01T20:59:06Z DEBUG: startup: mms, loaded? No | ||
269 | 2009-07-01T20:59:06Z DEBUG: startup: spcdec, loaded? No | ||
270 | 2009-07-01T20:59:06Z DEBUG: startup: speed, loaded? No | ||
271 | 2009-07-01T20:59:06Z DEBUG: startup: interleave, loaded? No | ||
272 | 2009-07-01T20:59:06Z DEBUG: startup: oss4, loaded? No | ||
273 | 2009-07-01T20:59:06Z DEBUG: startup: dvb, loaded? No | ||
274 | 2009-07-01T20:59:06Z DEBUG: startup: h264parse, loaded? No | ||
275 | 2009-07-01T20:59:06Z DEBUG: startup: bayer, loaded? No | ||
276 | 2009-07-01T20:59:06Z DEBUG: startup: dc1394, loaded? No | ||
277 | 2009-07-01T20:59:06Z DEBUG: startup: vcdsrc, loaded? No | ||
278 | 2009-07-01T20:59:06Z DEBUG: startup: tta, loaded? No | ||
279 | 2009-07-01T20:59:06Z DEBUG: startup: speexresample, loaded? No | ||
280 | 2009-07-01T20:59:06Z DEBUG: startup: mpeg2dec, loaded? No | ||
281 | 2009-07-01T20:59:06Z DEBUG: startup: gstinterlace, loaded? No | ||
282 | 2009-07-01T20:59:06Z DEBUG: startup: nuvdemux, loaded? No | ||
283 | 2009-07-01T20:59:06Z DEBUG: startup: faad, loaded? No | ||
284 | 2009-07-01T20:59:06Z DEBUG: startup: ladspa, loaded? No | ||
285 | 2009-07-01T20:59:06Z DEBUG: startup: mad, loaded? No | ||
286 | 2009-07-01T20:59:06Z DEBUG: startup: soundtouch, loaded? No | ||
287 | 2009-07-01T20:59:06Z DEBUG: startup: iec958, loaded? No | ||
288 | 2009-07-01T20:59:06Z DEBUG: startup: cdxaparse, loaded? No | ||
289 | 2009-07-01T20:59:06Z DEBUG: startup: sndfile, loaded? No | ||
290 | 2009-07-01T20:59:06Z DEBUG: startup: filter, loaded? No | ||
291 | 2009-07-01T20:59:06Z DEBUG: startup: replaygain, loaded? No | ||
292 | 2009-07-01T20:59:06Z DEBUG: startup: gsm, loaded? No | ||
293 | 2009-07-01T20:59:06Z DEBUG: startup: cdaudio, loaded? No | ||
294 | 2009-07-01T20:59:06Z DEBUG: startup: metadata, loaded? No | ||
295 | 2009-07-01T20:59:06Z DEBUG: startup: freeze, loaded? No | ||
296 | 2009-07-01T20:59:06Z DEBUG: startup: mve, loaded? No | ||
297 | 2009-07-01T20:59:06Z DEBUG: startup: jack, loaded? No | ||
298 | 2009-07-01T20:59:06Z DEBUG: startup: mpegaudioparse, loaded? No | ||
299 | 2009-07-01T20:59:06Z DEBUG: startup: dtsdec, loaded? No | ||
300 | 2009-07-01T20:59:06Z DEBUG: startup: selector, loaded? No | ||
301 | 2009-07-01T20:59:06Z DEBUG: startup: dvdspu, loaded? No | ||
302 | 2009-07-01T20:59:06Z DEBUG: startup: real, loaded? No | ||
303 | 2009-07-01T20:59:06Z DEBUG: startup: musepack, loaded? No | ||
304 | 2009-07-01T20:59:06Z DEBUG: startup: neon, loaded? No | ||
305 | 2009-07-01T20:59:06Z DEBUG: startup: bz2, loaded? No | ||
306 | 2009-07-01T20:59:06Z DEBUG: startup: modplug, loaded? No | ||
307 | 2009-07-01T20:59:06Z DEBUG: startup: rawparse, loaded? No | ||
308 | 2009-07-01T20:59:06Z DEBUG: startup: mythtv, loaded? No | ||
309 | 2009-07-01T20:59:06Z DEBUG: startup: vmnc, loaded? No | ||
310 | 2009-07-01T20:59:06Z DEBUG: startup: stereo, loaded? No | ||
311 | 2009-07-01T20:59:06Z DEBUG: startup: mpegstream, loaded? No | ||
312 | 2009-07-01T20:59:06Z DEBUG: startup: postproc, loaded? No | ||
313 | 2009-07-01T20:59:06Z DEBUG: startup: subenc, loaded? No | ||
314 | 2009-07-01T20:59:06Z DEBUG: startup: y4menc, loaded? No | ||
315 | 2009-07-01T20:59:06Z DEBUG: startup: debug, loaded? No | ||
316 | 2009-07-01T20:59:06Z DEBUG: startup: videobalance, loaded? No | ||
317 | 2009-07-01T20:59:06Z DEBUG: startup: alaw, loaded? No | ||
318 | 2009-07-01T20:59:06Z DEBUG: startup: videomixer, loaded? No | ||
319 | 2009-07-01T20:59:06Z DEBUG: startup: annodex, loaded? No | ||
320 | 2009-07-01T20:59:06Z DEBUG: startup: png, loaded? No | ||
321 | 2009-07-01T20:59:06Z DEBUG: startup: goom, loaded? No | ||
322 | 2009-07-01T20:59:06Z DEBUG: startup: goom2k1, loaded? No | ||
323 | 2009-07-01T20:59:06Z DEBUG: startup: sdl, loaded? No | ||
324 | 2009-07-01T20:59:06Z DEBUG: startup: audiotestsrc, loaded? No | ||
325 | 2009-07-01T20:59:06Z DEBUG: startup: level, loaded? No | ||
326 | 2009-07-01T20:59:06Z DEBUG: startup: matroska, loaded? No | ||
327 | 2009-07-01T20:59:06Z DEBUG: startup: ximagesink, loaded? No | ||
328 | 2009-07-01T20:59:06Z DEBUG: startup: gdkpixbuf, loaded? No | ||
329 | 2009-07-01T20:59:06Z DEBUG: startup: videorate, loaded? No | ||
330 | 2009-07-01T20:59:06Z DEBUG: startup: efence, loaded? No | ||
331 | 2009-07-01T20:59:06Z DEBUG: startup: mulaw, loaded? No | ||
332 | 2009-07-01T20:59:06Z DEBUG: startup: flac, loaded? No | ||
333 | 2009-07-01T20:59:06Z DEBUG: startup: spectrum, loaded? No | ||
334 | 2009-07-01T20:59:06Z DEBUG: startup: audiorate, loaded? No | ||
335 | 2009-07-01T20:59:06Z DEBUG: startup: xvimagesink, loaded? No | ||
336 | 2009-07-01T20:59:06Z DEBUG: startup: auparse, loaded? No | ||
337 | 2009-07-01T20:59:06Z DEBUG: startup: shout2send, loaded? No | ||
338 | 2009-07-01T20:59:06Z DEBUG: startup: rtsp, loaded? No | ||
339 | 2009-07-01T20:59:06Z DEBUG: startup: gio, loaded? No | ||
340 | 2009-07-01T20:59:06Z DEBUG: startup: gdp, loaded? No | ||
341 | 2009-07-01T20:59:06Z DEBUG: startup: equalizer, loaded? No | ||
342 | 2009-07-01T20:59:06Z DEBUG: startup: wavenc, loaded? No | ||
343 | 2009-07-01T20:59:06Z DEBUG: startup: wavpack, loaded? No | ||
344 | 2009-07-01T20:59:06Z DEBUG: startup: videobox, loaded? No | ||
345 | 2009-07-01T20:59:06Z DEBUG: startup: smpte, loaded? No | ||
346 | 2009-07-01T20:59:06Z DEBUG: startup: alphacolor, loaded? No | ||
347 | 2009-07-01T20:59:06Z DEBUG: startup: adder, loaded? No | ||
348 | 2009-07-01T20:59:06Z DEBUG: startup: video4linux, loaded? No | ||
349 | 2009-07-01T20:59:06Z DEBUG: startup: gamma, loaded? No | ||
350 | 2009-07-01T20:59:06Z DEBUG: startup: taglib, loaded? No | ||
351 | 2009-07-01T20:59:06Z DEBUG: startup: cacasink, loaded? No | ||
352 | 2009-07-01T20:59:06Z DEBUG: startup: jpeg, loaded? No | ||
353 | 2009-07-01T20:59:06Z DEBUG: startup: soup, loaded? No | ||
354 | 2009-07-01T20:59:06Z DEBUG: startup: videocrop, loaded? No | ||
355 | 2009-07-01T20:59:06Z DEBUG: startup: videotestsrc, loaded? No | ||
356 | 2009-07-01T20:59:06Z DEBUG: startup: videoflip, loaded? No | ||
357 | 2009-07-01T20:59:06Z DEBUG: startup: speex, loaded? No | ||
358 | 2009-07-01T20:59:06Z DEBUG: startup: cairo, loaded? No | ||
359 | 2009-07-01T20:59:06Z DEBUG: startup: monoscope, loaded? No | ||
360 | 2009-07-01T20:59:06Z DEBUG: startup: alpha, loaded? No | ||
361 | 2009-07-01T20:59:06Z DEBUG: startup: dv, loaded? No | ||
362 | 2009-07-01T20:59:06Z DEBUG: startup: subparse, loaded? No | ||
363 | 2009-07-01T20:59:06Z DEBUG: startup: aasink, loaded? No | ||
364 | 2009-07-01T20:59:06Z DEBUG: startup: halelements, loaded? No | ||
365 | 2009-07-01T20:59:06Z DEBUG: startup: audiofx, loaded? No | ||
366 | 2009-07-01T20:59:06Z DEBUG: startup: rtp, loaded? No | ||
367 | 2009-07-01T20:59:06Z DEBUG: startup: cdparanoia, loaded? No | ||
368 | 2009-07-01T20:59:06Z DEBUG: startup: pango, loaded? No | ||
369 | 2009-07-01T20:59:06Z DEBUG: startup: apetag, loaded? No | ||
370 | 2009-07-01T20:59:06Z DEBUG: startup: ximagesrc, loaded? No | ||
371 | 2009-07-01T20:59:06Z DEBUG: startup: navigationtest, loaded? No | ||
372 | 2009-07-01T20:59:06Z DEBUG: startup: cdio, loaded? No | ||
373 | 2009-07-01T20:59:06Z DEBUG: startup: video4linux2, loaded? No | ||
374 | 2009-07-01T20:59:06Z DEBUG: startup: 1394, loaded? No | ||
375 | 2009-07-01T20:59:06Z DEBUG: startup: flxdec, loaded? No | ||
376 | 2009-07-01T20:59:06Z DEBUG: startup: libvisual, loaded? No | ||
377 | 2009-07-01T20:59:06Z DEBUG: startup: cutter, loaded? No | ||
378 | 2009-07-01T20:59:06Z DEBUG: startup: gconfelements, loaded? No | ||
379 | 2009-07-01T20:59:06Z DEBUG: startup: effectv, loaded? No | ||
380 | 2009-07-01T20:59:06Z DEBUG: startup: staticelements, loaded? Yes | ||
381 | 2009-07-01T20:59:06Z INFO: setStartupState: Startup state changing from (state #12) to STATE_SEED_GRANTED_WAIT | ||
382 | 2009-07-01T20:59:06Z INFO: LLEventPollResponder: LLEventPoll initialized with sender 127.0.0.1:9000 | ||
383 | 2009-07-01T20:59:06Z INFO: start: LLEventPollResponder::start <1> http://127.0.0.1:9000/CAPS/EQG/<uuid>/ | ||
384 | 2009-07-01T20:59:06Z INFO: setStartupState: Startup state changing from STATE_SEED_GRANTED_WAIT to STATE_SEED_CAP_GRANTED | ||
385 | 2009-07-01T20:59:06Z INFO: idle_startup: Initializing communications... | ||
386 | 2009-07-01T20:59:06Z INFO: importFile: LLCacheName loaded 72 agent names | ||
387 | 2009-07-01T20:59:06Z INFO: importFile: LLCacheName loaded 1 group names | ||
388 | 2009-07-01T20:59:06Z WARNING: createDummyWidget: Making dummy icon named voice_channel_icon in voice_remote | ||
389 | 2009-07-01T20:59:06Z INFO: LLDrawPoolWLSky: loading WindLight cloud noise from /home/aw/src/aaamyimprudence/linden/indra/viewer-linux-i686-relwithdebinfo/newview/packaged/app_settings/windlight/clouds2.tga | ||
390 | 2009-07-01T20:59:07Z WARNING: LLViewerImage::setIsMissingAsset: /home/aw/src/aaamyimprudence/linden/indra/viewer-linux-i686-relwithdebinfo/newview/packaged/skins/default/textures/ <uuid>: Marking image as missing | ||
391 | 2009-07-01T20:59:08Z INFO: setStartupState: Startup state changing from STATE_SEED_CAP_GRANTED to STATE_WORLD_WAIT | ||
392 | 2009-07-01T20:59:08Z INFO: idle_startup: viewer: UserLoginLocationReply() Enabling 127.0.0.1:9000 with code <code> | ||
393 | 2009-07-01T20:59:08Z WARNING: logRanOffEndOfPacket: Ran off end of packet RegionHandshake from 127.0.0.1:9000 trying to read 4 bytes at position 243 going past packet end at 243 | ||
394 | 2009-07-01T20:59:08Z WARNING: logRanOffEndOfPacket: Ran off end of packet RegionHandshake from 127.0.0.1:9000 trying to read 4 bytes at position 247 going past packet end at 243 | ||
395 | 2009-07-01T20:59:08Z WARNING: logRanOffEndOfPacket: Ran off end of packet RegionHandshake from 127.0.0.1:9000 trying to read 1 bytes at position 251 going past packet end at 243 | ||
396 | 2009-07-01T20:59:08Z WARNING: logRanOffEndOfPacket: Ran off end of packet RegionHandshake from 127.0.0.1:9000 trying to read 1 bytes at position 252 going past packet end at 243 | ||
397 | 2009-07-01T20:59:08Z WARNING: logRanOffEndOfPacket: Ran off end of packet RegionHandshake from 127.0.0.1:9000 trying to read 1 bytes at position 253 going past packet end at 243 | ||
398 | 2009-07-01T20:59:08Z INFO: setStartupState: Startup state changing from STATE_WORLD_WAIT to STATE_AGENT_SEND | ||
399 | 2009-07-01T20:59:08Z INFO: setStartupState: Startup state changing from STATE_AGENT_SEND to STATE_AGENT_WAIT | ||
400 | 2009-07-01T20:59:08Z INFO: stopInternetStream: entered stopInternetStream() | ||
401 | 2009-07-01T20:59:09Z WARNING: process_agent_movement_complete: agent_movement_complete() with NULL avatarp. | ||
402 | 2009-07-01T20:59:09Z INFO: process_agent_movement_complete: Changing home region to 256000:256000 | ||
403 | 2009-07-01T20:59:09Z INFO: sendToSim: Sending throttle settings, total BW 1050 | ||
404 | 2009-07-01T20:59:09Z INFO: setStartupState: Startup state changing from STATE_AGENT_WAIT to STATE_INVENTORY_SEND | ||
405 | 2009-07-01T20:59:09Z INFO: loadFromFile: LLInventoryModel::loadFromFile(/home/aw/.imprudence/cache/<uuid>.inv) | ||
406 | 2009-07-01T20:59:09Z INFO: loadSkeleton: Successfully loaded 7 categories and 0 items from cache. | ||
407 | 2009-07-01T20:59:09Z INFO: loadFromFile: LLInventoryModel::loadFromFile(/home/aw/.imprudence/cache/<uuid>.inv) | ||
408 | 2009-07-01T20:59:09Z INFO: loadSkeleton: Successfully loaded 5 categories and 0 items from cache. | ||
409 | 2009-07-01T20:59:09Z INFO: buildParentChildMap: LLInventoryModel::buildParentChildMap() | ||
410 | 2009-07-01T20:59:09Z INFO: idle_startup: Setting Inventory changed mask and notifying observers | ||
411 | 2009-07-01T20:59:09Z INFO: idle_startup: Registering Callbacks | ||
412 | 2009-07-01T20:59:09Z INFO: idle_startup: Inventory | ||
413 | 2009-07-01T20:59:09Z INFO: idle_startup: AvatarTracker | ||
414 | 2009-07-01T20:59:09Z INFO: idle_startup: Landmark | ||
415 | 2009-07-01T20:59:09Z INFO: idle_startup: Requesting Mute List | ||
416 | 2009-07-01T20:59:09Z INFO: idle_startup: Requesting Money Balance | ||
417 | 2009-07-01T20:59:09Z INFO: idle_startup: Requesting Agent Data | ||
418 | 2009-07-01T20:59:09Z INFO: idle_startup: Creating Inventory Views | ||
419 | 2009-07-01T20:59:09Z INFO: init: LLInventoryView::init: reading from 0xbfa919f0 | ||
420 | 2009-07-01T20:59:09Z INFO: idle_startup: Inventory Views Created | ||
421 | 2009-07-01T20:59:09Z INFO: setStartupState: Startup state changing from STATE_INVENTORY_SEND to STATE_MISC | ||
422 | 2009-07-01T20:59:09Z INFO: initWind: LLAudioEngine_OpenAL::initWind() start | ||
423 | 2009-07-01T20:59:09Z INFO: initWind: LLAudioEngine_OpenAL::initWind() done | ||
424 | 2009-07-01T20:59:09Z INFO: setStartupState: Startup state changing from STATE_MISC to STATE_PRECACHE | ||
425 | 2009-07-01T20:59:09Z INFO: idle: Transmitting sessions stats | ||
426 | 2009-07-01T20:59:09Z WARNING: send_stats: Could not get ViewerStats capability | ||
427 | 2009-07-01T20:59:09Z WARNING: getVisualParam: LLCharacter::getVisualParam() Invalid visual parameter: Lipsync_Ooh | ||
428 | 2009-07-01T20:59:09Z WARNING: getVisualParam: LLCharacter::getVisualParam() Invalid visual parameter: Lipsync_Aah | ||
429 | 2009-07-01T20:59:09Z WARNING: buildCharacter: Missing 'Ooh' morph for lipsync, using fallback. | ||
430 | 2009-07-01T20:59:09Z WARNING: buildCharacter: Missing 'Aah' morph for lipsync, using fallback. | ||
431 | 2009-07-01T20:59:09Z INFO: backgroundFetch: Inventory fetch completed | ||
432 | 2009-07-01T20:59:09Z INFO: addCircuitData: LLCircuit::addCircuitData for 127.0.0.1:9002 | ||
433 | 2009-07-01T20:59:09Z INFO: addRegion: Adding new region (1000:1001) | ||
434 | 2009-07-01T20:59:09Z INFO: addRegion: Host: 127.0.0.1:9002 | ||
435 | 2009-07-01T20:59:09Z INFO: process_enable_simulator: simulator_enable() Enabling 127.0.0.1:9002 with code <code> | ||
436 | 2009-07-01T20:59:09Z INFO: setSeedCapability: posting to seed http://127.0.0.1:9000/CAPS/<uuid>/ | ||
437 | 2009-07-01T20:59:09Z INFO: processUseCachedMuteList: LLMuteList::processUseCachedMuteList() | ||
438 | 2009-07-01T20:59:09Z WARNING: loadFromFile: Couldn't open mute list /home/aw/.imprudence/cache/<uuid>.cached_mute | ||
439 | 2009-07-01T20:59:09Z INFO: process_money_balance_reply: L$, credit, committed: 0 0 0 | ||
440 | 2009-07-01T20:59:10Z INFO: LLAgent::sendAgentSetAppearance: TAT: Sent AgentSetAppearance: HEAD UPPER LOWER EYES | ||
441 | 2009-07-01T20:59:10Z INFO: LLAgent::sendAgentSetAppearance: TAT: Sending cached texture data | ||
442 | 2009-07-01T20:59:10Z INFO: deleteCachedImages: Clearing Static Textures KB GL:5120KB TGA:326KB | ||
443 | 2009-07-01T20:59:10Z INFO: LLEventPollResponder: LLEventPoll initialized with sender 127.0.0.1:9002 | ||
444 | 2009-07-01T20:59:10Z INFO: start: LLEventPollResponder::start <2> http://127.0.0.1:9000/CAPS/EQG/<uuid>/ | ||
445 | 2009-07-01T20:59:10Z WARNING: logRanOffEndOfPacket: Ran off end of packet RegionHandshake from 127.0.0.1:9002 trying to read 4 bytes at position 243 going past packet end at 243 | ||
446 | 2009-07-01T20:59:10Z WARNING: logRanOffEndOfPacket: Ran off end of packet RegionHandshake from 127.0.0.1:9002 trying to read 4 bytes at position 247 going past packet end at 243 | ||
447 | 2009-07-01T20:59:10Z WARNING: logRanOffEndOfPacket: Ran off end of packet RegionHandshake from 127.0.0.1:9002 trying to read 1 bytes at position 251 going past packet end at 243 | ||
448 | 2009-07-01T20:59:10Z WARNING: logRanOffEndOfPacket: Ran off end of packet RegionHandshake from 127.0.0.1:9002 trying to read 1 bytes at position 252 going past packet end at 243 | ||
449 | 2009-07-01T20:59:10Z WARNING: logRanOffEndOfPacket: Ran off end of packet RegionHandshake from 127.0.0.1:9002 trying to read 1 bytes at position 253 going past packet end at 243 | ||
450 | 2009-07-01T20:59:14Z INFO: idle: Unknown object updates: 3 | ||
451 | 2009-07-01T20:59:15Z INFO: setStartupState: Startup state changing from STATE_PRECACHE to STATE_WEARABLES_WAIT | ||
452 | 2009-07-01T20:59:15Z INFO: setStartupState: Startup state changing from STATE_WEARABLES_WAIT to STATE_CLEANUP | ||
453 | 2009-07-01T20:59:15Z INFO: setStartupState: Startup state changing from STATE_CLEANUP to STATE_STARTED | ||
454 | 2009-07-01T20:59:15Z INFO: idle_startup: Doing first audio_update_volume... | ||
455 | 2009-07-01T20:59:15Z INFO: idle_startup: Done first audio_update_volume. | ||
456 | 2009-07-01T20:59:15Z INFO: updateGeometry: WL Skydome strips in 3 batches. | ||
457 | 2009-07-01T20:59:20Z INFO: sendMapLayerRequest: LLWorldMap::sendMapLayerRequest via capability | ||
458 | 2009-07-01T20:59:20Z INFO: backgroundFetch: Inventory fetch completed | ||
459 | 2009-07-01T20:59:20Z INFO: parse: LLSDXMLParser::Impl::parse: XML_STATUS_ERROR parsing:OpenSim.Framework.Communications.Capabilities.LLSDMapLayerResponse | ||
460 | 2009-07-01T20:59:20Z INFO: result: LLMapLayerResponder::result from capabilities | ||
461 | 2009-07-01T20:59:26Z WARNING: onSelectServer: onSelectServer called | ||
462 | 2009-07-01T20:59:31Z WARNING: teleport: tp button current grid = local | ||
463 | 2009-07-01T20:59:31Z INFO: requestLogout: requestLogout | ||
464 | 2009-07-01T20:59:31Z WARNING: send_stats: Could not get ViewerStats capability | ||
465 | 2009-07-01T20:59:31Z INFO: sendLogoutRequest: Created logout marker file /home/aw/.imprudence/logs/Imprudence.logout_marker | ||
466 | 2009-07-01T20:59:31Z INFO: saveSnapshot: Saving snapshot to: /home/aw/.imprudence/armin_weatherwax/screen_last.bmp | ||
467 | 2009-07-01T20:59:32Z INFO: removeRegion: Removing region 256000:256256 | ||
468 | 2009-07-01T20:59:32Z INFO: stop: LLEventPollResponder::stop <2> http://127.0.0.1:9000/CAPS/EQG/<uuid>/ | ||
469 | 2009-07-01T20:59:32Z INFO: disableCircuit: LLMessageSystem::disableCircuit for 127.0.0.1:9002 | ||
470 | 2009-07-01T20:59:32Z WARNING: disableCircuit: Couldn't find circuit code for 127.0.0.1:9002 | ||
471 | 2009-07-01T20:59:32Z INFO: stop: LLEventPollResponder::stop <2> http://127.0.0.1:9000/CAPS/EQG/<uuid>/ | ||
472 | 2009-07-01T20:59:38Z INFO: forceQuit: Destroying the entire world | ||
473 | 2009-07-01T20:59:38Z INFO: setStartupState: Startup state changing from STATE_STARTED to STATE_LOGIN_SHOW | ||
474 | 2009-07-01T20:59:38Z WARNING: createDummyWidget: Making dummy text named ne_label in mini_mapview | ||
475 | 2009-07-01T20:59:38Z WARNING: createDummyWidget: Making dummy text named nw_label in mini_mapview | ||
476 | 2009-07-01T20:59:38Z WARNING: createDummyWidget: Making dummy text named sw_label in mini_mapview | ||
477 | 2009-07-01T20:59:38Z WARNING: createDummyWidget: Making dummy text named se_label in mini_mapview | ||
478 | 2009-07-01T20:59:38Z INFO: disconnectViewer: Disconnecting viewer! | ||
479 | 2009-07-01T20:59:38Z INFO: saveToFile: LLInventoryModel::saveToFile(/home/aw/.imprudence/cache/<uuid>.inv) | ||
480 | 2009-07-01T20:59:38Z INFO: saveToFile: LLInventoryModel::saveToFile(/home/aw/.imprudence/cache/<uuid>.inv) | ||
481 | 2009-07-01T20:59:38Z INFO: removeRegion: Removing region 256000:256000 | ||
482 | 2009-07-01T20:59:38Z INFO: stop: LLEventPollResponder::stop <1> http://127.0.0.1:9000/CAPS/EQG/<uuid>/ | ||
483 | 2009-07-01T20:59:38Z INFO: cleanup: Viewer disconnected | ||
484 | 2009-07-01T20:59:38Z INFO: cleanup: Cleaning Up | ||
485 | 2009-07-01T20:59:38Z INFO: cleanupHUDObjects: LLHUDObject 0xce9dc20 has 2 refs! | ||
486 | 2009-07-01T20:59:38Z INFO: cleanupHUDObjects: LLHUDObject 0x9534b040 has 2 refs! | ||
487 | 2009-07-01T20:59:38Z INFO: cleanupHUDObjects: LLHUDObject 0x95c48ed0 has 2 refs! | ||
488 | 2009-07-01T20:59:38Z INFO: LLAgent::setAvatarObject: Setting LLAgent::mAvatarObject to NULL | ||
489 | 2009-07-01T20:59:38Z WARNING: updateMeshTextures: updateMeshTextures: invalid host for object: <uuid> | ||
490 | 2009-07-01T20:59:38Z INFO: cleanupHUDObjects: LLHUDObject 0x953a0100 has 2 refs! | ||
491 | 2009-07-01T20:59:38Z INFO: cleanupHUDObjects: LLHUDObject 0x95855210 has 2 refs! | ||
492 | 2009-07-01T20:59:38Z INFO: cleanup: HUD Objects cleaned up | ||
493 | 2009-07-01T20:59:38Z INFO: LLVoiceClient::stateMachine: Disabling voice before connection to daemon, terminating. | ||
494 | 2009-07-01T20:59:38Z INFO: setStartupState: Startup state changing from STATE_LOGIN_SHOW to STATE_LOGIN_CLEANUP | ||
495 | 2009-07-01T20:59:38Z INFO: idle_startup: Attempting login as: Armin Weatherwax <uuid> | ||
496 | 2009-07-01T20:59:38Z WARNING: loadFromFile: Cannot find file /home/aw/.imprudence/armin_weatherwax/settings_crash_behavior.xml to load. | ||
497 | 2009-07-01T20:59:38Z WARNING: loadSettingsFromDirectory: Cannot load /home/aw/.imprudence/armin_weatherwax/settings_crash_behavior.xml - No settings found. | ||
498 | 2009-07-01T20:59:38Z WARNING: loadFromFile: Cannot find file /home/aw/.imprudence/armin_weatherwax/settings.xml to load. | ||
499 | 2009-07-01T20:59:38Z WARNING: loadSettingsFromDirectory: Cannot load /home/aw/.imprudence/armin_weatherwax/settings.xml - No settings found. | ||
500 | 2009-07-01T20:59:38Z INFO: loadSettingsFromDirectory: Loaded settings file /home/aw/.imprudence/armin_weatherwax/settings_per_account.xml | ||
501 | 2009-07-01T20:59:38Z INFO: loadFile: Loading history.xml file at url_history.xml | ||
502 | 2009-07-01T20:59:38Z INFO: loadFile: file missing, ill-formed, or simply undefined; not changing the file | ||
503 | 2009-07-01T20:59:39Z INFO: setStartupState: Startup state changing from STATE_LOGIN_CLEANUP to STATE_LOGIN_AUTH_INIT | ||
504 | 2009-07-01T20:59:39Z INFO: rewriteURI: Rewriting http://127.0.0.1:9000/ | ||
505 | 2009-07-01T20:59:39Z INFO: rewriteResult: [0] http://127.0.0.1:9000/ | ||
506 | 2009-07-01T20:59:39Z INFO: setStartupState: Startup state changing from STATE_LOGIN_AUTH_INIT to STATE_LOGIN_AUTHENTICATE | ||
507 | 2009-07-01T20:59:39Z INFO: authenticate: Authenticating: Armin Weatherwax, | ||
508 | 2009-07-01T20:59:39Z INFO: authenticate: Options: inventory-root, inventory-skeleton, inventory-lib-root, inventory-lib-owner, inventory-skel-lib, initial-outfit, gestures, event_categories, event_notifications, classified_categories, buddy-list, ui-config, tutorial_setting, login-flags, global-textures, END | ||
509 | 2009-07-01T20:59:39Z INFO: authenticate: LLUserAuth::authenticate: uri=http://127.0.0.1:9000/ | ||
510 | 2009-07-01T20:59:39Z INFO: setStartupState: Startup state changing from STATE_LOGIN_AUTHENTICATE to STATE_LOGIN_NO_DATA_YET | ||
511 | 2009-07-01T20:59:39Z INFO: transferRate: Buffer size: 105394 B | ||
512 | 2009-07-01T20:59:39Z INFO: transferRate: Transfer rate: 5616.14 Kb/s | ||
513 | 2009-07-01T20:59:39Z INFO: authResponse: Processed response: 0 | ||
514 | 2009-07-01T20:59:39Z INFO: setStartupState: Startup state changing from STATE_LOGIN_NO_DATA_YET to STATE_LOGIN_DOWNLOADING | ||
515 | 2009-07-01T20:59:39Z INFO: setStartupState: Startup state changing from STATE_LOGIN_DOWNLOADING to STATE_LOGIN_PROCESS_RESPONSE | ||
516 | 2009-07-01T20:59:39Z INFO: saveFile: Saved grids to /home/aw/.imprudence/user_settings/grid_info.xml | ||
517 | 2009-07-01T20:59:39Z INFO: setStartupState: Startup state changing from STATE_LOGIN_PROCESS_RESPONSE to STATE_WORLD_INIT | ||
518 | 2009-07-01T20:59:39Z INFO: LLVoiceClient::userAuthorized: name "Armin Weatherwax" , ID <uuid> | ||
519 | 2009-07-01T20:59:39Z INFO: saveToFile: Saved to /home/aw/.imprudence/user_settings/settings_imprudence.xml | ||
520 | 2009-07-01T20:59:39Z INFO: addRegion: Adding new region (1000:1000) | ||
521 | 2009-07-01T20:59:39Z INFO: addRegion: Host: 127.0.0.1:9000 | ||
522 | 2009-07-01T20:59:39Z INFO: idle_startup: Adding initial simulator { 256000, 256000, 0 } | ||
523 | 2009-07-01T20:59:39Z INFO: setSeedCapability: posting to seed http://127.0.0.1:9000/CAPS/<uuid>/ | ||
524 | 2009-07-01T20:59:39Z INFO: LLAgent::setRegion: Moving agent into region: located at 127.0.0.1:9000 | ||
525 | 2009-07-01T20:59:39Z INFO: setStartupState: Startup state changing from STATE_WORLD_INIT to (state #12) | ||
526 | 2009-07-01T20:59:39Z INFO: setStartupState: Startup state changing from (state #12) to STATE_SEED_GRANTED_WAIT | ||
527 | 2009-07-01T20:59:39Z INFO: LLEventPollResponder: LLEventPoll initialized with sender 127.0.0.1:9000 | ||
528 | 2009-07-01T20:59:39Z INFO: start: LLEventPollResponder::start <3> http://127.0.0.1:9000/CAPS/EQG/<uuid>/ | ||
529 | 2009-07-01T20:59:39Z INFO: setStartupState: Startup state changing from STATE_SEED_GRANTED_WAIT to STATE_SEED_CAP_GRANTED | ||
530 | 2009-07-01T20:59:39Z INFO: idle_startup: Initializing communications... | ||
531 | 2009-07-01T20:59:42Z INFO: setStartupState: Startup state changing from STATE_SEED_CAP_GRANTED to STATE_WORLD_WAIT | ||
532 | 2009-07-01T20:59:42Z INFO: idle_startup: viewer: UserLoginLocationReply() Enabling 127.0.0.1:9000 with code <code> | ||
533 | 2009-07-01T20:59:42Z INFO: stop: LLEventPollResponder::stop <1> http://127.0.0.1:9000/CAPS/EQG/<uuid>/ | ||
534 | 2009-07-01T20:59:42Z INFO: setStartupState: Startup state changing from STATE_WORLD_WAIT to STATE_AGENT_SEND | ||
535 | 2009-07-01T20:59:42Z WARNING: sendEffects: Trying to send dead effect! | ||
536 | 2009-07-01T20:59:42Z WARNING: sendEffects: Trying to send dead effect! | ||
537 | 2009-07-01T20:59:42Z WARNING: sendEffects: Trying to send dead effect! | ||
538 | 2009-07-01T20:59:42Z WARNING: sendEffects: Trying to send dead effect! | ||
539 | 2009-07-01T20:59:42Z INFO: setStartupState: Startup state changing from STATE_AGENT_SEND to STATE_AGENT_WAIT | ||
540 | 2009-07-01T20:59:42Z INFO: checkPacketInID: packet_out_of_order - got packet 370 expecting 1424 from 127.0.0.1:9000 | ||
541 | 2009-07-01T20:59:42Z INFO: setStartupState: Startup state changing from STATE_AGENT_WAIT to STATE_INVENTORY_SEND | ||
542 | 2009-07-01T20:59:42Z INFO: stopInternetStream: entered stopInternetStream() | ||
543 | 2009-07-01T20:59:42Z INFO: loadFromFile: LLInventoryModel::loadFromFile(/home/aw/.imprudence/cache/<uuid>.inv) | ||
544 | 2009-07-01T20:59:42Z INFO: loadSkeleton: Successfully loaded 7 categories and 0 items from cache. | ||
545 | 2009-07-01T20:59:42Z INFO: loadFromFile: LLInventoryModel::loadFromFile(/home/aw/.imprudence/cache/<uuid>.inv) | ||
546 | 2009-07-01T20:59:42Z INFO: loadSkeleton: Successfully loaded 5 categories and 0 items from cache. | ||
547 | 2009-07-01T20:59:42Z INFO: buildParentChildMap: LLInventoryModel::buildParentChildMap() | ||
548 | 2009-07-01T20:59:42Z INFO: idle_startup: Setting Inventory changed mask and notifying observers | ||
549 | 2009-07-01T20:59:42Z INFO: idle_startup: Registering Callbacks | ||
550 | 2009-07-01T20:59:42Z INFO: idle_startup: Inventory | ||
551 | 2009-07-01T20:59:42Z INFO: idle_startup: AvatarTracker | ||
552 | 2009-07-01T20:59:42Z INFO: idle_startup: Landmark | ||
553 | 2009-07-01T20:59:42Z INFO: idle_startup: Requesting Mute List | ||
554 | 2009-07-01T20:59:42Z INFO: idle_startup: Requesting Money Balance | ||
555 | 2009-07-01T20:59:42Z INFO: idle_startup: Requesting Agent Data | ||
556 | 2009-07-01T20:59:42Z INFO: idle_startup: Creating Inventory Views | ||
557 | 2009-07-01T20:59:42Z INFO: init: LLInventoryView::init: reading from 0xbfa919f0 | ||
558 | 2009-07-01T20:59:42Z INFO: idle_startup: Inventory Views Created | ||
559 | 2009-07-01T20:59:42Z INFO: setStartupState: Startup state changing from STATE_INVENTORY_SEND to STATE_MISC | ||
560 | 2009-07-01T20:59:42Z INFO: setStartupState: Startup state changing from STATE_MISC to STATE_PRECACHE | ||
561 | 2009-07-01T20:59:42Z WARNING: logRanOffEndOfPacket: Ran off end of packet RegionHandshake from 127.0.0.1:9000 trying to read 4 bytes at position 243 going past packet end at 243 | ||
562 | 2009-07-01T20:59:42Z WARNING: logRanOffEndOfPacket: Ran off end of packet RegionHandshake from 127.0.0.1:9000 trying to read 4 bytes at position 247 going past packet end at 243 | ||
563 | 2009-07-01T20:59:42Z WARNING: logRanOffEndOfPacket: Ran off end of packet RegionHandshake from 127.0.0.1:9000 trying to read 1 bytes at position 251 going past packet end at 243 | ||
564 | 2009-07-01T20:59:42Z WARNING: logRanOffEndOfPacket: Ran off end of packet RegionHandshake from 127.0.0.1:9000 trying to read 1 bytes at position 252 going past packet end at 243 | ||
565 | 2009-07-01T20:59:42Z WARNING: logRanOffEndOfPacket: Ran off end of packet RegionHandshake from 127.0.0.1:9000 trying to read 1 bytes at position 253 going past packet end at 243 | ||
566 | 2009-07-01T20:59:42Z INFO: checkPacketInID: packet_out_of_order - got packet 3 expecting 371 from 127.0.0.1:9000 | ||
567 | 2009-07-01T20:59:42Z WARNING: process_agent_movement_complete: agent_movement_complete() with NULL avatarp. | ||
568 | 2009-07-01T20:59:42Z INFO: process_agent_movement_complete: Changing home region to 256000:256000 | ||
569 | 2009-07-01T20:59:42Z INFO: sendToSim: Sending throttle settings, total BW 1050 | ||
570 | 2009-07-01T20:59:42Z INFO: backgroundFetch: Inventory fetch completed | ||
571 | 2009-07-01T20:59:42Z WARNING: getVisualParam: LLCharacter::getVisualParam() Invalid visual parameter: Lipsync_Ooh | ||
572 | 2009-07-01T20:59:42Z WARNING: getVisualParam: LLCharacter::getVisualParam() Invalid visual parameter: Lipsync_Aah | ||
573 | 2009-07-01T20:59:42Z WARNING: buildCharacter: Missing 'Ooh' morph for lipsync, using fallback. | ||
574 | 2009-07-01T20:59:42Z WARNING: buildCharacter: Missing 'Aah' morph for lipsync, using fallback. | ||
575 | 2009-07-01T20:59:42Z INFO: do_elfio_glibc_backtrace: Opening stack trace file /home/aw/.imprudence/logs/stack_trace.log | ||
576 | 2009-07-01T20:59:46Z INFO: do_elfio_glibc_backtrace: Finished generating stack trace. | ||
577 | 2009-07-01T20:59:46Z INFO: handleViewerCrash: Handle viewer crash entry. | ||
578 | 2009-07-01T20:59:46Z INFO: handleViewerCrash: Creating crash marker file /home/aw/.imprudence/logs/Imprudence.error_marker | ||
579 | 2009-07-01T20:59:46Z INFO: handleViewerCrash: Created crash marker file /home/aw/.imprudence/logs/Imprudence.error_marker | ||
580 | 2009-07-01T20:59:46Z INFO: handleViewerCrash: Handle viewer crash generating stats log. | ||
581 | 2009-07-01T20:59:46Z INFO: writeDebugInfo: Opening debug file /home/aw/.imprudence/logs/debug_info.log | ||
diff --git a/linden/indra/newview/llworld.cpp b/linden/indra/newview/llworld.cpp index 9ee789a..4c02191 100644 --- a/linden/indra/newview/llworld.cpp +++ b/linden/indra/newview/llworld.cpp | |||
@@ -117,6 +117,7 @@ LLWorld::LLWorld() : | |||
117 | 117 | ||
118 | void LLWorld::destroyClass() | 118 | void LLWorld::destroyClass() |
119 | { | 119 | { |
120 | mHoleWaterObjects.clear(); | ||
120 | gObjectList.destroy(); | 121 | gObjectList.destroy(); |
121 | for(region_list_t::iterator region_it = mRegionList.begin(); region_it != mRegionList.end(); ) | 122 | for(region_list_t::iterator region_it = mRegionList.begin(); region_it != mRegionList.end(); ) |
122 | { | 123 | { |
diff --git a/mAttachedObject.diff.txt b/mAttachedObject.diff.txt new file mode 100644 index 0000000..73ffab5 --- /dev/null +++ b/mAttachedObject.diff.txt | |||
@@ -0,0 +1,16 @@ | |||
1 | diff --git a/linden/indra/newview/llviewerjointattachment.h b/linden/indra/newview/llviewerjointattachment.h | ||
2 | index dd63bfd..6a505c0 100644 | ||
3 | --- a/linden/indra/newview/llviewerjointattachment.h | ||
4 | +++ b/linden/indra/newview/llviewerjointattachment.h | ||
5 | @@ -98,7 +98,9 @@ protected: | ||
6 | void calcLOD(); | ||
7 | |||
8 | protected: | ||
9 | - LLPointer<LLViewerObject> mAttachedObject; | ||
10 | + | ||
11 | + // Backlink only; don't make this an LLPointer. | ||
12 | + LLViewerObject* mAttachedObject; | ||
13 | BOOL mVisibleInFirst; | ||
14 | LLVector3 mOriginalPos; | ||
15 | S32 mGroup; | ||
16 | |||
diff --git a/meerkat-llmenugl.diff.txt b/meerkat-llmenugl.diff.txt new file mode 100644 index 0000000..7ca8c2c --- /dev/null +++ b/meerkat-llmenugl.diff.txt | |||
@@ -0,0 +1,534 @@ | |||
1 | diff -uwN /linden/indra/llui/llmenugl.cpp /linden/indra/llui/llmenugl.cpp | ||
2 | --- /linden/indra/llui/llmenugl.cpp 2009-06-12 14:14:40.000000000 +0200 | ||
3 | +++ /linden/indra/llui/llmenugl.cpp 2009-06-23 02:16:35.000000000 +0200 | ||
4 | @@ -413,7 +413,7 @@ | ||
5 | LLMenuGL::setKeyboardMode(FALSE); | ||
6 | |||
7 | doIt(); | ||
8 | - make_ui_sound("UISndClickRelease"); | ||
9 | + //make_ui_sound("UISndClickRelease"); | ||
10 | return TRUE; | ||
11 | } | ||
12 | |||
13 | @@ -1033,47 +1033,30 @@ | ||
14 | } | ||
15 | |||
16 | |||
17 | -LLMenuItemBranchGL::LLMenuItemBranchGL( const std::string& name, const std::string& label, LLHandle<LLView> branch, | ||
18 | +LLMenuItemBranchGL::LLMenuItemBranchGL( const std::string& name, const std::string& label, LLMenuGL* branch, | ||
19 | KEY key, MASK mask ) : | ||
20 | LLMenuItemGL( name, label, key, mask ), | ||
21 | mBranch( branch ) | ||
22 | { | ||
23 | - if(!dynamic_cast<LLMenuGL*>(branch.get())) | ||
24 | - { | ||
25 | - llerrs << "Non-menu handle passed as branch reference." << llendl; | ||
26 | - } | ||
27 | - | ||
28 | - if(getBranch()) | ||
29 | - { | ||
30 | - getBranch()->setVisible( FALSE ); | ||
31 | - getBranch()->setParentMenuItem(this); | ||
32 | - } | ||
33 | -} | ||
34 | - | ||
35 | -LLMenuItemBranchGL::~LLMenuItemBranchGL() | ||
36 | -{ | ||
37 | - LLView::deleteViewByHandle(mBranch); | ||
38 | + mBranch->setVisible( FALSE ); | ||
39 | + mBranch->setParentMenuItem(this); | ||
40 | } | ||
41 | |||
42 | // virtual | ||
43 | LLView* LLMenuItemBranchGL::getChildView(const std::string& name, BOOL recurse, BOOL create_if_missing) const | ||
44 | { | ||
45 | // richard: this is redundant with parent, remove | ||
46 | - if (getBranch()) | ||
47 | + if (mBranch->getName() == name) | ||
48 | { | ||
49 | - if(getBranch()->getName() == name) | ||
50 | - { | ||
51 | - return getBranch(); | ||
52 | + return mBranch; | ||
53 | } | ||
54 | - | ||
55 | // Always recurse on branches | ||
56 | - LLView* child = getBranch()->getChildView(name, recurse, FALSE); | ||
57 | - if(child) | ||
58 | + LLView* child = mBranch->getChildView(name, recurse, FALSE); | ||
59 | + if (!child) | ||
60 | { | ||
61 | - return child; | ||
62 | + child = LLView::getChildView(name, recurse, create_if_missing); | ||
63 | } | ||
64 | - } | ||
65 | - return LLView::getChildView(name, recurse, create_if_missing);; | ||
66 | + return child; | ||
67 | } | ||
68 | |||
69 | // virtual | ||
70 | @@ -1083,25 +1066,21 @@ | ||
71 | LLMenuGL::setKeyboardMode(FALSE); | ||
72 | |||
73 | doIt(); | ||
74 | - make_ui_sound("UISndClickRelease"); | ||
75 | + //make_ui_sound("UISndClickRelease"); | ||
76 | return TRUE; | ||
77 | } | ||
78 | |||
79 | BOOL LLMenuItemBranchGL::handleAcceleratorKey(KEY key, MASK mask) | ||
80 | { | ||
81 | - if(getBranch()) | ||
82 | - { | ||
83 | - return getBranch()->handleAcceleratorKey(key, mask); | ||
84 | - } | ||
85 | - return FALSE; | ||
86 | + return mBranch->handleAcceleratorKey(key, mask); | ||
87 | } | ||
88 | |||
89 | // virtual | ||
90 | LLXMLNodePtr LLMenuItemBranchGL::getXML(bool save_children) const | ||
91 | { | ||
92 | - if (getBranch()) | ||
93 | + if (mBranch) | ||
94 | { | ||
95 | - return getBranch()->getXML(); | ||
96 | + return mBranch->getXML(); | ||
97 | } | ||
98 | |||
99 | return LLMenuItemGL::getXML(); | ||
100 | @@ -1112,19 +1091,16 @@ | ||
101 | // if not, it will be added to the list | ||
102 | BOOL LLMenuItemBranchGL::addToAcceleratorList(std::list<LLKeyBinding*> *listp) | ||
103 | { | ||
104 | - if(getBranch()) | ||
105 | - { | ||
106 | - U32 item_count = getBranch()->getItemCount(); | ||
107 | + U32 item_count = mBranch->getItemCount(); | ||
108 | LLMenuItemGL *item; | ||
109 | |||
110 | while (item_count--) | ||
111 | { | ||
112 | - if ((item = getBranch()->getItem(item_count))) | ||
113 | + if ((item = mBranch->getItem(item_count))) | ||
114 | { | ||
115 | return item->addToAcceleratorList(listp); | ||
116 | } | ||
117 | } | ||
118 | - } | ||
119 | return FALSE; | ||
120 | } | ||
121 | |||
122 | @@ -1146,18 +1122,18 @@ | ||
123 | |||
124 | // keyboard navigation automatically propagates highlight to sub-menu | ||
125 | // to facilitate fast menu control via jump keys | ||
126 | - if (getBranch() && LLMenuGL::getKeyboardMode() && !getBranch()->getHighlightedItem()) | ||
127 | + if (LLMenuGL::getKeyboardMode() && !mBranch->getHighlightedItem()) | ||
128 | { | ||
129 | - getBranch()->highlightNextItem(NULL); | ||
130 | + mBranch->highlightNextItem(NULL); | ||
131 | } | ||
132 | } | ||
133 | |||
134 | BOOL LLMenuItemBranchGL::handleKey(KEY key, MASK mask, BOOL called_from_parent) | ||
135 | { | ||
136 | BOOL handled = FALSE; | ||
137 | - if (called_from_parent && getBranch()) | ||
138 | + if (called_from_parent) | ||
139 | { | ||
140 | - handled = getBranch()->handleKey(key, mask, called_from_parent); | ||
141 | + handled = mBranch->handleKey(key, mask, called_from_parent); | ||
142 | } | ||
143 | |||
144 | if (!handled) | ||
145 | @@ -1171,9 +1147,9 @@ | ||
146 | BOOL LLMenuItemBranchGL::handleUnicodeChar(llwchar uni_char, BOOL called_from_parent) | ||
147 | { | ||
148 | BOOL handled = FALSE; | ||
149 | - if (called_from_parent && getBranch()) | ||
150 | + if (called_from_parent) | ||
151 | { | ||
152 | - handled = getBranch()->handleUnicodeChar(uni_char, TRUE); | ||
153 | + handled = mBranch->handleUnicodeChar(uni_char, TRUE); | ||
154 | } | ||
155 | |||
156 | if (!handled) | ||
157 | @@ -1189,19 +1165,14 @@ | ||
158 | { | ||
159 | if (highlight == getHighlight()) return; | ||
160 | |||
161 | - if(!getBranch()) | ||
162 | - { | ||
163 | - return; | ||
164 | - } | ||
165 | - | ||
166 | - BOOL auto_open = getEnabled() && (!getBranch()->getVisible() || getBranch()->getTornOff()); | ||
167 | + BOOL auto_open = getEnabled() && (!mBranch->getVisible() || mBranch->getTornOff()); | ||
168 | // torn off menus don't open sub menus on hover unless they have focus | ||
169 | if (getMenu()->getTornOff() && !((LLFloater*)getMenu()->getParent())->hasFocus()) | ||
170 | { | ||
171 | auto_open = FALSE; | ||
172 | } | ||
173 | // don't auto open torn off sub-menus (need to explicitly active menu item to give them focus) | ||
174 | - if (getBranch()->getTornOff()) | ||
175 | + if (mBranch->getTornOff()) | ||
176 | { | ||
177 | auto_open = FALSE; | ||
178 | } | ||
179 | @@ -1215,14 +1186,14 @@ | ||
180 | } | ||
181 | else | ||
182 | { | ||
183 | - if (getBranch()->getTornOff()) | ||
184 | + if (mBranch->getTornOff()) | ||
185 | { | ||
186 | - ((LLFloater*)getBranch()->getParent())->setFocus(FALSE); | ||
187 | - getBranch()->clearHoverItem(); | ||
188 | + ((LLFloater*)mBranch->getParent())->setFocus(FALSE); | ||
189 | + mBranch->clearHoverItem(); | ||
190 | } | ||
191 | else | ||
192 | { | ||
193 | - getBranch()->setVisible( FALSE ); | ||
194 | + mBranch->setVisible( FALSE ); | ||
195 | } | ||
196 | } | ||
197 | } | ||
198 | @@ -1230,7 +1201,7 @@ | ||
199 | void LLMenuItemBranchGL::draw() | ||
200 | { | ||
201 | LLMenuItemGL::draw(); | ||
202 | - if (getBranch() && getBranch()->getVisible() && !getBranch()->getTornOff()) | ||
203 | + if (mBranch->getVisible() && !mBranch->getTornOff()) | ||
204 | { | ||
205 | setHighlight(TRUE); | ||
206 | } | ||
207 | @@ -1238,33 +1209,33 @@ | ||
208 | |||
209 | void LLMenuItemBranchGL::updateBranchParent(LLView* parentp) | ||
210 | { | ||
211 | - if (getBranch() && getBranch()->getParent() == NULL) | ||
212 | + if (mBranch->getParent() == NULL) | ||
213 | { | ||
214 | // make the branch menu a sibling of my parent menu | ||
215 | - getBranch()->updateParent(parentp); | ||
216 | + mBranch->updateParent(parentp); | ||
217 | } | ||
218 | } | ||
219 | |||
220 | void LLMenuItemBranchGL::onVisibilityChange( BOOL new_visibility ) | ||
221 | { | ||
222 | - if (new_visibility == FALSE && getBranch() && !getBranch()->getTornOff()) | ||
223 | + if (new_visibility == FALSE && !mBranch->getTornOff()) | ||
224 | { | ||
225 | - getBranch()->setVisible(FALSE); | ||
226 | + mBranch->setVisible(FALSE); | ||
227 | } | ||
228 | LLMenuItemGL::onVisibilityChange(new_visibility); | ||
229 | } | ||
230 | |||
231 | BOOL LLMenuItemBranchGL::handleKeyHere( KEY key, MASK mask ) | ||
232 | { | ||
233 | - if (getMenu()->getVisible() && getBranch() && getBranch()->getVisible() && key == KEY_LEFT) | ||
234 | + if (getMenu()->getVisible() && mBranch->getVisible() && key == KEY_LEFT) | ||
235 | { | ||
236 | // switch to keyboard navigation mode | ||
237 | LLMenuGL::setKeyboardMode(TRUE); | ||
238 | |||
239 | - BOOL handled = getBranch()->clearHoverItem(); | ||
240 | - if (getBranch()->getTornOff()) | ||
241 | + BOOL handled = mBranch->clearHoverItem(); | ||
242 | + if (mBranch->getTornOff()) | ||
243 | { | ||
244 | - ((LLFloater*)getBranch()->getParent())->setFocus(FALSE); | ||
245 | + ((LLFloater*)mBranch->getParent())->setFocus(FALSE); | ||
246 | } | ||
247 | if (handled && getMenu()->getTornOff()) | ||
248 | { | ||
249 | @@ -1275,12 +1246,12 @@ | ||
250 | |||
251 | if (getHighlight() && | ||
252 | getMenu()->isOpen() && | ||
253 | - key == KEY_RIGHT && getBranch() && !getBranch()->getHighlightedItem()) | ||
254 | + key == KEY_RIGHT && !mBranch->getHighlightedItem()) | ||
255 | { | ||
256 | // switch to keyboard navigation mode | ||
257 | LLMenuGL::setKeyboardMode(TRUE); | ||
258 | |||
259 | - LLMenuItemGL* itemp = getBranch()->highlightNextItem(NULL); | ||
260 | + LLMenuItemGL* itemp = mBranch->highlightNextItem(NULL); | ||
261 | if (itemp) | ||
262 | { | ||
263 | return TRUE; | ||
264 | @@ -1292,39 +1263,37 @@ | ||
265 | |||
266 | void LLMenuItemBranchGL::openMenu() | ||
267 | { | ||
268 | - if(!getBranch()) return; | ||
269 | - | ||
270 | - if (getBranch()->getTornOff()) | ||
271 | + if (mBranch->getTornOff()) | ||
272 | { | ||
273 | - gFloaterView->bringToFront((LLFloater*)getBranch()->getParent()); | ||
274 | + gFloaterView->bringToFront((LLFloater*)mBranch->getParent()); | ||
275 | // this might not be necessary, as torn off branches don't get focus and hence no highligth | ||
276 | - getBranch()->highlightNextItem(NULL); | ||
277 | + mBranch->highlightNextItem(NULL); | ||
278 | } | ||
279 | - else if( !getBranch()->getVisible() ) | ||
280 | + else if( !mBranch->getVisible() ) | ||
281 | { | ||
282 | // get valid rectangle for menus | ||
283 | const LLRect menu_region_rect = LLMenuGL::sMenuContainer->getMenuRect(); | ||
284 | |||
285 | - getBranch()->arrange(); | ||
286 | + mBranch->arrange(); | ||
287 | |||
288 | - LLRect rect = getBranch()->getRect(); | ||
289 | + LLRect rect = mBranch->getRect(); | ||
290 | // calculate root-view relative position for branch menu | ||
291 | S32 left = getRect().mRight; | ||
292 | S32 top = getRect().mTop - getRect().mBottom; | ||
293 | |||
294 | - localPointToOtherView(left, top, &left, &top, getBranch()->getParent()); | ||
295 | + localPointToOtherView(left, top, &left, &top, mBranch->getParent()); | ||
296 | |||
297 | rect.setLeftTopAndSize( left, top, | ||
298 | rect.getWidth(), rect.getHeight() ); | ||
299 | |||
300 | - if (getBranch()->getCanTearOff()) | ||
301 | + if (mBranch->getCanTearOff()) | ||
302 | { | ||
303 | rect.translate(0, TEAROFF_SEPARATOR_HEIGHT_PIXELS); | ||
304 | } | ||
305 | - getBranch()->setRect( rect ); | ||
306 | + mBranch->setRect( rect ); | ||
307 | S32 x = 0; | ||
308 | S32 y = 0; | ||
309 | - getBranch()->localPointToOtherView( 0, 0, &x, &y, getBranch()->getParent() ); | ||
310 | + mBranch->localPointToOtherView( 0, 0, &x, &y, mBranch->getParent() ); | ||
311 | S32 delta_x = 0; | ||
312 | S32 delta_y = 0; | ||
313 | if( y < menu_region_rect.mBottom ) | ||
314 | @@ -1338,9 +1307,8 @@ | ||
315 | // move sub-menu over to left side | ||
316 | delta_x = llmax(-x, (-1 * (rect.getWidth() + getRect().getWidth()))); | ||
317 | } | ||
318 | - getBranch()->translate( delta_x, delta_y ); | ||
319 | - getBranch()->setVisible( TRUE ); | ||
320 | - getBranch()->getParent()->sendChildToFront(getBranch()); | ||
321 | + mBranch->translate( delta_x, delta_y ); | ||
322 | + mBranch->setVisible( TRUE ); | ||
323 | } | ||
324 | } | ||
325 | |||
326 | @@ -1357,7 +1325,7 @@ | ||
327 | protected: | ||
328 | |||
329 | public: | ||
330 | - LLMenuItemBranchDownGL( const std::string& name, const std::string& label, LLHandle<LLView> branch, | ||
331 | + LLMenuItemBranchDownGL( const std::string& name, const std::string& label, LLMenuGL* branch, | ||
332 | KEY key = KEY_NONE, MASK mask = MASK_NONE ); | ||
333 | |||
334 | virtual std::string getType() const { return "menu"; } | ||
335 | @@ -1390,7 +1358,7 @@ | ||
336 | |||
337 | LLMenuItemBranchDownGL::LLMenuItemBranchDownGL( const std::string& name, | ||
338 | const std::string& label, | ||
339 | - LLHandle<LLView> branch, | ||
340 | + LLMenuGL* branch, | ||
341 | KEY key, MASK mask ) : | ||
342 | LLMenuItemBranchGL( name, label, branch, key, mask ) | ||
343 | { | ||
344 | @@ -1459,7 +1427,6 @@ | ||
345 | |||
346 | setHighlight(TRUE); | ||
347 | branch->setVisible( TRUE ); | ||
348 | - branch->getParent()->sendChildToFront(branch); | ||
349 | } | ||
350 | } | ||
351 | } | ||
352 | @@ -2288,7 +2255,7 @@ | ||
353 | mSpilloverMenu->setBackgroundColor( mBackgroundColor ); | ||
354 | mSpilloverMenu->setCanTearOff(FALSE); | ||
355 | |||
356 | - mSpilloverBranch = new LLMenuItemBranchGL(std::string("More"), std::string("More"), mSpilloverMenu->getHandle()); | ||
357 | + mSpilloverBranch = new LLMenuItemBranchGL(std::string("More"), std::string("More"), mSpilloverMenu); | ||
358 | mSpilloverBranch->setFontStyle(LLFontGL::ITALIC); | ||
359 | } | ||
360 | } | ||
361 | @@ -2308,6 +2275,9 @@ | ||
362 | mItems.erase(found_iter); | ||
363 | } | ||
364 | |||
365 | + delete mSpilloverBranch; | ||
366 | + mSpilloverBranch = NULL; | ||
367 | + | ||
368 | // pop off spillover items | ||
369 | while (mSpilloverMenu->getItemCount()) | ||
370 | { | ||
371 | @@ -2318,12 +2288,6 @@ | ||
372 | mItems.push_back(itemp); | ||
373 | addChild(itemp); | ||
374 | } | ||
375 | - | ||
376 | - // Delete the branch, and since the branch will delete the menu, | ||
377 | - // set the menu* to null. | ||
378 | - delete mSpilloverBranch; | ||
379 | - mSpilloverBranch = NULL; | ||
380 | - mSpilloverMenu = NULL; | ||
381 | } | ||
382 | } | ||
383 | |||
384 | @@ -2496,7 +2460,7 @@ | ||
385 | BOOL success = TRUE; | ||
386 | |||
387 | LLMenuItemBranchGL* branch = NULL; | ||
388 | - branch = new LLMenuItemBranchGL( menu->getName(), menu->getLabel(), menu->getHandle() ); | ||
389 | + branch = new LLMenuItemBranchGL( menu->getName(), menu->getLabel(), menu ); | ||
390 | branch->setJumpKey(menu->getJumpKey()); | ||
391 | success &= append( branch ); | ||
392 | |||
393 | @@ -2994,7 +2958,6 @@ | ||
394 | } | ||
395 | menu->translate( delta_x, delta_y ); | ||
396 | menu->setVisible( TRUE ); | ||
397 | - menu->getParent()->sendChildToFront(menu); | ||
398 | } | ||
399 | |||
400 | //----------------------------------------------------------------------------- | ||
401 | @@ -3185,31 +3148,31 @@ | ||
402 | switch(pieItemIndexFromXY(x, y)) | ||
403 | { | ||
404 | case 0: | ||
405 | - make_ui_sound("UISndPieMenuSliceHighlight0"); | ||
406 | + //make_ui_sound("UISndPieMenuSliceHighlight0"); | ||
407 | break; | ||
408 | case 1: | ||
409 | - make_ui_sound("UISndPieMenuSliceHighlight1"); | ||
410 | + //make_ui_sound("UISndPieMenuSliceHighlight1"); | ||
411 | break; | ||
412 | case 2: | ||
413 | - make_ui_sound("UISndPieMenuSliceHighlight2"); | ||
414 | + //make_ui_sound("UISndPieMenuSliceHighlight2"); | ||
415 | break; | ||
416 | case 3: | ||
417 | - make_ui_sound("UISndPieMenuSliceHighlight3"); | ||
418 | + //make_ui_sound("UISndPieMenuSliceHighlight3"); | ||
419 | break; | ||
420 | case 4: | ||
421 | - make_ui_sound("UISndPieMenuSliceHighlight4"); | ||
422 | + //make_ui_sound("UISndPieMenuSliceHighlight4"); | ||
423 | break; | ||
424 | case 5: | ||
425 | - make_ui_sound("UISndPieMenuSliceHighlight5"); | ||
426 | + //make_ui_sound("UISndPieMenuSliceHighlight5"); | ||
427 | break; | ||
428 | case 6: | ||
429 | - make_ui_sound("UISndPieMenuSliceHighlight6"); | ||
430 | + //make_ui_sound("UISndPieMenuSliceHighlight6"); | ||
431 | break; | ||
432 | case 7: | ||
433 | - make_ui_sound("UISndPieMenuSliceHighlight7"); | ||
434 | + //make_ui_sound("UISndPieMenuSliceHighlight7"); | ||
435 | break; | ||
436 | default: | ||
437 | - make_ui_sound("UISndPieMenuSliceHighlight0"); | ||
438 | + //make_ui_sound("UISndPieMenuSliceHighlight0"); | ||
439 | break; | ||
440 | } | ||
441 | } | ||
442 | @@ -3357,7 +3320,7 @@ | ||
443 | |||
444 | if (mFirstMouseDown) | ||
445 | { | ||
446 | - make_ui_sound("UISndPieMenuAppear"); | ||
447 | + //make_ui_sound("UISndPieMenuAppear"); | ||
448 | mFirstMouseDown = FALSE; | ||
449 | } | ||
450 | |||
451 | @@ -3730,7 +3693,7 @@ | ||
452 | |||
453 | if (!mFirstMouseDown) | ||
454 | { | ||
455 | - make_ui_sound("UISndPieMenuAppear"); | ||
456 | + //make_ui_sound("UISndPieMenuAppear"); | ||
457 | } | ||
458 | |||
459 | LLView::setVisible(TRUE); | ||
460 | @@ -3759,7 +3722,7 @@ | ||
461 | mHoverItem = NULL; | ||
462 | } | ||
463 | |||
464 | - make_ui_sound("UISndPieMenuHide"); | ||
465 | + //make_ui_sound("UISndPieMenuHide"); | ||
466 | |||
467 | mFirstMouseDown = FALSE; | ||
468 | mRightMouseDown = FALSE; | ||
469 | @@ -4105,7 +4068,7 @@ | ||
470 | BOOL success = TRUE; | ||
471 | |||
472 | LLMenuItemBranchGL* branch = NULL; | ||
473 | - branch = new LLMenuItemBranchDownGL( menu->getName(), menu->getLabel(), menu->getHandle()); | ||
474 | + branch = new LLMenuItemBranchDownGL( menu->getName(), menu->getLabel(), menu ); | ||
475 | success &= branch->addToAcceleratorList(&mAccelerators); | ||
476 | success &= append( branch ); | ||
477 | branch->setJumpKey(branch->getJumpKey()); | ||
478 | diff -uwN /linden/indra/llui/llmenugl.h /linden/indra/llui/llmenugl.h | ||
479 | --- /linden/indra/llui/llmenugl.h 2009-06-12 14:14:40.000000000 +0200 | ||
480 | +++ /linden/indra/llui/llmenugl.h 2009-06-23 02:16:35.000000000 +0200 | ||
481 | @@ -89,7 +89,6 @@ | ||
482 | static const LLColor4& getHighlightFGColor() { return sHighlightForeground; } | ||
483 | |||
484 | LLMenuItemGL( const std::string& name, const std::string& label, KEY key = KEY_NONE, MASK = MASK_NONE ); | ||
485 | - virtual ~LLMenuItemGL() {}; | ||
486 | |||
487 | virtual void setValue(const LLSD& value) { setLabel(value.asString()); } | ||
488 | |||
489 | @@ -562,11 +561,8 @@ | ||
490 | class LLMenuItemBranchGL : public LLMenuItemGL | ||
491 | { | ||
492 | public: | ||
493 | - LLMenuItemBranchGL( const std::string& name, const std::string& label, LLHandle<LLView> branch, | ||
494 | + LLMenuItemBranchGL( const std::string& name, const std::string& label, LLMenuGL* branch, | ||
495 | KEY key = KEY_NONE, MASK mask = MASK_NONE ); | ||
496 | - | ||
497 | - virtual ~LLMenuItemBranchGL(); | ||
498 | - | ||
499 | virtual LLXMLNodePtr getXML(bool save_children = true) const; | ||
500 | |||
501 | virtual std::string getType() const { return "menu"; } | ||
502 | @@ -593,11 +589,11 @@ | ||
503 | |||
504 | virtual BOOL handleKeyHere(KEY key, MASK mask); | ||
505 | |||
506 | - virtual BOOL isActive() const { return isOpen() && getBranch()->getHighlightedItem(); } | ||
507 | + virtual BOOL isActive() const { return isOpen() && mBranch->getHighlightedItem(); } | ||
508 | |||
509 | - virtual BOOL isOpen() const { return getBranch() && getBranch()->isOpen(); } | ||
510 | + virtual BOOL isOpen() const { return mBranch->isOpen(); } | ||
511 | |||
512 | - LLMenuGL *getBranch() const { return (LLMenuGL*)(mBranch.get()); } | ||
513 | + LLMenuGL *getBranch() const { return mBranch; } | ||
514 | |||
515 | virtual void updateBranchParent( LLView* parentp ); | ||
516 | |||
517 | @@ -606,14 +602,14 @@ | ||
518 | |||
519 | virtual void draw(); | ||
520 | |||
521 | - virtual void setEnabledSubMenus(BOOL enabled) { if(getBranch()) getBranch()->setEnabledSubMenus(enabled); } | ||
522 | + virtual void setEnabledSubMenus(BOOL enabled) { mBranch->setEnabledSubMenus(enabled); } | ||
523 | |||
524 | virtual void openMenu(); | ||
525 | |||
526 | virtual LLView* getChildView(const std::string& name, BOOL recurse = TRUE, BOOL create_if_missing = TRUE) const; | ||
527 | |||
528 | private: | ||
529 | - LLHandle<LLView> mBranch; | ||
530 | + LLMenuGL* mBranch; | ||
531 | }; // end class LLMenuItemBranchGL | ||
532 | |||
533 | |||
534 | |||
diff --git a/meerkat-message.diff.txt b/meerkat-message.diff.txt new file mode 100644 index 0000000..a0e3ffc --- /dev/null +++ b/meerkat-message.diff.txt | |||
@@ -0,0 +1,1319 @@ | |||
1 | diff --git a/linden/indra/llcommon/llstat.cpp b/linden/indra/llcommon/llstat.cpp | ||
2 | index 31a72e2..74e8bf1 100644 | ||
3 | --- a/linden/indra/llcommon/llstat.cpp | ||
4 | +++ b/linden/indra/llcommon/llstat.cpp | ||
5 | @@ -31,288 +31,17 @@ | ||
6 | #include "linden_common.h" | ||
7 | |||
8 | #include "llstat.h" | ||
9 | -#include "lllivefile.h" | ||
10 | -#include "llerrorcontrol.h" | ||
11 | #include "llframetimer.h" | ||
12 | #include "timing.h" | ||
13 | -#include "llsd.h" | ||
14 | -#include "llsdserialize.h" | ||
15 | -#include "llstl.h" | ||
16 | -#include "u64.h" | ||
17 | |||
18 | |||
19 | -// statics | ||
20 | -BOOL LLPerfBlock::sStatsEnabled = FALSE; // Flag for detailed information | ||
21 | -LLPerfBlock::stat_map_t LLPerfBlock::sStatMap; // Map full path string to LLStatTime objects, tracks all active objects | ||
22 | -std::string LLPerfBlock::sCurrentStatPath = ""; // Something like "/total_time/physics/physics step" | ||
23 | |||
24 | -//------------------------------------------------------------------------ | ||
25 | -// Live config file to trigger stats logging | ||
26 | -static const char STATS_CONFIG_FILE_NAME[] = "/dev/shm/simperf/simperf_proc_config.llsd"; | ||
27 | -static const F32 STATS_CONFIG_REFRESH_RATE = 5.0; // seconds | ||
28 | - | ||
29 | -class LLStatsConfigFile : public LLLiveFile | ||
30 | -{ | ||
31 | -public: | ||
32 | - LLStatsConfigFile() | ||
33 | - : LLLiveFile(filename(), STATS_CONFIG_REFRESH_RATE), | ||
34 | - mChanged(false), mStatsp(NULL) { } | ||
35 | - | ||
36 | - static std::string filename(); | ||
37 | - | ||
38 | -protected: | ||
39 | - /* virtual */ void loadFile(); | ||
40 | - | ||
41 | -public: | ||
42 | - void init(LLPerfStats* statsp); | ||
43 | - static LLStatsConfigFile& instance(); | ||
44 | - // return the singleton stats config file | ||
45 | - | ||
46 | - bool mChanged; | ||
47 | - | ||
48 | -protected: | ||
49 | - LLPerfStats* mStatsp; | ||
50 | -}; | ||
51 | - | ||
52 | -std::string LLStatsConfigFile::filename() | ||
53 | -{ | ||
54 | - return STATS_CONFIG_FILE_NAME; | ||
55 | -} | ||
56 | - | ||
57 | -void LLStatsConfigFile::init(LLPerfStats* statsp) | ||
58 | -{ | ||
59 | - mStatsp = statsp; | ||
60 | -} | ||
61 | - | ||
62 | -LLStatsConfigFile& LLStatsConfigFile::instance() | ||
63 | -{ | ||
64 | - static LLStatsConfigFile the_file; | ||
65 | - return the_file; | ||
66 | -} | ||
67 | - | ||
68 | - | ||
69 | -/* virtual */ | ||
70 | -// Load and parse the stats configuration file | ||
71 | -void LLStatsConfigFile::loadFile() | ||
72 | -{ | ||
73 | - if (!mStatsp) | ||
74 | - { | ||
75 | - llwarns << "Tries to load performance configure file without initializing LPerfStats" << llendl; | ||
76 | - return; | ||
77 | - } | ||
78 | - mChanged = true; | ||
79 | - | ||
80 | - LLSD stats_config; | ||
81 | - { | ||
82 | - llifstream file(filename().c_str()); | ||
83 | - if (file.is_open()) | ||
84 | - { | ||
85 | - LLSDSerialize::fromXML(stats_config, file); | ||
86 | - if (stats_config.isUndefined()) | ||
87 | - { | ||
88 | - llinfos << "Performance statistics configuration file ill-formed, not recording statistics" << llendl; | ||
89 | - mStatsp->setReportPerformanceDuration( 0.f ); | ||
90 | - return; | ||
91 | - } | ||
92 | - } | ||
93 | - else | ||
94 | - { // File went away, turn off stats if it was on | ||
95 | - if ( mStatsp->frameStatsIsRunning() ) | ||
96 | - { | ||
97 | - llinfos << "Performance statistics configuration file deleted, not recording statistics" << llendl; | ||
98 | - mStatsp->setReportPerformanceDuration( 0.f ); | ||
99 | - } | ||
100 | - return; | ||
101 | - } | ||
102 | - } | ||
103 | - | ||
104 | - F32 duration = 0.f; | ||
105 | - F32 interval = 0.f; | ||
106 | - | ||
107 | - const char * w = "duration"; | ||
108 | - if (stats_config.has(w)) | ||
109 | - { | ||
110 | - duration = (F32)stats_config[w].asReal(); | ||
111 | - } | ||
112 | - w = "interval"; | ||
113 | - if (stats_config.has(w)) | ||
114 | - { | ||
115 | - interval = (F32)stats_config[w].asReal(); | ||
116 | - } | ||
117 | - | ||
118 | - mStatsp->setReportPerformanceDuration( duration ); | ||
119 | - mStatsp->setReportPerformanceInterval( interval ); | ||
120 | - | ||
121 | - if ( duration > 0 ) | ||
122 | - { | ||
123 | - if ( interval == 0.f ) | ||
124 | - { | ||
125 | - llinfos << "Recording performance stats every frame for " << duration << " sec" << llendl; | ||
126 | - } | ||
127 | - else | ||
128 | - { | ||
129 | - llinfos << "Recording performance stats every " << interval << " seconds for " << duration << " seconds" << llendl; | ||
130 | - } | ||
131 | - } | ||
132 | - else | ||
133 | - { | ||
134 | - llinfos << "Performance stats recording turned off" << llendl; | ||
135 | - } | ||
136 | -} | ||
137 | - | ||
138 | - | ||
139 | -//------------------------------------------------------------------------ | ||
140 | - | ||
141 | -LLPerfStats::LLPerfStats(const std::string& process_name, S32 process_pid) : | ||
142 | - mFrameStatsFileFailure(FALSE), | ||
143 | - mSkipFirstFrameStats(FALSE), | ||
144 | - mProcessName(process_name), | ||
145 | - mProcessPID(process_pid), | ||
146 | - mReportPerformanceStatInterval(1.f), | ||
147 | - mReportPerformanceStatEnd(0.0) | ||
148 | -{ } | ||
149 | - | ||
150 | -LLPerfStats::~LLPerfStats() | ||
151 | -{ | ||
152 | - LLPerfBlock::clearDynamicStats(); | ||
153 | - mFrameStatsFile.close(); | ||
154 | -} | ||
155 | - | ||
156 | -void LLPerfStats::init() | ||
157 | -{ | ||
158 | - // Initialize the stats config file instance. | ||
159 | - (void) LLStatsConfigFile::instance().init(this); | ||
160 | - (void) LLStatsConfigFile::instance().checkAndReload(); | ||
161 | -} | ||
162 | - | ||
163 | -// Open file for statistics | ||
164 | -void LLPerfStats::openPerfStatsFile() | ||
165 | -{ | ||
166 | - if ( !mFrameStatsFile | ||
167 | - && !mFrameStatsFileFailure ) | ||
168 | - { | ||
169 | - std::string stats_file = llformat("/dev/shm/simperf/%s_proc.%d.llsd", mProcessName.c_str(), mProcessPID); | ||
170 | - mFrameStatsFile.close(); | ||
171 | - mFrameStatsFile.clear(); | ||
172 | - mFrameStatsFile.open(stats_file, llofstream::out); | ||
173 | - if ( mFrameStatsFile.fail() ) | ||
174 | - { | ||
175 | - llinfos << "Error opening statistics log file " << stats_file << llendl; | ||
176 | - mFrameStatsFileFailure = TRUE; | ||
177 | - } | ||
178 | - else | ||
179 | - { | ||
180 | - LLSD process_info = LLSD::emptyMap(); | ||
181 | - process_info["name"] = mProcessName; | ||
182 | - process_info["pid"] = (LLSD::Integer) mProcessPID; | ||
183 | - process_info["stat_rate"] = (LLSD::Integer) mReportPerformanceStatInterval; | ||
184 | - // Add process-specific info. | ||
185 | - addProcessHeaderInfo(process_info); | ||
186 | - | ||
187 | - mFrameStatsFile << LLSDNotationStreamer(process_info) << std::endl; | ||
188 | - } | ||
189 | - } | ||
190 | -} | ||
191 | - | ||
192 | -// Dump out performance metrics over some time interval | ||
193 | -void LLPerfStats::dumpIntervalPerformanceStats() | ||
194 | -{ | ||
195 | - // Ensure output file is OK | ||
196 | - openPerfStatsFile(); | ||
197 | - | ||
198 | - if ( mFrameStatsFile ) | ||
199 | - { | ||
200 | - LLSD stats = LLSD::emptyMap(); | ||
201 | - | ||
202 | - LLStatAccum::TimeScale scale; | ||
203 | - if ( getReportPerformanceInterval() == 0.f ) | ||
204 | - { | ||
205 | - scale = LLStatAccum::SCALE_PER_FRAME; | ||
206 | - } | ||
207 | - else if ( getReportPerformanceInterval() < 0.5f ) | ||
208 | - { | ||
209 | - scale = LLStatAccum::SCALE_100MS; | ||
210 | - } | ||
211 | - else | ||
212 | - { | ||
213 | - scale = LLStatAccum::SCALE_SECOND; | ||
214 | - } | ||
215 | - | ||
216 | - // Write LLSD into log | ||
217 | - stats["utc_time"] = (LLSD::String) LLError::utcTime(); | ||
218 | - stats["timestamp"] = U64_to_str((totalTime() / 1000) + (gUTCOffset * 1000)); // milliseconds since epoch | ||
219 | - stats["frame_number"] = (LLSD::Integer) LLFrameTimer::getFrameCount(); | ||
220 | - | ||
221 | - // Add process-specific frame info. | ||
222 | - addProcessFrameInfo(stats, scale); | ||
223 | - LLPerfBlock::addStatsToLLSDandReset( stats, scale ); | ||
224 | - | ||
225 | - mFrameStatsFile << LLSDNotationStreamer(stats) << std::endl; | ||
226 | - } | ||
227 | -} | ||
228 | - | ||
229 | -// Set length of performance stat recording | ||
230 | -void LLPerfStats::setReportPerformanceDuration( F32 seconds ) | ||
231 | -{ | ||
232 | - if ( seconds <= 0.f ) | ||
233 | - { | ||
234 | - mReportPerformanceStatEnd = 0.0; | ||
235 | - LLPerfBlock::setStatsEnabled( FALSE ); | ||
236 | - mFrameStatsFile.close(); | ||
237 | - LLPerfBlock::clearDynamicStats(); | ||
238 | - } | ||
239 | - else | ||
240 | - { | ||
241 | - mReportPerformanceStatEnd = LLFrameTimer::getElapsedSeconds() + ((F64) seconds); | ||
242 | - // Clear failure flag to try and create the log file once | ||
243 | - mFrameStatsFileFailure = FALSE; | ||
244 | - LLPerfBlock::setStatsEnabled( TRUE ); | ||
245 | - mSkipFirstFrameStats = TRUE; // Skip the first report (at the end of this frame) | ||
246 | - } | ||
247 | -} | ||
248 | - | ||
249 | -void LLPerfStats::updatePerFrameStats() | ||
250 | -{ | ||
251 | - (void) LLStatsConfigFile::instance().checkAndReload(); | ||
252 | - static LLFrameTimer performance_stats_timer; | ||
253 | - if ( frameStatsIsRunning() ) | ||
254 | - { | ||
255 | - if ( mReportPerformanceStatInterval == 0 ) | ||
256 | - { // Record info every frame | ||
257 | - if ( mSkipFirstFrameStats ) | ||
258 | - { // Skip the first time - was started this frame | ||
259 | - mSkipFirstFrameStats = FALSE; | ||
260 | - } | ||
261 | - else | ||
262 | - { | ||
263 | - dumpIntervalPerformanceStats(); | ||
264 | - } | ||
265 | - } | ||
266 | - else | ||
267 | - { | ||
268 | - performance_stats_timer.setTimerExpirySec( getReportPerformanceInterval() ); | ||
269 | - if (performance_stats_timer.checkExpirationAndReset( mReportPerformanceStatInterval )) | ||
270 | - { | ||
271 | - dumpIntervalPerformanceStats(); | ||
272 | - } | ||
273 | - } | ||
274 | - | ||
275 | - if ( LLFrameTimer::getElapsedSeconds() > mReportPerformanceStatEnd ) | ||
276 | - { // Reached end of time, clear it to stop reporting | ||
277 | - setReportPerformanceDuration(0.f); // Don't set mReportPerformanceStatEnd directly | ||
278 | - llinfos << "Recording performance stats completed" << llendl; | ||
279 | - } | ||
280 | - } | ||
281 | -} | ||
282 | - | ||
283 | - | ||
284 | -//------------------------------------------------------------------------ | ||
285 | - | ||
286 | -U64 LLStatAccum::sScaleTimes[NUM_SCALES] = | ||
287 | +U64 LLStatAccum::sScaleTimes[IMPL_NUM_SCALES] = | ||
288 | { | ||
289 | USEC_PER_SEC / 10, // 100 millisec | ||
290 | USEC_PER_SEC * 1, // seconds | ||
291 | USEC_PER_SEC * 60, // minutes | ||
292 | + USEC_PER_SEC * 60 * 2 // two minutes | ||
293 | #if ENABLE_LONG_TIME_STATS | ||
294 | // enable these when more time scales are desired | ||
295 | USEC_PER_SEC * 60*60, // hours | ||
296 | @@ -342,7 +71,7 @@ void LLStatAccum::reset(U64 when) | ||
297 | mRunning = TRUE; | ||
298 | mLastTime = when; | ||
299 | |||
300 | - for (int i = 0; i < NUM_SCALES; ++i) | ||
301 | + for (int i = 0; i < IMPL_NUM_SCALES; ++i) | ||
302 | { | ||
303 | mBuckets[i].accum = 0.0; | ||
304 | mBuckets[i].endTime = when + sScaleTimes[i]; | ||
305 | @@ -375,7 +104,7 @@ void LLStatAccum::sum(F64 value, U64 when) | ||
306 | // how long is this value for | ||
307 | U64 timeSpan = when - mLastTime; | ||
308 | |||
309 | - for (int i = 0; i < NUM_SCALES; ++i) | ||
310 | + for (int i = 0; i < IMPL_NUM_SCALES; ++i) | ||
311 | { | ||
312 | Bucket& bucket = mBuckets[i]; | ||
313 | |||
314 | @@ -421,12 +150,7 @@ F32 LLStatAccum::meanValue(TimeScale scale) const | ||
315 | { | ||
316 | return 0.0; | ||
317 | } | ||
318 | - if ( scale == SCALE_PER_FRAME ) | ||
319 | - { // Per-frame not supported here | ||
320 | - scale = SCALE_100MS; | ||
321 | - } | ||
322 | - | ||
323 | - if (scale < 0 || scale >= NUM_SCALES) | ||
324 | + if (scale < 0 || scale >= IMPL_NUM_SCALES) | ||
325 | { | ||
326 | llwarns << "llStatAccum::meanValue called for unsupported scale: " | ||
327 | << scale << llendl; | ||
328 | @@ -536,15 +260,12 @@ void LLStatMeasure::sample(F64 value) | ||
329 | |||
330 | // ------------------------------------------------------------------------ | ||
331 | |||
332 | -LLStatTime::LLStatTime(const std::string & key) | ||
333 | - : LLStatAccum(false), | ||
334 | - mFrameNumber(LLFrameTimer::getFrameCount()), | ||
335 | - mTotalTimeInFrame(0), | ||
336 | - mKey(key) | ||
337 | -#if LL_DEBUG | ||
338 | - , mRunning(FALSE) | ||
339 | -#endif | ||
340 | +LLStatTime::LLStatTime(bool use_frame_timer) | ||
341 | + : LLStatAccum(use_frame_timer), | ||
342 | + mFrameNumber(0), | ||
343 | + mTotalTimeInFrame(0) | ||
344 | { | ||
345 | + mFrameNumber = LLFrameTimer::getFrameCount(); | ||
346 | } | ||
347 | |||
348 | void LLStatTime::start() | ||
349 | @@ -558,12 +279,6 @@ void LLStatTime::start() | ||
350 | } | ||
351 | |||
352 | sum(0.0); | ||
353 | - | ||
354 | -#if LL_DEBUG | ||
355 | - // Shouldn't be running already | ||
356 | - llassert( !mRunning ); | ||
357 | - mRunning = TRUE; | ||
358 | -#endif | ||
359 | } | ||
360 | |||
361 | void LLStatTime::stop() | ||
362 | @@ -571,149 +286,7 @@ void LLStatTime::stop() | ||
363 | U64 end_time = getCurrentUsecs(); | ||
364 | U64 duration = end_time - mLastTime; | ||
365 | sum(F64(duration), end_time); | ||
366 | - //llinfos << "mTotalTimeInFrame incremented from " << mTotalTimeInFrame << " to " << (mTotalTimeInFrame + duration) << llendl; | ||
367 | mTotalTimeInFrame += duration; | ||
368 | - | ||
369 | -#if LL_DEBUG | ||
370 | - mRunning = FALSE; | ||
371 | -#endif | ||
372 | -} | ||
373 | - | ||
374 | -/* virtual */ F32 LLStatTime::meanValue(TimeScale scale) const | ||
375 | -{ | ||
376 | - if ( LLStatAccum::SCALE_PER_FRAME == scale ) | ||
377 | - { | ||
378 | - return mTotalTimeInFrame; | ||
379 | - } | ||
380 | - else | ||
381 | - { | ||
382 | - return LLStatAccum::meanValue(scale); | ||
383 | - } | ||
384 | -} | ||
385 | - | ||
386 | - | ||
387 | -// ------------------------------------------------------------------------ | ||
388 | - | ||
389 | - | ||
390 | -// Use this constructor for pre-defined LLStatTime objects | ||
391 | -LLPerfBlock::LLPerfBlock(LLStatTime* stat ) : mPredefinedStat(stat), mDynamicStat(NULL) | ||
392 | -{ | ||
393 | - if (mPredefinedStat) | ||
394 | - { | ||
395 | - // If dynamic stats are turned on, this will create a separate entry in the stat map. | ||
396 | - initDynamicStat(mPredefinedStat->mKey); | ||
397 | - | ||
398 | - // Start predefined stats. These stats are not part of the stat map. | ||
399 | - mPredefinedStat->start(); | ||
400 | - } | ||
401 | -} | ||
402 | - | ||
403 | -// Use this constructor for dynamically created LLStatTime objects (not pre-defined) with a multi-part key. | ||
404 | -// These are also turned on or off via the switch passed in | ||
405 | -LLPerfBlock::LLPerfBlock( const char* key1, const char* key2 ) : mPredefinedStat(NULL), mDynamicStat(NULL) | ||
406 | -{ | ||
407 | - if (!sStatsEnabled) return; | ||
408 | - | ||
409 | - if (NULL == key2 || strlen(key2) == 0) | ||
410 | - { | ||
411 | - initDynamicStat(key1); | ||
412 | - } | ||
413 | - else | ||
414 | - { | ||
415 | - std::ostringstream key; | ||
416 | - key << key1 << "_" << key2; | ||
417 | - initDynamicStat(key.str()); | ||
418 | - } | ||
419 | -} | ||
420 | - | ||
421 | -void LLPerfBlock::initDynamicStat(const std::string& key) | ||
422 | -{ | ||
423 | - // Early exit if dynamic stats aren't enabled. | ||
424 | - if (!sStatsEnabled) return; | ||
425 | - | ||
426 | - mLastPath = sCurrentStatPath; // Save and restore current path | ||
427 | - sCurrentStatPath += "/" + key; // Add key to current path | ||
428 | - | ||
429 | - // See if the LLStatTime object already exists | ||
430 | - stat_map_t::iterator iter = sStatMap.find(sCurrentStatPath); | ||
431 | - if ( iter == sStatMap.end() ) | ||
432 | - { | ||
433 | - // StatEntry object doesn't exist, so create it | ||
434 | - mDynamicStat = new StatEntry( key ); | ||
435 | - sStatMap[ sCurrentStatPath ] = mDynamicStat; // Set the entry for this path | ||
436 | - } | ||
437 | - else | ||
438 | - { | ||
439 | - // Found this path in the map, use the object there | ||
440 | - mDynamicStat = (*iter).second; // Get StatEntry for the current path | ||
441 | - } | ||
442 | - | ||
443 | - if (mDynamicStat) | ||
444 | - { | ||
445 | - mDynamicStat->mStat.start(); | ||
446 | - mDynamicStat->mCount++; | ||
447 | - } | ||
448 | - else | ||
449 | - { | ||
450 | - llwarns << "Initialized NULL dynamic stat at '" << sCurrentStatPath << "'" << llendl; | ||
451 | - sCurrentStatPath = mLastPath; | ||
452 | - } | ||
453 | -} | ||
454 | - | ||
455 | - | ||
456 | -// Destructor does the time accounting | ||
457 | -LLPerfBlock::~LLPerfBlock() | ||
458 | -{ | ||
459 | - if (mPredefinedStat) mPredefinedStat->stop(); | ||
460 | - if (mDynamicStat) | ||
461 | - { | ||
462 | - mDynamicStat->mStat.stop(); | ||
463 | - sCurrentStatPath = mLastPath; // Restore the path in case sStatsEnabled changed during this block | ||
464 | - } | ||
465 | -} | ||
466 | - | ||
467 | - | ||
468 | -// Clear the map of any dynamic stats. Static routine | ||
469 | -void LLPerfBlock::clearDynamicStats() | ||
470 | -{ | ||
471 | - std::for_each(sStatMap.begin(), sStatMap.end(), DeletePairedPointer()); | ||
472 | - sStatMap.clear(); | ||
473 | -} | ||
474 | - | ||
475 | -// static - Extract the stat info into LLSD | ||
476 | -void LLPerfBlock::addStatsToLLSDandReset( LLSD & stats, | ||
477 | - LLStatAccum::TimeScale scale ) | ||
478 | -{ | ||
479 | - // If we aren't in per-frame scale, we need to go from second to microsecond. | ||
480 | - U32 scale_adjustment = 1; | ||
481 | - if (LLStatAccum::SCALE_PER_FRAME != scale) | ||
482 | - { | ||
483 | - scale_adjustment = USEC_PER_SEC; | ||
484 | - } | ||
485 | - stat_map_t::iterator iter = sStatMap.begin(); | ||
486 | - for ( ; iter != sStatMap.end(); ++iter ) | ||
487 | - { // Put the entry into LLSD "/full/path/to/stat/" = microsecond total time | ||
488 | - const std::string & stats_full_path = (*iter).first; | ||
489 | - | ||
490 | - StatEntry * stat = (*iter).second; | ||
491 | - if (stat) | ||
492 | - { | ||
493 | - if (stat->mCount > 0) | ||
494 | - { | ||
495 | - stats[stats_full_path] = LLSD::emptyMap(); | ||
496 | - stats[stats_full_path]["us"] = (LLSD::Integer) (scale_adjustment * stat->mStat.meanValue(scale)); | ||
497 | - if (stat->mCount > 1) | ||
498 | - { | ||
499 | - stats[stats_full_path]["count"] = (LLSD::Integer) stat->mCount; | ||
500 | - } | ||
501 | - stat->mCount = 0; | ||
502 | - } | ||
503 | - } | ||
504 | - else | ||
505 | - { // WTF? Shouldn't have a NULL pointer in the map. | ||
506 | - llwarns << "Unexpected NULL dynamic stat at '" << stats_full_path << "'" << llendl; | ||
507 | - } | ||
508 | - } | ||
509 | } | ||
510 | |||
511 | |||
512 | diff --git a/linden/indra/llcommon/llstat.h b/linden/indra/llcommon/llstat.h | ||
513 | index eceb5e3..0e66cf0 100644 | ||
514 | --- a/linden/indra/llcommon/llstat.h | ||
515 | +++ b/linden/indra/llcommon/llstat.h | ||
516 | @@ -33,13 +33,9 @@ | ||
517 | #define LL_LLSTAT_H | ||
518 | |||
519 | #include <deque> | ||
520 | -#include <map> | ||
521 | |||
522 | #include "lltimer.h" | ||
523 | #include "llframetimer.h" | ||
524 | -#include "llfile.h" | ||
525 | - | ||
526 | -class LLSD; | ||
527 | |||
528 | // Set this if longer stats are needed | ||
529 | #define ENABLE_LONG_TIME_STATS 0 | ||
530 | @@ -62,18 +58,19 @@ public: | ||
531 | SCALE_100MS, | ||
532 | SCALE_SECOND, | ||
533 | SCALE_MINUTE, | ||
534 | + SCALE_TWO_MINUTE, | ||
535 | #if ENABLE_LONG_TIME_STATS | ||
536 | SCALE_HOUR, | ||
537 | SCALE_DAY, | ||
538 | SCALE_WEEK, | ||
539 | #endif | ||
540 | - NUM_SCALES, // Use to size storage arrays | ||
541 | - SCALE_PER_FRAME // For latest frame information - should be after NUM_SCALES since this doesn't go into the time buckets | ||
542 | + NUM_SCALES | ||
543 | }; | ||
544 | |||
545 | - static U64 sScaleTimes[NUM_SCALES]; | ||
546 | + static const TimeScale IMPL_NUM_SCALES = (TimeScale)(SCALE_TWO_MINUTE + 1); | ||
547 | + static U64 sScaleTimes[IMPL_NUM_SCALES]; | ||
548 | |||
549 | - virtual F32 meanValue(TimeScale scale) const; | ||
550 | + F32 meanValue(TimeScale scale) const; | ||
551 | // see the subclasses for the specific meaning of value | ||
552 | |||
553 | F32 meanValueOverLast100ms() const { return meanValue(SCALE_100MS); } | ||
554 | @@ -89,8 +86,8 @@ public: | ||
555 | // Get current microseconds based on timer type | ||
556 | |||
557 | BOOL mUseFrameTimer; | ||
558 | - BOOL mRunning; | ||
559 | |||
560 | + BOOL mRunning; | ||
561 | U64 mLastTime; | ||
562 | |||
563 | struct Bucket | ||
564 | @@ -102,7 +99,7 @@ public: | ||
565 | F64 lastAccum; | ||
566 | }; | ||
567 | |||
568 | - Bucket mBuckets[NUM_SCALES]; | ||
569 | + Bucket mBuckets[IMPL_NUM_SCALES]; | ||
570 | |||
571 | BOOL mLastSampleValid; | ||
572 | F64 mLastSampleValue; | ||
573 | @@ -139,115 +136,37 @@ public: | ||
574 | }; | ||
575 | |||
576 | |||
577 | +class LLTimeBlock; | ||
578 | + | ||
579 | class LLStatTime : public LLStatAccum | ||
580 | // gathers statistics about time spent in a block of code | ||
581 | // measure average duration per second in the block | ||
582 | { | ||
583 | public: | ||
584 | - LLStatTime( const std::string & key = "undefined" ); | ||
585 | + LLStatTime(bool use_frame_timer = false); | ||
586 | |||
587 | U32 mFrameNumber; // Current frame number | ||
588 | U64 mTotalTimeInFrame; // Total time (microseconds) accumulated during the last frame | ||
589 | |||
590 | - void setKey( const std::string & key ) { mKey = key; }; | ||
591 | - | ||
592 | - virtual F32 meanValue(TimeScale scale) const; | ||
593 | - | ||
594 | private: | ||
595 | - void start(); // Start and stop measuring time block | ||
596 | + void start(); | ||
597 | void stop(); | ||
598 | - | ||
599 | - std::string mKey; // Tag representing this time block | ||
600 | - | ||
601 | -#if LL_DEBUG | ||
602 | - BOOL mRunning; // TRUE if start() has been called | ||
603 | -#endif | ||
604 | - | ||
605 | - friend class LLPerfBlock; | ||
606 | + friend class LLTimeBlock; | ||
607 | }; | ||
608 | |||
609 | -// ---------------------------------------------------------------------------- | ||
610 | - | ||
611 | - | ||
612 | -// Use this class on the stack to record statistics about an area of code | ||
613 | -class LLPerfBlock | ||
614 | +class LLTimeBlock | ||
615 | { | ||
616 | public: | ||
617 | - struct StatEntry | ||
618 | - { | ||
619 | - StatEntry(const std::string& key) : mStat(LLStatTime(key)), mCount(0) {} | ||
620 | - LLStatTime mStat; | ||
621 | - U32 mCount; | ||
622 | - }; | ||
623 | - typedef std::map<std::string, StatEntry*> stat_map_t; | ||
624 | - | ||
625 | - // Use this constructor for pre-defined LLStatTime objects | ||
626 | - LLPerfBlock(LLStatTime* stat); | ||
627 | - | ||
628 | - // Use this constructor for dynamically created LLStatTime objects (not pre-defined) with a multi-part key | ||
629 | - LLPerfBlock( const char* key1, const char* key2 = NULL); | ||
630 | - | ||
631 | - | ||
632 | - ~LLPerfBlock(); | ||
633 | - | ||
634 | - static void setStatsEnabled( BOOL enable ) { sStatsEnabled = enable; }; | ||
635 | - static S32 getStatsEnabled() { return sStatsEnabled; }; | ||
636 | - | ||
637 | - static void clearDynamicStats(); // Reset maps to clear out dynamic objects | ||
638 | - static void addStatsToLLSDandReset( LLSD & stats, // Get current information and clear time bin | ||
639 | - LLStatAccum::TimeScale scale ); | ||
640 | - | ||
641 | + LLTimeBlock(LLStatTime& stat) : mStat(stat) { mStat.start(); } | ||
642 | + ~LLTimeBlock() { mStat.stop(); } | ||
643 | private: | ||
644 | - // Initialize dynamically created LLStatTime objects | ||
645 | - void initDynamicStat(const std::string& key); | ||
646 | - | ||
647 | - std::string mLastPath; // Save sCurrentStatPath when this is called | ||
648 | - LLStatTime * mPredefinedStat; // LLStatTime object to get data | ||
649 | - StatEntry * mDynamicStat; // StatEntryobject to get data | ||
650 | - | ||
651 | - static BOOL sStatsEnabled; // Normally FALSE | ||
652 | - static stat_map_t sStatMap; // Map full path string to LLStatTime objects | ||
653 | - static std::string sCurrentStatPath; // Something like "frame/physics/physics step" | ||
654 | + LLStatTime& mStat; | ||
655 | }; | ||
656 | |||
657 | -// ---------------------------------------------------------------------------- | ||
658 | |||
659 | -class LLPerfStats | ||
660 | -{ | ||
661 | -public: | ||
662 | - LLPerfStats(const std::string& process_name = "unknown", S32 process_pid = 0); | ||
663 | - virtual ~LLPerfStats(); | ||
664 | - | ||
665 | - virtual void init(); // Reset and start all stat timers | ||
666 | - virtual void updatePerFrameStats(); | ||
667 | - // Override these function to add process-specific information to the performance log header and per-frame logging. | ||
668 | - virtual void addProcessHeaderInfo(LLSD& info) { /* not implemented */ } | ||
669 | - virtual void addProcessFrameInfo(LLSD& info, LLStatAccum::TimeScale scale) { /* not implemented */ } | ||
670 | - | ||
671 | - // High-resolution frame stats | ||
672 | - BOOL frameStatsIsRunning() { return (mReportPerformanceStatEnd > 0.); }; | ||
673 | - F32 getReportPerformanceInterval() const { return mReportPerformanceStatInterval; }; | ||
674 | - void setReportPerformanceInterval( F32 interval ) { mReportPerformanceStatInterval = interval; }; | ||
675 | - void setReportPerformanceDuration( F32 seconds ); | ||
676 | - void setProcessName(const std::string& process_name) { mProcessName = process_name; } | ||
677 | - void setProcessPID(S32 process_pid) { mProcessPID = process_pid; } | ||
678 | - | ||
679 | -protected: | ||
680 | - void openPerfStatsFile(); // Open file for high resolution metrics logging | ||
681 | - void dumpIntervalPerformanceStats(); | ||
682 | |||
683 | - llofstream mFrameStatsFile; // File for per-frame stats | ||
684 | - BOOL mFrameStatsFileFailure; // Flag to prevent repeat opening attempts | ||
685 | - BOOL mSkipFirstFrameStats; // Flag to skip one (partial) frame report | ||
686 | - std::string mProcessName; | ||
687 | - S32 mProcessPID; | ||
688 | |||
689 | -private: | ||
690 | - F32 mReportPerformanceStatInterval; // Seconds between performance stats | ||
691 | - F64 mReportPerformanceStatEnd; // End time (seconds) for performance stats | ||
692 | -}; | ||
693 | |||
694 | -// ---------------------------------------------------------------------------- | ||
695 | class LLStat | ||
696 | { | ||
697 | public: | ||
698 | diff --git a/linden/indra/llcommon/llstatenums.h b/linden/indra/llcommon/llstatenums.h | ||
699 | index febd958..ae3be14 100644 | ||
700 | --- a/linden/indra/llcommon/llstatenums.h | ||
701 | +++ b/linden/indra/llcommon/llstatenums.h | ||
702 | @@ -33,41 +33,38 @@ | ||
703 | |||
704 | enum | ||
705 | { | ||
706 | - LL_SIM_STAT_TIME_DILATION, // 0 | ||
707 | + LL_SIM_STAT_TIME_DILATION, | ||
708 | LL_SIM_STAT_FPS, | ||
709 | LL_SIM_STAT_PHYSFPS, | ||
710 | LL_SIM_STAT_AGENTUPS, | ||
711 | LL_SIM_STAT_FRAMEMS, | ||
712 | - LL_SIM_STAT_NETMS, // 5 | ||
713 | + LL_SIM_STAT_NETMS, | ||
714 | LL_SIM_STAT_SIMOTHERMS, | ||
715 | LL_SIM_STAT_SIMPHYSICSMS, | ||
716 | LL_SIM_STAT_AGENTMS, | ||
717 | LL_SIM_STAT_IMAGESMS, | ||
718 | - LL_SIM_STAT_SCRIPTMS, // 10 | ||
719 | + LL_SIM_STAT_SCRIPTMS, | ||
720 | LL_SIM_STAT_NUMTASKS, | ||
721 | LL_SIM_STAT_NUMTASKSACTIVE, | ||
722 | LL_SIM_STAT_NUMAGENTMAIN, | ||
723 | LL_SIM_STAT_NUMAGENTCHILD, | ||
724 | - LL_SIM_STAT_NUMSCRIPTSACTIVE, // 15 | ||
725 | + LL_SIM_STAT_NUMSCRIPTSACTIVE, | ||
726 | LL_SIM_STAT_LSLIPS, | ||
727 | LL_SIM_STAT_INPPS, | ||
728 | LL_SIM_STAT_OUTPPS, | ||
729 | LL_SIM_STAT_PENDING_DOWNLOADS, | ||
730 | - LL_SIM_STAT_PENDING_UPLOADS, // 20 | ||
731 | + LL_SIM_STAT_PENDING_UPLOADS, | ||
732 | LL_SIM_STAT_VIRTUAL_SIZE_KB, | ||
733 | LL_SIM_STAT_RESIDENT_SIZE_KB, | ||
734 | LL_SIM_STAT_PENDING_LOCAL_UPLOADS, | ||
735 | LL_SIM_STAT_TOTAL_UNACKED_BYTES, | ||
736 | - LL_SIM_STAT_PHYSICS_PINNED_TASKS, // 25 | ||
737 | + LL_SIM_STAT_PHYSICS_PINNED_TASKS, | ||
738 | LL_SIM_STAT_PHYSICS_LOD_TASKS, | ||
739 | LL_SIM_STAT_SIMPHYSICSSTEPMS, | ||
740 | LL_SIM_STAT_SIMPHYSICSSHAPEMS, | ||
741 | LL_SIM_STAT_SIMPHYSICSOTHERMS, | ||
742 | - LL_SIM_STAT_SIMPHYSICSMEMORY, // 30 | ||
743 | + LL_SIM_STAT_SIMPHYSICSMEMORY, | ||
744 | LL_SIM_STAT_SCRIPT_EPS, | ||
745 | - LL_SIM_STAT_SIMSPARETIME, | ||
746 | - LL_SIM_STAT_SIMSLEEPTIME, | ||
747 | - LL_SIM_STAT_IOPUMPTIME, | ||
748 | }; | ||
749 | |||
750 | #endif | ||
751 | diff --git a/linden/indra/llmessage/lliohttpserver.cpp b/linden/indra/llmessage/lliohttpserver.cpp | ||
752 | index 167f212..39fecb4 100644 | ||
753 | --- a/linden/indra/llmessage/lliohttpserver.cpp | ||
754 | +++ b/linden/indra/llmessage/lliohttpserver.cpp | ||
755 | @@ -47,7 +47,6 @@ | ||
756 | #include "llpumpio.h" | ||
757 | #include "llsd.h" | ||
758 | #include "llsdserialize_xml.h" | ||
759 | -#include "llstat.h" | ||
760 | #include "llstl.h" | ||
761 | #include "lltimer.h" | ||
762 | |||
763 | @@ -172,26 +171,22 @@ LLIOPipe::EStatus LLHTTPPipe::process_impl( | ||
764 | std::string verb = context[CONTEXT_REQUEST][CONTEXT_VERB]; | ||
765 | if(verb == HTTP_VERB_GET) | ||
766 | { | ||
767 | - LLPerfBlock getblock("http_get"); | ||
768 | mNode.get(LLHTTPNode::ResponsePtr(mResponse), context); | ||
769 | } | ||
770 | else if(verb == HTTP_VERB_PUT) | ||
771 | { | ||
772 | - LLPerfBlock putblock("http_put"); | ||
773 | LLSD input; | ||
774 | LLSDSerialize::fromXML(input, istr); | ||
775 | mNode.put(LLHTTPNode::ResponsePtr(mResponse), context, input); | ||
776 | } | ||
777 | else if(verb == HTTP_VERB_POST) | ||
778 | { | ||
779 | - LLPerfBlock postblock("http_post"); | ||
780 | LLSD input; | ||
781 | LLSDSerialize::fromXML(input, istr); | ||
782 | mNode.post(LLHTTPNode::ResponsePtr(mResponse), context, input); | ||
783 | } | ||
784 | else if(verb == HTTP_VERB_DELETE) | ||
785 | { | ||
786 | - LLPerfBlock delblock("http_delete"); | ||
787 | mNode.del(LLHTTPNode::ResponsePtr(mResponse), context); | ||
788 | } | ||
789 | else if(verb == HTTP_VERB_OPTIONS) | ||
790 | diff --git a/linden/indra/llmessage/llmessagetemplate.h b/linden/indra/llmessage/llmessagetemplate.h | ||
791 | index 2390eea..a4062fa 100644 | ||
792 | --- a/linden/indra/llmessage/llmessagetemplate.h | ||
793 | +++ b/linden/indra/llmessage/llmessagetemplate.h | ||
794 | @@ -34,8 +34,11 @@ | ||
795 | |||
796 | #include "lldarray.h" | ||
797 | #include "message.h" // TODO: babbage: Remove... | ||
798 | -#include "llstat.h" | ||
799 | +#include "llmsgvariabletype.h" | ||
800 | #include "llstl.h" | ||
801 | +#include <list> | ||
802 | +#include <algorithm> | ||
803 | +#include <functional> | ||
804 | |||
805 | class LLMsgVarData | ||
806 | { | ||
807 | @@ -270,6 +273,31 @@ enum EMsgDeprecation | ||
808 | MD_DEPRECATED | ||
809 | }; | ||
810 | |||
811 | +class LLMessageTemplateHandlerEntry | ||
812 | +{ | ||
813 | +public: | ||
814 | + LLMessageTemplateHandlerEntry(message_handler_func_t handler, void **userdata = NULL) : | ||
815 | + mHandlerFunc(handler), mUserData(userdata) {} | ||
816 | + | ||
817 | + void call(LLMessageSystem *msgsystem) const { mHandlerFunc(msgsystem, mUserData); } | ||
818 | + | ||
819 | + bool operator==(const LLMessageTemplateHandlerEntry&a) { return mHandlerFunc == a.mHandlerFunc; } | ||
820 | +private: | ||
821 | + // message handler function (this is set by each application) | ||
822 | + message_handler_func_t mHandlerFunc; | ||
823 | + void **mUserData; | ||
824 | +}; | ||
825 | + | ||
826 | +class callHandler : public std::unary_function<LLMessageTemplateHandlerEntry, void> | ||
827 | +{ | ||
828 | +public: | ||
829 | + callHandler(LLMessageSystem *msg) : mMsg(msg) {} | ||
830 | + void operator()(const LLMessageTemplateHandlerEntry& a) const { a.call(mMsg); } | ||
831 | +private: | ||
832 | + LLMessageSystem *mMsg; | ||
833 | +}; | ||
834 | + | ||
835 | + | ||
836 | class LLMessageTemplate | ||
837 | { | ||
838 | public: | ||
839 | @@ -291,9 +319,10 @@ public: | ||
840 | mTotalDecodeTime(0.f), | ||
841 | mMaxDecodeTimePerMsg(0.f), | ||
842 | mBanFromTrusted(false), | ||
843 | - mBanFromUntrusted(false), | ||
844 | - mHandlerFunc(NULL), | ||
845 | - mUserData(NULL) | ||
846 | + //mBanFromUntrusted(false), | ||
847 | + //mHandlerFunc(NULL), | ||
848 | + //mUserData(NULL) | ||
849 | + mBanFromUntrusted(false) | ||
850 | { | ||
851 | mName = LLMessageStringTable::getInstance()->getString(name); | ||
852 | } | ||
853 | @@ -361,21 +390,91 @@ public: | ||
854 | return mDeprecation; | ||
855 | } | ||
856 | |||
857 | - void setHandlerFunc(void (*handler_func)(LLMessageSystem *msgsystem, void **user_data), void **user_data) | ||
858 | +// void setHandlerFunc(void (*handler_func)(LLMessageSystem *msgsystem, void **user_data), void **user_data) | ||
859 | + /** | ||
860 | + * @brief Adds a handler | ||
861 | + * This function adds a new handler to be called when the message arrives. | ||
862 | + * Repeated additions of the same handler function will be ignored. | ||
863 | + * @note delHandlerFunc() must be called to remove the registration | ||
864 | + * @param handler Function to call | ||
865 | + * @param user_data User specified data to pass to the function | ||
866 | + */ | ||
867 | + void addHandlerFunc(message_handler_func_t handler, void **user_data) | ||
868 | { | ||
869 | - mHandlerFunc = handler_func; | ||
870 | - mUserData = user_data; | ||
871 | + LLMessageTemplateHandlerEntry h(handler, user_data); | ||
872 | + | ||
873 | + if ( std::find(mHandlers.begin(), mHandlers.end(), h ) != mHandlers.end() ) | ||
874 | + { | ||
875 | + return; | ||
876 | + } | ||
877 | + | ||
878 | + mHandlers.push_back( h ); | ||
879 | + } | ||
880 | + | ||
881 | + /** | ||
882 | + * @brief Sets a handler | ||
883 | + * This function sets a handler to be called when the message arrives. | ||
884 | + * Any existing handlers are unregistered. | ||
885 | + * @note delHandlerFunc() must be called to remove the registration | ||
886 | + * @param handler Function to call | ||
887 | + * @param user_data User specified data to pass to the function | ||
888 | + */ | ||
889 | + void setHandlerFunc(message_handler_func_t handler, void **user_data) | ||
890 | + { | ||
891 | + mHandlers.clear(); | ||
892 | + if( handler ) | ||
893 | + { | ||
894 | + addHandlerFunc(handler, user_data); | ||
895 | + } | ||
896 | + else | ||
897 | + { | ||
898 | + llwarns << "code has reset handler for \"" << mName << "\" by setting it to NULL." << llendl; | ||
899 | + } | ||
900 | + } | ||
901 | + | ||
902 | + /** | ||
903 | + * @brief Removes a handler | ||
904 | + * Removes a handler from the list of handlers. | ||
905 | + * Attempts to remove handlers that aren't in the list are silently | ||
906 | + * ignored. | ||
907 | + * @param handler Function to remove | ||
908 | + */ | ||
909 | + void delHandlerFunc(message_handler_func_t handler) | ||
910 | + { | ||
911 | + //mHandlerFunc = handler_func; | ||
912 | + //mUserData = user_data; | ||
913 | + mHandlers.remove( LLMessageTemplateHandlerEntry(handler) ); | ||
914 | } | ||
915 | |||
916 | BOOL callHandlerFunc(LLMessageSystem *msgsystem) const | ||
917 | { | ||
918 | - if (mHandlerFunc) | ||
919 | + //if (mHandlerFunc) | ||
920 | + if ( mHandlers.empty() ) | ||
921 | + { | ||
922 | + return FALSE; | ||
923 | + } | ||
924 | + /* | ||
925 | + * Be on the safe side and use for_each only when necessary. There is Linden code ("ReplyPayPrice") that | ||
926 | + * does not take the multiple reply handlers into account and simply tries to unregister | ||
927 | + * by setting the handler function to 0, unfortunately from within the reply handler so in this case | ||
928 | + * the for_each iterator inside std_algo.h is invalidated leading to a crash if the memory is reused | ||
929 | + * in between. | ||
930 | + */ | ||
931 | + else if( mHandlers.size() == 1 ) | ||
932 | + { | ||
933 | + //KOW HACK we probably want to re-enable the llPerfBlocks here, may need a vendor merge for llstats.cpp stuff. | ||
934 | + //LLPerfBlock msg_cb_time("msg_cb", mName); | ||
935 | + //mHandlerFunc(msgsystem, mUserData); | ||
936 | + mHandlers.begin()->call(msgsystem); | ||
937 | + return TRUE; | ||
938 | + } | ||
939 | + else | ||
940 | { | ||
941 | - LLPerfBlock msg_cb_time("msg_cb", mName); | ||
942 | - mHandlerFunc(msgsystem, mUserData); | ||
943 | + //LLPerfBlock msg_cb_time("msg_cb", mName); | ||
944 | + std::for_each(mHandlers.begin(), mHandlers.end(), callHandler(msgsystem)); | ||
945 | return TRUE; | ||
946 | } | ||
947 | - return FALSE; | ||
948 | + //return FALSE; | ||
949 | } | ||
950 | |||
951 | bool isUdpBanned() const | ||
952 | @@ -421,8 +520,9 @@ public: | ||
953 | |||
954 | private: | ||
955 | // message handler function (this is set by each application) | ||
956 | - void (*mHandlerFunc)(LLMessageSystem *msgsystem, void **user_data); | ||
957 | - void **mUserData; | ||
958 | +// void (*mHandlerFunc)(LLMessageSystem *msgsystem, void **user_data); | ||
959 | +// void **mUserData; | ||
960 | + std::list<LLMessageTemplateHandlerEntry> mHandlers; | ||
961 | }; | ||
962 | |||
963 | #endif // LL_LLMESSAGETEMPLATE_H | ||
964 | diff --git a/linden/indra/llmessage/llpumpio.cpp b/linden/indra/llmessage/llpumpio.cpp | ||
965 | index 01a43ec..cc9e543 100644 | ||
966 | --- a/linden/indra/llmessage/llpumpio.cpp | ||
967 | +++ b/linden/indra/llmessage/llpumpio.cpp | ||
968 | @@ -41,7 +41,6 @@ | ||
969 | #include "llapr.h" | ||
970 | #include "llmemtype.h" | ||
971 | #include "llstl.h" | ||
972 | -#include "llstat.h" | ||
973 | |||
974 | // These should not be enabled in production, but they can be | ||
975 | // intensely useful during development for finding certain kinds of | ||
976 | @@ -177,8 +176,7 @@ LLPumpIO::LLPumpIO(apr_pool_t* pool) : | ||
977 | mCurrentPool(NULL), | ||
978 | mCurrentPoolReallocCount(0), | ||
979 | mChainsMutex(NULL), | ||
980 | - mCallbackMutex(NULL), | ||
981 | - mCurrentChain(mRunningChains.end()) | ||
982 | + mCallbackMutex(NULL) | ||
983 | { | ||
984 | LLMemType m1(LLMemType::MTYPE_IO_PUMP); | ||
985 | initialize(pool); | ||
986 | @@ -274,10 +272,7 @@ bool LLPumpIO::setTimeoutSeconds(F32 timeout) | ||
987 | void LLPumpIO::adjustTimeoutSeconds(F32 delta) | ||
988 | { | ||
989 | // If no chain is running, bail | ||
990 | - if(mRunningChains.end() == mCurrentChain) | ||
991 | - { | ||
992 | - return; | ||
993 | - } | ||
994 | + if(current_chain_t() == mCurrentChain) return; | ||
995 | (*mCurrentChain).adjustTimeoutSeconds(delta); | ||
996 | } | ||
997 | |||
998 | @@ -526,10 +521,7 @@ void LLPumpIO::pump(const S32& poll_timeout) | ||
999 | //llinfos << "polling" << llendl; | ||
1000 | S32 count = 0; | ||
1001 | S32 client_id = 0; | ||
1002 | - { | ||
1003 | - LLPerfBlock polltime("pump_poll"); | ||
1004 | apr_pollset_poll(mPollset, poll_timeout, &count, &poll_fd); | ||
1005 | - } | ||
1006 | PUMP_DEBUG; | ||
1007 | for(S32 ii = 0; ii < count; ++ii) | ||
1008 | { | ||
1009 | diff --git a/linden/indra/llmessage/message.cpp b/linden/indra/llmessage/message.cpp | ||
1010 | index ccc3d79..0d0ad18 100644 | ||
1011 | --- a/linden/indra/llmessage/message.cpp | ||
1012 | +++ b/linden/indra/llmessage/message.cpp | ||
1013 | @@ -754,7 +754,6 @@ BOOL LLMessageSystem::checkMessages( S64 frame_count ) | ||
1014 | clearReceiveState(); | ||
1015 | valid_packet = FALSE; | ||
1016 | } | ||
1017 | - | ||
1018 | if( valid_packet && mTemplateMessageReader->isUdpBanned()) | ||
1019 | { | ||
1020 | llwarns << "Received UDP black listed message " | ||
1021 | @@ -767,6 +766,7 @@ BOOL LLMessageSystem::checkMessages( S64 frame_count ) | ||
1022 | if( valid_packet ) | ||
1023 | { | ||
1024 | logValidMsg(cdp, host, recv_reliable, recv_resent, (BOOL)(acks>0) ); | ||
1025 | + | ||
1026 | valid_packet = mTemplateMessageReader->readMessage(buffer, host); | ||
1027 | } | ||
1028 | |||
1029 | @@ -2972,7 +2972,7 @@ void LLMessageSystem::addTemplate(LLMessageTemplate *templatep) | ||
1030 | } | ||
1031 | |||
1032 | |||
1033 | -void LLMessageSystem::setHandlerFuncFast(const char *name, void (*handler_func)(LLMessageSystem *msgsystem, void **user_data), void **user_data) | ||
1034 | +void LLMessageSystem::setHandlerFuncFast(const char *name, message_handler_func_t handler_func, void **user_data) | ||
1035 | { | ||
1036 | LLMessageTemplate* msgtemplate = get_ptr_in_map(mMessageTemplates, name); | ||
1037 | if (msgtemplate) | ||
1038 | @@ -2985,6 +2985,32 @@ void LLMessageSystem::setHandlerFuncFast(const char *name, void (*handler_func)( | ||
1039 | } | ||
1040 | } | ||
1041 | |||
1042 | +void LLMessageSystem::addHandlerFuncFast(const char *name, message_handler_func_t handler_func, void **user_data) | ||
1043 | +{ | ||
1044 | + LLMessageTemplate* msgtemplate = get_ptr_in_map(mMessageTemplates, name); | ||
1045 | + if (msgtemplate) | ||
1046 | + { | ||
1047 | + msgtemplate->addHandlerFunc(handler_func, user_data); | ||
1048 | + } | ||
1049 | + else | ||
1050 | + { | ||
1051 | + llerrs << name << " is not a known message name!" << llendl; | ||
1052 | + } | ||
1053 | +} | ||
1054 | + | ||
1055 | +void LLMessageSystem::delHandlerFuncFast(const char *name, message_handler_func_t handler_func) | ||
1056 | +{ | ||
1057 | + LLMessageTemplate* msgtemplate = get_ptr_in_map(mMessageTemplates, name); | ||
1058 | + if (msgtemplate) | ||
1059 | + { | ||
1060 | + msgtemplate->delHandlerFunc(handler_func); | ||
1061 | + } | ||
1062 | + else | ||
1063 | + { | ||
1064 | + llerrs << name << " is not a known message name!" << llendl; | ||
1065 | + } | ||
1066 | +} | ||
1067 | + | ||
1068 | bool LLMessageSystem::callHandler(const char *name, | ||
1069 | bool trustedSource, LLMessageSystem* msg) | ||
1070 | { | ||
1071 | @@ -3956,27 +3982,27 @@ void LLMessageSystem::getString(const char *block, const char *var, | ||
1072 | blocknum); | ||
1073 | } | ||
1074 | |||
1075 | -BOOL LLMessageSystem::has(const char *blockname) const | ||
1076 | +BOOL LLMessageSystem::has(const char *blockname) | ||
1077 | { | ||
1078 | return getNumberOfBlocks(blockname) > 0; | ||
1079 | } | ||
1080 | |||
1081 | -S32 LLMessageSystem::getNumberOfBlocksFast(const char *blockname) const | ||
1082 | +S32 LLMessageSystem::getNumberOfBlocksFast(const char *blockname) | ||
1083 | { | ||
1084 | return mMessageReader->getNumberOfBlocks(blockname); | ||
1085 | } | ||
1086 | |||
1087 | -S32 LLMessageSystem::getNumberOfBlocks(const char *blockname) const | ||
1088 | +S32 LLMessageSystem::getNumberOfBlocks(const char *blockname) | ||
1089 | { | ||
1090 | return getNumberOfBlocksFast(LLMessageStringTable::getInstance()->getString(blockname)); | ||
1091 | } | ||
1092 | |||
1093 | -S32 LLMessageSystem::getSizeFast(const char *blockname, const char *varname) const | ||
1094 | +S32 LLMessageSystem::getSizeFast(const char *blockname, const char *varname) | ||
1095 | { | ||
1096 | return mMessageReader->getSize(blockname, varname); | ||
1097 | } | ||
1098 | |||
1099 | -S32 LLMessageSystem::getSize(const char *blockname, const char *varname) const | ||
1100 | +S32 LLMessageSystem::getSize(const char *blockname, const char *varname) | ||
1101 | { | ||
1102 | return getSizeFast(LLMessageStringTable::getInstance()->getString(blockname), | ||
1103 | LLMessageStringTable::getInstance()->getString(varname)); | ||
1104 | @@ -3984,13 +4010,13 @@ S32 LLMessageSystem::getSize(const char *blockname, const char *varname) const | ||
1105 | |||
1106 | // size in bytes of variable length data | ||
1107 | S32 LLMessageSystem::getSizeFast(const char *blockname, S32 blocknum, | ||
1108 | - const char *varname) const | ||
1109 | + const char *varname) | ||
1110 | { | ||
1111 | return mMessageReader->getSize(blockname, blocknum, varname); | ||
1112 | } | ||
1113 | |||
1114 | S32 LLMessageSystem::getSize(const char *blockname, S32 blocknum, | ||
1115 | - const char *varname) const | ||
1116 | + const char *varname) | ||
1117 | { | ||
1118 | return getSizeFast(LLMessageStringTable::getInstance()->getString(blockname), blocknum, | ||
1119 | LLMessageStringTable::getInstance()->getString(varname)); | ||
1120 | diff --git a/linden/indra/llmessage/message.h b/linden/indra/llmessage/message.h | ||
1121 | index c503a58..4b96526 100644 | ||
1122 | --- a/linden/indra/llmessage/message.h | ||
1123 | +++ b/linden/indra/llmessage/message.h | ||
1124 | @@ -179,7 +179,7 @@ enum EMessageException | ||
1125 | MX_WROTE_PAST_BUFFER_SIZE // wrote past buffer size in zero code expand | ||
1126 | }; | ||
1127 | typedef void (*msg_exception_callback)(LLMessageSystem*,void*,EMessageException); | ||
1128 | - | ||
1129 | +typedef void (*message_handler_func_t)(LLMessageSystem *msgsystem, void **user_data); | ||
1130 | |||
1131 | // message data pieces are used to collect the data called for by the message template | ||
1132 | class LLMsgData; | ||
1133 | @@ -299,12 +299,24 @@ public: | ||
1134 | |||
1135 | |||
1136 | // methods for building, sending, receiving, and handling messages | ||
1137 | - void setHandlerFuncFast(const char *name, void (*handler_func)(LLMessageSystem *msgsystem, void **user_data), void **user_data = NULL); | ||
1138 | - void setHandlerFunc(const char *name, void (*handler_func)(LLMessageSystem *msgsystem, void **user_data), void **user_data = NULL) | ||
1139 | + void setHandlerFuncFast(const char *name, message_handler_func_t, void **user_data = NULL); | ||
1140 | + void setHandlerFunc(const char *name, message_handler_func_t handler_func, void **user_data = NULL) | ||
1141 | { | ||
1142 | setHandlerFuncFast(LLMessageStringTable::getInstance()->getString(name), handler_func, user_data); | ||
1143 | } | ||
1144 | |||
1145 | + void addHandlerFuncFast(const char *name, message_handler_func_t, void **user_data = NULL); | ||
1146 | + void addHandlerFunc(const char *name, message_handler_func_t handler_func, void **user_data = NULL) | ||
1147 | + { | ||
1148 | + addHandlerFuncFast(LLMessageStringTable::getInstance()->getString(name), handler_func, user_data); | ||
1149 | + } | ||
1150 | + | ||
1151 | + void delHandlerFuncFast(const char *name, message_handler_func_t); | ||
1152 | + void delHandlerFunc(const char *name, message_handler_func_t handler_func) | ||
1153 | + { | ||
1154 | + delHandlerFuncFast(LLMessageStringTable::getInstance()->getString(name), handler_func); | ||
1155 | + } | ||
1156 | + | ||
1157 | // Set a callback function for a message system exception. | ||
1158 | void setExceptionFunc(EMessageException exception, msg_exception_callback func, void* data = NULL); | ||
1159 | // Call the specified exception func, and return TRUE if a | ||
1160 | @@ -594,14 +606,14 @@ public: | ||
1161 | LLHost findHost(const U32 circuit_code); | ||
1162 | void sanityCheck(); | ||
1163 | |||
1164 | - BOOL has(const char *blockname) const; | ||
1165 | - S32 getNumberOfBlocksFast(const char *blockname) const; | ||
1166 | - S32 getNumberOfBlocks(const char *blockname) const; | ||
1167 | - S32 getSizeFast(const char *blockname, const char *varname) const; | ||
1168 | - S32 getSize(const char *blockname, const char *varname) const; | ||
1169 | + BOOL has(const char *blockname); | ||
1170 | + S32 getNumberOfBlocksFast(const char *blockname); | ||
1171 | + S32 getNumberOfBlocks(const char *blockname); | ||
1172 | + S32 getSizeFast(const char *blockname, const char *varname); | ||
1173 | + S32 getSize(const char *blockname, const char *varname); | ||
1174 | S32 getSizeFast(const char *blockname, S32 blocknum, | ||
1175 | - const char *varname) const; // size in bytes of data | ||
1176 | - S32 getSize(const char *blockname, S32 blocknum, const char *varname) const; | ||
1177 | + const char *varname); // size in bytes of data | ||
1178 | + S32 getSize(const char *blockname, S32 blocknum, const char *varname); | ||
1179 | |||
1180 | void resetReceiveCounts(); // resets receive counts for all message types to 0 | ||
1181 | void dumpReceiveCounts(); // dumps receive count for each message type to llinfos | ||
1182 | diff --git a/linden/indra/newview/app_settings/settings.xml b/linden/indra/newview/app_settings/settings.xml | ||
1183 | index cf9a7cd..4927571 100644 | ||
1184 | --- a/linden/indra/newview/app_settings/settings.xml | ||
1185 | +++ b/linden/indra/newview/app_settings/settings.xml | ||
1186 | @@ -4762,7 +4762,7 @@ | ||
1187 | <key>Type</key> | ||
1188 | <string>U32</string> | ||
1189 | <key>Value</key> | ||
1190 | - <integer>0</integer> | ||
1191 | + <integer>1</integer> | ||
1192 | </map> | ||
1193 | <key>MemoryLogFrequency</key> | ||
1194 | <map> | ||
1195 | diff --git a/linden/indra/newview/llstartup.cpp b/linden/indra/newview/llstartup.cpp | ||
1196 | index cab9815..5cd2a56 100644 | ||
1197 | --- a/linden/indra/newview/llstartup.cpp | ||
1198 | +++ b/linden/indra/newview/llstartup.cpp | ||
1199 | @@ -3152,7 +3152,7 @@ void register_viewer_callbacks(LLMessageSystem* msg) | ||
1200 | msg->setHandlerFunc("ParcelDwellReply", | ||
1201 | LLViewerParcelMgr::processParcelDwellReply); | ||
1202 | |||
1203 | - msg->setHandlerFunc("AvatarPropertiesReply", | ||
1204 | + msg->addHandlerFunc("AvatarPropertiesReply", | ||
1205 | LLPanelAvatar::processAvatarPropertiesReply); | ||
1206 | msg->setHandlerFunc("AvatarInterestsReply", | ||
1207 | LLPanelAvatar::processAvatarInterestsReply); | ||
1208 | diff --git a/linden/indra/newview/llviewermessage.cpp b/linden/indra/newview/llviewermessage.cpp | ||
1209 | index 03114f7..b984687 100644 | ||
1210 | --- a/linden/indra/newview/llviewermessage.cpp | ||
1211 | +++ b/linden/indra/newview/llviewermessage.cpp | ||
1212 | @@ -3516,15 +3516,6 @@ void process_sim_stats(LLMessageSystem *msg, void **user_data) | ||
1213 | case LL_SIM_STAT_SIMPHYSICSMEMORY: | ||
1214 | LLViewerStats::getInstance()->mPhysicsMemoryAllocated.addValue(stat_value); | ||
1215 | break; | ||
1216 | - case LL_SIM_STAT_SIMSPARETIME: | ||
1217 | - LLViewerStats::getInstance()->mSimSpareMsec.addValue(stat_value); | ||
1218 | - break; | ||
1219 | - case LL_SIM_STAT_SIMSLEEPTIME: | ||
1220 | - LLViewerStats::getInstance()->mSimSleepMsec.addValue(stat_value); | ||
1221 | - break; | ||
1222 | - case LL_SIM_STAT_IOPUMPTIME: | ||
1223 | - LLViewerStats::getInstance()->mSimPumpIOMsec.addValue(stat_value); | ||
1224 | - break; | ||
1225 | default: | ||
1226 | // Used to be a commented out warning. | ||
1227 | LL_DEBUGS("Messaging") << "Unknown stat id" << stat_id << LL_ENDL; | ||
1228 | diff --git a/linden/indra/newview/llviewerobject.h b/linden/indra/newview/llviewerobject.h | ||
1229 | index dc529cd..ebb46b9 100644 | ||
1230 | --- a/linden/indra/newview/llviewerobject.h | ||
1231 | +++ b/linden/indra/newview/llviewerobject.h | ||
1232 | @@ -600,7 +600,9 @@ protected: | ||
1233 | // extra data sent from the sim...currently only used for tree species info | ||
1234 | U8* mData; | ||
1235 | |||
1236 | +public: | ||
1237 | LLPointer<LLViewerPartSourceScript> mPartSourcep; // Particle source associated with this object. | ||
1238 | +protected: | ||
1239 | LLAudioSourceVO* mAudioSourcep; | ||
1240 | F32 mAudioGain; | ||
1241 | |||
1242 | diff --git a/linden/indra/newview/llvoavatar.cpp b/linden/indra/newview/llvoavatar.cpp | ||
1243 | index 3d2523e..86993df 100644 | ||
1244 | --- a/linden/indra/newview/llvoavatar.cpp | ||
1245 | +++ b/linden/indra/newview/llvoavatar.cpp | ||
1246 | @@ -891,7 +891,6 @@ LLVOAvatar::LLVOAvatar( | ||
1247 | mEyeBallLeftMesh1.setSpecular( LLColor4( 1.0f, 1.0f, 1.0f, 1.0f ), 1.f ); | ||
1248 | mEyeBallRightMesh0.setSpecular( LLColor4( 1.0f, 1.0f, 1.0f, 1.0f ), 1.f ); | ||
1249 | mEyeBallRightMesh1.setSpecular( LLColor4( 1.0f, 1.0f, 1.0f, 1.0f ), 1.f ); | ||
1250 | - | ||
1251 | //------------------------------------------------------------------------- | ||
1252 | // register motions | ||
1253 | //------------------------------------------------------------------------- | ||
1254 | @@ -960,7 +959,8 @@ LLVOAvatar::LLVOAvatar( | ||
1255 | //VTPause(); // VTune | ||
1256 | |||
1257 | mVoiceVisualizer->setVoiceEnabled( gVoiceClient->getVoiceEnabled( mID ) ); | ||
1258 | - mCurrentGesticulationLevel = 0; | ||
1259 | + mCurrentGesticulationLevel = 0; | ||
1260 | + | ||
1261 | } | ||
1262 | |||
1263 | //------------------------------------------------------------------------ | ||
1264 | @@ -1990,7 +1990,8 @@ void LLVOAvatar::buildCharacter() | ||
1265 | mWristRightp = (LLViewerJoint*)mRoot.findJoint("mWristRight"); | ||
1266 | mEyeLeftp = (LLViewerJoint*)mRoot.findJoint("mEyeLeft"); | ||
1267 | mEyeRightp = (LLViewerJoint*)mRoot.findJoint("mEyeRight"); | ||
1268 | - | ||
1269 | + | ||
1270 | + lldebugs << " initialized joint pointers" << llendl; | ||
1271 | //------------------------------------------------------------------------- | ||
1272 | // Make sure "well known" pointers exist | ||
1273 | //------------------------------------------------------------------------- | ||
1274 | @@ -2016,7 +2017,7 @@ void LLVOAvatar::buildCharacter() | ||
1275 | llerrs << "Failed to create avatar." << llendl; | ||
1276 | return; | ||
1277 | } | ||
1278 | - | ||
1279 | + lldebugs << "pointers exist, good." << llendl; | ||
1280 | //------------------------------------------------------------------------- | ||
1281 | // initialize the pelvis | ||
1282 | //------------------------------------------------------------------------- | ||
1283 | @@ -2140,7 +2141,7 @@ void LLVOAvatar::buildCharacter() | ||
1284 | } | ||
1285 | } | ||
1286 | } | ||
1287 | - | ||
1288 | + lldebugs << "builded the attach and detach menus" << llendl; | ||
1289 | // add screen attachments | ||
1290 | for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); | ||
1291 | iter != mAttachmentPoints.end(); ) | ||
1292 | @@ -2159,6 +2160,7 @@ void LLVOAvatar::buildCharacter() | ||
1293 | &handle_detach_from_avatar, object_attached, attachment)); | ||
1294 | } | ||
1295 | } | ||
1296 | + lldebugs << "added screen attachments" << llendl; | ||
1297 | |||
1298 | for (S32 pass = 0; pass < 2; pass++) | ||
1299 | { | ||
1300 | @@ -2188,6 +2190,7 @@ void LLVOAvatar::buildCharacter() | ||
1301 | gDetachSubMenu->appendSeparator(); | ||
1302 | } | ||
1303 | } | ||
1304 | + lldebugs << "added other attachments" << llendl; | ||
1305 | |||
1306 | for (S32 group = 0; group < 8; group++) | ||
1307 | { | ||
1308 | @@ -2241,9 +2244,11 @@ void LLVOAvatar::buildCharacter() | ||
1309 | } | ||
1310 | } | ||
1311 | } | ||
1312 | + lldebugs << "added pies" << llendl; | ||
1313 | } | ||
1314 | |||
1315 | mMeshValid = TRUE; | ||
1316 | + lldebugs << "mMeshValid = TRUE" << llendl; | ||
1317 | } | ||
1318 | |||
1319 | |||
diff --git a/meerkat-pipeline.cpp.diff.txt b/meerkat-pipeline.cpp.diff.txt new file mode 100644 index 0000000..b34cd94 --- /dev/null +++ b/meerkat-pipeline.cpp.diff.txt | |||
@@ -0,0 +1,22 @@ | |||
1 | --- /linden/indra/newview/pipeline.cpp 2009-06-25 15:23:44.000000000 +0200 | ||
2 | +++ /linden/indra/newview/pipeline.cpp 2009-06-25 23:49:51.000000000 +0200 | ||
3 | @@ -2691,7 +2711,10 @@ | ||
4 | // from Medium -> Low, because we unload all the shaders and the | ||
5 | // draw pools aren't aware. I don't know if this has to be a separate | ||
6 | // loop before actual rendering. JC | ||
7 | - for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter) | ||
8 | + | ||
9 | + // TODO: this is a useful fix, find out why it breaks logout -- RMS | ||
10 | + | ||
11 | +/* for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter) | ||
12 | { | ||
13 | LLDrawPool *poolp = *iter; | ||
14 | if (poolp->isFacePool() && hasRenderType(poolp->getType())) | ||
15 | @@ -2699,6 +2722,7 @@ | ||
16 | poolp->prerender(); | ||
17 | } | ||
18 | } | ||
19 | +*/ | ||
20 | for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter) | ||
21 | { | ||
22 | LLDrawPool *poolp = *iter; | ||
diff --git a/meerkat-voice.diff.txt b/meerkat-voice.diff.txt new file mode 100644 index 0000000..f49d511 --- /dev/null +++ b/meerkat-voice.diff.txt | |||
@@ -0,0 +1,7282 @@ | |||
1 | diff --git a/linden/indra/newview/llfloaterfriends.cpp b/linden/indra/newview/llfloaterfriends.cpp | ||
2 | index bf1f678..41137b4 100644 | ||
3 | --- a/linden/indra/newview/llfloaterfriends.cpp | ||
4 | +++ b/linden/indra/newview/llfloaterfriends.cpp | ||
5 | @@ -57,7 +57,6 @@ | ||
6 | #include "llviewermessage.h" | ||
7 | #include "lltimer.h" | ||
8 | #include "lltextbox.h" | ||
9 | -#include "llvoiceclient.h" | ||
10 | |||
11 | //Maximum number of people you can select to do an operation on at once. | ||
12 | #define MAX_FRIEND_SELECT 20 | ||
13 | @@ -65,8 +64,6 @@ | ||
14 | #define RIGHTS_CHANGE_TIMEOUT 5.0 | ||
15 | #define OBSERVER_TIMEOUT 0.5 | ||
16 | |||
17 | -#define ONLINE_SIP_ICON_NAME "slim_icon_16_viewer.tga" | ||
18 | - | ||
19 | // simple class to observe the calling cards. | ||
20 | class LLLocalFriendsObserver : public LLFriendObserver, public LLEventTimer | ||
21 | { | ||
22 | @@ -114,14 +111,10 @@ LLPanelFriends::LLPanelFriends() : | ||
23 | mEventTimer.stop(); | ||
24 | mObserver = new LLLocalFriendsObserver(this); | ||
25 | LLAvatarTracker::instance().addObserver(mObserver); | ||
26 | - // For notification when SIP online status changes. | ||
27 | - LLVoiceClient::getInstance()->addObserver(mObserver); | ||
28 | } | ||
29 | |||
30 | LLPanelFriends::~LLPanelFriends() | ||
31 | { | ||
32 | - // For notification when SIP online status changes. | ||
33 | - LLVoiceClient::getInstance()->removeObserver(mObserver); | ||
34 | LLAvatarTracker::instance().removeObserver(mObserver); | ||
35 | delete mObserver; | ||
36 | } | ||
37 | @@ -219,9 +212,7 @@ BOOL LLPanelFriends::addFriend(const LLUUID& agent_id) | ||
38 | LLAvatarTracker& at = LLAvatarTracker::instance(); | ||
39 | const LLRelationship* relationInfo = at.getBuddyInfo(agent_id); | ||
40 | if(!relationInfo) return FALSE; | ||
41 | - | ||
42 | - bool isOnlineSIP = LLVoiceClient::getInstance()->isOnlineSIP(agent_id); | ||
43 | - bool isOnline = relationInfo->isOnline(); | ||
44 | + BOOL online = relationInfo->isOnline(); | ||
45 | |||
46 | std::string fullname; | ||
47 | BOOL have_name = gCacheName->getFullName(agent_id, fullname); | ||
48 | @@ -237,17 +228,12 @@ BOOL LLPanelFriends::addFriend(const LLUUID& agent_id) | ||
49 | LLSD& online_status_column = element["columns"][LIST_ONLINE_STATUS]; | ||
50 | online_status_column["column"] = "icon_online_status"; | ||
51 | online_status_column["type"] = "icon"; | ||
52 | - | ||
53 | - if (isOnline) | ||
54 | + | ||
55 | + if (online) | ||
56 | { | ||
57 | friend_column["font-style"] = "BOLD"; | ||
58 | online_status_column["value"] = "icon_avatar_online.tga"; | ||
59 | } | ||
60 | - else if(isOnlineSIP) | ||
61 | - { | ||
62 | - friend_column["font-style"] = "BOLD"; | ||
63 | - online_status_column["value"] = ONLINE_SIP_ICON_NAME; | ||
64 | - } | ||
65 | |||
66 | LLSD& online_column = element["columns"][LIST_VISIBLE_ONLINE]; | ||
67 | online_column["column"] = "icon_visible_online"; | ||
68 | @@ -285,30 +271,14 @@ BOOL LLPanelFriends::updateFriendItem(const LLUUID& agent_id, const LLRelationsh | ||
69 | if (!info) return FALSE; | ||
70 | LLScrollListItem* itemp = mFriendsList->getItem(agent_id); | ||
71 | if (!itemp) return FALSE; | ||
72 | - | ||
73 | - bool isOnlineSIP = LLVoiceClient::getInstance()->isOnlineSIP(itemp->getUUID()); | ||
74 | - bool isOnline = info->isOnline(); | ||
75 | |||
76 | std::string fullname; | ||
77 | BOOL have_name = gCacheName->getFullName(agent_id, fullname); | ||
78 | - | ||
79 | - // Name of the status icon to use | ||
80 | - std::string statusIcon; | ||
81 | - | ||
82 | - if(isOnline) | ||
83 | - { | ||
84 | - statusIcon = "icon_avatar_online.tga"; | ||
85 | - } | ||
86 | - else if(isOnlineSIP) | ||
87 | - { | ||
88 | - statusIcon = ONLINE_SIP_ICON_NAME; | ||
89 | - } | ||
90 | |||
91 | - itemp->getColumn(LIST_ONLINE_STATUS)->setValue(statusIcon); | ||
92 | - | ||
93 | + itemp->getColumn(LIST_ONLINE_STATUS)->setValue(info->isOnline() ? std::string("icon_avatar_online.tga") : LLStringUtil::null); | ||
94 | itemp->getColumn(LIST_FRIEND_NAME)->setValue(fullname); | ||
95 | // render name of online friends in bold text | ||
96 | - ((LLScrollListText*)itemp->getColumn(LIST_FRIEND_NAME))->setFontStyle((isOnline || isOnlineSIP) ? LLFontGL::BOLD : LLFontGL::NORMAL); | ||
97 | + ((LLScrollListText*)itemp->getColumn(LIST_FRIEND_NAME))->setFontStyle(info->isOnline() ? LLFontGL::BOLD : LLFontGL::NORMAL); | ||
98 | itemp->getColumn(LIST_VISIBLE_ONLINE)->setValue(info->isRightGrantedTo(LLRelationship::GRANT_ONLINE_STATUS)); | ||
99 | itemp->getColumn(LIST_VISIBLE_MAP)->setValue(info->isRightGrantedTo(LLRelationship::GRANT_MAP_LOCATION)); | ||
100 | itemp->getColumn(LIST_EDIT_MINE)->setValue(info->isRightGrantedTo(LLRelationship::GRANT_MODIFY_OBJECTS)); | ||
101 | diff --git a/linden/indra/newview/llimpanel.cpp b/linden/indra/newview/llimpanel.cpp | ||
102 | index f30ae8c..d3139ad 100644 | ||
103 | --- a/linden/indra/newview/llimpanel.cpp | ||
104 | +++ b/linden/indra/newview/llimpanel.cpp | ||
105 | @@ -49,7 +49,6 @@ | ||
106 | #include "llconsole.h" | ||
107 | #include "llfloater.h" | ||
108 | #include "llfloatergroupinfo.h" | ||
109 | -#include "llfloaterchatterbox.h" | ||
110 | #include "llimview.h" | ||
111 | #include "llinventory.h" | ||
112 | #include "llinventorymodel.h" | ||
113 | @@ -69,6 +68,7 @@ | ||
114 | #include "lluictrlfactory.h" | ||
115 | #include "llviewerwindow.h" | ||
116 | #include "lllogchat.h" | ||
117 | +#include "llfloaterhtml.h" | ||
118 | #include "llweb.h" | ||
119 | #include "llhttpclient.h" | ||
120 | #include "llmutelist.h" | ||
121 | @@ -357,7 +357,7 @@ LLVoiceChannel::LLVoiceChannel(const LLUUID& session_id, const std::string& sess | ||
122 | llwarns << "Duplicate voice channels registered for session_id " << session_id << llendl; | ||
123 | } | ||
124 | |||
125 | - LLVoiceClient::getInstance()->addObserver(this); | ||
126 | + LLVoiceClient::getInstance()->addStatusObserver(this); | ||
127 | } | ||
128 | |||
129 | LLVoiceChannel::~LLVoiceChannel() | ||
130 | @@ -365,7 +365,7 @@ LLVoiceChannel::~LLVoiceChannel() | ||
131 | // Don't use LLVoiceClient::getInstance() here -- this can get called during atexit() time and that singleton MAY have already been destroyed. | ||
132 | if(gVoiceClient) | ||
133 | { | ||
134 | - gVoiceClient->removeObserver(this); | ||
135 | + gVoiceClient->removeStatusObserver(this); | ||
136 | } | ||
137 | |||
138 | sVoiceChannelMap.erase(mSessionID); | ||
139 | @@ -983,8 +983,7 @@ void LLVoiceChannelP2P::activate() | ||
140 | // otherwise answering the call | ||
141 | else | ||
142 | { | ||
143 | - LLVoiceClient::getInstance()->answerInvite(mSessionHandle); | ||
144 | - | ||
145 | + LLVoiceClient::getInstance()->answerInvite(mSessionHandle, mOtherUserID); | ||
146 | // using the session handle invalidates it. Clear it out here so we can't reuse it by accident. | ||
147 | mSessionHandle.clear(); | ||
148 | } | ||
149 | @@ -1001,7 +1000,7 @@ void LLVoiceChannelP2P::getChannelInfo() | ||
150 | } | ||
151 | |||
152 | // receiving session from other user who initiated call | ||
153 | -void LLVoiceChannelP2P::setSessionHandle(const std::string& handle, const std::string &inURI) | ||
154 | +void LLVoiceChannelP2P::setSessionHandle(const std::string& handle) | ||
155 | { | ||
156 | BOOL needs_activate = FALSE; | ||
157 | if (callStarted()) | ||
158 | @@ -1024,17 +1023,8 @@ void LLVoiceChannelP2P::setSessionHandle(const std::string& handle, const std::s | ||
159 | } | ||
160 | |||
161 | mSessionHandle = handle; | ||
162 | - | ||
163 | // The URI of a p2p session should always be the other end's SIP URI. | ||
164 | - if(!inURI.empty()) | ||
165 | - { | ||
166 | - setURI(inURI); | ||
167 | - } | ||
168 | - else | ||
169 | - { | ||
170 | - setURI(LLVoiceClient::getInstance()->sipURIFromID(mOtherUserID)); | ||
171 | - } | ||
172 | - | ||
173 | + setURI(LLVoiceClient::getInstance()->sipURIFromID(mOtherUserID)); | ||
174 | mReceivedCall = TRUE; | ||
175 | |||
176 | if (needs_activate) | ||
177 | @@ -1171,7 +1161,6 @@ void LLFloaterIMPanel::init(const std::string& session_label) | ||
178 | FALSE); | ||
179 | |||
180 | setTitle(mSessionLabel); | ||
181 | - | ||
182 | mInputEditor->setMaxTextLength(1023); | ||
183 | // enable line history support for instant message bar | ||
184 | mInputEditor->setEnableLineHistory(TRUE); | ||
185 | @@ -1218,23 +1207,7 @@ LLFloaterIMPanel::~LLFloaterIMPanel() | ||
186 | { | ||
187 | delete mSpeakers; | ||
188 | mSpeakers = NULL; | ||
189 | - | ||
190 | - // End the text IM session if necessary | ||
191 | - if(gVoiceClient && mOtherParticipantUUID.notNull()) | ||
192 | - { | ||
193 | - switch(mDialog) | ||
194 | - { | ||
195 | - case IM_NOTHING_SPECIAL: | ||
196 | - case IM_SESSION_P2P_INVITE: | ||
197 | - gVoiceClient->endUserIMSession(mOtherParticipantUUID); | ||
198 | - break; | ||
199 | - | ||
200 | - default: | ||
201 | - // Appease the compiler | ||
202 | - break; | ||
203 | - } | ||
204 | - } | ||
205 | - | ||
206 | + | ||
207 | //kicks you out of the voice channel if it is currently active | ||
208 | |||
209 | // HAVE to do this here -- if it happens in the LLVoiceChannel destructor it will call the wrong version (since the object's partially deconstructed at that point). | ||
210 | @@ -1424,7 +1397,6 @@ void LLFloaterIMPanel::draw() | ||
211 | childSetValue("mute_btn", LLMuteList::getInstance()->isMuted(mOtherParticipantUUID, LLMute::flagVoiceChat)); | ||
212 | childSetVisible("mute_btn", LLVoiceClient::voiceEnabled() && mVoiceChannel->isActive()); | ||
213 | } | ||
214 | - | ||
215 | LLFloater::draw(); | ||
216 | } | ||
217 | |||
218 | @@ -1505,7 +1477,7 @@ void LLFloaterIMPanel::addHistoryLine(const std::string &utf8msg, const LLColor4 | ||
219 | if (!hostp->isFloaterFlashing(this)) | ||
220 | { | ||
221 | hostp->setFloaterFlashing(this, TRUE); | ||
222 | - LLFloaterChatterBox::markAsUnread(true); | ||
223 | +//awfixme LLFloaterChatterBox::markAsUnread(true); | ||
224 | } | ||
225 | |||
226 | //// Only increment the number of unread IMs if they're from individuals | ||
227 | @@ -1585,7 +1557,7 @@ void LLFloaterIMPanel::setVisible(BOOL b) | ||
228 | if (hostp->isFloaterFlashing(this)) | ||
229 | { | ||
230 | hostp->setFloaterFlashing(this, FALSE); | ||
231 | - LLFloaterChatterBox::markAsUnread(false); | ||
232 | +//awfixme LLFloaterChatterBox::markAsUnread(false); | ||
233 | |||
234 | /* Don't change containing floater title - leave it "Instant Message" JC | ||
235 | LLUIString title = sTitleString; | ||
236 | @@ -1926,46 +1898,34 @@ void deliver_message(const std::string& utf8_text, | ||
237 | EInstantMessage dialog) | ||
238 | { | ||
239 | std::string name; | ||
240 | - bool sent = false; | ||
241 | gAgent.buildFullname(name); | ||
242 | |||
243 | const LLRelationship* info = NULL; | ||
244 | info = LLAvatarTracker::instance().getBuddyInfo(other_participant_id); | ||
245 | - | ||
246 | U8 offline = (!info || info->isOnline()) ? IM_ONLINE : IM_OFFLINE; | ||
247 | - | ||
248 | - if((offline == IM_OFFLINE) && (LLVoiceClient::getInstance()->isOnlineSIP(other_participant_id))) | ||
249 | - { | ||
250 | - // User is online through the OOW connector, but not with a regular viewer. Try to send the message via SLVoice. | ||
251 | - sent = gVoiceClient->sendTextMessage(other_participant_id, utf8_text); | ||
252 | - } | ||
253 | - | ||
254 | - if(!sent) | ||
255 | - { | ||
256 | - // Send message normally. | ||
257 | |||
258 | - // default to IM_SESSION_SEND unless it's nothing special - in | ||
259 | - // which case it's probably an IM to everyone. | ||
260 | - U8 new_dialog = dialog; | ||
261 | + // default to IM_SESSION_SEND unless it's nothing special - in | ||
262 | + // which case it's probably an IM to everyone. | ||
263 | + U8 new_dialog = dialog; | ||
264 | |||
265 | - if ( dialog != IM_NOTHING_SPECIAL ) | ||
266 | - { | ||
267 | - new_dialog = IM_SESSION_SEND; | ||
268 | - } | ||
269 | - pack_instant_message( | ||
270 | - gMessageSystem, | ||
271 | - gAgent.getID(), | ||
272 | - FALSE, | ||
273 | - gAgent.getSessionID(), | ||
274 | - other_participant_id, | ||
275 | - name.c_str(), | ||
276 | - utf8_text.c_str(), | ||
277 | - offline, | ||
278 | - (EInstantMessage)new_dialog, | ||
279 | - im_session_id); | ||
280 | - gAgent.sendReliableMessage(); | ||
281 | + if ( dialog != IM_NOTHING_SPECIAL ) | ||
282 | + { | ||
283 | + new_dialog = IM_SESSION_SEND; | ||
284 | } | ||
285 | |||
286 | + pack_instant_message( | ||
287 | + gMessageSystem, | ||
288 | + gAgent.getID(), | ||
289 | + FALSE, | ||
290 | + gAgent.getSessionID(), | ||
291 | + other_participant_id, | ||
292 | + name, | ||
293 | + utf8_text, | ||
294 | + offline, | ||
295 | + (EInstantMessage)new_dialog, | ||
296 | + im_session_id); | ||
297 | + gAgent.sendReliableMessage(); | ||
298 | + | ||
299 | // If there is a mute list and this is not a group chat... | ||
300 | if ( LLMuteList::getInstance() ) | ||
301 | { | ||
302 | diff --git a/linden/indra/newview/llimpanel.h b/linden/indra/newview/llimpanel.h | ||
303 | index 0f9c0f3..afec6db 100644 | ||
304 | --- a/linden/indra/newview/llimpanel.h | ||
305 | +++ b/linden/indra/newview/llimpanel.h | ||
306 | @@ -161,7 +161,7 @@ public: | ||
307 | /*virtual*/ void activate(); | ||
308 | /*virtual*/ void getChannelInfo(); | ||
309 | |||
310 | - void setSessionHandle(const std::string& handle, const std::string &inURI); | ||
311 | + void setSessionHandle(const std::string& handle); | ||
312 | |||
313 | protected: | ||
314 | virtual void setState(EState state); | ||
315 | @@ -295,6 +295,8 @@ private: | ||
316 | |||
317 | void sendTypingState(BOOL typing); | ||
318 | |||
319 | + static LLFloaterIMPanel* sInstance; | ||
320 | + | ||
321 | private: | ||
322 | LLLineEditor* mInputEditor; | ||
323 | LLViewerTextEditor* mHistoryEditor; | ||
324 | diff --git a/linden/indra/newview/llimview.cpp b/linden/indra/newview/llimview.cpp | ||
325 | index 1072b21..80c6d1c 100644 | ||
326 | --- a/linden/indra/newview/llimview.cpp | ||
327 | +++ b/linden/indra/newview/llimview.cpp | ||
328 | @@ -267,8 +267,7 @@ public: | ||
329 | EInstantMessage type, | ||
330 | EInvitationType inv_type, | ||
331 | const std::string& session_handle, | ||
332 | - const std::string& notify_box, | ||
333 | - const std::string& session_uri) : | ||
334 | + const std::string& notify_box) : | ||
335 | mSessionID(session_id), | ||
336 | mSessionName(session_name), | ||
337 | mCallerID(caller_id), | ||
338 | @@ -276,8 +275,7 @@ public: | ||
339 | mType(type), | ||
340 | mInvType(inv_type), | ||
341 | mSessionHandle(session_handle), | ||
342 | - mNotifyBox(notify_box), | ||
343 | - mSessionURI(session_uri) | ||
344 | + mNotifyBox(notify_box) | ||
345 | {}; | ||
346 | |||
347 | LLUUID mSessionID; | ||
348 | @@ -288,7 +286,6 @@ public: | ||
349 | EInvitationType mInvType; | ||
350 | std::string mSessionHandle; | ||
351 | std::string mNotifyBox; | ||
352 | - std::string mSessionURI; | ||
353 | }; | ||
354 | |||
355 | |||
356 | @@ -579,8 +576,7 @@ BOOL LLIMMgr::isIMSessionOpen(const LLUUID& uuid) | ||
357 | |||
358 | LLUUID LLIMMgr::addP2PSession(const std::string& name, | ||
359 | const LLUUID& other_participant_id, | ||
360 | - const std::string& voice_session_handle, | ||
361 | - const std::string& caller_uri) | ||
362 | + const std::string& voice_session_handle) | ||
363 | { | ||
364 | LLUUID session_id = addSession(name, IM_NOTHING_SPECIAL, other_participant_id); | ||
365 | |||
366 | @@ -588,7 +584,7 @@ LLUUID LLIMMgr::addP2PSession(const std::string& name, | ||
367 | if(floater) | ||
368 | { | ||
369 | LLVoiceChannelP2P* voice_channelp = (LLVoiceChannelP2P*)floater->getVoiceChannel(); | ||
370 | - voice_channelp->setSessionHandle(voice_session_handle, caller_uri); | ||
371 | + voice_channelp->setSessionHandle(voice_session_handle); | ||
372 | } | ||
373 | |||
374 | return session_id; | ||
375 | @@ -711,8 +707,7 @@ void LLIMMgr::inviteToSession( | ||
376 | const std::string& caller_name, | ||
377 | EInstantMessage type, | ||
378 | EInvitationType inv_type, | ||
379 | - const std::string& session_handle, | ||
380 | - const std::string& session_uri) | ||
381 | + const std::string& session_handle) | ||
382 | { | ||
383 | //ignore invites from muted residents | ||
384 | if (LLMuteList::getInstance()->isMuted(caller_id)) | ||
385 | @@ -754,8 +749,7 @@ void LLIMMgr::inviteToSession( | ||
386 | type, | ||
387 | inv_type, | ||
388 | session_handle, | ||
389 | - notify_box_type, | ||
390 | - session_uri); | ||
391 | + notify_box_type); | ||
392 | |||
393 | LLVoiceChannel* channelp = LLVoiceChannel::getChannelByID(session_id); | ||
394 | if (channelp && channelp->callStarted()) | ||
395 | @@ -930,8 +924,7 @@ void LLIMMgr::inviteUserResponse(S32 option, void* user_data) | ||
396 | invitep->mSessionID = gIMMgr->addP2PSession( | ||
397 | invitep->mSessionName, | ||
398 | invitep->mCallerID, | ||
399 | - invitep->mSessionHandle, | ||
400 | - invitep->mSessionURI ); | ||
401 | + invitep->mSessionHandle); | ||
402 | |||
403 | LLFloaterIMPanel* im_floater = | ||
404 | gIMMgr->findFloaterBySession( | ||
405 | diff --git a/linden/indra/newview/llimview.h b/linden/indra/newview/llimview.h | ||
406 | index cccd6b4..cde95b5 100644 | ||
407 | --- a/linden/indra/newview/llimview.h | ||
408 | +++ b/linden/indra/newview/llimview.h | ||
409 | @@ -97,8 +97,7 @@ public: | ||
410 | // Creates a P2P session with the requisite handle for responding to voice calls | ||
411 | LLUUID addP2PSession(const std::string& name, | ||
412 | const LLUUID& other_participant_id, | ||
413 | - const std::string& voice_session_handle, | ||
414 | - const std::string& caller_uri = LLStringUtil::null); | ||
415 | + const std::string& voice_session_handle); | ||
416 | |||
417 | // This removes the panel referenced by the uuid, and then | ||
418 | // restores internal consistency. The internal pointer is not | ||
419 | @@ -112,8 +111,7 @@ public: | ||
420 | const std::string& caller_name, | ||
421 | EInstantMessage type, | ||
422 | EInvitationType inv_type, | ||
423 | - const std::string& session_handle = LLStringUtil::null, | ||
424 | - const std::string& session_uri = LLStringUtil::null); | ||
425 | + const std::string& session_handle = LLStringUtil::null); | ||
426 | |||
427 | //Updates a given session's session IDs. Does not open, | ||
428 | //create or do anything new. If the old session doesn't | ||
429 | diff --git a/linden/indra/newview/llvoiceclient.cpp b/linden/indra/newview/llvoiceclient.cpp | ||
430 | index 76ef87d..881beb7 100644 | ||
431 | --- a/linden/indra/newview/llvoiceclient.cpp | ||
432 | +++ b/linden/indra/newview/llvoiceclient.cpp | ||
433 | @@ -1,3 +1,4 @@ | ||
434 | + | ||
435 | /** | ||
436 | * @file llvoiceclient.cpp | ||
437 | * @brief Implementation of LLVoiceClient class which is the interface to the voice client process. | ||
438 | @@ -62,20 +63,15 @@ | ||
439 | #include "llviewerwindow.h" | ||
440 | #include "llviewercamera.h" | ||
441 | |||
442 | -#include "llfloaterfriends.h" //VIVOX, inorder to refresh communicate panel | ||
443 | -#include "llfloaterchat.h" // for LLFloaterChat::addChat() | ||
444 | - | ||
445 | // for base64 decoding | ||
446 | #include "apr_base64.h" | ||
447 | |||
448 | // for SHA1 hash | ||
449 | #include "apr_sha1.h" | ||
450 | |||
451 | -// for MD5 hash | ||
452 | -#include "llmd5.h" | ||
453 | - | ||
454 | -#define USE_SESSION_GROUPS 0 | ||
455 | - | ||
456 | +// If we are connecting to agni AND the user's last name is "Linden", join this channel instead of looking up the sim name. | ||
457 | +// If we are connecting to agni and the user's last name is NOT "Linden", disable voice. | ||
458 | +#define AGNI_LINDENS_ONLY_CHANNEL "SL" | ||
459 | static bool sConnectingToAgni = false; | ||
460 | F32 LLVoiceClient::OVERDRIVEN_POWER_LEVEL = 0.7f; | ||
461 | |||
462 | @@ -95,44 +91,6 @@ const F32 UPDATE_THROTTLE_SECONDS = 0.1f; | ||
463 | const F32 LOGIN_RETRY_SECONDS = 10.0f; | ||
464 | const int MAX_LOGIN_RETRIES = 12; | ||
465 | |||
466 | -static void setUUIDFromStringHash(LLUUID &uuid, const std::string &str) | ||
467 | -{ | ||
468 | - LLMD5 md5_uuid; | ||
469 | - md5_uuid.update((const unsigned char*)str.data(), str.size()); | ||
470 | - md5_uuid.finalize(); | ||
471 | - md5_uuid.raw_digest(uuid.mData); | ||
472 | -} | ||
473 | - | ||
474 | -static int scale_mic_volume(float volume) | ||
475 | -{ | ||
476 | - // incoming volume has the range [0.0 ... 2.0], with 1.0 as the default. | ||
477 | - // Map it as follows: 0.0 -> 40, 1.0 -> 44, 2.0 -> 75 | ||
478 | - | ||
479 | - volume -= 1.0f; // offset volume to the range [-1.0 ... 1.0], with 0 at the default. | ||
480 | - int scaled_volume = 44; // offset scaled_volume by its default level | ||
481 | - if(volume < 0.0f) | ||
482 | - scaled_volume += ((int)(volume * 4.0f)); // (44 - 40) | ||
483 | - else | ||
484 | - scaled_volume += ((int)(volume * 31.0f)); // (75 - 44) | ||
485 | - | ||
486 | - return scaled_volume; | ||
487 | -} | ||
488 | - | ||
489 | -static int scale_speaker_volume(float volume) | ||
490 | -{ | ||
491 | - // incoming volume has the range [0.0 ... 1.0], with 0.5 as the default. | ||
492 | - // Map it as follows: 0.0 -> 0, 0.5 -> 62, 1.0 -> 75 | ||
493 | - | ||
494 | - volume -= 0.5f; // offset volume to the range [-0.5 ... 0.5], with 0 at the default. | ||
495 | - int scaled_volume = 62; // offset scaled_volume by its default level | ||
496 | - if(volume < 0.0f) | ||
497 | - scaled_volume += ((int)(volume * 124.0f)); // (62 - 0) * 2 | ||
498 | - else | ||
499 | - scaled_volume += ((int)(volume * 26.0f)); // (75 - 62) * 2 | ||
500 | - | ||
501 | - return scaled_volume; | ||
502 | -} | ||
503 | - | ||
504 | class LLViewerVoiceAccountProvisionResponder : | ||
505 | public LLHTTPClient::Responder | ||
506 | { | ||
507 | @@ -146,13 +104,12 @@ public: | ||
508 | { | ||
509 | if ( mRetries > 0 ) | ||
510 | { | ||
511 | - LL_WARNS("Voice") << "ProvisionVoiceAccountRequest returned an error, retrying. status = " << status << ", reason = \"" << reason << "\"" << LL_ENDL; | ||
512 | if ( gVoiceClient ) gVoiceClient->requestVoiceAccountProvision( | ||
513 | mRetries - 1); | ||
514 | } | ||
515 | else | ||
516 | { | ||
517 | - LL_WARNS("Voice") << "ProvisionVoiceAccountRequest returned an error, too many retries (giving up). status = " << status << ", reason = \"" << reason << "\"" << LL_ENDL; | ||
518 | + //TODO: throw an error message? | ||
519 | if ( gVoiceClient ) gVoiceClient->giveUp(); | ||
520 | } | ||
521 | } | ||
522 | @@ -161,23 +118,9 @@ public: | ||
523 | { | ||
524 | if ( gVoiceClient ) | ||
525 | { | ||
526 | - std::string voice_sip_uri_hostname; | ||
527 | - std::string voice_account_server_uri; | ||
528 | - | ||
529 | - LL_DEBUGS("Voice") << "ProvisionVoiceAccountRequest response:" << ll_pretty_print_sd(content) << LL_ENDL; | ||
530 | - | ||
531 | - if(content.has("voice_sip_uri_hostname")) | ||
532 | - voice_sip_uri_hostname = content["voice_sip_uri_hostname"].asString(); | ||
533 | - | ||
534 | - // this key is actually misnamed -- it will be an entire URI, not just a hostname. | ||
535 | - if(content.has("voice_account_server_name")) | ||
536 | - voice_account_server_uri = content["voice_account_server_name"].asString(); | ||
537 | - | ||
538 | gVoiceClient->login( | ||
539 | content["username"].asString(), | ||
540 | - content["password"].asString(), | ||
541 | - voice_sip_uri_hostname, | ||
542 | - voice_account_server_uri); | ||
543 | + content["password"].asString()); | ||
544 | } | ||
545 | } | ||
546 | |||
547 | @@ -224,27 +167,21 @@ protected: | ||
548 | int ignoreDepth; | ||
549 | |||
550 | // Members for processing responses. The values are transient and only valid within a call to processResponse(). | ||
551 | - bool squelchDebugOutput; | ||
552 | int returnCode; | ||
553 | int statusCode; | ||
554 | std::string statusString; | ||
555 | - std::string requestId; | ||
556 | + std::string uuidString; | ||
557 | std::string actionString; | ||
558 | std::string connectorHandle; | ||
559 | - std::string versionID; | ||
560 | std::string accountHandle; | ||
561 | std::string sessionHandle; | ||
562 | - std::string sessionGroupHandle; | ||
563 | - std::string alias; | ||
564 | - std::string applicationString; | ||
565 | + std::string eventSessionHandle; | ||
566 | |||
567 | // Members for processing events. The values are transient and only valid within a call to processResponse(). | ||
568 | std::string eventTypeString; | ||
569 | int state; | ||
570 | std::string uriString; | ||
571 | bool isChannel; | ||
572 | - bool incoming; | ||
573 | - bool enabled; | ||
574 | std::string nameString; | ||
575 | std::string audioMediaString; | ||
576 | std::string displayNameString; | ||
577 | @@ -254,21 +191,6 @@ protected: | ||
578 | bool isSpeaking; | ||
579 | int volume; | ||
580 | F32 energy; | ||
581 | - std::string messageHeader; | ||
582 | - std::string messageBody; | ||
583 | - std::string notificationType; | ||
584 | - bool hasText; | ||
585 | - bool hasAudio; | ||
586 | - bool hasVideo; | ||
587 | - bool terminated; | ||
588 | - std::string blockMask; | ||
589 | - std::string presenceOnly; | ||
590 | - std::string autoAcceptMask; | ||
591 | - std::string autoAddAsBuddy; | ||
592 | - int numberOfAliases; | ||
593 | - std::string subscriptionHandle; | ||
594 | - std::string subscriptionType; | ||
595 | - | ||
596 | |||
597 | // Members for processing text between tags | ||
598 | std::string textBuffer; | ||
599 | @@ -301,6 +223,8 @@ void LLVivoxProtocolParser::reset() | ||
600 | responseDepth = 0; | ||
601 | ignoringTags = false; | ||
602 | accumulateText = false; | ||
603 | + textBuffer.clear(); | ||
604 | + | ||
605 | energy = 0.f; | ||
606 | ignoreDepth = 0; | ||
607 | isChannel = false; | ||
608 | @@ -309,15 +233,10 @@ void LLVivoxProtocolParser::reset() | ||
609 | isModeratorMuted = false; | ||
610 | isSpeaking = false; | ||
611 | participantType = 0; | ||
612 | - squelchDebugOutput = false; | ||
613 | - returnCode = -1; | ||
614 | + returnCode = 0; | ||
615 | state = 0; | ||
616 | statusCode = 0; | ||
617 | volume = 0; | ||
618 | - textBuffer.clear(); | ||
619 | - alias.clear(); | ||
620 | - numberOfAliases = 0; | ||
621 | - applicationString.clear(); | ||
622 | } | ||
623 | |||
624 | //virtual | ||
625 | @@ -344,11 +263,33 @@ LLIOPipe::EStatus LLVivoxProtocolParser::process_impl( | ||
626 | mInput.append(buf, istr.gcount()); | ||
627 | } | ||
628 | |||
629 | + // MBW -- XXX -- This should no longer be necessary. Or even possible. | ||
630 | + // We've read all the data out of the buffer. Make sure it doesn't accumulate. | ||
631 | +// buffer->clear(); | ||
632 | + | ||
633 | // Look for input delimiter(s) in the input buffer. If one is found, send the message to the xml parser. | ||
634 | int start = 0; | ||
635 | int delim; | ||
636 | while((delim = mInput.find("\n\n\n", start)) != std::string::npos) | ||
637 | { | ||
638 | + // Turn this on to log incoming XML | ||
639 | + if(0) | ||
640 | + { | ||
641 | + int foo = mInput.find("Set3DPosition", start); | ||
642 | + int bar = mInput.find("ParticipantPropertiesEvent", start); | ||
643 | + if(foo != std::string::npos && (foo < delim)) | ||
644 | + { | ||
645 | + // This is a Set3DPosition response. Don't print it, since these are way too spammy. | ||
646 | + } | ||
647 | + else if(bar != std::string::npos && (bar < delim)) | ||
648 | + { | ||
649 | + // This is a ParticipantPropertiesEvent response. Don't print it, since these are way too spammy. | ||
650 | + } | ||
651 | + else | ||
652 | + { | ||
653 | + LL_INFOS("Voice") << "parsing: " << mInput.substr(start, delim - start) << LL_ENDL; | ||
654 | + } | ||
655 | + } | ||
656 | |||
657 | // Reset internal state of the LLVivoxProtocolParser (no effect on the expat parser) | ||
658 | reset(); | ||
659 | @@ -359,21 +300,15 @@ LLIOPipe::EStatus LLVivoxProtocolParser::process_impl( | ||
660 | XML_SetUserData(parser, this); | ||
661 | XML_Parse(parser, mInput.data() + start, delim - start, false); | ||
662 | |||
663 | - // If this message isn't set to be squelched, output the raw XML received. | ||
664 | - if(!squelchDebugOutput) | ||
665 | - { | ||
666 | - LL_DEBUGS("Voice") << "parsing: " << mInput.substr(start, delim - start) << LL_ENDL; | ||
667 | - } | ||
668 | - | ||
669 | start = delim + 3; | ||
670 | } | ||
671 | |||
672 | if(start != 0) | ||
673 | mInput = mInput.substr(start); | ||
674 | |||
675 | - LL_DEBUGS("VivoxProtocolParser") << "at end, mInput is: " << mInput << LL_ENDL; | ||
676 | - | ||
677 | - if(!gVoiceClient->mConnected) | ||
678 | + LL_DEBUGS("Voice") << "at end, mInput is: " << mInput << LL_ENDL; | ||
679 | + | ||
680 | + if((!gVoiceClient)||((gVoiceClient)&&(!gVoiceClient->mConnected))) | ||
681 | { | ||
682 | // If voice has been disabled, we just want to close the socket. This does so. | ||
683 | LL_INFOS("Voice") << "returning STATUS_STOP" << LL_ENDL; | ||
684 | @@ -426,9 +361,9 @@ void LLVivoxProtocolParser::StartTag(const char *tag, const char **attr) | ||
685 | |||
686 | if (responseDepth == 0) | ||
687 | { | ||
688 | - isEvent = !stricmp("Event", tag); | ||
689 | + isEvent = strcmp("Event", tag) == 0; | ||
690 | |||
691 | - if (!stricmp("Response", tag) || isEvent) | ||
692 | + if (strcmp("Response", tag) == 0 || isEvent) | ||
693 | { | ||
694 | // Grab the attributes | ||
695 | while (*attr) | ||
696 | @@ -436,62 +371,49 @@ void LLVivoxProtocolParser::StartTag(const char *tag, const char **attr) | ||
697 | const char *key = *attr++; | ||
698 | const char *value = *attr++; | ||
699 | |||
700 | - if (!stricmp("requestId", key)) | ||
701 | + if (strcmp("requestId", key) == 0) | ||
702 | { | ||
703 | - requestId = value; | ||
704 | + uuidString = value; | ||
705 | } | ||
706 | - else if (!stricmp("action", key)) | ||
707 | + else if (strcmp("action", key) == 0) | ||
708 | { | ||
709 | actionString = value; | ||
710 | } | ||
711 | - else if (!stricmp("type", key)) | ||
712 | + else if (strcmp("type", key) == 0) | ||
713 | { | ||
714 | eventTypeString = value; | ||
715 | } | ||
716 | } | ||
717 | } | ||
718 | - LL_DEBUGS("VivoxProtocolParser") << tag << " (" << responseDepth << ")" << LL_ENDL; | ||
719 | + LL_DEBUGS("Voice") << tag << " (" << responseDepth << ")" << LL_ENDL; | ||
720 | } | ||
721 | else | ||
722 | { | ||
723 | if (ignoringTags) | ||
724 | { | ||
725 | - LL_DEBUGS("VivoxProtocolParser") << "ignoring tag " << tag << " (depth = " << responseDepth << ")" << LL_ENDL; | ||
726 | + LL_DEBUGS("Voice") << "ignoring tag " << tag << " (depth = " << responseDepth << ")" << LL_ENDL; | ||
727 | } | ||
728 | else | ||
729 | { | ||
730 | - LL_DEBUGS("VivoxProtocolParser") << tag << " (" << responseDepth << ")" << LL_ENDL; | ||
731 | + LL_DEBUGS("Voice") << tag << " (" << responseDepth << ")" << LL_ENDL; | ||
732 | |||
733 | // Ignore the InputXml stuff so we don't get confused | ||
734 | - if (!stricmp("InputXml", tag)) | ||
735 | + if (strcmp("InputXml", tag) == 0) | ||
736 | { | ||
737 | ignoringTags = true; | ||
738 | ignoreDepth = responseDepth; | ||
739 | accumulateText = false; | ||
740 | |||
741 | - LL_DEBUGS("VivoxProtocolParser") << "starting ignore, ignoreDepth is " << ignoreDepth << LL_ENDL; | ||
742 | + LL_DEBUGS("Voice") << "starting ignore, ignoreDepth is " << ignoreDepth << LL_ENDL; | ||
743 | } | ||
744 | - else if (!stricmp("CaptureDevices", tag)) | ||
745 | + else if (strcmp("CaptureDevices", tag) == 0) | ||
746 | { | ||
747 | gVoiceClient->clearCaptureDevices(); | ||
748 | } | ||
749 | - else if (!stricmp("RenderDevices", tag)) | ||
750 | + else if (strcmp("RenderDevices", tag) == 0) | ||
751 | { | ||
752 | gVoiceClient->clearRenderDevices(); | ||
753 | } | ||
754 | - else if (!stricmp("Buddies", tag)) | ||
755 | - { | ||
756 | - gVoiceClient->deleteAllBuddies(); | ||
757 | - } | ||
758 | - else if (!stricmp("BlockRules", tag)) | ||
759 | - { | ||
760 | - gVoiceClient->deleteAllBlockRules(); | ||
761 | - } | ||
762 | - else if (!stricmp("AutoAcceptRules", tag)) | ||
763 | - { | ||
764 | - gVoiceClient->deleteAllAutoAcceptRules(); | ||
765 | - } | ||
766 | - | ||
767 | } | ||
768 | } | ||
769 | responseDepth++; | ||
770 | @@ -510,138 +432,90 @@ void LLVivoxProtocolParser::EndTag(const char *tag) | ||
771 | { | ||
772 | if (ignoreDepth == responseDepth) | ||
773 | { | ||
774 | - LL_DEBUGS("VivoxProtocolParser") << "end of ignore" << LL_ENDL; | ||
775 | + LL_DEBUGS("Voice") << "end of ignore" << LL_ENDL; | ||
776 | ignoringTags = false; | ||
777 | } | ||
778 | else | ||
779 | { | ||
780 | - LL_DEBUGS("VivoxProtocolParser") << "ignoring tag " << tag << " (depth = " << responseDepth << ")" << LL_ENDL; | ||
781 | + LL_DEBUGS("Voice") << "ignoring tag " << tag << " (depth = " << responseDepth << ")" << LL_ENDL; | ||
782 | } | ||
783 | } | ||
784 | |||
785 | if (!ignoringTags) | ||
786 | { | ||
787 | - LL_DEBUGS("VivoxProtocolParser") << "processing tag " << tag << " (depth = " << responseDepth << ")" << LL_ENDL; | ||
788 | + LL_DEBUGS("Voice") << "processing tag " << tag << " (depth = " << responseDepth << ")" << LL_ENDL; | ||
789 | |||
790 | // Closing a tag. Finalize the text we've accumulated and reset | ||
791 | - if (!stricmp("ReturnCode", tag)) | ||
792 | + if (strcmp("ReturnCode", tag) == 0) | ||
793 | returnCode = strtol(string.c_str(), NULL, 10); | ||
794 | - else if (!stricmp("SessionHandle", tag)) | ||
795 | - sessionHandle = string; | ||
796 | - else if (!stricmp("SessionGroupHandle", tag)) | ||
797 | - sessionGroupHandle = string; | ||
798 | - else if (!stricmp("StatusCode", tag)) | ||
799 | + else if (strcmp("StatusCode", tag) == 0) | ||
800 | statusCode = strtol(string.c_str(), NULL, 10); | ||
801 | - else if (!stricmp("StatusString", tag)) | ||
802 | - statusString = string; | ||
803 | - else if (!stricmp("ParticipantURI", tag)) | ||
804 | - uriString = string; | ||
805 | - else if (!stricmp("Volume", tag)) | ||
806 | - volume = strtol(string.c_str(), NULL, 10); | ||
807 | - else if (!stricmp("Energy", tag)) | ||
808 | - energy = (F32)strtod(string.c_str(), NULL); | ||
809 | - else if (!stricmp("IsModeratorMuted", tag)) | ||
810 | - isModeratorMuted = !stricmp(string.c_str(), "true"); | ||
811 | - else if (!stricmp("IsSpeaking", tag)) | ||
812 | - isSpeaking = !stricmp(string.c_str(), "true"); | ||
813 | - else if (!stricmp("Alias", tag)) | ||
814 | - alias = string; | ||
815 | - else if (!stricmp("NumberOfAliases", tag)) | ||
816 | - numberOfAliases = strtol(string.c_str(), NULL, 10); | ||
817 | - else if (!stricmp("Application", tag)) | ||
818 | - applicationString = string; | ||
819 | - else if (!stricmp("ConnectorHandle", tag)) | ||
820 | + else if (strcmp("ConnectorHandle", tag) == 0) | ||
821 | connectorHandle = string; | ||
822 | - else if (!stricmp("VersionID", tag)) | ||
823 | - versionID = string; | ||
824 | - else if (!stricmp("AccountHandle", tag)) | ||
825 | + else if (strcmp("AccountHandle", tag) == 0) | ||
826 | accountHandle = string; | ||
827 | - else if (!stricmp("State", tag)) | ||
828 | + else if (strcmp("SessionHandle", tag) == 0) | ||
829 | + { | ||
830 | + if (isEvent) | ||
831 | + eventSessionHandle = string; | ||
832 | + else | ||
833 | + sessionHandle = string; | ||
834 | + } | ||
835 | + else if (strcmp("StatusString", tag) == 0) | ||
836 | + statusString = string; | ||
837 | + else if (strcmp("State", tag) == 0) | ||
838 | state = strtol(string.c_str(), NULL, 10); | ||
839 | - else if (!stricmp("URI", tag)) | ||
840 | + else if (strcmp("URI", tag) == 0) | ||
841 | uriString = string; | ||
842 | - else if (!stricmp("IsChannel", tag)) | ||
843 | - isChannel = !stricmp(string.c_str(), "true"); | ||
844 | - else if (!stricmp("Incoming", tag)) | ||
845 | - incoming = !stricmp(string.c_str(), "true"); | ||
846 | - else if (!stricmp("Enabled", tag)) | ||
847 | - enabled = !stricmp(string.c_str(), "true"); | ||
848 | - else if (!stricmp("Name", tag)) | ||
849 | + else if (strcmp("IsChannel", tag) == 0) | ||
850 | + isChannel = string == "true" ? true : false; | ||
851 | + else if (strcmp("Name", tag) == 0) | ||
852 | nameString = string; | ||
853 | - else if (!stricmp("AudioMedia", tag)) | ||
854 | + else if (strcmp("AudioMedia", tag) == 0) | ||
855 | audioMediaString = string; | ||
856 | - else if (!stricmp("ChannelName", tag)) | ||
857 | + else if (strcmp("ChannelName", tag) == 0) | ||
858 | nameString = string; | ||
859 | - else if (!stricmp("DisplayName", tag)) | ||
860 | + else if (strcmp("ParticipantURI", tag) == 0) | ||
861 | + uriString = string; | ||
862 | + else if (strcmp("DisplayName", tag) == 0) | ||
863 | displayNameString = string; | ||
864 | - else if (!stricmp("AccountName", tag)) | ||
865 | + else if (strcmp("AccountName", tag) == 0) | ||
866 | nameString = string; | ||
867 | - else if (!stricmp("ParticipantType", tag)) | ||
868 | + else if (strcmp("ParticipantTyppe", tag) == 0) | ||
869 | participantType = strtol(string.c_str(), NULL, 10); | ||
870 | - else if (!stricmp("IsLocallyMuted", tag)) | ||
871 | - isLocallyMuted = !stricmp(string.c_str(), "true"); | ||
872 | - else if (!stricmp("MicEnergy", tag)) | ||
873 | + else if (strcmp("IsLocallyMuted", tag) == 0) | ||
874 | + isLocallyMuted = string == "true" ? true : false; | ||
875 | + else if (strcmp("IsModeratorMuted", tag) == 0) | ||
876 | + isModeratorMuted = string == "true" ? true : false; | ||
877 | + else if (strcmp("IsSpeaking", tag) == 0) | ||
878 | + isSpeaking = string == "true" ? true : false; | ||
879 | + else if (strcmp("Volume", tag) == 0) | ||
880 | + volume = strtol(string.c_str(), NULL, 10); | ||
881 | + else if (strcmp("Energy", tag) == 0) | ||
882 | energy = (F32)strtod(string.c_str(), NULL); | ||
883 | - else if (!stricmp("ChannelName", tag)) | ||
884 | + else if (strcmp("MicEnergy", tag) == 0) | ||
885 | + energy = (F32)strtod(string.c_str(), NULL); | ||
886 | + else if (strcmp("ChannelName", tag) == 0) | ||
887 | nameString = string; | ||
888 | - else if (!stricmp("ChannelURI", tag)) | ||
889 | - uriString = string; | ||
890 | - else if (!stricmp("BuddyURI", tag)) | ||
891 | + else if (strcmp("ChannelURI", tag) == 0) | ||
892 | uriString = string; | ||
893 | - else if (!stricmp("Presence", tag)) | ||
894 | - statusString = string; | ||
895 | - else if (!stricmp("Device", tag)) | ||
896 | + else if (strcmp("ChannelListResult", tag) == 0) | ||
897 | + { | ||
898 | + gVoiceClient->addChannelMapEntry(nameString, uriString); | ||
899 | + } | ||
900 | + else if (strcmp("Device", tag) == 0) | ||
901 | { | ||
902 | // This closing tag shouldn't clear the accumulated text. | ||
903 | clearbuffer = false; | ||
904 | } | ||
905 | - else if (!stricmp("CaptureDevice", tag)) | ||
906 | + else if (strcmp("CaptureDevice", tag) == 0) | ||
907 | { | ||
908 | gVoiceClient->addCaptureDevice(textBuffer); | ||
909 | } | ||
910 | - else if (!stricmp("RenderDevice", tag)) | ||
911 | + else if (strcmp("RenderDevice", tag) == 0) | ||
912 | { | ||
913 | gVoiceClient->addRenderDevice(textBuffer); | ||
914 | } | ||
915 | - else if (!stricmp("Buddy", tag)) | ||
916 | - { | ||
917 | - gVoiceClient->processBuddyListEntry(uriString, displayNameString); | ||
918 | - } | ||
919 | - else if (!stricmp("BlockRule", tag)) | ||
920 | - { | ||
921 | - gVoiceClient->addBlockRule(blockMask, presenceOnly); | ||
922 | - } | ||
923 | - else if (!stricmp("BlockMask", tag)) | ||
924 | - blockMask = string; | ||
925 | - else if (!stricmp("PresenceOnly", tag)) | ||
926 | - presenceOnly = string; | ||
927 | - else if (!stricmp("AutoAcceptRule", tag)) | ||
928 | - { | ||
929 | - gVoiceClient->addAutoAcceptRule(autoAcceptMask, autoAddAsBuddy); | ||
930 | - } | ||
931 | - else if (!stricmp("AutoAcceptMask", tag)) | ||
932 | - autoAcceptMask = string; | ||
933 | - else if (!stricmp("AutoAddAsBuddy", tag)) | ||
934 | - autoAddAsBuddy = string; | ||
935 | - else if (!stricmp("MessageHeader", tag)) | ||
936 | - messageHeader = string; | ||
937 | - else if (!stricmp("MessageBody", tag)) | ||
938 | - messageBody = string; | ||
939 | - else if (!stricmp("NotificationType", tag)) | ||
940 | - notificationType = string; | ||
941 | - else if (!stricmp("HasText", tag)) | ||
942 | - hasText = !stricmp(string.c_str(), "true"); | ||
943 | - else if (!stricmp("HasAudio", tag)) | ||
944 | - hasAudio = !stricmp(string.c_str(), "true"); | ||
945 | - else if (!stricmp("HasVideo", tag)) | ||
946 | - hasVideo = !stricmp(string.c_str(), "true"); | ||
947 | - else if (!stricmp("Terminated", tag)) | ||
948 | - terminated = !stricmp(string.c_str(), "true"); | ||
949 | - else if (!stricmp("SubscriptionHandle", tag)) | ||
950 | - subscriptionHandle = string; | ||
951 | - else if (!stricmp("SubscriptionType", tag)) | ||
952 | - subscriptionType = string; | ||
953 | - | ||
954 | |||
955 | if(clearbuffer) | ||
956 | { | ||
957 | @@ -676,296 +550,147 @@ void LLVivoxProtocolParser::CharData(const char *buffer, int length) | ||
958 | |||
959 | void LLVivoxProtocolParser::processResponse(std::string tag) | ||
960 | { | ||
961 | - LL_DEBUGS("VivoxProtocolParser") << tag << LL_ENDL; | ||
962 | + LL_DEBUGS("Voice") << tag << LL_ENDL; | ||
963 | + | ||
964 | + if (!gVoiceClient) | ||
965 | + return; | ||
966 | |||
967 | - // SLIM SDK: the SDK now returns a statusCode of "200" (OK) for success. This is a change vs. previous SDKs. | ||
968 | - // According to Mike S., "The actual API convention is that responses with return codes of 0 are successful, regardless of the status code returned", | ||
969 | - // so I believe this will give correct behavior. | ||
970 | - | ||
971 | - if(returnCode == 0) | ||
972 | - statusCode = 0; | ||
973 | - | ||
974 | if (isEvent) | ||
975 | { | ||
976 | - const char *eventTypeCstr = eventTypeString.c_str(); | ||
977 | - if (!stricmp(eventTypeCstr, "AccountLoginStateChangeEvent")) | ||
978 | + if (eventTypeString == "LoginStateChangeEvent") | ||
979 | { | ||
980 | - gVoiceClient->accountLoginStateChangeEvent(accountHandle, statusCode, statusString, state); | ||
981 | + gVoiceClient->loginStateChangeEvent(accountHandle, statusCode, statusString, state); | ||
982 | } | ||
983 | - else if (!stricmp(eventTypeCstr, "SessionAddedEvent")) | ||
984 | - { | ||
985 | - /* | ||
986 | - <Event type="SessionAddedEvent"> | ||
987 | - <SessionGroupHandle>c1_m1000xFnPP04IpREWNkuw1cOXlhw==_sg0</SessionGroupHandle> | ||
988 | - <SessionHandle>c1_m1000xFnPP04IpREWNkuw1cOXlhw==0</SessionHandle> | ||
989 | - <Uri>sip:confctl-1408789@bhr.vivox.com</Uri> | ||
990 | - <IsChannel>true</IsChannel> | ||
991 | - <Incoming>false</Incoming> | ||
992 | - <ChannelName /> | ||
993 | - </Event> | ||
994 | - */ | ||
995 | - gVoiceClient->sessionAddedEvent(uriString, alias, sessionHandle, sessionGroupHandle, isChannel, incoming, nameString, applicationString); | ||
996 | - } | ||
997 | - else if (!stricmp(eventTypeCstr, "SessionRemovedEvent")) | ||
998 | - { | ||
999 | - gVoiceClient->sessionRemovedEvent(sessionHandle, sessionGroupHandle); | ||
1000 | - } | ||
1001 | - else if (!stricmp(eventTypeCstr, "SessionGroupAddedEvent")) | ||
1002 | - { | ||
1003 | - gVoiceClient->sessionGroupAddedEvent(sessionGroupHandle); | ||
1004 | - } | ||
1005 | - else if (!stricmp(eventTypeCstr, "MediaStreamUpdatedEvent")) | ||
1006 | - { | ||
1007 | - /* | ||
1008 | - <Event type="MediaStreamUpdatedEvent"> | ||
1009 | - <SessionGroupHandle>c1_m1000xFnPP04IpREWNkuw1cOXlhw==_sg0</SessionGroupHandle> | ||
1010 | - <SessionHandle>c1_m1000xFnPP04IpREWNkuw1cOXlhw==0</SessionHandle> | ||
1011 | - <StatusCode>200</StatusCode> | ||
1012 | - <StatusString>OK</StatusString> | ||
1013 | - <State>2</State> | ||
1014 | - <Incoming>false</Incoming> | ||
1015 | - </Event> | ||
1016 | - */ | ||
1017 | - gVoiceClient->mediaStreamUpdatedEvent(sessionHandle, sessionGroupHandle, statusCode, statusString, state, incoming); | ||
1018 | - } | ||
1019 | - else if (!stricmp(eventTypeCstr, "TextStreamUpdatedEvent")) | ||
1020 | + else if (eventTypeString == "SessionNewEvent") | ||
1021 | { | ||
1022 | - /* | ||
1023 | - <Event type="TextStreamUpdatedEvent"> | ||
1024 | - <SessionGroupHandle>c1_m1000xFnPP04IpREWNkuw1cOXlhw==_sg1</SessionGroupHandle> | ||
1025 | - <SessionHandle>c1_m1000xFnPP04IpREWNkuw1cOXlhw==1</SessionHandle> | ||
1026 | - <Enabled>true</Enabled> | ||
1027 | - <State>1</State> | ||
1028 | - <Incoming>true</Incoming> | ||
1029 | - </Event> | ||
1030 | - */ | ||
1031 | - gVoiceClient->textStreamUpdatedEvent(sessionHandle, sessionGroupHandle, enabled, state, incoming); | ||
1032 | + gVoiceClient->sessionNewEvent(accountHandle, eventSessionHandle, state, nameString, uriString); | ||
1033 | } | ||
1034 | - else if (!stricmp(eventTypeCstr, "ParticipantAddedEvent")) | ||
1035 | + else if (eventTypeString == "SessionStateChangeEvent") | ||
1036 | { | ||
1037 | - /* | ||
1038 | - <Event type="ParticipantAddedEvent"> | ||
1039 | - <SessionGroupHandle>c1_m1000xFnPP04IpREWNkuw1cOXlhw==_sg4</SessionGroupHandle> | ||
1040 | - <SessionHandle>c1_m1000xFnPP04IpREWNkuw1cOXlhw==4</SessionHandle> | ||
1041 | - <ParticipantUri>sip:xI5auBZ60SJWIk606-1JGRQ==@bhr.vivox.com</ParticipantUri> | ||
1042 | - <AccountName>xI5auBZ60SJWIk606-1JGRQ==</AccountName> | ||
1043 | - <DisplayName /> | ||
1044 | - <ParticipantType>0</ParticipantType> | ||
1045 | - </Event> | ||
1046 | - */ | ||
1047 | - gVoiceClient->participantAddedEvent(sessionHandle, sessionGroupHandle, uriString, alias, nameString, displayNameString, participantType); | ||
1048 | + gVoiceClient->sessionStateChangeEvent(uriString, statusCode, statusString, eventSessionHandle, state, isChannel, nameString); | ||
1049 | } | ||
1050 | - else if (!stricmp(eventTypeCstr, "ParticipantRemovedEvent")) | ||
1051 | + else if (eventTypeString == "ParticipantStateChangeEvent") | ||
1052 | { | ||
1053 | - /* | ||
1054 | - <Event type="ParticipantRemovedEvent"> | ||
1055 | - <SessionGroupHandle>c1_m1000xFnPP04IpREWNkuw1cOXlhw==_sg4</SessionGroupHandle> | ||
1056 | - <SessionHandle>c1_m1000xFnPP04IpREWNkuw1cOXlhw==4</SessionHandle> | ||
1057 | - <ParticipantUri>sip:xtx7YNV-3SGiG7rA1fo5Ndw==@bhr.vivox.com</ParticipantUri> | ||
1058 | - <AccountName>xtx7YNV-3SGiG7rA1fo5Ndw==</AccountName> | ||
1059 | - </Event> | ||
1060 | - */ | ||
1061 | - gVoiceClient->participantRemovedEvent(sessionHandle, sessionGroupHandle, uriString, alias, nameString); | ||
1062 | - } | ||
1063 | - else if (!stricmp(eventTypeCstr, "ParticipantUpdatedEvent")) | ||
1064 | - { | ||
1065 | - /* | ||
1066 | - <Event type="ParticipantUpdatedEvent"> | ||
1067 | - <SessionGroupHandle>c1_m1000xFnPP04IpREWNkuw1cOXlhw==_sg0</SessionGroupHandle> | ||
1068 | - <SessionHandle>c1_m1000xFnPP04IpREWNkuw1cOXlhw==0</SessionHandle> | ||
1069 | - <ParticipantUri>sip:xFnPP04IpREWNkuw1cOXlhw==@bhr.vivox.com</ParticipantUri> | ||
1070 | - <IsModeratorMuted>false</IsModeratorMuted> | ||
1071 | - <IsSpeaking>true</IsSpeaking> | ||
1072 | - <Volume>44</Volume> | ||
1073 | - <Energy>0.0879437</Energy> | ||
1074 | - </Event> | ||
1075 | - */ | ||
1076 | + gVoiceClient->participantStateChangeEvent(uriString, statusCode, statusString, state, nameString, displayNameString, participantType); | ||
1077 | |||
1078 | - // These happen so often that logging them is pretty useless. | ||
1079 | - squelchDebugOutput = true; | ||
1080 | - | ||
1081 | - gVoiceClient->participantUpdatedEvent(sessionHandle, sessionGroupHandle, uriString, alias, isModeratorMuted, isSpeaking, volume, energy); | ||
1082 | - } | ||
1083 | - else if (!stricmp(eventTypeCstr, "AuxAudioPropertiesEvent")) | ||
1084 | - { | ||
1085 | - gVoiceClient->auxAudioPropertiesEvent(energy); | ||
1086 | - } | ||
1087 | - else if (!stricmp(eventTypeCstr, "BuddyPresenceEvent")) | ||
1088 | - { | ||
1089 | - gVoiceClient->buddyPresenceEvent(uriString, alias, statusString, applicationString); | ||
1090 | - } | ||
1091 | - else if (!stricmp(eventTypeCstr, "BuddyAndGroupListChangedEvent")) | ||
1092 | - { | ||
1093 | - // The buddy list was updated during parsing. | ||
1094 | - // Need to recheck against the friends list. | ||
1095 | - gVoiceClient->buddyListChanged(); | ||
1096 | - } | ||
1097 | - else if (!stricmp(eventTypeCstr, "BuddyChangedEvent")) | ||
1098 | - { | ||
1099 | - /* | ||
1100 | - <Event type="BuddyChangedEvent"> | ||
1101 | - <AccountHandle>c1_m1000xFnPP04IpREWNkuw1cOXlhw==</AccountHandle> | ||
1102 | - <BuddyURI>sip:x9fFHFZjOTN6OESF1DUPrZQ==@bhr.vivox.com</BuddyURI> | ||
1103 | - <DisplayName>Monroe Tester</DisplayName> | ||
1104 | - <BuddyData /> | ||
1105 | - <GroupID>0</GroupID> | ||
1106 | - <ChangeType>Set</ChangeType> | ||
1107 | - </Event> | ||
1108 | - */ | ||
1109 | - // TODO: Question: Do we need to process this at all? | ||
1110 | - } | ||
1111 | - else if (!stricmp(eventTypeCstr, "MessageEvent")) | ||
1112 | - { | ||
1113 | - gVoiceClient->messageEvent(sessionHandle, uriString, alias, messageHeader, messageBody, applicationString); | ||
1114 | } | ||
1115 | - else if (!stricmp(eventTypeCstr, "SessionNotificationEvent")) | ||
1116 | + else if (eventTypeString == "ParticipantPropertiesEvent") | ||
1117 | { | ||
1118 | - gVoiceClient->sessionNotificationEvent(sessionHandle, uriString, notificationType); | ||
1119 | + gVoiceClient->participantPropertiesEvent(uriString, statusCode, statusString, isLocallyMuted, isModeratorMuted, isSpeaking, volume, energy); | ||
1120 | } | ||
1121 | - else if (!stricmp(eventTypeCstr, "SubscriptionEvent")) | ||
1122 | + else if (eventTypeString == "AuxAudioPropertiesEvent") | ||
1123 | { | ||
1124 | - gVoiceClient->subscriptionEvent(uriString, subscriptionHandle, alias, displayNameString, applicationString, subscriptionType); | ||
1125 | - } | ||
1126 | - else if (!stricmp(eventTypeCstr, "SessionUpdatedEvent")) | ||
1127 | - { | ||
1128 | - /* | ||
1129 | - <Event type="SessionUpdatedEvent"> | ||
1130 | - <SessionGroupHandle>c1_m1000xFnPP04IpREWNkuw1cOXlhw==_sg0</SessionGroupHandle> | ||
1131 | - <SessionHandle>c1_m1000xFnPP04IpREWNkuw1cOXlhw==0</SessionHandle> | ||
1132 | - <Uri>sip:confctl-9@bhd.vivox.com</Uri> | ||
1133 | - <IsMuted>0</IsMuted> | ||
1134 | - <Volume>50</Volume> | ||
1135 | - <TransmitEnabled>1</TransmitEnabled> | ||
1136 | - <IsFocused>0</IsFocused> | ||
1137 | - <SpeakerPosition><Position><X>0</X><Y>0</Y><Z>0</Z></Position></SpeakerPosition> | ||
1138 | - <SessionFontID>0</SessionFontID> | ||
1139 | - </Event> | ||
1140 | - */ | ||
1141 | - // We don't need to process this, but we also shouldn't warn on it, since that confuses people. | ||
1142 | - } | ||
1143 | - else | ||
1144 | - { | ||
1145 | - LL_WARNS("VivoxProtocolParser") << "Unknown event type " << eventTypeString << LL_ENDL; | ||
1146 | + gVoiceClient->auxAudioPropertiesEvent(energy); | ||
1147 | } | ||
1148 | } | ||
1149 | else | ||
1150 | { | ||
1151 | - const char *actionCstr = actionString.c_str(); | ||
1152 | - if (!stricmp(actionCstr, "Connector.Create.1")) | ||
1153 | + if (actionString == "Connector.Create.1") | ||
1154 | { | ||
1155 | - gVoiceClient->connectorCreateResponse(statusCode, statusString, connectorHandle, versionID); | ||
1156 | + gVoiceClient->connectorCreateResponse(statusCode, statusString, connectorHandle); | ||
1157 | } | ||
1158 | - else if (!stricmp(actionCstr, "Account.Login.1")) | ||
1159 | + else if (actionString == "Account.Login.1") | ||
1160 | { | ||
1161 | - gVoiceClient->loginResponse(statusCode, statusString, accountHandle, numberOfAliases); | ||
1162 | + gVoiceClient->loginResponse(statusCode, statusString, accountHandle); | ||
1163 | } | ||
1164 | - else if (!stricmp(actionCstr, "Session.Create.1")) | ||
1165 | + else if (actionString == "Session.Create.1") | ||
1166 | { | ||
1167 | - gVoiceClient->sessionCreateResponse(requestId, statusCode, statusString, sessionHandle); | ||
1168 | + gVoiceClient->sessionCreateResponse(statusCode, statusString, sessionHandle); | ||
1169 | } | ||
1170 | - else if (!stricmp(actionCstr, "SessionGroup.AddSession.1")) | ||
1171 | + else if (actionString == "Session.Connect.1") | ||
1172 | { | ||
1173 | - gVoiceClient->sessionGroupAddSessionResponse(requestId, statusCode, statusString, sessionHandle); | ||
1174 | + gVoiceClient->sessionConnectResponse(statusCode, statusString); | ||
1175 | } | ||
1176 | - else if (!stricmp(actionCstr, "Session.Connect.1")) | ||
1177 | + else if (actionString == "Session.Terminate.1") | ||
1178 | { | ||
1179 | - gVoiceClient->sessionConnectResponse(requestId, statusCode, statusString); | ||
1180 | + gVoiceClient->sessionTerminateResponse(statusCode, statusString); | ||
1181 | } | ||
1182 | - else if (!stricmp(actionCstr, "Account.Logout.1")) | ||
1183 | + else if (actionString == "Account.Logout.1") | ||
1184 | { | ||
1185 | gVoiceClient->logoutResponse(statusCode, statusString); | ||
1186 | } | ||
1187 | - else if (!stricmp(actionCstr, "Connector.InitiateShutdown.1")) | ||
1188 | + else if (actionString == "Connector.InitiateShutdown.1") | ||
1189 | { | ||
1190 | gVoiceClient->connectorShutdownResponse(statusCode, statusString); | ||
1191 | } | ||
1192 | - else if (!stricmp(actionCstr, "Account.ListBlockRules.1")) | ||
1193 | - { | ||
1194 | - gVoiceClient->accountListBlockRulesResponse(statusCode, statusString); | ||
1195 | - } | ||
1196 | - else if (!stricmp(actionCstr, "Account.ListAutoAcceptRules.1")) | ||
1197 | - { | ||
1198 | - gVoiceClient->accountListAutoAcceptRulesResponse(statusCode, statusString); | ||
1199 | - } | ||
1200 | - else if (!stricmp(actionCstr, "Session.Set3DPosition.1")) | ||
1201 | + else if (actionString == "Account.ChannelGetList.1") | ||
1202 | { | ||
1203 | - // We don't need to process these, but they're so spammy we don't want to log them. | ||
1204 | - squelchDebugOutput = true; | ||
1205 | + gVoiceClient->channelGetListResponse(statusCode, statusString); | ||
1206 | } | ||
1207 | /* | ||
1208 | - else if (!stricmp(actionCstr, "Account.ChannelGetList.1")) | ||
1209 | + else if (actionString == "Connector.AccountCreate.1") | ||
1210 | { | ||
1211 | - gVoiceClient->channelGetListResponse(statusCode, statusString); | ||
1212 | + | ||
1213 | } | ||
1214 | - else if (!stricmp(actionCstr, "Connector.AccountCreate.1")) | ||
1215 | + else if (actionString == "Connector.MuteLocalMic.1") | ||
1216 | { | ||
1217 | |||
1218 | } | ||
1219 | - else if (!stricmp(actionCstr, "Connector.MuteLocalMic.1")) | ||
1220 | + else if (actionString == "Connector.MuteLocalSpeaker.1") | ||
1221 | { | ||
1222 | |||
1223 | } | ||
1224 | - else if (!stricmp(actionCstr, "Connector.MuteLocalSpeaker.1")) | ||
1225 | + else if (actionString == "Connector.SetLocalMicVolume.1") | ||
1226 | { | ||
1227 | |||
1228 | } | ||
1229 | - else if (!stricmp(actionCstr, "Connector.SetLocalMicVolume.1")) | ||
1230 | + else if (actionString == "Connector.SetLocalSpeakerVolume.1") | ||
1231 | { | ||
1232 | |||
1233 | } | ||
1234 | - else if (!stricmp(actionCstr, "Connector.SetLocalSpeakerVolume.1")) | ||
1235 | + else if (actionString == "Session.ListenerSetPosition.1") | ||
1236 | { | ||
1237 | |||
1238 | } | ||
1239 | - else if (!stricmp(actionCstr, "Session.ListenerSetPosition.1")) | ||
1240 | + else if (actionString == "Session.SpeakerSetPosition.1") | ||
1241 | { | ||
1242 | |||
1243 | } | ||
1244 | - else if (!stricmp(actionCstr, "Session.SpeakerSetPosition.1")) | ||
1245 | + else if (actionString == "Session.Set3DPosition.1") | ||
1246 | { | ||
1247 | |||
1248 | } | ||
1249 | - else if (!stricmp(actionCstr, "Session.AudioSourceSetPosition.1")) | ||
1250 | + else if (actionString == "Session.AudioSourceSetPosition.1") | ||
1251 | { | ||
1252 | |||
1253 | } | ||
1254 | - else if (!stricmp(actionCstr, "Session.GetChannelParticipants.1")) | ||
1255 | + else if (actionString == "Session.GetChannelParticipants.1") | ||
1256 | { | ||
1257 | |||
1258 | } | ||
1259 | - else if (!stricmp(actionCstr, "Account.ChannelCreate.1")) | ||
1260 | + else if (actionString == "Account.ChannelCreate.1") | ||
1261 | { | ||
1262 | |||
1263 | } | ||
1264 | - else if (!stricmp(actionCstr, "Account.ChannelUpdate.1")) | ||
1265 | + else if (actionString == "Account.ChannelUpdate.1") | ||
1266 | { | ||
1267 | |||
1268 | } | ||
1269 | - else if (!stricmp(actionCstr, "Account.ChannelDelete.1")) | ||
1270 | + else if (actionString == "Account.ChannelDelete.1") | ||
1271 | { | ||
1272 | |||
1273 | } | ||
1274 | - else if (!stricmp(actionCstr, "Account.ChannelCreateAndInvite.1")) | ||
1275 | + else if (actionString == "Account.ChannelCreateAndInvite.1") | ||
1276 | { | ||
1277 | |||
1278 | } | ||
1279 | - else if (!stricmp(actionCstr, "Account.ChannelFolderCreate.1")) | ||
1280 | + else if (actionString == "Account.ChannelFolderCreate.1") | ||
1281 | { | ||
1282 | |||
1283 | } | ||
1284 | - else if (!stricmp(actionCstr, "Account.ChannelFolderUpdate.1")) | ||
1285 | + else if (actionString == "Account.ChannelFolderUpdate.1") | ||
1286 | { | ||
1287 | |||
1288 | } | ||
1289 | - else if (!stricmp(actionCstr, "Account.ChannelFolderDelete.1")) | ||
1290 | + else if (actionString == "Account.ChannelFolderDelete.1") | ||
1291 | { | ||
1292 | |||
1293 | } | ||
1294 | - else if (!stricmp(actionCstr, "Account.ChannelAddModerator.1")) | ||
1295 | + else if (actionString == "Account.ChannelAddModerator.1") | ||
1296 | { | ||
1297 | |||
1298 | } | ||
1299 | - else if (!stricmp(actionCstr, "Account.ChannelDeleteModerator.1")) | ||
1300 | + else if (actionString == "Account.ChannelDeleteModerator.1") | ||
1301 | { | ||
1302 | |||
1303 | } | ||
1304 | @@ -979,18 +704,9 @@ class LLVoiceClientMuteListObserver : public LLMuteListObserver | ||
1305 | { | ||
1306 | /* virtual */ void onChange() { gVoiceClient->muteListChanged();} | ||
1307 | }; | ||
1308 | - | ||
1309 | -class LLVoiceClientFriendsObserver : public LLFriendObserver | ||
1310 | -{ | ||
1311 | -public: | ||
1312 | - /* virtual */ void changed(U32 mask) { gVoiceClient->updateFriends(mask);} | ||
1313 | -}; | ||
1314 | - | ||
1315 | static LLVoiceClientMuteListObserver mutelist_listener; | ||
1316 | static bool sMuteListListener_listening = false; | ||
1317 | |||
1318 | -static LLVoiceClientFriendsObserver *friendslist_listener = NULL; | ||
1319 | - | ||
1320 | /////////////////////////////////////////////////////////////////////////////////////////////// | ||
1321 | |||
1322 | class LLVoiceClientCapResponder : public LLHTTPClient::Responder | ||
1323 | @@ -1014,8 +730,11 @@ void LLVoiceClientCapResponder::error(U32 status, const std::string& reason) | ||
1324 | void LLVoiceClientCapResponder::result(const LLSD& content) | ||
1325 | { | ||
1326 | LLSD::map_const_iterator iter; | ||
1327 | - | ||
1328 | - LL_DEBUGS("Voice") << "ParcelVoiceInfoRequest response:" << ll_pretty_print_sd(content) << LL_ENDL; | ||
1329 | + for(iter = content.beginMap(); iter != content.endMap(); ++iter) | ||
1330 | + { | ||
1331 | + LL_DEBUGS("Voice") << "LLVoiceClientCapResponder::result got " | ||
1332 | + << iter->first << LL_ENDL; | ||
1333 | + } | ||
1334 | |||
1335 | if ( content.has("voice_credentials") ) | ||
1336 | { | ||
1337 | @@ -1101,26 +820,26 @@ LLVoiceClient::LLVoiceClient() | ||
1338 | mUserPTTState = false; | ||
1339 | mMuteMic = false; | ||
1340 | mSessionTerminateRequested = false; | ||
1341 | - mRelogRequested = false; | ||
1342 | mCommandCookie = 0; | ||
1343 | + mNonSpatialChannel = false; | ||
1344 | + mNextSessionSpatial = true; | ||
1345 | + mNextSessionNoReconnect = false; | ||
1346 | + mSessionP2P = false; | ||
1347 | mCurrentParcelLocalID = 0; | ||
1348 | mLoginRetryCount = 0; | ||
1349 | + mVivoxErrorStatusCode = 0; | ||
1350 | |||
1351 | + mNextSessionResetOnClose = false; | ||
1352 | + mSessionResetOnClose = false; | ||
1353 | mSpeakerVolume = 0; | ||
1354 | mMicVolume = 0; | ||
1355 | |||
1356 | - mAudioSession = NULL; | ||
1357 | - mAudioSessionChanged = false; | ||
1358 | - | ||
1359 | // Initial dirty state | ||
1360 | mSpatialCoordsDirty = false; | ||
1361 | mPTTDirty = true; | ||
1362 | - mFriendsListDirty = true; | ||
1363 | + mVolumeDirty = true; | ||
1364 | mSpeakerVolumeDirty = true; | ||
1365 | mMicVolumeDirty = true; | ||
1366 | - mBuddyListMapPopulated = false; | ||
1367 | - mBlockRulesListReceived = false; | ||
1368 | - mAutoAcceptRulesListReceived = false; | ||
1369 | mCaptureDeviceDirty = false; | ||
1370 | mRenderDeviceDirty = false; | ||
1371 | |||
1372 | @@ -1141,12 +860,14 @@ LLVoiceClient::LLVoiceClient() | ||
1373 | // gMuteListp isn't set up at this point, so we defer this until later. | ||
1374 | // gMuteListp->addObserver(&mutelist_listener); | ||
1375 | |||
1376 | + mParticipantMapChanged = false; | ||
1377 | + | ||
1378 | // stash the pump for later use | ||
1379 | // This now happens when init() is called instead. | ||
1380 | mPump = NULL; | ||
1381 | |||
1382 | #if LL_DARWIN || LL_LINUX | ||
1383 | - // HACK: THIS DOES NOT BELONG HERE | ||
1384 | + // MBW -- XXX -- THIS DOES NOT BELONG HERE | ||
1385 | // When the vivox daemon dies, the next write attempt on our socket generates a SIGPIPE, which kills us. | ||
1386 | // This should cause us to ignore SIGPIPE and handle the error through proper channels. | ||
1387 | // This should really be set up elsewhere. Where should it go? | ||
1388 | @@ -1182,10 +903,8 @@ void LLVoiceClient::terminate() | ||
1389 | { | ||
1390 | if(gVoiceClient) | ||
1391 | { | ||
1392 | -// gVoiceClient->leaveAudioSession(); | ||
1393 | + gVoiceClient->sessionTerminateSendMessage(); | ||
1394 | gVoiceClient->logout(); | ||
1395 | - // As of SDK version 4885, this should no longer be necessary. It will linger after the socket close if it needs to. | ||
1396 | - // ms_sleep(2000); | ||
1397 | gVoiceClient->connectorShutdown(); | ||
1398 | gVoiceClient->closeSocket(); // Need to do this now -- bad things happen if the destructor does it later. | ||
1399 | |||
1400 | @@ -1210,13 +929,13 @@ void LLVoiceClient::updateSettings() | ||
1401 | setPTTKey(keyString); | ||
1402 | setPTTIsToggle(gSavedSettings.getBOOL("PushToTalkToggle")); | ||
1403 | setEarLocation(gSavedSettings.getS32("VoiceEarLocation")); | ||
1404 | + std::string serverName = gSavedSettings.getString("VivoxDebugServerName"); | ||
1405 | + setVivoxDebugServerName(serverName); | ||
1406 | |||
1407 | std::string inputDevice = gSavedSettings.getString("VoiceInputAudioDevice"); | ||
1408 | setCaptureDevice(inputDevice); | ||
1409 | std::string outputDevice = gSavedSettings.getString("VoiceOutputAudioDevice"); | ||
1410 | setRenderDevice(outputDevice); | ||
1411 | - F32 mic_level = gSavedSettings.getF32("AudioLevelMic"); | ||
1412 | - setMicGain(mic_level); | ||
1413 | setLipSyncEnabled(gSavedSettings.getBOOL("LipSyncEnabled")); | ||
1414 | } | ||
1415 | |||
1416 | @@ -1232,10 +951,9 @@ bool LLVoiceClient::writeString(const std::string &str) | ||
1417 | apr_size_t size = (apr_size_t)str.size(); | ||
1418 | apr_size_t written = size; | ||
1419 | |||
1420 | - //MARK: Turn this on to log outgoing XML | ||
1421 | -// LL_DEBUGS("Voice") << "sending: " << str << LL_ENDL; | ||
1422 | + LL_DEBUGS("Voice") << "sending: " << str << LL_ENDL; | ||
1423 | |||
1424 | - // check return code - sockets will fail (broken, etc.) | ||
1425 | + // MBW -- XXX -- check return code - sockets will fail (broken, etc.) | ||
1426 | err = apr_socket_send( | ||
1427 | mSocket->getSocket(), | ||
1428 | (const char*)str.data(), | ||
1429 | @@ -1246,7 +964,7 @@ bool LLVoiceClient::writeString(const std::string &str) | ||
1430 | // Success. | ||
1431 | result = true; | ||
1432 | } | ||
1433 | - // TODO: handle partial writes (written is number of bytes written) | ||
1434 | + // MBW -- XXX -- handle partial writes (written is number of bytes written) | ||
1435 | // Need to set socket to non-blocking before this will work. | ||
1436 | // else if(APR_STATUS_IS_EAGAIN(err)) | ||
1437 | // { | ||
1438 | @@ -1270,7 +988,7 @@ bool LLVoiceClient::writeString(const std::string &str) | ||
1439 | void LLVoiceClient::connectorCreate() | ||
1440 | { | ||
1441 | std::ostringstream stream; | ||
1442 | - std::string logpath = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, ""); | ||
1443 | + std::string logpath; | ||
1444 | std::string loglevel = "0"; | ||
1445 | |||
1446 | // Transition to stateConnectorStarted when the connector handle comes back. | ||
1447 | @@ -1282,20 +1000,20 @@ void LLVoiceClient::connectorCreate() | ||
1448 | { | ||
1449 | LL_DEBUGS("Voice") << "creating connector with logging enabled" << LL_ENDL; | ||
1450 | loglevel = "10"; | ||
1451 | + logpath = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, ""); | ||
1452 | } | ||
1453 | |||
1454 | stream | ||
1455 | << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Connector.Create.1\">" | ||
1456 | << "<ClientName>V2 SDK</ClientName>" | ||
1457 | - << "<AccountManagementServer>" << mVoiceAccountServerURI << "</AccountManagementServer>" | ||
1458 | - << "<Mode>Normal</Mode>" | ||
1459 | + << "<AccountManagementServer>" << mAccountServerURI << "</AccountManagementServer>" | ||
1460 | << "<Logging>" | ||
1461 | + << "<Enabled>false</Enabled>" | ||
1462 | << "<Folder>" << logpath << "</Folder>" | ||
1463 | << "<FileNamePrefix>Connector</FileNamePrefix>" | ||
1464 | << "<FileNameSuffix>.log</FileNameSuffix>" | ||
1465 | << "<LogLevel>" << loglevel << "</LogLevel>" | ||
1466 | << "</Logging>" | ||
1467 | - << "<Application>SecondLifeViewer.1</Application>" | ||
1468 | << "</Request>\n\n\n"; | ||
1469 | |||
1470 | writeString(stream.str()); | ||
1471 | @@ -1333,6 +1051,20 @@ void LLVoiceClient::userAuthorized(const std::string& firstName, const std::stri | ||
1472 | |||
1473 | sConnectingToAgni = LLViewerLogin::getInstance()->isInProductionGrid(); | ||
1474 | |||
1475 | + // MBW -- XXX -- Enable this when the bhd.vivox.com server gets a real ssl cert. | ||
1476 | + if(sConnectingToAgni) | ||
1477 | + { | ||
1478 | + // Use the release account server | ||
1479 | + mAccountServerName = "bhr.vivox.com"; | ||
1480 | + mAccountServerURI = "https://www." + mAccountServerName + "/api2/"; | ||
1481 | + } | ||
1482 | + else | ||
1483 | + { | ||
1484 | + // Use the development account server | ||
1485 | + mAccountServerName = gSavedSettings.getString("VivoxDebugServerName"); | ||
1486 | + mAccountServerURI = "https://www." + mAccountServerName + "/api2/"; | ||
1487 | + } | ||
1488 | + | ||
1489 | mAccountName = nameFromID(agentID); | ||
1490 | } | ||
1491 | |||
1492 | @@ -1354,69 +1086,24 @@ void LLVoiceClient::requestVoiceAccountProvision(S32 retries) | ||
1493 | } | ||
1494 | |||
1495 | void LLVoiceClient::login( | ||
1496 | - const std::string& account_name, | ||
1497 | - const std::string& password, | ||
1498 | - const std::string& voice_sip_uri_hostname, | ||
1499 | - const std::string& voice_account_server_uri) | ||
1500 | + const std::string& accountName, | ||
1501 | + const std::string &password) | ||
1502 | { | ||
1503 | - mVoiceSIPURIHostName = voice_sip_uri_hostname; | ||
1504 | - mVoiceAccountServerURI = voice_account_server_uri; | ||
1505 | - | ||
1506 | - if(!mAccountHandle.empty()) | ||
1507 | + if((getState() >= stateLoggingIn) && (getState() < stateLoggedOut)) | ||
1508 | { | ||
1509 | - // Already logged in. | ||
1510 | - LL_WARNS("Voice") << "Called while already logged in." << LL_ENDL; | ||
1511 | - | ||
1512 | - // Don't process another login. | ||
1513 | - return; | ||
1514 | + // Already logged in. This is an internal error. | ||
1515 | + LL_ERRS("Voice") << "Can't login again. Called from wrong state." << LL_ENDL; | ||
1516 | } | ||
1517 | - else if ( account_name != mAccountName ) | ||
1518 | + else if ( accountName != mAccountName ) | ||
1519 | { | ||
1520 | //TODO: error? | ||
1521 | - LL_WARNS("Voice") << "Wrong account name! " << account_name | ||
1522 | + LL_WARNS("Voice") << "Wrong account name! " << accountName | ||
1523 | << " instead of " << mAccountName << LL_ENDL; | ||
1524 | } | ||
1525 | else | ||
1526 | { | ||
1527 | mAccountPassword = password; | ||
1528 | } | ||
1529 | - | ||
1530 | - std::string debugSIPURIHostName = gSavedSettings.getString("VivoxDebugSIPURIHostName"); | ||
1531 | - | ||
1532 | - if( !debugSIPURIHostName.empty() ) | ||
1533 | - { | ||
1534 | - mVoiceSIPURIHostName = debugSIPURIHostName; | ||
1535 | - } | ||
1536 | - | ||
1537 | - if( mVoiceSIPURIHostName.empty() ) | ||
1538 | - { | ||
1539 | - // we have an empty account server name | ||
1540 | - // so we fall back to hardcoded defaults | ||
1541 | - | ||
1542 | - if(sConnectingToAgni) | ||
1543 | - { | ||
1544 | - // Use the release account server | ||
1545 | - mVoiceSIPURIHostName = "bhr.vivox.com"; | ||
1546 | - } | ||
1547 | - else | ||
1548 | - { | ||
1549 | - // Use the development account server | ||
1550 | - mVoiceSIPURIHostName = "bhd.vivox.com"; | ||
1551 | - } | ||
1552 | - } | ||
1553 | - | ||
1554 | - std::string debugAccountServerURI = gSavedSettings.getString("VivoxDebugVoiceAccountServerURI"); | ||
1555 | - | ||
1556 | - if( !debugAccountServerURI.empty() ) | ||
1557 | - { | ||
1558 | - mVoiceAccountServerURI = debugAccountServerURI; | ||
1559 | - } | ||
1560 | - | ||
1561 | - if( mVoiceAccountServerURI.empty() ) | ||
1562 | - { | ||
1563 | - // If the account server URI isn't specified, construct it from the SIP URI hostname | ||
1564 | - mVoiceAccountServerURI = "https://www." + mVoiceSIPURIHostName + "/api2/"; | ||
1565 | - } | ||
1566 | } | ||
1567 | |||
1568 | void LLVoiceClient::idle(void* user_data) | ||
1569 | @@ -1434,16 +1121,11 @@ std::string LLVoiceClient::state2string(LLVoiceClient::state inState) | ||
1570 | |||
1571 | switch(inState) | ||
1572 | { | ||
1573 | - CASE(stateDisableCleanup); | ||
1574 | CASE(stateDisabled); | ||
1575 | CASE(stateStart); | ||
1576 | CASE(stateDaemonLaunched); | ||
1577 | CASE(stateConnecting); | ||
1578 | - CASE(stateConnected); | ||
1579 | CASE(stateIdle); | ||
1580 | - CASE(stateMicTuningStart); | ||
1581 | - CASE(stateMicTuningRunning); | ||
1582 | - CASE(stateMicTuningStop); | ||
1583 | CASE(stateConnectorStart); | ||
1584 | CASE(stateConnectorStarting); | ||
1585 | CASE(stateConnectorStarted); | ||
1586 | @@ -1452,8 +1134,12 @@ std::string LLVoiceClient::state2string(LLVoiceClient::state inState) | ||
1587 | CASE(stateNeedsLogin); | ||
1588 | CASE(stateLoggingIn); | ||
1589 | CASE(stateLoggedIn); | ||
1590 | - CASE(stateCreatingSessionGroup); | ||
1591 | CASE(stateNoChannel); | ||
1592 | + CASE(stateMicTuningStart); | ||
1593 | + CASE(stateMicTuningRunning); | ||
1594 | + CASE(stateMicTuningStop); | ||
1595 | + CASE(stateSessionCreate); | ||
1596 | + CASE(stateSessionConnect); | ||
1597 | CASE(stateJoiningSession); | ||
1598 | CASE(stateSessionJoined); | ||
1599 | CASE(stateRunning); | ||
1600 | @@ -1470,6 +1156,7 @@ std::string LLVoiceClient::state2string(LLVoiceClient::state inState) | ||
1601 | CASE(stateJoinSessionFailed); | ||
1602 | CASE(stateJoinSessionFailedWaiting); | ||
1603 | CASE(stateJail); | ||
1604 | + CASE(stateMicTuningNoLogin); | ||
1605 | } | ||
1606 | |||
1607 | #undef CASE | ||
1608 | @@ -1491,7 +1178,6 @@ std::string LLVoiceClientStatusObserver::status2string(LLVoiceClientStatusObserv | ||
1609 | CASE(STATUS_JOINING); | ||
1610 | CASE(STATUS_JOINED); | ||
1611 | CASE(STATUS_LEFT_CHANNEL); | ||
1612 | - CASE(STATUS_VOICE_DISABLED); | ||
1613 | CASE(BEGIN_ERROR_STATUS); | ||
1614 | CASE(ERROR_CHANNEL_FULL); | ||
1615 | CASE(ERROR_CHANNEL_LOCKED); | ||
1616 | @@ -1525,13 +1211,9 @@ void LLVoiceClient::stateMachine() | ||
1617 | { | ||
1618 | updatePosition(); | ||
1619 | } | ||
1620 | - else if(mTuningMode) | ||
1621 | - { | ||
1622 | - // Tuning mode is special -- it needs to launch SLVoice even if voice is disabled. | ||
1623 | - } | ||
1624 | else | ||
1625 | { | ||
1626 | - if((getState() != stateDisabled) && (getState() != stateDisableCleanup)) | ||
1627 | + if(getState() != stateDisabled) | ||
1628 | { | ||
1629 | // User turned off voice support. Send the cleanup messages, close the socket, and reset. | ||
1630 | if(!mConnected) | ||
1631 | @@ -1541,10 +1223,13 @@ void LLVoiceClient::stateMachine() | ||
1632 | killGateway(); | ||
1633 | } | ||
1634 | |||
1635 | + sessionTerminateSendMessage(); | ||
1636 | logout(); | ||
1637 | connectorShutdown(); | ||
1638 | - | ||
1639 | - setState(stateDisableCleanup); | ||
1640 | + closeSocket(); | ||
1641 | + removeAllParticipants(); | ||
1642 | + | ||
1643 | + setState(stateDisabled); | ||
1644 | } | ||
1645 | } | ||
1646 | |||
1647 | @@ -1559,7 +1244,7 @@ void LLVoiceClient::stateMachine() | ||
1648 | std::string regionName = region->getName(); | ||
1649 | std::string capURI = region->getCapability("ParcelVoiceInfoRequest"); | ||
1650 | |||
1651 | -// LL_DEBUGS("Voice") << "Region name = \"" << regionName <<"\", " << "parcel local ID = " << parcelLocalID << LL_ENDL; | ||
1652 | + LL_DEBUGS("Voice") << "Region name = \"" << regionName <<"\", " << "parcel local ID = " << parcelLocalID << LL_ENDL; | ||
1653 | |||
1654 | // The region name starts out empty and gets filled in later. | ||
1655 | // Also, the cap gets filled in a short time after the region cross, but a little too late for our purposes. | ||
1656 | @@ -1580,30 +1265,13 @@ void LLVoiceClient::stateMachine() | ||
1657 | |||
1658 | switch(getState()) | ||
1659 | { | ||
1660 | - //MARK: stateDisableCleanup | ||
1661 | - case stateDisableCleanup: | ||
1662 | - // Clean up and reset everything. | ||
1663 | - closeSocket(); | ||
1664 | - deleteAllSessions(); | ||
1665 | - deleteAllBuddies(); | ||
1666 | - | ||
1667 | - mConnectorHandle.clear(); | ||
1668 | - mAccountHandle.clear(); | ||
1669 | - mAccountPassword.clear(); | ||
1670 | - mVoiceAccountServerURI.clear(); | ||
1671 | - | ||
1672 | - setState(stateDisabled); | ||
1673 | - break; | ||
1674 | - | ||
1675 | - //MARK: stateDisabled | ||
1676 | case stateDisabled: | ||
1677 | - if(mTuningMode || (mVoiceEnabled && !mAccountName.empty())) | ||
1678 | + if(mVoiceEnabled && (!mAccountName.empty() || mTuningMode)) | ||
1679 | { | ||
1680 | setState(stateStart); | ||
1681 | } | ||
1682 | break; | ||
1683 | |||
1684 | - //MARK: stateStart | ||
1685 | case stateStart: | ||
1686 | if(gSavedSettings.getBOOL("CmdLineDisableVoice")) | ||
1687 | { | ||
1688 | @@ -1634,9 +1302,7 @@ void LLVoiceClient::stateMachine() | ||
1689 | if(!LLFile::stat(exe_path, &s)) | ||
1690 | { | ||
1691 | // vivox executable exists. Build the command line and launch the daemon. | ||
1692 | - // SLIM SDK: these arguments are no longer necessary. | ||
1693 | -// std::string args = " -p tcp -h -c"; | ||
1694 | - std::string args; | ||
1695 | + std::string args = " -p tcp -h -c"; | ||
1696 | std::string cmd; | ||
1697 | std::string loglevel = gSavedSettings.getString("VivoxDebugLevel"); | ||
1698 | |||
1699 | @@ -1721,15 +1387,14 @@ void LLVoiceClient::stateMachine() | ||
1700 | } | ||
1701 | else | ||
1702 | { | ||
1703 | - LL_INFOS("Voice") << exe_path << " not found." << LL_ENDL; | ||
1704 | + LL_INFOS("Voice") << exe_path << "not found." << LL_ENDL; | ||
1705 | } | ||
1706 | } | ||
1707 | else | ||
1708 | { | ||
1709 | - // SLIM SDK: port changed from 44124 to 44125. | ||
1710 | // We can connect to a client gateway running on another host. This is useful for testing. | ||
1711 | // To do this, launch the gateway on a nearby host like this: | ||
1712 | - // vivox-gw.exe -p tcp -i 0.0.0.0:44125 | ||
1713 | + // vivox-gw.exe -p tcp -i 0.0.0.0:44124 | ||
1714 | // and put that host's IP address here. | ||
1715 | mDaemonHost = LLHost(gSavedSettings.getString("VoiceHost"), gSavedSettings.getU32("VoicePort")); | ||
1716 | } | ||
1717 | @@ -1741,23 +1406,17 @@ void LLVoiceClient::stateMachine() | ||
1718 | |||
1719 | // Dirty the states we'll need to sync with the daemon when it comes up. | ||
1720 | mPTTDirty = true; | ||
1721 | - mMicVolumeDirty = true; | ||
1722 | mSpeakerVolumeDirty = true; | ||
1723 | - mSpeakerMuteDirty = true; | ||
1724 | // These only need to be set if they're not default (i.e. empty string). | ||
1725 | mCaptureDeviceDirty = !mCaptureDevice.empty(); | ||
1726 | mRenderDeviceDirty = !mRenderDevice.empty(); | ||
1727 | - | ||
1728 | - mMainSessionGroupHandle.clear(); | ||
1729 | } | ||
1730 | break; | ||
1731 | - | ||
1732 | - //MARK: stateDaemonLaunched | ||
1733 | + | ||
1734 | case stateDaemonLaunched: | ||
1735 | + LL_DEBUGS("Voice") << "Connecting to vivox daemon" << LL_ENDL; | ||
1736 | if(mUpdateTimer.hasExpired()) | ||
1737 | { | ||
1738 | - LL_DEBUGS("Voice") << "Connecting to vivox daemon" << LL_ENDL; | ||
1739 | - | ||
1740 | mUpdateTimer.setTimerExpirySec(CONNECT_THROTTLE_SECONDS); | ||
1741 | |||
1742 | if(!mSocket) | ||
1743 | @@ -1778,7 +1437,6 @@ void LLVoiceClient::stateMachine() | ||
1744 | } | ||
1745 | break; | ||
1746 | |||
1747 | - //MARK: stateConnecting | ||
1748 | case stateConnecting: | ||
1749 | // Can't do this until we have the pump available. | ||
1750 | if(mPump) | ||
1751 | @@ -1796,34 +1454,48 @@ void LLVoiceClient::stateMachine() | ||
1752 | |||
1753 | mPump->addChain(readChain, NEVER_CHAIN_EXPIRY_SECS); | ||
1754 | |||
1755 | - setState(stateConnected); | ||
1756 | + setState(stateIdle); | ||
1757 | } | ||
1758 | |||
1759 | break; | ||
1760 | |||
1761 | - //MARK: stateConnected | ||
1762 | - case stateConnected: | ||
1763 | + case stateIdle: | ||
1764 | // Initial devices query | ||
1765 | getCaptureDevicesSendMessage(); | ||
1766 | getRenderDevicesSendMessage(); | ||
1767 | |||
1768 | mLoginRetryCount = 0; | ||
1769 | - | ||
1770 | - setState(stateIdle); | ||
1771 | + | ||
1772 | + setState(stateConnectorStart); | ||
1773 | + | ||
1774 | break; | ||
1775 | - | ||
1776 | - //MARK: stateIdle | ||
1777 | - case stateIdle: | ||
1778 | - // This is the idle state where we're connected to the daemon but haven't set up a connector yet. | ||
1779 | - if(mTuningMode) | ||
1780 | + | ||
1781 | + case stateConnectorStart: | ||
1782 | + if(!mVoiceEnabled) | ||
1783 | { | ||
1784 | - mTuningExitState = stateIdle; | ||
1785 | + // We were never logged in. This will shut down the connector. | ||
1786 | + setState(stateLoggedOut); | ||
1787 | + } | ||
1788 | + else if(!mAccountServerURI.empty()) | ||
1789 | + { | ||
1790 | + connectorCreate(); | ||
1791 | + } | ||
1792 | + else if(mTuningMode) | ||
1793 | + { | ||
1794 | + mTuningExitState = stateConnectorStart; | ||
1795 | setState(stateMicTuningStart); | ||
1796 | } | ||
1797 | - else if(!mVoiceEnabled) | ||
1798 | + break; | ||
1799 | + | ||
1800 | + case stateConnectorStarting: // waiting for connector handle | ||
1801 | + // connectorCreateResponse() will transition from here to stateConnectorStarted. | ||
1802 | + break; | ||
1803 | + | ||
1804 | + case stateConnectorStarted: // connector handle received | ||
1805 | + if(!mVoiceEnabled) | ||
1806 | { | ||
1807 | - // We never started up the connector. This will shut down the daemon. | ||
1808 | - setState(stateConnectorStopped); | ||
1809 | + // We were never logged in. This will shut down the connector. | ||
1810 | + setState(stateLoggedOut); | ||
1811 | } | ||
1812 | else if(!mAccountName.empty()) | ||
1813 | { | ||
1814 | @@ -1837,13 +1509,12 @@ void LLVoiceClient::stateMachine() | ||
1815 | { | ||
1816 | requestVoiceAccountProvision(); | ||
1817 | } | ||
1818 | - setState(stateConnectorStart); | ||
1819 | + setState(stateNeedsLogin); | ||
1820 | } | ||
1821 | } | ||
1822 | } | ||
1823 | break; | ||
1824 | - | ||
1825 | - //MARK: stateMicTuningStart | ||
1826 | + | ||
1827 | case stateMicTuningStart: | ||
1828 | if(mUpdateTimer.hasExpired()) | ||
1829 | { | ||
1830 | @@ -1851,9 +1522,19 @@ void LLVoiceClient::stateMachine() | ||
1831 | { | ||
1832 | // These can't be changed while in tuning mode. Set them before starting. | ||
1833 | std::ostringstream stream; | ||
1834 | - | ||
1835 | - buildSetCaptureDevice(stream); | ||
1836 | - buildSetRenderDevice(stream); | ||
1837 | + | ||
1838 | + if(mCaptureDeviceDirty) | ||
1839 | + { | ||
1840 | + buildSetCaptureDevice(stream); | ||
1841 | + } | ||
1842 | + | ||
1843 | + if(mRenderDeviceDirty) | ||
1844 | + { | ||
1845 | + buildSetRenderDevice(stream); | ||
1846 | + } | ||
1847 | + | ||
1848 | + mCaptureDeviceDirty = false; | ||
1849 | + mRenderDeviceDirty = false; | ||
1850 | |||
1851 | if(!stream.str().empty()) | ||
1852 | { | ||
1853 | @@ -1875,9 +1556,8 @@ void LLVoiceClient::stateMachine() | ||
1854 | |||
1855 | break; | ||
1856 | |||
1857 | - //MARK: stateMicTuningRunning | ||
1858 | case stateMicTuningRunning: | ||
1859 | - if(!mTuningMode || mCaptureDeviceDirty || mRenderDeviceDirty) | ||
1860 | + if(!mTuningMode || !mVoiceEnabled || mSessionTerminateRequested || mCaptureDeviceDirty || mRenderDeviceDirty) | ||
1861 | { | ||
1862 | // All of these conditions make us leave tuning mode. | ||
1863 | setState(stateMicTuningStop); | ||
1864 | @@ -1917,7 +1597,6 @@ void LLVoiceClient::stateMachine() | ||
1865 | } | ||
1866 | break; | ||
1867 | |||
1868 | - //MARK: stateMicTuningStop | ||
1869 | case stateMicTuningStop: | ||
1870 | { | ||
1871 | // transition out of mic tuning | ||
1872 | @@ -1931,40 +1610,7 @@ void LLVoiceClient::stateMachine() | ||
1873 | |||
1874 | } | ||
1875 | break; | ||
1876 | - | ||
1877 | - //MARK: stateConnectorStart | ||
1878 | - case stateConnectorStart: | ||
1879 | - if(!mVoiceEnabled) | ||
1880 | - { | ||
1881 | - // We were never logged in. This will shut down the connector. | ||
1882 | - setState(stateLoggedOut); | ||
1883 | - } | ||
1884 | - else if(!mVoiceAccountServerURI.empty()) | ||
1885 | - { | ||
1886 | - connectorCreate(); | ||
1887 | - } | ||
1888 | - break; | ||
1889 | - | ||
1890 | - //MARK: stateConnectorStarting | ||
1891 | - case stateConnectorStarting: // waiting for connector handle | ||
1892 | - // connectorCreateResponse() will transition from here to stateConnectorStarted. | ||
1893 | - break; | ||
1894 | - | ||
1895 | - //MARK: stateConnectorStarted | ||
1896 | - case stateConnectorStarted: // connector handle received | ||
1897 | - if(!mVoiceEnabled) | ||
1898 | - { | ||
1899 | - // We were never logged in. This will shut down the connector. | ||
1900 | - setState(stateLoggedOut); | ||
1901 | - } | ||
1902 | - else | ||
1903 | - { | ||
1904 | - // The connector is started. Send a login message. | ||
1905 | - setState(stateNeedsLogin); | ||
1906 | - } | ||
1907 | - break; | ||
1908 | - | ||
1909 | - //MARK: stateLoginRetry | ||
1910 | + | ||
1911 | case stateLoginRetry: | ||
1912 | if(mLoginRetryCount == 0) | ||
1913 | { | ||
1914 | @@ -1988,7 +1634,6 @@ void LLVoiceClient::stateMachine() | ||
1915 | } | ||
1916 | break; | ||
1917 | |||
1918 | - //MARK: stateLoginRetryWait | ||
1919 | case stateLoginRetryWait: | ||
1920 | if(mUpdateTimer.hasExpired()) | ||
1921 | { | ||
1922 | @@ -1996,7 +1641,6 @@ void LLVoiceClient::stateMachine() | ||
1923 | } | ||
1924 | break; | ||
1925 | |||
1926 | - //MARK: stateNeedsLogin | ||
1927 | case stateNeedsLogin: | ||
1928 | if(!mAccountPassword.empty()) | ||
1929 | { | ||
1930 | @@ -2005,22 +1649,16 @@ void LLVoiceClient::stateMachine() | ||
1931 | } | ||
1932 | break; | ||
1933 | |||
1934 | - //MARK: stateLoggingIn | ||
1935 | case stateLoggingIn: // waiting for account handle | ||
1936 | // loginResponse() will transition from here to stateLoggedIn. | ||
1937 | break; | ||
1938 | |||
1939 | - //MARK: stateLoggedIn | ||
1940 | case stateLoggedIn: // account handle received | ||
1941 | + // Initial kick-off of channel lookup logic | ||
1942 | + parcelChanged(); | ||
1943 | |||
1944 | notifyStatusObservers(LLVoiceClientStatusObserver::STATUS_LOGGED_IN); | ||
1945 | |||
1946 | - // request the current set of block rules (we'll need them when updating the friends list) | ||
1947 | - accountListBlockRulesSendMessage(); | ||
1948 | - | ||
1949 | - // request the current set of auto-accept rules | ||
1950 | - accountListAutoAcceptRulesSendMessage(); | ||
1951 | - | ||
1952 | // Set up the mute list observer if it hasn't been set up already. | ||
1953 | if((!sMuteListListener_listening)) | ||
1954 | { | ||
1955 | @@ -2028,67 +1666,13 @@ void LLVoiceClient::stateMachine() | ||
1956 | sMuteListListener_listening = true; | ||
1957 | } | ||
1958 | |||
1959 | - // Set up the friends list observer if it hasn't been set up already. | ||
1960 | - if(friendslist_listener == NULL) | ||
1961 | - { | ||
1962 | - friendslist_listener = new LLVoiceClientFriendsObserver; | ||
1963 | - LLAvatarTracker::instance().addObserver(friendslist_listener); | ||
1964 | - } | ||
1965 | - | ||
1966 | - // Set the initial state of mic mute, local speaker volume, etc. | ||
1967 | - { | ||
1968 | - std::ostringstream stream; | ||
1969 | - | ||
1970 | - buildLocalAudioUpdates(stream); | ||
1971 | - | ||
1972 | - if(!stream.str().empty()) | ||
1973 | - { | ||
1974 | - writeString(stream.str()); | ||
1975 | - } | ||
1976 | - } | ||
1977 | - | ||
1978 | -#if USE_SESSION_GROUPS | ||
1979 | - // create the main session group | ||
1980 | - sessionGroupCreateSendMessage(); | ||
1981 | - | ||
1982 | - setState(stateCreatingSessionGroup); | ||
1983 | -#else | ||
1984 | - // Not using session groups -- skip the stateCreatingSessionGroup state. | ||
1985 | setState(stateNoChannel); | ||
1986 | - | ||
1987 | - // Initial kick-off of channel lookup logic | ||
1988 | - parcelChanged(); | ||
1989 | -#endif | ||
1990 | - break; | ||
1991 | - | ||
1992 | - //MARK: stateCreatingSessionGroup | ||
1993 | - case stateCreatingSessionGroup: | ||
1994 | - if(mSessionTerminateRequested || !mVoiceEnabled) | ||
1995 | - { | ||
1996 | - // TODO: Question: is this the right way out of this state | ||
1997 | - setState(stateSessionTerminated); | ||
1998 | - } | ||
1999 | - else if(!mMainSessionGroupHandle.empty()) | ||
2000 | - { | ||
2001 | - setState(stateNoChannel); | ||
2002 | - | ||
2003 | - // Start looped recording (needed for "panic button" anti-griefing tool) | ||
2004 | - recordingLoopStart(); | ||
2005 | - | ||
2006 | - // Initial kick-off of channel lookup logic | ||
2007 | - parcelChanged(); | ||
2008 | - } | ||
2009 | break; | ||
2010 | |||
2011 | - //MARK: stateNoChannel | ||
2012 | case stateNoChannel: | ||
2013 | - // Do this here as well as inside sendPositionalUpdate(). | ||
2014 | - // Otherwise, if you log in but don't join a proximal channel (such as when your login location has voice disabled), your friends list won't sync. | ||
2015 | - sendFriendsListUpdates(); | ||
2016 | - | ||
2017 | if(mSessionTerminateRequested || !mVoiceEnabled) | ||
2018 | { | ||
2019 | - // TODO: Question: Is this the right way out of this state? | ||
2020 | + // MBW -- XXX -- Is this the right way out of this state? | ||
2021 | setState(stateSessionTerminated); | ||
2022 | } | ||
2023 | else if(mTuningMode) | ||
2024 | @@ -2096,49 +1680,30 @@ void LLVoiceClient::stateMachine() | ||
2025 | mTuningExitState = stateNoChannel; | ||
2026 | setState(stateMicTuningStart); | ||
2027 | } | ||
2028 | - else if(sessionNeedsRelog(mNextAudioSession)) | ||
2029 | + else if(!mNextSessionHandle.empty()) | ||
2030 | { | ||
2031 | - requestRelog(); | ||
2032 | - setState(stateSessionTerminated); | ||
2033 | + setState(stateSessionConnect); | ||
2034 | } | ||
2035 | - else if(mNextAudioSession) | ||
2036 | - { | ||
2037 | - sessionState *oldSession = mAudioSession; | ||
2038 | - | ||
2039 | - mAudioSession = mNextAudioSession; | ||
2040 | - if(!mAudioSession->mReconnect) | ||
2041 | - { | ||
2042 | - mNextAudioSession = NULL; | ||
2043 | - } | ||
2044 | - | ||
2045 | - // The old session may now need to be deleted. | ||
2046 | - reapSession(oldSession); | ||
2047 | - | ||
2048 | - if(!mAudioSession->mHandle.empty()) | ||
2049 | - { | ||
2050 | - // Connect to a session by session handle | ||
2051 | - | ||
2052 | - sessionMediaConnectSendMessage(mAudioSession); | ||
2053 | - } | ||
2054 | - else | ||
2055 | - { | ||
2056 | - // Connect to a session by URI | ||
2057 | - sessionCreateSendMessage(mAudioSession, true, false); | ||
2058 | - } | ||
2059 | - | ||
2060 | - notifyStatusObservers(LLVoiceClientStatusObserver::STATUS_JOINING); | ||
2061 | - setState(stateJoiningSession); | ||
2062 | - } | ||
2063 | - else if(!mSpatialSessionURI.empty()) | ||
2064 | + else if(!mNextSessionURI.empty()) | ||
2065 | { | ||
2066 | - // If we're not headed elsewhere and have a spatial URI, return to spatial. | ||
2067 | - switchChannel(mSpatialSessionURI, true, false, false, mSpatialSessionCredentials); | ||
2068 | + setState(stateSessionCreate); | ||
2069 | } | ||
2070 | break; | ||
2071 | |||
2072 | - //MARK: stateJoiningSession | ||
2073 | + case stateSessionCreate: | ||
2074 | + sessionCreateSendMessage(); | ||
2075 | + notifyStatusObservers(LLVoiceClientStatusObserver::STATUS_JOINING); | ||
2076 | + setState(stateJoiningSession); | ||
2077 | + break; | ||
2078 | + | ||
2079 | + case stateSessionConnect: | ||
2080 | + sessionConnectSendMessage(); | ||
2081 | + notifyStatusObservers(LLVoiceClientStatusObserver::STATUS_JOINING); | ||
2082 | + setState(stateJoiningSession); | ||
2083 | + break; | ||
2084 | + | ||
2085 | case stateJoiningSession: // waiting for session handle | ||
2086 | - // joinedAudioSession() will transition from here to stateSessionJoined. | ||
2087 | + // sessionCreateResponse() will transition from here to stateSessionJoined. | ||
2088 | if(!mVoiceEnabled) | ||
2089 | { | ||
2090 | // User bailed out during connect -- jump straight to teardown. | ||
2091 | @@ -2146,27 +1711,30 @@ void LLVoiceClient::stateMachine() | ||
2092 | } | ||
2093 | else if(mSessionTerminateRequested) | ||
2094 | { | ||
2095 | - if(mAudioSession && !mAudioSession->mHandle.empty()) | ||
2096 | + if(!mSessionHandle.empty()) | ||
2097 | { | ||
2098 | // Only allow direct exits from this state in p2p calls (for cancelling an invite). | ||
2099 | // Terminating a half-connected session on other types of calls seems to break something in the vivox gateway. | ||
2100 | - if(mAudioSession->mIsP2P) | ||
2101 | + if(mSessionP2P) | ||
2102 | { | ||
2103 | - sessionMediaDisconnectSendMessage(mAudioSession); | ||
2104 | + sessionTerminateSendMessage(); | ||
2105 | setState(stateSessionTerminated); | ||
2106 | } | ||
2107 | } | ||
2108 | } | ||
2109 | break; | ||
2110 | |||
2111 | - //MARK: stateSessionJoined | ||
2112 | case stateSessionJoined: // session handle received | ||
2113 | - // It appears that I need to wait for BOTH the SessionGroup.AddSession response and the SessionStateChangeEvent with state 4 | ||
2114 | - // before continuing from this state. They can happen in either order, and if I don't wait for both, things can get stuck. | ||
2115 | - // For now, the SessionGroup.AddSession response handler sets mSessionHandle and the SessionStateChangeEvent handler transitions to stateSessionJoined. | ||
2116 | + // MBW -- XXX -- It appears that I need to wait for BOTH the Session.Create response and the SessionStateChangeEvent with state 4 | ||
2117 | + // before continuing from this state. They can happen in either order, and if I don't wait for both, things can get stuck. | ||
2118 | + // For now, the Session.Create response handler sets mSessionHandle and the SessionStateChangeEvent handler transitions to stateSessionJoined. | ||
2119 | // This is a cheap way to make sure both have happened before proceeding. | ||
2120 | - if(mAudioSession && mAudioSession->mVoiceEnabled) | ||
2121 | + if(!mSessionHandle.empty()) | ||
2122 | { | ||
2123 | + // Events that need to happen when a session is joined could go here. | ||
2124 | + // Maybe send initial spatial data? | ||
2125 | + notifyStatusObservers(LLVoiceClientStatusObserver::STATUS_JOINED); | ||
2126 | + | ||
2127 | // Dirty state that may need to be sync'ed with the daemon. | ||
2128 | mPTTDirty = true; | ||
2129 | mSpeakerVolumeDirty = true; | ||
2130 | @@ -2177,11 +1745,6 @@ void LLVoiceClient::stateMachine() | ||
2131 | // Start the throttle timer | ||
2132 | mUpdateTimer.start(); | ||
2133 | mUpdateTimer.setTimerExpirySec(UPDATE_THROTTLE_SECONDS); | ||
2134 | - | ||
2135 | - // Events that need to happen when a session is joined could go here. | ||
2136 | - // Maybe send initial spatial data? | ||
2137 | - notifyStatusObservers(LLVoiceClientStatusObserver::STATUS_JOINED); | ||
2138 | - | ||
2139 | } | ||
2140 | else if(!mVoiceEnabled) | ||
2141 | { | ||
2142 | @@ -2192,20 +1755,21 @@ void LLVoiceClient::stateMachine() | ||
2143 | { | ||
2144 | // Only allow direct exits from this state in p2p calls (for cancelling an invite). | ||
2145 | // Terminating a half-connected session on other types of calls seems to break something in the vivox gateway. | ||
2146 | - if(mAudioSession && mAudioSession->mIsP2P) | ||
2147 | + if(mSessionP2P) | ||
2148 | { | ||
2149 | - sessionMediaDisconnectSendMessage(mAudioSession); | ||
2150 | + sessionTerminateSendMessage(); | ||
2151 | setState(stateSessionTerminated); | ||
2152 | } | ||
2153 | } | ||
2154 | break; | ||
2155 | |||
2156 | - //MARK: stateRunning | ||
2157 | case stateRunning: // steady state | ||
2158 | + // sessionTerminateSendMessage() will transition from here to stateLeavingSession | ||
2159 | + | ||
2160 | // Disabling voice or disconnect requested. | ||
2161 | if(!mVoiceEnabled || mSessionTerminateRequested) | ||
2162 | { | ||
2163 | - leaveAudioSession(); | ||
2164 | + sessionTerminateSendMessage(); | ||
2165 | } | ||
2166 | else | ||
2167 | { | ||
2168 | @@ -2238,7 +1802,7 @@ void LLVoiceClient::stateMachine() | ||
2169 | } | ||
2170 | } | ||
2171 | |||
2172 | - if(!inSpatialChannel()) | ||
2173 | + if(mNonSpatialChannel) | ||
2174 | { | ||
2175 | // When in a non-spatial channel, never send positional updates. | ||
2176 | mSpatialCoordsDirty = false; | ||
2177 | @@ -2251,7 +1815,7 @@ void LLVoiceClient::stateMachine() | ||
2178 | |||
2179 | // Send an update if the ptt state has changed (which shouldn't be able to happen that often -- the user can only click so fast) | ||
2180 | // or every 10hz, whichever is sooner. | ||
2181 | - if((mAudioSession && mAudioSession->mVolumeDirty) || mPTTDirty || mSpeakerVolumeDirty || mUpdateTimer.hasExpired()) | ||
2182 | + if(mVolumeDirty || mPTTDirty || mSpeakerVolumeDirty || mUpdateTimer.hasExpired()) | ||
2183 | { | ||
2184 | mUpdateTimer.setTimerExpirySec(UPDATE_THROTTLE_SECONDS); | ||
2185 | sendPositionalUpdate(); | ||
2186 | @@ -2259,38 +1823,25 @@ void LLVoiceClient::stateMachine() | ||
2187 | } | ||
2188 | break; | ||
2189 | |||
2190 | - //MARK: stateLeavingSession | ||
2191 | case stateLeavingSession: // waiting for terminate session response | ||
2192 | // The handler for the Session.Terminate response will transition from here to stateSessionTerminated. | ||
2193 | break; | ||
2194 | |||
2195 | - //MARK: stateSessionTerminated | ||
2196 | case stateSessionTerminated: | ||
2197 | + // Always reset the terminate request flag when we get here. | ||
2198 | + mSessionTerminateRequested = false; | ||
2199 | |||
2200 | - // Must do this first, since it uses mAudioSession. | ||
2201 | notifyStatusObservers(LLVoiceClientStatusObserver::STATUS_LEFT_CHANNEL); | ||
2202 | - | ||
2203 | - if(mAudioSession) | ||
2204 | - { | ||
2205 | - sessionState *oldSession = mAudioSession; | ||
2206 | |||
2207 | - mAudioSession = NULL; | ||
2208 | - // We just notified status observers about this change. Don't do it again. | ||
2209 | - mAudioSessionChanged = false; | ||
2210 | - | ||
2211 | - // The old session may now need to be deleted. | ||
2212 | - reapSession(oldSession); | ||
2213 | - } | ||
2214 | - else | ||
2215 | + if(mVoiceEnabled) | ||
2216 | { | ||
2217 | - LL_WARNS("Voice") << "stateSessionTerminated with NULL mAudioSession" << LL_ENDL; | ||
2218 | - } | ||
2219 | - | ||
2220 | - // Always reset the terminate request flag when we get here. | ||
2221 | - mSessionTerminateRequested = false; | ||
2222 | - | ||
2223 | - if(mVoiceEnabled && !mRelogRequested) | ||
2224 | - { | ||
2225 | + // SPECIAL CASE: if going back to spatial but in a parcel with an empty URI, transfer the non-spatial flag now. | ||
2226 | + // This fixes the case where you come out of a group chat in a parcel with voice disabled, and get stuck unable to rejoin spatial chat thereafter. | ||
2227 | + if(mNextSessionSpatial && mNextSessionURI.empty()) | ||
2228 | + { | ||
2229 | + mNonSpatialChannel = !mNextSessionSpatial; | ||
2230 | + } | ||
2231 | + | ||
2232 | // Just leaving a channel, go back to stateNoChannel (the "logged in but have no channel" state). | ||
2233 | setState(stateNoChannel); | ||
2234 | } | ||
2235 | @@ -2298,67 +1849,49 @@ void LLVoiceClient::stateMachine() | ||
2236 | { | ||
2237 | // Shutting down voice, continue with disconnecting. | ||
2238 | logout(); | ||
2239 | - | ||
2240 | - // The state machine will take it from here | ||
2241 | - mRelogRequested = false; | ||
2242 | } | ||
2243 | |||
2244 | break; | ||
2245 | |||
2246 | - //MARK: stateLoggingOut | ||
2247 | case stateLoggingOut: // waiting for logout response | ||
2248 | // The handler for the Account.Logout response will transition from here to stateLoggedOut. | ||
2249 | break; | ||
2250 | - //MARK: stateLoggedOut | ||
2251 | case stateLoggedOut: // logout response received | ||
2252 | // shut down the connector | ||
2253 | connectorShutdown(); | ||
2254 | break; | ||
2255 | |||
2256 | - //MARK: stateConnectorStopping | ||
2257 | case stateConnectorStopping: // waiting for connector stop | ||
2258 | // The handler for the Connector.InitiateShutdown response will transition from here to stateConnectorStopped. | ||
2259 | break; | ||
2260 | |||
2261 | - //MARK: stateConnectorStopped | ||
2262 | case stateConnectorStopped: // connector stop received | ||
2263 | - setState(stateDisableCleanup); | ||
2264 | + // Clean up and reset everything. | ||
2265 | + closeSocket(); | ||
2266 | + removeAllParticipants(); | ||
2267 | + setState(stateDisabled); | ||
2268 | break; | ||
2269 | |||
2270 | - //MARK: stateConnectorFailed | ||
2271 | case stateConnectorFailed: | ||
2272 | setState(stateConnectorFailedWaiting); | ||
2273 | break; | ||
2274 | - //MARK: stateConnectorFailedWaiting | ||
2275 | case stateConnectorFailedWaiting: | ||
2276 | break; | ||
2277 | |||
2278 | - //MARK: stateLoginFailed | ||
2279 | case stateLoginFailed: | ||
2280 | setState(stateLoginFailedWaiting); | ||
2281 | break; | ||
2282 | - //MARK: stateLoginFailedWaiting | ||
2283 | case stateLoginFailedWaiting: | ||
2284 | // No way to recover from these. Yet. | ||
2285 | break; | ||
2286 | |||
2287 | - //MARK: stateJoinSessionFailed | ||
2288 | case stateJoinSessionFailed: | ||
2289 | // Transition to error state. Send out any notifications here. | ||
2290 | - if(mAudioSession) | ||
2291 | - { | ||
2292 | - LL_WARNS("Voice") << "stateJoinSessionFailed: (" << mAudioSession->mErrorStatusCode << "): " << mAudioSession->mErrorStatusString << LL_ENDL; | ||
2293 | - } | ||
2294 | - else | ||
2295 | - { | ||
2296 | - LL_WARNS("Voice") << "stateJoinSessionFailed with no current session" << LL_ENDL; | ||
2297 | - } | ||
2298 | - | ||
2299 | + LL_WARNS("Voice") << "stateJoinSessionFailed: (" << mVivoxErrorStatusCode << "): " << mVivoxErrorStatusString << LL_ENDL; | ||
2300 | notifyStatusObservers(LLVoiceClientStatusObserver::ERROR_UNKNOWN); | ||
2301 | setState(stateJoinSessionFailedWaiting); | ||
2302 | break; | ||
2303 | |||
2304 | - //MARK: stateJoinSessionFailedWaiting | ||
2305 | case stateJoinSessionFailedWaiting: | ||
2306 | // Joining a channel failed, either due to a failed channel name -> sip url lookup or an error from the join message. | ||
2307 | // Region crossings may leave this state and try the join again. | ||
2308 | @@ -2368,24 +1901,22 @@ void LLVoiceClient::stateMachine() | ||
2309 | } | ||
2310 | break; | ||
2311 | |||
2312 | - //MARK: stateJail | ||
2313 | case stateJail: | ||
2314 | // We have given up. Do nothing. | ||
2315 | break; | ||
2316 | |||
2317 | + case stateMicTuningNoLogin: | ||
2318 | + // *TODO: Implement me. | ||
2319 | + LL_WARNS("Voice") << "stateMicTuningNoLogin not handled" << LL_ENDL; | ||
2320 | + break; | ||
2321 | } | ||
2322 | - | ||
2323 | - if(mAudioSession && mAudioSession->mParticipantsChanged) | ||
2324 | - { | ||
2325 | - mAudioSession->mParticipantsChanged = false; | ||
2326 | - mAudioSessionChanged = true; | ||
2327 | - } | ||
2328 | - | ||
2329 | - if(mAudioSessionChanged) | ||
2330 | + | ||
2331 | + if(mParticipantMapChanged) | ||
2332 | { | ||
2333 | - mAudioSessionChanged = false; | ||
2334 | - notifyParticipantObservers(); | ||
2335 | + mParticipantMapChanged = false; | ||
2336 | + notifyObservers(); | ||
2337 | } | ||
2338 | + | ||
2339 | } | ||
2340 | |||
2341 | void LLVoiceClient::closeSocket(void) | ||
2342 | @@ -2403,9 +1934,6 @@ void LLVoiceClient::loginSendMessage() | ||
2343 | << "<AccountName>" << mAccountName << "</AccountName>" | ||
2344 | << "<AccountPassword>" << mAccountPassword << "</AccountPassword>" | ||
2345 | << "<AudioSessionAnswerMode>VerifyAnswer</AudioSessionAnswerMode>" | ||
2346 | - << "<EnableBuddiesAndPresence>true</EnableBuddiesAndPresence>" | ||
2347 | - << "<BuddyManagementMode>Application</BuddyManagementMode>" | ||
2348 | - << "<ParticipantPropertyFrequency>5</ParticipantPropertyFrequency>" | ||
2349 | << "</Request>\n\n\n"; | ||
2350 | |||
2351 | writeString(stream.str()); | ||
2352 | @@ -2413,10 +1941,7 @@ void LLVoiceClient::loginSendMessage() | ||
2353 | |||
2354 | void LLVoiceClient::logout() | ||
2355 | { | ||
2356 | - // Ensure that we'll re-request provisioning before logging in again | ||
2357 | - mAccountPassword.clear(); | ||
2358 | - mVoiceAccountServerURI.clear(); | ||
2359 | - | ||
2360 | + mAccountPassword = ""; | ||
2361 | setState(stateLoggingOut); | ||
2362 | logoutSendMessage(); | ||
2363 | } | ||
2364 | @@ -2438,164 +1963,78 @@ void LLVoiceClient::logoutSendMessage() | ||
2365 | } | ||
2366 | } | ||
2367 | |||
2368 | -void LLVoiceClient::accountListBlockRulesSendMessage() | ||
2369 | +void LLVoiceClient::channelGetListSendMessage() | ||
2370 | { | ||
2371 | - if(!mAccountHandle.empty()) | ||
2372 | - { | ||
2373 | - std::ostringstream stream; | ||
2374 | - | ||
2375 | - LL_DEBUGS("Voice") << "requesting block rules" << LL_ENDL; | ||
2376 | - | ||
2377 | - stream | ||
2378 | - << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Account.ListBlockRules.1\">" | ||
2379 | - << "<AccountHandle>" << mAccountHandle << "</AccountHandle>" | ||
2380 | - << "</Request>" | ||
2381 | - << "\n\n\n"; | ||
2382 | - | ||
2383 | - writeString(stream.str()); | ||
2384 | - } | ||
2385 | -} | ||
2386 | - | ||
2387 | -void LLVoiceClient::accountListAutoAcceptRulesSendMessage() | ||
2388 | -{ | ||
2389 | - if(!mAccountHandle.empty()) | ||
2390 | - { | ||
2391 | - std::ostringstream stream; | ||
2392 | - | ||
2393 | - LL_DEBUGS("Voice") << "requesting auto-accept rules" << LL_ENDL; | ||
2394 | - | ||
2395 | - stream | ||
2396 | - << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Account.ListAutoAcceptRules.1\">" | ||
2397 | - << "<AccountHandle>" << mAccountHandle << "</AccountHandle>" | ||
2398 | - << "</Request>" | ||
2399 | - << "\n\n\n"; | ||
2400 | + std::ostringstream stream; | ||
2401 | + stream | ||
2402 | + << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Account.ChannelGetList.1\">" | ||
2403 | + << "<AccountHandle>" << mAccountHandle << "</AccountHandle>" | ||
2404 | + << "</Request>\n\n\n"; | ||
2405 | |||
2406 | - writeString(stream.str()); | ||
2407 | - } | ||
2408 | + writeString(stream.str()); | ||
2409 | } | ||
2410 | |||
2411 | -void LLVoiceClient::sessionGroupCreateSendMessage() | ||
2412 | +void LLVoiceClient::sessionCreateSendMessage() | ||
2413 | { | ||
2414 | - if(!mAccountHandle.empty()) | ||
2415 | - { | ||
2416 | - std::ostringstream stream; | ||
2417 | - | ||
2418 | - LL_DEBUGS("Voice") << "creating session group" << LL_ENDL; | ||
2419 | + LL_DEBUGS("Voice") << "requesting join: " << mNextSessionURI << LL_ENDL; | ||
2420 | |||
2421 | - stream | ||
2422 | - << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"SessionGroup.Create.1\">" | ||
2423 | - << "<AccountHandle>" << mAccountHandle << "</AccountHandle>" | ||
2424 | - << "<Type>Normal</Type>" | ||
2425 | - << "</Request>" | ||
2426 | - << "\n\n\n"; | ||
2427 | - | ||
2428 | - writeString(stream.str()); | ||
2429 | - } | ||
2430 | -} | ||
2431 | - | ||
2432 | -void LLVoiceClient::sessionCreateSendMessage(sessionState *session, bool startAudio, bool startText) | ||
2433 | -{ | ||
2434 | - LL_DEBUGS("Voice") << "requesting create: " << session->mSIPURI << LL_ENDL; | ||
2435 | - | ||
2436 | - session->mCreateInProgress = true; | ||
2437 | - if(startAudio) | ||
2438 | + mSessionURI = mNextSessionURI; | ||
2439 | + mNonSpatialChannel = !mNextSessionSpatial; | ||
2440 | + mSessionResetOnClose = mNextSessionResetOnClose; | ||
2441 | + mNextSessionResetOnClose = false; | ||
2442 | + if(mNextSessionNoReconnect) | ||
2443 | { | ||
2444 | - session->mMediaConnectInProgress = true; | ||
2445 | + // Clear the stashed URI so it can't reconnect | ||
2446 | + mNextSessionURI.clear(); | ||
2447 | } | ||
2448 | + // Only p2p sessions are created with "no reconnect". | ||
2449 | + mSessionP2P = mNextSessionNoReconnect; | ||
2450 | |||
2451 | std::ostringstream stream; | ||
2452 | stream | ||
2453 | - << "<Request requestId=\"" << session->mSIPURI << "\" action=\"Session.Create.1\">" | ||
2454 | + << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Session.Create.1\">" | ||
2455 | << "<AccountHandle>" << mAccountHandle << "</AccountHandle>" | ||
2456 | - << "<URI>" << session->mSIPURI << "</URI>"; | ||
2457 | + << "<URI>" << mSessionURI << "</URI>"; | ||
2458 | |||
2459 | static const std::string allowed_chars = | ||
2460 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" | ||
2461 | "0123456789" | ||
2462 | "-._~"; | ||
2463 | |||
2464 | - if(!session->mHash.empty()) | ||
2465 | + if(!mNextSessionHash.empty()) | ||
2466 | { | ||
2467 | stream | ||
2468 | - << "<Password>" << LLURI::escape(session->mHash, allowed_chars) << "</Password>" | ||
2469 | + << "<Password>" << LLURI::escape(mNextSessionHash, allowed_chars) << "</Password>" | ||
2470 | << "<PasswordHashAlgorithm>SHA1UserName</PasswordHashAlgorithm>"; | ||
2471 | } | ||
2472 | |||
2473 | stream | ||
2474 | - << "<ConnectAudio>" << (startAudio?"true":"false") << "</ConnectAudio>" | ||
2475 | - << "<ConnectText>" << (startText?"true":"false") << "</ConnectText>" | ||
2476 | << "<Name>" << mChannelName << "</Name>" | ||
2477 | << "</Request>\n\n\n"; | ||
2478 | writeString(stream.str()); | ||
2479 | } | ||
2480 | |||
2481 | -void LLVoiceClient::sessionGroupAddSessionSendMessage(sessionState *session, bool startAudio, bool startText) | ||
2482 | +void LLVoiceClient::sessionConnectSendMessage() | ||
2483 | { | ||
2484 | - LL_DEBUGS("Voice") << "requesting create: " << session->mSIPURI << LL_ENDL; | ||
2485 | - | ||
2486 | - session->mCreateInProgress = true; | ||
2487 | - if(startAudio) | ||
2488 | - { | ||
2489 | - session->mMediaConnectInProgress = true; | ||
2490 | - } | ||
2491 | - | ||
2492 | - std::string password; | ||
2493 | - if(!session->mHash.empty()) | ||
2494 | - { | ||
2495 | - static const std::string allowed_chars = | ||
2496 | - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" | ||
2497 | - "0123456789" | ||
2498 | - "-._~" | ||
2499 | - ; | ||
2500 | - password = LLURI::escape(session->mHash, allowed_chars); | ||
2501 | - } | ||
2502 | - | ||
2503 | - std::ostringstream stream; | ||
2504 | - stream | ||
2505 | - << "<Request requestId=\"" << session->mSIPURI << "\" action=\"SessionGroup.AddSession.1\">" | ||
2506 | - << "<SessionGroupHandle>" << session->mGroupHandle << "</SessionGroupHandle>" | ||
2507 | - << "<URI>" << session->mSIPURI << "</URI>" | ||
2508 | - << "<Name>" << mChannelName << "</Name>" | ||
2509 | - << "<ConnectAudio>" << (startAudio?"true":"false") << "</ConnectAudio>" | ||
2510 | - << "<ConnectText>" << (startText?"true":"false") << "</ConnectText>" | ||
2511 | - << "<Password>" << password << "</Password>" | ||
2512 | - << "<PasswordHashAlgorithm>SHA1UserName</PasswordHashAlgorithm>" | ||
2513 | - << "</Request>\n\n\n" | ||
2514 | - ; | ||
2515 | + LL_DEBUGS("Voice") << "connecting to session handle: " << mNextSessionHandle << LL_ENDL; | ||
2516 | |||
2517 | - writeString(stream.str()); | ||
2518 | -} | ||
2519 | - | ||
2520 | -void LLVoiceClient::sessionMediaConnectSendMessage(sessionState *session) | ||
2521 | -{ | ||
2522 | - LL_DEBUGS("Voice") << "connecting audio to session handle: " << session->mHandle << LL_ENDL; | ||
2523 | - | ||
2524 | - session->mMediaConnectInProgress = true; | ||
2525 | + mSessionHandle = mNextSessionHandle; | ||
2526 | + mSessionURI = mNextP2PSessionURI; | ||
2527 | + mNextSessionHandle.clear(); // never want to re-use these. | ||
2528 | + mNextP2PSessionURI.clear(); | ||
2529 | + mNonSpatialChannel = !mNextSessionSpatial; | ||
2530 | + mSessionResetOnClose = mNextSessionResetOnClose; | ||
2531 | + mNextSessionResetOnClose = false; | ||
2532 | + // Joining by session ID is only used to answer p2p invitations, so we know this is a p2p session. | ||
2533 | + mSessionP2P = true; | ||
2534 | |||
2535 | std::ostringstream stream; | ||
2536 | - | ||
2537 | - stream | ||
2538 | - << "<Request requestId=\"" << session->mHandle << "\" action=\"Session.MediaConnect.1\">" | ||
2539 | - << "<SessionGroupHandle>" << session->mGroupHandle << "</SessionGroupHandle>" | ||
2540 | - << "<SessionHandle>" << session->mHandle << "</SessionHandle>" | ||
2541 | - << "<Media>Audio</Media>" | ||
2542 | - << "</Request>\n\n\n"; | ||
2543 | - | ||
2544 | - writeString(stream.str()); | ||
2545 | -} | ||
2546 | - | ||
2547 | -void LLVoiceClient::sessionTextConnectSendMessage(sessionState *session) | ||
2548 | -{ | ||
2549 | - LL_DEBUGS("Voice") << "connecting text to session handle: " << session->mHandle << LL_ENDL; | ||
2550 | |||
2551 | - std::ostringstream stream; | ||
2552 | - | ||
2553 | stream | ||
2554 | - << "<Request requestId=\"" << session->mHandle << "\" action=\"Session.TextConnect.1\">" | ||
2555 | - << "<SessionGroupHandle>" << session->mGroupHandle << "</SessionGroupHandle>" | ||
2556 | - << "<SessionHandle>" << session->mHandle << "</SessionHandle>" | ||
2557 | + << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Session.Connect.1\">" | ||
2558 | + << "<SessionHandle>" << mSessionHandle << "</SessionHandle>" | ||
2559 | + << "<AudioMedia>default</AudioMedia>" | ||
2560 | << "</Request>\n\n\n"; | ||
2561 | - | ||
2562 | writeString(stream.str()); | ||
2563 | } | ||
2564 | |||
2565 | @@ -2604,112 +2043,52 @@ void LLVoiceClient::sessionTerminate() | ||
2566 | mSessionTerminateRequested = true; | ||
2567 | } | ||
2568 | |||
2569 | -void LLVoiceClient::requestRelog() | ||
2570 | +void LLVoiceClient::sessionTerminateSendMessage() | ||
2571 | { | ||
2572 | - mSessionTerminateRequested = true; | ||
2573 | - mRelogRequested = true; | ||
2574 | -} | ||
2575 | + LL_DEBUGS("Voice") << "leaving session: " << mSessionURI << LL_ENDL; | ||
2576 | |||
2577 | - | ||
2578 | -void LLVoiceClient::leaveAudioSession() | ||
2579 | -{ | ||
2580 | - if(mAudioSession) | ||
2581 | + switch(getState()) | ||
2582 | { | ||
2583 | - LL_DEBUGS("Voice") << "leaving session: " << mAudioSession->mSIPURI << LL_ENDL; | ||
2584 | - | ||
2585 | - switch(getState()) | ||
2586 | - { | ||
2587 | - case stateNoChannel: | ||
2588 | - // In this case, we want to pretend the join failed so our state machine doesn't get stuck. | ||
2589 | - // Skip the join failed transition state so we don't send out error notifications. | ||
2590 | - setState(stateJoinSessionFailedWaiting); | ||
2591 | - break; | ||
2592 | - case stateJoiningSession: | ||
2593 | - case stateSessionJoined: | ||
2594 | - case stateRunning: | ||
2595 | - if(!mAudioSession->mHandle.empty()) | ||
2596 | - { | ||
2597 | - | ||
2598 | -#if RECORD_EVERYTHING | ||
2599 | - // HACK: for testing only | ||
2600 | - // Save looped recording | ||
2601 | - std::string savepath("/tmp/vivoxrecording"); | ||
2602 | - { | ||
2603 | - time_t now = time(NULL); | ||
2604 | - const size_t BUF_SIZE = 64; | ||
2605 | - char time_str[BUF_SIZE]; /* Flawfinder: ignore */ | ||
2606 | - | ||
2607 | - strftime(time_str, BUF_SIZE, "%Y-%m-%dT%H:%M:%SZ", gmtime(&now)); | ||
2608 | - savepath += time_str; | ||
2609 | - } | ||
2610 | - recordingLoopSave(savepath); | ||
2611 | -#endif | ||
2612 | - | ||
2613 | - sessionMediaDisconnectSendMessage(mAudioSession); | ||
2614 | - setState(stateLeavingSession); | ||
2615 | - } | ||
2616 | - else | ||
2617 | - { | ||
2618 | - LL_WARNS("Voice") << "called with no session handle" << LL_ENDL; | ||
2619 | - setState(stateSessionTerminated); | ||
2620 | - } | ||
2621 | - break; | ||
2622 | - case stateJoinSessionFailed: | ||
2623 | - case stateJoinSessionFailedWaiting: | ||
2624 | + case stateNoChannel: | ||
2625 | + // In this case, we want to pretend the join failed so our state machine doesn't get stuck. | ||
2626 | + // Skip the join failed transition state so we don't send out error notifications. | ||
2627 | + setState(stateJoinSessionFailedWaiting); | ||
2628 | + break; | ||
2629 | + case stateJoiningSession: | ||
2630 | + case stateSessionJoined: | ||
2631 | + case stateRunning: | ||
2632 | + if(!mSessionHandle.empty()) | ||
2633 | + { | ||
2634 | + sessionTerminateByHandle(mSessionHandle); | ||
2635 | + setState(stateLeavingSession); | ||
2636 | + } | ||
2637 | + else | ||
2638 | + { | ||
2639 | + LL_WARNS("Voice") << "called with no session handle" << LL_ENDL; | ||
2640 | setState(stateSessionTerminated); | ||
2641 | - break; | ||
2642 | - | ||
2643 | - default: | ||
2644 | - LL_WARNS("Voice") << "called from unknown state" << LL_ENDL; | ||
2645 | - break; | ||
2646 | - } | ||
2647 | - } | ||
2648 | - else | ||
2649 | - { | ||
2650 | - LL_WARNS("Voice") << "called with no active session" << LL_ENDL; | ||
2651 | - setState(stateSessionTerminated); | ||
2652 | + } | ||
2653 | + break; | ||
2654 | + case stateJoinSessionFailed: | ||
2655 | + case stateJoinSessionFailedWaiting: | ||
2656 | + setState(stateSessionTerminated); | ||
2657 | + break; | ||
2658 | + | ||
2659 | + default: | ||
2660 | + LL_WARNS("Voice") << "called from unknown state" << LL_ENDL; | ||
2661 | + break; | ||
2662 | } | ||
2663 | } | ||
2664 | |||
2665 | -void LLVoiceClient::sessionTerminateSendMessage(sessionState *session) | ||
2666 | +void LLVoiceClient::sessionTerminateByHandle(std::string &sessionHandle) | ||
2667 | { | ||
2668 | - std::ostringstream stream; | ||
2669 | - | ||
2670 | - LL_DEBUGS("Voice") << "Sending Session.Terminate with handle " << session->mHandle << LL_ENDL; | ||
2671 | - stream | ||
2672 | - << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Session.Terminate.1\">" | ||
2673 | - << "<SessionHandle>" << session->mHandle << "</SessionHandle>" | ||
2674 | - << "</Request>\n\n\n"; | ||
2675 | - | ||
2676 | - writeString(stream.str()); | ||
2677 | -} | ||
2678 | + LL_DEBUGS("Voice") << "Sending Session.Terminate with handle " << sessionHandle << LL_ENDL; | ||
2679 | |||
2680 | -void LLVoiceClient::sessionMediaDisconnectSendMessage(sessionState *session) | ||
2681 | -{ | ||
2682 | std::ostringstream stream; | ||
2683 | - | ||
2684 | - LL_DEBUGS("Voice") << "Sending Session.MediaDisconnect with handle " << session->mHandle << LL_ENDL; | ||
2685 | stream | ||
2686 | - << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Session.MediaDisconnect.1\">" | ||
2687 | - << "<SessionGroupHandle>" << session->mGroupHandle << "</SessionGroupHandle>" | ||
2688 | - << "<SessionHandle>" << session->mHandle << "</SessionHandle>" | ||
2689 | - << "<Media>Audio</Media>" | ||
2690 | - << "</Request>\n\n\n"; | ||
2691 | - | ||
2692 | - writeString(stream.str()); | ||
2693 | - | ||
2694 | -} | ||
2695 | - | ||
2696 | -void LLVoiceClient::sessionTextDisconnectSendMessage(sessionState *session) | ||
2697 | -{ | ||
2698 | - std::ostringstream stream; | ||
2699 | - | ||
2700 | - LL_DEBUGS("Voice") << "Sending Session.TextDisconnect with handle " << session->mHandle << LL_ENDL; | ||
2701 | - stream | ||
2702 | - << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Session.TextDisconnect.1\">" | ||
2703 | - << "<SessionGroupHandle>" << session->mGroupHandle << "</SessionGroupHandle>" | ||
2704 | - << "<SessionHandle>" << session->mHandle << "</SessionHandle>" | ||
2705 | - << "</Request>\n\n\n"; | ||
2706 | + << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Session.Terminate.1\">" | ||
2707 | + << "<SessionHandle>" << sessionHandle << "</SessionHandle>" | ||
2708 | + << "</Request>" | ||
2709 | + << "\n\n\n"; | ||
2710 | |||
2711 | writeString(stream.str()); | ||
2712 | } | ||
2713 | @@ -2736,12 +2115,14 @@ void LLVoiceClient::getRenderDevicesSendMessage() | ||
2714 | |||
2715 | void LLVoiceClient::clearCaptureDevices() | ||
2716 | { | ||
2717 | + // MBW -- XXX -- do something here | ||
2718 | LL_DEBUGS("Voice") << "called" << LL_ENDL; | ||
2719 | mCaptureDevices.clear(); | ||
2720 | } | ||
2721 | |||
2722 | void LLVoiceClient::addCaptureDevice(const std::string& name) | ||
2723 | { | ||
2724 | + // MBW -- XXX -- do something here | ||
2725 | LL_DEBUGS("Voice") << name << LL_ENDL; | ||
2726 | |||
2727 | mCaptureDevices.push_back(name); | ||
2728 | @@ -2773,13 +2154,15 @@ void LLVoiceClient::setCaptureDevice(const std::string& name) | ||
2729 | } | ||
2730 | |||
2731 | void LLVoiceClient::clearRenderDevices() | ||
2732 | -{ | ||
2733 | +{ | ||
2734 | + // MBW -- XXX -- do something here | ||
2735 | LL_DEBUGS("Voice") << "called" << LL_ENDL; | ||
2736 | mRenderDevices.clear(); | ||
2737 | } | ||
2738 | |||
2739 | void LLVoiceClient::addRenderDevice(const std::string& name) | ||
2740 | { | ||
2741 | + // MBW -- XXX -- do something here | ||
2742 | LL_DEBUGS("Voice") << name << LL_ENDL; | ||
2743 | mRenderDevices.push_back(name); | ||
2744 | } | ||
2745 | @@ -2891,22 +2274,29 @@ void LLVoiceClient::tuningCaptureStopSendMessage() | ||
2746 | |||
2747 | void LLVoiceClient::tuningSetMicVolume(float volume) | ||
2748 | { | ||
2749 | - int scaled_volume = scale_mic_volume(volume); | ||
2750 | - | ||
2751 | - if(scaled_volume != mTuningMicVolume) | ||
2752 | + int scaledVolume = ((int)(volume * 100.0f)) - 100; | ||
2753 | + if(scaledVolume != mTuningMicVolume) | ||
2754 | { | ||
2755 | - mTuningMicVolume = scaled_volume; | ||
2756 | + mTuningMicVolume = scaledVolume; | ||
2757 | mTuningMicVolumeDirty = true; | ||
2758 | } | ||
2759 | } | ||
2760 | |||
2761 | void LLVoiceClient::tuningSetSpeakerVolume(float volume) | ||
2762 | { | ||
2763 | - int scaled_volume = scale_speaker_volume(volume); | ||
2764 | + // incoming volume has the range [0.0 ... 1.0], with 0.5 as the default. | ||
2765 | + // Map it as follows: 0.0 -> -100, 0.5 -> 24, 1.0 -> 50 | ||
2766 | + | ||
2767 | + volume -= 0.5f; // offset volume to the range [-0.5 ... 0.5], with 0 at the default. | ||
2768 | + int scaledVolume = 24; // offset scaledVolume by its default level | ||
2769 | + if(volume < 0.0f) | ||
2770 | + scaledVolume += ((int)(volume * 248.0f)); // (24 - (-100)) * 2 | ||
2771 | + else | ||
2772 | + scaledVolume += ((int)(volume * 52.0f)); // (50 - 24) * 2 | ||
2773 | |||
2774 | - if(scaled_volume != mTuningSpeakerVolume) | ||
2775 | + if(scaledVolume != mTuningSpeakerVolume) | ||
2776 | { | ||
2777 | - mTuningSpeakerVolume = scaled_volume; | ||
2778 | + mTuningSpeakerVolume = scaledVolume; | ||
2779 | mTuningSpeakerVolumeDirty = true; | ||
2780 | } | ||
2781 | } | ||
2782 | @@ -2945,193 +2335,67 @@ void LLVoiceClient::daemonDied() | ||
2783 | // The daemon died, so the connection is gone. Reset everything and start over. | ||
2784 | LL_WARNS("Voice") << "Connection to vivox daemon lost. Resetting state."<< LL_ENDL; | ||
2785 | |||
2786 | + closeSocket(); | ||
2787 | + removeAllParticipants(); | ||
2788 | + | ||
2789 | // Try to relaunch the daemon | ||
2790 | - setState(stateDisableCleanup); | ||
2791 | + setState(stateDisabled); | ||
2792 | } | ||
2793 | |||
2794 | void LLVoiceClient::giveUp() | ||
2795 | { | ||
2796 | // All has failed. Clean up and stop trying. | ||
2797 | closeSocket(); | ||
2798 | - deleteAllSessions(); | ||
2799 | - deleteAllBuddies(); | ||
2800 | + removeAllParticipants(); | ||
2801 | |||
2802 | setState(stateJail); | ||
2803 | } | ||
2804 | |||
2805 | -static void oldSDKTransform (LLVector3 &left, LLVector3 &up, LLVector3 &at, LLVector3d &pos, LLVector3 &vel) | ||
2806 | -{ | ||
2807 | - F32 nat[3], nup[3], nl[3], nvel[3]; // the new at, up, left vectors and the new position and velocity | ||
2808 | - F64 npos[3]; | ||
2809 | - | ||
2810 | - // The original XML command was sent like this: | ||
2811 | - /* | ||
2812 | - << "<Position>" | ||
2813 | - << "<X>" << pos[VX] << "</X>" | ||
2814 | - << "<Y>" << pos[VZ] << "</Y>" | ||
2815 | - << "<Z>" << pos[VY] << "</Z>" | ||
2816 | - << "</Position>" | ||
2817 | - << "<Velocity>" | ||
2818 | - << "<X>" << mAvatarVelocity[VX] << "</X>" | ||
2819 | - << "<Y>" << mAvatarVelocity[VZ] << "</Y>" | ||
2820 | - << "<Z>" << mAvatarVelocity[VY] << "</Z>" | ||
2821 | - << "</Velocity>" | ||
2822 | - << "<AtOrientation>" | ||
2823 | - << "<X>" << l.mV[VX] << "</X>" | ||
2824 | - << "<Y>" << u.mV[VX] << "</Y>" | ||
2825 | - << "<Z>" << a.mV[VX] << "</Z>" | ||
2826 | - << "</AtOrientation>" | ||
2827 | - << "<UpOrientation>" | ||
2828 | - << "<X>" << l.mV[VZ] << "</X>" | ||
2829 | - << "<Y>" << u.mV[VY] << "</Y>" | ||
2830 | - << "<Z>" << a.mV[VZ] << "</Z>" | ||
2831 | - << "</UpOrientation>" | ||
2832 | - << "<LeftOrientation>" | ||
2833 | - << "<X>" << l.mV [VY] << "</X>" | ||
2834 | - << "<Y>" << u.mV [VZ] << "</Y>" | ||
2835 | - << "<Z>" << a.mV [VY] << "</Z>" | ||
2836 | - << "</LeftOrientation>"; | ||
2837 | - */ | ||
2838 | - | ||
2839 | -#if 1 | ||
2840 | - // This was the original transform done when building the XML command | ||
2841 | - nat[0] = left.mV[VX]; | ||
2842 | - nat[1] = up.mV[VX]; | ||
2843 | - nat[2] = at.mV[VX]; | ||
2844 | - | ||
2845 | - nup[0] = left.mV[VZ]; | ||
2846 | - nup[1] = up.mV[VY]; | ||
2847 | - nup[2] = at.mV[VZ]; | ||
2848 | - | ||
2849 | - nl[0] = left.mV[VY]; | ||
2850 | - nl[1] = up.mV[VZ]; | ||
2851 | - nl[2] = at.mV[VY]; | ||
2852 | - | ||
2853 | - npos[0] = pos.mdV[VX]; | ||
2854 | - npos[1] = pos.mdV[VZ]; | ||
2855 | - npos[2] = pos.mdV[VY]; | ||
2856 | - | ||
2857 | - nvel[0] = vel.mV[VX]; | ||
2858 | - nvel[1] = vel.mV[VZ]; | ||
2859 | - nvel[2] = vel.mV[VY]; | ||
2860 | - | ||
2861 | - for(int i=0;i<3;++i) { | ||
2862 | - at.mV[i] = nat[i]; | ||
2863 | - up.mV[i] = nup[i]; | ||
2864 | - left.mV[i] = nl[i]; | ||
2865 | - pos.mdV[i] = npos[i]; | ||
2866 | - } | ||
2867 | - | ||
2868 | - // This was the original transform done in the SDK | ||
2869 | - nat[0] = at.mV[2]; | ||
2870 | - nat[1] = 0; // y component of at vector is always 0, this was up[2] | ||
2871 | - nat[2] = -1 * left.mV[2]; | ||
2872 | - | ||
2873 | - // We override whatever the application gives us | ||
2874 | - nup[0] = 0; // x component of up vector is always 0 | ||
2875 | - nup[1] = 1; // y component of up vector is always 1 | ||
2876 | - nup[2] = 0; // z component of up vector is always 0 | ||
2877 | - | ||
2878 | - nl[0] = at.mV[0]; | ||
2879 | - nl[1] = 0; // y component of left vector is always zero, this was up[0] | ||
2880 | - nl[2] = -1 * left.mV[0]; | ||
2881 | - | ||
2882 | - npos[2] = pos.mdV[2] * -1.0; | ||
2883 | - npos[1] = pos.mdV[1]; | ||
2884 | - npos[0] = pos.mdV[0]; | ||
2885 | - | ||
2886 | - for(int i=0;i<3;++i) { | ||
2887 | - at.mV[i] = nat[i]; | ||
2888 | - up.mV[i] = nup[i]; | ||
2889 | - left.mV[i] = nl[i]; | ||
2890 | - pos.mdV[i] = npos[i]; | ||
2891 | - } | ||
2892 | -#else | ||
2893 | - // This is the compose of the two transforms (at least, that's what I'm trying for) | ||
2894 | - nat[0] = at.mV[VX]; | ||
2895 | - nat[1] = 0; // y component of at vector is always 0, this was up[2] | ||
2896 | - nat[2] = -1 * up.mV[VZ]; | ||
2897 | - | ||
2898 | - // We override whatever the application gives us | ||
2899 | - nup[0] = 0; // x component of up vector is always 0 | ||
2900 | - nup[1] = 1; // y component of up vector is always 1 | ||
2901 | - nup[2] = 0; // z component of up vector is always 0 | ||
2902 | - | ||
2903 | - nl[0] = left.mV[VX]; | ||
2904 | - nl[1] = 0; // y component of left vector is always zero, this was up[0] | ||
2905 | - nl[2] = -1 * left.mV[VY]; | ||
2906 | - | ||
2907 | - npos[0] = pos.mdV[VX]; | ||
2908 | - npos[1] = pos.mdV[VZ]; | ||
2909 | - npos[2] = pos.mdV[VY] * -1.0; | ||
2910 | - | ||
2911 | - nvel[0] = vel.mV[VX]; | ||
2912 | - nvel[1] = vel.mV[VZ]; | ||
2913 | - nvel[2] = vel.mV[VY]; | ||
2914 | - | ||
2915 | - for(int i=0;i<3;++i) { | ||
2916 | - at.mV[i] = nat[i]; | ||
2917 | - up.mV[i] = nup[i]; | ||
2918 | - left.mV[i] = nl[i]; | ||
2919 | - pos.mdV[i] = npos[i]; | ||
2920 | - } | ||
2921 | - | ||
2922 | -#endif | ||
2923 | -} | ||
2924 | - | ||
2925 | void LLVoiceClient::sendPositionalUpdate(void) | ||
2926 | { | ||
2927 | std::ostringstream stream; | ||
2928 | |||
2929 | if(mSpatialCoordsDirty) | ||
2930 | { | ||
2931 | - LLVector3 l, u, a, vel; | ||
2932 | - LLVector3d pos; | ||
2933 | - | ||
2934 | - mSpatialCoordsDirty = false; | ||
2935 | + LLVector3 l, u, a; | ||
2936 | |||
2937 | // Always send both speaker and listener positions together. | ||
2938 | stream << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Session.Set3DPosition.1\">" | ||
2939 | - << "<SessionHandle>" << getAudioSessionHandle() << "</SessionHandle>"; | ||
2940 | + << "<SessionHandle>" << mSessionHandle << "</SessionHandle>"; | ||
2941 | |||
2942 | stream << "<SpeakerPosition>"; | ||
2943 | |||
2944 | -// LL_DEBUGS("Voice") << "Sending speaker position " << mAvatarPosition << LL_ENDL; | ||
2945 | l = mAvatarRot.getLeftRow(); | ||
2946 | u = mAvatarRot.getUpRow(); | ||
2947 | a = mAvatarRot.getFwdRow(); | ||
2948 | - pos = mAvatarPosition; | ||
2949 | - vel = mAvatarVelocity; | ||
2950 | + | ||
2951 | + LL_DEBUGS("Voice") << "Sending speaker position " << mAvatarPosition << LL_ENDL; | ||
2952 | |||
2953 | - // SLIM SDK: the old SDK was doing a transform on the passed coordinates that the new one doesn't do anymore. | ||
2954 | - // The old transform is replicated by this function. | ||
2955 | - oldSDKTransform(l, u, a, pos, vel); | ||
2956 | - | ||
2957 | stream | ||
2958 | << "<Position>" | ||
2959 | - << "<X>" << pos.mdV[VX] << "</X>" | ||
2960 | - << "<Y>" << pos.mdV[VY] << "</Y>" | ||
2961 | - << "<Z>" << pos.mdV[VZ] << "</Z>" | ||
2962 | + << "<X>" << mAvatarPosition[VX] << "</X>" | ||
2963 | + << "<Y>" << mAvatarPosition[VZ] << "</Y>" | ||
2964 | + << "<Z>" << mAvatarPosition[VY] << "</Z>" | ||
2965 | << "</Position>" | ||
2966 | << "<Velocity>" | ||
2967 | - << "<X>" << vel.mV[VX] << "</X>" | ||
2968 | - << "<Y>" << vel.mV[VY] << "</Y>" | ||
2969 | - << "<Z>" << vel.mV[VZ] << "</Z>" | ||
2970 | + << "<X>" << mAvatarVelocity[VX] << "</X>" | ||
2971 | + << "<Y>" << mAvatarVelocity[VZ] << "</Y>" | ||
2972 | + << "<Z>" << mAvatarVelocity[VY] << "</Z>" | ||
2973 | << "</Velocity>" | ||
2974 | << "<AtOrientation>" | ||
2975 | - << "<X>" << a.mV[VX] << "</X>" | ||
2976 | - << "<Y>" << a.mV[VY] << "</Y>" | ||
2977 | - << "<Z>" << a.mV[VZ] << "</Z>" | ||
2978 | + << "<X>" << l.mV[VX] << "</X>" | ||
2979 | + << "<Y>" << u.mV[VX] << "</Y>" | ||
2980 | + << "<Z>" << a.mV[VX] << "</Z>" | ||
2981 | << "</AtOrientation>" | ||
2982 | << "<UpOrientation>" | ||
2983 | - << "<X>" << u.mV[VX] << "</X>" | ||
2984 | + << "<X>" << l.mV[VZ] << "</X>" | ||
2985 | << "<Y>" << u.mV[VY] << "</Y>" | ||
2986 | - << "<Z>" << u.mV[VZ] << "</Z>" | ||
2987 | + << "<Z>" << a.mV[VZ] << "</Z>" | ||
2988 | << "</UpOrientation>" | ||
2989 | << "<LeftOrientation>" | ||
2990 | - << "<X>" << l.mV [VX] << "</X>" | ||
2991 | - << "<Y>" << l.mV [VY] << "</Y>" | ||
2992 | - << "<Z>" << l.mV [VZ] << "</Z>" | ||
2993 | + << "<X>" << l.mV [VY] << "</X>" | ||
2994 | + << "<Y>" << u.mV [VZ] << "</Y>" | ||
2995 | + << "<Z>" << a.mV [VY] << "</Z>" | ||
2996 | << "</LeftOrientation>"; | ||
2997 | |||
2998 | stream << "</SpeakerPosition>"; | ||
2999 | @@ -3167,158 +2431,43 @@ void LLVoiceClient::sendPositionalUpdate(void) | ||
3000 | l = earRot.getLeftRow(); | ||
3001 | u = earRot.getUpRow(); | ||
3002 | a = earRot.getFwdRow(); | ||
3003 | - pos = earPosition; | ||
3004 | - vel = earVelocity; | ||
3005 | |||
3006 | -// LL_DEBUGS("Voice") << "Sending listener position " << earPosition << LL_ENDL; | ||
3007 | - | ||
3008 | - oldSDKTransform(l, u, a, pos, vel); | ||
3009 | - | ||
3010 | + LL_DEBUGS("Voice") << "Sending listener position " << earPosition << LL_ENDL; | ||
3011 | + | ||
3012 | stream | ||
3013 | << "<Position>" | ||
3014 | - << "<X>" << pos.mdV[VX] << "</X>" | ||
3015 | - << "<Y>" << pos.mdV[VY] << "</Y>" | ||
3016 | - << "<Z>" << pos.mdV[VZ] << "</Z>" | ||
3017 | + << "<X>" << earPosition[VX] << "</X>" | ||
3018 | + << "<Y>" << earPosition[VZ] << "</Y>" | ||
3019 | + << "<Z>" << earPosition[VY] << "</Z>" | ||
3020 | << "</Position>" | ||
3021 | << "<Velocity>" | ||
3022 | - << "<X>" << vel.mV[VX] << "</X>" | ||
3023 | - << "<Y>" << vel.mV[VY] << "</Y>" | ||
3024 | - << "<Z>" << vel.mV[VZ] << "</Z>" | ||
3025 | + << "<X>" << earVelocity[VX] << "</X>" | ||
3026 | + << "<Y>" << earVelocity[VZ] << "</Y>" | ||
3027 | + << "<Z>" << earVelocity[VY] << "</Z>" | ||
3028 | << "</Velocity>" | ||
3029 | << "<AtOrientation>" | ||
3030 | - << "<X>" << a.mV[VX] << "</X>" | ||
3031 | - << "<Y>" << a.mV[VY] << "</Y>" | ||
3032 | - << "<Z>" << a.mV[VZ] << "</Z>" | ||
3033 | + << "<X>" << l.mV[VX] << "</X>" | ||
3034 | + << "<Y>" << u.mV[VX] << "</Y>" | ||
3035 | + << "<Z>" << a.mV[VX] << "</Z>" | ||
3036 | << "</AtOrientation>" | ||
3037 | << "<UpOrientation>" | ||
3038 | - << "<X>" << u.mV[VX] << "</X>" | ||
3039 | + << "<X>" << l.mV[VZ] << "</X>" | ||
3040 | << "<Y>" << u.mV[VY] << "</Y>" | ||
3041 | - << "<Z>" << u.mV[VZ] << "</Z>" | ||
3042 | + << "<Z>" << a.mV[VZ] << "</Z>" | ||
3043 | << "</UpOrientation>" | ||
3044 | << "<LeftOrientation>" | ||
3045 | - << "<X>" << l.mV [VX] << "</X>" | ||
3046 | - << "<Y>" << l.mV [VY] << "</Y>" | ||
3047 | - << "<Z>" << l.mV [VZ] << "</Z>" | ||
3048 | + << "<X>" << l.mV [VY] << "</X>" | ||
3049 | + << "<Y>" << u.mV [VZ] << "</Y>" | ||
3050 | + << "<Z>" << a.mV [VY] << "</Z>" | ||
3051 | << "</LeftOrientation>"; | ||
3052 | |||
3053 | - | ||
3054 | stream << "</ListenerPosition>"; | ||
3055 | |||
3056 | stream << "</Request>\n\n\n"; | ||
3057 | } | ||
3058 | - | ||
3059 | - if(mAudioSession && mAudioSession->mVolumeDirty) | ||
3060 | - { | ||
3061 | - participantMap::iterator iter = mAudioSession->mParticipantsByURI.begin(); | ||
3062 | - | ||
3063 | - mAudioSession->mVolumeDirty = false; | ||
3064 | - | ||
3065 | - for(; iter != mAudioSession->mParticipantsByURI.end(); iter++) | ||
3066 | - { | ||
3067 | - participantState *p = iter->second; | ||
3068 | - | ||
3069 | - if(p->mVolumeDirty) | ||
3070 | - { | ||
3071 | - // Can't set volume/mute for yourself | ||
3072 | - if(!p->mIsSelf) | ||
3073 | - { | ||
3074 | - int volume = p->mUserVolume; | ||
3075 | - bool mute = p->mOnMuteList; | ||
3076 | - | ||
3077 | - // SLIM SDK: scale volume from 0-400 (with 100 as "normal") to 0-100 (with 56 as "normal") | ||
3078 | - if(volume < 100) | ||
3079 | - volume = (volume * 56) / 100; | ||
3080 | - else | ||
3081 | - volume = (((volume - 100) * (100 - 56)) / 300) + 56; | ||
3082 | - | ||
3083 | - if(mute) | ||
3084 | - { | ||
3085 | - // SetParticipantMuteForMe doesn't work in p2p sessions. | ||
3086 | - // If we want the user to be muted, set their volume to 0 as well. | ||
3087 | - // This isn't perfect, but it will at least reduce their volume to a minimum. | ||
3088 | - volume = 0; | ||
3089 | - } | ||
3090 | - | ||
3091 | - if(volume == 0) | ||
3092 | - mute = true; | ||
3093 | - | ||
3094 | - LL_DEBUGS("Voice") << "Setting volume/mute for avatar " << p->mAvatarID << " to " << volume << (mute?"/true":"/false") << LL_ENDL; | ||
3095 | - | ||
3096 | - // SLIM SDK: Send both volume and mute commands. | ||
3097 | - | ||
3098 | - // Send a "volume for me" command for the user. | ||
3099 | - stream << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Session.SetParticipantVolumeForMe.1\">" | ||
3100 | - << "<SessionHandle>" << getAudioSessionHandle() << "</SessionHandle>" | ||
3101 | - << "<ParticipantURI>" << p->mURI << "</ParticipantURI>" | ||
3102 | - << "<Volume>" << volume << "</Volume>" | ||
3103 | - << "</Request>\n\n\n"; | ||
3104 | - | ||
3105 | - // Send a "mute for me" command for the user | ||
3106 | - stream << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Session.SetParticipantMuteForMe.1\">" | ||
3107 | - << "<SessionHandle>" << getAudioSessionHandle() << "</SessionHandle>" | ||
3108 | - << "<ParticipantURI>" << p->mURI << "</ParticipantURI>" | ||
3109 | - << "<Mute>" << (mute?"1":"0") << "</Mute>" | ||
3110 | - << "</Request>\n\n\n"; | ||
3111 | - } | ||
3112 | - | ||
3113 | - p->mVolumeDirty = false; | ||
3114 | - } | ||
3115 | - } | ||
3116 | - } | ||
3117 | - | ||
3118 | - buildLocalAudioUpdates(stream); | ||
3119 | - | ||
3120 | - if(!stream.str().empty()) | ||
3121 | - { | ||
3122 | - writeString(stream.str()); | ||
3123 | - } | ||
3124 | - | ||
3125 | - // Friends list updates can be huge, especially on the first voice login of an account with lots of friends. | ||
3126 | - // Batching them all together can choke SLVoice, so send them in separate writes. | ||
3127 | - sendFriendsListUpdates(); | ||
3128 | -} | ||
3129 | - | ||
3130 | -void LLVoiceClient::buildSetCaptureDevice(std::ostringstream &stream) | ||
3131 | -{ | ||
3132 | - if(mCaptureDeviceDirty) | ||
3133 | - { | ||
3134 | - LL_DEBUGS("Voice") << "Setting input device = \"" << mCaptureDevice << "\"" << LL_ENDL; | ||
3135 | - | ||
3136 | - stream | ||
3137 | - << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Aux.SetCaptureDevice.1\">" | ||
3138 | - << "<CaptureDeviceSpecifier>" << mCaptureDevice << "</CaptureDeviceSpecifier>" | ||
3139 | - << "</Request>" | ||
3140 | - << "\n\n\n"; | ||
3141 | - | ||
3142 | - mCaptureDeviceDirty = false; | ||
3143 | - } | ||
3144 | -} | ||
3145 | - | ||
3146 | -void LLVoiceClient::buildSetRenderDevice(std::ostringstream &stream) | ||
3147 | -{ | ||
3148 | - if(mRenderDeviceDirty) | ||
3149 | - { | ||
3150 | - LL_DEBUGS("Voice") << "Setting output device = \"" << mRenderDevice << "\"" << LL_ENDL; | ||
3151 | - | ||
3152 | - stream | ||
3153 | - << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Aux.SetRenderDevice.1\">" | ||
3154 | - << "<RenderDeviceSpecifier>" << mRenderDevice << "</RenderDeviceSpecifier>" | ||
3155 | - << "</Request>" | ||
3156 | - << "\n\n\n"; | ||
3157 | - mRenderDeviceDirty = false; | ||
3158 | - } | ||
3159 | -} | ||
3160 | - | ||
3161 | -void LLVoiceClient::buildLocalAudioUpdates(std::ostringstream &stream) | ||
3162 | -{ | ||
3163 | - buildSetCaptureDevice(stream); | ||
3164 | - | ||
3165 | - buildSetRenderDevice(stream); | ||
3166 | |||
3167 | if(mPTTDirty) | ||
3168 | { | ||
3169 | - mPTTDirty = false; | ||
3170 | - | ||
3171 | // Send a local mute command. | ||
3172 | // NOTE that the state of "PTT" is the inverse of "local mute". | ||
3173 | // (i.e. when PTT is true, we send a mute command with "false", and vice versa) | ||
3174 | @@ -3329,337 +2478,119 @@ void LLVoiceClient::buildLocalAudioUpdates(std::ostringstream &stream) | ||
3175 | << "<ConnectorHandle>" << mConnectorHandle << "</ConnectorHandle>" | ||
3176 | << "<Value>" << (mPTT?"false":"true") << "</Value>" | ||
3177 | << "</Request>\n\n\n"; | ||
3178 | - | ||
3179 | + | ||
3180 | } | ||
3181 | + | ||
3182 | + if(mVolumeDirty) | ||
3183 | + { | ||
3184 | + participantMap::iterator iter = mParticipantMap.begin(); | ||
3185 | + | ||
3186 | + for(; iter != mParticipantMap.end(); iter++) | ||
3187 | + { | ||
3188 | + participantState *p = iter->second; | ||
3189 | + | ||
3190 | + if(p->mVolumeDirty) | ||
3191 | + { | ||
3192 | + int volume = p->mOnMuteList?0:p->mUserVolume; | ||
3193 | + | ||
3194 | + LL_INFOS("Voice") << "Setting volume for avatar " << p->mAvatarID << " to " << volume << LL_ENDL; | ||
3195 | + | ||
3196 | + // Send a mute/unumte command for the user (actually "volume for me"). | ||
3197 | + stream << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Session.SetParticipantVolumeForMe.1\">" | ||
3198 | + << "<SessionHandle>" << mSessionHandle << "</SessionHandle>" | ||
3199 | + << "<ParticipantURI>" << p->mURI << "</ParticipantURI>" | ||
3200 | + << "<Volume>" << volume << "</Volume>" | ||
3201 | + << "</Request>\n\n\n"; | ||
3202 | |||
3203 | + p->mVolumeDirty = false; | ||
3204 | + } | ||
3205 | + } | ||
3206 | + } | ||
3207 | + | ||
3208 | if(mSpeakerMuteDirty) | ||
3209 | { | ||
3210 | - const char *muteval = ((mSpeakerVolume == 0)?"true":"false"); | ||
3211 | - | ||
3212 | - mSpeakerMuteDirty = false; | ||
3213 | - | ||
3214 | + const char *muteval = ((mSpeakerVolume == -100)?"true":"false"); | ||
3215 | LL_INFOS("Voice") << "Setting speaker mute to " << muteval << LL_ENDL; | ||
3216 | |||
3217 | stream << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Connector.MuteLocalSpeaker.1\">" | ||
3218 | << "<ConnectorHandle>" << mConnectorHandle << "</ConnectorHandle>" | ||
3219 | << "<Value>" << muteval << "</Value>" | ||
3220 | - << "</Request>\n\n\n"; | ||
3221 | - | ||
3222 | + << "</Request>\n\n\n"; | ||
3223 | } | ||
3224 | |||
3225 | if(mSpeakerVolumeDirty) | ||
3226 | { | ||
3227 | - mSpeakerVolumeDirty = false; | ||
3228 | - | ||
3229 | LL_INFOS("Voice") << "Setting speaker volume to " << mSpeakerVolume << LL_ENDL; | ||
3230 | |||
3231 | stream << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Connector.SetLocalSpeakerVolume.1\">" | ||
3232 | << "<ConnectorHandle>" << mConnectorHandle << "</ConnectorHandle>" | ||
3233 | << "<Value>" << mSpeakerVolume << "</Value>" | ||
3234 | - << "</Request>\n\n\n"; | ||
3235 | - | ||
3236 | + << "</Request>\n\n\n"; | ||
3237 | } | ||
3238 | |||
3239 | if(mMicVolumeDirty) | ||
3240 | { | ||
3241 | - mMicVolumeDirty = false; | ||
3242 | - | ||
3243 | LL_INFOS("Voice") << "Setting mic volume to " << mMicVolume << LL_ENDL; | ||
3244 | |||
3245 | stream << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Connector.SetLocalMicVolume.1\">" | ||
3246 | << "<ConnectorHandle>" << mConnectorHandle << "</ConnectorHandle>" | ||
3247 | << "<Value>" << mMicVolume << "</Value>" | ||
3248 | - << "</Request>\n\n\n"; | ||
3249 | + << "</Request>\n\n\n"; | ||
3250 | } | ||
3251 | |||
3252 | |||
3253 | -} | ||
3254 | - | ||
3255 | -void LLVoiceClient::checkFriend(const LLUUID& id) | ||
3256 | -{ | ||
3257 | - std::string name; | ||
3258 | - buddyListEntry *buddy = findBuddy(id); | ||
3259 | - | ||
3260 | - // Make sure we don't add a name before it's been looked up. | ||
3261 | - if(gCacheName->getFullName(id, name)) | ||
3262 | + // MBW -- XXX -- Maybe check to make sure the capture/render devices are in the current list here? | ||
3263 | + if(mCaptureDeviceDirty) | ||
3264 | { | ||
3265 | - | ||
3266 | - const LLRelationship* relationInfo = LLAvatarTracker::instance().getBuddyInfo(id); | ||
3267 | - bool canSeeMeOnline = false; | ||
3268 | - if(relationInfo && relationInfo->isRightGrantedTo(LLRelationship::GRANT_ONLINE_STATUS)) | ||
3269 | - canSeeMeOnline = true; | ||
3270 | - | ||
3271 | - // When we get here, mNeedsSend is true and mInSLFriends is false. Change them as necessary. | ||
3272 | - | ||
3273 | - if(buddy) | ||
3274 | - { | ||
3275 | - // This buddy is already in both lists. | ||
3276 | - | ||
3277 | - if(name != buddy->mDisplayName) | ||
3278 | - { | ||
3279 | - // The buddy is in the list with the wrong name. Update it with the correct name. | ||
3280 | - LL_WARNS("Voice") << "Buddy " << id << " has wrong name (\"" << buddy->mDisplayName << "\" should be \"" << name << "\"), updating."<< LL_ENDL; | ||
3281 | - buddy->mDisplayName = name; | ||
3282 | - buddy->mNeedsNameUpdate = true; // This will cause the buddy to be resent. | ||
3283 | - } | ||
3284 | - } | ||
3285 | - else | ||
3286 | - { | ||
3287 | - // This buddy was not in the vivox list, needs to be added. | ||
3288 | - buddy = addBuddy(sipURIFromID(id), name); | ||
3289 | - buddy->mUUID = id; | ||
3290 | - } | ||
3291 | - | ||
3292 | - // In all the above cases, the buddy is in the SL friends list (which is how we got here). | ||
3293 | - buddy->mInSLFriends = true; | ||
3294 | - buddy->mCanSeeMeOnline = canSeeMeOnline; | ||
3295 | - buddy->mNameResolved = true; | ||
3296 | - | ||
3297 | + buildSetCaptureDevice(stream); | ||
3298 | } | ||
3299 | - else | ||
3300 | + | ||
3301 | + if(mRenderDeviceDirty) | ||
3302 | { | ||
3303 | - // This name hasn't been looked up yet. Don't do anything with this buddy list entry until it has. | ||
3304 | - if(buddy) | ||
3305 | - { | ||
3306 | - buddy->mNameResolved = false; | ||
3307 | - } | ||
3308 | - | ||
3309 | - // Initiate a lookup. | ||
3310 | - // The "lookup completed" callback will ensure that the friends list is rechecked after it completes. | ||
3311 | - lookupName(id); | ||
3312 | + buildSetRenderDevice(stream); | ||
3313 | } | ||
3314 | -} | ||
3315 | - | ||
3316 | -void LLVoiceClient::clearAllLists() | ||
3317 | -{ | ||
3318 | - // FOR TESTING ONLY | ||
3319 | |||
3320 | - // This will send the necessary commands to delete ALL buddies, autoaccept rules, and block rules SLVoice tells us about. | ||
3321 | - buddyListMap::iterator buddy_it; | ||
3322 | - for(buddy_it = mBuddyListMap.begin(); buddy_it != mBuddyListMap.end();) | ||
3323 | + mSpatialCoordsDirty = false; | ||
3324 | + mPTTDirty = false; | ||
3325 | + mVolumeDirty = false; | ||
3326 | + mSpeakerVolumeDirty = false; | ||
3327 | + mMicVolumeDirty = false; | ||
3328 | + mSpeakerMuteDirty = false; | ||
3329 | + mCaptureDeviceDirty = false; | ||
3330 | + mRenderDeviceDirty = false; | ||
3331 | + | ||
3332 | + if(!stream.str().empty()) | ||
3333 | { | ||
3334 | - buddyListEntry *buddy = buddy_it->second; | ||
3335 | - buddy_it++; | ||
3336 | - | ||
3337 | - std::ostringstream stream; | ||
3338 | - | ||
3339 | - if(buddy->mInVivoxBuddies) | ||
3340 | - { | ||
3341 | - // delete this entry from the vivox buddy list | ||
3342 | - buddy->mInVivoxBuddies = false; | ||
3343 | - LL_DEBUGS("Voice") << "delete " << buddy->mURI << " (" << buddy->mDisplayName << ")" << LL_ENDL; | ||
3344 | - stream << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Account.BuddyDelete.1\">" | ||
3345 | - << "<AccountHandle>" << mAccountHandle << "</AccountHandle>" | ||
3346 | - << "<BuddyURI>" << buddy->mURI << "</BuddyURI>" | ||
3347 | - << "</Request>\n\n\n"; | ||
3348 | - } | ||
3349 | - | ||
3350 | - if(buddy->mHasBlockListEntry) | ||
3351 | - { | ||
3352 | - // Delete the associated block list entry (so the block list doesn't fill up with junk) | ||
3353 | - buddy->mHasBlockListEntry = false; | ||
3354 | - stream << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Account.DeleteBlockRule.1\">" | ||
3355 | - << "<AccountHandle>" << mAccountHandle << "</AccountHandle>" | ||
3356 | - << "<BlockMask>" << buddy->mURI << "</BlockMask>" | ||
3357 | - << "</Request>\n\n\n"; | ||
3358 | - } | ||
3359 | - if(buddy->mHasAutoAcceptListEntry) | ||
3360 | - { | ||
3361 | - // Delete the associated auto-accept list entry (so the auto-accept list doesn't fill up with junk) | ||
3362 | - buddy->mHasAutoAcceptListEntry = false; | ||
3363 | - stream << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Account.DeleteAutoAcceptRule.1\">" | ||
3364 | - << "<AccountHandle>" << mAccountHandle << "</AccountHandle>" | ||
3365 | - << "<AutoAcceptMask>" << buddy->mURI << "</AutoAcceptMask>" | ||
3366 | - << "</Request>\n\n\n"; | ||
3367 | - } | ||
3368 | - | ||
3369 | writeString(stream.str()); | ||
3370 | - | ||
3371 | } | ||
3372 | } | ||
3373 | |||
3374 | -void LLVoiceClient::sendFriendsListUpdates() | ||
3375 | +void LLVoiceClient::buildSetCaptureDevice(std::ostringstream &stream) | ||
3376 | { | ||
3377 | - if(mBuddyListMapPopulated && mBlockRulesListReceived && mAutoAcceptRulesListReceived && mFriendsListDirty) | ||
3378 | - { | ||
3379 | - mFriendsListDirty = false; | ||
3380 | - | ||
3381 | - if(0) | ||
3382 | - { | ||
3383 | - // FOR TESTING ONLY -- clear all buddy list, block list, and auto-accept list entries. | ||
3384 | - clearAllLists(); | ||
3385 | - return; | ||
3386 | - } | ||
3387 | - | ||
3388 | - LL_INFOS("Voice") << "Checking vivox buddy list against friends list..." << LL_ENDL; | ||
3389 | - | ||
3390 | - buddyListMap::iterator buddy_it; | ||
3391 | - for(buddy_it = mBuddyListMap.begin(); buddy_it != mBuddyListMap.end(); buddy_it++) | ||
3392 | - { | ||
3393 | - // reset the temp flags in the local buddy list | ||
3394 | - buddy_it->second->mInSLFriends = false; | ||
3395 | - } | ||
3396 | - | ||
3397 | - // correlate with the friends list | ||
3398 | - { | ||
3399 | - LLCollectAllBuddies collect; | ||
3400 | - LLAvatarTracker::instance().applyFunctor(collect); | ||
3401 | - LLCollectAllBuddies::buddy_map_t::const_iterator it = collect.mOnline.begin(); | ||
3402 | - LLCollectAllBuddies::buddy_map_t::const_iterator end = collect.mOnline.end(); | ||
3403 | - | ||
3404 | - for ( ; it != end; ++it) | ||
3405 | - { | ||
3406 | - checkFriend(it->second); | ||
3407 | - } | ||
3408 | - it = collect.mOffline.begin(); | ||
3409 | - end = collect.mOffline.end(); | ||
3410 | - for ( ; it != end; ++it) | ||
3411 | - { | ||
3412 | - checkFriend(it->second); | ||
3413 | - } | ||
3414 | - } | ||
3415 | - | ||
3416 | - LL_INFOS("Voice") << "Sending friend list updates..." << LL_ENDL; | ||
3417 | - | ||
3418 | - for(buddy_it = mBuddyListMap.begin(); buddy_it != mBuddyListMap.end();) | ||
3419 | - { | ||
3420 | - buddyListEntry *buddy = buddy_it->second; | ||
3421 | - buddy_it++; | ||
3422 | - | ||
3423 | - // Ignore entries that aren't resolved yet. | ||
3424 | - if(buddy->mNameResolved) | ||
3425 | - { | ||
3426 | - std::ostringstream stream; | ||
3427 | - | ||
3428 | - if(buddy->mInSLFriends && (!buddy->mInVivoxBuddies || buddy->mNeedsNameUpdate)) | ||
3429 | - { | ||
3430 | - if(mNumberOfAliases > 0) | ||
3431 | - { | ||
3432 | - // Add (or update) this entry in the vivox buddy list | ||
3433 | - buddy->mInVivoxBuddies = true; | ||
3434 | - buddy->mNeedsNameUpdate = false; | ||
3435 | - LL_DEBUGS("Voice") << "add/update " << buddy->mURI << " (" << buddy->mDisplayName << ")" << LL_ENDL; | ||
3436 | - stream | ||
3437 | - << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Account.BuddySet.1\">" | ||
3438 | - << "<AccountHandle>" << mAccountHandle << "</AccountHandle>" | ||
3439 | - << "<BuddyURI>" << buddy->mURI << "</BuddyURI>" | ||
3440 | - << "<DisplayName>" << buddy->mDisplayName << "</DisplayName>" | ||
3441 | - << "<BuddyData></BuddyData>" // Without this, SLVoice doesn't seem to parse the command. | ||
3442 | - << "<GroupID>0</GroupID>" | ||
3443 | - << "</Request>\n\n\n"; | ||
3444 | - } | ||
3445 | - } | ||
3446 | - else if(!buddy->mInSLFriends) | ||
3447 | - { | ||
3448 | - // This entry no longer exists in your SL friends list. Remove all traces of it from the Vivox buddy list. | ||
3449 | - if(buddy->mInVivoxBuddies) | ||
3450 | - { | ||
3451 | - // delete this entry from the vivox buddy list | ||
3452 | - buddy->mInVivoxBuddies = false; | ||
3453 | - LL_DEBUGS("Voice") << "delete " << buddy->mURI << " (" << buddy->mDisplayName << ")" << LL_ENDL; | ||
3454 | - stream << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Account.BuddyDelete.1\">" | ||
3455 | - << "<AccountHandle>" << mAccountHandle << "</AccountHandle>" | ||
3456 | - << "<BuddyURI>" << buddy->mURI << "</BuddyURI>" | ||
3457 | - << "</Request>\n\n\n"; | ||
3458 | - } | ||
3459 | - | ||
3460 | - if(buddy->mHasBlockListEntry) | ||
3461 | - { | ||
3462 | - // Delete the associated block list entry, if any | ||
3463 | - buddy->mHasBlockListEntry = false; | ||
3464 | - stream << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Account.DeleteBlockRule.1\">" | ||
3465 | - << "<AccountHandle>" << mAccountHandle << "</AccountHandle>" | ||
3466 | - << "<BlockMask>" << buddy->mURI << "</BlockMask>" | ||
3467 | - << "</Request>\n\n\n"; | ||
3468 | - } | ||
3469 | - if(buddy->mHasAutoAcceptListEntry) | ||
3470 | - { | ||
3471 | - // Delete the associated auto-accept list entry, if any | ||
3472 | - buddy->mHasAutoAcceptListEntry = false; | ||
3473 | - stream << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Account.DeleteAutoAcceptRule.1\">" | ||
3474 | - << "<AccountHandle>" << mAccountHandle << "</AccountHandle>" | ||
3475 | - << "<AutoAcceptMask>" << buddy->mURI << "</AutoAcceptMask>" | ||
3476 | - << "</Request>\n\n\n"; | ||
3477 | - } | ||
3478 | - } | ||
3479 | - | ||
3480 | - if(buddy->mInSLFriends) | ||
3481 | - { | ||
3482 | - | ||
3483 | - if(buddy->mCanSeeMeOnline) | ||
3484 | - { | ||
3485 | - // Buddy should not be blocked. | ||
3486 | - | ||
3487 | - // If this buddy doesn't already have either a block or autoaccept list entry, we'll update their status when we receive a SubscriptionEvent. | ||
3488 | - | ||
3489 | - // If the buddy has a block list entry, delete it. | ||
3490 | - if(buddy->mHasBlockListEntry) | ||
3491 | - { | ||
3492 | - buddy->mHasBlockListEntry = false; | ||
3493 | - stream << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Account.DeleteBlockRule.1\">" | ||
3494 | - << "<AccountHandle>" << mAccountHandle << "</AccountHandle>" | ||
3495 | - << "<BlockMask>" << buddy->mURI << "</BlockMask>" | ||
3496 | - << "</Request>\n\n\n"; | ||
3497 | - | ||
3498 | - | ||
3499 | - // If we just deleted a block list entry, add an auto-accept entry. | ||
3500 | - if(!buddy->mHasAutoAcceptListEntry) | ||
3501 | - { | ||
3502 | - buddy->mHasAutoAcceptListEntry = true; | ||
3503 | - stream << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Account.CreateAutoAcceptRule.1\">" | ||
3504 | - << "<AccountHandle>" << mAccountHandle << "</AccountHandle>" | ||
3505 | - << "<AutoAcceptMask>" << buddy->mURI << "</AutoAcceptMask>" | ||
3506 | - << "<AutoAddAsBuddy>0</AutoAddAsBuddy>" | ||
3507 | - << "</Request>\n\n\n"; | ||
3508 | - } | ||
3509 | - } | ||
3510 | - } | ||
3511 | - else | ||
3512 | - { | ||
3513 | - // Buddy should be blocked. | ||
3514 | - | ||
3515 | - // If this buddy doesn't already have either a block or autoaccept list entry, we'll update their status when we receive a SubscriptionEvent. | ||
3516 | - | ||
3517 | - // If this buddy has an autoaccept entry, delete it | ||
3518 | - if(buddy->mHasAutoAcceptListEntry) | ||
3519 | - { | ||
3520 | - buddy->mHasAutoAcceptListEntry = false; | ||
3521 | - stream << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Account.DeleteAutoAcceptRule.1\">" | ||
3522 | - << "<AccountHandle>" << mAccountHandle << "</AccountHandle>" | ||
3523 | - << "<AutoAcceptMask>" << buddy->mURI << "</AutoAcceptMask>" | ||
3524 | - << "</Request>\n\n\n"; | ||
3525 | - | ||
3526 | - // If we just deleted an auto-accept entry, add a block list entry. | ||
3527 | - if(!buddy->mHasBlockListEntry) | ||
3528 | - { | ||
3529 | - buddy->mHasBlockListEntry = true; | ||
3530 | - stream << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Account.CreateBlockRule.1\">" | ||
3531 | - << "<AccountHandle>" << mAccountHandle << "</AccountHandle>" | ||
3532 | - << "<BlockMask>" << buddy->mURI << "</BlockMask>" | ||
3533 | - << "<PresenceOnly>1</PresenceOnly>" | ||
3534 | - << "</Request>\n\n\n"; | ||
3535 | - } | ||
3536 | - } | ||
3537 | - } | ||
3538 | + LL_DEBUGS("Voice") << "Setting input device = \"" << mCaptureDevice << "\"" << LL_ENDL; | ||
3539 | + | ||
3540 | + stream | ||
3541 | + << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Aux.SetCaptureDevice.1\">" | ||
3542 | + << "<CaptureDeviceSpecifier>" << mCaptureDevice << "</CaptureDeviceSpecifier>" | ||
3543 | + << "</Request>" | ||
3544 | + << "\n\n\n"; | ||
3545 | +} | ||
3546 | |||
3547 | - if(!buddy->mInSLFriends && !buddy->mInVivoxBuddies) | ||
3548 | - { | ||
3549 | - // Delete this entry from the local buddy list. This should NOT invalidate the iterator, | ||
3550 | - // since it has already been incremented to the next entry. | ||
3551 | - deleteBuddy(buddy->mURI); | ||
3552 | - } | ||
3553 | +void LLVoiceClient::buildSetRenderDevice(std::ostringstream &stream) | ||
3554 | +{ | ||
3555 | + LL_DEBUGS("Voice") << "Setting output device = \"" << mRenderDevice << "\"" << LL_ENDL; | ||
3556 | |||
3557 | - } | ||
3558 | - writeString(stream.str()); | ||
3559 | - } | ||
3560 | - } | ||
3561 | - } | ||
3562 | + stream | ||
3563 | + << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Aux.SetRenderDevice.1\">" | ||
3564 | + << "<RenderDeviceSpecifier>" << mRenderDevice << "</RenderDeviceSpecifier>" | ||
3565 | + << "</Request>" | ||
3566 | + << "\n\n\n"; | ||
3567 | } | ||
3568 | |||
3569 | ///////////////////////////// | ||
3570 | // Response/Event handlers | ||
3571 | |||
3572 | -void LLVoiceClient::connectorCreateResponse(int statusCode, std::string &statusString, std::string &connectorHandle, std::string &versionID) | ||
3573 | +void LLVoiceClient::connectorCreateResponse(int statusCode, std::string &statusString, std::string &connectorHandle) | ||
3574 | { | ||
3575 | if(statusCode != 0) | ||
3576 | { | ||
3577 | @@ -3669,7 +2600,6 @@ void LLVoiceClient::connectorCreateResponse(int statusCode, std::string &statusS | ||
3578 | else | ||
3579 | { | ||
3580 | // Connector created, move forward. | ||
3581 | - LL_INFOS("Voice") << "Connector.Create succeeded, Vivox SDK version is " << versionID << LL_ENDL; | ||
3582 | mConnectorHandle = connectorHandle; | ||
3583 | if(getState() == stateConnectorStarting) | ||
3584 | { | ||
3585 | @@ -3678,7 +2608,7 @@ void LLVoiceClient::connectorCreateResponse(int statusCode, std::string &statusS | ||
3586 | } | ||
3587 | } | ||
3588 | |||
3589 | -void LLVoiceClient::loginResponse(int statusCode, std::string &statusString, std::string &accountHandle, int numberOfAliases) | ||
3590 | +void LLVoiceClient::loginResponse(int statusCode, std::string &statusString, std::string &accountHandle) | ||
3591 | { | ||
3592 | LL_DEBUGS("Voice") << "Account.Login response (" << statusCode << "): " << statusString << LL_ENDL; | ||
3593 | |||
3594 | @@ -3699,8 +2629,7 @@ void LLVoiceClient::loginResponse(int statusCode, std::string &statusString, std | ||
3595 | { | ||
3596 | // Login succeeded, move forward. | ||
3597 | mAccountHandle = accountHandle; | ||
3598 | - mNumberOfAliases = numberOfAliases; | ||
3599 | - // This needs to wait until the AccountLoginStateChangeEvent is received. | ||
3600 | + // MBW -- XXX -- This needs to wait until the LoginStateChangeEvent is received. | ||
3601 | // if(getState() == stateLoggingIn) | ||
3602 | // { | ||
3603 | // setState(stateLoggedIn); | ||
3604 | @@ -3708,91 +2637,106 @@ void LLVoiceClient::loginResponse(int statusCode, std::string &statusString, std | ||
3605 | } | ||
3606 | } | ||
3607 | |||
3608 | -void LLVoiceClient::sessionCreateResponse(std::string &requestId, int statusCode, std::string &statusString, std::string &sessionHandle) | ||
3609 | -{ | ||
3610 | - sessionState *session = findSessionBeingCreatedByURI(requestId); | ||
3611 | - | ||
3612 | - if(session) | ||
3613 | - { | ||
3614 | - session->mCreateInProgress = false; | ||
3615 | - } | ||
3616 | - | ||
3617 | +void LLVoiceClient::channelGetListResponse(int statusCode, std::string &statusString) | ||
3618 | +{ | ||
3619 | if(statusCode != 0) | ||
3620 | { | ||
3621 | - LL_WARNS("Voice") << "Session.Create response failure (" << statusCode << "): " << statusString << LL_ENDL; | ||
3622 | - if(session) | ||
3623 | - { | ||
3624 | - session->mErrorStatusCode = statusCode; | ||
3625 | - session->mErrorStatusString = statusString; | ||
3626 | - if(session == mAudioSession) | ||
3627 | - { | ||
3628 | - setState(stateJoinSessionFailed); | ||
3629 | - } | ||
3630 | - else | ||
3631 | - { | ||
3632 | - reapSession(session); | ||
3633 | - } | ||
3634 | - } | ||
3635 | + LL_WARNS("Voice") << "Account.ChannelGetList response failure: " << statusString << LL_ENDL; | ||
3636 | + switchChannel(); | ||
3637 | } | ||
3638 | else | ||
3639 | { | ||
3640 | - LL_INFOS("Voice") << "Session.Create response received (success), session handle is " << sessionHandle << LL_ENDL; | ||
3641 | - if(session) | ||
3642 | + // Got the channel list, try to do a lookup. | ||
3643 | + std::string uri = findChannelURI(mChannelName); | ||
3644 | + if(uri.empty()) | ||
3645 | + { | ||
3646 | + // Lookup failed, can't join a channel for this area. | ||
3647 | + LL_INFOS("Voice") << "failed to map channel name: " << mChannelName << LL_ENDL; | ||
3648 | + } | ||
3649 | + else | ||
3650 | { | ||
3651 | - setSessionHandle(session, sessionHandle); | ||
3652 | + // We have a sip URL for this area. | ||
3653 | + LL_INFOS("Voice") << "mapped channel " << mChannelName << " to URI "<< uri << LL_ENDL; | ||
3654 | } | ||
3655 | + | ||
3656 | + // switchChannel with an empty uri string will do the right thing (leave channel and not rejoin) | ||
3657 | + switchChannel(uri); | ||
3658 | } | ||
3659 | } | ||
3660 | |||
3661 | -void LLVoiceClient::sessionGroupAddSessionResponse(std::string &requestId, int statusCode, std::string &statusString, std::string &sessionHandle) | ||
3662 | +void LLVoiceClient::sessionCreateResponse(int statusCode, std::string &statusString, std::string &sessionHandle) | ||
3663 | { | ||
3664 | - sessionState *session = findSessionBeingCreatedByURI(requestId); | ||
3665 | - | ||
3666 | - if(session) | ||
3667 | - { | ||
3668 | - session->mCreateInProgress = false; | ||
3669 | - } | ||
3670 | - | ||
3671 | if(statusCode != 0) | ||
3672 | { | ||
3673 | - LL_WARNS("Voice") << "SessionGroup.AddSession response failure (" << statusCode << "): " << statusString << LL_ENDL; | ||
3674 | - if(session) | ||
3675 | + LL_WARNS("Voice") << "Session.Create response failure (" << statusCode << "): " << statusString << LL_ENDL; | ||
3676 | +// if(statusCode == 1015) | ||
3677 | +// { | ||
3678 | +// if(getState() == stateJoiningSession) | ||
3679 | +// { | ||
3680 | +// // this happened during a real join. Going to sessionTerminated should cause a retry in appropriate cases. | ||
3681 | +// LL_WARNS("Voice") << "session handle \"" << sessionHandle << "\", mSessionStateEventHandle \"" << mSessionStateEventHandle << "\""<< LL_ENDL; | ||
3682 | +// if(!sessionHandle.empty()) | ||
3683 | +// { | ||
3684 | +// // This session is bad. Terminate it. | ||
3685 | +// mSessionHandle = sessionHandle; | ||
3686 | +// sessionTerminateByHandle(sessionHandle); | ||
3687 | +// setState(stateLeavingSession); | ||
3688 | +// } | ||
3689 | +// else if(!mSessionStateEventHandle.empty()) | ||
3690 | +// { | ||
3691 | +// mSessionHandle = mSessionStateEventHandle; | ||
3692 | +// sessionTerminateByHandle(mSessionStateEventHandle); | ||
3693 | +// setState(stateLeavingSession); | ||
3694 | +// } | ||
3695 | +// else | ||
3696 | +// { | ||
3697 | +// setState(stateSessionTerminated); | ||
3698 | +// } | ||
3699 | +// } | ||
3700 | +// else | ||
3701 | +// { | ||
3702 | +// // We didn't think we were in the middle of a join. Don't change state. | ||
3703 | +// LL_WARNS("Voice") << "Not in stateJoiningSession, ignoring" << LL_ENDL; | ||
3704 | +// } | ||
3705 | +// } | ||
3706 | +// else | ||
3707 | { | ||
3708 | - session->mErrorStatusCode = statusCode; | ||
3709 | - session->mErrorStatusString = statusString; | ||
3710 | - if(session == mAudioSession) | ||
3711 | - { | ||
3712 | - setState(stateJoinSessionFailed); | ||
3713 | - } | ||
3714 | - else | ||
3715 | - { | ||
3716 | - reapSession(session); | ||
3717 | - } | ||
3718 | + mVivoxErrorStatusCode = statusCode; | ||
3719 | + mVivoxErrorStatusString = statusString; | ||
3720 | + setState(stateJoinSessionFailed); | ||
3721 | } | ||
3722 | } | ||
3723 | else | ||
3724 | { | ||
3725 | - LL_DEBUGS("Voice") << "SessionGroup.AddSession response received (success), session handle is " << sessionHandle << LL_ENDL; | ||
3726 | - if(session) | ||
3727 | + LL_DEBUGS("Voice") << "Session.Create response received (success), session handle is " << sessionHandle << LL_ENDL; | ||
3728 | + if(getState() == stateJoiningSession) | ||
3729 | { | ||
3730 | - setSessionHandle(session, sessionHandle); | ||
3731 | + // This is also grabbed in the SessionStateChangeEvent handler, but it might be useful to have it early... | ||
3732 | + mSessionHandle = sessionHandle; | ||
3733 | + } | ||
3734 | + else | ||
3735 | + { | ||
3736 | + // We should never get a session.create response in any state except stateJoiningSession. Things are out of sync. Kill this session. | ||
3737 | + sessionTerminateByHandle(sessionHandle); | ||
3738 | } | ||
3739 | } | ||
3740 | } | ||
3741 | |||
3742 | -void LLVoiceClient::sessionConnectResponse(std::string &requestId, int statusCode, std::string &statusString) | ||
3743 | +void LLVoiceClient::sessionConnectResponse(int statusCode, std::string &statusString) | ||
3744 | { | ||
3745 | - sessionState *session = findSession(requestId); | ||
3746 | if(statusCode != 0) | ||
3747 | { | ||
3748 | LL_WARNS("Voice") << "Session.Connect response failure (" << statusCode << "): " << statusString << LL_ENDL; | ||
3749 | - if(session) | ||
3750 | +// if(statusCode == 1015) | ||
3751 | +// { | ||
3752 | +// LL_WARNS("Voice") << "terminating existing session" << LL_ENDL; | ||
3753 | +// sessionTerminate(); | ||
3754 | +// } | ||
3755 | +// else | ||
3756 | { | ||
3757 | - session->mMediaConnectInProgress = false; | ||
3758 | - session->mErrorStatusCode = statusCode; | ||
3759 | - session->mErrorStatusString = statusString; | ||
3760 | - if(session == mAudioSession) | ||
3761 | - setState(stateJoinSessionFailed); | ||
3762 | + mVivoxErrorStatusCode = statusCode; | ||
3763 | + mVivoxErrorStatusString = statusString; | ||
3764 | + setState(stateJoinSessionFailed); | ||
3765 | } | ||
3766 | } | ||
3767 | else | ||
3768 | @@ -3801,12 +2745,27 @@ void LLVoiceClient::sessionConnectResponse(std::string &requestId, int statusCod | ||
3769 | } | ||
3770 | } | ||
3771 | |||
3772 | +void LLVoiceClient::sessionTerminateResponse(int statusCode, std::string &statusString) | ||
3773 | +{ | ||
3774 | + if(statusCode != 0) | ||
3775 | + { | ||
3776 | + LL_WARNS("Voice") << "Session.Terminate response failure: (" << statusCode << "): " << statusString << LL_ENDL; | ||
3777 | + if(getState() == stateLeavingSession) | ||
3778 | + { | ||
3779 | + // This is probably "(404): Server reporting Failure. Not a member of this conference." | ||
3780 | + // Do this so we don't get stuck. | ||
3781 | + setState(stateSessionTerminated); | ||
3782 | + } | ||
3783 | + } | ||
3784 | + | ||
3785 | +} | ||
3786 | + | ||
3787 | void LLVoiceClient::logoutResponse(int statusCode, std::string &statusString) | ||
3788 | { | ||
3789 | if(statusCode != 0) | ||
3790 | { | ||
3791 | LL_WARNS("Voice") << "Account.Logout response failure: " << statusString << LL_ENDL; | ||
3792 | - // Should this ever fail? do we care if it does? | ||
3793 | + // MBW -- XXX -- Should this ever fail? do we care if it does? | ||
3794 | } | ||
3795 | |||
3796 | if(getState() == stateLoggingOut) | ||
3797 | @@ -3820,7 +2779,7 @@ void LLVoiceClient::connectorShutdownResponse(int statusCode, std::string &statu | ||
3798 | if(statusCode != 0) | ||
3799 | { | ||
3800 | LL_WARNS("Voice") << "Connector.InitiateShutdown response failure: " << statusString << LL_ENDL; | ||
3801 | - // Should this ever fail? do we care if it does? | ||
3802 | + // MBW -- XXX -- Should this ever fail? do we care if it does? | ||
3803 | } | ||
3804 | |||
3805 | mConnected = false; | ||
3806 | @@ -3831,277 +2790,109 @@ void LLVoiceClient::connectorShutdownResponse(int statusCode, std::string &statu | ||
3807 | } | ||
3808 | } | ||
3809 | |||
3810 | -void LLVoiceClient::sessionAddedEvent( | ||
3811 | +void LLVoiceClient::sessionStateChangeEvent( | ||
3812 | std::string &uriString, | ||
3813 | - std::string &alias, | ||
3814 | - std::string &sessionHandle, | ||
3815 | - std::string &sessionGroupHandle, | ||
3816 | + int statusCode, | ||
3817 | + std::string &statusString, | ||
3818 | + std::string &sessionHandle, | ||
3819 | + int state, | ||
3820 | bool isChannel, | ||
3821 | - bool incoming, | ||
3822 | - std::string &nameString, | ||
3823 | - std::string &applicationString) | ||
3824 | + std::string &nameString) | ||
3825 | { | ||
3826 | - sessionState *session = NULL; | ||
3827 | - | ||
3828 | - LL_INFOS("Voice") << "session " << uriString << ", alias " << alias << ", name " << nameString << " handle " << sessionHandle << LL_ENDL; | ||
3829 | - | ||
3830 | - session = addSession(uriString, sessionHandle); | ||
3831 | - if(session) | ||
3832 | + switch(state) | ||
3833 | { | ||
3834 | - session->mGroupHandle = sessionGroupHandle; | ||
3835 | - session->mIsChannel = isChannel; | ||
3836 | - session->mIncoming = incoming; | ||
3837 | - session->mAlias = alias; | ||
3838 | - | ||
3839 | - // Generate a caller UUID -- don't need to do this for channels | ||
3840 | - if(!session->mIsChannel) | ||
3841 | - { | ||
3842 | - if(IDFromName(session->mSIPURI, session->mCallerID)) | ||
3843 | + case 4: // I see this when joining the session | ||
3844 | + LL_INFOS("Voice") << "joined session " << uriString << ", name " << nameString << " handle " << mNextSessionHandle << LL_ENDL; | ||
3845 | + | ||
3846 | + // Session create succeeded, move forward. | ||
3847 | + mSessionStateEventHandle = sessionHandle; | ||
3848 | + mSessionStateEventURI = uriString; | ||
3849 | + if(sessionHandle == mSessionHandle) | ||
3850 | { | ||
3851 | - // Normal URI(base64-encoded UUID) | ||
3852 | + // This is the session we're joining. | ||
3853 | + if(getState() == stateJoiningSession) | ||
3854 | + { | ||
3855 | + setState(stateSessionJoined); | ||
3856 | + //RN: the uriString being returned by vivox here is actually your account uri, not the channel | ||
3857 | + // you are attempting to join, so ignore it | ||
3858 | + //LL_DEBUGS("Voice") << "received URI " << uriString << "(previously " << mSessionURI << ")" << LL_ENDL; | ||
3859 | + //mSessionURI = uriString; | ||
3860 | + } | ||
3861 | } | ||
3862 | - else if(!session->mAlias.empty() && IDFromName(session->mAlias, session->mCallerID)) | ||
3863 | + else if(sessionHandle == mNextSessionHandle) | ||
3864 | { | ||
3865 | - // Wrong URI, but an alias is available. Stash the incoming URI as an alternate | ||
3866 | - session->mAlternateSIPURI = session->mSIPURI; | ||
3867 | - | ||
3868 | - // and generate a proper URI from the ID. | ||
3869 | - setSessionURI(session, sipURIFromID(session->mCallerID)); | ||
3870 | +// LL_DEBUGS("Voice") << "received URI " << uriString << ", name " << nameString << " for next session (handle " << mNextSessionHandle << ")" << LL_ENDL; | ||
3871 | } | ||
3872 | else | ||
3873 | { | ||
3874 | - LL_INFOS("Voice") << "Could not generate caller id from uri, using hash of uri " << session->mSIPURI << LL_ENDL; | ||
3875 | - setUUIDFromStringHash(session->mCallerID, session->mSIPURI); | ||
3876 | - session->mSynthesizedCallerID = true; | ||
3877 | - | ||
3878 | - // Can't look up the name in this case -- we have to extract it from the URI. | ||
3879 | - std::string namePortion = nameFromsipURI(session->mSIPURI); | ||
3880 | - if(namePortion.empty()) | ||
3881 | - { | ||
3882 | - // Didn't seem to be a SIP URI, just use the whole provided name. | ||
3883 | - namePortion = nameString; | ||
3884 | - } | ||
3885 | - | ||
3886 | - // Some incoming names may be separated with an underscore instead of a space. Fix this. | ||
3887 | - LLStringUtil::replaceChar(namePortion, '_', ' '); | ||
3888 | - | ||
3889 | - // Act like we just finished resolving the name (this stores it in all the right places) | ||
3890 | - avatarNameResolved(session->mCallerID, namePortion); | ||
3891 | + LL_WARNS("Voice") << "joining unknown session handle " << sessionHandle << ", URI " << uriString << ", name " << nameString << LL_ENDL; | ||
3892 | + // MBW -- XXX -- Should we send a Session.Terminate here? | ||
3893 | } | ||
3894 | - | ||
3895 | - LL_INFOS("Voice") << "caller ID: " << session->mCallerID << LL_ENDL; | ||
3896 | - | ||
3897 | - if(!session->mSynthesizedCallerID) | ||
3898 | - { | ||
3899 | - // If we got here, we don't have a proper name. Initiate a lookup. | ||
3900 | - lookupName(session->mCallerID); | ||
3901 | - } | ||
3902 | - } | ||
3903 | - } | ||
3904 | -} | ||
3905 | - | ||
3906 | -void LLVoiceClient::sessionGroupAddedEvent(std::string &sessionGroupHandle) | ||
3907 | -{ | ||
3908 | - LL_DEBUGS("Voice") << "handle " << sessionGroupHandle << LL_ENDL; | ||
3909 | - | ||
3910 | -#if USE_SESSION_GROUPS | ||
3911 | - if(mMainSessionGroupHandle.empty()) | ||
3912 | - { | ||
3913 | - // This is the first (i.e. "main") session group. Save its handle. | ||
3914 | - mMainSessionGroupHandle = sessionGroupHandle; | ||
3915 | - } | ||
3916 | - else | ||
3917 | - { | ||
3918 | - LL_DEBUGS("Voice") << "Already had a session group handle " << mMainSessionGroupHandle << LL_ENDL; | ||
3919 | - } | ||
3920 | -#endif | ||
3921 | -} | ||
3922 | - | ||
3923 | -void LLVoiceClient::joinedAudioSession(sessionState *session) | ||
3924 | -{ | ||
3925 | - if(mAudioSession != session) | ||
3926 | - { | ||
3927 | - sessionState *oldSession = mAudioSession; | ||
3928 | - | ||
3929 | - mAudioSession = session; | ||
3930 | - mAudioSessionChanged = true; | ||
3931 | - | ||
3932 | - // The old session may now need to be deleted. | ||
3933 | - reapSession(oldSession); | ||
3934 | - } | ||
3935 | - | ||
3936 | - // This is the session we're joining. | ||
3937 | - if(getState() == stateJoiningSession) | ||
3938 | - { | ||
3939 | - setState(stateSessionJoined); | ||
3940 | - | ||
3941 | - // SLIM SDK: we don't always receive a participant state change for ourselves when joining a channel now. | ||
3942 | - // Add the current user as a participant here. | ||
3943 | - participantState *participant = session->addParticipant(sipURIFromName(mAccountName)); | ||
3944 | - if(participant) | ||
3945 | - { | ||
3946 | - participant->mIsSelf = true; | ||
3947 | - lookupName(participant->mAvatarID); | ||
3948 | + | ||
3949 | + break; | ||
3950 | + case 5: // I see this when leaving the session | ||
3951 | + LL_INFOS("Voice") << "left session " << uriString << ", name " << nameString << " handle " << mNextSessionHandle << LL_ENDL; | ||
3952 | |||
3953 | - LL_INFOS("Voice") << "added self as participant \"" << participant->mAccountName | ||
3954 | - << "\" (" << participant->mAvatarID << ")"<< LL_ENDL; | ||
3955 | - } | ||
3956 | - | ||
3957 | - if(!session->mIsChannel) | ||
3958 | - { | ||
3959 | - // this is a p2p session. Make sure the other end is added as a participant. | ||
3960 | - participantState *participant = session->addParticipant(session->mSIPURI); | ||
3961 | - if(participant) | ||
3962 | + // Set the session handle to the empty string. If we get back to stateJoiningSession, we'll want to wait for the new session handle. | ||
3963 | + if(sessionHandle == mSessionHandle) | ||
3964 | { | ||
3965 | - if(participant->mAvatarIDValid) | ||
3966 | + // MBW -- XXX -- I think this is no longer necessary, now that we've got mNextSessionURI/mNextSessionHandle | ||
3967 | + // mSessionURI.clear(); | ||
3968 | + // clear the session handle here just for sanity. | ||
3969 | + mSessionHandle.clear(); | ||
3970 | + if(mSessionResetOnClose) | ||
3971 | { | ||
3972 | - lookupName(participant->mAvatarID); | ||
3973 | - } | ||
3974 | - else if(!session->mName.empty()) | ||
3975 | - { | ||
3976 | - participant->mDisplayName = session->mName; | ||
3977 | - avatarNameResolved(participant->mAvatarID, session->mName); | ||
3978 | + mSessionResetOnClose = false; | ||
3979 | + mNonSpatialChannel = false; | ||
3980 | + mNextSessionSpatial = true; | ||
3981 | + parcelChanged(); | ||
3982 | } | ||
3983 | - | ||
3984 | - // TODO: Question: Do we need to set up mAvatarID/mAvatarIDValid here? | ||
3985 | - LL_INFOS("Voice") << "added caller as participant \"" << participant->mAccountName | ||
3986 | - << "\" (" << participant->mAvatarID << ")"<< LL_ENDL; | ||
3987 | - } | ||
3988 | - } | ||
3989 | - } | ||
3990 | -} | ||
3991 | - | ||
3992 | -void LLVoiceClient::sessionRemovedEvent( | ||
3993 | - std::string &sessionHandle, | ||
3994 | - std::string &sessionGroupHandle) | ||
3995 | -{ | ||
3996 | - LL_INFOS("Voice") << "handle " << sessionHandle << LL_ENDL; | ||
3997 | - | ||
3998 | - sessionState *session = findSession(sessionHandle); | ||
3999 | - if(session) | ||
4000 | - { | ||
4001 | - leftAudioSession(session); | ||
4002 | - | ||
4003 | - // This message invalidates the session's handle. Set it to empty. | ||
4004 | - setSessionHandle(session); | ||
4005 | - | ||
4006 | - // Reset the media state (we now have no info) | ||
4007 | - session->mMediaStreamState = streamStateUnknown; | ||
4008 | - session->mTextStreamState = streamStateUnknown; | ||
4009 | - | ||
4010 | - // Conditionally delete the session | ||
4011 | - reapSession(session); | ||
4012 | - } | ||
4013 | - else | ||
4014 | - { | ||
4015 | - LL_WARNS("Voice") << "unknown session " << sessionHandle << " removed" << LL_ENDL; | ||
4016 | - } | ||
4017 | -} | ||
4018 | - | ||
4019 | -void LLVoiceClient::reapSession(sessionState *session) | ||
4020 | -{ | ||
4021 | - if(session) | ||
4022 | - { | ||
4023 | - if(!session->mHandle.empty()) | ||
4024 | - { | ||
4025 | - LL_DEBUGS("Voice") << "NOT deleting session " << session->mSIPURI << " (non-null session handle)" << LL_ENDL; | ||
4026 | - } | ||
4027 | - else if(session->mCreateInProgress) | ||
4028 | - { | ||
4029 | - LL_DEBUGS("Voice") << "NOT deleting session " << session->mSIPURI << " (create in progress)" << LL_ENDL; | ||
4030 | - } | ||
4031 | - else if(session->mMediaConnectInProgress) | ||
4032 | - { | ||
4033 | - LL_DEBUGS("Voice") << "NOT deleting session " << session->mSIPURI << " (connect in progress)" << LL_ENDL; | ||
4034 | - } | ||
4035 | - else if(session == mAudioSession) | ||
4036 | - { | ||
4037 | - LL_DEBUGS("Voice") << "NOT deleting session " << session->mSIPURI << " (it's the current session)" << LL_ENDL; | ||
4038 | - } | ||
4039 | - else if(session == mNextAudioSession) | ||
4040 | - { | ||
4041 | - LL_DEBUGS("Voice") << "NOT deleting session " << session->mSIPURI << " (it's the next session)" << LL_ENDL; | ||
4042 | - } | ||
4043 | - else | ||
4044 | - { | ||
4045 | - // TODO: Question: Should we check for queued text messages here? | ||
4046 | - // We don't have a reason to keep tracking this session, so just delete it. | ||
4047 | - LL_DEBUGS("Voice") << "deleting session " << session->mSIPURI << LL_ENDL; | ||
4048 | - deleteSession(session); | ||
4049 | - session = NULL; | ||
4050 | - } | ||
4051 | - } | ||
4052 | - else | ||
4053 | - { | ||
4054 | -// LL_DEBUGS("Voice") << "session is NULL" << LL_ENDL; | ||
4055 | - } | ||
4056 | -} | ||
4057 | - | ||
4058 | -// Returns true if the session seems to indicate we've moved to a region on a different voice server | ||
4059 | -bool LLVoiceClient::sessionNeedsRelog(sessionState *session) | ||
4060 | -{ | ||
4061 | - bool result = false; | ||
4062 | - | ||
4063 | - if(session != NULL) | ||
4064 | - { | ||
4065 | - // Only make this check for spatial channels (so it won't happen for group or p2p calls) | ||
4066 | - if(session->mIsSpatial) | ||
4067 | - { | ||
4068 | - std::string::size_type atsign; | ||
4069 | |||
4070 | - atsign = session->mSIPURI.find("@"); | ||
4071 | - | ||
4072 | - if(atsign != std::string::npos) | ||
4073 | - { | ||
4074 | - std::string urihost = session->mSIPURI.substr(atsign + 1); | ||
4075 | - if(stricmp(urihost.c_str(), mVoiceSIPURIHostName.c_str())) | ||
4076 | + removeAllParticipants(); | ||
4077 | + | ||
4078 | + switch(getState()) | ||
4079 | { | ||
4080 | - // The hostname in this URI is different from what we expect. This probably means we need to relog. | ||
4081 | + case stateJoiningSession: | ||
4082 | + case stateSessionJoined: | ||
4083 | + case stateRunning: | ||
4084 | + case stateLeavingSession: | ||
4085 | + case stateJoinSessionFailed: | ||
4086 | + case stateJoinSessionFailedWaiting: | ||
4087 | + // normal transition | ||
4088 | + LL_INFOS("Voice") << "left session " << sessionHandle << "in state " << state2string(getState()) << LL_ENDL; | ||
4089 | + setState(stateSessionTerminated); | ||
4090 | + break; | ||
4091 | |||
4092 | - // We could make a ProvisionVoiceAccountRequest and compare the result with the current values of | ||
4093 | - // mVoiceSIPURIHostName and mVoiceAccountServerURI to be really sure, but this is a pretty good indicator. | ||
4094 | + case stateSessionTerminated: | ||
4095 | + // this will happen sometimes -- there are cases where we send the terminate and then go straight to this state. | ||
4096 | + LL_WARNS("Voice") << "left session " << sessionHandle << "in state " << state2string(getState()) << LL_ENDL; | ||
4097 | + break; | ||
4098 | |||
4099 | - result = true; | ||
4100 | + default: | ||
4101 | + LL_WARNS("Voice") << "unexpected SessionStateChangeEvent (left session) in state " << state2string(getState()) << LL_ENDL; | ||
4102 | + setState(stateSessionTerminated); | ||
4103 | + break; | ||
4104 | } | ||
4105 | + | ||
4106 | + // store status values for later notification of observers | ||
4107 | + mVivoxErrorStatusCode = statusCode; | ||
4108 | + mVivoxErrorStatusString = statusString; | ||
4109 | + } | ||
4110 | + else | ||
4111 | + { | ||
4112 | + LL_INFOS("Voice") << "leaving unknown session handle " << sessionHandle << ", URI " << uriString << ", name " << nameString << LL_ENDL; | ||
4113 | } | ||
4114 | - } | ||
4115 | - } | ||
4116 | - | ||
4117 | - return result; | ||
4118 | -} | ||
4119 | |||
4120 | -void LLVoiceClient::leftAudioSession( | ||
4121 | - sessionState *session) | ||
4122 | -{ | ||
4123 | - if(mAudioSession == session) | ||
4124 | - { | ||
4125 | - switch(getState()) | ||
4126 | - { | ||
4127 | - case stateJoiningSession: | ||
4128 | - case stateSessionJoined: | ||
4129 | - case stateRunning: | ||
4130 | - case stateLeavingSession: | ||
4131 | - case stateJoinSessionFailed: | ||
4132 | - case stateJoinSessionFailedWaiting: | ||
4133 | - // normal transition | ||
4134 | - LL_DEBUGS("Voice") << "left session " << session->mHandle << " in state " << state2string(getState()) << LL_ENDL; | ||
4135 | - setState(stateSessionTerminated); | ||
4136 | - break; | ||
4137 | - | ||
4138 | - case stateSessionTerminated: | ||
4139 | - // this will happen sometimes -- there are cases where we send the terminate and then go straight to this state. | ||
4140 | - LL_WARNS("Voice") << "left session " << session->mHandle << " in state " << state2string(getState()) << LL_ENDL; | ||
4141 | - break; | ||
4142 | - | ||
4143 | - default: | ||
4144 | - LL_WARNS("Voice") << "unexpected SessionStateChangeEvent (left session) in state " << state2string(getState()) << LL_ENDL; | ||
4145 | - setState(stateSessionTerminated); | ||
4146 | - break; | ||
4147 | - } | ||
4148 | + mSessionStateEventHandle.clear(); | ||
4149 | + mSessionStateEventURI.clear(); | ||
4150 | + break; | ||
4151 | + default: | ||
4152 | + LL_WARNS("Voice") << "unknown state: " << state << LL_ENDL; | ||
4153 | + break; | ||
4154 | } | ||
4155 | } | ||
4156 | |||
4157 | -void LLVoiceClient::accountLoginStateChangeEvent( | ||
4158 | +void LLVoiceClient::loginStateChangeEvent( | ||
4159 | std::string &accountHandle, | ||
4160 | int statusCode, | ||
4161 | std::string &statusString, | ||
4162 | @@ -4134,571 +2925,110 @@ void LLVoiceClient::accountLoginStateChangeEvent( | ||
4163 | } | ||
4164 | } | ||
4165 | |||
4166 | -void LLVoiceClient::mediaStreamUpdatedEvent( | ||
4167 | - std::string &sessionHandle, | ||
4168 | - std::string &sessionGroupHandle, | ||
4169 | - int statusCode, | ||
4170 | - std::string &statusString, | ||
4171 | - int state, | ||
4172 | - bool incoming) | ||
4173 | +void LLVoiceClient::sessionNewEvent( | ||
4174 | + std::string &accountHandle, | ||
4175 | + std::string &eventSessionHandle, | ||
4176 | + int state, | ||
4177 | + std::string &nameString, | ||
4178 | + std::string &uriString) | ||
4179 | { | ||
4180 | - sessionState *session = findSession(sessionHandle); | ||
4181 | - | ||
4182 | - LL_DEBUGS("Voice") << "session " << sessionHandle << ", status code " << statusCode << ", string \"" << statusString << "\"" << LL_ENDL; | ||
4183 | + LL_DEBUGS("Voice") << "state is " << state << LL_ENDL; | ||
4184 | |||
4185 | - if(session) | ||
4186 | - { | ||
4187 | - // We know about this session | ||
4188 | - | ||
4189 | - // Save the state for later use | ||
4190 | - session->mMediaStreamState = state; | ||
4191 | - | ||
4192 | - switch(statusCode) | ||
4193 | - { | ||
4194 | - case 0: | ||
4195 | - case 200: | ||
4196 | - // generic success | ||
4197 | - // Don't change the saved error code (it may have been set elsewhere) | ||
4198 | - break; | ||
4199 | - default: | ||
4200 | - // save the status code for later | ||
4201 | - session->mErrorStatusCode = statusCode; | ||
4202 | - break; | ||
4203 | - } | ||
4204 | - | ||
4205 | - switch(state) | ||
4206 | - { | ||
4207 | - case streamStateIdle: | ||
4208 | - // Standard "left audio session" | ||
4209 | - session->mVoiceEnabled = false; | ||
4210 | - session->mMediaConnectInProgress = false; | ||
4211 | - leftAudioSession(session); | ||
4212 | - break; | ||
4213 | - | ||
4214 | - case streamStateConnected: | ||
4215 | - session->mVoiceEnabled = true; | ||
4216 | - session->mMediaConnectInProgress = false; | ||
4217 | - joinedAudioSession(session); | ||
4218 | - break; | ||
4219 | - | ||
4220 | - case streamStateRinging: | ||
4221 | - if(incoming) | ||
4222 | - { | ||
4223 | - // Send the voice chat invite to the GUI layer | ||
4224 | - // TODO: Question: Should we correlate with the mute list here? | ||
4225 | - session->mIMSessionID = LLIMMgr::computeSessionID(IM_SESSION_P2P_INVITE, session->mCallerID); | ||
4226 | - session->mVoiceInvitePending = true; | ||
4227 | - if(session->mName.empty()) | ||
4228 | - { | ||
4229 | - lookupName(session->mCallerID); | ||
4230 | - } | ||
4231 | - else | ||
4232 | - { | ||
4233 | - // Act like we just finished resolving the name | ||
4234 | - avatarNameResolved(session->mCallerID, session->mName); | ||
4235 | - } | ||
4236 | - } | ||
4237 | - break; | ||
4238 | - | ||
4239 | - default: | ||
4240 | - LL_WARNS("Voice") << "unknown state " << state << LL_ENDL; | ||
4241 | - break; | ||
4242 | - | ||
4243 | - } | ||
4244 | - | ||
4245 | - } | ||
4246 | - else | ||
4247 | + switch(state) | ||
4248 | { | ||
4249 | - LL_WARNS("Voice") << "session " << sessionHandle << "not found"<< LL_ENDL; | ||
4250 | - } | ||
4251 | -} | ||
4252 | + case 0: | ||
4253 | + { | ||
4254 | + LL_DEBUGS("Voice") << "session handle = " << eventSessionHandle << ", name = " << nameString << ", uri = " << uriString << LL_ENDL; | ||
4255 | |||
4256 | -void LLVoiceClient::textStreamUpdatedEvent( | ||
4257 | - std::string &sessionHandle, | ||
4258 | - std::string &sessionGroupHandle, | ||
4259 | - bool enabled, | ||
4260 | - int state, | ||
4261 | - bool incoming) | ||
4262 | -{ | ||
4263 | - sessionState *session = findSession(sessionHandle); | ||
4264 | - | ||
4265 | - if(session) | ||
4266 | - { | ||
4267 | - // Save the state for later use | ||
4268 | - session->mTextStreamState = state; | ||
4269 | - | ||
4270 | - // We know about this session | ||
4271 | - switch(state) | ||
4272 | - { | ||
4273 | - case 0: // We see this when the text stream closes | ||
4274 | - LL_DEBUGS("Voice") << "stream closed" << LL_ENDL; | ||
4275 | - break; | ||
4276 | - | ||
4277 | - case 1: // We see this on an incoming call from the Connector | ||
4278 | - // Try to send any text messages queued for this session. | ||
4279 | - sendQueuedTextMessages(session); | ||
4280 | - | ||
4281 | - // Send the text chat invite to the GUI layer | ||
4282 | - // TODO: Question: Should we correlate with the mute list here? | ||
4283 | - session->mTextInvitePending = true; | ||
4284 | - if(session->mName.empty()) | ||
4285 | + LLUUID caller_id; | ||
4286 | + if(IDFromName(nameString, caller_id)) | ||
4287 | { | ||
4288 | - lookupName(session->mCallerID); | ||
4289 | + gIMMgr->inviteToSession( | ||
4290 | + LLIMMgr::computeSessionID( | ||
4291 | + IM_SESSION_P2P_INVITE, | ||
4292 | + caller_id), | ||
4293 | + LLStringUtil::null, | ||
4294 | + caller_id, | ||
4295 | + LLStringUtil::null, | ||
4296 | + IM_SESSION_P2P_INVITE, | ||
4297 | + LLIMMgr::INVITATION_TYPE_VOICE, | ||
4298 | + eventSessionHandle); | ||
4299 | } | ||
4300 | else | ||
4301 | { | ||
4302 | - // Act like we just finished resolving the name | ||
4303 | - avatarNameResolved(session->mCallerID, session->mName); | ||
4304 | + LL_WARNS("Voice") << "Could not generate caller id from uri " << uriString << LL_ENDL; | ||
4305 | } | ||
4306 | - break; | ||
4307 | - | ||
4308 | - default: | ||
4309 | - LL_WARNS("Voice") << "unknown state " << state << LL_ENDL; | ||
4310 | - break; | ||
4311 | - | ||
4312 | - } | ||
4313 | + } | ||
4314 | + break; | ||
4315 | + | ||
4316 | + default: | ||
4317 | + LL_WARNS("Voice") << "unknown state: " << state << LL_ENDL; | ||
4318 | + break; | ||
4319 | } | ||
4320 | } | ||
4321 | |||
4322 | -void LLVoiceClient::participantAddedEvent( | ||
4323 | - std::string &sessionHandle, | ||
4324 | - std::string &sessionGroupHandle, | ||
4325 | +void LLVoiceClient::participantStateChangeEvent( | ||
4326 | std::string &uriString, | ||
4327 | - std::string &alias, | ||
4328 | + int statusCode, | ||
4329 | + std::string &statusString, | ||
4330 | + int state, | ||
4331 | std::string &nameString, | ||
4332 | std::string &displayNameString, | ||
4333 | int participantType) | ||
4334 | { | ||
4335 | - sessionState *session = findSession(sessionHandle); | ||
4336 | - if(session) | ||
4337 | - { | ||
4338 | - participantState *participant = session->addParticipant(uriString); | ||
4339 | - if(participant) | ||
4340 | - { | ||
4341 | - participant->mAccountName = nameString; | ||
4342 | - | ||
4343 | - LL_DEBUGS("Voice") << "added participant \"" << participant->mAccountName | ||
4344 | - << "\" (" << participant->mAvatarID << ")"<< LL_ENDL; | ||
4345 | + participantState *participant = NULL; | ||
4346 | + LL_DEBUGS("Voice") << "state is " << state << LL_ENDL; | ||
4347 | |||
4348 | - if(participant->mAvatarIDValid) | ||
4349 | + switch(state) | ||
4350 | + { | ||
4351 | + case 7: // I see this when a participant joins | ||
4352 | + participant = addParticipant(uriString); | ||
4353 | + if(participant) | ||
4354 | { | ||
4355 | - // Initiate a lookup | ||
4356 | - lookupName(participant->mAvatarID); | ||
4357 | + participant->mName = nameString; | ||
4358 | + LL_DEBUGS("Voice") << "added participant \"" << participant->mName | ||
4359 | + << "\" (" << participant->mAvatarID << ")"<< LL_ENDL; | ||
4360 | } | ||
4361 | - else | ||
4362 | + break; | ||
4363 | + case 9: // I see this when a participant leaves | ||
4364 | + participant = findParticipant(uriString); | ||
4365 | + if(participant) | ||
4366 | { | ||
4367 | - // If we don't have a valid avatar UUID, we need to fill in the display name to make the active speakers floater work. | ||
4368 | - std::string namePortion = nameFromsipURI(uriString); | ||
4369 | - if(namePortion.empty()) | ||
4370 | - { | ||
4371 | - // Problem with the SIP URI, fall back to the display name | ||
4372 | - namePortion = displayNameString; | ||
4373 | - } | ||
4374 | - if(namePortion.empty()) | ||
4375 | - { | ||
4376 | - // Problems with both of the above, fall back to the account name | ||
4377 | - namePortion = nameString; | ||
4378 | - } | ||
4379 | - | ||
4380 | - // Set the display name (which is a hint to the active speakers window not to do its own lookup) | ||
4381 | - participant->mDisplayName = namePortion; | ||
4382 | - avatarNameResolved(participant->mAvatarID, namePortion); | ||
4383 | + removeParticipant(participant); | ||
4384 | } | ||
4385 | - } | ||
4386 | - } | ||
4387 | -} | ||
4388 | - | ||
4389 | -void LLVoiceClient::participantRemovedEvent( | ||
4390 | - std::string &sessionHandle, | ||
4391 | - std::string &sessionGroupHandle, | ||
4392 | - std::string &uriString, | ||
4393 | - std::string &alias, | ||
4394 | - std::string &nameString) | ||
4395 | -{ | ||
4396 | - sessionState *session = findSession(sessionHandle); | ||
4397 | - if(session) | ||
4398 | - { | ||
4399 | - participantState *participant = session->findParticipant(uriString); | ||
4400 | - if(participant) | ||
4401 | - { | ||
4402 | - session->removeParticipant(participant); | ||
4403 | - } | ||
4404 | - else | ||
4405 | - { | ||
4406 | - LL_DEBUGS("Voice") << "unknown participant " << uriString << LL_ENDL; | ||
4407 | - } | ||
4408 | - } | ||
4409 | - else | ||
4410 | - { | ||
4411 | - LL_DEBUGS("Voice") << "unknown session " << sessionHandle << LL_ENDL; | ||
4412 | + break; | ||
4413 | + default: | ||
4414 | + LL_DEBUGS("Voice") << "unknown state: " << state << LL_ENDL; | ||
4415 | + break; | ||
4416 | } | ||
4417 | } | ||
4418 | |||
4419 | - | ||
4420 | -void LLVoiceClient::participantUpdatedEvent( | ||
4421 | - std::string &sessionHandle, | ||
4422 | - std::string &sessionGroupHandle, | ||
4423 | +void LLVoiceClient::participantPropertiesEvent( | ||
4424 | std::string &uriString, | ||
4425 | - std::string &alias, | ||
4426 | + int statusCode, | ||
4427 | + std::string &statusString, | ||
4428 | + bool isLocallyMuted, | ||
4429 | bool isModeratorMuted, | ||
4430 | bool isSpeaking, | ||
4431 | int volume, | ||
4432 | F32 energy) | ||
4433 | { | ||
4434 | - sessionState *session = findSession(sessionHandle); | ||
4435 | - if(session) | ||
4436 | - { | ||
4437 | - participantState *participant = session->findParticipant(uriString); | ||
4438 | - | ||
4439 | - if(participant) | ||
4440 | - { | ||
4441 | - participant->mIsSpeaking = isSpeaking; | ||
4442 | - participant->mIsModeratorMuted = isModeratorMuted; | ||
4443 | - | ||
4444 | - // SLIM SDK: convert range: ensure that energy is set to zero if is_speaking is false | ||
4445 | - if (isSpeaking) | ||
4446 | - { | ||
4447 | - participant->mSpeakingTimeout.reset(); | ||
4448 | - participant->mPower = energy; | ||
4449 | - } | ||
4450 | - else | ||
4451 | - { | ||
4452 | - participant->mPower = 0.0f; | ||
4453 | - } | ||
4454 | - participant->mVolume = volume; | ||
4455 | - } | ||
4456 | - else | ||
4457 | - { | ||
4458 | - LL_WARNS("Voice") << "unknown participant: " << uriString << LL_ENDL; | ||
4459 | - } | ||
4460 | - } | ||
4461 | - else | ||
4462 | - { | ||
4463 | - LL_INFOS("Voice") << "unknown session " << sessionHandle << LL_ENDL; | ||
4464 | - } | ||
4465 | -} | ||
4466 | - | ||
4467 | -void LLVoiceClient::buddyPresenceEvent( | ||
4468 | - std::string &uriString, | ||
4469 | - std::string &alias, | ||
4470 | - std::string &statusString, | ||
4471 | - std::string &applicationString) | ||
4472 | -{ | ||
4473 | - buddyListEntry *buddy = findBuddy(uriString); | ||
4474 | - | ||
4475 | - if(buddy) | ||
4476 | + participantState *participant = findParticipant(uriString); | ||
4477 | + if(participant) | ||
4478 | { | ||
4479 | - LL_DEBUGS("Voice") << "Presence event for " << buddy->mDisplayName << " status \"" << statusString << "\", application \"" << applicationString << "\""<< LL_ENDL; | ||
4480 | - LL_DEBUGS("Voice") << "before: mOnlineSL = " << (buddy->mOnlineSL?"true":"false") << ", mOnlineSLim = " << (buddy->mOnlineSLim?"true":"false") << LL_ENDL; | ||
4481 | - | ||
4482 | - if(applicationString.empty()) | ||
4483 | + participant->mPTT = !isLocallyMuted; | ||
4484 | + participant->mIsSpeaking = isSpeaking; | ||
4485 | + participant->mIsModeratorMuted = isModeratorMuted; | ||
4486 | + if (isSpeaking) | ||
4487 | { | ||
4488 | - // This presence event is from a client that doesn't set up the Application string. Do things the old-skool way. | ||
4489 | - // NOTE: this will be needed to support people who aren't on the 3010-class SDK yet. | ||
4490 | - | ||
4491 | - if ( stricmp("Unknown", statusString.c_str())== 0) | ||
4492 | - { | ||
4493 | - // User went offline with a non-SLim-enabled viewer. | ||
4494 | - buddy->mOnlineSL = false; | ||
4495 | - } | ||
4496 | - else if ( stricmp("Online", statusString.c_str())== 0) | ||
4497 | - { | ||
4498 | - // User came online with a non-SLim-enabled viewer. | ||
4499 | - buddy->mOnlineSL = true; | ||
4500 | - } | ||
4501 | - else | ||
4502 | - { | ||
4503 | - // If the user is online through SLim, their status will be "Online-slc", "Away", or something else. | ||
4504 | - // NOTE: we should never see this unless someone is running an OLD version of SLim -- the versions that should be in use now all set the application string. | ||
4505 | - buddy->mOnlineSLim = true; | ||
4506 | - } | ||
4507 | + participant->mSpeakingTimeout.reset(); | ||
4508 | } | ||
4509 | - else if(applicationString.find("SecondLifeViewer") != std::string::npos) | ||
4510 | - { | ||
4511 | - // This presence event is from a viewer that sets the application string | ||
4512 | - if ( stricmp("Unknown", statusString.c_str())== 0) | ||
4513 | - { | ||
4514 | - // Viewer says they're offline | ||
4515 | - buddy->mOnlineSL = false; | ||
4516 | - } | ||
4517 | - else | ||
4518 | - { | ||
4519 | - // Viewer says they're online | ||
4520 | - buddy->mOnlineSL = true; | ||
4521 | - } | ||
4522 | - } | ||
4523 | - else | ||
4524 | - { | ||
4525 | - // This presence event is from something which is NOT the SL viewer (assume it's SLim). | ||
4526 | - if ( stricmp("Unknown", statusString.c_str())== 0) | ||
4527 | - { | ||
4528 | - // SLim says they're offline | ||
4529 | - buddy->mOnlineSLim = false; | ||
4530 | - } | ||
4531 | - else | ||
4532 | - { | ||
4533 | - // SLim says they're online | ||
4534 | - buddy->mOnlineSLim = true; | ||
4535 | - } | ||
4536 | - } | ||
4537 | - | ||
4538 | - LL_DEBUGS("Voice") << "after: mOnlineSL = " << (buddy->mOnlineSL?"true":"false") << ", mOnlineSLim = " << (buddy->mOnlineSLim?"true":"false") << LL_ENDL; | ||
4539 | - | ||
4540 | - // HACK -- increment the internal change serial number in the LLRelationship (without changing the actual status), so the UI notices the change. | ||
4541 | - LLAvatarTracker::instance().setBuddyOnline(buddy->mUUID,LLAvatarTracker::instance().isBuddyOnline(buddy->mUUID)); | ||
4542 | - | ||
4543 | - notifyFriendObservers(); | ||
4544 | + participant->mPower = energy; | ||
4545 | + participant->mVolume = volume; | ||
4546 | } | ||
4547 | else | ||
4548 | { | ||
4549 | - LL_DEBUGS("Voice") << "Presence for unknown buddy " << uriString << LL_ENDL; | ||
4550 | - } | ||
4551 | -} | ||
4552 | - | ||
4553 | -void LLVoiceClient::messageEvent( | ||
4554 | - std::string &sessionHandle, | ||
4555 | - std::string &uriString, | ||
4556 | - std::string &alias, | ||
4557 | - std::string &messageHeader, | ||
4558 | - std::string &messageBody, | ||
4559 | - std::string &applicationString) | ||
4560 | -{ | ||
4561 | - LL_DEBUGS("Voice") << "Message event, session " << sessionHandle << " from " << uriString << LL_ENDL; | ||
4562 | -// LL_DEBUGS("Voice") << " header " << messageHeader << ", body: \n" << messageBody << LL_ENDL; | ||
4563 | - | ||
4564 | - if(messageHeader.find("text/html") != std::string::npos) | ||
4565 | - { | ||
4566 | - std::string rawMessage; | ||
4567 | - | ||
4568 | - { | ||
4569 | - const std::string startMarker = "<body"; | ||
4570 | - const std::string startMarker2 = ">"; | ||
4571 | - const std::string endMarker = "</body>"; | ||
4572 | - const std::string startSpan = "<span"; | ||
4573 | - const std::string endSpan = "</span>"; | ||
4574 | - std::string::size_type start; | ||
4575 | - std::string::size_type end; | ||
4576 | - | ||
4577 | - // Default to displaying the raw string, so the message gets through. | ||
4578 | - rawMessage = messageBody; | ||
4579 | - | ||
4580 | - // Find the actual message text within the XML fragment | ||
4581 | - start = messageBody.find(startMarker); | ||
4582 | - start = messageBody.find(startMarker2, start); | ||
4583 | - end = messageBody.find(endMarker); | ||
4584 | - | ||
4585 | - if(start != std::string::npos) | ||
4586 | - { | ||
4587 | - start += startMarker2.size(); | ||
4588 | - | ||
4589 | - if(end != std::string::npos) | ||
4590 | - end -= start; | ||
4591 | - | ||
4592 | - rawMessage.assign(messageBody, start, end); | ||
4593 | - } | ||
4594 | - else | ||
4595 | - { | ||
4596 | - // Didn't find a <body>, try looking for a <span> instead. | ||
4597 | - start = messageBody.find(startSpan); | ||
4598 | - start = messageBody.find(startMarker2, start); | ||
4599 | - end = messageBody.find(endSpan); | ||
4600 | - | ||
4601 | - if(start != std::string::npos) | ||
4602 | - { | ||
4603 | - start += startMarker2.size(); | ||
4604 | - | ||
4605 | - if(end != std::string::npos) | ||
4606 | - end -= start; | ||
4607 | - | ||
4608 | - rawMessage.assign(messageBody, start, end); | ||
4609 | - } | ||
4610 | - } | ||
4611 | - } | ||
4612 | - | ||
4613 | -// LL_DEBUGS("Voice") << " raw message = \n" << rawMessage << LL_ENDL; | ||
4614 | - | ||
4615 | - // strip formatting tags | ||
4616 | - { | ||
4617 | - std::string::size_type start; | ||
4618 | - std::string::size_type end; | ||
4619 | - | ||
4620 | - while((start = rawMessage.find('<')) != std::string::npos) | ||
4621 | - { | ||
4622 | - if((end = rawMessage.find('>', start + 1)) != std::string::npos) | ||
4623 | - { | ||
4624 | - // Strip out the tag | ||
4625 | - rawMessage.erase(start, (end + 1) - start); | ||
4626 | - } | ||
4627 | - else | ||
4628 | - { | ||
4629 | - // Avoid an infinite loop | ||
4630 | - break; | ||
4631 | - } | ||
4632 | - } | ||
4633 | - } | ||
4634 | - | ||
4635 | - // Decode ampersand-escaped chars | ||
4636 | - { | ||
4637 | - std::string::size_type mark = 0; | ||
4638 | - | ||
4639 | - // The text may contain text encoded with <, >, and & | ||
4640 | - mark = 0; | ||
4641 | - while((mark = rawMessage.find("<", mark)) != std::string::npos) | ||
4642 | - { | ||
4643 | - rawMessage.replace(mark, 4, "<"); | ||
4644 | - mark += 1; | ||
4645 | - } | ||
4646 | - | ||
4647 | - mark = 0; | ||
4648 | - while((mark = rawMessage.find(">", mark)) != std::string::npos) | ||
4649 | - { | ||
4650 | - rawMessage.replace(mark, 4, ">"); | ||
4651 | - mark += 1; | ||
4652 | - } | ||
4653 | - | ||
4654 | - mark = 0; | ||
4655 | - while((mark = rawMessage.find("&", mark)) != std::string::npos) | ||
4656 | - { | ||
4657 | - rawMessage.replace(mark, 5, "&"); | ||
4658 | - mark += 1; | ||
4659 | - } | ||
4660 | - } | ||
4661 | - | ||
4662 | - // strip leading/trailing whitespace (since we always seem to get a couple newlines) | ||
4663 | - LLStringUtil::trim(rawMessage); | ||
4664 | - | ||
4665 | -// LL_DEBUGS("Voice") << " stripped message = \n" << rawMessage << LL_ENDL; | ||
4666 | - | ||
4667 | - sessionState *session = findSession(sessionHandle); | ||
4668 | - if(session) | ||
4669 | - { | ||
4670 | - bool is_busy = gAgent.getBusy(); | ||
4671 | - bool is_muted = LLMuteList::getInstance()->isMuted(session->mCallerID, session->mName, LLMute::flagTextChat); | ||
4672 | - bool is_linden = LLMuteList::getInstance()->isLinden(session->mName); | ||
4673 | - bool quiet_chat = false; | ||
4674 | - LLChat chat; | ||
4675 | - | ||
4676 | - chat.mMuted = is_muted && !is_linden; | ||
4677 | - | ||
4678 | - if(!chat.mMuted) | ||
4679 | - { | ||
4680 | - chat.mFromID = session->mCallerID; | ||
4681 | - chat.mFromName = session->mName; | ||
4682 | - chat.mSourceType = CHAT_SOURCE_AGENT; | ||
4683 | - | ||
4684 | - if(is_busy && !is_linden) | ||
4685 | - { | ||
4686 | - quiet_chat = true; | ||
4687 | - // TODO: Question: Return busy mode response here? Or maybe when session is started instead? | ||
4688 | - } | ||
4689 | - | ||
4690 | - std::string fullMessage = std::string(": ") + rawMessage; | ||
4691 | - | ||
4692 | - LL_DEBUGS("Voice") << "adding message, name " << session->mName << " session " << session->mIMSessionID << ", target " << session->mCallerID << LL_ENDL; | ||
4693 | - gIMMgr->addMessage(session->mIMSessionID, | ||
4694 | - session->mCallerID, | ||
4695 | - session->mName.c_str(), | ||
4696 | - fullMessage.c_str(), | ||
4697 | - LLStringUtil::null, // default arg | ||
4698 | - IM_NOTHING_SPECIAL, // default arg | ||
4699 | - 0, // default arg | ||
4700 | - LLUUID::null, // default arg | ||
4701 | - LLVector3::zero, // default arg | ||
4702 | - true); // prepend name and make it a link to the user's profile | ||
4703 | - | ||
4704 | - chat.mText = std::string("IM: ") + session->mName + std::string(": ") + rawMessage; | ||
4705 | - // If the chat should come in quietly (i.e. we're in busy mode), pretend it's from a local agent. | ||
4706 | - LLFloaterChat::addChat( chat, TRUE, quiet_chat ); | ||
4707 | - } | ||
4708 | - } | ||
4709 | - } | ||
4710 | -} | ||
4711 | - | ||
4712 | -void LLVoiceClient::sessionNotificationEvent(std::string &sessionHandle, std::string &uriString, std::string ¬ificationType) | ||
4713 | -{ | ||
4714 | - sessionState *session = findSession(sessionHandle); | ||
4715 | - | ||
4716 | - if(session) | ||
4717 | - { | ||
4718 | - participantState *participant = session->findParticipant(uriString); | ||
4719 | - if(participant) | ||
4720 | - { | ||
4721 | - if (!stricmp(notificationType.c_str(), "Typing")) | ||
4722 | - { | ||
4723 | - // Other end started typing | ||
4724 | - // TODO: The proper way to add a typing notification seems to be LLIMMgr::processIMTypingStart(). | ||
4725 | - // It requires an LLIMInfo for the message, which we don't have here. | ||
4726 | - } | ||
4727 | - else if (!stricmp(notificationType.c_str(), "NotTyping")) | ||
4728 | - { | ||
4729 | - // Other end stopped typing | ||
4730 | - // TODO: The proper way to remove a typing notification seems to be LLIMMgr::processIMTypingStop(). | ||
4731 | - // It requires an LLIMInfo for the message, which we don't have here. | ||
4732 | - } | ||
4733 | - else | ||
4734 | - { | ||
4735 | - LL_DEBUGS("Voice") << "Unknown notification type " << notificationType << "for participant " << uriString << " in session " << session->mSIPURI << LL_ENDL; | ||
4736 | - } | ||
4737 | - } | ||
4738 | - else | ||
4739 | - { | ||
4740 | - LL_DEBUGS("Voice") << "Unknown participant " << uriString << " in session " << session->mSIPURI << LL_ENDL; | ||
4741 | - } | ||
4742 | - } | ||
4743 | - else | ||
4744 | - { | ||
4745 | - LL_DEBUGS("Voice") << "Unknown session handle " << sessionHandle << LL_ENDL; | ||
4746 | - } | ||
4747 | -} | ||
4748 | - | ||
4749 | -void LLVoiceClient::subscriptionEvent(std::string &buddyURI, std::string &subscriptionHandle, std::string &alias, std::string &displayName, std::string &applicationString, std::string &subscriptionType) | ||
4750 | -{ | ||
4751 | - buddyListEntry *buddy = findBuddy(buddyURI); | ||
4752 | - | ||
4753 | - if(!buddy) | ||
4754 | - { | ||
4755 | - // Couldn't find buddy by URI, try converting the alias... | ||
4756 | - if(!alias.empty()) | ||
4757 | - { | ||
4758 | - LLUUID id; | ||
4759 | - if(IDFromName(alias, id)) | ||
4760 | - { | ||
4761 | - buddy = findBuddy(id); | ||
4762 | - } | ||
4763 | - } | ||
4764 | - } | ||
4765 | - | ||
4766 | - if(buddy) | ||
4767 | - { | ||
4768 | - std::ostringstream stream; | ||
4769 | - | ||
4770 | - if(buddy->mCanSeeMeOnline) | ||
4771 | - { | ||
4772 | - // Sending the response will create an auto-accept rule | ||
4773 | - buddy->mHasAutoAcceptListEntry = true; | ||
4774 | - } | ||
4775 | - else | ||
4776 | - { | ||
4777 | - // Sending the response will create a block rule | ||
4778 | - buddy->mHasBlockListEntry = true; | ||
4779 | - } | ||
4780 | - | ||
4781 | - if(buddy->mInSLFriends) | ||
4782 | - { | ||
4783 | - buddy->mInVivoxBuddies = true; | ||
4784 | - } | ||
4785 | - | ||
4786 | - stream | ||
4787 | - << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Account.SendSubscriptionReply.1\">" | ||
4788 | - << "<AccountHandle>" << mAccountHandle << "</AccountHandle>" | ||
4789 | - << "<BuddyURI>" << buddy->mURI << "</BuddyURI>" | ||
4790 | - << "<RuleType>" << (buddy->mCanSeeMeOnline?"Allow":"Hide") << "</RuleType>" | ||
4791 | - << "<AutoAccept>"<< (buddy->mInSLFriends?"1":"0")<< "</AutoAccept>" | ||
4792 | - << "<SubscriptionHandle>" << subscriptionHandle << "</SubscriptionHandle>" | ||
4793 | - << "</Request>" | ||
4794 | - << "\n\n\n"; | ||
4795 | - | ||
4796 | - writeString(stream.str()); | ||
4797 | + LL_WARNS("Voice") << "unknown participant: " << uriString << LL_ENDL; | ||
4798 | } | ||
4799 | } | ||
4800 | |||
4801 | @@ -4708,226 +3038,155 @@ void LLVoiceClient::auxAudioPropertiesEvent(F32 energy) | ||
4802 | mTuningEnergy = energy; | ||
4803 | } | ||
4804 | |||
4805 | -void LLVoiceClient::buddyListChanged() | ||
4806 | -{ | ||
4807 | - // This is called after we receive a BuddyAndGroupListChangedEvent. | ||
4808 | - mBuddyListMapPopulated = true; | ||
4809 | - mFriendsListDirty = true; | ||
4810 | -} | ||
4811 | - | ||
4812 | void LLVoiceClient::muteListChanged() | ||
4813 | { | ||
4814 | // The user's mute list has been updated. Go through the current participant list and sync it with the mute list. | ||
4815 | - if(mAudioSession) | ||
4816 | - { | ||
4817 | - participantMap::iterator iter = mAudioSession->mParticipantsByURI.begin(); | ||
4818 | - | ||
4819 | - for(; iter != mAudioSession->mParticipantsByURI.end(); iter++) | ||
4820 | - { | ||
4821 | - participantState *p = iter->second; | ||
4822 | - | ||
4823 | - // Check to see if this participant is on the mute list already | ||
4824 | - if(p->updateMuteState()) | ||
4825 | - mAudioSession->mVolumeDirty = true; | ||
4826 | - } | ||
4827 | - } | ||
4828 | -} | ||
4829 | |||
4830 | -void LLVoiceClient::updateFriends(U32 mask) | ||
4831 | -{ | ||
4832 | - if(mask & (LLFriendObserver::ADD | LLFriendObserver::REMOVE | LLFriendObserver::POWERS)) | ||
4833 | + participantMap::iterator iter = mParticipantMap.begin(); | ||
4834 | + | ||
4835 | + for(; iter != mParticipantMap.end(); iter++) | ||
4836 | { | ||
4837 | - // Just resend the whole friend list to the daemon | ||
4838 | - mFriendsListDirty = true; | ||
4839 | + participantState *p = iter->second; | ||
4840 | + | ||
4841 | + // Check to see if this participant is on the mute list already | ||
4842 | + updateMuteState(p); | ||
4843 | } | ||
4844 | } | ||
4845 | |||
4846 | ///////////////////////////// | ||
4847 | // Managing list of participants | ||
4848 | LLVoiceClient::participantState::participantState(const std::string &uri) : | ||
4849 | - mURI(uri), | ||
4850 | - mPTT(false), | ||
4851 | - mIsSpeaking(false), | ||
4852 | - mIsModeratorMuted(false), | ||
4853 | - mLastSpokeTimestamp(0.f), | ||
4854 | - mPower(0.f), | ||
4855 | - mVolume(0), | ||
4856 | - mOnMuteList(false), | ||
4857 | - mUserVolume(100), | ||
4858 | - mVolumeDirty(false), | ||
4859 | - mAvatarIDValid(false), | ||
4860 | - mIsSelf(false) | ||
4861 | + mURI(uri), mPTT(false), mIsSpeaking(false), mIsModeratorMuted(false), mLastSpokeTimestamp(0.f), mPower(0.f), mVolume(0), mServiceType(serviceTypeUnknown), | ||
4862 | + mOnMuteList(false), mUserVolume(100), mVolumeDirty(false), mAvatarIDValid(false) | ||
4863 | { | ||
4864 | } | ||
4865 | |||
4866 | -LLVoiceClient::participantState *LLVoiceClient::sessionState::addParticipant(const std::string &uri) | ||
4867 | +LLVoiceClient::participantState *LLVoiceClient::addParticipant(const std::string &uri) | ||
4868 | { | ||
4869 | participantState *result = NULL; | ||
4870 | - bool useAlternateURI = false; | ||
4871 | + | ||
4872 | + participantMap::iterator iter = mParticipantMap.find(uri); | ||
4873 | |||
4874 | - // Note: this is mostly the body of LLVoiceClient::sessionState::findParticipant(), but since we need to know if it | ||
4875 | - // matched the alternate SIP URI (so we can add it properly), we need to reproduce it here. | ||
4876 | + if(iter != mParticipantMap.end()) | ||
4877 | { | ||
4878 | - participantMap::iterator iter = mParticipantsByURI.find(&uri); | ||
4879 | - | ||
4880 | - if(iter == mParticipantsByURI.end()) | ||
4881 | - { | ||
4882 | - if(!mAlternateSIPURI.empty() && (uri == mAlternateSIPURI)) | ||
4883 | - { | ||
4884 | - // This is a p2p session (probably with the SLIM client) with an alternate URI for the other participant. | ||
4885 | - // Use mSIPURI instead, since it will be properly encoded. | ||
4886 | - iter = mParticipantsByURI.find(&(mSIPURI)); | ||
4887 | - useAlternateURI = true; | ||
4888 | - } | ||
4889 | - } | ||
4890 | - | ||
4891 | - if(iter != mParticipantsByURI.end()) | ||
4892 | - { | ||
4893 | - result = iter->second; | ||
4894 | - } | ||
4895 | + // Found a matching participant already in the map. | ||
4896 | + result = iter->second; | ||
4897 | } | ||
4898 | - | ||
4899 | + | ||
4900 | if(!result) | ||
4901 | { | ||
4902 | // participant isn't already in one list or the other. | ||
4903 | - result = new participantState(useAlternateURI?mSIPURI:uri); | ||
4904 | - mParticipantsByURI.insert(participantMap::value_type(&(result->mURI), result)); | ||
4905 | - mParticipantsChanged = true; | ||
4906 | + result = new participantState(uri); | ||
4907 | + mParticipantMap.insert(participantMap::value_type(uri, result)); | ||
4908 | + mParticipantMapChanged = true; | ||
4909 | |||
4910 | // Try to do a reverse transform on the URI to get the GUID back. | ||
4911 | { | ||
4912 | LLUUID id; | ||
4913 | - if(IDFromName(result->mURI, id)) | ||
4914 | + if(IDFromName(uri, id)) | ||
4915 | { | ||
4916 | result->mAvatarIDValid = true; | ||
4917 | result->mAvatarID = id; | ||
4918 | |||
4919 | - if(result->updateMuteState()) | ||
4920 | - mVolumeDirty = true; | ||
4921 | - } | ||
4922 | - else | ||
4923 | - { | ||
4924 | - // Create a UUID by hashing the URI, but do NOT set mAvatarIDValid. | ||
4925 | - // This tells both code in LLVoiceClient and code in llfloateractivespeakers.cpp that the ID will not be in the name cache. | ||
4926 | - setUUIDFromStringHash(result->mAvatarID, uri); | ||
4927 | + updateMuteState(result); | ||
4928 | } | ||
4929 | } | ||
4930 | |||
4931 | - mParticipantsByUUID.insert(participantUUIDMap::value_type(&(result->mAvatarID), result)); | ||
4932 | - | ||
4933 | LL_DEBUGS("Voice") << "participant \"" << result->mURI << "\" added." << LL_ENDL; | ||
4934 | } | ||
4935 | |||
4936 | return result; | ||
4937 | } | ||
4938 | |||
4939 | -bool LLVoiceClient::participantState::updateMuteState() | ||
4940 | +void LLVoiceClient::updateMuteState(participantState *p) | ||
4941 | { | ||
4942 | - bool result = false; | ||
4943 | - | ||
4944 | - if(mAvatarIDValid) | ||
4945 | + if(p->mAvatarIDValid) | ||
4946 | { | ||
4947 | - bool isMuted = LLMuteList::getInstance()->isMuted(mAvatarID, LLMute::flagVoiceChat); | ||
4948 | - if(mOnMuteList != isMuted) | ||
4949 | + bool isMuted = LLMuteList::getInstance()->isMuted(p->mAvatarID, LLMute::flagVoiceChat); | ||
4950 | + if(p->mOnMuteList != isMuted) | ||
4951 | { | ||
4952 | - mOnMuteList = isMuted; | ||
4953 | + p->mOnMuteList = isMuted; | ||
4954 | + p->mVolumeDirty = true; | ||
4955 | mVolumeDirty = true; | ||
4956 | - result = true; | ||
4957 | } | ||
4958 | } | ||
4959 | - return result; | ||
4960 | } | ||
4961 | |||
4962 | -void LLVoiceClient::sessionState::removeParticipant(LLVoiceClient::participantState *participant) | ||
4963 | +void LLVoiceClient::removeParticipant(LLVoiceClient::participantState *participant) | ||
4964 | { | ||
4965 | if(participant) | ||
4966 | { | ||
4967 | - participantMap::iterator iter = mParticipantsByURI.find(&(participant->mURI)); | ||
4968 | - participantUUIDMap::iterator iter2 = mParticipantsByUUID.find(&(participant->mAvatarID)); | ||
4969 | - | ||
4970 | + participantMap::iterator iter = mParticipantMap.find(participant->mURI); | ||
4971 | + | ||
4972 | LL_DEBUGS("Voice") << "participant \"" << participant->mURI << "\" (" << participant->mAvatarID << ") removed." << LL_ENDL; | ||
4973 | - | ||
4974 | - if(iter == mParticipantsByURI.end()) | ||
4975 | - { | ||
4976 | - LL_ERRS("Voice") << "Internal error: participant " << participant->mURI << " not in URI map" << LL_ENDL; | ||
4977 | - } | ||
4978 | - else if(iter2 == mParticipantsByUUID.end()) | ||
4979 | - { | ||
4980 | - LL_ERRS("Voice") << "Internal error: participant ID " << participant->mAvatarID << " not in UUID map" << LL_ENDL; | ||
4981 | - } | ||
4982 | - else if(iter->second != iter2->second) | ||
4983 | - { | ||
4984 | - LL_ERRS("Voice") << "Internal error: participant mismatch!" << LL_ENDL; | ||
4985 | - } | ||
4986 | - else | ||
4987 | - { | ||
4988 | - mParticipantsByURI.erase(iter); | ||
4989 | - mParticipantsByUUID.erase(iter2); | ||
4990 | - | ||
4991 | - delete participant; | ||
4992 | - mParticipantsChanged = true; | ||
4993 | - } | ||
4994 | + | ||
4995 | + mParticipantMap.erase(iter); | ||
4996 | + delete participant; | ||
4997 | + mParticipantMapChanged = true; | ||
4998 | } | ||
4999 | } | ||
5000 | |||
5001 | -void LLVoiceClient::sessionState::removeAllParticipants() | ||
5002 | +void LLVoiceClient::removeAllParticipants() | ||
5003 | { | ||
5004 | LL_DEBUGS("Voice") << "called" << LL_ENDL; | ||
5005 | |||
5006 | - while(!mParticipantsByURI.empty()) | ||
5007 | + while(!mParticipantMap.empty()) | ||
5008 | { | ||
5009 | - removeParticipant(mParticipantsByURI.begin()->second); | ||
5010 | - } | ||
5011 | - | ||
5012 | - if(!mParticipantsByUUID.empty()) | ||
5013 | - { | ||
5014 | - LL_ERRS("Voice") << "Internal error: empty URI map, non-empty UUID map" << LL_ENDL | ||
5015 | + removeParticipant(mParticipantMap.begin()->second); | ||
5016 | } | ||
5017 | } | ||
5018 | |||
5019 | LLVoiceClient::participantMap *LLVoiceClient::getParticipantList(void) | ||
5020 | { | ||
5021 | - participantMap *result = NULL; | ||
5022 | - if(mAudioSession) | ||
5023 | - { | ||
5024 | - result = &(mAudioSession->mParticipantsByURI); | ||
5025 | - } | ||
5026 | - return result; | ||
5027 | + return &mParticipantMap; | ||
5028 | } | ||
5029 | |||
5030 | |||
5031 | -LLVoiceClient::participantState *LLVoiceClient::sessionState::findParticipant(const std::string &uri) | ||
5032 | +LLVoiceClient::participantState *LLVoiceClient::findParticipant(const std::string &uri) | ||
5033 | { | ||
5034 | participantState *result = NULL; | ||
5035 | |||
5036 | - participantMap::iterator iter = mParticipantsByURI.find(&uri); | ||
5037 | - | ||
5038 | - if(iter == mParticipantsByURI.end()) | ||
5039 | + // Don't find any participants if we're not connected. This is so that we don't continue to get stale data | ||
5040 | + // after the daemon dies. | ||
5041 | + if(mConnected) | ||
5042 | { | ||
5043 | - if(!mAlternateSIPURI.empty() && (uri == mAlternateSIPURI)) | ||
5044 | + participantMap::iterator iter = mParticipantMap.find(uri); | ||
5045 | + | ||
5046 | + if(iter != mParticipantMap.end()) | ||
5047 | { | ||
5048 | - // This is a p2p session (probably with the SLIM client) with an alternate URI for the other participant. | ||
5049 | - // Look up the other URI | ||
5050 | - iter = mParticipantsByURI.find(&(mSIPURI)); | ||
5051 | + result = iter->second; | ||
5052 | } | ||
5053 | } | ||
5054 | - | ||
5055 | - if(iter != mParticipantsByURI.end()) | ||
5056 | - { | ||
5057 | - result = iter->second; | ||
5058 | - } | ||
5059 | - | ||
5060 | + | ||
5061 | return result; | ||
5062 | } | ||
5063 | |||
5064 | -LLVoiceClient::participantState* LLVoiceClient::sessionState::findParticipantByID(const LLUUID& id) | ||
5065 | + | ||
5066 | +LLVoiceClient::participantState *LLVoiceClient::findParticipantByAvatar(LLVOAvatar *avatar) | ||
5067 | { | ||
5068 | participantState * result = NULL; | ||
5069 | - participantUUIDMap::iterator iter = mParticipantsByUUID.find(&id); | ||
5070 | |||
5071 | - if(iter != mParticipantsByUUID.end()) | ||
5072 | + // You'd think this would work, but it doesn't... | ||
5073 | +// std::string uri = sipURIFromAvatar(avatar); | ||
5074 | + | ||
5075 | + // Currently, the URI is just the account name. | ||
5076 | + std::string loginName = nameFromAvatar(avatar); | ||
5077 | + result = findParticipant(loginName); | ||
5078 | + | ||
5079 | + if(result != NULL) | ||
5080 | { | ||
5081 | - result = iter->second; | ||
5082 | + if(!result->mAvatarIDValid) | ||
5083 | + { | ||
5084 | + result->mAvatarID = avatar->getID(); | ||
5085 | + result->mAvatarIDValid = true; | ||
5086 | + | ||
5087 | + // We just figured out the avatar ID, so the participant list has "changed" from the perspective of anyone who uses that to identify participants. | ||
5088 | + mParticipantMapChanged = true; | ||
5089 | + | ||
5090 | + updateMuteState(result); | ||
5091 | + } | ||
5092 | + | ||
5093 | + | ||
5094 | } | ||
5095 | |||
5096 | return result; | ||
5097 | @@ -4936,19 +3195,43 @@ LLVoiceClient::participantState* LLVoiceClient::sessionState::findParticipantByI | ||
5098 | LLVoiceClient::participantState* LLVoiceClient::findParticipantByID(const LLUUID& id) | ||
5099 | { | ||
5100 | participantState * result = NULL; | ||
5101 | + | ||
5102 | + // Currently, the URI is just the account name. | ||
5103 | + std::string loginName = nameFromID(id); | ||
5104 | + result = findParticipant(loginName); | ||
5105 | + | ||
5106 | + return result; | ||
5107 | +} | ||
5108 | + | ||
5109 | + | ||
5110 | +void LLVoiceClient::clearChannelMap(void) | ||
5111 | +{ | ||
5112 | + mChannelMap.clear(); | ||
5113 | +} | ||
5114 | + | ||
5115 | +void LLVoiceClient::addChannelMapEntry(std::string &name, std::string &uri) | ||
5116 | +{ | ||
5117 | + LL_DEBUGS("Voice") << "Adding channel name mapping: " << name << " -> " << uri << LL_ENDL; | ||
5118 | + mChannelMap.insert(channelMap::value_type(name, uri)); | ||
5119 | +} | ||
5120 | + | ||
5121 | +std::string LLVoiceClient::findChannelURI(std::string &name) | ||
5122 | +{ | ||
5123 | + std::string result; | ||
5124 | |||
5125 | - if(mAudioSession) | ||
5126 | + channelMap::iterator iter = mChannelMap.find(name); | ||
5127 | + | ||
5128 | + if(iter != mChannelMap.end()) | ||
5129 | { | ||
5130 | - result = mAudioSession->findParticipantByID(id); | ||
5131 | + result = iter->second; | ||
5132 | } | ||
5133 | |||
5134 | return result; | ||
5135 | } | ||
5136 | |||
5137 | - | ||
5138 | void LLVoiceClient::parcelChanged() | ||
5139 | { | ||
5140 | - if(getState() >= stateNoChannel) | ||
5141 | + if(getState() >= stateLoggedIn) | ||
5142 | { | ||
5143 | // If the user is logged in, start a channel lookup. | ||
5144 | LL_DEBUGS("Voice") << "sending ParcelVoiceInfoRequest (" << mCurrentRegionName << ", " << mCurrentParcelLocalID << ")" << LL_ENDL; | ||
5145 | @@ -4962,7 +3245,7 @@ void LLVoiceClient::parcelChanged() | ||
5146 | } | ||
5147 | else | ||
5148 | { | ||
5149 | - // The transition to stateNoChannel needs to kick this off again. | ||
5150 | + // The transition to stateLoggedIn needs to kick this off again. | ||
5151 | LL_INFOS("Voice") << "not logged in yet, deferring" << LL_ENDL; | ||
5152 | } | ||
5153 | } | ||
5154 | @@ -4970,17 +3253,12 @@ void LLVoiceClient::parcelChanged() | ||
5155 | void LLVoiceClient::switchChannel( | ||
5156 | std::string uri, | ||
5157 | bool spatial, | ||
5158 | - bool no_reconnect, | ||
5159 | - bool is_p2p, | ||
5160 | + bool noReconnect, | ||
5161 | std::string hash) | ||
5162 | { | ||
5163 | bool needsSwitch = false; | ||
5164 | |||
5165 | - LL_DEBUGS("Voice") | ||
5166 | - << "called in state " << state2string(getState()) | ||
5167 | - << " with uri \"" << uri << "\"" | ||
5168 | - << (spatial?", spatial is true":", spatial is false") | ||
5169 | - << LL_ENDL; | ||
5170 | + LL_DEBUGS("Voice") << "called in state " << state2string(getState()) << " with uri \"" << uri << "\"" << LL_ENDL; | ||
5171 | |||
5172 | switch(getState()) | ||
5173 | { | ||
5174 | @@ -4990,18 +3268,18 @@ void LLVoiceClient::switchChannel( | ||
5175 | // Always switch to the new URI from these states. | ||
5176 | needsSwitch = true; | ||
5177 | break; | ||
5178 | - | ||
5179 | + | ||
5180 | default: | ||
5181 | if(mSessionTerminateRequested) | ||
5182 | { | ||
5183 | // If a terminate has been requested, we need to compare against where the URI we're already headed to. | ||
5184 | - if(mNextAudioSession && (mNextAudioSession->mSIPURI != uri)) | ||
5185 | + if(mNextSessionURI != uri) | ||
5186 | needsSwitch = true; | ||
5187 | } | ||
5188 | else | ||
5189 | { | ||
5190 | // Otherwise, compare against the URI we're in now. | ||
5191 | - if(mAudioSession && (mAudioSession->mSIPURI != uri)) | ||
5192 | + if(mSessionURI != uri) | ||
5193 | needsSwitch = true; | ||
5194 | } | ||
5195 | break; | ||
5196 | @@ -5009,28 +3287,22 @@ void LLVoiceClient::switchChannel( | ||
5197 | |||
5198 | if(needsSwitch) | ||
5199 | { | ||
5200 | + mNextSessionURI = uri; | ||
5201 | + mNextSessionHash = hash; | ||
5202 | + mNextSessionHandle.clear(); | ||
5203 | + mNextP2PSessionURI.clear(); | ||
5204 | + mNextSessionSpatial = spatial; | ||
5205 | + mNextSessionNoReconnect = noReconnect; | ||
5206 | + | ||
5207 | if(uri.empty()) | ||
5208 | { | ||
5209 | // Leave any channel we may be in | ||
5210 | LL_DEBUGS("Voice") << "leaving channel" << LL_ENDL; | ||
5211 | - | ||
5212 | - sessionState *oldSession = mNextAudioSession; | ||
5213 | - mNextAudioSession = NULL; | ||
5214 | - | ||
5215 | - // The old session may now need to be deleted. | ||
5216 | - reapSession(oldSession); | ||
5217 | - | ||
5218 | notifyStatusObservers(LLVoiceClientStatusObserver::STATUS_VOICE_DISABLED); | ||
5219 | } | ||
5220 | else | ||
5221 | { | ||
5222 | LL_DEBUGS("Voice") << "switching to channel " << uri << LL_ENDL; | ||
5223 | - | ||
5224 | - mNextAudioSession = addSession(uri); | ||
5225 | - mNextAudioSession->mHash = hash; | ||
5226 | - mNextAudioSession->mIsSpatial = spatial; | ||
5227 | - mNextAudioSession->mReconnect = !no_reconnect; | ||
5228 | - mNextAudioSession->mIsP2P = is_p2p; | ||
5229 | } | ||
5230 | |||
5231 | if(getState() <= stateNoChannel) | ||
5232 | @@ -5045,10 +3317,15 @@ void LLVoiceClient::switchChannel( | ||
5233 | } | ||
5234 | } | ||
5235 | |||
5236 | -void LLVoiceClient::joinSession(sessionState *session) | ||
5237 | +void LLVoiceClient::joinSession(std::string handle, std::string uri) | ||
5238 | { | ||
5239 | - mNextAudioSession = session; | ||
5240 | - | ||
5241 | + mNextSessionURI.clear(); | ||
5242 | + mNextSessionHash.clear(); | ||
5243 | + mNextP2PSessionURI = uri; | ||
5244 | + mNextSessionHandle = handle; | ||
5245 | + mNextSessionSpatial = false; | ||
5246 | + mNextSessionNoReconnect = false; | ||
5247 | + | ||
5248 | if(getState() <= stateNoChannel) | ||
5249 | { | ||
5250 | // We're already set up to join a channel, just needed to fill in the session handle | ||
5251 | @@ -5064,7 +3341,7 @@ void LLVoiceClient::setNonSpatialChannel( | ||
5252 | const std::string &uri, | ||
5253 | const std::string &credentials) | ||
5254 | { | ||
5255 | - switchChannel(uri, false, false, false, credentials); | ||
5256 | + switchChannel(uri, false, false, credentials); | ||
5257 | } | ||
5258 | |||
5259 | void LLVoiceClient::setSpatialChannel( | ||
5260 | @@ -5072,216 +3349,51 @@ void LLVoiceClient::setSpatialChannel( | ||
5261 | const std::string &credentials) | ||
5262 | { | ||
5263 | mSpatialSessionURI = uri; | ||
5264 | - mSpatialSessionCredentials = credentials; | ||
5265 | mAreaVoiceDisabled = mSpatialSessionURI.empty(); | ||
5266 | |||
5267 | LL_DEBUGS("Voice") << "got spatial channel uri: \"" << uri << "\"" << LL_ENDL; | ||
5268 | |||
5269 | - if((mAudioSession && !(mAudioSession->mIsSpatial)) || (mNextAudioSession && !(mNextAudioSession->mIsSpatial))) | ||
5270 | + if(mNonSpatialChannel || !mNextSessionSpatial) | ||
5271 | { | ||
5272 | // User is in a non-spatial chat or joining a non-spatial chat. Don't switch channels. | ||
5273 | LL_INFOS("Voice") << "in non-spatial chat, not switching channels" << LL_ENDL; | ||
5274 | } | ||
5275 | else | ||
5276 | { | ||
5277 | - switchChannel(mSpatialSessionURI, true, false, false, mSpatialSessionCredentials); | ||
5278 | + switchChannel(mSpatialSessionURI, true, false, credentials); | ||
5279 | } | ||
5280 | } | ||
5281 | |||
5282 | -void LLVoiceClient::callUser(const LLUUID &uuid) | ||
5283 | +void LLVoiceClient::callUser(LLUUID &uuid) | ||
5284 | { | ||
5285 | std::string userURI = sipURIFromID(uuid); | ||
5286 | |||
5287 | - switchChannel(userURI, false, true, true); | ||
5288 | -} | ||
5289 | - | ||
5290 | -LLVoiceClient::sessionState* LLVoiceClient::startUserIMSession(const LLUUID &uuid) | ||
5291 | -{ | ||
5292 | - // Figure out if a session with the user already exists | ||
5293 | - sessionState *session = findSession(uuid); | ||
5294 | - if(!session) | ||
5295 | - { | ||
5296 | - // No session with user, need to start one. | ||
5297 | - std::string uri = sipURIFromID(uuid); | ||
5298 | - session = addSession(uri); | ||
5299 | - session->mIsSpatial = false; | ||
5300 | - session->mReconnect = false; | ||
5301 | - session->mIsP2P = true; | ||
5302 | - session->mCallerID = uuid; | ||
5303 | - } | ||
5304 | - | ||
5305 | - if(session) | ||
5306 | - { | ||
5307 | - if(session->mHandle.empty()) | ||
5308 | - { | ||
5309 | - // Session isn't active -- start it up. | ||
5310 | - sessionCreateSendMessage(session, false, true); | ||
5311 | - } | ||
5312 | - else | ||
5313 | - { | ||
5314 | - // Session is already active -- start up text. | ||
5315 | - sessionTextConnectSendMessage(session); | ||
5316 | - } | ||
5317 | - } | ||
5318 | - | ||
5319 | - return session; | ||
5320 | -} | ||
5321 | - | ||
5322 | -bool LLVoiceClient::sendTextMessage(const LLUUID& participant_id, const std::string& message) | ||
5323 | -{ | ||
5324 | - bool result = false; | ||
5325 | - | ||
5326 | - // Attempt to locate the indicated session | ||
5327 | - sessionState *session = startUserIMSession(participant_id); | ||
5328 | - if(session) | ||
5329 | - { | ||
5330 | - // found the session, attempt to send the message | ||
5331 | - session->mTextMsgQueue.push(message); | ||
5332 | - | ||
5333 | - // Try to send queued messages (will do nothing if the session is not open yet) | ||
5334 | - sendQueuedTextMessages(session); | ||
5335 | - | ||
5336 | - // The message is queued, so we succeed. | ||
5337 | - result = true; | ||
5338 | - } | ||
5339 | - else | ||
5340 | - { | ||
5341 | - LL_DEBUGS("Voice") << "Session not found for participant ID " << participant_id << LL_ENDL; | ||
5342 | - } | ||
5343 | - | ||
5344 | - return result; | ||
5345 | -} | ||
5346 | - | ||
5347 | -void LLVoiceClient::sendQueuedTextMessages(sessionState *session) | ||
5348 | -{ | ||
5349 | - if(session->mTextStreamState == 1) | ||
5350 | - { | ||
5351 | - if(!session->mTextMsgQueue.empty()) | ||
5352 | - { | ||
5353 | - std::ostringstream stream; | ||
5354 | - | ||
5355 | - while(!session->mTextMsgQueue.empty()) | ||
5356 | - { | ||
5357 | - std::string message = session->mTextMsgQueue.front(); | ||
5358 | - session->mTextMsgQueue.pop(); | ||
5359 | - stream | ||
5360 | - << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Session.SendMessage.1\">" | ||
5361 | - << "<SessionHandle>" << session->mHandle << "</SessionHandle>" | ||
5362 | - << "<MessageHeader>text/HTML</MessageHeader>" | ||
5363 | - << "<MessageBody>" << message << "</MessageBody>" | ||
5364 | - << "</Request>" | ||
5365 | - << "\n\n\n"; | ||
5366 | - } | ||
5367 | - writeString(stream.str()); | ||
5368 | - } | ||
5369 | - } | ||
5370 | - else | ||
5371 | - { | ||
5372 | - // Session isn't connected yet, defer until later. | ||
5373 | - } | ||
5374 | -} | ||
5375 | - | ||
5376 | -void LLVoiceClient::endUserIMSession(const LLUUID &uuid) | ||
5377 | -{ | ||
5378 | - // Figure out if a session with the user exists | ||
5379 | - sessionState *session = findSession(uuid); | ||
5380 | - if(session) | ||
5381 | - { | ||
5382 | - // found the session | ||
5383 | - if(!session->mHandle.empty()) | ||
5384 | - { | ||
5385 | - sessionTextDisconnectSendMessage(session); | ||
5386 | - } | ||
5387 | - } | ||
5388 | - else | ||
5389 | - { | ||
5390 | - LL_DEBUGS("Voice") << "Session not found for participant ID " << uuid << LL_ENDL; | ||
5391 | - } | ||
5392 | + switchChannel(userURI, false, true); | ||
5393 | } | ||
5394 | |||
5395 | -bool LLVoiceClient::answerInvite(std::string &sessionHandle) | ||
5396 | +void LLVoiceClient::answerInvite(std::string &sessionHandle, LLUUID& other_user_id) | ||
5397 | { | ||
5398 | - // this is only ever used to answer incoming p2p call invites. | ||
5399 | - | ||
5400 | - sessionState *session = findSession(sessionHandle); | ||
5401 | - if(session) | ||
5402 | - { | ||
5403 | - session->mIsSpatial = false; | ||
5404 | - session->mReconnect = false; | ||
5405 | - session->mIsP2P = true; | ||
5406 | - | ||
5407 | - joinSession(session); | ||
5408 | - return true; | ||
5409 | - } | ||
5410 | - | ||
5411 | - return false; | ||
5412 | -} | ||
5413 | - | ||
5414 | -bool LLVoiceClient::isOnlineSIP(const LLUUID &id) | ||
5415 | -{ | ||
5416 | - bool result = false; | ||
5417 | - buddyListEntry *buddy = findBuddy(id); | ||
5418 | - if(buddy) | ||
5419 | - { | ||
5420 | - result = buddy->mOnlineSLim; | ||
5421 | - LL_DEBUGS("Voice") << "Buddy " << buddy->mDisplayName << " is SIP " << (result?"online":"offline") << LL_ENDL; | ||
5422 | - } | ||
5423 | - | ||
5424 | - if(!result) | ||
5425 | - { | ||
5426 | - // This user isn't on the buddy list or doesn't show online status through the buddy list, but could be a participant in an existing session if they initiated a text IM. | ||
5427 | - sessionState *session = findSession(id); | ||
5428 | - if(session && !session->mHandle.empty()) | ||
5429 | - { | ||
5430 | - if((session->mTextStreamState != streamStateUnknown) || (session->mMediaStreamState > streamStateIdle)) | ||
5431 | - { | ||
5432 | - LL_DEBUGS("Voice") << "Open session with " << id << " found, returning SIP online state" << LL_ENDL; | ||
5433 | - // we have a p2p text session open with this user, so by definition they're online. | ||
5434 | - result = true; | ||
5435 | - } | ||
5436 | - } | ||
5437 | - } | ||
5438 | - | ||
5439 | - return result; | ||
5440 | + joinSession(sessionHandle, sipURIFromID(other_user_id)); | ||
5441 | } | ||
5442 | |||
5443 | void LLVoiceClient::declineInvite(std::string &sessionHandle) | ||
5444 | { | ||
5445 | - sessionState *session = findSession(sessionHandle); | ||
5446 | - if(session) | ||
5447 | - { | ||
5448 | - sessionMediaDisconnectSendMessage(session); | ||
5449 | - } | ||
5450 | + sessionTerminateByHandle(sessionHandle); | ||
5451 | } | ||
5452 | |||
5453 | void LLVoiceClient::leaveNonSpatialChannel() | ||
5454 | { | ||
5455 | - LL_DEBUGS("Voice") | ||
5456 | - << "called in state " << state2string(getState()) | ||
5457 | - << LL_ENDL; | ||
5458 | - | ||
5459 | - // Make sure we don't rejoin the current session. | ||
5460 | - sessionState *oldNextSession = mNextAudioSession; | ||
5461 | - mNextAudioSession = NULL; | ||
5462 | - | ||
5463 | - // Most likely this will still be the current session at this point, but check it anyway. | ||
5464 | - reapSession(oldNextSession); | ||
5465 | - | ||
5466 | - verifySessionState(); | ||
5467 | - | ||
5468 | - sessionTerminate(); | ||
5469 | + switchChannel(mSpatialSessionURI); | ||
5470 | } | ||
5471 | |||
5472 | std::string LLVoiceClient::getCurrentChannel() | ||
5473 | { | ||
5474 | - std::string result; | ||
5475 | - | ||
5476 | if((getState() == stateRunning) && !mSessionTerminateRequested) | ||
5477 | { | ||
5478 | - result = getAudioSessionURI(); | ||
5479 | + return mSessionURI; | ||
5480 | } | ||
5481 | |||
5482 | - return result; | ||
5483 | + return ""; | ||
5484 | } | ||
5485 | |||
5486 | bool LLVoiceClient::inProximalChannel() | ||
5487 | @@ -5290,7 +3402,7 @@ bool LLVoiceClient::inProximalChannel() | ||
5488 | |||
5489 | if((getState() == stateRunning) && !mSessionTerminateRequested) | ||
5490 | { | ||
5491 | - result = inSpatialChannel(); | ||
5492 | + result = !mNonSpatialChannel; | ||
5493 | } | ||
5494 | |||
5495 | return result; | ||
5496 | @@ -5302,7 +3414,7 @@ std::string LLVoiceClient::sipURIFromID(const LLUUID &id) | ||
5497 | result = "sip:"; | ||
5498 | result += nameFromID(id); | ||
5499 | result += "@"; | ||
5500 | - result += mVoiceSIPURIHostName; | ||
5501 | + result += mAccountServerName; | ||
5502 | |||
5503 | return result; | ||
5504 | } | ||
5505 | @@ -5315,7 +3427,7 @@ std::string LLVoiceClient::sipURIFromAvatar(LLVOAvatar *avatar) | ||
5506 | result = "sip:"; | ||
5507 | result += nameFromID(avatar->getID()); | ||
5508 | result += "@"; | ||
5509 | - result += mVoiceSIPURIHostName; | ||
5510 | + result += mAccountServerName; | ||
5511 | } | ||
5512 | |||
5513 | return result; | ||
5514 | @@ -5334,13 +3446,6 @@ std::string LLVoiceClient::nameFromAvatar(LLVOAvatar *avatar) | ||
5515 | std::string LLVoiceClient::nameFromID(const LLUUID &uuid) | ||
5516 | { | ||
5517 | std::string result; | ||
5518 | - | ||
5519 | - if (uuid.isNull()) { | ||
5520 | - //VIVOX, the uuid emtpy look for the mURIString and return that instead. | ||
5521 | - //result.assign(uuid.mURIStringName); | ||
5522 | - LLStringUtil::replaceChar(result, '_', ' '); | ||
5523 | - return result; | ||
5524 | - } | ||
5525 | // Prepending this apparently prevents conflicts with reserved names inside the vivox and diamondware code. | ||
5526 | result = "x"; | ||
5527 | |||
5528 | @@ -5354,24 +3459,13 @@ std::string LLVoiceClient::nameFromID(const LLUUID &uuid) | ||
5529 | // If you need to transform a GUID to this form on the Mac OS X command line, this will do so: | ||
5530 | // echo -n x && (echo e669132a-6c43-4ee1-a78d-6c82fff59f32 |xxd -r -p |openssl base64|tr '/+' '_-') | ||
5531 | |||
5532 | - // The reverse transform can be done with: | ||
5533 | - // echo 'x5mkTKmxDTuGnjWyC__WfMg==' |cut -b 2- -|tr '_-' '/+' |openssl base64 -d|xxd -p | ||
5534 | - | ||
5535 | return result; | ||
5536 | } | ||
5537 | |||
5538 | -bool LLVoiceClient::IDFromName(const std::string inName, LLUUID &uuid) | ||
5539 | +bool LLVoiceClient::IDFromName(const std::string name, LLUUID &uuid) | ||
5540 | { | ||
5541 | bool result = false; | ||
5542 | |||
5543 | - // SLIM SDK: The "name" may actually be a SIP URI such as: "sip:xFnPP04IpREWNkuw1cOXlhw==@bhr.vivox.com" | ||
5544 | - // If it is, convert to a bare name before doing the transform. | ||
5545 | - std::string name = nameFromsipURI(inName); | ||
5546 | - | ||
5547 | - // Doesn't look like a SIP URI, assume it's an actual name. | ||
5548 | - if(name.empty()) | ||
5549 | - name = inName; | ||
5550 | - | ||
5551 | // This will only work if the name is of the proper form. | ||
5552 | // As an example, the account name for Monroe Linden (UUID 1673cfd3-8229-4445-8d92-ec3570e5e587) is: | ||
5553 | // "xFnPP04IpREWNkuw1cOXlhw==" | ||
5554 | @@ -5393,13 +3487,6 @@ bool LLVoiceClient::IDFromName(const std::string inName, LLUUID &uuid) | ||
5555 | memcpy(uuid.mData, rawuuid, UUID_BYTES); | ||
5556 | result = true; | ||
5557 | } | ||
5558 | - } | ||
5559 | - | ||
5560 | - if(!result) | ||
5561 | - { | ||
5562 | - // VIVOX: not a standard account name, just copy the URI name mURIString field | ||
5563 | - // and hope for the best. bpj | ||
5564 | - uuid.setNull(); // VIVOX, set the uuid field to nulls | ||
5565 | } | ||
5566 | |||
5567 | return result; | ||
5568 | @@ -5416,59 +3503,13 @@ std::string LLVoiceClient::sipURIFromName(std::string &name) | ||
5569 | result = "sip:"; | ||
5570 | result += name; | ||
5571 | result += "@"; | ||
5572 | - result += mVoiceSIPURIHostName; | ||
5573 | + result += mAccountServerName; | ||
5574 | |||
5575 | // LLStringUtil::toLower(result); | ||
5576 | |||
5577 | return result; | ||
5578 | } | ||
5579 | |||
5580 | -std::string LLVoiceClient::nameFromsipURI(const std::string &uri) | ||
5581 | -{ | ||
5582 | - std::string result; | ||
5583 | - | ||
5584 | - std::string::size_type sipOffset, atOffset; | ||
5585 | - sipOffset = uri.find("sip:"); | ||
5586 | - atOffset = uri.find("@"); | ||
5587 | - if((sipOffset != std::string::npos) && (atOffset != std::string::npos)) | ||
5588 | - { | ||
5589 | - result = uri.substr(sipOffset + 4, atOffset - (sipOffset + 4)); | ||
5590 | - } | ||
5591 | - | ||
5592 | - return result; | ||
5593 | -} | ||
5594 | - | ||
5595 | -bool LLVoiceClient::inSpatialChannel(void) | ||
5596 | -{ | ||
5597 | - bool result = false; | ||
5598 | - | ||
5599 | - if(mAudioSession) | ||
5600 | - result = mAudioSession->mIsSpatial; | ||
5601 | - | ||
5602 | - return result; | ||
5603 | -} | ||
5604 | - | ||
5605 | -std::string LLVoiceClient::getAudioSessionURI() | ||
5606 | -{ | ||
5607 | - std::string result; | ||
5608 | - | ||
5609 | - if(mAudioSession) | ||
5610 | - result = mAudioSession->mSIPURI; | ||
5611 | - | ||
5612 | - return result; | ||
5613 | -} | ||
5614 | - | ||
5615 | -std::string LLVoiceClient::getAudioSessionHandle() | ||
5616 | -{ | ||
5617 | - std::string result; | ||
5618 | - | ||
5619 | - if(mAudioSession) | ||
5620 | - result = mAudioSession->mHandle; | ||
5621 | - | ||
5622 | - return result; | ||
5623 | -} | ||
5624 | - | ||
5625 | - | ||
5626 | ///////////////////////////// | ||
5627 | // Sending updates of current state | ||
5628 | |||
5629 | @@ -5507,8 +3548,7 @@ void LLVoiceClient::updatePosition(void) | ||
5630 | LLMatrix3 rot; | ||
5631 | LLVector3d pos; | ||
5632 | |||
5633 | - // TODO: If camera and avatar velocity are actually used by the voice system, we could compute them here... | ||
5634 | - // They're currently always set to zero. | ||
5635 | + // MBW -- XXX -- Setting both camera and avatar velocity to 0 for now. May figure it out later... | ||
5636 | |||
5637 | // Send the current camera position to the voice code | ||
5638 | rot.setRows(LLViewerCamera::getInstance()->getAtAxis(), LLViewerCamera::getInstance()->getLeftAxis (), LLViewerCamera::getInstance()->getUpAxis()); | ||
5639 | @@ -5523,7 +3563,7 @@ void LLVoiceClient::updatePosition(void) | ||
5640 | rot = agent->getRootJoint()->getWorldRotation().getMatrix3(); | ||
5641 | |||
5642 | pos = agent->getPositionGlobal(); | ||
5643 | - // TODO: Can we get the head offset from outside the LLVOAvatar? | ||
5644 | + // MBW -- XXX -- Can we get the head offset from outside the LLVOAvatar? | ||
5645 | // pos += LLVector3d(mHeadOffset); | ||
5646 | pos += LLVector3d(0.f, 0.f, 1.f); | ||
5647 | |||
5648 | @@ -5629,8 +3669,8 @@ void LLVoiceClient::setVoiceEnabled(bool enabled) | ||
5649 | } | ||
5650 | else | ||
5651 | { | ||
5652 | - // Turning voice off looses your current channel -- this makes sure the UI isn't out of sync when you re-enable it. | ||
5653 | - LLVoiceChannel::getCurrentVoiceChannel()->deactivate(); | ||
5654 | + // for now, leave active channel, to auto join when turning voice back on | ||
5655 | + //LLVoiceChannel::getCurrentVoiceChannel->deactivate(); | ||
5656 | } | ||
5657 | } | ||
5658 | } | ||
5659 | @@ -5710,34 +3750,56 @@ void LLVoiceClient::setEarLocation(S32 loc) | ||
5660 | |||
5661 | void LLVoiceClient::setVoiceVolume(F32 volume) | ||
5662 | { | ||
5663 | - int scaled_volume = scale_speaker_volume(volume); | ||
5664 | + LL_DEBUGS("Voice") << "volume is " << volume << LL_ENDL; | ||
5665 | |||
5666 | - if(scaled_volume != mSpeakerVolume) | ||
5667 | + // incoming volume has the range [0.0 ... 1.0], with 0.5 as the default. | ||
5668 | + // Map it as follows: 0.0 -> -100, 0.5 -> 24, 1.0 -> 50 | ||
5669 | + | ||
5670 | + volume -= 0.5f; // offset volume to the range [-0.5 ... 0.5], with 0 at the default. | ||
5671 | + int scaledVolume = 24; // offset scaledVolume by its default level | ||
5672 | + if(volume < 0.0f) | ||
5673 | + scaledVolume += ((int)(volume * 248.0f)); // (24 - (-100)) * 2 | ||
5674 | + else | ||
5675 | + scaledVolume += ((int)(volume * 52.0f)); // (50 - 24) * 2 | ||
5676 | + | ||
5677 | + if(scaledVolume != mSpeakerVolume) | ||
5678 | { | ||
5679 | - if((scaled_volume == 0) || (mSpeakerVolume == 0)) | ||
5680 | + if((scaledVolume == -100) || (mSpeakerVolume == -100)) | ||
5681 | { | ||
5682 | mSpeakerMuteDirty = true; | ||
5683 | } | ||
5684 | |||
5685 | - mSpeakerVolume = scaled_volume; | ||
5686 | + mSpeakerVolume = scaledVolume; | ||
5687 | mSpeakerVolumeDirty = true; | ||
5688 | } | ||
5689 | } | ||
5690 | |||
5691 | void LLVoiceClient::setMicGain(F32 volume) | ||
5692 | { | ||
5693 | - int scaled_volume = scale_mic_volume(volume); | ||
5694 | - | ||
5695 | - if(scaled_volume != mMicVolume) | ||
5696 | + int scaledVolume = ((int)(volume * 100.0f)) - 100; | ||
5697 | + if(scaledVolume != mMicVolume) | ||
5698 | { | ||
5699 | - mMicVolume = scaled_volume; | ||
5700 | + mMicVolume = scaledVolume; | ||
5701 | mMicVolumeDirty = true; | ||
5702 | } | ||
5703 | } | ||
5704 | |||
5705 | +void LLVoiceClient::setVivoxDebugServerName(std::string &serverName) | ||
5706 | +{ | ||
5707 | + if(!mAccountServerName.empty()) | ||
5708 | + { | ||
5709 | + // The name has been filled in already, which means we know whether we're connecting to agni or not. | ||
5710 | + if(!sConnectingToAgni) | ||
5711 | + { | ||
5712 | + // Only use the setting if we're connecting to a development grid -- always use bhr when on agni. | ||
5713 | + mAccountServerName = serverName; | ||
5714 | + } | ||
5715 | + } | ||
5716 | +} | ||
5717 | + | ||
5718 | void LLVoiceClient::keyDown(KEY key, MASK mask) | ||
5719 | { | ||
5720 | -// LL_DEBUGS("Voice") << "key is " << LLKeyboard::stringFromKey(key) << LL_ENDL; | ||
5721 | + LL_DEBUGS("Voice") << "key is " << LLKeyboard::stringFromKey(key) << LL_ENDL; | ||
5722 | |||
5723 | if (gKeyboard->getKeyRepeated(key)) | ||
5724 | { | ||
5725 | @@ -5875,6 +3937,19 @@ BOOL LLVoiceClient::getUsingPTT(const LLUUID& id) | ||
5726 | return result; | ||
5727 | } | ||
5728 | |||
5729 | +BOOL LLVoiceClient::getPTTPressed(const LLUUID& id) | ||
5730 | +{ | ||
5731 | + BOOL result = FALSE; | ||
5732 | + | ||
5733 | + participantState *participant = findParticipantByID(id); | ||
5734 | + if(participant) | ||
5735 | + { | ||
5736 | + result = participant->mPTT; | ||
5737 | + } | ||
5738 | + | ||
5739 | + return result; | ||
5740 | +} | ||
5741 | + | ||
5742 | BOOL LLVoiceClient::getOnMuteList(const LLUUID& id) | ||
5743 | { | ||
5744 | BOOL result = FALSE; | ||
5745 | @@ -5906,841 +3981,144 @@ F32 LLVoiceClient::getUserVolume(const LLUUID& id) | ||
5746 | |||
5747 | void LLVoiceClient::setUserVolume(const LLUUID& id, F32 volume) | ||
5748 | { | ||
5749 | - if(mAudioSession) | ||
5750 | - { | ||
5751 | - participantState *participant = findParticipantByID(id); | ||
5752 | - if (participant) | ||
5753 | - { | ||
5754 | - // volume can amplify by as much as 4x! | ||
5755 | - S32 ivol = (S32)(400.f * volume * volume); | ||
5756 | - participant->mUserVolume = llclamp(ivol, 0, 400); | ||
5757 | - participant->mVolumeDirty = TRUE; | ||
5758 | - mAudioSession->mVolumeDirty = TRUE; | ||
5759 | - } | ||
5760 | - } | ||
5761 | -} | ||
5762 | - | ||
5763 | -std::string LLVoiceClient::getGroupID(const LLUUID& id) | ||
5764 | -{ | ||
5765 | - std::string result; | ||
5766 | - | ||
5767 | participantState *participant = findParticipantByID(id); | ||
5768 | - if(participant) | ||
5769 | + if (participant) | ||
5770 | { | ||
5771 | - result = participant->mGroupID; | ||
5772 | + // volume can amplify by as much as 4x! | ||
5773 | + S32 ivol = (S32)(400.f * volume * volume); | ||
5774 | + participant->mUserVolume = llclamp(ivol, 0, 400); | ||
5775 | + participant->mVolumeDirty = TRUE; | ||
5776 | + mVolumeDirty = TRUE; | ||
5777 | } | ||
5778 | - | ||
5779 | - return result; | ||
5780 | } | ||
5781 | |||
5782 | -BOOL LLVoiceClient::getAreaVoiceDisabled() | ||
5783 | -{ | ||
5784 | - return mAreaVoiceDisabled; | ||
5785 | -} | ||
5786 | - | ||
5787 | -void LLVoiceClient::recordingLoopStart(int seconds, int deltaFramesPerControlFrame) | ||
5788 | -{ | ||
5789 | -// LL_DEBUGS("Voice") << "sending SessionGroup.ControlRecording (Start)" << LL_ENDL; | ||
5790 | - | ||
5791 | - if(!mMainSessionGroupHandle.empty()) | ||
5792 | - { | ||
5793 | - std::ostringstream stream; | ||
5794 | - stream | ||
5795 | - << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"SessionGroup.ControlRecording.1\">" | ||
5796 | - << "<SessionGroupHandle>" << mMainSessionGroupHandle << "</SessionGroupHandle>" | ||
5797 | - << "<RecordingControlType>Start</RecordingControlType>" | ||
5798 | - << "<DeltaFramesPerControlFrame>" << deltaFramesPerControlFrame << "</DeltaFramesPerControlFrame>" | ||
5799 | - << "<Filename>" << "" << "</Filename>" | ||
5800 | - << "<EnableAudioRecordingEvents>false</EnableAudioRecordingEvents>" | ||
5801 | - << "<LoopModeDurationSeconds>" << seconds << "</LoopModeDurationSeconds>" | ||
5802 | - << "</Request>\n\n\n"; | ||
5803 | |||
5804 | |||
5805 | - writeString(stream.str()); | ||
5806 | - } | ||
5807 | -} | ||
5808 | - | ||
5809 | -void LLVoiceClient::recordingLoopSave(const std::string& filename) | ||
5810 | +LLVoiceClient::serviceType LLVoiceClient::getServiceType(const LLUUID& id) | ||
5811 | { | ||
5812 | -// LL_DEBUGS("Voice") << "sending SessionGroup.ControlRecording (Flush)" << LL_ENDL; | ||
5813 | + serviceType result = serviceTypeUnknown; | ||
5814 | |||
5815 | - if(mAudioSession != NULL && !mAudioSession->mGroupHandle.empty()) | ||
5816 | - { | ||
5817 | - std::ostringstream stream; | ||
5818 | - stream | ||
5819 | - << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"SessionGroup.ControlRecording.1\">" | ||
5820 | - << "<SessionGroupHandle>" << mMainSessionGroupHandle << "</SessionGroupHandle>" | ||
5821 | - << "<RecordingControlType>Flush</RecordingControlType>" | ||
5822 | - << "<Filename>" << filename << "</Filename>" | ||
5823 | - << "</Request>\n\n\n"; | ||
5824 | - | ||
5825 | - writeString(stream.str()); | ||
5826 | - } | ||
5827 | -} | ||
5828 | - | ||
5829 | -void LLVoiceClient::recordingStop() | ||
5830 | -{ | ||
5831 | -// LL_DEBUGS("Voice") << "sending SessionGroup.ControlRecording (Stop)" << LL_ENDL; | ||
5832 | - | ||
5833 | - if(mAudioSession != NULL && !mAudioSession->mGroupHandle.empty()) | ||
5834 | - { | ||
5835 | - std::ostringstream stream; | ||
5836 | - stream | ||
5837 | - << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"SessionGroup.ControlRecording.1\">" | ||
5838 | - << "<SessionGroupHandle>" << mMainSessionGroupHandle << "</SessionGroupHandle>" | ||
5839 | - << "<RecordingControlType>Stop</RecordingControlType>" | ||
5840 | - << "</Request>\n\n\n"; | ||
5841 | - | ||
5842 | - writeString(stream.str()); | ||
5843 | - } | ||
5844 | -} | ||
5845 | - | ||
5846 | -void LLVoiceClient::filePlaybackStart(const std::string& filename) | ||
5847 | -{ | ||
5848 | -// LL_DEBUGS("Voice") << "sending SessionGroup.ControlPlayback (Start)" << LL_ENDL; | ||
5849 | - | ||
5850 | - if(mAudioSession != NULL && !mAudioSession->mGroupHandle.empty()) | ||
5851 | - { | ||
5852 | - std::ostringstream stream; | ||
5853 | - stream | ||
5854 | - << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"SessionGroup.ControlPlayback.1\">" | ||
5855 | - << "<SessionGroupHandle>" << mMainSessionGroupHandle << "</SessionGroupHandle>" | ||
5856 | - << "<RecordingControlType>Start</RecordingControlType>" | ||
5857 | - << "<Filename>" << filename << "</Filename>" | ||
5858 | - << "</Request>\n\n\n"; | ||
5859 | - | ||
5860 | - writeString(stream.str()); | ||
5861 | - } | ||
5862 | -} | ||
5863 | - | ||
5864 | -void LLVoiceClient::filePlaybackStop() | ||
5865 | -{ | ||
5866 | -// LL_DEBUGS("Voice") << "sending SessionGroup.ControlPlayback (Stop)" << LL_ENDL; | ||
5867 | - | ||
5868 | - if(mAudioSession != NULL && !mAudioSession->mGroupHandle.empty()) | ||
5869 | - { | ||
5870 | - std::ostringstream stream; | ||
5871 | - stream | ||
5872 | - << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"SessionGroup.ControlPlayback.1\">" | ||
5873 | - << "<SessionGroupHandle>" << mMainSessionGroupHandle << "</SessionGroupHandle>" | ||
5874 | - << "<RecordingControlType>Stop</RecordingControlType>" | ||
5875 | - << "</Request>\n\n\n"; | ||
5876 | - | ||
5877 | - writeString(stream.str()); | ||
5878 | - } | ||
5879 | -} | ||
5880 | - | ||
5881 | -void LLVoiceClient::filePlaybackSetPaused(bool paused) | ||
5882 | -{ | ||
5883 | - // TODO: Implement once Vivox gives me a sample | ||
5884 | -} | ||
5885 | - | ||
5886 | -void LLVoiceClient::filePlaybackSetMode(bool vox, float speed) | ||
5887 | -{ | ||
5888 | - // TODO: Implement once Vivox gives me a sample | ||
5889 | -} | ||
5890 | - | ||
5891 | -LLVoiceClient::sessionState::sessionState() : | ||
5892 | - mMediaStreamState(streamStateUnknown), | ||
5893 | - mTextStreamState(streamStateUnknown), | ||
5894 | - mCreateInProgress(false), | ||
5895 | - mMediaConnectInProgress(false), | ||
5896 | - mVoiceInvitePending(false), | ||
5897 | - mTextInvitePending(false), | ||
5898 | - mSynthesizedCallerID(false), | ||
5899 | - mIsChannel(false), | ||
5900 | - mIsSpatial(false), | ||
5901 | - mIsP2P(false), | ||
5902 | - mIncoming(false), | ||
5903 | - mVoiceEnabled(false), | ||
5904 | - mReconnect(false), | ||
5905 | - mVolumeDirty(false), | ||
5906 | - mParticipantsChanged(false) | ||
5907 | -{ | ||
5908 | -} | ||
5909 | - | ||
5910 | -LLVoiceClient::sessionState::~sessionState() | ||
5911 | -{ | ||
5912 | - removeAllParticipants(); | ||
5913 | -} | ||
5914 | - | ||
5915 | -LLVoiceClient::sessionIterator LLVoiceClient::sessionsBegin(void) | ||
5916 | -{ | ||
5917 | - return mSessions.begin(); | ||
5918 | -} | ||
5919 | - | ||
5920 | -LLVoiceClient::sessionIterator LLVoiceClient::sessionsEnd(void) | ||
5921 | -{ | ||
5922 | - return mSessions.end(); | ||
5923 | -} | ||
5924 | - | ||
5925 | - | ||
5926 | -LLVoiceClient::sessionState *LLVoiceClient::findSession(const std::string &handle) | ||
5927 | -{ | ||
5928 | - sessionState *result = NULL; | ||
5929 | - sessionMap::iterator iter = mSessionsByHandle.find(&handle); | ||
5930 | - if(iter != mSessionsByHandle.end()) | ||
5931 | - { | ||
5932 | - result = iter->second; | ||
5933 | - } | ||
5934 | - | ||
5935 | - return result; | ||
5936 | -} | ||
5937 | - | ||
5938 | -LLVoiceClient::sessionState *LLVoiceClient::findSessionBeingCreatedByURI(const std::string &uri) | ||
5939 | -{ | ||
5940 | - sessionState *result = NULL; | ||
5941 | - for(sessionIterator iter = sessionsBegin(); iter != sessionsEnd(); iter++) | ||
5942 | - { | ||
5943 | - sessionState *session = *iter; | ||
5944 | - if(session->mCreateInProgress && (session->mSIPURI == uri)) | ||
5945 | - { | ||
5946 | - result = session; | ||
5947 | - break; | ||
5948 | - } | ||
5949 | - } | ||
5950 | - | ||
5951 | - return result; | ||
5952 | -} | ||
5953 | - | ||
5954 | -LLVoiceClient::sessionState *LLVoiceClient::findSession(const LLUUID &participant_id) | ||
5955 | -{ | ||
5956 | - sessionState *result = NULL; | ||
5957 | - | ||
5958 | - for(sessionIterator iter = sessionsBegin(); iter != sessionsEnd(); iter++) | ||
5959 | - { | ||
5960 | - sessionState *session = *iter; | ||
5961 | - if(session->mCallerID == participant_id) | ||
5962 | - { | ||
5963 | - result = session; | ||
5964 | - break; | ||
5965 | - } | ||
5966 | - } | ||
5967 | - | ||
5968 | - return result; | ||
5969 | -} | ||
5970 | - | ||
5971 | -LLVoiceClient::sessionState *LLVoiceClient::addSession(const std::string &uri, const std::string &handle) | ||
5972 | -{ | ||
5973 | - sessionState *result = NULL; | ||
5974 | - | ||
5975 | - if(handle.empty()) | ||
5976 | - { | ||
5977 | - // No handle supplied. | ||
5978 | - // Check whether there's already a session with this URI | ||
5979 | - for(sessionIterator iter = sessionsBegin(); iter != sessionsEnd(); iter++) | ||
5980 | - { | ||
5981 | - sessionState *s = *iter; | ||
5982 | - if((s->mSIPURI == uri) || (s->mAlternateSIPURI == uri)) | ||
5983 | - { | ||
5984 | - // TODO: I need to think about this logic... it's possible that this case should raise an internal error. | ||
5985 | - result = s; | ||
5986 | - break; | ||
5987 | - } | ||
5988 | - } | ||
5989 | - } | ||
5990 | - else // (!handle.empty()) | ||
5991 | - { | ||
5992 | - // Check for an existing session with this handle | ||
5993 | - sessionMap::iterator iter = mSessionsByHandle.find(&handle); | ||
5994 | - | ||
5995 | - if(iter != mSessionsByHandle.end()) | ||
5996 | - { | ||
5997 | - result = iter->second; | ||
5998 | - } | ||
5999 | - } | ||
6000 | - | ||
6001 | - if(!result) | ||
6002 | - { | ||
6003 | - // No existing session found. | ||
6004 | - | ||
6005 | - LL_DEBUGS("Voice") << "adding new session: handle " << handle << " URI " << uri << LL_ENDL; | ||
6006 | - result = new sessionState(); | ||
6007 | - result->mSIPURI = uri; | ||
6008 | - result->mHandle = handle; | ||
6009 | - | ||
6010 | - mSessions.insert(result); | ||
6011 | - | ||
6012 | - if(!result->mHandle.empty()) | ||
6013 | - { | ||
6014 | - mSessionsByHandle.insert(sessionMap::value_type(&(result->mHandle), result)); | ||
6015 | - } | ||
6016 | - } | ||
6017 | - else | ||
6018 | - { | ||
6019 | - // Found an existing session | ||
6020 | - | ||
6021 | - if(uri != result->mSIPURI) | ||
6022 | - { | ||
6023 | - // TODO: Should this be an internal error? | ||
6024 | - LL_DEBUGS("Voice") << "changing uri from " << result->mSIPURI << " to " << uri << LL_ENDL; | ||
6025 | - setSessionURI(result, uri); | ||
6026 | - } | ||
6027 | - | ||
6028 | - if(handle != result->mHandle) | ||
6029 | - { | ||
6030 | - // TODO: Should this be an internal error? | ||
6031 | - LL_DEBUGS("Voice") << "changing handle from " << result->mHandle << " to " << handle << LL_ENDL; | ||
6032 | - setSessionHandle(result, handle); | ||
6033 | - } | ||
6034 | - | ||
6035 | - LL_DEBUGS("Voice") << "returning existing session: handle " << handle << " URI " << uri << LL_ENDL; | ||
6036 | - } | ||
6037 | - | ||
6038 | - verifySessionState(); | ||
6039 | - | ||
6040 | - return result; | ||
6041 | -} | ||
6042 | - | ||
6043 | -void LLVoiceClient::setSessionHandle(sessionState *session, const std::string &handle) | ||
6044 | -{ | ||
6045 | - // Have to remove the session from the handle-indexed map before changing the handle, or things will break badly. | ||
6046 | - | ||
6047 | - if(!session->mHandle.empty()) | ||
6048 | - { | ||
6049 | - // Remove session from the map if it should have been there. | ||
6050 | - sessionMap::iterator iter = mSessionsByHandle.find(&(session->mHandle)); | ||
6051 | - if(iter != mSessionsByHandle.end()) | ||
6052 | - { | ||
6053 | - if(iter->second != session) | ||
6054 | - { | ||
6055 | - LL_ERRS("Voice") << "Internal error: session mismatch!" << LL_ENDL; | ||
6056 | - } | ||
6057 | - | ||
6058 | - mSessionsByHandle.erase(iter); | ||
6059 | - } | ||
6060 | - else | ||
6061 | - { | ||
6062 | - LL_ERRS("Voice") << "Internal error: session handle not found in map!" << LL_ENDL; | ||
6063 | - } | ||
6064 | - } | ||
6065 | - | ||
6066 | - session->mHandle = handle; | ||
6067 | - | ||
6068 | - if(!handle.empty()) | ||
6069 | - { | ||
6070 | - mSessionsByHandle.insert(sessionMap::value_type(&(session->mHandle), session)); | ||
6071 | - } | ||
6072 | - | ||
6073 | - verifySessionState(); | ||
6074 | -} | ||
6075 | - | ||
6076 | -void LLVoiceClient::setSessionURI(sessionState *session, const std::string &uri) | ||
6077 | -{ | ||
6078 | - // There used to be a map of session URIs to sessions, which made this complex.... | ||
6079 | - session->mSIPURI = uri; | ||
6080 | - | ||
6081 | - verifySessionState(); | ||
6082 | -} | ||
6083 | - | ||
6084 | -void LLVoiceClient::deleteSession(sessionState *session) | ||
6085 | -{ | ||
6086 | - // Remove the session from the handle map | ||
6087 | - if(!session->mHandle.empty()) | ||
6088 | - { | ||
6089 | - sessionMap::iterator iter = mSessionsByHandle.find(&(session->mHandle)); | ||
6090 | - if(iter != mSessionsByHandle.end()) | ||
6091 | - { | ||
6092 | - if(iter->second != session) | ||
6093 | - { | ||
6094 | - LL_ERRS("Voice") << "Internal error: session mismatch" << LL_ENDL | ||
6095 | - } | ||
6096 | - mSessionsByHandle.erase(iter); | ||
6097 | - } | ||
6098 | - } | ||
6099 | - | ||
6100 | - // Remove the session from the URI map | ||
6101 | - mSessions.erase(session); | ||
6102 | - | ||
6103 | - // At this point, the session should be unhooked from all lists and all state should be consistent. | ||
6104 | - verifySessionState(); | ||
6105 | - | ||
6106 | - // If this is the current audio session, clean up the pointer which will soon be dangling. | ||
6107 | - if(mAudioSession == session) | ||
6108 | - { | ||
6109 | - mAudioSession = NULL; | ||
6110 | - mAudioSessionChanged = true; | ||
6111 | - } | ||
6112 | - | ||
6113 | - // ditto for the next audio session | ||
6114 | - if(mNextAudioSession == session) | ||
6115 | - { | ||
6116 | - mNextAudioSession = NULL; | ||
6117 | - } | ||
6118 | - | ||
6119 | - // delete the session | ||
6120 | - delete session; | ||
6121 | -} | ||
6122 | - | ||
6123 | -void LLVoiceClient::deleteAllSessions() | ||
6124 | -{ | ||
6125 | - LL_DEBUGS("Voice") << "called" << LL_ENDL; | ||
6126 | - | ||
6127 | - while(!mSessions.empty()) | ||
6128 | - { | ||
6129 | - deleteSession(*(sessionsBegin())); | ||
6130 | - } | ||
6131 | - | ||
6132 | - if(!mSessionsByHandle.empty()) | ||
6133 | - { | ||
6134 | - LL_ERRS("Voice") << "Internal error: empty session map, non-empty handle map" << LL_ENDL | ||
6135 | - } | ||
6136 | -} | ||
6137 | - | ||
6138 | -void LLVoiceClient::verifySessionState(void) | ||
6139 | -{ | ||
6140 | - // This is mostly intended for debugging problems with session state management. | ||
6141 | - LL_DEBUGS("Voice") << "Total session count: " << mSessions.size() << " , session handle map size: " << mSessionsByHandle.size() << LL_ENDL; | ||
6142 | - | ||
6143 | - for(sessionIterator iter = sessionsBegin(); iter != sessionsEnd(); iter++) | ||
6144 | - { | ||
6145 | - sessionState *session = *iter; | ||
6146 | - | ||
6147 | - LL_DEBUGS("Voice") << "session " << session << ": handle " << session->mHandle << ", URI " << session->mSIPURI << LL_ENDL; | ||
6148 | - | ||
6149 | - if(!session->mHandle.empty()) | ||
6150 | - { | ||
6151 | - // every session with a non-empty handle needs to be in the handle map | ||
6152 | - sessionMap::iterator i2 = mSessionsByHandle.find(&(session->mHandle)); | ||
6153 | - if(i2 == mSessionsByHandle.end()) | ||
6154 | - { | ||
6155 | - LL_ERRS("Voice") << "internal error (handle " << session->mHandle << " not found in session map)" << LL_ENDL; | ||
6156 | - } | ||
6157 | - else | ||
6158 | - { | ||
6159 | - if(i2->second != session) | ||
6160 | - { | ||
6161 | - LL_ERRS("Voice") << "internal error (handle " << session->mHandle << " in session map points to another session)" << LL_ENDL; | ||
6162 | - } | ||
6163 | - } | ||
6164 | - } | ||
6165 | - } | ||
6166 | - | ||
6167 | - // check that every entry in the handle map points to a valid session in the session set | ||
6168 | - for(sessionMap::iterator iter = mSessionsByHandle.begin(); iter != mSessionsByHandle.end(); iter++) | ||
6169 | - { | ||
6170 | - sessionState *session = iter->second; | ||
6171 | - sessionIterator i2 = mSessions.find(session); | ||
6172 | - if(i2 == mSessions.end()) | ||
6173 | - { | ||
6174 | - LL_ERRS("Voice") << "internal error (session for handle " << session->mHandle << " not found in session map)" << LL_ENDL; | ||
6175 | - } | ||
6176 | - else | ||
6177 | - { | ||
6178 | - if(session->mHandle != (*i2)->mHandle) | ||
6179 | - { | ||
6180 | - LL_ERRS("Voice") << "internal error (session for handle " << session->mHandle << " points to session with different handle " << (*i2)->mHandle << ")" << LL_ENDL; | ||
6181 | - } | ||
6182 | - } | ||
6183 | - } | ||
6184 | -} | ||
6185 | - | ||
6186 | -LLVoiceClient::buddyListEntry::buddyListEntry(const std::string &uri) : | ||
6187 | - mURI(uri) | ||
6188 | -{ | ||
6189 | - mOnlineSL = false; | ||
6190 | - mOnlineSLim = false; | ||
6191 | - mCanSeeMeOnline = true; | ||
6192 | - mHasBlockListEntry = false; | ||
6193 | - mHasAutoAcceptListEntry = false; | ||
6194 | - mNameResolved = false; | ||
6195 | - mInVivoxBuddies = false; | ||
6196 | - mInSLFriends = false; | ||
6197 | - mNeedsNameUpdate = false; | ||
6198 | -} | ||
6199 | - | ||
6200 | -void LLVoiceClient::processBuddyListEntry(const std::string &uri, const std::string &displayName) | ||
6201 | -{ | ||
6202 | - buddyListEntry *buddy = addBuddy(uri, displayName); | ||
6203 | - buddy->mInVivoxBuddies = true; | ||
6204 | -} | ||
6205 | - | ||
6206 | -LLVoiceClient::buddyListEntry *LLVoiceClient::addBuddy(const std::string &uri) | ||
6207 | -{ | ||
6208 | - std::string empty; | ||
6209 | - buddyListEntry *buddy = addBuddy(uri, empty); | ||
6210 | - if(buddy->mDisplayName.empty()) | ||
6211 | - { | ||
6212 | - buddy->mNameResolved = false; | ||
6213 | - } | ||
6214 | - return buddy; | ||
6215 | -} | ||
6216 | - | ||
6217 | -LLVoiceClient::buddyListEntry *LLVoiceClient::addBuddy(const std::string &uri, const std::string &displayName) | ||
6218 | -{ | ||
6219 | - buddyListEntry *result = NULL; | ||
6220 | - buddyListMap::iterator iter = mBuddyListMap.find(&uri); | ||
6221 | - | ||
6222 | - if(iter != mBuddyListMap.end()) | ||
6223 | - { | ||
6224 | - // Found a matching buddy already in the map. | ||
6225 | - LL_DEBUGS("Voice") << "adding existing buddy " << uri << LL_ENDL; | ||
6226 | - result = iter->second; | ||
6227 | - } | ||
6228 | - | ||
6229 | - if(!result) | ||
6230 | - { | ||
6231 | - // participant isn't already in one list or the other. | ||
6232 | - LL_DEBUGS("Voice") << "adding new buddy " << uri << LL_ENDL; | ||
6233 | - result = new buddyListEntry(uri); | ||
6234 | - result->mDisplayName = displayName; | ||
6235 | - | ||
6236 | - if(IDFromName(uri, result->mUUID)) | ||
6237 | - { | ||
6238 | - // Extracted UUID from name successfully. | ||
6239 | - } | ||
6240 | - else | ||
6241 | - { | ||
6242 | - LL_DEBUGS("Voice") << "Couldn't find ID for buddy " << uri << " (\"" << displayName << "\")" << LL_ENDL; | ||
6243 | - } | ||
6244 | - | ||
6245 | - mBuddyListMap.insert(buddyListMap::value_type(&(result->mURI), result)); | ||
6246 | - } | ||
6247 | - | ||
6248 | - return result; | ||
6249 | -} | ||
6250 | - | ||
6251 | -LLVoiceClient::buddyListEntry *LLVoiceClient::findBuddy(const std::string &uri) | ||
6252 | -{ | ||
6253 | - buddyListEntry *result = NULL; | ||
6254 | - buddyListMap::iterator iter = mBuddyListMap.find(&uri); | ||
6255 | - if(iter != mBuddyListMap.end()) | ||
6256 | - { | ||
6257 | - result = iter->second; | ||
6258 | - } | ||
6259 | - | ||
6260 | - return result; | ||
6261 | -} | ||
6262 | - | ||
6263 | -LLVoiceClient::buddyListEntry *LLVoiceClient::findBuddy(const LLUUID &id) | ||
6264 | -{ | ||
6265 | - buddyListEntry *result = NULL; | ||
6266 | - buddyListMap::iterator iter; | ||
6267 | - | ||
6268 | - for(iter = mBuddyListMap.begin(); iter != mBuddyListMap.end(); iter++) | ||
6269 | + participantState *participant = findParticipantByID(id); | ||
6270 | + if(participant) | ||
6271 | { | ||
6272 | - if(iter->second->mUUID == id) | ||
6273 | - { | ||
6274 | - result = iter->second; | ||
6275 | - break; | ||
6276 | - } | ||
6277 | + result = participant->mServiceType; | ||
6278 | } | ||
6279 | |||
6280 | return result; | ||
6281 | } | ||
6282 | |||
6283 | -LLVoiceClient::buddyListEntry *LLVoiceClient::findBuddyByDisplayName(const std::string &name) | ||
6284 | +std::string LLVoiceClient::getGroupID(const LLUUID& id) | ||
6285 | { | ||
6286 | - buddyListEntry *result = NULL; | ||
6287 | - buddyListMap::iterator iter; | ||
6288 | + std::string result; | ||
6289 | |||
6290 | - for(iter = mBuddyListMap.begin(); iter != mBuddyListMap.end(); iter++) | ||
6291 | + participantState *participant = findParticipantByID(id); | ||
6292 | + if(participant) | ||
6293 | { | ||
6294 | - if(iter->second->mDisplayName == name) | ||
6295 | - { | ||
6296 | - result = iter->second; | ||
6297 | - break; | ||
6298 | - } | ||
6299 | + result = participant->mGroupID; | ||
6300 | } | ||
6301 | |||
6302 | return result; | ||
6303 | } | ||
6304 | |||
6305 | -void LLVoiceClient::deleteBuddy(const std::string &uri) | ||
6306 | -{ | ||
6307 | - buddyListMap::iterator iter = mBuddyListMap.find(&uri); | ||
6308 | - if(iter != mBuddyListMap.end()) | ||
6309 | - { | ||
6310 | - LL_DEBUGS("Voice") << "deleting buddy " << uri << LL_ENDL; | ||
6311 | - buddyListEntry *buddy = iter->second; | ||
6312 | - mBuddyListMap.erase(iter); | ||
6313 | - delete buddy; | ||
6314 | - } | ||
6315 | - else | ||
6316 | - { | ||
6317 | - LL_DEBUGS("Voice") << "attempt to delete nonexistent buddy " << uri << LL_ENDL; | ||
6318 | - } | ||
6319 | - | ||
6320 | -} | ||
6321 | - | ||
6322 | -void LLVoiceClient::deleteAllBuddies(void) | ||
6323 | -{ | ||
6324 | - while(!mBuddyListMap.empty()) | ||
6325 | - { | ||
6326 | - deleteBuddy(*(mBuddyListMap.begin()->first)); | ||
6327 | - } | ||
6328 | - | ||
6329 | - // Don't want to correlate with friends list when we've emptied the buddy list. | ||
6330 | - mBuddyListMapPopulated = false; | ||
6331 | - | ||
6332 | - // Don't want to correlate with friends list when we've reset the block rules. | ||
6333 | - mBlockRulesListReceived = false; | ||
6334 | - mAutoAcceptRulesListReceived = false; | ||
6335 | -} | ||
6336 | - | ||
6337 | -void LLVoiceClient::deleteAllBlockRules(void) | ||
6338 | -{ | ||
6339 | - // Clear the block list entry flags from all local buddy list entries | ||
6340 | - buddyListMap::iterator buddy_it; | ||
6341 | - for(buddy_it = mBuddyListMap.begin(); buddy_it != mBuddyListMap.end(); buddy_it++) | ||
6342 | - { | ||
6343 | - buddy_it->second->mHasBlockListEntry = false; | ||
6344 | - } | ||
6345 | -} | ||
6346 | - | ||
6347 | -void LLVoiceClient::deleteAllAutoAcceptRules(void) | ||
6348 | -{ | ||
6349 | - // Clear the auto-accept list entry flags from all local buddy list entries | ||
6350 | - buddyListMap::iterator buddy_it; | ||
6351 | - for(buddy_it = mBuddyListMap.begin(); buddy_it != mBuddyListMap.end(); buddy_it++) | ||
6352 | - { | ||
6353 | - buddy_it->second->mHasAutoAcceptListEntry = false; | ||
6354 | - } | ||
6355 | -} | ||
6356 | - | ||
6357 | -void LLVoiceClient::addBlockRule(const std::string &blockMask, const std::string &presenceOnly) | ||
6358 | -{ | ||
6359 | - buddyListEntry *buddy = NULL; | ||
6360 | - | ||
6361 | - // blockMask is the SIP URI of a friends list entry | ||
6362 | - buddyListMap::iterator iter = mBuddyListMap.find(&blockMask); | ||
6363 | - if(iter != mBuddyListMap.end()) | ||
6364 | - { | ||
6365 | - LL_DEBUGS("Voice") << "block list entry for " << blockMask << LL_ENDL; | ||
6366 | - buddy = iter->second; | ||
6367 | - } | ||
6368 | - | ||
6369 | - if(buddy == NULL) | ||
6370 | - { | ||
6371 | - LL_DEBUGS("Voice") << "block list entry for unknown buddy " << blockMask << LL_ENDL; | ||
6372 | - buddy = addBuddy(blockMask); | ||
6373 | - } | ||
6374 | - | ||
6375 | - if(buddy != NULL) | ||
6376 | - { | ||
6377 | - buddy->mHasBlockListEntry = true; | ||
6378 | - } | ||
6379 | -} | ||
6380 | - | ||
6381 | -void LLVoiceClient::addAutoAcceptRule(const std::string &autoAcceptMask, const std::string &autoAddAsBuddy) | ||
6382 | -{ | ||
6383 | - buddyListEntry *buddy = NULL; | ||
6384 | - | ||
6385 | - // blockMask is the SIP URI of a friends list entry | ||
6386 | - buddyListMap::iterator iter = mBuddyListMap.find(&autoAcceptMask); | ||
6387 | - if(iter != mBuddyListMap.end()) | ||
6388 | - { | ||
6389 | - LL_DEBUGS("Voice") << "auto-accept list entry for " << autoAcceptMask << LL_ENDL; | ||
6390 | - buddy = iter->second; | ||
6391 | - } | ||
6392 | - | ||
6393 | - if(buddy == NULL) | ||
6394 | - { | ||
6395 | - LL_DEBUGS("Voice") << "auto-accept list entry for unknown buddy " << autoAcceptMask << LL_ENDL; | ||
6396 | - buddy = addBuddy(autoAcceptMask); | ||
6397 | - } | ||
6398 | - | ||
6399 | - if(buddy != NULL) | ||
6400 | - { | ||
6401 | - buddy->mHasAutoAcceptListEntry = true; | ||
6402 | - } | ||
6403 | -} | ||
6404 | - | ||
6405 | -void LLVoiceClient::accountListBlockRulesResponse(int statusCode, const std::string &statusString) | ||
6406 | -{ | ||
6407 | - // Block list entries were updated via addBlockRule() during parsing. Just flag that we're done. | ||
6408 | - mBlockRulesListReceived = true; | ||
6409 | -} | ||
6410 | - | ||
6411 | -void LLVoiceClient::accountListAutoAcceptRulesResponse(int statusCode, const std::string &statusString) | ||
6412 | +BOOL LLVoiceClient::getAreaVoiceDisabled() | ||
6413 | { | ||
6414 | - // Block list entries were updated via addBlockRule() during parsing. Just flag that we're done. | ||
6415 | - mAutoAcceptRulesListReceived = true; | ||
6416 | + return mAreaVoiceDisabled; | ||
6417 | } | ||
6418 | |||
6419 | void LLVoiceClient::addObserver(LLVoiceClientParticipantObserver* observer) | ||
6420 | { | ||
6421 | - mParticipantObservers.insert(observer); | ||
6422 | + mObservers.insert(observer); | ||
6423 | } | ||
6424 | |||
6425 | void LLVoiceClient::removeObserver(LLVoiceClientParticipantObserver* observer) | ||
6426 | { | ||
6427 | - mParticipantObservers.erase(observer); | ||
6428 | + mObservers.erase(observer); | ||
6429 | } | ||
6430 | |||
6431 | -void LLVoiceClient::notifyParticipantObservers() | ||
6432 | +void LLVoiceClient::notifyObservers() | ||
6433 | { | ||
6434 | - for (observer_set_t::iterator it = mParticipantObservers.begin(); | ||
6435 | - it != mParticipantObservers.end(); | ||
6436 | + for (observer_set_t::iterator it = mObservers.begin(); | ||
6437 | + it != mObservers.end(); | ||
6438 | ) | ||
6439 | { | ||
6440 | LLVoiceClientParticipantObserver* observer = *it; | ||
6441 | observer->onChange(); | ||
6442 | // In case onChange() deleted an entry. | ||
6443 | - it = mParticipantObservers.upper_bound(observer); | ||
6444 | + it = mObservers.upper_bound(observer); | ||
6445 | } | ||
6446 | } | ||
6447 | |||
6448 | -void LLVoiceClient::addObserver(LLVoiceClientStatusObserver* observer) | ||
6449 | +void LLVoiceClient::addStatusObserver(LLVoiceClientStatusObserver* observer) | ||
6450 | { | ||
6451 | mStatusObservers.insert(observer); | ||
6452 | } | ||
6453 | |||
6454 | -void LLVoiceClient::removeObserver(LLVoiceClientStatusObserver* observer) | ||
6455 | +void LLVoiceClient::removeStatusObserver(LLVoiceClientStatusObserver* observer) | ||
6456 | { | ||
6457 | mStatusObservers.erase(observer); | ||
6458 | } | ||
6459 | |||
6460 | void LLVoiceClient::notifyStatusObservers(LLVoiceClientStatusObserver::EStatusType status) | ||
6461 | { | ||
6462 | - if(mAudioSession) | ||
6463 | + if(status == LLVoiceClientStatusObserver::ERROR_UNKNOWN) | ||
6464 | { | ||
6465 | - if(status == LLVoiceClientStatusObserver::ERROR_UNKNOWN) | ||
6466 | - { | ||
6467 | - switch(mAudioSession->mErrorStatusCode) | ||
6468 | - { | ||
6469 | - case 20713: status = LLVoiceClientStatusObserver::ERROR_CHANNEL_FULL; break; | ||
6470 | - case 20714: status = LLVoiceClientStatusObserver::ERROR_CHANNEL_LOCKED; break; | ||
6471 | - case 20715: | ||
6472 | - //invalid channel, we may be using a set of poorly cached | ||
6473 | - //info | ||
6474 | - status = LLVoiceClientStatusObserver::ERROR_NOT_AVAILABLE; | ||
6475 | - break; | ||
6476 | - case 1009: | ||
6477 | - //invalid username and password | ||
6478 | - status = LLVoiceClientStatusObserver::ERROR_NOT_AVAILABLE; | ||
6479 | - break; | ||
6480 | - } | ||
6481 | - | ||
6482 | - // Reset the error code to make sure it won't be reused later by accident. | ||
6483 | - mAudioSession->mErrorStatusCode = 0; | ||
6484 | - } | ||
6485 | - else if(status == LLVoiceClientStatusObserver::STATUS_LEFT_CHANNEL) | ||
6486 | + switch(mVivoxErrorStatusCode) | ||
6487 | { | ||
6488 | - switch(mAudioSession->mErrorStatusCode) | ||
6489 | - { | ||
6490 | - case 404: // NOT_FOUND | ||
6491 | - case 480: // TEMPORARILY_UNAVAILABLE | ||
6492 | - case 408: // REQUEST_TIMEOUT | ||
6493 | - // call failed because other user was not available | ||
6494 | - // treat this as an error case | ||
6495 | - status = LLVoiceClientStatusObserver::ERROR_NOT_AVAILABLE; | ||
6496 | - | ||
6497 | - // Reset the error code to make sure it won't be reused later by accident. | ||
6498 | - mAudioSession->mErrorStatusCode = 0; | ||
6499 | - break; | ||
6500 | - } | ||
6501 | + case 20713: status = LLVoiceClientStatusObserver::ERROR_CHANNEL_FULL; break; | ||
6502 | + case 20714: status = LLVoiceClientStatusObserver::ERROR_CHANNEL_LOCKED; break; | ||
6503 | + case 20715: | ||
6504 | + //invalid channel, we may be using a set of poorly cached | ||
6505 | + //info | ||
6506 | + status = LLVoiceClientStatusObserver::ERROR_NOT_AVAILABLE; | ||
6507 | + break; | ||
6508 | + case 1009: | ||
6509 | + //invalid username and password | ||
6510 | + status = LLVoiceClientStatusObserver::ERROR_NOT_AVAILABLE; | ||
6511 | + break; | ||
6512 | } | ||
6513 | + | ||
6514 | + // Reset the error code to make sure it won't be reused later by accident. | ||
6515 | + mVivoxErrorStatusCode = 0; | ||
6516 | } | ||
6517 | - | ||
6518 | - LL_DEBUGS("Voice") | ||
6519 | - << " " << LLVoiceClientStatusObserver::status2string(status) | ||
6520 | - << ", session URI " << getAudioSessionURI() | ||
6521 | - << (inSpatialChannel()?", proximal is true":", proximal is false") | ||
6522 | - << LL_ENDL; | ||
6523 | + | ||
6524 | + if (status == LLVoiceClientStatusObserver::STATUS_LEFT_CHANNEL | ||
6525 | + //NOT_FOUND || TEMPORARILY_UNAVAILABLE || REQUEST_TIMEOUT | ||
6526 | + && (mVivoxErrorStatusCode == 404 || mVivoxErrorStatusCode == 480 || mVivoxErrorStatusCode == 408)) | ||
6527 | + { | ||
6528 | + // call failed because other user was not available | ||
6529 | + // treat this as an error case | ||
6530 | + status = LLVoiceClientStatusObserver::ERROR_NOT_AVAILABLE; | ||
6531 | + | ||
6532 | + // Reset the error code to make sure it won't be reused later by accident. | ||
6533 | + mVivoxErrorStatusCode = 0; | ||
6534 | + } | ||
6535 | + | ||
6536 | + LL_DEBUGS("Voice") << " " << LLVoiceClientStatusObserver::status2string(status) << ", session URI " << mSessionURI << LL_ENDL; | ||
6537 | |||
6538 | for (status_observer_set_t::iterator it = mStatusObservers.begin(); | ||
6539 | it != mStatusObservers.end(); | ||
6540 | ) | ||
6541 | { | ||
6542 | LLVoiceClientStatusObserver* observer = *it; | ||
6543 | - observer->onChange(status, getAudioSessionURI(), inSpatialChannel()); | ||
6544 | + observer->onChange(status, mSessionURI, !mNonSpatialChannel); | ||
6545 | // In case onError() deleted an entry. | ||
6546 | it = mStatusObservers.upper_bound(observer); | ||
6547 | } | ||
6548 | |||
6549 | } | ||
6550 | |||
6551 | -void LLVoiceClient::addObserver(LLFriendObserver* observer) | ||
6552 | -{ | ||
6553 | - mFriendObservers.insert(observer); | ||
6554 | -} | ||
6555 | - | ||
6556 | -void LLVoiceClient::removeObserver(LLFriendObserver* observer) | ||
6557 | -{ | ||
6558 | - mFriendObservers.erase(observer); | ||
6559 | -} | ||
6560 | - | ||
6561 | -void LLVoiceClient::notifyFriendObservers() | ||
6562 | -{ | ||
6563 | - for (friend_observer_set_t::iterator it = mFriendObservers.begin(); | ||
6564 | - it != mFriendObservers.end(); | ||
6565 | - ) | ||
6566 | - { | ||
6567 | - LLFriendObserver* observer = *it; | ||
6568 | - it++; | ||
6569 | - // The only friend-related thing we notify on is online/offline transitions. | ||
6570 | - observer->changed(LLFriendObserver::ONLINE); | ||
6571 | - } | ||
6572 | -} | ||
6573 | - | ||
6574 | -void LLVoiceClient::lookupName(const LLUUID &id) | ||
6575 | -{ | ||
6576 | - gCacheName->getName(id, onAvatarNameLookup); | ||
6577 | -} | ||
6578 | - | ||
6579 | //static | ||
6580 | -void LLVoiceClient::onAvatarNameLookup(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group, void* user_data) | ||
6581 | -{ | ||
6582 | - if(gVoiceClient) | ||
6583 | - { | ||
6584 | - std::string name = llformat("%s %s", first.c_str(), last.c_str()); | ||
6585 | - gVoiceClient->avatarNameResolved(id, name); | ||
6586 | - } | ||
6587 | -} | ||
6588 | +// void LLVoiceClient::onAvatarNameLookup(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group, void* user_data) | ||
6589 | +// { | ||
6590 | +// participantState* statep = gVoiceClient->findParticipantByID(id); | ||
6591 | |||
6592 | -void LLVoiceClient::avatarNameResolved(const LLUUID &id, const std::string &name) | ||
6593 | -{ | ||
6594 | - // If the avatar whose name just resolved is on our friends list, resync the friends list. | ||
6595 | - if(LLAvatarTracker::instance().getBuddyInfo(id) != NULL) | ||
6596 | - { | ||
6597 | - mFriendsListDirty = true; | ||
6598 | - } | ||
6599 | +// if (statep) | ||
6600 | +// { | ||
6601 | +// statep->mDisplayName = first + " " + last; | ||
6602 | +// } | ||
6603 | |||
6604 | - // Iterate over all sessions. | ||
6605 | - for(sessionIterator iter = sessionsBegin(); iter != sessionsEnd(); iter++) | ||
6606 | - { | ||
6607 | - sessionState *session = *iter; | ||
6608 | - | ||
6609 | - // Check for this user as a participant in this session | ||
6610 | - participantState *participant = session->findParticipantByID(id); | ||
6611 | - if(participant) | ||
6612 | - { | ||
6613 | - // Found -- fill in the name | ||
6614 | - participant->mAccountName = name; | ||
6615 | - // and post a "participants updated" message to listeners later. | ||
6616 | - session->mParticipantsChanged = true; | ||
6617 | - } | ||
6618 | - | ||
6619 | - // Check whether this is a p2p session whose caller name just resolved | ||
6620 | - if(session->mCallerID == id) | ||
6621 | - { | ||
6622 | - // this session's "caller ID" just resolved. Fill in the name. | ||
6623 | - session->mName = name; | ||
6624 | - if(session->mTextInvitePending) | ||
6625 | - { | ||
6626 | - session->mTextInvitePending = false; | ||
6627 | - | ||
6628 | - // We don't need to call gIMMgr->addP2PSession() here. The first incoming message will create the panel. | ||
6629 | - } | ||
6630 | - if(session->mVoiceInvitePending) | ||
6631 | - { | ||
6632 | - session->mVoiceInvitePending = false; | ||
6633 | - | ||
6634 | - gIMMgr->inviteToSession( | ||
6635 | - session->mIMSessionID, | ||
6636 | - session->mName, | ||
6637 | - session->mCallerID, | ||
6638 | - session->mName, | ||
6639 | - IM_SESSION_P2P_INVITE, | ||
6640 | - LLIMMgr::INVITATION_TYPE_VOICE, | ||
6641 | - session->mHandle, | ||
6642 | - session->mSIPURI); | ||
6643 | - } | ||
6644 | - | ||
6645 | - } | ||
6646 | - } | ||
6647 | -} | ||
6648 | +// gVoiceClient->notifyObservers(); | ||
6649 | +// } | ||
6650 | |||
6651 | class LLViewerParcelVoiceInfo : public LLHTTPNode | ||
6652 | { | ||
6653 | diff --git a/linden/indra/newview/llvoiceclient.h b/linden/indra/newview/llvoiceclient.h | ||
6654 | index 13dd974..d0b7839 100644 | ||
6655 | --- a/linden/indra/newview/llvoiceclient.h | ||
6656 | +++ b/linden/indra/newview/llvoiceclient.h | ||
6657 | @@ -41,7 +41,6 @@ class LLVivoxProtocolParser; | ||
6658 | #include "v3math.h" | ||
6659 | #include "llframetimer.h" | ||
6660 | #include "llviewerregion.h" | ||
6661 | -#include "llcallingcard.h" // for LLFriendObserver | ||
6662 | |||
6663 | class LLVoiceClientParticipantObserver | ||
6664 | { | ||
6665 | @@ -92,10 +91,41 @@ class LLVoiceClient: public LLSingleton<LLVoiceClient> | ||
6666 | |||
6667 | public: | ||
6668 | |||
6669 | + enum serviceType | ||
6670 | + { | ||
6671 | + serviceTypeUnknown, // Unknown, returned if no data on the avatar is available | ||
6672 | + serviceTypeA, // spatialized local chat | ||
6673 | + serviceTypeB, // remote multi-party chat | ||
6674 | + serviceTypeC // one-to-one and small group chat | ||
6675 | + }; | ||
6676 | static F32 OVERDRIVEN_POWER_LEVEL; | ||
6677 | |||
6678 | void updateSettings(); // call after loading settings and whenever they change | ||
6679 | |||
6680 | + ///////////////////////////// | ||
6681 | + // session control messages | ||
6682 | + void connect(); | ||
6683 | + | ||
6684 | + void connectorCreate(); | ||
6685 | + void connectorShutdown(); | ||
6686 | + | ||
6687 | + void requestVoiceAccountProvision(S32 retries = 3); | ||
6688 | + void userAuthorized( | ||
6689 | + const std::string& firstName, | ||
6690 | + const std::string& lastName, | ||
6691 | + const LLUUID &agentID); | ||
6692 | + void login(const std::string& accountName, const std::string &password); | ||
6693 | + void loginSendMessage(); | ||
6694 | + void logout(); | ||
6695 | + void logoutSendMessage(); | ||
6696 | + | ||
6697 | + void channelGetListSendMessage(); | ||
6698 | + void sessionCreateSendMessage(); | ||
6699 | + void sessionConnectSendMessage(); | ||
6700 | + void sessionTerminate(); | ||
6701 | + void sessionTerminateSendMessage(); | ||
6702 | + void sessionTerminateByHandle(std::string &sessionHandle); | ||
6703 | + | ||
6704 | void getCaptureDevicesSendMessage(); | ||
6705 | void getRenderDevicesSendMessage(); | ||
6706 | |||
6707 | @@ -140,32 +170,23 @@ class LLVoiceClient: public LLSingleton<LLVoiceClient> | ||
6708 | |||
6709 | ///////////////////////////// | ||
6710 | // Response/Event handlers | ||
6711 | - void connectorCreateResponse(int statusCode, std::string &statusString, std::string &connectorHandle, std::string &versionID); | ||
6712 | - void loginResponse(int statusCode, std::string &statusString, std::string &accountHandle, int numberOfAliases); | ||
6713 | - void sessionCreateResponse(std::string &requestId, int statusCode, std::string &statusString, std::string &sessionHandle); | ||
6714 | - void sessionGroupAddSessionResponse(std::string &requestId, int statusCode, std::string &statusString, std::string &sessionHandle); | ||
6715 | - void sessionConnectResponse(std::string &requestId, int statusCode, std::string &statusString); | ||
6716 | + void connectorCreateResponse(int statusCode, std::string &statusString, std::string &connectorHandle); | ||
6717 | + void loginResponse(int statusCode, std::string &statusString, std::string &accountHandle); | ||
6718 | + void channelGetListResponse(int statusCode, std::string &statusString); | ||
6719 | + void sessionCreateResponse(int statusCode, std::string &statusString, std::string &sessionHandle); | ||
6720 | + void sessionConnectResponse(int statusCode, std::string &statusString); | ||
6721 | + void sessionTerminateResponse(int statusCode, std::string &statusString); | ||
6722 | void logoutResponse(int statusCode, std::string &statusString); | ||
6723 | void connectorShutdownResponse(int statusCode, std::string &statusString); | ||
6724 | |||
6725 | - void accountLoginStateChangeEvent(std::string &accountHandle, int statusCode, std::string &statusString, int state); | ||
6726 | - void mediaStreamUpdatedEvent(std::string &sessionHandle, std::string &sessionGroupHandle, int statusCode, std::string &statusString, int state, bool incoming); | ||
6727 | - void textStreamUpdatedEvent(std::string &sessionHandle, std::string &sessionGroupHandle, bool enabled, int state, bool incoming); | ||
6728 | - void sessionAddedEvent(std::string &uriString, std::string &alias, std::string &sessionHandle, std::string &sessionGroupHandle, bool isChannel, bool incoming, std::string &nameString, std::string &applicationString); | ||
6729 | - void sessionGroupAddedEvent(std::string &sessionGroupHandle); | ||
6730 | - void sessionRemovedEvent(std::string &sessionHandle, std::string &sessionGroupHandle); | ||
6731 | - void participantAddedEvent(std::string &sessionHandle, std::string &sessionGroupHandle, std::string &uriString, std::string &alias, std::string &nameString, std::string &displayNameString, int participantType); | ||
6732 | - void participantRemovedEvent(std::string &sessionHandle, std::string &sessionGroupHandle, std::string &uriString, std::string &alias, std::string &nameString); | ||
6733 | - void participantUpdatedEvent(std::string &sessionHandle, std::string &sessionGroupHandle, std::string &uriString, std::string &alias, bool isModeratorMuted, bool isSpeaking, int volume, F32 energy); | ||
6734 | + void loginStateChangeEvent(std::string &accountHandle, int statusCode, std::string &statusString, int state); | ||
6735 | + void sessionNewEvent(std::string &accountHandle, std::string &eventSessionHandle, int state, std::string &nameString, std::string &uriString); | ||
6736 | + void sessionStateChangeEvent(std::string &uriString, int statusCode, std::string &statusString, std::string &sessionHandle, int state, bool isChannel, std::string &nameString); | ||
6737 | + void participantStateChangeEvent(std::string &uriString, int statusCode, std::string &statusString, int state, std::string &nameString, std::string &displayNameString, int participantType); | ||
6738 | + void participantPropertiesEvent(std::string &uriString, int statusCode, std::string &statusString, bool isLocallyMuted, bool isModeratorMuted, bool isSpeaking, int volume, F32 energy); | ||
6739 | void auxAudioPropertiesEvent(F32 energy); | ||
6740 | - void buddyPresenceEvent(std::string &uriString, std::string &alias, std::string &statusString, std::string &applicationString); | ||
6741 | - void messageEvent(std::string &sessionHandle, std::string &uriString, std::string &alias, std::string &messageHeader, std::string &messageBody, std::string &applicationString); | ||
6742 | - void sessionNotificationEvent(std::string &sessionHandle, std::string &uriString, std::string ¬ificationType); | ||
6743 | - void subscriptionEvent(std::string &buddyURI, std::string &subscriptionHandle, std::string &alias, std::string &displayName, std::string &applicationString, std::string &subscriptionType); | ||
6744 | - | ||
6745 | - void buddyListChanged(); | ||
6746 | + | ||
6747 | void muteListChanged(); | ||
6748 | - void updateFriends(U32 mask); | ||
6749 | |||
6750 | ///////////////////////////// | ||
6751 | // Sending updates of current state | ||
6752 | @@ -189,6 +210,7 @@ static void updatePosition(void); | ||
6753 | void setVoiceVolume(F32 volume); | ||
6754 | void setMicGain(F32 volume); | ||
6755 | void setUserVolume(const LLUUID& id, F32 volume); // set's volume for specified agent, from 0-1 (where .5 is nominal) | ||
6756 | + void setVivoxDebugServerName(std::string &serverName); | ||
6757 | void setLipSyncEnabled(BOOL enabled); | ||
6758 | BOOL lipSyncEnabled(); | ||
6759 | |||
6760 | @@ -203,261 +225,57 @@ static void updatePosition(void); | ||
6761 | BOOL getIsSpeaking(const LLUUID& id); | ||
6762 | BOOL getIsModeratorMuted(const LLUUID& id); | ||
6763 | F32 getCurrentPower(const LLUUID& id); // "power" is related to "amplitude" in a defined way. I'm just not sure what the formula is... | ||
6764 | + BOOL getPTTPressed(const LLUUID& id); // This is the inverse of the "locally muted" property. | ||
6765 | BOOL getOnMuteList(const LLUUID& id); | ||
6766 | F32 getUserVolume(const LLUUID& id); | ||
6767 | std::string getDisplayName(const LLUUID& id); | ||
6768 | |||
6769 | // MBW -- XXX -- Not sure how to get this data out of the TVC | ||
6770 | BOOL getUsingPTT(const LLUUID& id); | ||
6771 | + serviceType getServiceType(const LLUUID& id); // type of chat the user is involved in (see bHear scope doc for definitions of A/B/C) | ||
6772 | std::string getGroupID(const LLUUID& id); // group ID if the user is in group chat (empty string if not applicable) | ||
6773 | |||
6774 | ///////////////////////////// | ||
6775 | BOOL getAreaVoiceDisabled(); // returns true if the area the avatar is in is speech-disabled. | ||
6776 | // Use this to determine whether to show a "no speech" icon in the menu bar. | ||
6777 | - | ||
6778 | - ///////////////////////////// | ||
6779 | - // Recording controls | ||
6780 | - void recordingLoopStart(int seconds = 3600, int deltaFramesPerControlFrame = 200); | ||
6781 | - void recordingLoopSave(const std::string& filename); | ||
6782 | - void recordingStop(); | ||
6783 | - | ||
6784 | - // Playback controls | ||
6785 | - void filePlaybackStart(const std::string& filename); | ||
6786 | - void filePlaybackStop(); | ||
6787 | - void filePlaybackSetPaused(bool paused); | ||
6788 | - void filePlaybackSetMode(bool vox = false, float speed = 1.0f); | ||
6789 | - | ||
6790 | - | ||
6791 | - // This is used by the string-keyed maps below, to avoid storing the string twice. | ||
6792 | - // The 'const std::string *' in the key points to a string actually stored in the object referenced by the map. | ||
6793 | - // The add and delete operations for each map allocate and delete in the right order to avoid dangling references. | ||
6794 | - // The default compare operation would just compare pointers, which is incorrect, so they must use this comparitor instead. | ||
6795 | - struct stringMapComparitor | ||
6796 | - { | ||
6797 | - bool operator()(const std::string* a, const std::string * b) const | ||
6798 | - { | ||
6799 | - return a->compare(*b) < 0; | ||
6800 | - } | ||
6801 | - }; | ||
6802 | |||
6803 | - struct uuidMapComparitor | ||
6804 | - { | ||
6805 | - bool operator()(const LLUUID* a, const LLUUID * b) const | ||
6806 | - { | ||
6807 | - return *a < *b; | ||
6808 | - } | ||
6809 | - }; | ||
6810 | - | ||
6811 | struct participantState | ||
6812 | { | ||
6813 | public: | ||
6814 | participantState(const std::string &uri); | ||
6815 | - | ||
6816 | - bool updateMuteState(); | ||
6817 | - | ||
6818 | std::string mURI; | ||
6819 | - LLUUID mAvatarID; | ||
6820 | - std::string mAccountName; | ||
6821 | + std::string mName; | ||
6822 | std::string mDisplayName; | ||
6823 | + bool mPTT; | ||
6824 | + bool mIsSpeaking; | ||
6825 | + bool mIsModeratorMuted; | ||
6826 | LLFrameTimer mSpeakingTimeout; | ||
6827 | F32 mLastSpokeTimestamp; | ||
6828 | F32 mPower; | ||
6829 | int mVolume; | ||
6830 | + serviceType mServiceType; | ||
6831 | std::string mGroupID; | ||
6832 | - int mUserVolume; | ||
6833 | - bool mPTT; | ||
6834 | - bool mIsSpeaking; | ||
6835 | - bool mIsModeratorMuted; | ||
6836 | bool mOnMuteList; // true if this avatar is on the user's mute list (and should be muted) | ||
6837 | + int mUserVolume; | ||
6838 | bool mVolumeDirty; // true if this participant needs a volume command sent (either mOnMuteList or mUserVolume has changed) | ||
6839 | bool mAvatarIDValid; | ||
6840 | - bool mIsSelf; | ||
6841 | - }; | ||
6842 | - typedef std::map<const std::string *, participantState*, stringMapComparitor> participantMap; | ||
6843 | - | ||
6844 | - typedef std::map<const LLUUID *, participantState*, uuidMapComparitor> participantUUIDMap; | ||
6845 | - | ||
6846 | - enum streamState | ||
6847 | - { | ||
6848 | - streamStateUnknown = 0, | ||
6849 | - streamStateIdle = 1, | ||
6850 | - streamStateConnected = 2, | ||
6851 | - streamStateRinging = 3, | ||
6852 | + LLUUID mAvatarID; | ||
6853 | }; | ||
6854 | + typedef std::map<std::string, participantState*> participantMap; | ||
6855 | |||
6856 | - struct sessionState | ||
6857 | - { | ||
6858 | - public: | ||
6859 | - sessionState(); | ||
6860 | - ~sessionState(); | ||
6861 | - | ||
6862 | - participantState *addParticipant(const std::string &uri); | ||
6863 | - // Note: after removeParticipant returns, the participant* that was passed to it will have been deleted. | ||
6864 | - // Take care not to use the pointer again after that. | ||
6865 | - void removeParticipant(participantState *participant); | ||
6866 | - void removeAllParticipants(); | ||
6867 | - | ||
6868 | - participantState *findParticipant(const std::string &uri); | ||
6869 | - participantState *findParticipantByID(const LLUUID& id); | ||
6870 | - | ||
6871 | - std::string mHandle; | ||
6872 | - std::string mGroupHandle; | ||
6873 | - std::string mSIPURI; | ||
6874 | - std::string mAlias; | ||
6875 | - std::string mName; | ||
6876 | - std::string mAlternateSIPURI; | ||
6877 | - std::string mHash; // Channel password | ||
6878 | - std::string mErrorStatusString; | ||
6879 | - std::queue<std::string> mTextMsgQueue; | ||
6880 | - | ||
6881 | - LLUUID mIMSessionID; | ||
6882 | - LLUUID mCallerID; | ||
6883 | - int mErrorStatusCode; | ||
6884 | - int mMediaStreamState; | ||
6885 | - int mTextStreamState; | ||
6886 | - bool mCreateInProgress; // True if a Session.Create has been sent for this session and no response has been received yet. | ||
6887 | - bool mMediaConnectInProgress; // True if a Session.MediaConnect has been sent for this session and no response has been received yet. | ||
6888 | - bool mVoiceInvitePending; // True if a voice invite is pending for this session (usually waiting on a name lookup) | ||
6889 | - bool mTextInvitePending; // True if a text invite is pending for this session (usually waiting on a name lookup) | ||
6890 | - bool mSynthesizedCallerID; // True if the caller ID is a hash of the SIP URI -- this means we shouldn't do a name lookup. | ||
6891 | - bool mIsChannel; // True for both group and spatial channels (false for p2p, PSTN) | ||
6892 | - bool mIsSpatial; // True for spatial channels | ||
6893 | - bool mIsP2P; | ||
6894 | - bool mIncoming; | ||
6895 | - bool mVoiceEnabled; | ||
6896 | - bool mReconnect; // Whether we should try to reconnect to this session if it's dropped | ||
6897 | - // Set to true when the mute state of someone in the participant list changes. | ||
6898 | - // The code will have to walk the list to find the changed participant(s). | ||
6899 | - bool mVolumeDirty; | ||
6900 | - | ||
6901 | - bool mParticipantsChanged; | ||
6902 | - participantMap mParticipantsByURI; | ||
6903 | - participantUUIDMap mParticipantsByUUID; | ||
6904 | - }; | ||
6905 | - | ||
6906 | + participantState *findParticipant(const std::string &uri); | ||
6907 | + participantState *findParticipantByAvatar(LLVOAvatar *avatar); | ||
6908 | participantState *findParticipantByID(const LLUUID& id); | ||
6909 | - participantMap *getParticipantList(void); | ||
6910 | - | ||
6911 | - typedef std::map<const std::string*, sessionState*, stringMapComparitor> sessionMap; | ||
6912 | - typedef std::set<sessionState*> sessionSet; | ||
6913 | - | ||
6914 | - typedef sessionSet::iterator sessionIterator; | ||
6915 | - sessionIterator sessionsBegin(void); | ||
6916 | - sessionIterator sessionsEnd(void); | ||
6917 | - | ||
6918 | - sessionState *findSession(const std::string &handle); | ||
6919 | - sessionState *findSessionBeingCreatedByURI(const std::string &uri); | ||
6920 | - sessionState *findSession(const LLUUID &participant_id); | ||
6921 | - sessionState *findSessionByCreateID(const std::string &create_id); | ||
6922 | - | ||
6923 | - sessionState *addSession(const std::string &uri, const std::string &handle = LLStringUtil::null); | ||
6924 | - void setSessionHandle(sessionState *session, const std::string &handle = LLStringUtil::null); | ||
6925 | - void setSessionURI(sessionState *session, const std::string &uri); | ||
6926 | - void deleteSession(sessionState *session); | ||
6927 | - void deleteAllSessions(void); | ||
6928 | - | ||
6929 | - void verifySessionState(void); | ||
6930 | - | ||
6931 | - void joinedAudioSession(sessionState *session); | ||
6932 | - void leftAudioSession(sessionState *session); | ||
6933 | - | ||
6934 | - // This is called in several places where the session _may_ need to be deleted. | ||
6935 | - // It contains logic for whether to delete the session or keep it around. | ||
6936 | - void reapSession(sessionState *session); | ||
6937 | - | ||
6938 | - // Returns true if the session seems to indicate we've moved to a region on a different voice server | ||
6939 | - bool sessionNeedsRelog(sessionState *session); | ||
6940 | - | ||
6941 | - struct buddyListEntry | ||
6942 | - { | ||
6943 | - buddyListEntry(const std::string &uri); | ||
6944 | - std::string mURI; | ||
6945 | - std::string mDisplayName; | ||
6946 | - LLUUID mUUID; | ||
6947 | - bool mOnlineSL; | ||
6948 | - bool mOnlineSLim; | ||
6949 | - bool mCanSeeMeOnline; | ||
6950 | - bool mHasBlockListEntry; | ||
6951 | - bool mHasAutoAcceptListEntry; | ||
6952 | - bool mNameResolved; | ||
6953 | - bool mInSLFriends; | ||
6954 | - bool mInVivoxBuddies; | ||
6955 | - bool mNeedsNameUpdate; | ||
6956 | - }; | ||
6957 | - | ||
6958 | - typedef std::map<const std::string*, buddyListEntry*, stringMapComparitor> buddyListMap; | ||
6959 | |||
6960 | - // This should be called when parsing a buddy list entry sent by SLVoice. | ||
6961 | - void processBuddyListEntry(const std::string &uri, const std::string &displayName); | ||
6962 | - | ||
6963 | - buddyListEntry *addBuddy(const std::string &uri); | ||
6964 | - buddyListEntry *addBuddy(const std::string &uri, const std::string &displayName); | ||
6965 | - buddyListEntry *findBuddy(const std::string &uri); | ||
6966 | - buddyListEntry *findBuddy(const LLUUID &id); | ||
6967 | - buddyListEntry *findBuddyByDisplayName(const std::string &name); | ||
6968 | - void deleteBuddy(const std::string &uri); | ||
6969 | - void deleteAllBuddies(void); | ||
6970 | - | ||
6971 | - void deleteAllBlockRules(void); | ||
6972 | - void addBlockRule(const std::string &blockMask, const std::string &presenceOnly); | ||
6973 | - void deleteAllAutoAcceptRules(void); | ||
6974 | - void addAutoAcceptRule(const std::string &autoAcceptMask, const std::string &autoAddAsBuddy); | ||
6975 | - void accountListBlockRulesResponse(int statusCode, const std::string &statusString); | ||
6976 | - void accountListAutoAcceptRulesResponse(int statusCode, const std::string &statusString); | ||
6977 | - | ||
6978 | - ///////////////////////////// | ||
6979 | - // session control messages | ||
6980 | - void connectorCreate(); | ||
6981 | - void connectorShutdown(); | ||
6982 | - | ||
6983 | - void requestVoiceAccountProvision(S32 retries = 3); | ||
6984 | - void userAuthorized( | ||
6985 | - const std::string& firstName, | ||
6986 | - const std::string& lastName, | ||
6987 | - const LLUUID &agentID); | ||
6988 | - void login( | ||
6989 | - const std::string& account_name, | ||
6990 | - const std::string& password, | ||
6991 | - const std::string& voice_sip_uri_hostname, | ||
6992 | - const std::string& voice_account_server_uri); | ||
6993 | - void loginSendMessage(); | ||
6994 | - void logout(); | ||
6995 | - void logoutSendMessage(); | ||
6996 | - | ||
6997 | - void accountListBlockRulesSendMessage(); | ||
6998 | - void accountListAutoAcceptRulesSendMessage(); | ||
6999 | - | ||
7000 | - void sessionGroupCreateSendMessage(); | ||
7001 | - void sessionCreateSendMessage(sessionState *session, bool startAudio = true, bool startText = false); | ||
7002 | - void sessionGroupAddSessionSendMessage(sessionState *session, bool startAudio = true, bool startText = false); | ||
7003 | - void sessionMediaConnectSendMessage(sessionState *session); // just joins the audio session | ||
7004 | - void sessionTextConnectSendMessage(sessionState *session); // just joins the text session | ||
7005 | - void sessionTerminateSendMessage(sessionState *session); | ||
7006 | - void sessionMediaDisconnectSendMessage(sessionState *session); | ||
7007 | - void sessionTextDisconnectSendMessage(sessionState *session); | ||
7008 | + participantMap *getParticipantList(void); | ||
7009 | |||
7010 | - // Pokes the state machine to leave the audio session next time around. | ||
7011 | - void sessionTerminate(); | ||
7012 | - | ||
7013 | - // Pokes the state machine to shut down the connector and restart it. | ||
7014 | - void requestRelog(); | ||
7015 | - | ||
7016 | - // Does the actual work to get out of the audio session | ||
7017 | - void leaveAudioSession(); | ||
7018 | - | ||
7019 | void addObserver(LLVoiceClientParticipantObserver* observer); | ||
7020 | void removeObserver(LLVoiceClientParticipantObserver* observer); | ||
7021 | |||
7022 | - void addObserver(LLVoiceClientStatusObserver* observer); | ||
7023 | - void removeObserver(LLVoiceClientStatusObserver* observer); | ||
7024 | - | ||
7025 | - void addObserver(LLFriendObserver* observer); | ||
7026 | - void removeObserver(LLFriendObserver* observer); | ||
7027 | - | ||
7028 | - void lookupName(const LLUUID &id); | ||
7029 | - static void onAvatarNameLookup(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group, void* user_data); | ||
7030 | - void avatarNameResolved(const LLUUID &id, const std::string &name); | ||
7031 | + void addStatusObserver(LLVoiceClientStatusObserver* observer); | ||
7032 | + void removeStatusObserver(LLVoiceClientStatusObserver* observer); | ||
7033 | |||
7034 | +// static void onAvatarNameLookup(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group, void* user_data); | ||
7035 | typedef std::vector<std::string> deviceList; | ||
7036 | |||
7037 | deviceList *getCaptureDevices(); | ||
7038 | @@ -469,16 +287,8 @@ static void updatePosition(void); | ||
7039 | void setSpatialChannel( | ||
7040 | const std::string &uri, | ||
7041 | const std::string &credentials); | ||
7042 | - // start a voice session with the specified user | ||
7043 | - void callUser(const LLUUID &uuid); | ||
7044 | - | ||
7045 | - // Send a text message to the specified user, initiating the session if necessary. | ||
7046 | - bool sendTextMessage(const LLUUID& participant_id, const std::string& message); | ||
7047 | - | ||
7048 | - // close any existing text IM session with the specified user | ||
7049 | - void endUserIMSession(const LLUUID &uuid); | ||
7050 | - | ||
7051 | - bool answerInvite(std::string &sessionHandle); | ||
7052 | + void callUser(LLUUID &uuid); | ||
7053 | + void answerInvite(std::string &sessionHandle, LLUUID& other_user_id); | ||
7054 | void declineInvite(std::string &sessionHandle); | ||
7055 | void leaveNonSpatialChannel(); | ||
7056 | |||
7057 | @@ -491,37 +301,33 @@ static void updatePosition(void); | ||
7058 | bool inProximalChannel(); | ||
7059 | |||
7060 | std::string sipURIFromID(const LLUUID &id); | ||
7061 | - | ||
7062 | - // Returns true if the indicated user is online via SIP presence according to SLVoice. | ||
7063 | - // Note that we only get SIP presence data for other users that are in our vivox buddy list. | ||
7064 | - bool isOnlineSIP(const LLUUID &id); | ||
7065 | - | ||
7066 | + | ||
7067 | private: | ||
7068 | |||
7069 | // internal state for a simple state machine. This is used to deal with the asynchronous nature of some of the messages. | ||
7070 | // Note: if you change this list, please make corresponding changes to LLVoiceClient::state2string(). | ||
7071 | enum state | ||
7072 | { | ||
7073 | - stateDisableCleanup, | ||
7074 | stateDisabled, // Voice is turned off. | ||
7075 | stateStart, // Class is initialized, socket is created | ||
7076 | stateDaemonLaunched, // Daemon has been launched | ||
7077 | stateConnecting, // connect() call has been issued | ||
7078 | - stateConnected, // connection to the daemon has been made, send some initial setup commands. | ||
7079 | stateIdle, // socket is connected, ready for messaging | ||
7080 | - stateMicTuningStart, | ||
7081 | - stateMicTuningRunning, | ||
7082 | - stateMicTuningStop, | ||
7083 | stateConnectorStart, // connector needs to be started | ||
7084 | stateConnectorStarting, // waiting for connector handle | ||
7085 | stateConnectorStarted, // connector handle received | ||
7086 | + stateMicTuningNoLogin, // mic tuning before login | ||
7087 | stateLoginRetry, // need to retry login (failed due to changing password) | ||
7088 | stateLoginRetryWait, // waiting for retry timer | ||
7089 | stateNeedsLogin, // send login request | ||
7090 | stateLoggingIn, // waiting for account handle | ||
7091 | stateLoggedIn, // account handle received | ||
7092 | - stateCreatingSessionGroup, // Creating the main session group | ||
7093 | stateNoChannel, // | ||
7094 | + stateMicTuningStart, | ||
7095 | + stateMicTuningRunning, | ||
7096 | + stateMicTuningStop, | ||
7097 | + stateSessionCreate, // need to send Session.Create command | ||
7098 | + stateSessionConnect, // need to send Session.Connect command | ||
7099 | stateJoiningSession, // waiting for session handle | ||
7100 | stateSessionJoined, // session handle received | ||
7101 | stateRunning, // in session, steady state | ||
7102 | @@ -548,7 +354,7 @@ static void updatePosition(void); | ||
7103 | |||
7104 | state mState; | ||
7105 | bool mSessionTerminateRequested; | ||
7106 | - bool mRelogRequested; | ||
7107 | + bool mNonSpatialChannel; | ||
7108 | |||
7109 | void setState(state inState); | ||
7110 | state getState(void) { return mState; }; | ||
7111 | @@ -571,7 +377,18 @@ static void updatePosition(void); | ||
7112 | std::string mAccountDisplayName; | ||
7113 | std::string mAccountFirstName; | ||
7114 | std::string mAccountLastName; | ||
7115 | - | ||
7116 | + | ||
7117 | + std::string mNextP2PSessionURI; // URI of the P2P session to join next | ||
7118 | + std::string mNextSessionURI; // URI of the session to join next | ||
7119 | + std::string mNextSessionHandle; // Session handle of the session to join next | ||
7120 | + std::string mNextSessionHash; // Password hash for the session to join next | ||
7121 | + bool mNextSessionSpatial; // Will next session be a spatial chat? | ||
7122 | + bool mNextSessionNoReconnect; // Next session should not auto-reconnect (i.e. user -> user chat) | ||
7123 | + bool mNextSessionResetOnClose; // If this is true, go back to spatial chat when the next session terminates. | ||
7124 | + | ||
7125 | + std::string mSessionStateEventHandle; // session handle received in SessionStateChangeEvents | ||
7126 | + std::string mSessionStateEventURI; // session URI received in SessionStateChangeEvents | ||
7127 | + | ||
7128 | bool mTuningMode; | ||
7129 | float mTuningEnergy; | ||
7130 | std::string mTuningAudioFile; | ||
7131 | @@ -582,40 +399,32 @@ static void updatePosition(void); | ||
7132 | state mTuningExitState; // state to return to when we leave tuning mode. | ||
7133 | |||
7134 | std::string mSpatialSessionURI; | ||
7135 | - std::string mSpatialSessionCredentials; | ||
7136 | - | ||
7137 | - std::string mMainSessionGroupHandle; // handle of the "main" session group. | ||
7138 | + | ||
7139 | + bool mSessionResetOnClose; | ||
7140 | + | ||
7141 | + int mVivoxErrorStatusCode; | ||
7142 | + std::string mVivoxErrorStatusString; | ||
7143 | |||
7144 | std::string mChannelName; // Name of the channel to be looked up | ||
7145 | bool mAreaVoiceDisabled; | ||
7146 | - sessionState *mAudioSession; // Session state for the current audio session | ||
7147 | - bool mAudioSessionChanged; // set to true when the above pointer gets changed, so observers can be notified. | ||
7148 | - | ||
7149 | - sessionState *mNextAudioSession; // Session state for the audio session we're trying to join | ||
7150 | - | ||
7151 | -// std::string mSessionURI; // URI of the session we're in. | ||
7152 | -// std::string mSessionHandle; // returned by ? | ||
7153 | + std::string mSessionURI; // URI of the session we're in. | ||
7154 | + bool mSessionP2P; // true if this session is a p2p call | ||
7155 | |||
7156 | S32 mCurrentParcelLocalID; // Used to detect parcel boundary crossings | ||
7157 | std::string mCurrentRegionName; // Used to detect parcel boundary crossings | ||
7158 | |||
7159 | std::string mConnectorHandle; // returned by "Create Connector" message | ||
7160 | std::string mAccountHandle; // returned by login message | ||
7161 | - int mNumberOfAliases; | ||
7162 | + std::string mSessionHandle; // returned by ? | ||
7163 | U32 mCommandCookie; | ||
7164 | |||
7165 | - std::string mVoiceAccountServerURI; | ||
7166 | - std::string mVoiceSIPURIHostName; | ||
7167 | + std::string mAccountServerName; | ||
7168 | + std::string mAccountServerURI; | ||
7169 | |||
7170 | int mLoginRetryCount; | ||
7171 | |||
7172 | - sessionMap mSessionsByHandle; // Active sessions, indexed by session handle. Sessions which are being initiated may not be in this map. | ||
7173 | - sessionSet mSessions; // All sessions, not indexed. This is the canonical session list. | ||
7174 | - | ||
7175 | - bool mBuddyListMapPopulated; | ||
7176 | - bool mBlockRulesListReceived; | ||
7177 | - bool mAutoAcceptRulesListReceived; | ||
7178 | - buddyListMap mBuddyListMap; | ||
7179 | + participantMap mParticipantMap; | ||
7180 | + bool mParticipantMapChanged; | ||
7181 | |||
7182 | deviceList mCaptureDevices; | ||
7183 | deviceList mRenderDevices; | ||
7184 | @@ -625,41 +434,40 @@ static void updatePosition(void); | ||
7185 | bool mCaptureDeviceDirty; | ||
7186 | bool mRenderDeviceDirty; | ||
7187 | |||
7188 | + participantState *addParticipant(const std::string &uri); | ||
7189 | + // Note: after removeParticipant returns, the participant* that was passed to it will have been deleted. | ||
7190 | + // Take care not to use the pointer again after that. | ||
7191 | + void removeParticipant(participantState *participant); | ||
7192 | + void removeAllParticipants(); | ||
7193 | + | ||
7194 | + void updateMuteState(participantState *participant); | ||
7195 | + | ||
7196 | + typedef std::map<std::string, std::string> channelMap; | ||
7197 | + channelMap mChannelMap; | ||
7198 | + | ||
7199 | + // These are used by the parser when processing a channel list response. | ||
7200 | + void clearChannelMap(void); | ||
7201 | + void addChannelMapEntry(std::string &name, std::string &uri); | ||
7202 | + std::string findChannelURI(std::string &name); | ||
7203 | + | ||
7204 | // This should be called when the code detects we have changed parcels. | ||
7205 | // It initiates the call to the server that gets the parcel channel. | ||
7206 | void parcelChanged(); | ||
7207 | |||
7208 | - void switchChannel(std::string uri = std::string(), bool spatial = true, bool no_reconnect = false, bool is_p2p = false, std::string hash = ""); | ||
7209 | - void joinSession(sessionState *session); | ||
7210 | + void switchChannel(std::string uri = std::string(), bool spatial = true, bool noReconnect = false, std::string hash = ""); | ||
7211 | + void joinSession(std::string handle, std::string uri); | ||
7212 | |||
7213 | -static std::string nameFromAvatar(LLVOAvatar *avatar); | ||
7214 | -static std::string nameFromID(const LLUUID &id); | ||
7215 | -static bool IDFromName(const std::string name, LLUUID &uuid); | ||
7216 | -static std::string displayNameFromAvatar(LLVOAvatar *avatar); | ||
7217 | + std::string nameFromAvatar(LLVOAvatar *avatar); | ||
7218 | + std::string nameFromID(const LLUUID &id); | ||
7219 | + bool IDFromName(const std::string name, LLUUID &uuid); | ||
7220 | + std::string displayNameFromAvatar(LLVOAvatar *avatar); | ||
7221 | std::string sipURIFromAvatar(LLVOAvatar *avatar); | ||
7222 | std::string sipURIFromName(std::string &name); | ||
7223 | - | ||
7224 | - // Returns the name portion of the SIP URI if the string looks vaguely like a SIP URI, or an empty string if not. | ||
7225 | -static std::string nameFromsipURI(const std::string &uri); | ||
7226 | - | ||
7227 | - bool inSpatialChannel(void); | ||
7228 | - std::string getAudioSessionURI(); | ||
7229 | - std::string getAudioSessionHandle(); | ||
7230 | |||
7231 | void sendPositionalUpdate(void); | ||
7232 | |||
7233 | void buildSetCaptureDevice(std::ostringstream &stream); | ||
7234 | void buildSetRenderDevice(std::ostringstream &stream); | ||
7235 | - void buildLocalAudioUpdates(std::ostringstream &stream); | ||
7236 | - | ||
7237 | - void clearAllLists(); | ||
7238 | - void checkFriend(const LLUUID& id); | ||
7239 | - void sendFriendsListUpdates(); | ||
7240 | - | ||
7241 | - // start a text IM session with the specified user | ||
7242 | - // This will be asynchronous, the session may be established at a future time. | ||
7243 | - sessionState* startUserIMSession(const LLUUID& uuid); | ||
7244 | - void sendQueuedTextMessages(sessionState *session); | ||
7245 | |||
7246 | void enforceTether(void); | ||
7247 | |||
7248 | @@ -683,9 +491,10 @@ static std::string nameFromsipURI(const std::string &uri); | ||
7249 | bool mPTTIsToggle; | ||
7250 | bool mUserPTTState; | ||
7251 | bool mMuteMic; | ||
7252 | - | ||
7253 | - // Set to true when the friends list is known to have changed. | ||
7254 | - bool mFriendsListDirty; | ||
7255 | + | ||
7256 | + // Set to true when the mute state of someone in the participant list changes. | ||
7257 | + // The code will have to walk the list to find the changed participant(s). | ||
7258 | + bool mVolumeDirty; | ||
7259 | |||
7260 | enum | ||
7261 | { | ||
7262 | @@ -713,18 +522,14 @@ static std::string nameFromsipURI(const std::string &uri); | ||
7263 | BOOL mLipSyncEnabled; | ||
7264 | |||
7265 | typedef std::set<LLVoiceClientParticipantObserver*> observer_set_t; | ||
7266 | - observer_set_t mParticipantObservers; | ||
7267 | + observer_set_t mObservers; | ||
7268 | |||
7269 | - void notifyParticipantObservers(); | ||
7270 | + void notifyObservers(); | ||
7271 | |||
7272 | typedef std::set<LLVoiceClientStatusObserver*> status_observer_set_t; | ||
7273 | status_observer_set_t mStatusObservers; | ||
7274 | |||
7275 | void notifyStatusObservers(LLVoiceClientStatusObserver::EStatusType status); | ||
7276 | - | ||
7277 | - typedef std::set<LLFriendObserver*> friend_observer_set_t; | ||
7278 | - friend_observer_set_t mFriendObservers; | ||
7279 | - void notifyFriendObservers(); | ||
7280 | }; | ||
7281 | |||
7282 | extern LLVoiceClient *gVoiceClient; | ||
diff --git a/stack_trace.log b/stack_trace.log new file mode 100644 index 0000000..b04e344 --- /dev/null +++ b/stack_trace.log | |||
@@ -0,0 +1,32 @@ | |||
1 | 0: ELF(do_elfio_glibc_backtrace()+0x424) [0x9962c13] | ||
2 | 1: ELF(LLAppViewerLinux::handleSyncCrashTrace()+0xb) [0x9963533] | ||
3 | 2: ELF(LLAppViewer::handleSyncViewerCrash()+0x20) [0x85181a2] | ||
4 | 3: ELF(LLApp::runSyncErrorHandler()+0x16) [0x9e7d384] | ||
5 | 4: ELF(LLApp::setError()+0x17) [0x9e7d40d] | ||
6 | 5: ELF(default_unix_signal_handler(int, siginfo*, void*)+0xd22) [0x9e7f08e] | ||
7 | 6: [0xb807640c] | ||
8 | 7: /usr/lib/libstdc++.so.6(_ZNSs6assignERKSs+0x2b) [0xb617825b] | ||
9 | 8: /usr/lib/libstdc++.so.6(_ZNSsaSERKSs+0x24) [0xb6178334] | ||
10 | 9: ELF(attach_label(std::string&, void*)+0x32) [0x9563d7b] | ||
11 | 10: ELF(LLMenuItemCallGL::buildDrawLabel()+0x232) [0x9c2d012] | ||
12 | 11: ELF(LLMenuGL::arrange()+0xb07) [0x9c31719] | ||
13 | 12: ELF(LLMenuGL::append(LLMenuItemGL*)+0x4c) [0x9c280ca] | ||
14 | 13: ELF(LLMenuGL::arrange()+0x6b3) [0x9c312c5] | ||
15 | 14: ELF(LLMenuGL::append(LLMenuItemGL*)+0x4c) [0x9c280ca] | ||
16 | 15: ELF(LLVOAvatar::buildCharacter()+0x3a8e) [0x974689c] | ||
17 | 16: ELF(LLVOAvatar::LLVOAvatar(LLUUID const&, unsigned char, LLViewerRegion*)+0x4140) [0x97566e4] | ||
18 | 17: ELF(LLViewerObject::createObject(LLUUID const&, unsigned char, LLViewerRegion*)+0x193) [0x960ab0d] | ||
19 | 18: ELF(LLViewerObjectList::createObject(unsigned char, LLViewerRegion*, LLUUID const&, unsigned int, LLHost const&)+0x8f) [0x961c9f3] | ||
20 | 19: ELF(LLViewerObjectList::processObjectUpdate(LLMessageSystem*, void**, e_object_update_type, bool, bool)+0x8d1) [0x961e83d] | ||
21 | 20: ELF(process_object_update(LLMessageSystem*, void**)+0x9d) [0x95ccc9e] | ||
22 | 21: ELF(LLMessageTemplate::callHandlerFunc(LLMessageSystem*) const+0x47) [0x9af995d] | ||
23 | 22: ELF(LLTemplateMessageReader::decodeData(unsigned char const*, LLHost const&)+0xcc8) [0x9b2d12c] | ||
24 | 23: ELF(LLTemplateMessageReader::readMessage(unsigned char const*, LLHost const&)+0x1f) [0x9b2d653] | ||
25 | 24: ELF(LLMessageSystem::checkMessages(long long)+0x1211) [0x9af0205] | ||
26 | 25: ELF(LLMessageSystem::checkAllMessages(long long, LLPumpIO*)+0x2b) [0x9af057d] | ||
27 | 26: ELF(LLAppViewer::idleNetwork()+0x2ab) [0x8519b85] | ||
28 | 27: ELF(LLAppViewer::idle()+0xd5c) [0x85355fe] | ||
29 | 28: ELF(LLAppViewer::mainLoop()+0x7fe) [0x8536cdc] | ||
30 | 29: ELF(main+0x213) [0x996433c] | ||
31 | 30: /lib/i686/cmov/libc.so.6(__libc_start_main+0xe5) [0xb5f45775] | ||
32 | 31: bin/do-not-directly-run-imprudence-bin [0x846f7e1] | ||