sdtd_server 0.0.2 → 1.0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 525d890e97e4cfdc804886a29236c93ec4312417
4
- data.tar.gz: b8144d718c6a66f41b32bcfc497a173b67e19cf6
3
+ metadata.gz: f175e56b9473cae25374d4205f2d5aab510f597a
4
+ data.tar.gz: dad285222e10084651fe1c3df49c42038433f0a7
5
5
  SHA512:
6
- metadata.gz: 081649d03cf533e9668c89af5c423b8c9161df763f1ed7cf7b6bab79c16eb32e926f714107ef02c16fca9cef062ea4c88c7f6cd9faf44a82ed52d0290521665e
7
- data.tar.gz: 12342270ed6029f0bcb0ed0cb517a486290971b353a5650b49f7f6e3ef14c6d215837e80060e2dc7d8c7a38ae6ec9415ee10fdd19f3507cc8bc2b861629ba1b5
6
+ metadata.gz: c7b4e6417c0d02755441bbe725e0a836a0544d3596f89d0b6fed11be547e2314b021a501f203a5aa820347b4af1912b1481f2c77453171dd928b42a047a1688f
7
+ data.tar.gz: d235edb8abdf6497e14f089c694af7c872239edb3e0fe32fd3059df4de51e66a154b4350aff1038ac983952c4740e743ae8d89b27c7aa931f05cdade003b6cda
checksums.yaml.gz.sig ADDED
@@ -0,0 +1 @@
1
+ JhO�b9��tG���:쩬X�<��02kX� �<�fk
data.tar.gz.sig ADDED
@@ -0,0 +1 @@
1
+ �tX;E)��I����B��7�I�al�2��5Ζ�!����,��A $�gNi��~���!]�;߉{_��8�Z\]tW� ���R�Q/�.J~��*X��s7:V���w&�&����?ʹ >ϙW�d\y��1��-Oj�._���� ]��맇�t�C �3P�om 驏�N�h�ƹ���w���ur�J��{�FuzcY��d��6x��q��Ny}ӧ����u>��g+���{��%?x��񜌓m
data/lib/sdtd_server.rb CHANGED
@@ -4,35 +4,291 @@ class SDTD_Server
4
4
  #
5
5
  attr_reader :server, :port, :connected
6
6
  #
7
+ def whitelist
8
+ placeholder
9
+ end
7
10
  #
11
+ def admin
12
+ placeholder
13
+ end
8
14
  #
15
+ def commandpermission
16
+ placeholder
17
+ end
9
18
  #
19
+ def cp
20
+ commandpermission
21
+ end
10
22
  #
23
+ def weathersurvival(correct_state = nil)
24
+ raise InvalidFunctionInputError unless ['on', 'off', nil].include? correct_state
25
+
26
+ command = correct_state == nil ? 'weathersurvival' : "weathersurvival #{correct_state}"
27
+
28
+ console_output = telnet_command command, /Weather survival/, /Weather survival is (on|off)/
29
+
30
+ return correct_state == nil ? console_output.first : nil
31
+ end
11
32
  #
33
+ def spawnwanderinghorde
34
+ # I don't think this really does anything...
35
+ telnet_command 'spawnwanderinghorde'
36
+ return nil
37
+ end
38
+ #
39
+ def spawnentity(player_id, ent_id)
40
+ spawn_results = telnet_command "spawnentity #{player_id.to_s} #{ent_id.to_s}", /^No spawn point|^Spawned|^Player with|Entity/
41
+
42
+ return nil if spawn_results.include? 'Spawned'
43
+
44
+ if spawn_results.include? 'No spawn point'
45
+ raise NoSpawnPointError
46
+ elsif spawn_results.include? 'Player with id'
47
+ raise InvalidSpawnUserError
48
+ elsif spawn_results.include? 'Entity'
49
+ raise InvalidEntIDError
50
+ else
51
+ # This should never happen as telnet will raise a timeout error...
52
+ raise UnexpectedResultsError
53
+ end
54
+ end
55
+ #
56
+ def se(player_id, ent_id)
57
+ spawnentity player_id, ent_id
58
+ end
59
+ #
60
+ def spawnairdrop
61
+ telnet_command 'spawnairdrop'
62
+ return nil
63
+ end
64
+ #
65
+ def loggamestate(message)
66
+ telnet_command "loggamestate \"#{message}\"", /Wrote game state/
67
+ return nil
68
+ end
69
+ #
70
+ def lgs(message)
71
+ loggamestate message
72
+ end
73
+ #
74
+ def listplayers
75
+ # Regex Exampple: http://regexr.com/3cgoe
76
+ begin
77
+ player_list_output = telnet_command 'listplayers', /in the game/, /\d+\.\sid=(\d+),\s([^,]+), pos=\(([^\)]+)\), rot=\(([^\)]+)\), remote=(True|False), health=(\d+), deaths=(\d+), zombies=(\d+), players=(\d+), score=(\d+), level=(\d+), steamid=(\d+), ip=([^,]+), ping=(\d+)/
78
+ rescue NoMethodError
79
+ return {}
80
+ end
81
+
82
+ player_data = Hash.new
83
+
84
+ player_keys = [
85
+ 'name', 'position', 'rotation',
86
+ 'is_remote', 'health', 'deaths',
87
+ 'zombies', 'players', 'score',
88
+ 'level', 'steamid', 'ip',
89
+ 'ping']
90
+
91
+ player_list_output.each do |player|
92
+
93
+ player_id = player.shift
94
+ player_data[player_id] = Hash.new
95
+
96
+ player_keys.each do |key|
97
+ player_data[player_id][key.to_sym] = player.shift
98
+ end
99
+ end
100
+
101
+ return player_data
102
+ end
103
+ #
104
+ def lp
105
+ listplayers
106
+ end
12
107
  #
