frostbitten 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: []