varinvalid_session=NakamaSession.new()# An empty session, which will cause an errorvarinvalid_account=yield(client.get_account_async(invalid_session),"completed")print(invalid_account)# This will print the exceptionifinvalid_account.is_exception():print("We got an exception.")
# Make this a node variable or it will disconnect when the function that creates it returnsonreadyvarsocket:=Nakama.create_socket_from(client)func_ready():varconnected:NakamaAsyncResult=yield(socket.connect_async(session),"completed")ifconnected.is_exception():print("An error occurred: %s"%connected)returnprint("Socket connected.")
# Get the System's unique device identifiervardevice_id=OS.get_unique_id()# Authenticate with the Nakama server using Device Authenticationvarsession:NakamaSession=yield(client.authenticate_device_async(device_id),"completed")ifsession.is_exception():print("An error occurred: %s"%session)returnprint("Successfully authenticated: %s"%session)
vardevice_id="<unique_device_id>"# Link Device Authentication to existing player account.varlinked:NakamaAsyncResult=yield(client.link_custom_async(session,device_id),"completed")iflinked.is_exception():print("An error occurred: %s"%linked)returnprint("Id '%s' linked for user '%s'"%[device_id,session.user_id])
链接Facebook身份验证
1
2
3
4
5
6
7
varoauth_token="<token>"varimport_friends=truevarsession:NakamaSession=yield(client.link_facebook_async(session,oauth_token,import_friends),"completed")ifsession.is_exception():print("An error occurred: %s"%linked)returnprint("Facebook authentication linked for user '%s'"%[session.user_id])
varauth_token="restored from save location"varsession=NakamaClient.restore_session(auth_token)
检查会话是否已过期或即将过期,刷新会话使其保持活动状态:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# Check whether a session has expired or is close to expiryifsession.expired:# Attempt to refresh the existing session.session=yield(client.session_refresh_async(session),"completed)
if session.is_exception():
# Couldn't refresh the session so reauthenticate.
session = yield(client.authenticate_device_async(device_id), "completed")
# Save the new refresh token
<save_file>.set_value("refresh_token", session.refresh_token)
}
# Save the new auth token
<save_file>.set_value("auth_token", session.auth_token)
}
class_namemetadataexport(String)vartitleexport(String)varhatexport(String)varskin# Get the updated account objectvaraccount:NakamaAPI.ApiAccount=yield(client.get_account_async(session),"completed")# Parse the account user metadata.varmetadata=JSON.parse(account.user.metadata)Print("Title: %s",metadata.title)Print("Hat: %s",metadata.hat)Print("Skin: %s",metadata.skin)
varfavorite_hats=["cowboy","alien"]varcan_read=1# Only the server and owner can readvarcan_write=1# The server and owner can writevaracks:NakamaAPI.ApiStorageObjectAcks=yield(client.write_storage_objects_async(session,[NakamaWriteStorageObject.new("hats","favorite_hats",can_read,can_write)]),"completed")
# Assuming we already have a storage objectvarfavorite_hats=["cowboy","alien"]varcan_read=1# Only the server and owner can readvarcan_write=1# The server and owner can writevarversion=<version>varacks:NakamaAPI.ApiStorageObjectAcks=yield(client.write_storage_objects_async(session,[NakamaWriteStorageObject.new("hats","favorite_hats",can_read,can_write,version)]),"completed")ifacks.is_exception():print("An error occurred: %s"%acks)return
varids=["some_user_id","another_user_id]
var usernames = ["AlwaysTheImposter21", "SneakyBoi"]
# Add friends by username
var result : NakamaAsyncResult = yield(client.add_friends_async(session, usernames), "completed")
# Add friends by user id
var result : NakamaAsyncResult = yield(client.add_friends_async(session, ids), "completed")
varids=["some_user_id","another_user_id]
var usernames = ["AlwaysTheImposter21", "SneakyBoi"]
# Delete friends by username
var result : NakamaAsyncResult = yield(client.delete_friends_async(session, usernames), "completed")
# Delete friends by user id
var result : NakamaAsyncResult = yield(client.delete_friends_async(session, ids), "completed")
varids=["some_user_id","another_user_id]
var usernames = ["AlwaysTheImposter21", "SneakyBoi"]
# Block friends by username
var result : NakamaAsyncResult = yield(client.block_friends_async(session, usernames), "completed")
# Block friends by user id
var result : NakamaAsyncResult = yield(client.block_friends_async(session, ids), "completed")
func_ready():# Setup the socket and subscribe to the status eventsocket.connect("received_status_presence",self,"_on_status_presence")func_on_status_presence(p_presence:NakamaRTAPI.StatusPresenceEvent):print(p_presence)forjinp_presence.joins:print("%s is online with status: %s"%[j.user_id,j.status])forjinp_presence.leaves:print("%s went offline"%[j.user_id])# Follow mutual friends and get the initial Status of any that are currently onlinevarfriends_result=yield(client.list_friends_async(session,0),"completed")varfriend_ids=[]forfriendinfriends_result:varf=friendasNakamaAPI.ApiFriendifnotfornotf.user.online:continuefriend_ids.append(f.user)varresult:NakamaAsyncResult=yield(socket.follow_users_async(friend_ids)forpinresult.presences:print("%s is online with status: %s"%[presence.user_id,presence.status])
varname="Imposters R Us"vardescription="A group for people who love playing the imposter."varopen=true# public groupvarmax_size=100vargroup:NakamaAPI.ApiGroup=yield(client.create_group_async(session,name,description,open,max_size),"completed")
varlimit=20varresult:NakamaAPI.ApiGroupList=yield(client.list_groups_async(session,"imposter%",limit),"completed")forginresult.groups:vargroup=gasNakamaAPI.ApiGroupprint("Group: name &s, open %s",[group.name,group.open])$Getthenextpageofresultsvarnext_results:NakamaAPI.ApiGroupList=yield(client.list_groups_async(session,name:"imposter%",limit,result.cursor)
varuser_id="<user id>"varresult:NakamaAPI.ApiUserGroupList=yield(client.list_user_groups_async(session,user_id),"completed")foruginresult.user_groups:varg=ug.groupasNakamaAPI.ApiGroupprint("Group %s role %s",g.id,ug.state)
vargroup_id="<group id>"varmember_list:NakamaAPI.ApiGroupUserList=yield(client.list_group_users_async(session,group_id),"completed")foruginmember_list.group_users:varu=ug.userasNakamaAPI.ApiUserprint("User %s role %s"%[u.id,ug.state])
vargroup_id="<group_id>"varpersistence=truevarhidden=falsevartype=NakamaSocket.ChannelType.Groupvarchannel:NakamaRTAPI.Channel=yield(socket.join_chat_async(group_id,type,persistence,hidden),"completed")print("Connected to group channel: '%s'"%[channel.id])
varuser_id="<user_id>"varpersistence=truevarhidden=falsevartype=NakamaSocket.ChannelType.DirectMessagevarchannel:NakamaRTAPI.Channel=yield(socket.join_chat_async(user_id,type,persistence,hidden),"completed")print("Connected to direct message channel: '%s'"%[channel.id])
varchannel_id="<channel_id>"varmessage_content={"message":"I think Red is the imposter!"}varmessage_ack:NakamaRTAPI.ChannelMessageAck=yield(socket.write_chat_message_async(channel_id,message_content),"completed")varemote_content={"emote":"point","emoteTarget":"<red_player_user_id>",}varemote_ack:NakamaRTAPI.ChannelMessageAck=yield(socket.write_chat_message_async(channel_id,emote_content),"completed")
varchannel_id="<channel_id>"varmessage_content={"message":"I think Red is the imposter!"}varmessage_ack:NakamaRTAPI.ChannelMessageAck=yield(socket.write_chat_message_async(channel_id,message_content),"completed")
然后他们迅速编辑消息以迷惑他人:
1
2
3
varnew_message_content={"message":"I think BLUE is the imposter!"}varmessage_update_ack:NakamaRTAPI.ChannelMessageAck=yield(socket.update_chat_message_async(channel_id,new_message_content),"completed")
varmatch:NakamaRTAPI.Match=yield(socket.create_match_async(),"completed")varfriends_list=yield(client.list_friends_async(session,0,100)varonline_friends=[]forfriendinfriends_list:varf=friendasNakamaAPI.ApiFriendifnotfornotf.user.online:continueonline_friends.append(f.user)forfinonline_friends:varcontent={"message":"Hey %s, join me for a match!",match_id=match.id,}varchannel=yield(socket.join_chat_async(f.id,NakamaSocket.ChannelType.DirectMessage),"completed")varmessage_ack=yield(socket.write_chat_message_async(channel.id,content),"completed")
varstatus={"status":"Playing a match","matchid":"<match_id>",}yield(socket.update_status_async(status),"completed")
关注玩家的用户可以接收实时状态事件,并尝试加入比赛:
1
2
3
4
5
6
func_on_status_presence(p_presence:NakamaRTAPI.StatusPresenceEvent):# Join the first match found in a friend's statusforjinp_presence.joins:varstatus=JSON.parse(p_presence.status)ifmatchidinstatus:yield(socket.join_match_async(status["matchid"]),"completed")
func_on_match_presence(p_presence:NakamaRTApi.MatchPresenceEvent):# For each player that has joined in this event...forpinp_presence.joins:# Spawn a player for this presence and store it in a dictionary by session id.vargo=<player_node>.new()players.add(p_presence.session_id,go)# For each player that has left in this event...forpinp_presence.leaves:# Remove the player from the game if they've been spawnedifpresence.session_idinplayers:<player_node>.remove_and_skip()players.remove(presence.session_id)
func_on_match_state(p_state:NakamaRTAPI.MatchData):matchmatch_state.op_code:op_code.position:# Get the updated position datavarposition_state=JSON.parse(match_state.state)# Update the game object associated with that playervaruser=match_state.user_presence.session_idifuserinplayers:# Here we would normally do something like smoothly interpolate to the new position, but for this example let's just set the position directly.players[user].transform.Vector3=vec(position_state.x,position_state.y,position_state.z)_:print("Unsupported op code.")
contreward_code=100func_on_notification(p_notification:NakamaAPI.ApiNotification):matchnotification.code:reward_code:print("Congratulations, you won the tournament!\n%s\n%s",notification.subject,notification.content)_:print("Other notification: %s:%s\n%s",notification.code,notification.subject,notification.content)