108
+ def listents
109
+ # Regex Example: http://regexr.com/3cgok
110
+ listents_results = telnet_command 'listents', /in the game/, /\d\. id=(\d+), \[type=(\w+), name=(\w+), id=\d+\], pos=\(([^\)]+)\), rot=\(([^\)]+)\), lifetime=([^,]+), remote=(True|False), dead=(True|False), health=(\d+)/
111
+
112
+ ent_keys = [
113
+ 'type', 'name', 'position',
114
+ 'rotation', 'lifetime', 'remote',
115
+ 'dead', 'health']
116
+
117
+ ents = Hash.new
118
+
119
+ listents_results.each do |ent|
120
+
121
+ ent_id = ent.shift.to_sym
122
+ ents[ent_id] = Hash.new
123
+
124
+ ent_keys.each do |key|
125
+ ents[ent_id][key.to_sym] = ent.shift
126
+ end
127
+ end
128
+
129
+ return ents
130
+ end
131
+ #
132
+ def le
133
+ listents
134
+ end
135
+ #
136
+ def listgameobjects
137
+ return telnet_command('listgameobjects', /took/, /GOs: (\d+),/).first
138
+ end
139
+ #
140
+ def lgo
141
+ listgameobjects
142
+ end
143
+ #
144
+ def killall
145
+ telnet_command 'killall'
146
+ return nil
147
+ end
148
+ #
149
+ def kill(ent_id)
150
+ kill_results = telnet_command "kill #{ent_id.to_s}", /not found\.|damage to entity/
151
+
152
+ raise InvalidEntIDError unless kill_results.include? 'damage to'
153
+
154
+ return nil
155
+ end
156
+ #
157
+ def kick(user, reason=nil)
158
+ user = user.to_s
159
+
160
+ kick_command = reason == nil ? "kick #{user}" : "kick #{user} \"#{reason}\""
161
+ kick_results = telnet_command kick_command, /not a valid|Kicking/
162
+
163
+ raise InvalidUserError unless kick_results.include? 'Kicking'
164
+ return nil
165
+ end
166
+ #
167
+ def ban(subcommand, user_id=nil, time=nil, units=nil, reason=nil)
168
+ case subcommand
169
+ when 'list'
170
+ return ban_list
171
+ when 'remove'
172
+ raise MissingCommandOptionError unless user_id
173
+ return ban_remove user_id
174
+ when 'add'
175
+ raise MissingCommandOptionError unless user_id and time and units
176
+ return ban_add user_id, time, units, reason
177
+ else
178
+ raise UnknownBanSubCommandError
179
+ end
180
+
181
+ return nil
182
+ end
183
+ #
184
+ def getgamepref(pref_name=nil)
185
+ return get_all_game_prefs unless pref_name
186
+
187
+ gamepref = telnet_command "getgamepref #{pref_name}", /GamePref\./, /GamePref\.[^=]+=\s+(.*)/
188
+ gamepref = gamepref.first
189
+
190
+ return gamepref.first
191
+ end
13
192
  #
193
+ def gg(pref_name=nil)
194
+ getgamepref pref_name
195
+ end
14
196
  #
