synacrb 0.1.0

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 4964063b1ca35c7063231c1c10f1d86c088493f0
4
+ data.tar.gz: a0358c631c43e032dc73ef99785d479bf392d93b
5
+ SHA512:
6
+ metadata.gz: f4e7277192867a5e82655c3f586a40a8ad4e9da8cb4bd0e43d4580deb256dc93f7123b7639752712c7364a9681e754744609a895fb2a29cdcfd422f33048dc58
7
+ data.tar.gz: 0ddd97c3a7dbbae5f8070fbd55ba33350fd1055b432a305ec1e9e15ef95e728982ead47ab614f26bd92d52a9b7f28988617adae7c25773b5f13c2b27c8e78079
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+ synacrb-*.gem
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ source "https://rubygems.org"
2
+
3
+ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ gem "msgpack"
6
+ gem "openssl"
7
+
8
+ # Specify your gem's dependencies in synacrb.gemspec
9
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,24 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ synacrb (0.1.0)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ msgpack (1.1.0)
10
+ openssl (2.0.6)
11
+ rake (10.5.0)
12
+
13
+ PLATFORMS
14
+ ruby
15
+
16
+ DEPENDENCIES
17
+ bundler (~> 1.16)
18
+ msgpack
19
+ openssl
20
+ rake (~> 10.0)
21
+ synacrb!
22
+
23
+ BUNDLED WITH
24
+ 1.16.0
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2017 jD91mZM2
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,55 @@
1
+ # synacrb
2
+
3
+ This is a Ruby library for synac.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'synacrb'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install synacrb
20
+
21
+ ## Usage
22
+
23
+ Example:
24
+ ```Ruby
25
+ session = Synacrb::Session.new "<address>", "<certificate hash>"
26
+ session.login_with_token true, "<username>", "<token>" # true indicates bot account
27
+
28
+ # First message should be LoginSuccess or an error
29
+ result = session.read
30
+ # TODO: Use result
31
+
32
+ # Initiate state
33
+ state = Synacrb::State.new
34
+
35
+ # Main loop
36
+ loop do
37
+ packet = session.read
38
+ state.update packet
39
+ # TODO: Use packet
40
+ end
41
+ ```
42
+
43
+ ## Development
44
+
45
+ After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
46
+
47
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
48
+
49
+ ## Contributing
50
+
51
+ Bug reports and pull requests are welcome on GitHub at https://github.com/jD91mZM2/synacrb.
52
+
53
+ ## License
54
+
55
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "synacrb"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/lib/packets.rb ADDED
@@ -0,0 +1,203 @@
1
+ module Synacrb
2
+ module Common
3
+ DEFAULT_PORT = 8439
4
+ TYPING_TIMEOUT = 10
5
+
6
+ LIMIT_USER_NAME = 128
7
+ LIMIT_CHANNEL_NAME = 128
8
+ LIMIT_GROUP_NAME = 128
9
+ LIMIT_GROUP_AMOUNT = 2048
10
+ LIMIT_MESSAGE = 16384
11
+
12
+ LIMIT_BULK = 64
13
+
14
+ ERR_GROUP_INVALID_POS = 1
15
+ ERR_GROUP_LOCKED_NAME = 2
16
+ ERR_LIMIT_REACHED = 3
17
+ ERR_LOGIN_BANNED = 4
18
+ ERR_LOGIN_BOT = 5
19
+ ERR_LOGIN_INVALID = 6
20
+ ERR_MAX_CONN_PER_IP = 7
21
+ ERR_MISSING_FIELD = 8
22
+ ERR_MISSING_PERMISSION = 9
23
+ ERR_NAME_TAKEN = 10
24
+ ERR_UNKNOWN_BOT = 11
25
+ ERR_UNKNOWN_CHANNEL = 12
26
+ ERR_UNKNOWN_GROUP = 13
27
+ ERR_UNKNOWN_MESSAGE = 14
28
+ ERR_UNKNOWN_USER = 15
29
+
30
+ PERM_READ = 1
31
+ PERM_WRITE = 1 << 1
32
+
33
+ PERM_ASSIGN_GROUPS = 1 << 2
34
+ PERM_BAN = 1 << 3
35
+ PERM_MANAGE_CHANNELS = 1 << 4
36
+ PERM_MANAGE_GROUPS = 1 << 5
37
+ PERM_MANAGE_MESSAGES = 1 << 6
38
+
39
+ Channel = Struct.new(:id, :name, :overrides)
40
+ Group = Struct.new(:allow, :deny, :id, :name, :pos, :unassignable)
41
+ Message = Struct.new(:author, :channel, :id, :text, :timestamp, :timestamp_edit)
42
+ User = Struct.new(:ban, :bot, :groups, :id, :name)
43
+
44
+ # CLIENT PACKETS
45
+ PACKET_CLOSE_ID = 0; Close = Class.new
46
+ PACKET_ERR_ID = 1;
47
+ PACKET_RATELIMIT_ID = 2;
48
+ PACKET_CHANNELCREATE_ID = 3; ChannelCreate = Struct.new(:name, :overrides)
49
+ PACKET_CHANNELDELETE_ID = 4; ChannelDelete = Struct.new(:id)
50
+ PACKET_CHANNELUPDATE_ID = 5; ChannelUpdate = Struct.new(:inner, :keep_overrides)
51
+ PACKET_COMMAND_ID = 6; Command = Struct.new(:args, :recipient)
52
+ PACKET_GROUPCREATE_ID = 7; GroupCreate = Struct.new(:allow, :deny, :name, :pos, :unassignable)
53
+ PACKET_GROUPDELETE_ID = 8; GroupDelete = Struct.new(:id)
54
+ PACKET_GROUPUPDATE_ID = 9; GroupUpdate = Struct.new(:inner)
55
+ PACKET_LOGIN_ID = 10; Login = Struct.new(:bot, :name, :password, :token)
56
+ PACKET_LOGINUPDATE_ID = 11; LoginUpdate = Struct.new(:name, :password_current, :password_new, :reset_token)
57
+ PACKET_MESSAGECREATE_ID = 12; MessageCreate = Struct.new(:channel, :text)
58
+ PACKET_MESSAGEDELETE_ID = 13; MessageDelete = Struct.new(:id)
59
+ PACKET_MESSAGEDELETEBULK_ID = 14; MessageDeleteBulk = Struct.new(:channel, :ids)
60
+ PACKET_MESSAGELIST_ID = 15; MessageList = Struct.new(:after, :before, :channel, :limit)
61
+ PACKET_MESSAGEUPDATE_ID = 16; MessageUpdate = Struct.new(:id, :text)
62
+ PACKET_PRIVATEMESSAGE_ID = 17; PrivateMessage = Struct.new(:text, :recipient)
63
+ PACKET_TYPING_ID = 18; Typing = Struct.new(:channel)
64
+ PACKET_USERUPDATE_ID = 19; UserUpdate = Struct.new(:ban, :groups, :id)
65
+
66
+ # SERVER PACKETS
67
+ PACKET_CHANNELDELETERECEIVE_ID = 20; ChannelDeleteReceive = Struct.new(:inner)
68
+ PACKET_CHANNELRECEIVE_ID = 21; ChannelReceive = Struct.new(:inner)
69
+ PACKET_COMMANDRECEIVE_ID = 22; CommandReceive = Struct.new(:args, :author)
70
+ PACKET_GROUPDELETERECEIVE_ID = 23; GroupDeleteReceive = Struct.new(:inner)
71
+ PACKET_GROUPRECEIVE_ID = 24; GroupReceive = Struct.new(:inner, :new)
72
+ PACKET_LOGINSUCCESS_ID = 25; LoginSuccess = Struct.new(:created, :id, :token)
73
+ PACKET_MESSAGEDELETERECEIVE_ID = 26; MessageDeleteReceive = Struct.new(:id)
74
+ PACKET_MESSAGERECEIVE_ID = 27; MessageReceive = Struct.new(:inner, :new)
75
+ PACKET_PMRECEIVE_ID = 28; PMReceive = Struct.new(:author, :text)
76
+ PACKET_TYPINGRECEIVE_ID = 29; TypingReceive = Struct.new(:author, :channel)
77
+ PACKET_USERRECEIVE_ID = 30; UserReceive = Struct.new(:inner)
78
+
79
+ def self.packet_from_id(id)
80
+ case id
81
+ when PACKET_CLOSE_ID
82
+ Close
83
+ when PACKET_CHANNELCREATE_ID
84
+ ChannelCreate
85
+ when PACKET_CHANNELDELETE_ID
86
+ ChannelDelete
87
+ when PACKET_CHANNELUPDATE_ID
88
+ ChannelUpdate
89
+ when PACKET_COMMAND_ID
90
+ Command
91
+ when PACKET_GROUPCREATE_ID
92
+ GroupCreate
93
+ when PACKET_GROUPDELETE_ID
94
+ GroupDelete
95
+ when PACKET_GROUPUPDATE_ID
96
+ GroupUpdate
97
+ when PACKET_LOGIN_ID
98
+ Login
99
+ when PACKET_LOGINUPDATE_ID
100
+ LoginUpdate
101
+ when PACKET_MESSAGECREATE_ID
102
+ MessageCreate
103
+ when PACKET_MESSAGEDELETE_ID
104
+ MessageDelete
105
+ when PACKET_MESSAGEDELETEBULK_ID
106
+ MessageDeleteBulk
107
+ when PACKET_MESSAGELIST_ID
108
+ MessageList
109
+ when PACKET_MESSAGEUPDATE_ID
110
+ MessageUpdate
111
+ when PACKET_PRIVATEMESSAGE_ID
112
+ PrivateMessage
113
+ when PACKET_TYPING_ID
114
+ Typing
115
+ when PACKET_USERUPDATE_ID
116
+ UserUpdate
117
+ when PACKET_CHANNELDELETERECEIVE_ID
118
+ ChannelDeleteReceive
119
+ when PACKET_CHANNELRECEIVE_ID
120
+ ChannelReceive
121
+ when PACKET_COMMANDRECEIVE_ID
122
+ CommandReceive
123
+ when PACKET_GROUPDELETERECEIVE_ID
124
+ GroupDeleteReceive
125
+ when PACKET_GROUPRECEIVE_ID
126
+ GroupReceive
127
+ when PACKET_LOGINSUCCESS_ID
128
+ LoginSuccess
129
+ when PACKET_MESSAGEDELETERECEIVE_ID
130
+ MessageDeleteReceive
131
+ when PACKET_MESSAGERECEIVE_ID
132
+ MessageReceive
133
+ when PACKET_PMRECEIVE_ID
134
+ PMReceive
135
+ when PACKET_TYPINGRECEIVE_ID
136
+ TypingReceive
137
+ when PACKET_USERRECEIVE_ID
138
+ UserReceive
139
+ end
140
+ end
141
+ def self.packet_to_id(packet)
142
+ if packet.instance_of? Close
143
+ PACKET_CLOSE_ID
144
+ elsif packet.instance_of? ChannelCreate
145
+ PACKET_CHANNELCREATE_ID
146
+ elsif packet.instance_of? ChannelDelete
147
+ PACKET_CHANNELDELETE_ID
148
+ elsif packet.instance_of? ChannelUpdate
149
+ PACKET_CHANNELUPDATE_ID
150
+ elsif packet.instance_of? Command
151
+ PACKET_COMMAND_ID
152
+ elsif packet.instance_of? GroupCreate
153
+ PACKET_GROUPCREATE_ID
154
+ elsif packet.instance_of? GroupDelete
155
+ PACKET_GROUPDELETE_ID
156
+ elsif packet.instance_of? GroupUpdate
157
+ PACKET_GROUPUPDATE_ID
158
+ elsif packet.instance_of? Login
159
+ PACKET_LOGIN_ID
160
+ elsif packet.instance_of? LoginUpdate
161
+ PACKET_LOGINUPDATE_ID
162
+ elsif packet.instance_of? MessageCreate
163
+ PACKET_MESSAGECREATE_ID
164
+ elsif packet.instance_of? MessageDelete
165
+ PACKET_MESSAGEDELETE_ID
166
+ elsif packet.instance_of? MessageDeleteBulk
167
+ PACKET_MESSAGEDELETEBULK_ID
168
+ elsif packet.instance_of? MessageList
169
+ PACKET_MESSAGELIST_ID
170
+ elsif packet.instance_of? MessageUpdate
171
+ PACKET_MESSAGEUPDATE_ID
172
+ elsif packet.instance_of? PrivateMessage
173
+ PACKET_PRIVATEMESSAGE_ID
174
+ elsif packet.instance_of? Typing
175
+ PACKET_TYPING_ID
176
+ elsif packet.instance_of? UserUpdate
177
+ PACKET_USERUPDATE_ID
178
+ elsif packet.instance_of? ChannelDeleteReceive
179
+ PACKET_CHANNELDELETERECEIVE_ID
180
+ elsif packet.instance_of? ChannelReceive
181
+ PACKET_CHANNELRECEIVE_ID
182
+ elsif packet.instance_of? CommandReceive
183
+ PACKET_COMMANDRECEIVE_ID
184
+ elsif packet.instance_of? GroupDeleteReceive
185
+ PACKET_GROUPDELETERECEIVE_ID
186
+ elsif packet.instance_of? GroupReceive
187
+ PACKET_GROUPRECEIVE_ID
188
+ elsif packet.instance_of? LoginSuccess
189
+ PACKET_LOGINSUCCESS_ID
190
+ elsif packet.instance_of? MessageDeleteReceive
191
+ PACKET_MESSAGEDELETERECEIVE_ID
192
+ elsif packet.instance_of? MessageReceive
193
+ PACKET_MESSAGERECEIVE_ID
194
+ elsif packet.instance_of? PMReceive
195
+ PACKET_PMRECEIVE_ID
196
+ elsif packet.instance_of? TypingReceive
197
+ PACKET_TYPINGRECEIVE_ID
198
+ elsif packet.instance_of? UserReceive
199
+ PACKET_USERRECEIVE_ID
200
+ end
201
+ end
202
+ end
203
+ end
data/lib/state.rb ADDED
@@ -0,0 +1,71 @@
1
+ module Synacrb
2
+ class State
3
+ def initialize
4
+ @channels = {}
5
+ @groups = {}
6
+ @users = {}
7
+ end
8
+ def channels
9
+ @channels
10
+ end
11
+ def groups
12
+ @groups
13
+ end
14
+ def users
15
+ @users
16
+ end
17
+ def update(packet)
18
+ if packet.instance_of? Common::ChannelDeleteReceive
19
+ unless packet.inner.instance_of? Common::Channel
20
+ packet.inner = Common::Channel.new(*packet.inner)
21
+ end
22
+ @channels.delete packet.inner.id
23
+ elsif packet.instance_of? Common::ChannelReceive
24
+ unless packet.inner.instance_of? Common::Channel
25
+ packet.inner = Common::Channel.new(*packet.inner)
26
+ end
27
+ @channels[packet.inner.id] = packet.inner
28
+ elsif packet.instance_of? Common::GroupDeleteReceive
29
+ unless packet.inner.instance_of? Common::Group
30
+ packet.inner = Common::Group.new(*packet.inner)
31
+ end
32
+ for id in @groups.each_key
33
+ if @groups[id].pos > packet.inner.pos
34
+ @groups[id].pos -= 1
35
+ end
36
+ end
37
+ @groups.delete packet.inner.id
38
+ elsif packet.instance_of? Common::GroupReceive
39
+ unless packet.inner.instance_of? Common::Group
40
+ packet.inner = Common::Group.new(*packet.inner)
41
+ end
42
+ if packet.new
43
+ unless @groups[packet.inner.id].nil?
44
+ pos = @groups[packet.inner.id].pos
45
+
46
+ if packet.inner.pos > pos
47
+ for id in @groups.each_key
48
+ if @groups[id].pos > pos && @groups[id].pos <= packet.inner.pos
49
+ @groups[id].pos -= 1
50
+ end
51
+ end
52
+ elsif packet.inner.pos < pos
53
+ for group in @groups.each_key
54
+ if @groups[id].pos >= packet.inner.pos && @groups[id].pos < pos
55
+ @groups[id].pos += 1
56
+ end
57
+ end
58
+ end
59
+ else
60
+ for group in @groups.each_key
61
+ if @groups[id].pos >= packet.inner.pos
62
+ @groups[id].pos += 1
63
+ end
64
+ end
65
+ end
66
+ end
67
+ @groups[packet.inner.id] = packet.inner
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,3 @@
1
+ module Synacrb
2
+ VERSION = "0.1.0"
3
+ end
data/lib/synacrb.rb ADDED
@@ -0,0 +1,82 @@
1
+ require "state.rb"
2
+ require "packets.rb"
3
+
4
+ require "msgpack"
5
+ require "openssl"
6
+ require "socket"
7
+ require "synacrb/version"
8
+
9
+ module Synacrb
10
+ class Session
11
+ # Connect to the server
12
+ def initialize(addr, hash, &callback)
13
+ tcp = TCPSocket.new addr, 8439
14
+
15
+ @hash = hash
16
+
17
+ context = OpenSSL::SSL::SSLContext.new
18
+ if callback.nil?
19
+ callback = method(:verify_callback)
20
+ end
21
+ context.verify_callback = callback
22
+ context.verify_mode = OpenSSL::SSL::VERIFY_PEER
23
+
24
+ @stream = OpenSSL::SSL::SSLSocket.new tcp, context
25
+ @stream.connect
26
+ end
27
+ # OpenSSL verify callback used by initialize when optional callback argument isn't set.
28
+ def verify_callback(_, cert)
29
+ pem = cert.current_cert.public_key.to_pem
30
+ sha256 = OpenSSL::Digest::SHA256.new
31
+ hash = sha256.digest(pem).unpack("H*")
32
+
33
+ hash[0].casecmp(@hash).zero?
34
+ end
35
+
36
+ # Returns inner connection
37
+ def inner_stream()
38
+ @stream
39
+ end
40
+
41
+ # Sends the login packet with specific password.
42
+ # Read the result with `read`.
43
+ # Warning: Strongly disencouraged. Use tokens instead, when possible.
44
+ def login_with_password(bot, name, password)
45
+ send Common::Login.new(bot, name, password, nil)
46
+ end
47
+
48
+ # Sends the login packet with specific token.
49
+ # Read the result with `read`.
50
+ def login_with_token(bot, name, token)
51
+ send Common::Login.new(bot, name, nil, token)
52
+ end
53
+
54
+ # Transmit a packet over the connection
55
+ def send(packet)
56
+ id = Common.packet_to_id(packet)
57
+ data = [id, [packet.to_a]].to_msgpack
58
+ size1 = data.length >> 8
59
+ size2 = data.length % 256
60
+
61
+ @stream.write [size1, size2].pack("U*")
62
+ @stream.write data
63
+ end
64
+
65
+ # Read a packet from the connection
66
+ def read()
67
+ size_a = @stream.read 2
68
+ size = (size_a[0].ord << 8) + size_a[1].ord
69
+ data = @stream.read size
70
+
71
+ data = MessagePack.unpack data
72
+ class_ = Common.packet_from_id data[0]
73
+ class_.new *data[1][0]
74
+ end
75
+
76
+ # Close the connection
77
+ def close()
78
+ send(Common::Close)
79
+ @stream.close
80
+ end
81
+ end
82
+ end
data/synacrb.gemspec ADDED
@@ -0,0 +1,33 @@
1
+
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "synacrb/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "synacrb"
8
+ spec.version = Synacrb::VERSION
9
+ spec.authors = ["jD91mZM2"]
10
+ spec.email = ["me@krake.one"]
11
+
12
+ spec.summary = %q{synac library for ruby.}
13
+ spec.homepage = "https://github.com/jD91mZM2/synacrb"
14
+ spec.license = "MIT"
15
+
16
+ # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
17
+ # to allow pushing to a single host or delete this section to allow pushing to any host.
18
+ if spec.respond_to?(:metadata)
19
+ else
20
+ raise "RubyGems 2.0 or newer is required to protect against " \
21
+ "public gem pushes."
22
+ end
23
+
24
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
25
+ f.match(%r{^(test|spec|features)/})
26
+ end
27
+ spec.bindir = "exe"
28
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
29
+ spec.require_paths = ["lib"]
30
+
31
+ spec.add_development_dependency "bundler", "~> 1.16"
32
+ spec.add_development_dependency "rake", "~> 10.0"
33
+ end
metadata ADDED
@@ -0,0 +1,85 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: synacrb
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - jD91mZM2
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2017-11-23 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.16'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.16'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ description:
42
+ email:
43
+ - me@krake.one
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - ".gitignore"
49
+ - Gemfile
50
+ - Gemfile.lock
51
+ - LICENSE.txt
52
+ - README.md
53
+ - Rakefile
54
+ - bin/console
55
+ - bin/setup
56
+ - lib/packets.rb
57
+ - lib/state.rb
58
+ - lib/synacrb.rb
59
+ - lib/synacrb/version.rb
60
+ - synacrb.gemspec
61
+ homepage: https://github.com/jD91mZM2/synacrb
62
+ licenses:
63
+ - MIT
64
+ metadata: {}
65
+ post_install_message:
66
+ rdoc_options: []
67
+ require_paths:
68
+ - lib
69
+ required_ruby_version: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ version: '0'
74
+ required_rubygems_version: !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
+ requirements: []
80
+ rubyforge_project:
81
+ rubygems_version: 2.6.13
82
+ signing_key:
83
+ specification_version: 4
84
+ summary: synac library for ruby.
85
+ test_files: []