summary refs log tree commit diff stats
path: root/libs/cocoslive
diff options
context:
space:
mode:
Diffstat (limited to 'libs/cocoslive')
-rwxr-xr-xlibs/cocoslive/CLScoreServerPost.h142
-rwxr-xr-xlibs/cocoslive/CLScoreServerPost.m335
-rwxr-xr-xlibs/cocoslive/CLScoreServerRequest.h122
-rwxr-xr-xlibs/cocoslive/CLScoreServerRequest.m257
-rwxr-xr-xlibs/cocoslive/cocoslive.h43
-rwxr-xr-xlibs/cocoslive/cocoslive.m37
6 files changed, 936 insertions, 0 deletions
diff --git a/libs/cocoslive/CLScoreServerPost.h b/libs/cocoslive/CLScoreServerPost.h new file mode 100755 index 0000000..e782b90 --- /dev/null +++ b/libs/cocoslive/CLScoreServerPost.h
@@ -0,0 +1,142 @@
1/*
2 * cocos2d for iPhone: http://www.cocos2d-iphone.org
3 *
4 * Copyright (c) 2008-2010 Ricardo Quesada
5 * Copyright (c) 2011 Zynga Inc.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 * THE SOFTWARE.
24 *
25 */
26
27
28
29#import <UIKit/UIKit.h>
30
31// for MD5 signing
32#import <CommonCrypto/CommonDigest.h>
33
34// cocoslive definitions
35#import "cocoslive.h"
36
37// Score Server protocol version
38#define SCORE_SERVER_PROTOCOL_VERSION @"1.1"
39
40// Server URL
41#ifdef USE_LOCAL_SERVER
42#define SCORE_SERVER_SEND_URL @"http://localhost:8080/api/post-score"
43#define SCORE_SERVER_UPDATE_URL @"http://localhost:8080/api/update-score"
44#else
45#define SCORE_SERVER_SEND_URL @"http://fourislandscores.appspot.com/api/post-score"
46#define SCORE_SERVER_UPDATE_URL @"http://fourislandscores.appspot.com/api/update-score"
47#endif
48
49/// Type of errors from the Post Score request
50typedef enum {
51 /// post request successful
52 kPostStatusOK = 0,
53 /// post request failed to establish a connection. wi-fi isn't enabled.
54 /// Don't retry when this option is preset
55 kPostStatusConnectionFailed = 1,
56 /// post request failed to post the score. Server might be busy.
57 /// Retry is suggested
58 kPostStatusPostFailed = 2,
59} tPostStatus;
60
61enum {
62 //! Invalid Ranking. Valid rankins are from 1 to ...
63 kServerPostInvalidRanking = 0,
64};
65
66/**
67 * Handles the Score Post to the cocos live server
68 */
69@interface CLScoreServerPost : NSObject {
70 /// game key. secret shared with the server.
71 /// used to sign the values to prevent spoofing.
72 NSString *gameKey;
73
74 /// game name, used as a login name.
75 NSString *gameName;
76
77 /// delegate instance of fetch score
78 id delegate;
79
80 /// ranking
81 NSUInteger ranking_;
82
83 /// score was updated
84 BOOL scoreDidUpdate_;
85
86 /// data received
87 NSMutableData *receivedData;
88
89 /// values to send in the POST
90 NSMutableArray *bodyValues;
91
92 /// status of the request
93 tPostStatus postStatus_;
94
95 /// mdt context
96 CC_MD5_CTX md5Ctx;
97
98 /// the connection
99 NSURLConnection *connection_;
100}
101
102/** status from the score post */
103@property (nonatomic,readonly) tPostStatus postStatus;
104
105/** connection to the server */
106@property (nonatomic, retain) NSURLConnection *connection;
107
108/** ranking of your score
109 @since v0.7.3
110 */
111@property (nonatomic,readonly) NSUInteger ranking;
112
113/** whether or not the score was updated
114 @since v0.7.3
115 */
116@property (nonatomic,readonly) BOOL scoreDidUpdate;
117
118/** creates a cocos server with a game name and a game key */
119+(id) serverWithGameName:(NSString*) name gameKey:(NSString*) key delegate:(id)delegate;
120
121/** initializes a cocos server with a game name and a game key */
122-(id) initWithGameName:(NSString*) name gameKey:(NSString*) key delegate:(id)delegate;
123
124/** send the scores to the server. A new entre will be created on the server */
125-(BOOL) sendScore: (NSDictionary*) dict;
126
127/**
128 * Sends a score dictionary to the server for updating an existing entry by playername and device id, or creating a new one.
129 * The passed dictionary must contain a cc_playername key, otherwise it will raise and exception.
130 * @since v0.7.1
131 */
132-(BOOL) updateScore: (NSDictionary*) dict;
133
134@end
135
136/** CocosLivePost protocol */
137@protocol CLPostDelegate <NSObject>
138/** callback method that will be called if the post is successful */
139-(void) scorePostOk:(id) sender;
140/** callback method that will be called if the post fails */
141-(void) scorePostFail:(id) sender;
142@end
diff --git a/libs/cocoslive/CLScoreServerPost.m b/libs/cocoslive/CLScoreServerPost.m new file mode 100755 index 0000000..43ee7b2 --- /dev/null +++ b/libs/cocoslive/CLScoreServerPost.m
@@ -0,0 +1,335 @@
1/*
2 * cocos2d for iPhone: http://www.cocos2d-iphone.org
3 *
4 * Copyright (c) 2008-2010 Ricardo Quesada
5 * Copyright (c) 2011 Zynga Inc.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 * THE SOFTWARE.
24 *
25 */
26
27
28#import "CLScoreServerPost.h"
29#import "ccMacros.h"
30
31// free function used to sort
32NSInteger alphabeticSort(id string1, id string2, void *reverse);
33
34NSInteger alphabeticSort(id string1, id string2, void *reverse)
35{
36 if ((NSInteger *)reverse == NO)
37 return [string2 localizedCaseInsensitiveCompare:string1];
38 return [string1 localizedCaseInsensitiveCompare:string2];
39}
40
41
42@interface CLScoreServerPost (Private)
43-(void) addValue:(NSString*)value key:(NSString*)key;
44-(void) calculateHashAndAddValue:(id)value key:(NSString*)key;
45-(NSString*) getHashForData;
46-(NSData*) getBodyValues;
47-(NSString*) encodeData:(NSString*)data;
48-(NSMutableURLRequest *) scoreServerRequestWithURLString:(NSString *)url;
49-(BOOL) submitScore:(NSDictionary*)dict forUpdate:(BOOL)isUpdate;
50@end
51
52
53@implementation CLScoreServerPost
54
55@synthesize postStatus = postStatus_;
56@synthesize ranking = ranking_;
57@synthesize scoreDidUpdate = scoreDidUpdate_;
58@synthesize connection = connection_;
59
60+(id) serverWithGameName:(NSString*) name gameKey:(NSString*) key delegate:(id) delegate
61{
62 return [[[self alloc] initWithGameName:name gameKey:key delegate:delegate] autorelease];
63}
64
65-(id) initWithGameName:(NSString*) name gameKey:(NSString*) key delegate:(id)aDelegate
66{
67 self = [super init];
68 if( self ) {
69 gameKey = [key retain];
70 gameName = [name retain];
71 bodyValues = [[NSMutableArray arrayWithCapacity:5] retain];
72 delegate = [aDelegate retain];
73 receivedData = [[NSMutableData data] retain];
74
75 ranking_ = kServerPostInvalidRanking;
76 }
77
78 return self;
79}
80
81-(void) dealloc
82{
83 CCLOGINFO(@"deallocing %@", self);
84 [delegate release];
85 [gameKey release];
86 [gameName release];
87 [bodyValues release];
88 [receivedData release];
89 [connection_ release];
90 [super dealloc];
91}
92
93
94#pragma mark ScoreServer send scores
95-(BOOL) sendScore: (NSDictionary*) dict
96{
97 return [self submitScore:dict forUpdate:NO];
98}
99
100-(BOOL) updateScore: (NSDictionary*) dict
101{
102 if (![dict objectForKey:@"cc_playername"]) {
103 // fail. cc_playername + cc_device_id are needed to update an score
104 [NSException raise:@"cocosLive:updateScore" format:@"cc_playername not found"];
105 }
106 return [self submitScore:dict forUpdate:YES];
107}
108
109-(BOOL) submitScore: (NSDictionary*)dict forUpdate:(BOOL)isUpdate
110{
111 [receivedData setLength:0];
112 [bodyValues removeAllObjects];
113
114 // reset status
115 postStatus_ = kPostStatusOK;
116
117 // create the request
118 NSMutableURLRequest *post = [self scoreServerRequestWithURLString:(isUpdate ? SCORE_SERVER_UPDATE_URL : SCORE_SERVER_SEND_URL)];
119
120 CC_MD5_Init( &md5Ctx);
121
122 // hash SHALL be calculated in certain order
123 NSArray *keys = [dict allKeys];
124 int reverseSort = NO;
125 NSArray *sortedKeys = [keys sortedArrayUsingFunction:alphabeticSort context:&reverseSort];
126 for( id key in sortedKeys )
127 [self calculateHashAndAddValue:[dict objectForKey:key] key:key];
128
129 // device id is hashed to prevent spoofing this same score from different devices
130 // one way to prevent a replay attack is to send cc_id & cc_time and use it as primary keys
131
132 [self addValue:[[UIDevice currentDevice] uniqueIdentifier] key:@"cc_device_id"];
133 [self addValue:gameName key:@"cc_gamename"];
134 [self addValue:[self getHashForData] key:@"cc_hash"];
135 [self addValue:SCORE_SERVER_PROTOCOL_VERSION key:@"cc_prot_ver"];
136
137 [post setHTTPBody: [self getBodyValues] ];
138
139 // create the connection with the request
140 // and start loading the data
141 self.connection=[NSURLConnection connectionWithRequest:post delegate:self];
142
143 if ( ! connection_)
144 return NO;
145
146 return YES;
147}
148
149-(NSMutableURLRequest *) scoreServerRequestWithURLString:(NSString *)url {
150 NSMutableURLRequest *request=[NSMutableURLRequest requestWithURL:[NSURL URLWithString: url]
151 cachePolicy:NSURLRequestUseProtocolCachePolicy
152 timeoutInterval:10.0];
153
154 [request setHTTPMethod: @"POST"];
155 [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
156 return request;
157}
158
159-(void) calculateHashAndAddValue:(id) value key:(NSString*) key
160{
161 NSString *val;
162 // value shall be a string or nsnumber
163 if( [value respondsToSelector:@selector(stringValue)] )
164 val = [value stringValue];
165 else if( [value isKindOfClass:[NSString class]] )
166 val = value;
167 else
168 [NSException raise:@"Invalid format for value" format:@"Invalid format for value. addValue"];
169
170 [self addValue:val key:key];
171
172 const char * data = [val UTF8String];
173 CC_MD5_Update( &md5Ctx, data, strlen(data) );
174}
175
176-(void) addValue:(NSString*)value key:(NSString*) key
177{
178
179 NSString *encodedValue = [self encodeData:value];
180 NSString *encodedKey = [self encodeData:key];
181
182 [bodyValues addObject: [NSString stringWithFormat:@"%@=%@", encodedKey, encodedValue] ];
183}
184
185-(NSData*) getBodyValues {
186 NSMutableData *data = [[NSMutableData alloc] init];
187
188 BOOL first=YES;
189 for( NSString *s in bodyValues ) {
190 if( !first)
191 [data appendBytes:"&" length:1];
192
193 [data appendBytes:[s UTF8String] length:[s length]];
194 first = NO;
195 }
196
197 return [data autorelease];
198}
199
200-(NSString*) getHashForData
201{
202 NSString *ret;
203 unsigned char pTempKey[16];
204
205 // update the hash with the secret key
206 const char *data = [gameKey UTF8String];
207 CC_MD5_Update(&md5Ctx, data, strlen(data));
208
209 // then get the hash
210 CC_MD5_Final( pTempKey, &md5Ctx);
211
212// NSData *nsdata = [NSData dataWithBytes:pTempKey length:16];
213 ret = [NSString stringWithString:@""];
214 for( int i=0;i<16;i++) {
215 ret = [NSString stringWithFormat:@"%@%02x", ret, pTempKey[i] ];
216 }
217
218 return ret;
219}
220
221-(NSString*) encodeData:(NSString*) data
222{
223 NSString *newData;
224
225 newData = [data stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
226
227 // '&' and '=' should be encoded manually
228 newData = [newData stringByReplacingOccurrencesOfString:@"&" withString:@"%26"];
229 newData = [newData stringByReplacingOccurrencesOfString:@"=" withString:@"%3D"];
230
231 return newData;
232}
233
234#pragma mark NSURLConnection Delegate
235
236- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
237{
238 // this method is called when the server has determined that it
239 // has enough information to create the NSURLResponse
240
241 // it can be called multiple times, for example in the case of a
242 // redirect, so each time we reset the data.
243 // receivedData is declared as a method instance elsewhere
244 [receivedData setLength:0];
245}
246
247- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
248{
249 // append the new data to the receivedData
250 // receivedData is declared as a method instance elsewhere
251 [receivedData appendData:data];
252
253// NSString *dataString = [NSString stringWithCString:[data bytes] length: [data length]];
254// CCLOG( @"data: %@", dataString);
255}
256
257- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
258{
259 CCLOG(@"Connection failed");
260
261 // wifi problems ?
262 postStatus_ = kPostStatusConnectionFailed;
263
264 // release the connection
265 self.connection = nil;
266
267 if( [delegate respondsToSelector:@selector(scorePostFail:) ] )
268 [delegate scorePostFail:self];
269}
270
271- (void)connectionDidFinishLoading:(NSURLConnection *)connection
272{
273 // release the connection
274 self.connection = nil;
275
276// NSString *dataString = [NSString stringWithCString:[receivedData bytes] length: [receivedData length]];
277 NSString *dataString = [NSString stringWithCString:[receivedData bytes] encoding: NSASCIIStringEncoding];
278
279 if( [dataString hasPrefix:@"OK:"] ) {
280 // parse ranking and other possible answers
281 NSArray *values = [dataString componentsSeparatedByString:@":"];
282 NSArray *answer = [ [values objectAtIndex:1] componentsSeparatedByString:@","];
283 NSEnumerator *nse = [answer objectEnumerator];
284
285 // Create a holder for each line we are going to work with
286 NSString *line;
287
288 // Loop through all the lines in the lines array processing each one
289 while( (line = [nse nextObject]) ) {
290 NSArray *keyvalue = [line componentsSeparatedByString:@"="];
291// NSLog(@"%@",keyvalue);
292 if( [[keyvalue objectAtIndex:0] isEqual:@"ranking"] ) {
293 ranking_ = [[keyvalue objectAtIndex:1] intValue];
294 } else if( [[keyvalue objectAtIndex:0] isEqual:@"score_updated"] ) {
295 scoreDidUpdate_ = [[keyvalue objectAtIndex:1] boolValue];
296 }
297
298 }
299 if( [delegate respondsToSelector:@selector(scorePostOk:) ] )
300 [delegate scorePostOk:self];
301
302 } else if( [dataString hasPrefix: @"OK"] ) {
303
304 // Ok
305 postStatus_ = kPostStatusOK;
306
307 if( [delegate respondsToSelector:@selector(scorePostOk:) ] )
308 [delegate scorePostOk:self];
309
310
311 } else {
312
313 NSLog(@"cocoslive: Post Score failed. Reason: %@", dataString);
314
315 // Error parsing answer
316 postStatus_ = kPostStatusPostFailed;
317
318 if( [delegate respondsToSelector:@selector(scorePostFail:) ] )
319 [delegate scorePostFail:self];
320 }
321}
322
323-(NSURLRequest *)connection:(NSURLConnection *)connection
324 willSendRequest:(NSURLRequest *)request
325 redirectResponse:(NSURLResponse *)redirectResponse
326{
327 NSURLRequest *newRequest=request;
328 if (redirectResponse) {
329 newRequest=nil;
330 }
331
332 return newRequest;
333}
334
335@end
diff --git a/libs/cocoslive/CLScoreServerRequest.h b/libs/cocoslive/CLScoreServerRequest.h new file mode 100755 index 0000000..2002d4c --- /dev/null +++ b/libs/cocoslive/CLScoreServerRequest.h
@@ -0,0 +1,122 @@
1/*
2 * cocos2d for iPhone: http://www.cocos2d-iphone.org
3 *
4 * Copyright (c) 2008-2010 Ricardo Quesada
5 * Copyright (c) 2011 Zynga Inc.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 * THE SOFTWARE.
24 *
25 */
26
27
28
29#import <UIKit/UIKit.h>
30
31// cocoslive definitions
32#import "cocoslive.h"
33
34// Server URL
35#if USE_LOCAL_SERVER
36#define SCORE_SERVER_REQUEST_URL @"http://localhost:8080/api/get-scores"
37#define SCORE_SERVER_GETRANK_URL @"http://localhost:8080/api/get-rank-for-score"
38#else
39#define SCORE_SERVER_REQUEST_URL @"http://fourislandscores.appspot.com/api/get-scores"
40#define SCORE_SERVER_GETRANK_URL @"http://fourislandscores.appspot.com/api/get-rank-for-score"
41#endif
42
43/** Type of predefined Query */
44typedef enum {
45 kQueryIgnore = 0,
46 kQueryDay = 1,
47 kQueryWeek = 2,
48 kQueryMonth = 3,
49 kQueryAllTime = 4,
50} tQueryType;
51
52/** Flags that can be added to the query */
53typedef enum {
54 kQueryFlagIgnore = 0,
55 kQueryFlagByCountry = 1 << 0,
56 kQueryFlagByDevice = 1 << 1,
57} tQueryFlags;
58
59/**
60 * Handles the Request Scores to the cocos live server
61 */
62@interface CLScoreServerRequest : NSObject {
63
64 /// game name, used as a login name.
65 NSString *gameName;
66
67 /// delegate instance of fetch score
68 id delegate;
69
70 // data received
71 NSMutableData *receivedData;
72
73 // To determine which delegate method will be called in connectionDidFinishLoading: of NSURLConnection Delegate
74 BOOL reqRankOnly;
75
76 /// the connection
77 NSURLConnection *connection_;
78}
79
80/** connection to the server */
81@property (nonatomic, retain) NSURLConnection *connection;
82
83
84/** creates a ScoreServerRequest server with a game name*/
85+(id) serverWithGameName:(NSString*) name delegate:(id)delegate;
86
87/** initializes a ScoreServerRequest with a game name*/
88-(id) initWithGameName:(NSString*) name delegate:(id)delegate;
89
90/** request scores from server using a predefined query. This is an asyncronous request.
91 * limit: how many scores are being requested. Maximun is 100
92 * flags: can be kQueryFlagByCountry (fetches only scores from country)
93 * category: an NSString. For example: 'easy', 'medium', 'type1'... When requesting scores, they can be filtered by this field.
94 */
95-(BOOL) requestScores: (tQueryType) type limit:(int)limit offset:(int)offset flags:(tQueryFlags)flags category:(NSString*)category;
96
97/** request scores from server using a predefined query. This is an asyncronous request.
98 * limit: how many scores are being requested. Maximun is 100
99 * flags: can be kQueryFlagByCountry (fetches only scores from country)
100 */
101-(BOOL) requestScores: (tQueryType) type limit:(int)limit offset:(int)offset flags:(tQueryFlags)flags;
102
103/** parse the received JSON scores and convert it to objective-c objects */
104-(NSArray*) parseScores;
105
106/** request rank for a given score using a predefined query. This is an asyncronous request.
107 * score: int for a score
108 * category: an NSString. For example: 'easy', 'medium', 'type1'... When requesting ranks, they can be filtered by this field.
109 */
110-(BOOL) requestRankForScore:(int)score andCategory:(NSString*)category;
111
112/** It's actually not parsing anything, just returning int for a rank. Kept name PARSE for convinience with parseScores */
113-(int) parseRank;
114
115@end
116
117/** CocosLive Request protocol */
118@protocol CLRequestDelegate <NSObject>
119-(void) scoreRequestOk:(id) sender;
120-(void) scoreRequestRankOk:(id) sender;
121-(void) scoreRequestFail:(id) sender;
122@end
diff --git a/libs/cocoslive/CLScoreServerRequest.m b/libs/cocoslive/CLScoreServerRequest.m new file mode 100755 index 0000000..e16b895 --- /dev/null +++ b/libs/cocoslive/CLScoreServerRequest.m
@@ -0,0 +1,257 @@
1/*
2 * cocos2d for iPhone: http://www.cocos2d-iphone.org
3 *
4 * Copyright (c) 2008-2010 Ricardo Quesada
5 * Copyright (c) 2011 Zynga Inc.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 * THE SOFTWARE.
24 *
25 */
26
27
28// 3rd party imports
29#import "CJSONDeserializer.h"
30
31// local imports
32#import "CLScoreServerPost.h"
33#import "CLScoreServerRequest.h"
34#import "ccMacros.h"
35
36@implementation CLScoreServerRequest
37
38@synthesize connection=connection_;
39
40+(id) serverWithGameName:(NSString*) name delegate:(id)delegate
41{
42 return [[[self alloc] initWithGameName:name delegate:delegate] autorelease];
43}
44
45-(id) initWithGameName:(NSString*) name delegate:(id)aDelegate
46{
47 self = [super init];
48 if( self ) {
49 gameName = [[name stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding] retain];
50 delegate = [aDelegate retain];
51 receivedData = [[NSMutableData data] retain];
52 }
53 return self;
54}
55
56-(void) dealloc
57{
58 CCLOGINFO(@"deallocing %@", self);
59
60 [delegate release];
61 [gameName release];
62 [receivedData release];
63 [connection_ release];
64 [super dealloc];
65}
66
67-(BOOL) requestScores:(tQueryType)type
68 limit:(int)limit
69 offset:(int)offset
70 flags:(tQueryFlags)flags
71 category:(NSString*)category
72{
73 // create the request
74 [receivedData setLength:0];
75
76 // it's not a call for rank
77 reqRankOnly = NO;
78
79 NSString *device = @"";
80 if( flags & kQueryFlagByDevice )
81 device = [[UIDevice currentDevice] uniqueIdentifier];
82
83 // arguments:
84 // query: type of query
85 // limit: how many scores are being requested. Default is 25. Maximun is 100
86 // offset: offset of the scores
87 // flags: bring only country scores, world scores, etc.
88 // category: string user defined string used to filter
89 NSString *url= [NSString stringWithFormat:@"%@?gamename=%@&querytype=%d&offset=%d&limit=%d&flags=%d&category=%@&device=%@",
90 SCORE_SERVER_REQUEST_URL,
91 gameName,
92 type,
93 offset,
94 limit,
95 flags,
96 [category stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding],
97 device
98 ];
99
100 // NSLog(@"%@", url);
101
102 NSURLRequest *request=[NSURLRequest requestWithURL:[NSURL URLWithString:url]
103 cachePolicy:NSURLRequestUseProtocolCachePolicy
104 timeoutInterval:10.0];
105
106 // create the connection with the request
107 // and start loading the data
108 self.connection=[NSURLConnection connectionWithRequest:request delegate:self];
109 if (! connection_)
110 return NO;
111
112 return YES;
113}
114
115-(BOOL) requestScores:(tQueryType)type
116 limit:(int)limit
117 offset:(int)offset
118 flags:(tQueryFlags)flags
119{
120 // create the request
121 [receivedData setLength:0];
122
123 // arguments:
124 // query: type of query
125 // limit: how many scores are being requested. Maximun is 100
126 // offset: offset of the scores
127 // flags: bring only country scores, world scores, etc.
128 return [self requestScores:type limit:limit offset:offset flags:flags category:@""];
129}
130
131-(NSArray*) parseScores
132{
133 NSArray *array = nil;
134 NSError *error = nil;
135 NSDictionary *dictionary = [[CJSONDeserializer deserializer] deserializeAsDictionary:receivedData error:&error];
136
137// NSLog(@"r: %@", dictionary);
138 if( ! error ) {
139 array = [dictionary objectForKey:@"scores"];
140 } else {
141 CCLOG(@"Error parsing scores: %@", error);
142 }
143 return array;
144}
145
146#pragma mark Request rank for score
147
148-(BOOL) requestRankForScore:(int)score andCategory:(NSString*)category {
149 // create the request
150 [receivedData setLength:0];
151
152 reqRankOnly = YES;
153
154 // arguments:
155 // score: score for which you need rank
156 // category: user defined string used to filter
157 NSString *url= [NSString stringWithFormat:@"%@?gamename=%@&category=%@&score=%d",
158 SCORE_SERVER_GETRANK_URL,
159 gameName,
160 [category stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding],
161 score
162 ];
163
164 NSURLRequest *request=[NSURLRequest requestWithURL:[NSURL URLWithString:url]
165 cachePolicy:NSURLRequestUseProtocolCachePolicy
166 timeoutInterval:10.0];
167
168 // create the connection with the request
169 // and start loading the data
170 self.connection=[NSURLConnection connectionWithRequest:request delegate:self];
171 if (! connection_)
172 return NO;
173
174 return YES;
175}
176
177-(int) parseRank {
178// NSString *rankStr = [NSString stringWithCString:[receivedData bytes] length: [receivedData length]];
179 NSString *rankStr = [NSString stringWithCString:[receivedData bytes] encoding: NSASCIIStringEncoding];
180
181// NSLog(@"XXXX: Ranking: %@", rankStr);
182
183 // creating trimmed string by trimming everything that's not numbers from the receivedData
184 NSString *trimmedStr = [rankStr stringByTrimmingCharactersInSet:[[NSCharacterSet decimalDigitCharacterSet] invertedSet]];
185
186 int scoreInt = [trimmedStr intValue];
187
188 return scoreInt;
189}
190
191
192#pragma mark NSURLConnection Delegate
193
194- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
195{
196 // this method is called when the server has determined that it
197 // has enough information to create the NSURLResponse
198
199 // it can be called multiple times, for example in the case of a
200 // redirect, so each time we reset the data.
201 // receivedData is declared as a method instance elsewhere
202
203 [receivedData setLength:0];
204}
205
206- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
207{
208 // append the new data to the receivedData
209 // receivedData is declared as a method instance elsewhere
210 [receivedData appendData:data];
211}
212
213- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
214{
215 // release the connection, and the data object
216 self.connection = nil;
217
218
219 CCLOG(@"Error getting scores: %@", error);
220
221 if( [delegate respondsToSelector:@selector(scoreRequestFail:) ] )
222 [delegate scoreRequestFail:self];
223
224}
225
226- (void)connectionDidFinishLoading:(NSURLConnection *)connection
227{
228 // release the connection, and the data object
229 self.connection = nil;
230
231
232 if(reqRankOnly) {
233 // because it's request for rank, different delegate method is called scoreRequestRankOk:
234 // if connection failed the same delegate method is used as for standard scores - scoreRequestFail:
235 if( [delegate respondsToSelector:@selector(scoreRequestRankOk:) ] ) {
236 [delegate scoreRequestRankOk:self];
237 }
238 } else {
239 if( [delegate respondsToSelector:@selector(scoreRequestOk:) ] ) {
240 [delegate scoreRequestOk:self];
241 }
242
243 }
244}
245
246-(NSURLRequest *)connection:(NSURLConnection *)connection
247 willSendRequest:(NSURLRequest *)request
248 redirectResponse:(NSURLResponse *)redirectResponse
249{
250 NSURLRequest *newRequest=request;
251 if (redirectResponse) {
252 newRequest=nil;
253 }
254 return newRequest;
255}
256
257@end
diff --git a/libs/cocoslive/cocoslive.h b/libs/cocoslive/cocoslive.h new file mode 100755 index 0000000..15dbe1a --- /dev/null +++ b/libs/cocoslive/cocoslive.h
@@ -0,0 +1,43 @@
1/*
2 * cocos2d for iPhone: http://www.cocos2d-iphone.org
3 *
4 * Copyright (c) 2008-2010 Ricardo Quesada
5 * Copyright (c) 2011 Zynga Inc.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 * THE SOFTWARE.
24 *
25 */
26
27
28
29// 0x00 HI ME LO
30// 00 00 03 02
31#define COCOSLIVE_VERSION 0x00000302
32
33// to use localserver. DEBUG ONLY
34//#define USE_LOCAL_SERVER 1
35
36// all cocos live include files
37//
38#import "CLScoreServerPost.h"
39#import "CLScoreServerRequest.h"
40
41
42// free functions
43NSString * cocosLiveVersion(void);
diff --git a/libs/cocoslive/cocoslive.m b/libs/cocoslive/cocoslive.m new file mode 100755 index 0000000..613a9d7 --- /dev/null +++ b/libs/cocoslive/cocoslive.m
@@ -0,0 +1,37 @@
1/*
2 * cocos2d for iPhone: http://www.cocos2d-iphone.org
3 *
4 * Copyright (c) 2008-2010 Ricardo Quesada
5 * Copyright (c) 2011 Zynga Inc.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 * THE SOFTWARE.
24 *
25 */
26
27
28#import <UIKit/UIKit.h>
29
30#import "cocoslive.h"
31
32static NSString *version = @"cocoslive v0.3.2";
33
34NSString *cocosLiveVersion()
35{
36 return version;
37}