197
+ def version
198
+ # Regex example: http://regexr.com/3cgo5
199
+ version_output = telnet_command 'version', /version/, /Game version:\s+(.+)Compatibility Version:\s+(.+)$/
200
+ version_output = version_output.first
201
+
202
+ return {:version => version_output.first, :compatibility_version => version_output.last}
203
+ end
15
204
  #
205
+ def shutdown
206
+ kickall 'The server is shutting down soon...'
207
+ telnet_command 'shutdown'
208
+ return nil
209
+ end
16
210
  #
211
+ def say(message)
212
+ telnet_command "say \"#{message}\""
213
+ return nil
214
+ end
17
215
  #
216
+ def kickall(reason="Everyone has been kicked from the server.")
217
+ telnet_command "kickall \"#{reason}\""
218
+ return nil
219
+ end
18
220
  #
221
+ def setgamepref(pref_name, new_value)
222
+ set_game_pref_output = telnet_command "setgamepref #{pref_name} #{new_value}", /set|Error parsing parameter/
223
+
224
+ raise UnknownGamePrefError if set_game_pref_output.include? 'Error parsing parameter'
225
+
226
+ return nil
227
+ end
19
228
  #
229
+ def sg(pref_name, new_value)
230
+ setgamepref pref_name, new_value
231
+ end
20
232
  #
233
+ def settime(params = {})
234
+ # TODO: Add the ability to accept only 1 or 3 inputs to the function, just like the console command.
235
+ day = params.fetch(:day, '1')
236
+ hour = params.fetch(:hour, '08')
237
+ minute = params.fetch(:minute, '00')
238
+
239
+ telnet_command "settime #{day} #{hour} #{minute}", /Set time to/
240
+ end
21
241
  #
242
+ def st(params = {})
243
+ settime params
244
+ end
22
245
  #
246
+ def gettime
247
+ get_time_results = telnet_command 'gettime', /Day/, /Day\s+(\d+),\s+(\d+):(\d+)/
248
+ get_time_results = get_time_results.first
249
+
250
+ return {:day => get_time_results.shift, :hour => get_time_results.shift, :minute => get_time_results.shift}
251
+ end
23
252
  #
253
+ def gt
254
+ gettime
255
+ end
24
256
  #
257
+ def saveworld
258
+ telnet_command 'saveworld', /World saved/
259
+ return nil
260
+ end
25
261
  #
262
+ def sa
263
+ saveworld
264
+ end
26
265
  #
266
+ def mem
267
+ # Regex extract example: http://regexr.com/3cglt
268
+ mem_results = telnet_command 'mem', /Time:/, /Time:\s+([^\s]+)\s+FPS:\s+([\d\.]+)\s+Heap:\s+([^\s]+)\s+Max:\s+([^\s]+)\s+Chunks:\s+(\d+)\s+CGO:\s+(\d+)\s+Ply:\s+(\d+)\s+Zom:\s+(\d+)\s+Ent:\s+([^\)]+\))\s+Items:\s+(\d+)\s+CO:\s+(\d+)/
269
+ mem_results = mem_results.first
270
+
271
+ keys = [
272
+ 'time', 'fps', 'heap',
273
+ 'max', 'chunks', 'cgo',
274
+ 'ply', 'zom', 'ent',
275
+ 'items', 'co'
276
+ ]
277
+
278
+ result_hash = Hash.new
279
+
280
+ keys.each { |key| result_hash[key]=mem_results.shift }
281
+
282
+ return result_hash
283
+ end
27
284
  #
28
- def get_active_players
285
+ def listplayerids
29
286
  console_output = telnet_command 'listplayerids', /Total of/
30
287
 
31
288
  players = Hash.new
32
289
 
33
290
  console_output.scan( /\d+\.\s+id=(\d+),\s+(.+)/ ).each do |current_player|
34
- puts current_player
35
- user_id = current_player[0]
291
+ user_id = current_player[0].to_sym
36
292
  user_name = current_player[1]
37
293
 
38
294
  players[user_id] = user_name
@@ -41,9 +297,8 @@ class SDTD_Server
41
297
  return players
42
298
  end
43
299
  #
44
- def save_world
45
- telnet_command 'saveworld', /World saved/
46
- return nil
300
+ def lpi
301
+ listplayerids
47
302
  end
48
303
  #
49
304
  def close
@@ -51,19 +306,92 @@ class SDTD_Server
51
306
  end
52
307
  #
53
308
  private
