Пример #1
0
 internal Transaction(Bundle serverData)
 {
     Description = serverData["desc"];
     Domain = serverData["domain"];
     RunDate = Common.ParseHttpDate(serverData["ts"]);
     TxData = serverData["tx"];
 }
Пример #2
0
 internal TransactionResult(Bundle serverData)
     : base(serverData)
 {
     Balance = serverData["balance"];
     foreach (var pair in serverData["achievements"].AsDictionary()) {
         TriggeredAchievements[pair.Key] = new AchievementDefinition(pair.Key, pair.Value);
     }
 }
Пример #3
0
 internal Score(Bundle serverData)
     : base(serverData)
 {
     GamerInfo = new GamerInfo(serverData);
     Info = serverData["score"]["info"];
     PostedAt = Common.ParseHttpDate(serverData["score"]["timestamp"]);
     Rank = serverData["rank"];
     Value = serverData["score"]["score"];
 }
Пример #4
0
 /// <summary>
 /// Allows to store arbitrary data for a given achievement and the current player (appears in the
 /// 'gamerData' node of achievements).
 /// </summary>
 /// <returns>Promise resolved when the operation has completed. The attached value contains the updated definition
 ///     of the achievement.</returns>
 /// <param name="achName">Name of the achievement to update.</param>
 /// <param name="data">Data to associate with the achievement, merged with the current data (that is, existing keys
 ///     are not affected)</param>
 public Promise<AchievementDefinition> AssociateData(string achName, Bundle data)
 {
     UrlBuilder url = new UrlBuilder("/v1/gamer/achievements").Path(domain).Path(achName).Path("gamerdata");
     HttpRequest req = Gamer.MakeHttpRequest(url);
     req.BodyJson = data;
     return Common.RunInTask<AchievementDefinition>(req, (response, task) => {
         task.PostResult(new AchievementDefinition(achName, response.BodyJson["achievement"]));
     });
 }
Пример #5
0
 internal Match(Gamer gamer, Bundle serverData)
     : base(serverData)
 {
     Gamer = gamer;
     CustomProperties = Bundle.Empty;
     Moves = new List<MatchMove>();
     GlobalState = Bundle.Empty;
     Players = new List<GamerInfo>();
     Shoe = Bundle.Empty;
     UpdateWithServerData(serverData);
 }
Пример #6
0
 /// <summary>
 /// Indexes a new object.
 /// Use this API to add or update an object in an index. You can have as many indexes as you need: one
 /// for gamer properties, one for matches, one for finished matches, etc. It only depends on what you
 /// want to search for.
 /// </summary>
 /// <returns>Promise resolved when the request has finished.</returns>
 /// <param name="objectId">The ID of the object to be indexed. It can be anything; this ID only needs to uniquely
 ///     identify your document. Therefore, using the match ID to index a match is recommended for instance.</param>
 /// <param name="properties">A freeform object, whose attributes will be indexed and searchable. These properties
 ///     are typed! So if 'age' is once passed as an int, it must always be an int, or an error will be
 ///     thrown upon insertion.</param>
 /// <param name="payload">Another freeform object. These properties are attached to the document in the same way
 ///     as the properties, however those are not indexed (cannot be looked for in a search request). Its
 ///     content is returned in searches (#CotcSdk.IndexResult.Payload property).</param>
 public Promise<Done> IndexObject(string objectId, Bundle properties, Bundle payload)
 {
     UrlBuilder url = new UrlBuilder("/v1/index").Path(Domain).Path(IndexName);
     HttpRequest req = Cloud.MakeUnauthenticatedHttpRequest(url);
     req.BodyJson = Bundle.CreateObject(
         "id", objectId,
         "properties", properties,
         "payload", payload
     );
     return Common.RunInTask<Done>(req, (response, task) => {
         task.PostResult(new Done(true, response.BodyJson));
     });
 }
