arkrb 0.1.0

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