54
- def get_game_prefrence(preference_name)
55
- return telnet_command("getgamepref #{preference_name}", /\s+=/, /=\s*(.*)$/).first
309
+ def ban_add(user_id, time, units, reason)
310
+ ban_add_command = "ban add #{user_id} #{time} #{units}"
311
+ ban_add_command += " \"#{reason}\"" unless reason == nil
312
+
313
+ ban_add_results = telnet_command ban_add_command, /banned|not a valid entity id|valid integer|duration unit/
314
+
315
+ return nil if ban_add_results.include? 'banned'
316
+
317
+ if ban_add_results.include? 'not a valid entity id'
318
+ raise InvalidUserError
319
+ elsif ban_add_results.include? 'valid integer'
320
+ raise InvalidBanTimeError
321
+ elsif ban_add_results.include? 'duration unit'
322
+ raise InvalidBanUnitError
323
+ else
324
+ raise UnexpectedResultsError
325
+ end
326
+
327
+ return nil
56
328
  end
57
329
  #
58
- def telnet_command(string, match, extract=nil)
59
- command_results = @connection.cmd('String' => string, 'Match' => match)
60
- return command_results unless extract
61
- return command_results.match(extract).captures
330
+ def ban_remove(steam_id)
331
+ remove_results = telnet_command "ban remove #{steam_id}", /not a valid steam id\.|removed/
332
+
333
+ return nil if remove_results.include? 'removed from'
334
+
335
+ if remove_results.include? 'is not a valid steam id.'
336
+ raise InvalidUserError
337
+ end
338
+
339
+ return nil
340
+ end
341
+ #
342
+ def ban_list
343
+ # Regex Example: http://regexr.com/3cgp3
344
+ ban_data = telnet_command 'ban list', /-/, /\s([\d\/]{8,10})\s([\d:]+\s(?:AM|PM))\s-\s(\d+)\s-\s?(.*)/
345
+
346
+ return {} unless ban_data.length > 0
347
+
348
+ ban_keys = ['expire_date', 'expire_time', 'reason']
349
+
350
+ bans = Hash.new
351
+
352
+ ban_data.each do |this_ban|
353
+ player_id = this_ban.delete_at 2
354
+
355
+ bans[player_id] = Hash.new
356
+
357
+ ban_keys.each { |key| bans[player_id][key.to_sym] = this_ban.shift }
358
+ end
359
+
360
+ return bans
361
+ end
362
+ #
363
+ def get_all_game_prefs
364
+ game_pref_results = telnet_command('getgamepref', /^GamePref\.ZombiesRun/).split "\n"
365
+
366
+ game_prefs = Hash.new
367
+
368
+ game_pref_data = game_pref_results.select{ |x| x if x.include? 'GamePref.' }.map do |current_pref|
369
+ extracted_pref_data = current_pref.match( /^GamePref\.([^\s]+)\s+=\s+(.*)/ ).captures
370
+
371
+ key = extracted_pref_data.first.to_sym
372
+ value = extracted_pref_data.last
373
+
374
+ game_prefs[key] = value
375
+ end
376
+
377
+ return game_prefs
378
+ end
379
+ #
380
+ def loglevel(level, state)
381
+ level.upcase!
382
+
383
+ valid_log_levels = [
384
+ 'INF', 'WRN', 'ERR',
385
+ 'EXC', 'ALL']
386
+
387
+ raise InvalidConsoleLogLevelError unless valid_log_levels.include? level and [true, false].include? state
388
+
389
+ results = telnet_command "loglevel #{level} #{state}", /on this connection\./
62
390
  end
63
391
  #
64
392
  def console_login
65
393
  login_response = telnet_command @password, /Logon successful.|Password incorrect/
66
- raise InvalidConsolePasswordError unless login_response.include? 'ogon successful.'
394
+ raise InvalidConsolePasswordError unless login_response.include? 'Logon successful.'
67
395
  @connected = true
68
396
  end
69
397
  #
@@ -72,6 +400,12 @@ class SDTD_Server
72
400
  @connection.close
73
401
  end
74
402
  #
403
+ def telnet_command(string, match=/.*/, extract=nil)
404
+ command_results = @connection.cmd('String' => string, 'Match' => match)
405
+ return command_results unless extract
406
+ return command_results.scan(extract)
407
+ end
408
+ #
75
409
  def initialize(params = {})
76
410
  #
77
411
  @server = params.fetch(:server, 'localhost')
@@ -81,8 +415,25 @@ class SDTD_Server
81
415
  @connected = false
82
416
  #
83
417
  console_login
418
+ loglevel 'ALL', false
84
419
  #
85
420
  end
421
+ #
422
+ def placeholder
423
+ puts "This function has not been added yet."
424
+ end
86
425
  end
87
426
 