Пример #7
0
 /// <summary>To be used when an HTTP request has failed. Will extract a default error code (server error, network error) from the HTTP request.</summary>
 internal CotcException(HttpResponse response, string failureDescription = null)
 {
     Json = response.BodyJson;
     HttpStatusCode = response.StatusCode;
     if (response.HasFailed) {
         ErrorCode = ErrorCode.NetworkError;
         ErrorInformation = failureDescription;
     }
     else if (response.StatusCode < 200 || response.StatusCode >= 300) {
         ErrorCode = ErrorCode.ServerError;
         ErrorInformation = failureDescription;
     }
     else {
         throw new InvalidOperationException("Should only call this for a failed request");
     }
 }
 internal SocialNetworkFriendResponse(Bundle serverData)
     : base(serverData)
 {
     ByNetwork = new Dictionary<LoginNetwork, List<SocialNetworkFriend>>();
     // Parse the response, per network
     foreach (var pair in serverData.AsDictionary()) {
         try {
             LoginNetwork net = (LoginNetwork) Enum.Parse(typeof(LoginNetwork), pair.Key, true);
             var list = new List<SocialNetworkFriend>();
             foreach (var friendPair in pair.Value.AsDictionary()) {
                 list.Add(new SocialNetworkFriend(friendPair.Value));
             }
             ByNetwork[net] = list;
         }
         catch (Exception e) {
             Common.LogError("Unknown network " + pair.Key + ", ignoring. Details: " + e.ToString());
         }
     }
 }
Пример #9
0
        /// <summary>
        /// Creates a match, available for join by other players. If you would like to make your match private, please read
        /// the general documentation about matches.
        /// </summary>
        /// <returns>Promise resolved when the operation has completed. The attached Match object allows to operate with the
        ///     match.</returns>
        /// <param name="maxPlayers">The maximum number of players who may be in the game at a time.</param>
        /// <param name="description">String describing the match (available for other who want to join).</param>
        /// <param name="customProperties">Freeform object containing the properties of the match, which may be used by other players
        ///     to search for a suited match.</param>
        /// <param name="shoe">Freeform object containing a list of objects which will be shuffled upon match creation. This offers
        ///     an easy way to make a random generator that is safe, unbiased (since made on the server) and can be verified
        ///     by all players once the game is finished. This bundle needs to be an array (use Bundle.CreateArray).</param>
        public Promise<Match> Create(int maxPlayers, string description = null, Bundle customProperties = null, Bundle shoe = null)
        {
            var task = new Promise<Match>();
            if (shoe != null && shoe.Type != Bundle.DataType.Array) {
                task.PostResult(ErrorCode.BadParameters, "The shoe must be an array");
                return task;
            }

            UrlBuilder url = new UrlBuilder("/v1/gamer/matches").QueryParam("domain", domain);
            HttpRequest req = Gamer.MakeHttpRequest(url);
            Bundle config = Bundle.CreateObject();
            config["maxPlayers"] = maxPlayers;
            config["description"] = description;
            config["customProperties"] = customProperties;
            config["shoe"] = shoe;
            req.BodyJson = config;
            return Common.RunRequest(req, task, (HttpResponse response) => {
                task.PostResult(new Match(Gamer, response.BodyJson["match"]));
            });
        }
Пример #10
0
 internal MatchLeaveEvent(Gamer gamer, Bundle serverData)
     : base(gamer, serverData)
 {
     foreach (Bundle b in serverData["event"]["playersLeft"].AsArray()) {
         PlayersLeft.Add(new GamerInfo(b));
     }
 }
Пример #11
0
 internal MatchMove(string playerId, Bundle moveData)
 {
     MoveData = moveData;
     PlayerId = playerId;
 }
