EditorPropertyExposer.gd 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. class_name PropertyExposer
  2. extends Node
  3. @export var properties: Array[String] = []
  4. @export var filters: Dictionary[String, String] = {}
  5. @export var properties_force_selector: Dictionary[String, PackedScene] = {}
  6. const base64_charset := "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
  7. static var entity_map := {}
  8. signal modifier_applied
  9. func _ready() -> void:
  10. name = "EditorPropertyExposer"
  11. if entity_map.is_empty():
  12. entity_map = JSON.parse_string(FileAccess.open(EntityIDMapper.MAP_PATH, FileAccess.READ).get_as_text())
  13. func get_string() -> String:
  14. var string = ""
  15. for i in properties:
  16. string += ","
  17. if owner is Track:
  18. if owner.get(i) is Array:
  19. for x in owner.get(i):
  20. string += base64_charset[(Track.DIRECTIONS.find(x))]
  21. if owner.get(i) is String:
  22. string += owner.get(i).replace(",", "&")
  23. elif owner.get(i) is PackedScene:
  24. var key = EntityIDMapper.get_map_id(owner.get(i).resource_path)
  25. if key == null or key == "":
  26. key = "!!"
  27. string += key
  28. elif owner.get(i) is int:
  29. if owner.get(i) >= 64:
  30. string += encode_to_base64_2char(owner.get(i))
  31. else:
  32. string += base64_charset[owner.get(i)]
  33. elif owner.get(i) is bool:
  34. string += base64_charset[int(owner.get(i))]
  35. elif owner.get(i) == null:
  36. string += "!!"
  37. return string
  38. func apply_string(entity_string := "") -> void:
  39. var idx := 2
  40. var slice = entity_string.split(",")
  41. for i in properties:
  42. if slice.size() <= idx:
  43. return
  44. var value = slice[idx]
  45. if owner is Track:
  46. if owner.get(i) is Array:
  47. for x in value:
  48. owner.get(i).append(Track.DIRECTIONS[base64_charset.find(x)])
  49. owner._ready()
  50. if owner.get(i) is String:
  51. owner.set(i, value.replace("&", ","))
  52. if owner.get(i) is PackedScene or (owner.get(i) == null and i == "item"):
  53. var scene = entity_map.get(value)
  54. if scene != null:
  55. owner.set(i, load(entity_map.get(value)[0]))
  56. elif owner.get(i) is int:
  57. var num = value
  58. if value.length() > 1:
  59. num = decode_from_base64_2char(value)
  60. else:
  61. num = base64_charset.find(value)
  62. owner.set(i, num)
  63. elif owner.get(i) is bool:
  64. owner.set(i, bool(base64_charset.find(value)))
  65. idx += 1
  66. modifier_applied.emit()
  67. func encode_to_base64_2char(value: int) -> String:
  68. if value < 0 or value >= 4096:
  69. push_error("Value out of range for 2-char base64 encoding.")
  70. return ""
  71. var char1 = base64_charset[(value >> 6) & 0b111111] # Top 6 bits
  72. var char2 = base64_charset[value & 0b111111] # Bottom 6 bits
  73. return char1 + char2
  74. func decode_from_base64_2char(encoded: String) -> int:
  75. if encoded.length() != 2:
  76. push_error("Encoded string must be exactly 2 characters.")
  77. return -1
  78. var char1_val = base64_charset.find(encoded[0])
  79. var char2_val = base64_charset.find(encoded[1])
  80. if char1_val == -1 or char2_val == -1:
  81. push_error("Invalid character in base64 string.")
  82. return -1
  83. return (char1_val << 6) | char2_val