427
+ class InvalidBanTimeError < StandardError ; end
428
+ class InvalidBanUnitError < StandardError ; end
429
+ class InvalidConsoleLogLevelError < StandardError ; end
88
430
  class InvalidConsolePasswordError < StandardError ; end
431
+ class InvalidEntIDError < StandardError ; end
432
+ class InvalidFunctionInputError < StandardError ; end
433
+ class InvalidSpawnUserError < StandardError ; end
434
+ class InvalidUserError < StandardError ; end
435
+ class MissingCommandOptionError < StandardError ; end
436
+ class NoSpawnPointError < StandardError ; end
437
+ class UnexpectedResultsError < StandardError ; end
438
+ class UnknownBanSubCommandError < StandardError ; end
439
+ class UnknownGamePrefError < StandardError ; end
metadata CHANGED
@@ -1,13 +1,35 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sdtd_server
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brandon Ingalls
8
8
  autorequire:
9
9
  bindir: bin
10
- cert_chain: []
10
+ cert_chain:
11
+ - |
12
+ -----BEGIN CERTIFICATE-----
13
+ MIIDcDCCAligAwIBAgIBATANBgkqhkiG9w0BAQUFADA/MRAwDgYDVQQDDAdCcmFu
14
+ ZG9uMRcwFQYKCZImiZPyLGQBGRYHSW5nYWxsczESMBAGCgmSJomT8ixkARkWAmlv
15
+ MB4XDTE2MDEwMjE4MzUzOVoXDTE3MDEwMTE4MzUzOVowPzEQMA4GA1UEAwwHQnJh
16
+ bmRvbjEXMBUGCgmSJomT8ixkARkWB0luZ2FsbHMxEjAQBgoJkiaJk/IsZAEZFgJp
17
+ bzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMy0P0OGJn4AuDKuJwKB
18
+ dWpbJ1C7Q0ZOquxRYLCKuo/fPbVL1EojMeL6kw5TY29t3IusYVfZiu7kbiICnMd+
19
+ pHbNt0HVsARKSeF0gTx+z+m6ktmYkGWiMvyTJMcIU+y1EK8HSP1eXeN7IedBmMRm
20
+ FgXKdhrfVX31lZ2Q+YtamoZ/7GchjtOBwuDnycWuttncn1tZggSTNZP+OH440NK3
21
+ F7r4cxBxClIMxC+v4oZ2SypLjMzhGMa29Fpg0wJPVERYwazinL2QrgQbEZgiPDTl
22
+ x8QvebcrDSFosLvCxsxrWXmG/SoODMf/ufcRqKA5DiqSYgHSy/45jeXpD5hYqUlY
23
+ HykCAwEAAaN3MHUwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAwHQYDVR0OBBYEFL0t
24
+ eOFrJv48CSnVLy9CuYDRDmwhMB0GA1UdEQQWMBSBEkJyYW5kb25ASW5nYWxscy5p
25
+ bzAdBgNVHRIEFjAUgRJCcmFuZG9uQEluZ2FsbHMuaW8wDQYJKoZIhvcNAQEFBQAD
26
+ ggEBADd68w1Xk7P/wquW6kPgLHCtBqzKLtiTKyyAceUQUqBmiTHFEqIP+TuNPDuE
27
+ C+tRWh5qho+L2O/WlvcDlMRVPN2nlUtelUNR8w8N54wuMG8A5P33vIUG2/xrqm+N
28
+ yPbfVFGt1re3xF3W1ViyrTYj3vm1WrdZKC4ew2n8Gpb3hFQ3APpUVhVwj1VjTuCG
29
+ b/Qok1+A0nJMp1CodEJsUnAgsocKwTJBMGWeyCTx5aSd7r5v2Sg+GhqA+61Y/gJ6
30
+ YZ86vkdIIgE6zZs7TY31c/94emgOeD3KS2OsQwL7MI9aYXt1J+Gb8mVkziM/xh8P
31
+ j4OFWZyCTGfJ/8AlsVn9S9Mfo6M=
32
+ -----END CERTIFICATE-----
11
33
  date: 2016-01-02 00:00:00.000000000 Z
12
34
  dependencies: []
13
35
  description: A gem to interface with a 7 days to die dedicated server with the telnet
metadata.gz.sig ADDED
@@ -0,0 +1,3 @@
1
+ ~N}>�>��7գ�*(��h��*�=R@��K�b(D���/X���n�
2
+ �:u��@�6�h�NY�x\�r=�T�
3
+ M���A9�r�'3m[���>�դt�>Tw�s��~�x?P!