Пример #12
0
 private void UpdateWithServerData(Bundle serverData)
 {
     Lock(() => {
         if (serverData.Has("creator")) Creator = new GamerInfo(serverData["creator"]);
         if (serverData.Has("customProperties")) CustomProperties = serverData["customProperties"];
         if (serverData.Has("domain")) Domain = serverData["domain"];
         if (serverData.Has("description")) Description = serverData["description"];
         if (serverData.Has("globalState")) GlobalState = serverData["globalState"];
         MatchId = serverData["_id"];
         if (serverData.Has("maxPlayers")) MaxPlayers = serverData["maxPlayers"];
         if (serverData.Has("seed")) Seed = serverData["seed"];
         Status = Common.ParseEnum<MatchStatus>(serverData["status"]);
         if (serverData.Has("shoe")) Shoe = serverData["shoe"];
         // Process pending events
         if (serverData.Has("events")) {
             Moves.Clear();
             foreach (var b in serverData["events"].AsArray()) {
                 if (b["type"] == "match.move") {
                     Moves.Add(new MatchMove(serverData["event"]["player_id"], serverData["event"]["move"]));
                 }
             }
         }
         // Players
         if (serverData.Has("players")) {
             Players.Clear();
             foreach (var b in serverData["players"].AsArray()) {
                 Players.Add(new GamerInfo(b));
             }
         }
         // Last event ID (null if 0; =first time)
         string lastEvent = serverData["lastEventId"];
         if (lastEvent != "0") LastEventId = lastEvent;
     });
 }
Пример #13
0
        /// <summary>Posts a move to other players.</summary>
        /// <returns>Promise resolved when the operation has completed.</returns>
        /// <param name="moveData">A freeform object indicating the move data to be posted and transfered to other players. This
        ///     move data will be kept in the events, and new players should be able to use it to reproduce the local game
        ///     state.</param>
        /// <param name="updatedGameState">A freeform object replacing the global game state, to be used by players who join from
        ///     now on. Passing a non null value clears the pending events in the match.</param>
        /// <param name="notification">A push notification that can be sent to all players except you.</param>
        public Promise<Done> PostMove(Bundle moveData, Bundle updatedGameState = null, PushNotification notification = null)
        {
            UrlBuilder url = new UrlBuilder("/v1/gamer/matches").Path(MatchId).Path("move").QueryParam("lastEventId", LastEventId);
            Bundle config = Bundle.CreateObject();
            config["move"] = moveData;
            config["globalState"] = updatedGameState;
            if (notification != null) config["osn"] = notification.Data;

            HttpRequest req = Gamer.MakeHttpRequest(url);
            req.BodyJson = config;
            return Common.RunInTask<Done>(req, (response, task) => {
                UpdateWithServerData(response.BodyJson["match"]);
                // Record event
                if (updatedGameState != null) {
                    Moves.Clear();
                    GlobalState = updatedGameState;
                }
                Moves.Add(new MatchMove(Gamer.GamerId, moveData));
                task.PostResult(new Done(true, response.BodyJson));
            });
        }
Пример #14
0
 internal ConfiguredProduct(Bundle serverData)
     : base(serverData)
 {
 }
Пример #15
0
 protected PropertiesObject(Bundle baseData)
 {
     Props = baseData;
 }
Пример #16
0
 public GotGodchildEvent(Bundle serverData)
     : base(serverData)
 {
     Gamer = new GamerInfo(serverData["event"]["godchildren"]);
     Reward = serverData["reward"];
 }
Пример #17
0
 /// <summary>
 /// Alternative search function (see #Search for more information) that takes a bundle as a search criteria.
 /// 
 /// It allows using the full Elastic search capabilities with full query DSL search. The query bundle represents
 /// the JSON document as documented here:
 /// https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl.html
 ///
 /// </summary>
 /// <returns>Promise resolved when the operation has finished. The attached object contains various
 ///     information about the results, including a Hits member, which handles the results in a
 ///     paginated way.</returns>
 /// <param name="query">Search query as described in the summary.</param>
 /// <param name="limit">The maximum number of results to return per page.</param>
 /// <param name="offset">Number of the first result.</param>
 public Promise<IndexSearchResult> SearchExtended(Bundle query, int limit = 30, int offset = 0)
 {
     return Search(null, query, null, limit, offset);
 }
