Skip to content

Instantly share code, notes, and snippets.

@litvil
Created January 13, 2016 17:01
Show Gist options
  • Save litvil/c3a02b5cf12f3e9f7cf8 to your computer and use it in GitHub Desktop.
Save litvil/c3a02b5cf12f3e9f7cf8 to your computer and use it in GitHub Desktop.
class YamlGenerator
def items_params
#override this function
return {
"template_name" => "",
"source_url" => "",
"output_file" => "",
"server_classes_folder" => "",
"write_mode" => "w" #w - erase and fill file, a - append to file
}
end
def description_fields
return ['description.ru','description.ko','description_acc.ru','description_acc.ko','description_acc2.ru','description_acc2.ko', 'description_acc5.ru','description_acc5.ko', 'description_post.ru', 'description_text.ru', 'description_text.ko']
end
def quotes_fields
return ['swf_name']
end
def default_fields
return ['id', 'name', 'declare', 'parent', 'super_class', 'enabled'] + description_fields
end
def read_items(url)
puts "downloading items from: #{url}"
uri = URI.parse(url)
if uri.host.nil? #Локально
body = File.read(url);
else
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
request = Net::HTTP::Get.new(uri.request_uri)
response = http.request(request)
begin
body = response.body.force_encoding("UTF-8") #for ruby 1.9 set force_encoding("UTF-8")
rescue
body = response.body
end
end
return [] if body.nil?
csv = CSV.parse(body)
headers = csv.shift.map { |i| i.to_s.sub(/ .*$/, "") }
headers = perform_header(headers)
string_data = csv.map { |row| row.map { |cell| cell.to_s } }
result = string_data.map { |row| Hash[*headers.zip(row).flatten] }
result
end
def item_value(item, name, default)
if item[name] && item[name].length && item[name] != ""
return item[name]
end
default
end
def perform_header(header_fields)
state_index = -1
for i in 0..header_fields.length-1 do
if (header_fields[i].split('-').length == 2 && header_fields[i].split('-')[0]=='state')
state_index = header_fields[i].split('-')[1].to_i
else
header_fields[i] += "-" + state_index.to_s if(state_index >= 0)
end
end
return header_fields
end
def generate_item(item, template_name, ruby_classes_folder="")
template_name = "default" if (template_name.nil? or template_name.empty?)
template = File.open("items_generator/templates/#{template_name}.yml.erb").read
result = ERB.new(template).result(binding)
ruby_template_file = "items_generator/templates/#{template_name}.rb.erb"
if (File.exists?(ruby_template_file) && !ruby_classes_folder.empty?)
class_tmp = File.open(ruby_template_file).read
class_name = item["name"].split("_").map { |word| word.capitalize }.join
class_result = ERB.new(class_tmp).result(binding)
if(!File.exists?("#{ruby_classes_folder}/#{item["name"]}_item.rb") && !items_params["include_class_rb"].nil? && !items_params["include_class_rb"].empty?)
File.new("#{ruby_classes_folder}/#{item["name"]}_item.rb", File::CREAT|File::TRUNC|File::RDWR, 0644).write(class_result)
end
end
return result
end
def generate_object_states(item, object_states_items)
return nil if object_states_items.length <= 0
object_state = {}
state_ind=0
while(item.keys.select { |i| i.split("-").length == 2 && i.split("-")[1].to_i == state_ind }.length > 0)
state = {"state_params" => item["state-" + state_ind.to_s].to_s}
item.keys.select { |i| i.split("-").length == 2 && i.split("-")[1].to_i == state_ind }.each do |sf|
state[sf] = [] if (sf != ("state-" + state_ind.to_s))
end
object_state["state-" + state_ind.to_s] = state
state_ind+=1
end
object_state.each do |state_key, state_data|
state_data.each do |action_key, action_data|
object_states_items.each do |item|
action_data.push({"params" => item[state_key], "items" => item[action_key]}) if (!item[state_key].nil? && !item[action_key].nil? && !item[action_key].empty?)
end
end
object_state[state_key] = state_data.select{|k,v| v.length>0}
end
return object_state
end
def is_item_enabled(item_enabled_field, param_release)
data = item_enabled_field.split(':')
return (data[0].to_s.empty? || data[0].to_s.downcase == 'true') &&
((data[1].nil? || data[1].empty?) || (!data[1].nil? && !data[1].empty? && data[1].to_s.downcase == param_release))
end
def get_items_to_generate(array_of_hashes, param_release)
array_of_hashes = array_of_hashes.select { |i| i["id"] && i["id"]!="" }
result = []
for item in array_of_hashes
next if item['name'].empty?
next if !is_item_enabled(item['enabled'], param_release)
item.each_key do |key|
item[key]||=""
raise "Item invalid name ##{item[key]} " if item[key] =~ /_\d/ && key == "name"
end
result.push(perform_item_to_generate(item, array_of_hashes.select { |i| i['id'] == item['id'] && i['name'].empty?}))
end
return result
end
def perform_item_to_generate(item, array_of_hashes)
item = item.merge(generate_descriptions(item))
item = item.select {|k, v| !k.end_with?("_ru") && !k.end_with?("_ko") && !v.nil?}
item['object_states'] = generate_object_states(item, array_of_hashes)
item = item.select {|k,v| k.split('-').length == 1}
return item
end
def generate_descriptions(item)
new_fields = {}
item.each do |ifield, ivalue|
if(ifield.start_with?('desription_numeral'))
new_fields = new_fields.merge(get_description_numeral_fields(ivalue, ifield.slice(-2,2)))
ivalue = nil
next
end
new_key = ifield.sub(/_ru$/, ".ru")
new_key = new_key.sub(/_ko$/, ".ko")
if(new_key != ifield)
new_fields[new_key] = ivalue
ivalue = nil
end
end
return new_fields
end
def get_description_numeral_fields(numerals, lang)
new_fields = {}
if(!numerals.nil? && !numerals.empty?)
desc_numerals = numerals.split("\n")
new_fields["description_acc." + lang] = desc_numerals[0] if(desc_numerals[0])
new_fields["description_acc2." + lang] = desc_numerals[1] if(desc_numerals[1])
new_fields["description_acc5." + lang] = desc_numerals[2] if(desc_numerals[2])
end
return new_fields
end
def generate_items(array_of_hashes, template_name, classes_folder = "")
result = ""
array_of_hashes.each do |item|
result = result.concat(generate_item(item, template_name, classes_folder))
end
return result
end
def write_result(file_name, result, write_mode = "w")
puts "write items metadata #{file_name}"
if(write_mode == "a" && File.exists?(file_name))
File.open(file_name, write_mode).write(result)
return
end
File.new(file_name, "w", 0644).write(result)
end
def generate_yml_field_data(field_name, field_data)
if(field_name == 'object_states')
return generate_object_state_yml_data(field_data)
end
if(field_name == 'quest_tag')
return generate_field_list_yml_data(field_data)
end
data = field_data
if(description_fields.index(field_name) || quotes_fields.index(field_name))
data = "\"#{field_data}\""
end
if(field_data.to_s.downcase == "true" || field_data.to_s.downcase == "false")
data = field_data.to_s.downcase
end
return data
end
def generate_state_params(state_params, spaces)
state_params_str = ""
if !state_params.nil? and !state_params.empty?
params = state_params.split("\n")
params.each do |param|
state_params_str += "#{param.split(':')[0]}: #{param.split(':')[1].to_s||""}"
state_params_str += "\n" + spaces
end
end
return state_params_str
end
def generate_object_state_yml_data(field_data)
object_states_data = ""
field_data.each do |state_key, state_data|
object_states_data += "\n - "
object_states_data += generate_state_params(state_data['state_params'], " ")
object_states_data += "drop:"
state_data.each do |action_key, action_data|
next if action_key == 'state_params'
object_states_data += "\n " + action_key.to_s.split('-')[0] + ":"
action_data.each do |roll|
roll_percent = genrate_roll_items_percent(roll["items"])
roll_str = "\n - roll: " + roll_percent.to_s
roll_params_str = generate_roll_params(roll["params"])
roll_items_str = generate_roll_items(roll["items"], roll_percent, roll["params"], spaces = " ")
object_states_data += roll_str + roll_params_str + roll_items_str
end
end
end
return object_states_data
end
def generate_roll_params(roll_params, spaces = " ")
return "" if (roll_params.nil? or roll_params.empty?)
spaces = "\n" + spaces
params_str = ""
params = roll_params.split("\n")
params.each do |param|
params_str += spaces + "#{param.split(':')[0]}: #{param.split(':')[1].to_s||""}"
end
return params_str
end
def generate_roll_items(roll_items, roll_percent, roll_params, spaces = " ")
return "" if (roll_items.nil? or roll_items.empty?)
rp = roll_percent/100 if roll_percent > 0
sum = 0
spaces = "\n" + spaces
items_str = spaces + " items:"
items = roll_items.split("\n")
items.each do |item|
item_data = item.split(':')
min_value = max_value = 0
min_quantity = max_quantity = ""
items_str += spaces + " - " + item_data[0] + ": {"
values_data = item_data[1].split(',')
percent_value = values_data.select {|i| i =~ /%|\./}[0]
quantity_value = values_data.select {|i| i != percent_value && i.to_i != 0}[0]
unlocker = values_data.select {|i| i!=percent_value && i!=quantity_value}[0].to_s.strip||""
if(percent_value)
percent_value_arr = percent_value.split('-')
min_percent_value = (rp > 0) ? 1.0/rp.to_f : 0
max_percent_value = percent_value_arr[0].to_f
if percent_value_arr.length >= 2
min_percent_value = percent_value_arr[0].to_f
max_percent_value = percent_value_arr[1].to_f
end
percent = max_percent_value.to_f * rp
min_value = sum+ (min_percent_value*rp).to_i
sum = sum += percent.to_i
sum = roll_percent if(sum > roll_percent)
max_value = sum
end
if(quantity_value)
if(quantity_value.to_i < 0)
min_quantity = quantity_value
else
quantity_values_arr = quantity_value.split('-')
min_quantity = quantity_values_arr[0].to_s||""
max_quantity = quantity_values_arr[1].to_s||""
end
end
temp_str = ""
temp_str += "min_value: " + min_value.to_s if min_value != 0 || roll_params =~ /collectibles/
temp_str += (!temp_str.empty? ? ", " : "") + "max_value: " + max_value.to_s if max_value != 0
temp_str += (!temp_str.empty? ? ", " : "") + "min_quantity: " + min_quantity.to_s if !min_quantity.empty?
temp_str += (!temp_str.empty? ? ", " : "") + "max_quantity: " + max_quantity.to_s if !max_quantity.empty?
temp_str += (!temp_str.empty? ? ", " : "") + "unlocker: " + unlocker if !unlocker.empty?
items_str += temp_str + "}"
end
return items_str
end
def genrate_roll_items_percent(roll_items)
return 0 if (roll_items.nil? or roll_items.empty?)
roll_percent = 0
items = roll_items.split("\n")
items.each do |item|
item_data = item.split(':')
next if item_data[1].nil?
values_data = item_data[1].split(',')
percent_value = values_data.select {|i| i =~ /%|\./}[0]
next if(percent_value.nil?)
percent_value_arr = percent_value.split('-')
max_percent_value = percent_value_arr[0].to_f
if percent_value_arr.length >= 2
max_percent_value = percent_value_arr[1].to_f
end
perc = (10 ** (max_percent_value.to_f.to_s.split(".")[1].length+2)).to_i
roll_percent = perc if perc > roll_percent
end
return roll_percent
end
def generate_field_list_yml_data(field_data, spaces = " ")
field_data.split("\n").map{|el| "\n" + spaces + "- \"#{el}\""}.join("")
end
def get_array_of_hashes(template_name, source_url)
puts "======================================================="
puts "generate items metadata from template: #{template_name}"
arr = read_items(source_url)
puts 'read_items - OK'
return arr
end
def generate_yaml(param_release)
array_of_hashes = get_array_of_hashes(items_params["items_category"], items_params["source_url"])
items = get_items_to_generate(array_of_hashes, param_release)
result = generate_items(items, items_params["template_name"], items_params["server_classes_folder"])
puts 'generate_items_list - OK'
write_result(items_params["output_file"], result, items_params["write_mode"])
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment