corrade-vassal – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | vero | 1 | /* |
2 | * Copyright (c) 2006-2014, openmetaverse.org |
||
3 | * All rights reserved. |
||
4 | * |
||
5 | * - Redistribution and use in source and binary forms, with or without |
||
6 | * modification, are permitted provided that the following conditions are met: |
||
7 | * |
||
8 | * - Redistributions of source code must retain the above copyright notice, this |
||
9 | * list of conditions and the following disclaimer. |
||
10 | * - Neither the name of the openmetaverse.org nor the names |
||
11 | * of its contributors may be used to endorse or promote products derived from |
||
12 | * this software without specific prior written permission. |
||
13 | * |
||
14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
||
15 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
||
16 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
||
17 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
||
18 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
||
19 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
||
20 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
||
21 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
||
22 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
||
23 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
||
24 | * POSSIBILITY OF SUCH DAMAGE. |
||
25 | */ |
||
26 | |||
27 | using System; |
||
28 | using System.Collections.Generic; |
||
29 | using System.Text; |
||
30 | using OpenMetaverse; |
||
31 | |||
32 | namespace OpenMetaverse.Voice |
||
33 | { |
||
34 | /// <summary> |
||
35 | /// Represents a single Voice Session to the Vivox service. |
||
36 | /// </summary> |
||
37 | public class VoiceSession |
||
38 | { |
||
39 | private string m_Handle; |
||
40 | private static Dictionary<string, VoiceParticipant> knownParticipants; |
||
41 | public string RegionName; |
||
42 | private bool m_spatial; |
||
43 | public bool IsSpatial { get { return m_spatial; } } |
||
44 | private VoiceGateway connector; |
||
45 | |||
46 | public VoiceGateway Connector { get { return connector; } } |
||
47 | public string Handle { get { return m_Handle; } } |
||
48 | |||
49 | public event System.EventHandler OnParticipantAdded; |
||
50 | public event System.EventHandler OnParticipantUpdate; |
||
51 | public event System.EventHandler OnParticipantRemoved; |
||
52 | |||
53 | public VoiceSession(VoiceGateway conn, string handle) |
||
54 | { |
||
55 | m_Handle = handle; |
||
56 | connector = conn; |
||
57 | |||
58 | m_spatial = true; |
||
59 | knownParticipants = new Dictionary<string, VoiceParticipant>(); |
||
60 | } |
||
61 | |||
62 | /// <summary> |
||
63 | /// Close this session. |
||
64 | /// </summary> |
||
65 | internal void Close() |
||
66 | { |
||
67 | |||
68 | knownParticipants.Clear(); |
||
69 | } |
||
70 | |||
71 | internal void ParticipantUpdate(string URI, |
||
72 | bool isMuted, |
||
73 | bool isSpeaking, |
||
74 | int volume, |
||
75 | float energy) |
||
76 | { |
||
77 | lock (knownParticipants) |
||
78 | { |
||
79 | // Locate in this session |
||
80 | VoiceParticipant p = FindParticipant(URI); |
||
81 | if (p == null) return; |
||
82 | |||
83 | // Set properties |
||
84 | p.SetProperties(isSpeaking, isMuted, energy); |
||
85 | |||
86 | // Inform interested parties. |
||
87 | if (OnParticipantUpdate != null) |
||
88 | OnParticipantUpdate(p, null); |
||
89 | } |
||
90 | } |
||
91 | |||
92 | internal void AddParticipant(string URI) |
||
93 | { |
||
94 | lock (knownParticipants) |
||
95 | { |
||
96 | VoiceParticipant p = FindParticipant(URI); |
||
97 | |||
98 | // We expect that to come back null. If it is not |
||
99 | // null, this is a duplicate |
||
100 | if (p != null) |
||
101 | { |
||
102 | return; |
||
103 | } |
||
104 | |||
105 | // It was not found, so add it. |
||
106 | p = new VoiceParticipant(URI, this); |
||
107 | knownParticipants.Add(URI, p); |
||
108 | |||
109 | /* TODO |
||
110 | // Fill in the name. |
||
111 | if (p.Name == null || p.Name.StartsWith("Loading...")) |
||
112 | p.Name = control.instance.getAvatarName(p.ID); |
||
113 | return p; |
||
114 | */ |
||
115 | |||
116 | // Inform interested parties. |
||
117 | if (OnParticipantAdded != null) |
||
118 | OnParticipantAdded(p, null); |
||
119 | } |
||
120 | } |
||
121 | |||
122 | internal void RemoveParticipant(string URI) |
||
123 | { |
||
124 | lock (knownParticipants) |
||
125 | { |
||
126 | VoiceParticipant p = FindParticipant(URI); |
||
127 | if (p == null) return; |
||
128 | |||
129 | // Remove from list for this session. |
||
130 | knownParticipants.Remove(URI); |
||
131 | |||
132 | // Inform interested parties. |
||
133 | if (OnParticipantRemoved != null) |
||
134 | OnParticipantRemoved(p, null); |
||
135 | } |
||
136 | } |
||
137 | |||
138 | /// <summary> |
||
139 | /// Look up an existing Participants in this session |
||
140 | /// </summary> |
||
141 | /// <param name="puri"></param> |
||
142 | /// <returns></returns> |
||
143 | private VoiceParticipant FindParticipant(string puri) |
||
144 | { |
||
145 | if (knownParticipants.ContainsKey(puri)) |
||
146 | return knownParticipants[puri]; |
||
147 | |||
148 | return null; |
||
149 | } |
||
150 | |||
151 | public void Set3DPosition(VoicePosition SpeakerPosition, VoicePosition ListenerPosition) |
||
152 | { |
||
153 | connector.SessionSet3DPosition(m_Handle, SpeakerPosition, ListenerPosition); |
||
154 | } |
||
155 | } |
||
156 | |||
157 | public partial class VoiceGateway |
||
158 | { |
||
159 | /// <summary> |
||
160 | /// Create a Session |
||
161 | /// Sessions typically represent a connection to a media session with one or more |
||
162 | /// participants. This is used to generate an ‘outbound’ call to another user or |
||
163 | /// channel. The specifics depend on the media types involved. A session handle is |
||
164 | /// required to control the local user functions within the session (or remote |
||
165 | /// users if the current account has rights to do so). Currently creating a |
||
166 | /// session automatically connects to the audio media, there is no need to call |
||
167 | /// Session.Connect at this time, this is reserved for future use. |
||
168 | /// </summary> |
||
169 | /// <param name="AccountHandle">Handle returned from successful Connector ‘create’ request</param> |
||
170 | /// <param name="URI">This is the URI of the terminating point of the session (ie who/what is being called)</param> |
||
171 | /// <param name="Name">This is the display name of the entity being called (user or channel)</param> |
||
172 | /// <param name="Password">Only needs to be supplied when the target URI is password protected</param> |
||
173 | /// <param name="PasswordHashAlgorithm">This indicates the format of the password as passed in. This can either be |
||
174 | /// “ClearText” or “SHA1UserName”. If this element does not exist, it is assumed to be “ClearText”. If it is |
||
175 | /// “SHA1UserName”, the password as passed in is the SHA1 hash of the password and username concatenated together, |
||
176 | /// then base64 encoded, with the final “=” character stripped off.</param> |
||
177 | /// <param name="JoinAudio"></param> |
||
178 | /// <param name="JoinText"></param> |
||
179 | /// <returns></returns> |
||
180 | public int SessionCreate(string AccountHandle, string URI, string Name, string Password, |
||
181 | bool JoinAudio, bool JoinText, string PasswordHashAlgorithm) |
||
182 | { |
||
183 | StringBuilder sb = new StringBuilder(); |
||
184 | sb.Append(VoiceGateway.MakeXML("AccountHandle", AccountHandle)); |
||
185 | sb.Append(VoiceGateway.MakeXML("URI", URI)); |
||
186 | sb.Append(VoiceGateway.MakeXML("Name", Name)); |
||
187 | if (Password != null && Password != "") |
||
188 | { |
||
189 | sb.Append(VoiceGateway.MakeXML("Password", Password)); |
||
190 | sb.Append(VoiceGateway.MakeXML("PasswordHashAlgorithm", PasswordHashAlgorithm)); |
||
191 | } |
||
192 | sb.Append(VoiceGateway.MakeXML("ConnectAudio", JoinAudio ? "true" : "false")); |
||
193 | sb.Append(VoiceGateway.MakeXML("ConnectText", JoinText ? "true" : "false")); |
||
194 | sb.Append(VoiceGateway.MakeXML("JoinAudio", JoinAudio ? "true" : "false")); |
||
195 | sb.Append(VoiceGateway.MakeXML("JoinText", JoinText ? "true" : "false")); |
||
196 | sb.Append(VoiceGateway.MakeXML("VoiceFontID", "0")); |
||
197 | |||
198 | return Request("Session.Create.1", sb.ToString()); |
||
199 | } |
||
200 | |||
201 | /// <summary> |
||
202 | /// Used to accept a call |
||
203 | /// </summary> |
||
204 | /// <param name="SessionHandle">SessionHandle such as received from SessionNewEvent</param> |
||
205 | /// <param name="AudioMedia">"default"</param> |
||
206 | /// <returns></returns> |
||
207 | public int SessionConnect(string SessionHandle, string AudioMedia) |
||
208 | { |
||
209 | StringBuilder sb = new StringBuilder(); |
||
210 | sb.Append(VoiceGateway.MakeXML("SessionHandle", SessionHandle)); |
||
211 | sb.Append(VoiceGateway.MakeXML("AudioMedia", AudioMedia)); |
||
212 | return Request("Session.Connect.1", sb.ToString()); |
||
213 | } |
||
214 | |||
215 | /// <summary> |
||
216 | /// This command is used to start the audio render process, which will then play |
||
217 | /// the passed in file through the selected audio render device. This command |
||
218 | /// should not be issued if the user is on a call. |
||
219 | /// </summary> |
||
220 | /// <param name="SoundFilePath">The fully qualified path to the sound file.</param> |
||
221 | /// <param name="Loop">True if the file is to be played continuously and false if it is should be played once.</param> |
||
222 | /// <returns></returns> |
||
223 | public int SessionRenderAudioStart(string SoundFilePath, bool Loop) |
||
224 | { |
||
225 | StringBuilder sb = new StringBuilder(); |
||
226 | sb.Append(VoiceGateway.MakeXML("SoundFilePath", SoundFilePath)); |
||
227 | sb.Append(VoiceGateway.MakeXML("Loop", Loop ? "1" : "0")); |
||
228 | return Request("Session.RenderAudioStart.1", sb.ToString()); |
||
229 | } |
||
230 | |||
231 | /// <summary> |
||
232 | /// This command is used to stop the audio render process. |
||
233 | /// </summary> |
||
234 | /// <param name="SoundFilePath">The fully qualified path to the sound file issued in the start render command.</param> |
||
235 | /// <returns></returns> |
||
236 | public int SessionRenderAudioStop(string SoundFilePath) |
||
237 | { |
||
238 | string RequestXML = VoiceGateway.MakeXML("SoundFilePath", SoundFilePath); |
||
239 | return Request("Session.RenderAudioStop.1", RequestXML); |
||
240 | } |
||
241 | |||
242 | /// <summary> |
||
243 | /// This is used to ‘end’ an established session (i.e. hang-up or disconnect). |
||
244 | /// </summary> |
||
245 | /// <param name="SessionHandle">Handle returned from successful Session ‘create’ request or a SessionNewEvent</param> |
||
246 | /// <returns></returns> |
||
247 | public int SessionTerminate(string SessionHandle) |
||
248 | { |
||
249 | string RequestXML = VoiceGateway.MakeXML("SessionHandle", SessionHandle); |
||
250 | return Request("Session.Terminate.1", RequestXML); |
||
251 | } |
||
252 | |||
253 | /// <summary> |
||
254 | /// Set the combined speaking and listening position in 3D space. |
||
255 | /// </summary> |
||
256 | /// <param name="SessionHandle">Handle returned from successful Session ‘create’ request or a SessionNewEvent</param> |
||
257 | /// <param name="SpeakerPosition">Speaking position</param> |
||
258 | /// <param name="ListenerPosition">Listening position</param> |
||
259 | /// <returns></returns> |
||
260 | public int SessionSet3DPosition(string SessionHandle, VoicePosition SpeakerPosition, VoicePosition ListenerPosition) |
||
261 | { |
||
262 | StringBuilder sb = new StringBuilder(); |
||
263 | sb.Append(VoiceGateway.MakeXML("SessionHandle", SessionHandle)); |
||
264 | sb.Append("<SpeakerPosition>"); |
||
265 | sb.Append("<Position>"); |
||
266 | sb.Append(VoiceGateway.MakeXML("X", SpeakerPosition.Position.X.ToString())); |
||
267 | sb.Append(VoiceGateway.MakeXML("Y", SpeakerPosition.Position.Y.ToString())); |
||
268 | sb.Append(VoiceGateway.MakeXML("Z", SpeakerPosition.Position.Z.ToString())); |
||
269 | sb.Append("</Position>"); |
||
270 | sb.Append("<Velocity>"); |
||
271 | sb.Append(VoiceGateway.MakeXML("X", SpeakerPosition.Velocity.X.ToString())); |
||
272 | sb.Append(VoiceGateway.MakeXML("Y", SpeakerPosition.Velocity.Y.ToString())); |
||
273 | sb.Append(VoiceGateway.MakeXML("Z", SpeakerPosition.Velocity.Z.ToString())); |
||
274 | sb.Append("</Velocity>"); |
||
275 | sb.Append("<AtOrientation>"); |
||
276 | sb.Append(VoiceGateway.MakeXML("X", SpeakerPosition.AtOrientation.X.ToString())); |
||
277 | sb.Append(VoiceGateway.MakeXML("Y", SpeakerPosition.AtOrientation.Y.ToString())); |
||
278 | sb.Append(VoiceGateway.MakeXML("Z", SpeakerPosition.AtOrientation.Z.ToString())); |
||
279 | sb.Append("</AtOrientation>"); |
||
280 | sb.Append("<UpOrientation>"); |
||
281 | sb.Append(VoiceGateway.MakeXML("X", SpeakerPosition.UpOrientation.X.ToString())); |
||
282 | sb.Append(VoiceGateway.MakeXML("Y", SpeakerPosition.UpOrientation.Y.ToString())); |
||
283 | sb.Append(VoiceGateway.MakeXML("Z", SpeakerPosition.UpOrientation.Z.ToString())); |
||
284 | sb.Append("</UpOrientation>"); |
||
285 | sb.Append("<LeftOrientation>"); |
||
286 | sb.Append(VoiceGateway.MakeXML("X", SpeakerPosition.LeftOrientation.X.ToString())); |
||
287 | sb.Append(VoiceGateway.MakeXML("Y", SpeakerPosition.LeftOrientation.Y.ToString())); |
||
288 | sb.Append(VoiceGateway.MakeXML("Z", SpeakerPosition.LeftOrientation.Z.ToString())); |
||
289 | sb.Append("</LeftOrientation>"); |
||
290 | sb.Append("</SpeakerPosition>"); |
||
291 | sb.Append("<ListenerPosition>"); |
||
292 | sb.Append("<Position>"); |
||
293 | sb.Append(VoiceGateway.MakeXML("X", ListenerPosition.Position.X.ToString())); |
||
294 | sb.Append(VoiceGateway.MakeXML("Y", ListenerPosition.Position.Y.ToString())); |
||
295 | sb.Append(VoiceGateway.MakeXML("Z", ListenerPosition.Position.Z.ToString())); |
||
296 | sb.Append("</Position>"); |
||
297 | sb.Append("<Velocity>"); |
||
298 | sb.Append(VoiceGateway.MakeXML("X", ListenerPosition.Velocity.X.ToString())); |
||
299 | sb.Append(VoiceGateway.MakeXML("Y", ListenerPosition.Velocity.Y.ToString())); |
||
300 | sb.Append(VoiceGateway.MakeXML("Z", ListenerPosition.Velocity.Z.ToString())); |
||
301 | sb.Append("</Velocity>"); |
||
302 | sb.Append("<AtOrientation>"); |
||
303 | sb.Append(VoiceGateway.MakeXML("X", ListenerPosition.AtOrientation.X.ToString())); |
||
304 | sb.Append(VoiceGateway.MakeXML("Y", ListenerPosition.AtOrientation.Y.ToString())); |
||
305 | sb.Append(VoiceGateway.MakeXML("Z", ListenerPosition.AtOrientation.Z.ToString())); |
||
306 | sb.Append("</AtOrientation>"); |
||
307 | sb.Append("<UpOrientation>"); |
||
308 | sb.Append(VoiceGateway.MakeXML("X", ListenerPosition.UpOrientation.X.ToString())); |
||
309 | sb.Append(VoiceGateway.MakeXML("Y", ListenerPosition.UpOrientation.Y.ToString())); |
||
310 | sb.Append(VoiceGateway.MakeXML("Z", ListenerPosition.UpOrientation.Z.ToString())); |
||
311 | sb.Append("</UpOrientation>"); |
||
312 | sb.Append("<LeftOrientation>"); |
||
313 | sb.Append(VoiceGateway.MakeXML("X", ListenerPosition.LeftOrientation.X.ToString())); |
||
314 | sb.Append(VoiceGateway.MakeXML("Y", ListenerPosition.LeftOrientation.Y.ToString())); |
||
315 | sb.Append(VoiceGateway.MakeXML("Z", ListenerPosition.LeftOrientation.Z.ToString())); |
||
316 | sb.Append("</LeftOrientation>"); |
||
317 | sb.Append("</ListenerPosition>"); |
||
318 | return Request("Session.Set3DPosition.1", sb.ToString()); |
||
319 | } |
||
320 | |||
321 | /// <summary> |
||
322 | /// Set User Volume for a particular user. Does not affect how other users hear that user. |
||
323 | /// </summary> |
||
324 | /// <param name="SessionHandle">Handle returned from successful Session ‘create’ request or a SessionNewEvent</param> |
||
325 | /// <param name="ParticipantURI"></param> |
||
326 | /// <param name="Volume">The level of the audio, a number between -100 and 100 where 0 represents ‘normal’ speaking volume</param> |
||
327 | /// <returns></returns> |
||
328 | public int SessionSetParticipantVolumeForMe(string SessionHandle, string ParticipantURI, int Volume) |
||
329 | { |
||
330 | StringBuilder sb = new StringBuilder(); |
||
331 | sb.Append(VoiceGateway.MakeXML("SessionHandle", SessionHandle)); |
||
332 | sb.Append(VoiceGateway.MakeXML("ParticipantURI", ParticipantURI)); |
||
333 | sb.Append(VoiceGateway.MakeXML("Volume", Volume.ToString())); |
||
334 | return Request("Session.SetParticipantVolumeForMe.1", sb.ToString()); |
||
335 | } |
||
336 | } |
||
337 | } |