mumble-ruby2 1.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.rdoc +119 -0
- data/Rakefile +2 -0
- data/lib/mumble-ruby2.rb +39 -0
- data/lib/mumble-ruby2/audio_player.rb +107 -0
- data/lib/mumble-ruby2/audio_recorder.rb +79 -0
- data/lib/mumble-ruby2/cert_manager.rb +67 -0
- data/lib/mumble-ruby2/channel.rb +48 -0
- data/lib/mumble-ruby2/client.rb +218 -0
- data/lib/mumble-ruby2/connection.rb +85 -0
- data/lib/mumble-ruby2/img_reader.rb +37 -0
- data/lib/mumble-ruby2/messages.rb +361 -0
- data/lib/mumble-ruby2/model.rb +43 -0
- data/lib/mumble-ruby2/mumble.proto +291 -0
- data/lib/mumble-ruby2/packet_data_stream.rb +157 -0
- data/lib/mumble-ruby2/thread_tools.rb +24 -0
- data/lib/mumble-ruby2/user.rb +51 -0
- data/lib/mumble-ruby2/version.rb +3 -0
- data/mumble-ruby2.gemspec +24 -0
- metadata +137 -0
@@ -0,0 +1,48 @@
|
|
1
|
+
module Mumble
|
2
|
+
class Channel < Model
|
3
|
+
attribute :channel_id do
|
4
|
+
self.data.fetch('channel_id', 0)
|
5
|
+
end
|
6
|
+
attribute :name
|
7
|
+
attribute :parent_id do
|
8
|
+
self.data['parent']
|
9
|
+
end
|
10
|
+
attribute :links do
|
11
|
+
self.data.fetch('links', [])
|
12
|
+
end
|
13
|
+
|
14
|
+
def parent
|
15
|
+
client.channels[parent_id]
|
16
|
+
end
|
17
|
+
|
18
|
+
def children
|
19
|
+
client.channels.values.select do |channel|
|
20
|
+
channel.parent_id == channel_id
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def linked_channels
|
25
|
+
links.map do |channel_id|
|
26
|
+
client.channels[channel_id]
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def users
|
31
|
+
client.users.values.select do |user|
|
32
|
+
user.channel_id == channel_id
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def join
|
37
|
+
client.join_channel(self)
|
38
|
+
end
|
39
|
+
|
40
|
+
def send_text(string)
|
41
|
+
client.text_channel(self, string)
|
42
|
+
end
|
43
|
+
|
44
|
+
def send_image(file)
|
45
|
+
client.text_channel_img(self, file)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,218 @@
|
|
1
|
+
require 'hashie'
|
2
|
+
|
3
|
+
module Mumble
|
4
|
+
class ChannelNotFound < StandardError; end
|
5
|
+
class UserNotFound < StandardError; end
|
6
|
+
class NoSupportedCodec < StandardError; end
|
7
|
+
|
8
|
+
class Client
|
9
|
+
include ThreadTools
|
10
|
+
attr_reader :users, :channels
|
11
|
+
|
12
|
+
CODEC_OPUS = 4
|
13
|
+
|
14
|
+
def initialize(host, port=64738, username="RubyClient", password="")
|
15
|
+
@users, @channels = {}, {}
|
16
|
+
@callbacks = Hash.new { |h, k| h[k] = [] }
|
17
|
+
|
18
|
+
@config = Mumble.configuration.dup.tap do |c|
|
19
|
+
c.host = host
|
20
|
+
c.port = port
|
21
|
+
c.username = username
|
22
|
+
c.password = password
|
23
|
+
end
|
24
|
+
yield(@config) if block_given?
|
25
|
+
end
|
26
|
+
|
27
|
+
def connect
|
28
|
+
@conn = Connection.new @config.host, @config.port, cert_manager
|
29
|
+
@conn.connect
|
30
|
+
|
31
|
+
init_callbacks
|
32
|
+
version_exchange
|
33
|
+
authenticate
|
34
|
+
|
35
|
+
spawn_threads :read, :ping
|
36
|
+
connected? # just to get a nice return value
|
37
|
+
end
|
38
|
+
|
39
|
+
def disconnect
|
40
|
+
kill_threads
|
41
|
+
@conn.disconnect
|
42
|
+
@connected = false
|
43
|
+
end
|
44
|
+
|
45
|
+
def connected?
|
46
|
+
@connected ||= false
|
47
|
+
end
|
48
|
+
|
49
|
+
def cert_manager
|
50
|
+
@cert_manager ||= CertManager.new @config.username, @config.ssl_cert_opts
|
51
|
+
end
|
52
|
+
|
53
|
+
def recorder
|
54
|
+
raise NoSupportedCodec unless @codec
|
55
|
+
@recorder ||= AudioRecorder.new self, @config.sample_rate
|
56
|
+
end
|
57
|
+
|
58
|
+
def player
|
59
|
+
raise NoSupportedCodec unless @codec
|
60
|
+
@audio_streamer ||= AudioPlayer.new @codec, @conn, @config.sample_rate, @config.bitrate
|
61
|
+
end
|
62
|
+
|
63
|
+
def me
|
64
|
+
users[@session]
|
65
|
+
end
|
66
|
+
|
67
|
+
def set_comment(comment="")
|
68
|
+
send_user_state(comment: comment)
|
69
|
+
end
|
70
|
+
|
71
|
+
def join_channel(channel)
|
72
|
+
id = channel_id channel
|
73
|
+
send_user_state(session: @session, channel_id: id)
|
74
|
+
channels[id]
|
75
|
+
end
|
76
|
+
|
77
|
+
def move_user(user, channel)
|
78
|
+
cid = channel_id channel
|
79
|
+
uid = user_session user
|
80
|
+
send_user_state(session: uid, channel_id: cid)
|
81
|
+
channels[cid]
|
82
|
+
end
|
83
|
+
|
84
|
+
def text_user(user, string)
|
85
|
+
session = user_session user
|
86
|
+
send_text_message(session: [user_session(user)], message: string)
|
87
|
+
users[session]
|
88
|
+
end
|
89
|
+
|
90
|
+
def text_user_img(user, file)
|
91
|
+
text_user(user, ImgReader.msg_from_file(file))
|
92
|
+
end
|
93
|
+
|
94
|
+
def text_channel(channel, string)
|
95
|
+
id = channel_id channel
|
96
|
+
send_text_message(channel_id: [id], message: string)
|
97
|
+
channels[id]
|
98
|
+
end
|
99
|
+
|
100
|
+
def text_channel_img(channel, file)
|
101
|
+
text_channel(channel, ImgReader.msg_from_file(file))
|
102
|
+
end
|
103
|
+
|
104
|
+
def find_user(name)
|
105
|
+
users.values.find { |u| u.name == name }
|
106
|
+
end
|
107
|
+
|
108
|
+
def find_channel(name)
|
109
|
+
channels.values.find { |c| c.name == name }
|
110
|
+
end
|
111
|
+
|
112
|
+
def on_connected(&block)
|
113
|
+
@callbacks[:connected] << block
|
114
|
+
end
|
115
|
+
|
116
|
+
def remove_callback(symbol, callback)
|
117
|
+
@callbacks[symbol].delete callback
|
118
|
+
end
|
119
|
+
|
120
|
+
Messages.all_types.each do |msg_type|
|
121
|
+
define_method "on_#{msg_type}" do |&block|
|
122
|
+
@callbacks[msg_type] << block
|
123
|
+
end
|
124
|
+
|
125
|
+
define_method "send_#{msg_type}" do |opts|
|
126
|
+
@conn.send_message(msg_type, opts)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
private
|
131
|
+
def read
|
132
|
+
message = @conn.read_message
|
133
|
+
sym = message.class.to_s.demodulize.underscore.to_sym
|
134
|
+
run_callbacks sym, Hashie::Mash.new(message.to_hash)
|
135
|
+
end
|
136
|
+
|
137
|
+
def ping
|
138
|
+
send_ping timestamp: Time.now.to_i
|
139
|
+
sleep(20)
|
140
|
+
end
|
141
|
+
|
142
|
+
def run_callbacks(sym, *args)
|
143
|
+
@callbacks[sym].each { |c| c.call *args }
|
144
|
+
end
|
145
|
+
|
146
|
+
def init_callbacks
|
147
|
+
on_server_sync do |message|
|
148
|
+
@session = message.session
|
149
|
+
@connected = true
|
150
|
+
@callbacks[:connected].each { |c| c.call }
|
151
|
+
end
|
152
|
+
on_channel_state do |message|
|
153
|
+
if channel = channels[message.channel_id]
|
154
|
+
channel.update message.to_hash
|
155
|
+
else
|
156
|
+
channels[message.channel_id] = Channel.new(self, message.to_hash)
|
157
|
+
end
|
158
|
+
end
|
159
|
+
on_channel_remove do |message|
|
160
|
+
channels.delete(message.channel_id)
|
161
|
+
end
|
162
|
+
on_user_state do |message|
|
163
|
+
if user = users[message.session]
|
164
|
+
user.update(message.to_hash)
|
165
|
+
else
|
166
|
+
users[message.session] = User.new(self, message.to_hash)
|
167
|
+
end
|
168
|
+
end
|
169
|
+
on_user_remove do |message|
|
170
|
+
users.delete(message.session)
|
171
|
+
end
|
172
|
+
on_codec_version do |message|
|
173
|
+
codec_negotiation(message)
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
def version_exchange
|
178
|
+
send_version({
|
179
|
+
version: encode_version(1, 2, 10),
|
180
|
+
release: "mumble-ruby2 #{Mumble::VERSION}",
|
181
|
+
os: %x{uname -s}.strip,
|
182
|
+
os_version: %x{uname -v}.strip
|
183
|
+
})
|
184
|
+
end
|
185
|
+
|
186
|
+
def authenticate
|
187
|
+
send_authenticate({
|
188
|
+
username: @config.username,
|
189
|
+
password: @config.password,
|
190
|
+
opus: true
|
191
|
+
})
|
192
|
+
end
|
193
|
+
|
194
|
+
def codec_negotiation(message)
|
195
|
+
@codec = CODEC_OPUS if message.opus
|
196
|
+
end
|
197
|
+
|
198
|
+
def channel_id(channel)
|
199
|
+
channel = find_channel(channel) if channel.is_a? String
|
200
|
+
id = channel.respond_to?(:channel_id) ? channel.channel_id : channel
|
201
|
+
|
202
|
+
raise ChannelNotFound unless @channels.has_key? id
|
203
|
+
id
|
204
|
+
end
|
205
|
+
|
206
|
+
def user_session(user)
|
207
|
+
user = find_user(user) if user.is_a? String
|
208
|
+
id = user.respond_to?(:session) ? user.session : user
|
209
|
+
|
210
|
+
raise UserNotFound unless @users.has_key? id
|
211
|
+
id
|
212
|
+
end
|
213
|
+
|
214
|
+
def encode_version(major, minor, patch)
|
215
|
+
(major << 16) | (minor << 8) | (patch & 0xFF)
|
216
|
+
end
|
217
|
+
end
|
218
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'socket'
|
2
|
+
require 'openssl'
|
3
|
+
require 'thread'
|
4
|
+
|
5
|
+
module Mumble
|
6
|
+
class Connection
|
7
|
+
def initialize(host, port, cert_manager)
|
8
|
+
@host = host
|
9
|
+
@port = port
|
10
|
+
@cert_manager = cert_manager
|
11
|
+
@write_lock = Mutex.new
|
12
|
+
end
|
13
|
+
|
14
|
+
def connect
|
15
|
+
context = OpenSSL::SSL::SSLContext.new(:TLSv1)
|
16
|
+
context.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
17
|
+
[:key, :cert].each { |s| context.send("#{s}=", @cert_manager.send(s)) }
|
18
|
+
tcp_sock = TCPSocket.new @host, @port
|
19
|
+
@sock = OpenSSL::SSL::SSLSocket.new tcp_sock, context
|
20
|
+
@sock.connect
|
21
|
+
end
|
22
|
+
|
23
|
+
def disconnect
|
24
|
+
@sock.close
|
25
|
+
end
|
26
|
+
|
27
|
+
def read_message
|
28
|
+
header = read_data 6
|
29
|
+
type, len = header.unpack Messages::HEADER_FORMAT
|
30
|
+
data = read_data len
|
31
|
+
if type == message_type(:udp_tunnel)
|
32
|
+
# UDP Packet -- No Protobuf
|
33
|
+
message = message_class(:udp_tunnel).new
|
34
|
+
message.packet = data
|
35
|
+
else
|
36
|
+
message = message_raw type, data
|
37
|
+
end
|
38
|
+
message
|
39
|
+
end
|
40
|
+
|
41
|
+
def send_udp_packet(packet)
|
42
|
+
header = [message_type(:udp_tunnel), packet.length].pack Messages::HEADER_FORMAT
|
43
|
+
send_data(header + packet)
|
44
|
+
end
|
45
|
+
|
46
|
+
def send_message(sym, attrs)
|
47
|
+
type, klass = message(sym)
|
48
|
+
message = klass.new
|
49
|
+
attrs.each { |k, v| message.send("#{k}=", v) }
|
50
|
+
serial = message.serialize_to_string
|
51
|
+
header = [type, serial.size].pack Messages::HEADER_FORMAT
|
52
|
+
send_data(header + serial)
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
def send_data(data)
|
57
|
+
@write_lock.synchronize do
|
58
|
+
@sock.write data
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def read_data(len)
|
63
|
+
@sock.read len
|
64
|
+
end
|
65
|
+
|
66
|
+
def message(obj)
|
67
|
+
return message_type(obj), message_class(obj)
|
68
|
+
end
|
69
|
+
|
70
|
+
def message_type(obj)
|
71
|
+
if obj.is_a? Protobuf::Message
|
72
|
+
obj = obj.class.to_s.demodulize.underscore.to_sym
|
73
|
+
end
|
74
|
+
Messages.sym_to_type(obj)
|
75
|
+
end
|
76
|
+
|
77
|
+
def message_class(obj)
|
78
|
+
Messages.type_to_class(message_type(obj))
|
79
|
+
end
|
80
|
+
|
81
|
+
def message_raw(type, data)
|
82
|
+
Messages.raw_to_obj(type, data)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'base64'
|
2
|
+
|
3
|
+
module Mumble
|
4
|
+
class UnsupportedImgFormat < StandardError
|
5
|
+
def initialize
|
6
|
+
super "Image format must be one of the following: #{ImgReader::FORMATS}"
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
class ImgTooLarge < StandardError
|
11
|
+
def initialize
|
12
|
+
super "Image must be smaller than 128 kB"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class ImgReader
|
17
|
+
class << self
|
18
|
+
FORMATS = %w(png jpg jpeg svg)
|
19
|
+
|
20
|
+
def msg_from_file(file)
|
21
|
+
@@file = file
|
22
|
+
@@ext = File.extname(@@file)[1..-1]
|
23
|
+
validate_file
|
24
|
+
|
25
|
+
data = File.read @@file
|
26
|
+
"<img src='data:image/#{@@ext};base64,#{Base64.encode64(data)}'/>"
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
def validate_file
|
31
|
+
raise LoadError.new("#{@@file} not found") unless File.exists? @@file
|
32
|
+
raise UnsupportedImgFormat unless FORMATS.include? @@ext
|
33
|
+
raise ImgTooLarge unless File.size(@@file) <= 128 * 1024
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,361 @@
|
|
1
|
+
### Generated by rprotoc. DO NOT EDIT!
|
2
|
+
### <proto file: mumble.proto>
|
3
|
+
|
4
|
+
require 'protobuf/message/message'
|
5
|
+
require 'protobuf/message/enum'
|
6
|
+
require 'protobuf/message/service'
|
7
|
+
require 'protobuf/message/extend'
|
8
|
+
|
9
|
+
module Mumble
|
10
|
+
module Messages
|
11
|
+
::Protobuf::OPTIONS[:"optimize_for"] = :SPEED
|
12
|
+
HEADER_FORMAT = "nN"
|
13
|
+
|
14
|
+
@@sym_to_type = {
|
15
|
+
version: 0,
|
16
|
+
udp_tunnel: 1,
|
17
|
+
authenticate: 2,
|
18
|
+
ping: 3,
|
19
|
+
reject: 4,
|
20
|
+
server_sync: 5,
|
21
|
+
channel_remove: 6,
|
22
|
+
channel_state: 7,
|
23
|
+
user_remove: 8,
|
24
|
+
user_state: 9,
|
25
|
+
ban_list: 10,
|
26
|
+
text_message: 11,
|
27
|
+
permission_denied: 12,
|
28
|
+
acl: 13,
|
29
|
+
query_users: 14,
|
30
|
+
crypt_setup: 15,
|
31
|
+
context_action_add: 16,
|
32
|
+
context_action: 17,
|
33
|
+
user_list: 18,
|
34
|
+
voice_target: 19,
|
35
|
+
permission_query: 20,
|
36
|
+
codec_version: 21,
|
37
|
+
user_stats: 22,
|
38
|
+
request_blob: 23,
|
39
|
+
server_config: 24,
|
40
|
+
suggest_config: 25
|
41
|
+
}
|
42
|
+
|
43
|
+
@@type_to_sym = @@sym_to_type.invert
|
44
|
+
|
45
|
+
class << self
|
46
|
+
def all_types
|
47
|
+
return @@sym_to_type.keys
|
48
|
+
end
|
49
|
+
|
50
|
+
def sym_to_type(sym)
|
51
|
+
@@sym_to_type[sym]
|
52
|
+
end
|
53
|
+
|
54
|
+
def type_to_class(type)
|
55
|
+
const_get(@@type_to_sym[type].to_s.camelcase)
|
56
|
+
end
|
57
|
+
|
58
|
+
def raw_to_obj(type, data)
|
59
|
+
message = type_to_class(type).new
|
60
|
+
message.parse_from_string(data)
|
61
|
+
message
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
class Version < ::Protobuf::Message
|
66
|
+
defined_in __FILE__
|
67
|
+
optional :uint32, :version, 1
|
68
|
+
optional :string, :release, 2
|
69
|
+
optional :string, :os, 3
|
70
|
+
optional :string, :os_version, 4
|
71
|
+
end
|
72
|
+
class UdpTunnel < ::Protobuf::Message
|
73
|
+
defined_in __FILE__
|
74
|
+
required :bytes, :packet, 1
|
75
|
+
end
|
76
|
+
class Authenticate < ::Protobuf::Message
|
77
|
+
defined_in __FILE__
|
78
|
+
optional :string, :username, 1
|
79
|
+
optional :string, :password, 2
|
80
|
+
repeated :string, :tokens, 3
|
81
|
+
repeated :int32, :celt_versions, 4
|
82
|
+
optional :bool, :opus, 5, :default => false
|
83
|
+
end
|
84
|
+
class Ping < ::Protobuf::Message
|
85
|
+
defined_in __FILE__
|
86
|
+
optional :uint64, :timestamp, 1
|
87
|
+
optional :uint32, :good, 2
|
88
|
+
optional :uint32, :late, 3
|
89
|
+
optional :uint32, :lost, 4
|
90
|
+
optional :uint32, :resync, 5
|
91
|
+
optional :uint32, :udp_packets, 6
|
92
|
+
optional :uint32, :tcp_packets, 7
|
93
|
+
optional :float, :udp_ping_avg, 8
|
94
|
+
optional :float, :udp_ping_var, 9
|
95
|
+
optional :float, :tcp_ping_avg, 10
|
96
|
+
optional :float, :tcp_ping_var, 11
|
97
|
+
end
|
98
|
+
class Reject < ::Protobuf::Message
|
99
|
+
defined_in __FILE__
|
100
|
+
class RejectType < ::Protobuf::Enum
|
101
|
+
defined_in __FILE__
|
102
|
+
None = value(:None, 0)
|
103
|
+
WrongVersion = value(:WrongVersion, 1)
|
104
|
+
InvalidUsername = value(:InvalidUsername, 2)
|
105
|
+
WrongUserPW = value(:WrongUserPW, 3)
|
106
|
+
WrongServerPW = value(:WrongServerPW, 4)
|
107
|
+
UsernameInUse = value(:UsernameInUse, 5)
|
108
|
+
ServerFull = value(:ServerFull, 6)
|
109
|
+
NoCertificate = value(:NoCertificate, 7)
|
110
|
+
end
|
111
|
+
optional :RejectType, :type, 1
|
112
|
+
optional :string, :reason, 2
|
113
|
+
end
|
114
|
+
class ServerConfig < ::Protobuf::Message
|
115
|
+
defined_in __FILE__
|
116
|
+
optional :uint32, :max_bandwidth, 1
|
117
|
+
optional :string, :welcome_text, 2
|
118
|
+
optional :bool, :allow_html, 3
|
119
|
+
optional :uint32, :message_length, 4
|
120
|
+
optional :uint32, :image_message_length, 5
|
121
|
+
end
|
122
|
+
class ServerSync < ::Protobuf::Message
|
123
|
+
defined_in __FILE__
|
124
|
+
optional :uint32, :session, 1
|
125
|
+
optional :uint32, :max_bandwidth, 2
|
126
|
+
optional :string, :welcome_text, 3
|
127
|
+
optional :uint64, :permissions, 4
|
128
|
+
end
|
129
|
+
class SuggestConfig < ::Protobuf::Message
|
130
|
+
defined_in __FILE__
|
131
|
+
optional :uint32, :version, 1
|
132
|
+
optional :bool, :positional, 2
|
133
|
+
optional :bool, :push_to_talk, 3
|
134
|
+
end
|
135
|
+
class ChannelRemove < ::Protobuf::Message
|
136
|
+
defined_in __FILE__
|
137
|
+
required :uint32, :channel_id, 1
|
138
|
+
end
|
139
|
+
class ChannelState < ::Protobuf::Message
|
140
|
+
defined_in __FILE__
|
141
|
+
optional :uint32, :channel_id, 1
|
142
|
+
optional :uint32, :parent, 2
|
143
|
+
optional :string, :name, 3
|
144
|
+
repeated :uint32, :links, 4
|
145
|
+
optional :string, :description, 5
|
146
|
+
repeated :uint32, :links_add, 6
|
147
|
+
repeated :uint32, :links_remove, 7
|
148
|
+
optional :bool, :temporary, 8, :default => false
|
149
|
+
optional :int32, :position, 9, :default => 0
|
150
|
+
optional :bytes, :description_hash, 10
|
151
|
+
end
|
152
|
+
class UserRemove < ::Protobuf::Message
|
153
|
+
defined_in __FILE__
|
154
|
+
required :uint32, :session, 1
|
155
|
+
optional :uint32, :actor, 2
|
156
|
+
optional :string, :reason, 3
|
157
|
+
optional :bool, :ban, 4
|
158
|
+
end
|
159
|
+
class UserState < ::Protobuf::Message
|
160
|
+
defined_in __FILE__
|
161
|
+
optional :uint32, :session, 1
|
162
|
+
optional :uint32, :actor, 2
|
163
|
+
optional :string, :name, 3
|
164
|
+
optional :uint32, :user_id, 4
|
165
|
+
optional :uint32, :channel_id, 5
|
166
|
+
optional :bool, :mute, 6
|
167
|
+
optional :bool, :deaf, 7
|
168
|
+
optional :bool, :suppress, 8
|
169
|
+
optional :bool, :self_mute, 9
|
170
|
+
optional :bool, :self_deaf, 10
|
171
|
+
optional :bytes, :texture, 11
|
172
|
+
optional :bytes, :plugin_context, 12
|
173
|
+
optional :string, :plugin_identity, 13
|
174
|
+
optional :string, :comment, 14
|
175
|
+
optional :string, :hash, 15
|
176
|
+
optional :bytes, :comment_hash, 16
|
177
|
+
optional :bytes, :texture_hash, 17
|
178
|
+
optional :bool, :priority_speaker, 18
|
179
|
+
optional :bool, :recording, 19
|
180
|
+
end
|
181
|
+
class BanList < ::Protobuf::Message
|
182
|
+
defined_in __FILE__
|
183
|
+
class BanEntry < ::Protobuf::Message
|
184
|
+
defined_in __FILE__
|
185
|
+
required :bytes, :address, 1
|
186
|
+
required :uint32, :mask, 2
|
187
|
+
optional :string, :name, 3
|
188
|
+
optional :string, :hash, 4
|
189
|
+
optional :string, :reason, 5
|
190
|
+
optional :string, :start, 6
|
191
|
+
optional :uint32, :duration, 7
|
192
|
+
end
|
193
|
+
repeated :BanEntry, :bans, 1
|
194
|
+
optional :bool, :query, 2, :default => false
|
195
|
+
end
|
196
|
+
class TextMessage < ::Protobuf::Message
|
197
|
+
defined_in __FILE__
|
198
|
+
optional :uint32, :actor, 1
|
199
|
+
repeated :uint32, :session, 2
|
200
|
+
repeated :uint32, :channel_id, 3
|
201
|
+
repeated :uint32, :tree_id, 4
|
202
|
+
required :string, :message, 5
|
203
|
+
end
|
204
|
+
class PermissionDenied < ::Protobuf::Message
|
205
|
+
defined_in __FILE__
|
206
|
+
class DenyType < ::Protobuf::Enum
|
207
|
+
defined_in __FILE__
|
208
|
+
Text = value(:Text, 0)
|
209
|
+
Permission = value(:Permission, 1)
|
210
|
+
SuperUser = value(:SuperUser, 2)
|
211
|
+
ChannelName = value(:ChannelName, 3)
|
212
|
+
TextTooLong = value(:TextTooLong, 4)
|
213
|
+
H9K = value(:H9K, 5)
|
214
|
+
TemporaryChannel = value(:TemporaryChannel, 6)
|
215
|
+
MissingCertificate = value(:MissingCertificate, 7)
|
216
|
+
UserName = value(:UserName, 8)
|
217
|
+
ChannelFull = value(:ChannelFull, 9)
|
218
|
+
NestingLimit = value(:NestingLimit, 10)
|
219
|
+
end
|
220
|
+
optional :uint32, :permission, 1
|
221
|
+
optional :uint32, :channel_id, 2
|
222
|
+
optional :uint32, :session, 3
|
223
|
+
optional :string, :reason, 4
|
224
|
+
optional :DenyType, :type, 5
|
225
|
+
optional :string, :name, 6
|
226
|
+
end
|
227
|
+
class Acl < ::Protobuf::Message
|
228
|
+
defined_in __FILE__
|
229
|
+
class ChanGroup < ::Protobuf::Message
|
230
|
+
defined_in __FILE__
|
231
|
+
required :string, :name, 1
|
232
|
+
optional :bool, :inherited, 2, :default => true
|
233
|
+
optional :bool, :inherit, 3, :default => true
|
234
|
+
optional :bool, :inheritable, 4, :default => true
|
235
|
+
repeated :uint32, :add, 5
|
236
|
+
repeated :uint32, :remove, 6
|
237
|
+
repeated :uint32, :inherited_members, 7
|
238
|
+
end
|
239
|
+
class ChanACL < ::Protobuf::Message
|
240
|
+
defined_in __FILE__
|
241
|
+
optional :bool, :apply_here, 1, :default => true
|
242
|
+
optional :bool, :apply_subs, 2, :default => true
|
243
|
+
optional :bool, :inherited, 3, :default => true
|
244
|
+
optional :uint32, :user_id, 4
|
245
|
+
optional :string, :group, 5
|
246
|
+
optional :uint32, :grant, 6
|
247
|
+
optional :uint32, :deny, 7
|
248
|
+
end
|
249
|
+
required :uint32, :channel_id, 1
|
250
|
+
optional :bool, :inherit_acls, 2, :default => true
|
251
|
+
repeated :ChanGroup, :groups, 3
|
252
|
+
repeated :ChanACL, :acls, 4
|
253
|
+
optional :bool, :query, 5, :default => false
|
254
|
+
end
|
255
|
+
class QueryUsers < ::Protobuf::Message
|
256
|
+
defined_in __FILE__
|
257
|
+
repeated :uint32, :ids, 1
|
258
|
+
repeated :string, :names, 2
|
259
|
+
end
|
260
|
+
class CryptSetup < ::Protobuf::Message
|
261
|
+
defined_in __FILE__
|
262
|
+
optional :bytes, :key, 1
|
263
|
+
optional :bytes, :client_nonce, 2
|
264
|
+
optional :bytes, :server_nonce, 3
|
265
|
+
end
|
266
|
+
class ContextActionModify < ::Protobuf::Message
|
267
|
+
defined_in __FILE__
|
268
|
+
class Context < ::Protobuf::Enum
|
269
|
+
defined_in __FILE__
|
270
|
+
Server = value(:Server, 1)
|
271
|
+
Channel = value(:Channel, 2)
|
272
|
+
User = value(:User, 4)
|
273
|
+
end
|
274
|
+
class Operation < ::Protobuf::Enum
|
275
|
+
defined_in __FILE__
|
276
|
+
Add = value(:Add, 0)
|
277
|
+
Remove = value(:Remove, 1)
|
278
|
+
end
|
279
|
+
required :string, :action, 1
|
280
|
+
optional :string, :text, 2
|
281
|
+
optional :uint32, :context, 3
|
282
|
+
optional :Operation, :operation, 4
|
283
|
+
end
|
284
|
+
class ContextAction < ::Protobuf::Message
|
285
|
+
defined_in __FILE__
|
286
|
+
optional :uint32, :session, 1
|
287
|
+
optional :uint32, :channel_id, 2
|
288
|
+
required :string, :action, 3
|
289
|
+
end
|
290
|
+
class UserList < ::Protobuf::Message
|
291
|
+
defined_in __FILE__
|
292
|
+
class User < ::Protobuf::Message
|
293
|
+
defined_in __FILE__
|
294
|
+
required :uint32, :user_id, 1
|
295
|
+
optional :string, :name, 2
|
296
|
+
end
|
297
|
+
repeated :User, :users, 1
|
298
|
+
end
|
299
|
+
class VoiceTarget < ::Protobuf::Message
|
300
|
+
defined_in __FILE__
|
301
|
+
class Target < ::Protobuf::Message
|
302
|
+
defined_in __FILE__
|
303
|
+
repeated :uint32, :session, 1
|
304
|
+
optional :uint32, :channel_id, 2
|
305
|
+
optional :string, :group, 3
|
306
|
+
optional :bool, :links, 4, :default => false
|
307
|
+
optional :bool, :children, 5, :default => false
|
308
|
+
end
|
309
|
+
optional :uint32, :id, 1
|
310
|
+
repeated :Target, :targets, 2
|
311
|
+
end
|
312
|
+
class PermissionQuery < ::Protobuf::Message
|
313
|
+
defined_in __FILE__
|
314
|
+
optional :uint32, :channel_id, 1
|
315
|
+
optional :uint32, :permissions, 2
|
316
|
+
optional :bool, :flush, 3, :default => false
|
317
|
+
end
|
318
|
+
class CodecVersion < ::Protobuf::Message
|
319
|
+
defined_in __FILE__
|
320
|
+
required :int32, :alpha, 1
|
321
|
+
required :int32, :beta, 2
|
322
|
+
required :bool, :prefer_alpha, 3, :default => true
|
323
|
+
optional :bool, :opus, 4, :default => false
|
324
|
+
end
|
325
|
+
class UserStats < ::Protobuf::Message
|
326
|
+
defined_in __FILE__
|
327
|
+
class Stats < ::Protobuf::Message
|
328
|
+
defined_in __FILE__
|
329
|
+
optional :uint32, :good, 1
|
330
|
+
optional :uint32, :late, 2
|
331
|
+
optional :uint32, :lost, 3
|
332
|
+
optional :uint32, :resync, 4
|
333
|
+
end
|
334
|
+
optional :uint32, :session, 1
|
335
|
+
optional :bool, :stats_only, 2, :default => false
|
336
|
+
repeated :bytes, :certificates, 3
|
337
|
+
optional :Stats, :from_client, 4
|
338
|
+
optional :Stats, :from_server, 5
|
339
|
+
optional :uint32, :udp_packets, 6
|
340
|
+
optional :uint32, :tcp_packets, 7
|
341
|
+
optional :float, :udp_ping_avg, 8
|
342
|
+
optional :float, :udp_ping_var, 9
|
343
|
+
optional :float, :tcp_ping_avg, 10
|
344
|
+
optional :float, :tcp_ping_var, 11
|
345
|
+
optional :Version, :version, 12
|
346
|
+
repeated :int32, :celt_versions, 13
|
347
|
+
optional :bytes, :address, 14
|
348
|
+
optional :uint32, :bandwidth, 15
|
349
|
+
optional :uint32, :onlinesecs, 16
|
350
|
+
optional :uint32, :idlesecs, 17
|
351
|
+
optional :bool, :strong_certificate, 18, :default => false
|
352
|
+
optional :bool, :opus, 19, :default => false
|
353
|
+
end
|
354
|
+
class RequestBlob < ::Protobuf::Message
|
355
|
+
defined_in __FILE__
|
356
|
+
repeated :uint32, :session_texture, 1
|
357
|
+
repeated :uint32, :session_comment, 2
|
358
|
+
repeated :uint32, :channel_description, 3
|
359
|
+
end
|
360
|
+
end
|
361
|
+
end
|