Skip to content

Commit 7af6392

Browse files
committed
feat(integrations): Add Steam integration
Removed/disabled automatic usage of steam Can be re-enabled by uncommenting the respective line in Main.gd drop Godot 4.3 support using exactly Godot 4.4.1 to see if the godotextension actually works Check, whether GDExtension is loaded, and Steam is running cleanup Main.tscn Add autoregister of PlayFabSteam to PlayFabEditor.gd Implemented login with Steam Add GodotSteam settigns Updated main scene Fixed layout of Steam Login button Autoload PlayFabSteam added steam_appid.txt to gitignore GodotSteam Update LoginSteam Add stuff from example repo Add godot-steam Mainline updates for steam branch - ⚙️ Fix image to use in main-godot4.yml to use ubuntu-latest, like all other steps - 📄 Updated docs
1 parent 80c7b4a commit 7af6392

35 files changed

+348
-10
lines changed

.github/workflows/main-godot4.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ jobs:
3737
max-parallel: 10
3838
matrix:
3939
os: [ubuntu-latest]
40-
godot-version: ['4.3', '4.4']
40+
godot-version: ['4.4.1']
4141
godot-status: ['stable']
4242

4343
permissions:

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,8 @@ exports/
2727

2828

2929
[Ee]xport/
30+
31+
steam_appid.txt
32+
33+
# Ignore temp files
34+
~*

Scenes/LoggedIn.gd

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@ func _ready():
99
var _error = PlayFabManager.client.connect("api_error", func(error: ApiErrorWrapper):
1010
print_debug(error.errorMessage)
1111
)
12+
update()
1213

13-
14-
# Called when the node enters the scene tree for the first time.
1514
func update():
16-
if login_result != null:
15+
if PlayFabManager.client.is_logged_in():
16+
login_result = PlayFabManager.client.get_login_result()
1717
$VBoxContainer/LoginResultContainer/AccountPlayerId/Edit.text = login_result.PlayFabId
1818
$VBoxContainer/LoginResultContainer/TitlePlayerId/Edit.text = login_result.InfoResultPayload.AccountInfo.TitleInfo.TitlePlayerAccount.Id
1919
$VBoxContainer/LoginResultContainer/TitlePlayerName/Edit.text = login_result.InfoResultPayload.AccountInfo.TitleInfo.DisplayName

Scenes/Login.gd

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,6 @@ func _on_logged_in(login_result: LoginResult):
9393
_hide_progess()
9494

9595
$LoggedIn.login_result = login_result
96-
$LoggedIn.update()
9796
$LoggedIn.show()
9897

9998
func _on_api_error(api_error_wrapper: ApiErrorWrapper):

Scenes/Main.gd

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,26 @@
1-
extends HBoxContainer
1+
extends Control
2+
3+
func _ready():
4+
# determine whether godot-steam addon is enabled
5+
if ClassDB.can_instantiate("Steam"):
6+
%LoginWithSteam.disabled = true
7+
# PlayFabSteam.connect("logged_in", _on_logged_in) # Enable, if using GodotSteam/PlayFabSteam (4.4.1+)
8+
else:
9+
print_debug("Steam is NOT installed")
10+
%LoginWithSteam.visible = false
11+
%LoginWithSteam.disconnect("pressed", _on_login_with_steam_pressed)
12+
%StatusLabel.text = "Steam wasn't detected."
213

314
func _on_Register_pressed():
415
SceneManager.goto_scene("res://Scenes/Register.tscn")
516

617
func _on_Login_pressed():
718
SceneManager.goto_scene("res://Scenes/Login.tscn")
19+
20+
func _on_login_with_steam_pressed():
21+
SceneManager.goto_scene("res://Scenes/LoggedIn.tscn")
22+
23+
func _on_logged_in(playfab_id: String, steam_persona_name: String) -> void:
24+
print_debug("PlayFab ID: %s\nSteam Persona: %s" % [ playfab_id, steam_persona_name ])
25+
%LoginWithSteam.disabled = false
26+
%StatusLabel.text = "Steam initialized!\nPlayFab ID %s\nSteam Persona: \"%s\"" % [ playfab_id, steam_persona_name ]

Scenes/Main.tscn

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,25 @@ anchor_right = 1.0
99
anchor_bottom = 1.0
1010
grow_horizontal = 2
1111
grow_vertical = 2
12+
script = ExtResource("1")
13+
14+
[node name="StatusLabel" type="Label" parent="."]
15+
unique_name_in_owner = true
16+
layout_mode = 1
17+
anchors_preset = 5
18+
anchor_left = 0.5
19+
anchor_right = 0.5
20+
offset_left = -230.0
21+
offset_top = 199.0
22+
offset_right = 231.0
23+
offset_bottom = 271.0
24+
grow_horizontal = 2
25+
text = "Trying login with Steam..."
26+
horizontal_alignment = 1
1227