Пример #18
0
 private JsonData ToJson(Bundle bundle)
 {
     JsonData target = new JsonData();
     if (bundle.Type == DataType.Object) {
         target.SetJsonType(JsonType.Object);
         foreach (KeyValuePair<string, Bundle> entry in bundle.Dictionary) {
             switch (entry.Value.Type) {
             case DataType.Boolean: target[entry.Key] = entry.Value.AsBool(); break;
             case DataType.Integer: target[entry.Key] = entry.Value.AsLong(); break;
             case DataType.Double: target[entry.Key] = entry.Value.AsDouble(); break;
             case DataType.String: target[entry.Key] = entry.Value.AsString(); break;
             default: target[entry.Key] = ToJson(entry.Value); break;
             }
         }
     }
     else {
         target.SetJsonType(JsonType.Array);
         foreach (Bundle entry in bundle.Array) {
             switch (entry.Type) {
             case DataType.Boolean: target.Add(entry.AsBool()); break;
             case DataType.Integer: target.Add(entry.AsInt()); break;
             case DataType.Double: target.Add(entry.AsDouble()); break;
             case DataType.String: target.Add(entry.AsString()); break;
             default: target.Add(ToJson(entry)); break;
             }
         }
     }
     return target;
 }
Пример #19
0
 internal Score(Bundle serverData, int rank)
     : this(serverData)
 {
     Rank = rank;
 }
Пример #20
0
 internal MatchShoeDrawnEvent(Gamer gamer, Bundle serverData)
     : base(gamer, serverData)
 {
     Count = serverData["event"]["count"];
 }
Пример #21
0
 internal MatchFinishEvent(Gamer gamer, Bundle serverData)
     : base(gamer, serverData)
 {
     Finished = serverData["event"]["finished"];
 }
Пример #22
0
 internal FriendStatusChangeEvent(string status, Bundle serverData)
 {
     FriendId = serverData["event"]["friend"];
     NewStatus = Common.ParseEnum<FriendRelationshipStatus>(status);
 }
Пример #23
0
        /// <summary>
        /// Use this method to send a message to another user from your game.
        /// 
        /// Messages are sent to a specific user, in a specific domain. You can use domains to send messages
        /// across games (or use private for messages sent to your game only).
        ///
        /// </summary>
        /// <returns>Promise resolved when the operation has completed.</returns>
        /// <param name="gamerId">ID of the recipient gamer.</param>
        /// <param name="eventData">JSON object representing the event to be sent. The recipient will receive it as is
        ///     when subscribed to a #CotcSdk.DomainEventLoop (ReceivedEvent property). If the application is not active,
        ///     the message will be queued and transmitted the next time the domain event loop is started.</param>
        /// <param name="notification">Push notification to send to the recipient player if not currently active.</param>
        public Promise<Done> SendEvent(string gamerId, Bundle eventData, PushNotification notification = null)
        {
            UrlBuilder url = new UrlBuilder("/v1/gamer/event").Path(domain).Path(gamerId);
            HttpRequest req = Gamer.MakeHttpRequest(url);
            Bundle config = Bundle.CreateObject();
            config["type"] = "user";
            config["event"] = eventData;
            config["from"] = Gamer.GamerId;
            config["to"] = gamerId;
            config["name"] = Gamer["profile"]["displayname"];
            if (notification != null) config["osn"] = notification.Data;

            req.BodyJson = config;
            return Common.RunInTask<Done>(req, (response, task) => {
                task.PostResult(new Done(true, response.BodyJson));
            });
        }
Пример #24
0
 protected MatchEvent(Gamer gamer, Bundle serverData)
     : base(serverData)
 {
     MatchEventId = serverData["event"]["_id"];
     Match = new MatchInfo(gamer, serverData["event"]["match_id"]);
 }
