/// <summary> /// Rejoin the room. /// </summary> /// <param name="roomName">Room name.</param> public static void RejoinRoom(string roomName = null) { if (string.IsNullOrEmpty(roomName)) { if (Play.Room == null) { Play.InvokeEvent(PlayEventCode.OnJoinRoomFailed, "-100", "can NOT join a room with the name is NULL."); return; } roomName = Play.Room.Name; } var joinRoomCommand = new PlayCommand() { Body = new Dictionary <string, object>() { { "cmd", "conv" }, { "op", "add" }, { "cid", roomName }, { "rejoin", true }, }, }; RunSocketCommand(joinRoomCommand, done: DoRejoinRoom); }
/// <summary> /// Join or create room. /// </summary> /// <param name="roomName">Room name.</param> /// <param name="roomConfig">Room config.</param> public static void JoinOrCreateRoom(string roomName, PlayRoom.RoomConfig roomConfig) { if (string.IsNullOrEmpty(roomName)) { LogError("roomName can NOT be null or empty."); return; } var joinOrCreateRoomCommand = new PlayCommand() { Body = new Dictionary <string, object>() { { "cmd", "conv" }, { "op", "add" }, { "cid", roomName }, { "createOnNotFound", true }, }, }; if (roomConfig.ExpectedUsers != null) { joinOrCreateRoomCommand.Body.Add("expectMembers", roomConfig.ExpectedUsers.ToArray()); } RunSocketCommand(joinOrCreateRoomCommand, PlayEventCode.OnJoinOrCreatingRoom, (req, res) => { if (res.Body.ContainsKey("cid")) { DoJoinRoom(req, res); } else { CreateRoom(roomConfig, roomName); } }); }
internal static void DoUpdateFriends(PlayCommand request, PlayResponse response) { lock (friendListMutex) { var onlineListStr = response.Body["online_list"] as string; var onlineList = onlineListStr.Split(','); } }
internal void Save(Hashtable propertiesToUpdateOrSet = null, Hashtable expectedValues = null) { if (this.Name == null) { return; } var updateCommand = new PlayCommand(); updateCommand.Body = new Dictionary <string, object>(); updateCommand.Body["cmd"] = "conv"; updateCommand.Body["cid"] = this.Name; updateCommand.Body["op"] = "update"; if (expectedValues != null) { if (propertiesToUpdateOrSet != null) { IDictionary <string, object> casAttr = new Dictionary <string, object>(); expectedValues.Every(kv => { var key = kv.Key; if (propertiesToUpdateOrSet.ContainsKey(key)) { IDictionary <string, object> cas = new Dictionary <string, object>(); var toUpdateValue = propertiesToUpdateOrSet[key]; cas.Add("expect", kv.Value); cas.Add("value", toUpdateValue); casAttr.Add(key.ToString(), cas); } }); updateCommand.Body["casAttr"] = casAttr; } } else { if (propertiesToUpdateOrSet != null) { updateCommand.Body["attr"] = propertiesToUpdateOrSet.ToDictionary(); } else { updateCommand.Body["attr"] = this.EncodeAttributes(); } } Play.RunSocketCommand(updateCommand, done: (request, response) => { lock (this.metaDataMutex) { response.Body.GetValue <IDictionary <string, object> >("attr", null); IDictionary <string, object> attr = response.Body.GetValue <IDictionary <string, object> >("attr", null); this.CustomPropertiesMetaData.Merge(attr); } }); base.Save(); }
internal static void RunSocketCommand(PlayCommand command, PlayEventCode eventCode = PlayEventCode.None, Action <PlayCommand, PlayResponse> done = null) { var encoded = command.SokcetEncode; Play.Log("socket=>" + encoded); Play.RoomConnection.Send(encoded); var repsonseListener = new SocketResponseListener() { Command = command, Done = done, EventCode = eventCode }; Play.SubscribeNoticeReceived(repsonseListener); //Action<string> onMessage = null; //LogCommand(command, null, CommandType.WebSocket); //onMessage = (messgae) => //{ // var messageJson = Json.Parse(messgae) as IDictionary<string, object>; // if (messageJson.Keys.Contains("i")) // { // if (command.Body["i"].ToString() == messageJson["i"].ToString()) // { // RoomConnection.OnMessage -= onMessage; // var response = new PlayResponse(messageJson); // LogCommand(null, response, CommandType.WebSocket); // if (response.IsSuccessful) // { // if (done != null) // { // done(command, response); // } // } // if (eventCode != PlayEventCode.None) // { // var next = PlayStateMachine.Next(eventCode, response); // if (response.IsSuccessful) // { // Play.InvokeEvent(next); // } // else // { // Play.InvokeEvent(next, response.ErrorCode, response.ErrorReason); // } // } // } // } //}; //RoomConnection.OnMessage += onMessage; }
internal static void DoRejoinRoom(PlayCommand request, PlayResponse response) { if (!response.IsSuccessful) { Play.InvokeEvent(PlayEventCode.OnJoinRoomFailed, response.ErrorCode, response.ErrorReason); return; } var room = GetRoomWhenGet(request, response); Play.InvokeEvent(PlayEventCode.OnJoiningRoom); ConnectRoom(room, true); }
internal static void RunHttpCommand(PlayCommand command, PlayEventCode eventCode = PlayEventCode.None, Action <PlayCommand, PlayResponse> done = null) { if (eventCode != PlayEventCode.None) { Play.InvokeEvent(eventCode); } var httpRequest = command.HttpEncode; Play.ExecuteHttp(httpRequest, (tuple => { int statusCode = (int)HttpStatusCode.BadRequest; IDictionary <string, object> body = new Dictionary <string, object>(); try { body = Json.Parse(tuple.Item2) as IDictionary <string, object>; statusCode = (int)tuple.Item1; } catch { } var response = new PlayResponse() { Body = body as IDictionary <string, object>, StatusCode = (int)tuple.Item1 }; if (response.IsSuccessful) { LogCommand(command, response); if (done != null) { done(command, response); } } else { LogCommand(command, response, printer: ErrorLogger); } if (eventCode != PlayEventCode.None) { var next = PlayStateMachine.Next(eventCode, response); if (response.IsSuccessful) { Play.InvokeEvent(next); } else { Play.InvokeEvent(next, response.ErrorCode, response.ErrorReason); } } })); }
internal static PlayRoom GetRoomWhenGet(PlayCommand request, PlayResponse response) { var room = new PlayRoom(); room.RoomRemoteSecureAddress = response.Body["secureAddr"] as string; room.RoomRemoteAddress = response.Body["addr"] as string; var roomProperties = response.Body; room.SetProperties(roomProperties); return(room); }
internal static void ExecuteRPC(PlayRpcMessage rpcMessage) { var rpcCommand = new PlayCommand(); rpcCommand.Body = new Dictionary <string, object>(); rpcCommand.Body["cmd"] = "direct"; rpcCommand.Body["cid"] = Room.Name; rpcCommand.Body["msg"] = rpcMessage.Serialize(); rpcCommand.Body["echo"] = rpcMessage.Echo; rpcCommand.Body["cached"] = rpcMessage.Cached; rpcCommand.Body["toPeerIds"] = rpcMessage.ToPeers; Play.RunSocketCommand(rpcCommand); }
/// <summary> /// leave current game Room. /// </summary> /// <returns></returns> public static void LeaveRoom() { var leaveRoomCommand = new PlayCommand() { Body = new Dictionary <string, object>() { { "cmd", "conv" }, { "op", "remove" }, { "cid", Room.Name } }, }; RunSocketCommand(leaveRoomCommand, PlayEventCode.OnLeavingRoom, DoLeaveRoom); }
/// <summary> /// player /// </summary> /// <param name="player"></param> public static void SetMasterClient(Player player) { var setMasterClientCommand = new PlayCommand() { Body = new Dictionary <string, object>() { { "cmd", "conv" }, { "op", "update-master-client" }, { "masterClientId", player.UserID }, { "cid", Play.Room.Name }, } }; RunSocketCommand(setMasterClientCommand, PlayEventCode.None); }
/// <summary> /// join a random Room. /// </summary> /// <returns></returns> public static void JoinRandomRoom(Hashtable matchProperties = null) { var joinRandomRoomCommand = new PlayCommand() { Body = new Dictionary <string, object>() { { "cmd", "conv" }, { "op", "start" }, }, }; if (matchProperties != null) { joinRandomRoomCommand.Body.Add("expectAttr", matchProperties.ToDictionary <string, object>()); } RunSocketCommand(joinRandomRoomCommand, PlayEventCode.OnRandomJoiningRoom, DoJoinRoom); }
public void AuthenticateFromRouteServer() { var authCommand = new PlayCommand() { Body = new Dictionary <string, object>() { { "ua", Play.PlayVersion + "_" + Play.GameVersion }, { "client_id", this.ID } }, Method = "POST", RelativeUrl = "/authorization" }; Play.RunHttpCommand(authCommand, PlayEventCode.OnAuthenticating, (req, resp) => { this.SessionToken = resp.Body["token"] as string; }); }
internal static void LogCommand(PlayCommand command, PlayResponse response = null, CommandType commandType = CommandType.Http, Action <string> printer = null) { if (printer == null) { printer = Logger; } lock (logMutext) { if (command != null) { IDictionary <string, object> requestDictionary = new Dictionary <string, object>(); if (commandType == CommandType.Http) { requestDictionary.Add("url", command.RelativeUrl); requestDictionary.Add("method", command.Method); requestDictionary.Add("headers", PlayCommand.Headers); requestDictionary.Add("body", command.Body); } else { requestDictionary = command.Body; } var requestId = requestDictionary.ContainsKey("i") ? requestDictionary["i"].ToString() : ""; Print(printer, commandType + " request:" + requestId + "=>" + requestDictionary.ToJsonLog()); } if (response != null) { IDictionary <string, object> responseDictionary = new Dictionary <string, object>(); if (commandType == CommandType.Http) { responseDictionary.Add("statusCode", response.StatusCode); responseDictionary.Add("body", response.Body); } else { responseDictionary = response.Body; } var responseId = responseDictionary.ContainsKey("i") ? responseDictionary["i"].ToString() : ""; Print(printer, commandType + " response:" + responseId + "<=" + responseDictionary.ToJsonLog()); } } }
/// <summary> /// find friends. /// </summary> public static void FindFriends(IEnumerable <string> friendsToFind) { var friendIdInStr = string.Join(",", friendsToFind.ToArray()); var findFriendsCommand = new PlayCommand() { Body = new Dictionary <string, object>() { { "friend_ids", friendIdInStr }, { "client_id", Play.peer.ID }, } }; RunHttpCommand(findFriendsCommand, PlayEventCode.OnFindingFriends, (req, res) => { lock (friendListMutex) { var onlineListStr = res.Body["online_list"] as string; var onlineList = onlineListStr.Split(','); var inRoomListAStr = res.Body["roomid_list"] as string; var inRoomList = inRoomListAStr.Split(','); var friendsToFindArray = friendsToFind.ToArray(); for (var i = 0; i < friendsToFindArray.Length; i++) { var userId = friendsToFindArray[i]; var inCacheRoom = Play.Friends.FirstOrDefault(f => f.UserId == userId); if (inCacheRoom != null) { inCacheRoom.IsOnline = bool.Parse(onlineList[i]); inCacheRoom.Room = inRoomList[i] == "null" ? "" : inRoomList[i]; } else { Play.friends.Add(new PlayFriend() { UserId = userId, IsOnline = bool.Parse(onlineList[i]), Room = inRoomList[i] == "null" ? "" : inRoomList[i] }); } } } }); }
public void ConnectGameServer() { Play.DoConnectToGameSever(Play.GameServer, () => { var sessionOpenCmd = new PlayCommand() { Body = new Dictionary <string, object>() { { "cmd", "session" }, { "op", "open" }, { "ua", Play.PlayVersion + "_" + Play.GameVersion }, { "peerId", this.ID } } }; Play.RunSocketCommand(sessionOpenCmd, PlayEventCode.OnAuthenticating, done: (req, res) => { this.SessionToken = res.Body["st"] as string; }); }); }
/// <summary> /// Get the lobby server. /// </summary> /// <param name="secure">If set to <c>true</c> secure.</param> /// <param name="lobbyLoaded">after lobby loaded.</param> public void GetLobbyServer(bool secure = true, Action <PlayGameServer> lobbyLoaded = null) { var lobbyGetCmd = new PlayCommand() { RelativeUrl = "/router", UrlParameters = new Dictionary <string, object>() { { "appId", AVClient.CurrentConfiguration.ApplicationId }, { "secure", secure } }, }; Play.RunHttpCommand(lobbyGetCmd, done: (request, response) => { var gameServer = Play.GameServer = PlayGameServer.FetchFromPublicCloud(response); if (lobbyLoaded != null) { lobbyLoaded(gameServer); } }); }
internal void SessionOpen(Action sessionOpened = null) { var sessionCommand = new PlayCommand() { Body = new Dictionary <string, object>() { { "cmd", "session" }, { "op", "open" }, { "ua", Play.PlayVersion + "_" + Play.GameVersion }, { "st", SessionToken } } }; Play.RunSocketCommand(sessionCommand, done: (req, response) => { if (sessionOpened != null) { sessionOpened(); } }); }
internal override void Save(IDictionary <string, object> increment) { var updateCommand = new PlayCommand() { Body = new Dictionary <string, object>() { { "cmd", "conv" }, { "op", "update-player-prop" }, { "cid", Play.Room.Name }, { "targetClientId", this.UserID }, { "playerProperty", increment } } }; Play.RunSocketCommand(updateCommand, done: (request, response) => { if (response.IsSuccessful) { //IDictionary<string, object> results = response.Body["results"] as IDictionary<string, object>; //this.MergeFromServer(results); //Play.InvokeEvent(PlayEventCode.OnPlayerCustomPropertiesChanged, this, results.ToHashtable()); } }); }
internal void SessionRoomJoin(PlayRoom room, bool isRejoin = false, Action <PlayRoom, PlayResponse> roomJoined = null) { var joinCommand = new PlayCommand() { Body = new Dictionary <string, object>() { { "cmd", "conv" }, { "op", "add" }, { "cid", room.Name }, } }; if (isRejoin) { joinCommand.Body.Add("rejoin", isRejoin); } Play.RunSocketCommand(joinCommand, done: (req, response) => { if (roomJoined != null) { roomJoined(room, response); } }); }
/// <summary> /// create a room with config and name. /// </summary> /// <param name="roomConfig">config of Room</param> /// <param name="roomName">name of Room</param> public static void CreateRoom(PlayRoom.RoomConfig roomConfig, string roomName = null) { var createRoomCommand = new PlayCommand() { Body = new Dictionary <string, object>() { { "cmd", "conv" }, { "op", "start" }, }, }; if (string.IsNullOrEmpty(roomName)) { roomName = PlayRoom.RandomRoomName(24); } RunSocketCommand(createRoomCommand, done: (request, response) => { // get game server address from game router var roomRemoteSecureAddress = response.Body["secureAddr"] as string; var roomRemoteAddress = response.Body["addr"] as string; // open websocket connection with game server DoConnectToGameSever(roomRemoteSecureAddress, () => { Play.InvokeEvent(PlayEventCode.OnCreatingRoom); // create room at game server peer.SessionCreateRoom(roomName, roomConfig, (room) => { Play.Room = room; Play.InvokeEvent(PlayEventCode.OnCreatedRoom); Play.InvokeEvent(PlayEventCode.OnJoinedRoom); }); }); }); }
internal void SessionCreateRoom(string roomName, PlayRoom.RoomConfig roomConfig, Action <PlayRoom> roomCreated = null) { IDictionary <string, object> body = new Dictionary <string, object>(); if (roomConfig.CustomRoomProperties != null) { body.Add("attr", roomConfig.CustomRoomProperties.ToDictionary()); } if (roomConfig.MaxPlayerCount > 0 && roomConfig.MaxPlayerCount != PlayRoom.DefaultMaxPlayerCount) { body.Add("maxMembers", roomConfig.MaxPlayerCount); } if (roomConfig.EmptyTimeToLive > 0 && roomConfig.EmptyTimeToLive != PlayRoom.DefaultMaxEmptyTimeToLive) { body.Add("emptyRoomTtl", roomConfig.EmptyTimeToLive); } if (roomConfig.PlayerTimeToKeep > 0 && roomConfig.PlayerTimeToKeep != PlayRoom.DefaultMaxKeepPlayerTime) { body.Add("playerTtl", roomConfig.PlayerTimeToKeep); } if (roomConfig.ExpectedUsers != null) { body.Add("expectMembers", roomConfig.ExpectedUsers); } if (!roomConfig.IsVisible) { body.Add("visible", roomConfig.IsVisible); } if (!roomConfig.IsOpen) { body.Add("open", roomConfig.IsOpen); } if (roomConfig.LobbyMatchKeys != null) { body.Add("lobbyAttrKeys", roomConfig.LobbyMatchKeys); } body.Add("cmd", "conv"); body.Add("op", "start"); body.Add("cid", roomName); var createCommand = new PlayCommand() { Body = body }; Play.RunSocketCommand(createCommand, done: (req, response) => { if (response.IsSuccessful) { var room = new PlayRoom(roomConfig, roomName); Play.DoSetRoomProperties(room, response); if (roomCreated != null) { roomCreated(room); } } else { Play.InvokeEvent(PlayEventCode.OnCreateRoomFailed, response.ErrorCode, response.ErrorReason); } }); }
internal static void DoLeaveRoom(PlayCommand request, PlayResponse response) { DisconnectRoom(Play.Room); }