1328
[node name="Main" type="HBoxContainer" parent="."]
14-
layout_mode = 0
29+
layout_mode = 1
30+
anchors_preset = 8
1531
anchor_left = 0.5
1632
anchor_top = 0.5
1733
anchor_right = 0.5
@@ -20,19 +36,29 @@ offset_left = -232.5
2036
offset_top = -46.0
2137
offset_right = 232.5
2238
offset_bottom = 46.0
23-
script = ExtResource("1")
39+
grow_horizontal = 2
40+
grow_vertical = 2
2441

2542
[node name="Register" type="Button" parent="Main"]
43+
unique_name_in_owner = true
2644
layout_mode = 2
2745
size_flags_horizontal = 3
2846
size_flags_vertical = 3
2947
text = "Register"
3048

3149
[node name="Login" type="Button" parent="Main"]
50+
unique_name_in_owner = true
3251
layout_mode = 2
3352
size_flags_horizontal = 3
3453
size_flags_vertical = 3
3554
text = "Login"
3655

37-
[connection signal="pressed" from="Main/Register" to="Main" method="_on_Register_pressed"]
38-
[connection signal="pressed" from="Main/Login" to="Main" method="_on_Login_pressed"]
56+
[node name="LoginWithSteam" type="Button" parent="Main"]
57+
unique_name_in_owner = true
58+
layout_mode = 2
59+
size_flags_horizontal = 3
60+
text = "Steam Login"
61+
62+
[connection signal="pressed" from="Main/Register" to="." method="_on_Register_pressed"]
63+
[connection signal="pressed" from="Main/Login" to="." method="_on_Login_pressed"]
64+
[connection signal="pressed" from="Main/LoginWithSteam" to="." method="_on_login_with_steam_pressed"]

addons/godot-playfab/PlayFab.gd

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ signal registered(RegisterPlayFabUserResult)
99
## Emitted when the player logged in successfully
1010
## @param login_result: LoginResult
1111
signal logged_in(login_result)
12+
var _login_result: LoginResult
1213

1314
enum AUTH_TYPE {SESSION_TICKET, ENTITY_TOKEN}
1415

@@ -28,6 +29,7 @@ func _ready():
2829

2930
func _on_logged_in(login_result: LoginResult):
3031
# Setting SessionTicket for subsequent client requests
32+
_login_result = login_result
3133
PlayFabManager.client_config.session_ticket = login_result.SessionTicket
3234
PlayFabManager.client_config.master_player_account_id = login_result.PlayFabId
3335
PlayFabManager.client_config.entity_token = login_result.EntityToken
@@ -192,3 +194,12 @@ func _add_auth_headers(additional_headers: Dictionary, auth_type) -> bool:
192194
push_error("auth_type \"" + auth_type + "\" is invalid")
193195

194196
return true
197+
198+
func is_logged_in():
199+
return _login_result != null
200+
201+
func get_login_result():
202+
if (!is_logged_in()):
203+
push_error("No use logged in with PlayFab")
204+
205+
return _login_result

addons/godot-playfab/PlayFabEditor.gd

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ func _init():
2424

2525
func _enter_tree():
2626
add_autoload_singleton("PlayFabManager", "res://addons/godot-playfab/PlayFabManager.gd")
27+
if Engine.get_version_info().hex >= 0x040401: # load only if Godot 4.4.1
28+
add_autoload_singleton("PlayFabSteam", "res://addons/godot-playfab/PlayFabSteam.gd")
2729

2830
main_panel_instance = MainPanel.instantiate()
2931
# Add the main panel to the editor's main viewport.
@@ -33,6 +35,7 @@ func _enter_tree():
3335

3436

3537
func _exit_tree():
38+
remove_autoload_singleton("PlayFabSteam")
3639
remove_autoload_singleton("PlayFabManager")
3740

