frostbitten 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.
@@ -0,0 +1,38 @@
1
+ require 'hashie'
2
+
3
+ module Frostbitten
4
+ class Map < Hashie::Trash
5
+ class << self
6
+ def maps_from_list(list,index=0)
7
+ number_of_maps = list.slice!(index).to_i
8
+ number_of_words_per_map = list.slice!(index).to_i
9
+ columns = number_of_maps*number_of_words_per_map
10
+ return [].tap do |maps|
11
+ list.slice(index,columns).each_slice(number_of_words_per_map) do |map_data|
12
+ maps << Map.new(map_data)
13
+ end
14
+ end
15
+ end
16
+ end
17
+
18
+ property :name
19
+ property :gamemode
20
+ property :round_count
21
+
22
+ def initialize(data,gamemode=nil,round_count=nil)
23
+ if data.is_a? Array
24
+ self.name = data[0]
25
+ self.gamemode = data[1]
26
+ self.round_count = data[2]
27
+ elsif data.is_a? Hash
28
+ self.name = data["name"]
29
+ self.gamemode = data["gamemode"]
30
+ self.round_count = data["round_count"]
31
+ elsif data.is_a? String
32
+ self.name = data
33
+ self.gamemode = gamemode
34
+ self.round_count = round_count
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,29 @@
1
+ module Frostbitten
2
+ module Methods
3
+ module AdminCommands
4
+ def map_list(start_index=0)
5
+ return nil unless @logged_in
6
+ return Map.maps_from_list(send(['mapList.list', "#{start_index}"]))
7
+ end
8
+
9
+ def ban_list(start_index=0)
10
+ return nil unless @logged_in
11
+ return BannedPlayer.players_from_list(send(['banList.list', "#{start_index}"]))
12
+ end
13
+
14
+ def reserved_slots_list(start_index=0)
15
+ return nil unless @logged_in
16
+ return [].tap do |players|
17
+ send(['reservedSlotsList.list', "#{start_index}"]).each do |player_name|
18
+ players << Player.new({:name => player_name})
19
+ end
20
+ end
21
+ end
22
+
23
+ def events(start=true)
24
+ return nil unless @logged_in
25
+ return send(['admin.eventsEnabled',(start ? 'true' : 'false')])
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,47 @@
1
+ require 'pp'
2
+ module Frostbitten
3
+ module Methods
4
+ # Methods not requiring admin rcon priveleges
5
+ module NormalCommands
6
+ # Authenticate connection using password or pregiven password in uri.
7
+ def auth(password=nil)
8
+ unless password
9
+ raise ArgumentError, "No password supplied" unless self.server and self.server.password
10
+ end
11
+
12
+ password = password ? password : self.server.password
13
+
14
+ data = send("login.hashed")
15
+
16
+ salt = [data.first].pack("H*")
17
+ hashed = Digest::MD5.hexdigest("#{salt}#{password}")
18
+ if send(["login.hashed", hashed.upcase])
19
+ @logged_in = true
20
+ else
21
+ @logged_in = false
22
+ end
23
+
24
+ return self
25
+ end
26
+
27
+ # Lists players and will return list of players
28
+ def players(list="all")
29
+ data = send(['listPlayers', list])
30
+ if data
31
+ return Player.players_from_list(data,0)
32
+ end
33
+ end
34
+
35
+ # General server information
36
+ def serverinfo
37
+ score_data = send("serverinfo")
38
+ score_data.insert(7,Frostbitten::Score.scores_from_list(score_data,7))
39
+ return Server.new {}.tap do |hash|
40
+ score_data.to_enum.with_index(1).each do |value,key|
41
+ hash["data#{key}"] = value
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,54 @@
1
+ require 'hashie'
2
+
3
+ module Frostbitten
4
+ # Class to repesent a player object returned by server
5
+ class Player < Hashie::Trash
6
+ class << self
7
+ def players_from_list(list,index)
8
+ key_count = list.slice!(index).to_i
9
+ keys = list.slice!(index,key_count)
10
+ player_count = list.slice!(index).to_i
11
+
12
+ return [].tap do |players|
13
+ {}.tap do |player|
14
+ if player_count > 0
15
+ list.slice!(index,player_count*key_count).each_slice(key_count) do |player_values|
16
+ player_values.each_with_index { |value,index| player[keys[index]] = value }
17
+ players << Player.new(player)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+
25
+ property :name
26
+ property :guid
27
+ property :team_id, :from => :teamId, :with => lambda { |v| v.to_i }
28
+ property :squad_id, :from => :squadId, :with => lambda { |v| v.to_i }
29
+ property :kills, :transform_with => lambda { |v| v.to_i }
30
+ property :deaths, :transform_with => lambda { |v| v.to_i }
31
+ property :score, :transform_with => lambda { |v| v.to_i }
32
+ end
33
+
34
+ class BannedPlayer < Hashie::Trash
35
+ class << self
36
+ def players_from_list(list,index)
37
+ list_count = list.slice!(index).to_i
38
+ return [].tap do |players|
39
+ list.slice!(index,list_count*5).each_slice(5) do |player_value|
40
+ p = {}
41
+ player_value.to_enum.with_index(1) { |val,index| p["data#{index}"] = val }
42
+ players << BannedPlayer.new(p)
43
+ end
44
+ end
45
+ end
46
+ end
47
+
48
+ property :type_id, :from => "data1"
49
+ property :player_id, :from => "data2"
50
+ property :type, :from => "data3"
51
+ property :time, :from => "data4"
52
+ property :reason, :from => "data5"
53
+ end
54
+ end
@@ -0,0 +1,21 @@
1
+ require 'enumerator'
2
+ module Frostbitten
3
+ class Score
4
+ attr_accessor :team_one,:team_two
5
+ class << self
6
+ def scores_from_list(list,index)
7
+ element_count = list.slice!(index).to_i
8
+ return [].tap do |scores|
9
+ list.slice!(index,element_count).each_slice(2) do |slice|
10
+ scores << Score.new(slice)
11
+ end
12
+ end
13
+ end
14
+ end
15
+
16
+ def initialize(scores)
17
+ self.team_one = scores[0].to_i
18
+ self.team_two = scores[1].to_i
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,27 @@
1
+ require 'hashie'
2
+ module Frostbitten
3
+ class Server < Hashie::Trash
4
+ property :name, :from => "data1"
5
+ property :playercount, :from => "data2"
6
+ property :playermax, :from => "data3"
7
+ property :playmode, :from => "data4"
8
+ property :map, :from => "data5"
9
+ property :played_rounds, :from => "data6"
10
+ property :total_rounds, :from => "data7"
11
+ property :scores, :from => "data8"
12
+ property :end_score, :from => "data9"
13
+ property :online_state, :from => "data10"
14
+ property :ranked, :from => "data11"
15
+ property :punkbuster, :from => "data12"
16
+ property :password, :from => "data13"
17
+ property :uptime, :from => "data14"
18
+ property :round_time, :from => "data15"
19
+ property :ip_port, :from => "data16"
20
+ property :punkbuster_version, :from => "data17"
21
+ property :join_queue_enabled, :from => "data18"
22
+ property :region, :from => "data19"
23
+ property :ping_site, :from => "data20"
24
+ property :country, :from => "data21"
25
+ property :match_making_enabled, :from => "data22"
26
+ end
27
+ end
@@ -0,0 +1,15 @@
1
+ module Frostbitten
2
+ module Version
3
+ MAJOR = 0
4
+ MINOR = 1
5
+ PATCH = 0
6
+ BUILD = nil
7
+
8
+ STRING = [MAJOR, MINOR, PATCH, BUILD].compact.join('.')
9
+ def self.string
10
+ "Frostbitten version #{Frostbitten::Version::STRING}"
11
+ end
12
+ end
13
+
14
+
15
+ end
@@ -0,0 +1,8 @@
1
+ require 'spec_helper'
2
+ require 'frostbitten'
3
+
4
+ describe Frostbitten do
5
+ it 'should return correct version string' do
6
+ Frostbitten::Version.string.should == "Frostbitten version #{Frostbitten::Version::STRING}"
7
+ end
8
+ end
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+ require 'frostbitten'
3
+
4
+ describe Frostbitten::Client do
5
+ it { should respond_to(:send) }
6
+ it { should respond_to(:server)}
7
+ it { should respond_to(:server=)}
8
+
9
+ it 'should update server upon server=' do
10
+ server = double("Frostbitten::Server")
11
+ client = Frostbitten::Client.new
12
+ expect { client.server = server}.to change{client.server}.from(nil).to(server)
13
+ end
14
+ end
@@ -0,0 +1,48 @@
1
+ require 'spec_helper'
2
+ require 'frostbitten'
3
+ RCON_PORT = 11000
4
+ RCON_IP = "192.168.1.102"
5
+ RCON_PASSWORD = nil
6
+ RCON_PWD = ""
7
+ RCON_PWD = "@#{RCON_PASSWORD}" if RCON_PASSWORD
8
+ RCON_URI = "fbrcon://#{RCON_PWD}#{RCON_IP}:#{RCON_PORT}"
9
+
10
+ describe Frostbitten::Server do
11
+ it 'should parse a fbrcon uri' do
12
+ server = Frostbitten::Server.new(RCON_URI)
13
+ server.hostname.should == RCON_IP
14
+ server.port.should == RCON_PORT
15
+ server.password.should == RCON_PASSWORD ? RCON_PASSWORD : nil
16
+ server.sequence.should == 0
17
+
18
+ server = Frostbitten::Server.new("fbrcon://moo@127.0.0.1")
19
+ server.port.should == 47200
20
+ end
21
+
22
+ it 'should parse a fbrcon uri with options' do
23
+ server = Frostbitten::Server.new(RCON_URI, {:sequence => 30})
24
+ server.sequence.should == 30
25
+ end
26
+
27
+ it 'should return false on alive? since we havent connected' do
28
+ server = Frostbitten::Server.new(RCON_URI)
29
+ server.alive?.should == false
30
+ end
31
+
32
+ it 'should respond to connect' do
33
+ server = Frostbitten::Server.new(RCON_URI)
34
+ expect { server.connect }.to_not raise_error(NoMethodError)
35
+ end
36
+
37
+ it 'should return true on alive?' do
38
+ server = Frostbitten::Server.new(RCON_URI)
39
+ server.connect
40
+ server.alive?.should == true
41
+ end
42
+
43
+ it 'should respond to close' do
44
+ server = Frostbitten::Server.new(RCON_URI)
45
+ server.connect
46
+ expect { server.close }.to_not raise_error(NoMethodError)
47
+ end
48
+ end
@@ -0,0 +1,7 @@
1
+ require 'rspec'
2
+ require 'frostbitten'
3
+
4
+ RSpec.configure do |config|
5
+ config.color_enabled = true
6
+ config.formatter = 'documentation'
7
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,15 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
10
+ require 'test/unit'
11
+ require 'shoulda'
12
+
13
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
14
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
15
+ require 'frostbitten'
@@ -0,0 +1,7 @@
1
+ require 'helper'
2
+
3
+ class TestFrostbitten < Test::Unit::TestCase
4
+ should "probably rename this file and start testing for real" do
5
+ flunk "hey buddy, you should probably rename this file and start testing for real"
6
+ end
7
+ end
metadata ADDED
@@ -0,0 +1,252 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: frostbitten
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Emil Palm
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-02-22 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: hashie
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: shoulda
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: rdoc
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: '3.12'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '3.12'
62
+ - !ruby/object:Gem::Dependency
63
+ name: bundler
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: jeweler
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ~>
84
+ - !ruby/object:Gem::Version
85
+ version: 1.8.4
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ~>
92
+ - !ruby/object:Gem::Version
93
+ version: 1.8.4
94
+ - !ruby/object:Gem::Dependency
95
+ name: rspec
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ - !ruby/object:Gem::Dependency
111
+ name: rb-fsevent
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ! '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ! '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ - !ruby/object:Gem::Dependency
127
+ name: guard-rspec
128
+ requirement: !ruby/object:Gem::Requirement
129
+ none: false
130
+ requirements:
131
+ - - ! '>='
132
+ - !ruby/object:Gem::Version
133
+ version: '0'
134
+ type: :development
135
+ prerelease: false
136
+ version_requirements: !ruby/object:Gem::Requirement
137
+ none: false
138
+ requirements:
139
+ - - ! '>='
140
+ - !ruby/object:Gem::Version
141
+ version: '0'
142
+ - !ruby/object:Gem::Dependency
143
+ name: terminal-notifier-guard
144
+ requirement: !ruby/object:Gem::Requirement
145
+ none: false
146
+ requirements:
147
+ - - ! '>='
148
+ - !ruby/object:Gem::Version
149
+ version: '0'
150
+ type: :development
151
+ prerelease: false
152
+ version_requirements: !ruby/object:Gem::Requirement
153
+ none: false
154
+ requirements:
155
+ - - ! '>='
156
+ - !ruby/object:Gem::Version
157
+ version: '0'
158
+ - !ruby/object:Gem::Dependency
159
+ name: rake-compiler
160
+ requirement: !ruby/object:Gem::Requirement
161
+ none: false
162
+ requirements:
163
+ - - ! '>='
164
+ - !ruby/object:Gem::Version
165
+ version: '0'
166
+ type: :development
167
+ prerelease: false
168
+ version_requirements: !ruby/object:Gem::Requirement
169
+ none: false
170
+ requirements:
171
+ - - ! '>='
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ description: Gem that provides RCON commands for frostbite 2 engine games. BF3, BFBC2
175
+ and so on
176
+ email: emil.palm@x86.nu
177
+ executables: []
178
+ extensions:
179
+ - ext/frostbitten/extconf.rb
180
+ extra_rdoc_files:
181
+ - LICENSE.txt
182
+ - README.rdoc
183
+ files:
184
+ - .document
185
+ - Gemfile
186
+ - Gemfile.lock
187
+ - Guardfile
188
+ - LICENSE.txt
189
+ - README.rdoc
190
+ - Rakefile
191
+ - VERSION
192
+ - ext/.DS_Store
193
+ - ext/frostbitten/.DS_Store
194
+ - ext/frostbitten/Makefile
195
+ - ext/frostbitten/extconf.rb
196
+ - ext/frostbitten/frostbitten.h
197
+ - ext/frostbitten/header.c
198
+ - ext/frostbitten/header.h
199
+ - ext/frostbitten/message.c
200
+ - ext/frostbitten/message.h
201
+ - ext/frostbitten/native.c
202
+ - ext/frostbitten/packet.c
203
+ - ext/frostbitten/packet.h
204
+ - ext/frostbitten/word.c
205
+ - ext/frostbitten/word.h
206
+ - frostbitten.gemspec
207
+ - lib/frostbitten.rb
208
+ - lib/frostbitten/client.rb
209
+ - lib/frostbitten/connection.rb
210
+ - lib/frostbitten/map.rb
211
+ - lib/frostbitten/methods/admin.rb
212
+ - lib/frostbitten/methods/normal.rb
213
+ - lib/frostbitten/player.rb
214
+ - lib/frostbitten/score.rb
215
+ - lib/frostbitten/server.rb
216
+ - lib/frostbitten/version.rb
217
+ - spec/frostbitten_spec.rb
218
+ - spec/lib/frostbitten_client_spec.rb
219
+ - spec/lib/frostbitten_server_spec.rb
220
+ - spec/spec_helper.rb
221
+ - test/helper.rb
222
+ - test/test_frostbitten.rb
223
+ homepage: http://github.com/mrevilme/frostbitten
224
+ licenses:
225
+ - MIT
226
+ post_install_message:
227
+ rdoc_options: []
228
+ require_paths:
229
+ - lib
230
+ required_ruby_version: !ruby/object:Gem::Requirement
231
+ none: false
232
+ requirements:
233
+ - - ! '>='
234
+ - !ruby/object:Gem::Version
235
+ version: '0'
236
+ segments:
237
+ - 0
238
+ hash: -4588266518836475296
239
+ required_rubygems_version: !ruby/object:Gem::Requirement
240
+ none: false
241
+ requirements:
242
+ - - ! '>='
243
+ - !ruby/object:Gem::Version
244
+ version: '0'
245
+ requirements: []
246
+ rubyforge_project:
247
+ rubygems_version: 1.8.24
248
+ signing_key:
249
+ specification_version: 3
250
+ summary: Gem that provides RCON commands for frostbite 2 engine games. BF3, BFBC2
251
+ and so on
252
+ test_files: []