Commit 577926e8 authored by Gerard Gascón's avatar Gerard Gascón
Browse files

feat: generate dragon code

parent ca4959af
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -40,5 +40,9 @@ func _on_change_shoes_pressed() -> void:
func _on_create_pressed() -> void:
	if dragon_name.text.is_empty():
		return
	var result: String = CodeGenerator.new(hat_outfits, shirt_outfits, shoes_outfits).encrypt(hat.texture, shirt.texture, shoes.texture, dragon_name.text)
	print(result)
	var decrypted: Dictionary = CodeGenerator.new(hat_outfits, shirt_outfits, shoes_outfits).descrypt(result)
	print(decrypted)
	on_create_dragon.emit(hat.texture, shirt.texture, shoes.texture, dragon_name.text)
	queue_free()
+23 −1
Original line number Diff line number Diff line
@@ -6,6 +6,28 @@ func _ready() -> void:


func _text_to_upper(new_text: String):
	var ascii_map := {
		"á":"a", "à":"a", "â":"a", "ä":"a", "ã":"a", "å":"a",
		"é":"e", "è":"e", "ê":"e", "ë":"e",
		"í":"i", "ì":"i", "î":"i", "ï":"i",
		"ó":"o", "ò":"o", "ô":"o", "ö":"o", "õ":"o",
		"ú":"u", "ù":"u", "û":"u", "ü":"u",
		"ñ":"n", "ç":"c",
		"Á":"A", "À":"A", "Â":"A", "Ä":"A", "Ã":"A", "Å":"A",
		"É":"E", "È":"E", "Ê":"E", "Ë":"E",
		"Í":"I", "Ì":"I", "Î":"I", "Ï":"I",
		"Ó":"O", "Ò":"O", "Ô":"O", "Ö":"O", "Õ":"O",
		"Ú":"U", "Ù":"U", "Û":"U", "Ü":"U",
		"Ñ":"N", "Ç":"C"
	}

	var filtered_text := ""
	for c in new_text:
		if ascii_map.has(c):
			filtered_text += ascii_map[c]
		elif c.unicode_at(0) <= 127:
			filtered_text += c

	var last_caret_column = caret_column
	text = new_text.to_upper()
	text = filtered_text.to_upper()
	caret_column = last_caret_column
+141 −0
Original line number Diff line number Diff line
class_name CodeGenerator

var hat_outfits: DragonOutfit
var shirt_outfits: DragonOutfit
var shoes_outfits: DragonOutfit

var key: int = 123

var alphabet: Dictionary = {
	'A': '00',
	'B': '01',
	'C': '02',
	'D': '03',
	'E': '04',
	'F': '05',
	'G': '06',
	'H': '07',
	'I': '08',
	'J': '09',
	'K': '10',
	'L': '11',
	'M': '12',
	'N': '13',
	'O': '14',
	'P': '15',
	'Q': '16',
	'R': '17',
	'S': '18',
	'T': '19',
	'U': '20',
	'V': '21',
	'W': '22',
	'X': '23',
	'Y': '24',
	'Z': '25',
}

var alphabet_inverse: Dictionary = {
	'00': 'A',
	'01': 'B',
	'02': 'C',
	'03': 'D',
	'04': 'E',
	'05': 'F',
	'06': 'G',
	'07': 'H',
	'08': 'I',
	'09': 'J',
	'10': 'K',
	'11': 'L',
	'12': 'M',
	'13': 'N',
	'14': 'O',
	'15': 'P',
	'16': 'Q',
	'17': 'R',
	'18': 'S',
	'19': 'T',
	'20': 'U',
	'21': 'V',
	'22': 'W',
	'23': 'X',
	'24': 'Y',
	'25': 'Z',
}


func _init(hat: DragonOutfit, shirt: DragonOutfit, shoes: DragonOutfit) -> void:
	hat_outfits = hat
	shirt_outfits = shirt
	shoes_outfits = shoes


func encrypt(hat: Texture2D, shirt: Texture2D, shoes: Texture2D, name: String) -> String:
	var hat_index: int = hat_outfits.get_index(hat)
	var shirt_index: int = shirt_outfits.get_index(shirt)
	var shoes_index: int = shoes_outfits.get_index(shoes)
	var code: String = generate_code(hat_index, shirt_index, shoes_index, name)
	return xor_encrypt_decrypt(code)


func descrypt(input: String) -> Dictionary:
	var decrypted_code: String = xor_encrypt_decrypt(input)
	
	if len(decrypted_code) % 2 != 0 or len(decrypted_code) <= 6:
		return {'hat': null, 'shirt': null, 'shoes': null, 'name': null}

	return read_code(decrypted_code)


func generate_code(int1: int, int2: int, int3: int, input_string: String) -> String:
	input_string = input_string.substr(0, 8)

	var binary_data: String = ""
	binary_data += _int_to_bin(int1)
	binary_data += _int_to_bin(int2)
	binary_data += _int_to_bin(int3)

	for i in range(input_string.length()):
		binary_data += _char_to_bin(input_string[i])

	return binary_data


func _int_to_bin(value: int) -> String:
	return "%02X" % value


func _bin_to_int(value: String) -> int:
	return value.hex_to_int()


func _char_to_bin(character: String) -> String:
	return alphabet[character]


func _bin_to_char(character: String) -> String:
	return alphabet_inverse[character]


func xor_encrypt_decrypt(data: String) -> String:
	var result: String = ""
	for i in range(data.length()):
		var c: int = data[i].unicode_at(0)
		var encrypted_char: int = c ^ key
		result += char(encrypted_char)
	return result


func read_code(code: String) -> Dictionary:
	var hat: Texture2D = hat_outfits.get_texture(_bin_to_int(code.substr(0, 2)))
	var shirt: Texture2D = shirt_outfits.get_texture(_bin_to_int(code.substr(2, 2)))
	var shoes: Texture2D = shoes_outfits.get_texture(_bin_to_int(code.substr(4, 2)))
	
	var name: String = ""
	for i in range(code.substr(6).length()):
		if i % 2 != 0:
			continue
		name += _bin_to_char(code.substr(6 + i, 2))
	
	return {'hat': hat, 'shirt': shirt, 'shoes': shoes, 'name': name}
+1 −0
Original line number Diff line number Diff line
uid://bhnm8ysguu4u4
+11 −0
Original line number Diff line number Diff line
@@ -17,3 +17,14 @@ func pick_next() -> Texture2D:
		return null
	
	return outfits[index - 1]


func get_index(texture: Texture2D) -> int:
	return outfits.find(texture)


func get_texture(index: int) -> Texture2D:
	if index < 0 or index >= len(outfits):
		return null
	
	return outfits[index]