arkrb 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,4 @@
1
+ #!/usr/bin/env ruby
2
+ require 'arkrb/cli'
3
+
4
+ Arkrb::CLI.start
@@ -0,0 +1,44 @@
1
+ require 'arkrb/version'
2
+ require 'arkrb/constants'
3
+ require 'arkrb/error_parsing'
4
+ require 'arkrb/output_parsing'
5
+ require 'open3'
6
+
7
+ module Arkrb
8
+
9
+ # @return [Arkrb::Install]
10
+ def self.install
11
+ Arkrb::Install.new
12
+ end
13
+
14
+ # @return [String]
15
+ def self.executable(path = "#{USER_HOME}/bin")
16
+ arkmanager_exec = find_executable('arkmanager', path)
17
+ raise Arkrb::Error::ArkManagerExecutableNotFound, 'We could not find the ark_rb binary! Please install it by running Arkrb.install.server_tools or executing the command `ark_rb install tools``' if arkmanager_exec.nil?
18
+ arkmanager_exec
19
+ end
20
+
21
+ # @return [Integer, String]
22
+ def self.execute(command, command_opts = '', instance = 'main', sanitize = false)
23
+ exec_this = format('%s %s %s @%s', executable, command.to_s.tr('_', ''), command_opts, instance)
24
+ stdin, stdout, stderr = Open3.popen3(exec_this)
25
+ output = stdout.read.chomp
26
+ errors = stderr.read.chomp
27
+ errors += 'Your ARK server exec could not be found.' if output =~ /#{'ARK server exec could not be found'}/im
28
+
29
+ Arkrb::ErrorParsing.new.sanitize!(command, errors) unless errors.strip.empty?
30
+
31
+ # todo: Remove the sanatize equals true line below.
32
+ sanitize = true
33
+
34
+ if sanitize
35
+ output_parsing = Arkrb::OutputParsing.new
36
+ pp output_parsing.sanitize!(command, output)
37
+ else
38
+ puts output
39
+ puts errors
40
+ end
41
+
42
+ end
43
+
44
+ end
@@ -0,0 +1,149 @@
1
+ require 'thor'
2
+ require 'colorize'
3
+ require 'arkrb/constants'
4
+ require 'arkrb/install'
5
+ module Arkrb
6
+ class CLI < Thor
7
+
8
+ package_name 'arkrb'
9
+ class_option :instance, type: :string, default: 'main', aliases: '-i'
10
+
11
+ desc "install APP_NAME", "install one of the available apps" # [4]
12
+ method_option :list, type: :boolean, aliases: '-l'
13
+
14
+ def install(name = nil)
15
+ if options[:list] || name.nil?
16
+ arkmanager_status = (find_executable('arkmanager').nil?) ? 'Not Installed'.red : 'Installed'.green
17
+ ark_install_status = (ark_installed?(options[:instance])) ? 'Installed'.green : 'Not Installed'.red
18
+ # arkmanager_status = 'Not Installed'.red
19
+ printf format("%-20s Status %21s\n", 'APP_NAME', 'Description')
20
+ print_status('ark_manager', arkmanager_status, 'Installs ark-server-tools; Install with: ark_rb install tools')
21
+ print_status('ark_server', ark_install_status, 'Installs the ark server; Install with: ark_rb install ark')
22
+ end
23
+ unless name.nil?
24
+ case name.to_sym
25
+ when :arkmanager, :ark_manager, :tools
26
+ Arkrb.install.server_tools
27
+ when :ark
28
+ Arkrb.install.ark(options[:instance], false)
29
+ else
30
+ # do nothing
31
+ end
32
+ end
33
+ end
34
+
35
+ desc 'start', 'Starts the ark server'
36
+
37
+ def start
38
+ ark_server(options[:instance]).start!
39
+ end
40
+
41
+ desc 'stop', 'Stops the ark server'
42
+
43
+ def stop
44
+ ark_server(options[:instance]).stop!
45
+ end
46
+
47
+ desc 'restart', 'Restarts the ark server'
48
+
49
+ def restart
50
+ ark_server(options[:instance]).restart!
51
+ end
52
+
53
+ desc 'status', 'Displays the status of the server'
54
+
55
+ def status
56
+ ark_server(options[:instance]).status!
57
+ end
58
+
59
+ desc 'update', 'Updates the ark server'
60
+
61
+ def update
62
+ ark_server(options[:instance]).update!
63
+ end
64
+
65
+ desc 'backup', 'Backups the ark server'
66
+
67
+ def backup
68
+ ark_server(options[:instance]).backup!
69
+ end
70
+
71
+ desc 'saveworld', 'Saves the ark world'
72
+
73
+ def saveworld
74
+ ark_server(options[:instance]).save_world!
75
+ end
76
+
77
+ desc 'enablemod MOD_ID', 'Enables a mod via mod ID'
78
+
79
+ def enablemod(mod_id)
80
+ ark_server(options[:instance]).enable_mod mod_id
81
+ end
82
+
83
+ desc 'disablemod MOD_ID', 'Disables a mod via mod ID'
84
+
85
+ def disablemod(mod_id)
86
+ ark_server(options[:instance]).disable_mod mod_id
87
+ end
88
+
89
+ desc 'installmod MOD_ID', 'Installs a mod via mod ID'
90
+
91
+ def installmod(mod_id)
92
+ ark_server(options[:instance]).install_mod mod_id
93
+ end
94
+
95
+ desc 'uninstallmod MOD_ID', 'Uninstalls the mod via mod ID'
96
+
97
+ def uninstallmod(mod_id)
98
+ ark_server(options[:instance]).uninstall_mod mod_id
99
+ end
100
+
101
+ desc 'reinstallmod MOD_ID', 'Reinstalls the mod via mod ID'
102
+
103
+ def reinstallmod(mod_id)
104
+ ark_server(options[:instance]).reinstall_mod mod_id
105
+ end
106
+
107
+ desc 'broadcast MESSAGE', 'Broadcasts a message to the server. Make sure to put it in parentheses.'
108
+
109
+ def broadcast(message)
110
+ ark_server(options[:instance]).broadcast message
111
+ end
112
+
113
+ desc 'rcon COMMAND', 'Runs an rcon command on the ark server'
114
+
115
+ def rcon(command)
116
+ ark_server(options[:instance]).rcon_cmd command
117
+ end
118
+
119
+ desc 'checkupdate', 'Checks for updates to ark'
120
+
121
+ def checkupdate
122
+ ark_server(options[:instance]).update_available?
123
+ end
124
+
125
+ desc 'checkmodupdates', 'Checks for updates on installed mods'
126
+
127
+ def checkmodupdates
128
+ ark_server(options[:instance]).mod_updates_available?
129
+ end
130
+
131
+ private
132
+
133
+ # @return [Boolean]
134
+ def ark_installed?(instance = 'main')
135
+ Arkrb.install.ark_installed?(instance)
136
+ end
137
+
138
+ # @return [Arkrb::Server]
139
+ def ark_server(instance = 'main')
140
+ Arkrb::Server.new(instance, false)
141
+ end
142
+
143
+ def print_status(item, status, how_to)
144
+ printf format("%-20s %-30s %s\n", item, "[#{status}]", how_to)
145
+ end
146
+
147
+ end
148
+ end
149
+
@@ -0,0 +1,14 @@
1
+ require 'mkmf'
2
+
3
+ module Arkrb
4
+
5
+ old_mkmf_log = MakeMakefile::Logging.instance_variable_get(:@logfile)
6
+ MakeMakefile::Logging.instance_variable_set(:@logfile, '/dev/null')
7
+ BASH_EXEC = find_executable0 'bash' unless defined? BASH_EXEC
8
+ CURL_EXEC = find_executable0 'curl' unless defined? CURL_EXEC
9
+ MakeMakefile::Logging.instance_variable_set(:@logfile, old_mkmf_log)
10
+
11
+ USER_HOME = Dir.home unless defined? USER_HOME
12
+ ARK_SERVER_TOOLS_MD5 = '773b17d67eff8944bcd0e2a39089c96d'
13
+
14
+ end
@@ -0,0 +1,53 @@
1
+ module Arkrb
2
+ module Error
3
+
4
+ class CustomError < RuntimeError
5
+ end
6
+
7
+ class UnknownError < CustomError
8
+ end
9
+
10
+ class ExecutableAlreadyExists < CustomError
11
+ end
12
+
13
+ class ArkManagerExecutableNotFound < CustomError
14
+ end
15
+
16
+ class CURLNotInstalled < CustomError
17
+ end
18
+
19
+ class BASHNotInstalled < CustomError
20
+ end
21
+
22
+ class InstallScriptMD5Changed < CustomError
23
+ end
24
+
25
+ class SteamCMDError < CustomError
26
+ end
27
+
28
+ class ArkExecutableNotFound < CustomError
29
+ end
30
+
31
+ class ServerAlreadyRunning < CustomError
32
+ end
33
+
34
+ class ServerAlreadyStopped < CustomError
35
+ end
36
+
37
+ class SanitizationUnsupportedForThisMethod < CustomError
38
+ end
39
+
40
+ class ModIDNotFound < CustomError
41
+ end
42
+
43
+ class ModDoesNotExist < CustomError
44
+ end
45
+
46
+ class ModAlreadyExists < CustomError
47
+ end
48
+
49
+ end
50
+
51
+ end
52
+
53
+
@@ -0,0 +1,51 @@
1
+ require 'arkrb/error'
2
+ module Arkrb
3
+ class ErrorParsing
4
+ def sanitize!(command, error_output, command_opts = nil)
5
+ ark_exe_not_found = potential_errors[:ark_exe_not_found]
6
+ raise ark_exe_not_found[:class], ark_exe_not_found[:message] if error_output =~ /#{ark_exe_not_found[:cause]}/im
7
+
8
+ case command
9
+ when :install
10
+ install_command(error_output)
11
+ else
12
+ raise_unknown_error(command, error_output, command_opts)
13
+ end
14
+ end
15
+
16
+ def install_command(error_output)
17
+ missing_32_gcc = potential_errors[:missing_32_gcc]
18
+ case error_output
19
+ when /#{missing_32_gcc[:cause]}/im
20
+ raise missing_32_gcc[:class], missing_32_gcc[:message]
21
+ else
22
+ raise_unknown_error('install', error_output)
23
+ end
24
+ end
25
+
26
+ private
27
+
28
+ def potential_errors
29
+ @potential_errors ||= {
30
+ missing_32_gcc: {
31
+ cause: '/steamcmd/linux32/steamcmd: No such file or directory',
32
+ class: Arkrb::Error::SteamCMDError,
33
+ message: 'It appears that you are missing the lib32gcc1 package please have an Administrator install it!'
34
+ },
35
+ ark_exe_not_found: {
36
+ cause: 'ARK server exec could not be found',
37
+ class: Arkrb::Error::ArkExecutableNotFound,
38
+ message: 'Whooah! The Ark Server Executable was not found, please install the ark server using `arkrb install ark`'
39
+ }
40
+ }
41
+ end
42
+
43
+ def raise_unknown_error(command, error_output, command_opts = nil)
44
+ error_message = (command_opts.nil?) ?
45
+ format("An unknown error has occurred while attempting to run command %s\n%s", command, error_output) :
46
+ format("An unknown error has occurred while attempting to run command %s with opts %s\n%s", command, command_opts, error_output)
47
+ raise Arkrb::Error::UnknownError, error_message
48
+ end
49
+
50
+ end
51
+ end
@@ -0,0 +1,34 @@
1
+ require 'mkmf'
2
+ require 'digest'
3
+ require 'arkrb/server'
4
+ require 'arkrb/constants'
5
+
6
+ module Arkrb
7
+ class Install
8
+
9
+ # @return [True, Exception]
10
+ def server_tools
11
+ server_tools_install_sh_path = "/tmp/server_tools_install_#{Time.now.strftime('%Y%m%d-%H%M%S')}.sh"
12
+ File.delete(server_tools_install_sh_path) if File.exist?(server_tools_install_sh_path)
13
+
14
+ `#{CURL_EXEC} -sL http://git.io/vtf5N > #{server_tools_install_sh_path}`
15
+ file_md5 = Digest::MD5.hexdigest File.read(server_tools_install_sh_path)
16
+
17
+ raise Arkrb::Error::InstallScriptMD5Changed, "Uhh oh!!! #{file_md5} did not match #{Arkrb::ARK_SERVER_TOOLS_MD5}; Please report this issue at https://github.com/mbround18/Arkrb" unless file_md5.eql? Arkrb::ARK_SERVER_TOOLS_MD5
18
+
19
+ `#{BASH_EXEC} #{server_tools_install_sh_path} --me --perform-user-install`
20
+
21
+ unless find_executable('arkmanager', "#{Arkrb::USER_HOME}/bin")
22
+ File.open("#{Arkrb::USER_HOME}/.bashrc", 'a') do |file|
23
+ file.write "export PATH=$PATH:#{File.expand_path(Arkrb::USER_HOME + '/bin')}"
24
+ end
25
+ puts 'arkmanager was successfully added to your path' if find_executable('arkmanager', "#{Arkrb::USER_HOME}/bin")
26
+ end
27
+ end
28
+
29
+ def ark(instance = 'main', sanitize_output = false)
30
+ Arkrb::Server.new(instance, sanitize_output).install
31
+ end
32
+
33
+ end
34
+ end
@@ -0,0 +1,188 @@
1
+ module Arkrb
2
+ class OutputParsing
3
+
4
+ def sanitize!(command, output)
5
+ if public_methods(false).include?(command.to_sym)
6
+ method(command.to_sym).call(output)
7
+ else
8
+ raise Arkrb::Error::SanitizationUnsupportedForThisMethod, "\n#{output}"
9
+ end
10
+ end
11
+
12
+
13
+ def install(output)
14
+ if output.strip.empty?
15
+ true
16
+ else
17
+ if output =~ /#{'server already running'}/im
18
+ raise Arkrb::Error::ServerAlreadyRunning, output
19
+ else
20
+ raise_unknown_error(:install, output)
21
+ end
22
+ end
23
+ end
24
+
25
+ # @return [True, Exception]
26
+ def start(output)
27
+ if output =~ /#{'the server is now running'}/im
28
+ true
29
+ else
30
+ if output =~ /#{'server already running'}/im
31
+ raise Arkrb::Error::ServerAlreadyRunning, output
32
+ else
33
+ raise_unknown_error(:start, output)
34
+ end
35
+ end
36
+ end
37
+
38
+ # @return [True, Exception]
39
+ def stop(output)
40
+ if output =~ /#{'The server has been stopped'}/im
41
+ true
42
+ else
43
+ if output =~ /#{'The server is already stopped'}/im
44
+ raise Arkrb::Error::ServerAlreadyStopped, output
45
+ else
46
+ raise_unknown_error(__method__.to_sym, output)
47
+ end
48
+ end
49
+ end
50
+
51
+ # @return [True, Exception]
52
+ def restart(output)
53
+ if output =~ /#{'server has been stopped'}/im &&
54
+ output =~ /#{'the server is now running'}/im
55
+ true
56
+ else
57
+ raise_unknown_error(__method__.to_sym, output)
58
+ end
59
+ end
60
+
61
+ def status(output)
62
+ status_items = {}
63
+ status = output.gsub(/\e\[([;\d]+)?m/, '')
64
+ if status =~ /Server running/im
65
+ status = status.split("\n").map {|s| s.strip }
66
+ status.shift
67
+ status.each do |item|
68
+ item_info = item.split(':', 2)
69
+ status_items[item_info.first.gsub('Server', '').strip.downcase.tr(' ', '_').to_sym] = item_info[1].strip
70
+ end
71
+ status_items[:arkservers_link] = status_items.delete(:arks_link)
72
+ status_items
73
+ else
74
+ raise_unknown_error(__method__.to_sym, output)
75
+ end
76
+ end
77
+
78
+ # @return [True, Exception]
79
+ def update(output)
80
+ if output =~ /#{'already up to date '}/im || output =~ /#{'updated'}/im
81
+ else
82
+ raise_unknown_error(__method__.to_sym, output)
83
+ end
84
+ end
85
+
86
+
87
+ # @return [True, Exception]
88
+ def backup(output)
89
+ if output =~ /Created Backup/im
90
+ console_response = output.split("\n").map {|x| x.gsub(/\e\[([;\d]+)?m/, '').strip}
91
+ dir_path = console_response.find {|x| x =~ /Saved arks directory is/im}.split('directory is').last.strip
92
+ file_name = console_response.find {|x| x =~ /Created Backup/im}.split(':').last.strip
93
+ {
94
+ status: 'success',
95
+ path: File.join(dir_path, file_name)
96
+ }
97
+ else
98
+ raise_unknown_error(__method__.to_sym, output)
99
+ end
100
+ end
101
+
102
+ # @return [True, Exception]
103
+ def save_world(output)
104
+ if output =~ /world saved/im
105
+ true
106
+ else
107
+ raise_unknown_error(__method__.to_sym, output)
108
+ end
109
+ end
110
+
111
+ # @return [True, Exception]
112
+ def enable_mod(output)
113
+ if output =~ /enable mod/im
114
+ true
115
+ else
116
+ raise_unknown_error(__method__.to_sym, output)
117
+ end
118
+ end
119
+
120
+ # @return [True, Exception]
121
+ def disable_mod(output)
122
+ if output =~ /disablemod/im
123
+ true
124
+ else
125
+ raise_unknown_error(__method__.to_sym, output)
126
+ end
127
+ end
128
+
129
+ # @return [True, Exception]
130
+ def install_mod(output)
131
+ if output =~ /mod [0-9]+ installed/im
132
+ true
133
+ else
134
+ raise_unknown_error(__method__.to_sym, output.gsub("\r", "\n"))
135
+ end
136
+ end
137
+
138
+ # @return [True, Exception]
139
+ def uninstall_mod(output)
140
+ if output =~ /uninstallmod/im
141
+ true
142
+ else
143
+ raise_unknown_error(__method__.to_sym, output)
144
+ end
145
+ end
146
+
147
+ # @return [True, Exception]
148
+ def reinstall_mod(output)
149
+ if output =~ /mod [0-9]+ installed/im
150
+ true
151
+ else
152
+ raise_unknown_error(__method__.to_sym, output.gsub("\r", "\n"))
153
+ end
154
+ end
155
+
156
+ # @return [True, Exception]
157
+ def broadcast(output)
158
+ if output =~ /command processed/im
159
+ true
160
+ else
161
+ raise_unknown_error(__method__.to_sym, output.gsub("\r", "\n"))
162
+ end
163
+ end
164
+
165
+ # @return [Object]
166
+ # def rcon_cmd(output)
167
+ # arkmanager_exec(:rcon, command)
168
+ # end
169
+
170
+ # @return [Boolean]
171
+ # def update_available?(output)
172
+ # arkmanager_exec :check_update
173
+ # end
174
+
175
+ # @return [Boolean]
176
+ # def mod_updates_available?(output)
177
+ # output
178
+ # end
179
+
180
+ private
181
+
182
+ def raise_unknown_error(command, output)
183
+ error_message = format("An unknown error has occurred while attempting to run command %s\n%s", command, output)
184
+ raise Arkrb::Error::UnknownError, error_message
185
+ end
186
+
187
+ end
188
+ end