Пример #25
0
 /// <summary>Call this to attribute a godfather to the currently logged in user.</summary>
 /// <returns>Promise resolved when the operation has completed.</returns>
 /// <param name="code">Is a string as generated by #GenerateCode.</param>
 /// <param name="rewardTx">A transaction Json rewarding the godfather formed as follows:
 ///     { transaction : { "unit" : amount},
 ///     description : "reward transaction",
 ///     domain : "com.clanoftcloud.text.DOMAIN" }
 ///     where description and domain are optional.</param>
 /// <param name="notification">Optional OS notification to be sent to the godfather who generated the code.
 ///     The godfather will reveive an event of type 'godchildren' containing the id of the godchildren
 ///     and the balance/achievements field if rewarded.</param>
 public Promise<Done> UseCode(string code, Bundle rewardTx = null, PushNotification notification = null)
 {
     UrlBuilder url = new UrlBuilder("/v2.6/gamer/godfather").Path(domain);
     HttpRequest req = Gamer.MakeHttpRequest(url);
     Bundle config = Bundle.CreateObject();
     config["godfather"] = code;
     config["osn"] = notification != null ? notification.Data : null;
     config["reward"] = rewardTx;
     req.BodyJson = config;
     return Common.RunInTask<Done>(req, (response, task) => {
         task.PostResult(new Done(response.BodyJson));
     });
 }
Пример #26
0
 private Promise<IndexSearchResult> Search(string query, Bundle jsonData, List<string> sortingProperties, int limit, int offset)
 {
     UrlBuilder url = new UrlBuilder("/v1/index").Path(Domain).Path(IndexName).Path("search");
     if (query != null) url.QueryParam("q", query);
     url.QueryParam("from", offset).QueryParam("max", limit);
     // Build sort property
     if (sortingProperties != null) {
         Bundle sort = Bundle.CreateArray();
         foreach (string s in sortingProperties) sort.Add(s);
         url.QueryParam("sort", sort.ToJson());
     }
     var request = Cloud.MakeUnauthenticatedHttpRequest(url);
     request.Method = "POST";
     if (jsonData != null) request.BodyJson = jsonData;
     return Common.RunInTask<IndexSearchResult>(request, (response, task) => {
         // Fetch listed scores
         IndexSearchResult result = new IndexSearchResult(response.BodyJson, offset);
         foreach (Bundle b in response.BodyJson["hits"].AsArray()) {
             result.Hits.Add(new IndexResult(b));
         }
         // Handle pagination
         if (offset > 0) {
             result.Hits.Previous = () => {
                 var promise = new Promise<PagedList<IndexResult>>();
                 Search(query, jsonData, sortingProperties, limit, offset - limit)
                     .Then(r => promise.Resolve(r.Hits))
                     .Catch(e => promise.Reject(e));
                 return promise;
             };
         }
         if (offset + result.Hits.Count < result.Hits.Total) {
             result.Hits.Next = () => {
                 var promise = new Promise<PagedList<IndexResult>>();
                 Search(query, jsonData, sortingProperties, limit, offset + limit)
                     .Then(r => promise.Resolve(r.Hits))
                     .Catch(e => promise.Reject(e));
                 return promise;
             };
         }
         task.PostResult(result);
     });
 }
Пример #27
0
 internal MatchMoveEvent(Gamer gamer, Bundle serverData)
     : base(gamer, serverData)
 {
     MoveData = serverData["event"]["move"];
     PlayerId = serverData["event"]["player_id"];
 }
Пример #28
0
 public DrawnItemsResult(Bundle serverData)
     : base(serverData)
 {
 }
Пример #29
0
 internal PurchaseTransaction(Bundle serverData)
     : base(serverData)
 {
 }
Пример #30
0
 internal MatchInviteEvent(Gamer gamer, Bundle serverData)
     : base(gamer, serverData)
 {
     Inviter = new GamerInfo(serverData["event"]["inviter"]);
 }