3841
if main_panel_instance:
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
extends Node
2+
3+
const PRICE_REFRESH_INTERVAL: int = 3600 # Specifies, after how many seconds prices will be refreshed.
4+
5+
var steam_auth_ticket : Dictionary
6+
var steam_name: String = ""
7+
var playfab_id: String = ""
8+
9+
var inventory_items: Array = []
10+
var inventory_item_definitions: Array = []
11+
12+
var _refresh_prices_timer: Timer = Timer.new()
13+
14+
signal logged_in(playfab_id, steam_persona_name)
15+
signal inventory_updated(items: Array)
16+
17+
func _init() -> void:
18+
self.connect("logged_in", _update_player_inventory, CONNECT_ONE_SHOT)
19+
if not ClassDB.can_instantiate("Steam"):
20+
print_debug("Steam class is not available!")
21+
return
22+
23+
if not Steam.isSteamRunning():
24+
print_debug("Steam client is not running!")
25+
return
26+
27+
PlayFabManager.client.logged_in.connect(_on_logged_in)
28+
PlayFabManager.client.api_error.connect(_on_api_error)
29+
PlayFabManager.client.server_error.connect(_on_server_error)
30+
Steam.get_auth_session_ticket_response.connect(_on_get_auth_sesssion_ticket)
31+
Steam.get_ticket_for_web_api.connect(_on_get_auth_ticket_for_web_api_response)
32+
33+
var result : Dictionary = Steam.steamInitEx(false) # Set to true if you want some local user's data
34+
if result.status > 0:
35+
print("Failure to initialize Steam with status %s" % result.status)
36+
else:
37+
create_auth_session_ticket()
38+
#create_auth_ticket_for_web_api() #Use this line instead if you need Steam Auth Ticket for Web Api
39+
40+
func _enter_tree() -> void:
41+
add_child(_refresh_prices_timer)
42+
_request_prices()
43+
44+
func _process(_delta: float) -> void:
45+
Steam.run_callbacks()
46+
47+
func _exit_tree() -> void:
48+
if steam_auth_ticket.size() > 0:
49+
cancel_auth_ticket()
50+
51+
func _on_logged_in(login_result: LoginResult) -> void:
52+
print("PlayFab Login successful: %s" % login_result)
53+
logged_in.emit(login_result.PlayFabId, Steam.getPersonaName())
54+
55+
func _on_api_error(error_wrapper: ApiErrorWrapper) -> void:
56+
print("PlayFab API Error: %s" % error_wrapper.errorMessage)
57+
58+
func _on_server_error(error_wrapper: ApiErrorWrapper) -> void:
59+
print("PlayFab Server Error: %s" % error_wrapper.errorMessage)
60+
61+
func login(ticket: String, is_auth_ticket_for_api: bool) -> void:
62+
var combined_info_request_params = GetPlayerCombinedInfoRequestParams.new()
63+
combined_info_request_params.show_all()
64+
var player_profile_view_constraints = PlayerProfileViewConstraints.new()
65+
combined_info_request_params.ProfileConstraints = player_profile_view_constraints
66+
PlayFabManager.client.login_with_steam(ticket, is_auth_ticket_for_api, true, combined_info_request_params)
67+
68+
func cancel_auth_ticket() -> void:
69+
Steam.cancelAuthTicket(steam_auth_ticket.id)
70+
71+
func create_auth_session_ticket() -> void:
72+
steam_auth_ticket = Steam.getAuthSessionTicket()
73+
74+
func create_auth_ticket_for_web_api() -> void:
75+
Steam.getAuthTicketForWebApi("AzurePlayFab")
76+
77+
func convert_auth_ticket() -> String:
78+
var ticket: String = ""
79+
for number in steam_auth_ticket.buffer:
80+
ticket += "%02X" % number
81+
return ticket
82+
83+
func _on_get_auth_sesssion_ticket(auth_ticket_id: int, result: int) -> void:
84+
print("Auth Session Ticket (%s) return with result %s" % [auth_ticket_id, result])
85+
if result == 1:
86+
login(convert_auth_ticket(), false)
87+
88+
func _on_get_auth_ticket_for_web_api_response(auth_ticket: int, result: int, ticket_size: int, ticket_buffer: Array) -> void:
89+
print("Auth Ticket for Web API (%s) return with the result %s" % [auth_ticket, result])
90+
steam_auth_ticket.id = auth_ticket
91+
steam_auth_ticket.buffer = ticket_buffer
92+
steam_auth_ticket.size = ticket_size
93+
if result == 1:
94+
login(convert_auth_ticket(), true)
95+
96+
97+
func _request_prices():
98+
print("Requesting Steam prices...")
99+
Steam.requestPrices()
100+
print("Prices requested.")
101+
_refresh_prices_timer.start(PRICE_REFRESH_INTERVAL)
102+
_refresh_prices_timer.connect("timeout", _request_prices, CONNECT_ONE_SHOT)
103+
104+
func _on_inventory_definition_update(definitions: Array) -> void:
105+
inventory_item_definitions = definitions
106+
print("Loaded %s definitions." % inventory_item_definitions.size())
107+
108+
func _update_player_inventory(_playFabId, _steam_persona_name) -> void:
109+
Steam.inventory_definition_update.connect(_on_inventory_definition_update)
110+
Steam.loadItemDefinitions()
111+
Steam.getAllItems()
112+
113+
Steam.inventory_result_ready.connect(_on_inventory_result_ready)
114+
115+
func _on_inventory_result_ready(_result: int, _inventory_handle: int):
116+
inventory_items = Steam.getResultItems(Steam.inventory_handle)
117+
inventory_updated.emit(inventory_items)
118+
print("Items in inventory: %s" % inventory_items.size())
119+
120+
121+
func _grant_test_items() -> int:
122+
var items: PackedInt64Array = [1, 2]
123+
var quantities: PackedInt32Array = [2, 3]
124+
var handler = Steam.generateItems(items, quantities)
125+
return handler
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
uid://bwjpctbep1gob

0 commit comments

Comments
 (0)