Skip to content

Commit

Permalink
feat: implement ethereum controller (#122)
Browse files Browse the repository at this point in the history
* add cancel sign-in button

* working with refactor

* add send async, fix format

* update url

* android fix

* godot update to 4.2.1
change auth server request timeout to 15secs (previous 1s)
default ui_scale on mobile set to 1.75

* implement sendAsync
change avatar dictionary to profile dictionary
implement rejection of remote wallet response
fix clear debug panel

* fix format/clippy

* fix testing
fix guest session
  • Loading branch information
leanmendoza authored Dec 21, 2023
1 parent bf1c62e commit 6023442
Show file tree
Hide file tree
Showing 40 changed files with 719 additions and 450 deletions.
2 changes: 1 addition & 1 deletion build-android-apk.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ cargo run -- run --only-build
echo "Link export templates"
mkdir -p ${HOME}/.local/share/godot/export_templates/
cd ${HOME}/.local/share/godot/export_templates/
ln -sf ${EXPLORER_PATH}/.bin/godot/templates/templates/ 4.2.stable
ln -sf ${EXPLORER_PATH}/.bin/godot/templates/templates/ 4.2.1.stable

echo "Build for Android"
cd ${EXPLORER_PATH}/rust/decentraland-godot-lib
Expand Down
6 changes: 5 additions & 1 deletion godot/src/config/config_data.gd
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,11 @@ func load_from_default():

self.resolution = "1280 x 720"
self.window_size = "1280 x 720"
self.ui_scale = 1
if Global.is_mobile:
self.ui_scale = 1.75
else:
self.ui_scale = 1.0

self.session_account = {}

self.last_realm_joined = "https://sdk-team-cdn.decentraland.org/ipfs/goerli-plaza-main"
Expand Down
45 changes: 39 additions & 6 deletions godot/src/decentraland_components/avatar.gd
Original file line number Diff line number Diff line change
Expand Up @@ -62,22 +62,40 @@ func _unset_avatar_modifier_area():
# TODO: Passport (enable functionality)


func async_update_avatar_from_profile(profile: Dictionary):
var profile_content: Dictionary = profile.get("content", {})
var id = profile_content.get("userId", "unknown")
if id == null:
id = "unknown"

avatar_id = id
if profile_content.get("name", "") != null:
avatar_name = profile_content.get("name", "")

await async_update_avatar(profile.get("content", {}).get("avatar", {}))


func async_update_avatar(avatar: Dictionary):
current_content_url = "https://peer.decentraland.org/content/"
if not Global.realm.content_base_url.is_empty():
current_content_url = Global.realm.content_base_url

if avatar.is_empty():
printerr("Trying to update an avatar with an empty object")
return

playing_emote = false
set_idle()

avatar_name = avatar.get("name")
avatar_id = avatar.get("userId", "")
if avatar.get("name", "") != null:
avatar_name = avatar.get("name", "")

label_3d_name.text = avatar_name
current_wearables = avatar.get("wearables")
current_body_shape = avatar.get("body_shape")
current_eyes_color = avatar.get("eyes")
current_skin_color = avatar.get("skin")
current_hair_color = avatar.get("hair")
current_body_shape = avatar.get("bodyShape")
current_eyes_color = Avatar.from_color_object(avatar.get("eyes", {}).get("color", null))
current_skin_color = Avatar.from_color_object(avatar.get("skin", {}).get("color", null))
current_hair_color = Avatar.from_color_object(avatar.get("hair", {}).get("color", null))

var wearable_to_request := PackedStringArray(current_wearables)
wearable_to_request.push_back(current_body_shape)
Expand All @@ -91,6 +109,21 @@ func async_update_avatar(avatar: Dictionary):
async_fetch_wearables_dependencies()


static func from_color_object(color: Variant, default: Color = Color.WHITE) -> Color:
if color is Dictionary:
return Color(
color.get("r", default.r),
color.get("g", default.g),
color.get("b", default.b),
color.get("a", default.a)
)
return default


static func to_color_object(color: Color) -> Dictionary:
return {"color": {"r": color.r, "g": color.g, "b": color.b, "a": color.a}}


func _add_animation(index: int, animation_name: String):
var animation = Global.animation_importer.get_animation_from_gltf(animation_name)
global_animation_library.add_animation(animation_name, animation)
Expand Down
4 changes: 2 additions & 2 deletions godot/src/decentraland_components/nft_shape.gd
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,9 @@ func _set_picture_frame_material(


func _set_loading_material(
style: NftFrameStyleLoader.NFTFrameStyles, current_frame: Node3D, background_color: Color
style: NftFrameStyleLoader.NFTFrameStyles, new_current_frame: Node3D, background_color: Color
):
var mesh_instance_3d: MeshInstance3D = _get_mesh_instance_3d(current_frame)
var mesh_instance_3d: MeshInstance3D = _get_mesh_instance_3d(new_current_frame)
if mesh_instance_3d == null:
printerr("set nft mesh_instance_3d is null")
return
Expand Down
10 changes: 8 additions & 2 deletions godot/src/global.gd
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@ enum CameraMode {

# Only for debugging purpose, Godot editor doesn't include a custom param debugging
const FORCE_TEST = false
const FORCE_TEST_ARG = '["52,-52"]'
const FORCE_TEST_REALM = "https://sdilauro.github.io/dae-unit-tests/dae-unit-tests"
const FORCE_TEST_ARG = "[[52,-52],[52,-54],[52,-56],[52,-58],[52,-60],[52,-62],[52,-64],[52,-66],[52,-68],[54,-52],[54,-54],[54,-56],[54,-58],[54,-60],[54,-62]]"
const FORCE_TEST_REALM = "https://decentraland.github.io/scene-explorer-tests/scene-explorer-tests"
#const FORCE_TEST_ARG = "[[52,-64]]"
#const FORCE_TEST_REALM = "http://localhost:8000"

## Global classes (singleton pattern)
var content_manager: ContentManager
Expand All @@ -27,6 +29,7 @@ var nft_fetcher: OpenSeaFetcher = OpenSeaFetcher.new()
var nft_frame_loader: NftFrameStyleLoader = NftFrameStyleLoader.new()

var standalone = false
var dcl_android_plugin

@onready var is_mobile = OS.has_feature("mobile")
#@onready var is_mobile = true
Expand Down Expand Up @@ -56,6 +59,9 @@ func _ready():
if not DirAccess.dir_exists_absolute("user://content/"):
DirAccess.make_dir_absolute("user://content/")

if Engine.has_singleton("DclAndroidPlugin"):
dcl_android_plugin = Engine.get_singleton("DclAndroidPlugin")

self.realm = Realm.new()
self.realm.set_name("realm")

Expand Down
2 changes: 1 addition & 1 deletion godot/src/logic/player/player.gd
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ func _ready():


func _on_player_profile_changed(new_profile: Dictionary):
avatar.async_update_avatar(new_profile)
avatar.async_update_avatar_from_profile(new_profile)


func _on_param_changed(_param):
Expand Down
4 changes: 2 additions & 2 deletions godot/src/logic/player/player_identity.gd
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ func async_fetch_profile(address: String, lambda_server_base_url: String) -> voi
self.set_default_profile()


func _on_wallet_connected(address: String, _chain_id: int, is_guest: bool):
if is_guest:
func _on_wallet_connected(address: String, _chain_id: int, is_guest_value: bool):
if is_guest_value:
self.set_default_profile()
return

Expand Down
21 changes: 11 additions & 10 deletions godot/src/test/avatar/test_avatar.gd
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,17 @@ var emotes: Array = []

# Called when the node enters the scene tree for the first time.
func _ready():
avatar.async_update_avatar(
"https://peer.decentraland.org/content",
"Godot User",
body_shape,
eyes_color,
hair_color,
skin_color,
wearables,
emotes
)
# TODO: this is outdated
#avatar.async_update_avatar(
#"https://peer.decentraland.org/content",
#"Godot User",
#body_shape,
#eyes_color,
#hair_color,
#skin_color,
#wearables,
#emotes
#)


# Called every frame. 'delta' is the elapsed time since the previous frame.
Expand Down
39 changes: 25 additions & 14 deletions godot/src/test/testing_api.gd
Original file line number Diff line number Diff line change
Expand Up @@ -68,17 +68,19 @@ func start():
prints("parcels_str=" + str(parcels_str))

var parcels = JSON.parse_string(parcels_str)
for pos_str in parcels:
var pos = pos_str.split(",")
if pos.size() == 2:
var parcel_pos: Vector2i = Vector2i(int(pos[0]), int(pos[1]))
for pos_array in parcels:
if not pos_array is Array:
continue

if pos_array.size() == 2:
var parcel_pos: Vector2i = Vector2i(int(pos_array[0]), int(pos_array[1]))
scene_tests.push_back(SceneTestItem.new(parcel_pos, ""))
else:
printerr("Scene to test '" + pos_str + "' not supported for now.")
printerr("Scene to test '" + pos_array + "' not supported for now.")

if scene_tests.is_empty():
printerr(
'Couldn\'t get any scene to test in the scene-test mode. Please try --scene-test ["52,-52"]'
"Couldn't get any scene to test in the scene-test mode. Please try --scene-test [[52,-52]]"
)
get_tree().quit(1)
return
Expand Down Expand Up @@ -151,14 +153,17 @@ func async_take_and_compare_snapshot(

RenderingServer.set_default_clear_color(Color(0, 0, 0, 0))
var viewport = get_viewport()
var camera = viewport.get_camera_3d()
var previous_camera_position = camera.global_position
var previous_camera_rotation = camera.global_rotation
var previous_camera = viewport.get_camera_3d()

var test_camera_3d = Camera3D.new()
add_child(test_camera_3d)
test_camera_3d.make_current()

var previous_viewport_size = viewport.size

viewport.size = screenshot_size
camera.global_position = camera_position
camera.look_at(camera_target)
test_camera_3d.global_position = camera_position
test_camera_3d.look_at(camera_target)

get_node("/root/explorer").set_visible_ui(false)
if hide_player:
Expand All @@ -170,13 +175,16 @@ func async_take_and_compare_snapshot(

var viewport_img := viewport.get_texture().get_image()

#await get_tree().create_timer(10.0).timeout

get_node("/root/explorer").set_visible_ui(true)
if hide_player:
get_node("/root/explorer/Player").show()

viewport.size = previous_viewport_size
camera.global_position = previous_camera_position
camera.global_rotation = previous_camera_rotation
previous_camera.make_current()
remove_child(test_camera_3d)
test_camera_3d.queue_free()

var existing_snapshot: Image = null
var content_mapping = Global.scene_runner.get_scene_content_mapping(scene_id)
Expand Down Expand Up @@ -224,6 +232,7 @@ func dump_test_result_and_get_ok() -> bool:
for scene in scene_tests:
if scene.test_result.is_empty():
ok = false
prints("🔴 test result is empty in the scene " + str(scene.parcel_position))
continue

prints(scene.test_result.text)
Expand All @@ -250,7 +259,9 @@ func _process(_delta):
scene.already_telep = true
scene.reset_timeout()
test_player_node.global_position = Vector3(
scene.parcel_position.x * 16.0, 1.0, -scene.parcel_position.y * 16.0
scene.parcel_position.x * 16.0 + 8.0,
1.0,
-scene.parcel_position.y * 16.0 - 8.0
)
elif scene.timeout():
printerr(
Expand Down
34 changes: 31 additions & 3 deletions godot/src/ui/components/auth/sign_in.gd
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
extends Control

var cancel_action: Callable = Callable()

@onready var panel_main = $Panel_Main

@onready var v_box_container_connect = $Panel_Main/VBoxContainer_Connect
@onready var v_box_container_waiting = $Panel_Main/VBoxContainer_Waiting
@onready var v_box_container_guest_confirm = $Panel_Main/VBoxContainer_GuestConfirm

@onready var label_waiting = $Panel_Main/VBoxContainer_Waiting/Label_Waiting
@onready var button_waiting_cancel = $Panel_Main/VBoxContainer_Waiting/Button_WaitingCancel


func show_panel(child_node: Control):
Expand All @@ -16,8 +19,16 @@ func show_panel(child_node: Control):
child_node.show()


func show_waiting_panel(text: String):
func show_waiting_panel(text: String, new_cancel_action: Variant = null):
label_waiting.text = text

if new_cancel_action != null and new_cancel_action is Callable:
button_waiting_cancel.show()
cancel_action = new_cancel_action
else:
button_waiting_cancel.hide()
cancel_action = Callable()

show_panel(v_box_container_waiting)


Expand All @@ -34,9 +45,18 @@ func _ready():
show_panel(v_box_container_connect)


func _on_button_sign_in_pressed_abort():
Global.player_identity.abort_try_connect_account()
show_panel(v_box_container_connect)


func _on_button_sign_in_pressed():
Global.player_identity.try_connect_account()
show_waiting_panel("Please follow the steps to connect your account and sign the message")

show_waiting_panel(
"Please follow the steps to connect your account and sign the message",
self._on_button_sign_in_pressed_abort
)


func _on_button_guest_pressed():
Expand All @@ -48,7 +68,11 @@ func _on_button_confirm_guest_risk_pressed():


func _on_need_open_url(url: String, _description: String) -> void:
OS.shell_open(url)
if Global.dcl_android_plugin != null:
Global.dcl_android_plugin.showDecentralandMobileToast()
Global.dcl_android_plugin.openUrl(url)
else:
OS.shell_open(url)


func _on_wallet_connected(_address: String, _chain_id: int, is_guest: bool) -> void:
Expand All @@ -63,3 +87,7 @@ func _on_wallet_connected(_address: String, _chain_id: int, is_guest: bool) -> v
Global.config.save_to_settings_file()

close_sign_in()


func _on_button_waiting_cancel_pressed():
cancel_action.call()
7 changes: 6 additions & 1 deletion godot/src/ui/components/auth/sign_in.tscn
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@ theme_override_font_sizes/font_size = 20
text = "Continue as a guest"

[node name="VBoxContainer_Waiting" type="VBoxContainer" parent="Panel_Main"]
visible = false
layout_mode = 1
anchors_preset = 8
anchor_left = 0.5
Expand All @@ -90,6 +89,11 @@ autowrap_mode = 3
layout_mode = 2
size_flags_horizontal = 4

[node name="Button_WaitingCancel" type="Button" parent="Panel_Main/VBoxContainer_Waiting"]
visible = false
layout_mode = 2
text = "Cancel"

[node name="VBoxContainer_GuestConfirm" type="VBoxContainer" parent="Panel_Main"]
visible = false
layout_mode = 1
Expand Down Expand Up @@ -121,4 +125,5 @@ text = "I assume the risk"

[connection signal="pressed" from="Panel_Main/VBoxContainer_Connect/Button_SignIn" to="." method="_on_button_sign_in_pressed"]
[connection signal="pressed" from="Panel_Main/VBoxContainer_Connect/Button_Guest" to="." method="_on_button_guest_pressed"]
[connection signal="pressed" from="Panel_Main/VBoxContainer_Waiting/Button_WaitingCancel" to="." method="_on_button_waiting_cancel_pressed"]
[connection signal="pressed" from="Panel_Main/VBoxContainer_GuestConfirm/Button_ConfirmGuestRisk" to="." method="_on_button_confirm_guest_risk_pressed"]
4 changes: 3 additions & 1 deletion godot/src/ui/components/backpack/avatar_preview.gd
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ var dirty_is_dragging

func _ready():
if Global.standalone:
avatar.async_update_avatar(Global.config.avatar_profile)
pass
# TODO: this config no longer exists
#avatar.async_update_avatar(Global.config.avatar_profile)


func focus_camera_on(type):
Expand Down
Loading

0 comments on commit 6023442

Please sign in to comment.