// This import is only required with React Native
vardeviceInfo=require('react-native-device-info');vardeviceId=null;// If the user's device ID is already stored, grab that - alternatively get the System's unique device identifier.
try{constvalue=awaitAsyncStorage.getItem('@MyApp:deviceKey');if(value!==null){deviceId=value}else{deviceId=deviceInfo.getUniqueID();// Save the user's device ID so it can be retrieved during a later play session for re-authenticating.
AsyncStorage.setItem('@MyApp:deviceKey',deviceId).catch(function(error){console.log("An error occurred: %o",error);});}}catch(error){console.log("An error occurred: %o",error);}// Authenticate with the Nakama server using Device Authentication.
varcreate=true;constsession=awaitclient.authenticateDevice(deviceId,create,"mycustomusername");console.info("Successfully authenticated:",session);
// Acquiring the unique device ID has been shortened for brevity, see previous example.
vardeviceId="<uniqueDeviceId>";// Link Device Authentication to existing player account.
try{awaitclient.linkDevice(session,deviceId);console.log("Successfully linked Device ID authentication to existing player account");}catch(err){console.log("Error linking Device ID: %o",err.message);}
链接Facebook身份验证
1
2
3
4
5
6
7
8
9
constoauthToken="<token>";constimport=true;try{constsession=awaitclient.linkFacebook(session,oauthToken,true,import);console.log("Successfully linked Facebook authentication to existing player account");}catch(err){console.log("Error authenticating with Facebook: %o",err.message);}
// Check whether a session has expired or is close to expiry.
if(session.isexpired||session.isexpired(Date.now+1){try{// Attempt to refresh the existing session.
session=awaitclient.sessionRefresh(session);}catch(error){// Couldn't refresh the session so reauthenticate.
session=awaitclient.authenticateDevice(deviceId);varrefreshToken=session.refresh_token;}varauthToken=session.token;}
// Get the updated account object.
varaccount=awaitclient.getAccount(session);// Parse the account user metadata.
varmetadata=JSON.parse(account.user.metadata);console.log("Title: %o",metadata.title);console.log("Hat: %o",metadata.hat);console.log("Skin: %o",metadata.skin);
varfavoriteHats=new{hats=["cowboy","alien"]};varwriteObject=newWriteStorageObject{collection="favorites",ley="Hats",value=JSON.stringify(favoriteHats),permissionRead=1,// Only the server and owner can read
permissionWrite=1// The server and owner can write
};awaitclient.writeStorageObjects(session,writeObject);
// Assuming we already have a storage object (storageObject)
varwriteObject=newWriteStorageObject{collection=storageObject.collection,key=storageObject.key,value="<NewJSONValue>",permissionWrite=0,permissionRead=1,version=storageObject.version};try{awaitclient.writeStorageObjects(session,writeObjects);}catch(error){console.log(error.message);}
try{varpayload={"item":"cowboy"};varresponse=awaitclient.rpc(session,"EquipHat",payload);console.log("New hat equipped successfully",response);}catch(error){console.log("Error: %o",error.message);}
// Add friends by Username.
varusernames=["AlwaysTheImposter21","SneakyBoi"];awaitclient.addFriends(session,usernames);// Add friends by User ID.
varids=["<SomeUserId>","<AnotherUserId>"];awaitclient.addFriends(session,ids);
varlimit=20;// Limit is capped at 1000
varfriendshipState=0;varresult=awaitclient.listFriends(session,friendshipState,limit,cursor:null);result.forEach((friend)=>{console.log("ID: %o",friend.user.id);});
// Delete friends by User ID.
varids=["<SomeUserId>","<AnotherUserId>"];awaitclient.deleteFriends(session,ids});// Delete friends by Username.
varusernames=["AlwaysTheImposter21","SneakyBoi"];awaitclient.deleteFriends(session,null,usernames});
// Block friends by User ID.
varids=["<SomeUserId>","<AnotherUserId>"];awaitclient.blockFriends(session,ids);// Block friends by Username.
varusernames=["AlwaysTheImposter21","SneakyBoi"];awaitclient.blockFriends(session,usernames);
// Subscribe to the Status event.
socket.onstatuspresence=(e)=>{e.joins.forEach(function(presence){console.log("%o is online with status: %o",presence.username,presence.status);})e.leaves.forEach(function(presence){console.log("%o went offline",presence.username);})};// Follow mutual friends and get the initial Status of any that are currently online.
varfriendsResult=awaitclient.listFriends(session,0);varfriendIds=[];friendsResult.friends.forEach(function(friend){friendIds.push(friend.user.id);});varresult=awaitsocket.followUsers(friendIds);result.presences.forEach(function(presence){console.log("%o is online with status: %o",presence.username,presence.status);});
constgroupName="Imposters R Us";constdescription="A group for people who love playing the imposter.";constgroup=awaitclient.createGroup(session{name:groupName,description:description,open:true,// public group
maxSize=100});
varlimit=20;varresult=awaitclient.ListGroupsAsync(session,"imposter%",limit);result.groups.forEach(function(group){console.log("%o group is %o",group.name,group.open);});// Get the next page of results.
varnextResults=awaitclient.listGroups(session,name:"imposter%",limit,result.cursor);
constgroupId="<group id>";constpersistence=true;consthidden=false;// 1 = Room, 2 = Direct Message, 3 = Group
constchannel=awaitsocket.joinChat(3,groupId,persistence,hidden);console.log("Connected to group channel: %o",channel.id);
constuserId="<user id>";constpersistence=true;consthidden=false;// 1 = Room, 2 = Direct Message, 3 = Group
constchannel=awaitsocket.joinChat(2,userId,persistence,hidden);console.log("Connected to direct message channel: %o",channel.id);
varchannelId="<channel id>";vardata={"message":"I think Red is the imposter!"};constmessageAck=awaitsocket.writeChatMessage(channelId,data);varemoteData={"emote":"point","emoteTarget":"<redPlayerUserId>"}constemoteMessageAck=awaitsocket.writeChatMessage(channelId,emoteData);
varchannelId="<ChannelId>";varmessageData={"message":"I think Red is the imposter!"};constmessageSendAck=awaitsocket.writeChatMessage(channelId,messageData);
然后改玩家迅速编辑消息来迷惑他人:
1
2
varnewMessageData={"message":"I think BLUE is the imposter!"};constmessageUpdateAck=awaitsocket.updateChatMessage(channelId,messageSendAck.message.id,newMessageData));
varmatch=awaitsocket.createMatch();varfriendsList=awaitclient.listFriends(session);varonlineFriends=[];friendsList.friends.forEach((friend){if(friend.user.online){onlineFriends.push(friend.user);}});onlineFriends.friend.forEach(function(friend){varmessageData={"message":"Hey %o, join me for a match!",friends.username},varmatchId=match.id,constchannel=awaitsocket.joinChat(2,friend.id),constmessageAck=awaitsocket.writeChatMessage(channel,messageData)});
varstatus={"Status":"Playing a match","MatchId":"<MatchId>"};awaitsocket.updateStatus(JSON.stringify(status));
关注玩家的用户可以接收实时状态事件,并尝试加入比赛:
1
2
3
4
5
6
7
8
9
socket.onstatuspresence=async(e)=>{// Join the first match found in a friend's status
e.joins.forEach(function(presence){varstatus=JSON.parse(presence.status),if(status.hasOwnProperty("MatchId")){awaitsocket.joinMatch(status["MatchId"]);break;}});
varmatch=awaitsocket.joinMatch(matchId);varplayers={};match.presences.forEach(function(presence){vargo=spawnPlayer();// Instantiate player object
players.push(presence.session.id,go);});
Sagi-shi使用接收到的比赛显示的在线状态事件,使生成的玩家在离开和加入比赛时保持最新状态:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
socket.onmatchpresence=(matchPresenceEvent)=>{// For each player that has joined in this event...
matchPresenceEvent.joins.forEach(function(presence){// Spawn a player for this presence and store it in a dictionary by session id.
vargo=// Instantiate player object;
players.push(presence.session.id,go);})// For each player that has left in this event...
matchPresenceEvent.leaves.forEach(function(presence){// Remove the player from the game if they've been spawned
if(players.hasOwnProperty("SessionId"){constindex=players.session.id;if(index>-1){players.splice(index,1);}})})};
socket.onmatchdata=(matchState)=>{switch(matchState.opCode){caseopCodes.position:// Get the updated position data
varstateJson=matchState.state;varpositionState=JSON.parse(stateJson);// Update the GameObject associated with that player
if(players.hasOwnProperty(matchState.user_presence.session.id)){// 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[matchState.user_presence.session.id].transform.position=newVector3(positionState.s,positionState.y,positionState.z);}break;default:console.log("Unsupported op code");break;}};
varcategoryStart=1;varcategoryEnd=2;varstartTime=1538147711;varendTime=null;// all tournaments from the start time
varlimit=100;// number to list per page
varcursor=null;varresult=awaitclient.listTournaments(session,categoryStart,categoryEnd,startTime,endTime,limit,cursor);result.tournaments.forEach(function(tournament){console.log("%o:%o",tournament.id,tournament.title);});
socket.onnotification=(notification)=>{constrewardCode=100;switch(notification.code){caserewardCode:console.log("Congratulations, you won the tournament!\n%o\n%o",notification.subject,notification.content);break;default:console.log("Other notification: %o:%o\n%o",notification.code,notification.subject,notification.content);break;}};
constresult=awaitclient.listNotifications(session,10);result.notifications.forEach(notification=>{console.info("Notification code %o and subject %o.",notification.code,notification.subject);});console.info("Fetch more results with cursor:",result.cacheable_cursor);